@oh-my-pi/pi-coding-agent 15.9.3 → 15.9.67

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 (142) hide show
  1. package/CHANGELOG.md +74 -1
  2. package/dist/types/cli/classify-install-target.d.ts +5 -1
  3. package/dist/types/config/keybindings.d.ts +4 -1
  4. package/dist/types/config/settings-schema.d.ts +24 -5
  5. package/dist/types/edit/file-snapshot-store.d.ts +1 -1
  6. package/dist/types/eval/__tests__/kernel-spawn.test.d.ts +1 -0
  7. package/dist/types/eval/backend.d.ts +6 -6
  8. package/dist/types/eval/bridge-timeout.d.ts +27 -0
  9. package/dist/types/eval/idle-timeout.d.ts +16 -14
  10. package/dist/types/eval/js/executor.d.ts +3 -3
  11. package/dist/types/eval/py/executor.d.ts +2 -2
  12. package/dist/types/eval/py/spawn-options.d.ts +58 -0
  13. package/dist/types/modes/components/assistant-message.d.ts +16 -0
  14. package/dist/types/modes/components/copy-selector.d.ts +22 -0
  15. package/dist/types/modes/components/custom-editor.d.ts +3 -1
  16. package/dist/types/modes/components/error-banner.d.ts +11 -0
  17. package/dist/types/modes/components/model-selector.d.ts +1 -0
  18. package/dist/types/modes/components/tool-execution.d.ts +15 -0
  19. package/dist/types/modes/components/transcript-container.d.ts +1 -0
  20. package/dist/types/modes/components/user-message.d.ts +1 -1
  21. package/dist/types/modes/controllers/command-controller.d.ts +0 -1
  22. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  23. package/dist/types/modes/image-references.d.ts +17 -0
  24. package/dist/types/modes/interactive-mode.d.ts +8 -1
  25. package/dist/types/modes/types.d.ts +8 -1
  26. package/dist/types/modes/utils/copy-targets.d.ts +53 -0
  27. package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
  28. package/dist/types/session/blob-store.d.ts +12 -11
  29. package/dist/types/session/session-manager.d.ts +5 -3
  30. package/dist/types/system-prompt.d.ts +2 -0
  31. package/dist/types/tiny/title-client.d.ts +16 -1
  32. package/dist/types/tool-discovery/mode.d.ts +8 -0
  33. package/dist/types/tools/archive-reader.d.ts +5 -1
  34. package/dist/types/tools/eval-render.d.ts +8 -0
  35. package/dist/types/tools/render-utils.d.ts +25 -0
  36. package/dist/types/tui/code-cell.d.ts +6 -0
  37. package/dist/types/tui/hyperlink.d.ts +12 -0
  38. package/dist/types/tui/output-block.d.ts +11 -0
  39. package/dist/types/web/search/render.d.ts +1 -2
  40. package/package.json +9 -9
  41. package/src/autoresearch/dashboard.ts +11 -21
  42. package/src/cli/classify-install-target.ts +31 -5
  43. package/src/cli/claude-trace-cli.ts +13 -1
  44. package/src/cli/plugin-cli.ts +45 -0
  45. package/src/cli/web-search-cli.ts +0 -1
  46. package/src/config/keybindings.ts +58 -1
  47. package/src/config/model-registry.ts +54 -4
  48. package/src/config/settings-schema.ts +25 -5
  49. package/src/debug/raw-sse.ts +18 -4
  50. package/src/edit/file-snapshot-store.ts +1 -1
  51. package/src/edit/index.ts +1 -1
  52. package/src/edit/renderer.ts +7 -7
  53. package/src/edit/streaming.ts +1 -1
  54. package/src/eval/__tests__/agent-bridge.test.ts +100 -27
  55. package/src/eval/__tests__/bridge-timeout.test.ts +64 -0
  56. package/src/eval/__tests__/idle-timeout.test.ts +26 -12
  57. package/src/eval/__tests__/kernel-spawn.test.ts +103 -0
  58. package/src/eval/__tests__/llm-bridge.test.ts +10 -10
  59. package/src/eval/__tests__/shared-executors.test.ts +2 -2
  60. package/src/eval/agent-bridge.ts +4 -5
  61. package/src/eval/backend.ts +6 -6
  62. package/src/eval/bridge-timeout.ts +44 -0
  63. package/src/eval/idle-timeout.ts +33 -15
  64. package/src/eval/js/executor.ts +10 -10
  65. package/src/eval/llm-bridge.ts +4 -5
  66. package/src/eval/py/executor.ts +6 -6
  67. package/src/eval/py/kernel.ts +11 -1
  68. package/src/eval/py/spawn-options.ts +126 -0
  69. package/src/eval/py/tool-bridge.ts +43 -5
  70. package/src/export/ttsr.ts +9 -0
  71. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +31 -2
  72. package/src/extensibility/extensions/runner.ts +2 -0
  73. package/src/internal-urls/docs-index.generated.ts +9 -8
  74. package/src/lsp/client.ts +80 -2
  75. package/src/lsp/index.ts +38 -4
  76. package/src/lsp/render.ts +3 -3
  77. package/src/main.ts +8 -2
  78. package/src/modes/components/agent-dashboard.ts +13 -4
  79. package/src/modes/components/assistant-message.ts +44 -1
  80. package/src/modes/components/copy-selector.ts +249 -0
  81. package/src/modes/components/custom-editor.ts +14 -2
  82. package/src/modes/components/error-banner.ts +33 -0
  83. package/src/modes/components/extensions/extension-list.ts +17 -8
  84. package/src/modes/components/history-search.ts +19 -11
  85. package/src/modes/components/model-selector.ts +125 -29
  86. package/src/modes/components/oauth-selector.ts +28 -12
  87. package/src/modes/components/session-observer-overlay.ts +13 -15
  88. package/src/modes/components/session-selector.ts +24 -13
  89. package/src/modes/components/tool-execution.ts +71 -13
  90. package/src/modes/components/transcript-container.ts +93 -32
  91. package/src/modes/components/tree-selector.ts +19 -7
  92. package/src/modes/components/user-message-selector.ts +25 -14
  93. package/src/modes/components/user-message.ts +9 -2
  94. package/src/modes/controllers/command-controller.ts +0 -116
  95. package/src/modes/controllers/event-controller.ts +67 -12
  96. package/src/modes/controllers/input-controller.ts +33 -1
  97. package/src/modes/controllers/selector-controller.ts +38 -1
  98. package/src/modes/image-references.ts +111 -0
  99. package/src/modes/interactive-mode.ts +52 -17
  100. package/src/modes/theme/theme.ts +46 -10
  101. package/src/modes/types.ts +11 -2
  102. package/src/modes/utils/copy-targets.ts +254 -0
  103. package/src/modes/utils/ui-helpers.ts +23 -2
  104. package/src/prompts/ci-green-request.md +5 -3
  105. package/src/prompts/system/project-prompt.md +1 -0
  106. package/src/prompts/tools/ast-edit.md +1 -1
  107. package/src/prompts/tools/ast-grep.md +1 -1
  108. package/src/prompts/tools/read.md +1 -1
  109. package/src/prompts/tools/search.md +1 -1
  110. package/src/sdk.ts +17 -9
  111. package/src/session/agent-session.ts +43 -14
  112. package/src/session/blob-store.ts +96 -9
  113. package/src/session/session-manager.ts +19 -10
  114. package/src/slash-commands/builtin-registry.ts +3 -11
  115. package/src/system-prompt.ts +4 -0
  116. package/src/task/render.ts +38 -11
  117. package/src/tiny/title-client.ts +7 -1
  118. package/src/tool-discovery/mode.ts +24 -0
  119. package/src/tools/archive-reader.ts +339 -31
  120. package/src/tools/bash.ts +18 -8
  121. package/src/tools/browser/render.ts +5 -4
  122. package/src/tools/debug.ts +3 -3
  123. package/src/tools/eval-render.ts +24 -9
  124. package/src/tools/eval.ts +14 -19
  125. package/src/tools/fetch.ts +34 -14
  126. package/src/tools/gh.ts +65 -11
  127. package/src/tools/index.ts +6 -8
  128. package/src/tools/read.ts +65 -19
  129. package/src/tools/render-utils.ts +46 -0
  130. package/src/tools/search-tool-bm25.ts +4 -6
  131. package/src/tools/search.ts +60 -11
  132. package/src/tools/ssh.ts +21 -8
  133. package/src/tools/write.ts +17 -8
  134. package/src/tui/code-cell.ts +19 -4
  135. package/src/tui/hyperlink.ts +42 -7
  136. package/src/tui/output-block.ts +14 -0
  137. package/src/web/search/index.ts +2 -2
  138. package/src/web/search/render.ts +23 -55
  139. package/dist/types/eval/heartbeat.d.ts +0 -45
  140. package/src/eval/__tests__/heartbeat.test.ts +0 -84
  141. package/src/eval/heartbeat.ts +0 -74
  142. /package/dist/types/eval/__tests__/{heartbeat.test.d.ts → bridge-timeout.test.d.ts} +0 -0
