@oh-my-pi/pi-coding-agent 16.1.14 → 16.1.16

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/cli.js +3705 -4015
  3. package/dist/types/advisor/runtime.d.ts +3 -0
  4. package/dist/types/cli/args.d.ts +2 -5
  5. package/dist/types/cli/flag-tables.d.ts +2 -2
  6. package/dist/types/cli/session-picker.d.ts +4 -2
  7. package/dist/types/commands/launch.d.ts +1 -1
  8. package/dist/types/config/settings-schema.d.ts +32 -1
  9. package/dist/types/eval/agent-bridge.d.ts +19 -0
  10. package/dist/types/eval/js/shared/helpers.d.ts +1 -13
  11. package/dist/types/eval/js/shared/types.d.ts +1 -1
  12. package/dist/types/eval/js/worker-protocol.d.ts +1 -1
  13. package/dist/types/eval/py/executor.d.ts +1 -1
  14. package/dist/types/export/share.d.ts +8 -1
  15. package/dist/types/internal-urls/local-protocol.d.ts +18 -1
  16. package/dist/types/main.d.ts +2 -0
  17. package/dist/types/mcp/transports/stdio.d.ts +12 -1
  18. package/dist/types/modes/components/plugin-settings.d.ts +5 -0
  19. package/dist/types/modes/components/session-selector.d.ts +25 -0
  20. package/dist/types/modes/components/status-line/context-thresholds.d.ts +4 -3
  21. package/dist/types/modes/components/status-line/types.d.ts +1 -0
  22. package/dist/types/secrets/obfuscator.d.ts +3 -3
  23. package/dist/types/task/isolation-runner.d.ts +128 -0
  24. package/dist/types/task/worktree.d.ts +14 -1
  25. package/dist/types/thinking.d.ts +15 -0
  26. package/dist/types/tools/eval-render.d.ts +3 -0
  27. package/dist/types/tools/eval.d.ts +11 -17
  28. package/dist/types/tools/todo.d.ts +26 -28
  29. package/dist/types/tui/output-block.d.ts +8 -0
  30. package/dist/types/utils/image-resize.d.ts +2 -0
  31. package/dist/types/utils/shell-snapshot.d.ts +10 -0
  32. package/dist/types/web/search/providers/exa.d.ts +2 -0
  33. package/dist/types/web/search/providers/perplexity.d.ts +17 -3
  34. package/package.json +12 -12
  35. package/scripts/build-binary.ts +18 -4
  36. package/src/advisor/__tests__/advisor.test.ts +114 -0
  37. package/src/advisor/runtime.ts +129 -1
  38. package/src/cli/args.ts +4 -5
  39. package/src/cli/flag-tables.ts +3 -3
  40. package/src/cli/gallery-fixtures/interaction.ts +6 -9
  41. package/src/cli/gallery-fixtures/shell.ts +15 -23
  42. package/src/cli/session-picker.ts +17 -3
  43. package/src/commands/launch.ts +3 -3
  44. package/src/config/model-registry.ts +12 -4
  45. package/src/config/settings-schema.ts +37 -1
  46. package/src/edit/renderer.ts +34 -12
  47. package/src/eval/__tests__/agent-bridge.test.ts +462 -3
  48. package/src/eval/__tests__/helpers-local-roots.test.ts +2 -5
  49. package/src/eval/__tests__/julia-prelude.test.ts +1 -30
  50. package/src/eval/__tests__/prelude-agent.test.ts +42 -8
  51. package/src/eval/agent-bridge.ts +301 -71
  52. package/src/eval/jl/prelude.jl +32 -227
  53. package/src/eval/jl/runner.jl +38 -12
  54. package/src/eval/js/shared/helpers.ts +1 -114
  55. package/src/eval/js/shared/prelude.txt +13 -27
  56. package/src/eval/js/shared/runtime.ts +0 -6
  57. package/src/eval/js/shared/types.ts +1 -1
  58. package/src/eval/js/worker-protocol.ts +1 -1
  59. package/src/eval/py/__tests__/prelude.test.ts +13 -0
  60. package/src/eval/py/executor.ts +1 -1
  61. package/src/eval/py/prelude.py +47 -105
  62. package/src/eval/py/runner.py +0 -6
  63. package/src/eval/rb/prelude.rb +21 -189
  64. package/src/eval/rb/runner.rb +116 -9
  65. package/src/exec/bash-executor.ts +44 -0
  66. package/src/export/html/tool-views.generated.js +29 -29
  67. package/src/export/share.ts +51 -28
  68. package/src/internal-urls/docs-index.generated.txt +1 -1
  69. package/src/internal-urls/local-protocol.ts +100 -53
  70. package/src/main.ts +15 -4
  71. package/src/mcp/transports/stdio.ts +20 -4
  72. package/src/modes/acp/acp-event-mapper.ts +7 -2
  73. package/src/modes/components/custom-editor.test.ts +22 -0
  74. package/src/modes/components/custom-editor.ts +10 -1
  75. package/src/modes/components/footer.ts +4 -3
  76. package/src/modes/components/plugin-settings.ts +7 -1
  77. package/src/modes/components/session-selector.ts +143 -29
  78. package/src/modes/components/status-line/component.ts +5 -1
  79. package/src/modes/components/status-line/context-thresholds.ts +11 -3
  80. package/src/modes/components/status-line/segments.ts +1 -1
  81. package/src/modes/components/status-line/types.ts +1 -0
  82. package/src/modes/controllers/command-controller.ts +6 -0
  83. package/src/modes/rpc/rpc-mode.ts +6 -0
  84. package/src/modes/utils/copy-targets.ts +7 -2
  85. package/src/prompts/system/system-prompt.md +6 -6
  86. package/src/prompts/system/workflow-notice.md +3 -3
  87. package/src/prompts/tools/bash.md +18 -2
  88. package/src/prompts/tools/eval.md +19 -19
  89. package/src/prompts/tools/search.md +1 -0
  90. package/src/prompts/tools/todo.md +1 -1
  91. package/src/secrets/obfuscator.ts +3 -9
  92. package/src/session/agent-session.ts +264 -52
  93. package/src/slash-commands/builtin-registry.ts +2 -1
  94. package/src/task/index.ts +61 -207
  95. package/src/task/isolation-runner.ts +354 -0
  96. package/src/task/worktree.ts +46 -9
  97. package/src/thinking.ts +20 -0
  98. package/src/tools/ask.ts +44 -38
  99. package/src/tools/bash.ts +9 -2
  100. package/src/tools/browser/tab-worker.ts +1 -1
  101. package/src/tools/eval-render.ts +34 -27
  102. package/src/tools/eval.ts +100 -103
  103. package/src/tools/index.ts +8 -1
  104. package/src/tools/read.ts +136 -60
  105. package/src/tools/todo.ts +60 -64
  106. package/src/tui/code-cell.ts +1 -1
  107. package/src/tui/output-block.ts +11 -0
  108. package/src/utils/image-resize.ts +30 -0
  109. package/src/utils/shell-snapshot.ts +63 -1
  110. package/src/web/search/providers/exa.ts +85 -1
  111. package/src/web/search/providers/perplexity.ts +18 -6
