@leing2021/super-pi 0.22.1 → 0.23.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.
- package/README.md +66 -293
- package/extensions/ce-core/index.ts +276 -48
- package/extensions/ce-core/tools/parallel-subagent.ts +3 -3
- package/extensions/ce-core/tools/subagent.ts +2 -2
- package/package.json +4 -20
- package/rules/common/naming.md +154 -0
- package/skills/01-brainstorm/SKILL.md +42 -79
- package/skills/01-brainstorm/references/ce-brainstorm-mode.md +47 -0
- package/skills/02-plan/SKILL.md +43 -61
- package/skills/02-plan/references/solution-search.md +46 -0
- package/skills/03-work/SKILL.md +34 -52
- package/skills/03-work/references/completion-report.md +51 -0
- package/skills/04-review/SKILL.md +44 -51
- package/skills/04-review/references/solution-search.md +46 -0
- package/skills/06-next/SKILL.md +35 -20
- package/skills/06-next/references/recommendation-logic.md +47 -2
- package/skills/07-worktree/SKILL.md +21 -20
- package/skills/08-help/SKILL.md +46 -0
- package/skills/08-help/references/workflow-sequence.md +135 -0
- package/skills/references/language-detection.md +44 -0
- package/LICENSE +0 -21
- package/THIRD-PARTY-NOTICES.md +0 -35
- package/extensions/subagent/__tests__/async-job-tracker.test.ts +0 -21
- package/extensions/subagent/__tests__/execution-activity.test.ts +0 -15
- package/extensions/subagent/__tests__/parallel-render-stress.test.ts +0 -82
- package/extensions/subagent/__tests__/render-dedup.test.ts +0 -98
- package/extensions/subagent/__tests__/render-widget.test.ts +0 -28
- package/extensions/subagent/__tests__/throttle.test.ts +0 -90
- package/extensions/subagent/agent-management.ts +0 -596
- package/extensions/subagent/agent-manager-chain-detail.ts +0 -163
- package/extensions/subagent/agent-manager-detail.ts +0 -232
- package/extensions/subagent/agent-manager-edit.ts +0 -391
- package/extensions/subagent/agent-manager-list.ts +0 -279
- package/extensions/subagent/agent-manager-parallel.ts +0 -305
- package/extensions/subagent/agent-manager.ts +0 -706
- package/extensions/subagent/agent-scope.ts +0 -9
- package/extensions/subagent/agent-selection.ts +0 -26
- package/extensions/subagent/agent-serializer.ts +0 -124
- package/extensions/subagent/agent-templates.ts +0 -63
- package/extensions/subagent/agents/context-builder.md +0 -37
- package/extensions/subagent/agents/delegate.md +0 -9
- package/extensions/subagent/agents/oracle.md +0 -73
- package/extensions/subagent/agents/planner.md +0 -52
- package/extensions/subagent/agents/researcher.md +0 -50
- package/extensions/subagent/agents/reviewer.md +0 -38
- package/extensions/subagent/agents/scout.md +0 -48
- package/extensions/subagent/agents/worker.md +0 -52
- package/extensions/subagent/agents.ts +0 -762
- package/extensions/subagent/artifacts.ts +0 -101
- package/extensions/subagent/async-execution.ts +0 -521
- package/extensions/subagent/async-job-tracker.ts +0 -240
- package/extensions/subagent/async-status.ts +0 -242
- package/extensions/subagent/chain-clarify.ts +0 -1365
- package/extensions/subagent/chain-execution.ts +0 -854
- package/extensions/subagent/chain-serializer.ts +0 -127
- package/extensions/subagent/completion-dedupe.ts +0 -66
- package/extensions/subagent/doctor.ts +0 -201
- package/extensions/subagent/execution.ts +0 -748
- package/extensions/subagent/file-coalescer.ts +0 -43
- package/extensions/subagent/fork-context.ts +0 -64
- package/extensions/subagent/formatters.ts +0 -123
- package/extensions/subagent/frontmatter.ts +0 -32
- package/extensions/subagent/index.ts +0 -586
- package/extensions/subagent/intercom-bridge.ts +0 -241
- package/extensions/subagent/jsonl-writer.ts +0 -84
- package/extensions/subagent/model-fallback.ts +0 -109
- package/extensions/subagent/notify.ts +0 -111
- package/extensions/subagent/parallel-utils.ts +0 -109
- package/extensions/subagent/pi-args.ts +0 -139
- package/extensions/subagent/pi-spawn.ts +0 -101
- package/extensions/subagent/post-exit-stdio-guard.ts +0 -88
- package/extensions/subagent/prompt-template-bridge.ts +0 -400
- package/extensions/subagent/prompts/gather-context-and-clarify.md +0 -13
- package/extensions/subagent/prompts/parallel-cleanup.md +0 -42
- package/extensions/subagent/prompts/parallel-research.md +0 -50
- package/extensions/subagent/prompts/parallel-review.md +0 -40
- package/extensions/subagent/render-helpers.ts +0 -83
- package/extensions/subagent/render.ts +0 -908
- package/extensions/subagent/result-intercom.ts +0 -238
- package/extensions/subagent/result-watcher.ts +0 -172
- package/extensions/subagent/run-history.ts +0 -58
- package/extensions/subagent/run-status.ts +0 -137
- package/extensions/subagent/schemas.ts +0 -165
- package/extensions/subagent/session-tokens.ts +0 -51
- package/extensions/subagent/settings.ts +0 -368
- package/extensions/subagent/single-output.ts +0 -98
- package/extensions/subagent/skills.ts +0 -627
- package/extensions/subagent/slash-bridge.ts +0 -177
- package/extensions/subagent/slash-commands.ts +0 -304
- package/extensions/subagent/slash-live-state.ts +0 -295
- package/extensions/subagent/subagent-control.ts +0 -151
- package/extensions/subagent/subagent-executor.ts +0 -1915
- package/extensions/subagent/subagent-prompt-runtime.ts +0 -76
- package/extensions/subagent/subagent-runner.ts +0 -1471
- package/extensions/subagent/subagents-status.ts +0 -473
- package/extensions/subagent/text-editor.ts +0 -273
- package/extensions/subagent/throttle.ts +0 -77
- package/extensions/subagent/top-level-async.ts +0 -16
- package/extensions/subagent/types.ts +0 -624
- package/extensions/subagent/utils.ts +0 -457
- package/extensions/subagent/worktree.ts +0 -580
- package/extensions/super-pi-extension/agents/ce-oracle.md +0 -109
- package/extensions/super-pi-extension/agents/ce-planner.md +0 -116
- package/extensions/super-pi-extension/agents/ce-reviewer.md +0 -99
- package/extensions/super-pi-extension/agents/ce-scout.md +0 -80
- package/extensions/super-pi-extension/agents/ce-worker.md +0 -78
- package/extensions/super-pi-extension/chains/ce-parallel-review.chain.md +0 -34
- package/extensions/super-pi-extension/chains/ce-review-only.chain.md +0 -12
- package/extensions/super-pi-extension/chains/ce-standard.chain.md +0 -28
- package/extensions/super-pi-extension/index.ts +0 -129
- package/extensions/super-pi-extension/model-sync.ts +0 -204
- package/skills/08-status/SKILL.md +0 -41
- package/skills/08-status/references/artifact-locations.md +0 -10
- package/skills/09-help/SKILL.md +0 -37
- package/skills/09-help/references/workflow-sequence.md +0 -9
- package/skills/10-rules/SKILL.md +0 -76
- package/skills/pi-subagents/SKILL.md +0 -566
|
@@ -4,23 +4,25 @@ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"
|
|
|
4
4
|
import { Type } from "typebox"
|
|
5
5
|
import { createArtifactHelperTool, type ArtifactType } from "./tools/artifact-helper"
|
|
6
6
|
import { createAskUserQuestionTool } from "./tools/ask-user-question"
|
|
7
|
+
import { createSubagentTool } from "./tools/subagent"
|
|
7
8
|
import { createWorkflowStateTool } from "./tools/workflow-state"
|
|
8
9
|
import { createWorktreeManagerTool } from "./tools/worktree-manager"
|
|
9
10
|
import { createReviewRouterTool } from "./tools/review-router"
|
|
11
|
+
import { createParallelSubagentTool } from "./tools/parallel-subagent"
|
|
10
12
|
import { createSessionCheckpointTool } from "./tools/session-checkpoint"
|
|
11
13
|
import { createTaskSplitterTool } from "./tools/task-splitter"
|
|
12
14
|
import { createBrainstormDialogTool } from "./tools/brainstorm-dialog"
|
|
13
15
|
import { createPlanDiffTool } from "./tools/plan-diff"
|
|
14
16
|
import { createSessionHistoryTool } from "./tools/session-history"
|
|
15
17
|
import { createPatternExtractorTool } from "./tools/pattern-extractor"
|
|
18
|
+
import { createContextHandoffTool } from "./tools/context-handoff"
|
|
16
19
|
import { filterBashOutput } from "./tools/bash-output-filter"
|
|
17
20
|
import { filterReadOutput } from "./tools/read-output-filter"
|
|
18
21
|
import { COMPACTION_FOCUS_INSTRUCTIONS } from "./tools/compaction-optimizer"
|
|
22
|
+
import { AsyncMutex } from "./tools/async-mutex"
|
|
23
|
+
import type { SubagentExecOptions, SubagentRunner } from "./tools/subagent"
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
// Subagent capabilities are provided by the pi-subagents package.
|
|
22
|
-
// super-pi focuses on CE-specific tools only.
|
|
23
|
-
|
|
25
|
+
const _subagentEnvMutex = new AsyncMutex()
|
|
24
26
|
const PIPELINE_STAGE_KEYS = new Set([
|
|
25
27
|
"01-brainstorm",
|
|
26
28
|
"02-plan",
|
|
@@ -29,15 +31,46 @@ const PIPELINE_STAGE_KEYS = new Set([
|
|
|
29
31
|
"05-learn",
|
|
30
32
|
])
|
|
31
33
|
|
|
32
|
-
interface
|
|
34
|
+
interface StrategySettings {
|
|
33
35
|
modelStrategy?: Record<string, string>
|
|
36
|
+
thinkingStrategy?: Record<string, string>
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Read settings from two locations:
|
|
41
|
+
* 1. Project-level: {cwd}/.pi/settings.json (highest priority)
|
|
42
|
+
* 2. Global-level: ~/.pi/agent/settings.json (fallback)
|
|
43
|
+
*
|
|
44
|
+
* Project-level takes precedence; global-level is used as fallback.
|
|
45
|
+
*/
|
|
46
|
+
async function readSettings(cwd: string): Promise<StrategySettings | null> {
|
|
47
|
+
// Try project-level first
|
|
48
|
+
const projectPath = path.join(cwd, ".pi", "settings.json")
|
|
38
49
|
try {
|
|
39
|
-
const content = await readFile(
|
|
40
|
-
|
|
50
|
+
const content = await readFile(projectPath, "utf8")
|
|
51
|
+
const projectSettings = JSON.parse(content) as StrategySettings
|
|
52
|
+
// If project has modelStrategy or thinkingStrategy, use it
|
|
53
|
+
if (projectSettings.modelStrategy || projectSettings.thinkingStrategy) {
|
|
54
|
+
return projectSettings
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// Project settings not found, continue to global
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Fallback to global-level
|
|
61
|
+
const globalPath = path.join(process.env.HOME || "~", ".pi", "agent", "settings.json")
|
|
62
|
+
try {
|
|
63
|
+
const content = await readFile(globalPath, "utf8")
|
|
64
|
+
return JSON.parse(content) as StrategySettings
|
|
65
|
+
} catch {
|
|
66
|
+
// Global settings not found either
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Try ~/.pi/settings.json as another fallback
|
|
70
|
+
const altGlobalPath = path.join(process.env.HOME || "~", ".pi", "settings.json")
|
|
71
|
+
try {
|
|
72
|
+
const content = await readFile(altGlobalPath, "utf8")
|
|
73
|
+
return JSON.parse(content) as StrategySettings
|
|
41
74
|
} catch {
|
|
42
75
|
return null
|
|
43
76
|
}
|
|
@@ -81,6 +114,47 @@ function parseModelRef(
|
|
|
81
114
|
}
|
|
82
115
|
}
|
|
83
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Create a subagent runner that handles env injection with mutex protection
|
|
119
|
+
* for concurrency safety when multiple parallel subagents share the process.
|
|
120
|
+
*/
|
|
121
|
+
function createSubagentRunner(
|
|
122
|
+
pi: ExtensionAPI,
|
|
123
|
+
signal?: AbortSignal,
|
|
124
|
+
): SubagentRunner {
|
|
125
|
+
return async (prompt: string, options?: SubagentExecOptions) => {
|
|
126
|
+
const args = ["--no-session", ...(options?.extraFlags ?? []), "-p", prompt]
|
|
127
|
+
const release = await _subagentEnvMutex.acquire()
|
|
128
|
+
const savedEnv: Record<string, string | undefined> = {}
|
|
129
|
+
const extraEnv = options?.extraEnv ?? {}
|
|
130
|
+
for (const [key, value] of Object.entries(extraEnv)) {
|
|
131
|
+
savedEnv[key] = process.env[key]
|
|
132
|
+
process.env[key] = value
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const execResult = await pi.exec("pi", args, {
|
|
136
|
+
signal,
|
|
137
|
+
timeout: 10 * 60 * 1000,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
if (execResult.code !== 0) {
|
|
141
|
+
throw new Error(execResult.stderr || execResult.stdout || `Subagent failed for prompt: ${prompt}`)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return (execResult.stdout || "").trim()
|
|
145
|
+
} finally {
|
|
146
|
+
for (const [key, oldValue] of Object.entries(savedEnv)) {
|
|
147
|
+
if (oldValue === undefined) {
|
|
148
|
+
delete process.env[key]
|
|
149
|
+
} else {
|
|
150
|
+
process.env[key] = oldValue
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
release()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
84
158
|
const artifactHelperParams = Type.Object({
|
|
85
159
|
repoRoot: Type.String({ description: "Repository root where workflow artifacts should be created" }),
|
|
86
160
|
artifactType: Type.Union([
|
|
@@ -103,6 +177,18 @@ const askUserQuestionParams = Type.Object({
|
|
|
103
177
|
allowCustom: Type.Optional(Type.Boolean({ description: "Allow a custom answer when options are present" })),
|
|
104
178
|
})
|
|
105
179
|
|
|
180
|
+
const subagentTaskSchema = Type.Object({
|
|
181
|
+
agent: Type.String({ description: "Skill name to invoke via /skill:<name>" }),
|
|
182
|
+
task: Type.String({ description: "Task text passed to the subagent" }),
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
const subagentParams = Type.Object({
|
|
186
|
+
agent: Type.Optional(Type.String({ description: "Single subagent skill name" })),
|
|
187
|
+
task: Type.Optional(Type.String({ description: "Single subagent task" })),
|
|
188
|
+
chain: Type.Optional(Type.Array(subagentTaskSchema, { description: "Serial subagent chain with optional {previous} placeholder" })),
|
|
189
|
+
inheritSkills: Type.Optional(Type.Boolean({ description: "Whether the subagent should inherit skills. Default: true" })),
|
|
190
|
+
})
|
|
191
|
+
|
|
106
192
|
const workflowStateParams = Type.Object({
|
|
107
193
|
repoRoot: Type.String({ description: "Repository root to scan for workflow artifacts" }),
|
|
108
194
|
})
|
|
@@ -125,6 +211,19 @@ const reviewRouterParams = Type.Object({
|
|
|
125
211
|
deletions: Type.Number({ description: "Number of lines removed" }),
|
|
126
212
|
})
|
|
127
213
|
|
|
214
|
+
const parallelSubagentTaskSchema = Type.Object({
|
|
215
|
+
agent: Type.String({ description: "Skill name to invoke via /skill:<name>" }),
|
|
216
|
+
task: Type.String({ description: "Task text passed to the subagent" }),
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const parallelSubagentParams = Type.Object({
|
|
220
|
+
tasks: Type.Union([
|
|
221
|
+
Type.Array(parallelSubagentTaskSchema),
|
|
222
|
+
Type.String({ description: "JSON stringified array of tasks" }),
|
|
223
|
+
], { description: "Array of independent tasks to run concurrently (can be a JSON string)" }),
|
|
224
|
+
inheritSkills: Type.Optional(Type.Boolean({ description: "Whether subagents should inherit skills. Default: false" })),
|
|
225
|
+
})
|
|
226
|
+
|
|
128
227
|
const sessionCheckpointParams = Type.Object({
|
|
129
228
|
operation: Type.Union([
|
|
130
229
|
Type.Literal("save"),
|
|
@@ -205,6 +304,30 @@ const patternSchema = Type.Object({
|
|
|
205
304
|
sources: Type.Array(Type.String(), { description: "Artifact sources" }),
|
|
206
305
|
})
|
|
207
306
|
|
|
307
|
+
const contextHandoffParams = Type.Object({
|
|
308
|
+
operation: Type.Union([
|
|
309
|
+
Type.Literal("save"),
|
|
310
|
+
Type.Literal("load"),
|
|
311
|
+
Type.Literal("latest"),
|
|
312
|
+
Type.Literal("status"),
|
|
313
|
+
], { description: "Handoff operation" }),
|
|
314
|
+
repoRoot: Type.String({ description: "Repository root" }),
|
|
315
|
+
currentStage: Type.Optional(Type.String({ description: "Current pipeline stage (e.g. 02-plan)" })),
|
|
316
|
+
nextStage: Type.Optional(Type.String({ description: "Next pipeline stage" })),
|
|
317
|
+
contextHealth: Type.Optional(Type.Union([
|
|
318
|
+
Type.Literal("good"),
|
|
319
|
+
Type.Literal("watch"),
|
|
320
|
+
Type.Literal("heavy"),
|
|
321
|
+
Type.Literal("critical"),
|
|
322
|
+
], { description: "Context health assessment" })),
|
|
323
|
+
activeFiles: Type.Optional(Type.Array(Type.String(), { description: "1-5 must-know active file paths" })),
|
|
324
|
+
blocker: Type.Optional(Type.String({ description: "Current blocker description" })),
|
|
325
|
+
verification: Type.Optional(Type.String({ description: "Latest verification command + result" })),
|
|
326
|
+
artifacts: Type.Optional(Type.Record(Type.String(), Type.Optional(Type.String()), { description: "Artifact paths (requirements, plan, checkpoint, proof)" })),
|
|
327
|
+
handoffMarkdown: Type.Optional(Type.String({ description: "Custom handoff markdown content" })),
|
|
328
|
+
handoffPath: Type.Optional(Type.String({ description: "Specific handoff file path to load" })),
|
|
329
|
+
})
|
|
330
|
+
|
|
208
331
|
const patternExtractorParams = Type.Object({
|
|
209
332
|
operation: Type.Union([
|
|
210
333
|
Type.Literal("extract"),
|
|
@@ -227,47 +350,61 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
227
350
|
return { action: "continue" as const }
|
|
228
351
|
}
|
|
229
352
|
|
|
230
|
-
const settings = await
|
|
353
|
+
const settings = await readSettings(ctx.cwd)
|
|
231
354
|
const modelStrategy = settings?.modelStrategy
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
355
|
+
const thinkingStrategy = settings?.thinkingStrategy
|
|
356
|
+
|
|
357
|
+
// Model switching
|
|
358
|
+
if (modelStrategy) {
|
|
359
|
+
const targetModelRef = modelStrategy[stageKey] ?? modelStrategy.default
|
|
360
|
+
if (targetModelRef) {
|
|
361
|
+
const parsed = parseModelRef(targetModelRef, ctx.model?.provider)
|
|
362
|
+
if (parsed) {
|
|
363
|
+
// Skip if already using the same model
|
|
364
|
+
if (ctx.model?.provider !== parsed.provider || ctx.model?.id !== parsed.id) {
|
|
365
|
+
const model = ctx.modelRegistry.find(parsed.provider, parsed.id)
|
|
366
|
+
if (model) {
|
|
367
|
+
const switched = await pi.setModel(model)
|
|
368
|
+
if (switched) {
|
|
369
|
+
if (ctx.hasUI) {
|
|
370
|
+
ctx.ui.notify(`Switched model for ${stageKey}: ${model.provider}/${model.id}`, "info")
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
if (ctx.hasUI) {
|
|
374
|
+
ctx.ui.notify(`No API key for ${stageKey}: ${model.provider}/${model.id}`, "warning")
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
} else if (ctx.hasUI) {
|
|
378
|
+
ctx.ui.notify(`Model not found for ${stageKey}: ${targetModelRef}`, "warning")
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
} else if (ctx.hasUI) {
|
|
382
|
+
ctx.ui.notify(`Invalid modelStrategy for ${stageKey}: ${targetModelRef}`, "warning")
|
|
383
|
+
}
|
|
257
384
|
}
|
|
258
|
-
return { action: "continue" as const }
|
|
259
385
|
}
|
|
260
386
|
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
387
|
+
// Thinking level switching
|
|
388
|
+
if (thinkingStrategy) {
|
|
389
|
+
const targetThinking = thinkingStrategy[stageKey] ?? thinkingStrategy.default
|
|
390
|
+
if (targetThinking) {
|
|
391
|
+
const levelMap: Record<string, "low" | "medium" | "high"> = {
|
|
392
|
+
low: "low",
|
|
393
|
+
medium: "medium",
|
|
394
|
+
high: "high",
|
|
395
|
+
"0": "low",
|
|
396
|
+
"1": "medium",
|
|
397
|
+
"2": "high",
|
|
398
|
+
}
|
|
399
|
+
const normalized = levelMap[targetThinking.toLowerCase()] ?? "medium"
|
|
400
|
+
const currentLevel = ctx.getThinkingLevel?.() ?? "medium"
|
|
401
|
+
if (currentLevel !== normalized) {
|
|
402
|
+
ctx.setThinkingLevel?.(normalized)
|
|
403
|
+
if (ctx.hasUI) {
|
|
404
|
+
ctx.ui.notify(`Switched thinking level for ${stageKey}: ${normalized}`, "info")
|
|
405
|
+
}
|
|
406
|
+
}
|
|
265
407
|
}
|
|
266
|
-
return { action: "continue" as const }
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (ctx.hasUI) {
|
|
270
|
-
ctx.ui.notify(`No API key available for configured model: ${model.provider}/${model.id}`, "warning")
|
|
271
408
|
}
|
|
272
409
|
|
|
273
410
|
return { action: "continue" as const }
|
|
@@ -275,15 +412,18 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
275
412
|
|
|
276
413
|
const artifactHelper = createArtifactHelperTool()
|
|
277
414
|
const askUserQuestion = createAskUserQuestionTool()
|
|
415
|
+
const subagent = createSubagentTool()
|
|
278
416
|
const workflowState = createWorkflowStateTool()
|
|
279
417
|
const worktreeManager = createWorktreeManagerTool()
|
|
280
418
|
const reviewRouter = createReviewRouterTool()
|
|
419
|
+
const parallelSubagent = createParallelSubagentTool()
|
|
281
420
|
const sessionCheckpoint = createSessionCheckpointTool()
|
|
282
421
|
const taskSplitter = createTaskSplitterTool()
|
|
283
422
|
const brainstormDialog = createBrainstormDialogTool()
|
|
284
423
|
const planDiff = createPlanDiffTool()
|
|
285
424
|
const sessionHistory = createSessionHistoryTool()
|
|
286
425
|
const patternExtractor = createPatternExtractorTool()
|
|
426
|
+
const contextHandoff = createContextHandoffTool()
|
|
287
427
|
|
|
288
428
|
pi.registerTool({
|
|
289
429
|
name: artifactHelper.name,
|
|
@@ -350,6 +490,29 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
350
490
|
},
|
|
351
491
|
})
|
|
352
492
|
|
|
493
|
+
pi.registerTool({
|
|
494
|
+
name: subagent.name,
|
|
495
|
+
label: "CE Subagent",
|
|
496
|
+
description: "Run a single CE skill-based subagent or a serial chain in an isolated Pi process.",
|
|
497
|
+
parameters: subagentParams,
|
|
498
|
+
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
499
|
+
const result = await subagent.execute(
|
|
500
|
+
{
|
|
501
|
+
agent: params.agent,
|
|
502
|
+
task: params.task,
|
|
503
|
+
chain: params.chain,
|
|
504
|
+
inheritSkills: params.inheritSkills,
|
|
505
|
+
},
|
|
506
|
+
createSubagentRunner(pi, signal),
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
return {
|
|
510
|
+
content: [{ type: "text", text: result.outputs[result.outputs.length - 1] ?? "" }],
|
|
511
|
+
details: result,
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
})
|
|
515
|
+
|
|
353
516
|
pi.registerTool({
|
|
354
517
|
name: workflowState.name,
|
|
355
518
|
label: "Workflow State",
|
|
@@ -421,6 +584,39 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
421
584
|
},
|
|
422
585
|
})
|
|
423
586
|
|
|
587
|
+
pi.registerTool({
|
|
588
|
+
name: parallelSubagent.name,
|
|
589
|
+
label: "CE Parallel Subagent",
|
|
590
|
+
description: "Run multiple CE skill-based subagent tasks concurrently. IMPORTANT: Provide 'tasks' as a clean JSON array object. If the environment forces a string, provide a valid JSON array string.",
|
|
591
|
+
parameters: parallelSubagentParams,
|
|
592
|
+
async execute(_toolCallId, params, signal) {
|
|
593
|
+
let tasks: any[]
|
|
594
|
+
if (typeof params.tasks === "string") {
|
|
595
|
+
try {
|
|
596
|
+
const cleaned = params.tasks.replace(/^```json\s*|```$/g, "").trim()
|
|
597
|
+
tasks = JSON.parse(cleaned)
|
|
598
|
+
} catch (e) {
|
|
599
|
+
throw new Error(`Failed to parse tasks string as JSON: ${e instanceof Error ? e.message : String(e)}`)
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
tasks = params.tasks
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const result = await parallelSubagent.execute(
|
|
606
|
+
{
|
|
607
|
+
tasks,
|
|
608
|
+
inheritSkills: params.inheritSkills,
|
|
609
|
+
},
|
|
610
|
+
createSubagentRunner(pi, signal),
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
return {
|
|
614
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
615
|
+
details: result,
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
})
|
|
619
|
+
|
|
424
620
|
pi.registerTool({
|
|
425
621
|
name: sessionCheckpoint.name,
|
|
426
622
|
label: "Session Checkpoint",
|
|
@@ -544,6 +740,33 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
544
740
|
},
|
|
545
741
|
})
|
|
546
742
|
|
|
743
|
+
pi.registerTool({
|
|
744
|
+
name: contextHandoff.name,
|
|
745
|
+
label: "Context Handoff",
|
|
746
|
+
description: "Manage cross-stage context handoffs with evidence-first templates. Supports save (write handoff + state), load (read handoff + state), latest (read latest dated handoff), and status (read current state).",
|
|
747
|
+
parameters: contextHandoffParams,
|
|
748
|
+
async execute(_toolCallId, params) {
|
|
749
|
+
const result = await contextHandoff.execute({
|
|
750
|
+
operation: params.operation,
|
|
751
|
+
repoRoot: params.repoRoot,
|
|
752
|
+
currentStage: params.currentStage,
|
|
753
|
+
nextStage: params.nextStage,
|
|
754
|
+
contextHealth: params.contextHealth,
|
|
755
|
+
activeFiles: params.activeFiles,
|
|
756
|
+
blocker: params.blocker,
|
|
757
|
+
verification: params.verification,
|
|
758
|
+
artifacts: params.artifacts as Record<string, string | undefined> | undefined,
|
|
759
|
+
handoffMarkdown: params.handoffMarkdown,
|
|
760
|
+
handoffPath: params.handoffPath,
|
|
761
|
+
})
|
|
762
|
+
|
|
763
|
+
return {
|
|
764
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
765
|
+
details: result,
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
})
|
|
769
|
+
|
|
547
770
|
// Bash output smart filter — reduces context waste from verbose command output
|
|
548
771
|
pi.on("tool_result", async (event, _ctx) => {
|
|
549
772
|
if (event.toolName !== "bash") return undefined
|
|
@@ -587,8 +810,8 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
587
810
|
if (event.toolName !== "read") return undefined
|
|
588
811
|
|
|
589
812
|
// Extract path from input
|
|
590
|
-
const
|
|
591
|
-
if (!
|
|
813
|
+
const path = (event.input as any)?.path ?? ""
|
|
814
|
+
if (!path) return undefined
|
|
592
815
|
|
|
593
816
|
// Extract text content from tool result
|
|
594
817
|
const textBlocks = (event.content as Array<any>)?.filter((b: any) => b.type === "text") ?? []
|
|
@@ -598,7 +821,7 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
598
821
|
const isImage = (event.content as Array<any>)?.some((b: any) => b.type === "image") ?? false
|
|
599
822
|
|
|
600
823
|
const result = filterReadOutput({
|
|
601
|
-
path
|
|
824
|
+
path,
|
|
602
825
|
output,
|
|
603
826
|
isError: event.isError ?? false,
|
|
604
827
|
isImage,
|
|
@@ -631,15 +854,20 @@ export default function ceCoreExtension(pi: ExtensionAPI) {
|
|
|
631
854
|
|
|
632
855
|
export { createArtifactHelperTool } from "./tools/artifact-helper"
|
|
633
856
|
export { createAskUserQuestionTool } from "./tools/ask-user-question"
|
|
857
|
+
export { createSubagentTool } from "./tools/subagent"
|
|
858
|
+
export { checkSubagentDepth, getChildDepthEnv, DEFAULT_MAX_SUBAGENT_DEPTH } from "./tools/subagent-depth-guard"
|
|
859
|
+
export { AsyncMutex } from "./tools/async-mutex"
|
|
634
860
|
export { createWorkflowStateTool } from "./tools/workflow-state"
|
|
635
861
|
export { createWorktreeManagerTool } from "./tools/worktree-manager"
|
|
636
862
|
export { createReviewRouterTool } from "./tools/review-router"
|
|
863
|
+
export { createParallelSubagentTool } from "./tools/parallel-subagent"
|
|
637
864
|
export { createSessionCheckpointTool } from "./tools/session-checkpoint"
|
|
638
865
|
export { createTaskSplitterTool } from "./tools/task-splitter"
|
|
639
866
|
export { createBrainstormDialogTool } from "./tools/brainstorm-dialog"
|
|
640
867
|
export { createPlanDiffTool } from "./tools/plan-diff"
|
|
641
868
|
export { createSessionHistoryTool } from "./tools/session-history"
|
|
642
869
|
export { createPatternExtractorTool } from "./tools/pattern-extractor"
|
|
870
|
+
export { createContextHandoffTool } from "./tools/context-handoff"
|
|
643
871
|
export {
|
|
644
872
|
getBrainstormArtifactPath,
|
|
645
873
|
getPlanArtifactPath,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* CE parallel subagent tool — runs multiple CE skill-based subagent tasks concurrently.
|
|
3
3
|
*
|
|
4
4
|
* Features:
|
|
5
5
|
* - Recursion depth guard (PI_SUBAGENT_DEPTH / PI_SUBAGENT_MAX_DEPTH)
|
|
@@ -40,7 +40,7 @@ function buildPrompt(agent: string, task: string): string {
|
|
|
40
40
|
|
|
41
41
|
export function createParallelSubagentTool() {
|
|
42
42
|
return {
|
|
43
|
-
name: "
|
|
43
|
+
name: "ce_parallel_subagent",
|
|
44
44
|
async execute(input: ParallelSubagentInput, runner: SubagentRunner): Promise<ParallelSubagentResult> {
|
|
45
45
|
// Recursion depth guard
|
|
46
46
|
const depthCheck = checkSubagentDepth()
|
|
@@ -49,7 +49,7 @@ export function createParallelSubagentTool() {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (!input.tasks || input.tasks.length === 0) {
|
|
52
|
-
throw new Error("
|
|
52
|
+
throw new Error("ce_parallel_subagent requires at least one task")
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// Default: parallel workers get a slim context (no inherited skills)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* CE subagent tool — runs a single CE skill-based subagent or a serial chain.
|
|
3
3
|
*
|
|
4
4
|
* Features:
|
|
5
5
|
* - Recursion depth guard (PI_SUBAGENT_DEPTH / PI_SUBAGENT_MAX_DEPTH)
|
|
@@ -43,7 +43,7 @@ export type SubagentRunner = (
|
|
|
43
43
|
|
|
44
44
|
export function createSubagentTool() {
|
|
45
45
|
return {
|
|
46
|
-
name: "
|
|
46
|
+
name: "ce_subagent",
|
|
47
47
|
async execute(input: SubagentInput, runner: SubagentRunner): Promise<SubagentResult> {
|
|
48
48
|
// Recursion depth guard
|
|
49
49
|
const depthCheck = checkSubagentDepth()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leing2021/super-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Pi-native Compound Engineering package for iterative development workflows",
|
|
@@ -25,8 +25,6 @@
|
|
|
25
25
|
"skills",
|
|
26
26
|
"extensions",
|
|
27
27
|
"rules",
|
|
28
|
-
"THIRD-PARTY-NOTICES.md",
|
|
29
|
-
"LICENSE",
|
|
30
28
|
"README.md",
|
|
31
29
|
"package.json"
|
|
32
30
|
],
|
|
@@ -37,10 +35,8 @@
|
|
|
37
35
|
"test": "bun test"
|
|
38
36
|
},
|
|
39
37
|
"peerDependencies": {
|
|
40
|
-
"@mariozechner/pi-coding-agent": "
|
|
41
|
-
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"typebox": "^1.1.24"
|
|
38
|
+
"@mariozechner/pi-coding-agent": ">=0.69.0",
|
|
39
|
+
"typebox": ">=1.0.0"
|
|
44
40
|
},
|
|
45
41
|
"devDependencies": {
|
|
46
42
|
"@mariozechner/pi-coding-agent": "0.69.0",
|
|
@@ -51,19 +47,7 @@
|
|
|
51
47
|
"./skills"
|
|
52
48
|
],
|
|
53
49
|
"extensions": [
|
|
54
|
-
"./extensions"
|
|
55
|
-
"./extensions/super-pi-extension",
|
|
56
|
-
"./extensions/subagent"
|
|
57
|
-
],
|
|
58
|
-
"agents": [
|
|
59
|
-
"./extensions/super-pi-extension/agents",
|
|
60
|
-
"./extensions/subagent/agents"
|
|
61
|
-
],
|
|
62
|
-
"prompts": [
|
|
63
|
-
"./extensions/subagent/prompts"
|
|
64
|
-
],
|
|
65
|
-
"chains": [
|
|
66
|
-
"./extensions/super-pi-extension/chains"
|
|
50
|
+
"./extensions"
|
|
67
51
|
]
|
|
68
52
|
}
|
|
69
53
|
}
|