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.
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/autoloop/loop.d.ts +48 -0
- package/dist/autoloop/loop.js +145 -0
- package/dist/autoloop/parser.d.ts +12 -0
- package/dist/autoloop/parser.js +121 -0
- package/dist/autoloop/types.d.ts +54 -0
- package/dist/autoloop/types.js +4 -0
- package/dist/cli/autoloop.d.ts +7 -0
- package/dist/cli/autoloop.js +170 -0
- package/dist/cli/evaluate.d.ts +7 -0
- package/dist/cli/evaluate.js +166 -0
- package/dist/cli/interview.d.ts +7 -0
- package/dist/cli/interview.js +117 -0
- package/dist/cli/unstuck.d.ts +7 -0
- package/dist/cli/unstuck.js +150 -0
- package/dist/evaluate/mechanical.d.ts +8 -0
- package/dist/evaluate/mechanical.js +106 -0
- package/dist/evaluate/semantic.d.ts +13 -0
- package/dist/evaluate/semantic.js +167 -0
- package/dist/evaluate/types.d.ts +57 -0
- package/dist/evaluate/types.js +4 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +20 -0
- package/dist/interview/ambiguity.d.ts +9 -0
- package/dist/interview/ambiguity.js +53 -0
- package/dist/interview/seed.d.ts +12 -0
- package/dist/interview/seed.js +120 -0
- package/dist/interview/types.d.ts +49 -0
- package/dist/interview/types.js +4 -0
- package/dist/unstuck/strategies.d.ts +20 -0
- package/dist/unstuck/strategies.js +164 -0
- package/dist/unstuck/types.d.ts +23 -0
- package/dist/unstuck/types.js +4 -0
- package/package.json +51 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unstuck persona strategies and auto-selection
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* All available unstuck strategies
|
|
6
|
+
*/
|
|
7
|
+
export const STRATEGIES = {
|
|
8
|
+
hacker: {
|
|
9
|
+
persona: 'hacker',
|
|
10
|
+
name: 'Hacker',
|
|
11
|
+
philosophy: "You don't accept 'impossible' — you find the path others miss.",
|
|
12
|
+
approach: [
|
|
13
|
+
'List every explicit and implicit constraint',
|
|
14
|
+
'Question which constraints are actually required',
|
|
15
|
+
'Look for edge cases and bypasses',
|
|
16
|
+
'Consider solving a completely different (easier) problem'
|
|
17
|
+
],
|
|
18
|
+
bestFor: ['Blocked by error', 'API limitation', 'Library bug', 'Impossible constraint']
|
|
19
|
+
},
|
|
20
|
+
researcher: {
|
|
21
|
+
persona: 'researcher',
|
|
22
|
+
name: 'Researcher',
|
|
23
|
+
philosophy: 'Most blocks exist because we\'re missing information. Stop guessing — go find the answer.',
|
|
24
|
+
approach: [
|
|
25
|
+
'Define exactly what is unknown',
|
|
26
|
+
'Gather evidence systematically (source code, docs, tests)',
|
|
27
|
+
'Read official documentation first',
|
|
28
|
+
'Form a specific, evidence-based hypothesis'
|
|
29
|
+
],
|
|
30
|
+
bestFor: ['Unclear behavior', 'Undocumented APIs', 'Version-specific bugs', 'Should work but does not']
|
|
31
|
+
},
|
|
32
|
+
simplifier: {
|
|
33
|
+
persona: 'simplifier',
|
|
34
|
+
name: 'Simplifier',
|
|
35
|
+
philosophy: 'Complexity is the enemy of progress. Remove until only the essential remains.',
|
|
36
|
+
approach: [
|
|
37
|
+
'List every component involved',
|
|
38
|
+
'Challenge each one: "Is this truly necessary?"',
|
|
39
|
+
'Find the absolute minimum that solves the core problem',
|
|
40
|
+
'Ask: "What\'s the simplest thing that could possibly work?"'
|
|
41
|
+
],
|
|
42
|
+
bestFor: ['Over-engineered solutions', 'Scope creep', 'Analysis paralysis', 'Too many moving parts']
|
|
43
|
+
},
|
|
44
|
+
architect: {
|
|
45
|
+
persona: 'architect',
|
|
46
|
+
name: 'Architect',
|
|
47
|
+
philosophy: 'If you\'re fighting the architecture, the architecture is wrong.',
|
|
48
|
+
approach: [
|
|
49
|
+
'Identify structural symptoms (recurring bugs, high coupling)',
|
|
50
|
+
'Map current abstractions and coupling points',
|
|
51
|
+
'Find the root misalignment',
|
|
52
|
+
'Propose minimal structural change that unblocks progress'
|
|
53
|
+
],
|
|
54
|
+
bestFor: ['Recurring bugs in different forms', 'Simple changes touching many files', 'Performance problems']
|
|
55
|
+
},
|
|
56
|
+
contrarian: {
|
|
57
|
+
persona: 'contrarian',
|
|
58
|
+
name: 'Contrarian',
|
|
59
|
+
philosophy: 'The opposite of a great truth is often another great truth.',
|
|
60
|
+
approach: [
|
|
61
|
+
'List every assumption being made',
|
|
62
|
+
'Consider: what if the opposite were true?',
|
|
63
|
+
'Challenge the problem statement itself',
|
|
64
|
+
'Ask: what would happen if we did nothing?'
|
|
65
|
+
],
|
|
66
|
+
bestFor: ['Groupthink', 'Assumed requirements', 'Obvious solutions not working']
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Signal patterns for auto-selecting the best unstuck persona
|
|
71
|
+
*/
|
|
72
|
+
const SIGNAL_PATTERNS = {
|
|
73
|
+
// Hacker signals
|
|
74
|
+
'error': [{ persona: 'hacker', weight: 3 }],
|
|
75
|
+
'bug': [{ persona: 'hacker', weight: 3 }],
|
|
76
|
+
'crash': [{ persona: 'hacker', weight: 3 }],
|
|
77
|
+
'broken': [{ persona: 'hacker', weight: 3 }],
|
|
78
|
+
'cannot': [{ persona: 'hacker', weight: 2 }],
|
|
79
|
+
'won\'t': [{ persona: 'hacker', weight: 2 }],
|
|
80
|
+
'impossible': [{ persona: 'hacker', weight: 5 }],
|
|
81
|
+
'constraint': [{ persona: 'hacker', weight: 2 }],
|
|
82
|
+
'limitation': [{ persona: 'hacker', weight: 2 }],
|
|
83
|
+
// Researcher signals
|
|
84
|
+
'don\'t understand': [{ persona: 'researcher', weight: 4 }],
|
|
85
|
+
'unclear': [{ persona: 'researcher', weight: 3 }],
|
|
86
|
+
'unexpected': [{ persona: 'researcher', weight: 3 }],
|
|
87
|
+
'why': [{ persona: 'researcher', weight: 2 }],
|
|
88
|
+
'behavior': [{ persona: 'researcher', weight: 2 }],
|
|
89
|
+
'document': [{ persona: 'researcher', weight: 2 }],
|
|
90
|
+
'version': [{ persona: 'researcher', weight: 2 }],
|
|
91
|
+
// Simplifier signals
|
|
92
|
+
'complex': [{ persona: 'simplifier', weight: 4 }],
|
|
93
|
+
'too many': [{ persona: 'simplifier', weight: 4 }],
|
|
94
|
+
'overwhelm': [{ persona: 'simplifier', weight: 3 }],
|
|
95
|
+
'scope': [{ persona: 'simplifier', weight: 2 }],
|
|
96
|
+
'scope creep': [{ persona: 'simplifier', weight: 5 }],
|
|
97
|
+
'simple': [{ persona: 'simplifier', weight: 2 }],
|
|
98
|
+
'mvp': [{ persona: 'simplifier', weight: 3 }],
|
|
99
|
+
// Architect signals
|
|
100
|
+
'recurring': [{ persona: 'architect', weight: 4 }],
|
|
101
|
+
'keeps breaking': [{ persona: 'architect', weight: 5 }],
|
|
102
|
+
'touching everything': [{ persona: 'architect', weight: 5 }],
|
|
103
|
+
'structural': [{ persona: 'architect', weight: 3 }],
|
|
104
|
+
'architecture': [{ persona: 'architect', weight: 3 }],
|
|
105
|
+
'refactor': [{ persona: 'architect', weight: 2 }],
|
|
106
|
+
'performance': [{ persona: 'architect', weight: 2 }],
|
|
107
|
+
// Contrarian signals
|
|
108
|
+
'wrong approach': [{ persona: 'contrarian', weight: 4 }],
|
|
109
|
+
'step back': [{ persona: 'contrarian', weight: 3 }],
|
|
110
|
+
'assumption': [{ persona: 'contrarian', weight: 2 }],
|
|
111
|
+
'should we': [{ persona: 'contrarian', weight: 2 }],
|
|
112
|
+
'do nothing': [{ persona: 'contrarian', weight: 2 }]
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Auto-select the best unstuck persona based on problem description
|
|
116
|
+
*/
|
|
117
|
+
export function autoSelectPersona(problem) {
|
|
118
|
+
const lower = problem.toLowerCase();
|
|
119
|
+
const scores = {
|
|
120
|
+
hacker: 0,
|
|
121
|
+
researcher: 0,
|
|
122
|
+
simplifier: 0,
|
|
123
|
+
architect: 0,
|
|
124
|
+
contrarian: 0
|
|
125
|
+
};
|
|
126
|
+
const signals = [];
|
|
127
|
+
for (const [pattern, matches] of Object.entries(SIGNAL_PATTERNS)) {
|
|
128
|
+
if (lower.includes(pattern)) {
|
|
129
|
+
signals.push(pattern);
|
|
130
|
+
for (const match of matches) {
|
|
131
|
+
scores[match.persona] += match.weight;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Find highest scoring persona
|
|
136
|
+
let bestPersona = 'contrarian'; // Default
|
|
137
|
+
let bestScore = 0;
|
|
138
|
+
for (const [persona, score] of Object.entries(scores)) {
|
|
139
|
+
if (score > bestScore) {
|
|
140
|
+
bestScore = score;
|
|
141
|
+
bestPersona = persona;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Calculate confidence
|
|
145
|
+
const totalScore = Object.values(scores).reduce((a, b) => a + b, 0);
|
|
146
|
+
const confidence = totalScore > 0 ? bestScore / totalScore : 0.2;
|
|
147
|
+
return {
|
|
148
|
+
persona: bestPersona,
|
|
149
|
+
confidence: Math.min(confidence, 1),
|
|
150
|
+
signals
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get strategy for a specific persona
|
|
155
|
+
*/
|
|
156
|
+
export function getStrategy(persona) {
|
|
157
|
+
return STRATEGIES[persona];
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all available personas
|
|
161
|
+
*/
|
|
162
|
+
export function getAllPersonas() {
|
|
163
|
+
return Object.keys(STRATEGIES);
|
|
164
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for unstuck lateral thinking
|
|
3
|
+
*/
|
|
4
|
+
export type UnstuckPersona = 'hacker' | 'researcher' | 'simplifier' | 'architect' | 'contrarian';
|
|
5
|
+
export interface UnstuckStrategy {
|
|
6
|
+
persona: UnstuckPersona;
|
|
7
|
+
name: string;
|
|
8
|
+
philosophy: string;
|
|
9
|
+
approach: string[];
|
|
10
|
+
bestFor: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface UnstuckSession {
|
|
13
|
+
id: string;
|
|
14
|
+
problem: string;
|
|
15
|
+
selectedPersona: UnstuckPersona;
|
|
16
|
+
timestamp: number;
|
|
17
|
+
suggestions: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface AutoSelectResult {
|
|
20
|
+
persona: UnstuckPersona;
|
|
21
|
+
confidence: number;
|
|
22
|
+
signals: string[];
|
|
23
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zouroboros-workflow",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Spec-first development tools: interview, evaluation, unstuck, and autoloop",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/marlandoj/zouroboros.git",
|
|
21
|
+
"directory": "packages/workflow"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"zouroboros-interview": "./dist/cli/interview.js",
|
|
25
|
+
"zouroboros-evaluate": "./dist/cli/evaluate.js",
|
|
26
|
+
"zouroboros-unstuck": "./dist/cli/unstuck.js",
|
|
27
|
+
"zouroboros-autoloop": "./dist/cli/autoloop.js"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"zouroboros-core": "2.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/bun": "latest",
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"workflow",
|
|
39
|
+
"spec-first",
|
|
40
|
+
"evaluation",
|
|
41
|
+
"autoloop",
|
|
42
|
+
"zouroboros"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"author": "marlandoj.zo.computer",
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc",
|
|
48
|
+
"dev": "tsc --watch",
|
|
49
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
50
|
+
}
|
|
51
|
+
}
|