@wundam/orchex 1.0.0-rc.2 → 1.0.0-rc.21
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/README.md +59 -18
- package/dist/cloud-executor.d.ts +71 -0
- package/dist/cloud-executor.js +335 -0
- package/dist/cloud-sync.d.ts +8 -0
- package/dist/cloud-sync.js +52 -0
- package/dist/config.d.ts +30 -4
- package/dist/config.js +61 -2
- package/dist/context-builder.d.ts +2 -0
- package/dist/context-builder.js +11 -3
- package/dist/cost.js +1 -1
- package/dist/entitlements/jwt.d.ts +7 -0
- package/dist/entitlements/jwt.js +78 -0
- package/dist/entitlements/resolve.d.ts +17 -0
- package/dist/entitlements/resolve.js +49 -0
- package/dist/entitlements/types.d.ts +21 -0
- package/dist/entitlements/types.js +4 -0
- package/dist/executors/base.d.ts +1 -1
- package/dist/executors/bedrock-executor.d.ts +39 -0
- package/dist/executors/bedrock-executor.js +197 -0
- package/dist/executors/index.d.ts +1 -0
- package/dist/executors/index.js +24 -1
- package/dist/index.js +468 -23
- package/dist/intelligence/index.d.ts +44 -0
- package/dist/intelligence/index.js +160 -0
- package/dist/key-cache.d.ts +31 -0
- package/dist/key-cache.js +84 -0
- package/dist/login-helpers.d.ts +25 -0
- package/dist/login-helpers.js +54 -0
- package/dist/manifest.js +18 -1
- package/dist/mcp-instructions.d.ts +1 -0
- package/dist/mcp-instructions.js +84 -0
- package/dist/mcp-resources.d.ts +8 -0
- package/dist/mcp-resources.js +420 -0
- package/dist/model-cache.d.ts +18 -0
- package/dist/model-cache.js +62 -0
- package/dist/model-validator.d.ts +20 -0
- package/dist/model-validator.js +125 -0
- package/dist/orchestrator.d.ts +14 -0
- package/dist/orchestrator.js +191 -32
- package/dist/setup/ide-registry.d.ts +13 -0
- package/dist/setup/ide-registry.js +51 -0
- package/dist/setup/index.d.ts +1 -0
- package/dist/setup/index.js +111 -0
- package/dist/tier-gating.js +0 -16
- package/dist/tiers.d.ts +35 -5
- package/dist/tiers.js +39 -3
- package/dist/tools.d.ts +6 -1
- package/dist/tools.js +852 -95
- package/dist/types.d.ts +71 -60
- package/dist/types.js +3 -0
- package/dist/waves.d.ts +1 -1
- package/dist/waves.js +29 -2
- package/package.json +41 -5
- package/src/entitlements/public-key.pem +9 -0
- package/dist/intelligence/anti-pattern-detector.d.ts +0 -117
- package/dist/intelligence/anti-pattern-detector.js +0 -327
- package/dist/intelligence/budget-enforcer.d.ts +0 -119
- package/dist/intelligence/budget-enforcer.js +0 -226
- package/dist/intelligence/context-optimizer.d.ts +0 -111
- package/dist/intelligence/context-optimizer.js +0 -282
- package/dist/intelligence/cost-tracker.d.ts +0 -114
- package/dist/intelligence/cost-tracker.js +0 -183
- package/dist/intelligence/deliverable-extractor.d.ts +0 -134
- package/dist/intelligence/deliverable-extractor.js +0 -909
- package/dist/intelligence/dependency-inferrer.d.ts +0 -87
- package/dist/intelligence/dependency-inferrer.js +0 -403
- package/dist/intelligence/diagnostics.d.ts +0 -33
- package/dist/intelligence/diagnostics.js +0 -64
- package/dist/intelligence/error-analyzer.d.ts +0 -7
- package/dist/intelligence/error-analyzer.js +0 -76
- package/dist/intelligence/file-chunker.d.ts +0 -15
- package/dist/intelligence/file-chunker.js +0 -64
- package/dist/intelligence/fix-stream-manager.d.ts +0 -59
- package/dist/intelligence/fix-stream-manager.js +0 -212
- package/dist/intelligence/heuristics.d.ts +0 -23
- package/dist/intelligence/heuristics.js +0 -124
- package/dist/intelligence/learning-engine.d.ts +0 -157
- package/dist/intelligence/learning-engine.js +0 -433
- package/dist/intelligence/learning-feedback.d.ts +0 -96
- package/dist/intelligence/learning-feedback.js +0 -202
- package/dist/intelligence/pattern-analyzer.d.ts +0 -35
- package/dist/intelligence/pattern-analyzer.js +0 -189
- package/dist/intelligence/plan-parser.d.ts +0 -124
- package/dist/intelligence/plan-parser.js +0 -498
- package/dist/intelligence/planner.d.ts +0 -29
- package/dist/intelligence/planner.js +0 -86
- package/dist/intelligence/self-healer.d.ts +0 -16
- package/dist/intelligence/self-healer.js +0 -84
- package/dist/intelligence/slicing-metrics.d.ts +0 -62
- package/dist/intelligence/slicing-metrics.js +0 -202
- package/dist/intelligence/slicing-templates.d.ts +0 -81
- package/dist/intelligence/slicing-templates.js +0 -420
- package/dist/intelligence/split-suggester.d.ts +0 -69
- package/dist/intelligence/split-suggester.js +0 -176
- package/dist/intelligence/stream-generator.d.ts +0 -90
- package/dist/intelligence/stream-generator.js +0 -452
- package/dist/telemetry/telemetry-types.d.ts +0 -85
- package/dist/telemetry/telemetry-types.js +0 -1
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Template Definitions
|
|
3
|
-
// ============================================================================
|
|
4
|
-
/**
|
|
5
|
-
* Template for documentation sets (guides, API docs, tutorials).
|
|
6
|
-
*/
|
|
7
|
-
const DOCUMENTATION_SET_TEMPLATE = {
|
|
8
|
-
id: 'documentation-set',
|
|
9
|
-
name: 'Documentation Set',
|
|
10
|
-
description: 'Multiple documentation files (guides, tutorials, API references) that should be created independently',
|
|
11
|
-
keywords: ['docs', 'documentation', 'guide', 'tutorial', 'readme', 'api reference', 'multiple pages'],
|
|
12
|
-
patterns: [
|
|
13
|
-
'Multiple .md files in docs/',
|
|
14
|
-
'Creating 3+ documentation files',
|
|
15
|
-
'Tutorial series',
|
|
16
|
-
'API documentation pages',
|
|
17
|
-
],
|
|
18
|
-
streamStructure: [
|
|
19
|
-
{
|
|
20
|
-
namePattern: 'docs-{topic}',
|
|
21
|
-
purpose: 'Create documentation for a specific topic',
|
|
22
|
-
dependsOn: [],
|
|
23
|
-
ownsPatterns: ['docs/{topic}/**/*.md'],
|
|
24
|
-
readsPatterns: ['src/**/*.ts', 'README.md'],
|
|
25
|
-
planOutline: 'Research implementation → Write documentation → Add examples → Review completeness',
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
guidelines: [
|
|
29
|
-
'Split by logical topic, not file count',
|
|
30
|
-
'Each stream should own 1-3 related doc files',
|
|
31
|
-
'Order dependencies: concepts → API reference → tutorials → advanced guides',
|
|
32
|
-
'Streams can run in parallel if topics are independent',
|
|
33
|
-
'Keep related examples with their topic',
|
|
34
|
-
],
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Template for code feature implementations.
|
|
38
|
-
*/
|
|
39
|
-
const CODE_FEATURE_TEMPLATE = {
|
|
40
|
-
id: 'code-feature',
|
|
41
|
-
name: 'Code Feature Implementation',
|
|
42
|
-
description: 'Multi-component feature with types, implementation, tests, and documentation',
|
|
43
|
-
keywords: ['feature', 'implement', 'add', 'create', 'types', 'tests', 'integration'],
|
|
44
|
-
patterns: [
|
|
45
|
-
'Types → Implementation → Tests → Docs',
|
|
46
|
-
'Multiple source files with dependencies',
|
|
47
|
-
'Test files alongside implementation',
|
|
48
|
-
'Integration with existing code',
|
|
49
|
-
],
|
|
50
|
-
streamStructure: [
|
|
51
|
-
{
|
|
52
|
-
namePattern: '{feature}-types',
|
|
53
|
-
purpose: 'Define interfaces, types, and schemas',
|
|
54
|
-
dependsOn: [],
|
|
55
|
-
ownsPatterns: ['src/types/{feature}.ts', 'src/schemas/{feature}.ts'],
|
|
56
|
-
readsPatterns: ['src/types.ts'],
|
|
57
|
-
planOutline: 'Analyze requirements → Define types → Add validation schemas → Export types',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
namePattern: '{feature}-core',
|
|
61
|
-
purpose: 'Core feature implementation',
|
|
62
|
-
dependsOn: ['{feature}-types'],
|
|
63
|
-
ownsPatterns: ['src/{feature}/*.ts'],
|
|
64
|
-
readsPatterns: ['src/types/{feature}.ts', 'src/utils/*.ts'],
|
|
65
|
-
planOutline: 'Implement core logic → Add error handling → Integrate with existing systems',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
namePattern: '{feature}-tests',
|
|
69
|
-
purpose: 'Unit and integration tests',
|
|
70
|
-
dependsOn: ['{feature}-core'],
|
|
71
|
-
ownsPatterns: ['tests/{feature}.test.ts'],
|
|
72
|
-
readsPatterns: ['src/{feature}/*.ts'],
|
|
73
|
-
planOutline: 'Write unit tests → Add integration tests → Test edge cases → Verify coverage',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
namePattern: '{feature}-docs',
|
|
77
|
-
purpose: 'Documentation and examples',
|
|
78
|
-
dependsOn: ['{feature}-core'],
|
|
79
|
-
ownsPatterns: ['docs/{feature}/*.md'],
|
|
80
|
-
readsPatterns: ['src/{feature}/*.ts'],
|
|
81
|
-
planOutline: 'Document API → Add usage examples → Write integration guide',
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
guidelines: [
|
|
85
|
-
'Always start with types to establish contracts',
|
|
86
|
-
'Core implementation depends on types being defined',
|
|
87
|
-
'Tests and docs can run in parallel after core is complete',
|
|
88
|
-
'Keep streams focused: one stream = one responsibility',
|
|
89
|
-
'If a file has 200+ lines, consider splitting implementation into multiple streams',
|
|
90
|
-
],
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Template for data/code migrations.
|
|
94
|
-
*/
|
|
95
|
-
const MIGRATION_TEMPLATE = {
|
|
96
|
-
id: 'migration',
|
|
97
|
-
name: 'Migration',
|
|
98
|
-
description: 'Migrating code, data, or structure with backward compatibility',
|
|
99
|
-
keywords: ['migration', 'migrate', 'refactor', 'rename', 'move', 'deprecate', 'backward compatible'],
|
|
100
|
-
patterns: [
|
|
101
|
-
'From old to new',
|
|
102
|
-
'Rename/move files or functions',
|
|
103
|
-
'Change data structure',
|
|
104
|
-
'Update multiple call sites',
|
|
105
|
-
'Maintain backward compatibility',
|
|
106
|
-
],
|
|
107
|
-
streamStructure: [
|
|
108
|
-
{
|
|
109
|
-
namePattern: '{migration}-new-implementation',
|
|
110
|
-
purpose: 'Create new implementation alongside old one',
|
|
111
|
-
dependsOn: [],
|
|
112
|
-
ownsPatterns: ['src/{new}/*.ts'],
|
|
113
|
-
readsPatterns: ['src/{old}/*.ts'],
|
|
114
|
-
planOutline: 'Implement new version → Match old API → Add compatibility layer',
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
namePattern: '{migration}-migrate-{component}',
|
|
118
|
-
purpose: 'Migrate specific component to new implementation',
|
|
119
|
-
dependsOn: ['{migration}-new-implementation'],
|
|
120
|
-
ownsPatterns: ['src/{component}/**/*.ts'],
|
|
121
|
-
readsPatterns: ['src/{new}/*.ts', 'src/{old}/*.ts'],
|
|
122
|
-
planOutline: 'Update imports → Replace function calls → Update tests → Verify behavior',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
namePattern: '{migration}-deprecate-old',
|
|
126
|
-
purpose: 'Mark old implementation as deprecated',
|
|
127
|
-
dependsOn: ['{migration}-migrate-*'],
|
|
128
|
-
ownsPatterns: ['src/{old}/*.ts'],
|
|
129
|
-
readsPatterns: [],
|
|
130
|
-
planOutline: 'Add deprecation notices → Update docs → Plan removal timeline',
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
guidelines: [
|
|
134
|
-
'Create new before removing old',
|
|
135
|
-
'Migrate in small, independent chunks (by component/module)',
|
|
136
|
-
'Each migration stream should be independently testable',
|
|
137
|
-
'Keep deprecation as the final step',
|
|
138
|
-
'Ensure each stream leaves the codebase in a working state',
|
|
139
|
-
],
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* Template for tutorial/example creation.
|
|
143
|
-
*/
|
|
144
|
-
const TUTORIAL_TEMPLATE = {
|
|
145
|
-
id: 'tutorial',
|
|
146
|
-
name: 'Tutorial Series',
|
|
147
|
-
description: 'Progressive tutorial series from basics to advanced',
|
|
148
|
-
keywords: ['tutorial', 'guide', 'example', 'walkthrough', 'getting started', 'beginner', 'advanced'],
|
|
149
|
-
patterns: [
|
|
150
|
-
'Multiple tutorial steps',
|
|
151
|
-
'Progressive complexity',
|
|
152
|
-
'Beginner → Intermediate → Advanced',
|
|
153
|
-
'Examples with documentation',
|
|
154
|
-
],
|
|
155
|
-
streamStructure: [
|
|
156
|
-
{
|
|
157
|
-
namePattern: 'tutorial-{level}-{topic}',
|
|
158
|
-
purpose: 'Create tutorial for specific level and topic',
|
|
159
|
-
dependsOn: ['tutorial-{previous-level}-*'],
|
|
160
|
-
ownsPatterns: ['docs/tutorials/{level}-{topic}.md', 'examples/{topic}/**/*'],
|
|
161
|
-
readsPatterns: ['src/**/*.ts', 'docs/tutorials/{previous}*.md'],
|
|
162
|
-
planOutline: 'Define learning objectives → Write tutorial → Create working example → Add exercises',
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
guidelines: [
|
|
166
|
-
'Order by prerequisite knowledge: basics → intermediate → advanced',
|
|
167
|
-
'Each tutorial should be self-contained but build on previous concepts',
|
|
168
|
-
'Include working code examples',
|
|
169
|
-
'Beginner tutorials can run in parallel if they cover different topics',
|
|
170
|
-
'Advanced tutorials depend on relevant beginner/intermediate tutorials',
|
|
171
|
-
],
|
|
172
|
-
};
|
|
173
|
-
/**
|
|
174
|
-
* Template for API reference documentation.
|
|
175
|
-
*/
|
|
176
|
-
const API_REFERENCE_TEMPLATE = {
|
|
177
|
-
id: 'api-reference',
|
|
178
|
-
name: 'API Reference',
|
|
179
|
-
description: 'Comprehensive API documentation for modules, classes, and functions',
|
|
180
|
-
keywords: ['api', 'reference', 'documentation', 'modules', 'classes', 'functions', 'methods'],
|
|
181
|
-
patterns: [
|
|
182
|
-
'Documenting multiple modules',
|
|
183
|
-
'Class/function reference',
|
|
184
|
-
'Method documentation',
|
|
185
|
-
'Parameter and return type docs',
|
|
186
|
-
],
|
|
187
|
-
streamStructure: [
|
|
188
|
-
{
|
|
189
|
-
namePattern: 'api-{module}-reference',
|
|
190
|
-
purpose: 'Create API reference for a specific module',
|
|
191
|
-
dependsOn: [],
|
|
192
|
-
ownsPatterns: ['docs/api/{module}.md'],
|
|
193
|
-
readsPatterns: ['src/{module}/**/*.ts'],
|
|
194
|
-
planOutline: 'Extract types/interfaces → Document functions → Add examples → Cross-link related APIs',
|
|
195
|
-
},
|
|
196
|
-
],
|
|
197
|
-
guidelines: [
|
|
198
|
-
'Split by module or logical grouping',
|
|
199
|
-
'All API reference streams can run in parallel',
|
|
200
|
-
'Include type signatures and examples',
|
|
201
|
-
'Cross-reference related APIs',
|
|
202
|
-
'Keep each stream to 1-2 related modules',
|
|
203
|
-
],
|
|
204
|
-
};
|
|
205
|
-
/**
|
|
206
|
-
* All available templates.
|
|
207
|
-
*/
|
|
208
|
-
const ALL_TEMPLATES = [
|
|
209
|
-
DOCUMENTATION_SET_TEMPLATE,
|
|
210
|
-
CODE_FEATURE_TEMPLATE,
|
|
211
|
-
MIGRATION_TEMPLATE,
|
|
212
|
-
TUTORIAL_TEMPLATE,
|
|
213
|
-
API_REFERENCE_TEMPLATE,
|
|
214
|
-
];
|
|
215
|
-
// ============================================================================
|
|
216
|
-
// Template Matching
|
|
217
|
-
// ============================================================================
|
|
218
|
-
/**
|
|
219
|
-
* Find the best matching template for a stream description.
|
|
220
|
-
* Returns null if no good match is found.
|
|
221
|
-
*/
|
|
222
|
-
export function findMatchingTemplate(description) {
|
|
223
|
-
const lowerDesc = description.toLowerCase();
|
|
224
|
-
let bestMatch = null;
|
|
225
|
-
for (const template of ALL_TEMPLATES) {
|
|
226
|
-
let score = 0;
|
|
227
|
-
// Check keyword matches
|
|
228
|
-
for (const keyword of template.keywords) {
|
|
229
|
-
if (lowerDesc.includes(keyword.toLowerCase())) {
|
|
230
|
-
score += 2;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// Check pattern matches (partial)
|
|
234
|
-
for (const pattern of template.patterns) {
|
|
235
|
-
// Split on whitespace and common punctuation (/, ,) to handle patterns like "Rename/move"
|
|
236
|
-
const patternWords = pattern
|
|
237
|
-
.toLowerCase()
|
|
238
|
-
.split(/[\s/,]+/)
|
|
239
|
-
.filter(word => word.length > 2); // Filter short words like "or", "to"
|
|
240
|
-
const matchedWords = patternWords.filter(word => lowerDesc.includes(word));
|
|
241
|
-
if (matchedWords.length >= patternWords.length / 2) {
|
|
242
|
-
score += 1;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Update best match if this template scores higher
|
|
246
|
-
if (score > 0 && (!bestMatch || score > bestMatch.score)) {
|
|
247
|
-
bestMatch = { template, score };
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
// Return template if we have a reasonable match (score >= 3)
|
|
251
|
-
return bestMatch && bestMatch.score >= 3 ? bestMatch.template : null;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Apply a template to generate stream definitions.
|
|
255
|
-
* Returns suggested streams based on the template structure.
|
|
256
|
-
*/
|
|
257
|
-
export function applyTemplate(template, context) {
|
|
258
|
-
const streams = [];
|
|
259
|
-
if (template.id === 'documentation-set') {
|
|
260
|
-
// Generate streams for each topic
|
|
261
|
-
const topics = context.topics || [];
|
|
262
|
-
for (const topic of topics) {
|
|
263
|
-
streams.push({
|
|
264
|
-
name: `docs-${topic}`,
|
|
265
|
-
deps: [],
|
|
266
|
-
owns: [`docs/${topic}/**/*.md`],
|
|
267
|
-
reads: ['src/**/*.ts', 'README.md'],
|
|
268
|
-
plan: `Research ${topic} implementation → Write documentation → Add examples → Review completeness`,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
else if (template.id === 'code-feature') {
|
|
273
|
-
// Generate types → core → tests → docs
|
|
274
|
-
const feature = context.featureName;
|
|
275
|
-
streams.push({
|
|
276
|
-
name: `${feature}-types`,
|
|
277
|
-
deps: [],
|
|
278
|
-
owns: [`src/types/${feature}.ts`],
|
|
279
|
-
reads: ['src/types.ts'],
|
|
280
|
-
plan: 'Analyze requirements → Define types → Add validation schemas → Export types',
|
|
281
|
-
}, {
|
|
282
|
-
name: `${feature}-core`,
|
|
283
|
-
deps: [`${feature}-types`],
|
|
284
|
-
owns: [`src/${feature}/*.ts`],
|
|
285
|
-
reads: [`src/types/${feature}.ts`, 'src/utils/*.ts'],
|
|
286
|
-
plan: 'Implement core logic → Add error handling → Integrate with existing systems',
|
|
287
|
-
}, {
|
|
288
|
-
name: `${feature}-tests`,
|
|
289
|
-
deps: [`${feature}-core`],
|
|
290
|
-
owns: [`tests/${feature}.test.ts`],
|
|
291
|
-
reads: [`src/${feature}/*.ts`],
|
|
292
|
-
plan: 'Write unit tests → Add integration tests → Test edge cases → Verify coverage',
|
|
293
|
-
}, {
|
|
294
|
-
name: `${feature}-docs`,
|
|
295
|
-
deps: [`${feature}-core`],
|
|
296
|
-
owns: [`docs/${feature}/*.md`],
|
|
297
|
-
reads: [`src/${feature}/*.ts`],
|
|
298
|
-
plan: 'Document API → Add usage examples → Write integration guide',
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
else if (template.id === 'migration') {
|
|
302
|
-
// Generate new implementation → migrate components → deprecate old
|
|
303
|
-
const feature = context.featureName;
|
|
304
|
-
const components = context.components || [];
|
|
305
|
-
streams.push({
|
|
306
|
-
name: `${feature}-new-implementation`,
|
|
307
|
-
deps: [],
|
|
308
|
-
owns: [`src/${feature}-new/*.ts`],
|
|
309
|
-
reads: [`src/${feature}-old/*.ts`],
|
|
310
|
-
plan: 'Implement new version → Match old API → Add compatibility layer',
|
|
311
|
-
});
|
|
312
|
-
for (const component of components) {
|
|
313
|
-
streams.push({
|
|
314
|
-
name: `${feature}-migrate-${component}`,
|
|
315
|
-
deps: [`${feature}-new-implementation`],
|
|
316
|
-
owns: [`src/${component}/**/*.ts`],
|
|
317
|
-
reads: [`src/${feature}-new/*.ts`, `src/${feature}-old/*.ts`],
|
|
318
|
-
plan: 'Update imports → Replace function calls → Update tests → Verify behavior',
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
streams.push({
|
|
322
|
-
name: `${feature}-deprecate-old`,
|
|
323
|
-
deps: components.map(c => `${feature}-migrate-${c}`),
|
|
324
|
-
owns: [`src/${feature}-old/*.ts`],
|
|
325
|
-
reads: [],
|
|
326
|
-
plan: 'Add deprecation notices → Update docs → Plan removal timeline',
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
else if (template.id === 'tutorial') {
|
|
330
|
-
// Generate tutorial streams for each topic
|
|
331
|
-
const topics = context.topics || [];
|
|
332
|
-
for (const topic of topics) {
|
|
333
|
-
streams.push({
|
|
334
|
-
name: `tutorial-${topic}`,
|
|
335
|
-
deps: [],
|
|
336
|
-
owns: [`docs/tutorials/${topic}.md`, `examples/${topic}/**/*`],
|
|
337
|
-
reads: ['src/**/*.ts'],
|
|
338
|
-
plan: 'Define learning objectives → Write tutorial → Create working example → Add exercises',
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
else if (template.id === 'api-reference') {
|
|
343
|
-
// Generate API reference streams for each module
|
|
344
|
-
const modules = context.modules || [];
|
|
345
|
-
for (const module of modules) {
|
|
346
|
-
streams.push({
|
|
347
|
-
name: `api-${module}-reference`,
|
|
348
|
-
deps: [],
|
|
349
|
-
owns: [`docs/api/${module}.md`],
|
|
350
|
-
reads: [`src/${module}/**/*.ts`],
|
|
351
|
-
plan: 'Extract types/interfaces → Document functions → Add examples → Cross-link related APIs',
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return streams;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Analyze a stream and suggest how to split it if needed.
|
|
359
|
-
* Returns null if the stream seems appropriately sized.
|
|
360
|
-
*/
|
|
361
|
-
export function suggestSplit(stream) {
|
|
362
|
-
const owns = stream.owns || [];
|
|
363
|
-
const reads = stream.reads || [];
|
|
364
|
-
// Check if stream owns too many files
|
|
365
|
-
if (owns.length > 5) {
|
|
366
|
-
return {
|
|
367
|
-
originalStream: stream.name,
|
|
368
|
-
reason: `Stream owns ${owns.length} files, which may be too many for a single stream`,
|
|
369
|
-
guidance: [
|
|
370
|
-
'Consider grouping related files together',
|
|
371
|
-
'Split by logical component or responsibility',
|
|
372
|
-
'Create dependencies between resulting streams if needed',
|
|
373
|
-
],
|
|
374
|
-
suggestedStreams: [],
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
// Check if stream reads too many files
|
|
378
|
-
if (reads.length > 10) {
|
|
379
|
-
return {
|
|
380
|
-
originalStream: stream.name,
|
|
381
|
-
reason: `Stream reads ${reads.length} files, which may indicate broad scope`,
|
|
382
|
-
guidance: [
|
|
383
|
-
'Reading many files often means the stream is doing too much',
|
|
384
|
-
'Consider splitting into smaller, focused streams',
|
|
385
|
-
'Each stream should ideally read 3-5 context files',
|
|
386
|
-
],
|
|
387
|
-
suggestedStreams: [],
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
// Try to find a matching template for suggestions
|
|
391
|
-
const description = `${stream.name} ${stream.plan || ''}`;
|
|
392
|
-
const template = findMatchingTemplate(description);
|
|
393
|
-
if (template) {
|
|
394
|
-
// Check if stream name suggests it should be split
|
|
395
|
-
const nameKeywords = ['multiple', 'all', 'complete', 'full', 'entire'];
|
|
396
|
-
const shouldSplit = nameKeywords.some(keyword => stream.name.toLowerCase().includes(keyword));
|
|
397
|
-
if (shouldSplit) {
|
|
398
|
-
return {
|
|
399
|
-
originalStream: stream.name,
|
|
400
|
-
reason: `Stream name suggests broad scope that could be split`,
|
|
401
|
-
template,
|
|
402
|
-
guidance: template.guidelines,
|
|
403
|
-
suggestedStreams: [],
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Get all available templates.
|
|
411
|
-
*/
|
|
412
|
-
export function getAllTemplates() {
|
|
413
|
-
return [...ALL_TEMPLATES];
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Get a specific template by ID.
|
|
417
|
-
*/
|
|
418
|
-
export function getTemplate(id) {
|
|
419
|
-
return ALL_TEMPLATES.find(t => t.id === id) || null;
|
|
420
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Split suggester for interactive stream improvement.
|
|
3
|
-
* Combines anti-pattern detection with template-based split suggestions.
|
|
4
|
-
*/
|
|
5
|
-
import type { StreamDefinitionInput } from '../types.js';
|
|
6
|
-
import { type AntiPatternIssue, type StreamAnalysis, AntiPatternDetector } from './anti-pattern-detector.js';
|
|
7
|
-
import { type SlicingTemplate } from './slicing-templates.js';
|
|
8
|
-
/**
|
|
9
|
-
* Interactive suggestion for a problematic stream.
|
|
10
|
-
*/
|
|
11
|
-
export interface InteractiveSuggestion {
|
|
12
|
-
/** Stream ID with issues */
|
|
13
|
-
streamId: string;
|
|
14
|
-
/** Anti-pattern violations found */
|
|
15
|
-
violations: AntiPatternIssue[];
|
|
16
|
-
/** Quality score (0-100) */
|
|
17
|
-
qualityScore: number;
|
|
18
|
-
/** Matched template (if any) */
|
|
19
|
-
templateMatch: SlicingTemplate | null;
|
|
20
|
-
/** Suggested replacement streams */
|
|
21
|
-
suggestedSplit: StreamDefinitionInput[] | null;
|
|
22
|
-
/** Human-readable message for CLI */
|
|
23
|
-
message: string;
|
|
24
|
-
/** Suggested action */
|
|
25
|
-
action: 'accept_split' | 'modify' | 'ignore';
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Summary of all suggestions for a stream set.
|
|
29
|
-
*/
|
|
30
|
-
export interface SuggestionsSummary {
|
|
31
|
-
/** Total streams analyzed */
|
|
32
|
-
totalStreams: number;
|
|
33
|
-
/** Streams with errors (critical issues) */
|
|
34
|
-
errorCount: number;
|
|
35
|
-
/** Streams with warnings */
|
|
36
|
-
warningCount: number;
|
|
37
|
-
/** Streams with template matches */
|
|
38
|
-
templateMatches: number;
|
|
39
|
-
/** Human-readable summary */
|
|
40
|
-
summary: string;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Generate an interactive suggestion for a problematic stream.
|
|
44
|
-
*/
|
|
45
|
-
export declare function generateInteractiveSuggestion(streamId: string, stream: StreamDefinitionInput, analysis: StreamAnalysis): InteractiveSuggestion | null;
|
|
46
|
-
/**
|
|
47
|
-
* Generate suggestions for all streams in a set.
|
|
48
|
-
*/
|
|
49
|
-
export declare function generateAllSuggestions(streams: Record<string, StreamDefinitionInput>, detector?: AntiPatternDetector): InteractiveSuggestion[];
|
|
50
|
-
/**
|
|
51
|
-
* Apply accepted splits to a stream set.
|
|
52
|
-
* Returns new stream set with original streams replaced by split streams.
|
|
53
|
-
*/
|
|
54
|
-
export declare function applySplits(streams: Record<string, StreamDefinitionInput>, acceptedSplits: Array<{
|
|
55
|
-
originalId: string;
|
|
56
|
-
newStreams: StreamDefinitionInput[];
|
|
57
|
-
}>): Record<string, StreamDefinitionInput>;
|
|
58
|
-
/**
|
|
59
|
-
* Generate a summary of all suggestions.
|
|
60
|
-
*/
|
|
61
|
-
export declare function getSuggestionsSummary(suggestions: InteractiveSuggestion[]): SuggestionsSummary;
|
|
62
|
-
/**
|
|
63
|
-
* Format a single suggestion for CLI display.
|
|
64
|
-
*/
|
|
65
|
-
export declare function formatSuggestion(suggestion: InteractiveSuggestion): string;
|
|
66
|
-
/**
|
|
67
|
-
* Format all suggestions as a report.
|
|
68
|
-
*/
|
|
69
|
-
export declare function formatSuggestionsReport(suggestions: InteractiveSuggestion[]): string;
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Split suggester for interactive stream improvement.
|
|
3
|
-
* Combines anti-pattern detection with template-based split suggestions.
|
|
4
|
-
*/
|
|
5
|
-
import { createDetector, } from './anti-pattern-detector.js';
|
|
6
|
-
import { findMatchingTemplate, applyTemplate, } from './slicing-templates.js';
|
|
7
|
-
/**
|
|
8
|
-
* Generate an interactive suggestion for a problematic stream.
|
|
9
|
-
*/
|
|
10
|
-
export function generateInteractiveSuggestion(streamId, stream, analysis) {
|
|
11
|
-
// Only suggest for streams with issues
|
|
12
|
-
if (analysis.issues.length === 0) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const hasErrors = analysis.issues.some(i => i.severity === 'error');
|
|
16
|
-
const hasWarnings = analysis.issues.some(i => i.severity === 'warning');
|
|
17
|
-
// Try to find a matching template
|
|
18
|
-
const description = `${stream.name ?? streamId} ${stream.plan ?? ''}`;
|
|
19
|
-
const template = findMatchingTemplate(description);
|
|
20
|
-
// Generate suggested split if template matches
|
|
21
|
-
let suggestedSplit = null;
|
|
22
|
-
if (template) {
|
|
23
|
-
// Extract feature name from stream ID
|
|
24
|
-
const featureName = streamId.replace(/-/g, '_');
|
|
25
|
-
suggestedSplit = applyTemplate(template, { featureName });
|
|
26
|
-
}
|
|
27
|
-
// Build CLI message
|
|
28
|
-
let message = '';
|
|
29
|
-
if (hasErrors) {
|
|
30
|
-
message = `Stream "${streamId}" has critical issues:\n`;
|
|
31
|
-
}
|
|
32
|
-
else if (hasWarnings) {
|
|
33
|
-
message = `Stream "${streamId}" has potential issues:\n`;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
message = `Stream "${streamId}" has suggestions:\n`;
|
|
37
|
-
}
|
|
38
|
-
for (const issue of analysis.issues) {
|
|
39
|
-
const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';
|
|
40
|
-
message += ` ${icon} ${issue.message}\n`;
|
|
41
|
-
if (issue.details) {
|
|
42
|
-
message += ` ${issue.details}\n`;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (template && suggestedSplit && suggestedSplit.length > 0) {
|
|
46
|
-
message += `\n📋 Suggested split using "${template.name}" template:\n`;
|
|
47
|
-
for (const s of suggestedSplit) {
|
|
48
|
-
const owns = s.owns?.join(', ') ?? 'TBD';
|
|
49
|
-
message += ` • ${s.name}: ${owns}\n`;
|
|
50
|
-
}
|
|
51
|
-
message += '\nAccept suggested split? [Y/n/edit]';
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
message += '\nNo template match. Consider manual split or ignore.';
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
streamId,
|
|
58
|
-
violations: analysis.issues,
|
|
59
|
-
qualityScore: analysis.qualityScore,
|
|
60
|
-
templateMatch: template,
|
|
61
|
-
suggestedSplit,
|
|
62
|
-
message,
|
|
63
|
-
action: hasErrors ? 'accept_split' : hasWarnings ? 'modify' : 'ignore',
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Generate suggestions for all streams in a set.
|
|
68
|
-
*/
|
|
69
|
-
export function generateAllSuggestions(streams, detector) {
|
|
70
|
-
const det = detector ?? createDetector();
|
|
71
|
-
const suggestions = [];
|
|
72
|
-
for (const [id, stream] of Object.entries(streams)) {
|
|
73
|
-
const analysis = det.analyzeStream(id, stream);
|
|
74
|
-
const suggestion = generateInteractiveSuggestion(id, stream, analysis);
|
|
75
|
-
if (suggestion) {
|
|
76
|
-
suggestions.push(suggestion);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Sort by severity (errors first, then warnings, then info)
|
|
80
|
-
suggestions.sort((a, b) => {
|
|
81
|
-
const aHasError = a.violations.some(v => v.severity === 'error');
|
|
82
|
-
const bHasError = b.violations.some(v => v.severity === 'error');
|
|
83
|
-
if (aHasError && !bHasError)
|
|
84
|
-
return -1;
|
|
85
|
-
if (!aHasError && bHasError)
|
|
86
|
-
return 1;
|
|
87
|
-
const aHasWarning = a.violations.some(v => v.severity === 'warning');
|
|
88
|
-
const bHasWarning = b.violations.some(v => v.severity === 'warning');
|
|
89
|
-
if (aHasWarning && !bHasWarning)
|
|
90
|
-
return -1;
|
|
91
|
-
if (!aHasWarning && bHasWarning)
|
|
92
|
-
return 1;
|
|
93
|
-
return 0;
|
|
94
|
-
});
|
|
95
|
-
return suggestions;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Apply accepted splits to a stream set.
|
|
99
|
-
* Returns new stream set with original streams replaced by split streams.
|
|
100
|
-
*/
|
|
101
|
-
export function applySplits(streams, acceptedSplits) {
|
|
102
|
-
const result = { ...streams };
|
|
103
|
-
for (const split of acceptedSplits) {
|
|
104
|
-
// Remove original stream
|
|
105
|
-
delete result[split.originalId];
|
|
106
|
-
// Add new streams
|
|
107
|
-
for (const stream of split.newStreams) {
|
|
108
|
-
const streamId = stream.name.replace(/\s+/g, '-').toLowerCase();
|
|
109
|
-
result[streamId] = stream;
|
|
110
|
-
}
|
|
111
|
-
// Update dependencies in other streams that depended on the original
|
|
112
|
-
for (const [id, stream] of Object.entries(result)) {
|
|
113
|
-
if (stream.deps?.includes(split.originalId)) {
|
|
114
|
-
// Replace dependency with the last stream in the split (typically the integration stream)
|
|
115
|
-
const newStreamIds = split.newStreams.map(s => s.name.replace(/\s+/g, '-').toLowerCase());
|
|
116
|
-
const lastStream = newStreamIds[newStreamIds.length - 1];
|
|
117
|
-
stream.deps = stream.deps.map(d => d === split.originalId ? lastStream : d);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return result;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Generate a summary of all suggestions.
|
|
125
|
-
*/
|
|
126
|
-
export function getSuggestionsSummary(suggestions) {
|
|
127
|
-
const errorCount = suggestions.filter(s => s.violations.some(v => v.severity === 'error')).length;
|
|
128
|
-
const warningCount = suggestions.filter(s => s.violations.some(v => v.severity === 'warning') &&
|
|
129
|
-
!s.violations.some(v => v.severity === 'error')).length;
|
|
130
|
-
const templateMatches = suggestions.filter(s => s.templateMatch !== null).length;
|
|
131
|
-
let summary = '';
|
|
132
|
-
if (suggestions.length === 0) {
|
|
133
|
-
summary = '✅ All streams passed validation. No issues detected.';
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
summary = `Stream Validation Summary:\n`;
|
|
137
|
-
summary += ` ${errorCount} stream${errorCount !== 1 ? 's' : ''} with errors\n`;
|
|
138
|
-
summary += ` ${warningCount} stream${warningCount !== 1 ? 's' : ''} with warnings\n`;
|
|
139
|
-
summary += ` ${templateMatches} template match${templateMatches !== 1 ? 'es' : ''} found\n`;
|
|
140
|
-
if (errorCount > 0) {
|
|
141
|
-
summary += '\n❌ Critical issues (must fix):\n';
|
|
142
|
-
for (const s of suggestions.filter(s => s.violations.some(v => v.severity === 'error'))) {
|
|
143
|
-
const errors = s.violations.filter(v => v.severity === 'error').map(v => v.type);
|
|
144
|
-
summary += ` • ${s.streamId}: ${errors.join(', ')}\n`;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
totalStreams: suggestions.length,
|
|
150
|
-
errorCount,
|
|
151
|
-
warningCount,
|
|
152
|
-
templateMatches,
|
|
153
|
-
summary,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Format a single suggestion for CLI display.
|
|
158
|
-
*/
|
|
159
|
-
export function formatSuggestion(suggestion) {
|
|
160
|
-
return suggestion.message;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Format all suggestions as a report.
|
|
164
|
-
*/
|
|
165
|
-
export function formatSuggestionsReport(suggestions) {
|
|
166
|
-
const summary = getSuggestionsSummary(suggestions);
|
|
167
|
-
if (suggestions.length === 0) {
|
|
168
|
-
return summary.summary;
|
|
169
|
-
}
|
|
170
|
-
let report = summary.summary + '\n';
|
|
171
|
-
report += '─'.repeat(50) + '\n';
|
|
172
|
-
for (const suggestion of suggestions) {
|
|
173
|
-
report += '\n' + formatSuggestion(suggestion) + '\n';
|
|
174
|
-
}
|
|
175
|
-
return report;
|
|
176
|
-
}
|