workspace-maxxing 0.1.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 (198) hide show
  1. package/.agents/skills/workspace-maxxing/.workspace-templates/CONTEXT.md +44 -0
  2. package/.agents/skills/workspace-maxxing/.workspace-templates/SYSTEM.md +44 -0
  3. package/.agents/skills/workspace-maxxing/.workspace-templates/references/anti-patterns.md +16 -0
  4. package/.agents/skills/workspace-maxxing/.workspace-templates/references/iron-laws.md +26 -0
  5. package/.agents/skills/workspace-maxxing/.workspace-templates/references/reporting-format.md +52 -0
  6. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/benchmark.ts +171 -0
  7. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/dispatch.ts +473 -0
  8. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/generate-tests.ts +158 -0
  9. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/install-tool.ts +82 -0
  10. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/iterate.ts +265 -0
  11. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/orchestrator.ts +539 -0
  12. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/scaffold.ts +282 -0
  13. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/validate.ts +452 -0
  14. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/architecture/SKILL.md +95 -0
  15. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/fixer/SKILL.md +109 -0
  16. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/iteration/SKILL.md +89 -0
  17. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
  18. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/research/SKILL.md +94 -0
  19. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/testing/SKILL.md +89 -0
  20. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/tooling/SKILL.md +87 -0
  21. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/validation/SKILL.md +103 -0
  22. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/worker/SKILL.md +79 -0
  23. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
  24. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
  25. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
  26. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
  27. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
  28. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/README.md +14 -0
  29. package/.agents/skills/workspace-maxxing/SKILL.md +312 -0
  30. package/.agents/skills/workspace-maxxing/scripts/benchmark.ts +171 -0
  31. package/.agents/skills/workspace-maxxing/scripts/dispatch.ts +473 -0
  32. package/.agents/skills/workspace-maxxing/scripts/generate-tests.ts +158 -0
  33. package/.agents/skills/workspace-maxxing/scripts/install-tool.ts +82 -0
  34. package/.agents/skills/workspace-maxxing/scripts/iterate.ts +265 -0
  35. package/.agents/skills/workspace-maxxing/scripts/orchestrator.ts +539 -0
  36. package/.agents/skills/workspace-maxxing/scripts/scaffold.ts +282 -0
  37. package/.agents/skills/workspace-maxxing/scripts/validate.ts +452 -0
  38. package/README.md +144 -0
  39. package/dist/agent-creator.d.ts +9 -0
  40. package/dist/agent-creator.d.ts.map +1 -0
  41. package/dist/agent-creator.js +199 -0
  42. package/dist/agent-creator.js.map +1 -0
  43. package/dist/agent-iterator.d.ts +38 -0
  44. package/dist/agent-iterator.d.ts.map +1 -0
  45. package/dist/agent-iterator.js +327 -0
  46. package/dist/agent-iterator.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +197 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/install.d.ts +18 -0
  52. package/dist/install.d.ts.map +1 -0
  53. package/dist/install.js +117 -0
  54. package/dist/install.js.map +1 -0
  55. package/dist/platforms/claude.d.ts +7 -0
  56. package/dist/platforms/claude.d.ts.map +1 -0
  57. package/dist/platforms/claude.js +70 -0
  58. package/dist/platforms/claude.js.map +1 -0
  59. package/dist/platforms/copilot.d.ts +7 -0
  60. package/dist/platforms/copilot.d.ts.map +1 -0
  61. package/dist/platforms/copilot.js +75 -0
  62. package/dist/platforms/copilot.js.map +1 -0
  63. package/dist/platforms/gemini.d.ts +7 -0
  64. package/dist/platforms/gemini.d.ts.map +1 -0
  65. package/dist/platforms/gemini.js +81 -0
  66. package/dist/platforms/gemini.js.map +1 -0
  67. package/dist/platforms/index.d.ts +8 -0
  68. package/dist/platforms/index.d.ts.map +1 -0
  69. package/dist/platforms/index.js +41 -0
  70. package/dist/platforms/index.js.map +1 -0
  71. package/dist/platforms/opencode.d.ts +7 -0
  72. package/dist/platforms/opencode.d.ts.map +1 -0
  73. package/dist/platforms/opencode.js +70 -0
  74. package/dist/platforms/opencode.js.map +1 -0
  75. package/dist/scripts/benchmark.d.ts +20 -0
  76. package/dist/scripts/benchmark.d.ts.map +1 -0
  77. package/dist/scripts/benchmark.js +170 -0
  78. package/dist/scripts/benchmark.js.map +1 -0
  79. package/dist/scripts/dispatch.d.ts +32 -0
  80. package/dist/scripts/dispatch.d.ts.map +1 -0
  81. package/dist/scripts/dispatch.js +386 -0
  82. package/dist/scripts/dispatch.js.map +1 -0
  83. package/dist/scripts/generate-tests.d.ts +11 -0
  84. package/dist/scripts/generate-tests.d.ts.map +1 -0
  85. package/dist/scripts/generate-tests.js +118 -0
  86. package/dist/scripts/generate-tests.js.map +1 -0
  87. package/dist/scripts/install-tool.d.ts +8 -0
  88. package/dist/scripts/install-tool.d.ts.map +1 -0
  89. package/dist/scripts/install-tool.js +98 -0
  90. package/dist/scripts/install-tool.js.map +1 -0
  91. package/dist/scripts/iterate.d.ts +44 -0
  92. package/dist/scripts/iterate.d.ts.map +1 -0
  93. package/dist/scripts/iterate.js +260 -0
  94. package/dist/scripts/iterate.js.map +1 -0
  95. package/dist/scripts/orchestrator.d.ts +40 -0
  96. package/dist/scripts/orchestrator.d.ts.map +1 -0
  97. package/dist/scripts/orchestrator.js +378 -0
  98. package/dist/scripts/orchestrator.js.map +1 -0
  99. package/dist/scripts/scaffold.d.ts +8 -0
  100. package/dist/scripts/scaffold.d.ts.map +1 -0
  101. package/dist/scripts/scaffold.js +279 -0
  102. package/dist/scripts/scaffold.js.map +1 -0
  103. package/dist/scripts/validate.d.ts +11 -0
  104. package/dist/scripts/validate.d.ts.map +1 -0
  105. package/dist/scripts/validate.js +472 -0
  106. package/dist/scripts/validate.js.map +1 -0
  107. package/docs/superpowers/plans/2026-04-07-autonomous-iteration-plan.md +1123 -0
  108. package/docs/superpowers/plans/2026-04-07-autonomous-iteration-sub-agent-batches.md +1923 -0
  109. package/docs/superpowers/plans/2026-04-07-autonomous-workflow-sub-skill-plan.md +1505 -0
  110. package/docs/superpowers/plans/2026-04-07-benchmarking-multi-agent-plan.md +854 -0
  111. package/docs/superpowers/plans/2026-04-07-workspace-builder-logic-plan.md +1426 -0
  112. package/docs/superpowers/plans/2026-04-07-workspace-maxxing-plan.md +1299 -0
  113. package/docs/superpowers/plans/2026-04-08-session-294c-subagent-invocation-plan.md +320 -0
  114. package/docs/superpowers/plans/2026-04-08-workflow-prompt-hardening-plan.md +1025 -0
  115. package/docs/superpowers/plans/2026-04-12-workspace-agent-creation-plan.md +992 -0
  116. package/docs/superpowers/specs/2026-04-07-autonomous-iteration-design.md +214 -0
  117. package/docs/superpowers/specs/2026-04-07-autonomous-iteration-sub-agent-batches-design.md +188 -0
  118. package/docs/superpowers/specs/2026-04-07-autonomous-workflow-sub-skill-design.md +137 -0
  119. package/docs/superpowers/specs/2026-04-07-benchmarking-multi-agent-design.md +105 -0
  120. package/docs/superpowers/specs/2026-04-07-workspace-builder-logic-design.md +179 -0
  121. package/docs/superpowers/specs/2026-04-07-workspace-maxxing-design.md +227 -0
  122. package/docs/superpowers/specs/2026-04-08-session-294c-subagent-invocation-design.md +265 -0
  123. package/docs/superpowers/specs/2026-04-08-workflow-prompt-hardening-design.md +146 -0
  124. package/docs/superpowers/specs/2026-04-12-workspace-agent-creation-design.md +239 -0
  125. package/jest.config.js +8 -0
  126. package/package.json +32 -0
  127. package/src/agent-creator.ts +180 -0
  128. package/src/agent-iterator.ts +397 -0
  129. package/src/index.ts +189 -0
  130. package/src/install.ts +105 -0
  131. package/src/platforms/claude.ts +40 -0
  132. package/src/platforms/copilot.ts +50 -0
  133. package/src/platforms/gemini.ts +55 -0
  134. package/src/platforms/index.ts +45 -0
  135. package/src/platforms/opencode.ts +41 -0
  136. package/src/scripts/benchmark.ts +171 -0
  137. package/src/scripts/dispatch.ts +473 -0
  138. package/src/scripts/generate-tests.ts +112 -0
  139. package/src/scripts/install-tool.ts +82 -0
  140. package/src/scripts/iterate.ts +271 -0
  141. package/src/scripts/orchestrator.ts +539 -0
  142. package/src/scripts/scaffold.ts +282 -0
  143. package/src/scripts/validate.ts +516 -0
  144. package/templates/.workspace-templates/CONTEXT.md +44 -0
  145. package/templates/.workspace-templates/SYSTEM.md +44 -0
  146. package/templates/.workspace-templates/references/anti-patterns.md +16 -0
  147. package/templates/.workspace-templates/references/iron-laws.md +26 -0
  148. package/templates/.workspace-templates/references/reporting-format.md +52 -0
  149. package/templates/.workspace-templates/scripts/benchmark.ts +171 -0
  150. package/templates/.workspace-templates/scripts/dispatch.ts +473 -0
  151. package/templates/.workspace-templates/scripts/generate-tests.ts +158 -0
  152. package/templates/.workspace-templates/scripts/install-tool.ts +82 -0
  153. package/templates/.workspace-templates/scripts/iterate.ts +265 -0
  154. package/templates/.workspace-templates/scripts/orchestrator.ts +539 -0
  155. package/templates/.workspace-templates/scripts/scaffold.ts +282 -0
  156. package/templates/.workspace-templates/scripts/validate.ts +452 -0
  157. package/templates/.workspace-templates/skills/architecture/SKILL.md +95 -0
  158. package/templates/.workspace-templates/skills/fixer/SKILL.md +109 -0
  159. package/templates/.workspace-templates/skills/iteration/SKILL.md +89 -0
  160. package/templates/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
  161. package/templates/.workspace-templates/skills/research/SKILL.md +94 -0
  162. package/templates/.workspace-templates/skills/testing/SKILL.md +89 -0
  163. package/templates/.workspace-templates/skills/tooling/SKILL.md +87 -0
  164. package/templates/.workspace-templates/skills/validation/SKILL.md +103 -0
  165. package/templates/.workspace-templates/skills/worker/SKILL.md +79 -0
  166. package/templates/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
  167. package/templates/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
  168. package/templates/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
  169. package/templates/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
  170. package/templates/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
  171. package/templates/.workspace-templates/workspace/README.md +14 -0
  172. package/templates/SKILL.md +347 -0
  173. package/tests/benchmark.test.ts +158 -0
  174. package/tests/cli.test.ts +109 -0
  175. package/tests/dispatch-parallel.test.ts +124 -0
  176. package/tests/dispatch.test.ts +218 -0
  177. package/tests/fixer-skill.test.ts +203 -0
  178. package/tests/generate-tests.test.ts +101 -0
  179. package/tests/install-tool.test.ts +141 -0
  180. package/tests/install.test.ts +144 -0
  181. package/tests/integration.test.ts +324 -0
  182. package/tests/iterate.test.ts +219 -0
  183. package/tests/orchestrator.test.ts +710 -0
  184. package/tests/scaffold.test.ts +238 -0
  185. package/tests/templates-enhanced.test.ts +208 -0
  186. package/tests/templates.test.ts +219 -0
  187. package/tests/validate.test.ts +421 -0
  188. package/tests/validation-enhanced.test.ts +303 -0
  189. package/tests/worker-skill.test.ts +88 -0
  190. package/tsconfig.json +19 -0
  191. package/workspace/00-meta/CONTEXT.md +3 -0
  192. package/workspace/00-meta/execution-log.md +17 -0
  193. package/workspace/00-meta/tools.md +11 -0
  194. package/workspace/01-input/CONTEXT.md +27 -0
  195. package/workspace/CONTEXT.md +35 -0
  196. package/workspace/README.md +14 -0
  197. package/workspace/SYSTEM.md +36 -0
  198. package/workspace-maxxing-0.1.0.tgz +0 -0