@@ -1,84 +0,0 @@
1
- import { afterEach, describe, expect, it } from "bun:test";
2
- import { EVAL_HEARTBEAT_OP, setBridgeHeartbeatIntervalMs, withBridgeHeartbeat } from "../heartbeat";
3
- import type { JsStatusEvent } from "../js/shared/types";
4
-
5
- describe("withBridgeHeartbeat", () => {
6
- afterEach(() => {
7
- setBridgeHeartbeatIntervalMs();
8
- });
9
-
10
- it("pumps heartbeat events on cadence while the operation is pending, then stops", async () => {
11
- setBridgeHeartbeatIntervalMs(20);
12
- const events: JsStatusEvent[] = [];
13
-
14
- const value = await withBridgeHeartbeat(
15
- event => events.push(event),
16
- async () => {
17
- await Bun.sleep(130);
18
- return "done";
19
- },
20
- );
21
-
22
- expect(value).toBe("done");
23
- // ~6 ticks fit in 130ms at a 20ms cadence; assert it ticked repeatedly
24
- // without pinning the exact count (scheduler jitter).
25
- expect(events.length).toBeGreaterThanOrEqual(3);
26
- expect(events.every(event => event.op === EVAL_HEARTBEAT_OP)).toBe(true);
27
-
28
- // The interval is cleared once the operation settles: no further ticks.
29
- const settledCount = events.length;
30
- await Bun.sleep(80);
31
- expect(events.length).toBe(settledCount);
32
- });
33
-
34
- it("emits a heartbeat immediately so a bridge call extends the budget at once", async () => {
35
- // Interval far longer than the operation: the only beat that can fire is
36
- // the immediate one at call start. It must still reach the sink.
37
- setBridgeHeartbeatIntervalMs(10_000);
38
- const events: JsStatusEvent[] = [];
39
-
40
- await withBridgeHeartbeat(
41
- event => events.push(event),
42
- async () => {
43
- await Bun.sleep(30);
44
- return "done";
45
- },
46
- );
47
-
48
- expect(events.length).toBe(1);
49
- expect(events[0]?.op).toBe(EVAL_HEARTBEAT_OP);
50
- });
51
-
52
- it("runs the operation without emitting when no status sink is wired", async () => {
53
- setBridgeHeartbeatIntervalMs(5);
54
- let ran = 0;
55
-
56
- const value = await withBridgeHeartbeat(undefined, async () => {
57
- ran++;
58
- await Bun.sleep(40);
59
- return 42;
60
- });
61
-
62
- expect(value).toBe(42);
63
- expect(ran).toBe(1);
64
- });
65
-
66
- it("clears the heartbeat even when the operation throws", async () => {
67
- setBridgeHeartbeatIntervalMs(15);
68
- const events: JsStatusEvent[] = [];
69
-
70
- await expect(
71
- withBridgeHeartbeat(
72
- event => events.push(event),
73
- async () => {
74
- await Bun.sleep(60);
75
- throw new Error("boom");
76
- },
77
- ),
78
- ).rejects.toThrow("boom");
79
-
80
- const afterThrow = events.length;
81
- await Bun.sleep(60);
82
- expect(events.length).toBe(afterThrow);
83
- });
84
- });
@@ -1,74 +0,0 @@
1
- /**
2
- * Keepalive for in-flight host-side eval bridge calls.
3
- *
4
- * The eval watchdog ({@link ../tools/eval IdleTimeout}) caps a cell's `timeout`
5
- * as a wall-clock budget on the cell's *own* work, but pauses that budget while
6
- * a host-side `agent()`/`parallel()` (via `runSubprocess`) or `llm()` (a single
7
- * completion) call is in flight. Those calls are the only thing that re-arms the
8
- * watchdog — and they can run for long stretches with **no** status of their own
9
- * (a subagent's time-to-first-token on a reasoning model, a long quiet nested
10
- * tool, or the entire body of a oneshot `llm()` call). Without a keepalive the
11
- * watchdog would mistake that delegated work for the cell stalling and abort it
12
- * mid-flight, killing the subagent.
13
- *
14
- * {@link withBridgeHeartbeat} bridges that gap by emitting a synthetic
15
- * {@link EVAL_HEARTBEAT_OP} status event immediately when the call begins and
16
- * then on a fixed cadence until it settles. The event rides the same
17
- * `emitStatus → onStatus` channel both runtimes already forward, so it re-arms
18
- * the watchdog without any new plumbing. The heartbeat is the *sole* signal that
19
- * extends the budget: consumers MUST treat it as a pure keepalive — bump the
20
- * watchdog and drop it (never persist or render it) — see the executor display
21
- * sinks and the eval tool's `onStatus` handler. Every other status event
22
- * (compute helpers, `log()`/`phase()`, tool results) counts against the budget.
23
- */
24
- import type { JsStatusEvent } from "./js/shared/types";
25
-
26
- /**
27
- * Synthetic status op emitted purely to keep the eval idle watchdog alive while
28
- * a host-side bridge call is in flight. Carries no payload.
29
- */
30
- export const EVAL_HEARTBEAT_OP = "heartbeat";
31
-
32
- /**
33
- * Heartbeat cadence. Comfortably below the default 30s idle budget (and the
34
- * larger budgets long fanouts run under), so a working bridge call always bumps
35
- * the watchdog before it expires, while a genuine stall is still bounded once
36
- * the call settles and the heartbeat stops.
37
- */
38
- const HEARTBEAT_INTERVAL_MS = 5_000;
39
-
40
- let heartbeatIntervalMs = HEARTBEAT_INTERVAL_MS;
41
-
42
- /**
43
- * Test seam: override the heartbeat cadence so integration tests can exercise
44
- * the keepalive within a sub-second idle budget. Pass no value to restore the
45
- * production default.
46
- */
47
- export function setBridgeHeartbeatIntervalMs(ms?: number): void {
48
- heartbeatIntervalMs = ms === undefined ? HEARTBEAT_INTERVAL_MS : Math.max(1, Math.floor(ms));
49
- }
50
-
51
- /**
52
- * Run {@link operation}, pumping {@link EVAL_HEARTBEAT_OP} status events through
53
- * {@link emitStatus} — one immediately, then on a fixed cadence — until it
54
- * settles. The immediate beat pauses the watchdog the instant the call begins,
55
- * so a bridge call that starts close to the budget edge (after the cell already
56
- * spent most of it computing) is not aborted before the first interval tick. A
57
- * no-op wrapper when no `emitStatus` sink is wired (the heartbeat would reach
58
- * nobody).
59
- */
60
- export async function withBridgeHeartbeat<T>(
61
- emitStatus: ((event: JsStatusEvent) => void) | undefined,
62
- operation: () => Promise<T>,
63
- ): Promise<T> {
64
- if (!emitStatus) return operation();
65
- emitStatus({ op: EVAL_HEARTBEAT_OP });
66
- const timer = setInterval(() => emitStatus({ op: EVAL_HEARTBEAT_OP }), heartbeatIntervalMs);
67
- // Never keep the event loop alive for the heartbeat alone.
68
- timer.unref?.();
69
- try {
70
- return await operation();
71
- } finally {
72
- clearInterval(timer);
73
- }
74
- }