@oh-my-pi/pi-coding-agent 17.3.4 → 17.3.7
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 +88 -0
- package/dist/{CHANGELOG-trcc215s.md → CHANGELOG-1hmwwt45.md} +88 -0
- package/dist/cli.js +3156 -3163
- package/dist/docs-index.generated.txt +1 -1
- package/dist/types/cli/stats-cli.d.ts +1 -6
- package/dist/types/commands/stats.d.ts +4 -0
- package/dist/types/config/model-discovery.d.ts +2 -0
- package/dist/types/config/model-registry.d.ts +6 -1
- package/dist/types/config/settings-schema.d.ts +10 -0
- package/dist/types/debug/report-bundle.d.ts +7 -2
- package/dist/types/extensibility/extensions/loader.d.ts +2 -0
- package/dist/types/extensibility/extensions/runner.d.ts +24 -6
- package/dist/types/extensibility/extensions/types.d.ts +60 -0
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +4 -0
- package/dist/types/launch/presence.d.ts +11 -0
- package/dist/types/lsp/client.d.ts +22 -0
- package/dist/types/lsp/workspace-diagnostics.d.ts +2 -0
- package/dist/types/mcp/config.d.ts +3 -1
- package/dist/types/modes/components/tool-execution.d.ts +3 -1
- package/dist/types/registry/agent-lifecycle.d.ts +11 -0
- package/dist/types/registry/agent-registry.d.ts +4 -0
- package/dist/types/session/agent-session-types.d.ts +0 -2
- package/dist/types/session/agent-session.d.ts +20 -0
- package/dist/types/session/date-cwd-reminder.d.ts +22 -0
- package/dist/types/session/irc-bridge.d.ts +2 -0
- package/dist/types/session/messages.d.ts +4 -0
- package/dist/types/session/session-loader.d.ts +18 -11
- package/dist/types/session/session-maintenance.d.ts +6 -2
- package/dist/types/session/session-manager.d.ts +19 -3
- package/dist/types/session/session-tools.d.ts +0 -1
- package/dist/types/session/turn-recovery.d.ts +7 -7
- package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +1 -0
- package/dist/types/tools/browser/attach.d.ts +16 -0
- package/dist/types/tools/browser/launch.d.ts +2 -2
- package/dist/types/tools/browser.d.ts +1 -1
- package/dist/types/tools/builtin-names.d.ts +1 -1
- package/dist/types/tools/file-write-fallback.d.ts +124 -0
- package/dist/types/tools/hub/jobs.d.ts +6 -0
- package/dist/types/tools/hub/types.d.ts +6 -0
- package/dist/types/tools/index.d.ts +1 -0
- package/dist/types/tools/path-utils.d.ts +23 -0
- package/dist/types/vibe/runtime.d.ts +3 -3
- package/package.json +13 -13
- package/src/auto-thinking/classifier.ts +37 -23
- package/src/cli/models-cli.ts +1 -1
- package/src/cli/stats-cli.ts +6 -72
- package/src/commands/stats.ts +7 -4
- package/src/commit/analysis/conventional.ts +15 -9
- package/src/commit/analysis/summary.ts +15 -9
- package/src/commit/changelog/generate.ts +15 -9
- package/src/commit/map-reduce/map-phase.ts +3 -19
- package/src/commit/map-reduce/reduce-phase.ts +15 -9
- package/src/config/model-discovery.ts +3 -3
- package/src/config/model-registry.ts +29 -16
- package/src/config/settings-schema.ts +13 -0
- package/src/debug/report-bundle.ts +25 -59
- package/src/discovery/claude-plugins.ts +2 -1
- package/src/discovery/claude.ts +4 -2
- package/src/discovery/helpers.ts +5 -0
- package/src/edit/hashline/filesystem.ts +9 -3
- package/src/edit/modes/patch.ts +31 -5
- package/src/edit/renderer.ts +48 -19
- package/src/extensibility/extensions/loader.ts +20 -5
- package/src/extensibility/extensions/runner.ts +239 -24
- package/src/extensibility/extensions/types.ts +62 -0
- package/src/extensibility/extensions/wrapper.ts +26 -11
- package/src/extensibility/legacy-pi-ai-shim.ts +4 -0
- package/src/extensibility/plugins/marketplace/manager.ts +15 -18
- package/src/irc/bus.ts +1 -1
- package/src/launch/broker.ts +8 -1
- package/src/launch/presence.ts +77 -1
- package/src/lsp/client.ts +35 -3
- package/src/lsp/clients/biome-client.ts +47 -93
- package/src/lsp/servers.ts +17 -11
- package/src/lsp/tool.ts +2 -4
- package/src/lsp/workspace-diagnostics.ts +24 -2
- package/src/lsp/writethrough.ts +20 -10
- package/src/mcp/config.ts +50 -6
- package/src/memories/index.ts +29 -25
- package/src/mnemopi/backend.ts +13 -11
- package/src/modes/components/ask-dialog.ts +25 -5
- package/src/modes/components/tool-execution.ts +10 -6
- package/src/modes/components/welcome.ts +4 -1
- package/src/modes/controllers/extension-ui-controller.ts +52 -32
- package/src/modes/controllers/selector-controller.ts +6 -0
- package/src/modes/controllers/tan-command-controller.ts +1 -0
- package/src/modes/interactive-mode.ts +49 -10
- package/src/modes/theme/defaults/birch.json +2 -2
- package/src/prompts/system/checkpoint-active-notice.md +5 -0
- package/src/prompts/system/date-cwd-reminder.md +3 -0
- package/src/prompts/system/project-prompt.md +0 -1
- package/src/prompts/system/rewind-report.md +1 -3
- package/src/prompts/tools/browser.md +1 -0
- package/src/prompts/tools/rewind.md +1 -13
- package/src/registry/agent-lifecycle.ts +34 -0
- package/src/registry/agent-registry.ts +27 -2
- package/src/registry/persisted-agents.ts +40 -20
- package/src/sdk.ts +32 -2
- package/src/session/agent-session-types.ts +0 -2
- package/src/session/agent-session.ts +178 -46
- package/src/session/date-cwd-reminder.ts +77 -0
- package/src/session/irc-bridge.ts +5 -0
- package/src/session/messages.ts +5 -1
- package/src/session/session-loader.ts +106 -64
- package/src/session/session-maintenance.ts +189 -115
- package/src/session/session-manager.ts +142 -35
- package/src/session/session-persistence.ts +4 -4
- package/src/session/session-storage.ts +18 -5
- package/src/session/session-tools.ts +5 -10
- package/src/session/turn-recovery.ts +102 -20
- package/src/session/unexpected-stop-classifier.ts +33 -21
- package/src/slash-commands/builtin-session.ts +1 -1
- package/src/slash-commands/helpers/stats-dashboard.ts +23 -9
- package/src/system-prompt.ts +0 -5
- package/src/task/executor.ts +4 -15
- package/src/task/persisted-revive.ts +3 -6
- package/src/tools/ask.ts +10 -3
- package/src/tools/browser/attach.ts +80 -25
- package/src/tools/browser/launch.ts +44 -15
- package/src/tools/browser/relay/daemon.ts +3 -7
- package/src/tools/browser/render.ts +1 -1
- package/src/tools/browser/shared-daemon.ts +3 -7
- package/src/tools/browser.ts +5 -5
- package/src/tools/builtin-names.ts +7 -3
- package/src/tools/checkpoint.ts +1 -7
- package/src/tools/file-write-fallback.ts +467 -0
- package/src/tools/hub/index.ts +1 -1
- package/src/tools/hub/jobs.ts +20 -3
- package/src/tools/hub/types.ts +6 -0
- package/src/tools/index.ts +1 -0
- package/src/tools/path-utils.ts +79 -0
- package/src/tools/render-utils.ts +53 -21
- package/src/tools/think.ts +15 -3
- package/src/tts/speech-enhancer.ts +19 -14
- package/src/utils/commit-message-generator.ts +14 -12
- package/src/utils/title-generator.ts +23 -19
- package/src/vibe/runtime.ts +32 -17
|
@@ -121,23 +121,36 @@ async function loadBrowsers(): Promise<typeof BrowsersNs> {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* Resolve the Chromium executable puppeteer will launch
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
124
|
+
* Resolve the Chromium executable puppeteer will launch.
|
|
125
|
+
*
|
|
126
|
+
* `PUPPETEER_EXECUTABLE_PATH` always wins. On macOS the isolated Chrome for
|
|
127
|
+
* Testing binary is preferred over a detected system Chrome: a headless
|
|
128
|
+
* daemon launched from a system `Google Chrome.app` bundle shares its
|
|
129
|
+
* LaunchServices bundle identity (`com.google.Chrome`), so macOS can deliver
|
|
130
|
+
* the user's open-URL Apple Events to the daemon and silently swallow their
|
|
131
|
+
* link clicks (#8673). Chrome for Testing uses a dedicated bundle id
|
|
132
|
+
* (`com.google.chrome.for.testing`) that is never a user's default handler;
|
|
133
|
+
* system Chrome is used on macOS only when Chrome for Testing cannot be
|
|
134
|
+
* obtained. Other platforms keep the download-avoiding system Chrome
|
|
135
|
+
* preference and fall back to Chrome for Testing. The managed browser is
|
|
136
|
+
* cached under ~/.omp/puppeteer (getPuppeteerDir). Returns undefined when
|
|
137
|
+
* platform detection fails (puppeteer default resolution takes over).
|
|
138
|
+
* Exported so real-browser tests can probe launchability and skip on hosts
|
|
139
|
+
* missing Chrome's system libraries.
|
|
131
140
|
*/
|
|
132
141
|
let chromiumExecutablePromise: Promise<string | undefined> | undefined;
|
|
133
142
|
export async function ensureChromiumExecutable(): Promise<string | undefined> {
|
|
134
143
|
const envPath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
135
144
|
if (envPath) return envPath;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
// macOS: never route a background daemon through the user's GUI Chrome
|
|
146
|
+
// bundle; prefer the isolated Chrome for Testing binary instead (#8673).
|
|
147
|
+
const preferManagedChromium = process.platform === "darwin";
|
|
148
|
+
if (!preferManagedChromium) {
|
|
149
|
+
const sysChrome = await resolveSystemChromium();
|
|
150
|
+
if (sysChrome) return sysChrome;
|
|
151
|
+
}
|
|
139
152
|
|
|
140
|
-
chromiumExecutablePromise
|
|
153
|
+
chromiumExecutablePromise ??= (async () => {
|
|
141
154
|
const browsers = await loadBrowsers();
|
|
142
155
|
const platform = browsers.detectBrowserPlatform();
|
|
143
156
|
if (!platform) {
|
|
@@ -185,7 +198,23 @@ export async function ensureChromiumExecutable(): Promise<string | undefined> {
|
|
|
185
198
|
"Set PUPPETEER_EXECUTABLE_PATH to use an existing Chrome/Chromium binary, or install one manually.",
|
|
186
199
|
);
|
|
187
200
|
});
|
|
188
|
-
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
return await chromiumExecutablePromise;
|
|
204
|
+
} catch (err) {
|
|
205
|
+
if (!preferManagedChromium) throw err;
|
|
206
|
+
// Chrome for Testing could not be obtained on macOS; degrade to the
|
|
207
|
+
// system Chrome bundle rather than leaving the browser tool unusable.
|
|
208
|
+
const sysChrome = await resolveSystemChromium();
|
|
209
|
+
if (!sysChrome) throw err;
|
|
210
|
+
logger.warn(
|
|
211
|
+
"Chrome for Testing unavailable; falling back to the system Chrome bundle. On macOS this can let the " +
|
|
212
|
+
"headless browser daemon capture your link clicks (#8673). Set PUPPETEER_EXECUTABLE_PATH to a " +
|
|
213
|
+
"dedicated Chromium to avoid this.",
|
|
214
|
+
{ path: sysChrome, error: (err as Error).message },
|
|
215
|
+
);
|
|
216
|
+
return sysChrome;
|
|
217
|
+
}
|
|
189
218
|
}
|
|
190
219
|
|
|
191
220
|
let resolvedChromium: string | null | undefined; // undefined = unchecked; null = not found
|
|
@@ -430,8 +459,8 @@ export interface SharedBrowserLaunchSpec {
|
|
|
430
459
|
* Resolve the executable and complete argv for a shared Chromium the daemon
|
|
431
460
|
* broker spawns directly (no puppeteer inside the broker). Mirrors
|
|
432
461
|
* `launchHeadlessBrowser` flag assembly — puppeteer's default args minus the
|
|
433
|
-
* stealth-suppressed set —
|
|
434
|
-
*
|
|
462
|
+
* stealth-suppressed set — suppresses Puppeteer's unowned startup window, and
|
|
463
|
+
* exposes CDP on an ephemeral port. Returns null when no executable resolves;
|
|
435
464
|
* callers fall back to a process-local launch.
|
|
436
465
|
*/
|
|
437
466
|
export async function resolveSharedBrowserLaunchSpec(opts: {
|
|
@@ -451,7 +480,7 @@ export async function resolveSharedBrowserLaunchSpec(opts: {
|
|
|
451
480
|
});
|
|
452
481
|
return {
|
|
453
482
|
executablePath,
|
|
454
|
-
args: [...defaults.filter(arg => !ignored.has(arg)), "--remote-debugging-port=0"],
|
|
483
|
+
args: [...defaults.filter(arg => !ignored.has(arg)), "--no-startup-window", "--remote-debugging-port=0"],
|
|
455
484
|
};
|
|
456
485
|
}
|
|
457
486
|
|
|
@@ -17,6 +17,7 @@ import { daemonClientForGlobal } from "../../../launch/client";
|
|
|
17
17
|
import { describeQuietly, stopQuietly, waitReady } from "../../../launch/ensure";
|
|
18
18
|
import { resolveWorkerSpawnCmd } from "../../../subprocess/worker-client";
|
|
19
19
|
import { throwIfAborted } from "../../tool-errors";
|
|
20
|
+
import { probeCdpStatus } from "../attach";
|
|
20
21
|
|
|
21
22
|
/** Stable broker daemon name for the relay server. */
|
|
22
23
|
export const RELAY_DAEMON_NAME = "omp.browser.relay";
|
|
@@ -30,13 +31,8 @@ const ENSURE_ATTEMPTS = 3;
|
|
|
30
31
|
|
|
31
32
|
/** True when the relay HTTP server answers /json/version at all (200 = extension connected, 503 = waiting for it). */
|
|
32
33
|
export async function probeRelayServer(cdpUrl: string): Promise<boolean> {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await res.body?.cancel();
|
|
36
|
-
return res.ok || res.status === 503;
|
|
37
|
-
} catch {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
34
|
+
const status = await probeCdpStatus(`${cdpUrl}/json/version`, { timeoutMs: PROBE_TIMEOUT_MS });
|
|
35
|
+
return status === 503 || (status !== null && status >= 200 && status < 300);
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
/** Auto-start is only safe for endpoints this machine can own. */
|
|
@@ -162,7 +162,7 @@ function renderOpenOrCloseLine(
|
|
|
162
162
|
let title: string;
|
|
163
163
|
if (action === "close") {
|
|
164
164
|
const all = args.all === true || (args.name === undefined && details?.name === undefined);
|
|
165
|
-
title = all ? "
|
|
165
|
+
title = all ? "Release all tabs" : `Release ${tabLabel(args, details)}`;
|
|
166
166
|
if (args.kill) title += " (kill)";
|
|
167
167
|
} else {
|
|
168
168
|
title = `Open ${tabLabel(args, details)}`;
|
|
@@ -16,6 +16,7 @@ import { describeQuietly, stopQuietly, waitReady } from "../../launch/ensure";
|
|
|
16
16
|
import { daemonRuntimeDir } from "../../launch/paths";
|
|
17
17
|
import type { DaemonSnapshot } from "../../launch/protocol";
|
|
18
18
|
import { throwIfAborted } from "../tool-errors";
|
|
19
|
+
import { probeCdpStatus } from "./attach";
|
|
19
20
|
import { resolveSharedBrowserLaunchSpec } from "./launch";
|
|
20
21
|
|
|
21
22
|
/** Chrome prints this on stderr once the CDP listener is up; the broker's ready probe captures the line. */
|
|
@@ -50,13 +51,8 @@ async function probeEndpoint(wsEndpoint: string): Promise<boolean> {
|
|
|
50
51
|
} catch {
|
|
51
52
|
return false;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
await res.body?.cancel();
|
|
56
|
-
return res.ok;
|
|
57
|
-
} catch {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
54
|
+
const status = await probeCdpStatus(`http://${host}/json/version`, { timeoutMs: PROBE_TIMEOUT_MS });
|
|
55
|
+
return status !== null && status >= 200 && status < 300;
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
/**
|
package/src/tools/browser.ts
CHANGED
|
@@ -69,7 +69,7 @@ const browserSchema = type({
|
|
|
69
69
|
"dialogs?": type("'accept' | 'dismiss'").describe("auto-handle dialogs"),
|
|
70
70
|
"code?": type("string").describe("js body to run in tab"),
|
|
71
71
|
"timeout?": type("number").describe("timeout in seconds"),
|
|
72
|
-
"all?": type("boolean").describe("
|
|
72
|
+
"all?": type("boolean").describe("release every managed tab"),
|
|
73
73
|
"kill?": type("boolean").describe("also kill spawned-app browsers"),
|
|
74
74
|
});
|
|
75
75
|
|
|
@@ -133,7 +133,7 @@ function resolveBrowserKind(params: BrowserParams, session: ToolSession): Browse
|
|
|
133
133
|
/**
|
|
134
134
|
* Browser tool: stateful, multi-tab. Three actions:
|
|
135
135
|
* - `open` → acquire/create a named tab on a browser kind (headless | spawned | connected) and optionally goto a url.
|
|
136
|
-
* - `close` → release a named tab (or all
|
|
136
|
+
* - `close` → release a named tab handle (or all handles); attached/relay pages remain open, and spawned pages remain unless killed.
|
|
137
137
|
* - `run` → execute JS code against an existing tab with `page`/`browser`/`tab` helpers in scope.
|
|
138
138
|
*/
|
|
139
139
|
export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolDetails> {
|
|
@@ -204,7 +204,7 @@ export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolD
|
|
|
204
204
|
},
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
|
-
caption: "
|
|
207
|
+
caption: "Release every managed tab and kill spawned-app processes",
|
|
208
208
|
call: { action: "close", all: true, kill: true },
|
|
209
209
|
},
|
|
210
210
|
];
|
|
@@ -362,11 +362,11 @@ export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolD
|
|
|
362
362
|
const kill = !!params.kill;
|
|
363
363
|
if (params.all) {
|
|
364
364
|
const count = await untilAborted(signal, () => releaseAllTabs({ kill, timeoutMs }));
|
|
365
|
-
details.result = `
|
|
365
|
+
details.result = `Released ${count} managed tab${count === 1 ? "" : "s"}`;
|
|
366
366
|
return toolResult(details).text(details.result).done();
|
|
367
367
|
}
|
|
368
368
|
const closed = await untilAborted(signal, () => releaseTab(name, { kill, timeoutMs }));
|
|
369
|
-
details.result = closed ? `
|
|
369
|
+
details.result = closed ? `Released managed tab ${JSON.stringify(name)}` : `No tab named ${JSON.stringify(name)}`;
|
|
370
370
|
return toolResult(details).text(details.result).done();
|
|
371
371
|
}
|
|
372
372
|
|
|
@@ -41,10 +41,14 @@ const LEGACY_BUILTIN_TOOL_NAME_ALIASES: ReadonlyMap<string, BuiltinToolName> = n
|
|
|
41
41
|
["find", "glob"],
|
|
42
42
|
]);
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
const CANONICAL_TOOL_NAMES: Record<string, true> = Object.fromEntries(
|
|
45
|
+
[...BUILTIN_TOOL_NAMES, ...HIDDEN_TOOL_NAMES].map(name => [name, true]),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
/** Canonicalize built-in IDs and legacy aliases. Leave plugin names unchanged. */
|
|
45
49
|
export function normalizeToolName(name: string): string {
|
|
46
|
-
const
|
|
47
|
-
return LEGACY_BUILTIN_TOOL_NAME_ALIASES.get(
|
|
50
|
+
const lower = name.toLowerCase();
|
|
51
|
+
return LEGACY_BUILTIN_TOOL_NAME_ALIASES.get(lower) ?? (Object.hasOwn(CANONICAL_TOOL_NAMES, lower) ? lower : name);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
/** Normalize and deduplicate tool names while preserving first-seen order. */
|
package/src/tools/checkpoint.ts
CHANGED
|
@@ -81,13 +81,7 @@ export class CheckpointTool implements AgentTool<typeof checkpointSchema, Checkp
|
|
|
81
81
|
}
|
|
82
82
|
const startedAt = new Date().toISOString();
|
|
83
83
|
return toolResult<CheckpointToolDetails>({ goal: params.goal, startedAt })
|
|
84
|
-
.text(
|
|
85
|
-
[
|
|
86
|
-
"Checkpoint created.",
|
|
87
|
-
`Goal: ${params.goal}`,
|
|
88
|
-
"Run your investigation, then call rewind with a concise report.",
|
|
89
|
-
].join("\n"),
|
|
90
|
-
)
|
|
84
|
+
.text([`Checkpoint: ${params.goal}`, "Finish exploration and formulate findings."].join("\n"))
|
|
91
85
|
.done();
|
|
92
86
|
}
|
|
93
87
|
}
|