@leing2021/super-pi 0.14.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 (53) hide show
  1. package/README.md +372 -0
  2. package/extensions/.gitkeep +0 -0
  3. package/extensions/ce-core/index.ts +528 -0
  4. package/extensions/ce-core/tools/artifact-helper.ts +73 -0
  5. package/extensions/ce-core/tools/ask-user-question.ts +53 -0
  6. package/extensions/ce-core/tools/brainstorm-dialog.ts +167 -0
  7. package/extensions/ce-core/tools/parallel-subagent.ts +54 -0
  8. package/extensions/ce-core/tools/pattern-extractor.ts +139 -0
  9. package/extensions/ce-core/tools/plan-diff.ts +136 -0
  10. package/extensions/ce-core/tools/review-router.ts +95 -0
  11. package/extensions/ce-core/tools/session-checkpoint.ts +212 -0
  12. package/extensions/ce-core/tools/session-history.ts +117 -0
  13. package/extensions/ce-core/tools/subagent.ts +59 -0
  14. package/extensions/ce-core/tools/task-splitter.ts +122 -0
  15. package/extensions/ce-core/tools/workflow-state.ts +80 -0
  16. package/extensions/ce-core/tools/worktree-manager.ts +131 -0
  17. package/extensions/ce-core/utils/artifact-paths.ts +23 -0
  18. package/extensions/ce-core/utils/name-utils.ts +8 -0
  19. package/package.json +53 -0
  20. package/skills/.gitkeep +0 -0
  21. package/skills/01-brainstorm/SKILL.md +120 -0
  22. package/skills/01-brainstorm/references/builder-mode.md +39 -0
  23. package/skills/01-brainstorm/references/handoff.md +8 -0
  24. package/skills/01-brainstorm/references/premise-challenge.md +23 -0
  25. package/skills/01-brainstorm/references/requirements-template.md +25 -0
  26. package/skills/01-brainstorm/references/startup-diagnostic.md +108 -0
  27. package/skills/02-plan/SKILL.md +77 -0
  28. package/skills/02-plan/references/ceo-review-mode.md +130 -0
  29. package/skills/02-plan/references/handoff.md +8 -0
  30. package/skills/02-plan/references/implementation-unit-template.md +25 -0
  31. package/skills/02-plan/references/plan-template.md +21 -0
  32. package/skills/03-work/SKILL.md +65 -0
  33. package/skills/03-work/references/handoff.md +8 -0
  34. package/skills/03-work/references/progress-update-format.md +17 -0
  35. package/skills/04-review/SKILL.md +72 -0
  36. package/skills/04-review/references/findings-schema.md +17 -0
  37. package/skills/04-review/references/handoff.md +20 -0
  38. package/skills/04-review/references/qa-test-mode.md +134 -0
  39. package/skills/04-review/references/reviewer-selection.md +24 -0
  40. package/skills/05-compound/SKILL.md +32 -0
  41. package/skills/05-compound/assets/solution-template.md +27 -0
  42. package/skills/05-compound/references/category-map.md +9 -0
  43. package/skills/05-compound/references/overlap-rules.md +7 -0
  44. package/skills/05-compound/references/solution-schema.yaml +27 -0
  45. package/skills/05-compound/references/solution-search-strategy.md +60 -0
  46. package/skills/06-next/SKILL.md +37 -0
  47. package/skills/06-next/references/recommendation-logic.md +46 -0
  48. package/skills/07-worktree/SKILL.md +35 -0
  49. package/skills/07-worktree/references/worktree-lifecycle.md +22 -0
  50. package/skills/08-status/SKILL.md +41 -0
  51. package/skills/08-status/references/artifact-locations.md +10 -0
  52. package/skills/09-help/SKILL.md +37 -0
  53. package/skills/09-help/references/workflow-sequence.md +9 -0
