@oh-my-pi/pi-coding-agent 17.3.0 → 17.3.2

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 (70) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{CHANGELOG-66nakf5b.md → CHANGELOG-fr2awajz.md} +20 -0
  3. package/dist/cli.js +2823 -2823
  4. package/dist/docs-index.generated.txt +1 -1
  5. package/dist/types/cli/args.d.ts +2 -0
  6. package/dist/types/cli/extension-flags.d.ts +3 -3
  7. package/dist/types/cli/flag-tables.d.ts +0 -1
  8. package/dist/types/cli/setup-cli.d.ts +10 -0
  9. package/dist/types/cli/update-cli.d.ts +48 -9
  10. package/dist/types/commands/completions.d.ts +3 -0
  11. package/dist/types/config/claude-paths.d.ts +7 -0
  12. package/dist/types/discovery/agents.d.ts +6 -6
  13. package/dist/types/discovery/helpers.d.ts +3 -4
  14. package/dist/types/extensibility/extensions/runner.d.ts +2 -2
  15. package/dist/types/extensibility/extensions/types.d.ts +4 -0
  16. package/dist/types/launch/broker.d.ts +5 -1
  17. package/dist/types/main.d.ts +1 -1
  18. package/dist/types/mcp/transports/stdio.d.ts +6 -3
  19. package/dist/types/modes/components/footer.d.ts +3 -2
  20. package/dist/types/modes/interactive-mode.d.ts +2 -1
  21. package/dist/types/modes/rpc/rpc-client.d.ts +2 -0
  22. package/dist/types/modes/rpc/rpc-input.d.ts +5 -0
  23. package/dist/types/modes/runtime-init.d.ts +3 -1
  24. package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
  25. package/dist/types/task/executor.d.ts +2 -0
  26. package/dist/types/utils/git.d.ts +19 -0
  27. package/dist/types/utils/shell-snapshot.d.ts +4 -1
  28. package/package.json +13 -13
  29. package/src/async/job-manager.ts +33 -4
  30. package/src/cli/args.ts +14 -3
  31. package/src/cli/extension-flags.ts +6 -10
  32. package/src/cli/flag-tables.ts +2 -10
  33. package/src/cli/gc-cli.ts +13 -3
  34. package/src/cli/setup-cli.ts +2 -2
  35. package/src/cli/update-cli.ts +246 -107
  36. package/src/commands/completions.ts +16 -14
  37. package/src/config/claude-paths.ts +18 -0
  38. package/src/config/model-registry.ts +2 -2
  39. package/src/config.ts +4 -3
  40. package/src/discovery/agents.ts +7 -7
  41. package/src/discovery/claude.ts +5 -6
  42. package/src/discovery/helpers.ts +12 -11
  43. package/src/extensibility/extensions/runner.ts +5 -0
  44. package/src/extensibility/extensions/types.ts +5 -0
  45. package/src/extensibility/legacy-typebox.ts +45 -4
  46. package/src/launch/broker.ts +26 -4
  47. package/src/lsp/mux/server.ts +7 -1
  48. package/src/main.ts +30 -3
  49. package/src/mcp/transports/stdio.ts +7 -3
  50. package/src/modes/acp/acp-agent.ts +1 -0
  51. package/src/modes/components/footer.ts +17 -35
  52. package/src/modes/components/status-line/component.ts +14 -27
  53. package/src/modes/controllers/extension-ui-controller.ts +2 -2
  54. package/src/modes/interactive-mode.ts +16 -9
  55. package/src/modes/print-mode.ts +1 -0
  56. package/src/modes/rpc/rpc-client.ts +4 -2
  57. package/src/modes/rpc/rpc-input.ts +27 -0
  58. package/src/modes/rpc/rpc-mode.ts +11 -19
  59. package/src/modes/runtime-init.ts +5 -1
  60. package/src/modes/utils/ui-helpers.ts +74 -53
  61. package/src/session/agent-session.ts +24 -9
  62. package/src/session/claude-session-store.ts +4 -3
  63. package/src/task/executor.ts +8 -4
  64. package/src/tools/browser/launch.ts +9 -0
  65. package/src/tools/read-format.ts +11 -10
  66. package/src/tools/run-scope.ts +4 -2
  67. package/src/utils/external-editor.ts +10 -11
  68. package/src/utils/git.ts +27 -0
  69. package/src/utils/shell-snapshot.ts +5 -1
  70. package/src/web/search/providers/gemini.ts +4 -9
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Utilities for launching an external text editor ($VISUAL / $EDITOR).
3
3
  */
