@oh-my-pi/pi-coding-agent 4.1.0 → 4.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +2 -1
  3. package/docs/sdk.md +0 -3
  4. package/package.json +6 -5
  5. package/src/config.ts +9 -0
  6. package/src/core/agent-session.ts +3 -3
  7. package/src/core/agent-storage.ts +450 -0
  8. package/src/core/auth-storage.ts +102 -183
  9. package/src/core/compaction/branch-summarization.ts +5 -4
  10. package/src/core/compaction/compaction.ts +7 -6
  11. package/src/core/compaction/utils.ts +6 -11
  12. package/src/core/custom-commands/bundled/review/index.ts +22 -94
  13. package/src/core/custom-share.ts +66 -0
  14. package/src/core/export-html/index.ts +1 -33
  15. package/src/core/history-storage.ts +15 -7
  16. package/src/core/prompt-templates.ts +271 -1
  17. package/src/core/sdk.ts +14 -3
  18. package/src/core/settings-manager.ts +100 -34
  19. package/src/core/slash-commands.ts +4 -1
  20. package/src/core/storage-migration.ts +215 -0
  21. package/src/core/system-prompt.ts +130 -290
  22. package/src/core/title-generator.ts +3 -2
  23. package/src/core/tools/ask.ts +2 -2
  24. package/src/core/tools/bash.ts +2 -1
  25. package/src/core/tools/calculator.ts +2 -1
  26. package/src/core/tools/complete.ts +5 -2
  27. package/src/core/tools/edit.ts +2 -1
  28. package/src/core/tools/find.ts +2 -1
  29. package/src/core/tools/gemini-image.ts +2 -1
  30. package/src/core/tools/git.ts +2 -2
  31. package/src/core/tools/grep.ts +2 -1
  32. package/src/core/tools/index.test.ts +0 -28
  33. package/src/core/tools/index.ts +0 -6
  34. package/src/core/tools/lsp/index.ts +2 -1
  35. package/src/core/tools/output.ts +2 -1
  36. package/src/core/tools/read.ts +4 -1
  37. package/src/core/tools/ssh.ts +4 -2
  38. package/src/core/tools/task/agents.ts +56 -30
  39. package/src/core/tools/task/commands.ts +5 -8
  40. package/src/core/tools/task/index.ts +7 -15
  41. package/src/core/tools/web-fetch.ts +2 -1
  42. package/src/core/tools/web-search/auth.ts +106 -16
  43. package/src/core/tools/web-search/index.ts +3 -2
  44. package/src/core/tools/web-search/providers/anthropic.ts +44 -6
  45. package/src/core/tools/write.ts +2 -1
  46. package/src/core/voice.ts +3 -1
  47. package/src/discovery/builtin.ts +9 -54
  48. package/src/discovery/claude.ts +16 -69
  49. package/src/discovery/codex.ts +11 -36
  50. package/src/discovery/helpers.ts +52 -1
  51. package/src/main.ts +1 -1
  52. package/src/migrations.ts +20 -20
  53. package/src/modes/interactive/controllers/command-controller.ts +527 -0
  54. package/src/modes/interactive/controllers/event-controller.ts +340 -0
  55. package/src/modes/interactive/controllers/extension-ui-controller.ts +600 -0
  56. package/src/modes/interactive/controllers/input-controller.ts +585 -0
  57. package/src/modes/interactive/controllers/selector-controller.ts +585 -0
  58. package/src/modes/interactive/interactive-mode.ts +363 -3139
  59. package/src/modes/interactive/theme/theme.ts +5 -5
  60. package/src/modes/interactive/types.ts +189 -0
  61. package/src/modes/interactive/utils/ui-helpers.ts +449 -0
  62. package/src/modes/interactive/utils/voice-manager.ts +96 -0
  63. package/src/prompts/{explore.md → agents/explore.md} +7 -5
  64. package/src/prompts/agents/frontmatter.md +7 -0
  65. package/src/prompts/{plan.md → agents/plan.md} +3 -3
  66. package/src/prompts/agents/planner.md +112 -0
  67. package/src/prompts/agents/task.md +15 -0
  68. package/src/prompts/review-request.md +44 -8
  69. package/src/prompts/system/custom-system-prompt.md +80 -0
  70. package/src/prompts/system/file-operations.md +12 -0
  71. package/src/prompts/system/system-prompt.md +237 -0
  72. package/src/prompts/system/title-system.md +2 -0
  73. package/src/prompts/tools/bash.md +1 -1
  74. package/src/prompts/tools/read.md +1 -1
  75. package/src/prompts/tools/task.md +34 -22
  76. package/src/core/tools/rulebook.ts +0 -132
  77. package/src/prompts/architect-plan.md +0 -10
  78. package/src/prompts/implement-with-critic.md +0 -11
  79. package/src/prompts/implement.md +0 -11
  80. package/src/prompts/system-prompt.md +0 -43
  81. package/src/prompts/task.md +0 -14
  82. package/src/prompts/title-system.md +0 -8
  83. /package/src/prompts/{init.md → agents/init.md} +0 -0
  84. /package/src/prompts/{reviewer.md → agents/reviewer.md} +0 -0
  85. /package/src/prompts/{branch-summary-preamble.md → compaction/branch-summary-preamble.md} +0 -0
  86. /package/src/prompts/{branch-summary.md → compaction/branch-summary.md} +0 -0
  87. /package/src/prompts/{compaction-summary.md → compaction/compaction-summary.md} +0 -0
  88. /package/src/prompts/{compaction-turn-prefix.md → compaction/compaction-turn-prefix.md} +0 -0
  89. /package/src/prompts/{compaction-update-summary.md → compaction/compaction-update-summary.md} +0 -0
  90. /package/src/prompts/{summarization-system.md → system/summarization-system.md} +0 -0
