@leing2021/super-pi 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +38 -209
  2. package/extensions/ce-core/index.ts +190 -7
  3. package/extensions/ce-core/tools/parallel-subagent.ts +3 -3
  4. package/extensions/ce-core/tools/subagent.ts +2 -2
  5. package/package.json +4 -18
  6. package/rules/common/naming.md +154 -0
  7. package/skills/02-plan/SKILL.md +3 -2
  8. package/skills/03-work/SKILL.md +9 -6
  9. package/skills/04-review/SKILL.md +3 -2
  10. package/skills/06-next/SKILL.md +38 -10
  11. package/skills/06-next/references/recommendation-logic.md +2 -2
  12. package/skills/07-worktree/SKILL.md +9 -8
  13. package/skills/{09-help → 08-help}/SKILL.md +3 -3
  14. package/skills/{09-help → 08-help}/references/workflow-sequence.md +2 -1
  15. package/skills/references/language-detection.md +44 -0
  16. package/extensions/subagent/agent-management.ts +0 -595
  17. package/extensions/subagent/agent-manager-chain-detail.ts +0 -162
  18. package/extensions/subagent/agent-manager-detail.ts +0 -231
  19. package/extensions/subagent/agent-manager-edit.ts +0 -390
  20. package/extensions/subagent/agent-manager-list.ts +0 -278
  21. package/extensions/subagent/agent-manager-parallel.ts +0 -304
  22. package/extensions/subagent/agent-manager.ts +0 -705
  23. package/extensions/subagent/agent-scope.ts +0 -8
  24. package/extensions/subagent/agent-selection.ts +0 -25
  25. package/extensions/subagent/agent-serializer.ts +0 -123
  26. package/extensions/subagent/agent-templates.ts +0 -62
  27. package/extensions/subagent/agents/context-builder.md +0 -37
  28. package/extensions/subagent/agents/delegate.md +0 -9
  29. package/extensions/subagent/agents/oracle.md +0 -73
  30. package/extensions/subagent/agents/planner.md +0 -52
  31. package/extensions/subagent/agents/researcher.md +0 -50
  32. package/extensions/subagent/agents/reviewer.md +0 -38
  33. package/extensions/subagent/agents/scout.md +0 -48
  34. package/extensions/subagent/agents/worker.md +0 -52
  35. package/extensions/subagent/agents.ts +0 -761
  36. package/extensions/subagent/artifacts.ts +0 -100
  37. package/extensions/subagent/async-execution.ts +0 -520
  38. package/extensions/subagent/async-job-tracker.ts +0 -216
  39. package/extensions/subagent/async-status.ts +0 -241
  40. package/extensions/subagent/chain-clarify.ts +0 -1364
  41. package/extensions/subagent/chain-execution.ts +0 -853
  42. package/extensions/subagent/chain-serializer.ts +0 -126
  43. package/extensions/subagent/completion-dedupe.ts +0 -65
  44. package/extensions/subagent/doctor.ts +0 -200
  45. package/extensions/subagent/execution.ts +0 -738
  46. package/extensions/subagent/file-coalescer.ts +0 -42
  47. package/extensions/subagent/fork-context.ts +0 -63
  48. package/extensions/subagent/formatters.ts +0 -122
  49. package/extensions/subagent/frontmatter.ts +0 -31
  50. package/extensions/subagent/index.ts +0 -585
  51. package/extensions/subagent/intercom-bridge.ts +0 -240
  52. package/extensions/subagent/jsonl-writer.ts +0 -83
  53. package/extensions/subagent/model-fallback.ts +0 -108
  54. package/extensions/subagent/notify.ts +0 -110
  55. package/extensions/subagent/parallel-utils.ts +0 -108
  56. package/extensions/subagent/pi-args.ts +0 -138
  57. package/extensions/subagent/pi-spawn.ts +0 -100
  58. package/extensions/subagent/post-exit-stdio-guard.ts +0 -87
  59. package/extensions/subagent/prompt-template-bridge.ts +0 -399
  60. package/extensions/subagent/prompts/gather-context-and-clarify.md +0 -13
  61. package/extensions/subagent/prompts/parallel-cleanup.md +0 -42
  62. package/extensions/subagent/prompts/parallel-research.md +0 -50
  63. package/extensions/subagent/prompts/parallel-review.md +0 -40
  64. package/extensions/subagent/render-helpers.ts +0 -82
  65. package/extensions/subagent/render.ts +0 -836
  66. package/extensions/subagent/result-intercom.ts +0 -237
  67. package/extensions/subagent/result-watcher.ts +0 -171
  68. package/extensions/subagent/run-history.ts +0 -57
  69. package/extensions/subagent/run-status.ts +0 -136
  70. package/extensions/subagent/schemas.ts +0 -164
  71. package/extensions/subagent/session-tokens.ts +0 -50
  72. package/extensions/subagent/settings.ts +0 -367
  73. package/extensions/subagent/single-output.ts +0 -97
  74. package/extensions/subagent/skills.ts +0 -626
  75. package/extensions/subagent/slash-bridge.ts +0 -176
  76. package/extensions/subagent/slash-commands.ts +0 -303
  77. package/extensions/subagent/slash-live-state.ts +0 -294
  78. package/extensions/subagent/subagent-control.ts +0 -150
  79. package/extensions/subagent/subagent-executor.ts +0 -1899
  80. package/extensions/subagent/subagent-prompt-runtime.ts +0 -75
  81. package/extensions/subagent/subagent-runner.ts +0 -1470
  82. package/extensions/subagent/subagents-status.ts +0 -472
  83. package/extensions/subagent/text-editor.ts +0 -272
  84. package/extensions/subagent/top-level-async.ts +0 -15
  85. package/extensions/subagent/types.ts +0 -623
  86. package/extensions/subagent/utils.ts +0 -456
  87. package/extensions/subagent/worktree.ts +0 -579
  88. package/extensions/super-pi-extension/agents/ce-oracle.md +0 -109
  89. package/extensions/super-pi-extension/agents/ce-planner.md +0 -116
  90. package/extensions/super-pi-extension/agents/ce-reviewer.md +0 -99
  91. package/extensions/super-pi-extension/agents/ce-scout.md +0 -80
  92. package/extensions/super-pi-extension/agents/ce-worker.md +0 -78
  93. package/extensions/super-pi-extension/chains/ce-parallel-review.chain.md +0 -34
  94. package/extensions/super-pi-extension/chains/ce-review-only.chain.md +0 -12
  95. package/extensions/super-pi-extension/chains/ce-standard.chain.md +0 -28
  96. package/extensions/super-pi-extension/index.ts +0 -129
  97. package/extensions/super-pi-extension/model-sync.ts +0 -204
  98. package/skills/08-status/SKILL.md +0 -41
  99. package/skills/08-status/references/artifact-locations.md +0 -10
  100. package/skills/10-rules/SKILL.md +0 -76
  101. package/skills/pi-subagents/SKILL.md +0 -566
