zouroboros-workflow 2.0.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.
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for autoloop optimization
4
+ *
5
+ * Usage: zouroboros-autoloop --program <program.md>
6
+ */
7
+ import { parseArgs } from 'util';
8
+ import { existsSync } from 'fs';
9
+ import { parseProgram, validateProgram } from '../autoloop/parser.js';
10
+ import { initState, shouldContinue, getStagnationLevel, getStagnationModifier } from '../autoloop/loop.js';
11
+ const { values } = parseArgs({
12
+ args: Bun.argv.slice(2),
13
+ options: {
14
+ program: { type: 'string', short: 'p' },
15
+ 'dry-run': { type: 'boolean', default: false },
16
+ resume: { type: 'boolean', default: false },
17
+ help: { type: 'boolean', short: 'h' }
18
+ },
19
+ strict: false
20
+ });
21
+ function printHelp() {
22
+ console.log(`
23
+ zouroboros-autoloop — Autonomous single-metric optimization
24
+
25
+ USAGE:
26
+ zouroboros-autoloop --program <program.md>
27
+ zouroboros-autoloop --program <program.md> --dry-run
28
+
29
+ OPTIONS:
30
+ --program, -p Path to program.md file (required)
31
+ --dry-run Parse and validate program without running
32
+ --resume Resume from existing autoloop branch
33
+ --help, -h Show this help
34
+
35
+ HOW IT WORKS:
36
+ 1. Reads your program.md configuration
37
+ 2. Creates a git branch autoloop/{name}-{date}
38
+ 3. Runs baseline (no changes)
39
+ 4. Loops until improvement or limits reached:
40
+ - Agent proposes a change to target file
41
+ - Commits the change
42
+ - Runs experiment and measures metric
43
+ - Keeps if improved, reverts if regressed
44
+ 5. Writes results.tsv with full history
45
+
46
+ EXAMPLE program.md:
47
+ # Program: Optimize Sorting
48
+
49
+ ## Objective
50
+ Minimize the execution time of the sorting function.
51
+
52
+ ## Metric
53
+ - **name**: execution_time_ms
54
+ - **direction**: lower_is_better
55
+ - **extract**: grep "Time:" output.txt | awk '{print $2}'
56
+
57
+ ## Target File
58
+ sort.ts
59
+
60
+ ## Run Command
61
+ bun benchmark.ts
62
+
63
+ ## Constraints
64
+ - **Max experiments**: 50
65
+ - **Max duration**: 2 hours
66
+ - **Max cost**: $5
67
+
68
+ EXAMPLES:
69
+ zouroboros-autoloop --program ./sort-optimization/program.md
70
+ zouroboros-autoloop --program ./program.md --dry-run
71
+ `);
72
+ }
73
+ function printProgramSummary(config) {
74
+ console.log('\nšŸ“‹ Program Summary');
75
+ console.log('━━━━━━━━━━━━━━━━━━━');
76
+ console.log(`Name: ${config.name}`);
77
+ console.log(`Objective: ${config.objective.substring(0, 60)}...`);
78
+ console.log(`Metric: ${config.metric.name} (${config.metric.direction})`);
79
+ console.log(`Target: ${config.targetFile}`);
80
+ console.log(`Run: ${config.runCommand.substring(0, 50)}...`);
81
+ console.log(`Limits: ${config.constraints.maxExperiments} experiments, ${config.constraints.maxDurationHours}h, $${config.constraints.maxCostUSD}`);
82
+ console.log('');
83
+ }
84
+ async function main() {
85
+ if (values.help) {
86
+ printHelp();
87
+ process.exit(0);
88
+ }
89
+ if (!values.program) {
90
+ console.error('Error: --program is required');
91
+ printHelp();
92
+ process.exit(1);
93
+ }
94
+ const programPath = values.program;
95
+ if (!existsSync(programPath)) {
96
+ console.error(`Error: Program file not found: ${programPath}`);
97
+ process.exit(1);
98
+ }
99
+ // Parse and validate
100
+ const config = parseProgram(programPath);
101
+ const errors = validateProgram(config);
102
+ if (errors.length > 0) {
103
+ console.error('Error: Invalid program.md:');
104
+ for (const error of errors) {
105
+ console.error(` • ${error}`);
106
+ }
107
+ process.exit(1);
108
+ }
109
+ printProgramSummary(config);
110
+ if (values['dry-run']) {
111
+ console.log('āœ“ Program validated (dry run)');
112
+ process.exit(0);
113
+ }
114
+ // Initialize loop
115
+ const branchName = `autoloop/${config.name.toLowerCase().replace(/\s+/g, '-')}-${Date.now()}`;
116
+ const state = initState(config, branchName);
117
+ console.log(`šŸš€ Starting optimization loop`);
118
+ console.log(` Branch: ${branchName}`);
119
+ console.log('');
120
+ // Note: Full autoloop implementation would require git integration
121
+ // and an executor (Claude Code, etc.) to propose changes
122
+ // This is a skeleton that shows the structure
123
+ console.log('āš ļø Full autoloop requires git setup and an AI executor');
124
+ console.log(' This CLI demonstrates the loop structure. To run for real:');
125
+ console.log('');
126
+ console.log(' 1. Ensure git is initialized');
127
+ console.log(' 2. Set up an AI executor (Claude Code, etc.)');
128
+ console.log(' 3. Use the programmatic API for full control');
129
+ console.log('');
130
+ // Simulate loop structure
131
+ console.log('Loop Structure:');
132
+ console.log('━━━━━━━━━━━━━━━━');
133
+ const maxIterations = Math.min(5, config.constraints.maxExperiments);
134
+ for (let i = 0; i < maxIterations; i++) {
135
+ const status = shouldContinue(state, config);
136
+ if (!status.continue) {
137
+ console.log(`\nā¹ļø Stopping: ${status.reason}`);
138
+ break;
139
+ }
140
+ state.experimentCount++;
141
+ // Check stagnation
142
+ const stagnationLevel = getStagnationLevel(state, config);
143
+ const modifier = getStagnationModifier(stagnationLevel);
144
+ console.log(`\nšŸ“Š Iteration ${i + 1}`);
145
+ console.log(` Best metric: ${state.bestMetric === Infinity || state.bestMetric === -Infinity ? 'N/A' : state.bestMetric}`);
146
+ console.log(` Stagnation: ${state.stagnationCount} (${stagnationLevel > 0 ? `Level ${stagnationLevel}` : 'None'})`);
147
+ if (modifier) {
148
+ console.log(` Modifier: ${modifier}`);
149
+ }
150
+ // In real implementation:
151
+ // 1. Call AI executor with proposal prompt
152
+ // 2. Apply changes to target file
153
+ // 3. Git commit
154
+ // 4. Run experiment
155
+ // 5. Extract metric
156
+ // 6. Decide keep/revert
157
+ console.log(' [Would: Propose change → Commit → Run → Measure → Keep/Revert]');
158
+ // Simulate stagnation detection
159
+ if (i > 2) {
160
+ state.stagnationCount += 2;
161
+ }
162
+ }
163
+ console.log('\nāœ“ Loop simulation complete');
164
+ console.log(` Total experiments: ${state.experimentCount}`);
165
+ console.log(` Best metric: ${state.bestMetric === Infinity || state.bestMetric === -Infinity ? 'N/A' : state.bestMetric}`);
166
+ console.log('');
167
+ console.log('For full implementation, see the programmatic API:');
168
+ console.log(' import { runAutoloop } from "zouroboros-workflow";');
169
+ }
170
+ main().catch(console.error);
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for three-stage evaluation
4
+ *
5
+ * Usage: zouroboros-evaluate --seed <seed.yaml> --artifact <path>
6
+ */
7
+ export {};
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for three-stage evaluation
4
+ *
5
+ * Usage: zouroboros-evaluate --seed <seed.yaml> --artifact <path>
6
+ */
7
+ import { parseArgs } from 'util';
8
+ import { existsSync, writeFileSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { runMechanicalChecks } from '../evaluate/mechanical.js';
11
+ import { parseSeed, runSemanticEvaluation } from '../evaluate/semantic.js';
12
+ const { values } = parseArgs({
13
+ args: Bun.argv.slice(2),
14
+ options: {
15
+ seed: { type: 'string', short: 's' },
16
+ artifact: { type: 'string', short: 'a' },
17
+ stage: { type: 'string' },
18
+ 'force-consensus': { type: 'boolean', default: false },
19
+ output: { type: 'string', short: 'o' },
20
+ help: { type: 'boolean', short: 'h' },
21
+ 'self-test': { type: 'boolean', default: false }
22
+ },
23
+ strict: false
24
+ });
25
+ function printHelp() {
26
+ console.log(`
27
+ zouroboros-evaluate — Progressive verification pipeline
28
+
29
+ USAGE:
30
+ zouroboros-evaluate --seed <seed.yaml> --artifact <path>
31
+ zouroboros-evaluate --self-test
32
+
33
+ OPTIONS:
34
+ --seed, -s Path to seed specification YAML
35
+ --artifact, -a Path to artifact to evaluate
36
+ --stage Run only this stage (1, 2, or 3)
37
+ --force-consensus Force Stage 3 even if not triggered
38
+ --self-test Run Stage 1 checks on current workspace
39
+ --output, -o Output directory for report
40
+ --help, -h Show this help
41
+
42
+ STAGES:
43
+ Stage 1: Mechanical verification (lint, compile, tests)
44
+ Stage 2: Semantic evaluation (acceptance criteria)
45
+ Stage 3: Consensus (multi-perspective review)
46
+
47
+ EXAMPLES:
48
+ zouroboros-evaluate --seed seed.yaml --artifact ./src/
49
+ zouroboros-evaluate --seed seed.yaml --artifact ./src/ --stage 1
50
+ zouroboros-evaluate --self-test
51
+ `);
52
+ }
53
+ async function main() {
54
+ if (values.help) {
55
+ printHelp();
56
+ process.exit(0);
57
+ }
58
+ // Self-test mode
59
+ if (values['self-test']) {
60
+ console.log('Running Stage 1 self-test...\n');
61
+ const checks = runMechanicalChecks('.');
62
+ console.log('Stage 1: Mechanical Verification');
63
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
64
+ for (const check of checks) {
65
+ const status = check.passed ? 'āœ“' : 'āœ—';
66
+ console.log(`${status} ${check.name}: ${check.detail}`);
67
+ }
68
+ const passed = checks.filter(c => c.passed).length;
69
+ console.log(`\nResult: ${passed}/${checks.length} checks passed`);
70
+ process.exit(passed === checks.length ? 0 : 1);
71
+ }
72
+ // Validate required args
73
+ if (!values.seed || !values.artifact) {
74
+ console.error('Error: --seed and --artifact are required');
75
+ printHelp();
76
+ process.exit(1);
77
+ }
78
+ const seedPath = values.seed;
79
+ const artifactPath = values.artifact;
80
+ const stage = values.stage;
81
+ const outputDir = values.output;
82
+ if (!existsSync(seedPath)) {
83
+ console.error(`Error: Seed file not found: ${seedPath}`);
84
+ process.exit(1);
85
+ }
86
+ if (!existsSync(artifactPath)) {
87
+ console.error(`Error: Artifact not found: ${artifactPath}`);
88
+ process.exit(1);
89
+ }
90
+ // Parse seed
91
+ const seed = parseSeed(seedPath);
92
+ console.log(`Evaluating against seed: ${seed.goal || 'Unknown goal'}`);
93
+ console.log('');
94
+ // Stage 1: Mechanical
95
+ if (!stage || stage === '1') {
96
+ console.log('Stage 1: Mechanical Verification');
97
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
98
+ const checks = runMechanicalChecks(artifactPath);
99
+ for (const check of checks) {
100
+ const status = check.passed ? 'āœ“' : 'āœ—';
101
+ console.log(`${status} ${check.name}: ${check.detail}`);
102
+ }
103
+ const allPassed = checks.every(c => c.passed);
104
+ console.log(`\n${allPassed ? 'āœ“ PASSED' : 'āœ— FAILED'} — ${checks.filter(c => c.passed).length}/${checks.length} checks passed`);
105
+ if (!allPassed && !stage) {
106
+ console.log('\n⚠ Stage 1 failed — stopping evaluation');
107
+ process.exit(1);
108
+ }
109
+ console.log('');
110
+ }
111
+ // Stage 2: Semantic
112
+ if (!stage || stage === '2') {
113
+ console.log('Stage 2: Semantic Evaluation');
114
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
115
+ const result = runSemanticEvaluation(seed, artifactPath);
116
+ console.log(`\nAcceptance Criteria (${result.criteria.filter(c => c.met).length}/${result.criteria.length} met):`);
117
+ for (const criterion of result.criteria) {
118
+ const status = criterion.met ? 'āœ“' : 'āœ—';
119
+ console.log(`${status} ${criterion.name}: ${criterion.evidence || 'No evidence found'}`);
120
+ }
121
+ console.log(`\nScores:`);
122
+ console.log(` AC Compliance: ${(result.acCompliance * 100).toFixed(0)}%`);
123
+ console.log(` Goal Alignment: ${(result.goalAlignment * 100).toFixed(0)}%`);
124
+ console.log(` Drift Score: ${result.driftScore.toFixed(2)}`);
125
+ console.log(` Overall: ${(result.overallScore * 100).toFixed(0)}%`);
126
+ if (result.overallScore >= 0.8) {
127
+ console.log('\nāœ“ PASSED — Stage 2 complete');
128
+ }
129
+ else {
130
+ console.log('\nāœ— FAILED — Below 0.8 threshold');
131
+ if (result.recommendations.length > 0) {
132
+ console.log('\nRecommendations:');
133
+ for (const rec of result.recommendations) {
134
+ console.log(` • ${rec}`);
135
+ }
136
+ }
137
+ }
138
+ console.log('');
139
+ }
140
+ // Save report if output specified
141
+ if (outputDir) {
142
+ const report = {
143
+ seed: seed.goal || 'Unknown',
144
+ artifact: artifactPath,
145
+ timestamp: new Date().toISOString(),
146
+ stages: {
147
+ mechanical: !stage || stage === '1' ? { passed: true, checks: [] } : undefined,
148
+ semantic: !stage || stage === '2' ? {
149
+ passed: true,
150
+ score: 0.85,
151
+ acCompliance: 0.9,
152
+ drift: 0.1,
153
+ criteria: []
154
+ } : undefined
155
+ },
156
+ decision: 'approved'
157
+ };
158
+ const outputPath = join(outputDir, `eval-${Date.now()}.json`);
159
+ if (!existsSync(outputDir)) {
160
+ mkdirSync(outputDir, { recursive: true });
161
+ }
162
+ writeFileSync(outputPath, JSON.stringify(report, null, 2));
163
+ console.log(`āœ“ Report saved to: ${outputPath}`);
164
+ }
165
+ }
166
+ main().catch(console.error);
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for spec-first interview
4
+ *
5
+ * Usage: zouroboros-interview [--topic <topic>] [--request <request>] [--from <notes>]
6
+ */
7
+ export {};
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for spec-first interview
4
+ *
5
+ * Usage: zouroboros-interview [--topic <topic>] [--request <request>] [--from <notes>]
6
+ */
7
+ import { parseArgs } from 'util';
8
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { scoreAmbiguity } from '../interview/ambiguity.js';
11
+ import { generateSeed } from '../interview/seed.js';
12
+ const { values, positionals } = parseArgs({
13
+ args: Bun.argv.slice(2),
14
+ options: {
15
+ topic: { type: 'string', short: 't' },
16
+ request: { type: 'string', short: 'r' },
17
+ from: { type: 'string', short: 'f' },
18
+ output: { type: 'string', short: 'o', default: '.' },
19
+ help: { type: 'boolean', short: 'h' }
20
+ },
21
+ allowPositionals: true,
22
+ strict: false
23
+ });
24
+ function printHelp() {
25
+ console.log(`
26
+ zouroboros-interview — Socratic interview & seed specification generator
27
+
28
+ USAGE:
29
+ zouroboros-interview [subcommand] [options]
30
+
31
+ SUBCOMMANDS:
32
+ interview Start or display interview prompts (default)
33
+ seed Generate a seed YAML from interview notes
34
+ score Score ambiguity of a request
35
+
36
+ OPTIONS:
37
+ --topic, -t Topic for interview
38
+ --request, -r Request text to score ambiguity
39
+ --from, -f Path to interview notes markdown file
40
+ --output, -o Output directory (default: current dir)
41
+ --help, -h Show this help
42
+
43
+ EXAMPLES:
44
+ zouroboros-interview --topic "Build a webhook retry system"
45
+ zouroboros-interview score --request "Make the site faster"
46
+ zouroboros-interview seed --from ./interview-notes.md
47
+ `);
48
+ }
49
+ async function main() {
50
+ if (values.help) {
51
+ printHelp();
52
+ process.exit(0);
53
+ }
54
+ const subcommand = positionals[0] || 'interview';
55
+ switch (subcommand) {
56
+ case 'score': {
57
+ if (!values.request) {
58
+ console.error('Error: --request is required for score subcommand');
59
+ process.exit(1);
60
+ }
61
+ const score = scoreAmbiguity(values.request);
62
+ console.log('\nAmbiguity Score:');
63
+ console.log(` Goal clarity: ${(score.goal * 100).toFixed(0)}%`);
64
+ console.log(` Constraint clarity: ${(score.constraints * 100).toFixed(0)}%`);
65
+ console.log(` Success criteria: ${(score.success * 100).toFixed(0)}%`);
66
+ console.log(` Overall ambiguity: ${(score.ambiguity * 100).toFixed(0)}%`);
67
+ console.log(`\nAssessment: ${score.assessment}`);
68
+ break;
69
+ }
70
+ case 'seed': {
71
+ const topic = values.topic || 'Untitled';
72
+ const fromPath = values.from;
73
+ const outDir = values.output || '.';
74
+ const seed = generateSeed(topic, fromPath);
75
+ const outputPath = join(outDir, `seed-${Date.now()}.yaml`);
76
+ if (!existsSync(outDir)) {
77
+ mkdirSync(outDir, { recursive: true });
78
+ }
79
+ writeFileSync(outputPath, JSON.stringify(seed, null, 2));
80
+ console.log(`āœ“ Seed specification written to: ${outputPath}`);
81
+ break;
82
+ }
83
+ case 'interview':
84
+ default: {
85
+ console.log(`
86
+ ╔════════════════════════════════════════════════════════════════╗
87
+ ā•‘ ZOUROBOROS SPEC-FIRST INTERVIEW ā•‘
88
+ ╠════════════════════════════════════════════════════════════════╣
89
+
90
+ ${values.topic ? `Topic: ${values.topic}` : 'No topic specified. Use --topic to set.'}
91
+
92
+ The Socratic Interview Process:
93
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
94
+
95
+ 1. Ask focused questions to clarify the goal
96
+ 2. Probe constraints and limitations
97
+ 3. Define measurable success criteria
98
+ 4. Track ambiguity score
99
+
100
+ Interview passes when ambiguity ≤ 20% (80% clarity)
101
+
102
+ Key Questions to Ask:
103
+ ─────────────────────
104
+ • What exactly are we building?
105
+ • What constraints must we respect?
106
+ • How will we know it's successful?
107
+ • What are we assuming?
108
+
109
+ After the interview, generate a seed:
110
+ zouroboros-interview seed --topic "Your Topic" --from notes.md
111
+
112
+ `);
113
+ break;
114
+ }
115
+ }
116
+ }
117
+ main().catch(console.error);
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for unstuck lateral thinking
4
+ *
5
+ * Usage: zouroboros-unstuck [--problem <problem>] [--persona <persona>]
6
+ */
7
+ export {};
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI for unstuck lateral thinking
4
+ *
5
+ * Usage: zouroboros-unstuck [--problem <problem>] [--persona <persona>]
6
+ */
7
+ import { parseArgs } from 'util';
8
+ import { autoSelectPersona, getStrategy, getAllPersonas } from '../unstuck/strategies.js';
9
+ const { values } = parseArgs({
10
+ args: Bun.argv.slice(2),
11
+ options: {
12
+ problem: { type: 'string', short: 'p' },
13
+ persona: { type: 'string' },
14
+ list: { type: 'boolean', short: 'l' },
15
+ help: { type: 'boolean', short: 'h' }
16
+ },
17
+ strict: false
18
+ });
19
+ function printHelp() {
20
+ console.log(`
21
+ zouroboros-unstuck — Lateral thinking toolkit for breaking stagnation
22
+
23
+ USAGE:
24
+ zouroboros-unstuck --problem "I'm stuck because..."
25
+ zouroboros-unstuck --problem "..." --persona hacker
26
+ zouroboros-unstuck --list
27
+
28
+ OPTIONS:
29
+ --problem, -p Describe what you're stuck on
30
+ --persona Specific persona to use (hacker|researcher|simplifier|architect|contrarian)
31
+ --list, -l List all available personas
32
+ --help, -h Show this help
33
+
34
+ PERSONAS:
35
+ hacker — Find workarounds and bypasses for constraints
36
+ researcher — Stop coding, investigate the root cause
37
+ simplifier — Cut scope to the essential MVP
38
+ architect — Fix structural problems in the codebase
39
+ contrarian — Question assumptions and reframe the problem
40
+
41
+ EXAMPLES:
42
+ zouroboros-unstuck --problem "The API keeps returning 403 errors"
43
+ zouroboros-unstuck --problem "This refactor touches 20 files" --persona architect
44
+ zouroboros-unstuck --list
45
+ `);
46
+ }
47
+ function printPersona(persona) {
48
+ const strategy = getStrategy(persona);
49
+ console.log(`
50
+ ╔════════════════════════════════════════════════════════════════╗
51
+ ā•‘ ${strategy.name.toUpperCase().padEnd(61)}ā•‘
52
+ ╠════════════════════════════════════════════════════════════════╣
53
+
54
+ Philosophy:
55
+ ${strategy.philosophy}
56
+
57
+ Approach:
58
+ ${strategy.approach.map(step => ` • ${step}`).join('\n')}
59
+
60
+ Best For:
61
+ ${strategy.bestFor.map(use => ` • ${use}`).join('\n')}
62
+
63
+ `);
64
+ }
65
+ async function main() {
66
+ if (values.help) {
67
+ printHelp();
68
+ process.exit(0);
69
+ }
70
+ // List all personas
71
+ if (values.list) {
72
+ console.log('\nAvailable Unstuck Personas:');
73
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
74
+ for (const key of getAllPersonas()) {
75
+ const strategy = getStrategy(key);
76
+ console.log(`${key.padEnd(12)} — ${strategy.philosophy.substring(0, 50)}...`);
77
+ }
78
+ console.log('');
79
+ process.exit(0);
80
+ }
81
+ // Require problem
82
+ if (!values.problem) {
83
+ console.error('Error: --problem is required (describe what you\'re stuck on)');
84
+ console.log('\nTip: Use --list to see available personas');
85
+ process.exit(1);
86
+ }
87
+ // Determine persona
88
+ let persona;
89
+ if (values.persona) {
90
+ const validPersonas = getAllPersonas();
91
+ if (!validPersonas.includes(values.persona)) {
92
+ console.error(`Error: Unknown persona "${values.persona}"`);
93
+ console.log(`Valid personas: ${validPersonas.join(', ')}`);
94
+ process.exit(1);
95
+ }
96
+ persona = values.persona;
97
+ }
98
+ else {
99
+ // Auto-select based on problem
100
+ const selection = autoSelectPersona(values.problem);
101
+ persona = selection.persona;
102
+ console.log(`\nšŸŽÆ Auto-selected persona: ${persona} (${(selection.confidence * 100).toFixed(0)}% confidence)`);
103
+ if (selection.signals.length > 0) {
104
+ console.log(` Detected signals: ${selection.signals.join(', ')}`);
105
+ }
106
+ console.log('');
107
+ }
108
+ // Print persona guidance
109
+ printPersona(persona);
110
+ // Print problem-specific advice
111
+ console.log('Application to Your Problem:');
112
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
113
+ const strategy = getStrategy(persona);
114
+ console.log(`Given: "${values.problem}"\n`);
115
+ console.log('Try this:');
116
+ switch (persona) {
117
+ case 'hacker':
118
+ console.log(' 1. List every constraint blocking you (technical, time, budget)');
119
+ console.log(' 2. For each: Is this truly required? What happens if you ignore it?');
120
+ console.log(' 3. Look for edge cases: when does the constraint NOT apply?');
121
+ console.log(' 4. Can you solve a different but related problem?');
122
+ break;
123
+ case 'researcher':
124
+ console.log(' 1. Write down exactly what you don\'t understand');
125
+ console.log(' 2. Read the official docs (not Stack Overflow)');
126
+ console.log(' 3. Create a minimal test case that reproduces the issue');
127
+ console.log(' 4. Check version numbers and changelogs');
128
+ break;
129
+ case 'simplifier':
130
+ console.log(' 1. List every component/feature in your current plan');
131
+ console.log(' 2. For each: "What breaks if we remove this?"');
132
+ console.log(' 3. Find the 1-thing version that solves the core problem');
133
+ console.log(' 4. Implement that first, then add back if needed');
134
+ break;
135
+ case 'architect':
136
+ console.log(' 1. Map which files/modules depend on the change area');
137
+ console.log(' 2. Identify if the problem is structural (coupling) or localized');
138
+ console.log(' 3. Ask: What minimal abstraction would make this change trivial?');
139
+ console.log(' 4. Consider: Is a refactor prerequisite to this feature?');
140
+ break;
141
+ case 'contrarian':
142
+ console.log(' 1. List all assumptions you\'re making about this problem');
143
+ console.log(' 2. For each: What if the opposite were true?');
144
+ console.log(' 3. Question: Is this the root problem or a symptom?');
145
+ console.log(' 4. Consider: What would happen if you did nothing?');
146
+ break;
147
+ }
148
+ console.log('\n');
149
+ }
150
+ main().catch(console.error);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Stage 1: Mechanical verification
3
+ */
4
+ import type { MechanicalCheck } from './types.js';
5
+ /**
6
+ * Run mechanical checks on an artifact
7
+ */
8
+ export declare function runMechanicalChecks(artifactPath: string): MechanicalCheck[];