@oh-my-pi/pi-coding-agent 13.2.0 → 13.2.1
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 +26 -0
- package/package.json +7 -7
- package/scripts/format-prompts.ts +33 -14
- package/src/capability/index.ts +1 -2
- package/src/cli/args.ts +1 -2
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/file-processor.ts +1 -2
- package/src/cli/grep-cli.ts +1 -1
- package/src/cli/jupyter-cli.ts +1 -1
- package/src/cli/plugin-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 +1 -2
- package/src/cli/update-cli.ts +1 -2
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/launch.ts +2 -1
- package/src/commit/agentic/agent.ts +2 -1
- package/src/commit/agentic/index.ts +1 -2
- package/src/commit/agentic/prompts/system.md +3 -3
- package/src/commit/agentic/tools/propose-changelog.ts +30 -19
- package/src/commit/changelog/generate.ts +16 -6
- package/src/commit/changelog/index.ts +2 -1
- package/src/commit/pipeline.ts +1 -2
- package/src/commit/prompts/reduce-system.md +1 -1
- package/src/commit/types.ts +10 -1
- package/src/config/keybindings.ts +1 -2
- package/src/config/model-registry.ts +1 -1
- package/src/config/prompt-templates.ts +14 -2
- package/src/config/settings.ts +9 -2
- package/src/config.ts +1 -2
- package/src/debug/index.ts +1 -1
- package/src/debug/report-bundle.ts +1 -2
- package/src/debug/system-info.ts +1 -2
- package/src/discovery/agents.ts +2 -2
- package/src/discovery/builtin.ts +8 -9
- package/src/discovery/claude-plugins.ts +2 -2
- package/src/discovery/claude.ts +7 -7
- package/src/discovery/codex.ts +3 -3
- package/src/discovery/cursor.ts +5 -4
- package/src/discovery/gemini.ts +5 -5
- package/src/discovery/helpers.ts +47 -69
- package/src/discovery/mcp-json.ts +3 -3
- package/src/discovery/opencode.ts +7 -8
- package/src/discovery/ssh.ts +3 -3
- package/src/discovery/vscode.ts +3 -2
- package/src/discovery/windsurf.ts +3 -2
- package/src/exa/company.ts +1 -1
- package/src/exa/factory.ts +1 -6
- package/src/exa/linkedin.ts +1 -1
- package/src/exa/mcp-client.ts +19 -8
- package/src/exa/search.ts +2 -2
- package/src/exa/types.ts +3 -3
- package/src/exec/bash-executor.ts +2 -1
- package/src/exec/non-interactive-env.ts +43 -0
- package/src/export/custom-share.ts +1 -1
- package/src/export/html/index.ts +1 -2
- package/src/extensibility/custom-commands/loader.ts +1 -2
- package/src/extensibility/plugins/installer.ts +1 -2
- package/src/extensibility/plugins/loader.ts +1 -2
- package/src/extensibility/plugins/manager.ts +3 -2
- package/src/extensibility/skills.ts +59 -115
- package/src/index.ts +1 -3
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/ipy/executor.ts +1 -2
- package/src/ipy/gateway-coordinator.ts +1 -2
- package/src/ipy/modules.ts +1 -1
- package/src/ipy/runtime.ts +1 -3
- package/src/main.ts +1 -2
- package/src/mcp/config.ts +1 -1
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/memories/index.ts +1 -2
- package/src/modes/components/extensions/extension-dashboard.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +8 -2
- package/src/modes/components/footer.ts +1 -2
- package/src/modes/components/status-line/segments.ts +1 -2
- package/src/modes/components/tool-execution.ts +3 -10
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/command-controller.ts +1 -2
- package/src/modes/controllers/mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +1 -1
- package/src/modes/controllers/ssh-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +2 -3
- package/src/modes/shared.ts +1 -2
- package/src/modes/theme/theme.ts +1 -2
- package/src/patch/index.ts +1 -25
- package/src/prompts/agents/designer.md +7 -10
- package/src/prompts/agents/explore.md +15 -23
- package/src/prompts/agents/init.md +23 -23
- package/src/prompts/agents/plan.md +14 -77
- package/src/prompts/agents/reviewer.md +6 -5
- package/src/prompts/agents/task.md +13 -11
- package/src/prompts/compaction/branch-summary.md +3 -3
- package/src/prompts/compaction/compaction-short-summary.md +7 -7
- package/src/prompts/compaction/compaction-summary-context.md +1 -1
- package/src/prompts/compaction/compaction-summary.md +5 -5
- package/src/prompts/compaction/compaction-turn-prefix.md +3 -3
- package/src/prompts/compaction/compaction-update-summary.md +11 -11
- package/src/prompts/memories/consolidation.md +5 -5
- package/src/prompts/memories/read-path.md +6 -6
- package/src/prompts/memories/stage_one_input.md +1 -1
- package/src/prompts/memories/stage_one_system.md +5 -5
- package/src/prompts/review-request.md +4 -4
- package/src/prompts/system/agent-creation-architect.md +17 -17
- package/src/prompts/system/agent-creation-user.md +2 -2
- package/src/prompts/system/custom-system-prompt.md +4 -4
- package/src/prompts/system/plan-mode-active.md +20 -20
- package/src/prompts/system/plan-mode-approved.md +7 -7
- package/src/prompts/system/plan-mode-reference.md +2 -2
- package/src/prompts/system/plan-mode-subagent.md +8 -8
- package/src/prompts/system/subagent-submit-reminder.md +5 -5
- package/src/prompts/system/subagent-system-prompt.md +29 -22
- package/src/prompts/system/subagent-user-prompt.md +7 -3
- package/src/prompts/system/summarization-system.md +1 -1
- package/src/prompts/system/system-prompt.md +201 -226
- package/src/prompts/system/title-system.md +2 -2
- package/src/prompts/system/ttsr-interrupt.md +1 -1
- package/src/prompts/system/web-search.md +16 -16
- package/src/prompts/tools/ask.md +1 -3
- package/src/prompts/tools/await.md +2 -4
- package/src/prompts/tools/bash.md +5 -7
- package/src/prompts/tools/browser.md +4 -6
- package/src/prompts/tools/calculator.md +1 -3
- package/src/prompts/tools/cancel-job.md +2 -4
- package/src/prompts/tools/exit-plan-mode.md +7 -7
- package/src/prompts/tools/fetch.md +0 -2
- package/src/prompts/tools/find.md +3 -5
- package/src/prompts/tools/gemini-image.md +6 -22
- package/src/prompts/tools/grep.md +4 -6
- package/src/prompts/tools/hashline.md +12 -15
- package/src/prompts/tools/lsp.md +1 -3
- package/src/prompts/tools/patch.md +7 -9
- package/src/prompts/tools/python.md +10 -14
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/replace.md +5 -7
- package/src/prompts/tools/ssh.md +3 -5
- package/src/prompts/tools/task.md +6 -8
- package/src/prompts/tools/todo-write.md +7 -9
- package/src/prompts/tools/web-search.md +3 -5
- package/src/prompts/tools/write.md +3 -5
- package/src/sdk.ts +1 -2
- package/src/session/agent-session.ts +10 -26
- package/src/session/agent-storage.ts +1 -2
- package/src/session/history-storage.ts +1 -2
- package/src/session/session-manager.ts +10 -2
- package/src/ssh/connection-manager.ts +11 -2
- package/src/ssh/sshfs-mount.ts +7 -1
- package/src/system-prompt.ts +25 -103
- package/src/task/agents.ts +1 -1
- package/src/task/worktree.ts +1 -2
- package/src/tools/ask.ts +0 -1
- package/src/tools/bash-interactive.ts +2 -45
- package/src/tools/bash.ts +5 -5
- package/src/tools/browser.ts +1 -2
- package/src/tools/gemini-image.ts +8 -28
- package/src/tools/json-tree.ts +2 -1
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +1 -2
- package/src/utils/tools-manager.ts +1 -2
- package/src/web/scrapers/artifacthub.ts +2 -1
- package/src/web/scrapers/aur.ts +2 -1
- package/src/web/scrapers/biorxiv.ts +2 -1
- package/src/web/scrapers/bluesky.ts +2 -1
- package/src/web/scrapers/chocolatey.ts +2 -1
- package/src/web/scrapers/cisa-kev.ts +2 -1
- package/src/web/scrapers/clojars.ts +2 -1
- package/src/web/scrapers/coingecko.ts +2 -1
- package/src/web/scrapers/crates-io.ts +2 -1
- package/src/web/scrapers/crossref.ts +2 -1
- package/src/web/scrapers/discogs.ts +3 -1
- package/src/web/scrapers/discourse.ts +2 -1
- package/src/web/scrapers/dockerhub.ts +2 -1
- package/src/web/scrapers/fdroid.ts +2 -1
- package/src/web/scrapers/firefox-addons.ts +2 -1
- package/src/web/scrapers/flathub.ts +2 -1
- package/src/web/scrapers/gitlab.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +2 -1
- package/src/web/scrapers/hackage.ts +2 -1
- package/src/web/scrapers/hackernews.ts +2 -1
- package/src/web/scrapers/hex.ts +2 -1
- package/src/web/scrapers/huggingface.ts +2 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +2 -1
- package/src/web/scrapers/lemmy.ts +2 -1
- package/src/web/scrapers/lobsters.ts +2 -1
- package/src/web/scrapers/mastodon.ts +2 -1
- package/src/web/scrapers/maven.ts +2 -1
- package/src/web/scrapers/mdn.ts +2 -1
- package/src/web/scrapers/metacpan.ts +2 -1
- package/src/web/scrapers/musicbrainz.ts +3 -1
- package/src/web/scrapers/npm.ts +2 -1
- package/src/web/scrapers/nuget.ts +2 -1
- package/src/web/scrapers/nvd.ts +2 -1
- package/src/web/scrapers/ollama.ts +2 -1
- package/src/web/scrapers/open-vsx.ts +2 -1
- package/src/web/scrapers/opencorporates.ts +2 -1
- package/src/web/scrapers/openlibrary.ts +2 -1
- package/src/web/scrapers/orcid.ts +3 -1
- package/src/web/scrapers/osv.ts +2 -1
- package/src/web/scrapers/packagist.ts +2 -1
- package/src/web/scrapers/pub-dev.ts +2 -1
- package/src/web/scrapers/pubmed.ts +2 -1
- package/src/web/scrapers/pypi.ts +2 -1
- package/src/web/scrapers/rawg.ts +2 -8
- package/src/web/scrapers/reddit.ts +2 -1
- package/src/web/scrapers/repology.ts +2 -1
- package/src/web/scrapers/rfc.ts +2 -1
- package/src/web/scrapers/rubygems.ts +2 -1
- package/src/web/scrapers/searchcode.ts +2 -1
- package/src/web/scrapers/sec-edgar.ts +2 -1
- package/src/web/scrapers/semantic-scholar.ts +2 -1
- package/src/web/scrapers/snapcraft.ts +2 -1
- package/src/web/scrapers/sourcegraph.ts +2 -1
- package/src/web/scrapers/spdx.ts +2 -1
- package/src/web/scrapers/stackoverflow.ts +2 -1
- package/src/web/scrapers/terraform.ts +2 -1
- package/src/web/scrapers/types.ts +0 -11
- package/src/web/scrapers/vimeo.ts +2 -1
- package/src/web/scrapers/vscode-marketplace.ts +2 -1
- package/src/web/scrapers/w3c.ts +2 -1
- package/src/web/scrapers/wikidata.ts +2 -1
- package/src/web/search/index.ts +10 -14
- package/src/web/search/provider.ts +2 -2
- package/src/web/search/providers/codex.ts +1 -2
- package/src/web/search/providers/exa.ts +1 -6
- package/src/web/search/providers/gemini.ts +1 -1
- package/src/web/search/providers/perplexity.ts +1 -2
- package/src/web/search/providers/utils.ts +1 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Navigate, click, type, scroll, drag, query DOM content, and capture screenshots.
|
|
1
|
+
Navigates, clicks, types, scrolls, drags, queries DOM content, and captures screenshots.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
4
|
- `"open"` starts a headless session (or implicitly on first action); `"goto"` navigates to `url`; `"close"` releases the browser
|
|
@@ -15,10 +13,10 @@ Navigate, click, type, scroll, drag, query DOM content, and capture screenshots.
|
|
|
15
13
|
</instruction>
|
|
16
14
|
|
|
17
15
|
<critical>
|
|
18
|
-
**You MUST default to `observe`, not `screenshot`.**
|
|
16
|
+
**You **MUST** default to `observe`, not `screenshot`.**
|
|
19
17
|
- `observe` is cheaper, faster, and returns structured data — use it to understand page state, find elements, and plan interactions.
|
|
20
|
-
- You SHOULD only use `screenshot` when visual appearance matters (verifying layout, debugging CSS, capturing a visual artifact for the user).
|
|
21
|
-
- You MUST NOT screenshot just to "see what's on the page" — `observe` gives you that with element IDs you can act on immediately.
|
|
18
|
+
- You **SHOULD** only use `screenshot` when visual appearance matters (verifying layout, debugging CSS, capturing a visual artifact for the user).
|
|
19
|
+
- You **MUST NOT** screenshot just to "see what's on the page" — `observe` gives you that with element IDs you can act on immediately.
|
|
22
20
|
</critical>
|
|
23
21
|
|
|
24
22
|
<output>
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
# Cancel Job
|
|
2
|
-
|
|
3
1
|
Cancels a running background job started via async tool execution.
|
|
4
2
|
|
|
5
|
-
You SHOULD use this when a background `bash` or `task` job is no longer needed or is stuck.
|
|
3
|
+
You **SHOULD** use this when a background `bash` or `task` job is no longer needed or is stuck.
|
|
6
4
|
|
|
7
|
-
You MAY inspect jobs first with `read jobs://` or `read jobs://<job-id>`.
|
|
5
|
+
You **MAY** inspect jobs first with `read jobs://` or `read jobs://<job-id>`.
|
|
@@ -8,9 +8,9 @@ Use when:
|
|
|
8
8
|
</conditions>
|
|
9
9
|
|
|
10
10
|
<instruction>
|
|
11
|
-
- You MUST write plan to plan file BEFORE calling this tool
|
|
11
|
+
- You **MUST** write plan to plan file BEFORE calling this tool
|
|
12
12
|
- Tool reads plan from file—does not take plan content as parameter
|
|
13
|
-
- You MUST provide a `title` argument for the final plan artifact (example: `WP_MIGRATION_PLAN`)
|
|
13
|
+
- You **MUST** provide a `title` argument for the final plan artifact (example: `WP_MIGRATION_PLAN`)
|
|
14
14
|
- `.md` is optional in `title`; it is appended automatically when omitted
|
|
15
15
|
- User sees plan contents when reviewing
|
|
16
16
|
</instruction>
|
|
@@ -30,12 +30,12 @@ Unsure about auth method (OAuth vs JWT).
|
|
|
30
30
|
</example>
|
|
31
31
|
|
|
32
32
|
<avoid>
|
|
33
|
-
- MUST NOT call before plan is written to file
|
|
34
|
-
- MUST NOT omit `title`
|
|
35
|
-
- MUST NOT use `ask` to request plan approval (this tool does that)
|
|
36
|
-
- MUST NOT call after pure research tasks (no implementation planned)
|
|
33
|
+
- **MUST NOT** call before plan is written to file
|
|
34
|
+
- **MUST NOT** omit `title`
|
|
35
|
+
- **MUST NOT** use `ask` to request plan approval (this tool does that)
|
|
36
|
+
- **MUST NOT** call after pure research tasks (no implementation planned)
|
|
37
37
|
</avoid>
|
|
38
38
|
|
|
39
39
|
<critical>
|
|
40
|
-
You MUST only use when planning implementation steps. Research tasks (searching, reading, understanding) do not need this tool.
|
|
40
|
+
You **MUST** only use when planning implementation steps. Research tasks (searching, reading, understanding) do not need this tool.
|
|
41
41
|
</critical>
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Fast file pattern matching that works with any codebase size.
|
|
1
|
+
Finds files using fast pattern matching that works with any codebase size.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
4
|
- Pattern includes the search path: `src/**/*.ts`, `lib/*.json`, `**/*.md`
|
|
7
5
|
- Simple patterns like `*.ts` automatically search recursively from cwd
|
|
8
6
|
- Includes hidden files by default (use `hidden: false` to exclude)
|
|
9
|
-
- You SHOULD perform multiple searches in parallel when potentially useful
|
|
7
|
+
- You **SHOULD** perform multiple searches in parallel when potentially useful
|
|
10
8
|
</instruction>
|
|
11
9
|
|
|
12
10
|
<output>
|
|
@@ -23,5 +21,5 @@ Matching file paths sorted by modification time (most recent first). Truncated a
|
|
|
23
21
|
</example>
|
|
24
22
|
|
|
25
23
|
<avoid>
|
|
26
|
-
For open-ended searches requiring multiple rounds of globbing and grepping, you MUST use Task tool instead.
|
|
24
|
+
For open-ended searches requiring multiple rounds of globbing and grepping, you **MUST** use Task tool instead.
|
|
27
25
|
</avoid>
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
Generates or edits images using Gemini image models.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
When using multiple `input_images`, you MUST describe each image's role in `subject` or `scene` field:
|
|
9
|
-
- "Use Image 1 for the character's face and outfit, Image 2 for the pose, Image 3 for the background environment"
|
|
10
|
-
- "Match the color palette from Image 1, apply the lighting style from Image 2"
|
|
11
|
-
</instruction>
|
|
12
|
-
|
|
13
|
-
<output>
|
|
14
|
-
Returns generated image saved to disk. Response includes file path where image was written.
|
|
15
|
-
</output>
|
|
16
|
-
|
|
17
|
-
<caution>
|
|
18
|
-
- For photoreal: you SHOULD add "ultra-detailed, realistic, natural skin texture" to style
|
|
19
|
-
- For posters/cards: you SHOULD use 9:16 aspect ratio with negative space for text placement
|
|
20
|
-
- For iteration: you SHOULD use `changes` for targeted adjustments rather than regenerating from scratch
|
|
21
|
-
- For text: you SHOULD add "sharp, legible, correctly spelled" for important text; keep text short
|
|
22
|
-
- For diagrams: you SHOULD include "scientifically accurate" in style and provide facts explicitly
|
|
23
|
-
</caution>
|
|
3
|
+
<instructions>
|
|
4
|
+
- You **MUST** provide a single detailed `subject` prompt for image generation or editing.
|
|
5
|
+
- When using multiple `input`, you **SHOULD** describe each image's role directly in `subject`, e.g. `Image 1` for composition reference, `Image 2` for lighting reference, `Image 3` for background.
|
|
6
|
+
- For text: you **SHOULD** add "sharp, legible, correctly spelled" for important text; keep text short
|
|
7
|
+
</instructions>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Powerful search tool built on ripgrep.
|
|
1
|
+
Searches files using powerful regex matching built on ripgrep.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
4
|
- Supports full regex syntax (e.g., `log.*Error`, `function\\s+\\w+`); literal braces need escaping (`interface\\{\\}` for `interface{}` in Go)
|
|
@@ -20,7 +18,7 @@ Powerful search tool built on ripgrep.
|
|
|
20
18
|
</output>
|
|
21
19
|
|
|
22
20
|
<critical>
|
|
23
|
-
- You MUST use Grep when searching for content.
|
|
24
|
-
- You MUST NOT invoke `grep` or `rg` via Bash.
|
|
25
|
-
- If the search is open-ended, requiring multiple rounds, you MUST use Task tool with explore subagent instead.
|
|
21
|
+
- You **MUST** use Grep when searching for content.
|
|
22
|
+
- You **MUST NOT** invoke `grep` or `rg` via Bash.
|
|
23
|
+
- If the search is open-ended, requiring multiple rounds, you **MUST** use Task tool with explore subagent instead.
|
|
26
24
|
</critical>
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Apply precise file edits using `LINE#ID` tags from `read` output.
|
|
1
|
+
Applies precise file edits using `LINE#ID` tags from `read` output.
|
|
4
2
|
|
|
5
3
|
<workflow>
|
|
6
|
-
1. You SHOULD issue a `read` call before editing if you have no tagged context for a file.
|
|
7
|
-
2. You MUST pick the smallest operation per change site.
|
|
8
|
-
3. You MUST submit one `edit` call per file with all operations, think your changes through before submitting.
|
|
4
|
+
1. You **SHOULD** issue a `read` call before editing if you have no tagged context for a file.
|
|
5
|
+
2. You **MUST** pick the smallest operation per change site.
|
|
6
|
+
3. You **MUST** submit one `edit` call per file with all operations, think your changes through before submitting.
|
|
9
7
|
</workflow>
|
|
10
8
|
|
|
11
9
|
<operations>
|
|
@@ -40,16 +38,14 @@ Every edit has `op`, `pos`, and `lines`. Range replaces also have `end`. Both `p
|
|
|
40
38
|
</operations>
|
|
41
39
|
|
|
42
40
|
<rules>
|
|
43
|
-
1. **Minimize scope:** You MUST use one logical mutation per operation.
|
|
44
|
-
2. **
|
|
45
|
-
3. **
|
|
46
|
-
4. **For swaps/moves:** You SHOULD prefer one range op over multiple single-line ops.
|
|
47
|
-
5. **Range end tag:** When replacing a block (e.g., an `if` body), the `end` tag MUST include the block's closing brace/bracket — not just the last interior line. Verify the `end` tag covers all lines being logically removed, including trailing `}`, `]`, or `)`. An off-by-one on `end` orphans a brace and breaks syntax.
|
|
41
|
+
1. **Minimize scope:** You **MUST** use one logical mutation per operation.
|
|
42
|
+
2. **Prefer insertion over neighbor rewrites:** You **SHOULD** anchor on structural boundaries (`}`, `]`, `},`), not interior lines.
|
|
43
|
+
3. **Range end tag:** When replacing a block (e.g., an `if` body), the `end` tag **MUST** include the block's closing brace/bracket — not just the last interior line. Verify the `end` tag covers all lines being logically removed, including trailing `}`, `]`, or `)`. An off-by-one on `end` orphans a brace and breaks syntax.
|
|
48
44
|
</rules>
|
|
49
45
|
|
|
50
46
|
<recovery>
|
|
51
|
-
**Tag mismatch (`>>>`):** You MUST retry using fresh tags from the error snippet.
|
|
52
|
-
**No-op (`identical`):** You MUST NOT resubmit. Re-read target lines and adjust the edit.
|
|
47
|
+
**Tag mismatch (`>>>`):** You **MUST** retry using fresh tags from the error snippet. If snippet lacks context, or if you repeatedly fail, you **MUST** re-read the file and issue less ambitious edits, i.e. single op.
|
|
48
|
+
**No-op (`identical`):** You **MUST NOT** resubmit. Re-read target lines and adjust the edit.
|
|
53
49
|
</recovery>
|
|
54
50
|
|
|
55
51
|
<example name="single-line replace">
|
|
@@ -186,6 +182,7 @@ Good — anchors to structural line:
|
|
|
186
182
|
|
|
187
183
|
<critical>
|
|
188
184
|
- Edit payload: `{ path, edits[] }`. Each entry: `op`, `lines`, optional `pos`/`end`. No extra keys.
|
|
189
|
-
- Every tag MUST be copied exactly from fresh tool result as `N#ID`.
|
|
190
|
-
- You MUST re-read after each edit call before issuing another on same file.
|
|
185
|
+
- Every tag **MUST** be copied exactly from fresh tool result as `N#ID`.
|
|
186
|
+
- You **MUST** re-read after each edit call before issuing another on same file.
|
|
187
|
+
- Formatting is a batch operation. You **MUST** never use this tool for formatting.
|
|
191
188
|
</critical>
|
package/src/prompts/tools/lsp.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Patch operations on file given diff. Primary tool for existing-file edits.
|
|
1
|
+
Patches files given diff hunks. Primary tool for existing-file edits.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
4
|
**Hunk Headers:**
|
|
@@ -43,12 +41,12 @@ Returns success/failure; on failure, error message indicates:
|
|
|
43
41
|
</output>
|
|
44
42
|
|
|
45
43
|
<critical>
|
|
46
|
-
- You MUST read the target file before editing
|
|
47
|
-
- You MUST copy anchors and context lines verbatim (including whitespace)
|
|
48
|
-
- You MUST NOT use anchors as comments (no line numbers, location labels, placeholders like `@@ @@`)
|
|
49
|
-
- You MUST NOT place new lines outside the intended block
|
|
50
|
-
- If edit fails or breaks structure, you MUST re-read the file and produce a new patch from current content — you MUST NOT retry the same diff
|
|
51
|
-
- **NEVER** use edit to fix indentation, whitespace, or reformat code. Formatting is a single command run once at the end (`bun fmt`, `cargo fmt`, `prettier
|
|
44
|
+
- You **MUST** read the target file before editing
|
|
45
|
+
- You **MUST** copy anchors and context lines verbatim (including whitespace)
|
|
46
|
+
- You **MUST NOT** use anchors as comments (no line numbers, location labels, placeholders like `@@ @@`)
|
|
47
|
+
- You **MUST NOT** place new lines outside the intended block
|
|
48
|
+
- If edit fails or breaks structure, you **MUST** re-read the file and produce a new patch from current content — you **MUST NOT** retry the same diff
|
|
49
|
+
- **NEVER** use edit to fix indentation, whitespace, or reformat code. Formatting is a single command run once at the end (`bun fmt`, `cargo fmt`, `prettier —write`, etc.)—not N individual edits. If you see inconsistent indentation after an edit, leave it; the formatter will fix all of it in one pass.
|
|
52
50
|
</critical>
|
|
53
51
|
|
|
54
52
|
<example name="create">
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
# Python
|
|
2
|
-
|
|
3
1
|
Runs Python cells sequentially in persistent IPython kernel.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
4
|
Kernel persists across calls and cells; **imports, variables, and functions survive—use this.**
|
|
7
5
|
**Work incrementally:**
|
|
8
|
-
- You SHOULD use one logical step per cell (imports, define function, test it, use it)
|
|
9
|
-
- You SHOULD pass multiple small cells in one call
|
|
10
|
-
- You SHOULD define small functions you can reuse and debug individually
|
|
11
|
-
- You MUST put explanations in assistant message or cell title, MUST NOT put them in code
|
|
6
|
+
- You **SHOULD** use one logical step per cell (imports, define function, test it, use it)
|
|
7
|
+
- You **SHOULD** pass multiple small cells in one call
|
|
8
|
+
- You **SHOULD** define small functions you can reuse and debug individually
|
|
9
|
+
- You **MUST** put explanations in assistant message or cell title, **MUST NOT** put them in code
|
|
12
10
|
**When something fails:**
|
|
13
11
|
- Errors tell you which cell failed (e.g., "Cell 3 failed")
|
|
14
|
-
- You SHOULD resubmit only the fixed cell (or fixed cell + remaining cells)
|
|
12
|
+
- You **SHOULD** resubmit only the fixed cell (or fixed cell + remaining cells)
|
|
15
13
|
</instruction>
|
|
16
14
|
|
|
15
|
+
{{#if categories.length}}
|
|
17
16
|
<prelude>
|
|
18
17
|
All helpers auto-print results and return values for chaining.
|
|
19
18
|
|
|
20
|
-
{{#if categories.length}}
|
|
21
19
|
{{#each categories}}
|
|
22
20
|
### {{name}}
|
|
23
21
|
|
|
@@ -28,10 +26,8 @@ All helpers auto-print results and return values for chaining.
|
|
|
28
26
|
{{/each}}
|
|
29
27
|
```
|
|
30
28
|
{{/each}}
|
|
31
|
-
{{else}}
|
|
32
|
-
(Documentation unavailable — Python kernel failed to start)
|
|
33
|
-
{{/if}}
|
|
34
29
|
</prelude>
|
|
30
|
+
{{/if}}
|
|
35
31
|
|
|
36
32
|
<output>
|
|
37
33
|
User sees output like Jupyter notebook; rich displays render fully:
|
|
@@ -39,16 +35,16 @@ User sees output like Jupyter notebook; rich displays render fully:
|
|
|
39
35
|
- `display(HTML(…))` → rendered HTML
|
|
40
36
|
- `display(Markdown(…))` → formatted markdown
|
|
41
37
|
- `plt.show()` → inline figures
|
|
42
|
-
**You will see object repr** (e.g., `<IPython.core.display.JSON object>`). Trust `display()`; you MUST NOT assume user sees only repr.
|
|
38
|
+
**You will see object repr** (e.g., `<IPython.core.display.JSON object>`). Trust `display()`; you **MUST NOT** assume user sees only repr.
|
|
43
39
|
</output>
|
|
44
40
|
|
|
45
41
|
<caution>
|
|
46
42
|
- Per-call mode uses fresh kernel each call
|
|
47
|
-
- You MUST use `reset: true` to clear state when session mode active
|
|
43
|
+
- You **MUST** use `reset: true` to clear state when session mode active
|
|
48
44
|
</caution>
|
|
49
45
|
|
|
50
46
|
<critical>
|
|
51
|
-
- You MUST use `run()` for shell commands; you MUST NOT use raw `subprocess`
|
|
47
|
+
- You **MUST** use `run()` for shell commands; you **MUST NOT** use raw `subprocess`
|
|
52
48
|
</critical>
|
|
53
49
|
|
|
54
50
|
<example name="good">
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
String replacements in files with fuzzy whitespace matching.
|
|
1
|
+
Performs string replacements in files with fuzzy whitespace matching.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
|
-
- You MUST use the smallest edit that uniquely identifies the change
|
|
7
|
-
- If `old_text` not unique, you MUST expand to include more context or use `all: true` to replace all occurrences
|
|
4
|
+
- You **MUST** use the smallest edit that uniquely identifies the change
|
|
5
|
+
- If `old_text` not unique, you **MUST** expand to include more context or use `all: true` to replace all occurrences
|
|
8
6
|
- Fuzzy matching handles minor whitespace/indentation differences automatically
|
|
9
|
-
- You SHOULD prefer editing existing files over creating new ones
|
|
7
|
+
- You **SHOULD** prefer editing existing files over creating new ones
|
|
10
8
|
</instruction>
|
|
11
9
|
|
|
12
10
|
<output>
|
|
@@ -14,7 +12,7 @@ Returns success/failure status. On success, file modified in place with replacem
|
|
|
14
12
|
</output>
|
|
15
13
|
|
|
16
14
|
<critical>
|
|
17
|
-
- You MUST read the file at least once in the conversation before editing. Tool errors if you attempt edit without reading file first.
|
|
15
|
+
- You **MUST** read the file at least once in the conversation before editing. Tool errors if you attempt edit without reading file first.
|
|
18
16
|
</critical>
|
|
19
17
|
|
|
20
18
|
<bash-alternatives>
|
package/src/prompts/tools/ssh.md
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Run commands on remote hosts.
|
|
1
|
+
Runs commands on remote hosts.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
|
-
You MUST build commands from the reference below
|
|
4
|
+
You **MUST** build commands from the reference below
|
|
7
5
|
</instruction>
|
|
8
6
|
|
|
9
7
|
<commands>
|
|
@@ -24,7 +22,7 @@ You MUST build commands from the reference below
|
|
|
24
22
|
</commands>
|
|
25
23
|
|
|
26
24
|
<critical>
|
|
27
|
-
You MUST verify the shell type from "Available hosts" and use matching commands.
|
|
25
|
+
You **MUST** verify the shell type from "Available hosts" and use matching commands.
|
|
28
26
|
</critical>
|
|
29
27
|
|
|
30
28
|
<example name="linux">
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
# Task
|
|
2
|
-
|
|
3
1
|
Launches subagents to parallelize workflows.
|
|
4
2
|
|
|
5
3
|
{{#if asyncEnabled}}
|
|
6
4
|
- Use `read jobs://` to inspect state; `read jobs://<job_id>` for detail.
|
|
7
|
-
- Use the `await` tool to wait until completion. You MUST NOT poll `read jobs://` in a loop.
|
|
5
|
+
- Use the `await` tool to wait until completion. You **MUST NOT** poll `read jobs://` in a loop.
|
|
8
6
|
{{/if}}
|
|
9
7
|
|
|
10
|
-
Subagents lack your conversation history. Every decision, file content, and user requirement they need MUST be explicit in `context` or `assignment`.
|
|
8
|
+
Subagents lack your conversation history. Every decision, file content, and user requirement they need **MUST** be explicit in `context` or `assignment`.
|
|
11
9
|
|
|
12
10
|
<parameters>
|
|
13
11
|
- `agent`: Agent type for all tasks.
|
|
@@ -16,15 +14,15 @@ Subagents lack your conversation history. Every decision, file content, and user
|
|
|
16
14
|
- `.assignment`: Complete self-contained instructions. One-liners PROHIBITED; missing acceptance criteria = too vague.
|
|
17
15
|
- `.skills`: Skill names to preload
|
|
18
16
|
- `context`: Shared background prepended to every assignment. Session-specific info only.
|
|
19
|
-
- `schema`: JTD schema for expected output. Format lives here — MUST NOT be duplicated in assignments.
|
|
17
|
+
- `schema`: JTD schema for expected output. Format lives here — **MUST NOT** be duplicated in assignments.
|
|
20
18
|
- `tasks`: Tasks to execute in parallel.
|
|
21
19
|
- `isolated`: Run in isolated git worktree; returns patches. Use when tasks edit overlapping files.
|
|
22
20
|
</parameters>
|
|
23
21
|
|
|
24
22
|
<critical>
|
|
25
|
-
- MUST NOT include AGENTS.md rules, coding conventions, or style guidelines — subagents already have them.
|
|
26
|
-
- MUST NOT duplicate shared constraints across assignments — put them in `context` once.
|
|
27
|
-
- MUST NOT tell tasks to run project-wide build/test/lint. Parallel agents share the working tree; each task edits, stops. Caller verifies after all complete.
|
|
23
|
+
- **MUST NOT** include AGENTS.md rules, coding conventions, or style guidelines — subagents already have them.
|
|
24
|
+
- **MUST NOT** duplicate shared constraints across assignments — put them in `context` once.
|
|
25
|
+
- **MUST NOT** tell tasks to run project-wide build/test/lint. Parallel agents share the working tree; each task edits, stops. Caller verifies after all complete.
|
|
28
26
|
- For large payloads (traces, JSON blobs), write to `local://<path>` and pass the path in context.
|
|
29
27
|
- If scope is unclear, run a **Discovery task** first to enumerate files and callsites, then fan out.
|
|
30
28
|
</critical>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Manage a phased task list. Submit an `ops` array — each op mutates state incrementally.
|
|
1
|
+
Manages a phased task list. Submit an `ops` array — each op mutates state incrementally.
|
|
4
2
|
**Primary op: `update`.** Use it to mark tasks `in_progress` or `completed`. Only reach for other ops when the structure itself needs to change.
|
|
5
3
|
|
|
6
4
|
<critical>
|
|
7
|
-
You MUST call this tool twice per task:
|
|
5
|
+
You **MUST** call this tool twice per task:
|
|
8
6
|
1. Before beginning — `{op: "update", id: "task-N", status: "in_progress"}`
|
|
9
7
|
2. Immediately after finishing — `{op: "update", id: "task-N", status: "completed"}`
|
|
10
8
|
|
|
11
|
-
You MUST keep exactly one task `in_progress` at all times. Mark `completed` immediately — no batching.
|
|
9
|
+
You **MUST** keep exactly one task `in_progress` at all times. Mark `completed` immediately — no batching.
|
|
12
10
|
</critical>
|
|
13
11
|
|
|
14
12
|
<conditions>
|
|
@@ -40,10 +38,10 @@ Create a todo list when:
|
|
|
40
38
|
|`abandoned`|Dropped intentionally|
|
|
41
39
|
|
|
42
40
|
## Rules
|
|
43
|
-
- You MUST mark `in_progress` **before** starting work, not after
|
|
44
|
-
- You MUST mark `completed` **immediately** — never defer
|
|
45
|
-
- You MUST keep exactly **one** task `in_progress`
|
|
46
|
-
- You MUST complete phases in order — do not mark later tasks `completed` while earlier ones are `pending`
|
|
41
|
+
- You **MUST** mark `in_progress` **before** starting work, not after
|
|
42
|
+
- You **MUST** mark `completed` **immediately** — never defer
|
|
43
|
+
- You **MUST** keep exactly **one** task `in_progress`
|
|
44
|
+
- You **MUST** complete phases in order — do not mark later tasks `completed` while earlier ones are `pending`
|
|
47
45
|
- On blockers: keep `in_progress`, add a new task describing the blocker
|
|
48
46
|
- Multiple ops can be batched in one call (e.g., complete current + start next)
|
|
49
47
|
</protocol>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Search the web for up-to-date information beyond Claude's knowledge cutoff.
|
|
1
|
+
Searches the web for up-to-date information beyond Claude's knowledge cutoff.
|
|
4
2
|
|
|
5
3
|
<instruction>
|
|
6
|
-
- You SHOULD prefer primary sources (papers, official docs) and corroborate key claims with multiple sources
|
|
7
|
-
- You MUST include links for cited sources in the final response
|
|
4
|
+
- You **SHOULD** prefer primary sources (papers, official docs) and corroborate key claims with multiple sources
|
|
5
|
+
- You **MUST** include links for cited sources in the final response
|
|
8
6
|
</instruction>
|
|
9
7
|
|
|
10
8
|
<caution>
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# Write
|
|
2
|
-
|
|
3
1
|
Creates or overwrites file at specified path.
|
|
4
2
|
|
|
5
3
|
<conditions>
|
|
@@ -8,7 +6,7 @@ Creates or overwrites file at specified path.
|
|
|
8
6
|
</conditions>
|
|
9
7
|
|
|
10
8
|
<critical>
|
|
11
|
-
- You SHOULD use Edit tool for modifying existing files (more precise, preserves formatting)
|
|
12
|
-
- You MUST NOT create documentation files (*.md, README) unless explicitly requested
|
|
13
|
-
- You MUST NOT use emojis unless requested
|
|
9
|
+
- You **SHOULD** use Edit tool for modifying existing files (more precise, preserves formatting)
|
|
10
|
+
- You **MUST NOT** create documentation files (*.md, README) unless explicitly requested
|
|
11
|
+
- You **MUST NOT** use emojis unless requested
|
|
14
12
|
</critical>
|
package/src/sdk.ts
CHANGED
|
@@ -9,8 +9,7 @@ import {
|
|
|
9
9
|
import { type Message, type Model, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import { prewarmOpenAICodexResponses } from "@oh-my-pi/pi-ai/providers/openai-codex-responses";
|
|
11
11
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
12
|
-
import { $env, logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
13
|
-
import { getAgentDbPath, getAgentDir, getProjectDir } from "@oh-my-pi/pi-utils/dirs";
|
|
12
|
+
import { $env, getAgentDbPath, getAgentDir, getProjectDir, logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
14
13
|
import chalk from "chalk";
|
|
15
14
|
import { AsyncJobManager } from "./async";
|
|
16
15
|
import { loadCapability } from "./capability";
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type AgentMessage,
|
|
24
24
|
type AgentState,
|
|
25
25
|
type AgentTool,
|
|
26
|
+
INTENT_FIELD,
|
|
26
27
|
type ThinkingLevel,
|
|
27
28
|
} from "@oh-my-pi/pi-agent-core";
|
|
28
29
|
import type {
|
|
@@ -38,8 +39,7 @@ import type {
|
|
|
38
39
|
UsageReport,
|
|
39
40
|
} from "@oh-my-pi/pi-ai";
|
|
40
41
|
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
41
|
-
import { abortableSleep, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
42
|
-
import { getAgentDbPath } from "@oh-my-pi/pi-utils/dirs";
|
|
42
|
+
import { abortableSleep, getAgentDbPath, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
43
43
|
import type { AsyncJob, AsyncJobManager } from "../async";
|
|
44
44
|
import type { Rule } from "../capability/rule";
|
|
45
45
|
import { MODEL_ROLE_IDS, type ModelRegistry, type ModelRole } from "../config/model-registry";
|
|
@@ -84,8 +84,6 @@ import planModeActivePrompt from "../prompts/system/plan-mode-active.md" with {
|
|
|
84
84
|
import planModeReferencePrompt from "../prompts/system/plan-mode-reference.md" with { type: "text" };
|
|
85
85
|
import ttsrInterruptTemplate from "../prompts/system/ttsr-interrupt.md" with { type: "text" };
|
|
86
86
|
import type { SecretObfuscator } from "../secrets/obfuscator";
|
|
87
|
-
import { closeAllConnections } from "../ssh/connection-manager";
|
|
88
|
-
import { unmountAll } from "../ssh/sshfs-mount";
|
|
89
87
|
import { outputMeta } from "../tools/output-meta";
|
|
90
88
|
import { resolveToCwd } from "../tools/path-utils";
|
|
91
89
|
import { getLatestTodoPhasesFromEntries, type TodoItem, type TodoPhase } from "../tools/todo-write";
|
|
@@ -273,15 +271,6 @@ const noOpUIContext: ExtensionUIContext = {
|
|
|
273
271
|
setToolsExpanded: () => {},
|
|
274
272
|
};
|
|
275
273
|
|
|
276
|
-
async function cleanupSshResources(): Promise<void> {
|
|
277
|
-
const results = await Promise.allSettled([closeAllConnections(), unmountAll()]);
|
|
278
|
-
for (const result of results) {
|
|
279
|
-
if (result.status === "rejected") {
|
|
280
|
-
logger.warn("SSH cleanup failed", { error: String(result.reason) });
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
274
|
// ============================================================================
|
|
286
275
|
// AgentSession Class
|
|
287
276
|
// ============================================================================
|
|
@@ -1275,13 +1264,19 @@ export class AgentSession {
|
|
|
1275
1264
|
* Call this when completely done with the session.
|
|
1276
1265
|
*/
|
|
1277
1266
|
async dispose(): Promise<void> {
|
|
1267
|
+
try {
|
|
1268
|
+
if (this.#extensionRunner?.hasHandlers("session_shutdown")) {
|
|
1269
|
+
await this.#extensionRunner.emit({ type: "session_shutdown" });
|
|
1270
|
+
}
|
|
1271
|
+
} catch (error) {
|
|
1272
|
+
logger.warn("Failed to emit session_shutdown event", { error: String(error) });
|
|
1273
|
+
}
|
|
1278
1274
|
const drained = await this.#asyncJobManager?.dispose({ timeoutMs: 3_000 });
|
|
1279
1275
|
const deliveryState = this.#asyncJobManager?.getDeliveryState();
|
|
1280
1276
|
if (drained === false && deliveryState) {
|
|
1281
1277
|
logger.warn("Async job completion deliveries still pending during dispose", { ...deliveryState });
|
|
1282
1278
|
}
|
|
1283
1279
|
await this.sessionManager.flush();
|
|
1284
|
-
await cleanupSshResources();
|
|
1285
1280
|
for (const state of this.#providerSessionState.values()) {
|
|
1286
1281
|
state.close();
|
|
1287
1282
|
}
|
|
@@ -4615,7 +4610,7 @@ Be thorough - include exact file paths, function names, error messages, and tech
|
|
|
4615
4610
|
function formatArgsAsXml(args: Record<string, unknown>, indent = "\t"): string {
|
|
4616
4611
|
const parts: string[] = [];
|
|
4617
4612
|
for (const [key, value] of Object.entries(args)) {
|
|
4618
|
-
if (key ===
|
|
4613
|
+
if (key === INTENT_FIELD) continue;
|
|
4619
4614
|
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
4620
4615
|
parts.push(`${indent}<parameter name="${key}">${text}</parameter>`);
|
|
4621
4616
|
}
|
|
@@ -4861,15 +4856,4 @@ Be thorough - include exact file paths, function names, error messages, and tech
|
|
|
4861
4856
|
get extensionRunner(): ExtensionRunner | undefined {
|
|
4862
4857
|
return this.#extensionRunner;
|
|
4863
4858
|
}
|
|
4864
|
-
|
|
4865
|
-
/**
|
|
4866
|
-
* Emit a custom tool session event (backwards compatibility for older callers).
|
|
4867
|
-
*/
|
|
4868
|
-
async emitCustomToolSessionEvent(reason: "start" | "switch" | "branch" | "tree" | "shutdown"): Promise<void> {
|
|
4869
|
-
if (reason !== "shutdown") return;
|
|
4870
|
-
if (this.#extensionRunner?.hasHandlers("session_shutdown")) {
|
|
4871
|
-
await this.#extensionRunner.emit({ type: "session_shutdown" });
|
|
4872
|
-
}
|
|
4873
|
-
await cleanupSshResources();
|
|
4874
|
-
}
|
|
4875
4859
|
}
|
|
@@ -2,8 +2,7 @@ import { Database, type Statement } from "bun:sqlite";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { type AuthCredential, AuthCredentialStore, type StoredAuthCredential } from "@oh-my-pi/pi-ai";
|
|
5
|
-
import { isRecord, logger } from "@oh-my-pi/pi-utils";
|
|
6
|
-
import { getAgentDbPath } from "@oh-my-pi/pi-utils/dirs";
|
|
5
|
+
import { getAgentDbPath, isRecord, logger } from "@oh-my-pi/pi-utils";
|
|
7
6
|
import type { RawSettings as Settings } from "../config/settings";
|
|
8
7
|
|
|
9
8
|
/** Row shape for settings table queries */
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Database, type Statement } from "bun:sqlite";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import { getAgentDir } from "@oh-my-pi/pi-utils/dirs";
|
|
4
|
+
import { getAgentDir, logger } from "@oh-my-pi/pi-utils";
|
|
6
5
|
|
|
7
6
|
export interface HistoryEntry {
|
|
8
7
|
id: number;
|
|
@@ -4,8 +4,16 @@ import * as path from "node:path";
|
|
|
4
4
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
5
5
|
import type { ImageContent, Message, TextContent, Usage } from "@oh-my-pi/pi-ai";
|
|
6
6
|
import { getTerminalId } from "@oh-my-pi/pi-tui";
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
getBlobsDir,
|
|
9
|
+
getAgentDir as getDefaultAgentDir,
|
|
10
|
+
getProjectDir,
|
|
11
|
+
isEnoent,
|
|
12
|
+
logger,
|
|
13
|
+
parseJsonlLenient,
|
|
14
|
+
Snowflake,
|
|
15
|
+
toError,
|
|
16
|
+
} from "@oh-my-pi/pi-utils";
|
|
9
17
|
import { ArtifactManager } from "./artifacts";
|
|
10
18
|
import { type BlobPutResult, BlobStore, externalizeImageData, isBlobRef, resolveImageData } from "./blob-store";
|
|
11
19
|
import {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
4
|
-
import { getRemoteHostDir, getSshControlDir } from "@oh-my-pi/pi-utils/dirs";
|
|
3
|
+
import { getRemoteHostDir, getSshControlDir, isEnoent, logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
5
4
|
import { $ } from "bun";
|
|
6
5
|
import { buildSshTarget, sanitizeHostName } from "./utils";
|
|
7
6
|
|
|
@@ -69,6 +68,7 @@ async function validateKeyPermissions(keyPath?: string): Promise<void> {
|
|
|
69
68
|
|
|
70
69
|
function buildCommonArgs(host: SSHConnectionTarget): string[] {
|
|
71
70
|
const args = [
|
|
71
|
+
"-n",
|
|
72
72
|
"-o",
|
|
73
73
|
"ControlMaster=auto",
|
|
74
74
|
"-o",
|
|
@@ -362,6 +362,8 @@ export async function buildRemoteCommand(host: SSHConnectionTarget, command: str
|
|
|
362
362
|
return [...buildCommonArgs(host), buildSshTarget(host.username, host.host), command];
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
let registered = false;
|
|
366
|
+
|
|
365
367
|
export async function ensureConnection(host: SSHConnectionTarget): Promise<void> {
|
|
366
368
|
const key = host.name;
|
|
367
369
|
const pending = pendingConnections.get(key);
|
|
@@ -375,6 +377,13 @@ export async function ensureConnection(host: SSHConnectionTarget): Promise<void>
|
|
|
375
377
|
ensureControlDir();
|
|
376
378
|
await validateKeyPermissions(host.keyPath);
|
|
377
379
|
|
|
380
|
+
if (!registered) {
|
|
381
|
+
registered = true;
|
|
382
|
+
postmortem.register("ssh-cleanup", async () => {
|
|
383
|
+
await closeAllConnections();
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
378
387
|
const target = buildSshTarget(host.username, host.host);
|
|
379
388
|
const check = await runSshSync(["-O", "check", ...buildCommonArgs(host), target]);
|
|
380
389
|
if (check.exitCode === 0) {
|