@dyyz1993/pi-coding-agent 0.74.24 → 0.74.27

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 (157) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +3 -0
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/session-manager.d.ts +5 -0
  6. package/dist/core/session-manager.d.ts.map +1 -1
  7. package/dist/core/session-manager.js +8 -0
  8. package/dist/core/session-manager.js.map +1 -1
  9. package/dist/extensions/agent-permissions/index.ts +235 -0
  10. package/dist/extensions/ask-tools/index.ts +115 -0
  11. package/dist/extensions/auto-memory/contract.d.ts +51 -0
  12. package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
  13. package/dist/extensions/auto-memory/contract.js +2 -0
  14. package/dist/extensions/auto-memory/contract.js.map +1 -0
  15. package/dist/extensions/auto-memory/contract.ts +56 -0
  16. package/dist/extensions/auto-memory/index.ts +969 -0
  17. package/dist/extensions/auto-memory/prompts.ts +202 -0
  18. package/dist/extensions/auto-memory/skip-rules.ts +297 -0
  19. package/dist/extensions/auto-memory/utils.ts +208 -0
  20. package/dist/extensions/auto-session-title/index.ts +83 -0
  21. package/dist/extensions/bash-ext/contract.d.ts +79 -0
  22. package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
  23. package/dist/extensions/bash-ext/contract.js +2 -0
  24. package/dist/extensions/bash-ext/contract.js.map +1 -0
  25. package/dist/extensions/bash-ext/contract.ts +69 -0
  26. package/dist/extensions/bash-ext/index.ts +858 -0
  27. package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
  28. package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
  29. package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
  30. package/dist/extensions/claude-hooks-compat/index.ts +178 -0
  31. package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
  32. package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
  33. package/dist/extensions/claude-hooks-compat/types.ts +77 -0
  34. package/dist/extensions/compaction-manager/config.ts +47 -0
  35. package/dist/extensions/compaction-manager/context-fold.ts +63 -0
  36. package/dist/extensions/compaction-manager/index.ts +151 -0
  37. package/dist/extensions/compaction-manager/microcompact.ts +49 -0
  38. package/dist/extensions/compaction-manager/reactive.ts +9 -0
  39. package/dist/extensions/compaction-manager/session-memory.ts +48 -0
  40. package/dist/extensions/coordinator/INTEGRATION.md +376 -0
  41. package/dist/extensions/coordinator/handler.test.ts +277 -0
  42. package/dist/extensions/coordinator/handler.ts +189 -0
  43. package/dist/extensions/coordinator/index.ts +261 -0
  44. package/dist/extensions/coordinator/types.d.ts +100 -0
  45. package/dist/extensions/coordinator/types.d.ts.map +1 -0
  46. package/dist/extensions/coordinator/types.js +2 -0
  47. package/dist/extensions/coordinator/types.js.map +1 -0
  48. package/dist/extensions/coordinator/types.ts +72 -0
  49. package/dist/extensions/file-snapshot/index.ts +131 -0
  50. package/dist/extensions/file-time-guard/README.md +133 -0
  51. package/dist/extensions/file-time-guard/config.ts +13 -0
  52. package/dist/extensions/file-time-guard/index.ts +171 -0
  53. package/dist/extensions/hooks-engine/index.ts +117 -0
  54. package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
  55. package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
  56. package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
  57. package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
  58. package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
  59. package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
  60. package/dist/extensions/lsp/lsp/contract.js +2 -0
  61. package/dist/extensions/lsp/lsp/contract.js.map +1 -0
  62. package/dist/extensions/lsp/lsp/contract.ts +103 -0
  63. package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
  64. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
  65. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
  66. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
  67. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
  68. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
  69. package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
  70. package/dist/extensions/lsp/lsp/index.ts +310 -0
  71. package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
  72. package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
  73. package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
  74. package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
  75. package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
  76. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
  77. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
  78. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
  79. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
  80. package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
  81. package/dist/extensions/message-bridge/GUIDE.md +210 -0
  82. package/dist/extensions/message-bridge/index.ts +222 -0
  83. package/dist/extensions/output-guard/index.ts +446 -0
  84. package/dist/extensions/preview/index.ts +278 -0
  85. package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
  86. package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
  87. package/dist/extensions/rules-engine/cache.js +232 -0
  88. package/dist/extensions/rules-engine/cache.ts +38 -0
  89. package/dist/extensions/rules-engine/config.js +63 -0
  90. package/dist/extensions/rules-engine/config.ts +70 -0
  91. package/dist/extensions/rules-engine/index.js +1530 -0
  92. package/dist/extensions/rules-engine/index.ts +552 -0
  93. package/dist/extensions/rules-engine/injector.js +68 -0
  94. package/dist/extensions/rules-engine/injector.ts +74 -0
  95. package/dist/extensions/rules-engine/loader.js +179 -0
  96. package/dist/extensions/rules-engine/loader.ts +205 -0
  97. package/dist/extensions/rules-engine/matcher.js +534 -0
  98. package/dist/extensions/rules-engine/matcher.ts +52 -0
  99. package/dist/extensions/rules-engine/types.d.ts +156 -0
  100. package/dist/extensions/rules-engine/types.d.ts.map +1 -0
  101. package/dist/extensions/rules-engine/types.js +2 -0
  102. package/dist/extensions/rules-engine/types.js.map +1 -0
  103. package/dist/extensions/rules-engine/types.ts +169 -0
  104. package/dist/extensions/session-supervisor/checker.ts +116 -0
  105. package/dist/extensions/session-supervisor/config.ts +45 -0
  106. package/dist/extensions/session-supervisor/index.ts +726 -0
  107. package/dist/extensions/session-supervisor/prompts.ts +132 -0
  108. package/dist/extensions/session-supervisor/scheduler.ts +69 -0
  109. package/dist/extensions/session-supervisor/types.ts +215 -0
  110. package/dist/extensions/subagent/README.md +172 -0
  111. package/dist/extensions/subagent/agents/explorer.md +25 -0
  112. package/dist/extensions/subagent/agents/guide.md +27 -0
  113. package/dist/extensions/subagent/agents/planner.md +37 -0
  114. package/dist/extensions/subagent/agents/reviewer.md +35 -0
  115. package/dist/extensions/subagent/agents/scout.md +50 -0
  116. package/dist/extensions/subagent/agents/verification.md +35 -0
  117. package/dist/extensions/subagent/agents/worker.md +24 -0
  118. package/dist/extensions/subagent/agents.ts +25 -0
  119. package/dist/extensions/subagent/index.ts +987 -0
  120. package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
  121. package/dist/extensions/subagent/prompts/implement.md +10 -0
  122. package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
  123. package/dist/extensions/subagent-ext/contract.d.ts +2 -0
  124. package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
  125. package/dist/extensions/subagent-ext/contract.js +2 -0
  126. package/dist/extensions/subagent-ext/contract.js.map +1 -0
  127. package/dist/extensions/subagent-ext/contract.ts +1 -0
  128. package/dist/extensions/subagent-ext/index.ts +347 -0
  129. package/dist/extensions/subagent-shared/contract.d.ts +25 -0
  130. package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
  131. package/dist/extensions/subagent-shared/contract.js +2 -0
  132. package/dist/extensions/subagent-shared/contract.js.map +1 -0
  133. package/dist/extensions/subagent-shared/contract.ts +28 -0
  134. package/dist/extensions/subagent-shared/index.ts +4 -0
  135. package/dist/extensions/subagent-shared/render.ts +166 -0
  136. package/dist/extensions/subagent-shared/types.ts +35 -0
  137. package/dist/extensions/subagent-shared/utils.ts +112 -0
  138. package/dist/extensions/subagent-v2/contract.d.ts +2 -0
  139. package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
  140. package/dist/extensions/subagent-v2/contract.js +2 -0
  141. package/dist/extensions/subagent-v2/contract.js.map +1 -0
  142. package/dist/extensions/subagent-v2/contract.ts +1 -0
  143. package/dist/extensions/subagent-v2/index.ts +599 -0
  144. package/dist/extensions/todo-ext/contract.d.ts +27 -0
  145. package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
  146. package/dist/extensions/todo-ext/contract.js +2 -0
  147. package/dist/extensions/todo-ext/contract.js.map +1 -0
  148. package/dist/extensions/todo-ext/contract.ts +30 -0
  149. package/dist/extensions/todo-ext/index.ts +419 -0
  150. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  151. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  152. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  153. package/examples/extensions/sandbox/package-lock.json +2 -2
  154. package/examples/extensions/sandbox/package.json +1 -1
  155. package/examples/extensions/with-deps/package-lock.json +2 -2
  156. package/examples/extensions/with-deps/package.json +1 -1
  157. package/package.json +6 -5