@@ -0,0 +1,96 @@
1
+ import type { InteractiveModeContext } from "../types";
2
+
3
+ const VOICE_PROGRESS_DELAY_MS = 15000;
4
+ const VOICE_PROGRESS_MIN_CHARS = 160;
5
+ const VOICE_PROGRESS_DELTA_CHARS = 120;
6
+
7
+ export class VoiceManager {
8
+ constructor(private ctx: InteractiveModeContext) {}
9
+
10
+ setVoiceStatus(text: string | undefined): void {
11
+ this.ctx.statusLine.setHookStatus("voice", text);
12
+ this.ctx.ui.requestRender();
13
+ }
14
+
15
+ async handleVoiceInterrupt(reason?: string): Promise<void> {
16
+ const now = Date.now();
17
+ if (now - this.ctx.lastVoiceInterruptAt < 200) return;
18
+ this.ctx.lastVoiceInterruptAt = now;
19
+ if (this.ctx.session.isBashRunning) {
20
+ this.ctx.session.abortBash();
21
+ }
22
+ if (this.ctx.session.isStreaming) {
23
+ await this.ctx.session.abort();
24
+ }
25
+ if (reason) {
26
+ this.ctx.showStatus(reason);
27
+ }
28
+ }
29
+
30
+ stopVoiceProgressTimer(): void {
31
+ if (this.ctx.voiceProgressTimer) {
32
+ clearTimeout(this.ctx.voiceProgressTimer);
33
+ this.ctx.voiceProgressTimer = undefined;
34
+ }
35
+ }
36
+
37
+ startVoiceProgressTimer(): void {
38
+ this.stopVoiceProgressTimer();
39
+ if (!this.ctx.settingsManager.getVoiceEnabled() || !this.ctx.voiceAutoModeEnabled) return;
40
+ this.ctx.voiceProgressSpoken = false;
41
+ this.ctx.voiceProgressLastLength = 0;
42
+ this.ctx.voiceProgressTimer = setTimeout(() => {
43
+ void this.maybeSpeakProgress();
44
+ }, VOICE_PROGRESS_DELAY_MS);
45
+ }
46
+
47
+ async maybeSpeakProgress(): Promise<void> {
48
+ if (!this.ctx.session.isStreaming || this.ctx.voiceProgressSpoken || !this.ctx.voiceAutoModeEnabled) return;
49
+ const streaming = this.ctx.streamingMessage;
50
+ if (!streaming) return;
51
+ const text = this.ctx.extractAssistantText(streaming);
52
+ if (!text || text.length < VOICE_PROGRESS_MIN_CHARS) {
53
+ if (this.ctx.session.isStreaming) {
54
+ this.ctx.voiceProgressTimer = setTimeout(() => {
55
+ void this.maybeSpeakProgress();
56
+ }, VOICE_PROGRESS_DELAY_MS);
57
+ }
58
+ return;
59
+ }
60
+
61
+ const delta = text.length - this.ctx.voiceProgressLastLength;
62
+ if (delta < VOICE_PROGRESS_DELTA_CHARS) {
63
+ if (this.ctx.session.isStreaming) {
64
+ this.ctx.voiceProgressTimer = setTimeout(() => {
65
+ void this.maybeSpeakProgress();
66
+ }, VOICE_PROGRESS_DELAY_MS);
67
+ }
68
+ return;
69
+ }
70
+
71
+ this.ctx.voiceProgressLastLength = text.length;
72
+ this.ctx.voiceProgressSpoken = true;
73
+ this.ctx.voiceSupervisor.notifyProgress(text);
74
+ }
75
+
76
+ async submitVoiceText(text: string): Promise<void> {
77
+ const cleaned = text.trim();
78
+ if (!cleaned) {
79
+ this.ctx.showWarning("No speech detected. Try again.");
80
+ return;
81
+ }
82
+ const toSend = cleaned;
83
+ this.ctx.editor.addToHistory(toSend);
84
+
85
+ if (this.ctx.session.isStreaming) {
86
+ await this.ctx.session.abort();
87
+ await this.ctx.session.steer(toSend);
88
+ this.ctx.updatePendingMessagesDisplay();
89
+ return;
90
+ }
91
+
92
+ if (this.ctx.onInputCallback) {
93
+ this.ctx.onInputCallback({ text: toSend });
94
+ }
95
+ }
96
+ }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: explore
3
3
  description: Fast read-only codebase scout that returns compressed context for handoff
