@oh-my-pi/pi-coding-agent 17.2.8 → 17.2.10
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 +94 -1
- package/dist/{CHANGELOG-0b0w17se.md → CHANGELOG-rhwzpexa.md} +94 -1
- package/dist/cli.js +13216 -15614
- package/dist/types/async/job-manager.d.ts +12 -0
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/config/model-resolver.d.ts +13 -0
- package/dist/types/discovery/agents.d.ts +11 -0
- package/dist/types/extensibility/custom-commands/types.d.ts +5 -5
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/loader.d.ts +2 -2
- package/dist/types/extensibility/extensions/types.d.ts +34 -8
- package/dist/types/extensibility/hooks/types.d.ts +5 -5
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +10 -0
- package/dist/types/hindsight/state.d.ts +0 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/lsp/utils.d.ts +8 -0
- package/dist/types/main.d.ts +1 -1
- package/dist/types/modes/acp/acp-agent.d.ts +1 -1
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -1
- package/dist/types/modes/acp/acp-event-mapper.d.ts +1 -1
- package/dist/types/modes/acp/acp-mode.d.ts +1 -1
- package/dist/types/modes/components/agent-hub-projection.d.ts +38 -0
- package/dist/types/modes/components/agent-hub-renderer.d.ts +41 -0
- package/dist/types/modes/components/agent-hub.d.ts +12 -5
- package/dist/types/modes/components/model-browser.d.ts +9 -1
- package/dist/types/modes/interactive-mode.d.ts +8 -1
- package/dist/types/modes/session-observer-registry.d.ts +2 -0
- package/dist/types/registry/agent-lifecycle.d.ts +1 -1
- package/dist/types/registry/agent-registry.d.ts +47 -0
- package/dist/types/registry/persisted-agents.d.ts +3 -1
- package/dist/types/session/agent-session-types.d.ts +7 -0
- package/dist/types/session/agent-session.d.ts +8 -4
- package/dist/types/session/session-entries.d.ts +10 -0
- package/dist/types/session/session-loader.d.ts +11 -1
- package/dist/types/session/session-manager.d.ts +9 -1
- package/dist/types/session/session-tools.d.ts +10 -1
- package/dist/types/session/turn-recovery.d.ts +6 -2
- package/dist/types/slash-commands/acp-builtins.d.ts +1 -1
- package/dist/types/slash-commands/available-commands.d.ts +1 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +2 -3
- package/dist/types/task/read-only-policy.d.ts +3 -0
- package/dist/types/task/structured-subagent.d.ts +2 -0
- package/dist/types/task/types.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +3 -3
- package/dist/types/tools/browser/launch.d.ts +3 -0
- package/dist/types/tools/browser/tab-worker.d.ts +2 -2
- package/dist/types/tools/path-utils.d.ts +8 -0
- package/dist/types/tools/read.d.ts +3 -5
- package/dist/types/tools/run-scope.d.ts +27 -1
- package/dist/types/tools/shell-tokenize.d.ts +21 -3
- package/dist/types/tools/terminal-output.d.ts +1 -1
- package/dist/types/utils/changelog.d.ts +3 -2
- package/dist/types/utils/late-cleanup.d.ts +2 -0
- package/dist/types/utils/turndown.d.ts +1 -1
- package/dist/types/vibe/runtime.d.ts +4 -3
- package/dist/types/web/scrapers/readthedocs.d.ts +0 -3
- package/dist/types/web/search/providers/browser-headers.d.ts +2 -3
- package/examples/custom-tools/README.md +1 -1
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/api-demo.ts +5 -6
- package/examples/extensions/chalk-logger.ts +1 -1
- package/examples/extensions/hello.ts +2 -2
- package/examples/extensions/reload-runtime.ts +1 -1
- package/examples/extensions/tools.ts +2 -2
- package/examples/extensions/with-deps/index.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/package.json +15 -31
- package/scripts/bundle-dist.ts +1 -11
- package/scripts/omp +11 -2
- package/src/advisor/runtime.ts +54 -0
- package/src/async/job-manager.ts +26 -0
- package/src/cli/agents-cli.ts +1 -1
- package/src/cli/args.ts +24 -2
- package/src/cli/auth-broker-cli.ts +1 -1
- package/src/cli/auth-gateway-cli.ts +1 -1
- package/src/cli/bench-cli.ts +1 -1
- package/src/cli/claude-trace-cli.ts +1 -1
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/dry-balance-cli.ts +1 -1
- package/src/cli/file-processor.ts +1 -1
- package/src/cli/flag-tables.ts +4 -0
- package/src/cli/grep-cli.ts +1 -1
- package/src/cli/grievances-cli.ts +1 -1
- package/src/cli/help-extra.ts +1 -1
- package/src/cli/models-cli.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/read-cli.ts +1 -1
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli/shell-cli.ts +1 -1
- package/src/cli/ssh-cli.ts +1 -1
- package/src/cli/stats-cli.ts +4 -4
- package/src/cli/tiny-models-cli.ts +1 -1
- package/src/cli/ttsr-cli.ts +1 -1
- package/src/cli/update-cli.ts +3 -57
- package/src/cli/usage-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli/worktree-cli.ts +1 -1
- package/src/commands/say.ts +1 -1
- package/src/commands/token.ts +1 -1
- package/src/commit/agentic/agent.ts +1 -1
- package/src/commit/cli.ts +1 -1
- package/src/config/config-file.ts +2 -2
- package/src/config/keybindings.ts +3 -3
- package/src/config/model-discovery.ts +36 -2
- package/src/config/model-registry.ts +4 -1
- package/src/config/model-resolver.ts +54 -7
- package/src/discovery/agents.ts +73 -3
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +5 -4
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +1 -1
- package/src/discovery/claude.ts +8 -5
- package/src/discovery/cursor.ts +8 -5
- package/src/discovery/gemini.ts +11 -8
- package/src/discovery/vscode.ts +1 -0
- package/src/discovery/windsurf.ts +4 -2
- package/src/edit/hashline/filesystem.ts +7 -7
- package/src/eval/agent-bridge.ts +1 -3
- package/src/eval/jl/prelude.jl +4 -4
- package/src/eval/js/shared/prelude.txt +2 -2
- package/src/eval/py/prelude.py +0 -3
- package/src/eval/py/runner.py +38 -1
- package/src/eval/rb/prelude.rb +1 -2
- package/src/extensibility/custom-commands/loader.ts +4 -4
- package/src/extensibility/custom-commands/types.ts +5 -5
- package/src/extensibility/custom-tools/loader.ts +4 -4
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/loader.ts +7 -6
- package/src/extensibility/extensions/types.ts +39 -8
- package/src/extensibility/hooks/loader.ts +4 -5
- package/src/extensibility/hooks/types.ts +5 -5
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +23 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +53 -0
- package/src/hindsight/state.ts +2 -22
- package/src/index.ts +2 -2
- package/src/internal-urls/memory-protocol.ts +33 -0
- package/src/launch/terminal-output.ts +1 -1
- package/src/lsp/client.ts +2 -2
- package/src/lsp/utils.ts +29 -0
- package/src/main.ts +85 -21
- package/src/markit/converters/docx.ts +1 -1
- package/src/markit/converters/epub.ts +1 -1
- package/src/markit/converters/pptx.ts +1 -1
- package/src/markit/converters/xlsx.ts +1 -1
- package/src/modes/acp/acp-agent.ts +7 -6
- package/src/modes/acp/acp-client-bridge.ts +1 -1
- package/src/modes/acp/acp-event-mapper.ts +1 -1
- package/src/modes/acp/acp-mode.ts +1 -1
- package/src/modes/components/agent-hub-projection.ts +248 -0
- package/src/modes/components/agent-hub-renderer.ts +194 -0
- package/src/modes/components/agent-hub.ts +670 -192
- package/src/modes/components/agent-transcript-viewer.ts +1 -3
- package/src/modes/components/assistant-message.ts +1 -1
- package/src/modes/components/bordered-loader.ts +1 -1
- package/src/modes/components/custom-editor.ts +2 -2
- package/src/modes/components/extensions/inspector-panel.ts +11 -6
- package/src/modes/components/footer.ts +1 -3
- package/src/modes/components/hook-input.ts +1 -1
- package/src/modes/components/hook-selector.ts +2 -2
- package/src/modes/components/model-browser.ts +11 -3
- package/src/modes/components/model-hub.ts +4 -1
- package/src/modes/components/session-selector.ts +2 -2
- package/src/modes/components/status-line/segments.ts +4 -3
- package/src/modes/controllers/event-controller.ts +188 -7
- package/src/modes/controllers/extension-ui-controller.ts +4 -3
- package/src/modes/controllers/mcp-command-controller.ts +81 -20
- package/src/modes/controllers/selector-controller.ts +40 -49
- package/src/modes/controllers/streaming-reveal.ts +1 -1
- package/src/modes/interactive-mode.ts +13 -2
- package/src/modes/print-mode.ts +29 -12
- package/src/modes/rpc/rpc-mode.ts +2 -2
- package/src/modes/runtime-init.ts +1 -1
- package/src/modes/session-observer-registry.ts +5 -0
- package/src/modes/theme/theme.ts +2 -2
- package/src/prompts/tools/computer.md +1 -1
- package/src/registry/agent-lifecycle.ts +35 -10
- package/src/registry/agent-registry.ts +65 -2
- package/src/registry/persisted-agents.ts +341 -16
- package/src/sdk.ts +11 -5
- package/src/session/agent-session-types.ts +8 -0
- package/src/session/agent-session.ts +177 -188
- package/src/session/session-entries.ts +10 -0
- package/src/session/session-listing.ts +1 -1
- package/src/session/session-loader.ts +74 -8
- package/src/session/session-manager.ts +22 -2
- package/src/session/session-paths.ts +105 -110
- package/src/session/session-tools.ts +28 -1
- package/src/session/settings-stream-fn.ts +7 -3
- package/src/session/turn-recovery.ts +236 -18
- package/src/session/unexpected-stop-classifier.ts +12 -3
- package/src/slash-commands/acp-builtins.ts +1 -1
- package/src/slash-commands/available-commands.ts +1 -1
- package/src/slash-commands/helpers/stats-dashboard.ts +2 -1
- package/src/task/agents.ts +1 -1
- package/src/task/executor.ts +173 -47
- package/src/task/index.ts +9 -28
- package/src/task/isolation-runner.ts +43 -12
- package/src/task/persisted-revive.ts +12 -5
- package/src/task/read-only-policy.ts +27 -0
- package/src/task/structured-subagent.ts +31 -6
- package/src/task/types.ts +4 -0
- package/src/tiny/worker.ts +1 -1
- package/src/tools/auto-generated-guard.ts +1 -1
- package/src/tools/bash-interactive.ts +4 -4
- package/src/tools/bash-interceptor.ts +8 -4
- package/src/tools/bash.ts +6 -6
- package/src/tools/browser/cmux/cmux-tab.ts +66 -18
- package/src/tools/browser/launch.ts +76 -19
- package/src/tools/browser/readable.ts +9 -9
- package/src/tools/browser/tab-supervisor.ts +12 -3
- package/src/tools/browser/tab-worker-entry.ts +1 -1
- package/src/tools/browser/tab-worker.ts +101 -12
- package/src/tools/fetch.ts +1 -1
- package/src/tools/glob.ts +4 -2
- package/src/tools/path-utils.ts +22 -5
- package/src/tools/read.ts +22 -5
- package/src/tools/run-scope.ts +290 -4
- package/src/tools/shell-tokenize.ts +38 -9
- package/src/tools/terminal-output.ts +1 -1
- package/src/tools/todo.ts +1 -1
- package/src/utils/changelog.ts +5 -4
- package/src/utils/clipboard.ts +10 -2
- package/src/utils/external-editor.ts +4 -2
- package/src/utils/jj.ts +1 -1
- package/src/utils/late-cleanup.ts +17 -0
- package/src/utils/turndown.ts +1 -2
- package/src/vibe/runtime.ts +202 -58
- package/src/web/scrapers/arxiv.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +1 -1
- package/src/web/scrapers/hackage.ts +1 -12
- package/src/web/scrapers/iacr.ts +1 -1
- package/src/web/scrapers/readthedocs.ts +2 -1
- package/src/web/scrapers/twitter.ts +2 -2
- package/src/web/scrapers/types.ts +1 -1
- package/src/web/scrapers/wikipedia.ts +1 -1
- package/src/web/search/providers/browser-headers.ts +12 -39
- package/src/web/search/providers/codex.ts +3 -26
- package/src/web/search/providers/duckduckgo.ts +1 -1
- package/src/web/search/providers/ecosia.ts +2 -2
- package/src/web/search/providers/exa.ts +1 -1
- package/src/web/search/providers/firecrawl.ts +1 -1
- package/src/web/search/providers/google.ts +1 -1
- package/src/web/search/providers/mojeek.ts +2 -2
- package/src/web/search/providers/perplexity.ts +1 -1
- package/src/web/search/providers/public.ts +1 -1
- package/src/web/search/providers/startpage.ts +2 -2
- package/src/markit/converters/mammoth.d.ts +0 -24
|
@@ -87,11 +87,11 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
87
87
|
return resolvePlanPath(this.session, relativePath);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
canonicalPath(relativePath: string): string {
|
|
90
|
+
override canonicalPath(relativePath: string): string {
|
|
91
91
|
return canonicalSnapshotKey(this.resolveAbsolute(relativePath));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
allowTagPathRecovery(authoredPath: string, resolvedPath: string): boolean {
|
|
94
|
+
override allowTagPathRecovery(authoredPath: string, resolvedPath: string): boolean {
|
|
95
95
|
// Internal-URL authored targets (`local://`, `vault://`, …) are approved
|
|
96
96
|
// at the lower "read" privilege; never let one redirect onto a "write".
|
|
97
97
|
if (isInternalUrlPath(authoredPath)) return false;
|
|
@@ -125,7 +125,7 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
125
125
|
return content;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
async readBinary(relativePath: string): Promise<Uint8Array | undefined> {
|
|
128
|
+
override async readBinary(relativePath: string): Promise<Uint8Array | undefined> {
|
|
129
129
|
const absolutePath = this.resolveAbsolute(relativePath);
|
|
130
130
|
if (isNotebookPath(absolutePath)) return undefined;
|
|
131
131
|
try {
|
|
@@ -136,7 +136,7 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
async preflightWrite(relativePath: string, options?: PreflightWriteOptions): Promise<void> {
|
|
139
|
+
override async preflightWrite(relativePath: string, options?: PreflightWriteOptions): Promise<void> {
|
|
140
140
|
const fileOp = options?.fileOp;
|
|
141
141
|
if (fileOp?.kind === "rem") {
|
|
142
142
|
enforcePlanModeWrite(this.session, relativePath, { op: "delete" });
|
|
@@ -149,7 +149,7 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
149
149
|
enforcePlanModeWrite(this.session, relativePath, { op: "update" });
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async delete(relativePath: string): Promise<void> {
|
|
152
|
+
override async delete(relativePath: string): Promise<void> {
|
|
153
153
|
enforcePlanModeWrite(this.session, relativePath, { op: "delete" });
|
|
154
154
|
const absolutePath = this.resolveAbsolute(relativePath);
|
|
155
155
|
try {
|
|
@@ -168,7 +168,7 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
168
168
|
invalidateFsScanAfterWrite(absolutePath);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
async move(fromRelative: string, toRelative: string, content?: string): Promise<void> {
|
|
171
|
+
override async move(fromRelative: string, toRelative: string, content?: string): Promise<void> {
|
|
172
172
|
enforcePlanModeWrite(this.session, fromRelative, { op: "update", move: toRelative });
|
|
173
173
|
const fromAbsolute = this.resolveAbsolute(fromRelative);
|
|
174
174
|
const toAbsolute = this.resolveAbsolute(toRelative);
|
|
@@ -240,7 +240,7 @@ export class HashlineFilesystem extends Filesystem {
|
|
|
240
240
|
return { text: content };
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
async exists(relativePath: string): Promise<boolean> {
|
|
243
|
+
override async exists(relativePath: string): Promise<boolean> {
|
|
244
244
|
const absolutePath = this.resolveAbsolute(relativePath);
|
|
245
245
|
return Bun.file(absolutePath).exists();
|
|
246
246
|
}
|
package/src/eval/agent-bridge.ts
CHANGED
|
@@ -23,7 +23,6 @@ export const EVAL_AGENT_BRIDGE_NAME = "__agent__";
|
|
|
23
23
|
const agentArgsSchema = type({
|
|
24
24
|
prompt: "string>0",
|
|
25
25
|
"agent?": "string>0",
|
|
26
|
-
"model?": "string>0|string>0[]",
|
|
27
26
|
"label?": "string",
|
|
28
27
|
"schema?": "unknown",
|
|
29
28
|
"schemaMode?": "'permissive' | 'strict'",
|
|
@@ -31,12 +30,12 @@ const agentArgsSchema = type({
|
|
|
31
30
|
"apply?": "boolean",
|
|
32
31
|
"merge?": "boolean",
|
|
33
32
|
"handle?": "boolean",
|
|
33
|
+
"+": "delete",
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
interface EvalAgentArgs {
|
|
37
37
|
prompt: string;
|
|
38
38
|
agent?: string;
|
|
39
|
-
model?: string | string[];
|
|
40
39
|
label?: string;
|
|
41
40
|
schema?: unknown;
|
|
42
41
|
schemaMode?: StructuredSubagentSchemaMode;
|
|
@@ -148,7 +147,6 @@ export async function runEvalAgent(args: unknown, options: EvalAgentBridgeOption
|
|
|
148
147
|
invocationKind: "eval",
|
|
149
148
|
assignment: parsed.prompt,
|
|
150
149
|
...(parsed.agent !== undefined ? { agent: parsed.agent } : {}),
|
|
151
|
-
...(parsed.model !== undefined ? { model: parsed.model } : {}),
|
|
152
150
|
...(Object.hasOwn(parsed, "schema") ? { outputSchema: parsed.schema } : {}),
|
|
153
151
|
...(parsed.schemaMode !== undefined ? { schemaMode: parsed.schemaMode } : {}),
|
|
154
152
|
...(parsed.label !== undefined ? { identity: { label: parsed.label } } : {}),
|
package/src/eval/jl/prelude.jl
CHANGED
|
@@ -519,14 +519,11 @@ function completion(prompt::String; model="default", system=nothing, schema=noth
|
|
|
519
519
|
return schema === nothing ? text : Main.json_parse(string(text))
|
|
520
520
|
end
|
|
521
521
|
|
|
522
|
-
function agent(prompt::String; agent="task",
|
|
522
|
+
function agent(prompt::String; agent="task", label=nothing, schema=nothing, schema_mode=nothing, isolated=nothing, apply=nothing, merge=nothing, handle=false, kwargs...)
|
|
523
523
|
args_dict = Dict{String, Any}("prompt" => prompt)
|
|
524
524
|
if agent !== nothing
|
|
525
525
|
args_dict["agent"] = agent
|
|
526
526
|
end
|
|
527
|
-
if model !== nothing
|
|
528
|
-
args_dict["model"] = model
|
|
529
|
-
end
|
|
530
527
|
if label !== nothing
|
|
531
528
|
args_dict["label"] = label
|
|
532
529
|
end
|
|
@@ -545,6 +542,9 @@ function agent(prompt::String; agent="task", model=nothing, label=nothing, schem
|
|
|
545
542
|
if merge !== nothing
|
|
546
543
|
args_dict["merge"] = Bool(merge)
|
|
547
544
|
end
|
|
545
|
+
if haskey(kwargs, :model)
|
|
546
|
+
error("agent() no longer accepts a per-call model override; the selected agent's frontmatter model is used")
|
|
547
|
+
end
|
|
548
548
|
handle_result = handle
|
|
549
549
|
for (k, v) in kwargs
|
|
550
550
|
args_dict[string(k)] = v
|
|
@@ -104,8 +104,8 @@ if (!globalThis.__omp_js_prelude_loaded__) {
|
|
|
104
104
|
"agent",
|
|
105
105
|
opts,
|
|
106
106
|
rest,
|
|
107
|
-
["agent", "
|
|
108
|
-
"{ agent,
|
|
107
|
+
["agent", "label", "schema", "isolated", "apply", "merge", "schemaMode"],
|
|
108
|
+
"{ agent, label, schema, isolated, apply, merge, schemaMode, handle }",
|
|
109
109
|
);
|
|
110
110
|
const { handle, ...callArgs } = o;
|
|
111
111
|
const res = await globalThis.__omp_call_tool__("__agent__", { prompt, ...callArgs, handle: Boolean(handle) });
|
package/src/eval/py/prelude.py
CHANGED
|
@@ -488,7 +488,6 @@ if "__omp_prelude_loaded__" not in globals():
|
|
|
488
488
|
prompt,
|
|
489
489
|
*,
|
|
490
490
|
agent="task",
|
|
491
|
-
model=None,
|
|
492
491
|
label=None,
|
|
493
492
|
schema=None,
|
|
494
493
|
schema_mode=None,
|
|
@@ -506,8 +505,6 @@ if "__omp_prelude_loaded__" not in globals():
|
|
|
506
505
|
args = {"prompt": prompt}
|
|
507
506
|
if agent is not None:
|
|
508
507
|
args["agent"] = agent
|
|
509
|
-
if model is not None:
|
|
510
|
-
args["model"] = model
|
|
511
508
|
if label is not None:
|
|
512
509
|
args["label"] = label
|
|
513
510
|
if schema is not None:
|
package/src/eval/py/runner.py
CHANGED
|
@@ -40,6 +40,7 @@ import os
|
|
|
40
40
|
import re
|
|
41
41
|
import runpy
|
|
42
42
|
import shlex
|
|
43
|
+
import shutil
|
|
43
44
|
import signal
|
|
44
45
|
import subprocess
|
|
45
46
|
import sys
|
|
@@ -576,8 +577,10 @@ class _BoundedLineScanner:
|
|
|
576
577
|
def _magic_pip(args: str) -> None:
|
|
577
578
|
argv = shlex.split(args) if args else ["--help"]
|
|
578
579
|
cmd = [sys.executable, "-m", "pip", *argv]
|
|
580
|
+
# stdin=DEVNULL: see _run_shell_body.
|
|
579
581
|
proc = subprocess.Popen(
|
|
580
582
|
cmd,
|
|
583
|
+
stdin=subprocess.DEVNULL,
|
|
581
584
|
stdout=subprocess.PIPE,
|
|
582
585
|
stderr=subprocess.STDOUT,
|
|
583
586
|
)
|
|
@@ -737,9 +740,37 @@ def _magic_run(args: str) -> None:
|
|
|
737
740
|
_STATE.user_ns[name] = value
|
|
738
741
|
|
|
739
742
|
|
|
743
|
+
def _resolve_bash() -> str:
|
|
744
|
+
if os.name != "nt":
|
|
745
|
+
return "/bin/bash"
|
|
746
|
+
# Prefer Git Bash over WSL's System32 bash.exe, which runs inside a
|
|
747
|
+
# separate Linux environment and does not share the Windows filesystem
|
|
748
|
+
# layout or PATH.
|
|
749
|
+
for env_var, suffix in (
|
|
750
|
+
("ProgramFiles", r"Git\bin\bash.exe"),
|
|
751
|
+
("ProgramFiles(x86)", r"Git\bin\bash.exe"),
|
|
752
|
+
("LOCALAPPDATA", r"Programs\Git\bin\bash.exe"),
|
|
753
|
+
):
|
|
754
|
+
root = os.environ.get(env_var)
|
|
755
|
+
if root:
|
|
756
|
+
candidate = os.path.join(root, suffix)
|
|
757
|
+
if os.path.isfile(candidate):
|
|
758
|
+
return candidate
|
|
759
|
+
found = shutil.which("bash")
|
|
760
|
+
if found and "system32" not in found.lower():
|
|
761
|
+
return found
|
|
762
|
+
# WSL's System32 bash.exe runs in a separate Linux environment, so
|
|
763
|
+
# silently falling back to it would execute the cell somewhere the user
|
|
764
|
+
# did not intend; fail loudly instead.
|
|
765
|
+
raise RuntimeError(
|
|
766
|
+
"%%bash requires a POSIX bash, but none was found. "
|
|
767
|
+
"Install Git for Windows or add a non-WSL bash to PATH."
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
|
|
740
771
|
@cell_magic("bash")
|
|
741
772
|
def _magic_cell_bash(args: str, body: str) -> int:
|
|
742
|
-
return _run_shell_body(body, shell_arg=
|
|
773
|
+
return _run_shell_body(body, shell_arg=_resolve_bash())
|
|
743
774
|
|
|
744
775
|
|
|
745
776
|
@cell_magic("capture")
|
|
@@ -780,8 +811,12 @@ def _magic_cell_writefile(args: str, body: str) -> str:
|
|
|
780
811
|
|
|
781
812
|
|
|
782
813
|
def _run_shell_body(body: str, *, shell_arg: str) -> int:
|
|
814
|
+
# stdin=DEVNULL: children must not inherit the runner's stdin, which is
|
|
815
|
+
# the host's NDJSON control channel (a reading child would steal frames,
|
|
816
|
+
# and inheriting the pipe deadlocks nested interpreters on Windows).
|
|
783
817
|
proc = subprocess.Popen(
|
|
784
818
|
[shell_arg, "-c", body],
|
|
819
|
+
stdin=subprocess.DEVNULL,
|
|
785
820
|
stdout=subprocess.PIPE,
|
|
786
821
|
stderr=subprocess.STDOUT,
|
|
787
822
|
)
|
|
@@ -821,9 +856,11 @@ class _ShellResult(list):
|
|
|
821
856
|
|
|
822
857
|
|
|
823
858
|
def __omp_shell(cmd: str) -> _ShellResult:
|
|
859
|
+
# stdin=DEVNULL: see _run_shell_body.
|
|
824
860
|
proc = subprocess.Popen(
|
|
825
861
|
cmd,
|
|
826
862
|
shell=True,
|
|
863
|
+
stdin=subprocess.DEVNULL,
|
|
827
864
|
stdout=subprocess.PIPE,
|
|
828
865
|
stderr=subprocess.STDOUT,
|
|
829
866
|
)
|
package/src/eval/rb/prelude.rb
CHANGED
|
@@ -392,10 +392,9 @@ unless defined?($__omp_prelude_loaded) && $__omp_prelude_loaded
|
|
|
392
392
|
schema.nil? ? text : JSON.parse(text)
|
|
393
393
|
end
|
|
394
394
|
|
|
395
|
-
def agent(prompt, agent: "task",
|
|
395
|
+
def agent(prompt, agent: "task", label: nil, schema: nil, schema_mode: nil, isolated: nil, apply: nil, merge: nil, handle: false)
|
|
396
396
|
args = { "prompt" => prompt }
|
|
397
397
|
args["agent"] = agent unless agent.nil?
|
|
398
|
-
args["model"] = model unless model.nil?
|
|
399
398
|
args["label"] = label unless label.nil?
|
|
400
399
|
args["schema"] = schema unless schema.nil?
|
|
401
400
|
args["schemaMode"] = schema_mode unless schema_mode.nil?
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
import
|
|
10
|
-
import * as
|
|
9
|
+
import { type } from "@oh-my-pi/omptype";
|
|
10
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
11
11
|
import { getAgentDir, getProjectDir, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
12
12
|
import { getConfigDirs } from "../../config";
|
|
13
13
|
import { execCommand } from "../../exec/exec";
|
|
@@ -187,8 +187,8 @@ export async function loadCustomCommands(options: LoadCustomCommandsOptions = {}
|
|
|
187
187
|
exec: (command: string, args: string[], execOptions) =>
|
|
188
188
|
execCommand(command, args, execOptions?.cwd ?? cwd, execOptions),
|
|
189
189
|
typebox,
|
|
190
|
-
arktype,
|
|
191
|
-
zod
|
|
190
|
+
arktype: type,
|
|
191
|
+
zod,
|
|
192
192
|
pi: PiCodingAgent,
|
|
193
193
|
};
|
|
194
194
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Unlike markdown commands which expand to prompts, custom commands can execute
|
|
6
6
|
* arbitrary logic with full access to the hook context.
|
|
7
7
|
*/
|
|
8
|
-
import type
|
|
8
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
9
9
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
10
10
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
11
11
|
import type { ExecOptions, ExecResult, HookCommandContext } from "../../extensibility/hooks/types";
|
|
@@ -23,11 +23,11 @@ export interface CustomCommandAPI {
|
|
|
23
23
|
cwd: string;
|
|
24
24
|
/** Execute a shell command */
|
|
25
25
|
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
26
|
-
/** Injected
|
|
26
|
+
/** Injected TypeBox shim (legacy/compat). */
|
|
27
27
|
typebox: typeof TypeBox;
|
|
28
|
-
/** Injected
|
|
29
|
-
arktype: typeof
|
|
30
|
-
/** Injected
|
|
28
|
+
/** Injected omptype schema builder for custom commands. */
|
|
29
|
+
arktype: typeof ArkType;
|
|
30
|
+
/** Injected Zod-compatible omptype builder for custom commands. */
|
|
31
31
|
zod: typeof zod;
|
|
32
32
|
/** Injected pi-coding-agent exports */
|
|
33
33
|
pi: typeof PiCodingAgent;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom tool loader - loads TypeScript tool modules using native Bun import.
|
|
3
3
|
*
|
|
4
|
-
* Dependencies
|
|
5
|
-
*
|
|
4
|
+
* Dependencies are injected through CustomToolAPI so tools loaded from user
|
|
5
|
+
* directories do not depend on workspace module resolution.
|
|
6
6
|
*/
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import { type } from "@oh-my-pi/omptype";
|
|
9
|
-
import * as
|
|
9
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
10
10
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
11
11
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
12
12
|
import { toolCapability } from "../../capability/tool";
|
|
@@ -149,7 +149,7 @@ export class CustomToolLoader {
|
|
|
149
149
|
logger,
|
|
150
150
|
typebox,
|
|
151
151
|
arktype: type,
|
|
152
|
-
zod
|
|
152
|
+
zod,
|
|
153
153
|
pi,
|
|
154
154
|
pushPendingAction: action => {
|
|
155
155
|
if (!pushPendingAction) {
|
|
@@ -70,7 +70,7 @@ export interface CustomToolAPI {
|
|
|
70
70
|
typebox: typeof TypeBox;
|
|
71
71
|
/** Injected arktype module for arktype-authored custom tools. */
|
|
72
72
|
arktype: typeof ArkType;
|
|
73
|
-
/** Injected
|
|
73
|
+
/** Injected Zod-compatible omptype builder for custom tools. */
|
|
74
74
|
zod: typeof zod;
|
|
75
75
|
/** Injected pi-coding-agent exports */
|
|
76
76
|
pi: typeof PiCodingAgent;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import type * as fs1 from "node:fs";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import {
|
|
8
|
-
import * as
|
|
7
|
+
import { type } from "@oh-my-pi/omptype";
|
|
8
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
9
9
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
10
10
|
import type {
|
|
11
11
|
ImageContent,
|
|
@@ -46,6 +46,7 @@ import type {
|
|
|
46
46
|
ProviderConfig,
|
|
47
47
|
RegisteredCommand,
|
|
48
48
|
ToolDefinition,
|
|
49
|
+
ToolInfo,
|
|
49
50
|
} from "./types";
|
|
50
51
|
|
|
51
52
|
installLegacyPiSpecifierShim();
|
|
@@ -92,7 +93,7 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
|
|
92
93
|
throw new ExtensionRuntimeNotInitializedError();
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
getAllTools():
|
|
96
|
+
getAllTools(): ToolInfo[] {
|
|
96
97
|
throw new ExtensionRuntimeNotInitializedError();
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -141,8 +142,8 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
|
|
141
142
|
class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
142
143
|
readonly logger = logger;
|
|
143
144
|
readonly typebox = TypeBox;
|
|
144
|
-
readonly arktype =
|
|
145
|
-
readonly zod =
|
|
145
|
+
readonly arktype = type;
|
|
146
|
+
readonly zod = zod;
|
|
146
147
|
readonly flagValues = new Map<string, boolean | string>();
|
|
147
148
|
readonly pendingProviderRegistrations: Array<{
|
|
148
149
|
name: string;
|
|
@@ -245,7 +246,7 @@ class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
|
245
246
|
return this.runtime.getActiveTools();
|
|
246
247
|
}
|
|
247
248
|
|
|
248
|
-
getAllTools():
|
|
249
|
+
getAllTools(): ToolInfo[] {
|
|
249
250
|
return this.runtime.getAllTools();
|
|
250
251
|
}
|
|
251
252
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Interact with the user via UI primitives
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
12
12
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
13
13
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
14
14
|
import type {
|
|
@@ -596,6 +596,36 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
596
596
|
) => Component;
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
+
/** Whether a tool's source is scoped to the user, the project, or a transient runtime session. */
|
|
600
|
+
export type SourceScope = "user" | "project" | "temporary";
|
|
601
|
+
|
|
602
|
+
/** Whether a tool's source came from an installed package or a top-level (loose) file. */
|
|
603
|
+
export type SourceOrigin = "package" | "top-level";
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Provenance metadata describing where a registered tool came from. Mirrors the
|
|
607
|
+
* `@earendil-works/pi-coding-agent` `SourceInfo` contract so extensions authored
|
|
608
|
+
* against upstream pi (e.g. gentle-pi) can read `sourceInfo.source` unchanged.
|
|
609
|
+
*/
|
|
610
|
+
export interface SourceInfo {
|
|
611
|
+
/** Synthetic or on-disk identifier for the tool's origin (e.g. `<builtin:read>`). */
|
|
612
|
+
path: string;
|
|
613
|
+
/** Origin class: `"builtin"`, `"sdk"`, `"mcp"`, or `"extension"`. */
|
|
614
|
+
source: string;
|
|
615
|
+
scope: SourceScope;
|
|
616
|
+
origin: SourceOrigin;
|
|
617
|
+
baseDir?: string;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** Tool metadata returned by {@link ExtensionAPI.getAllTools}: identity, schema, and source provenance. */
|
|
621
|
+
export interface ToolInfo {
|
|
622
|
+
name: string;
|
|
623
|
+
description: string;
|
|
624
|
+
parameters: TSchema;
|
|
625
|
+
promptGuidelines?: string[];
|
|
626
|
+
sourceInfo: SourceInfo;
|
|
627
|
+
}
|
|
628
|
+
|
|
599
629
|
// ============================================================================
|
|
600
630
|
// Resource Events
|
|
601
631
|
// ============================================================================
|
|
@@ -1109,12 +1139,13 @@ export interface ExtensionAPI {
|
|
|
1109
1139
|
/** File logger for error/warning/debug messages */
|
|
1110
1140
|
logger: typeof PiLogger;
|
|
1111
1141
|
|
|
1112
|
-
/** Injected
|
|
1142
|
+
/** Injected TypeBox shim for legacy `Type.Object(...)` parameter authoring. */
|
|
1113
1143
|
typebox: typeof TypeBox;
|
|
1114
1144
|
|
|
1115
|
-
/** Injected
|
|
1116
|
-
arktype: typeof
|
|
1117
|
-
|
|
1145
|
+
/** Injected omptype schema builder for extension tools. */
|
|
1146
|
+
arktype: typeof ArkType;
|
|
1147
|
+
|
|
1148
|
+
/** Injected Zod-compatible omptype builder for extension tools. */
|
|
1118
1149
|
zod: typeof zod;
|
|
1119
1150
|
|
|
1120
1151
|
/** Injected pi-coding-agent exports for accessing SDK utilities */
|
|
@@ -1267,8 +1298,8 @@ export interface ExtensionAPI {
|
|
|
1267
1298
|
/** Get the list of currently active tool names. */
|
|
1268
1299
|
getActiveTools(): string[];
|
|
1269
1300
|
|
|
1270
|
-
/** Get all configured tools (built-in + extension tools). */
|
|
1271
|
-
getAllTools():
|
|
1301
|
+
/** Get all configured tools (built-in + extension tools) with schema and source metadata. */
|
|
1302
|
+
getAllTools(): ToolInfo[];
|
|
1272
1303
|
|
|
1273
1304
|
/** Set the active tools by name. */
|
|
1274
1305
|
setActiveTools(toolNames: string[]): Promise<void>;
|
|
@@ -1464,7 +1495,7 @@ export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) =>
|
|
|
1464
1495
|
|
|
1465
1496
|
export type GetActiveToolsHandler = () => string[];
|
|
1466
1497
|
|
|
1467
|
-
export type GetAllToolsHandler = () =>
|
|
1498
|
+
export type GetAllToolsHandler = () => ToolInfo[];
|
|
1468
1499
|
|
|
1469
1500
|
export type GetCommandsHandler = () => SlashCommandInfo[];
|
|
1470
1501
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Hook loader - loads TypeScript hook modules using native Bun import.
|
|
3
3
|
*/
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import
|
|
6
|
-
import * as
|
|
5
|
+
import { type } from "@oh-my-pi/omptype";
|
|
6
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
7
7
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { hookCapability } from "../../capability/hook";
|
|
9
9
|
import type { Hook } from "../../discovery";
|
|
@@ -122,9 +122,8 @@ async function createHookAPI(
|
|
|
122
122
|
},
|
|
123
123
|
logger,
|
|
124
124
|
typebox,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
zod: zodModule,
|
|
125
|
+
arktype: type,
|
|
126
|
+
zod,
|
|
128
127
|
pi: PiCodingAgent,
|
|
129
128
|
} as HookAPI;
|
|
130
129
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
2
2
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
3
3
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
4
4
|
import type { ImageContent, Message, Model, TextContent } from "@oh-my-pi/pi-ai";
|
|
@@ -582,11 +582,11 @@ export interface HookAPI {
|
|
|
582
582
|
|
|
583
583
|
/** File logger for error/warning/debug messages */
|
|
584
584
|
logger: typeof PiLogger;
|
|
585
|
-
/** Injected
|
|
585
|
+
/** Injected TypeBox shim (legacy/compat — prefer `arktype`). */
|
|
586
586
|
typebox: typeof TypeBox;
|
|
587
|
-
/** Injected
|
|
588
|
-
arktype: typeof
|
|
589
|
-
/** Injected
|
|
587
|
+
/** Injected omptype schema builder for hooks. */
|
|
588
|
+
arktype: typeof ArkType;
|
|
589
|
+
/** Injected Zod-compatible omptype builder for hooks. */
|
|
590
590
|
zod: typeof zod;
|
|
591
591
|
/** Injected pi-coding-agent exports */
|
|
592
592
|
pi: typeof PiCodingAgent;
|
|
@@ -54,6 +54,7 @@ import { ReadTool } from "../tools/read";
|
|
|
54
54
|
import { formatBytes } from "../tools/render-utils";
|
|
55
55
|
import { WriteTool } from "../tools/write";
|
|
56
56
|
import { EventBus } from "../utils/event-bus";
|
|
57
|
+
import { convertImageToPng } from "../utils/image-loading";
|
|
57
58
|
import { discoverExtensionPaths, loadExtensionFromFactory, loadExtensions } from "./extensions";
|
|
58
59
|
import { ExtensionRuntime } from "./extensions/loader";
|
|
59
60
|
import type { ExtensionFactory, ToolDefinition } from "./extensions/types";
|
|
@@ -384,6 +385,28 @@ async function executeLegacyBashOperations(
|
|
|
384
385
|
}
|
|
385
386
|
}
|
|
386
387
|
|
|
388
|
+
/**
|
|
389
|
+
* Convert an image attachment to PNG using the legacy package-root contract.
|
|
390
|
+
*
|
|
391
|
+
* Invalid or unsupported image data returns `null`, matching Pi's historical
|
|
392
|
+
* helper instead of surfacing Bun's decoder error to extensions.
|
|
393
|
+
*/
|
|
394
|
+
export async function convertToPng(
|
|
395
|
+
base64Data: string,
|
|
396
|
+
mimeType: string,
|
|
397
|
+
): Promise<{ data: string; mimeType: string } | null> {
|
|
398
|
+
if (mimeType === "image/png") {
|
|
399
|
+
return { data: base64Data, mimeType };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
const converted = await convertImageToPng({ type: "image", data: base64Data, mimeType });
|
|
404
|
+
return { data: converted.data, mimeType: converted.mimeType };
|
|
405
|
+
} catch {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
387
410
|
/** Format the active shortcut for legacy extensions that render keybinding hints. */
|
|
388
411
|
export function keyText(action: Keybinding): string {
|
|
389
412
|
return formatKeyHints(getKeybindings().getKeys(action));
|
|
@@ -423,6 +423,25 @@ function isGlobalRequireCall(node: StructuralAstNode | null, scope: BindingScope
|
|
|
423
423
|
);
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Whether `node` is a `createRequire(...)` factory call imported from
|
|
428
|
+
* `node:module` (or its `module` alias).
|
|
429
|
+
*/
|
|
430
|
+
function isCreateRequireInvocation(
|
|
431
|
+
node: StructuralAstNode | null,
|
|
432
|
+
createRequireBindings: ReadonlySet<string>,
|
|
433
|
+
moduleNamespaceBindings: ReadonlySet<string>,
|
|
434
|
+
): boolean {
|
|
435
|
+
if (node?.type !== "CallExpression") return false;
|
|
436
|
+
const callee = asAstNode(node.callee);
|
|
437
|
+
if (callee?.type === "Identifier" && typeof callee.name === "string") {
|
|
438
|
+
return createRequireBindings.has(callee.name);
|
|
439
|
+
}
|
|
440
|
+
if (callee?.type !== "MemberExpression" || staticMemberPropertyName(callee) !== "createRequire") return false;
|
|
441
|
+
const object = asAstNode(callee.object);
|
|
442
|
+
return object?.type === "Identifier" && typeof object.name === "string" && moduleNamespaceBindings.has(object.name);
|
|
443
|
+
}
|
|
444
|
+
|
|
426
445
|
function staticMemberPropertyName(node: StructuralAstNode): string | null {
|
|
427
446
|
const property = asAstNode(node.property);
|
|
428
447
|
if (node.computed !== true && property?.type === "Identifier" && typeof property.name === "string") {
|
|
@@ -458,6 +477,28 @@ function collectExtensionSpecifierReferences(
|
|
|
458
477
|
references.push({ kind, specifier: node.value, start: node.start, end: node.end });
|
|
459
478
|
}
|
|
460
479
|
};
|
|
480
|
+
const createRequireBindings = new Set<string>();
|
|
481
|
+
const moduleNamespaceBindings = new Set<string>();
|
|
482
|
+
for (const { node } of collectScopedAstNodes(ast, candidate => candidate.type === "ImportDeclaration")) {
|
|
483
|
+
const source = asAstNode(node.source);
|
|
484
|
+
if (source?.type !== "StringLiteral" || (source.value !== "node:module" && source.value !== "module")) continue;
|
|
485
|
+
for (const value of Array.isArray(node.specifiers) ? node.specifiers : []) {
|
|
486
|
+
const specifier = asAstNode(value);
|
|
487
|
+
const local = asAstNode(specifier?.local);
|
|
488
|
+
if (local?.type !== "Identifier" || typeof local.name !== "string") continue;
|
|
489
|
+
if (specifier?.type === "ImportNamespaceSpecifier") {
|
|
490
|
+
moduleNamespaceBindings.add(local.name);
|
|
491
|
+
} else if (specifier?.type === "ImportSpecifier") {
|
|
492
|
+
const imported = asAstNode(specifier.imported);
|
|
493
|
+
if (
|
|
494
|
+
(imported?.type === "Identifier" && imported.name === "createRequire") ||
|
|
495
|
+
(imported?.type === "StringLiteral" && imported.value === "createRequire")
|
|
496
|
+
) {
|
|
497
|
+
createRequireBindings.add(local.name);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
461
502
|
for (const { node, scope } of collectScopedAstNodes(ast, isSpecifierReferenceNode)) {
|
|
462
503
|
if (
|
|
463
504
|
node.type === "ImportDeclaration" ||
|
|
@@ -478,6 +519,18 @@ function collectExtensionSpecifierReferences(
|
|
|
478
519
|
record("import", nodeArgument(node, 0));
|
|
479
520
|
} else if (isIdentifier(callee, "require") && !scopeHasBinding(scope, REQUIRE_BINDING)) {
|
|
480
521
|
record("require", nodeArgument(node, 0));
|
|
522
|
+
} else if (isCreateRequireInvocation(callee, createRequireBindings, moduleNamespaceBindings)) {
|
|
523
|
+
// `createRequire(base)(spec)` — pin the invoked bare dependency so it
|
|
524
|
+
// loads without a runtime `node_modules` lookup. Relative specifiers
|
|
525
|
+
// resolve against `base`, which is not rewritten, so restrict to bare.
|
|
526
|
+
const argument = nodeArgument(node, 0);
|
|
527
|
+
if (
|
|
528
|
+
argument?.type === "StringLiteral" &&
|
|
529
|
+
typeof argument.value === "string" &&
|
|
530
|
+
isBareExtensionDependencySpecifier(argument.value)
|
|
531
|
+
) {
|
|
532
|
+
record("require", argument);
|
|
533
|
+
}
|
|
481
534
|
}
|
|
482
535
|
}
|
|
483
536
|
}
|
package/src/hindsight/state.ts
CHANGED
|
@@ -411,24 +411,6 @@ export class HindsightSessionState {
|
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
|
|
414
|
-
async maybeRecallOnAgentStart(): Promise<void> {
|
|
415
|
-
if (!this.config.autoRecall || this.hasRecalledForFirstTurn) return;
|
|
416
|
-
const messages = extractMessages(this.session.sessionManager);
|
|
417
|
-
const lastUser = messages.findLast(m => m.role === "user");
|
|
418
|
-
if (!lastUser) return;
|
|
419
|
-
|
|
420
|
-
const query = composeRecallQuery(lastUser.content, messages, this.config.recallContextTurns);
|
|
421
|
-
const truncated = truncateRecallQuery(query, lastUser.content, this.config.recallMaxQueryChars);
|
|
422
|
-
const { context, ok } = await this.recallForContext(truncated);
|
|
423
|
-
if (!ok) return;
|
|
424
|
-
|
|
425
|
-
this.hasRecalledForFirstTurn = true;
|
|
426
|
-
if (!context) return;
|
|
427
|
-
|
|
428
|
-
this.lastRecallSnippet = context;
|
|
429
|
-
await this.#refreshBaseSystemPromptAfter("recall");
|
|
430
|
-
}
|
|
431
|
-
|
|
432
414
|
async beforeAgentStartPrompt(promptText: string): Promise<string | undefined> {
|
|
433
415
|
if (this.config.mentalModelsEnabled && this.mentalModelsLoadPromise && this.mentalModelsLoadedAt === undefined) {
|
|
434
416
|
await Promise.race([this.mentalModelsLoadPromise, Bun.sleep(MENTAL_MODEL_FIRST_TURN_DEADLINE_MS)]);
|
|
@@ -509,9 +491,7 @@ export class HindsightSessionState {
|
|
|
509
491
|
attachSessionListeners(): void {
|
|
510
492
|
this.unsubscribe?.();
|
|
511
493
|
this.unsubscribe = this.session.subscribe(event => {
|
|
512
|
-
if (event.type === "
|
|
513
|
-
void this.maybeRecallOnAgentStart();
|
|
514
|
-
} else if (event.type === "agent_end") {
|
|
494
|
+
if (event.type === "agent_end") {
|
|
515
495
|
void this.maybeRetainOnAgentEnd();
|
|
516
496
|
// Drain any queued tool-initiated retain calls now that the turn
|
|
517
497
|
// is settled. The queue is also debounced/size-bounded, but
|
|
@@ -540,7 +520,7 @@ export class HindsightSessionState {
|
|
|
540
520
|
this.retainQueue.dispose();
|
|
541
521
|
}
|
|
542
522
|
|
|
543
|
-
async #refreshBaseSystemPromptAfter(reason: "
|
|
523
|
+
async #refreshBaseSystemPromptAfter(reason: "MM load" | "MM reload" | "MM TTL reload"): Promise<void> {
|
|
544
524
|
try {
|
|
545
525
|
await this.session.refreshBaseSystemPrompt();
|
|
546
526
|
} catch (err) {
|