@@ -1,126 +0,0 @@
1
- // Based on pi-subagents by Nico Bailon (https://github.com/nicobailon/pi-subagents)
2
- // MIT License
3
- import type { ChainConfig, ChainStepConfig } from "./agents.ts";
4
- import { parseFrontmatter } from "./frontmatter.ts";
5
-
6
- function parseStepBody(agent: string, sectionBody: string): ChainStepConfig {
7
- const lines = sectionBody.split("\n");
8
- const blankIndex = lines.findIndex((line) => line.trim() === "");
9
- const configLines = blankIndex === -1 ? lines : lines.slice(0, blankIndex);
10
- const task = (blankIndex === -1 ? "" : lines.slice(blankIndex + 1).join("\n")).trim();
11
-
12
- const step: ChainStepConfig = { agent, task };
13
- for (const line of configLines) {
14
- const match = line.match(/^([\w-]+):\s*(.*)$/);
15
- if (!match) continue;
16
- const key = match[1].trim().toLowerCase();
17
- const rawValue = match[2].trim();
18
-
19
- if (key === "output") {
20
- if (rawValue === "false") step.output = false;
21
- else if (rawValue) step.output = rawValue;
22
- continue;
23
- }
24
- if (key === "reads") {
25
- if (rawValue === "false") {
26
- step.reads = false;
27
- } else {
28
- const reads = rawValue
29
- .split(",")
30
- .map((v) => v.trim())
31
- .filter(Boolean);
32
- step.reads = reads.length > 0 ? reads : false;
33
- }
34
- continue;
35
- }
36
- if (key === "model") {
37
- if (rawValue) step.model = rawValue;
38
- continue;
39
- }
40
- if (key === "skills") {
41
- if (rawValue === "false") {
42
- step.skills = false;
43
- } else {
44
- const skills = rawValue
45
- .split(",")
46
- .map((v) => v.trim())
47
- .filter(Boolean);
48
- step.skills = skills.length > 0 ? skills : false;
49
- }
50
- continue;
51
- }
52
- if (key === "progress") {
53
- if (rawValue === "true") step.progress = true;
54
- else if (rawValue === "false") step.progress = false;
55
- }
56
- }
57
-
58
- return step;
59
- }
60
-
61
- export function parseChain(content: string, source: "user" | "project", filePath: string): ChainConfig {
62
- const { frontmatter, body } = parseFrontmatter(content);
63
- if (!frontmatter.name || !frontmatter.description) {
64
- throw new Error("Chain frontmatter must include name and description");
65
- }
66
-
67
- const matches = [...body.matchAll(/^##\s+(.+)[^\S\n]*$/gm)];
68
- const steps: ChainStepConfig[] = [];
69
-
70
- for (let i = 0; i < matches.length; i++) {
71
- const match = matches[i]!;
72
- const agent = match[1]!.trim();
73
- const lineEndOffset = body[match.index! + match[0].length] === "\n" ? 1 : 0;
74
- const sectionStart = match.index! + match[0].length + lineEndOffset;
75
- const sectionEnd = i + 1 < matches.length ? matches[i + 1]!.index! : body.length;
76
- const sectionBody = body.slice(sectionStart, sectionEnd).trimEnd();
77
- steps.push(parseStepBody(agent, sectionBody));
78
- }
79
-
80
- const extraFields: Record<string, string> = {};
81
- for (const [key, value] of Object.entries(frontmatter)) {
82
- if (key === "name" || key === "description") continue;
83
- extraFields[key] = value;
84
- }
85
-
86
- return {
87
- name: frontmatter.name,
88
- description: frontmatter.description,
89
- source,
90
- filePath,
91
- steps,
92
- extraFields: Object.keys(extraFields).length > 0 ? extraFields : undefined,
93
- };
94
- }
95
-
96
- export function serializeChain(config: ChainConfig): string {
97
- const lines: string[] = [];
98
- lines.push("---");
99
- lines.push(`name: ${config.name}`);
100
- lines.push(`description: ${config.description}`);
101
- if (config.extraFields) {
102
- for (const [key, value] of Object.entries(config.extraFields)) {
103
- lines.push(`${key}: ${value}`);
104
- }
105
- }
106
- lines.push("---");
107
- lines.push("");
108
-
109
- for (let i = 0; i < config.steps.length; i++) {
110
- const step = config.steps[i]!;
111
- lines.push(`## ${step.agent}`);
112
- if (step.output === false) lines.push("output: false");
113
- else if (step.output) lines.push(`output: ${step.output}`);
114
- if (step.reads === false) lines.push("reads: false");
115
- else if (Array.isArray(step.reads) && step.reads.length > 0) lines.push(`reads: ${step.reads.join(", ")}`);
116
- if (step.model) lines.push(`model: ${step.model}`);
117
- if (step.skills === false) lines.push("skills: false");
118
- else if (Array.isArray(step.skills) && step.skills.length > 0) lines.push(`skills: ${step.skills.join(", ")}`);
119
- if (step.progress !== undefined) lines.push(`progress: ${step.progress ? "true" : "false"}`);
120
- lines.push("");
121
- lines.push(step.task ?? "");
122
- if (i < config.steps.length - 1) lines.push("");
123
- }
124
-
125
- return `${lines.join("\n")}\n`;
126
- }
@@ -1,65 +0,0 @@
1
- // Based on pi-subagents by Nico Bailon (https://github.com/nicobailon/pi-subagents)
2
- // MIT License
3
- interface CompletionDataLike {
4
- id?: unknown;
5
- agent?: unknown;
6
- timestamp?: unknown;
7
- sessionId?: unknown;
8
- taskIndex?: unknown;
9
- totalTasks?: unknown;
10
- success?: unknown;
11
- }
12
-
13
- function asNonEmptyString(value: unknown): string | undefined {
14
- if (typeof value !== "string") return undefined;
15
- const trimmed = value.trim();
16
- return trimmed.length > 0 ? trimmed : undefined;
17
- }
18
-
19
- function asFiniteNumber(value: unknown): number | undefined {
20
- if (typeof value !== "number") return undefined;
21
- return Number.isFinite(value) ? value : undefined;
22
- }
23
-
24
- export function buildCompletionKey(data: CompletionDataLike, fallback: string): string {
25
- const id = asNonEmptyString(data.id);
26
- if (id) return `id:${id}`;
27
- const sessionId = asNonEmptyString(data.sessionId) ?? "no-session";
28
- const agent = asNonEmptyString(data.agent) ?? "unknown";
29
- const timestamp = asFiniteNumber(data.timestamp);
30
- const taskIndex = asFiniteNumber(data.taskIndex);
31
- const totalTasks = asFiniteNumber(data.totalTasks);
32
- const success = typeof data.success === "boolean" ? (data.success ? "1" : "0") : "?";
33
- return [
34
- "meta",
35
- sessionId,
36
- agent,
37
- timestamp !== undefined ? String(timestamp) : "no-ts",
38
- taskIndex !== undefined ? String(taskIndex) : "-",
39
- totalTasks !== undefined ? String(totalTasks) : "-",
40
- success,
41
- fallback,
42
- ].join(":");
43
- }
44
-
45
- export function pruneSeenMap(seen: Map<string, number>, now: number, ttlMs: number): void {
46
- for (const [key, ts] of seen.entries()) {
47
- if (now - ts > ttlMs) seen.delete(key);
48
- }
49
- }
50
-
51
- export function markSeenWithTtl(seen: Map<string, number>, key: string, now: number, ttlMs: number): boolean {
52
- pruneSeenMap(seen, now, ttlMs);
53
- if (seen.has(key)) return true;
54
- seen.set(key, now);
55
- return false;
56
- }
57
-
58
- export function getGlobalSeenMap(storeKey: string): Map<string, number> {
59
- const globalStore = globalThis as Record<string, unknown>;
60
- const existing = globalStore[storeKey];
61
- if (existing instanceof Map) return existing as Map<string, number>;
62
- const map = new Map<string, number>();
63
- globalStore[storeKey] = map;
64
- return map;
65
- }
@@ -1,200 +0,0 @@
1
- // Based on pi-subagents by Nico Bailon (https://github.com/nicobailon/pi-subagents)
2
- // MIT License
3
- import * as fs from "node:fs";
4
- import * as path from "node:path";
5
- import { discoverAgentsAll, type AgentSource } from "./agents.ts";
6
- import { isAsyncAvailable } from "./async-execution.ts";
7
- import { diagnoseIntercomBridge, type IntercomBridgeDiagnostic } from "./intercom-bridge.ts";
8
- import { discoverAvailableSkills, type SkillSource } from "./skills.ts";
9
- import {
10
- ASYNC_DIR,
11
- CHAIN_RUNS_DIR,
12
- RESULTS_DIR,
13
- TEMP_ROOT_DIR,
14
- type ExtensionConfig,
15
- type SubagentState,
16
- } from "./types.ts";
17
-
18
- interface DoctorPaths {
19
- tempRootDir: string;
20
- asyncDir: string;
21
- resultsDir: string;
22
- chainRunsDir: string;
23
- }
24
-
25
- interface DoctorDeps {
26
- isAsyncAvailable: () => boolean;
27
- discoverAgentsAll: typeof discoverAgentsAll;
28
- discoverAvailableSkills: typeof discoverAvailableSkills;
29
- diagnoseIntercomBridge: typeof diagnoseIntercomBridge;
30
- }
31
-
32
- export interface DoctorReportInput {
33
- cwd: string;
34
- config: ExtensionConfig;
35
- state: SubagentState;
36
- context?: "fresh" | "fork";
37
- requestedSessionDir?: string;
38
- currentSessionFile?: string | null;
39
- currentSessionId?: string | null;
40
- orchestratorTarget?: string;
41
- sessionError?: string;
42
- expandTilde?: (value: string) => string;
43
- paths?: DoctorPaths;
44
- deps?: Partial<DoctorDeps>;
45
- }
46
-
47
- const DEFAULT_PATHS: DoctorPaths = {
48
- tempRootDir: TEMP_ROOT_DIR,
49
- asyncDir: ASYNC_DIR,
50
- resultsDir: RESULTS_DIR,
51
- chainRunsDir: CHAIN_RUNS_DIR,
52
- };
53
-
54
- const DEFAULT_DEPS: DoctorDeps = {
55
- isAsyncAvailable,
56
- discoverAgentsAll,
57
- discoverAvailableSkills,
58
- diagnoseIntercomBridge,
59
- };
60
-
61
- function errorText(error: unknown): string {
62
- return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
63
- }
64
-
65
- function lineFromCheck(label: string, check: () => string): string {
66
- try {
67
- return check();
68
- } catch (error) {
69
- return `- ${label}: failed — ${errorText(error)}`;
70
- }
71
- }
72
-
73
- function formatExistingDirectory(label: string, dirPath: string): string {
74
- try {
75
- if (!fs.existsSync(dirPath)) return `- ${label}: missing (${dirPath})`;
76
- const stats = fs.statSync(dirPath);
77
- if (!stats.isDirectory()) throw new Error(`not a directory: ${dirPath}`);
78
- fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
79
- return `- ${label}: ok (${dirPath})`;
80
- } catch (error) {
81
- return `- ${label}: failed (${dirPath}) — ${errorText(error)}`;
82
- }
83
- }
84
-
85
- function formatSourceCounts(counts: Record<AgentSource, number>): string {
86
- return `builtin ${counts.builtin}, user ${counts.user}, project ${counts.project}`;
87
- }
88
-
89
- function formatSkillSourceCounts(skills: Array<{ source: SkillSource }>): string {
90
- const counts = new Map<SkillSource, number>();
91
- for (const skill of skills) counts.set(skill.source, (counts.get(skill.source) ?? 0) + 1);
92
- const ordered: SkillSource[] = [
93
- "project",
94
- "project-settings",
95
- "project-package",
96
- "user",
97
- "user-settings",
98
- "user-package",
99
- "extension",
100
- "builtin",
101
- "unknown",
102
- ];
103
- const parts = ordered
104
- .map((source) => `${source} ${counts.get(source) ?? 0}`)
105
- .filter((part) => !part.endsWith(" 0"));
106
- return parts.length > 0 ? parts.join(", ") : "none";
107
- }
108
-
109
- function formatConfiguredSessionDir(input: DoctorReportInput): string {
110
- if (input.requestedSessionDir) {
111
- return path.resolve(input.expandTilde?.(input.requestedSessionDir) ?? input.requestedSessionDir);
112
- }
113
- if (input.config.defaultSessionDir) {
114
- return path.resolve(input.expandTilde?.(input.config.defaultSessionDir) ?? input.config.defaultSessionDir);
115
- }
116
- return "not configured";
117
- }
118
-
119
- function formatSessionLines(input: DoctorReportInput): string[] {
120
- const sessionFile = input.currentSessionFile ?? null;
121
- const lines = [
122
- lineFromCheck("configured session dir", () => `- configured session dir: ${formatConfiguredSessionDir(input)}`),
123
- `- current session file: ${sessionFile ?? "not available"}`,
124
- `- current session dir: ${sessionFile ? path.dirname(sessionFile) : "not available"}`,
125
- `- current session id: ${input.currentSessionId ?? input.state.currentSessionId ?? "not available"}`,
126
- ];
127
- if (input.sessionError) lines.push(`- session manager: failed — ${input.sessionError}`);
128
- return lines;
129
- }
130
-
131
- function formatDiscovery(input: DoctorReportInput, deps: DoctorDeps): string[] {
132
- return [
133
- lineFromCheck("agents/chains", () => {
134
- const discovered = deps.discoverAgentsAll(input.cwd);
135
- const agentCounts = {
136
- builtin: discovered.builtin.length,
137
- user: discovered.user.length,
138
- project: discovered.project.length,
139
- };
140
- const chainCounts = discovered.chains.reduce<Record<AgentSource, number>>((counts, chain) => {
141
- counts[chain.source] += 1;
142
- return counts;
143
- }, { builtin: 0, user: 0, project: 0 });
144
- return [
145
- `- agents: total ${agentCounts.builtin + agentCounts.user + agentCounts.project} (${formatSourceCounts(agentCounts)})`,
146
- `- chains: total ${discovered.chains.length} (${formatSourceCounts(chainCounts)})`,
147
- ].join("\n");
148
- }),
149
- lineFromCheck("skills", () => {
150
- const skills = deps.discoverAvailableSkills(input.cwd);
151
- return `- skills: total ${skills.length} (${formatSkillSourceCounts(skills)})`;
152
- }),
153
- ];
154
- }
155
-
156
- function formatIntercomDiagnostic(diagnostic: IntercomBridgeDiagnostic, context: "fresh" | "fork" | undefined): string[] {
157
- const lines = [
158
- `- bridge: ${diagnostic.active ? "active" : "inactive"}${diagnostic.reason ? ` (${diagnostic.reason})` : ""}`,
159
- `- mode: ${diagnostic.mode}; context: ${context ?? "unspecified"}`,
160
- `- orchestrator target: ${diagnostic.orchestratorTarget ?? "not available"}`,
161
- `- pi-intercom: ${diagnostic.piIntercomAvailable ? "available" : "unavailable"} at ${diagnostic.extensionDir}`,
162
- ];
163
- if (diagnostic.configPath && diagnostic.intercomConfigEnabled !== undefined) {
164
- lines.push(`- intercom config: ${diagnostic.intercomConfigEnabled === false ? "disabled" : "enabled or absent"} (${diagnostic.configPath})`);
165
- }
166
- if (diagnostic.intercomConfigError) {
167
- lines.push(`- intercom config warning: ${diagnostic.intercomConfigError}; runtime assumes enabled`);
168
- }
169
- return lines;
170
- }
171
-
172
- export function buildDoctorReport(input: DoctorReportInput): string {
173
- const paths = input.paths ?? DEFAULT_PATHS;
174
- const deps = { ...DEFAULT_DEPS, ...input.deps };
175
- const lines = [
176
- "Subagents doctor report",
177
- "",
178
- "Runtime",
179
- `- cwd: ${input.cwd}`,
180
- lineFromCheck("async support", () => `- async support: ${deps.isAsyncAvailable() ? "available" : "unavailable"}`),
181
- ...formatSessionLines(input),
182
- "",
183
- "Filesystem",
184
- formatExistingDirectory("temp root", paths.tempRootDir),
185
- formatExistingDirectory("async runs", paths.asyncDir),
186
- formatExistingDirectory("results", paths.resultsDir),
187
- formatExistingDirectory("chain runs", paths.chainRunsDir),
188
- "",
189
- "Discovery",
190
- ...formatDiscovery(input, deps),
191
- "",
192
- "Intercom bridge",
193
- ...lineFromCheck("intercom bridge", () => formatIntercomDiagnostic(deps.diagnoseIntercomBridge({
194
- config: input.config.intercomBridge,
195
- context: input.context,
196
- orchestratorTarget: input.orchestratorTarget,
197
- }), input.context).join("\n")).split("\n"),
198
- ];
199
- return lines.join("\n");
200
- }