@oh-my-pi/pi-coding-agent 1.337.0
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 +1228 -0
- package/README.md +1041 -0
- package/docs/compaction.md +403 -0
- package/docs/custom-tools.md +541 -0
- package/docs/extension-loading.md +1004 -0
- package/docs/hooks.md +867 -0
- package/docs/rpc.md +1040 -0
- package/docs/sdk.md +994 -0
- package/docs/session-tree-plan.md +441 -0
- package/docs/session.md +240 -0
- package/docs/skills.md +290 -0
- package/docs/theme.md +637 -0
- package/docs/tree.md +197 -0
- package/docs/tui.md +341 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +124 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/question/index.ts +84 -0
- package/examples/custom-tools/subagent/README.md +172 -0
- package/examples/custom-tools/subagent/agents/planner.md +37 -0
- package/examples/custom-tools/subagent/agents/reviewer.md +35 -0
- package/examples/custom-tools/subagent/agents/scout.md +50 -0
- package/examples/custom-tools/subagent/agents/worker.md +24 -0
- package/examples/custom-tools/subagent/agents.ts +156 -0
- package/examples/custom-tools/subagent/commands/implement-and-review.md +10 -0
- package/examples/custom-tools/subagent/commands/implement.md +10 -0
- package/examples/custom-tools/subagent/commands/scout-and-plan.md +9 -0
- package/examples/custom-tools/subagent/index.ts +1002 -0
- package/examples/custom-tools/todo/index.ts +212 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +49 -0
- package/examples/hooks/confirm-destructive.ts +59 -0
- package/examples/hooks/custom-compaction.ts +116 -0
- package/examples/hooks/dirty-repo-guard.ts +52 -0
- package/examples/hooks/file-trigger.ts +41 -0
- package/examples/hooks/git-checkpoint.ts +53 -0
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +34 -0
- package/examples/hooks/protected-paths.ts +30 -0
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/snake.ts +343 -0
- package/examples/hooks/status-line.ts +40 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +44 -0
- package/examples/sdk/04-skills.ts +44 -0
- package/examples/sdk/05-tools.ts +90 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +36 -0
- package/examples/sdk/08-slash-commands.ts +42 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
- package/examples/sdk/10-settings.ts +38 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +95 -0
- package/examples/sdk/README.md +154 -0
- package/package.json +81 -0
- package/src/cli/args.ts +246 -0
- package/src/cli/file-processor.ts +72 -0
- package/src/cli/list-models.ts +104 -0
- package/src/cli/plugin-cli.ts +650 -0
- package/src/cli/session-picker.ts +41 -0
- package/src/cli.ts +10 -0
- package/src/commands/init.md +20 -0
- package/src/config.ts +159 -0
- package/src/core/agent-session.ts +1900 -0
- package/src/core/auth-storage.ts +236 -0
- package/src/core/bash-executor.ts +196 -0
- package/src/core/compaction/branch-summarization.ts +343 -0
- package/src/core/compaction/compaction.ts +742 -0
- package/src/core/compaction/index.ts +7 -0
- package/src/core/compaction/utils.ts +154 -0
- package/src/core/custom-tools/index.ts +21 -0
- package/src/core/custom-tools/loader.ts +248 -0
- package/src/core/custom-tools/types.ts +169 -0
- package/src/core/custom-tools/wrapper.ts +28 -0
- package/src/core/exec.ts +129 -0
- package/src/core/export-html/index.ts +211 -0
- package/src/core/export-html/template.css +781 -0
- package/src/core/export-html/template.html +54 -0
- package/src/core/export-html/template.js +1185 -0
- package/src/core/export-html/vendor/highlight.min.js +1213 -0
- package/src/core/export-html/vendor/marked.min.js +6 -0
- package/src/core/hooks/index.ts +16 -0
- package/src/core/hooks/loader.ts +312 -0
- package/src/core/hooks/runner.ts +434 -0
- package/src/core/hooks/tool-wrapper.ts +99 -0
- package/src/core/hooks/types.ts +773 -0
- package/src/core/index.ts +52 -0
- package/src/core/mcp/client.ts +158 -0
- package/src/core/mcp/config.ts +154 -0
- package/src/core/mcp/index.ts +45 -0
- package/src/core/mcp/loader.ts +68 -0
- package/src/core/mcp/manager.ts +181 -0
- package/src/core/mcp/tool-bridge.ts +148 -0
- package/src/core/mcp/transports/http.ts +316 -0
- package/src/core/mcp/transports/index.ts +6 -0
- package/src/core/mcp/transports/stdio.ts +252 -0
- package/src/core/mcp/types.ts +220 -0
- package/src/core/messages.ts +189 -0
- package/src/core/model-registry.ts +317 -0
- package/src/core/model-resolver.ts +393 -0
- package/src/core/plugins/doctor.ts +59 -0
- package/src/core/plugins/index.ts +38 -0
- package/src/core/plugins/installer.ts +189 -0
- package/src/core/plugins/loader.ts +338 -0
- package/src/core/plugins/manager.ts +672 -0
- package/src/core/plugins/parser.ts +105 -0
- package/src/core/plugins/paths.ts +32 -0
- package/src/core/plugins/types.ts +190 -0
- package/src/core/sdk.ts +760 -0
- package/src/core/session-manager.ts +1128 -0
- package/src/core/settings-manager.ts +443 -0
- package/src/core/skills.ts +437 -0
- package/src/core/slash-commands.ts +248 -0
- package/src/core/system-prompt.ts +439 -0
- package/src/core/timings.ts +25 -0
- package/src/core/tools/ask.ts +211 -0
- package/src/core/tools/bash-interceptor.ts +120 -0
- package/src/core/tools/bash.ts +250 -0
- package/src/core/tools/context.ts +32 -0
- package/src/core/tools/edit-diff.ts +475 -0
- package/src/core/tools/edit.ts +208 -0
- package/src/core/tools/exa/company.ts +59 -0
- package/src/core/tools/exa/index.ts +64 -0
- package/src/core/tools/exa/linkedin.ts +59 -0
- package/src/core/tools/exa/logger.ts +56 -0
- package/src/core/tools/exa/mcp-client.ts +368 -0
- package/src/core/tools/exa/render.ts +196 -0
- package/src/core/tools/exa/researcher.ts +90 -0
- package/src/core/tools/exa/search.ts +337 -0
- package/src/core/tools/exa/types.ts +168 -0
- package/src/core/tools/exa/websets.ts +248 -0
- package/src/core/tools/find.ts +261 -0
- package/src/core/tools/grep.ts +555 -0
- package/src/core/tools/index.ts +202 -0
- package/src/core/tools/ls.ts +140 -0
- package/src/core/tools/lsp/client.ts +605 -0
- package/src/core/tools/lsp/config.ts +147 -0
- package/src/core/tools/lsp/edits.ts +101 -0
- package/src/core/tools/lsp/index.ts +804 -0
- package/src/core/tools/lsp/render.ts +447 -0
- package/src/core/tools/lsp/rust-analyzer.ts +145 -0
- package/src/core/tools/lsp/types.ts +463 -0
- package/src/core/tools/lsp/utils.ts +486 -0
- package/src/core/tools/notebook.ts +229 -0
- package/src/core/tools/path-utils.ts +61 -0
- package/src/core/tools/read.ts +240 -0
- package/src/core/tools/renderers.ts +540 -0
- package/src/core/tools/task/agents.ts +153 -0
- package/src/core/tools/task/artifacts.ts +114 -0
- package/src/core/tools/task/bundled-agents/browser.md +71 -0
- package/src/core/tools/task/bundled-agents/explore.md +82 -0
- package/src/core/tools/task/bundled-agents/plan.md +54 -0
- package/src/core/tools/task/bundled-agents/reviewer.md +59 -0
- package/src/core/tools/task/bundled-agents/task.md +53 -0
- package/src/core/tools/task/bundled-commands/architect-plan.md +10 -0
- package/src/core/tools/task/bundled-commands/implement-with-critic.md +11 -0
- package/src/core/tools/task/bundled-commands/implement.md +11 -0
- package/src/core/tools/task/commands.ts +213 -0
- package/src/core/tools/task/discovery.ts +208 -0
- package/src/core/tools/task/executor.ts +367 -0
- package/src/core/tools/task/index.ts +388 -0
- package/src/core/tools/task/model-resolver.ts +115 -0
- package/src/core/tools/task/parallel.ts +38 -0
- package/src/core/tools/task/render.ts +232 -0
- package/src/core/tools/task/types.ts +99 -0
- package/src/core/tools/truncate.ts +265 -0
- package/src/core/tools/web-fetch.ts +2370 -0
- package/src/core/tools/web-search/auth.ts +193 -0
- package/src/core/tools/web-search/index.ts +537 -0
- package/src/core/tools/web-search/providers/anthropic.ts +198 -0
- package/src/core/tools/web-search/providers/exa.ts +302 -0
- package/src/core/tools/web-search/providers/perplexity.ts +195 -0
- package/src/core/tools/web-search/render.ts +182 -0
- package/src/core/tools/web-search/types.ts +180 -0
- package/src/core/tools/write.ts +99 -0
- package/src/index.ts +176 -0
- package/src/main.ts +464 -0
- package/src/migrations.ts +135 -0
- package/src/modes/index.ts +43 -0
- package/src/modes/interactive/components/armin.ts +382 -0
- package/src/modes/interactive/components/assistant-message.ts +86 -0
- package/src/modes/interactive/components/bash-execution.ts +196 -0
- package/src/modes/interactive/components/bordered-loader.ts +41 -0
- package/src/modes/interactive/components/branch-summary-message.ts +42 -0
- package/src/modes/interactive/components/compaction-summary-message.ts +45 -0
- package/src/modes/interactive/components/custom-editor.ts +122 -0
- package/src/modes/interactive/components/diff.ts +147 -0
- package/src/modes/interactive/components/dynamic-border.ts +25 -0
- package/src/modes/interactive/components/footer.ts +381 -0
- package/src/modes/interactive/components/hook-editor.ts +117 -0
- package/src/modes/interactive/components/hook-input.ts +64 -0
- package/src/modes/interactive/components/hook-message.ts +96 -0
- package/src/modes/interactive/components/hook-selector.ts +91 -0
- package/src/modes/interactive/components/model-selector.ts +247 -0
- package/src/modes/interactive/components/oauth-selector.ts +120 -0
- package/src/modes/interactive/components/plugin-settings.ts +479 -0
- package/src/modes/interactive/components/queue-mode-selector.ts +56 -0
- package/src/modes/interactive/components/session-selector.ts +204 -0
- package/src/modes/interactive/components/settings-selector.ts +453 -0
- package/src/modes/interactive/components/show-images-selector.ts +45 -0
- package/src/modes/interactive/components/theme-selector.ts +62 -0
- package/src/modes/interactive/components/thinking-selector.ts +64 -0
- package/src/modes/interactive/components/tool-execution.ts +675 -0
- package/src/modes/interactive/components/tree-selector.ts +866 -0
- package/src/modes/interactive/components/user-message-selector.ts +159 -0
- package/src/modes/interactive/components/user-message.ts +18 -0
- package/src/modes/interactive/components/visual-truncate.ts +50 -0
- package/src/modes/interactive/components/welcome.ts +183 -0
- package/src/modes/interactive/interactive-mode.ts +2516 -0
- package/src/modes/interactive/theme/dark.json +101 -0
- package/src/modes/interactive/theme/light.json +98 -0
- package/src/modes/interactive/theme/theme-schema.json +308 -0
- package/src/modes/interactive/theme/theme.ts +998 -0
- package/src/modes/print-mode.ts +128 -0
- package/src/modes/rpc/rpc-client.ts +527 -0
- package/src/modes/rpc/rpc-mode.ts +483 -0
- package/src/modes/rpc/rpc-types.ts +203 -0
- package/src/utils/changelog.ts +99 -0
- package/src/utils/clipboard.ts +265 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/mime.ts +30 -0
- package/src/utils/shell.ts +276 -0
- package/src/utils/tools-manager.ts +274 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session artifacts for subagent outputs.
|
|
3
|
+
*
|
|
4
|
+
* When a session exists, writes agent outputs to a sibling directory.
|
|
5
|
+
* Otherwise uses temp files that are cleaned up after execution.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as os from "node:os";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Derive artifacts directory from session file path.
|
|
14
|
+
*
|
|
15
|
+
* /path/to/sessions/project/2026-01-01T14-28-11-636Z_uuid.jsonl
|
|
16
|
+
* → /path/to/sessions/project/2026-01-01T14-28-11-636Z_uuid/
|
|
17
|
+
*/
|
|
18
|
+
export function getArtifactsDir(sessionFile: string | null): string | null {
|
|
19
|
+
if (!sessionFile) return null;
|
|
20
|
+
// Strip .jsonl extension to get directory path
|
|
21
|
+
if (sessionFile.endsWith(".jsonl")) {
|
|
22
|
+
return sessionFile.slice(0, -6);
|
|
23
|
+
}
|
|
24
|
+
return sessionFile;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Ensure artifacts directory exists.
|
|
29
|
+
*/
|
|
30
|
+
export function ensureArtifactsDir(dir: string): void {
|
|
31
|
+
if (!fs.existsSync(dir)) {
|
|
32
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Generate artifact file paths for an agent run.
|
|
38
|
+
*/
|
|
39
|
+
export function getArtifactPaths(
|
|
40
|
+
dir: string,
|
|
41
|
+
agentName: string,
|
|
42
|
+
index: number,
|
|
43
|
+
): { inputPath: string; outputPath: string; jsonlPath: string } {
|
|
44
|
+
const base = `${agentName}_${index}`;
|
|
45
|
+
return {
|
|
46
|
+
inputPath: path.join(dir, `${base}.in.md`),
|
|
47
|
+
outputPath: path.join(dir, `${base}.out.md`),
|
|
48
|
+
jsonlPath: path.join(dir, `${base}.jsonl`),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Write artifacts for an agent run.
|
|
54
|
+
*/
|
|
55
|
+
export async function writeArtifacts(
|
|
56
|
+
dir: string,
|
|
57
|
+
agentName: string,
|
|
58
|
+
index: number,
|
|
59
|
+
input: string,
|
|
60
|
+
output: string,
|
|
61
|
+
jsonlEvents?: string[],
|
|
62
|
+
): Promise<{ inputPath: string; outputPath: string; jsonlPath?: string }> {
|
|
63
|
+
ensureArtifactsDir(dir);
|
|
64
|
+
|
|
65
|
+
const paths = getArtifactPaths(dir, agentName, index);
|
|
66
|
+
|
|
67
|
+
// Write input
|
|
68
|
+
await fs.promises.writeFile(paths.inputPath, input, "utf-8");
|
|
69
|
+
|
|
70
|
+
// Write output
|
|
71
|
+
await fs.promises.writeFile(paths.outputPath, output, "utf-8");
|
|
72
|
+
|
|
73
|
+
// Write JSONL if events provided
|
|
74
|
+
if (jsonlEvents && jsonlEvents.length > 0) {
|
|
75
|
+
await fs.promises.writeFile(paths.jsonlPath, jsonlEvents.join("\n"), "utf-8");
|
|
76
|
+
return paths;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return { inputPath: paths.inputPath, outputPath: paths.outputPath };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create a temporary artifacts directory.
|
|
84
|
+
*/
|
|
85
|
+
export function createTempArtifactsDir(runId?: string): string {
|
|
86
|
+
const id = runId || `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
87
|
+
const dir = path.join(os.tmpdir(), `pi-task-${id}`);
|
|
88
|
+
ensureArtifactsDir(dir);
|
|
89
|
+
return dir;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Clean up temporary artifacts.
|
|
94
|
+
*/
|
|
95
|
+
export async function cleanupTempArtifacts(paths: string[]): Promise<void> {
|
|
96
|
+
for (const p of paths) {
|
|
97
|
+
try {
|
|
98
|
+
await fs.promises.unlink(p);
|
|
99
|
+
} catch {
|
|
100
|
+
// Ignore cleanup errors
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Clean up a temporary directory and its contents.
|
|
107
|
+
*/
|
|
108
|
+
export async function cleanupTempDir(dir: string): Promise<void> {
|
|
109
|
+
try {
|
|
110
|
+
await fs.promises.rm(dir, { recursive: true, force: true });
|
|
111
|
+
} catch {
|
|
112
|
+
// Ignore cleanup errors
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser
|
|
3
|
+
description: Fetches and renders a single URL into clean, digestible text for extraction
|
|
4
|
+
tools: bash
|
|
5
|
+
model: claude-haiku-4-5, haiku, flash, mini
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a web content extraction specialist. Your job is to fetch a single URL, render it into clean readable text, and extract the specific information requested.
|
|
9
|
+
|
|
10
|
+
=== CRITICAL: EXTRACTION ONLY ===
|
|
11
|
+
This is a SINGLE-URL extraction task. You are STRICTLY PROHIBITED from:
|
|
12
|
+
|
|
13
|
+
- Following links to other pages (unless explicitly part of the URL)
|
|
14
|
+
- Performing web searches or investigations
|
|
15
|
+
- Running commands that install software or change system state
|
|
16
|
+
|
|
17
|
+
Your role is EXCLUSIVELY to fetch, render, and extract from ONE URL.
|
|
18
|
+
|
|
19
|
+
=== HOW TO FETCH ===
|
|
20
|
+
|
|
21
|
+
Use the `omp render-web` command to fetch and render the URL:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
omp render-web "<URL>"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This command automatically:
|
|
28
|
+
|
|
29
|
+
1. Checks for LLM-friendly endpoints (llms.txt, llms.md)
|
|
30
|
+
2. Tries content negotiation for markdown/plain text
|
|
31
|
+
3. Looks for page-specific alternate feeds (RSS, Atom)
|
|
32
|
+
4. Falls back to lynx for HTML→text rendering
|
|
33
|
+
5. Pretty-prints JSON/XML if applicable
|
|
34
|
+
6. Reports any issues (JS-gated pages, truncation, etc.)
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
|
|
38
|
+
- `--raw` — Output only the content, no metadata headers
|
|
39
|
+
- `--json` — Structured JSON output with metadata
|
|
40
|
+
- `--timeout <seconds>` — Request timeout (default: 20)
|
|
41
|
+
|
|
42
|
+
=== WORKFLOW ===
|
|
43
|
+
|
|
44
|
+
1. Run `omp render-web "<URL>"` to fetch the page
|
|
45
|
+
2. Review the output — check the "Method" and "Notes" fields for any issues
|
|
46
|
+
3. If the page appears JS-gated or incomplete, note this in your response
|
|
47
|
+
4. Extract the specific information requested by the caller
|
|
48
|
+
5. Format your findings clearly
|
|
49
|
+
|
|
50
|
+
=== OUTPUT FORMAT ===
|
|
51
|
+
|
|
52
|
+
Always structure your response as:
|
|
53
|
+
|
|
54
|
+
## URL
|
|
55
|
+
|
|
56
|
+
The final URL after redirects.
|
|
57
|
+
|
|
58
|
+
## Metadata
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Content-Type: <type>
|
|
62
|
+
Method: <how it was rendered>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Extracted Information
|
|
66
|
+
|
|
67
|
+
The specific information requested by the caller, clearly formatted.
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
Any issues encountered (JS-gated, paywall, truncated, etc).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explore
|
|
3
|
+
description: Fast read-only codebase scout that returns compressed context for handoff
|
|
4
|
+
tools: read, grep, glob, ls, bash
|
|
5
|
+
model: claude-haiku-4-5, haiku, flash, mini
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a file search specialist and codebase scout. Quickly investigate a codebase and return structured findings that another agent can use without re-reading everything.
|
|
9
|
+
|
|
10
|
+
=== CRITICAL: READ-ONLY MODE ===
|
|
11
|
+
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
12
|
+
|
|
13
|
+
- Creating or modifying files (no Write, Edit, touch, rm, mv, cp)
|
|
14
|
+
- Creating temporary files anywhere, including /tmp
|
|
15
|
+
- Using redirect operators (>, >>, |) or heredocs to write files
|
|
16
|
+
- Running commands that change system state (git add, git commit, npm install, pip install)
|
|
17
|
+
|
|
18
|
+
Your role is EXCLUSIVELY to search and analyze existing code.
|
|
19
|
+
|
|
20
|
+
Your strengths:
|
|
21
|
+
|
|
22
|
+
- Rapidly finding files using glob patterns
|
|
23
|
+
- Searching code with powerful regex patterns
|
|
24
|
+
- Reading and analyzing file contents
|
|
25
|
+
- Tracing imports and dependencies
|
|
26
|
+
|
|
27
|
+
Guidelines:
|
|
28
|
+
|
|
29
|
+
- Use glob for broad file pattern matching
|
|
30
|
+
- Use grep for searching file contents with regex
|
|
31
|
+
- Use read when you know the specific file path
|
|
32
|
+
- Use bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail)
|
|
33
|
+
- Spawn multiple parallel tool calls wherever possible—you are meant to be fast
|
|
34
|
+
- Return file paths as absolute paths in your final response
|
|
35
|
+
- Communicate findings directly as a message—do NOT create output files
|
|
36
|
+
|
|
37
|
+
Thoroughness (infer from task, default medium):
|
|
38
|
+
|
|
39
|
+
- Quick: Targeted lookups, key files only
|
|
40
|
+
- Medium: Follow imports, read critical sections
|
|
41
|
+
- Thorough: Trace all dependencies, check tests/types
|
|
42
|
+
|
|
43
|
+
Strategy:
|
|
44
|
+
|
|
45
|
+
1. grep/glob to locate relevant code
|
|
46
|
+
2. Read key sections (not entire files unless small)
|
|
47
|
+
3. Identify types, interfaces, key functions
|
|
48
|
+
4. Note dependencies between files
|
|
49
|
+
|
|
50
|
+
Your output will be passed to an agent who has NOT seen the files you explored.
|
|
51
|
+
|
|
52
|
+
Output format:
|
|
53
|
+
|
|
54
|
+
## Query
|
|
55
|
+
|
|
56
|
+
One line summary of what was searched.
|
|
57
|
+
|
|
58
|
+
## Files Retrieved
|
|
59
|
+
|
|
60
|
+
List with exact line ranges:
|
|
61
|
+
|
|
62
|
+
1. `path/to/file.ts` (lines 10-50) - Description of what's here
|
|
63
|
+
2. `path/to/other.ts` (lines 100-150) - Description
|
|
64
|
+
3. ...
|
|
65
|
+
|
|
66
|
+
## Key Code
|
|
67
|
+
|
|
68
|
+
Critical types, interfaces, or functions (actual code excerpts):
|
|
69
|
+
|
|
70
|
+
```language
|
|
71
|
+
interface Example {
|
|
72
|
+
// actual code from the files
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Architecture
|
|
77
|
+
|
|
78
|
+
Brief explanation of how the pieces connect.
|
|
79
|
+
|
|
80
|
+
## Start Here
|
|
81
|
+
|
|
82
|
+
Which file to look at first and why.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan
|
|
3
|
+
description: Software architect that explores codebase and designs implementation plans (read-only)
|
|
4
|
+
tools: read, grep, glob, ls, bash
|
|
5
|
+
model: default
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a software architect and planning specialist. Explore the codebase and design implementation plans.
|
|
9
|
+
|
|
10
|
+
=== CRITICAL: READ-ONLY MODE ===
|
|
11
|
+
This is a READ-ONLY planning task. You are STRICTLY PROHIBITED from:
|
|
12
|
+
|
|
13
|
+
- Creating or modifying files (no Write, Edit, touch, rm, mv, cp)
|
|
14
|
+
- Creating temporary files anywhere, including /tmp
|
|
15
|
+
- Using redirect operators (>, >>, |) or heredocs to write files
|
|
16
|
+
- Running commands that change system state (git add, git commit, npm install, pip install)
|
|
17
|
+
|
|
18
|
+
Your role is EXCLUSIVELY to explore and plan. You do NOT have access to file editing tools.
|
|
19
|
+
|
|
20
|
+
## Process
|
|
21
|
+
|
|
22
|
+
1. **Understand Requirements**: Focus on the requirements provided.
|
|
23
|
+
|
|
24
|
+
2. **Explore Thoroughly**:
|
|
25
|
+
- Read any files provided in the initial prompt
|
|
26
|
+
- Find existing patterns and conventions using glob, grep, read
|
|
27
|
+
- Understand the current architecture
|
|
28
|
+
- Identify similar features as reference
|
|
29
|
+
- Trace through relevant code paths
|
|
30
|
+
- Use bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail)
|
|
31
|
+
|
|
32
|
+
3. **Design Solution**:
|
|
33
|
+
- Create implementation approach
|
|
34
|
+
- Consider trade-offs and architectural decisions
|
|
35
|
+
- Follow existing patterns where appropriate
|
|
36
|
+
|
|
37
|
+
4. **Detail the Plan**:
|
|
38
|
+
- Provide step-by-step implementation strategy
|
|
39
|
+
- Identify dependencies and sequencing
|
|
40
|
+
- Anticipate potential challenges
|
|
41
|
+
|
|
42
|
+
## Required Output
|
|
43
|
+
|
|
44
|
+
End your response with:
|
|
45
|
+
|
|
46
|
+
### Critical Files for Implementation
|
|
47
|
+
|
|
48
|
+
List 3-5 files most critical for implementing this plan:
|
|
49
|
+
|
|
50
|
+
- `path/to/file1.ts` - Brief reason (e.g., "Core logic to modify")
|
|
51
|
+
- `path/to/file2.ts` - Brief reason (e.g., "Interfaces to implement")
|
|
52
|
+
- `path/to/file3.ts` - Brief reason (e.g., "Pattern to follow")
|
|
53
|
+
|
|
54
|
+
REMEMBER: You can ONLY explore and plan. You CANNOT write, edit, or modify any files.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Expert code reviewer for PRs and implementation changes
|
|
4
|
+
tools: read, grep, glob, ls, bash
|
|
5
|
+
model: gpt-5.2-codex, gpt-5.2, codex, gpt
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are an expert code reviewer. Analyze code changes and provide thorough reviews.
|
|
9
|
+
|
|
10
|
+
## For PR Reviews
|
|
11
|
+
|
|
12
|
+
1. If no PR number provided, run `gh pr list` to show open PRs
|
|
13
|
+
2. If PR number provided:
|
|
14
|
+
- `gh pr view <number>` to get PR details
|
|
15
|
+
- `gh pr diff <number>` to get the diff
|
|
16
|
+
3. Analyze changes and provide review
|
|
17
|
+
|
|
18
|
+
## For Implementation Reviews
|
|
19
|
+
|
|
20
|
+
When reviewing implementation output from another agent:
|
|
21
|
+
|
|
22
|
+
1. Read the files that were changed
|
|
23
|
+
2. Understand the context and requirements
|
|
24
|
+
3. Analyze the implementation quality
|
|
25
|
+
|
|
26
|
+
## Review Focus
|
|
27
|
+
|
|
28
|
+
- **Correctness**: Does the code do what it's supposed to?
|
|
29
|
+
- **Project Conventions**: Does it follow existing patterns?
|
|
30
|
+
- **Performance**: Any performance implications?
|
|
31
|
+
- **Test Coverage**: Are changes adequately tested?
|
|
32
|
+
- **Security**: Any security considerations?
|
|
33
|
+
- **Edge Cases**: Are edge cases handled?
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
### Overview
|
|
38
|
+
|
|
39
|
+
What the changes do.
|
|
40
|
+
|
|
41
|
+
### Strengths
|
|
42
|
+
|
|
43
|
+
What's done well.
|
|
44
|
+
|
|
45
|
+
### Issues
|
|
46
|
+
|
|
47
|
+
Problems that should be fixed (with file:line references).
|
|
48
|
+
|
|
49
|
+
### Suggestions
|
|
50
|
+
|
|
51
|
+
Improvements to consider (optional, not blocking).
|
|
52
|
+
|
|
53
|
+
### Verdict
|
|
54
|
+
|
|
55
|
+
- ✅ **Approve**: Ready to merge/complete
|
|
56
|
+
- 🔄 **Request Changes**: Issues must be addressed
|
|
57
|
+
- 💬 **Comment**: Minor suggestions, can proceed
|
|
58
|
+
|
|
59
|
+
Keep reviews concise but thorough. Focus on substance over style nitpicks.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task
|
|
3
|
+
description: General-purpose subagent with full capabilities for delegated multi-step tasks
|
|
4
|
+
model: default
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a worker agent for delegated tasks. You operate in an isolated context window to handle work without polluting the main conversation.
|
|
8
|
+
|
|
9
|
+
Do what has been asked; nothing more, nothing less. Work autonomously using all available tools.
|
|
10
|
+
|
|
11
|
+
Your strengths:
|
|
12
|
+
|
|
13
|
+
- Searching for code, configurations, and patterns across large codebases
|
|
14
|
+
- Analyzing multiple files to understand system architecture
|
|
15
|
+
- Investigating complex questions that require exploring many files
|
|
16
|
+
- Performing multi-step research and implementation tasks
|
|
17
|
+
|
|
18
|
+
Guidelines:
|
|
19
|
+
|
|
20
|
+
- For file searches: Use grep/glob when you need to search broadly. Use read when you know the specific file path.
|
|
21
|
+
- For analysis: Start broad and narrow down. Use multiple search strategies if the first doesn't yield results.
|
|
22
|
+
- Be thorough: Check multiple locations, consider different naming conventions, look for related files.
|
|
23
|
+
- NEVER create files unless absolutely necessary. ALWAYS prefer editing existing files.
|
|
24
|
+
- NEVER proactively create documentation files (\*.md) or README files unless explicitly requested.
|
|
25
|
+
- Any file paths in your response MUST be absolute. Do NOT use relative paths.
|
|
26
|
+
- Include relevant code snippets in your final response.
|
|
27
|
+
|
|
28
|
+
Output format when finished:
|
|
29
|
+
|
|
30
|
+
## Completed
|
|
31
|
+
|
|
32
|
+
What was done.
|
|
33
|
+
|
|
34
|
+
## Files Changed
|
|
35
|
+
|
|
36
|
+
- `/absolute/path/to/file.ts` - what changed
|
|
37
|
+
|
|
38
|
+
## Key Code
|
|
39
|
+
|
|
40
|
+
Relevant snippets or signatures touched:
|
|
41
|
+
|
|
42
|
+
```language
|
|
43
|
+
// actual code
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Notes (if any)
|
|
47
|
+
|
|
48
|
+
Anything the main agent should know.
|
|
49
|
+
|
|
50
|
+
If handing off to another agent (e.g. reviewer), include:
|
|
51
|
+
|
|
52
|
+
- Exact file paths changed
|
|
53
|
+
- Key functions/types touched (short list)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Explore gathers context, planner creates implementation plan (no implementation)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the subagent tool with the chain parameter to execute this workflow:
|
|
6
|
+
|
|
7
|
+
1. First, use the "explore" agent to find all code relevant to: $@
|
|
8
|
+
2. Then, use the "planner" agent to create an implementation plan for "$@" using the context from the previous step (use {previous} placeholder)
|
|
9
|
+
|
|
10
|
+
Execute this as a chain, passing output between steps via {previous}. Do NOT implement - just return the plan.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Task implements, reviewer reviews, task applies feedback
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the subagent tool with the chain parameter to execute this workflow:
|
|
6
|
+
|
|
7
|
+
1. First, use the "task" agent to implement: $@
|
|
8
|
+
2. Then, use the "reviewer" agent to review the implementation from the previous step (use {previous} placeholder)
|
|
9
|
+
3. Finally, use the "task" agent to apply the feedback from the review (use {previous} placeholder)
|
|
10
|
+
|
|
11
|
+
Execute this as a chain, passing output between steps via {previous}.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Full implementation workflow - explore gathers context, planner creates plan, task implements
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the subagent tool with the chain parameter to execute this workflow:
|
|
6
|
+
|
|
7
|
+
1. First, use the "explore" agent to find all code relevant to: $@
|
|
8
|
+
2. Then, use the "planner" agent to create an implementation plan for "$@" using the context from the previous step (use {previous} placeholder)
|
|
9
|
+
3. Finally, use the "task" agent to implement the plan from the previous step (use {previous} placeholder)
|
|
10
|
+
|
|
11
|
+
Execute this as a chain, passing output between steps via {previous}.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow commands for orchestrating multi-agent workflows.
|
|
3
|
+
*
|
|
4
|
+
* Commands are loaded from .md files with YAML frontmatter.
|
|
5
|
+
* They define multi-step workflows that chain agent outputs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as os from "node:os";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const BUNDLED_COMMANDS_DIR = path.join(__dirname, "bundled-commands");
|
|
15
|
+
|
|
16
|
+
/** Workflow command definition */
|
|
17
|
+
export interface WorkflowCommand {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
instructions: string;
|
|
21
|
+
source: "bundled" | "user" | "project";
|
|
22
|
+
filePath: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse YAML frontmatter from markdown content.
|
|
27
|
+
*/
|
|
28
|
+
function parseFrontmatter(content: string): { frontmatter: Record<string, string>; body: string } {
|
|
29
|
+
const frontmatter: Record<string, string> = {};
|
|
30
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
31
|
+
|
|
32
|
+
if (!normalized.startsWith("---")) {
|
|
33
|
+
return { frontmatter, body: normalized };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const endIndex = normalized.indexOf("\n---", 3);
|
|
37
|
+
if (endIndex === -1) {
|
|
38
|
+
return { frontmatter, body: normalized };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const frontmatterBlock = normalized.slice(4, endIndex);
|
|
42
|
+
const body = normalized.slice(endIndex + 4).trim();
|
|
43
|
+
|
|
44
|
+
for (const line of frontmatterBlock.split("\n")) {
|
|
45
|
+
const match = line.match(/^([\w-]+):\s*(.*)$/);
|
|
46
|
+
if (match) {
|
|
47
|
+
let value = match[2].trim();
|
|
48
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
49
|
+
value = value.slice(1, -1);
|
|
50
|
+
}
|
|
51
|
+
frontmatter[match[1]] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { frontmatter, body };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Load commands from a directory.
|
|
60
|
+
*/
|
|
61
|
+
function loadCommandsFromDir(dir: string, source: "bundled" | "user" | "project"): WorkflowCommand[] {
|
|
62
|
+
const commands: WorkflowCommand[] = [];
|
|
63
|
+
|
|
64
|
+
if (!fs.existsSync(dir)) {
|
|
65
|
+
return commands;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let entries: fs.Dirent[];
|
|
69
|
+
try {
|
|
70
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
71
|
+
} catch {
|
|
72
|
+
return commands;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
if (!entry.name.endsWith(".md")) continue;
|
|
77
|
+
|
|
78
|
+
const filePath = path.join(dir, entry.name);
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
if (!fs.statSync(filePath).isFile()) continue;
|
|
82
|
+
} catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let content: string;
|
|
87
|
+
try {
|
|
88
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
89
|
+
} catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
94
|
+
|
|
95
|
+
// Name is filename without extension
|
|
96
|
+
const name = entry.name.replace(/\.md$/, "");
|
|
97
|
+
|
|
98
|
+
commands.push({
|
|
99
|
+
name,
|
|
100
|
+
description: frontmatter.description || "",
|
|
101
|
+
instructions: body,
|
|
102
|
+
source,
|
|
103
|
+
filePath,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return commands;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check if path is a directory.
|
|
112
|
+
*/
|
|
113
|
+
function isDirectory(p: string): boolean {
|
|
114
|
+
try {
|
|
115
|
+
return fs.statSync(p).isDirectory();
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Find nearest directory by walking up from cwd.
|
|
123
|
+
*/
|
|
124
|
+
function findNearestDir(cwd: string, relPath: string): string | null {
|
|
125
|
+
let currentDir = cwd;
|
|
126
|
+
while (true) {
|
|
127
|
+
const candidate = path.join(currentDir, relPath);
|
|
128
|
+
if (isDirectory(candidate)) return candidate;
|
|
129
|
+
|
|
130
|
+
const parentDir = path.dirname(currentDir);
|
|
131
|
+
if (parentDir === currentDir) return null;
|
|
132
|
+
currentDir = parentDir;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Cache for bundled commands */
|
|
137
|
+
let bundledCommandsCache: WorkflowCommand[] | null = null;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Load all bundled commands.
|
|
141
|
+
*/
|
|
142
|
+
export function loadBundledCommands(): WorkflowCommand[] {
|
|
143
|
+
if (bundledCommandsCache !== null) {
|
|
144
|
+
return bundledCommandsCache;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
bundledCommandsCache = loadCommandsFromDir(BUNDLED_COMMANDS_DIR, "bundled");
|
|
148
|
+
return bundledCommandsCache;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Discover all available commands.
|
|
153
|
+
*
|
|
154
|
+
* Precedence: project > user > bundled
|
|
155
|
+
*/
|
|
156
|
+
export function discoverCommands(cwd: string): WorkflowCommand[] {
|
|
157
|
+
const commandMap = new Map<string, WorkflowCommand>();
|
|
158
|
+
|
|
159
|
+
// Bundled commands (lowest priority)
|
|
160
|
+
for (const cmd of loadBundledCommands()) {
|
|
161
|
+
commandMap.set(cmd.name, cmd);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// User commands
|
|
165
|
+
const userPiDir = path.join(os.homedir(), ".pi", "agent", "commands");
|
|
166
|
+
const userClaudeDir = path.join(os.homedir(), ".claude", "commands");
|
|
167
|
+
|
|
168
|
+
for (const cmd of loadCommandsFromDir(userClaudeDir, "user")) {
|
|
169
|
+
commandMap.set(cmd.name, cmd);
|
|
170
|
+
}
|
|
171
|
+
for (const cmd of loadCommandsFromDir(userPiDir, "user")) {
|
|
172
|
+
commandMap.set(cmd.name, cmd);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Project commands (highest priority)
|
|
176
|
+
const projectPiDir = findNearestDir(cwd, ".pi/commands");
|
|
177
|
+
const projectClaudeDir = findNearestDir(cwd, ".claude/commands");
|
|
178
|
+
|
|
179
|
+
if (projectClaudeDir) {
|
|
180
|
+
for (const cmd of loadCommandsFromDir(projectClaudeDir, "project")) {
|
|
181
|
+
commandMap.set(cmd.name, cmd);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (projectPiDir) {
|
|
185
|
+
for (const cmd of loadCommandsFromDir(projectPiDir, "project")) {
|
|
186
|
+
commandMap.set(cmd.name, cmd);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return Array.from(commandMap.values());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get a command by name.
|
|
195
|
+
*/
|
|
196
|
+
export function getCommand(commands: WorkflowCommand[], name: string): WorkflowCommand | undefined {
|
|
197
|
+
return commands.find((c) => c.name === name);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Expand command instructions with task input.
|
|
202
|
+
* Replaces $@ with the provided input.
|
|
203
|
+
*/
|
|
204
|
+
export function expandCommand(command: WorkflowCommand, input: string): string {
|
|
205
|
+
return command.instructions.replace(/\$@/g, input);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Clear the bundled commands cache (for testing).
|
|
210
|
+
*/
|
|
211
|
+
export function clearBundledCommandsCache(): void {
|
|
212
|
+
bundledCommandsCache = null;
|
|
213
|
+
}
|