4
- tools: read, grep, glob, ls, bash
4
+ tools: read, grep, find, ls, bash
5
5
  model: pi/smol, haiku, flash, mini
6
6
  ---
7
7
 
@@ -19,17 +19,17 @@ Your role is EXCLUSIVELY to search and analyze existing code.
19
19
 
20
20
  Your strengths:
21
21
 
22
- - Rapidly finding files using glob patterns
22
+ - Rapidly finding files using find (glob) patterns
23
23
  - Searching code with powerful regex patterns
24
24
  - Reading and analyzing file contents
25
25
  - Tracing imports and dependencies
26
26
 
27
27
  Guidelines:
28
28
 
29
- - Use glob for broad file pattern matching
29
+ - Use find for broad file pattern matching
30
30
  - Use grep for searching file contents with regex
31
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)
32
+ - Use bash ONLY for git status/log/diff; use read/grep/find/ls tools for file and search operations
33
33
  - Spawn multiple parallel tool calls wherever possible—you are meant to be fast
34
34
  - Return file paths as absolute paths in your final response
35
35
  - Communicate findings directly as a message—do NOT create output files
@@ -42,7 +42,7 @@ Thoroughness (infer from task, default medium):
42
42
 
43
43
  Strategy:
44
44
 
45
- 1. grep/glob to locate relevant code
45
+ 1. grep/find to locate relevant code
46
46
  2. Read key sections (not entire files unless small)
47
47
  3. Identify types, interfaces, key functions
48
48
  4. Note dependencies between files
@@ -80,3 +80,5 @@ Brief explanation of how the pieces connect.
80
80
  ## Start Here
81
81
 
82
82
  Which file to look at first and why.