@@ -3,13 +3,13 @@
3
3
  *
4
4
  * The session JSON is gzipped and sealed with a fresh AES-256-GCM key
5
5
  * (`[12B IV][ciphertext+tag]`, same layout as collab frames), then pushed to
6
- * one of two stores:
6
+ * one of two stores, chosen by `share.store`:
7
7
  *
8
- * 1. A secret GitHub gist (preferredfree, durable, no relay storage)
9
- * holding base64 of the sealed blob, when an authenticated `gh` exists.
10
- * 2. The share server (`POST <serverUrl>` `{"id":"…"}`), capped at 1 MB;
11
- * oversized sessions are truncated (images first, then long strings,
12
- * then oldest entries) until the sealed blob fits.
8
+ * 1. The share server (default`POST <serverUrl>` `{"id":"…"}`), capped
9
+ * at 1 MB; oversized sessions are truncated (images first, then long
10
+ * strings, then oldest entries) until the sealed blob fits.
11
+ * 2. A secret GitHub gist (`store: "gist"`, when an authenticated `gh`
12
+ * exists; falls back to the share server) holding base64 of the blob.
13
13
  *
14
14
  * Either way the link is `<serverUrl>/<id>#<base64url key>`. The viewer page
15
15
  * served there fetches the blob (gist ids are hex; server ids never are),
@@ -50,9 +50,17 @@ const TEXT_CAPS = [32_768, 8_192, 2_048, 512];
50
50
  const BLANK_IMAGE_DATA_URL = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
51
51
  const IMAGE_OMITTED_TEXT = "[image omitted from share]";
52
52
 