@@ -0,0 +1,167 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises"
2
+ import path from "node:path"
3
+ import { normalizeSlug } from "../utils/name-utils"
4
+
5
+ export interface BrainstormDialogInput {
6
+ operation: "start" | "refine" | "summarize"
7
+ repoRoot: string
8
+ artifactPath: string
9
+ analysis?: string
10
+ questions?: string[]
11
+ userResponses?: string[]
12
+ }
13
+
14
+ export interface DialogState {
15
+ artifactPath: string
16
+ round: number
17
+ status: "in_progress" | "complete"
18
+ analysis: string
19
+ openQuestions: string[]
20
+ history: DialogRound[]
21
+ }
22
+
23
+ export interface DialogRound {
24
+ round: number
25
+ analysis: string
26
+ questions: string[]
27
+ userResponses: string[]
28
+ }
29
+
30
+ export interface BrainstormDialogResult {
31
+ artifactPath: string
32
+ round: number
33
+ status: "in_progress" | "complete"
34
+ analysis: string
35
+ openQuestions: string[]
36
+ }
37
+
38
+ function dialogDir(repoRoot: string): string {
39
+ return path.join(repoRoot, ".context", "compound-engineering", "dialogs")
40
+ }
41
+
42
+ function dialogPath(repoRoot: string, artifactPath: string): string {
43
+ const slug = normalizeSlug(artifactPath.replace(/\//g, "-"))
44
+ return path.join(dialogDir(repoRoot), `${slug}.json`)
45
+ }
46
+
47
+ export function createBrainstormDialogTool() {
48
+ return {
49
+ name: "brainstorm_dialog",
50
+ async execute(input: BrainstormDialogInput): Promise<BrainstormDialogResult> {
51
+ switch (input.operation) {
52
+ case "start":
53
+ return startDialog(input)
54
+ case "refine":
55
+ return refineDialog(input)
56
+ case "summarize":
57
+ return summarizeDialog(input)
58
+ default:
59
+ throw new Error(`Unknown operation: ${input.operation}`)
60
+ }
61
+ },
62
+ }
63
+ }
64
+
65
+ async function readState(repoRoot: string, artifactPath: string): Promise<DialogState | null> {
66
+ const filePath = dialogPath(repoRoot, artifactPath)
67
+ try {
68
+ const content = await readFile(filePath, "utf8")
69
+ return JSON.parse(content)
70
+ } catch {
71
+ return null
72
+ }
73
+ }
74
+
75
+ async function writeState(repoRoot: string, state: DialogState): Promise<void> {
76
+ const filePath = dialogPath(repoRoot, state.artifactPath)
77
+ await mkdir(path.dirname(filePath), { recursive: true })
78
+ await writeFile(filePath, JSON.stringify(state, null, 2), "utf8")
79
+ }
80
+
81
+ async function startDialog(input: BrainstormDialogInput): Promise<BrainstormDialogResult> {
82
+ const existing = await readState(input.repoRoot, input.artifactPath)
83
+ if (existing) {
84
+ return {
85
+ artifactPath: existing.artifactPath,
86
+ round: existing.round,
87
+ status: existing.status,
88
+ analysis: existing.analysis,
89
+ openQuestions: existing.openQuestions,
90
+ }
91
+ }
92
+
93
+ const state: DialogState = {
94
+ artifactPath: input.artifactPath,
95
+ round: 1,
96
+ status: "in_progress",
97
+ analysis: input.analysis ?? "",
98
+ openQuestions: input.questions ?? [],
99
+ history: [
100
+ {
101
+ round: 1,
102
+ analysis: input.analysis ?? "",
103
+ questions: input.questions ?? [],
104
+ userResponses: [],
105
+ },
106
+ ],
107
+ }
108
+
109
+ await writeState(input.repoRoot, state)
110
+
111
+ return {
112
+ artifactPath: state.artifactPath,
113
+ round: state.round,
114
+ status: state.status,
115
+ analysis: state.analysis,
116
+ openQuestions: state.openQuestions,
117
+ }
118
+ }
119
+
120
+ async function refineDialog(input: BrainstormDialogInput): Promise<BrainstormDialogResult> {
121
+ const existing = await readState(input.repoRoot, input.artifactPath)
122
+ if (!existing) {
123
+ throw new Error("No dialog found. Use 'start' first.")
124
+ }
125
+
126
+ existing.round += 1
127
+ existing.analysis = input.analysis ?? existing.analysis
128
+ existing.openQuestions = input.questions ?? []
129
+
130
+ existing.history.push({
131
+ round: existing.round,
132
+ analysis: existing.analysis,
133
+ questions: existing.openQuestions,
134
+ userResponses: input.userResponses ?? [],
135
+ })
136
+
137
+ await writeState(input.repoRoot, existing)
138
+
139
+ return {
140
+ artifactPath: existing.artifactPath,
141
+ round: existing.round,
142
+ status: existing.status,
143
+ analysis: existing.analysis,
144
+ openQuestions: existing.openQuestions,
145
+ }
146
+ }
147
+
148
+ async function summarizeDialog(input: BrainstormDialogInput): Promise<BrainstormDialogResult> {
149
+ const existing = await readState(input.repoRoot, input.artifactPath)
150
+ if (!existing) {
151
+ throw new Error("No dialog found. Use 'start' first.")
152
+ }
153
+
154
+ existing.status = "complete"
155
+ existing.analysis = input.analysis ?? existing.analysis
156
+ existing.openQuestions = []
157
+
158
+ await writeState(input.repoRoot, existing)
159
+
160
+ return {
161
+ artifactPath: existing.artifactPath,
162
+ round: existing.round,
163
+ status: existing.status,
164
+ analysis: existing.analysis,
165
+ openQuestions: [],
166
+ }
167
+ }
@@ -0,0 +1,54 @@
1
+ export interface ParallelSubagentTask {
2
+ agent: string
3
+ task: string
4
+ }
5
+
6
+ export interface ParallelSubagentInput {
7
+ tasks: ParallelSubagentTask[]
8
+ }
9
+
10
+ export interface ParallelResultItem {
11
+ status: "fulfilled" | "rejected"
12
+ value?: string
13
+ reason?: string
14
+ }
15
+
16
+ export interface ParallelSubagentResult {
17
+ mode: "parallel"
18
+ outputs: ParallelResultItem[]
19
+ }
20
+
21
+ export type SubagentRunner = (prompt: string) => Promise<string>
22
+
23
+ function buildPrompt(agent: string, task: string): string {
24
+ return `/skill:${agent} ${task}`
25
+ }
26
+
27
+ export function createParallelSubagentTool() {
28
+ return {
29
+ name: "parallel_subagent",
30
+ async execute(input: ParallelSubagentInput, runner: SubagentRunner): Promise<ParallelSubagentResult> {
31
+ if (!input.tasks || input.tasks.length === 0) {
32
+ throw new Error("parallel_subagent requires at least one task")
33
+ }
34
+
35
+ const promises = input.tasks.map(({ agent, task }) =>
36
+ runner(buildPrompt(agent, task)),
37
+ )
38
+
39
+ const settled = await Promise.allSettled(promises)
40
+
41
+ const outputs: ParallelResultItem[] = settled.map((result) => {
42
+ if (result.status === "fulfilled") {
43
+ return { status: "fulfilled", value: result.value }
44
+ }
45
+ return { status: "rejected", reason: result.reason?.message || String(result.reason) }
46
+ })
47
+
48
+ return {
49
+ mode: "parallel",
50
+ outputs,
51
+ }
52
+ },
53
+ }
54
+ }
@@ -0,0 +1,139 @@
1
+ export interface ArtifactInput {
2
+ path: string
3
+ content: string
4
+ }
5
+
6
+ export interface Pattern {
7
+ keyword: string
8
+ occurrences: number
9
+ sources: string[]
10
+ }
11
+
12
+ export interface ExtractInput {
13
+ operation: "extract"
14
+ artifacts: ArtifactInput[]
15
+ keywords?: string[]
16
+ }
17
+
18
+ export interface ExtractResult {
19
+ operation: "extract"
20
+ patterns: Pattern[]
21
+ }
22
+
23
+ export interface CategorizeInput {
24
+ operation: "categorize"
25
+ patterns: Pattern[]
26
+ categories: Record<string, string[]>
27
+ }
28
+
29
+ export interface CategorizeResult {
30
+ operation: "categorize"
31
+ categories: Record<string, Pattern[]>
32
+ uncategorized: Pattern[]
33
+ }
34
+
35
+ export type PatternExtractorInput = ExtractInput | CategorizeInput | { operation: string; artifacts?: ArtifactInput[] }
36
+ export type PatternExtractorResult = ExtractResult | CategorizeResult
37
+
38
+ function extractKeywords(content: string): string[] {
39
+ return content
40
+ .toLowerCase()
41
+ .replace(/[^a-z0-9\s]/g, " ")
42
+ .split(/\s+/)
43
+ .filter((w) => w.length > 2)
44
+ }
45
+
46
+ function extractWithKeywords(artifacts: ArtifactInput[], keywords: string[]): Pattern[] {
47
+ const patterns: Pattern[] = []
48
+
49
+ for (const keyword of keywords) {
50
+ const sources: string[] = []
51
+ let occurrences = 0
52
+
53
+ for (const artifact of artifacts) {
54
+ const regex = new RegExp(keyword, "gi")
55
+ const matches = artifact.content.match(regex)
56
+ if (matches && matches.length > 0) {
57
+ occurrences += matches.length
58
+ sources.push(artifact.path)
59
+ }
60
+ }
61
+
62
+ if (occurrences > 0) {
63
+ patterns.push({ keyword, occurrences, sources })
64
+ }
65
+ }
66
+
67
+ return patterns.sort((a, b) => b.occurrences - a.occurrences)
68
+ }
69
+
70
+ function extractAllKeywords(artifacts: ArtifactInput[]): Pattern[] {
71
+ const wordMap = new Map<string, { count: number; sources: Set<string> }>()
72
+
73
+ for (const artifact of artifacts) {
74
+ const words = extractKeywords(artifact.content)
75
+ const uniqueWords = new Set(words)
76
+
77
+ for (const word of uniqueWords) {
78
+ const existing = wordMap.get(word) ?? { count: 0, sources: new Set<string>() }
79
+ existing.count += words.filter((w) => w === word).length
80
+ existing.sources.add(artifact.path)
81
+ wordMap.set(word, existing)
82
+ }
83
+ }
84
+
85
+ return Array.from(wordMap.entries())
86
+ .map(([keyword, data]) => ({
87
+ keyword,
88
+ occurrences: data.count,
89
+ sources: Array.from(data.sources),
90
+ }))
91
+ .sort((a, b) => b.occurrences - a.occurrences)
92
+ }
93
+
94
+ export function createPatternExtractorTool() {
95
+ return {
96
+ name: "pattern_extractor",
97
+ execute(input: PatternExtractorInput): PatternExtractorResult {
98
+ switch (input.operation) {
99
+ case "extract": {
100
+ const artifacts = (input as ExtractInput).artifacts
101
+ const keywords = (input as ExtractInput).keywords
102
+ const patterns = keywords && keywords.length > 0
103
+ ? extractWithKeywords(artifacts, keywords)
104
+ : extractAllKeywords(artifacts)
105
+ return { operation: "extract", patterns }
106
+ }
107
+ case "categorize": {
108
+ const { patterns, categories } = input as CategorizeInput
109
+ const result: Record<string, Pattern[]> = {}
110
+ const uncategorized: Pattern[] = []
111
+ const matched = new Set<string>()
112
+
113
+ for (const [category, catKeywords] of Object.entries(categories)) {
114
+ result[category] = []
115
+ }
116
+
117
+ for (const pattern of patterns) {
118
+ let found = false
119
+ for (const [category, catKeywords] of Object.entries(categories)) {
120
+ if (catKeywords.some((kw) => kw.toLowerCase() === pattern.keyword.toLowerCase())) {
121
+ result[category].push(pattern)
122
+ matched.add(pattern.keyword)
123
+ found = true
124
+ break
125
+ }
126
+ }
127
+ if (!found) {
128
+ uncategorized.push(pattern)
129
+ }
130
+ }
131
+
132
+ return { operation: "categorize", categories: result, uncategorized }
133
+ }
134
+ default:
135
+ throw new Error(`Unknown operation: ${input.operation}`)
136
+ }
137
+ },
138
+ }
139
+ }
@@ -0,0 +1,136 @@
1
+ export interface PlanUnit {
2
+ name: string
3
+ description: string
4
+ files: string[]
5
+ }
6
+
7
+ export interface PlanChange {
8
+ action: "add" | "remove" | "modify"
9
+ name: string
10
+ description?: string
11
+ files?: string[]
12
+ }
13
+
14
+ export interface PlanDiffInput {
15
+ operation: "compare" | "patch"
16
+ existingUnits: PlanUnit[]
17
+ newRequirements?: PlanUnit[]
18
+ changes?: PlanChange[]
19
+ }
20
+
21
+ export interface CompareResult {
22
+ operation: "compare"
23
+ added: PlanUnit[]
24
+ removed: PlanUnit[]
25
+ modified: PlanUnit[]
26
+ unchanged: PlanUnit[]
27
+ }
28
+
29
+ export interface PatchResult {
30
+ operation: "patch"
31
+ units: PlanUnit[]
32
+ appliedChanges: number
33
+ }
34
+
35
+ export type PlanDiffResult = CompareResult | PatchResult
36
+
37
+ function unitKey(u: PlanUnit): string {
38
+ return u.name
39
+ }
40
+
41
+ function unitsEqual(a: PlanUnit, b: PlanUnit): boolean {
42
+ return (
43
+ a.description === b.description &&
44
+ a.files.length === b.files.length &&
45
+ a.files.every((f, i) => f === b.files[i])
46
+ )
47
+ }
48
+
49
+ export function createPlanDiffTool() {
50
+ return {
51
+ name: "plan_diff",
52
+ execute(input: PlanDiffInput): PlanDiffResult {
53
+ switch (input.operation) {
54
+ case "compare":
55
+ return compare(input.existingUnits, input.newRequirements ?? [])
56
+ case "patch":
57
+ return patch(input.existingUnits, input.changes ?? [])
58
+ default:
59
+ throw new Error(`Unknown operation: ${input.operation}`)
60
+ }
61
+ },
62
+ }
63
+ }
64
+
65
+ function compare(existing: PlanUnit[], newReqs: PlanUnit[]): CompareResult {
66
+ const existingMap = new Map(existing.map((u) => [unitKey(u), u]))
67
+ const newMap = new Map(newReqs.map((u) => [unitKey(u), u]))
68
+
69
+ const added: PlanUnit[] = []
70
+ const removed: PlanUnit[] = []
71
+ const modified: PlanUnit[] = []
72
+ const unchanged: PlanUnit[] = []
73
+
74
+ // Find added and modified
75
+ for (const [key, newUnit] of newMap) {
76
+ const existingUnit = existingMap.get(key)
77
+ if (!existingUnit) {
78
+ added.push(newUnit)
79
+ } else if (!unitsEqual(existingUnit, newUnit)) {
80
+ modified.push(newUnit)
81
+ } else {
82
+ unchanged.push(newUnit)
83
+ }
84
+ }
85
+
86
+ // Find removed
87
+ for (const [key, existingUnit] of existingMap) {
88
+ if (!newMap.has(key)) {
89
+ removed.push(existingUnit)
90
+ }
91
+ }
92
+
93
+ return { operation: "compare", added, removed, modified, unchanged }
94
+ }
95
+
96
+ function patch(existing: PlanUnit[], changes: PlanChange[]): PatchResult {
97
+ const unitMap = new Map(existing.map((u) => [unitKey(u), { ...u }]))
98
+ let appliedChanges = 0
99
+
100
+ for (const change of changes) {
101
+ switch (change.action) {
102
+ case "add":
103
+ unitMap.set(change.name, {
104
+ name: change.name,
105
+ description: change.description ?? "",
106
+ files: change.files ?? [],
107
+ })
108
+ appliedChanges++
109
+ break
110
+ case "remove":
111
+ if (unitMap.has(change.name)) {
112
+ unitMap.delete(change.name)
113
+ appliedChanges++
114
+ }
115
+ break
116
+ case "modify": {
117
+ const existing = unitMap.get(change.name)
118
+ if (existing) {
119
+ unitMap.set(change.name, {
120
+ ...existing,
121
+ description: change.description ?? existing.description,
122
+ files: change.files ?? existing.files,
123
+ })
124
+ appliedChanges++
125
+ }
126
+ break
127
+ }
128
+ }
129
+ }
130
+
131
+ return {
132
+ operation: "patch",
133
+ units: Array.from(unitMap.values()),
134
+ appliedChanges,
135
+ }
136
+ }
@@ -0,0 +1,95 @@
1
+ export interface ReviewRouterInput {
2
+ filesChanged: string[]
3
+ insertions: number
4
+ deletions: number
5
+ }
6
+
7
+ export interface ReviewerRecommendation {
8
+ name: string
9
+ reason: string
10
+ }
11
+
12
+ export interface ReviewRouterResult {
13
+ reviewers: ReviewerRecommendation[]
14
+ }
15
+
16
+ interface ReviewerRule {
17
+ name: string
18
+ reason: string
19
+ condition: (input: ReviewRouterInput) => boolean
20
+ }
21
+
22
+ const BASE_REVIEWERS: ReviewerRule[] = [
23
+ {
24
+ name: "correctness-reviewer",
25
+ reason: "Always review for logical correctness and intended behavior.",
26
+ condition: () => true,
27
+ },
28
+ {
29
+ name: "testing-reviewer",
30
+ reason: "Always review test coverage and test quality.",
31
+ condition: () => true,
32
+ },
33
+ {
34
+ name: "maintainability-reviewer",
35
+ reason: "Always review code clarity, naming, and structure.",
36
+ condition: () => true,
37
+ },
38
+ ]
39
+
40
+ const CONDITIONAL_REVIEWERS: ReviewerRule[] = [
41
+ {
42
+ name: "security-reviewer",
43
+ reason: "Auth, permissions, or user input files were changed.",
44
+ condition: (input) =>
45
+ input.filesChanged.some((f) =>
46
+ /auth|permission|login|password|token|session|credential|crypto/i.test(f),
47
+ ),
48
+ },
49
+ {
50
+ name: "performance-reviewer",
51
+ reason: "Data, query, or cache-related files were changed.",
52
+ condition: (input) =>
53
+ input.filesChanged.some((f) =>
54
+ /query|cache|database|db\/|sql|perf|benchmark|stream|batch/i.test(f),
55
+ ),
56
+ },
57
+ {
58
+ name: "integration-reviewer",
59
+ reason: "Configuration, CI/CD, or package files were changed.",
60
+ condition: (input) =>
61
+ input.filesChanged.some((f) =>
62
+ /workflows|docker|compose|package\.json|tsconfig|\.env|config/i.test(f),
63
+ ),
64
+ },
65
+ {
66
+ name: "thoroughness-reviewer",
67
+ reason: "Large diff with many changes across multiple files.",
68
+ condition: (input) =>
69
+ input.filesChanged.length >= 5 ||
70
+ input.insertions + input.deletions >= 300,
71
+ },
72
+ ]
73
+
74
+ export function createReviewRouterTool() {
75
+ return {
76
+ name: "review_router",
77
+ async execute(input: ReviewRouterInput): Promise<ReviewRouterResult> {
78
+ const reviewers: ReviewerRecommendation[] = []
79
+
80
+ for (const rule of BASE_REVIEWERS) {
81
+ if (rule.condition(input)) {
82
+ reviewers.push({ name: rule.name, reason: rule.reason })
83
+ }
84
+ }
85
+
86
+ for (const rule of CONDITIONAL_REVIEWERS) {
87
+ if (rule.condition(input)) {
88
+ reviewers.push({ name: rule.name, reason: rule.reason })
89
+ }
90
+ }
91
+
92
+ return { reviewers }
93
+ },
94
+ }
95
+ }