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.
- package/.agents/skills/workspace-maxxing/.workspace-templates/CONTEXT.md +44 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/SYSTEM.md +44 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/anti-patterns.md +16 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/iron-laws.md +26 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/reporting-format.md +52 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/benchmark.ts +171 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/dispatch.ts +473 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/generate-tests.ts +158 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/install-tool.ts +82 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/iterate.ts +265 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/orchestrator.ts +539 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/scaffold.ts +282 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/validate.ts +452 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/architecture/SKILL.md +95 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/fixer/SKILL.md +109 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/iteration/SKILL.md +89 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/research/SKILL.md +94 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/testing/SKILL.md +89 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/tooling/SKILL.md +87 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/validation/SKILL.md +103 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/worker/SKILL.md +79 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/README.md +14 -0
- package/.agents/skills/workspace-maxxing/SKILL.md +312 -0
- package/.agents/skills/workspace-maxxing/scripts/benchmark.ts +171 -0
- package/.agents/skills/workspace-maxxing/scripts/dispatch.ts +473 -0
- package/.agents/skills/workspace-maxxing/scripts/generate-tests.ts +158 -0
- package/.agents/skills/workspace-maxxing/scripts/install-tool.ts +82 -0
- package/.agents/skills/workspace-maxxing/scripts/iterate.ts +265 -0
- package/.agents/skills/workspace-maxxing/scripts/orchestrator.ts +539 -0
- package/.agents/skills/workspace-maxxing/scripts/scaffold.ts +282 -0
- package/.agents/skills/workspace-maxxing/scripts/validate.ts +452 -0
- package/README.md +144 -0
- package/dist/agent-creator.d.ts +9 -0
- package/dist/agent-creator.d.ts.map +1 -0
- package/dist/agent-creator.js +199 -0
- package/dist/agent-creator.js.map +1 -0
- package/dist/agent-iterator.d.ts +38 -0
- package/dist/agent-iterator.d.ts.map +1 -0
- package/dist/agent-iterator.js +327 -0
- package/dist/agent-iterator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +18 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +117 -0
- package/dist/install.js.map +1 -0
- package/dist/platforms/claude.d.ts +7 -0
- package/dist/platforms/claude.d.ts.map +1 -0
- package/dist/platforms/claude.js +70 -0
- package/dist/platforms/claude.js.map +1 -0
- package/dist/platforms/copilot.d.ts +7 -0
- package/dist/platforms/copilot.d.ts.map +1 -0
- package/dist/platforms/copilot.js +75 -0
- package/dist/platforms/copilot.js.map +1 -0
- package/dist/platforms/gemini.d.ts +7 -0
- package/dist/platforms/gemini.d.ts.map +1 -0
- package/dist/platforms/gemini.js +81 -0
- package/dist/platforms/gemini.js.map +1 -0
- package/dist/platforms/index.d.ts +8 -0
- package/dist/platforms/index.d.ts.map +1 -0
- package/dist/platforms/index.js +41 -0
- package/dist/platforms/index.js.map +1 -0
- package/dist/platforms/opencode.d.ts +7 -0
- package/dist/platforms/opencode.d.ts.map +1 -0
- package/dist/platforms/opencode.js +70 -0
- package/dist/platforms/opencode.js.map +1 -0
- package/dist/scripts/benchmark.d.ts +20 -0
- package/dist/scripts/benchmark.d.ts.map +1 -0
- package/dist/scripts/benchmark.js +170 -0
- package/dist/scripts/benchmark.js.map +1 -0
- package/dist/scripts/dispatch.d.ts +32 -0
- package/dist/scripts/dispatch.d.ts.map +1 -0
- package/dist/scripts/dispatch.js +386 -0
- package/dist/scripts/dispatch.js.map +1 -0
- package/dist/scripts/generate-tests.d.ts +11 -0
- package/dist/scripts/generate-tests.d.ts.map +1 -0
- package/dist/scripts/generate-tests.js +118 -0
- package/dist/scripts/generate-tests.js.map +1 -0
- package/dist/scripts/install-tool.d.ts +8 -0
- package/dist/scripts/install-tool.d.ts.map +1 -0
- package/dist/scripts/install-tool.js +98 -0
- package/dist/scripts/install-tool.js.map +1 -0
- package/dist/scripts/iterate.d.ts +44 -0
- package/dist/scripts/iterate.d.ts.map +1 -0
- package/dist/scripts/iterate.js +260 -0
- package/dist/scripts/iterate.js.map +1 -0
- package/dist/scripts/orchestrator.d.ts +40 -0
- package/dist/scripts/orchestrator.d.ts.map +1 -0
- package/dist/scripts/orchestrator.js +378 -0
- package/dist/scripts/orchestrator.js.map +1 -0
- package/dist/scripts/scaffold.d.ts +8 -0
- package/dist/scripts/scaffold.d.ts.map +1 -0
- package/dist/scripts/scaffold.js +279 -0
- package/dist/scripts/scaffold.js.map +1 -0
- package/dist/scripts/validate.d.ts +11 -0
- package/dist/scripts/validate.d.ts.map +1 -0
- package/dist/scripts/validate.js +472 -0
- package/dist/scripts/validate.js.map +1 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-iteration-plan.md +1123 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-iteration-sub-agent-batches.md +1923 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-workflow-sub-skill-plan.md +1505 -0
- package/docs/superpowers/plans/2026-04-07-benchmarking-multi-agent-plan.md +854 -0
- package/docs/superpowers/plans/2026-04-07-workspace-builder-logic-plan.md +1426 -0
- package/docs/superpowers/plans/2026-04-07-workspace-maxxing-plan.md +1299 -0
- package/docs/superpowers/plans/2026-04-08-session-294c-subagent-invocation-plan.md +320 -0
- package/docs/superpowers/plans/2026-04-08-workflow-prompt-hardening-plan.md +1025 -0
- package/docs/superpowers/plans/2026-04-12-workspace-agent-creation-plan.md +992 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-iteration-design.md +214 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-iteration-sub-agent-batches-design.md +188 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-workflow-sub-skill-design.md +137 -0
- package/docs/superpowers/specs/2026-04-07-benchmarking-multi-agent-design.md +105 -0
- package/docs/superpowers/specs/2026-04-07-workspace-builder-logic-design.md +179 -0
- package/docs/superpowers/specs/2026-04-07-workspace-maxxing-design.md +227 -0
- package/docs/superpowers/specs/2026-04-08-session-294c-subagent-invocation-design.md +265 -0
- package/docs/superpowers/specs/2026-04-08-workflow-prompt-hardening-design.md +146 -0
- package/docs/superpowers/specs/2026-04-12-workspace-agent-creation-design.md +239 -0
- package/jest.config.js +8 -0
- package/package.json +32 -0
- package/src/agent-creator.ts +180 -0
- package/src/agent-iterator.ts +397 -0
- package/src/index.ts +189 -0
- package/src/install.ts +105 -0
- package/src/platforms/claude.ts +40 -0
- package/src/platforms/copilot.ts +50 -0
- package/src/platforms/gemini.ts +55 -0
- package/src/platforms/index.ts +45 -0
- package/src/platforms/opencode.ts +41 -0
- package/src/scripts/benchmark.ts +171 -0
- package/src/scripts/dispatch.ts +473 -0
- package/src/scripts/generate-tests.ts +112 -0
- package/src/scripts/install-tool.ts +82 -0
- package/src/scripts/iterate.ts +271 -0
- package/src/scripts/orchestrator.ts +539 -0
- package/src/scripts/scaffold.ts +282 -0
- package/src/scripts/validate.ts +516 -0
- package/templates/.workspace-templates/CONTEXT.md +44 -0
- package/templates/.workspace-templates/SYSTEM.md +44 -0
- package/templates/.workspace-templates/references/anti-patterns.md +16 -0
- package/templates/.workspace-templates/references/iron-laws.md +26 -0
- package/templates/.workspace-templates/references/reporting-format.md +52 -0
- package/templates/.workspace-templates/scripts/benchmark.ts +171 -0
- package/templates/.workspace-templates/scripts/dispatch.ts +473 -0
- package/templates/.workspace-templates/scripts/generate-tests.ts +158 -0
- package/templates/.workspace-templates/scripts/install-tool.ts +82 -0
- package/templates/.workspace-templates/scripts/iterate.ts +265 -0
- package/templates/.workspace-templates/scripts/orchestrator.ts +539 -0
- package/templates/.workspace-templates/scripts/scaffold.ts +282 -0
- package/templates/.workspace-templates/scripts/validate.ts +452 -0
- package/templates/.workspace-templates/skills/architecture/SKILL.md +95 -0
- package/templates/.workspace-templates/skills/fixer/SKILL.md +109 -0
- package/templates/.workspace-templates/skills/iteration/SKILL.md +89 -0
- package/templates/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
- package/templates/.workspace-templates/skills/research/SKILL.md +94 -0
- package/templates/.workspace-templates/skills/testing/SKILL.md +89 -0
- package/templates/.workspace-templates/skills/tooling/SKILL.md +87 -0
- package/templates/.workspace-templates/skills/validation/SKILL.md +103 -0
- package/templates/.workspace-templates/skills/worker/SKILL.md +79 -0
- package/templates/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
- package/templates/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
- package/templates/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/README.md +14 -0
- package/templates/SKILL.md +347 -0
- package/tests/benchmark.test.ts +158 -0
- package/tests/cli.test.ts +109 -0
- package/tests/dispatch-parallel.test.ts +124 -0
- package/tests/dispatch.test.ts +218 -0
- package/tests/fixer-skill.test.ts +203 -0
- package/tests/generate-tests.test.ts +101 -0
- package/tests/install-tool.test.ts +141 -0
- package/tests/install.test.ts +144 -0
- package/tests/integration.test.ts +324 -0
- package/tests/iterate.test.ts +219 -0
- package/tests/orchestrator.test.ts +710 -0
- package/tests/scaffold.test.ts +238 -0
- package/tests/templates-enhanced.test.ts +208 -0
- package/tests/templates.test.ts +219 -0
- package/tests/validate.test.ts +421 -0
- package/tests/validation-enhanced.test.ts +303 -0
- package/tests/worker-skill.test.ts +88 -0
- package/tsconfig.json +19 -0
- package/workspace/00-meta/CONTEXT.md +3 -0
- package/workspace/00-meta/execution-log.md +17 -0
- package/workspace/00-meta/tools.md +11 -0
- package/workspace/01-input/CONTEXT.md +27 -0
- package/workspace/CONTEXT.md +35 -0
- package/workspace/README.md +14 -0
- package/workspace/SYSTEM.md +36 -0
- package/workspace-maxxing-0.1.0.tgz +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import { scaffoldWorkspace, ScaffoldOptions } from '../src/scripts/scaffold';
|
|
5
|
+
|
|
6
|
+
describe('scaffold', () => {
|
|
7
|
+
let tempDir: string;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'scaffold-test-'));
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('scaffoldWorkspace', () => {
|
|
18
|
+
it('creates output directory', () => {
|
|
19
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
20
|
+
const options: ScaffoldOptions = {
|
|
21
|
+
name: 'research',
|
|
22
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
23
|
+
output: outputDir,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
scaffoldWorkspace(options);
|
|
27
|
+
|
|
28
|
+
expect(fs.existsSync(outputDir)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('creates SYSTEM.md with folder map', () => {
|
|
32
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
33
|
+
const options: ScaffoldOptions = {
|
|
34
|
+
name: 'research',
|
|
35
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
36
|
+
output: outputDir,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
scaffoldWorkspace(options);
|
|
40
|
+
|
|
41
|
+
const systemMd = fs.readFileSync(path.join(outputDir, 'SYSTEM.md'), 'utf-8');
|
|
42
|
+
expect(systemMd).toContain('## Folder Map');
|
|
43
|
+
expect(systemMd).toContain('01-research');
|
|
44
|
+
expect(systemMd).toContain('02-analysis');
|
|
45
|
+
expect(systemMd).toContain('03-report');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('creates CONTEXT.md at root level', () => {
|
|
49
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
50
|
+
const options: ScaffoldOptions = {
|
|
51
|
+
name: 'research',
|
|
52
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
53
|
+
output: outputDir,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
scaffoldWorkspace(options);
|
|
57
|
+
|
|
58
|
+
const contextMd = fs.readFileSync(path.join(outputDir, 'CONTEXT.md'), 'utf-8');
|
|
59
|
+
expect(contextMd).toContain('## Task Routing');
|
|
60
|
+
expect(contextMd).toContain('01-research');
|
|
61
|
+
expect(contextMd).toContain('02-analysis');
|
|
62
|
+
expect(contextMd).toContain('03-report');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('creates robust SYSTEM.md sections for workflow-following prompts', () => {
|
|
66
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
67
|
+
scaffoldWorkspace({
|
|
68
|
+
name: 'research',
|
|
69
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
70
|
+
output: outputDir,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const systemMd = fs.readFileSync(path.join(outputDir, 'SYSTEM.md'), 'utf-8');
|
|
74
|
+
expect(systemMd).toContain('## Role');
|
|
75
|
+
expect(systemMd).toContain('## Folder Map');
|
|
76
|
+
expect(systemMd).toContain('## Workflow Rules');
|
|
77
|
+
expect(systemMd).toContain('## Scope Guardrails');
|
|
78
|
+
expect(systemMd).toContain('## Sequential Execution Protocol');
|
|
79
|
+
expect(systemMd).toContain('## Stage Boundaries');
|
|
80
|
+
expect(systemMd).toContain('## Tooling Policy');
|
|
81
|
+
expect(systemMd.toLowerCase()).toContain('markdown');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('creates robust root CONTEXT.md routing and loading order', () => {
|
|
85
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
86
|
+
scaffoldWorkspace({
|
|
87
|
+
name: 'research',
|
|
88
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
89
|
+
output: outputDir,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const contextMd = fs.readFileSync(path.join(outputDir, 'CONTEXT.md'), 'utf-8');
|
|
93
|
+
expect(contextMd).toContain('## How to Use This File');
|
|
94
|
+
expect(contextMd).toContain('## Task Routing');
|
|
95
|
+
expect(contextMd).toContain('## Loading Order');
|
|
96
|
+
expect(contextMd).toContain('## Scope Guardrails');
|
|
97
|
+
expect(contextMd).toContain('## Sequential Routing Contract');
|
|
98
|
+
expect(contextMd).toContain('## Stage Handoff Routing');
|
|
99
|
+
expect(contextMd).toContain('## Escalation');
|
|
100
|
+
|
|
101
|
+
expect(contextMd).toContain('01-research/CONTEXT.md');
|
|
102
|
+
expect(contextMd).toContain('02-analysis/CONTEXT.md');
|
|
103
|
+
expect(contextMd).toContain('03-report/CONTEXT.md');
|
|
104
|
+
expect(contextMd).toContain('SYSTEM.md');
|
|
105
|
+
expect(contextMd.toLowerCase()).toContain('markdown');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('creates numbered stage folders with CONTEXT.md', () => {
|
|
109
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
110
|
+
const options: ScaffoldOptions = {
|
|
111
|
+
name: 'research',
|
|
112
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
113
|
+
output: outputDir,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
scaffoldWorkspace(options);
|
|
117
|
+
|
|
118
|
+
for (const stage of options.stages) {
|
|
119
|
+
const stageDir = path.join(outputDir, stage);
|
|
120
|
+
expect(fs.existsSync(stageDir)).toBe(true);
|
|
121
|
+
const contextMd = fs.readFileSync(path.join(stageDir, 'CONTEXT.md'), 'utf-8');
|
|
122
|
+
expect(contextMd.trim().length).toBeGreaterThan(0);
|
|
123
|
+
expect(contextMd).toContain(stage);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('creates stage CONTEXT.md files with completion and handoff contracts', () => {
|
|
128
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
129
|
+
const stages = ['01-research', '02-analysis', '03-report'];
|
|
130
|
+
|
|
131
|
+
scaffoldWorkspace({
|
|
132
|
+
name: 'research',
|
|
133
|
+
stages,
|
|
134
|
+
output: outputDir,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
for (let i = 0; i < stages.length; i++) {
|
|
138
|
+
const stage = stages[i];
|
|
139
|
+
const nextStage = stages[i + 1];
|
|
140
|
+
const stageContext = fs.readFileSync(path.join(outputDir, stage, 'CONTEXT.md'), 'utf-8');
|
|
141
|
+
|
|
142
|
+
expect(stageContext).toContain('## Purpose');
|
|
143
|
+
expect(stageContext).toContain('## Inputs');
|
|
144
|
+
expect(stageContext).toContain('## Outputs');
|
|
145
|
+
expect(stageContext).toContain('## Dependencies');
|
|
146
|
+
expect(stageContext).toContain('## Required Evidence');
|
|
147
|
+
expect(stageContext).toContain('## Completion Criteria');
|
|
148
|
+
expect(stageContext).toContain('## Handoff');
|
|
149
|
+
expect(stageContext.toLowerCase()).toContain('markdown');
|
|
150
|
+
expect(stageContext).toContain('00-meta/execution-log.md');
|
|
151
|
+
|
|
152
|
+
if (nextStage) {
|
|
153
|
+
expect(stageContext).toContain(nextStage);
|
|
154
|
+
} else {
|
|
155
|
+
expect(stageContext.toLowerCase()).toContain('final output');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('creates 00-meta folder with tools.md', () => {
|
|
161
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
162
|
+
const options: ScaffoldOptions = {
|
|
163
|
+
name: 'research',
|
|
164
|
+
stages: ['01-research'],
|
|
165
|
+
output: outputDir,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
scaffoldWorkspace(options);
|
|
169
|
+
|
|
170
|
+
const toolsMd = path.join(outputDir, '00-meta', 'tools.md');
|
|
171
|
+
expect(fs.existsSync(toolsMd)).toBe(true);
|
|
172
|
+
const content = fs.readFileSync(toolsMd, 'utf-8');
|
|
173
|
+
expect(content).toContain('## Tool Inventory');
|
|
174
|
+
|
|
175
|
+
const executionLogPath = path.join(outputDir, '00-meta', 'execution-log.md');
|
|
176
|
+
expect(fs.existsSync(executionLogPath)).toBe(true);
|
|
177
|
+
const executionLog = fs.readFileSync(executionLogPath, 'utf-8');
|
|
178
|
+
expect(executionLog).toContain('## Stage Checklist');
|
|
179
|
+
expect(executionLog).toContain('- [ ] 01-research');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('creates README.md', () => {
|
|
183
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
184
|
+
const options: ScaffoldOptions = {
|
|
185
|
+
name: 'research',
|
|
186
|
+
stages: ['01-research'],
|
|
187
|
+
output: outputDir,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
scaffoldWorkspace(options);
|
|
191
|
+
|
|
192
|
+
const readme = fs.readFileSync(path.join(outputDir, 'README.md'), 'utf-8');
|
|
193
|
+
expect(readme.trim().length).toBeGreaterThan(0);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('throws if output directory already exists', () => {
|
|
197
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
198
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
199
|
+
|
|
200
|
+
const options: ScaffoldOptions = {
|
|
201
|
+
name: 'research',
|
|
202
|
+
stages: ['01-research'],
|
|
203
|
+
output: outputDir,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
expect(() => scaffoldWorkspace(options)).toThrow('already exists');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('overwrites if force is true', () => {
|
|
210
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
211
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
212
|
+
fs.writeFileSync(path.join(outputDir, 'existing.txt'), 'data');
|
|
213
|
+
|
|
214
|
+
const options: ScaffoldOptions = {
|
|
215
|
+
name: 'research',
|
|
216
|
+
stages: ['01-research'],
|
|
217
|
+
output: outputDir,
|
|
218
|
+
force: true,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
scaffoldWorkspace(options);
|
|
222
|
+
|
|
223
|
+
const systemMd = path.join(outputDir, 'SYSTEM.md');
|
|
224
|
+
expect(fs.existsSync(systemMd)).toBe(true);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('throws if stages list is empty', () => {
|
|
228
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
229
|
+
const options: ScaffoldOptions = {
|
|
230
|
+
name: 'research',
|
|
231
|
+
stages: [],
|
|
232
|
+
output: outputDir,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
expect(() => scaffoldWorkspace(options)).toThrow('stages');
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
|
|
4
|
+
const templatesDir = path.join(__dirname, '..', 'templates', '.workspace-templates');
|
|
5
|
+
const skillsDir = path.join(templatesDir, 'skills');
|
|
6
|
+
|
|
7
|
+
describe('Shared References', () => {
|
|
8
|
+
describe('references/ directory', () => {
|
|
9
|
+
it('contains anti-patterns.md', () => {
|
|
10
|
+
const filePath = path.join(templatesDir, 'references', 'anti-patterns.md');
|
|
11
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
12
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
13
|
+
expect(content).toContain('Rationalization');
|
|
14
|
+
expect(content).toContain('Thought');
|
|
15
|
+
expect(content).toContain('Reality');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('contains reporting-format.md', () => {
|
|
19
|
+
const filePath = path.join(templatesDir, 'references', 'reporting-format.md');
|
|
20
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
21
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
22
|
+
expect(content).toContain('skill');
|
|
23
|
+
expect(content).toContain('status');
|
|
24
|
+
expect(content).toContain('findings');
|
|
25
|
+
expect(content).toContain('recommendations');
|
|
26
|
+
expect(content).toContain('nextSkill');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('contains iron-laws.md', () => {
|
|
30
|
+
const filePath = path.join(templatesDir, 'references', 'iron-laws.md');
|
|
31
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
32
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
33
|
+
expect(content).toContain('NO BUILD WITHOUT PLAN');
|
|
34
|
+
expect(content).toContain('NO PLAN WITHOUT RESEARCH');
|
|
35
|
+
expect(content).toContain('NO IMPROVEMENT WITHOUT VALIDATION');
|
|
36
|
+
expect(content).toContain('NO COMPLETION CLAIM WITHOUT VERIFICATION');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('Sub-Skills', () => {
|
|
42
|
+
describe('validation', () => {
|
|
43
|
+
it('has SKILL.md with required sections', () => {
|
|
44
|
+
const filePath = path.join(skillsDir, 'validation', 'SKILL.md');
|
|
45
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
46
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
47
|
+
expect(content).toContain('---');
|
|
48
|
+
expect(content).toContain('name:');
|
|
49
|
+
expect(content).toContain('description:');
|
|
50
|
+
expect(content).toContain('## Overview');
|
|
51
|
+
expect(content).toContain('## When to Use');
|
|
52
|
+
expect(content).toContain('## The Process');
|
|
53
|
+
expect(content).toContain('## Red Flags');
|
|
54
|
+
expect(content).toContain('## Report Format');
|
|
55
|
+
expect(content).toContain('## Integration');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('references validate.ts script', () => {
|
|
59
|
+
const filePath = path.join(skillsDir, 'validation', 'SKILL.md');
|
|
60
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
61
|
+
expect(content).toContain('validate.ts');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('research', () => {
|
|
66
|
+
it('has SKILL.md with required sections', () => {
|
|
67
|
+
const filePath = path.join(skillsDir, 'research', 'SKILL.md');
|
|
68
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
69
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
70
|
+
expect(content).toContain('---');
|
|
71
|
+
expect(content).toContain('name:');
|
|
72
|
+
expect(content).toContain('description:');
|
|
73
|
+
expect(content).toContain('## Overview');
|
|
74
|
+
expect(content).toContain('## When to Use');
|
|
75
|
+
expect(content).toContain('## The Process');
|
|
76
|
+
expect(content).toContain('## Red Flags');
|
|
77
|
+
expect(content).toContain('## Report Format');
|
|
78
|
+
expect(content).toContain('## Integration');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('architecture', () => {
|
|
83
|
+
it('has SKILL.md with required sections', () => {
|
|
84
|
+
const filePath = path.join(skillsDir, 'architecture', 'SKILL.md');
|
|
85
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
86
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
87
|
+
expect(content).toContain('---');
|
|
88
|
+
expect(content).toContain('name:');
|
|
89
|
+
expect(content).toContain('description:');
|
|
90
|
+
expect(content).toContain('## Overview');
|
|
91
|
+
expect(content).toContain('## When to Use');
|
|
92
|
+
expect(content).toContain('## The Process');
|
|
93
|
+
expect(content).toContain('## Red Flags');
|
|
94
|
+
expect(content).toContain('## Report Format');
|
|
95
|
+
expect(content).toContain('## Integration');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('prompt-engineering', () => {
|
|
100
|
+
it('has SKILL.md with required sections', () => {
|
|
101
|
+
const filePath = path.join(skillsDir, 'prompt-engineering', 'SKILL.md');
|
|
102
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
103
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
104
|
+
expect(content).toContain('---');
|
|
105
|
+
expect(content).toContain('name:');
|
|
106
|
+
expect(content).toContain('description:');
|
|
107
|
+
expect(content).toContain('## Overview');
|
|
108
|
+
expect(content).toContain('## When to Use');
|
|
109
|
+
expect(content).toContain('## The Process');
|
|
110
|
+
expect(content).toContain('## Red Flags');
|
|
111
|
+
expect(content).toContain('## Report Format');
|
|
112
|
+
expect(content).toContain('## Integration');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('testing', () => {
|
|
117
|
+
it('has SKILL.md with required sections', () => {
|
|
118
|
+
const filePath = path.join(skillsDir, 'testing', 'SKILL.md');
|
|
119
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
120
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
121
|
+
expect(content).toContain('---');
|
|
122
|
+
expect(content).toContain('name:');
|
|
123
|
+
expect(content).toContain('description:');
|
|
124
|
+
expect(content).toContain('## Overview');
|
|
125
|
+
expect(content).toContain('## When to Use');
|
|
126
|
+
expect(content).toContain('## The Process');
|
|
127
|
+
expect(content).toContain('## Red Flags');
|
|
128
|
+
expect(content).toContain('## Report Format');
|
|
129
|
+
expect(content).toContain('## Integration');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('iteration', () => {
|
|
134
|
+
it('has SKILL.md with required sections', () => {
|
|
135
|
+
const filePath = path.join(skillsDir, 'iteration', 'SKILL.md');
|
|
136
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
137
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
138
|
+
expect(content).toContain('---');
|
|
139
|
+
expect(content).toContain('name:');
|
|
140
|
+
expect(content).toContain('description:');
|
|
141
|
+
expect(content).toContain('## Overview');
|
|
142
|
+
expect(content).toContain('## When to Use');
|
|
143
|
+
expect(content).toContain('## The Process');
|
|
144
|
+
expect(content).toContain('## Red Flags');
|
|
145
|
+
expect(content).toContain('## Report Format');
|
|
146
|
+
expect(content).toContain('## Integration');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('tooling', () => {
|
|
151
|
+
it('has SKILL.md with required sections', () => {
|
|
152
|
+
const filePath = path.join(skillsDir, 'tooling', 'SKILL.md');
|
|
153
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
154
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
155
|
+
expect(content).toContain('---');
|
|
156
|
+
expect(content).toContain('name:');
|
|
157
|
+
expect(content).toContain('description:');
|
|
158
|
+
expect(content).toContain('## Overview');
|
|
159
|
+
expect(content).toContain('## When to Use');
|
|
160
|
+
expect(content).toContain('## The Process');
|
|
161
|
+
expect(content).toContain('## Red Flags');
|
|
162
|
+
expect(content).toContain('## Report Format');
|
|
163
|
+
expect(content).toContain('## Integration');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('worker', () => {
|
|
168
|
+
it('documents strict external runner contract and payload schema', () => {
|
|
169
|
+
const filePath = path.join(skillsDir, 'worker', 'SKILL.md');
|
|
170
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
171
|
+
|
|
172
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
173
|
+
expect(content).toContain('External Runner Contract');
|
|
174
|
+
expect(content).toContain('--subagent-runner');
|
|
175
|
+
expect(content).toContain('{skill}');
|
|
176
|
+
expect(content).toContain('{workspace}');
|
|
177
|
+
expect(content).toContain('{batchId}');
|
|
178
|
+
expect(content).toContain('{testCaseId}');
|
|
179
|
+
expect(content).toContain('report.json');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('fixer', () => {
|
|
184
|
+
it('documents strict external runner contract and payload schema', () => {
|
|
185
|
+
const filePath = path.join(skillsDir, 'fixer', 'SKILL.md');
|
|
186
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
187
|
+
|
|
188
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
189
|
+
expect(content).toContain('External Runner Contract');
|
|
190
|
+
expect(content).toContain('--subagent-runner');
|
|
191
|
+
expect(content).toContain('{skill}');
|
|
192
|
+
expect(content).toContain('{workspace}');
|
|
193
|
+
expect(content).toContain('{batchId}');
|
|
194
|
+
expect(content).toContain('{testCaseId}');
|
|
195
|
+
expect(content).toContain('report.json');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe('Dispatch Script', () => {
|
|
201
|
+
it('exists in templates scripts directory', () => {
|
|
202
|
+
const filePath = path.join(templatesDir, 'scripts', 'dispatch.ts');
|
|
203
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
204
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
205
|
+
expect(content).toContain('dispatchSkill');
|
|
206
|
+
expect(content).toContain('DispatchReport');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
|
|
4
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
5
|
+
|
|
6
|
+
describe('Template files', () => {
|
|
7
|
+
const requiredFiles = [
|
|
8
|
+
'SKILL.md',
|
|
9
|
+
'.workspace-templates/SYSTEM.md',
|
|
10
|
+
'.workspace-templates/CONTEXT.md',
|
|
11
|
+
'.workspace-templates/workspace/00-meta/CONTEXT.md',
|
|
12
|
+
'.workspace-templates/workspace/00-meta/execution-log.md',
|
|
13
|
+
'.workspace-templates/workspace/01-input/CONTEXT.md',
|
|
14
|
+
'.workspace-templates/workspace/02-process/CONTEXT.md',
|
|
15
|
+
'.workspace-templates/workspace/03-output/CONTEXT.md',
|
|
16
|
+
'.workspace-templates/workspace/README.md',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
describe.each(requiredFiles)('%s', (filePath) => {
|
|
20
|
+
it('exists', () => {
|
|
21
|
+
const fullPath = path.join(templatesDir, filePath);
|
|
22
|
+
expect(fs.existsSync(fullPath)).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('is not empty', () => {
|
|
26
|
+
const fullPath = path.join(templatesDir, filePath);
|
|
27
|
+
if (!fs.existsSync(fullPath)) {
|
|
28
|
+
fail(`File does not exist: ${fullPath}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
32
|
+
expect(content.trim().length).toBeGreaterThan(0);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('SKILL.md contains required sections', () => {
|
|
37
|
+
const skillPath = path.join(templatesDir, 'SKILL.md');
|
|
38
|
+
if (!fs.existsSync(skillPath)) {
|
|
39
|
+
fail('SKILL.md does not exist');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
43
|
+
|
|
44
|
+
expect(content).toContain('# Workspace-Maxxing');
|
|
45
|
+
expect(content).toContain('## Overview');
|
|
46
|
+
expect(content).toContain('## When to Use');
|
|
47
|
+
expect(content).toContain('## The Iron Law');
|
|
48
|
+
expect(content).toContain('## Hybrid Flow');
|
|
49
|
+
expect(content).toContain('## Sub-Skill Dispatch');
|
|
50
|
+
expect(content).toContain('## Available Scripts');
|
|
51
|
+
expect(content).toContain('## Anti-Rationalization Table');
|
|
52
|
+
expect(content).toContain('## Scope Guardrails');
|
|
53
|
+
expect(content).toContain('## Integration');
|
|
54
|
+
expect(content).toContain('## ICM Rules');
|
|
55
|
+
expect(content).toContain('## Output Format');
|
|
56
|
+
expect(content).toContain('## Sub-Agent Runner Contract');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('README.md documents strict external runner contract for worker/fixer', () => {
|
|
60
|
+
const readmePath = path.join(__dirname, '..', 'README.md');
|
|
61
|
+
expect(fs.existsSync(readmePath)).toBe(true);
|
|
62
|
+
|
|
63
|
+
const content = fs.readFileSync(readmePath, 'utf-8');
|
|
64
|
+
expect(content).toContain('--subagent-runner');
|
|
65
|
+
expect(content).toContain('{skill}');
|
|
66
|
+
expect(content.toLowerCase()).toContain('worker/fixer');
|
|
67
|
+
expect(content.toLowerCase()).toContain('external runner');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('SYSTEM.md contains Layer 0 content', () => {
|
|
71
|
+
const systemPath = path.join(templatesDir, '.workspace-templates', 'SYSTEM.md');
|
|
72
|
+
if (!fs.existsSync(systemPath)) {
|
|
73
|
+
fail('SYSTEM.md does not exist');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const content = fs.readFileSync(systemPath, 'utf-8');
|
|
77
|
+
|
|
78
|
+
expect(content.toLowerCase()).toContain('folder map');
|
|
79
|
+
expect(content).toContain('workspace');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('CONTEXT.md contains routing table structure', () => {
|
|
83
|
+
const contextPath = path.join(templatesDir, '.workspace-templates', 'CONTEXT.md');
|
|
84
|
+
if (!fs.existsSync(contextPath)) {
|
|
85
|
+
fail('CONTEXT.md does not exist');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const content = fs.readFileSync(contextPath, 'utf-8');
|
|
89
|
+
|
|
90
|
+
expect(content).toContain('routing');
|
|
91
|
+
expect(content).toContain('workspace');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('SYSTEM.md includes robust workflow sections', () => {
|
|
95
|
+
const systemPath = path.join(templatesDir, '.workspace-templates', 'SYSTEM.md');
|
|
96
|
+
if (!fs.existsSync(systemPath)) {
|
|
97
|
+
fail('SYSTEM.md does not exist');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const content = fs.readFileSync(systemPath, 'utf-8');
|
|
102
|
+
|
|
103
|
+
expect(content).toContain('## Role');
|
|
104
|
+
expect(content).toContain('## Folder Map');
|
|
105
|
+
expect(content).toContain('## Workflow Rules');
|
|
106
|
+
expect(content).toContain('## Scope Guardrails');
|
|
107
|
+
expect(content).toContain('## Sequential Execution Protocol');
|
|
108
|
+
expect(content).toContain('## Stage Boundaries');
|
|
109
|
+
expect(content).toContain('## Tooling Policy');
|
|
110
|
+
expect(content.toLowerCase()).toContain('markdown');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('root CONTEXT.md includes routing, loading order, and handoff routing', () => {
|
|
114
|
+
const contextPath = path.join(templatesDir, '.workspace-templates', 'CONTEXT.md');
|
|
115
|
+
if (!fs.existsSync(contextPath)) {
|
|
116
|
+
fail('CONTEXT.md does not exist');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const content = fs.readFileSync(contextPath, 'utf-8');
|
|
121
|
+
|
|
122
|
+
expect(content).toContain('## How to Use This File');
|
|
123
|
+
expect(content).toContain('## Task Routing');
|
|
124
|
+
expect(content).toContain('## Loading Order');
|
|
125
|
+
expect(content).toContain('## Scope Guardrails');
|
|
126
|
+
expect(content).toContain('## Sequential Routing Contract');
|
|
127
|
+
expect(content).toContain('## Stage Handoff Routing');
|
|
128
|
+
expect(content).toContain('## Escalation');
|
|
129
|
+
expect(content.toLowerCase()).toContain('markdown');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('stage context templates include completion and handoff sections', () => {
|
|
133
|
+
const stageFiles = [
|
|
134
|
+
'.workspace-templates/workspace/01-input/CONTEXT.md',
|
|
135
|
+
'.workspace-templates/workspace/02-process/CONTEXT.md',
|
|
136
|
+
'.workspace-templates/workspace/03-output/CONTEXT.md',
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
for (const file of stageFiles) {
|
|
140
|
+
const fullPath = path.join(templatesDir, file);
|
|
141
|
+
if (!fs.existsSync(fullPath)) {
|
|
142
|
+
fail(`File does not exist: ${fullPath}`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
147
|
+
expect(content).toContain('## Purpose');
|
|
148
|
+
expect(content).toContain('## Inputs');
|
|
149
|
+
expect(content).toContain('## Outputs');
|
|
150
|
+
expect(content).toContain('## Dependencies');
|
|
151
|
+
expect(content).toContain('## Required Evidence');
|
|
152
|
+
expect(content).toContain('## Completion Criteria');
|
|
153
|
+
expect(content).toContain('## Handoff');
|
|
154
|
+
expect(content.toLowerCase()).toContain('markdown');
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('execution-log template provides sequential stage checklist format', () => {
|
|
159
|
+
const logPath = path.join(templatesDir, '.workspace-templates', 'workspace', '00-meta', 'execution-log.md');
|
|
160
|
+
if (!fs.existsSync(logPath)) {
|
|
161
|
+
fail('execution-log.md does not exist');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
166
|
+
expect(content).toContain('## Stage Checklist');
|
|
167
|
+
expect(content).toContain('- [ ] 01-input');
|
|
168
|
+
expect(content).toContain('- [ ] 02-process');
|
|
169
|
+
expect(content).toContain('- [ ] 03-output');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('template scaffold script generates robust routing and scope sections', () => {
|
|
173
|
+
const scriptPath = path.join(templatesDir, '.workspace-templates', 'scripts', 'scaffold.ts');
|
|
174
|
+
if (!fs.existsSync(scriptPath)) {
|
|
175
|
+
fail('Template scaffold script does not exist');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const content = fs.readFileSync(scriptPath, 'utf-8');
|
|
180
|
+
expect(content).toContain('## Workflow Rules');
|
|
181
|
+
expect(content).toContain('## Scope Guardrails');
|
|
182
|
+
expect(content).toContain('## Stage Boundaries');
|
|
183
|
+
expect(content).toContain('## Task Routing');
|
|
184
|
+
expect(content).toContain('## Loading Order');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('template validate script enforces structural and semantic routing checks', () => {
|
|
188
|
+
const scriptPath = path.join(templatesDir, '.workspace-templates', 'scripts', 'validate.ts');
|
|
189
|
+
if (!fs.existsSync(scriptPath)) {
|
|
190
|
+
fail('Template validate script does not exist');
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const content = fs.readFileSync(scriptPath, 'utf-8');
|
|
195
|
+
expect(content).toContain('REQUIRED_SYSTEM_HEADINGS');
|
|
196
|
+
expect(content).toContain('REQUIRED_ROOT_CONTEXT_HEADINGS');
|
|
197
|
+
expect(content).toContain('Root routing references all numbered stages');
|
|
198
|
+
expect(content).toContain('dependencies do not point to later stages');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('SKILL.md has YAML frontmatter with name and description', () => {
|
|
202
|
+
const skillPath = path.join(templatesDir, 'SKILL.md');
|
|
203
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
204
|
+
expect(content).toMatch(/^---\nname:/m);
|
|
205
|
+
expect(content).toMatch(/description:/);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('SKILL.md references all 7 sub-skills', () => {
|
|
209
|
+
const skillPath = path.join(templatesDir, 'SKILL.md');
|
|
210
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
211
|
+
expect(content).toContain('validation');
|
|
212
|
+
expect(content).toContain('research');
|
|
213
|
+
expect(content).toContain('prompt-engineering');
|
|
214
|
+
expect(content).toContain('testing');
|
|
215
|
+
expect(content).toContain('iteration');
|
|
216
|
+
expect(content).toContain('architecture');
|
|
217
|
+
expect(content).toContain('tooling');
|
|
218
|
+
});
|
|
219
|
+
});
|