4
- import { spawn } from "node:child_process";
5
4
  import * as fs from "node:fs/promises";
6
5
  import * as os from "node:os";
7
6
  import * as path from "node:path";
@@ -51,17 +50,17 @@ export async function openInEditor(
51
50
  try {
52
51
  await Bun.write(tmpFile, content);
53
52
 
54
- const [editor, ...editorArgs] = editorCmd.split(" ");
55
- const stdio = options?.stdio ?? ["inherit", "inherit", "inherit"];
56
- const child =
53
+ const [stdin, stdout, stderr] = options?.stdio ?? ["inherit", "inherit", "inherit"];
54
+ const cmd =
57
55
  process.platform === "win32"
58
- ? spawn(editor, [...editorArgs, tmpFile], { stdio, shell: true })
59
- : spawn($which("sh") ?? "sh", ["-c", `${editorCmd} "$1"`, "sh", tmpFile], { stdio });
60
- const { promise, reject, resolve } = Promise.withResolvers<number>();
61
- child.once("exit", (code, signal) => resolve(code ?? (signal ? -1 : 0)));
62
- child.once("error", error => reject(error));
63
- const exitCode = await promise;
64
-
56
+ ? ["cmd", "/c", `${editorCmd} "${tmpFile}"`]
57
+ : [$which("sh") ?? "sh", "-c", `${editorCmd} "$1"`, "sh", tmpFile];
58
+ const child = Bun.spawn(cmd, {
59
+ stdin,
60
+ stdout,
61
+ stderr,
62
+ });
63
+ const exitCode = await child.exited;
65
64
  if (exitCode === 0) {
66
65
  const text = await Bun.file(tmpFile).text();
67
66
  if (options?.trimTrailingNewline === false) {
package/src/utils/git.ts CHANGED
@@ -226,6 +226,11 @@ export const GIT_COMMAND_OUTPUT_LIMIT_BYTES = 8 * 1024 * 1024;
226
226
  * degrades instead of freezing the UI indefinitely.
227
227
  */
228
228
  export const GIT_SPAWN_SYNC_TIMEOUT_MS = 5_000;
229
+ /**
230
+ * Stat-poll interval for {@link head.watch}. One `stat` per interval keeps an
231
+ * always-on status line cheap while surfacing a branch switch within a second.
232
+ */
233
+ export const HEAD_WATCH_INTERVAL_MS = 1000;
229
234
 
230
235
  const GIT_COMMAND_TIMEOUT_EXIT_CODE = 124;
231
236
  // Exit code returned when the `git` binary cannot be launched at all (spawn
@@ -2296,6 +2301,28 @@ export const head = {
2296
2301
  if (result.exitCode !== 0) return null;
2297
2302
  return result.stdout.trim() || null;
2298
2303
  },
2304
+
2305
+ /**
2306
+ * Watch the repository's HEAD for branch moves. Returns a disposer.
2307
+ *
2308
+ * Deliberately stat-polls via `fs.watchFile` instead of `fs.watch`: git
2309
+ * swaps HEAD with `HEAD.lock` + atomic rename, which unlinks the HEAD inode
2310
+ * — and Bun's inotify-backed `fs.watch` permanently stops delivering events
2311
+ * after observing a rename in the watched directory (oven-sh/bun#24875), so
2312
+ * an event watcher fires once and then freezes on Linux (issue #8412 was
2313
+ * the same freeze for file-inode watches on every platform). A path-based
2314
+ * stat poll re-resolves the path each interval and survives inode swaps
2315
+ * everywhere. Reftable repos keep ref state in `<gitDir>/reftable` (their
2316
+ * HEAD file is a static stub), so the poll targets that directory instead.
2317
+ */
2318
+ watch(repository: GitRepository, onChange: () => void): () => void {
2319
+ const target = isReftableRepoSync(repository) ? path.join(repository.gitDir, "reftable") : repository.headPath;
2320
+ const listener = (curr: fs.Stats, prev: fs.Stats) => {
2321
+ if (curr.mtimeMs !== prev.mtimeMs || curr.ino !== prev.ino || curr.size !== prev.size) onChange();
2322
+ };
2323
+ fs.watchFile(target, { interval: HEAD_WATCH_INTERVAL_MS }, listener).unref();
2324
+ return () => fs.unwatchFile(target, listener);
2325
+ },
2299
2326
  };
2300
2327
 
2301
2328
  // ════════════════════════════════════════════════════════════════════════════
@@ -208,10 +208,14 @@ fi
208
208
  /**
209
209
  * Create a shell snapshot, caching the result.
210
210
  * Returns the path to the snapshot file, or null if creation failed.
211
+ *
212
+ * `timeoutMs` is configurable so callers exercising failure handling do not
213
+ * have to wait out the production startup budget.
211
214
  */
212
215
  export async function getOrCreateSnapshot(
213
216
  shell: string,
214
217
  env: Record<string, string | undefined>,
218
+ timeoutMs = SNAPSHOT_TIMEOUT_MS,
215
219
  ): Promise<string | null> {
216
220
  const cacheKey = shell;
217
221
  // Return cached snapshot if valid
@@ -284,7 +288,7 @@ export async function getOrCreateSnapshot(
284
288
  stdin: "ignore",
285
289
  stdout: "ignore",
286
290
  stderr: "ignore",
287
- timeout: SNAPSHOT_TIMEOUT_MS,
291
+ timeout: timeoutMs,
288
292
  killSignal: "SIGKILL",
289
293
  });
290
294
 
@@ -9,11 +9,7 @@
9
9
  * endpoint.
10
10
  */
11
11
  import { type AuthStorage, type FetchImpl, type OAuthAccess, withOAuthAccess } from "@oh-my-pi/pi-ai";
12
- import {
13
- ANTIGRAVITY_SYSTEM_INSTRUCTION,
14
- getAntigravityUserAgent,
15
- getGeminiCliHeaders,
16
- } from "@oh-my-pi/pi-catalog/wire/gemini-headers";
12
+ import { getAntigravityUserAgent, getGeminiCliHeaders } from "@oh-my-pi/pi-catalog/wire/gemini-headers";
17
13
  import { fetchWithRetry, USER_AGENT } from "@oh-my-pi/pi-utils";
18
14
 
19
15
  import type { SearchCitation, SearchResponse, SearchSource } from "../../../web/search/types";
@@ -441,10 +437,9 @@ async function callGeminiSearch(
441
437
  };
442
438
 
443
439
  const normalizedSystemPrompt = systemPrompt?.toWellFormed();
444
- const systemInstructionParts: Array<{ text: string }> = [
445
- ...(auth.isAntigravity ? [{ text: ANTIGRAVITY_SYSTEM_INSTRUCTION }] : []),
446
- ...(normalizedSystemPrompt ? [{ text: normalizedSystemPrompt }] : []),
447
- ];
440
+ const systemInstructionParts: Array<{ text: string }> = normalizedSystemPrompt
441
+ ? [{ text: normalizedSystemPrompt }]
442
+ : [];
448
443
 
449
444
  const requestBody: Record<string, unknown> = {
450
445
  project: auth.projectId,