53
+ export type ShareStore = "blob" | "gist";
54
+
53
55
  export interface ShareSessionOptions {
54
56
  /** Share server/viewer base URL; defaults to {@link DEFAULT_SHARE_URL}. */
55
57
  serverUrl?: string;
58
+ /**
59
+ * Where to upload the sealed blob. `"blob"` (default) posts to the share
60
+ * server; `"gist"` pushes to a secret GitHub gist first (needs an
61
+ * authenticated `gh`) and falls back to the server.
62
+ */
63
+ store?: ShareStore;
56
64
  /** Agent state for system prompt + tool descriptions in the snapshot. */
57
65
  state?: AgentState;
58
66
  /**
@@ -268,7 +276,7 @@ function redactShareMessage(o: SecretObfuscator, message: AgentMessage): AgentMe
268
276
  }
269
277
  }
270
278
 
271
- /** Share the session; tries a secret gist first, then the share server. */
279
+ /** Share the session; uploads to the share server unless `options.store` is `"gist"`. */
272
280
  export async function shareSession(sm: SessionManager, options?: ShareSessionOptions): Promise<ShareSessionResult> {
273
281
  const data = buildShareSnapshot(sm, options);
274
282
  const keyBytes = new Uint8Array(SHARE_KEY_BYTES);
@@ -277,29 +285,23 @@ export async function shareSession(sm: SessionManager, options?: ShareSessionOpt
277
285
  const keyText = Buffer.from(keyBytes).toString("base64url");
278
286
  const base = normalizeShareServerUrl(options?.serverUrl);
279
287
 
280
- const forGist = await sealToFit(key, data, GIST_MAX_SEALED_BYTES);
281
- const gist = await tryCreateGist(forGist.sealed);
282
- if (gist) {
283
- return {
284
- url: `${base}/${gist.id}#${keyText}`,
285
- method: "gist",
286
- gistUrl: gist.url,
287
- truncated: forGist.truncated,
288
- sealedBytes: forGist.sealed.byteLength,
289
- };
288
+ if (options?.store === "gist") {
289
+ const forGist = await sealToFit(key, data, GIST_MAX_SEALED_BYTES);
290
+ const gist = await tryCreateGist(forGist.sealed);
291
+ if (gist) {
292
+ return {
293
+ url: `${base}/${gist.id}#${keyText}`,
294
+ method: "gist",
295
+ gistUrl: gist.url,
296
+ truncated: forGist.truncated,
297
+ sealedBytes: forGist.sealed.byteLength,
298
+ };
299
+ }
300
+ // gh unusable or gist creation failed — fall back to the share server.
301
+ return shareViaServer(key, data, base, keyText, forGist);
290
302
  }
291
303
 
292
- const forServer =
293
- forGist.sealed.byteLength <= SERVER_MAX_SEALED_BYTES
294
- ? forGist
295
- : await sealToFit(key, data, SERVER_MAX_SEALED_BYTES);
296
- const id = await uploadToServer(forServer.sealed, base);
297
- return {
298
- url: `${base}/${id}#${keyText}`,
299
- method: "server",
300
- truncated: forServer.truncated,
301
- sealedBytes: forServer.sealed.byteLength,
302
- };
304
+ return shareViaServer(key, data, base, keyText);
303
305
  }
304
306
 
305
307
  /** Strip trailing slashes so `<base>/<id>` composes cleanly. */
@@ -433,6 +435,27 @@ async function tryCreateGist(sealed: Uint8Array): Promise<{ id: string; url: str
433
435
  }
434
436
  }
435
437
 
438
+ /** Seal to the server cap (reusing `preFit` when it already fits) and upload. */
439
+ async function shareViaServer(
440
+ key: CryptoKey,
441
+ data: SessionData,
442
+ base: string,
443
+ keyText: string,
444
+ preFit?: SealedSession,
445
+ ): Promise<ShareSessionResult> {
446
+ const forServer =
447
+ preFit && preFit.sealed.byteLength <= SERVER_MAX_SEALED_BYTES
448
+ ? preFit
449
+ : await sealToFit(key, data, SERVER_MAX_SEALED_BYTES);
450
+ const id = await uploadToServer(forServer.sealed, base);
451
+ return {
452
+ url: `${base}/${id}#${keyText}`,
453
+ method: "server",
454
+ truncated: forServer.truncated,
455
+ sealedBytes: forServer.sealed.byteLength,
456
+ };
457
+ }
458
+
436
459
  /** POST the sealed blob to the share server; returns the assigned id. */
437
460
  async function uploadToServer(sealed: Uint8Array, base: string): Promise<string> {
438
461
  let res: Response;