@@ -0,0 +1,158 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ export interface TestCase {
5
+ stage: string;
6
+ type: 'sample' | 'edge-case' | 'empty';
7
+ input: string;
8
+ expected: string;
9
+ }
10
+
11
+ export interface TestCasesOutput {
12
+ testCases: TestCase[];
13
+ }
14
+
15
+ export function generateTestCases(
16
+ workspacePath: string,
17
+ outputPath?: string,
18
+ ): TestCasesOutput {
19
+ const ws = path.resolve(workspacePath);
20
+ const testCases: TestCase[] = [];
21
+ const workspaceDomain = detectWorkspaceDomain(ws);
22
+
23
+ const stageFolders = getNumberedFolders(ws);
24
+
25
+ if (stageFolders.length === 0) {
26
+ console.warn('Warning: No numbered stage folders found in workspace');
27
+ }
28
+
29
+ for (const stage of stageFolders) {
30
+ const contextPath = path.join(ws, stage, 'CONTEXT.md');
31
+ let purpose = '';
32
+ if (fs.existsSync(contextPath)) {
33
+ const content = fs.readFileSync(contextPath, 'utf-8');
34
+ const purposeMatch = content.match(/## Purpose\n([\s\S]*?)(?=##|$)/i);
35
+ if (purposeMatch) {
36
+ purpose = purposeMatch[1].trim();
37
+ }
38
+ }
39
+
40
+ testCases.push({
41
+ stage,
42
+ type: 'sample',
43
+ input: generateSampleInput(stage, purpose, workspaceDomain),
44
+ expected: `Stage should fulfill its purpose: ${purpose || 'handle stage-specific processing'}`,
45
+ });
46
+
47
+ testCases.push({
48
+ stage,
49
+ type: 'edge-case',
50
+ input: generateEdgeCaseInput(stage, workspaceDomain),
51
+ expected: `Stage should handle edge case gracefully`,
52
+ });
53
+
54
+ testCases.push({
55
+ stage,
56
+ type: 'empty',
57
+ input: '',
58
+ expected: `Stage should handle empty input gracefully`,
59
+ });
60
+ }
61
+
62
+ const result: TestCasesOutput = { testCases };
63
+
64
+ if (outputPath) {
65
+ fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
66
+ console.log(`Test cases written to: ${outputPath}`);
67
+ }
68
+
69
+ return result;
70
+ }
71
+
72
+ function generateSampleInput(stage: string, purpose: string, domain: string): string {
73
+ if (domain === 'sports-prediction') {
74
+ const sportsSamples: Record<string, string> = {
75
+ '01-input': 'Barcelona vs Real Madrid next match prediction request with team form and injury notes',
76
+ '02-process': 'UCL finals winner prediction using recent xG, head-to-head history, and squad availability',
77
+ '03-output': 'Liverpool vs Arsenal game prediction with confidence score and rationale summary',
78
+ };
79
+
80
+ return sportsSamples[stage] || `Sports match outcome prediction scenario for ${stage}`;
81
+ }
82
+
83
+ const samples: Record<string, string> = {
84
+ '01-input': 'A sample input document with valid data for processing',
85
+ '02-process': 'Processed data from the input stage ready for transformation',
86
+ '03-output': 'Final processed data ready for report generation',
87
+ };
88
+ return samples[stage] || `Sample data for ${stage}`;
89
+ }
90
+
91
+ function generateEdgeCaseInput(stage: string, domain: string): string {
92
+ if (domain === 'sports-prediction') {
93
+ const sportsEdgeCases: Record<string, string> = {
94
+ '01-input': 'Barcelona vs Real Madrid request missing kickoff date and missing expected league context',
95
+ '02-process': 'UCL finals winner scenario with conflicting bookmaker odds and incomplete player availability data',
96
+ '03-output': 'Liverpool vs Arsenal prediction where confidence exceeds bounds and explanation is inconsistent',
97
+ };
98
+
99
+ return sportsEdgeCases[stage] || `Sports prediction edge case data for ${stage}`;
100
+ }
101
+
102
+ const edgeCases: Record<string, string> = {
103
+ '01-input': 'Input with special characters: <>&"\' and very long text that exceeds normal length expectations',
104
+ '02-process': 'Data with missing fields and inconsistent formatting',
105
+ '03-output': 'Conflicting output requirements from upstream stages',
106
+ };
107
+ return edgeCases[stage] || `Edge case data for ${stage}`;
108
+ }
109
+
110
+ function detectWorkspaceDomain(workspacePath: string): string {
111
+ const filesToScan = ['SYSTEM.md', 'CONTEXT.md'];
112
+ const textChunks: string[] = [];
113
+
114
+ for (const fileName of filesToScan) {
115
+ const filePath = path.join(workspacePath, fileName);
116
+ if (fs.existsSync(filePath)) {
117
+ textChunks.push(fs.readFileSync(filePath, 'utf-8'));
118
+ }
119
+ }
120
+
121
+ const stageFolders = getNumberedFolders(workspacePath);
122
+ for (const stage of stageFolders) {
123
+ const contextPath = path.join(workspacePath, stage, 'CONTEXT.md');
124
+ if (fs.existsSync(contextPath)) {
125
+ textChunks.push(fs.readFileSync(contextPath, 'utf-8'));
126
+ }
127
+ }
128
+
129
+ const corpus = textChunks.join('\n').toLowerCase();
130
+ const sportsPredictionMatch = /(football|soccer|ucl|champions league|match prediction|sports prediction|game prediction)/i.test(corpus);
131
+
132
+ return sportsPredictionMatch ? 'sports-prediction' : 'generic';
133
+ }
134
+
135
+ function getNumberedFolders(workspacePath: string): string[] {
136
+ const entries = fs.readdirSync(workspacePath, { withFileTypes: true });
137
+ return entries
138
+ .filter((e) => e.isDirectory() && /^\d{2}-/.test(e.name) && e.name !== '00-meta')
139
+ .map((e) => e.name);
140
+ }
141
+
142
+ if (require.main === module) {
143
+ const args = process.argv.slice(2);
144
+ const parseArg = (flag: string): string | undefined => {
145
+ const idx = args.indexOf(flag);
146
+ return idx !== -1 ? args[idx + 1] : undefined;
147
+ };
148
+
149
+ const workspace = parseArg('--workspace');
150
+ const output = parseArg('--output');
151
+
152
+ if (!workspace) {
153
+ console.error('Usage: node generate-tests.ts --workspace <path> [--output <path>]');
154
+ process.exit(1);
155
+ }
156
+
157
+ generateTestCases(workspace, output);
158
+ }
@@ -0,0 +1,82 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { execSync } from 'child_process';
4
+
5
+ export type PackageManager = 'npm' | 'pip' | 'npx' | 'brew';
6
+
7
+ export interface InstallToolOptions {
8
+ tool: string;
9
+ manager: PackageManager;
10
+ workspace: string;
11
+ }
12
+
13
+ export function installTool(options: InstallToolOptions): void {
14
+ const { tool, manager, workspace } = options;
15
+ const ws = path.resolve(workspace);
16
+
17
+ const validManagers: PackageManager[] = ['npm', 'pip', 'npx', 'brew'];
18
+ if (!validManagers.includes(manager)) {
19
+ throw new Error(`Unsupported package manager: ${manager}. Supported: ${validManagers.join(', ')}`);
20
+ }
21
+
22
+ const command = manager === 'npx' ? `npx ${tool}` : `${manager} install ${tool}`;
23
+
24
+ console.log(`Installing ${tool} via ${manager}...`);
25
+ try {
26
+ execSync(command, { cwd: ws, stdio: 'inherit' });
27
+ } catch (error) {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ throw new Error(`Failed to install ${tool}: ${message}`);
30
+ }
31
+
32
+ updateToolsMd(ws, tool, manager);
33
+
34
+ console.log(`✓ ${tool} installed and added to tool inventory`);
35
+ }
36
+
37
+ function updateToolsMd(workspace: string, tool: string, manager: string): void {
38
+ const toolsMdPath = path.join(workspace, '00-meta', 'tools.md');
39
+
40
+ if (!fs.existsSync(toolsMdPath)) {
41
+ throw new Error(`tools.md not found at: ${toolsMdPath}`);
42
+ }
43
+
44
+ const content = fs.readFileSync(toolsMdPath, 'utf-8');
45
+ const now = new Date().toISOString().split('T')[0];
46
+
47
+ const placeholderRow = '| — | — | — | — |';
48
+ const newRow = `| ${tool} | latest | ${manager} | ${now} |`;
49
+
50
+ let updated: string;
51
+ if (content.includes(placeholderRow)) {
52
+ updated = content.replace(placeholderRow, `${placeholderRow}\n${newRow}`);
53
+ } else {
54
+ const pendingIdx = content.indexOf('## Pending Tools');
55
+ if (pendingIdx !== -1) {
56
+ updated = content.slice(0, pendingIdx) + newRow + '\n\n' + content.slice(pendingIdx);
57
+ } else {
58
+ updated = content + '\n' + newRow + '\n';
59
+ }
60
+ }
61
+
62
+ fs.writeFileSync(toolsMdPath, updated);
63
+ }
64
+
65
+ if (require.main === module) {
66
+ const args = process.argv.slice(2);
67
+ const parseArg = (flag: string): string | undefined => {
68
+ const idx = args.indexOf(flag);
69
+ return idx !== -1 ? args[idx + 1] : undefined;
70
+ };
71
+
72
+ const tool = parseArg('--tool');
73
+ const manager = parseArg('--manager') as PackageManager;
74
+ const workspace = parseArg('--workspace');
75
+
76
+ if (!tool || !manager || !workspace) {
77
+ console.error('Usage: node install-tool.ts --tool <name> --manager <npm|pip|npx|brew> --workspace <path>');
78
+ process.exit(1);
79
+ }
80
+
81
+ installTool({ tool, manager, workspace });
82
+ }
@@ -0,0 +1,265 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { validateWorkspace } from './validate';
4
+
5
+ export interface IterateOptions {
6
+ maxRetries?: number;
7
+ }
8
+
9
+ export interface ValidatePassResult {
10
+ status: 'passed' | 'failed' | 'escalated';
11
+ retries: number;
12
+ failures?: string[];
13
+ }
14
+
15
+ export interface ScorePassResult {
16
+ score: number;
17
+ improvements: string[];
18
+ }
19
+
20
+ export interface ChecklistResult {
21
+ items: number;
22
+ passed: number;
23
+ failed: number;
24
+ details: { name: string; passed: boolean }[];
25
+ }
26
+
27
+ export interface IterateResult {
28
+ passes: {
29
+ validate: ValidatePassResult;
30
+ score: ScorePassResult;
31
+ checklist: ChecklistResult;
32
+ };
33
+ escalate: boolean;
34
+ }
35
+
36
+ export interface ScoreBreakdown {
37
+ system: number;
38
+ context: number;
39
+ stages: number;
40
+ tools: number;
41
+ total: number;
42
+ improvements: string[];
43
+ }
44
+
45
+ export function iterateWorkspace(
46
+ workspacePath: string,
47
+ options: IterateOptions = {},
48
+ ): IterateResult {
49
+ const { maxRetries = 3 } = options;
50
+ const ws = path.resolve(workspacePath);
51
+
52
+ const validateResult = runValidatePass(ws, maxRetries);
53
+ const scoreResult = runScorePass(ws);
54
+ const checklistResult = runChecklist(ws);
55
+
56
+ const result: IterateResult = {
57
+ passes: {
58
+ validate: validateResult,
59
+ score: scoreResult,
60
+ checklist: checklistResult,
61
+ },
62
+ escalate: validateResult.status === 'escalated',
63
+ };
64
+
65
+ console.log(JSON.stringify(result, null, 2));
66
+
67
+ return result;
68
+ }
69
+
70
+ function runValidatePass(ws: string, maxRetries: number): ValidatePassResult {
71
+ let retries = 0;
72
+
73
+ for (let i = 0; i < maxRetries; i++) {
74
+ const result = validateWorkspace(ws);
75
+
76
+ if (result.passed) {
77
+ return { status: 'passed', retries: i };
78
+ }
79
+
80
+ retries = i + 1;
81
+ }
82
+
83
+ const lastResult = validateWorkspace(ws);
84
+ const failures = lastResult.checks.filter((c) => !c.passed).map((c) => `${c.name}: ${c.message}`);
85
+
86
+ return {
87
+ status: 'escalated',
88
+ retries,
89
+ failures,
90
+ };
91
+ }
92
+
93
+ function runScorePass(ws: string): ScorePassResult {
94
+ const score = scoreWorkspace(ws);
95
+ return {
96
+ score: score.total,
97
+ improvements: score.improvements,
98
+ };
99
+ }
100
+
101
+ export function scoreWorkspace(workspacePath: string): ScoreBreakdown {
102
+ const ws = path.resolve(workspacePath);
103
+ const improvements: string[] = [];
104
+ let system = 0;
105
+ let context = 0;
106
+ let stages = 0;
107
+ let tools = 0;
108
+
109
+ const systemMdPath = path.join(ws, 'SYSTEM.md');
110
+ if (fs.existsSync(systemMdPath)) {
111
+ const content = fs.readFileSync(systemMdPath, 'utf-8');
112
+ if (content.toLowerCase().includes('## role') || content.toLowerCase().includes('role')) system += 7;
113
+ else improvements.push('SYSTEM.md missing Role section');
114
+ if (content.toLowerCase().includes('folder map')) system += 7;
115
+ else improvements.push('SYSTEM.md missing Folder Map');
116
+ if (content.toLowerCase().includes('## rules') || content.toLowerCase().includes('rule')) system += 6;
117
+ else improvements.push('SYSTEM.md missing Rules section');
118
+ } else {
119
+ improvements.push('SYSTEM.md missing entirely');
120
+ }
121
+
122
+ const contextMdPath = path.join(ws, 'CONTEXT.md');
123
+ if (fs.existsSync(contextMdPath)) {
124
+ const content = fs.readFileSync(contextMdPath, 'utf-8');
125
+ if (content.toLowerCase().includes('routing table')) context += 10;
126
+ else improvements.push('CONTEXT.md missing Routing Table');
127
+ const numberedFolders = getNumberedFolders(ws);
128
+ const allReferenced = numberedFolders.every((f) => content.includes(f));
129
+ if (allReferenced && numberedFolders.length > 0) context += 10;
130
+ else if (numberedFolders.length > 0) improvements.push('CONTEXT.md does not reference all stages');
131
+ } else {
132
+ improvements.push('CONTEXT.md missing entirely');
133
+ }
134
+
135
+ const stageFolders = getNumberedFolders(ws);
136
+ let stageScore = 0;
137
+ for (const folder of stageFolders) {
138
+ const stageContextPath = path.join(ws, folder, 'CONTEXT.md');
139
+ let folderScore = 0;
140
+ if (fs.existsSync(stageContextPath)) {
141
+ const content = fs.readFileSync(stageContextPath, 'utf-8');
142
+ if (content.toLowerCase().includes('purpose') || content.toLowerCase().includes('## purpose')) folderScore += 4;
143
+ else improvements.push(`${folder}/CONTEXT.md missing Purpose`);
144
+ if (content.toLowerCase().includes('input')) folderScore += 4;
145
+ else improvements.push(`${folder}/CONTEXT.md missing Inputs`);
146
+ if (content.toLowerCase().includes('output')) folderScore += 4;
147
+ else improvements.push(`${folder}/CONTEXT.md missing Outputs`);
148
+ if (content.toLowerCase().includes('dependenc')) folderScore += 3;
149
+ else improvements.push(`${folder}/CONTEXT.md missing Dependencies`);
150
+ } else {
151
+ improvements.push(`${folder}/CONTEXT.md missing`);
152
+ }
153
+ stageScore += folderScore;
154
+ }
155
+ stages = Math.min(stageScore, 45);
156
+
157
+ const toolsMdPath = path.join(ws, '00-meta', 'tools.md');
158
+ if (fs.existsSync(toolsMdPath)) {
159
+ const content = fs.readFileSync(toolsMdPath, 'utf-8');
160
+ if (content.trim().length > 20) tools += 15;
161
+ else {
162
+ tools += 5;
163
+ improvements.push('tools.md exists but has minimal content');
164
+ }
165
+ } else {
166
+ improvements.push('tools.md missing');
167
+ }
168
+
169
+ return {
170
+ system,
171
+ context,
172
+ stages,
173
+ tools,
174
+ total: system + context + stages + tools,
175
+ improvements,
176
+ };
177
+ }
178
+
179
+ export function runChecklist(workspacePath: string): ChecklistResult {
180
+ const ws = path.resolve(workspacePath);
181
+ const details: { name: string; passed: boolean }[] = [];
182
+
183
+ const stageFolders = getNumberedFolders(ws);
184
+
185
+ for (const folder of stageFolders) {
186
+ const contextPath = path.join(ws, folder, 'CONTEXT.md');
187
+ if (fs.existsSync(contextPath)) {
188
+ const content = fs.readFileSync(contextPath, 'utf-8');
189
+ details.push({
190
+ name: `${folder} has inputs defined`,
191
+ passed: content.toLowerCase().includes('input'),
192
+ });
193
+ details.push({
194
+ name: `${folder} has outputs defined`,
195
+ passed: content.toLowerCase().includes('output'),
196
+ });
197
+ details.push({
198
+ name: `${folder} has dependencies defined`,
199
+ passed: content.toLowerCase().includes('dependenc'),
200
+ });
201
+ } else {
202
+ details.push({ name: `${folder} has CONTEXT.md`, passed: false });
203
+ details.push({ name: `${folder} has inputs defined`, passed: false });
204
+ details.push({ name: `${folder} has outputs defined`, passed: false });
205
+ details.push({ name: `${folder} has dependencies defined`, passed: false });
206
+ }
207
+ }
208
+
209
+ const contextMdPath = path.join(ws, 'CONTEXT.md');
210
+ if (fs.existsSync(contextMdPath)) {
211
+ const content = fs.readFileSync(contextMdPath, 'utf-8');
212
+ const allReferenced = stageFolders.every((f) => content.includes(f));
213
+ details.push({
214
+ name: 'Routing table references all numbered folders',
215
+ passed: allReferenced,
216
+ });
217
+ } else {
218
+ details.push({
219
+ name: 'Routing table references all numbered folders',
220
+ passed: false,
221
+ });
222
+ }
223
+
224
+ const readmePath = path.join(ws, 'README.md');
225
+ details.push({
226
+ name: 'README.md exists and has usage instructions',
227
+ passed: fs.existsSync(readmePath) && fs.readFileSync(readmePath, 'utf-8').trim().length > 0,
228
+ });
229
+
230
+ const passed = details.filter((d) => d.passed).length;
231
+ const failed = details.filter((d) => !d.passed).length;
232
+
233
+ return {
234
+ items: details.length,
235
+ passed,
236
+ failed,
237
+ details,
238
+ };
239
+ }
240
+
241
+ function getNumberedFolders(workspacePath: string): string[] {
242
+ const entries = fs.readdirSync(workspacePath, { withFileTypes: true });
243
+ return entries
244
+ .filter((e) => e.isDirectory() && /^\d{2}-/.test(e.name) && e.name !== '00-meta')
245
+ .map((e) => e.name);
246
+ }
247
+
248
+ if (require.main === module) {
249
+ const args = process.argv.slice(2);
250
+ const parseArg = (flag: string): string | undefined => {
251
+ const idx = args.indexOf(flag);
252
+ return idx !== -1 ? args[idx + 1] : undefined;
253
+ };
254
+
255
+ const workspace = parseArg('--workspace');
256
+ const maxRetriesStr = parseArg('--max-retries');
257
+ const maxRetries = maxRetriesStr ? parseInt(maxRetriesStr, 10) : 3;
258
+
259
+ if (!workspace) {
260
+ console.error('Usage: node iterate.ts --workspace <path> [--max-retries <n>]');
261
+ process.exit(1);
262
+ }
263
+
264
+ iterateWorkspace(workspace, { maxRetries });
265
+ }