@@ -0,0 +1,132 @@
1
+ export const COMPLETION_CHECK_SYSTEM_PROMPT = `You are a session completion checker. Your job is to determine if a coding agent session has truly completed all tasks or if there are remaining incomplete tasks.
2
+
3
+ Analyze the conversation history and determine:
4
+
5
+ 1. **completed**: Whether all requested tasks have been finished
6
+ 2. **confidence**: Your confidence level (0-1)
7
+ 3. **incompleteTasks**: List any tasks that appear incomplete, with severity:
8
+ - "high": Critical unfinished task (e.g., build errors, test failures, incomplete code changes)
9
+ - "medium": Important but non-blocking (e.g., documentation pending, minor refactoring)
10
+ - "low": Nice-to-have (e.g., optimization opportunities, style improvements)
11
+ 4. **reasoning**: Brief explanation of your assessment
12
+
13
+ IMPORTANT:
14
+ - A task is incomplete only if the user explicitly requested it and it hasn't been done
15
+ - If the agent mentioned it would do something but hasn't done it yet, mark it incomplete
16
+ - If there are running background processes (CI, builds, tests), mark them as incomplete
17
+ - If the agent asked a question and hasn't received an answer, mark it incomplete
18
+ - If all tasks are done and the agent is just summarizing, mark as completed
19
+
20
+ You MUST respond with valid JSON only, no markdown.`;
21
+
22
+ // ── Generic continue prompt ──
23
+
24
+ export const CONTINUE_PROMPT = (reason: string, tasks: string[]) =>
25
+ `[Supervisor] Session may not be fully complete.
26
+
27
+ Reason: ${reason}
28
+
29
+ Remaining items:
30
+ ${tasks.map((t, i) => `${i + 1}. ${t}`).join("\n")}
31
+
32
+ Please continue working on the remaining items. Do not repeat work that has already been completed.`;
33
+
34
+ // ── Guard-specific prompt generators ──
35
+
36
+ export const TODO_GUARD_PROMPT = (remainingTodos: string[]) =>
37
+ `[Supervisor/TodoGuard] The following todo items are not yet completed:
38
+
39
+ ${remainingTodos.map((t, i) => `${i + 1}. ${t}`).join("\n")}
40
+
41
+ Please continue working on these items. Complete each one before moving on.`;
42
+
43
+ export const SPECS_GUARD_PROMPT = (
44
+ specsFile: string,
45
+ completedItems: string[],
46
+ remainingItems: string[],
47
+ progress: string,
48
+ ) =>
49
+ `[Supervisor/SpecsGuard] Specs progress report (${specsFile}):
50
+
51
+ Progress: ${progress}
52
+
53
+ Completed items:
54
+ ${completedItems.length > 0 ? completedItems.map((t, i) => ` ✓ ${t}`).join("\n") : " (none yet)"}
55
+
56
+ Remaining items:
57
+ ${remainingItems.map((t, i) => ` ○ ${t}`).join("\n")}
58
+
59
+ IMPORTANT: You MUST continue working on the remaining items. Do NOT declare completion until ALL items are done.
60
+ Do not skip any item. Work through them one by one.`;
61
+
62
+ export const SPECS_GUARD_BLOCK_MESSAGE = (
63
+ remainingItems: string[],
64
+ attempt: number,
65
+ ) =>
66
+ `[Supervisor/SpecsGuard/BLOCKED] Agent attempted to declare completion, but ${remainingItems.length} items remain (attempt #${attempt}).
67
+
68
+ Remaining:
69
+ ${remainingItems.map((t, i) => ` ${i + 1}. ${t}`).join("\n")}
70
+
71
+ You MUST continue. Do not argue that the work is done — the specs file is the source of truth.`;
72
+
73
+ export const CI_GUARD_PROMPT = (status: string, command?: string) =>
74
+ `[Supervisor/CiGuard] CI check result: ${status}${command ? `\nCheck command: ${command}` : ""}
75
+
76
+ Please wait for CI to complete or fix any failures before declaring completion.`;
77
+
78
+ export const KEYWORD_GUARD_PROMPT = (foundKeywords: string[], context: string) =>
79
+ `[Supervisor/KeywordGuard] The following keywords indicate incomplete work: ${foundKeywords.join(", ")}
80
+
81
+ Context: ${context}
82
+
83
+ Please address these items before completing.`;
84
+
85
+ export const CUSTOM_GUARD_PROMPT = (template: string, context: Record<string, string>) => {
86
+ let result = template;
87
+ for (const [key, value] of Object.entries(context)) {
88
+ result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), value);
89
+ }
90
+ return result;
91
+ };
92
+
93
+ export const PAUSE_NOTIFICATION = (delayMs: number, reason?: string) =>
94
+ `[Supervisor] Session paused for ${Math.round(delayMs / 1000)}s${reason ? `: ${reason}` : ""}. Will auto-continue after delay.`;
95
+
96
+ // ── Guard check prompts (for model-based guards) ──
97
+
98
+ export const TODO_CHECK_PROMPT = (todosJson: string) =>
99
+ `You are checking if all todo items are completed. Here is the current todo list:
100
+
101
+ ${todosJson}
102
+
103
+ For each item, determine if it is completed or not. Respond with JSON:
104
+ {
105
+ "completed": boolean,
106
+ "confidence": number (0-1),
107
+ "remainingItems": string[],
108
+ "reasoning": string
109
+ }
110
+
111
+ You MUST respond with valid JSON only.`;
112
+
113
+ export const SPECS_CHECK_PROMPT = (specsContent: string, lastAssistantText: string) =>
114
+ `You are checking specs completion. Here is the specs file:
115
+
116
+ ${specsContent}
117
+
118
+ Here is the agent's last message:
119
+ ${lastAssistantText.slice(0, 2000)}
120
+
121
+ For each spec item, determine if it has been implemented. Respond with JSON:
122
+ {
123
+ "completed": boolean,
124
+ "confidence": number (0-1),
125
+ "completedItems": string[],
126
+ "remainingItems": string[],
127
+ "reasoning": string
128
+ }
129
+
130
+ IMPORTANT: An item is only "completed" if there is clear evidence in the conversation that it was implemented. If the agent merely mentions it will do something but hasn't done it yet, mark it as remaining.
131
+
132
+ You MUST respond with valid JSON only.`;
@@ -0,0 +1,69 @@
1
+ export class Scheduler {
2
+ private timers: Map<
3
+ string,
4
+ { timer: NodeJS.Timeout; abort: AbortController }
5
+ > = new Map();
6
+ private continueCount = 0;
7
+
8
+ constructor(
9
+ private maxContinueCount: number,
10
+ private pauseThresholdMs: number,
11
+ ) {}
12
+
13
+ scheduleContinue(
14
+ id: string,
15
+ delayMs: number,
16
+ callback: () => void,
17
+ ): { scheduled: boolean; scheduledAt?: number } {
18
+ if (this.continueCount >= this.maxContinueCount) {
19
+ return { scheduled: false };
20
+ }
21
+
22
+ this.cancelTimer(id);
23
+
24
+ const abort = new AbortController();
25
+ const scheduledAt = Date.now() + delayMs;
26
+
27
+ const timer = setTimeout(() => {
28
+ this.continueCount++;
29
+ this.timers.delete(id);
30
+ if (!abort.signal.aborted) {
31
+ callback();
32
+ }
33
+ }, delayMs);
34
+
35
+ this.timers.set(id, { timer, abort });
36
+ return { scheduled: true, scheduledAt };
37
+ }
38
+
39
+ cancelTimer(id: string): boolean {
40
+ const entry = this.timers.get(id);
41
+ if (!entry) return false;
42
+ clearTimeout(entry.timer);
43
+ entry.abort.abort();
44
+ this.timers.delete(id);
45
+ return true;
46
+ }
47
+
48
+ cancelAll(): void {
49
+ for (const [id] of this.timers) {
50
+ this.cancelTimer(id);
51
+ }
52
+ }
53
+
54
+ shouldPause(delayMs: number): boolean {
55
+ return delayMs >= this.pauseThresholdMs;
56
+ }
57
+
58
+ isExhausted(): boolean {
59
+ return this.continueCount >= this.maxContinueCount;
60
+ }
61
+
62
+ getContinueCount(): number {
63
+ return this.continueCount;
64
+ }
65
+
66
+ resetCount(): void {
67
+ this.continueCount = 0;
68
+ }
69
+ }
@@ -0,0 +1,215 @@
1
+ import type { ChannelContract } from "@dyyz1993/pi-coding-agent";
2
+ import { Type, type Static } from "@sinclair/typebox";
3
+
4
+ // ── Guard Configuration ──
5
+
6
+ export const BaseGuardConfigSchema = Type.Object({
7
+ /** Guard unique identifier */
8
+ name: Type.String(),
9
+ /** Enable/disable this specific guard */
10
+ enable: Type.Boolean({ default: true }),
11
+ });
12
+
13
+ export const TodoGuardConfigSchema = Type.Intersect([
14
+ BaseGuardConfigSchema,
15
+ Type.Object({
16
+ type: Type.Literal("todo"),
17
+ }),
18
+ ]);
19
+
20
+ export const SpecsGuardConfigSchema = Type.Intersect([
21
+ BaseGuardConfigSchema,
22
+ Type.Object({
23
+ type: Type.Literal("specs"),
24
+ /** Path to specs file, relative to project root */
25
+ specsFile: Type.String({ default: "specs.md" }),
26
+ /** Max iterations for specs guard (0 = infinite) */
27
+ maxIterations: Type.Integer({ default: 100 }),
28
+ }),
29
+ ]);
30
+
31
+ export const CiGuardConfigSchema = Type.Intersect([
32
+ BaseGuardConfigSchema,
33
+ Type.Object({
34
+ type: Type.Literal("ci"),
35
+ /** Command to check CI status */
36
+ checkCommand: Type.Optional(Type.String()),
37
+ /** Polling interval in ms */
38
+ pollIntervalMs: Type.Integer({ default: 30_000 }),
39
+ }),
40
+ ]);
41
+
42
+ export const KeywordGuardConfigSchema = Type.Intersect([
43
+ BaseGuardConfigSchema,
44
+ Type.Object({
45
+ type: Type.Literal("keyword"),
46
+ /** Keywords that indicate incomplete work */
47
+ keywords: Type.Array(Type.String()),
48
+ }),
49
+ ]);
50
+
51
+ export const CustomGuardConfigSchema = Type.Intersect([
52
+ BaseGuardConfigSchema,
53
+ Type.Object({
54
+ type: Type.Literal("custom"),
55
+ /** System prompt for the guard model */
56
+ checkPrompt: Type.String(),
57
+ /** Prompt template for generating continue message */
58
+ continuePromptTemplate: Type.Optional(Type.String()),
59
+ }),
60
+ ]);
61
+
62
+ export const GuardConfigSchema = Type.Union([
63
+ TodoGuardConfigSchema,
64
+ SpecsGuardConfigSchema,
65
+ CiGuardConfigSchema,
66
+ KeywordGuardConfigSchema,
67
+ CustomGuardConfigSchema,
68
+ ]);
69
+
70
+ export type GuardConfig = Static<typeof GuardConfigSchema>;
71
+
72
+ // ── Main Supervisor Config ──
73
+
74
+ export const SupervisorConfigSchema = Type.Object({
75
+ /** Master switch — default OFF */
76
+ enable: Type.Boolean({ default: false }),
77
+ /** Check when agent ends a turn */
78
+ checkOnAgentEnd: Type.Boolean({ default: true }),
79
+ /** Small model for guard checks */
80
+ smallModel: Type.String({ default: "fast" }),
81
+ /** Max auto-continue count (0 = infinite) */
82
+ maxContinueCount: Type.Integer({ default: 5 }),
83
+ /** Default delay before auto-continue */
84
+ defaultDelayMs: Type.Integer({ default: 30_000 }),
85
+ /** Delay threshold for pausing (vs immediate continue) */
86
+ pauseThresholdMs: Type.Integer({ default: 300_000 }),
87
+ /** Guard plugins */
88
+ guards: Type.Array(GuardConfigSchema, { default: [] }),
89
+ });
90
+
91
+ export type SupervisorConfig = Static<typeof SupervisorConfigSchema>;
92
+
93
+ // ── Guard Runtime Types ──
94
+
95
+ export interface GuardCheckResult {
96
+ /** This guard's name */
97
+ guardName: string;
98
+ /** Whether the guard thinks work is done */
99
+ completed: boolean;
100
+ /** Confidence 0-1 */
101
+ confidence: number;
102
+ /** Remaining items if not completed */
103
+ remainingItems: string[];
104
+ /** Optional detail message */
105
+ detail?: string;
106
+ }
107
+
108
+ export interface GuardContinueMessage {
109
+ /** The message to inject as supervisor continue */
110
+ content: string;
111
+ /** Whether this guard wants to block agent completion */
112
+ blockCompletion: boolean;
113
+ }
114
+
115
+ // ── Channel Contract ──
116
+
117
+ export interface SupervisorChannelContract extends ChannelContract {
118
+ methods: {
119
+ "supervisor.getStatus": {
120
+ params: Record<string, never>;
121
+ return: SupervisorStatus;
122
+ };
123
+ "supervisor.requestPause": {
124
+ params: { delayMs?: number; reason?: string };
125
+ return: { scheduled: boolean; scheduledAt?: number };
126
+ };
127
+ "supervisor.cancelPause": {
128
+ params: Record<string, never>;
129
+ return: { cancelled: boolean };
130
+ };
131
+ "supervisor.forceContinue": {
132
+ params: { reason?: string };
133
+ return: { triggered: boolean };
134
+ };
135
+ "supervisor.disable": {
136
+ params: Record<string, never>;
137
+ return: { disabled: boolean };
138
+ };
139
+ "supervisor.enable": {
140
+ params: Record<string, never>;
141
+ return: { enabled: boolean };
142
+ };
143
+ "supervisor.getTaskReport": {
144
+ params: Record<string, never>;
145
+ return: { tasks: TaskReport[] };
146
+ };
147
+ "supervisor.checkToolStatus": {
148
+ params: { toolName: string; channelName?: string; method?: string };
149
+ return: { reachable: boolean; status?: string; error?: string };
150
+ };
151
+ };
152
+ events: {
153
+ "supervisor.statusChanged": SupervisorStatus;
154
+ "supervisor.pauseRequested": { delayMs: number; reason?: string };
155
+ "supervisor.pauseCancelled": { reason: string };
156
+ "supervisor.continueTriggered": { reason: string; delayMs: number };
157
+ "supervisor.taskReport": { tasks: TaskReport[] };
158
+ };
159
+ }
160
+
161
+ // ── Status & Reporting ──
162
+
163
+ export interface SupervisorStatus {
164
+ enabled: boolean;
165
+ state: "idle" | "checking" | "paused" | "continuing" | "disabled";
166
+ continueCount: number;
167
+ maxContinueCount: number;
168
+ activeGuards: string[];
169
+ lastCheckResult?: CheckResult;
170
+ pendingPause?: { scheduledAt: number; delayMs: number; reason?: string };
171
+ }
172
+
173
+ export interface CheckResult {
174
+ completed: boolean;
175
+ confidence: number;
176
+ incompleteTasks: IncompleteTask[];
177
+ modelResponse?: string;
178
+ guardResults?: GuardCheckResult[];
179
+ }
180
+
181
+ export interface IncompleteTask {
182
+ ruleName: string;
183
+ description: string;
184
+ severity: "high" | "medium" | "low";
185
+ }
186
+
187
+ export interface TaskReport {
188
+ guardName: string;
189
+ guardType: string;
190
+ status: "completed" | "incomplete" | "unknown" | "error";
191
+ details?: string;
192
+ error?: string;
193
+ remainingItems?: string[];
194
+ }
195
+
196
+ // ── Structured LLM output ──
197
+
198
+ export const CompletionCheckSchema = Type.Object({
199
+ completed: Type.Boolean({ description: "会话是否已经真正完成" }),
200
+ confidence: Type.Number({ description: "置信度 0-1", minimum: 0, maximum: 1 }),
201
+ incompleteTasks: Type.Array(
202
+ Type.Object({
203
+ ruleName: Type.String(),
204
+ description: Type.String(),
205
+ severity: Type.Union([
206
+ Type.Literal("high"),
207
+ Type.Literal("medium"),
208
+ Type.Literal("low"),
209
+ ]),
210
+ }),
211
+ ),
212
+ reasoning: Type.String({ description: "判断理由" }),
213
+ });
214
+
215
+ export type CompletionCheckResult = Static<typeof CompletionCheckSchema>;
@@ -0,0 +1,172 @@
1
+ # Subagent Example
2
+
3
+ Delegate tasks to specialized subagents with isolated context windows.
4
+
5
+ ## Features
6
+
7
+ - **Isolated context**: Each subagent runs in a separate `pi` process
8
+ - **Streaming output**: See tool calls and progress as they happen
9
+ - **Parallel streaming**: All parallel tasks stream updates simultaneously
10
+ - **Markdown rendering**: Final output rendered with proper formatting (expanded view)
11
+ - **Usage tracking**: Shows turns, tokens, cost, and context usage per agent
12
+ - **Abort support**: Ctrl+C propagates to kill subagent processes
13
+
14
+ ## Structure
15
+
16
+ ```
17
+ subagent/
18
+ ├── README.md # This file
19
+ ├── index.ts # The extension (entry point)
20
+ ├── agents.ts # Agent discovery logic
21
+ ├── agents/ # Sample agent definitions
22
+ │ ├── scout.md # Fast recon, returns compressed context
23
+ │ ├── planner.md # Creates implementation plans
24
+ │ ├── reviewer.md # Code review
25
+ │ └── worker.md # General-purpose (full capabilities)
26
+ └── prompts/ # Workflow presets (prompt templates)
27
+ ├── implement.md # scout -> planner -> worker
28
+ ├── scout-and-plan.md # scout -> planner (no implementation)
29
+ └── implement-and-review.md # worker -> reviewer -> worker
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ From the repository root, symlink the files:
35
+
36
+ ```bash
37
+ # Symlink the extension (must be in a subdirectory with index.ts)
38
+ mkdir -p ~/.pi/agent/extensions/subagent
39
+ ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.pi/agent/extensions/subagent/index.ts
40
+ ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.pi/agent/extensions/subagent/agents.ts
41
+
42
+ # Symlink agents
43
+ mkdir -p ~/.pi/agent/agents
44
+ for f in packages/coding-agent/examples/extensions/subagent/agents/*.md; do
45
+ ln -sf "$(pwd)/$f" ~/.pi/agent/agents/$(basename "$f")
46
+ done
47
+
48
+ # Symlink workflow prompts
49
+ mkdir -p ~/.pi/agent/prompts
50
+ for f in packages/coding-agent/examples/extensions/subagent/prompts/*.md; do
51
+ ln -sf "$(pwd)/$f" ~/.pi/agent/prompts/$(basename "$f")
52
+ done
53
+ ```
54
+
55
+ ## Security Model
56
+
57
+ This tool executes a separate `pi` subprocess with a delegated system prompt and tool/model configuration.
58
+
59
+ **Project-local agents** (`.pi/agents/*.md`) are repo-controlled prompts that can instruct the model to read files, run bash commands, etc.
60
+
61
+ **Default behavior:** Only loads **user-level agents** from `~/.pi/agent/agents`.
62
+
63
+ To enable project-local agents, pass `agentScope: "both"` (or `"project"`). Only do this for repositories you trust.
64
+
65
+ When running interactively, the tool prompts for confirmation before running project-local agents. Set `confirmProjectAgents: false` to disable.
66
+
67
+ ## Usage
68
+
69
+ ### Single agent
70
+ ```
71
+ Use scout to find all authentication code
72
+ ```
73
+
74
+ ### Parallel execution
75
+ ```
76
+ Run 2 scouts in parallel: one to find models, one to find providers
77
+ ```
78
+
79
+ ### Chained workflow
80
+ ```
81
+ Use a chain: first have scout find the read tool, then have planner suggest improvements
82
+ ```
83
+
84
+ ### Workflow prompts
85
+ ```
86
+ /implement add Redis caching to the session store
87
+ /scout-and-plan refactor auth to support OAuth
88
+ /implement-and-review add input validation to API endpoints
89
+ ```
90
+
91
+ ## Tool Modes
92
+
93
+ | Mode | Parameter | Description |
94
+ |------|-----------|-------------|
95
+ | Single | `{ agent, task }` | One agent, one task |
96
+ | Parallel | `{ tasks: [...] }` | Multiple agents run concurrently (max 8, 4 concurrent) |
97
+ | Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder |
98
+
99
+ ## Output Display
100
+
101
+ **Collapsed view** (default):
102
+ - Status icon (✓/✗/⏳) and agent name
103
+ - Last 5-10 items (tool calls and text)
104
+ - Usage stats: `3 turns ↑input ↓output RcacheRead WcacheWrite $cost ctx:contextTokens model`
105
+
106
+ **Expanded view** (Ctrl+O):
107
+ - Full task text
108
+ - All tool calls with formatted arguments
109
+ - Final output rendered as Markdown
110
+ - Per-task usage (for chain/parallel)
111
+
112
+ **Parallel mode streaming**:
113
+ - Shows all tasks with live status (⏳ running, ✓ done, ✗ failed)
114
+ - Updates as each task makes progress
115
+ - Shows "2/3 done, 1 running" status
116
+
117
+ **Tool call formatting** (mimics built-in tools):
118
+ - `$ command` for bash
119
+ - `read ~/path:1-10` for read
120
+ - `grep /pattern/ in ~/path` for grep
121
+ - etc.
122
+
123
+ ## Agent Definitions
124
+
125
+ Agents are markdown files with YAML frontmatter:
126
+
127
+ ```markdown
128
+ ---
129
+ name: my-agent
130
+ description: What this agent does
131
+ tools: read, grep, find, ls
132
+ model: claude-haiku-4-5
133
+ ---
134
+
135
+ System prompt for the agent goes here.
136
+ ```
137
+
138
+ **Locations:**
139
+ - `~/.pi/agent/agents/*.md` - User-level (always loaded)
140
+ - `.pi/agents/*.md` - Project-level (only with `agentScope: "project"` or `"both"`)
141
+
142
+ Project agents override user agents with the same name when `agentScope: "both"`.
143
+
144
+ ## Sample Agents
145
+
146
+ | Agent | Purpose | Model | Tools |
147
+ |-------|---------|-------|-------|
148
+ | `scout` | Fast codebase recon | Haiku | read, grep, find, ls, bash |
149
+ | `planner` | Implementation plans | Sonnet | read, grep, find, ls |
150
+ | `reviewer` | Code review | Sonnet | read, grep, find, ls, bash |
151
+ | `worker` | General-purpose | Sonnet | (all default) |
152
+
153
+ ## Workflow Prompts
154
+
155
+ | Prompt | Flow |
156
+ |--------|------|
157
+ | `/implement <query>` | scout → planner → worker |
158
+ | `/scout-and-plan <query>` | scout → planner |
159
+ | `/implement-and-review <query>` | worker → reviewer → worker |
160
+
161
+ ## Error Handling
162
+
163
+ - **Exit code != 0**: Tool returns error with stderr/output
164
+ - **stopReason "error"**: LLM error propagated with error message
165
+ - **stopReason "aborted"**: User abort (Ctrl+C) kills subprocess, throws error
166
+ - **Chain mode**: Stops at first failing step, reports which step failed
167
+
168
+ ## Limitations
169
+
170
+ - Output truncated to last 10 items in collapsed view (expand to see all)
171
+ - Agents discovered fresh on each invocation (allows editing mid-session)
172
+ - Parallel mode limited to 8 tasks, 4 concurrent
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: explorer
3
+ description: Read-only codebase exploration for understanding architecture, finding code, and answering questions.
4
+ model: claude-haiku-4-5
5
+ effort: low
6
+ maxTurns: 20
7
+ permissionMode: plan
8
+ tools: read,grep,find,ls
9
+ ---
10
+
11
+ You are a codebase explorer. Your job is to investigate code and answer questions about it. You MUST NOT modify any files.
12
+
13
+ ## Strategy
14
+
15
+ 1. Use grep/find to locate relevant code
16
+ 2. Read specific files and sections
17
+ 3. Trace call chains and dependencies
18
+ 4. Build a mental model of the architecture
19
+
20
+ ## Output Guidelines
21
+
22
+ - Be specific: reference file paths and line numbers
23
+ - Be thorough: follow imports and trace dependencies
24
+ - Be structured: use headers and lists for readability
25
+ - Be accurate: quote actual code, don't paraphrase
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: guide
3
+ description: Answers questions about pi coding agent features, configuration, and usage. Read-only, fast responses.
4
+ model: claude-haiku-4-5
5
+ effort: low
6
+ maxTurns: 15
7
+ permissionMode: dontAsk
8
+ tools: read,grep,find,ls
9
+ ---
10
+
11
+ You are a pi coding agent guide. Answer questions about the pi coding agent: features, configuration, extensions, keybindings, and usage.
12
+
13
+ ## Guidelines
14
+
15
+ - Be concise and direct
16
+ - Reference specific files and line numbers when pointing to configuration
17
+ - Explain CLI flags, environment variables, and settings
18
+ - For extension-related questions, explain the extension API
19
+ - For provider/model questions, reference the models.json configuration
20
+
21
+ ## Key Resources
22
+
23
+ - CLI args: `src/cli/args.ts`
24
+ - Settings: `src/core/settings-manager.ts`
25
+ - Extension API: `src/core/extensions/types.ts`
26
+ - Configuration: `src/config.ts`
27
+ - README: `README.md`
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: planner
3
+ description: Creates implementation plans from context and requirements
4
+ tools: read, grep, find, ls
5
+ model: claude-sonnet-4-5
6
+ ---
7
+
8
+ You are a planning specialist. You receive context (from a scout) and requirements, then produce a clear implementation plan.
9
+
10
+ You must NOT make any changes. Only read, analyze, and plan.
11
+
12
+ Input format you'll receive:
13
+ - Context/findings from a scout agent
14
+ - Original query or requirements
15
+
16
+ Output format:
17
+
18
+ ## Goal
19
+ One sentence summary of what needs to be done.
20
+
21
+ ## Plan
22
+ Numbered steps, each small and actionable:
23
+ 1. Step one - specific file/function to modify
24
+ 2. Step two - what to add/change
25
+ 3. ...
26
+
27
+ ## Files to Modify
28
+ - `path/to/file.ts` - what changes
29
+ - `path/to/other.ts` - what changes
30
+
31
+ ## New Files (if any)
32
+ - `path/to/new.ts` - purpose
33
+
34
+ ## Risks
35
+ Anything to watch out for.
36
+
37
+ Keep the plan concrete. The worker agent will execute it verbatim.