@earendil-works/pi-coding-agent 0.78.0 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/README.md +26 -6
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +15 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +3 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +2 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -3
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +3 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +9 -3
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/export-html/template.js +19 -6
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +4 -4
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +9 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +41 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +25 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +2 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +29 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +1 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +3 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +3 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +47 -13
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/provider-attribution.d.ts +4 -0
- package/dist/core/provider-attribution.d.ts.map +1 -0
- package/dist/core/provider-attribution.js +72 -0
- package/dist/core/provider-attribution.js.map +1 -0
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +3 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/resource-loader.d.ts +13 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +129 -54
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +7 -33
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +92 -68
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +71 -30
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts +10 -0
- package/dist/core/trust-manager.d.ts.map +1 -0
- package/dist/core/trust-manager.js +133 -0
- package/dist/core/trust-manager.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +195 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +2 -2
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -0
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -12
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +22 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts +20 -0
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/trust-selector.js +86 -0
- package/dist/modes/interactive/components/trust-selector.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +87 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +55 -8
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +54 -22
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/open-browser.d.ts +9 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +22 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/docs/containerization.md +111 -0
- package/docs/docs.json +8 -0
- package/docs/extensions.md +58 -12
- package/docs/index.md +2 -0
- package/docs/packages.md +3 -1
- package/docs/prompt-templates.md +1 -1
- package/docs/providers.md +5 -0
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +5 -0
- package/docs/security.md +57 -0
- package/docs/settings.md +10 -0
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +36 -2
- package/docs/themes.md +1 -1
- package/docs/tmux.md +4 -2
- package/docs/tui.md +10 -1
- package/docs/usage.md +16 -4
- package/examples/extensions/README.md +2 -0
- package/examples/extensions/custom-header.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/gondolin/index.ts +531 -0
- package/examples/extensions/gondolin/package-lock.json +185 -0
- package/examples/extensions/gondolin/package.json +19 -0
- package/examples/extensions/handoff.ts +1 -1
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/overlay-qa-tests.ts +152 -81
- package/examples/extensions/project-trust.ts +64 -0
- package/examples/extensions/qna.ts +1 -1
- package/examples/extensions/question.ts +1 -1
- package/examples/extensions/questionnaire.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/snake.ts +1 -1
- package/examples/extensions/space-invaders.ts +1 -1
- package/examples/extensions/summarize.ts +1 -1
- package/examples/extensions/tic-tac-toe.ts +1 -1
- package/examples/extensions/todo.ts +1 -1
- package/examples/extensions/tools.ts +5 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +5 -8
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { uuidv7 } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
|
-
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync,
|
|
4
|
-
import { readdir,
|
|
3
|
+
import { appendFileSync, closeSync, createReadStream, existsSync, mkdirSync, openSync, readdirSync, readSync, statSync, writeFileSync, } from "fs";
|
|
4
|
+
import { readdir, stat } from "fs/promises";
|
|
5
5
|
import { join, resolve } from "path";
|
|
6
|
+
import { createInterface } from "readline";
|
|
7
|
+
import { StringDecoder } from "string_decoder";
|
|
6
8
|
import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
|
|
7
9
|
import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
8
10
|
import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "./messages.js";
|
|
@@ -228,24 +230,52 @@ export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
|
|
|
228
230
|
}
|
|
229
231
|
return sessionDir;
|
|
230
232
|
}
|
|
233
|
+
const SESSION_READ_BUFFER_SIZE = 1024 * 1024;
|
|
234
|
+
function parseSessionEntryLine(line) {
|
|
235
|
+
if (!line.trim())
|
|
236
|
+
return null;
|
|
237
|
+
try {
|
|
238
|
+
return JSON.parse(line);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// Skip malformed lines
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
231
245
|
/** Exported for testing */
|
|
232
246
|
export function loadEntriesFromFile(filePath) {
|
|
233
247
|
const resolvedFilePath = normalizePath(filePath);
|
|
234
248
|
if (!existsSync(resolvedFilePath))
|
|
235
249
|
return [];
|
|
236
|
-
const content = readFileSync(resolvedFilePath, "utf8");
|
|
237
250
|
const entries = [];
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
251
|
+
const fd = openSync(resolvedFilePath, "r");
|
|
252
|
+
try {
|
|
253
|
+
const decoder = new StringDecoder("utf8");
|
|
254
|
+
const buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);
|
|
255
|
+
let pending = "";
|
|
256
|
+
while (true) {
|
|
257
|
+
const bytesRead = readSync(fd, buffer, 0, buffer.length, null);
|
|
258
|
+
if (bytesRead === 0)
|
|
259
|
+
break;
|
|
260
|
+
pending += decoder.write(buffer.subarray(0, bytesRead));
|
|
261
|
+
let lineStart = 0;
|
|
262
|
+
let newlineIndex = pending.indexOf("\n", lineStart);
|
|
263
|
+
while (newlineIndex !== -1) {
|
|
264
|
+
const entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));
|
|
265
|
+
if (entry)
|
|
266
|
+
entries.push(entry);
|
|
267
|
+
lineStart = newlineIndex + 1;
|
|
268
|
+
newlineIndex = pending.indexOf("\n", lineStart);
|
|
269
|
+
}
|
|
270
|
+
pending = pending.slice(lineStart);
|
|
248
271
|
}
|
|
272
|
+
pending += decoder.end();
|
|
273
|
+
const finalEntry = parseSessionEntryLine(pending);
|
|
274
|
+
if (finalEntry)
|
|
275
|
+
entries.push(finalEntry);
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
closeSync(fd);
|
|
249
279
|
}
|
|
250
280
|
// Validate session header
|
|
251
281
|
if (entries.length === 0)
|
|
@@ -314,73 +344,53 @@ function extractTextContent(message) {
|
|
|
314
344
|
.map((block) => block.text)
|
|
315
345
|
.join(" ");
|
|
316
346
|
}
|
|
317
|
-
function
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
continue;
|
|
327
|
-
const msgTimestamp = message.timestamp;
|
|
328
|
-
if (typeof msgTimestamp === "number") {
|
|
329
|
-
lastActivityTime = Math.max(lastActivityTime ?? 0, msgTimestamp);
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
const entryTimestamp = entry.timestamp;
|
|
333
|
-
if (typeof entryTimestamp === "string") {
|
|
334
|
-
const t = new Date(entryTimestamp).getTime();
|
|
335
|
-
if (!Number.isNaN(t)) {
|
|
336
|
-
lastActivityTime = Math.max(lastActivityTime ?? 0, t);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return lastActivityTime;
|
|
341
|
-
}
|
|
342
|
-
function getSessionModifiedDate(entries, header, statsMtime) {
|
|
343
|
-
const lastActivityTime = getLastActivityTime(entries);
|
|
344
|
-
if (typeof lastActivityTime === "number" && lastActivityTime > 0) {
|
|
345
|
-
return new Date(lastActivityTime);
|
|
347
|
+
function getMessageActivityTime(entry) {
|
|
348
|
+
const message = entry.message;
|
|
349
|
+
if (!isMessageWithContent(message))
|
|
350
|
+
return undefined;
|
|
351
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
352
|
+
return undefined;
|
|
353
|
+
const msgTimestamp = message.timestamp;
|
|
354
|
+
if (typeof msgTimestamp === "number") {
|
|
355
|
+
return msgTimestamp;
|
|
346
356
|
}
|
|
347
|
-
const
|
|
348
|
-
return
|
|
357
|
+
const t = new Date(entry.timestamp).getTime();
|
|
358
|
+
return Number.isNaN(t) ? undefined : t;
|
|
349
359
|
}
|
|
350
360
|
async function buildSessionInfo(filePath) {
|
|
351
361
|
try {
|
|
352
|
-
const content = await readFile(filePath, "utf8");
|
|
353
|
-
const entries = [];
|
|
354
|
-
const lines = content.trim().split("\n");
|
|
355
|
-
for (const line of lines) {
|
|
356
|
-
if (!line.trim())
|
|
357
|
-
continue;
|
|
358
|
-
try {
|
|
359
|
-
entries.push(JSON.parse(line));
|
|
360
|
-
}
|
|
361
|
-
catch {
|
|
362
|
-
// Skip malformed lines
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
if (entries.length === 0)
|
|
366
|
-
return null;
|
|
367
|
-
const header = entries[0];
|
|
368
|
-
if (header.type !== "session")
|
|
369
|
-
return null;
|
|
370
362
|
const stats = await stat(filePath);
|
|
363
|
+
let header = null;
|
|
371
364
|
let messageCount = 0;
|
|
372
365
|
let firstMessage = "";
|
|
373
366
|
const allMessages = [];
|
|
374
367
|
let name;
|
|
375
|
-
|
|
368
|
+
let lastActivityTime;
|
|
369
|
+
const rl = createInterface({
|
|
370
|
+
input: createReadStream(filePath, { encoding: "utf8" }),
|
|
371
|
+
crlfDelay: Infinity,
|
|
372
|
+
});
|
|
373
|
+
for await (const line of rl) {
|
|
374
|
+
const entry = parseSessionEntryLine(line);
|
|
375
|
+
if (!entry)
|
|
376
|
+
continue;
|
|
377
|
+
if (!header) {
|
|
378
|
+
if (entry.type !== "session")
|
|
379
|
+
return null;
|
|
380
|
+
header = entry;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
376
383
|
// Extract session name (use latest, including explicit clears)
|
|
377
384
|
if (entry.type === "session_info") {
|
|
378
|
-
|
|
379
|
-
name = infoEntry.name?.trim() || undefined;
|
|
385
|
+
name = entry.name?.trim() || undefined;
|
|
380
386
|
}
|
|
381
387
|
if (entry.type !== "message")
|
|
382
388
|
continue;
|
|
383
389
|
messageCount++;
|
|
390
|
+
const activityTime = getMessageActivityTime(entry);
|
|
391
|
+
if (typeof activityTime === "number") {
|
|
392
|
+
lastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);
|
|
393
|
+
}
|
|
384
394
|
const message = entry.message;
|
|
385
395
|
if (!isMessageWithContent(message))
|
|
386
396
|
continue;
|
|
@@ -394,9 +404,16 @@ async function buildSessionInfo(filePath) {
|
|
|
394
404
|
firstMessage = textContent;
|
|
395
405
|
}
|
|
396
406
|
}
|
|
407
|
+
if (!header)
|
|
408
|
+
return null;
|
|
397
409
|
const cwd = typeof header.cwd === "string" ? header.cwd : "";
|
|
398
410
|
const parentSessionPath = header.parentSession;
|
|
399
|
-
const
|
|
411
|
+
const headerTime = typeof header.timestamp === "string" ? new Date(header.timestamp).getTime() : NaN;
|
|
412
|
+
const modified = typeof lastActivityTime === "number" && lastActivityTime > 0
|
|
413
|
+
? new Date(lastActivityTime)
|
|
414
|
+
: !Number.isNaN(headerTime)
|
|
415
|
+
? new Date(headerTime)
|
|
416
|
+
: stats.mtime;
|
|
400
417
|
return {
|
|
401
418
|
path: filePath,
|
|
402
419
|
id: header.id,
|
|
@@ -589,8 +606,15 @@ export class SessionManager {
|
|
|
589
606
|
_rewriteFile() {
|
|
590
607
|
if (!this.persist || !this.sessionFile)
|
|
591
608
|
return;
|
|
592
|
-
const
|
|
593
|
-
|
|
609
|
+
const fd = openSync(this.sessionFile, "w");
|
|
610
|
+
try {
|
|
611
|
+
for (const entry of this.fileEntries) {
|
|
612
|
+
writeFileSync(fd, `${JSON.stringify(entry)}\n`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
finally {
|
|
616
|
+
closeSync(fd);
|
|
617
|
+
}
|
|
594
618
|
}
|
|
595
619
|
isPersisted() {
|
|
596
620
|
return this.persist;
|