@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.
Files changed (224) hide show
  1. package/CHANGELOG.md +1228 -0
  2. package/README.md +1041 -0
  3. package/docs/compaction.md +403 -0
  4. package/docs/custom-tools.md +541 -0
  5. package/docs/extension-loading.md +1004 -0
  6. package/docs/hooks.md +867 -0
  7. package/docs/rpc.md +1040 -0
  8. package/docs/sdk.md +994 -0
  9. package/docs/session-tree-plan.md +441 -0
  10. package/docs/session.md +240 -0
  11. package/docs/skills.md +290 -0
  12. package/docs/theme.md +637 -0
  13. package/docs/tree.md +197 -0
  14. package/docs/tui.md +341 -0
  15. package/examples/README.md +21 -0
  16. package/examples/custom-tools/README.md +124 -0
  17. package/examples/custom-tools/hello/index.ts +20 -0
  18. package/examples/custom-tools/question/index.ts +84 -0
  19. package/examples/custom-tools/subagent/README.md +172 -0
  20. package/examples/custom-tools/subagent/agents/planner.md +37 -0
  21. package/examples/custom-tools/subagent/agents/reviewer.md +35 -0
  22. package/examples/custom-tools/subagent/agents/scout.md +50 -0
  23. package/examples/custom-tools/subagent/agents/worker.md +24 -0
  24. package/examples/custom-tools/subagent/agents.ts +156 -0
  25. package/examples/custom-tools/subagent/commands/implement-and-review.md +10 -0
  26. package/examples/custom-tools/subagent/commands/implement.md +10 -0
  27. package/examples/custom-tools/subagent/commands/scout-and-plan.md +9 -0
  28. package/examples/custom-tools/subagent/index.ts +1002 -0
  29. package/examples/custom-tools/todo/index.ts +212 -0
  30. package/examples/hooks/README.md +56 -0
  31. package/examples/hooks/auto-commit-on-exit.ts +49 -0
  32. package/examples/hooks/confirm-destructive.ts +59 -0
  33. package/examples/hooks/custom-compaction.ts +116 -0
  34. package/examples/hooks/dirty-repo-guard.ts +52 -0
  35. package/examples/hooks/file-trigger.ts +41 -0
  36. package/examples/hooks/git-checkpoint.ts +53 -0
  37. package/examples/hooks/handoff.ts +150 -0
  38. package/examples/hooks/permission-gate.ts +34 -0
  39. package/examples/hooks/protected-paths.ts +30 -0
  40. package/examples/hooks/qna.ts +119 -0
  41. package/examples/hooks/snake.ts +343 -0
  42. package/examples/hooks/status-line.ts +40 -0
  43. package/examples/sdk/01-minimal.ts +22 -0
  44. package/examples/sdk/02-custom-model.ts +49 -0
  45. package/examples/sdk/03-custom-prompt.ts +44 -0
  46. package/examples/sdk/04-skills.ts +44 -0
  47. package/examples/sdk/05-tools.ts +90 -0
  48. package/examples/sdk/06-hooks.ts +61 -0
  49. package/examples/sdk/07-context-files.ts +36 -0
  50. package/examples/sdk/08-slash-commands.ts +42 -0
  51. package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
  52. package/examples/sdk/10-settings.ts +38 -0
  53. package/examples/sdk/11-sessions.ts +48 -0
  54. package/examples/sdk/12-full-control.ts +95 -0
  55. package/examples/sdk/README.md +154 -0
  56. package/package.json +81 -0
  57. package/src/cli/args.ts +246 -0
  58. package/src/cli/file-processor.ts +72 -0
  59. package/src/cli/list-models.ts +104 -0
  60. package/src/cli/plugin-cli.ts +650 -0
  61. package/src/cli/session-picker.ts +41 -0
  62. package/src/cli.ts +10 -0
  63. package/src/commands/init.md +20 -0
  64. package/src/config.ts +159 -0
  65. package/src/core/agent-session.ts +1900 -0
  66. package/src/core/auth-storage.ts +236 -0
  67. package/src/core/bash-executor.ts +196 -0
  68. package/src/core/compaction/branch-summarization.ts +343 -0
  69. package/src/core/compaction/compaction.ts +742 -0
  70. package/src/core/compaction/index.ts +7 -0
  71. package/src/core/compaction/utils.ts +154 -0
  72. package/src/core/custom-tools/index.ts +21 -0
  73. package/src/core/custom-tools/loader.ts +248 -0
  74. package/src/core/custom-tools/types.ts +169 -0
  75. package/src/core/custom-tools/wrapper.ts +28 -0
  76. package/src/core/exec.ts +129 -0
  77. package/src/core/export-html/index.ts +211 -0
  78. package/src/core/export-html/template.css +781 -0
  79. package/src/core/export-html/template.html +54 -0
  80. package/src/core/export-html/template.js +1185 -0
  81. package/src/core/export-html/vendor/highlight.min.js +1213 -0
  82. package/src/core/export-html/vendor/marked.min.js +6 -0
  83. package/src/core/hooks/index.ts +16 -0
  84. package/src/core/hooks/loader.ts +312 -0
  85. package/src/core/hooks/runner.ts +434 -0
  86. package/src/core/hooks/tool-wrapper.ts +99 -0
  87. package/src/core/hooks/types.ts +773 -0
  88. package/src/core/index.ts +52 -0
  89. package/src/core/mcp/client.ts +158 -0
  90. package/src/core/mcp/config.ts +154 -0
  91. package/src/core/mcp/index.ts +45 -0
  92. package/src/core/mcp/loader.ts +68 -0
  93. package/src/core/mcp/manager.ts +181 -0
  94. package/src/core/mcp/tool-bridge.ts +148 -0
  95. package/src/core/mcp/transports/http.ts +316 -0
  96. package/src/core/mcp/transports/index.ts +6 -0
  97. package/src/core/mcp/transports/stdio.ts +252 -0
  98. package/src/core/mcp/types.ts +220 -0
  99. package/src/core/messages.ts +189 -0
  100. package/src/core/model-registry.ts +317 -0
  101. package/src/core/model-resolver.ts +393 -0
  102. package/src/core/plugins/doctor.ts +59 -0
  103. package/src/core/plugins/index.ts +38 -0
  104. package/src/core/plugins/installer.ts +189 -0
  105. package/src/core/plugins/loader.ts +338 -0
  106. package/src/core/plugins/manager.ts +672 -0
  107. package/src/core/plugins/parser.ts +105 -0
  108. package/src/core/plugins/paths.ts +32 -0
  109. package/src/core/plugins/types.ts +190 -0
  110. package/src/core/sdk.ts +760 -0
  111. package/src/core/session-manager.ts +1128 -0
  112. package/src/core/settings-manager.ts +443 -0
  113. package/src/core/skills.ts +437 -0
  114. package/src/core/slash-commands.ts +248 -0
  115. package/src/core/system-prompt.ts +439 -0
  116. package/src/core/timings.ts +25 -0
  117. package/src/core/tools/ask.ts +211 -0
  118. package/src/core/tools/bash-interceptor.ts +120 -0
  119. package/src/core/tools/bash.ts +250 -0
  120. package/src/core/tools/context.ts +32 -0
  121. package/src/core/tools/edit-diff.ts +475 -0
  122. package/src/core/tools/edit.ts +208 -0
  123. package/src/core/tools/exa/company.ts +59 -0
  124. package/src/core/tools/exa/index.ts +64 -0
  125. package/src/core/tools/exa/linkedin.ts +59 -0
  126. package/src/core/tools/exa/logger.ts +56 -0
  127. package/src/core/tools/exa/mcp-client.ts +368 -0
  128. package/src/core/tools/exa/render.ts +196 -0
  129. package/src/core/tools/exa/researcher.ts +90 -0
  130. package/src/core/tools/exa/search.ts +337 -0
  131. package/src/core/tools/exa/types.ts +168 -0
  132. package/src/core/tools/exa/websets.ts +248 -0
  133. package/src/core/tools/find.ts +261 -0
  134. package/src/core/tools/grep.ts +555 -0
  135. package/src/core/tools/index.ts +202 -0
  136. package/src/core/tools/ls.ts +140 -0
  137. package/src/core/tools/lsp/client.ts +605 -0
  138. package/src/core/tools/lsp/config.ts +147 -0
  139. package/src/core/tools/lsp/edits.ts +101 -0
  140. package/src/core/tools/lsp/index.ts +804 -0
  141. package/src/core/tools/lsp/render.ts +447 -0
  142. package/src/core/tools/lsp/rust-analyzer.ts +145 -0
  143. package/src/core/tools/lsp/types.ts +463 -0
  144. package/src/core/tools/lsp/utils.ts +486 -0
  145. package/src/core/tools/notebook.ts +229 -0
  146. package/src/core/tools/path-utils.ts +61 -0
  147. package/src/core/tools/read.ts +240 -0
  148. package/src/core/tools/renderers.ts +540 -0
  149. package/src/core/tools/task/agents.ts +153 -0
  150. package/src/core/tools/task/artifacts.ts +114 -0
  151. package/src/core/tools/task/bundled-agents/browser.md +71 -0
  152. package/src/core/tools/task/bundled-agents/explore.md +82 -0
  153. package/src/core/tools/task/bundled-agents/plan.md +54 -0
  154. package/src/core/tools/task/bundled-agents/reviewer.md +59 -0
  155. package/src/core/tools/task/bundled-agents/task.md +53 -0
  156. package/src/core/tools/task/bundled-commands/architect-plan.md +10 -0
  157. package/src/core/tools/task/bundled-commands/implement-with-critic.md +11 -0
  158. package/src/core/tools/task/bundled-commands/implement.md +11 -0
  159. package/src/core/tools/task/commands.ts +213 -0
  160. package/src/core/tools/task/discovery.ts +208 -0
  161. package/src/core/tools/task/executor.ts +367 -0
  162. package/src/core/tools/task/index.ts +388 -0
  163. package/src/core/tools/task/model-resolver.ts +115 -0
  164. package/src/core/tools/task/parallel.ts +38 -0
  165. package/src/core/tools/task/render.ts +232 -0
  166. package/src/core/tools/task/types.ts +99 -0
  167. package/src/core/tools/truncate.ts +265 -0
  168. package/src/core/tools/web-fetch.ts +2370 -0
  169. package/src/core/tools/web-search/auth.ts +193 -0
  170. package/src/core/tools/web-search/index.ts +537 -0
  171. package/src/core/tools/web-search/providers/anthropic.ts +198 -0
  172. package/src/core/tools/web-search/providers/exa.ts +302 -0
  173. package/src/core/tools/web-search/providers/perplexity.ts +195 -0
  174. package/src/core/tools/web-search/render.ts +182 -0
  175. package/src/core/tools/web-search/types.ts +180 -0
  176. package/src/core/tools/write.ts +99 -0
  177. package/src/index.ts +176 -0
  178. package/src/main.ts +464 -0
  179. package/src/migrations.ts +135 -0
  180. package/src/modes/index.ts +43 -0
  181. package/src/modes/interactive/components/armin.ts +382 -0
  182. package/src/modes/interactive/components/assistant-message.ts +86 -0
  183. package/src/modes/interactive/components/bash-execution.ts +196 -0
  184. package/src/modes/interactive/components/bordered-loader.ts +41 -0
  185. package/src/modes/interactive/components/branch-summary-message.ts +42 -0
  186. package/src/modes/interactive/components/compaction-summary-message.ts +45 -0
  187. package/src/modes/interactive/components/custom-editor.ts +122 -0
  188. package/src/modes/interactive/components/diff.ts +147 -0
  189. package/src/modes/interactive/components/dynamic-border.ts +25 -0
  190. package/src/modes/interactive/components/footer.ts +381 -0
  191. package/src/modes/interactive/components/hook-editor.ts +117 -0
  192. package/src/modes/interactive/components/hook-input.ts +64 -0
  193. package/src/modes/interactive/components/hook-message.ts +96 -0
  194. package/src/modes/interactive/components/hook-selector.ts +91 -0
  195. package/src/modes/interactive/components/model-selector.ts +247 -0
  196. package/src/modes/interactive/components/oauth-selector.ts +120 -0
  197. package/src/modes/interactive/components/plugin-settings.ts +479 -0
  198. package/src/modes/interactive/components/queue-mode-selector.ts +56 -0
  199. package/src/modes/interactive/components/session-selector.ts +204 -0
  200. package/src/modes/interactive/components/settings-selector.ts +453 -0
  201. package/src/modes/interactive/components/show-images-selector.ts +45 -0
  202. package/src/modes/interactive/components/theme-selector.ts +62 -0
  203. package/src/modes/interactive/components/thinking-selector.ts +64 -0
  204. package/src/modes/interactive/components/tool-execution.ts +675 -0
  205. package/src/modes/interactive/components/tree-selector.ts +866 -0
  206. package/src/modes/interactive/components/user-message-selector.ts +159 -0
  207. package/src/modes/interactive/components/user-message.ts +18 -0
  208. package/src/modes/interactive/components/visual-truncate.ts +50 -0
  209. package/src/modes/interactive/components/welcome.ts +183 -0
  210. package/src/modes/interactive/interactive-mode.ts +2516 -0
  211. package/src/modes/interactive/theme/dark.json +101 -0
  212. package/src/modes/interactive/theme/light.json +98 -0
  213. package/src/modes/interactive/theme/theme-schema.json +308 -0
  214. package/src/modes/interactive/theme/theme.ts +998 -0
  215. package/src/modes/print-mode.ts +128 -0
  216. package/src/modes/rpc/rpc-client.ts +527 -0
  217. package/src/modes/rpc/rpc-mode.ts +483 -0
  218. package/src/modes/rpc/rpc-types.ts +203 -0
  219. package/src/utils/changelog.ts +99 -0
  220. package/src/utils/clipboard.ts +265 -0
  221. package/src/utils/fuzzy.ts +108 -0
  222. package/src/utils/mime.ts +30 -0
  223. package/src/utils/shell.ts +276 -0
  224. 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
+ }