83
+
84
+ REMEMBER: Read-only; no file modifications.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: {{name}}
3
+ description: {{description}}
4
+ {{#if spawns}}spawns: {{spawns}}
5
+ {{/if}}{{#if model}}model: {{model}}
6
+ {{/if}}---
7
+ {{body}}
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: plan
3
3
  description: Software architect that explores codebase and designs implementation plans (read-only)
4
- tools: read, grep, glob, ls, bash
4
+ tools: read, grep, find, ls, bash
5
5
  model: default
6
6
  ---
7
7
 
@@ -23,11 +23,11 @@ Your role is EXCLUSIVELY to explore and plan. You do NOT have access to file edi
23
23
 
24
24
  2. **Explore Thoroughly**:
25
25
  - Read any files provided in the initial prompt
26
- - Find existing patterns and conventions using glob, grep, read
26
+ - Find existing patterns and conventions using find, grep, read
27
27
  - Understand the current architecture
28
28
  - Identify similar features as reference
29
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)
30
+ - Use bash ONLY for git status/log/diff; use read/grep/find/ls tools for file and search operations
31
31
 
32
32
  3. **Design Solution**:
33
33
  - Create implementation approach
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: planner
3
+ description: Software architect that explores codebase and produces detailed implementation plans
4
+ tools: read, grep, find, ls, bash
5
+ spawns: explore
6
+ model: pi/slow, gpt-5.2-codex, gpt-5.2, codex, gpt
7
+ ---
8
+
9
+ <role>Senior software architect producing implementation plans. READ-ONLY — no file modifications, no state changes.</role>
10
+
11
+ <context>
12
+ Another engineer will execute your plan without re-exploring the codebase. Your plan must be specific enough to implement directly.
13
+ </context>
14
+
15
+ <process>
16
+ ## Phase 1: Understand
17
+
18
+ 1. Parse the task requirements precisely
19
+ 2. Identify ambiguities — list assumptions you're making
20
+ 3. Spawn parallel `explore` agents if the task spans multiple areas
21
+
22
+ ## Phase 2: Explore
23
+
24
+ Investigate thoroughly before designing:
25
+
26
+ 1. Find existing patterns via grep/find
27
+ 2. Read key files to understand current architecture
28
+ 3. Trace data flow through relevant code paths
29
+ 4. Identify types, interfaces, and contracts involved
30
+ 5. Note dependencies between components
31
+
32
+ Spawn `explore` agents for independent search areas. Synthesize findings.
33
+
34
+ ## Phase 3: Design
35
+
36
+ Create implementation approach:
37
+
38
+ 1. List concrete changes required (files, functions, types)
39
+ 2. Define the sequence — what depends on what
40
+ 3. Identify edge cases and error conditions
41
+ 4. Consider alternatives; justify your choice
42
+ 5. Note potential pitfalls or tricky parts
43
+
44
+ ## Phase 4: Produce Plan
45
+
46
+ Write a plan another engineer can execute without re-exploring the codebase.
47
+ </process>
48
+
49
+ <example>
50
+ ## Summary
51
+ What we're building and why (one paragraph).
52
+
53
+ ## Changes
54
+ 1. **`path/to/file.ts`** — What to change
55
+ - Specific modifications
56
+ 2. **`path/to/other.ts`** — ...
57
+
58
+ ## Sequence
59
+ 1. X (no dependencies)
60
+ 2. Y (depends on X)
61
+ 3. Z (integration)
62
+
63
+ ## Edge Cases
64
+ - Case: How to handle
65
+
66
+ ## Verification
67
+ - [ ] Test command or check
68
+ - [ ] Expected behavior
69
+
70
+ ## Critical Files
71
+ - `path/to/file.ts` (lines 50-120) — Why to read
72
+ </example>
73
+
74
+ <example>
75
+ ## Summary
76
+ Add rate limiting to the API gateway to prevent abuse. Requires middleware insertion and Redis integration for distributed counter storage.
77
+
78
+ ## Changes
79
+ 1. **`src/middleware/rate-limit.ts`** — New file
80
+ - Create `RateLimitMiddleware` class using sliding window algorithm
81
+ - Accept `maxRequests`, `windowMs`, `keyGenerator` options
82
+ 2. **`src/gateway/index.ts`** — Wire middleware
83
+ - Import and register before auth middleware (line 45)
84
+ 3. **`src/config/redis.ts`** — Add rate limit key prefix
85
+ - Add `RATE_LIMIT_PREFIX` constant
86
+
87
+ ## Sequence
88
+ 1. `rate-limit.ts` (standalone, no deps)
89
+ 2. `redis.ts` (config only)
90
+ 3. `gateway/index.ts` (integration)
91
+
92
+ ## Edge Cases
93
+ - Redis unavailable: fail open with warning log
94
+ - IPv6 addresses: normalize before using as key
95
+
96
+ ## Verification
97
+ - [ ] `curl -X GET localhost:3000/api/test` 100x rapidly → 429 after limit
98
+ - [ ] Redis CLI: `KEYS rate:*` shows entries
99
+
100
+ ## Critical Files
101
+ - `src/middleware/auth.ts` (lines 20-50) — Pattern to follow
102
+ - `src/types/middleware.ts` — Interface to implement
103
+ </example>
104
+
105
+ <requirements>
106
+ - Plan must be specific enough to implement without additional exploration
107
+ - Include exact file paths and line ranges where relevant
108
+ - Sequence must respect dependencies
109
+ - Verification must be concrete and testable
110
+ </requirements>
111
+
112
+ Keep going until complete. This matters — get it right.
@@ -0,0 +1,15 @@
1
+ You are a worker agent for delegated tasks. You have FULL access to all tools (edit, write, bash, grep, read, etc.) - use them as needed to complete your task.
2
+
3
+ Finish only the assigned work and return the minimum useful result.
4
+
5
+ Principles:
6
+
7
+ - You CAN and SHOULD make file edits, run commands, and create files when your task requires it.
8
+ - Be concise. No filler, repetition, or tool transcripts.
9
+ - Prefer narrow search (grep/find) then read only needed ranges.
10
+ - Avoid full-file reads unless necessary.
11
+ - Prefer edits to existing files over creating new ones.
12
+ - NEVER create documentation files (\*.md) unless explicitly requested.
13
+ - When spawning subagents with the Task tool, include a 5-8 word user-facing description.
14
+ - Include the smallest relevant code snippet when discussing code or config.
15
+ - Follow the main agent's instructions.
@@ -1,27 +1,63 @@
1
1
  ## Code Review Request
2
2
 
3
3
  ### Mode
4
- {MODE}
4
+ {{mode}}
5
5
 
6
- ### Changed Files ({FILE_COUNT} files, +{LINES_ADDED}/-{LINES_REMOVED} lines)
6
+ ### Changed Files ({{len files}} files, +{{totalAdded}}/-{{totalRemoved}} lines)
7
7
 
8
- {FILE_TABLE}
8
+ {{#if files.length}}
9
+ {{#table files headers="File|+/-|Type"}}
10
+ {{path}} | +{{linesAdded}}/-{{linesRemoved}} | {{ext}}
11
+ {{/table}}
12
+ {{else}}
13
+ _No files to review._
14
+ {{/if}}
9
15
 
10
- {EXCLUDED_SECTION}
16
+ {{#if excluded.length}}
17
+ ### Excluded Files ({{len excluded}})
18
+
19
+ {{#list excluded prefix="- " join="\n"}}
20
+ `{{path}}` (+{{linesAdded}}/-{{linesRemoved}}) — {{reason}}
21
+ {{/list}}
22
+ {{/if}}
11
23
 
12
24
  ### Distribution Guidelines
13
25
 
14
- {DISTRIBUTION_GUIDANCE}
26
+ Based on the diff weight (~{{totalLines}} lines across {{len files}} files), {{#when agentCount "==" 1}}use **1 reviewer agent**.{{else}}spawn **{{agentCount}} reviewer agents** in parallel.{{/when}}
27
+
28
+ {{#if multiAgent}}
29
+ Group files by locality (related changes together). For example:
30
+ - Files in the same directory or module → same agent
31
+ - Files that implement related functionality → same agent
32
+ - Test files with their implementation files → same agent
15
33
 
16
- {GROUPING_GUIDANCE}
34
+ Use the Task tool with `agent: "reviewer"` and the batch `tasks` array to run reviews in parallel.
35
+ {{/if}}
17
36
 
18
37
  ### Reviewer Instructions
19
38
 
20
39
  Each reviewer agent should:
21
40
  1. Focus ONLY on its assigned files
22
- 2. {DIFF_INSTRUCTION}
41
+ 2. {{#if skipDiff}}Run `git diff` or `git show` to get the diff for assigned files{{else}}Use the diff hunks provided below (don't re-run git diff){{/if}}
23
42
  3. Read full file context as needed via the `read` tool
24
43
  4. Call `report_finding` for each issue found
25
44
  5. Call `complete` with verdict when done
26
45
 
27
- {DIFF_SECTION}
46
+ {{#if skipDiff}}
47
+ ### Diff Previews
48
+
49
+ _Full diff too large ({{len files}} files). Showing first ~{{linesPerFile}} lines per file. Reviewers should fetch full diffs for assigned files._
50
+
51
+ {{#list files join="\n\n"}}
52
+ #### {{path}}
53
+ {{#codeblock lang="diff"}}
54
+ {{hunksPreview}}
55
+ {{/codeblock}}
56
+ {{/list}}
57
+ {{else}}
58
+ ### Diff
59
+
60
+ <diff>
61
+ {{rawDiff}}
62
+ </diff>
63
+ {{/if}}
@@ -0,0 +1,80 @@
1
+ {{#if systemPromptCustomization}}
2
+ {{systemPromptCustomization}}
3
+
4
+ {{/if}}
5
+ {{customPrompt}}
6
+ {{#if appendPrompt}}
7
+
8
+ {{appendPrompt}}
9
+ {{/if}}
10
+ {{#if contextFiles.length}}
11
+
12
+ # Project Context
13
+
14
+ <project_context_files>
15
+ {{#list contextFiles join="\n"}}
16
+ <file path="{{path}}">
17
+ {{content}}
18
+ </file>
19
+ {{/list}}
20
+ </project_context_files>
21
+ {{/if}}
22
+ {{#if toolDescriptions.length}}
23
+
24
+ # Tools
25
+
26
+ {{#list toolDescriptions prefix="- " join="\n"}}{{name}}: {{description}}{{/list}}
27
+ {{/if}}
28
+ {{#if git.isRepo}}
29
+
30
+ # Git Status
31
+
32
+ This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.
33
+ Current branch: {{git.currentBranch}}
34
+ Main branch: {{git.mainBranch}}
35
+
36
+ Status:
37
+ {{git.status}}
38
+
39
+ Recent commits:
40
+ {{git.commits}}
41
+ {{/if}}
42
+ {{#if skills.length}}
43
+
44
+ The following skills provide specialized instructions for specific tasks.
45
+ Use the read tool to load a skill's file when the task matches its description.
46
+
47
+ <available_skills>
48
+ {{#list skills join="\n"}}
49
+ <skill>
50
+ <name>{{escapeXml name}}</name>
51
+ <description>{{escapeXml description}}</description>
52
+ <location>{{escapeXml filePath}}</location>
53
+ </skill>
54
+ {{/list}}
55
+ </available_skills>
56
+ {{/if}}
57
+ {{#if rules.length}}
58
+
59
+ The following rules define project-specific guidelines and constraints:
60
+
61
+ <rules>
62
+ {{#list rules join="\n"}}
63
+ <rule>
64
+ <name>{{escapeXml name}}</name>
65
+ <description>{{escapeXml description}}</description>
66
+ {{#if globs.length}}
67
+ <globs>
68
+ {{#list globs join="\n"}}
69
+ <glob>{{escapeXml this}}</glob>
70
+ {{/list}}
71
+ </globs>
72
+ {{/if}}
73
+ <location>{{escapeXml path}}</location>
74
+ </rule>
75
+ {{/list}}
76
+ </rules>
77
+ {{/if}}
78
+
79
+ Current date and time: {{dateTime}}
80
+ Current working directory: {{cwd}}
@@ -0,0 +1,12 @@
1
+ {{#if readFiles.length}}
2
+
3
+ {{#xml "read-files"}}
4
+ {{join readFiles "\n"}}
5
+ {{/xml}}
6
+ {{/if}}
7
+ {{#if modifiedFiles.length}}
8
+
9
+ {{#xml "modified-files"}}
10
+ {{join modifiedFiles "\n"}}
11
+ {{/xml}}
12
+ {{/if}}