@dyyz1993/pi-coding-agent 0.74.24 → 0.74.25
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/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/extensions/agent-permissions/index.ts +235 -0
- package/dist/extensions/ask-tools/index.ts +115 -0
- package/dist/extensions/auto-memory/contract.d.ts +51 -0
- package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
- package/dist/extensions/auto-memory/contract.js +2 -0
- package/dist/extensions/auto-memory/contract.js.map +1 -0
- package/dist/extensions/auto-memory/contract.ts +56 -0
- package/dist/extensions/auto-memory/index.ts +969 -0
- package/dist/extensions/auto-memory/prompts.ts +202 -0
- package/dist/extensions/auto-memory/skip-rules.ts +297 -0
- package/dist/extensions/auto-memory/utils.ts +208 -0
- package/dist/extensions/auto-session-title/index.ts +83 -0
- package/dist/extensions/bash-ext/contract.d.ts +79 -0
- package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
- package/dist/extensions/bash-ext/contract.js +2 -0
- package/dist/extensions/bash-ext/contract.js.map +1 -0
- package/dist/extensions/bash-ext/contract.ts +69 -0
- package/dist/extensions/bash-ext/index.ts +858 -0
- package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
- package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
- package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
- package/dist/extensions/claude-hooks-compat/index.ts +178 -0
- package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
- package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
- package/dist/extensions/claude-hooks-compat/types.ts +77 -0
- package/dist/extensions/compaction-manager/config.ts +47 -0
- package/dist/extensions/compaction-manager/context-fold.ts +63 -0
- package/dist/extensions/compaction-manager/index.ts +151 -0
- package/dist/extensions/compaction-manager/microcompact.ts +49 -0
- package/dist/extensions/compaction-manager/reactive.ts +9 -0
- package/dist/extensions/compaction-manager/session-memory.ts +48 -0
- package/dist/extensions/coordinator/INTEGRATION.md +376 -0
- package/dist/extensions/coordinator/handler.test.ts +277 -0
- package/dist/extensions/coordinator/handler.ts +189 -0
- package/dist/extensions/coordinator/index.ts +261 -0
- package/dist/extensions/coordinator/types.d.ts +100 -0
- package/dist/extensions/coordinator/types.d.ts.map +1 -0
- package/dist/extensions/coordinator/types.js +2 -0
- package/dist/extensions/coordinator/types.js.map +1 -0
- package/dist/extensions/coordinator/types.ts +72 -0
- package/dist/extensions/file-snapshot/index.ts +131 -0
- package/dist/extensions/file-time-guard/README.md +133 -0
- package/dist/extensions/file-time-guard/config.ts +13 -0
- package/dist/extensions/file-time-guard/index.ts +171 -0
- package/dist/extensions/hooks-engine/index.ts +117 -0
- package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
- package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
- package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
- package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
- package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
- package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/contract.js +2 -0
- package/dist/extensions/lsp/lsp/contract.js.map +1 -0
- package/dist/extensions/lsp/lsp/contract.ts +103 -0
- package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
- package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
- package/dist/extensions/lsp/lsp/index.ts +307 -0
- package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
- package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
- package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
- package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
- package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
- package/dist/extensions/message-bridge/GUIDE.md +210 -0
- package/dist/extensions/message-bridge/index.ts +222 -0
- package/dist/extensions/output-guard/index.ts +384 -0
- package/dist/extensions/preview/index.ts +278 -0
- package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
- package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
- package/dist/extensions/rules-engine/cache.js +232 -0
- package/dist/extensions/rules-engine/cache.ts +38 -0
- package/dist/extensions/rules-engine/config.js +63 -0
- package/dist/extensions/rules-engine/config.ts +70 -0
- package/dist/extensions/rules-engine/index.js +1530 -0
- package/dist/extensions/rules-engine/index.ts +552 -0
- package/dist/extensions/rules-engine/injector.js +68 -0
- package/dist/extensions/rules-engine/injector.ts +74 -0
- package/dist/extensions/rules-engine/loader.js +179 -0
- package/dist/extensions/rules-engine/loader.ts +205 -0
- package/dist/extensions/rules-engine/matcher.js +534 -0
- package/dist/extensions/rules-engine/matcher.ts +52 -0
- package/dist/extensions/rules-engine/types.d.ts +156 -0
- package/dist/extensions/rules-engine/types.d.ts.map +1 -0
- package/dist/extensions/rules-engine/types.js +2 -0
- package/dist/extensions/rules-engine/types.js.map +1 -0
- package/dist/extensions/rules-engine/types.ts +169 -0
- package/dist/extensions/session-supervisor/checker.ts +116 -0
- package/dist/extensions/session-supervisor/config.ts +45 -0
- package/dist/extensions/session-supervisor/index.ts +726 -0
- package/dist/extensions/session-supervisor/prompts.ts +132 -0
- package/dist/extensions/session-supervisor/scheduler.ts +69 -0
- package/dist/extensions/session-supervisor/types.ts +215 -0
- package/dist/extensions/subagent/README.md +172 -0
- package/dist/extensions/subagent/agents/explorer.md +25 -0
- package/dist/extensions/subagent/agents/guide.md +27 -0
- package/dist/extensions/subagent/agents/planner.md +37 -0
- package/dist/extensions/subagent/agents/reviewer.md +35 -0
- package/dist/extensions/subagent/agents/scout.md +50 -0
- package/dist/extensions/subagent/agents/verification.md +35 -0
- package/dist/extensions/subagent/agents/worker.md +24 -0
- package/dist/extensions/subagent/agents.ts +25 -0
- package/dist/extensions/subagent/index.ts +987 -0
- package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/dist/extensions/subagent/prompts/implement.md +10 -0
- package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/dist/extensions/subagent-ext/contract.d.ts +2 -0
- package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-ext/contract.js +2 -0
- package/dist/extensions/subagent-ext/contract.js.map +1 -0
- package/dist/extensions/subagent-ext/contract.ts +1 -0
- package/dist/extensions/subagent-ext/index.ts +347 -0
- package/dist/extensions/subagent-shared/contract.d.ts +25 -0
- package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-shared/contract.js +2 -0
- package/dist/extensions/subagent-shared/contract.js.map +1 -0
- package/dist/extensions/subagent-shared/contract.ts +28 -0
- package/dist/extensions/subagent-shared/index.ts +4 -0
- package/dist/extensions/subagent-shared/render.ts +166 -0
- package/dist/extensions/subagent-shared/types.ts +35 -0
- package/dist/extensions/subagent-shared/utils.ts +112 -0
- package/dist/extensions/subagent-v2/contract.d.ts +2 -0
- package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-v2/contract.js +2 -0
- package/dist/extensions/subagent-v2/contract.js.map +1 -0
- package/dist/extensions/subagent-v2/contract.ts +1 -0
- package/dist/extensions/subagent-v2/index.ts +599 -0
- package/dist/extensions/todo-ext/contract.d.ts +27 -0
- package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
- package/dist/extensions/todo-ext/contract.js +2 -0
- package/dist/extensions/todo-ext/contract.js.map +1 -0
- package/dist/extensions/todo-ext/contract.ts +30 -0
- package/dist/extensions/todo-ext/index.ts +419 -0
- 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.
|