@oh-my-pi/pi-coding-agent 16.1.15 → 16.1.17
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 +78 -0
- package/dist/cli.js +3531 -3812
- package/dist/types/auto-thinking/classifier.d.ts +4 -2
- package/dist/types/cli/args.d.ts +2 -5
- package/dist/types/cli/flag-tables.d.ts +2 -2
- package/dist/types/cli/session-picker.d.ts +4 -2
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/model-discovery.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/settings-schema.d.ts +12 -1
- package/dist/types/eval/agent-bridge.d.ts +19 -0
- package/dist/types/eval/js/shared/helpers.d.ts +1 -13
- package/dist/types/eval/js/shared/types.d.ts +1 -1
- package/dist/types/eval/js/worker-protocol.d.ts +1 -1
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +22 -7
- package/dist/types/extensibility/plugins/loader.d.ts +16 -9
- package/dist/types/extensibility/tool-event-input.d.ts +2 -0
- package/dist/types/hindsight/content.d.ts +2 -10
- package/dist/types/internal-urls/local-protocol.d.ts +18 -1
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -0
- package/dist/types/modes/components/plugin-settings.d.ts +5 -0
- package/dist/types/modes/components/session-selector.d.ts +25 -0
- package/dist/types/modes/components/status-line/types.d.ts +1 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +11 -0
- package/dist/types/session/agent-session.d.ts +6 -6
- package/dist/types/session/provider-image-budget.d.ts +3 -0
- package/dist/types/session/session-context.d.ts +6 -5
- package/dist/types/task/isolation-runner.d.ts +128 -0
- package/dist/types/task/parallel.d.ts +4 -0
- package/dist/types/task/worktree.d.ts +14 -1
- package/dist/types/thinking.d.ts +23 -1
- package/dist/types/tiny/title-client.d.ts +2 -2
- package/dist/types/tools/eval-render.d.ts +3 -0
- package/dist/types/tools/eval.d.ts +11 -17
- package/dist/types/tools/todo.d.ts +26 -28
- package/dist/types/tui/output-block.d.ts +8 -0
- package/dist/types/utils/image-resize.d.ts +2 -0
- package/dist/types/utils/tools-manager.d.ts +2 -0
- package/dist/types/web/search/providers/exa.d.ts +2 -0
- package/package.json +12 -12
- package/scripts/build-binary.ts +18 -4
- package/src/auto-thinking/classifier.ts +7 -2
- package/src/cli/args.ts +4 -5
- package/src/cli/flag-tables.ts +3 -3
- package/src/cli/gallery-fixtures/interaction.ts +6 -9
- package/src/cli/gallery-fixtures/shell.ts +15 -23
- package/src/cli/profile-alias.ts +38 -7
- package/src/cli/session-picker.ts +17 -3
- package/src/cli/usage-cli.ts +5 -1
- package/src/commands/launch.ts +3 -3
- package/src/config/model-discovery.ts +59 -8
- package/src/config/model-registry.ts +74 -3
- package/src/config/settings-schema.ts +13 -1
- package/src/discovery/omp-extension-roots.ts +1 -3
- package/src/edit/renderer.ts +34 -12
- package/src/eval/__tests__/agent-bridge.test.ts +462 -3
- package/src/eval/__tests__/helpers-local-roots.test.ts +2 -5
- package/src/eval/__tests__/julia-prelude.test.ts +1 -30
- package/src/eval/__tests__/prelude-agent.test.ts +42 -8
- package/src/eval/agent-bridge.ts +301 -71
- package/src/eval/jl/prelude.jl +32 -227
- package/src/eval/jl/runner.jl +38 -12
- package/src/eval/js/shared/helpers.ts +1 -114
- package/src/eval/js/shared/prelude.txt +13 -27
- package/src/eval/js/shared/runtime.ts +0 -6
- package/src/eval/js/shared/types.ts +1 -1
- package/src/eval/js/worker-protocol.ts +1 -1
- package/src/eval/py/__tests__/prelude.test.ts +13 -0
- package/src/eval/py/executor.ts +1 -1
- package/src/eval/py/prelude.py +47 -105
- package/src/eval/py/runner.py +0 -6
- package/src/eval/rb/prelude.rb +21 -189
- package/src/eval/rb/runner.rb +116 -9
- package/src/export/html/tool-views.generated.js +29 -29
- package/src/extensibility/extensions/wrapper.ts +3 -2
- package/src/extensibility/hooks/tool-wrapper.ts +4 -3
- package/src/extensibility/plugins/legacy-pi-compat.ts +40 -8
- package/src/extensibility/plugins/loader.ts +71 -23
- package/src/extensibility/plugins/marketplace/manager.ts +134 -0
- package/src/extensibility/tool-event-input.ts +57 -0
- package/src/hindsight/content.ts +21 -12
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/internal-urls/local-protocol.ts +100 -53
- package/src/main.ts +15 -4
- package/src/mcp/tool-bridge.ts +27 -2
- package/src/mnemopi/state.ts +5 -2
- package/src/modes/acp/acp-event-mapper.ts +7 -2
- package/src/modes/components/agent-transcript-viewer.ts +193 -41
- package/src/modes/components/chat-transcript-builder.ts +6 -0
- package/src/modes/components/custom-editor.test.ts +18 -1
- package/src/modes/components/custom-editor.ts +77 -45
- package/src/modes/components/hook-editor.ts +15 -2
- package/src/modes/components/plugin-settings.ts +7 -1
- package/src/modes/components/session-selector.ts +143 -29
- package/src/modes/components/settings-selector.ts +2 -2
- package/src/modes/components/status-line/component.ts +52 -8
- package/src/modes/components/status-line/segments.ts +5 -1
- package/src/modes/components/status-line/types.ts +1 -0
- package/src/modes/components/welcome.ts +12 -14
- package/src/modes/controllers/command-controller.ts +21 -5
- package/src/modes/controllers/input-controller.ts +115 -3
- package/src/modes/controllers/selector-controller.ts +19 -1
- package/src/modes/interactive-mode.ts +3 -3
- package/src/modes/rpc/rpc-mode.ts +6 -0
- package/src/modes/utils/copy-targets.ts +7 -2
- package/src/modes/utils/ui-helpers.ts +3 -3
- package/src/prompts/system/system-prompt.md +3 -3
- package/src/prompts/system/workflow-notice.md +3 -3
- package/src/prompts/tools/bash.md +16 -0
- package/src/prompts/tools/eval.md +19 -19
- package/src/prompts/tools/todo.md +1 -1
- package/src/sdk.ts +8 -10
- package/src/session/agent-session.ts +422 -97
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/session-context.ts +14 -7
- package/src/session/session-storage.ts +24 -2
- package/src/session/snapcompact-inline.ts +19 -3
- package/src/slash-commands/builtin-registry.ts +0 -22
- package/src/slash-commands/helpers/usage-report.ts +9 -1
- package/src/task/index.ts +61 -207
- package/src/task/isolation-runner.ts +354 -0
- package/src/task/parallel.ts +6 -1
- package/src/task/worktree.ts +46 -9
- package/src/thinking.ts +29 -2
- package/src/tiny/title-client.ts +75 -21
- package/src/tools/ask.ts +44 -38
- package/src/tools/bash.ts +9 -2
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/eval-render.ts +34 -27
- package/src/tools/eval.ts +100 -103
- package/src/tools/index.ts +8 -1
- package/src/tools/read.ts +136 -60
- package/src/tools/todo.ts +60 -64
- package/src/tui/code-cell.ts +1 -1
- package/src/tui/output-block.ts +11 -0
- package/src/utils/image-resize.ts +30 -0
- package/src/utils/tools-manager.ts +67 -10
- package/src/web/search/providers/exa.ts +85 -1
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
Runs bash in a shell session — terminal ops: git, bun, cargo, python.
|
|
2
2
|
|
|
3
|
+
# When to use bash — and when not to
|
|
4
|
+
|
|
5
|
+
Bash invokes **real binaries** with simple args. It is NOT a scripting surface.
|
|
6
|
+
|
|
7
|
+
Use bash ONLY for: a single binary call, or one short pipeline that COMPUTES a fact (`wc -l`, `sort | uniq -c`, `comm`, `diff`, a checksum, `git status`).
|
|
8
|
+
|
|
9
|
+
Anything below → `eval` cell, not bash:
|
|
10
|
+
- Inline interpreter scripts (`-e`/`-c`/`--eval`) when an eval runtime exists for that language
|
|
11
|
+
- Heredocs (`<<EOF`), `while`/`for`/`if`/`case` shell control flow
|
|
12
|
+
- `$(…)` command substitution nested inside another command
|
|
13
|
+
- Pipelines with more than two stages, or stages that need control flow or quote/JSON escaping
|
|
14
|
+
- Multiline commands, `&&`-chains mixing control flow
|
|
15
|
+
- Quote/JSON escaping that fights the shell
|
|
16
|
+
|
|
3
17
|
<instruction>
|
|
4
18
|
- `cwd` sets the working dir, not `cd dir && …`
|
|
5
19
|
- `env: { NAME: "…" }` for multiline / quote-heavy / untrusted values; reference `$NAME`
|
|
@@ -14,7 +28,9 @@ Runs bash in a shell session — terminal ops: git, bun, cargo, python.
|
|
|
14
28
|
</instruction>
|
|
15
29
|
|
|
16
30
|
<critical>
|
|
31
|
+
- Bash invokes real binaries with simple args; it is NOT a scripting surface. Loops, conditionals, heredocs, inline interpreter scripts (`-e`/`-c`/`--eval`) when an eval runtime exists, several piped stages, or quote/JSON escaping mean you're writing a program → use `eval` cells: restartable, stateful, and free of shell-quoting traps.
|
|
17
32
|
- NEVER shell out to search content or files: `grep/rg` → `search`.
|
|
33
|
+
- NEVER use `ls` or `find` to list or locate files — `ls` → `read` (a directory path lists entries), `find` → the `find` tool (globbing). This is non-negotiable, even for a single quick listing.
|
|
18
34
|
- Avoid head/tail/redirections: stderr already merged; long output auto-truncated, FULL capture kept at `artifact://<id>`.
|
|
19
35
|
</critical>
|
|
20
36
|
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
Run code in a persistent kernel
|
|
1
|
+
Run one step of code in a persistent kernel.
|
|
2
2
|
|
|
3
3
|
<instruction>
|
|
4
|
-
|
|
4
|
+
**One eval call = one cell = one logical step.** State persists per language across separate eval calls, tool calls, and `task` subagents — define helpers/datasets/clients in one call, then later calls reuse them directly.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Work incrementally: imports in one call, define in the next, test, then use — each its own eval call. Re-run setup ONLY after `reset`, a kernel crash, or a `NameError`/`ReferenceError` proving the state is gone. Parallelize work *within* a cell with the `parallel(thunks)` helper, not by batching steps.
|
|
7
|
+
|
|
8
|
+
Fields:
|
|
7
9
|
|
|
8
10
|
- `language` — {{#if py}}`"py"` IPython kernel{{/if}}{{#ifAll py js}}, {{/ifAll}}{{#if js}}`"js"` persistent JavaScript VM{{/if}}{{#if rb}}{{#ifAny py js}}, {{/ifAny}}`"rb"` persistent Ruby kernel{{/if}}{{#if jl}}{{#ifAny py js rb}}, {{/ifAny}}`"jl"` persistent Julia kernel{{/if}}.
|
|
9
11
|
- `code` — cell body, verbatim. Newlines/quotes JSON-encoded; no fences, no headers.
|
|
10
12
|
- `title` (optional) — short transcript label (e.g. `"imports"`).
|
|
11
|
-
- `timeout` (optional) —
|
|
12
|
-
- `reset` (optional) — wipe this
|
|
13
|
+
- `timeout` (optional) — seconds. Raise only for heavy compute or long non-agent tool calls.
|
|
14
|
+
- `reset` (optional) — wipe this language's kernel first.{{#ifAll py js}} Per-language: a `py` reset never touches the JS VM.{{/ifAll}}
|
|
13
15
|
|
|
14
|
-
Work incrementally — one logical step per cell (imports, define, test, use), many small cells per call; workflow notes in the assistant message or `title`, never in cell code.
|
|
15
16
|
{{#if py}}Live event loop: use top-level `await` directly; `asyncio.run(…)` raises "cannot be called from a running event loop".{{/if}}
|
|
16
|
-
{{#if
|
|
17
|
-
{{#if
|
|
18
|
-
|
|
17
|
+
{{#if js}}JS runs under **Bun**: Bun globals/APIs are available (`Bun.file`, `Bun.write`, `Bun.$`, `fetch`, `Buffer`); top-level `await`/`return` work directly.{{/if}}
|
|
18
|
+
{{#if rb}}Ruby: synchronous; helper options are keyword args (e.g. `output("id", limit: 2)`); the last expression auto-displays unless it is `nil`, an assignment, or a definition (like IRB).{{/if}}
|
|
19
|
+
{{#if jl}}Julia: synchronous; helper options are standard keyword args (e.g. `output("id", limit=2)`); the last expression auto-displays unless it is an assignment or a definition (like the Julia REPL).{{/if}}
|
|
20
|
+
On error, fix and re-run only the failing step — prior calls' state survives.
|
|
19
21
|
</instruction>
|
|
20
22
|
|
|
21
23
|
<prelude>
|
|
@@ -29,12 +31,6 @@ read(path, offset?=1, limit?=None) → str
|
|
|
29
31
|
File as text; offset/limit 1-indexed lines. Accepts `local://…`.
|
|
30
32
|
write(path, content) → str
|
|
31
33
|
Write file (creates parents) → resolved path. `local://…` persists across turns/subagents.
|
|
32
|
-
append(path, content) → str
|
|
33
|
-
Append → resolved path. Accepts `local://…`.
|
|
34
|
-
tree(path?=".", max_depth?=3, show_hidden?=False) → str
|
|
35
|
-
Directory tree.
|
|
36
|
-
diff(a, b) → str
|
|
37
|
-
Unified diff of two files.
|
|
38
34
|
env(key?=None, value?=None) → str | None | dict
|
|
39
35
|
No args → full env dict; one → value of `key`; two → set `key=value`, return value.
|
|
40
36
|
output(*ids, format?="raw", query?=None, offset?=None, limit?=None) → str | dict | list[dict]
|
|
@@ -43,9 +39,9 @@ tool.<name>(args) → unknown
|
|
|
43
39
|
Invoke any session tool; `args` = its parameter object.
|
|
44
40
|
completion(prompt, model?="default", system?=None, schema?=None) → str | dict
|
|
45
41
|
Oneshot, stateless (no history/tools). `model`: "smol" fast | "default" session | "slow" most capable. `schema` (JSON-Schema) → structured output, parsed object.
|
|
46
|
-
{{#if spawns}}agent(prompt,
|
|
47
|
-
Run a subagent → final output. `
|
|
48
|
-
{{#if js}} JS: options are ONE trailing object — agent(prompt, {
|
|
42
|
+
{{#if spawns}}agent(prompt, agent?="task", model?=None, label?=None, schema?=None, handle?=False) → str | dict
|
|
43
|
+
Run a subagent → final output. `agent` picks another discovered agent; `schema` as in completion(). Background via `local://` files named in the prompt. `handle` → DAG node dict { text, output, handle: "agent://<id>", id, agent } (parsed under `data` when `schema` set).
|
|
44
|
+
{{#if js}} JS: options are ONE trailing object — agent(prompt, { agent, schema, handle }).
|
|
49
45
|
{{/if}}
|
|
50
46
|
{{/if}}
|
|
51
47
|
parallel(thunks) → list
|
|
@@ -63,10 +59,14 @@ budget → per-turn token budget
|
|
|
63
59
|
{{#if spawns}}
|
|
64
60
|
<dag>
|
|
65
61
|
Pipe handles through stage helpers to build a dependency graph — acyclic waves:
|
|
66
|
-
- **Name nodes.** Capture each `agent(…, {{#if py}}
|
|
62
|
+
- **Name nodes.** Capture each `agent(…, {{#if py}}handle=True{{/if}}{{#if js}}{ handle: true }{{/if}}{{#if jl}}handle=true{{/if}})` result; carries `handle` (`agent://<id>`) + `output`.
|
|
67
63
|
- **Wire edges by reference.** Put an upstream node's `handle`/`output` in the dependent stage's prompt — large transcript never re-inlined. Bulk: `write("local://<name>.md", …)`, pass the URI.
|
|
68
64
|
- **`pipeline(items, *stages)` = staged waves**, barrier between stages (every item clears stage N before any enters N+1). **`parallel(thunks)` = one wave** of independent nodes.
|
|
69
65
|
- **Isolate failure.** A raising node re-raises the lowest-index error, aborts its wave; wrap risky nodes in try/except so a failure degrades only its dependent subtree, independent branches finish.
|
|
70
66
|
- **Acyclic only.** A node never waits on its own descendant.
|
|
71
67
|
</dag>
|
|
72
68
|
{{/if}}
|
|
69
|
+
|
|
70
|
+
<critical>
|
|
71
|
+
Prior top-level names (`data`, `sessions`, helpers, imports) survive into the next eval call — reuse them; NEVER re-import, re-require, or re-declare a helper. Re-read a file only if it may have changed since the last read. Re-run setup only after `reset`, a crash, or a `NameError`/`ReferenceError`.
|
|
72
|
+
</critical>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
**Tasks referenced by verbatim content string, NEVER an auto-generated ID — no "task-1"/"task-N" exists. Pass the content text in the `task` field.**
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Next pending task auto-promotes to `in_progress` on each completion.
|
|
4
4
|
|
|
5
5
|
## Operations
|
|
6
6
|
|
package/src/sdk.ts
CHANGED
|
@@ -115,6 +115,7 @@ import {
|
|
|
115
115
|
USER_INTERRUPT_LABEL,
|
|
116
116
|
wrapSteeringForModel,
|
|
117
117
|
} from "./session/messages";
|
|
118
|
+
import { clampProviderContextImages } from "./session/provider-image-budget";
|
|
118
119
|
import { getRestorableSessionModels } from "./session/session-context";
|
|
119
120
|
import { SessionManager } from "./session/session-manager";
|
|
120
121
|
import { SnapcompactInlineTransformer } from "./session/snapcompact-inline";
|
|
@@ -2420,8 +2421,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2420
2421
|
return wrapSteeringForModel(withContext);
|
|
2421
2422
|
};
|
|
2422
2423
|
// Per-request provider-context transforms. Obfuscate FIRST so secrets are
|
|
2423
|
-
// redacted from text before snapcompact rasterizes it into PNG frames
|
|
2424
|
-
//
|
|
2424
|
+
// redacted from text before snapcompact rasterizes it into PNG frames, then
|
|
2425
|
+
// clamp images to the active provider budget before the request is sent.
|
|
2425
2426
|
const snapcompactSystemPromptMode = settings.get("snapcompact.systemPrompt");
|
|
2426
2427
|
const snapcompactInline =
|
|
2427
2428
|
snapcompactSystemPromptMode !== "none" || settings.get("snapcompact.toolResults")
|
|
@@ -2436,14 +2437,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2436
2437
|
createSnapcompactSavingsRecorder(() => sessionManager.getSessionFile() ?? null),
|
|
2437
2438
|
)
|
|
2438
2439
|
: undefined;
|
|
2439
|
-
const transformProviderContext =
|
|
2440
|
-
obfuscator
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
return transformed;
|
|
2445
|
-
}
|
|
2446
|
-
: undefined;
|
|
2440
|
+
const transformProviderContext = async (context: Context, transformModel: Model): Promise<Context> => {
|
|
2441
|
+
let transformed = obfuscator ? obfuscateProviderContext(obfuscator, context) : context;
|
|
2442
|
+
if (snapcompactInline) transformed = await snapcompactInline.transform(transformed, transformModel);
|
|
2443
|
+
return clampProviderContextImages(transformed, transformModel);
|
|
2444
|
+
};
|
|
2447
2445
|
const onPayload = async (payload: unknown, _model?: Model) => {
|
|
2448
2446
|
return await extensionRunner.emitBeforeProviderRequest(payload);
|
|
2449
2447
|
};
|