@wundam/orchex 1.0.0-rc.30 → 1.0.0-rc.32
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/dist/cloud-executor.d.ts +17 -2
- package/dist/cloud-executor.js +79 -10
- package/dist/config.d.ts +10 -0
- package/dist/config.js +24 -0
- package/dist/index.js +5 -1
- package/dist/intelligence/index.js +18 -18
- package/dist/logger.d.ts +17 -1
- package/dist/logger.js +24 -4
- package/dist/manifest.js +10 -1
- package/dist/orchestrator.js +3 -3
- package/dist/setup/index.js +2 -1
- package/dist/types.d.ts +82 -0
- package/dist/types.js +15 -0
- package/package.json +2 -1
package/dist/cloud-executor.d.ts
CHANGED
|
@@ -34,8 +34,21 @@ export declare class CloudExecutor implements ExecutorStrategy {
|
|
|
34
34
|
private config;
|
|
35
35
|
constructor(apiUrl: string, apiKey: string, config?: Partial<CloudExecutorConfig>);
|
|
36
36
|
execute(request: ExecutionRequest): Promise<ExecutionResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Per-fetch timeout cap for individual poll calls (poll loop has its own deadline).
|
|
39
|
+
* Set well below typical poll backoff (max ~10s) to ensure each poll attempt is
|
|
40
|
+
* either bounded or aborts. Distinct from the overall execute() deadline.
|
|
41
|
+
*/
|
|
42
|
+
private static readonly POLL_FETCH_TIMEOUT_MS;
|
|
43
|
+
/**
|
|
44
|
+
* Per-fetch timeout cap for best-effort cleanup calls (cancel + final usage).
|
|
45
|
+
* Short — cleanup must not itself hang.
|
|
46
|
+
*/
|
|
47
|
+
private static readonly CLEANUP_FETCH_TIMEOUT_MS;
|
|
37
48
|
/**
|
|
38
49
|
* Submit a job to the cloud server with retry logic for transient errors.
|
|
50
|
+
* Each attempt's fetch is bounded by AbortController to honor effectiveTimeout
|
|
51
|
+
* on the wire — prevents silent hangs when the server never responds.
|
|
39
52
|
*/
|
|
40
53
|
private submitJobWithRetry;
|
|
41
54
|
/**
|
|
@@ -46,12 +59,14 @@ export declare class CloudExecutor implements ExecutorStrategy {
|
|
|
46
59
|
private pollForCompletionWithRetry;
|
|
47
60
|
/**
|
|
48
61
|
* Cancel a job on the cloud server to stop token consumption.
|
|
49
|
-
* Best effort — silently fails if server is unreachable.
|
|
62
|
+
* Best effort — silently fails if server is unreachable. Short AbortController
|
|
63
|
+
* timeout ensures cleanup doesn't itself hang.
|
|
50
64
|
*/
|
|
51
65
|
private cancelJob;
|
|
52
66
|
/**
|
|
53
67
|
* Fetch final token usage from job state on timeout.
|
|
54
|
-
* Best effort — returns zeros if fetch fails.
|
|
68
|
+
* Best effort — returns zeros if fetch fails. Short AbortController timeout
|
|
69
|
+
* ensures cleanup doesn't itself hang.
|
|
55
70
|
*/
|
|
56
71
|
private fetchFinalTokenUsage;
|
|
57
72
|
/**
|
package/dist/cloud-executor.js
CHANGED
|
@@ -77,8 +77,10 @@ export class CloudExecutor {
|
|
|
77
77
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
78
78
|
}
|
|
79
79
|
async execute(request) {
|
|
80
|
-
//
|
|
81
|
-
const
|
|
80
|
+
// Use request-level timeout if provided, otherwise fall back to config
|
|
81
|
+
const effectiveTimeout = request.timeoutMs ?? this.config.timeoutMs;
|
|
82
|
+
// 1. Submit job with retry (per-call abort enforces wire-level timeout)
|
|
83
|
+
const submitResult = await this.submitJobWithRetry(request, effectiveTimeout);
|
|
82
84
|
if (!submitResult.success) {
|
|
83
85
|
return {
|
|
84
86
|
success: false,
|
|
@@ -89,16 +91,29 @@ export class CloudExecutor {
|
|
|
89
91
|
}
|
|
90
92
|
const jobId = submitResult.jobId;
|
|
91
93
|
// 2. Poll for completion with retry and adaptive intervals
|
|
92
|
-
// Use request-level timeout if provided, otherwise fall back to config
|
|
93
|
-
const effectiveTimeout = request.timeoutMs ?? this.config.timeoutMs;
|
|
94
94
|
return this.pollForCompletionWithRetry(jobId, effectiveTimeout, request.ownership);
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Per-fetch timeout cap for individual poll calls (poll loop has its own deadline).
|
|
98
|
+
* Set well below typical poll backoff (max ~10s) to ensure each poll attempt is
|
|
99
|
+
* either bounded or aborts. Distinct from the overall execute() deadline.
|
|
100
|
+
*/
|
|
101
|
+
static POLL_FETCH_TIMEOUT_MS = 30_000;
|
|
102
|
+
/**
|
|
103
|
+
* Per-fetch timeout cap for best-effort cleanup calls (cancel + final usage).
|
|
104
|
+
* Short — cleanup must not itself hang.
|
|
105
|
+
*/
|
|
106
|
+
static CLEANUP_FETCH_TIMEOUT_MS = 5_000;
|
|
96
107
|
/**
|
|
97
108
|
* Submit a job to the cloud server with retry logic for transient errors.
|
|
109
|
+
* Each attempt's fetch is bounded by AbortController to honor effectiveTimeout
|
|
110
|
+
* on the wire — prevents silent hangs when the server never responds.
|
|
98
111
|
*/
|
|
99
|
-
async submitJobWithRetry(request) {
|
|
112
|
+
async submitJobWithRetry(request, effectiveTimeout) {
|
|
100
113
|
let lastError;
|
|
101
114
|
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
115
|
+
const controller = new AbortController();
|
|
116
|
+
const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);
|
|
102
117
|
try {
|
|
103
118
|
const submitRes = await fetch(`${this.apiUrl}/api/v1/execute`, {
|
|
104
119
|
method: 'POST',
|
|
@@ -115,6 +130,7 @@ export class CloudExecutor {
|
|
|
115
130
|
...(request.fileContext && { fileContext: request.fileContext }),
|
|
116
131
|
...(request.ownership && { ownership: request.ownership }),
|
|
117
132
|
}),
|
|
133
|
+
signal: controller.signal,
|
|
118
134
|
});
|
|
119
135
|
if (submitRes.ok) {
|
|
120
136
|
const { jobId } = (await submitRes.json());
|
|
@@ -139,13 +155,21 @@ export class CloudExecutor {
|
|
|
139
155
|
}
|
|
140
156
|
}
|
|
141
157
|
catch (err) {
|
|
142
|
-
|
|
158
|
+
if (err.name === 'AbortError') {
|
|
159
|
+
lastError = `Submit timed out after ${effectiveTimeout}ms`;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
lastError = `Network error: ${err.message}`;
|
|
163
|
+
}
|
|
143
164
|
if (attempt < this.config.maxRetries) {
|
|
144
165
|
const delay = this.calculateRetryDelay(attempt);
|
|
145
166
|
await this.sleep(delay);
|
|
146
167
|
continue;
|
|
147
168
|
}
|
|
148
169
|
}
|
|
170
|
+
finally {
|
|
171
|
+
clearTimeout(timeoutId);
|
|
172
|
+
}
|
|
149
173
|
}
|
|
150
174
|
return {
|
|
151
175
|
success: false,
|
|
@@ -162,9 +186,16 @@ export class CloudExecutor {
|
|
|
162
186
|
let pollInterval = this.config.pollIntervalMs;
|
|
163
187
|
let consecutiveErrors = 0;
|
|
164
188
|
while (Date.now() < deadline) {
|
|
189
|
+
// Per-poll AbortController — each fetch bounded by POLL_FETCH_TIMEOUT_MS
|
|
190
|
+
// so a hung connection can't block the deadline-check loop indefinitely.
|
|
191
|
+
const remainingMs = deadline - Date.now();
|
|
192
|
+
const pollFetchTimeout = Math.min(CloudExecutor.POLL_FETCH_TIMEOUT_MS, Math.max(remainingMs, 100));
|
|
193
|
+
const pollController = new AbortController();
|
|
194
|
+
const pollTimeoutId = setTimeout(() => pollController.abort(), pollFetchTimeout);
|
|
165
195
|
try {
|
|
166
196
|
const pollRes = await fetch(`${this.apiUrl}/api/v1/job/${jobId}`, {
|
|
167
197
|
headers: { 'Authorization': `Bearer ${this.apiKey}` },
|
|
198
|
+
signal: pollController.signal,
|
|
168
199
|
});
|
|
169
200
|
if (pollRes.ok) {
|
|
170
201
|
consecutiveErrors = 0; // Reset error count on success
|
|
@@ -256,6 +287,27 @@ export class CloudExecutor {
|
|
|
256
287
|
};
|
|
257
288
|
}
|
|
258
289
|
catch (err) {
|
|
290
|
+
// AbortError on a single poll = wire-level fetch timeout; loop continues
|
|
291
|
+
// and re-checks the overall deadline at the top of the next iteration.
|
|
292
|
+
if (err.name === 'AbortError') {
|
|
293
|
+
// If overall deadline expired during this hung poll, fall through to
|
|
294
|
+
// the timeout-cleanup block below.
|
|
295
|
+
if (Date.now() >= deadline)
|
|
296
|
+
break;
|
|
297
|
+
// Otherwise, treat as a transient retryable error.
|
|
298
|
+
consecutiveErrors++;
|
|
299
|
+
if (consecutiveErrors <= this.config.maxRetries) {
|
|
300
|
+
const delay = this.calculateRetryDelay(consecutiveErrors - 1);
|
|
301
|
+
await this.sleep(delay);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
rawResponse: '',
|
|
307
|
+
tokensUsed: { input: 0, output: 0 },
|
|
308
|
+
error: `Poll fetch timed out after ${pollFetchTimeout}ms (after ${consecutiveErrors} retries)`,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
259
311
|
consecutiveErrors++;
|
|
260
312
|
if (consecutiveErrors <= this.config.maxRetries) {
|
|
261
313
|
const delay = this.calculateRetryDelay(consecutiveErrors - 1);
|
|
@@ -269,6 +321,9 @@ export class CloudExecutor {
|
|
|
269
321
|
error: `Network error: ${err.message} (after ${consecutiveErrors} retries)`,
|
|
270
322
|
};
|
|
271
323
|
}
|
|
324
|
+
finally {
|
|
325
|
+
clearTimeout(pollTimeoutId);
|
|
326
|
+
}
|
|
272
327
|
}
|
|
273
328
|
// On timeout:
|
|
274
329
|
// 1. Cancel the job to stop further token consumption
|
|
@@ -284,27 +339,38 @@ export class CloudExecutor {
|
|
|
284
339
|
}
|
|
285
340
|
/**
|
|
286
341
|
* Cancel a job on the cloud server to stop token consumption.
|
|
287
|
-
* Best effort — silently fails if server is unreachable.
|
|
342
|
+
* Best effort — silently fails if server is unreachable. Short AbortController
|
|
343
|
+
* timeout ensures cleanup doesn't itself hang.
|
|
288
344
|
*/
|
|
289
345
|
async cancelJob(jobId) {
|
|
346
|
+
const controller = new AbortController();
|
|
347
|
+
const timeoutId = setTimeout(() => controller.abort(), CloudExecutor.CLEANUP_FETCH_TIMEOUT_MS);
|
|
290
348
|
try {
|
|
291
349
|
await fetch(`${this.apiUrl}/api/v1/job/${jobId}/cancel`, {
|
|
292
350
|
method: 'POST',
|
|
293
351
|
headers: { 'Authorization': `Bearer ${this.apiKey}` },
|
|
352
|
+
signal: controller.signal,
|
|
294
353
|
});
|
|
295
354
|
}
|
|
296
355
|
catch {
|
|
297
|
-
// Best effort — ignore errors
|
|
356
|
+
// Best effort — ignore errors (including AbortError on cleanup timeout)
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
clearTimeout(timeoutId);
|
|
298
360
|
}
|
|
299
361
|
}
|
|
300
362
|
/**
|
|
301
363
|
* Fetch final token usage from job state on timeout.
|
|
302
|
-
* Best effort — returns zeros if fetch fails.
|
|
364
|
+
* Best effort — returns zeros if fetch fails. Short AbortController timeout
|
|
365
|
+
* ensures cleanup doesn't itself hang.
|
|
303
366
|
*/
|
|
304
367
|
async fetchFinalTokenUsage(jobId) {
|
|
368
|
+
const controller = new AbortController();
|
|
369
|
+
const timeoutId = setTimeout(() => controller.abort(), CloudExecutor.CLEANUP_FETCH_TIMEOUT_MS);
|
|
305
370
|
try {
|
|
306
371
|
const res = await fetch(`${this.apiUrl}/api/v1/job/${jobId}`, {
|
|
307
372
|
headers: { 'Authorization': `Bearer ${this.apiKey}` },
|
|
373
|
+
signal: controller.signal,
|
|
308
374
|
});
|
|
309
375
|
if (res.ok) {
|
|
310
376
|
const job = (await res.json());
|
|
@@ -312,7 +378,10 @@ export class CloudExecutor {
|
|
|
312
378
|
}
|
|
313
379
|
}
|
|
314
380
|
catch {
|
|
315
|
-
// Best effort — ignore errors
|
|
381
|
+
// Best effort — ignore errors (including AbortError on cleanup timeout)
|
|
382
|
+
}
|
|
383
|
+
finally {
|
|
384
|
+
clearTimeout(timeoutId);
|
|
316
385
|
}
|
|
317
386
|
return { input: 0, output: 0 };
|
|
318
387
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -34,6 +34,16 @@ export declare function getConfiguredProvider(config: Config): LLMProvider;
|
|
|
34
34
|
* Priority: ORCHEX_MODEL env > config.model > provider default
|
|
35
35
|
*/
|
|
36
36
|
export declare function getConfiguredModel(config: Config): string;
|
|
37
|
+
/**
|
|
38
|
+
* Emit a fail-loud stderr warning when ORCHEX_PROVIDER or ORCHEX_MODEL env vars
|
|
39
|
+
* are set. Env-var precedence is a footgun: a user editing ~/.orchex/config.json
|
|
40
|
+
* sees no effect because env beats config. The warning names the override and
|
|
41
|
+
* points to common sources (.mcp.json in project root). Stderr-only so MCP
|
|
42
|
+
* stdio JSON-RPC traffic is not corrupted.
|
|
43
|
+
*
|
|
44
|
+
* Optional `writer` injection for testing.
|
|
45
|
+
*/
|
|
46
|
+
export declare function warnEnvOverrides(writer?: (msg: string) => void): void;
|
|
37
47
|
export declare const TelemetryConfigSchema: z.ZodObject<{
|
|
38
48
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
39
49
|
endpoint: z.ZodOptional<z.ZodString>;
|
package/dist/config.js
CHANGED
|
@@ -135,6 +135,30 @@ export function getConfiguredModel(config) {
|
|
|
135
135
|
const provider = getConfiguredProvider(config);
|
|
136
136
|
return DEFAULT_MODELS[provider];
|
|
137
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Emit a fail-loud stderr warning when ORCHEX_PROVIDER or ORCHEX_MODEL env vars
|
|
140
|
+
* are set. Env-var precedence is a footgun: a user editing ~/.orchex/config.json
|
|
141
|
+
* sees no effect because env beats config. The warning names the override and
|
|
142
|
+
* points to common sources (.mcp.json in project root). Stderr-only so MCP
|
|
143
|
+
* stdio JSON-RPC traffic is not corrupted.
|
|
144
|
+
*
|
|
145
|
+
* Optional `writer` injection for testing.
|
|
146
|
+
*/
|
|
147
|
+
export function warnEnvOverrides(writer = (msg) => process.stderr.write(msg)) {
|
|
148
|
+
const overrides = [];
|
|
149
|
+
if (process.env.ORCHEX_PROVIDER) {
|
|
150
|
+
overrides.push(` ORCHEX_PROVIDER=${process.env.ORCHEX_PROVIDER}`);
|
|
151
|
+
}
|
|
152
|
+
if (process.env.ORCHEX_MODEL) {
|
|
153
|
+
overrides.push(` ORCHEX_MODEL=${process.env.ORCHEX_MODEL}`);
|
|
154
|
+
}
|
|
155
|
+
if (overrides.length === 0)
|
|
156
|
+
return;
|
|
157
|
+
writer(`[orchex] Notice: env vars override ~/.orchex/config.json:\n` +
|
|
158
|
+
overrides.join('\n') + `\n` +
|
|
159
|
+
`[orchex] Edits to ~/.orchex/config.json will NOT take effect for these fields while the env vars are set.\n` +
|
|
160
|
+
`[orchex] Common source: .mcp.json in the project root. To use config-file values, unset these env vars.\n`);
|
|
161
|
+
}
|
|
138
162
|
// ============================================================================
|
|
139
163
|
// Config Schema
|
|
140
164
|
// ============================================================================
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { registerTools, setProjectDir } from './tools.js';
|
|
|
5
5
|
import { ORCHEX_INSTRUCTIONS } from './mcp-instructions.js';
|
|
6
6
|
import { registerResources } from './mcp-resources.js';
|
|
7
7
|
import { broadcaster } from './execution-broadcaster.js';
|
|
8
|
-
import { loadConfig, saveConfig, maskConfigForDisplay, resolveApiUrl, PRODUCTION_URL, LLMProviderSchema } from './config.js';
|
|
8
|
+
import { loadConfig, saveConfig, maskConfigForDisplay, resolveApiUrl, PRODUCTION_URL, LLMProviderSchema, warnEnvOverrides } from './config.js';
|
|
9
9
|
import { analyzeError } from './intelligence/index.js';
|
|
10
10
|
import { buildVerificationMessage, buildStatusMessage, parseLoginApiResponse, } from './login-helpers.js';
|
|
11
11
|
import { PKG_VERSION } from './version.js';
|
|
@@ -796,6 +796,10 @@ async function main() {
|
|
|
796
796
|
if (pdIdx !== -1 && args[pdIdx + 1]) {
|
|
797
797
|
setProjectDir(args[pdIdx + 1]);
|
|
798
798
|
}
|
|
799
|
+
// Warn fail-loud on env-var overrides BEFORE the MCP transport is connected,
|
|
800
|
+
// so the user sees the notice even if they're surprised by mismatched config.
|
|
801
|
+
// Stderr-only — must not corrupt JSON-RPC stdio traffic.
|
|
802
|
+
warnEnvOverrides();
|
|
799
803
|
// Start MCP server
|
|
800
804
|
const server = new McpServer({ name: 'orchex', version: PKG_VERSION }, { instructions: ORCHEX_INSTRUCTIONS, capabilities: { logging: {} } });
|
|
801
805
|
registerTools(server);
|
|
@@ -96,24 +96,24 @@ Start with \`# <Feature Title>\` and include all H2 stream sections with YAML bl
|
|
|
96
96
|
`).trim()),o=[];let l=c[1].length,u=c[2].trim(),d={level:l,title:u,content:"",codeBlocks:[],fileReferences:[],explicitDeps:[],children:[]};for(;s.length>0&&s[s.length-1].level>=l;)s.pop();s.length>0?s[s.length-1].children.push(d):t.push(d),s.push(d)}else o.push(a)}s.length>0&&(s[s.length-1].content=o.join(`
|
|
97
97
|
`).trim());function i(a){a.codeBlocks=lo(a.content),a.fileReferences=ao(a.content),a.explicitDeps=co(a.content);for(let c of a.children)i(c)}for(let a of t)i(a);return t}function gt(e){let n=uo(e),t=n.find(c=>c.level===1)?.title??"Untitled Plan",o=n.find(c=>c.level===1)?.content.split(`
|
|
98
98
|
`).slice(0,3).join(`
|
|
99
|
-
`)??"",r=new Set,i=[];function a(c){for(let l of c.fileReferences)r.add(l);i.push(...c.codeBlocks);for(let l of c.children)a(l)}for(let c of n)a(c);return{title:t,description:o,sections:n,allFileReferences:[...r],allCodeBlocks:i}}function Z(e,n){let t=[];function s(o){o.level===n&&t.push(o);for(let r of o.children)s(r)}for(let o of e)s(o);return t}function le(e){let n=[];function t(s){n.push(s);for(let o of s.children)t(o)}for(let s of e)t(s);return n}function
|
|
99
|
+
`)??"",r=new Set,i=[];function a(c){for(let l of c.fileReferences)r.add(l);i.push(...c.codeBlocks);for(let l of c.children)a(l)}for(let c of n)a(c);return{title:t,description:o,sections:n,allFileReferences:[...r],allCodeBlocks:i}}function Z(e,n){let t=[];function s(o){o.level===n&&t.push(o);for(let r of o.children)s(r)}for(let o of e)s(o);return t}function le(e){let n=[];function t(s){n.push(s);for(let o of s.children)t(o)}for(let s of e)t(s);return n}function Re(e){let n=e.trim();return n.startsWith('"')&&n.endsWith('"')||n.startsWith("'")&&n.endsWith("'")?n:n.replace(/\s+#(?=\s|$).*/,"").trim()}function fo(e){let n={},t=e.split(`
|
|
100
100
|
`),s=null,o=[],r=!1,i=!1,a=[];for(let c of t){if(r&&(c.startsWith(" ")||c.startsWith(" ")||c.trim()==="")){o.push(c.replace(/^ /,"").replace(/^\t/,""));continue}else r&&(s&&(n[s]=o.join(`
|
|
101
|
-
`).trim()),r=!1,s=null,o=[]);if(i&&c.match(/^\s+-\s+/)){let u=c.replace(/^\s+-\s+/,"").trim();a.push(
|
|
101
|
+
`).trim()),r=!1,s=null,o=[]);if(i&&c.match(/^\s+-\s+/)){let u=c.replace(/^\s+-\s+/,"").trim();a.push(Re(u));continue}else i&&!c.match(/^\s+-\s+/)&&c.trim()!==""&&(s&&(n[s]=a),i=!1,s=null,a=[]);let l=c.match(/^([\w-]+):\s*(.*)$/);if(l){let[,u,d]=l;if(d.startsWith("[")&&d.endsWith("]")){let f=d.slice(1,-1).split(",").map(p=>Re(p).replace(/['"]/g,""));n[u]=f.filter(p=>p.length>0);continue}if(d==="|"||d==="|-"){s=u,o=[],r=!0;continue}if(d===""){s=u,a=[],i=!0;continue}n[u]=Re(d).replace(/^["']|["']$/g,"")}}return r&&s&&(n[s]=o.join(`
|
|
102
102
|
`).trim()),i&&s&&(n[s]=a),n}function po(e){let n=e.split(`
|
|
103
103
|
`),t=[],s=n.findIndex(i=>/^streams:\s*$/.test(i));if(s===-1)return[];let o=null,r=[];for(let i=s+1;i<n.length;i++){let a=n[i],c=a.match(/^ ([\w-]+):\s*$/);if(c){o&&r.some(l=>l.trim())&&t.push({id:o,block:r.join(`
|
|
104
104
|
`)}),o=c[1],r=[];continue}if(o&&(/^ /.test(a)||a.trim()==="")){r.push(a.replace(/^ /,""));continue}if(a.trim()!==""&&!/^\s/.test(a))break}return o&&r.some(i=>i.trim())&&t.push({id:o,block:r.join(`
|
|
105
|
-
`)}),t}function ht(e,n){let t=fo(e),s=n??t.id??"",o=t.name??"";if(!s&&!o){ro.warn({block:e.slice(0,100)},"Malformed YAML block skipped \u2014 no id or name found");return}let r={id:s,name:o};return t.deps&&(r.deps=Array.isArray(t.deps)?t.deps:[t.deps]),t.owns&&(r.owns=Array.isArray(t.owns)?t.owns:[t.owns]),t.reads&&(r.reads=Array.isArray(t.reads)?t.reads:[t.reads]),t.plan&&(r.plan=t.plan),t.verify&&(r.verify=Array.isArray(t.verify)?t.verify:[t.verify]),t.setup&&(r.setup=Array.isArray(t.setup)?t.setup:[t.setup]),r}function
|
|
105
|
+
`)}),t}function ht(e,n){let t=fo(e),s=n??t.id??"",o=t.name??"";if(!s&&!o){ro.warn({block:e.slice(0,100)},"Malformed YAML block skipped \u2014 no id or name found");return}let r={id:s,name:o};return t.deps&&(r.deps=Array.isArray(t.deps)?t.deps:[t.deps]),t.owns&&(r.owns=Array.isArray(t.owns)?t.owns:[t.owns]),t.reads&&(r.reads=Array.isArray(t.reads)?t.reads:[t.reads]),t.plan&&(r.plan=t.plan),t.verify&&(r.verify=Array.isArray(t.verify)?t.verify:[t.verify]),t.setup&&(r.setup=Array.isArray(t.setup)?t.setup:[t.setup]),r}function Ae(e){let n=[];for(let t of e.codeBlocks){if(t.language!=="yaml"&&t.language!=="yml")continue;let s=po(t.code);if(s.length>0){for(let{id:r,block:i}of s){let a=ht(i,r);a&&n.push(a)}continue}if(!t.code.includes("id:")&&!t.code.includes("name:"))continue;let o=ht(t.code);o&&n.push(o)}return n}function wt(e){return e.includes("ORCHEX PLAN TEMPLATE")}var ro,je=y(()=>{"use strict";ro=oo("plan-parser")});import*as M from"fs/promises";import*as q from"path";import{createLogger as mo}from"../logging.js";function wo(e){return e>=ho?"high":e>=go?"medium":"low"}function te(e,n){let t=`${e} ${n??""}`.toLowerCase();return t.includes("test")||t.includes("spec")?"test":t.includes("migration")||t.includes("migrate")||t.includes("refactor")||t.includes("restructure")?"migration":t.includes("integration")&&(t.includes("guide")||t.includes("doc"))?"integration-guide":t.includes("tutorial")||t.includes("getting-started")||t.includes("getting started")?"tutorial":t.includes("api")&&(t.includes("ref")||t.includes("doc"))?"api-reference":t.includes("doc")||t.includes("readme")||t.includes("md")||t.includes("guide")?"docs":"code"}function yo(e,n=Fe){let t=[],s=[],o=e.filter(u=>(u.eventType==="stream_complete"||u.eventType==="stream_failed")&&u.contextTokensEstimated!==void 0);if(o.length<n)return{correlations:[],suggestedThresholds:{},insights:[`Not enough data for learning. Have ${o.length}, need ${n} samples.`],hasEnoughData:!1};let r=o.filter(u=>u.eventType==="stream_complete").length,i=r/o.length;s.push(`Overall success rate: ${(i*100).toFixed(1)}% (${r}/${o.length})`);let a=xo(o);a.optimalRange&&(t.push({factor:"contextTokens",successRate:a.optimalSuccessRate,sampleSize:a.optimalSampleSize,threshold:a.optimalRange.max,recommendation:`Optimal context size: ${a.optimalRange.min.toLocaleString()}-${a.optimalRange.max.toLocaleString()} tokens (${(a.optimalSuccessRate*100).toFixed(1)}% success)`}),s.push(t[t.length-1].recommendation));let c=vo(o);c.softViolationSuccessRate!==void 0&&t.push({factor:"softViolation",successRate:c.softViolationSuccessRate,sampleSize:c.softViolationCount,threshold:0,recommendation:c.softViolationSuccessRate<.7?"Soft limit violations have low success rate - consider lowering soft limit":"Soft limit violations acceptable - current threshold is appropriate"});let l=So(t,a,o.length);return{correlations:t,suggestedThresholds:l,insights:s,hasEnoughData:!0}}function xo(e){let n=[{min:0,max:5e4},{min:5e4,max:1e5},{min:1e5,max:15e4},{min:15e4,max:2e5}],t=n[0],s=0,o=0;for(let r of n){let i=e.filter(a=>a.contextTokensEstimated!==void 0&&a.contextTokensEstimated>=r.min&&a.contextTokensEstimated<r.max);if(i.length>=5){let c=i.filter(l=>l.eventType==="stream_complete").length/i.length;c>s&&(s=c,t=r,o=i.length)}}return{optimalRange:o>=5?t:void 0,optimalSuccessRate:s,optimalSampleSize:o}}function vo(e){let n=e.filter(s=>s.budgetViolationType==="soft"),t=e.filter(s=>s.budgetViolationType==="hard");return{softViolationCount:n.length,softViolationSuccessRate:n.length>=5?n.filter(s=>s.eventType==="stream_complete").length/n.length:void 0,hardViolationCount:t.length,hardViolationSuccessRate:t.length>=5?t.filter(s=>s.eventType==="stream_complete").length/t.length:void 0}}function So(e,n,t){let s={sampleCount:t,confidence:wo(t),lastUpdated:new Date().toISOString(),version:1};return n.optimalRange&&(s.globalSoftLimit=n.optimalRange.max,s.globalHardLimit=Math.round(n.optimalRange.max*1.3)),s}function ko(e,n,t=.3){if(!n.hasEnoughData)return e;let s={...e},o=n.suggestedThresholds;return o.globalSoftLimit!==void 0&&(s.globalSoftLimit=Math.round(e.globalSoftLimit*(1-t)+o.globalSoftLimit*t)),o.globalHardLimit!==void 0&&(s.globalHardLimit=Math.round(e.globalHardLimit*(1-t)+o.globalHardLimit*t)),o.sampleCount!==void 0&&(s.sampleCount=o.sampleCount),o.confidence!==void 0&&(s.confidence=o.confidence),s.lastUpdated=new Date().toISOString(),s}function yt(e){return q.join(e,".orchex","learn","thresholds.json")}async function $o(e,n){let t=yt(e),s=q.dirname(t);await M.mkdir(s,{recursive:!0}),await M.writeFile(t,JSON.stringify(n,null,2),"utf-8")}async function bo(e){let n=yt(e);try{let t=await M.readFile(n,"utf-8"),s=JSON.parse(t);return s.version!==1?(ue.warn({version:s.version},"unknown_thresholds_version"),null):s}catch{return null}}async function De(e){return await bo(e)??{...ee}}function xt(e,n,t){switch(t){case"owns":return e.maxOwnsCount[n]??ee.maxOwnsCount.other;case"reads":return e.maxReadsCount[n]??ee.maxReadsCount.other;case"tokens":return e.maxContextTokens[n]??e.globalSoftLimit}}function vt(e){return q.join(e,".orchex","learn","events.jsonl")}function St(e,n,t){return{id:`learn-${Date.now()}-${e.id}`,sessionHash:"local",eventType:e.status==="complete"?"stream_complete":"stream_failed",timestamp:new Date().toISOString(),durationMs:e.executionTimeMs,success:e.status==="complete",tokensInput:e.tokensUsed?.input,tokensOutput:e.tokensUsed?.output,provider:n,model:t,contextTokensEstimated:e.contextMetrics?.estimatedTokens,contextTokensActual:e.contextMetrics?.actualTokens,contextBudgetUtilization:e.contextMetrics?.budgetUtilization,budgetViolationType:e.contextMetrics?.violationType}}async function kt(e,n){if(n.length===0)return;let t=vt(e),s=q.dirname(t);await M.mkdir(s,{recursive:!0});let o=n.map(r=>JSON.stringify(r)).join(`
|
|
106
106
|
`)+`
|
|
107
107
|
`;await M.appendFile(t,o,"utf-8")}async function Co(e){let n=vt(e);try{let t=await M.readFile(n,"utf-8"),s=[];for(let o of t.split(`
|
|
108
|
-
`))if(o.trim())try{s.push(JSON.parse(o))}catch{}return s}catch{return[]}}async function $t(e){let n=await Co(e);if(n.length<
|
|
108
|
+
`))if(o.trim())try{s.push(JSON.parse(o))}catch{}return s}catch{return[]}}async function $t(e){let n=await Co(e);if(n.length<Fe)return ue.debug({eventCount:n.length,minRequired:Fe},"learning_skipped_insufficient_data"),null;let t=yo(n);if(!t.hasEnoughData)return ue.debug({insights:t.insights},"learning_insufficient_context_data"),t;let s=await De(e),o=ko(s,t);return await $o(e,o),ue.info({sampleCount:o.sampleCount,confidence:o.confidence,globalSoftLimit:o.globalSoftLimit,globalHardLimit:o.globalHardLimit},"learning_cycle_completed"),t}var ue,ee,Fe,ho,go,Le=y(()=>{"use strict";ue=mo("learning-engine"),ee={maxOwnsCount:{code:4,docs:6,tutorial:3,"integration-guide":3,test:4,migration:3,"api-reference":4,other:4},maxReadsCount:{code:4,docs:3,tutorial:4,"integration-guide":4,test:5,migration:4,"api-reference":3,other:4},maxContextTokens:{code:14e4,docs:8e4,tutorial:1e5,"integration-guide":1e5,test:14e4,migration:16e4,"api-reference":8e4,other:1e5},globalSoftLimit:14e4,globalHardLimit:18e4,sampleCount:0,confidence:"low",lastUpdated:new Date().toISOString(),version:1},Fe=20,ho=100,go=50});function Po(e){let n=e.toLowerCase(),t=n.split("/").pop()??n;for(let s of Eo)switch(s){case"tests":if(n.includes("/test")||n.includes("/__tests__/")||t.includes(".test.")||t.includes(".spec.")||t.startsWith("test_")||t.endsWith("_test.ts")||t.endsWith("_test.js"))return"tests";break;case"migrations":if(n.includes("/migration")||t.includes("migration")||t.endsWith(".sql"))return"migrations";break;case"docs":if(n.endsWith(".md")||n.includes("/docs/")||n.includes("/documentation/"))return"docs";break;case"types":if(t.includes("types")||t.includes("schema")||t.includes("interface")||t==="index.d.ts")return"types";break;case"styles":if(n.endsWith(".css")||n.endsWith(".scss")||n.endsWith(".less")||n.endsWith(".sass")||n.includes("/styles/"))return"styles";break}return"core"}function _o(e,n,t){let s=e.split(`
|
|
109
109
|
`),o=To[n],r=t.map(a=>(a.split("/").pop()??a).toLowerCase().replace(/\.[^.]+$/,"")),i=s.filter(a=>{let c=a.toLowerCase();return!!(o.some(l=>c.includes(l))||r.some(l=>c.includes(l)))});return i.length>0?i.join(`
|
|
110
110
|
`):`${e}
|
|
111
111
|
|
|
112
|
-
Files: ${t.join(", ")}`}function Io(e,n){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return n?`${n}-${t}`:t}function Ct(e){let n=[],t=[],s=/^\s*[-*]?\s*(?:Create|Modify|Test):\s*`([^`]+)`/gim,o;for(;(o=s.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&n.push(a)}let r=/\*\*(?:New\s+)?[Ff]ile:\*\*\s*`([^`]+)`/gi;for(;(o=r.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&n.push(a)}let i=/^\s*[-*]?\s*(?:Reads?|Imports?):\s*`([^`]+)`/gim;for(;(o=i.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}return{owned:n,reads:t}}function Et(e,n){let t=new Set,s=new Set(n),o=/(?:import\s+(?:[\s\S]*?\s+from\s+)?|import\s*\()['"]([^'"]+)['"]/g,r=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(let i of e){let a=[],c;for(o.lastIndex=0;(c=o.exec(i.code))!==null;)a.push(c[1]);for(r.lastIndex=0;(c=r.exec(i.code))!==null;)a.push(c[1]);for(let l of a){let u=Mo(l,i.filename);u&&(s.has(u)||n.some(d=>d.endsWith("/"+u))||t.add(u))}}return[...t]}function Mo(e,n){if(!e.startsWith(".")&&!e.startsWith("src/")&&!e.startsWith("tests/")&&!e.startsWith("lib/")||e.startsWith("node:"))return null;let t;if(e.startsWith(".")){if(!n)return null;let s=n.split("/");s.pop();let o=s.join("/"),r=[...o?o.split("/"):[]];for(let i of e.split("/"))i!=="."&&(i===".."?r.pop():r.push(i));t=r.join("/")}else t=e;return t.endsWith(".js")&&(t=t.replace(/\.js$/,".ts")),t.includes(".")||(t=t+".ts"),t}function
|
|
112
|
+
Files: ${t.join(", ")}`}function Io(e,n){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return n?`${n}-${t}`:t}function Ct(e){let n=[],t=[],s=/^\s*[-*]?\s*(?:Create|Modify|Test):\s*`([^`]+)`/gim,o;for(;(o=s.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&n.push(a)}let r=/\*\*(?:New\s+)?[Ff]ile:\*\*\s*`([^`]+)`/gi;for(;(o=r.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&n.push(a)}let i=/^\s*[-*]?\s*(?:Reads?|Imports?):\s*`([^`]+)`/gim;for(;(o=i.exec(e))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}return{owned:n,reads:t}}function Et(e,n){let t=new Set,s=new Set(n),o=/(?:import\s+(?:[\s\S]*?\s+from\s+)?|import\s*\()['"]([^'"]+)['"]/g,r=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(let i of e){let a=[],c;for(o.lastIndex=0;(c=o.exec(i.code))!==null;)a.push(c[1]);for(r.lastIndex=0;(c=r.exec(i.code))!==null;)a.push(c[1]);for(let l of a){let u=Mo(l,i.filename);u&&(s.has(u)||n.some(d=>d.endsWith("/"+u))||t.add(u))}}return[...t]}function Mo(e,n){if(!e.startsWith(".")&&!e.startsWith("src/")&&!e.startsWith("tests/")&&!e.startsWith("lib/")||e.startsWith("node:"))return null;let t;if(e.startsWith(".")){if(!n)return null;let s=n.split("/");s.pop();let o=s.join("/"),r=[...o?o.split("/"):[]];for(let i of e.split("/"))i!=="."&&(i===".."?r.pop():r.push(i));t=r.join("/")}else t=e;return t.endsWith(".js")&&(t=t.replace(/\.js$/,".ts")),t.includes(".")||(t=t+".ts"),t}function Ro(e,n){let t=new Set,s=new Set,o=e.content.match(/reads:\s*\[([^\]]+)\]/i);if(o){let d=o[1].split(",").map(f=>f.trim().replace(/[`"']/g,""));for(let f of d)f&&f.includes(".")&&s.add(f)}let r=ne(e),i=Ot(r),a=Ct(i);for(let d of a.owned)s.has(d)||t.add(d);let c=de(e,n);for(let d of c)d.filename&&d.filename.includes(".")&&!s.has(d.filename)&&t.add(d.filename);let l=/owns:\s*\[([^\]]+)\]/gi,u;for(;(u=l.exec(i))!==null;){let d=u[1].split(",").map(f=>f.trim().replace(/[`"']/g,""));for(let f of d)f&&f.includes(".")&&!s.has(f)&&t.add(f)}return[...t]}function Ot(e){return e.replace(/^```[^\n]*\n[\s\S]*?^```\s*$/gm,"")}function ne(e){let n=e.content;for(let t of e.children)n+=`
|
|
113
113
|
`+t.title+`
|
|
114
|
-
`+ne(t);return n}function de(e,n){let t=[...n];for(let s of e.children){t.push(...s.codeBlocks);for(let o of s.children)t.push(...de(o,[]))}return t}function
|
|
115
|
-
`);for(let t of n){let s=t.trim();if(!s||/^-{3,}$/.test(s)||/^\*\*[^*]+\*\*$/.test(s)&&s.split(/\s+/).length<=3)continue;if(s.split(/\s+/).filter(r=>r.length>0).length>3)return s.length>150?s.slice(0,147)+"...":s}return""}function
|
|
116
|
-
`)}function
|
|
114
|
+
`+ne(t);return n}function de(e,n){let t=[...n];for(let s of e.children){t.push(...s.codeBlocks);for(let o of s.children)t.push(...de(o,[]))}return t}function Ao(e){let n=e.split(`
|
|
115
|
+
`);for(let t of n){let s=t.trim();if(!s||/^-{3,}$/.test(s)||/^\*\*[^*]+\*\*$/.test(s)&&s.split(/\s+/).length<=3)continue;if(s.split(/\s+/).filter(r=>r.length>0).length>3)return s.length>150?s.slice(0,147)+"...":s}return""}function jo(e,n,t=3e3){let s=ne(e);if(s.length<=t||e.children.length<3)return s.slice(0,t);let o=[],r=e.content.trim();r&&o.push(r.slice(0,300));for(let c=0;c<e.children.length;c++){let l=e.children[c],u=l.title,d=Ao(l.content),p=(l.fileReferences||[]).filter(h=>n.includes(h)),m=`${c+1}. ${u}`;p.length>0&&(m+=` (${p.join(", ")})`),d&&(m+=` \u2014 ${d}`),o.push(m)}let i=0,a=[];for(let c of o){if(i+c.length+1>t&&a.length>0)break;a.push(c),i+=c.length+1}return a.join(`
|
|
116
|
+
`)}function Fo(e,n){let t=new Set,s=ne(e),o=Ot(s),r=o.match(/reads:\s*\[([^\]]+)\]/i);if(r){let l=r[1].split(",").map(u=>u.trim().replace(/[`"']/g,""));for(let u of l)u&&u.includes(".")&&!n.includes(u)&&t.add(u)}let i=Ct(o);for(let l of i.reads)n.includes(l)||t.add(l);let a=de(e,e.codeBlocks),c=Et(a,n);for(let l of c)n.includes(l)||t.add(l);return[...t]}function Pt(e){let n=new Map;for(let t of e){let s=Po(t);n.has(s)||n.set(s,[]),n.get(s).push(t)}return n}function Tt(e){if(e._fromYaml)return{split:!1,reasons:[]};let t=[];e.ownedFiles.length>4&&t.push(`Owns ${e.ownedFiles.length} files (max recommended: 4)`);let s=(e.description.match(/\band\b/gi)??[]).length;if(s>2&&t.push(`Description has ${s} "and" conjunctions (suggests multiple tasks)`),e.ownedFiles.length>1){let o=Pt(e.ownedFiles);if(o.size>1){let r=[...o.keys()].join(", ");t.push(`Files belong to ${o.size} different concerns (${r})`)}}return{split:t.length>0,reasons:t}}function Do(e){let n=te(e.name,e.plan||"");return{id:e.id,name:e.name,description:e.plan||"",category:n,ownedFiles:e.owns||[],readFiles:e.reads||[],explicitDeps:e.deps||[],codeExamples:[],isAtomic:!0,_fromYaml:!0,_verify:e.verify,_setup:e.setup}}function Lo(e,n,t){let s=[],o=le(e.sections);for(let r of o){let i=Ae(r);if(t){let a=r.codeBlocks.filter(c=>c.language==="yaml"||c.language==="yml");t.yamlBlocksFound+=a.length,t.yamlBlocksParsed+=i.length}for(let a of i){n&&!a.id.startsWith(n)&&(a.id=`${n}-${a.id}`);let c=Do(a),l=Tt(c);l.split&&(c.isAtomic=!1,c.suggestedSplit=l.reasons),s.push(c)}}return s}function No(e){let n=le(e.sections);for(let t of n)if(Ae(t).length>0)return!0;return!1}function Wo(e){if(["test plan","implementation order","security checklist","gap inventory","task order","dependency order","execution order","deployment order","wave order"].some(r=>e.includes(r)))return!0;let t=["checklist","inventory","roadmap","timeline","schedule"],s=e.split(/[\s:]+/).filter(r=>r.length>0),o=s[s.length-1]??"";return!!t.includes(o)}function _t(e,n={}){let{deliverableLevel:t=2,prefix:s,preferYaml:o=!0,diagnostics:r}=n;if(o&&No(e)){r&&(r.extractionPath="yaml");let l=Lo(e,s,r);return r&&(r.deliverableCount=l.length),l}if(r){let l=le(e.sections);for(let u of l)r.yamlBlocksFound+=u.codeBlocks.filter(d=>d.language==="yaml"||d.language==="yml").length;r.extractionPath="markdown"}let i=[],a=Z(e.sections,t);if(r)for(let l of[2,3,4])r.sectionsFound[l]=Z(e.sections,l).length;for(let l of a){let $=function(D){for(let A of D.fileReferences)m.includes(A)||h.includes(A)||b&&!k.has(A)||h.push(A);for(let A of D.children)$(A)};var c=$;let u=l.title.toLowerCase(),f=u.split(/[\s:]+/).filter(D=>D.length>0)[0]??"";if(u.includes("overview")&&a.indexOf(l)===0||f==="summary"||u==="summary: task order"||f==="conclusion"||f==="introduction"||f==="context"||f==="background"||f==="appendix"||f==="references"||f==="changelog"||f==="prerequisites"||Wo(u)){r&&r.sectionsFilteredAsMeta.push(l.title);continue}let p=Io(l.title,s),m=Ro(l,l.codeBlocks),h=Fo(l,m),w=de(l,l.codeBlocks),k=new Set(Et(w,m)),b=k.size>0;for(let D of l.children)$(D);let S=ne(l),g=te(l.title,S),x={id:p,name:l.title,description:jo(l,m),category:g,ownedFiles:m,readFiles:h,explicitDeps:l.explicitDeps,codeExamples:w,isAtomic:!0,childCount:l.children.length},U=Tt(x);U.split&&(x.isAtomic=!1,x.suggestedSplit=U.reasons),i.push(x)}return r&&(r.deliverableCount=i.length),i}function Uo(e,n){let t=(e.language||"").toLowerCase(),s=e.code.toLowerCase();switch(n){case"migrations":return t==="sql"||s.includes("create table")||s.includes("alter table");case"types":return(t==="typescript"||t==="ts")&&(s.includes("export type ")||s.includes("export interface ")||s.includes("z.object"));case"tests":return s.includes("describe(")||s.includes("it(")||s.includes("expect(");case"docs":return t==="markdown"||t==="md";case"styles":return t==="css"||t==="scss"||t==="less"||t==="sass";case"core":return(t==="typescript"||t==="ts"||t==="javascript"||t==="js")&&!s.includes("export type ")&&!s.includes("export interface ")&&!s.includes("describe(")&&!s.includes("it(");default:return!1}}function Ho(e){if(e._fromYaml)return[{...e,isAtomic:!0}];let t=Pt(e.ownedFiles);if(t.size<=1)return[{...e,isAtomic:!0}];let s=[],o=null,r=0;for(let i of Oo){let a=t.get(i);if(!a||a.length===0)continue;r++;let c=`${e.id}-${i}`,l=`${e.name} (${i})`,u=_o(e.description,i,a),d=[];r===1&&e.explicitDeps.length>0&&d.push(...e.explicitDeps),o&&d.push(o);let f=[];switch(i){case"types":break;case"core":case"migrations":f=[...e.readFiles];break;case"tests":f=[...t.get("core")||[]];break;case"docs":f=[...t.get("core")||t.get("types")||[]];break}let p=e.codeExamples.filter(m=>m.filename&&a.some(h=>m.filename===h)?!0:m.filename?!1:Uo(m,i));s.push({id:c,name:l,description:u,category:e.category,ownedFiles:a,readFiles:f,explicitDeps:d,codeExamples:p,isAtomic:!0}),o=c}return s}function It(e){let n=[];for(let t of e)t.isAtomic?n.push(t):n.push(...Ho(t));return n}function bt(e){let n=[];return n.push(`${e.id}:`),n.push(` Name: ${e.name}`),n.push(` Category: ${e.category}`),n.push(` Owns: ${e.ownedFiles.join(", ")||"(none)"}`),e.readFiles.length>0&&n.push(` Reads: ${e.readFiles.join(", ")}`),e.explicitDeps.length>0&&n.push(` Deps: ${e.explicitDeps.join(", ")}`),e.isAtomic||n.push(` \u26A0\uFE0F Should split: ${e.suggestedSplit?.join("; ")}`),n.join(`
|
|
117
117
|
`)}function Mt(e){let n=e.filter(o=>o.isAtomic),t=e.filter(o=>!o.isAtomic),s=`=== Deliverables Report ===
|
|
118
118
|
|
|
119
119
|
`;if(s+=`Total: ${e.length} deliverables
|
|
@@ -128,8 +128,8 @@ Files: ${t.join(", ")}`}function Io(e,n){let t=e.toLowerCase().replace(/[^a-z0-9
|
|
|
128
128
|
|
|
129
129
|
`;for(let o of n)s+=bt(o)+`
|
|
130
130
|
|
|
131
|
-
`;return s}var Eo,
|
|
132
|
-
`)}var
|
|
131
|
+
`;return s}var Eo,Oo,To,Rt=y(()=>{"use strict";je();Le();Eo=["tests","migrations","docs","types","styles","core"],Oo=["types","migrations","styles","core","tests","docs"];To={types:["type","interface","schema","define","definition","typescript","zod"],migrations:["migrate","migration","schema","table","column","database","sql","alter"],core:["implement","create","add","configure","setup","install","build"],tests:["test","verify","check","assert","coverage","spec","expect"],docs:["document","readme","guide","example","usage","api reference"],styles:["style","css","scss","theme","design","token","color","layout"]}});function Ne(e,n){let t=At.find(a=>e.id.endsWith(a));if(!t)return e;let s=e.id.slice(0,-t.length),o=n.filter(a=>At.some(c=>a.id===`${s}${c}`));if(o.length<=1)return e;let r=o.find(a=>a.id===`${s}-core`);if(r)return r;let i=["-migrations","-types"];for(let a of i){let c=o.find(l=>l.id===`${s}${a}`);if(c)return c}return e}function zo(e,n){let t=e.toLowerCase().trim(),s=n.find(c=>c.id===e);if(s)return s;let o=n.find(c=>c.name.toLowerCase()===t);if(o)return Ne(o,n);let r=n.find(c=>c.id.includes(t)||t.includes(c.id));if(r)return Ne(r,n);let i=t.split(/[\s-_]+/).filter(c=>c.length>2),a=n.find(c=>{let l=c.name.toLowerCase().split(/[\s-_]+/);return i.filter(d=>l.some(f=>f.includes(d)||d.includes(f))).length>=i.length*.5});if(a)return Ne(a,n)}function Bo(e){let n=`${e.name} ${e.description}`.toLowerCase();return/\b(cleanup|clean\s*up|remove|delete|drop)\b/.test(n)}function qo(e){let n=[],t=new Map;for(let r of e)if(!Bo(r))for(let i of r.ownedFiles)t.set(i,r);for(let r of e)for(let i of r.readFiles){let a=t.get(i);a&&a.id!==r.id&&n.push({from:r.id,to:a.id,reason:"file-ownership",explanation:`${r.id} reads ${i} which is owned by ${a.id}`})}let s=new Set(n.map(r=>`${r.from}\u2192${r.to}`)),o=new Set;for(let r of n){let i=`${r.to}\u2192${r.from}`;s.has(i)&&(o.add(`${r.from}\u2192${r.to}`),o.add(i))}return n.filter(r=>!o.has(`${r.from}\u2192${r.to}`))}function Yo(e){let n=[];for(let t of e){if(t.category==="test"){let s=t.id.replace(/-tests?$/,"").replace(/^tests?-/,""),o=e.find(r=>r.id!==t.id&&r.category==="code"&&(r.id===s||r.id===`${s}-core`||r.id===`${s}-service`||r.id===`${s}-implementation`));o&&n.push({from:t.id,to:o.id,reason:"content-pattern",explanation:`${t.id} (test) depends on ${o.id} (implementation)`})}if(t.category==="docs"||t.category==="tutorial"){let s=t.id.replace(/^docs?-/,"").replace(/-docs?$/,"").replace(/^tutorials?-/,"").replace(/-tutorials?$/,""),o=e.filter(i=>i.id!==t.id&&i.category==="code"),r=o.find(i=>i.id===s)||o.find(i=>i.id===`${s}-service`||i.id===`${s}-core`||i.id===`${s}-implementation`)||o.find(i=>i.id.startsWith(`${s}-`)&&!i.id.includes("types"));r&&n.push({from:t.id,to:r.id,reason:"content-pattern",explanation:`${t.id} (${t.category}) documents ${r.id}`})}}return n}function Ko(e,n){let t=[];for(let s of e)for(let o of s.explicitDeps){let r=zo(o,e);if(r&&r.id!==s.id)t.push({from:s.id,to:r.id,reason:"explicit",explanation:`${s.id} explicitly depends on "${o}" (matched ${r.id})`});else if(!r){let i=`Stream '${s.id}': unmatched explicit dep '${o}'`;n?.diagnostics?.unmatchedDeps.push(i),n?.diagnostics?.warnings.push(i)}}return t}function jt(e){let n=[],t=new Set,s=new Set,o=[];function r(i){t.add(i),s.add(i),o.push(i);let a=e.get(i)||[];for(let c of a)if(!t.has(c))r(c);else if(s.has(c)){let l=o.indexOf(c);if(l!==-1){let u=[...o.slice(l),c];n.push(u)}}o.pop(),s.delete(i)}for(let i of e.keys())t.has(i)||r(i);return n}function Vo(e,n,t){let s=0,o=new Set;for(let r of e){let i=[];for(let f=0;f<r.length-1;f++)i.push({from:r[f],to:r[f+1]});let a=[];for(let f of i){let p=n.find(m=>m.from===f.from&&m.to===f.to&&!o.has(`${m.from}\u2192${m.to}`));p&&a.push(p)}if(a.length===0||!a.every(f=>f.reason==="file-ownership"))continue;let l=a.reduce((f,p)=>{let m=t.get(f.from)?.length??0,h=t.get(p.from)?.length??0;return h<m||h===m&&p.from<f.from?p:f}),u=n.indexOf(l);u!==-1&&n.splice(u,1);let d=t.get(l.from);if(d){let f=d.indexOf(l.to);f!==-1&&d.splice(f,1)}o.add(`${l.from}\u2192${l.to}`),s++}return{broken:s}}function Ft(e,n){let t=[...Ko(e,n),...qo(e),...Yo(e)],s=new Set,o=[];for(let a of t){let c=`${a.from}\u2192${a.to}`;s.has(c)||(s.add(c),o.push(a))}let r=new Map;for(let a of e)r.set(a.id,[]);for(let a of o){let c=r.get(a.from)||[];c.includes(a.to)||c.push(a.to),r.set(a.from,c)}let i=jt(r);if(i.length>0){let{broken:a}=Vo(i,o,r);a>0&&(i=jt(r))}return{dependencies:r,edges:o,cycles:i,isAcyclic:i.length===0}}function Dt(e){let n=["=== Dependency Analysis ===",""];if(n.push(`Total edges: ${e.edges.length}`),n.push(`Acyclic: ${e.isAcyclic?"Yes \u2713":"No \u26A0\uFE0F"}`),e.cycles.length>0){n.push(""),n.push("--- Cycles Detected ---");for(let t of e.cycles)n.push(` ${t.join(" \u2192 ")}`)}n.push(""),n.push("--- Dependencies by Deliverable ---");for(let[t,s]of e.dependencies)s.length>0&&n.push(`${t}: ${s.join(", ")}`);n.push(""),n.push("--- Edge Details ---");for(let t of e.edges)n.push(`${t.from} \u2192 ${t.to} (${t.reason})`),n.push(` ${t.explanation}`);return n.join(`
|
|
132
|
+
`)}var At,Lt=y(()=>{"use strict";At=["-types","-migrations","-core","-tests","-docs"]});function Y(e){return new We({...Nt,...e})}var Nt,We,fe=y(()=>{"use strict";Nt={maxOwnsCount:4,maxReadsCount:4,maxDirectories:2,maxPlanConjunctions:4,warnOnMixedActions:!0,warnOnMixedFileTypes:!0,requireVerifyCommands:!0},We=class{config;constructor(n=Nt){this.config=n}analyzeStream(n,t){let s=[],o=t.owns||[],r=t.reads||[],i=t.plan||"",a=t.verify||[],c=o.length,l=r.length,u=this.countDirectories(o),d=this.countConjunctions(i),f=a.length,p=this.detectActionTypes(i),m=this.detectFileTypes([...o,...r]),h={ownsCount:c,readsCount:l,directoriesAffected:u,planConjunctions:d,verifyCommands:f,actionTypes:p,fileTypes:m};c>this.config.maxOwnsCount&&u>this.config.maxDirectories?s.push({type:"high_owns_complexity",severity:"error",message:`Stream owns ${c} files across ${u} directories`,details:`Consider splitting into smaller streams. Threshold: ${this.config.maxOwnsCount} files across ${this.config.maxDirectories} directories`,streamName:n}):c>this.config.maxOwnsCount&&s.push({type:"high_owns_count",severity:"warning",message:`Stream owns ${c} files (threshold: ${this.config.maxOwnsCount})`,details:"Consider splitting into smaller, more focused streams",streamName:n}),l>this.config.maxReadsCount&&s.push({type:"high_reads_count",severity:"warning",message:`Stream reads ${l} files (threshold: ${this.config.maxReadsCount})`,details:"Too many dependencies may indicate unclear scope or context bloat",streamName:n}),d>this.config.maxPlanConjunctions&&s.push({type:"compound_plan",severity:"warning",message:`Plan contains ${d} 'and' conjunctions (threshold: ${this.config.maxPlanConjunctions})`,details:"Complex plans with multiple actions should be split into separate streams",streamName:n}),this.config.warnOnMixedActions&&this.hasMixedActions(p)&&s.push({type:"mixed_actions",severity:"warning",message:"Stream mixes structural changes with content changes",details:`Detected actions: ${p.join(", ")}. Consider separating setup/structure from implementation`,streamName:n}),this.hasUnboundedTutorial(i,o)&&s.push({type:"unbounded_tutorial",severity:"error",message:"Stream appears to create tutorial/documentation without specific file ownership",details:"Tutorial or documentation streams must specify exact files in owns[]",streamName:n}),this.config.warnOnMixedFileTypes&&m.size>3&&s.push({type:"mixed_file_types",severity:"info",message:`Stream touches ${m.size} different file types`,details:`File types: ${Array.from(m).join(", ")}. Consider organizing by concern`,streamName:n}),this.config.requireVerifyCommands&&f===0&&c>0&&s.push({type:"no_verify",severity:"warning",message:"Stream has no verify commands",details:"Add verify commands to ensure implementation correctness",streamName:n}),(!i||i.trim().length===0)&&s.push({type:"empty_plan",severity:"error",message:"Stream has no plan description",details:"Every stream must have a clear plan describing what it does",streamName:n}),this.hasVaguePlan(i)&&s.push({type:"vague_plan",severity:"info",message:"Plan may be too vague or generic",details:"Use specific, actionable language describing exact changes",streamName:n});let w=this.calculateQualityScore(s,h);return{streamName:n,qualityScore:w,issues:s,metrics:h}}analyzeStreams(n){let t=[];for(let[r,i]of Object.entries(n))t.push(this.analyzeStream(r,i));let s=this.countIssuesBySeverity(t),o=this.calculateOverallScore(t);return{streams:t,overallScore:o,totalIssues:s}}countDirectories(n){let t=new Set;for(let s of n){let o=s.substring(0,s.lastIndexOf("/"));o?t.add(o):t.add(".")}return t.size}countConjunctions(n){let s=n.toLowerCase().match(/\band\b/g);return s?s.length:0}detectActionTypes(n){let t=n.toLowerCase(),s=[],o=[{type:"create",pattern:/\b(create|add|implement|build)\b/},{type:"update",pattern:/\b(update|modify|change|edit|refactor)\b/},{type:"delete",pattern:/\b(delete|remove)\b/},{type:"configure",pattern:/\b(configure|setup|install)\b/},{type:"test",pattern:/\b(test|verify)\b/},{type:"document",pattern:/\b(document|write|tutorial)\b/}];for(let{type:r,pattern:i}of o)i.test(t)&&s.push(r);return s}detectFileTypes(n){let t=new Set;for(let s of n){let o=s.substring(s.lastIndexOf(".")+1).toLowerCase();o&&o!==s&&t.add(o)}return t}hasMixedActions(n){let t=["create","delete","configure"],s=["update","document"],o=n.some(i=>t.includes(i)),r=n.some(i=>s.includes(i));return o&&r}hasUnboundedTutorial(n,t){let s=n.toLowerCase();return/\b(tutorial|guide|documentation|example)\b/.test(s)&&t.length===0}hasVaguePlan(n){let t=n.toLowerCase(),s=["various","some","multiple","general","misc","other","stuff","things"];for(let o of s)if(t.includes(o))return!0;return n.trim().split(/\s+/).length<5}calculateQualityScore(n,t){let s=100;for(let o of n)switch(o.severity){case"error":s-=20;break;case"warning":s-=10;break;case"info":s-=5;break}return t.verifyCommands>0&&(s+=5),t.ownsCount>0&&t.ownsCount<=3&&(s+=5),t.planConjunctions===0&&(s+=5),Math.max(0,Math.min(100,s))}calculateOverallScore(n){if(n.length===0)return 0;let t=n.reduce((s,o)=>s+o.qualityScore,0);return Math.round(t/n.length)}countIssuesBySeverity(n){let t={errors:0,warnings:0,info:0};for(let s of n)for(let o of s.issues)switch(o.severity){case"error":t.errors++;break;case"warning":t.warnings++;break;case"info":t.info++;break}return t}}});import{createLogger as Go}from"../logging.js";function Xo(e){let n=new Map,t=[...e.keys()];function s(o,r){let i=new Set,a=[o];for(;a.length>0;){let c=a.shift();if(!i.has(c)){i.add(c);for(let l of e.get(c)??[])l!==r&&!i.has(l)&&a.push(l)}}return i}for(let o of t){let r=e.get(o)??[],i=[];for(let a of r){let c=r.filter(u=>u!==a),l=!1;for(let u of c)if(s(u,o).has(a)){l=!0;break}l||i.push(a)}n.set(o,i)}return n}function Qo(e){let n=new Map,t=new Map;for(let r of e){n.set(r.id,r.deps.length);for(let i of r.deps)t.has(i)||t.set(i,[]),t.get(i).push(r.id);t.has(r.id)||t.set(r.id,[])}let s=e.filter(r=>r.deps.length===0).map(r=>r.id),o=0;for(;s.length>0;){let r=s.shift();o++;for(let i of t.get(r)??[])n.set(i,(n.get(i)??1)-1),n.get(i)===0&&s.push(i)}return o===e.length}function Zo(e){let n=[],t=new Set,s=new Map(e.map(o=>[o.id,[...o.deps]]));for(;s.size>0;){let o=[];for(let[r,i]of s)i.every(a=>t.has(a))&&o.push(r);if(o.length===0)break;for(let r of o)s.delete(r),t.add(r);n.push(o)}return n}function pe(e){let n=[],t=e.reduce((f,p)=>f+p.deps.length,0),s=new Map(e.map(f=>[f.id,[...f.deps]])),o=Xo(s);n.push("transitive-reduction");let r=e.map(f=>({...f,deps:o.get(f.id)??f.deps})),i=r.reduce((f,p)=>f+p.deps.length,0),a=t-i;a>0&&Jo.info({edgesRemoved:a,original:t},"transitive_reduction_applied");let c=Zo(r),l=Qo(r),u=Math.max(0,...c.map(f=>f.length)),d=c.length===1?"parallel":u===1?"sequential":"mixed";return{streams:r,waves:c,report:{originalEdgeCount:t,edgesRemoved:a,waveCount:c.length,classification:d,passesApplied:n},isValid:l}}var Jo,Ue=y(()=>{"use strict";Jo=Go("topology-optimizer")});import*as N from"node:fs";import*as T from"node:path";function Wt(e,n){let t=[];if(!n)return{streams:e,warnings:t};let s={},o=new Set;for(let r of Object.values(e))for(let i of r.owns||[])o.add(i);for(let[r,i]of Object.entries(e)){let a=[...i.reads||[]],c=[];for(let l=0;l<a.length;l++){let u=a[l];if(o.has(u))continue;let d=T.join(n,u);if(N.existsSync(d))continue;let f=T.basename(u),p=er(n,f);p.matches===1&&p.path?(t.push(`${r}: path_corrected - reads path "${u}" corrected to "${p.path}" (only match found)`),a[l]=p.path):p.matches>1?t.push(`${r}: path_ambiguous - reads path "${u}" not found, ${p.matches} candidates exist`):(t.push(`${r}: path_removed - reads path "${u}" not found on disk, removed from reads`),c.push(l))}for(let l=c.length-1;l>=0;l--)a.splice(c[l],1);s[r]={...i,reads:a}}return{streams:s,warnings:t}}function er(e,n){let t=[],s=["src","tests","lib","scripts"];for(let r of s){let i=T.join(e,r);N.existsSync(i)&&Ut(i,n,t)}let o=T.join(e,n);return N.existsSync(o)&&N.statSync(o).isFile()&&t.push(n),t.length===1?{matches:1,path:t[0]}:{matches:t.length}}function Ut(e,n,t,s){let o=s||T.dirname(e);try{let r=N.readdirSync(e,{withFileTypes:!0});for(let i of r){if(i.name==="node_modules"||i.name===".git"||i.name==="dist")continue;let a=T.join(e,i.name);i.isDirectory()?Ut(a,n,t,o):i.name===n&&t.push(T.relative(o,a))}}catch{}}var Ht=y(()=>{"use strict"});import*as Yt from"node:fs";import*as Kt from"node:path";function nr(e,n=5,t=4e3){let s=e.description.trim();if(s.split(/\s+/).filter(r=>r.length>0).length<n){let r=sr(e.category),i=e.ownedFiles.join(", ")||"the target files";s=`${r} ${e.name}. ${s}. Target: ${i}`}if(e.codeExamples.length>0){let r=[],i=0;for(let a of e.codeExamples){let c=`\`\`\`${a.language||""}
|
|
133
133
|
${a.code}
|
|
134
134
|
\`\`\``;if(i+c.length>t)break;r.push(c),i+=c.length}r.length>0&&(s+=`
|
|
135
135
|
|
|
@@ -141,11 +141,11 @@ Reference code:
|
|
|
141
141
|
`)}function Jt(e){return e.streams}function qt(e){let n=e.replace(/^\s*[-*]\s*/,"").trim();return n=n.replace(/\s*\(.*?\)\s*$/,"").trim(),n=n.replace(/[`"']/g,"").trim(),/^@?[a-z0-9][\w./-]*$/i.test(n)?n:null}function Xt(e,n="npm"){let t=new Set;for(let s of Object.values(e)){let o=s.plan??"",r;for(zt.lastIndex=0;(r=zt.exec(o))!==null;){let i=r[1].split(/\s+/).filter(a=>a&&!a.startsWith("-"));for(let a of i){let c=qt(a);c&&t.add(c)}}for(Bt.lastIndex=0;(r=Bt.exec(o))!==null;){let i=r[1].split(`
|
|
142
142
|
`);for(let a of i){let c=qt(a);c&&t.add(c)}}}return t.size===0?[]:[lt(n,[...t])]}var tr,zt,Bt,Qt=y(()=>{"use strict";fe();Ue();Ht();_e();tr={code:12e4,test:9e4,docs:6e4,tutorial:9e4,"integration-guide":9e4,"api-reference":6e4,migration:18e4,other:12e4};zt=/(?:npm\s+install|pnpm\s+add|yarn\s+add|pip\s+install|bun\s+add)\s+(.+)/gi,Bt=/install\s+(?:dependencies|packages)\s*:\s*\n((?:\s+[-*]\s+.+\n?)+)/gi});import{z as v}from"zod";import{ContextBudgetSchema as ar,StreamStatusSchema as cr}from"../types.js";function nn(e,n){let t=[],s={};for(let[i,a]of Object.entries(e)){if(i.length===0||i.length>en){t.push({streamName:i,field:"",message:`stream ID must be 1-${en} chars`});continue}if(!Zt.test(i)){t.push({streamName:i,field:"",message:`stream ID "${i}" must match ${Zt} (alphanumeric + _ -)`});continue}let c=He.safeParse(a);if(!c.success){for(let l of c.error.issues)t.push({streamName:i,field:l.path.join("."),message:l.message});continue}s[i]=c.data}if(t.length>0)return{ok:!1,errors:t};let o=new Map;for(let[i,a]of Object.entries(s))for(let c of a.owns){let l=o.get(c);l&&l!==i?t.push({streamName:i,field:"owns",message:`file "${c}" already owned by stream "${l}"`}):o.set(c,i)}for(let[i,a]of Object.entries(s)){for(let c of a.reads)a.owns.includes(c)&&t.push({streamName:i,field:"reads",message:`stream reads its own owned file "${c}"`});a.deps.includes(i)&&t.push({streamName:i,field:"deps",message:"stream cannot depend on itself"});for(let c of a.deps)s[c]||t.push({streamName:i,field:"deps",message:`dependency "${c}" is not a defined stream`})}let r=lr(s);for(let i of r)t.push({streamName:i[0],field:"deps",message:`circular dependency: ${i.join(" \u2192 ")}`});return t.length>0?{ok:!1,errors:t}:{ok:!0,streams:s}}function lr(e){let n=[],t=new Set,s=new Set,o=new Set;function r(i,a){if(o.has(i)){let c=a.indexOf(i),l=a.slice(c).concat(i),u=ur(l);t.has(u)||(t.add(u),n.push(l));return}if(!s.has(i)){s.add(i),o.add(i);for(let c of e[i]?.deps??[])r(c,[...a,i]);o.delete(i)}}for(let i of Object.keys(e))r(i,[]);return n}function ur(e){let n=e.slice(0,-1);if(n.length===0)return"";let t=n.reduce((o,r,i)=>r<n[o]?i:o,0);return[...n.slice(t),...n.slice(0,t)].join("\u2192")}function sn(e){return e.map(n=>` ${n.field?`${n.streamName}.${n.field}`:n.streamName}: ${n.message}`).join(`
|
|
143
143
|
`)}var K,Zt,en,He,tn,on=y(()=>{"use strict";K=v.string().min(1,"file path must not be empty").refine(e=>!e.startsWith("/"),"file path must be relative (no leading /)").refine(e=>!e.endsWith("/"),"file path must not be a directory (trailing /)").refine(e=>!e.split("/").includes(".."),"file path must not contain path traversal (..)").refine(e=>!e.includes("*")&&!e.includes("?")&&!e.includes("["),"glob characters (* ? [) are not allowed in file paths"),Zt=/^[a-zA-Z0-9_-]+$/,en=100,He=v.object({name:v.string().min(1,"stream name required").max(200),deps:v.array(v.string()).optional().default([]),owns:v.array(K).optional().default([]),reads:v.array(K).optional().default([]),plan:v.string().optional(),setup:v.array(v.string().max(1024)).max(20).optional().default([]),verify:v.array(v.string().max(1024)).max(20).optional().default([]),status:cr.optional().default("pending"),error:v.string().optional(),attempts:v.number().optional().default(0),parentStreamId:v.string().optional(),appliedAt:v.string().optional(),timeoutMs:v.number().optional(),contextBudget:ar.optional(),estimatedTokens:v.number().optional(),provider:v.string().optional(),suggestedProvider:v.string().optional(),model:v.string().optional()}).strict(),tn=v.object({name:v.string().min(1,"stream name required").max(200),deps:v.array(v.string()).optional().default([]),owns:v.array(K).optional().default([]),reads:v.array(K).optional().default([]),plan:v.string().optional(),setup:v.array(v.string().max(1024)).max(20).optional().default([]),verify:v.array(v.string().max(1024)).max(20).optional().default([]),provider:v.string().optional(),model:v.string().optional(),timeoutMs:v.number().optional()}).strict()});var rn={};ae(rn,{autoFixSequentialEdits:()=>ze,detectSequentialEdits:()=>me});function me(e){let n=new Map;for(let[r,i]of Object.entries(e))for(let a of i.owns??[]){let c=n.get(a)??[];c.push(r),n.set(a,c)}let t=new Map;function s(r,i=new Set){if(t.has(r))return t.get(r);if(i.has(r))return new Set;i.add(r);let a=e[r]?.deps??[],c=new Set(a);for(let l of a)for(let u of s(l,i))c.add(u);return t.set(r,c),c}for(let r of Object.keys(e))s(r);let o=[];for(let[r,i]of n){if(i.length<2)continue;let a=[];for(let c=0;c<i.length;c++){let l=!1;for(let u=0;u<i.length;u++){if(c===u)continue;let d=t.get(i[c])??new Set,f=t.get(i[u])??new Set;if(d.has(i[u])||f.has(i[c])){l=!0;break}}l||a.push(i[c])}a.length>=2&&o.push({file:r,streams:a,suggestion:`${r} is modified by ${a.join(" and ")} in the same wave. Split into separate waves by adding a dependency edge, or merge into one stream.`})}return o}function ze(e){let n=me(e),t=0,s=[];for(let o of n)for(let r=1;r<o.streams.length;r++){let i=e[o.streams[r]],a=o.streams[r-1],c=i.deps??[];c.includes(a)||(c.push(a),i.deps=c,t++,s.push(`Added dep: ${o.streams[r]} \u2192 ${a} (shared file: ${o.file})`))}return{edgesAdded:t,fixes:s}}var Be=y(()=>{"use strict"});var cn={};ae(cn,{calculateWaves:()=>fr,findCurrentWave:()=>pr});import{existsSync as dr}from"fs";import*as an from"path";function fr(e,n){let t=[],s=[],o=[],r=new Set,i=new Set,a=new Map;for(let[u,d]of Object.entries(e.streams))d.status==="complete"||d.status==="skipped"?r.add(u):d.status==="failed"||d.status==="blocked"?i.add(u):a.set(u,d.deps);let c=1,l=a.size+1;for(let u=0;u<l&&a.size>0;u++){let d=!0;for(;d;){d=!1;let m=[];for(let[h,w]of a){let k=w.filter(b=>i.has(b));if(k.length>0)if(!(n?k.every($=>{let S=e.streams[$];return!S?.owns||S.owns.length===0?!1:S.owns.every(g=>{try{return dr(an.resolve(n,g))}catch{return!1}})}):!1))m.push(h);else for(let $ of k)r.has($)||r.add($)}for(let h of m){o.push(h),i.add(h),a.delete(h),d=!0;let k=e.streams[h].deps.filter(b=>i.has(b));t.push(`Stream '${h}' blocked: ${k.length===1?`dependency '${k[0]}' failed`:`dependencies '${k.join("', '")}' failed`}`)}}let f=[];for(let[m,h]of a)h.every(k=>r.has(k)||!e.streams[k])&&f.push(m);if(f.length===0&&a.size>0){let m=Array.from(a.keys()).join(", ");t.push(`Circular dependency detected among streams: ${m}`);break}if(f.length===0)break;let p=f.map(m=>({id:m,...e.streams[m]}));s.push({number:c,streams:p});for(let m of f)r.add(m),a.delete(m);c++}return{waves:s,errors:t,blocked:o}}function pr(e,n){for(let t of e)if(t.streams.some(s=>!n.has(s.id)))return t;return null}var ln=y(()=>{"use strict"});import*as z from"fs/promises";import*as qe from"path";import*as un from"os";function dn(){return process.env.ORCHEX_CONFIG_DIR??qe.join(un.homedir(),".orchex")}function fn(){return qe.join(dn(),hr)}async function gr(e){let n=dn();await z.mkdir(n,{recursive:!0}),await z.writeFile(fn(),JSON.stringify(e,null,2),{encoding:"utf-8",mode:384})}async function pn(){try{let e=await z.readFile(fn(),"utf-8"),n=JSON.parse(e);return Date.now()-new Date(n.fetchedAt).getTime()>mr?null:n}catch{return null}}async function mn(e){try{let n=await fetch(`${e}/api/v1/models`,{signal:AbortSignal.timeout(5e3)});if(!n.ok)return null;let s={providers:(await n.json()).providers,fetchedAt:new Date().toISOString()};return await gr(s),s}catch{return null}}var mr,hr,hn=y(()=>{"use strict";mr=1440*60*1e3,hr="models.json"});import{z as E}from"zod";var Ye,Hi,gn=y(()=>{"use strict";Ye=E.enum(["free","pro","team","enterprise"]),Hi=E.object({id:Ye,name:E.string(),price:E.number().describe("Monthly price in USD, -1 = contact sales"),cloudOrchestrations:E.number().describe("Max cloud orchestrations per month, 0 = local only, -1 = unlimited"),maxParallelAgents:E.number().describe("Max parallel agents"),selfHealing:E.enum(["none","full"]),smartPlanning:E.enum(["none","full"]),teamMembers:E.number().describe("Max team members, 1 = solo, -1 = unlimited"),maxWaves:E.number().describe("Max dependency waves allowed. -1 = unlimited"),maxProviders:E.number().describe("Max LLM providers allowed per orchestration. -1 = unlimited"),maxApiTokens:E.number().describe("Max API tokens per user. -1 = unlimited")})});import he from"pino";function ge(e){return yr.child({module:e})}var wr,yr,Ke=y(()=>{"use strict";wr=["password","hashedPassword","hashed_password","token","resetToken","sessionId","apiKey","api_key","masterKey","master_key","clientSecret","client_secret","databaseUrl","database_url","webhookSecret","webhook_secret","secretKey","secret_key","encryptionKey","encryption_key","req.headers.authorization","req.headers.cookie"],yr=he({level:process.env.LOG_LEVEL||"info",redact:wr,serializers:{err:he.stdSerializers.err,req:he.stdSerializers.req,res:he.stdSerializers.res},transport:process.env.LOG_PRETTY==="1"?{target:"pino-pretty",options:{colorize:!0}}:void 0})});import*as Ve from"fs/promises";import*as xr from"path";import{z as _}from"zod";function wn(e){switch(e){case"anthropic":return process.env.ANTHROPIC_API_KEY;case"openai":return process.env.OPENAI_API_KEY;case"gemini":return process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY;case"deepseek":return process.env.DEEPSEEK_API_KEY;case"kimi":return process.env.KIMI_API_KEY||process.env.MOONSHOT_API_KEY;case"bedrock":return;case"ollama":return}}var Gi,vr,Sr,yn,kr,Ji,xn=y(()=>{"use strict";gn();Ke();Gi=ge("config"),vr="https://orchex.dev",Sr=_.enum(["anthropic","openai","gemini","ollama","deepseek","bedrock","kimi"]);yn={anthropic:"claude-sonnet-4-5-20250929",openai:"gpt-4.1",gemini:"gemini-2.0-flash",deepseek:"deepseek-coder",bedrock:"claude-3.5-sonnet",ollama:"llama3.3:70b",kimi:"kimi-k2-0905-preview"},kr=_.object({enabled:_.boolean().default(!1),endpoint:_.string().url().optional()}),Ji=_.object({mode:_.enum(["local","cloud"]).default("local"),apiUrl:_.string().url().refine(e=>e.startsWith("https://")||e.startsWith("http://localhost")||e.startsWith("http://127.0.0.1"),{message:"apiUrl must use https:// (http://localhost and http://127.0.0.1 are allowed for development)"}).default(vr),apiKey:_.string().optional(),tier:Ye.default("free"),provider:Sr.optional(),model:_.string().optional(),trialRunsRemaining:_.number().optional(),accountCreatedAt:_.string().optional(),telemetry:kr.default({enabled:!1})})});var vn={};ae(vn,{MODEL_FALLBACKS:()=>Je,isProviderAvailable:()=>Cr,resolveModel:()=>br});async function $r(){let e=process.env.OLLAMA_BASE_URL??process.env.OLLAMA_HOST??"http://localhost:11434";try{let n=await fetch(`${e}/api/tags`,{signal:AbortSignal.timeout(3e3)});return n.ok?(await n.json()).models.map(s=>s.name):[]}catch{return[]}}async function br(e,n,t){if(e==="ollama"){let i=await $r();if(i.length>0){if(i.includes(n))return{originalModel:n,resolvedModel:n,wasFallback:!1};let a=i.find(c=>c.startsWith(n)||n.startsWith(c.split(":")[0]));return a?{originalModel:n,resolvedModel:a,wasFallback:!0,reason:`Partial match: ${a}`}:{originalModel:n,resolvedModel:i[0],wasFallback:!0,reason:`${n} not installed, using ${i[0]}`}}}let s=await pn();if(!s&&t&&(s=await mn(t)),s?.providers[e]){let i=s.providers[e];if(i.some(l=>l.modelId===n))return{originalModel:n,resolvedModel:n,wasFallback:!1};let c=Je[e]??[];for(let l of c)if(i.some(u=>u.modelId===l))return Ge.warn({provider:e,original:n,fallback:l},"model_fallback"),{originalModel:n,resolvedModel:l,wasFallback:!0,reason:`${n} not found in ${e} model registry, using ${l}`};if(i.length>0){let l=i[0].modelId;return Ge.warn({provider:e,original:n,fallback:l},"model_fallback_registry_first"),{originalModel:n,resolvedModel:l,wasFallback:!0,reason:`${n} not found, using first available: ${l}`}}}let o=Je[e]??[];if(o.includes(n))return{originalModel:n,resolvedModel:n,wasFallback:!1};let r=o[0]??yn[e]??n;return r!==n?(Ge.warn({provider:e,original:n,fallback:r},"model_fallback_static"),{originalModel:n,resolvedModel:r,wasFallback:!0,reason:`Offline \u2014 ${n} unverified, using safe default ${r}`}):{originalModel:n,resolvedModel:n,wasFallback:!1}}function Cr(e){return e==="ollama"||e==="bedrock"?!0:!!wn(e)}var Ge,Je,Sn=y(()=>{"use strict";hn();xn();Ke();Ge=ge("model-validator"),Je={anthropic:["claude-sonnet-4-5-20250929","claude-3-5-sonnet-20241022","claude-3-haiku-20240307"],openai:["gpt-4.1","gpt-4o","gpt-4o-mini","gpt-3.5-turbo"],gemini:["gemini-2.5-pro","gemini-2.0-flash","gemini-1.5-flash"],deepseek:["deepseek-chat","deepseek-coder"],kimi:["kimi-k2-0905-preview","kimi-latest","moonshot-v1-128k","moonshot-v1-32k","moonshot-v1-8k"],bedrock:["claude-3.5-sonnet","claude-3-haiku"],ollama:["llama3.3:70b","llama3.2:latest"]}});function Xe(e,n,t,s,o){let r=new Set;for(let d of Object.values(e))for(let f of d.owns??[])r.add(f);let i=0;if(o)for(let d of Object.values(o))d.estimatedCostUsd&&(i+=d.estimatedCostUsd);let a=n.map(d=>({number:d.number,streams:d.streams.map(f=>{let p=e[f],m=o?.[f];return{id:f,name:p?.name??f,owns:p?.owns??[],reads:p?.reads??[],deps:p?.deps??[],provider:m?.provider,model:m?.model,estimatedCostUsd:m?.estimatedCostUsd,modelFallback:m?.fallback}})})),c=[...t];if(s)for(let d of s)c.push(`Sequential edit conflict: ${d.suggestion}`);if(o)for(let[d,f]of Object.entries(o))f.fallback&&c.push(`${d}: ${f.fallback}`);let l=100;c.length>0&&(l-=c.length*5);let u=Object.values(e).filter(d=>!d.owns||d.owns.length===0).length;return l-=u*10,l=Math.max(0,Math.min(100,l)),{summary:{streamCount:Object.keys(e).length,waveCount:n.length,fileCount:r.size,estimatedCostUsd:i>0?i:void 0},waves:a,warnings:c,qualityScore:l}}function Er(e){return!e||e===0?"":e<.01?" ~< $0.01":` ~$${e.toFixed(2)}`}function kn(e){let n=[],t=e.summary.estimatedCostUsd?`, est. ~$${e.summary.estimatedCostUsd.toFixed(2)}`:"";n.push(`Plan Preview: ${e.summary.streamCount} streams, ${e.summary.waveCount} waves, ${e.summary.fileCount} files${t}`),n.push(`Quality Score: ${e.qualityScore}/100`),n.push("");for(let s of e.waves){n.push(`Wave ${s.number}:`);for(let o of s.streams){let r=o.deps.length>0?` (deps: ${o.deps.join(", ")})`:"",i=o.model?` (${o.model})`:"",a=Er(o.estimatedCostUsd);n.push(` ${o.id}: ${o.name}${i}${a}${r}`),o.owns.length>0&&n.push(` owns: ${o.owns.join(", ")}`),o.reads.length>0&&n.push(` reads: ${o.reads.join(", ")}`)}n.push("")}if(e.warnings.length>0){n.push("Warnings:");for(let s of e.warnings)n.push(` - ${s}`);n.push("")}return n.join(`
|
|
144
|
-
`)}async function $n(e){let{generatePlan:n,parsePlanDocument:t,extractDeliverables:s,processDeliverables:o,buildDependencyGraph:r,generateStreams:i,toInitFormat:a,createDiagnostics:c,estimatePlannedCost:l}=await Promise.resolve().then(()=>(En(),Cn)),{detectSequentialEdits:u}=await Promise.resolve().then(()=>(Be(),rn)),{calculateWaves:d}=await Promise.resolve().then(()=>(ln(),cn)),{resolveModel:f}=await Promise.resolve().then(()=>(Sn(),vn)),{DEFAULT_MODELS:p}=await import("../config.js"),m=e.planMarkdown,h={input:0,output:0};if(!m){let
|
|
145
|
-
`)}function Wn(e,n){let t=0,s=n;for(;s;){let o=e.streams[s];if(!o)break;t+=o.attempts??0,s=o.parentStreamId}return t}function
|
|
144
|
+
`)}async function $n(e){let{generatePlan:n,parsePlanDocument:t,extractDeliverables:s,processDeliverables:o,buildDependencyGraph:r,generateStreams:i,toInitFormat:a,createDiagnostics:c,estimatePlannedCost:l}=await Promise.resolve().then(()=>(En(),Cn)),{detectSequentialEdits:u}=await Promise.resolve().then(()=>(Be(),rn)),{calculateWaves:d}=await Promise.resolve().then(()=>(ln(),cn)),{resolveModel:f}=await Promise.resolve().then(()=>(Sn(),vn)),{DEFAULT_MODELS:p}=await import("../config.js"),m=e.planMarkdown,h={input:0,output:0};if(!m){let j=await n(e.intent,e.projectDir,e.executor,{model:e.model,provider:e.provider,maxStreams:e.maxStreams});m=j.planMarkdown,h=j.tokensUsed}let w=c(),k=t(m),b=s(k,{diagnostics:w}),$=o(b);if($.length===0)throw new Error("Plan generated no deliverables. Try a more specific intent.");let S=r($,{diagnostics:w}),g=i($,S,{validateAntiPatterns:!0,projectDir:e.projectDir,diagnostics:w}),x=u(g.streams),U=a(g),D=Object.fromEntries(Object.entries(U).map(([j,P])=>[j,{name:P.name,deps:P.deps||[],owns:P.owns||[],reads:P.reads||[],setup:[],plan:P.plan,verify:P.verify||[],status:"pending",attempts:0}])),{waves:A}=d({feature:k.title,streams:D,status:"pending",created:new Date().toISOString()}),qs=A.map(j=>({number:j.number,streams:j.streams.map(P=>P.id)})),Ys=[...g.warnings,...w.warnings],Oe={};for(let[j,P]of Object.entries(U)){let Pe=P.suggestedProvider??e.provider,Vs=p[Pe]??e.model,X=await f(Pe,Vs??"",e.modelApiUrl),Gs=(P.owns??[]).length*100,Js=l(Gs*4,X.resolvedModel);Oe[j]={provider:Pe,model:X.resolvedModel,estimatedCostUsd:Js.finalCost,fallback:X.wasFallback?`${X.originalModel} \u2192 ${X.resolvedModel}`:void 0}}let Ks=Xe(U,qs,Ys,x,Oe);return{planMarkdown:m,preview:Ks,initStreams:U,waves:A,sequentialDiagnostics:x,modelDecisions:Oe,tokensUsed:h}}var bn=y(()=>{"use strict"});function On(){return{yamlBlocksFound:0,yamlBlocksParsed:0,yamlParseErrors:[],extractionPath:null,sectionsFound:{},sectionsFilteredAsMeta:[],deliverableCount:0,splitCount:0,unmatchedDeps:[],ownershipConflicts:[],warnings:[]}}function Pn(e){let n=new Map;for(let[s,o]of Object.entries(e))for(let r of o.owns||[]){let i=n.get(r)||[];i.push(s),n.set(r,i)}let t=[];for(let[s,o]of n)o.length>1&&t.push(`${s} owned by: ${o.join(", ")}`);return t}var Tn=y(()=>{"use strict"});function we(e,n){for(let{pattern:s,category:o,retryable:r,selfHealable:i,suggestion:a}of Or)if(s.test(e))return{category:o,retryable:r,selfHealable:i,suggestion:a};let t=n==="artifact"||n==="verify";return{category:"unknown",retryable:t,selfHealable:t,suggestion:t?"Unknown code error. Retry with the full error message included in the prompt.":`Unknown infrastructure error (origin: ${n??"unspecified"}). Check API key, model availability, and network connectivity.`}}var Or,Qe=y(()=>{"use strict";Or=[{pattern:/model.*not.found|not_found_error.*model|Model ".*" not found/i,category:"model_not_found",retryable:!1,selfHealable:!1,suggestion:"Model not found. Check the model name in your configuration and ensure it is available for your API key."},{pattern:/invalid api key|api key.*expired|authentication failed|(?<!\d)401(?!\d)|unauthorized/i,category:"auth_error",retryable:!1,selfHealable:!1,suggestion:"Authentication error. Check your API key configuration and ensure it is valid and not expired."},{pattern:/cloud api error: 5\d{2}|502 bad gateway|503 service unavailable|504 gateway timeout|internal server error|overloaded_error/i,category:"server_error",retryable:!0,selfHealable:!1,suggestion:"Cloud server error. Transport retries exhausted \u2014 try again later or switch to local mode."},{pattern:/timed?\s*out|ETIMEDOUT|deadline|timeout/i,category:"timeout",retryable:!1,selfHealable:!1,suggestion:"Timeout is an infrastructure issue. Consider increasing stream timeout or reducing scope."},{pattern:/network error|ECONNREFUSED|ECONNRESET|EHOSTUNREACH|socket hang up/i,category:"network",retryable:!1,selfHealable:!1,suggestion:"Network connectivity issue. Check API endpoint availability and network configuration."},{pattern:/rate limit|too many requests|429|quota exceeded/i,category:"rate_limit",retryable:!1,selfHealable:!1,suggestion:"Rate limited by API. Wait before retrying or reduce parallel stream count."},{pattern:/old_?content.*not found|edit.*mismatch|does not match|oldContent/i,category:"edit_mismatch",retryable:!0,selfHealable:!0,suggestion:"The file content changed since context was built. Re-read the file and retry with updated content."},{pattern:/invalid.*artifact|parse.*error|orchex-artifact.*not found|JSON\.parse/i,category:"invalid_artifact",retryable:!0,selfHealable:!0,suggestion:"The agent produced malformed output. Retry with clearer instructions about the artifact format."},{pattern:/ENOENT|EACCES|EPERM|ENOSPC|no such file|permission denied/i,category:"environment",retryable:!1,selfHealable:!1,suggestion:"File system error. Check file paths and permissions."},{pattern:/ownership violation|outside owned files|SECURITY.*path traversal|SECURITY.*absolute path/i,category:"ownership_violation",retryable:!0,selfHealable:!0,suggestion:"File operation attempted outside owned files. The fix stream should only modify files in the owns list, or the owns list should be updated to include the new file."},{pattern:/test.*fail|expect.*received|assertion.*error|FAIL\s+tests\//i,category:"test_failure",retryable:!0,selfHealable:!0,suggestion:"Tests are failing. Include the test error output in the retry prompt so the agent can fix the issue."},{pattern:/lint|eslint|prettier|formatting/i,category:"lint_error",retryable:!0,selfHealable:!0,suggestion:"Lint or formatting error. Include the lint output in the retry prompt."},{pattern:/TypeError|ReferenceError|SyntaxError|Cannot find module|cannot find name|TS\d{4}/i,category:"runtime_error",retryable:!0,selfHealable:!0,suggestion:"Code has type or runtime errors. Include the error output and relevant type definitions in the retry prompt."}]});import{loadManifest as _n,saveManifest as In}from"../manifest.js";import{createLogger as Pr}from"../logging.js";async function Mn(e){let n=await _n(e),t={skipped:[],warnings:[]},s=Object.entries(n.streams).filter(([o,r])=>r.parentStreamId!==void 0);for(let[o,r]of s)r.status==="pending"&&Tr(n,r.parentStreamId)&&(n.streams[o].status="skipped",n.streams[o].error="Parent stream completed; fix no longer needed",t.skipped.push(o));return t.skipped.length>0&&await In(e,n),t}async function Rn(e,n){let t=await _n(e),s={skipped:[],warnings:[]},o=_r(t,n);for(let a of o){let c=t.streams[a];c.status==="pending"?(t.streams[a].status="skipped",t.streams[a].error=`Ancestor '${n}' completed; fix no longer needed`,s.skipped.push(a)):c.status==="in_progress"&&(t.streams[a].status="skipped",t.streams[a].error=`Sibling fix already resolved this stream (completed: '${n}')`,s.skipped.push(a))}let r=!1,i=t.streams[n];if(i?.parentStreamId){let a=i.parentStreamId;for(;t.streams[a]?.parentStreamId;)a=t.streams[a].parentStreamId;let c=t.streams[a];c&&c.status==="failed"&&(t.streams[a].status="complete",delete t.streams[a].error,r=!0,Ze.info({fixStreamId:n,rootStreamId:a},"fix_stream_propagated_completion_to_root"))}return(s.skipped.length>0||r)&&await In(e,t),s}function se(e,n){let t=e.streams[n];if(!t||!t.parentStreamId)return null;let s=[n],o=t.parentStreamId,r=new Set;for(;o&&!r.has(o);){r.add(o);let i=e.streams[o];if(!i)break;if(s.unshift(o),!i.parentStreamId)return{rootStreamId:o,fixChain:s.slice(1),rootStatus:i.status??"pending"};o=i.parentStreamId}return null}function An(e,n){return e.streams[n]?.parentStreamId!==void 0}function jn(e,n){return se(e,n)?.rootStreamId??n}function Tr(e,n){let t=n,s=new Set;for(;t;){if(s.has(t)){Ze.warn({streamId:t},"circular_reference_in_fix_chain");break}s.add(t);let o=e.streams[t];if(!o){Ze.warn({parentId:t},"fix_stream_orphaned_parent");break}if(o.status==="complete")return!0;t=o.parentStreamId}return!1}function _r(e,n){let t=[];for(let[s,o]of Object.entries(e.streams))o.parentStreamId&&Ir(e,s,n)&&t.push(s);return t}function Ir(e,n,t){let s=e.streams[n]?.parentStreamId,o=new Set;for(;s&&!o.has(s);){if(o.add(s),s===t)return!0;s=e.streams[s]?.parentStreamId}return!1}var Ze,et=y(()=>{"use strict";Ze=Pr("fix-stream-manager")});import{existsSync as Mr,statSync as Rr}from"node:fs";import*as Dn from"node:path";function Nn(e,n){if(!e||e.length===0)return"";let t=[],s=[];for(let r of e)try{let i=Dn.resolve(n,r);Mr(i)&&Rr(i).isFile()?t.push(r):s.push(r)}catch{}if(t.length===0&&s.length===0)return"";let o=["","### Disk State (for files you own)"];if(t.length>0){o.push(""),o.push("The following files currently exist on disk from a previous attempt:");for(let r of t)o.push(`- ${r}`)}if(s.length>0){o.push(""),o.push("The following files do NOT exist on disk:");for(let r of s)o.push(`- ${r}`)}return o.push(""),o.push('IMPORTANT: For files that already exist, use operation type `edit` or `replace`, NEVER `create`. Using `create` on an existing file will fail with "Conflicts detected" and this fix attempt will be wasted.'),s.length>0&&o.push("For files that do NOT exist, use `create`."),o.join(`
|
|
145
|
+
`)}function Wn(e,n){let t=0,s=n;for(;s;){let o=e.streams[s];if(!o)break;t+=o.attempts??0,s=o.parentStreamId}return t}function Fn(e,n){return se(e,n)?.rootStreamId??n}function Un(e,n){let t=Fn(e,n);for(let[s,o]of Object.entries(e.streams)){if(s===n||!o.parentStreamId||o.status!=="pending"&&o.status!=="in_progress")continue;if(Fn(e,s)===t)return!0}return!1}function Hn(e,n,t,s,o){let r=e.streams[n];if(!r||r.status==="failed"&&r.error?.startsWith("Setup failed:"))return null;let i=r.error??"",a=t??we(i);if(!a.selfHealable||Un(e,n)||Wn(e,n)>=Ln)return null;let u=(r.attempts??0)+1,d=`${n}-fix-${u}`,f=n,p=o?Nn(r.owns??[],o):"",m=[`## Fix Attempt #${u} for "${r.name}"`,"","### Original Plan",r.plan??"(no plan)","","### Error That Occurred","```",i,"```","",`### Error Category: ${a.category}`,"",`### Suggestion: ${a.suggestion}`,"","### Instructions",`This is a retry of the failed stream "${n}".`,"Fix the issue described above. The original files are in your owns list.","Make sure to address the specific error before implementing the rest of the plan.",...s?["","### Upstream Dependency Warning",`Your error references '${s.errorRef}' which is likely defined by upstream stream '${s.suspectStreamId}'.`,`That stream owns: ${s.suspectFiles.join(", ")}`,"Before fixing your own code, verify that the upstream dependency exports the types/values you need.","If the upstream output is incorrect (wrong type names, missing exports), this fix will fail again.","In that case, the issue will be escalated to fix the upstream stream directly."]:[],...p?[p]:[]].join(`
|
|
146
146
|
`),h={name:`${r.name} (Fix #${u})`,deps:r.deps??[],owns:r.owns??[],reads:r.reads??[],plan:m,setup:r.setup??[],verify:r.verify??[],status:"pending",attempts:0,parentStreamId:f};return{fixStreamId:d,fixStream:h,analysis:{category:a.category,suggestion:a.suggestion}}}function zn(e,n){let t=e.streams[n];if(!t?.error)return null;let s=t.deps??[];if(s.length===0)return null;let o=/(?:Cannot find (?:name|module) '(\w+)'|Type '(\w+)'|has no (?:exported )?member '(\w+)'|is not assignable to type '(\w+)'|does not exist on type '(\w+)'|Property '(\w+)' does not exist)/gi,r=new Set,i;for(;(i=o.exec(t.error))!==null;){let a=i[1]||i[2]||i[3]||i[4]||i[5]||i[6];a&&r.add(a)}if(r.size===0)return null;for(let a of s){let c=e.streams[a];if(!c||c.status!=="complete")continue;let l=c.owns??[];if(l.length===0)continue;let u=l.filter(d=>d.endsWith(".ts")||d.endsWith(".tsx")||d.endsWith(".d.ts"));if(u.length!==0)for(let d of r){let f=d.toLowerCase();if(u.some(m=>{let h=m.toLowerCase();return h.includes("type")||h.includes("index")||h.includes(f)||h.includes("model")||h.includes("schema")||h.includes("interface")}))return{suspectStreamId:a,errorRef:d,suspectFiles:u}}}return null}function ye(e,n){if(n.length<2)return null;let t=new Map;for(let d of n){let f=e.streams[d];f?.error&&t.set(d,f.error)}if(t.size<2)return null;let s=/(?:Cannot find (?:name|module)|Type '(\w+)'|has no (?:exported )?member '(\w+)'|is not assignable|does not exist on type '(\w+)')/.source,o=new Map;for(let[d,f]of t){let p=new RegExp(s,"gi"),m,h=new Set;for(;(m=p.exec(f))!==null;){let w=m[1]||m[2]||m[3]||m[0];h.add(w)}for(let w of h){let k=o.get(w)??[];k.push(d),o.set(w,k)}}let r="",i=0;for(let[d,f]of o)f.length>i&&(r=d,i=f.length);if(i<2)return null;let a=o.get(r),c=new Map;for(let d of a){let f=e.streams[d];for(let p of f?.deps??[])c.set(p,(c.get(p)??0)+1)}let l="",u=0;for(let[d,f]of c)e.streams[d]?.status==="complete"&&f>u&&(l=d,u=f);return l?{rootCauseStreamId:l,reason:`Stream '${l}' completed but ${a.length} downstream streams failed with errors referencing '${r}'`,affectedStreamIds:a,commonErrorPattern:r}:null}function Bn(e,n,t){let s=n.rootCauseStreamId,o=e.streams[s];if(!o||o.status!=="failed"||Wn(e,s)>=Ln||Un(e,s))return null;let a=(o.attempts??0)+1,c=`${s}-fix-${a}`,l=[];for(let p of n.affectedStreamIds.slice(0,3)){let m=e.streams[p];m?.error&&l.push(`- ${m.name}: ${m.error.slice(0,200)}`)}let u=t?Nn(o.owns??[],t):"",d=[`## Root Cause Fix #${a} for "${o.name}"`,"","### Original Plan",o.plan??"(no plan)","","### Problem Identified",`This stream completed but its output caused ${n.affectedStreamIds.length} downstream streams to fail.`,`All downstream errors reference: **${n.commonErrorPattern}**`,"","### Downstream Error Samples",...l,"","### Instructions",`This stream's output is incorrect. The code you produce must define '${n.commonErrorPattern}' correctly`,"so that downstream streams importing from this file can compile successfully.","Re-read the original plan carefully and ensure your output matches the specified types, exports, and signatures exactly.","Pay special attention to type definitions, enum values, and const arrays \u2014 they must match what downstream code expects.",...u?[u]:[]].join(`
|
|
147
|
-
`),f={name:`${o.name} (Root Cause Fix #${a})`,deps:o.deps??[],owns:o.owns??[],reads:o.reads??[],plan:d,setup:o.setup??[],verify:o.verify??[],status:"pending",attempts:0,parentStreamId:s};return{fixStreamId:c,fixStream:f,analysis:{category:"runtime_error",suggestion:n.reason}}}var Ln,tt=y(()=>{"use strict";Qe();et();Ln=3});import{randomUUID as
|
|
148
|
-
`)}var Jn,es=y(()=>{"use strict";Jn=".first-run-complete"});import*as oe from"fs/promises";import*as A from"path";async function ns(e,n){if(!n.confirm)throw new Error("Reset learning requires --confirm flag. This permanently deletes learning data.");let t=[],s=A.join(e,".orchex","learn"),o=A.join(e,".orchex","reports");n.patternsOnly?await xe(A.join(s,"patterns.json"),t):n.reportsOnly?await ts(o,t,".json"):(await xe(A.join(s,"thresholds.json"),t),await xe(A.join(s,"events.jsonl"),t),await xe(A.join(s,"patterns.json"),t),await ts(o,t,".json"));let r=n.patternsOnly?"patterns":n.reportsOnly?"reports":"all learning data";return{deleted:t,totalDeleted:t.length,message:t.length>0?`Reset ${r}: ${t.length} file(s) deleted.`:`No ${r} found to delete.`}}async function xe(e,n){try{await oe.unlink(e),n.push(A.basename(e))}catch(t){if(t.code!=="ENOENT")throw t}}async function ts(e,n,t){try{let s=await oe.readdir(e);for(let o of s)t&&!o.endsWith(t)||(await oe.unlink(A.join(e,o)),n.push(o))}catch(s){if(s.code!=="ENOENT")throw s}}var ss=y(()=>{"use strict"});import{createLogger as Dr}from"../logging.js";function os(e){let{streamResults:n,iterationNumber:t,maxIterations:s,intent:o}=e;if(t>=s){let d=n.filter(f=>f.status==="failed"||!f.verifyPassed).length;return{complete:!0,reason:`Reached max iterations (${s})${d>0?` with ${d} unresolved failure(s)`:""}`,failureSummary:d>0?n.filter(f=>f.status==="failed").map(f=>`${f.id}: ${f.error}`).join("; "):void 0}}let r=n.filter(d=>d.status==="failed"),i=n.filter(d=>d.status==="complete"&&!d.verifyPassed);if(r.length===0&&i.length===0)return{complete:!0,reason:`All ${n.length} stream(s) completed and verified successfully`};let c=[];for(let d of r)c.push(`Stream "${d.id}" failed: ${d.error??"unknown error"}`);for(let d of i)c.push(`Stream "${d.id}" verify failed: ${d.verifyError??"verification error"}`);let l=c.join("; "),u=`Fix the following issues from the previous attempt to "${o}": ${l}`;return Lr.info({iteration:t,failed:r.length,verifyFailed:i.length},"iteration_incomplete"),{complete:!1,reason:`${r.length} stream(s) failed, ${i.length} verification(s) failed`,nextIntent:u,failureSummary:l}}var Lr,rs=y(()=>{"use strict";Lr=Dr("iteration-evaluator")});function re(e){let n=e.toLowerCase(),t=null;for(let s of Br){let o=0;for(let r of s.keywords)n.includes(r.toLowerCase())&&(o+=2);for(let r of s.patterns){let i=r.toLowerCase().split(/[\s/,]+/).filter(c=>c.length>2);i.filter(c=>n.includes(c)).length>=i.length/2&&(o+=1)}o>0&&(!t||o>t.score)&&(t={template:s,score:o})}return t&&t.score>=3?t.template:null}function ve(e,n){let t=[];if(e.id==="documentation-set"){let s=n.topics||[];for(let o of s)t.push({name:`docs-${o}`,deps:[],owns:[`docs/${o}/**/*.md`],reads:["src/**/*.ts","README.md"],plan:`Research ${o} implementation \u2192 Write documentation \u2192 Add examples \u2192 Review completeness`})}else if(e.id==="code-feature"){let s=n.featureName;t.push({name:`${s}-types`,deps:[],owns:[`src/types/${s}.ts`],reads:["src/types.ts"],plan:"Analyze requirements \u2192 Define types \u2192 Add validation schemas \u2192 Export types"},{name:`${s}-core`,deps:[`${s}-types`],owns:[`src/${s}/*.ts`],reads:[`src/types/${s}.ts`,"src/utils/*.ts"],plan:"Implement core logic \u2192 Add error handling \u2192 Integrate with existing systems"},{name:`${s}-tests`,deps:[`${s}-core`],owns:[`tests/${s}.test.ts`],reads:[`src/${s}/*.ts`],plan:"Write unit tests \u2192 Add integration tests \u2192 Test edge cases \u2192 Verify coverage"},{name:`${s}-docs`,deps:[`${s}-core`],owns:[`docs/${s}/*.md`],reads:[`src/${s}/*.ts`],plan:"Document API \u2192 Add usage examples \u2192 Write integration guide"})}else if(e.id==="migration"){let s=n.featureName,o=n.components||[];t.push({name:`${s}-new-implementation`,deps:[],owns:[`src/${s}-new/*.ts`],reads:[`src/${s}-old/*.ts`],plan:"Implement new version \u2192 Match old API \u2192 Add compatibility layer"});for(let r of o)t.push({name:`${s}-migrate-${r}`,deps:[`${s}-new-implementation`],owns:[`src/${r}/**/*.ts`],reads:[`src/${s}-new/*.ts`,`src/${s}-old/*.ts`],plan:"Update imports \u2192 Replace function calls \u2192 Update tests \u2192 Verify behavior"});t.push({name:`${s}-deprecate-old`,deps:o.map(r=>`${s}-migrate-${r}`),owns:[`src/${s}-old/*.ts`],reads:[],plan:"Add deprecation notices \u2192 Update docs \u2192 Plan removal timeline"})}else if(e.id==="tutorial"){let s=n.topics||[];for(let o of s)t.push({name:`tutorial-${o}`,deps:[],owns:[`docs/tutorials/${o}.md`,`examples/${o}/**/*`],reads:["src/**/*.ts"],plan:"Define learning objectives \u2192 Write tutorial \u2192 Create working example \u2192 Add exercises"})}else if(e.id==="api-reference"){let s=n.modules||[];for(let o of s)t.push({name:`api-${o}-reference`,deps:[],owns:[`docs/api/${o}.md`],reads:[`src/${o}/**/*.ts`],plan:"Extract types/interfaces \u2192 Document functions \u2192 Add examples \u2192 Cross-link related APIs"})}return t}function is(e){let n=e.owns||[],t=e.reads||[];if(n.length>5)return{originalStream:e.name,reason:`Stream owns ${n.length} files, which may be too many for a single stream`,guidance:["Consider grouping related files together","Split by logical component or responsibility","Create dependencies between resulting streams if needed"],suggestedStreams:[]};if(t.length>10)return{originalStream:e.name,reason:`Stream reads ${t.length} files, which may indicate broad scope`,guidance:["Reading many files often means the stream is doing too much","Consider splitting into smaller, focused streams","Each stream should ideally read 3-5 context files"],suggestedStreams:[]};let s=`${e.name} ${e.plan||""}`,o=re(s);return o&&["multiple","all","complete","full","entire"].some(a=>e.name.toLowerCase().includes(a))?{originalStream:e.name,reason:"Stream name suggests broad scope that could be split",template:o,guidance:o.guidelines,suggestedStreams:[]}:null}var Nr,Wr,Ur,Hr,zr,Br,nt=y(()=>{"use strict";Nr={id:"documentation-set",name:"Documentation Set",description:"Multiple documentation files (guides, tutorials, API references) that should be created independently",keywords:["docs","documentation","guide","tutorial","readme","api reference","multiple pages"],patterns:["Multiple .md files in docs/","Creating 3+ documentation files","Tutorial series","API documentation pages"],streamStructure:[{namePattern:"docs-{topic}",purpose:"Create documentation for a specific topic",dependsOn:[],ownsPatterns:["docs/{topic}/**/*.md"],readsPatterns:["src/**/*.ts","README.md"],planOutline:"Research implementation \u2192 Write documentation \u2192 Add examples \u2192 Review completeness"}],guidelines:["Split by logical topic, not file count","Each stream should own 1-3 related doc files","Order dependencies: concepts \u2192 API reference \u2192 tutorials \u2192 advanced guides","Streams can run in parallel if topics are independent","Keep related examples with their topic"]},Wr={id:"code-feature",name:"Code Feature Implementation",description:"Multi-component feature with types, implementation, tests, and documentation",keywords:["feature","implement","add","create","types","tests","integration"],patterns:["Types \u2192 Implementation \u2192 Tests \u2192 Docs","Multiple source files with dependencies","Test files alongside implementation","Integration with existing code"],streamStructure:[{namePattern:"{feature}-types",purpose:"Define interfaces, types, and schemas",dependsOn:[],ownsPatterns:["src/types/{feature}.ts","src/schemas/{feature}.ts"],readsPatterns:["src/types.ts"],planOutline:"Analyze requirements \u2192 Define types \u2192 Add validation schemas \u2192 Export types"},{namePattern:"{feature}-core",purpose:"Core feature implementation",dependsOn:["{feature}-types"],ownsPatterns:["src/{feature}/*.ts"],readsPatterns:["src/types/{feature}.ts","src/utils/*.ts"],planOutline:"Implement core logic \u2192 Add error handling \u2192 Integrate with existing systems"},{namePattern:"{feature}-tests",purpose:"Unit and integration tests",dependsOn:["{feature}-core"],ownsPatterns:["tests/{feature}.test.ts"],readsPatterns:["src/{feature}/*.ts"],planOutline:"Write unit tests \u2192 Add integration tests \u2192 Test edge cases \u2192 Verify coverage"},{namePattern:"{feature}-docs",purpose:"Documentation and examples",dependsOn:["{feature}-core"],ownsPatterns:["docs/{feature}/*.md"],readsPatterns:["src/{feature}/*.ts"],planOutline:"Document API \u2192 Add usage examples \u2192 Write integration guide"}],guidelines:["Always start with types to establish contracts","Core implementation depends on types being defined","Tests and docs can run in parallel after core is complete","Keep streams focused: one stream = one responsibility","If a file has 200+ lines, consider splitting implementation into multiple streams"]},Ur={id:"migration",name:"Migration",description:"Migrating code, data, or structure with backward compatibility",keywords:["migration","migrate","refactor","rename","move","deprecate","backward compatible"],patterns:["From old to new","Rename/move files or functions","Change data structure","Update multiple call sites","Maintain backward compatibility"],streamStructure:[{namePattern:"{migration}-new-implementation",purpose:"Create new implementation alongside old one",dependsOn:[],ownsPatterns:["src/{new}/*.ts"],readsPatterns:["src/{old}/*.ts"],planOutline:"Implement new version \u2192 Match old API \u2192 Add compatibility layer"},{namePattern:"{migration}-migrate-{component}",purpose:"Migrate specific component to new implementation",dependsOn:["{migration}-new-implementation"],ownsPatterns:["src/{component}/**/*.ts"],readsPatterns:["src/{new}/*.ts","src/{old}/*.ts"],planOutline:"Update imports \u2192 Replace function calls \u2192 Update tests \u2192 Verify behavior"},{namePattern:"{migration}-deprecate-old",purpose:"Mark old implementation as deprecated",dependsOn:["{migration}-migrate-*"],ownsPatterns:["src/{old}/*.ts"],readsPatterns:[],planOutline:"Add deprecation notices \u2192 Update docs \u2192 Plan removal timeline"}],guidelines:["Create new before removing old","Migrate in small, independent chunks (by component/module)","Each migration stream should be independently testable","Keep deprecation as the final step","Ensure each stream leaves the codebase in a working state"]},Hr={id:"tutorial",name:"Tutorial Series",description:"Progressive tutorial series from basics to advanced",keywords:["tutorial","guide","example","walkthrough","getting started","beginner","advanced"],patterns:["Multiple tutorial steps","Progressive complexity","Beginner \u2192 Intermediate \u2192 Advanced","Examples with documentation"],streamStructure:[{namePattern:"tutorial-{level}-{topic}",purpose:"Create tutorial for specific level and topic",dependsOn:["tutorial-{previous-level}-*"],ownsPatterns:["docs/tutorials/{level}-{topic}.md","examples/{topic}/**/*"],readsPatterns:["src/**/*.ts","docs/tutorials/{previous}*.md"],planOutline:"Define learning objectives \u2192 Write tutorial \u2192 Create working example \u2192 Add exercises"}],guidelines:["Order by prerequisite knowledge: basics \u2192 intermediate \u2192 advanced","Each tutorial should be self-contained but build on previous concepts","Include working code examples","Beginner tutorials can run in parallel if they cover different topics","Advanced tutorials depend on relevant beginner/intermediate tutorials"]},zr={id:"api-reference",name:"API Reference",description:"Comprehensive API documentation for modules, classes, and functions",keywords:["api","reference","documentation","modules","classes","functions","methods"],patterns:["Documenting multiple modules","Class/function reference","Method documentation","Parameter and return type docs"],streamStructure:[{namePattern:"api-{module}-reference",purpose:"Create API reference for a specific module",dependsOn:[],ownsPatterns:["docs/api/{module}.md"],readsPatterns:["src/{module}/**/*.ts"],planOutline:"Extract types/interfaces \u2192 Document functions \u2192 Add examples \u2192 Cross-link related APIs"}],guidelines:["Split by module or logical grouping","All API reference streams can run in parallel","Include type signatures and examples","Cross-reference related APIs","Keep each stream to 1-2 related modules"]},Br=[Nr,Wr,Ur,Hr,zr]});function qr(e,n,t){if(t.issues.length===0)return null;let s=t.issues.some(l=>l.severity==="error"),o=t.issues.some(l=>l.severity==="warning"),r=`${n.name??e} ${n.plan??""}`,i=re(r),a=null;if(i){let l=e.replace(/-/g,"_");a=ve(i,{featureName:l})}let c="";s?c=`Stream "${e}" has critical issues:
|
|
147
|
+
`),f={name:`${o.name} (Root Cause Fix #${a})`,deps:o.deps??[],owns:o.owns??[],reads:o.reads??[],plan:d,setup:o.setup??[],verify:o.verify??[],status:"pending",attempts:0,parentStreamId:s};return{fixStreamId:c,fixStream:f,analysis:{category:"runtime_error",suggestion:n.reason}}}var Ln,tt=y(()=>{"use strict";Qe();et();Ln=3});import{randomUUID as Ar}from"crypto";function jr(e,n,t){let s=100,o=e.filter(r=>r.status==="failed").length;return s-=o*20,s-=t*10,s+=n*5,Math.max(0,Math.min(100,s))}function qn(e,n,t){let s=e.runId??Ar(),o=new Date().toISOString(),r=[];for(let g of n)r.push(...g.streams);let i=new Set;for(let g of n)if(g.fixStreamsGenerated)for(let x of g.fixStreamsGenerated)i.add(x);for(let[g,x]of Object.entries(e.streams))x.parentStreamId&&i.add(g);let a=new Map;for(let g of r)a.set(g.id,g);let c=[...a.values()].map(g=>({id:g.id,name:g.name,status:g.status,tokensUsed:g.tokensUsed,executionTimeMs:g.executionTimeMs,selfHealCount:i.has(g.id)?1:0,errorCategory:g.errorDetail?.category,errorMessage:g.error,errorSuggestion:g.errorDetail?.suggestion,errorRetryable:g.errorDetail?.retryable,errorSelfHealable:g.errorDetail?.selfHealable,provider:g.provider,model:g.model,filesChanged:g.filesChanged})),l=0,u=0,d={};for(let g of r)if(g.tokensUsed){l+=g.tokensUsed.input,u+=g.tokensUsed.output;let x=g.provider??"unknown";d[x]||(d[x]={input:0,output:0}),d[x].input+=g.tokensUsed.input,d[x].output+=g.tokensUsed.output}let f=0,p=0;for(let g of n)g.timing&&(f+=g.timing.parallelMs,p+=g.timing.sequentialMs);let m=new Set;for(let g of r)if(g.filesChanged)for(let x of g.filesChanged)m.add(x);let h=0;for(let g of n)g.streams.length>0&&g.streams.every(x=>x.status==="complete")&&h++;let w={};for(let g of r)if(g.status==="failed"&&g.errorDetail?.category){let x=g.errorDetail.category;w[x]=(w[x]??0)+1}let k,b=r.filter(g=>g.status==="failed").map(g=>g.id);if(b.length>=2){let g=ye(e,b);g&&(k=g)}let $=i.size,S=jr(r,h,$);return{runId:s,timestamp:o,feature:e.feature,planQualityScore:S,streamResults:c,waveEfficiency:{parallelMs:f,sequentialMs:p,timeSavedMs:Math.max(0,p-f)},autoPlanAccuracy:t?.autoPlanEdits!==void 0?{editsBeforeApproval:t.autoPlanEdits}:void 0,tokenUsage:{totalInput:l,totalOutput:u,byProvider:d},fileChangeImpact:{filesCreated:0,filesModified:m.size,totalFilesChanged:m.size},failurePatterns:w,failureCorrelation:k,totalWaves:n.length,totalStreams:a.size}}async function Yn(e,n){let{mkdir:t,writeFile:s}=await import("fs/promises"),{join:o}=await import("path"),r=o(e,".orchex","reports");await t(r,{recursive:!0});let i=o(r,`${n.runId}.json`);return await s(i,JSON.stringify(n,null,2),"utf-8"),i}var Kn=y(()=>{"use strict";tt()});import{formatDuration as Fr}from"../types.js";function Vn(e,n){let t=[];if(e.waveEfficiency.timeSavedMs>0&&e.totalStreams>1){let r=Fr(e.waveEfficiency.timeSavedMs),i=e.waveEfficiency.sequentialMs>0?Math.round(e.waveEfficiency.timeSavedMs/e.waveEfficiency.sequentialMs*100):0;t.push(`${e.totalStreams} streams ran in parallel across ${e.totalWaves} wave(s), saving ${r} (${i}%).`)}else e.totalStreams>1&&t.push(`${e.totalStreams} streams executed across ${e.totalWaves} wave(s).`);let s=Object.entries(e.failurePatterns);if(s.length>0){s.sort((c,l)=>l[1]-c[1]);let[r,i]=s[0],a=s.reduce((c,[,l])=>c+l,0);r==="type_error"?t.push(`${r} was the most common failure (${i}/${a}). Consider adding a types-only stream first.`):t.push(`${r} was the most common failure (${i}/${a}).`)}if(n&&n.length>0){let r=n.reduce((a,c)=>a+c.planQualityScore,0)/n.length,i=e.planQualityScore-r;i>10?t.push(`Plan quality improved from ${Math.round(r)} to ${e.planQualityScore} \u2014 orchex is learning your patterns.`):i<-10?t.push(`Plan quality dropped from ${Math.round(r)} to ${e.planQualityScore}. Review the failure patterns above.`):t.push(`Plan quality score: ${e.planQualityScore}/100 (consistent with previous runs at ~${Math.round(r)}).`)}else t.push(`Plan quality score: ${e.planQualityScore}/100.`);let o=e.tokenUsage.totalInput+e.tokenUsage.totalOutput;if(o>0&&t.length<3){let r=Object.keys(e.tokenUsage.byProvider);r.length>1&&t.push(`Used ${r.length} providers: ${r.join(", ")} \u2014 total ${o.toLocaleString()} tokens.`)}return t.slice(0,3)}var Gn=y(()=>{"use strict"});import*as O from"fs/promises";import*as W from"path";async function Xn(e){let n=W.join(e,".orchex");try{await O.access(n)}catch{return!0}try{return await O.access(W.join(n,Jn)),!1}catch{}try{let t=W.join(n,"archive");if((await O.readdir(t)).length>0)return!1}catch{}try{let t=W.join(n,"reports");if((await O.readdir(t)).some(o=>o.endsWith(".json")))return!1}catch{}try{let t=W.join(n,"learn","events.jsonl");if((await O.stat(t)).size>0)return!1}catch{}return!0}async function Qn(e){let n=W.join(e,".orchex");await O.mkdir(n,{recursive:!0}),await O.writeFile(W.join(n,Jn),new Date().toISOString(),"utf-8")}function Zn(){return["Welcome to orchex! This looks like your first time using orchex in this project.","","Try a quick demo to see orchestration in action:",' orchex run "Add a hello world API endpoint to this project"',"","Or use the MCP auto tool in your AI assistant:",' auto({ prompt: "Add a health check endpoint" })',"","Orchex will generate a plan, show you a preview, and execute in parallel.","Learn more: https://orchex.dev/docs/user-guide/quickstart"].join(`
|
|
148
|
+
`)}var Jn,es=y(()=>{"use strict";Jn=".first-run-complete"});import*as oe from"fs/promises";import*as R from"path";async function ns(e,n){if(!n.confirm)throw new Error("Reset learning requires --confirm flag. This permanently deletes learning data.");let t=[],s=R.join(e,".orchex","learn"),o=R.join(e,".orchex","reports");n.patternsOnly?await xe(R.join(s,"patterns.json"),t):n.reportsOnly?await ts(o,t,".json"):(await xe(R.join(s,"thresholds.json"),t),await xe(R.join(s,"events.jsonl"),t),await xe(R.join(s,"patterns.json"),t),await ts(o,t,".json"));let r=n.patternsOnly?"patterns":n.reportsOnly?"reports":"all learning data";return{deleted:t,totalDeleted:t.length,message:t.length>0?`Reset ${r}: ${t.length} file(s) deleted.`:`No ${r} found to delete.`}}async function xe(e,n){try{await oe.unlink(e),n.push(R.basename(e))}catch(t){if(t.code!=="ENOENT")throw t}}async function ts(e,n,t){try{let s=await oe.readdir(e);for(let o of s)t&&!o.endsWith(t)||(await oe.unlink(R.join(e,o)),n.push(o))}catch(s){if(s.code!=="ENOENT")throw s}}var ss=y(()=>{"use strict"});import{createLogger as Dr}from"../logging.js";function os(e){let{streamResults:n,iterationNumber:t,maxIterations:s,intent:o}=e;if(t>=s){let d=n.filter(f=>f.status==="failed"||!f.verifyPassed).length;return{complete:!0,reason:`Reached max iterations (${s})${d>0?` with ${d} unresolved failure(s)`:""}`,failureSummary:d>0?n.filter(f=>f.status==="failed").map(f=>`${f.id}: ${f.error}`).join("; "):void 0}}let r=n.filter(d=>d.status==="failed"),i=n.filter(d=>d.status==="complete"&&!d.verifyPassed);if(r.length===0&&i.length===0)return{complete:!0,reason:`All ${n.length} stream(s) completed and verified successfully`};let c=[];for(let d of r)c.push(`Stream "${d.id}" failed: ${d.error??"unknown error"}`);for(let d of i)c.push(`Stream "${d.id}" verify failed: ${d.verifyError??"verification error"}`);let l=c.join("; "),u=`Fix the following issues from the previous attempt to "${o}": ${l}`;return Lr.info({iteration:t,failed:r.length,verifyFailed:i.length},"iteration_incomplete"),{complete:!1,reason:`${r.length} stream(s) failed, ${i.length} verification(s) failed`,nextIntent:u,failureSummary:l}}var Lr,rs=y(()=>{"use strict";Lr=Dr("iteration-evaluator")});function re(e){let n=e.toLowerCase(),t=null;for(let s of Br){let o=0;for(let r of s.keywords)n.includes(r.toLowerCase())&&(o+=2);for(let r of s.patterns){let i=r.toLowerCase().split(/[\s/,]+/).filter(c=>c.length>2);i.filter(c=>n.includes(c)).length>=i.length/2&&(o+=1)}o>0&&(!t||o>t.score)&&(t={template:s,score:o})}return t&&t.score>=3?t.template:null}function ve(e,n){let t=[];if(e.id==="documentation-set"){let s=n.topics||[];for(let o of s)t.push({name:`docs-${o}`,deps:[],owns:[`docs/${o}/**/*.md`],reads:["src/**/*.ts","README.md"],plan:`Research ${o} implementation \u2192 Write documentation \u2192 Add examples \u2192 Review completeness`})}else if(e.id==="code-feature"){let s=n.featureName;t.push({name:`${s}-types`,deps:[],owns:[`src/types/${s}.ts`],reads:["src/types.ts"],plan:"Analyze requirements \u2192 Define types \u2192 Add validation schemas \u2192 Export types"},{name:`${s}-core`,deps:[`${s}-types`],owns:[`src/${s}/*.ts`],reads:[`src/types/${s}.ts`,"src/utils/*.ts"],plan:"Implement core logic \u2192 Add error handling \u2192 Integrate with existing systems"},{name:`${s}-tests`,deps:[`${s}-core`],owns:[`tests/${s}.test.ts`],reads:[`src/${s}/*.ts`],plan:"Write unit tests \u2192 Add integration tests \u2192 Test edge cases \u2192 Verify coverage"},{name:`${s}-docs`,deps:[`${s}-core`],owns:[`docs/${s}/*.md`],reads:[`src/${s}/*.ts`],plan:"Document API \u2192 Add usage examples \u2192 Write integration guide"})}else if(e.id==="migration"){let s=n.featureName,o=n.components||[];t.push({name:`${s}-new-implementation`,deps:[],owns:[`src/${s}-new/*.ts`],reads:[`src/${s}-old/*.ts`],plan:"Implement new version \u2192 Match old API \u2192 Add compatibility layer"});for(let r of o)t.push({name:`${s}-migrate-${r}`,deps:[`${s}-new-implementation`],owns:[`src/${r}/**/*.ts`],reads:[`src/${s}-new/*.ts`,`src/${s}-old/*.ts`],plan:"Update imports \u2192 Replace function calls \u2192 Update tests \u2192 Verify behavior"});t.push({name:`${s}-deprecate-old`,deps:o.map(r=>`${s}-migrate-${r}`),owns:[`src/${s}-old/*.ts`],reads:[],plan:"Add deprecation notices \u2192 Update docs \u2192 Plan removal timeline"})}else if(e.id==="tutorial"){let s=n.topics||[];for(let o of s)t.push({name:`tutorial-${o}`,deps:[],owns:[`docs/tutorials/${o}.md`,`examples/${o}/**/*`],reads:["src/**/*.ts"],plan:"Define learning objectives \u2192 Write tutorial \u2192 Create working example \u2192 Add exercises"})}else if(e.id==="api-reference"){let s=n.modules||[];for(let o of s)t.push({name:`api-${o}-reference`,deps:[],owns:[`docs/api/${o}.md`],reads:[`src/${o}/**/*.ts`],plan:"Extract types/interfaces \u2192 Document functions \u2192 Add examples \u2192 Cross-link related APIs"})}return t}function is(e){let n=e.owns||[],t=e.reads||[];if(n.length>5)return{originalStream:e.name,reason:`Stream owns ${n.length} files, which may be too many for a single stream`,guidance:["Consider grouping related files together","Split by logical component or responsibility","Create dependencies between resulting streams if needed"],suggestedStreams:[]};if(t.length>10)return{originalStream:e.name,reason:`Stream reads ${t.length} files, which may indicate broad scope`,guidance:["Reading many files often means the stream is doing too much","Consider splitting into smaller, focused streams","Each stream should ideally read 3-5 context files"],suggestedStreams:[]};let s=`${e.name} ${e.plan||""}`,o=re(s);return o&&["multiple","all","complete","full","entire"].some(a=>e.name.toLowerCase().includes(a))?{originalStream:e.name,reason:"Stream name suggests broad scope that could be split",template:o,guidance:o.guidelines,suggestedStreams:[]}:null}var Nr,Wr,Ur,Hr,zr,Br,nt=y(()=>{"use strict";Nr={id:"documentation-set",name:"Documentation Set",description:"Multiple documentation files (guides, tutorials, API references) that should be created independently",keywords:["docs","documentation","guide","tutorial","readme","api reference","multiple pages"],patterns:["Multiple .md files in docs/","Creating 3+ documentation files","Tutorial series","API documentation pages"],streamStructure:[{namePattern:"docs-{topic}",purpose:"Create documentation for a specific topic",dependsOn:[],ownsPatterns:["docs/{topic}/**/*.md"],readsPatterns:["src/**/*.ts","README.md"],planOutline:"Research implementation \u2192 Write documentation \u2192 Add examples \u2192 Review completeness"}],guidelines:["Split by logical topic, not file count","Each stream should own 1-3 related doc files","Order dependencies: concepts \u2192 API reference \u2192 tutorials \u2192 advanced guides","Streams can run in parallel if topics are independent","Keep related examples with their topic"]},Wr={id:"code-feature",name:"Code Feature Implementation",description:"Multi-component feature with types, implementation, tests, and documentation",keywords:["feature","implement","add","create","types","tests","integration"],patterns:["Types \u2192 Implementation \u2192 Tests \u2192 Docs","Multiple source files with dependencies","Test files alongside implementation","Integration with existing code"],streamStructure:[{namePattern:"{feature}-types",purpose:"Define interfaces, types, and schemas",dependsOn:[],ownsPatterns:["src/types/{feature}.ts","src/schemas/{feature}.ts"],readsPatterns:["src/types.ts"],planOutline:"Analyze requirements \u2192 Define types \u2192 Add validation schemas \u2192 Export types"},{namePattern:"{feature}-core",purpose:"Core feature implementation",dependsOn:["{feature}-types"],ownsPatterns:["src/{feature}/*.ts"],readsPatterns:["src/types/{feature}.ts","src/utils/*.ts"],planOutline:"Implement core logic \u2192 Add error handling \u2192 Integrate with existing systems"},{namePattern:"{feature}-tests",purpose:"Unit and integration tests",dependsOn:["{feature}-core"],ownsPatterns:["tests/{feature}.test.ts"],readsPatterns:["src/{feature}/*.ts"],planOutline:"Write unit tests \u2192 Add integration tests \u2192 Test edge cases \u2192 Verify coverage"},{namePattern:"{feature}-docs",purpose:"Documentation and examples",dependsOn:["{feature}-core"],ownsPatterns:["docs/{feature}/*.md"],readsPatterns:["src/{feature}/*.ts"],planOutline:"Document API \u2192 Add usage examples \u2192 Write integration guide"}],guidelines:["Always start with types to establish contracts","Core implementation depends on types being defined","Tests and docs can run in parallel after core is complete","Keep streams focused: one stream = one responsibility","If a file has 200+ lines, consider splitting implementation into multiple streams"]},Ur={id:"migration",name:"Migration",description:"Migrating code, data, or structure with backward compatibility",keywords:["migration","migrate","refactor","rename","move","deprecate","backward compatible"],patterns:["From old to new","Rename/move files or functions","Change data structure","Update multiple call sites","Maintain backward compatibility"],streamStructure:[{namePattern:"{migration}-new-implementation",purpose:"Create new implementation alongside old one",dependsOn:[],ownsPatterns:["src/{new}/*.ts"],readsPatterns:["src/{old}/*.ts"],planOutline:"Implement new version \u2192 Match old API \u2192 Add compatibility layer"},{namePattern:"{migration}-migrate-{component}",purpose:"Migrate specific component to new implementation",dependsOn:["{migration}-new-implementation"],ownsPatterns:["src/{component}/**/*.ts"],readsPatterns:["src/{new}/*.ts","src/{old}/*.ts"],planOutline:"Update imports \u2192 Replace function calls \u2192 Update tests \u2192 Verify behavior"},{namePattern:"{migration}-deprecate-old",purpose:"Mark old implementation as deprecated",dependsOn:["{migration}-migrate-*"],ownsPatterns:["src/{old}/*.ts"],readsPatterns:[],planOutline:"Add deprecation notices \u2192 Update docs \u2192 Plan removal timeline"}],guidelines:["Create new before removing old","Migrate in small, independent chunks (by component/module)","Each migration stream should be independently testable","Keep deprecation as the final step","Ensure each stream leaves the codebase in a working state"]},Hr={id:"tutorial",name:"Tutorial Series",description:"Progressive tutorial series from basics to advanced",keywords:["tutorial","guide","example","walkthrough","getting started","beginner","advanced"],patterns:["Multiple tutorial steps","Progressive complexity","Beginner \u2192 Intermediate \u2192 Advanced","Examples with documentation"],streamStructure:[{namePattern:"tutorial-{level}-{topic}",purpose:"Create tutorial for specific level and topic",dependsOn:["tutorial-{previous-level}-*"],ownsPatterns:["docs/tutorials/{level}-{topic}.md","examples/{topic}/**/*"],readsPatterns:["src/**/*.ts","docs/tutorials/{previous}*.md"],planOutline:"Define learning objectives \u2192 Write tutorial \u2192 Create working example \u2192 Add exercises"}],guidelines:["Order by prerequisite knowledge: basics \u2192 intermediate \u2192 advanced","Each tutorial should be self-contained but build on previous concepts","Include working code examples","Beginner tutorials can run in parallel if they cover different topics","Advanced tutorials depend on relevant beginner/intermediate tutorials"]},zr={id:"api-reference",name:"API Reference",description:"Comprehensive API documentation for modules, classes, and functions",keywords:["api","reference","documentation","modules","classes","functions","methods"],patterns:["Documenting multiple modules","Class/function reference","Method documentation","Parameter and return type docs"],streamStructure:[{namePattern:"api-{module}-reference",purpose:"Create API reference for a specific module",dependsOn:[],ownsPatterns:["docs/api/{module}.md"],readsPatterns:["src/{module}/**/*.ts"],planOutline:"Extract types/interfaces \u2192 Document functions \u2192 Add examples \u2192 Cross-link related APIs"}],guidelines:["Split by module or logical grouping","All API reference streams can run in parallel","Include type signatures and examples","Cross-reference related APIs","Keep each stream to 1-2 related modules"]},Br=[Nr,Wr,Ur,Hr,zr]});function qr(e,n,t){if(t.issues.length===0)return null;let s=t.issues.some(l=>l.severity==="error"),o=t.issues.some(l=>l.severity==="warning"),r=`${n.name??e} ${n.plan??""}`,i=re(r),a=null;if(i){let l=e.replace(/-/g,"_");a=ve(i,{featureName:l})}let c="";s?c=`Stream "${e}" has critical issues:
|
|
149
149
|
`:o?c=`Stream "${e}" has potential issues:
|
|
150
150
|
`:c=`Stream "${e}" has suggestions:
|
|
151
151
|
`;for(let l of t.issues){let u=l.severity==="error"?"\u274C":l.severity==="warning"?"\u26A0\uFE0F":"\u2139\uFE0F";c+=` ${u} ${l.message}
|
|
@@ -168,10 +168,10 @@ ${g.plan}`),c.set(S,u)}for(let S of f)p.delete(S);let k=new Set(l);for(let S of
|
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
|
-
`),verify:h,setup:$.length>0?$:void 0,timeoutMs:b},a.push(`Merged [${l.join(", ")}] \u2192 ${u} (shared files: ${[...f].filter(S=>(n.get(S)??[]).length>1).join(", ")})`)}for(let[l,u]of Object.entries(i)){let d=u.deps??[],f=[...new Set(d.map(p=>c.get(p)??p))].filter(p=>p!==l);u.deps=f}return{streams:i,merges:a}}var ds=y(()=>{"use strict"});function fs(e){return e.isTestGeneration?{provider:void 0,confidence:.3,reason:"Test generation works well with any provider \u2014 use your default."}:e.isStructuralChange&&(e.totalOwnedLines>500||e.fileCount>4)?{provider:"anthropic",confidence:.7,reason:`Structural edits across ${e.fileCount} files (${e.totalOwnedLines} lines) \u2014 Claude handles complex multi-file reasoning best.`}:!e.isStructuralChange&&e.totalOwnedLines<200&&e.fileCount<=2?{provider:"openai",model:"gpt-4.1-mini",confidence:.6,reason:`Simple transform (${e.totalOwnedLines} lines, ${e.fileCount} files) \u2014 GPT-4.1-mini is cost-effective for small tasks.`}:e.isStructuralChange?{provider:"anthropic",confidence:.5,reason:`Structural changes across ${e.fileCount} files \u2014 Claude recommended for refactoring tasks.`}:{provider:void 0,confidence:.2,reason:"No strong provider preference for this task type \u2014 use your configured default."}}function ps(e,n,t){let s=e.toLowerCase(),o=s.includes("test")||s.includes("spec")||n.some(a=>a.includes(".test.")||a.includes(".spec.")||a.startsWith("tests/")),i=["refactor","restructure","reorganize","migrate","rewrite","split","merge","move","rename","extract","inline","new module","new class","new service","new component"].some(a=>s.includes(a));return{totalOwnedLines:t,isStructuralChange:i,isTestGeneration:o,fileCount:n.length}}var ms=y(()=>{"use strict"});import*as V from"fs/promises";import*as st from"path";import*as Se from"yaml";import{exec as Yr}from"child_process";import{promisify as Kr}from"util";async function gs(e,n){let t=st.join(e,".orchex","active","manifest.yaml"),s=await V.readFile(t,"utf-8"),o=Se.parse(s),r=new Set(n);for(let[i,a]of Object.entries(o.streams))a.status==="pending"&&(r.has(i)||(o.streams[i].status="skipped"));await V.writeFile(t,Se.stringify(o,{indent:2,lineWidth:0}),"utf-8")}async function ws(e,n,t){let s=[],o=[];for(let r of t){let i=st.join(e,r);try{let{stdout:a}=await hs(`git ls-files "${r}"`,{cwd:e});if(a.trim())await hs(`git checkout HEAD -- "${r}"`,{cwd:e}),s.push(r);else try{await V.unlink(i),s.push(r)}catch(c){c.code!=="ENOENT"&&o.push(`Failed to delete ${r}: ${c.message}`)}}catch(a){if(a.message?.includes("did not match any"))continue;o.push(`Failed to rollback ${r}: ${a.message}`)}}return{streamId:n,reverted:s,errors:o}}var hs,ys=y(()=>{"use strict";hs=Kr(Yr)});function ot(e){if(ke[e])return ke[e];let n=e.toLowerCase();for(let[t,s]of Object.entries(ke))if(t!=="default"&&n.includes(t.split("-").slice(0,2).join("-")))return s;return ke.default}function xs(e,n,t,s){let o=ot(t),r=e/1e3*o.input,i=n/1e3*o.output,a=r+i,c;s&&s>0&&(c=s/1e3*o.input*Vr);let l=a-(c??0);return{inputTokens:e,outputTokens:n,inputCost:r,outputCost:i,totalCost:a,cacheHitTokens:s,cacheDiscount:c,finalCost:l,model:t}}function vs(e,n,t=.3){let s=Math.ceil(e*t);return xs(e,s,n)}var ke,Vr,rt=y(()=>{"use strict";ke={"claude-opus-4-5-20251101":{input:.015,output:.075},"claude-sonnet-4-5-20250929":{input:.003,output:.015},"claude-sonnet-4-20250514":{input:.003,output:.015},"claude-3-5-sonnet-20241022":{input:.003,output:.015},"claude-3-opus-20240229":{input:.015,output:.075},"claude-3-haiku-20240307":{input:25e-5,output:.00125},"gpt-4.5-turbo":{input:.005,output:.015},"gpt-4-turbo":{input:.01,output:.03},"gpt-4-turbo-preview":{input:.01,output:.03},"gpt-4o":{input:.005,output:.015},"gpt-4o-mini":{input:15e-5,output:6e-4},"o1-preview":{input:.015,output:.06},"o1-mini":{input:.003,output:.012},"o3-mini":{input:.0011,output:.0044},"gpt-3.5-turbo":{input:5e-4,output:.0015},"gemini-2.5-pro":{input:.00125,output:.01},"gemini-2.0-flash":{input:1e-4,output:4e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4},"gemini-pro":{input:125e-6,output:375e-6},"deepseek-chat":{input:28e-5,output:42e-5},"deepseek-coder":{input:28e-5,output:42e-5},"deepseek-reasoner":{input:55e-5,output:.00219},"kimi-k2-0905-preview":{input:6e-4,output:.0025},"kimi-k2-turbo-preview":{input:6e-4,output:.0025},"kimi-latest":{input:6e-4,output:.0025},"moonshot-v1-8k":{input:.00168,output:.00168},"moonshot-v1-32k":{input:.0024,output:.0024},"moonshot-v1-128k":{input:.012,output:.012},"llama3.3:70b":{input:0,output:0},"llama3.2:latest":{input:0,output:0},"mistral:latest":{input:0,output:0},default:{input:.003,output:.015}},Vr=.9});import*as ks from"fs";import*as it from"path";import{createLogger as Gr}from"../logging.js";function Jr(e){let n=[...e.owns,...e.reads??[]],t=e.name.toLowerCase(),s=(e.plan??"").toLowerCase();return n.some(o=>o.match(/\.(md|mdx|txt|rst)$/))||t.includes("doc")||t.includes("readme")?"docs":n.some(o=>o.includes(".test.")||o.includes(".spec.")||o.includes("__tests__"))||t.includes("test")?"test":n.some(o=>o.includes("migration"))||t.includes("migrat")?"migration":e.owns.length>=3||(e.estimatedLines??0)>500||s.includes("refactor")||s.includes("restructur")?"complex-code":"simple-code"}function Xr(e,n){switch(e){case"docs":return{provider:"deepseek",model:"deepseek-chat",reasoning:`Routed documentation stream "${n.name}" to cheapest provider (DeepSeek)`};case"test":return{provider:"openai",model:"gpt-4o",reasoning:`Routed test stream "${n.name}" to mid-tier provider (GPT-4o)`};case"migration":return{provider:"google",model:"gemini-2.5-pro",reasoning:`Routed migration stream "${n.name}" to cost-effective provider (Gemini)`};case"complex-code":return{provider:"anthropic",model:"claude-sonnet-4-5-20250929",reasoning:`Routed complex code stream "${n.name}" (${n.owns.length} files${(n.estimatedLines??0)>500?", large file edits":""}) to premium provider (Claude)`};default:return{provider:"openai",model:"gpt-4o",reasoning:`Routed simple code stream "${n.name}" to balanced provider (GPT-4o)`}}}function Qr(e){switch(e){case"docs":return["gemini","openai","anthropic"];case"test":return["anthropic","gemini","deepseek"];case"migration":return["openai","anthropic","deepseek"];case"complex-code":return["openai","gemini","deepseek"];default:return["anthropic","gemini","deepseek"]}}function $s(e,n,t){let s=t?.availableProviders,o=t?.registryModels,r=(c,l)=>o?.[c]?.length?o[c].includes(l)?l:o[c][0]:l;if(n.overrides?.[e.id]){let c=n.overrides[e.id];return{provider:c.provider,model:c.model,reasoning:"User override"}}if(n.defaultProvider){let c=n.defaultModel??Ss[n.defaultProvider]??n.defaultProvider,l=r(n.defaultProvider,c);return{provider:n.defaultProvider,model:l,reasoning:"User default provider preference"}}let i=Jr(e),a=Xr(i,e);if(s&&!s.has(a.provider)){let c=Qr(i);for(let l of c)if(s.has(l)){let u=r(l,Ss[l]??l);return{provider:l,model:u,reasoning:`${a.reasoning} \u2014 ${a.provider} not available, fell back to ${l}`}}}return a.model=r(a.provider,a.model),a}function bs(e){let n=e??it.join(process.env.HOME??"",".orchex"),t=it.join(n,"config.json");try{let s=ks.readFileSync(t,"utf-8"),o=JSON.parse(s);return{defaultProvider:o.routing?.defaultProvider,defaultModel:o.routing?.defaultModel,overrides:o.routing?.overrides}}catch{return{}}}var Ma,Ss,Cs=y(()=>{"use strict";rt();Ma=Gr("smart-router"),Ss={anthropic:"claude-sonnet-4-5-20250929",openai:"gpt-4.1",google:"gemini-2.5-pro",deepseek:"deepseek-chat",kimi:"kimi-k2-0905-preview",ollama:"llama3.3:70b"}});import*as G from"fs/promises";import*as $e from"path";function Es(e){let n=e.streamResults.filter(r=>r.status==="complete").length,t=e.streamResults.filter(r=>r.status==="failed").length,s=e.streamResults.filter(r=>r.status==="skipped").length,o=e.streamResults.reduce((r,i)=>r+(i.executionTimeMs??0),0);return{id:e.runId,feature:e.feature,timestamp:e.timestamp,success:e.planQualityScore>=80,totalStreams:e.totalStreams,completedStreams:n,failedStreams:t,skippedStreams:s,totalWaves:e.totalWaves,executionTimeMs:o,streams:e.streamResults.map(r=>({id:r.id,name:r.name,status:r.status,wave:0,filesOwned:0,executionTimeMs:r.executionTimeMs??0,tokensUsed:r.tokensUsed??{input:0,output:0},errorCategory:r.errorCategory}))}}function Ps(e){if(e.length<Zr)return[];let n=[],t=[ei,ti,ni,si,oi,ri,ii];for(let s of t){let o=s(e);o&&n.push(o)}return n}function ei(e){let n={low:{total:0,success:0,ids:[]},mid:{total:0,success:0,ids:[]},high:{total:0,success:0,ids:[]}};for(let u of e){let d=u.totalStreams<=5?"low":u.totalStreams<=8?"mid":"high";n[d].total++,u.success&&n[d].success++,n[d].ids.push(u.id)}if(n.low.total<3&&n.mid.total<3||n.high.total<2&&n.mid.total<2)return null;let t=n.low.total>0?n.low.success/n.low.total:0,s=n.high.total>0?n.high.success/n.high.total:0,o=n.mid.total>0?n.mid.success/n.mid.total:0,r=Math.max(t,o),i=Math.min(t,o,s);if(r-i<.2)return null;let a=t>=o?"low (1-5 streams)":"mid (6-8 streams)",c=Math.max(t,o),l=[...n.low.ids,...n.mid.ids,...n.high.ids];return{type:j.STREAM_COUNT_SWEET_SPOT,description:`Plans with ${a} succeed ${(c*100).toFixed(0)}% of the time`,confidence:Math.min(e.length/20,1),recommendation:`Prefer ${a.includes("low")?"3-5":"6-8"} streams per plan. Larger plans (${n.high.total>0?`>8 streams: ${(s*100).toFixed(0)}% success`:"not enough data"}) tend to fail more.`,evidence:{reportIds:l,metric:"streamCount",values:{"low_1-5_rate":`${(t*100).toFixed(0)}%`,"mid_6-8_rate":`${(o*100).toFixed(0)}%`,"high_9+_rate":`${(s*100).toFixed(0)}%`,low_count:n.low.total,high_count:n.high.total}}}}function ti(e){let n=0,t=0,s=0,o=0,r=[];for(let c of e){for(let l of c.streams)l.filesOwned<=4?(t++,l.status==="complete"&&n++):(o++,l.status==="complete"&&s++);r.push(c.id)}if(t<5||o<3)return null;let i=n/t,a=s/o;return i-a<.15?null:{type:j.FILE_PER_STREAM,description:`Streams with <=4 files succeed ${(i*100).toFixed(0)}%, streams with >4 files succeed ${(a*100).toFixed(0)}%`,confidence:Math.min((t+o)/30,1),recommendation:"Keep streams to 4 or fewer owned files. Split larger streams into focused units.",evidence:{reportIds:r,metric:"filesPerStream",values:{low_files_success_rate:`${(i*100).toFixed(0)}%`,high_files_success_rate:`${(a*100).toFixed(0)}%`,low_files_count:t,high_files_count:o}}}}function ni(e){let n={},t=0,s=[];for(let c of e){for(let l of c.streams)l.status==="failed"&&l.errorCategory&&(n[l.errorCategory]=(n[l.errorCategory]||0)+1,t++);c.failedStreams>0&&s.push(c.id)}if(t<3)return null;let o=Object.entries(n).sort((c,l)=>l[1]-c[1]),[r,i]=o[0],a=i/t*100;return{type:j.SELF_HEAL_PATTERN,description:`${r} errors are the most common failure (${a.toFixed(0)}% of all errors)`,confidence:Math.min(t/15,1),recommendation:`Focus on preventing ${r} errors. Consider adding targeted verify commands or adjusting prompts to avoid this error type.`,evidence:{reportIds:s,metric:"errorCategories",values:Object.fromEntries(o.map(([c,l])=>[c,`${l} (${(l/t*100).toFixed(0)}%)`]))}}}function si(e){let n=0,t=0,s=0,o=0,r=[];for(let c of e){let l=new Set(c.streams.filter(u=>!u.name.toLowerCase().includes("test")).map(u=>u.id));for(let u of c.streams){if(!u.name.toLowerCase().includes("test"))continue;u.deps&&u.deps.some(p=>l.has(p))?(n++,u.status==="complete"&&t++):(s++,u.status==="complete"&&o++)}r.push(c.id)}if(n<3||s<3)return null;let i=t/n,a=o/s;return i-a<.15?null:{type:j.DEPENDENCY_ORDERING,description:`Test streams with impl dependencies succeed ${(i*100).toFixed(0)}%, without: ${(a*100).toFixed(0)}%`,confidence:Math.min((n+s)/15,1),recommendation:"Always add implementation streams as dependencies of test streams. Place tests in later waves.",evidence:{reportIds:r,metric:"dependencyOrdering",values:{with_deps_rate:`${(i*100).toFixed(0)}%`,without_deps_rate:`${(a*100).toFixed(0)}%`,with_deps_count:n,without_deps_count:s}}}}function oi(e){let n={low:{total:0,success:0},high:{total:0,success:0}},t=[];for(let c of e){let l=c.totalWaves<=3?"low":"high";n[l].total++,c.success&&n[l].success++,t.push(c.id)}if(n.low.total<3||n.high.total<3)return null;let s=n.low.success/n.low.total,o=n.high.success/n.high.total;if(Math.abs(s-o)<.15)return null;let r=s>=o?"low":"high",i=r==="low"?s:o,a=r==="low"?"1-3":"4+";return{type:j.WAVE_EFFICIENCY,description:`Orchestrations with ${a} waves succeed ${(i*100).toFixed(0)}%`,confidence:Math.min(e.length/15,1),recommendation:`Prefer ${a} waves for best results. ${r==="low"?"Keep dependency depth shallow.":"More waves indicates better dependency structure."}`,evidence:{reportIds:t,metric:"waveCount",values:{"low_1-3_rate":`${(s*100).toFixed(0)}%`,"high_4+_rate":`${(o*100).toFixed(0)}%`,low_count:n.low.total,high_count:n.high.total}}}}function ri(e){let n={},t=[];for(let c of e){for(let l of c.streams){let u=l.provider??c.provider??"unknown";u!=="unknown"&&(n[u]||(n[u]={total:0,success:0}),n[u].total++,l.status==="complete"&&n[u].success++)}t.push(c.id)}let s=Object.entries(n).filter(([c,l])=>l.total>=3);if(s.length<2)return null;let o=s.map(([c,l])=>({name:c,rate:l.success/l.total,total:l.total})),r=o.sort((c,l)=>l.rate-c.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.1?null:{type:j.PROVIDER_PERFORMANCE,description:`${i.name} succeeds ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(s.reduce((c,[l,u])=>c+u.total,0)/30,1),recommendation:`${i.name} performs best in your project. Consider using it as the default provider.`,evidence:{reportIds:t,metric:"providerPerformance",values:Object.fromEntries(o.map(c=>[c.name,`${(c.rate*100).toFixed(0)}% (n=${c.total})`]))}}}function ii(e){let n={morning:{total:0,success:0},afternoon:{total:0,success:0},evening:{total:0,success:0},night:{total:0,success:0}},t=[];for(let c of e){let l=new Date(c.timestamp).getHours(),u=l<6?"night":l<12?"morning":l<18?"afternoon":"evening";n[u].total++,c.success&&n[u].success++,t.push(c.id)}let s=Object.entries(n).filter(([c,l])=>l.total>=3);if(s.length<2)return null;let o=s.map(([c,l])=>({name:c,rate:l.success/l.total,total:l.total})),r=o.sort((c,l)=>l.rate-c.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.2?null:{type:j.TIME_OF_DAY,description:`${i.name} runs succeed ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(e.length/20,1),recommendation:`Orchestrations during ${i.name} hours have the highest success rate. This may correlate with API rate limit availability.`,evidence:{reportIds:t,metric:"timeOfDay",values:Object.fromEntries(o.map(c=>[c.name,`${(c.rate*100).toFixed(0)}% (n=${c.total})`]))}}}function Os(e){if(e.length===0)return"No significant patterns detected yet. Need more execution history.";let n=["=== Detected Patterns ===",""];for(let t of e){let s=t.confidence>=.7?"HIGH":t.confidence>=.4?"MEDIUM":"LOW";n.push(`[${s}] ${t.description}`),n.push(` Recommendation: ${t.recommendation}`),n.push("")}return n.join(`
|
|
171
|
+
`),verify:h,setup:$.length>0?$:void 0,timeoutMs:b},a.push(`Merged [${l.join(", ")}] \u2192 ${u} (shared files: ${[...f].filter(S=>(n.get(S)??[]).length>1).join(", ")})`)}for(let[l,u]of Object.entries(i)){let d=u.deps??[],f=[...new Set(d.map(p=>c.get(p)??p))].filter(p=>p!==l);u.deps=f}return{streams:i,merges:a}}var ds=y(()=>{"use strict"});function fs(e){return e.isTestGeneration?{provider:void 0,confidence:.3,reason:"Test generation works well with any provider \u2014 use your default."}:e.isStructuralChange&&(e.totalOwnedLines>500||e.fileCount>4)?{provider:"anthropic",confidence:.7,reason:`Structural edits across ${e.fileCount} files (${e.totalOwnedLines} lines) \u2014 Claude handles complex multi-file reasoning best.`}:!e.isStructuralChange&&e.totalOwnedLines<200&&e.fileCount<=2?{provider:"openai",model:"gpt-4.1-mini",confidence:.6,reason:`Simple transform (${e.totalOwnedLines} lines, ${e.fileCount} files) \u2014 GPT-4.1-mini is cost-effective for small tasks.`}:e.isStructuralChange?{provider:"anthropic",confidence:.5,reason:`Structural changes across ${e.fileCount} files \u2014 Claude recommended for refactoring tasks.`}:{provider:void 0,confidence:.2,reason:"No strong provider preference for this task type \u2014 use your configured default."}}function ps(e,n,t){let s=e.toLowerCase(),o=s.includes("test")||s.includes("spec")||n.some(a=>a.includes(".test.")||a.includes(".spec.")||a.startsWith("tests/")),i=["refactor","restructure","reorganize","migrate","rewrite","split","merge","move","rename","extract","inline","new module","new class","new service","new component"].some(a=>s.includes(a));return{totalOwnedLines:t,isStructuralChange:i,isTestGeneration:o,fileCount:n.length}}var ms=y(()=>{"use strict"});import*as V from"fs/promises";import*as st from"path";import*as Se from"yaml";import{exec as Yr}from"child_process";import{promisify as Kr}from"util";async function gs(e,n){let t=st.join(e,".orchex","active","manifest.yaml"),s=await V.readFile(t,"utf-8"),o=Se.parse(s),r=new Set(n);for(let[i,a]of Object.entries(o.streams))a.status==="pending"&&(r.has(i)||(o.streams[i].status="skipped"));await V.writeFile(t,Se.stringify(o,{indent:2,lineWidth:0}),"utf-8")}async function ws(e,n,t){let s=[],o=[];for(let r of t){let i=st.join(e,r);try{let{stdout:a}=await hs(`git ls-files "${r}"`,{cwd:e});if(a.trim())await hs(`git checkout HEAD -- "${r}"`,{cwd:e}),s.push(r);else try{await V.unlink(i),s.push(r)}catch(c){c.code!=="ENOENT"&&o.push(`Failed to delete ${r}: ${c.message}`)}}catch(a){if(a.message?.includes("did not match any"))continue;o.push(`Failed to rollback ${r}: ${a.message}`)}}return{streamId:n,reverted:s,errors:o}}var hs,ys=y(()=>{"use strict";hs=Kr(Yr)});function ot(e){if(ke[e])return ke[e];let n=e.toLowerCase();for(let[t,s]of Object.entries(ke))if(t!=="default"&&n.includes(t.split("-").slice(0,2).join("-")))return s;return ke.default}function xs(e,n,t,s){let o=ot(t),r=e/1e3*o.input,i=n/1e3*o.output,a=r+i,c;s&&s>0&&(c=s/1e3*o.input*Vr);let l=a-(c??0);return{inputTokens:e,outputTokens:n,inputCost:r,outputCost:i,totalCost:a,cacheHitTokens:s,cacheDiscount:c,finalCost:l,model:t}}function vs(e,n,t=.3){let s=Math.ceil(e*t);return xs(e,s,n)}var ke,Vr,rt=y(()=>{"use strict";ke={"claude-opus-4-5-20251101":{input:.015,output:.075},"claude-sonnet-4-5-20250929":{input:.003,output:.015},"claude-sonnet-4-20250514":{input:.003,output:.015},"claude-3-5-sonnet-20241022":{input:.003,output:.015},"claude-3-opus-20240229":{input:.015,output:.075},"claude-3-haiku-20240307":{input:25e-5,output:.00125},"gpt-4.5-turbo":{input:.005,output:.015},"gpt-4-turbo":{input:.01,output:.03},"gpt-4-turbo-preview":{input:.01,output:.03},"gpt-4o":{input:.005,output:.015},"gpt-4o-mini":{input:15e-5,output:6e-4},"o1-preview":{input:.015,output:.06},"o1-mini":{input:.003,output:.012},"o3-mini":{input:.0011,output:.0044},"gpt-3.5-turbo":{input:5e-4,output:.0015},"gemini-2.5-pro":{input:.00125,output:.01},"gemini-2.0-flash":{input:1e-4,output:4e-4},"gemini-1.5-pro":{input:.00125,output:.005},"gemini-1.5-flash":{input:75e-6,output:3e-4},"gemini-pro":{input:125e-6,output:375e-6},"deepseek-chat":{input:28e-5,output:42e-5},"deepseek-coder":{input:28e-5,output:42e-5},"deepseek-reasoner":{input:55e-5,output:.00219},"kimi-k2-0905-preview":{input:6e-4,output:.0025},"kimi-k2-turbo-preview":{input:6e-4,output:.0025},"kimi-latest":{input:6e-4,output:.0025},"moonshot-v1-8k":{input:.00168,output:.00168},"moonshot-v1-32k":{input:.0024,output:.0024},"moonshot-v1-128k":{input:.012,output:.012},"llama3.3:70b":{input:0,output:0},"llama3.2:latest":{input:0,output:0},"mistral:latest":{input:0,output:0},default:{input:.003,output:.015}},Vr=.9});import*as ks from"fs";import*as it from"path";import{createLogger as Gr}from"../logging.js";function Jr(e){let n=[...e.owns,...e.reads??[]],t=e.name.toLowerCase(),s=(e.plan??"").toLowerCase();return n.some(o=>o.match(/\.(md|mdx|txt|rst)$/))||t.includes("doc")||t.includes("readme")?"docs":n.some(o=>o.includes(".test.")||o.includes(".spec.")||o.includes("__tests__"))||t.includes("test")?"test":n.some(o=>o.includes("migration"))||t.includes("migrat")?"migration":e.owns.length>=3||(e.estimatedLines??0)>500||s.includes("refactor")||s.includes("restructur")?"complex-code":"simple-code"}function Xr(e,n){switch(e){case"docs":return{provider:"deepseek",model:"deepseek-chat",reasoning:`Routed documentation stream "${n.name}" to cheapest provider (DeepSeek)`};case"test":return{provider:"openai",model:"gpt-4o",reasoning:`Routed test stream "${n.name}" to mid-tier provider (GPT-4o)`};case"migration":return{provider:"google",model:"gemini-2.5-pro",reasoning:`Routed migration stream "${n.name}" to cost-effective provider (Gemini)`};case"complex-code":return{provider:"anthropic",model:"claude-sonnet-4-5-20250929",reasoning:`Routed complex code stream "${n.name}" (${n.owns.length} files${(n.estimatedLines??0)>500?", large file edits":""}) to premium provider (Claude)`};default:return{provider:"openai",model:"gpt-4o",reasoning:`Routed simple code stream "${n.name}" to balanced provider (GPT-4o)`}}}function Qr(e){switch(e){case"docs":return["gemini","openai","anthropic"];case"test":return["anthropic","gemini","deepseek"];case"migration":return["openai","anthropic","deepseek"];case"complex-code":return["openai","gemini","deepseek"];default:return["anthropic","gemini","deepseek"]}}function $s(e,n,t){let s=t?.availableProviders,o=t?.registryModels,r=(c,l)=>o?.[c]?.length?o[c].includes(l)?l:o[c][0]:l;if(n.overrides?.[e.id]){let c=n.overrides[e.id];return{provider:c.provider,model:c.model,reasoning:"User override"}}if(n.defaultProvider){let c=n.defaultModel??Ss[n.defaultProvider]??n.defaultProvider,l=r(n.defaultProvider,c);return{provider:n.defaultProvider,model:l,reasoning:"User default provider preference"}}let i=Jr(e),a=Xr(i,e);if(s&&!s.has(a.provider)){let c=Qr(i);for(let l of c)if(s.has(l)){let u=r(l,Ss[l]??l);return{provider:l,model:u,reasoning:`${a.reasoning} \u2014 ${a.provider} not available, fell back to ${l}`}}}return a.model=r(a.provider,a.model),a}function bs(e){let n=e??it.join(process.env.HOME??"",".orchex"),t=it.join(n,"config.json");try{let s=ks.readFileSync(t,"utf-8"),o=JSON.parse(s);return{defaultProvider:o.routing?.defaultProvider,defaultModel:o.routing?.defaultModel,overrides:o.routing?.overrides}}catch{return{}}}var Ma,Ss,Cs=y(()=>{"use strict";rt();Ma=Gr("smart-router"),Ss={anthropic:"claude-sonnet-4-5-20250929",openai:"gpt-4.1",google:"gemini-2.5-pro",deepseek:"deepseek-chat",kimi:"kimi-k2-0905-preview",ollama:"llama3.3:70b"}});import*as G from"fs/promises";import*as $e from"path";function Es(e){let n=e.streamResults.filter(r=>r.status==="complete").length,t=e.streamResults.filter(r=>r.status==="failed").length,s=e.streamResults.filter(r=>r.status==="skipped").length,o=e.streamResults.reduce((r,i)=>r+(i.executionTimeMs??0),0);return{id:e.runId,feature:e.feature,timestamp:e.timestamp,success:e.planQualityScore>=80,totalStreams:e.totalStreams,completedStreams:n,failedStreams:t,skippedStreams:s,totalWaves:e.totalWaves,executionTimeMs:o,streams:e.streamResults.map(r=>({id:r.id,name:r.name,status:r.status,wave:0,filesOwned:0,executionTimeMs:r.executionTimeMs??0,tokensUsed:r.tokensUsed??{input:0,output:0},errorCategory:r.errorCategory}))}}function Os(e){if(e.length<Zr)return[];let n=[],t=[ei,ti,ni,si,oi,ri,ii];for(let s of t){let o=s(e);o&&n.push(o)}return n}function ei(e){let n={low:{total:0,success:0,ids:[]},mid:{total:0,success:0,ids:[]},high:{total:0,success:0,ids:[]}};for(let u of e){let d=u.totalStreams<=5?"low":u.totalStreams<=8?"mid":"high";n[d].total++,u.success&&n[d].success++,n[d].ids.push(u.id)}if(n.low.total<3&&n.mid.total<3||n.high.total<2&&n.mid.total<2)return null;let t=n.low.total>0?n.low.success/n.low.total:0,s=n.high.total>0?n.high.success/n.high.total:0,o=n.mid.total>0?n.mid.success/n.mid.total:0,r=Math.max(t,o),i=Math.min(t,o,s);if(r-i<.2)return null;let a=t>=o?"low (1-5 streams)":"mid (6-8 streams)",c=Math.max(t,o),l=[...n.low.ids,...n.mid.ids,...n.high.ids];return{type:F.STREAM_COUNT_SWEET_SPOT,description:`Plans with ${a} succeed ${(c*100).toFixed(0)}% of the time`,confidence:Math.min(e.length/20,1),recommendation:`Prefer ${a.includes("low")?"3-5":"6-8"} streams per plan. Larger plans (${n.high.total>0?`>8 streams: ${(s*100).toFixed(0)}% success`:"not enough data"}) tend to fail more.`,evidence:{reportIds:l,metric:"streamCount",values:{"low_1-5_rate":`${(t*100).toFixed(0)}%`,"mid_6-8_rate":`${(o*100).toFixed(0)}%`,"high_9+_rate":`${(s*100).toFixed(0)}%`,low_count:n.low.total,high_count:n.high.total}}}}function ti(e){let n=0,t=0,s=0,o=0,r=[];for(let c of e){for(let l of c.streams)l.filesOwned<=4?(t++,l.status==="complete"&&n++):(o++,l.status==="complete"&&s++);r.push(c.id)}if(t<5||o<3)return null;let i=n/t,a=s/o;return i-a<.15?null:{type:F.FILE_PER_STREAM,description:`Streams with <=4 files succeed ${(i*100).toFixed(0)}%, streams with >4 files succeed ${(a*100).toFixed(0)}%`,confidence:Math.min((t+o)/30,1),recommendation:"Keep streams to 4 or fewer owned files. Split larger streams into focused units.",evidence:{reportIds:r,metric:"filesPerStream",values:{low_files_success_rate:`${(i*100).toFixed(0)}%`,high_files_success_rate:`${(a*100).toFixed(0)}%`,low_files_count:t,high_files_count:o}}}}function ni(e){let n={},t=0,s=[];for(let c of e){for(let l of c.streams)l.status==="failed"&&l.errorCategory&&(n[l.errorCategory]=(n[l.errorCategory]||0)+1,t++);c.failedStreams>0&&s.push(c.id)}if(t<3)return null;let o=Object.entries(n).sort((c,l)=>l[1]-c[1]),[r,i]=o[0],a=i/t*100;return{type:F.SELF_HEAL_PATTERN,description:`${r} errors are the most common failure (${a.toFixed(0)}% of all errors)`,confidence:Math.min(t/15,1),recommendation:`Focus on preventing ${r} errors. Consider adding targeted verify commands or adjusting prompts to avoid this error type.`,evidence:{reportIds:s,metric:"errorCategories",values:Object.fromEntries(o.map(([c,l])=>[c,`${l} (${(l/t*100).toFixed(0)}%)`]))}}}function si(e){let n=0,t=0,s=0,o=0,r=[];for(let c of e){let l=new Set(c.streams.filter(u=>!u.name.toLowerCase().includes("test")).map(u=>u.id));for(let u of c.streams){if(!u.name.toLowerCase().includes("test"))continue;u.deps&&u.deps.some(p=>l.has(p))?(n++,u.status==="complete"&&t++):(s++,u.status==="complete"&&o++)}r.push(c.id)}if(n<3||s<3)return null;let i=t/n,a=o/s;return i-a<.15?null:{type:F.DEPENDENCY_ORDERING,description:`Test streams with impl dependencies succeed ${(i*100).toFixed(0)}%, without: ${(a*100).toFixed(0)}%`,confidence:Math.min((n+s)/15,1),recommendation:"Always add implementation streams as dependencies of test streams. Place tests in later waves.",evidence:{reportIds:r,metric:"dependencyOrdering",values:{with_deps_rate:`${(i*100).toFixed(0)}%`,without_deps_rate:`${(a*100).toFixed(0)}%`,with_deps_count:n,without_deps_count:s}}}}function oi(e){let n={low:{total:0,success:0},high:{total:0,success:0}},t=[];for(let c of e){let l=c.totalWaves<=3?"low":"high";n[l].total++,c.success&&n[l].success++,t.push(c.id)}if(n.low.total<3||n.high.total<3)return null;let s=n.low.success/n.low.total,o=n.high.success/n.high.total;if(Math.abs(s-o)<.15)return null;let r=s>=o?"low":"high",i=r==="low"?s:o,a=r==="low"?"1-3":"4+";return{type:F.WAVE_EFFICIENCY,description:`Orchestrations with ${a} waves succeed ${(i*100).toFixed(0)}%`,confidence:Math.min(e.length/15,1),recommendation:`Prefer ${a} waves for best results. ${r==="low"?"Keep dependency depth shallow.":"More waves indicates better dependency structure."}`,evidence:{reportIds:t,metric:"waveCount",values:{"low_1-3_rate":`${(s*100).toFixed(0)}%`,"high_4+_rate":`${(o*100).toFixed(0)}%`,low_count:n.low.total,high_count:n.high.total}}}}function ri(e){let n={},t=[];for(let c of e){for(let l of c.streams){let u=l.provider??c.provider??"unknown";u!=="unknown"&&(n[u]||(n[u]={total:0,success:0}),n[u].total++,l.status==="complete"&&n[u].success++)}t.push(c.id)}let s=Object.entries(n).filter(([c,l])=>l.total>=3);if(s.length<2)return null;let o=s.map(([c,l])=>({name:c,rate:l.success/l.total,total:l.total})),r=o.sort((c,l)=>l.rate-c.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.1?null:{type:F.PROVIDER_PERFORMANCE,description:`${i.name} succeeds ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(s.reduce((c,[l,u])=>c+u.total,0)/30,1),recommendation:`${i.name} performs best in your project. Consider using it as the default provider.`,evidence:{reportIds:t,metric:"providerPerformance",values:Object.fromEntries(o.map(c=>[c.name,`${(c.rate*100).toFixed(0)}% (n=${c.total})`]))}}}function ii(e){let n={morning:{total:0,success:0},afternoon:{total:0,success:0},evening:{total:0,success:0},night:{total:0,success:0}},t=[];for(let c of e){let l=new Date(c.timestamp).getHours(),u=l<6?"night":l<12?"morning":l<18?"afternoon":"evening";n[u].total++,c.success&&n[u].success++,t.push(c.id)}let s=Object.entries(n).filter(([c,l])=>l.total>=3);if(s.length<2)return null;let o=s.map(([c,l])=>({name:c,rate:l.success/l.total,total:l.total})),r=o.sort((c,l)=>l.rate-c.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.2?null:{type:F.TIME_OF_DAY,description:`${i.name} runs succeed ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(e.length/20,1),recommendation:`Orchestrations during ${i.name} hours have the highest success rate. This may correlate with API rate limit availability.`,evidence:{reportIds:t,metric:"timeOfDay",values:Object.fromEntries(o.map(c=>[c.name,`${(c.rate*100).toFixed(0)}% (n=${c.total})`]))}}}function Ps(e){if(e.length===0)return"No significant patterns detected yet. Need more execution history.";let n=["=== Detected Patterns ===",""];for(let t of e){let s=t.confidence>=.7?"HIGH":t.confidence>=.4?"MEDIUM":"LOW";n.push(`[${s}] ${t.description}`),n.push(` Recommendation: ${t.recommendation}`),n.push("")}return n.join(`
|
|
172
172
|
`)}function Ts(e){if(e.length===0)return"";let n=e.filter(t=>t.confidence>=.4).map(t=>`- ${t.recommendation}`).join(`
|
|
173
173
|
`);return n?["## Project-Specific Guidance (from execution history)","","Based on this project's past orchestration runs:",n,"","Apply these recommendations when generating the plan."].join(`
|
|
174
|
-
`):""}function _s(e){return $e.join(e,".orchex","learn","patterns.json")}async function Is(e,n){let t=_s(e),s=$e.dirname(t);await G.mkdir(s,{recursive:!0}),await G.writeFile(t,JSON.stringify(n,null,2),"utf-8")}async function Ms(e){let n=_s(e);try{let t=await G.readFile(n,"utf-8");return JSON.parse(t)}catch{return[]}}var
|
|
175
|
-
`),o=0,r=0,i=0,a=0;for(let f of s){let p=f.trim();if(o+=f.length,p.length===0){a+=f.length;continue}if(p.startsWith("//")||p.startsWith("/*")||p.startsWith("*")||p.startsWith("#"))i+=f.length;else{r+=f.length;let m=f.length-p.length;a+=m,r-=m}}let c=Math.ceil(r/J.CODE),l=Math.ceil(i/J.COMMENTS),u=Math.ceil(a/J.WHITESPACE),d=Math.ceil((o-r-i-a)/J.COMMENTS);return c+l+u+d}var J,
|
|
174
|
+
`):""}function _s(e){return $e.join(e,".orchex","learn","patterns.json")}async function Is(e,n){let t=_s(e),s=$e.dirname(t);await G.mkdir(s,{recursive:!0}),await G.writeFile(t,JSON.stringify(n,null,2),"utf-8")}async function Ms(e){let n=_s(e);try{let t=await G.readFile(n,"utf-8");return JSON.parse(t)}catch{return[]}}var F,Zr,Rs=y(()=>{"use strict";(function(e){e.STREAM_COUNT_SWEET_SPOT="stream-count-sweet-spot",e.DEPENDENCY_ORDERING="dependency-ordering",e.FILE_PER_STREAM="file-per-stream",e.WAVE_EFFICIENCY="wave-efficiency",e.PROVIDER_PERFORMANCE="provider-performance",e.SELF_HEAL_PATTERN="self-heal-pattern",e.TIME_OF_DAY="time-of-day"})(F||(F={}));Zr=5});function be(e){let n=[],t=/(?:import|export)\s+.*?from\s+['"](.+?)['"]/g,s;for(;(s=t.exec(e))!==null;)n.push(s[1]);let o=/require\s*\(\s*['"](.+?)['"]\s*\)/g;for(;(s=o.exec(e))!==null;)n.push(s[1]);return n}function Ce(e,n){if(!n.startsWith("."))return null;let t=e.substring(0,e.lastIndexOf("/")),s=n.replace(/\.js$/,""),o=[...t.split("/"),...s.split("/")],r=[];for(let a of o)a===".."?r.pop():a!=="."&&r.push(a);let i=r.join("/");return i.endsWith(".ts")?i:i+".ts"}var at=y(()=>{"use strict"});function As(e,n,t){let s=new Set([...e]),o=new Set,r=[...e],i=[],a=new Map;for(let l of e)a.set(l,[]);for(;r.length>0;){let l=r.shift();if(o.has(l))continue;o.add(l);let u=t[l];if(!u)continue;let d=be(u);for(let f of d){let p=Ce(l,f);if(p&&t[p]){if(o.has(p)){let m=a.get(l)||[];i.push(`Circular dependency detected: ${[...m,l,p].join(" \u2192 ")}`)}else if(!s.has(p)){s.add(p),r.push(p);let m=a.get(l)||[];a.set(p,[...m,l])}}}}for(let l of n)s.add(l);let c=Object.keys(t).filter(l=>!s.has(l));return{needed:[...s],pruned:c,warnings:i.length>0?i:void 0}}function js(e,n,t){let s=[];return t.length>100&&s.push({content:t,type:"system_prompt",reusable:!0,estimatedTokens:ie(t)}),e.length>500&&s.push({content:e,type:"project_context",reusable:!0,estimatedTokens:ie(e)}),n.length>500&&s.push({content:n,type:"stream_context",reusable:!0,estimatedTokens:ie(n)}),s}function ie(e){if(!e||e.length===0)return 0;let n=e.trim().startsWith("{")||e.trim().startsWith("["),t=/^#+\s|^-\s|^\*\s|^\d+\.\s/m.test(e);if(n)return Math.ceil(e.length/J.JSON);if(t)return Math.ceil(e.length/J.MARKDOWN);let s=e.split(`
|
|
175
|
+
`),o=0,r=0,i=0,a=0;for(let f of s){let p=f.trim();if(o+=f.length,p.length===0){a+=f.length;continue}if(p.startsWith("//")||p.startsWith("/*")||p.startsWith("*")||p.startsWith("#"))i+=f.length;else{r+=f.length;let m=f.length-p.length;a+=m,r-=m}}let c=Math.ceil(r/J.CODE),l=Math.ceil(i/J.COMMENTS),u=Math.ceil(a/J.WHITESPACE),d=Math.ceil((o-r-i-a)/J.COMMENTS);return c+l+u+d}var J,Fs=y(()=>{"use strict";at();J={CODE:3.5,COMMENTS:4.5,WHITESPACE:6,JSON:3.8,MARKDOWN:4.2}});function Ns(e,n){return n&&Ls[n]?Ls[n]:Ds[e]??Ds.default}function Ws(e,n,t){let s=Ns(n,t),o=e?.softLimitTokens??Math.floor(s*ai),r=e?.hardLimitTokens??Math.floor(s*ci),i=e?.enforcementLevel??"warn",a=e?.warningThreshold??li;return{enforcementLevel:i,softLimitTokens:o,hardLimitTokens:r,warningThreshold:a,provider:n,model:t}}function ui(e,n,t){let s=n-t,o=Math.round(s/t*100);if(e==="none")return"";let r=[`Context is ${o}% over the ${e} limit.`,"Consider:",' - Reducing the number of files in "reads"'," - Splitting the stream into smaller tasks"," - Using file patterns instead of directories"," - Extracting only function signatures instead of full files"];return e==="hard"&&r.push(" - Or increase the hard limit in contextBudget settings"),r.join(`
|
|
176
176
|
`)}function Us(e,n){let t=Ns(n.provider,n.model),{softLimitTokens:s,hardLimitTokens:o,warningThreshold:r,enforcementLevel:i}=n,a="none",c=s;e>=o?(a="hard",c=o):e>=s&&(a="soft",c=s);let l=e/s,u=!0;a==="hard"&&i==="hard"?u=!1:a==="soft"&&i==="soft"&&(u=!0);let d;if(a!=="none"){let p=a==="hard"?"hard limit":"soft limit";d=`Context size (${e.toLocaleString()} tokens) exceeds ${p} (${c.toLocaleString()} tokens)`,u||(d+=". Execution blocked.")}else l>=r&&(d=`Context size at ${Math.round(l*100)}% of soft limit (${e.toLocaleString()} / ${s.toLocaleString()} tokens)`);let f=a!=="none"?ui(a,e,c):void 0;return{allowed:u,violationType:a,estimatedTokens:e,budgetLimit:c,utilizationRatio:l,warning:d,suggestion:f,providerLimit:t}}var Ds,Ls,ai,ci,li,Ee,Hs=y(()=>{"use strict";Ds={anthropic:2e5,openai:128e3,gemini:1e6,deepseek:128e3,kimi:262144,ollama:128e3,default:1e5},Ls={"claude-opus-4-5-20251101":2e5,"claude-sonnet-4-5-20250929":2e5,"claude-sonnet-4-20250514":2e5,"claude-3-5-sonnet-20241022":2e5,"claude-3-opus-20240229":2e5,"claude-3-haiku-20240307":2e5,"gpt-4.5-turbo":128e3,"gpt-4-turbo":128e3,"gpt-4-turbo-preview":128e3,"gpt-4o":128e3,"gpt-4o-mini":128e3,"o1-preview":128e3,"o1-mini":128e3,"o3-mini":2e5,"gpt-3.5-turbo":16385,"gemini-2.5-pro":1e6,"gemini-2.0-flash":1e6,"gemini-1.5-pro":1e6,"gemini-1.5-flash":1e6,"gemini-pro":32768,"deepseek-chat":128e3,"deepseek-coder":128e3,"deepseek-reasoner":128e3,"kimi-k2-0905-preview":262144,"kimi-k2-turbo-preview":262144,"kimi-latest":262144,"moonshot-v1-8k":8192,"moonshot-v1-32k":32768,"moonshot-v1-128k":131072,"llama3.3:70b":128e3,"llama3.2:latest":128e3,"mistral:latest":32e3},ai=.7,ci=.9,li=.8;Ee=class extends Error{checkResult;streamId;constructor(n,t){let s=t?` for stream "${t}"`:"";super(`Context budget exceeded${s}: ${n.warning}`),this.checkResult=n,this.streamId=t,this.name="ContextBudgetExceededError"}}});function zs(e,n,t=300,s=10,o=120,r=!1){let i=e.split(/\r?\n/);if(i.length<t||n.length===0)return e;let a=n.map(h=>new RegExp(di(h),"i")),c=[];for(let h=0;h<i.length;++h)a.some(w=>w.test(i[h]))&&c.push(h);let l=new Set;for(let h of c)for(let w=Math.max(0,h-s);w<=Math.min(i.length-1,h+s);++w)l.add(w);if(l.size<Math.min(20,s*2)){for(let h=0;h<Math.min(s*2,i.length);++h)l.add(h);for(let h=Math.max(0,i.length-s*2);h<i.length;++h)l.add(h)}let d=Array.from(l).sort((h,w)=>h-w).slice(0,o),f=-2,p=[],m=r?String(i.length).length:0;for(let h of d)h>f+1&&p.length>0&&p.push("..."),r?p.push(`${String(h+1).padStart(m)}: ${i[h]}`):p.push(i[h]),f=h;return p.join(`
|
|
177
|
-
`)}function di(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Bs=y(()=>{"use strict"});var Cn={};ae(Cn,{ContextBudgetExceededError:()=>Ee,DEFAULT_THRESHOLDS:()=>ee,FilePathSchema:()=>K,PlanContractStreamInputSchema:()=>tn,PlanContractStreamSchema:()=>He,adaptReport:()=>Es,analyzeError:()=>we,analyzeFailureCorrelation:()=>ye,appendLocalEvents:()=>kt,applyPartialApproval:()=>gs,applyTemplate:()=>ve,autoFixSequentialEdits:()=>ze,autoMergeOwnershipConflicts:()=>us,buildDependencyGraph:()=>
|
|
177
|
+
`)}function di(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Bs=y(()=>{"use strict"});var Cn={};ae(Cn,{ContextBudgetExceededError:()=>Ee,DEFAULT_THRESHOLDS:()=>ee,FilePathSchema:()=>K,PlanContractStreamInputSchema:()=>tn,PlanContractStreamSchema:()=>He,adaptReport:()=>Es,analyzeError:()=>we,analyzeFailureCorrelation:()=>ye,appendLocalEvents:()=>kt,applyPartialApproval:()=>gs,applyTemplate:()=>ve,autoFixSequentialEdits:()=>ze,autoMergeOwnershipConflicts:()=>us,buildDependencyGraph:()=>Ft,categorizeStream:()=>te,checkBudget:()=>Us,classifyTask:()=>ps,cleanupOrphanFixStreams:()=>Mn,createBudgetConfig:()=>Ws,createDetector:()=>Y,createDiagnostics:()=>On,detectOwnershipConflicts:()=>Pn,detectPatterns:()=>Os,detectSequentialEdits:()=>me,detectUpstreamSuspect:()=>zn,estimatePlannedCost:()=>vs,estimateTokens:()=>ie,evaluateCompletion:()=>os,extractDeliverables:()=>_t,extractImports:()=>be,extractPrerequisites:()=>Xt,extractRelevantChunks:()=>zs,extractSpecPaths:()=>Me,findMatchingTemplate:()=>re,formatDeliverablesReport:()=>Mt,formatDependencyReport:()=>Dt,formatPatterns:()=>Ps,formatPlanPreview:()=>Xe,formatPlanPreviewText:()=>kn,formatPlanValidationErrors:()=>sn,formatStreamsForReview:()=>Gt,gatherProjectContext:()=>Ie,generateAllSuggestions:()=>as,generateCachingHints:()=>js,generateFixStream:()=>Hn,generateLearningSummary:()=>Vn,generatePlan:()=>pt,generatePlanPreview:()=>$n,generateReport:()=>qn,generateRootCauseFixStream:()=>Bn,generateStreams:()=>Vt,getFirstRunSuggestion:()=>Zn,getFixChainInfo:()=>se,getModelCosts:()=>ot,getOriginalStreamId:()=>jn,getRecommendedLimit:()=>xt,getSectionsAtLevel:()=>Z,getSuggestionsSummary:()=>cs,getThresholds:()=>De,isFirstRun:()=>Xn,isFixStream:()=>An,isUnpopulatedTemplate:()=>wt,loadPatterns:()=>Ms,loadRoutingRules:()=>bs,markFirstRunComplete:()=>Qn,onStreamComplete:()=>Rn,optimizeTopology:()=>pe,parsePlanDocument:()=>gt,patternsToPromptHints:()=>Ts,processDeliverables:()=>It,pruneUnusedFiles:()=>As,resetLearning:()=>ns,resolveImportPath:()=>Ce,rollbackStream:()=>ws,routeStream:()=>$s,runLearningCycle:()=>$t,savePatterns:()=>Is,saveReportLocally:()=>Yn,streamResultToTelemetryEvent:()=>St,suggestProvider:()=>fs,suggestSplit:()=>is,toInitFormat:()=>Jt,validatePlan:()=>nn});var En=y(()=>{mt();je();Rt();Lt();Qt();on();bn();Be();Tn();Kn();Gn();es();ss();Qe();rs();Le();fe();ls();ds();ms();ys();tt();et();Cs();Rs();Fs();Hs();Bs();rt();at();nt();Ue()});En();export{Ee as ContextBudgetExceededError,ee as DEFAULT_THRESHOLDS,K as FilePathSchema,tn as PlanContractStreamInputSchema,He as PlanContractStreamSchema,Es as adaptReport,we as analyzeError,ye as analyzeFailureCorrelation,kt as appendLocalEvents,gs as applyPartialApproval,ve as applyTemplate,ze as autoFixSequentialEdits,us as autoMergeOwnershipConflicts,Ft as buildDependencyGraph,te as categorizeStream,Us as checkBudget,ps as classifyTask,Mn as cleanupOrphanFixStreams,Ws as createBudgetConfig,Y as createDetector,On as createDiagnostics,Pn as detectOwnershipConflicts,Os as detectPatterns,me as detectSequentialEdits,zn as detectUpstreamSuspect,vs as estimatePlannedCost,ie as estimateTokens,os as evaluateCompletion,_t as extractDeliverables,be as extractImports,Xt as extractPrerequisites,zs as extractRelevantChunks,Me as extractSpecPaths,re as findMatchingTemplate,Mt as formatDeliverablesReport,Dt as formatDependencyReport,Ps as formatPatterns,Xe as formatPlanPreview,kn as formatPlanPreviewText,sn as formatPlanValidationErrors,Gt as formatStreamsForReview,Ie as gatherProjectContext,as as generateAllSuggestions,js as generateCachingHints,Hn as generateFixStream,Vn as generateLearningSummary,pt as generatePlan,$n as generatePlanPreview,qn as generateReport,Bn as generateRootCauseFixStream,Vt as generateStreams,Zn as getFirstRunSuggestion,se as getFixChainInfo,ot as getModelCosts,jn as getOriginalStreamId,xt as getRecommendedLimit,Z as getSectionsAtLevel,cs as getSuggestionsSummary,De as getThresholds,Xn as isFirstRun,An as isFixStream,wt as isUnpopulatedTemplate,Ms as loadPatterns,bs as loadRoutingRules,Qn as markFirstRunComplete,Rn as onStreamComplete,pe as optimizeTopology,gt as parsePlanDocument,Ts as patternsToPromptHints,It as processDeliverables,As as pruneUnusedFiles,ns as resetLearning,Ce as resolveImportPath,ws as rollbackStream,$s as routeStream,$t as runLearningCycle,Is as savePatterns,Yn as saveReportLocally,St as streamResultToTelemetryEvent,fs as suggestProvider,is as suggestSplit,Jt as toInitFormat,nn as validatePlan};
|
package/dist/logger.d.ts
CHANGED
|
@@ -29,6 +29,22 @@ export declare function createLogger(projectDir: string): {
|
|
|
29
29
|
};
|
|
30
30
|
export type Logger = ReturnType<typeof createLogger>;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Append a run-boundary marker to the execution log.
|
|
33
|
+
*
|
|
34
|
+
* Replaces the prior `clearExecutionLog` truncate-on-every-executeWave behavior
|
|
35
|
+
* which wiped forensic data (heartbeats, retries, errors from the prior run)
|
|
36
|
+
* before any post-mortem could read it. Now the log is append-only with
|
|
37
|
+
* explicit `=== RUN <ISO-8601> ===` markers separating runs.
|
|
38
|
+
*
|
|
39
|
+
* Per 2026-05-04 team review (`.claude/team/reviews/2026-05-04-rc32-orchex-broken-sequencing.md`):
|
|
40
|
+
* the empirically-observed silent-hang pattern (`attempts:N, in_progress, [no error]`
|
|
41
|
+
* with truncated log) was caused in part by `clearExecutionLog` racing the
|
|
42
|
+
* recover-without-record reset path. Append-only preservation closes that gap;
|
|
43
|
+
* full retention/rotation policy (>10MB) is rc.33 work.
|
|
44
|
+
*/
|
|
45
|
+
export declare function appendRunBoundary(projectDir: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Use `appendRunBoundary` instead. Retained as an alias for any
|
|
48
|
+
* external caller; will be removed in a future release.
|
|
33
49
|
*/
|
|
34
50
|
export declare function clearExecutionLog(projectDir: string): Promise<void>;
|
package/dist/logger.js
CHANGED
|
@@ -70,14 +70,34 @@ export function createLogger(projectDir) {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Append a run-boundary marker to the execution log.
|
|
74
|
+
*
|
|
75
|
+
* Replaces the prior `clearExecutionLog` truncate-on-every-executeWave behavior
|
|
76
|
+
* which wiped forensic data (heartbeats, retries, errors from the prior run)
|
|
77
|
+
* before any post-mortem could read it. Now the log is append-only with
|
|
78
|
+
* explicit `=== RUN <ISO-8601> ===` markers separating runs.
|
|
79
|
+
*
|
|
80
|
+
* Per 2026-05-04 team review (`.claude/team/reviews/2026-05-04-rc32-orchex-broken-sequencing.md`):
|
|
81
|
+
* the empirically-observed silent-hang pattern (`attempts:N, in_progress, [no error]`
|
|
82
|
+
* with truncated log) was caused in part by `clearExecutionLog` racing the
|
|
83
|
+
* recover-without-record reset path. Append-only preservation closes that gap;
|
|
84
|
+
* full retention/rotation policy (>10MB) is rc.33 work.
|
|
74
85
|
*/
|
|
75
|
-
export async function
|
|
86
|
+
export async function appendRunBoundary(projectDir) {
|
|
76
87
|
const logPath = path.join(projectDir, LOG_FILE);
|
|
88
|
+
const marker = `=== RUN ${new Date().toISOString()} ===\n`;
|
|
77
89
|
try {
|
|
78
|
-
await fs.
|
|
90
|
+
await fs.mkdir(path.dirname(logPath), { recursive: true });
|
|
91
|
+
await fs.appendFile(logPath, marker);
|
|
79
92
|
}
|
|
80
93
|
catch {
|
|
81
|
-
//
|
|
94
|
+
// Best effort — don't fail execution for logging issues
|
|
82
95
|
}
|
|
83
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* @deprecated Use `appendRunBoundary` instead. Retained as an alias for any
|
|
99
|
+
* external caller; will be removed in a future release.
|
|
100
|
+
*/
|
|
101
|
+
export async function clearExecutionLog(projectDir) {
|
|
102
|
+
await appendRunBoundary(projectDir);
|
|
103
|
+
}
|
package/dist/manifest.js
CHANGED
|
@@ -199,13 +199,22 @@ export async function recoverStuckStreams(projectDir, options) {
|
|
|
199
199
|
const recovered = [];
|
|
200
200
|
for (const [id, stream] of Object.entries(manifest.streams)) {
|
|
201
201
|
if (stream.status === 'in_progress') {
|
|
202
|
+
// Preserve forensic context BEFORE resetting status — closes the silent-hang
|
|
203
|
+
// gap where a stream stuck in_progress without an error trace (timeout swallow,
|
|
204
|
+
// network hang) would lose all failure context on the next recovery cycle.
|
|
205
|
+
manifest.streams[id].lastFailure = {
|
|
206
|
+
error: stream.error ?? 'Stream stuck in_progress (no error recorded — silent hang)',
|
|
207
|
+
timestamp: new Date().toISOString(),
|
|
208
|
+
attempts: stream.attempts,
|
|
209
|
+
category: stream.error ? 'recorded' : 'silent_hang',
|
|
210
|
+
};
|
|
202
211
|
manifest.streams[id].status = 'pending';
|
|
203
212
|
// Don't reset attempts - we want to track total attempts
|
|
204
213
|
recovered.push(id);
|
|
205
214
|
}
|
|
206
215
|
else if (options?.includeFailed && stream.status === 'failed') {
|
|
207
216
|
manifest.streams[id].status = 'pending';
|
|
208
|
-
// Remove error if any
|
|
217
|
+
// Remove error if any (lastFailure is preserved if present)
|
|
209
218
|
if ('error' in manifest.streams[id]) {
|
|
210
219
|
delete manifest.streams[id].error;
|
|
211
220
|
}
|
package/dist/orchestrator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { loadManifest, saveManifest, updateStreamStatus, addStream, recoverStuckStreams, cleanStaleLock } from './manifest.js';
|
|
2
|
-
import { createLogger,
|
|
2
|
+
import { createLogger, appendRunBoundary } from './logger.js';
|
|
3
3
|
import { createLogger as createPinoLogger } from './logging.js';
|
|
4
4
|
const log = createPinoLogger('orchestrator');
|
|
5
5
|
import { generateFixStream, generateRootCauseFixStream, analyzeFailureCorrelation, detectUpstreamSuspect, analyzeError, cleanupOrphanFixStreams, streamResultToTelemetryEvent, appendLocalEvents, runLearningCycle, routeStream, loadRoutingRules, } from './intelligence/index.js';
|
|
@@ -135,8 +135,8 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
|
|
|
135
135
|
catch (err) {
|
|
136
136
|
await logger.error('recovery_failed', { error: err.message });
|
|
137
137
|
}
|
|
138
|
-
//
|
|
139
|
-
await
|
|
138
|
+
// Append run-boundary marker for fresh execution (preserves prior forensic data)
|
|
139
|
+
await appendRunBoundary(projectDir);
|
|
140
140
|
await logger.info('execution_starting', { provider: executor.provider });
|
|
141
141
|
// 0b. CLEANUP — remove orphan fix streams before wave calculation
|
|
142
142
|
// This handles edge cases where cleanup wasn't triggered (e.g., manual status updates)
|
package/dist/setup/index.js
CHANGED
|
@@ -106,6 +106,7 @@ Setup complete! Next steps:
|
|
|
106
106
|
1. Restart your IDE/editor
|
|
107
107
|
2. Verify with: orchex_status (in MCP client)
|
|
108
108
|
3. API keys: Set ANTHROPIC_API_KEY or OPENAI_API_KEY
|
|
109
|
-
(Orchex auto-detects from environment)
|
|
109
|
+
(Orchex auto-detects from environment)
|
|
110
|
+
4. Optional: \`orchex login\` → 10 free cloud runs (no card, no expiry)`);
|
|
110
111
|
}
|
|
111
112
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -75,6 +75,29 @@ export declare const StreamDefinitionSchema: z.ZodObject<{
|
|
|
75
75
|
verify: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
76
76
|
status: z.ZodDefault<z.ZodOptional<z.ZodEnum<["pending", "in_progress", "complete", "failed", "skipped", "blocked", "circuit_breaker"]>>>;
|
|
77
77
|
error: z.ZodOptional<z.ZodString>;
|
|
78
|
+
/**
|
|
79
|
+
* Snapshot of the prior attempt's failure context, captured by recoverStuckStreams
|
|
80
|
+
* BEFORE resetting in_progress→pending. Closes the silent-hang forensic gap:
|
|
81
|
+
* without this, a hung stream's manifest entry shows `attempts: N, status: in_progress, [no error]`
|
|
82
|
+
* indefinitely as recovery cycles wipe the trail. Categories: 'recorded' = prior `error` field
|
|
83
|
+
* was populated; 'silent_hang' = stream stuck in_progress without an error trace (timeout swallow).
|
|
84
|
+
*/
|
|
85
|
+
lastFailure: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
error: z.ZodString;
|
|
87
|
+
timestamp: z.ZodString;
|
|
88
|
+
attempts: z.ZodNumber;
|
|
89
|
+
category: z.ZodOptional<z.ZodEnum<["recorded", "silent_hang"]>>;
|
|
90
|
+
}, "strip", z.ZodTypeAny, {
|
|
91
|
+
error: string;
|
|
92
|
+
timestamp: string;
|
|
93
|
+
attempts: number;
|
|
94
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
95
|
+
}, {
|
|
96
|
+
error: string;
|
|
97
|
+
timestamp: string;
|
|
98
|
+
attempts: number;
|
|
99
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
100
|
+
}>>;
|
|
78
101
|
attempts: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
79
102
|
/** For fix streams, the ID of the original stream being fixed */
|
|
80
103
|
parentStreamId: z.ZodOptional<z.ZodString>;
|
|
@@ -122,6 +145,12 @@ export declare const StreamDefinitionSchema: z.ZodObject<{
|
|
|
122
145
|
provider?: string | undefined;
|
|
123
146
|
plan?: string | undefined;
|
|
124
147
|
estimatedTokens?: number | undefined;
|
|
148
|
+
lastFailure?: {
|
|
149
|
+
error: string;
|
|
150
|
+
timestamp: string;
|
|
151
|
+
attempts: number;
|
|
152
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
153
|
+
} | undefined;
|
|
125
154
|
parentStreamId?: string | undefined;
|
|
126
155
|
appliedAt?: string | undefined;
|
|
127
156
|
timeoutMs?: number | undefined;
|
|
@@ -145,6 +174,12 @@ export declare const StreamDefinitionSchema: z.ZodObject<{
|
|
|
145
174
|
setup?: string[] | undefined;
|
|
146
175
|
estimatedTokens?: number | undefined;
|
|
147
176
|
attempts?: number | undefined;
|
|
177
|
+
lastFailure?: {
|
|
178
|
+
error: string;
|
|
179
|
+
timestamp: string;
|
|
180
|
+
attempts: number;
|
|
181
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
182
|
+
} | undefined;
|
|
148
183
|
parentStreamId?: string | undefined;
|
|
149
184
|
appliedAt?: string | undefined;
|
|
150
185
|
timeoutMs?: number | undefined;
|
|
@@ -203,6 +238,29 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
203
238
|
verify: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
204
239
|
status: z.ZodDefault<z.ZodOptional<z.ZodEnum<["pending", "in_progress", "complete", "failed", "skipped", "blocked", "circuit_breaker"]>>>;
|
|
205
240
|
error: z.ZodOptional<z.ZodString>;
|
|
241
|
+
/**
|
|
242
|
+
* Snapshot of the prior attempt's failure context, captured by recoverStuckStreams
|
|
243
|
+
* BEFORE resetting in_progress→pending. Closes the silent-hang forensic gap:
|
|
244
|
+
* without this, a hung stream's manifest entry shows `attempts: N, status: in_progress, [no error]`
|
|
245
|
+
* indefinitely as recovery cycles wipe the trail. Categories: 'recorded' = prior `error` field
|
|
246
|
+
* was populated; 'silent_hang' = stream stuck in_progress without an error trace (timeout swallow).
|
|
247
|
+
*/
|
|
248
|
+
lastFailure: z.ZodOptional<z.ZodObject<{
|
|
249
|
+
error: z.ZodString;
|
|
250
|
+
timestamp: z.ZodString;
|
|
251
|
+
attempts: z.ZodNumber;
|
|
252
|
+
category: z.ZodOptional<z.ZodEnum<["recorded", "silent_hang"]>>;
|
|
253
|
+
}, "strip", z.ZodTypeAny, {
|
|
254
|
+
error: string;
|
|
255
|
+
timestamp: string;
|
|
256
|
+
attempts: number;
|
|
257
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
258
|
+
}, {
|
|
259
|
+
error: string;
|
|
260
|
+
timestamp: string;
|
|
261
|
+
attempts: number;
|
|
262
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
263
|
+
}>>;
|
|
206
264
|
attempts: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
207
265
|
/** For fix streams, the ID of the original stream being fixed */
|
|
208
266
|
parentStreamId: z.ZodOptional<z.ZodString>;
|
|
@@ -250,6 +308,12 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
250
308
|
provider?: string | undefined;
|
|
251
309
|
plan?: string | undefined;
|
|
252
310
|
estimatedTokens?: number | undefined;
|
|
311
|
+
lastFailure?: {
|
|
312
|
+
error: string;
|
|
313
|
+
timestamp: string;
|
|
314
|
+
attempts: number;
|
|
315
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
316
|
+
} | undefined;
|
|
253
317
|
parentStreamId?: string | undefined;
|
|
254
318
|
appliedAt?: string | undefined;
|
|
255
319
|
timeoutMs?: number | undefined;
|
|
@@ -273,6 +337,12 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
273
337
|
setup?: string[] | undefined;
|
|
274
338
|
estimatedTokens?: number | undefined;
|
|
275
339
|
attempts?: number | undefined;
|
|
340
|
+
lastFailure?: {
|
|
341
|
+
error: string;
|
|
342
|
+
timestamp: string;
|
|
343
|
+
attempts: number;
|
|
344
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
345
|
+
} | undefined;
|
|
276
346
|
parentStreamId?: string | undefined;
|
|
277
347
|
appliedAt?: string | undefined;
|
|
278
348
|
timeoutMs?: number | undefined;
|
|
@@ -349,6 +419,12 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
349
419
|
provider?: string | undefined;
|
|
350
420
|
plan?: string | undefined;
|
|
351
421
|
estimatedTokens?: number | undefined;
|
|
422
|
+
lastFailure?: {
|
|
423
|
+
error: string;
|
|
424
|
+
timestamp: string;
|
|
425
|
+
attempts: number;
|
|
426
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
427
|
+
} | undefined;
|
|
352
428
|
parentStreamId?: string | undefined;
|
|
353
429
|
appliedAt?: string | undefined;
|
|
354
430
|
timeoutMs?: number | undefined;
|
|
@@ -391,6 +467,12 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
391
467
|
setup?: string[] | undefined;
|
|
392
468
|
estimatedTokens?: number | undefined;
|
|
393
469
|
attempts?: number | undefined;
|
|
470
|
+
lastFailure?: {
|
|
471
|
+
error: string;
|
|
472
|
+
timestamp: string;
|
|
473
|
+
attempts: number;
|
|
474
|
+
category?: "recorded" | "silent_hang" | undefined;
|
|
475
|
+
} | undefined;
|
|
394
476
|
parentStreamId?: string | undefined;
|
|
395
477
|
appliedAt?: string | undefined;
|
|
396
478
|
timeoutMs?: number | undefined;
|
package/dist/types.js
CHANGED
|
@@ -65,6 +65,21 @@ export const StreamDefinitionSchema = z.object({
|
|
|
65
65
|
verify: z.array(z.string().max(1024)).max(20).optional().default([]),
|
|
66
66
|
status: StreamStatusSchema.optional().default('pending'),
|
|
67
67
|
error: z.string().optional(),
|
|
68
|
+
/**
|
|
69
|
+
* Snapshot of the prior attempt's failure context, captured by recoverStuckStreams
|
|
70
|
+
* BEFORE resetting in_progress→pending. Closes the silent-hang forensic gap:
|
|
71
|
+
* without this, a hung stream's manifest entry shows `attempts: N, status: in_progress, [no error]`
|
|
72
|
+
* indefinitely as recovery cycles wipe the trail. Categories: 'recorded' = prior `error` field
|
|
73
|
+
* was populated; 'silent_hang' = stream stuck in_progress without an error trace (timeout swallow).
|
|
74
|
+
*/
|
|
75
|
+
lastFailure: z
|
|
76
|
+
.object({
|
|
77
|
+
error: z.string(),
|
|
78
|
+
timestamp: z.string(),
|
|
79
|
+
attempts: z.number(),
|
|
80
|
+
category: z.enum(['recorded', 'silent_hang']).optional(),
|
|
81
|
+
})
|
|
82
|
+
.optional(),
|
|
68
83
|
attempts: z.number().optional().default(0),
|
|
69
84
|
/** For fix streams, the ID of the original stream being fixed */
|
|
70
85
|
parentStreamId: z.string().optional(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wundam/orchex",
|
|
3
3
|
"mcpName": "io.github.wundam/orchex",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.32",
|
|
5
5
|
"description": "Autopilot AI orchestration — auto-plan, parallelize, and execute with ownership enforcement",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"test:coverage": "vitest run --coverage",
|
|
17
17
|
"test:coverage:html": "vitest run --coverage --coverage.reporter=html && open coverage/index.html",
|
|
18
18
|
"lint": "eslint src/",
|
|
19
|
+
"postversion": "npm install --package-lock-only && node scripts/sync-server-json-version.mjs",
|
|
19
20
|
"prepublishOnly": "node scripts/sync-server-json-version.mjs && node scripts/prepublish-clean.mjs && npm run build && node scripts/bundle-intelligence.mjs",
|
|
20
21
|
"postpublish": "node scripts/prepublish-clean.mjs restore"
|
|
21
22
|
},
|