@wundam/orchex 1.0.0-rc.21 → 1.0.0-rc.23

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/index.js CHANGED
@@ -4,6 +4,7 @@ import { exec as execChildProcess } from 'child_process';
4
4
  import { registerTools, setProjectDir } from './tools.js';
5
5
  import { ORCHEX_INSTRUCTIONS } from './mcp-instructions.js';
6
6
  import { registerResources } from './mcp-resources.js';
7
+ import { broadcaster } from './execution-broadcaster.js';
7
8
  import { loadConfig, saveConfig, maskConfigForDisplay, resolveApiUrl, PRODUCTION_URL, LLMProviderSchema } from './config.js';
8
9
  import { buildVerificationMessage, buildStatusMessage, parseLoginApiResponse, } from './login-helpers.js';
9
10
  /** Opens browser cross-platform. Errors are silently ignored — URL already printed to terminal. */
@@ -606,12 +607,34 @@ async function handleRunCommand(args) {
606
607
  let done = false;
607
608
  let waveNum = 1;
608
609
  while (!done) {
609
- console.log(`Executing wave ${waveNum}...`);
610
+ // Subscribe to broadcaster for per-stream progress during this wave
611
+ const orchestrationId = plan.title;
612
+ const cliProgressListener = (event) => {
613
+ switch (event.type) {
614
+ case 'stream_started':
615
+ process.stdout.write(` ⟳ ${event.data.streamId} — running...\n`);
616
+ break;
617
+ case 'stream_completed': {
618
+ const dur = event.data.duration ? ` (${Math.round(event.data.duration / 1000)}s)` : '';
619
+ process.stdout.write(` ✓ ${event.data.streamId} — complete${dur}\n`);
620
+ break;
621
+ }
622
+ case 'stream_failed':
623
+ process.stdout.write(` ✗ ${event.data.streamId} — failed: ${String(event.data.error).slice(0, 100)}\n`);
624
+ break;
625
+ case 'stream_rate_limited':
626
+ process.stdout.write(` ⏳ ${event.data.streamId} — rate limited (retry in ${Math.round((event.data.retryAfterMs ?? 0) / 1000)}s)\n`);
627
+ break;
628
+ }
629
+ };
630
+ broadcaster.subscribe(orchestrationId, cliProgressListener);
631
+ console.log(`\nExecuting wave ${waveNum}...`);
610
632
  const response = await executeWave(projectDir, exec, { model: modelFlag });
611
633
  allResponses.push(response);
634
+ broadcaster.unsubscribe(orchestrationId, cliProgressListener);
612
635
  const completed = response.streams.filter(s => s.status === 'complete').length;
613
636
  const failed = response.streams.filter(s => s.status === 'failed').length;
614
- console.log(` Wave ${waveNum}: ${completed} complete, ${failed} failed`);
637
+ console.log(` Wave ${waveNum} summary: ${completed} complete, ${failed} failed`);
615
638
  done = response.done;
616
639
  waveNum++;
617
640
  }
@@ -27,7 +27,7 @@ export type { InteractiveSuggestion } from './split-suggester.js';
27
27
  export { autoMergeOwnershipConflicts } from './ownership-resolver.js';
28
28
  export { suggestProvider, classifyTask } from './model-routing.js';
29
29
  export { applyPartialApproval, rollbackStream } from './interactive-approval.js';
30
- export { generateFixStream } from './self-healer.js';
30
+ export { generateFixStream, generateRootCauseFixStream, analyzeFailureCorrelation, type FailureCorrelation } from './self-healer.js';
31
31
  export { cleanupOrphanFixStreams, getFixChainInfo, isFixStream, getOriginalStreamId, onStreamComplete } from './fix-stream-manager.js';
32
32
  export { routeStream, loadRoutingRules } from './smart-router.js';
33
33
  export type { RouteDecision, RouteOptions } from './smart-router.js';
@@ -1,5 +1,5 @@
1
- import*as R from"fs/promises";import{existsSync as Je}from"fs";import*as P from"path";import{DEFAULT_MODELS as Qe}from"../config.js";var Xe=new Set(["node_modules",".git","dist","build",".next",".orchex","coverage",".turbo",".cache","__pycache__",".venv","venv"]),he=500;async function ge(n,t,e){if(e.length>=he)return;let s;try{s=await R.readdir(n,{withFileTypes:!0})}catch{return}for(let o of s){if(e.length>=he)break;if(Xe.has(o.name)||o.name.startsWith(".")&&o.name!==".env.example")continue;let r=P.join(n,o.name);o.isDirectory()?await ge(r,t,e):e.push(P.relative(t,r))}}async function we(n){let t=[];await ge(n,n,t);let e=t.sort().join(`
2
- `),s={};try{let r=await R.readFile(P.join(n,"package.json"),"utf-8");s=JSON.parse(r)}catch{}let o;try{let r=await R.readFile(P.join(n,"tsconfig.json"),"utf-8");o=JSON.parse(r)}catch{}return{fileTree:e,packageJson:s,tsconfig:o,existingFiles:t}}function Ze(n,t){let e=[],s=/(?:spec|plan|design|doc):\s*(\S+\.(?:md|txt|yaml|yml))/gi,o;for(;(o=s.exec(n))!==null;)e.push(o[1]);if(t&&e.length===0){let r=/(\S+\.(?:md|txt|yaml|yml))/gi;for(;(o=r.exec(n))!==null;){let i=o[1],a=P.join(t,i);Je(a)&&e.push(i)}}return e}function et(n,t,e){let s=[];if(s.push(`You are an expert software architect using orchex, a parallel AI orchestration tool.
1
+ import*as _ from"fs/promises";import{existsSync as et}from"fs";import*as P from"path";import{DEFAULT_MODELS as tt}from"../config.js";var nt=new Set(["node_modules",".git","dist","build",".next",".orchex","coverage",".turbo",".cache","__pycache__",".venv","venv"]),ge=500;async function we(n,t,e){if(e.length>=ge)return;let s;try{s=await _.readdir(n,{withFileTypes:!0})}catch{return}for(let o of s){if(e.length>=ge)break;if(nt.has(o.name)||o.name.startsWith(".")&&o.name!==".env.example")continue;let r=P.join(n,o.name);o.isDirectory()?await we(r,t,e):e.push(P.relative(t,r))}}async function ye(n){let t=[];await we(n,n,t);let e=t.sort().join(`
2
+ `),s={};try{let r=await _.readFile(P.join(n,"package.json"),"utf-8");s=JSON.parse(r)}catch{}let o;try{let r=await _.readFile(P.join(n,"tsconfig.json"),"utf-8");o=JSON.parse(r)}catch{}return{fileTree:e,packageJson:s,tsconfig:o,existingFiles:t}}function st(n,t){let e=[],s=/(?:spec|plan|design|doc):\s*(\S+\.(?:md|txt|yaml|yml))/gi,o;for(;(o=s.exec(n))!==null;)e.push(o[1]);if(t&&e.length===0){let r=/(\S+\.(?:md|txt|yaml|yml))/gi;for(;(o=r.exec(n))!==null;){let i=o[1],a=P.join(t,i);et(a)&&e.push(i)}}return e}function ot(n,t,e){let s=[];if(s.push(`You are an expert software architect using orchex, a parallel AI orchestration tool.
3
3
  Your task: generate a plan document in orchex format from the user's intent.
4
4
 
5
5
  ## Output Format Rules
@@ -34,7 +34,8 @@ streams:
34
34
  - The \`plan:\` field is the LLM's ENTIRE instruction set. Be specific and complete.
35
35
  - Do NOT create circular dependencies.
36
36
  - Keep streams small and focused \u2014 better to have more small streams than fewer large ones.
37
- - CRITICAL: No two streams can own the same file. Each file must have exactly one owner. If multiple tasks need to modify the same file (e.g., adding imports to index.ts), combine those tasks into a single stream. Prefer fewer, larger streams over ownership conflicts.`),s.push(`
37
+ - CRITICAL: No two streams can own the same file. Each file must have exactly one owner. If multiple tasks need to modify the same file (e.g., adding imports to index.ts), combine those tasks into a single stream. Prefer fewer, larger streams over ownership conflicts.
38
+ - For \`verify:\` commands: use \`npm run build\` for non-test streams that create/modify source code. Only use vitest/jest when the stream creates or modifies test files. Do NOT use vitest as a verify command for streams that only create config files (package.json, tsconfig.json, etc.).`),s.push(`
38
39
  ## User Intent
39
40
 
40
41
  ${n}`),s.push(`
@@ -52,12 +53,21 @@ ${JSON.stringify(i,null,2)}
52
53
 
53
54
  \`\`\`json
54
55
  ${JSON.stringify(t.tsconfig,null,2)}
55
- \`\`\``),e?.specContents&&Object.keys(e.specContents).length>0)for(let[i,a]of Object.entries(e.specContents)){let l=a.length>8e3?a.substring(0,8e3)+`
56
+ \`\`\``),e?.specContents&&Object.keys(e.specContents).length>0){for(let[i,a]of Object.entries(e.specContents)){let l=a.length>8e3?a.substring(0,8e3)+`
56
57
 
57
58
  [... truncated]`:a;s.push(`
58
59
  ## Referenced Document: ${i}
59
60
 
60
- ${l}`)}let o=[],r=t.packageJson?.files;if(Array.isArray(r)&&r.length>0&&o.push("- This is an npm package with an explicit `files` list in package.json. When creating new source files that compile to dist/, add their dist/ paths (e.g., `dist/new-module.js`, `dist/new-module.d.ts`) to the `files` array."),t.fileTree.split(`
61
+ ${l}`)}s.push(`
62
+ ## IMPORTANT: Referenced Document Fidelity
63
+
64
+ When a Referenced Document above contains:
65
+ - Exact code (function bodies, type definitions, imports) \u2014 use it **verbatim** in stream plans. Do NOT rewrite, rename, or reinterpret the code.
66
+ - Specific file paths \u2014 use those exact paths in \`owns:\` and \`reads:\`.
67
+ - Step-by-step tasks \u2014 map each task to a stream, preserving the document's structure.
68
+ - Type definitions (interfaces, enums, const arrays) \u2014 copy them exactly. Do NOT invent different field names, roles, or values.
69
+
70
+ The user has already designed the implementation. Your job is to decompose it into parallel streams, not to redesign it.`)}let o=[],r=t.packageJson?.files;if(Array.isArray(r)&&r.length>0&&o.push("- This is an npm package with an explicit `files` list in package.json. When creating new source files that compile to dist/, add their dist/ paths (e.g., `dist/new-module.js`, `dist/new-module.d.ts`) to the `files` array."),t.fileTree.split(`
61
71
  `).some(i=>i.startsWith("public/"))&&o.push("- The `public/` directory contains static assets served by Express. If the feature involves web-discoverable content (e.g., llms.txt, robots.txt), update files in public/."),t.fileTree.split(`
62
72
  `).some(i=>i==="src/index.ts")&&o.push("- If adding a new CLI subcommand, add its dispatch in src/index.ts and update the help text in the printHelp() function."),o.length>0&&s.push(`
63
73
  ## Project Conventions
@@ -74,33 +84,33 @@ NEVER exceed ${e.maxStreams} streams \u2014 the plan will be rejected if you do.
74
84
 
75
85
  Generate the plan document now. Output ONLY the markdown plan document \u2014 no preamble, no explanation.
76
86
  Start with \`# <Feature Title>\` and include all H2 stream sections with YAML blocks.`),s.join(`
77
- `)}async function tt(n,t,e,s){let o=await we(t),r=Ze(n,t),i={};for(let u of r)try{let d=P.join(t,u),f=await R.readFile(d,"utf-8");i[u]=f}catch{}let a=et(n,o,{specContents:Object.keys(i).length>0?i:void 0,maxStreams:s?.maxStreams});s?.extraContext&&(a+=`
87
+ `)}async function rt(n,t,e,s){let o=await ye(t),r=st(n,t),i={};for(let u of r)try{let d=P.join(t,u),f=await _.readFile(d,"utf-8");i[u]=f}catch{}let a=ot(n,o,{specContents:Object.keys(i).length>0?i:void 0,maxStreams:s?.maxStreams});s?.extraContext&&(a+=`
78
88
 
79
- `+s.extraContext);let l=await e.execute({prompt:a,model:s?.model??Qe[s?.provider??e.provider??"anthropic"]??"claude-sonnet-4-5-20250929",maxTokens:s?.maxTokens??16384,streamId:"_auto-plan"});if(!l.rawResponse?.trim())throw new Error(`Auto-plan generation failed: ${l.error??"Empty response from LLM"}`);let c=l.rawResponse.trim();return c.startsWith("```markdown")?(c=c.slice(11),c.endsWith("```")&&(c=c.slice(0,-3)),c=c.trim()):c.startsWith("```")&&(c=c.slice(3),c.endsWith("```")&&(c=c.slice(0,-3)),c=c.trim()),{planMarkdown:c,tokensUsed:l.tokensUsed}}import{createLogger as nt}from"../logging.js";var st=nt("plan-parser");function ot(n){return n.replace(/^```[\s\S]*?^```/gm,"")}function rt(n){let t=ot(n),e=[/`([^`]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))`/g,/"([^"]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))"/g,/\[([^\]]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))\]/g,/\b(src\/[^\s,)]+\.(ts|js|tsx|jsx))/g,/\b(tests?\/[^\s,)]+\.(ts|js|tsx|jsx))/g,/\b(docs\/[^\s,)]+\.md)/g],s=new Set;for(let r of e){r.lastIndex=0;let i;for(;(i=r.exec(t))!==null;){let a=i[1].trim();a&&!a.includes(" ")&&s.add(a)}}return[...s].filter(r=>{if(r.endsWith(".js")){let i=r.replace(/\.js$/,".ts");if(s.has(i))return!1}if(r.endsWith(".jsx")){let i=r.replace(/\.jsx$/,".tsx");if(s.has(i))return!1}return!0})}function it(n){let t=[/depends?\s+on\s+[`"]?([^`",.]+)[`"]?/gi,/requires?\s+[`"]?([^`",.]+)[`"]?/gi,/after\s+[`"]?([^`",.]+)[`"]?\s+(?:is\s+)?(?:complete|done|finished)/gi,/\bdeps?:\s*\[([^\]]+)\]/gi],e=new Set;for(let s of t){s.lastIndex=0;let o;for(;(o=s.exec(n))!==null;)if(s.source.includes("deps")){let r=o[1].split(",").map(i=>i.trim().replace(/[`"']/g,""));for(let i of r)i&&i.length>2&&i.length<50&&e.add(i)}else{let r=o[1].trim().replace(/\s+is$/i,"").replace(/[`"]/g,"");r&&r.length>2&&r.length<50&&e.add(r)}}return[...e]}function at(n){let t=[],e=n.replace(/\r\n/g,`
80
- `),s=/^```(\w+)?[ \t]*\n(?:\/\/\s*(\S+)\n)?([\s\S]*?)^```[ \t]*$/gm,o;for(;(o=s.exec(e))!==null;)t.push({language:o[1]||"text",filename:o[2],code:o[3].trim()});return t}function ct(n){let t=n.split(`
89
+ `+s.extraContext);let l=await e.execute({prompt:a,model:s?.model??tt[s?.provider??e.provider??"anthropic"]??"claude-sonnet-4-5-20250929",maxTokens:s?.maxTokens??16384,streamId:"_auto-plan"});if(!l.rawResponse?.trim())throw new Error(`Auto-plan generation failed: ${l.error??"Empty response from LLM"}`);let c=l.rawResponse.trim();return c.startsWith("```markdown")?(c=c.slice(11),c.endsWith("```")&&(c=c.slice(0,-3)),c=c.trim()):c.startsWith("```")&&(c=c.slice(3),c.endsWith("```")&&(c=c.slice(0,-3)),c=c.trim()),{planMarkdown:c,tokensUsed:l.tokensUsed}}import{createLogger as it}from"../logging.js";var at=it("plan-parser");function ct(n){return n.replace(/^```[\s\S]*?^```/gm,"")}function lt(n){let t=ct(n),e=[/`([^`]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))`/g,/"([^"]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))"/g,/\[([^\]]+\.(ts|js|tsx|jsx|md|sql|json|yaml|yml))\]/g,/\b(src\/[^\s,)]+\.(ts|js|tsx|jsx))/g,/\b(tests?\/[^\s,)]+\.(ts|js|tsx|jsx))/g,/\b(docs\/[^\s,)]+\.md)/g],s=new Set;for(let r of e){r.lastIndex=0;let i;for(;(i=r.exec(t))!==null;){let a=i[1].trim();a&&!a.includes(" ")&&s.add(a)}}return[...s].filter(r=>{if(r.endsWith(".js")){let i=r.replace(/\.js$/,".ts");if(s.has(i))return!1}if(r.endsWith(".jsx")){let i=r.replace(/\.jsx$/,".tsx");if(s.has(i))return!1}return!0})}function ut(n){let t=[/depends?\s+on\s+[`"]?([^`",.]+)[`"]?/gi,/requires?\s+[`"]?([^`",.]+)[`"]?/gi,/after\s+[`"]?([^`",.]+)[`"]?\s+(?:is\s+)?(?:complete|done|finished)/gi,/\bdeps?:\s*\[([^\]]+)\]/gi],e=new Set;for(let s of t){s.lastIndex=0;let o;for(;(o=s.exec(n))!==null;)if(s.source.includes("deps")){let r=o[1].split(",").map(i=>i.trim().replace(/[`"']/g,""));for(let i of r)i&&i.length>2&&i.length<50&&e.add(i)}else{let r=o[1].trim().replace(/\s+is$/i,"").replace(/[`"]/g,"");r&&r.length>2&&r.length<50&&e.add(r)}}return[...e]}function dt(n){let t=[],e=n.replace(/\r\n/g,`
90
+ `),s=/^```(\w+)?[ \t]*\n(?:\/\/\s*(\S+)\n)?([\s\S]*?)^```[ \t]*$/gm,o;for(;(o=s.exec(e))!==null;)t.push({language:o[1]||"text",filename:o[2],code:o[3].trim()});return t}function ft(n){let t=n.split(`
81
91
  `),e=[],s=[],o=[],r=!1;for(let a of t){if(a.startsWith("```")){r=!r,o.push(a);continue}if(r){o.push(a);continue}let l=a.match(/^(#{1,6})\s+(.+)$/);if(l){s.length>0&&(s[s.length-1].content=o.join(`
82
92
  `).trim()),o=[];let c=l[1].length,u=l[2].trim(),d={level:c,title:u,content:"",codeBlocks:[],fileReferences:[],explicitDeps:[],children:[]};for(;s.length>0&&s[s.length-1].level>=c;)s.pop();s.length>0?s[s.length-1].children.push(d):e.push(d),s.push(d)}else o.push(a)}s.length>0&&(s[s.length-1].content=o.join(`
83
- `).trim());function i(a){a.codeBlocks=at(a.content),a.fileReferences=rt(a.content),a.explicitDeps=it(a.content);for(let l of a.children)i(l)}for(let a of e)i(a);return e}function lt(n){let t=ct(n),e=t.find(l=>l.level===1)?.title??"Untitled Plan",o=t.find(l=>l.level===1)?.content.split(`
93
+ `).trim());function i(a){a.codeBlocks=dt(a.content),a.fileReferences=lt(a.content),a.explicitDeps=ut(a.content);for(let l of a.children)i(l)}for(let a of e)i(a);return e}function pt(n){let t=ft(n),e=t.find(l=>l.level===1)?.title??"Untitled Plan",o=t.find(l=>l.level===1)?.content.split(`
84
94
  `).slice(0,3).join(`
85
- `)??"",r=new Set,i=[];function a(l){for(let c of l.fileReferences)r.add(c);i.push(...l.codeBlocks);for(let c of l.children)a(c)}for(let l of t)a(l);return{title:e,description:o,sections:t,allFileReferences:[...r],allCodeBlocks:i}}function U(n,t){let e=[];function s(o){o.level===t&&e.push(o);for(let r of o.children)s(r)}for(let o of n)s(o);return e}function H(n){let t=[];function e(s){t.push(s);for(let o of s.children)e(o)}for(let s of n)e(s);return t}function ee(n){let t=n.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t:t.replace(/\s+#(?=\s|$).*/,"").trim()}function ut(n){let t={},e=n.split(`
95
+ `)??"",r=new Set,i=[];function a(l){for(let c of l.fileReferences)r.add(c);i.push(...l.codeBlocks);for(let c of l.children)a(c)}for(let l of t)a(l);return{title:e,description:o,sections:t,allFileReferences:[...r],allCodeBlocks:i}}function U(n,t){let e=[];function s(o){o.level===t&&e.push(o);for(let r of o.children)s(r)}for(let o of n)s(o);return e}function z(n){let t=[];function e(s){t.push(s);for(let o of s.children)e(o)}for(let s of n)e(s);return t}function ee(n){let t=n.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t:t.replace(/\s+#(?=\s|$).*/,"").trim()}function mt(n){let t={},e=n.split(`
86
96
  `),s=null,o=[],r=!1,i=!1,a=[];for(let l of e){if(r&&(l.startsWith(" ")||l.startsWith(" ")||l.trim()==="")){o.push(l.replace(/^ /,"").replace(/^\t/,""));continue}else r&&(s&&(t[s]=o.join(`
87
97
  `).trim()),r=!1,s=null,o=[]);if(i&&l.match(/^\s+-\s+/)){let u=l.replace(/^\s+-\s+/,"").trim();a.push(ee(u));continue}else i&&!l.match(/^\s+-\s+/)&&l.trim()!==""&&(s&&(t[s]=a),i=!1,s=null,a=[]);let c=l.match(/^([\w-]+):\s*(.*)$/);if(c){let[,u,d]=c;if(d.startsWith("[")&&d.endsWith("]")){let f=d.slice(1,-1).split(",").map(p=>ee(p).replace(/['"]/g,""));t[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}t[u]=ee(d).replace(/^["']|["']$/g,"")}}return r&&s&&(t[s]=o.join(`
88
- `).trim()),i&&s&&(t[s]=a),t}function dt(n){let t=n.split(`
98
+ `).trim()),i&&s&&(t[s]=a),t}function ht(n){let t=n.split(`
89
99
  `),e=[],s=t.findIndex(i=>/^streams:\s*$/.test(i));if(s===-1)return[];let o=null,r=[];for(let i=s+1;i<t.length;i++){let a=t[i],l=a.match(/^ ([\w-]+):\s*$/);if(l){o&&r.some(c=>c.trim())&&e.push({id:o,block:r.join(`
90
100
  `)}),o=l[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())&&e.push({id:o,block:r.join(`
91
- `)}),e}function ye(n,t){let e=ut(n),s=t??e.id??"",o=e.name??"";if(!s&&!o){st.warn({block:n.slice(0,100)},"Malformed YAML block skipped \u2014 no id or name found");return}let r={id:s,name:o};return e.deps&&(r.deps=Array.isArray(e.deps)?e.deps:[e.deps]),e.owns&&(r.owns=Array.isArray(e.owns)?e.owns:[e.owns]),e.reads&&(r.reads=Array.isArray(e.reads)?e.reads:[e.reads]),e.plan&&(r.plan=e.plan),e.verify&&(r.verify=Array.isArray(e.verify)?e.verify:[e.verify]),e.setup&&(r.setup=Array.isArray(e.setup)?e.setup:[e.setup]),r}function te(n){let t=[];for(let e of n.codeBlocks){if(e.language!=="yaml"&&e.language!=="yml")continue;let s=dt(e.code);if(s.length>0){for(let{id:r,block:i}of s){let a=ye(i,r);a&&t.push(a)}continue}if(!e.code.includes("id:")&&!e.code.includes("name:"))continue;let o=ye(e.code);o&&t.push(o)}return t}function ft(n){return n.includes("ORCHEX PLAN TEMPLATE")}import*as b from"fs/promises";import*as F from"path";import{createLogger as pt}from"../logging.js";var z=pt("learning-engine"),B={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},ne=20,mt=100,ht=50;function gt(n){return n>=mt?"high":n>=ht?"medium":"low"}function q(n,t){let e=`${n} ${t??""}`.toLowerCase();return e.includes("test")||e.includes("spec")?"test":e.includes("migration")||e.includes("migrate")||e.includes("refactor")||e.includes("restructure")?"migration":e.includes("integration")&&(e.includes("guide")||e.includes("doc"))?"integration-guide":e.includes("tutorial")||e.includes("getting-started")||e.includes("getting started")?"tutorial":e.includes("api")&&(e.includes("ref")||e.includes("doc"))?"api-reference":e.includes("doc")||e.includes("readme")||e.includes("md")||e.includes("guide")?"docs":"code"}function wt(n,t=ne){let e=[],s=[],o=n.filter(u=>(u.eventType==="stream_complete"||u.eventType==="stream_failed")&&u.contextTokensEstimated!==void 0);if(o.length<t)return{correlations:[],suggestedThresholds:{},insights:[`Not enough data for learning. Have ${o.length}, need ${t} 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=yt(o);a.optimalRange&&(e.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(e[e.length-1].recommendation));let l=xt(o);l.softViolationSuccessRate!==void 0&&e.push({factor:"softViolation",successRate:l.softViolationSuccessRate,sampleSize:l.softViolationCount,threshold:0,recommendation:l.softViolationSuccessRate<.7?"Soft limit violations have low success rate - consider lowering soft limit":"Soft limit violations acceptable - current threshold is appropriate"});let c=St(e,a,o.length);return{correlations:e,suggestedThresholds:c,insights:s,hasEnoughData:!0}}function yt(n){let t=[{min:0,max:5e4},{min:5e4,max:1e5},{min:1e5,max:15e4},{min:15e4,max:2e5}],e=t[0],s=0,o=0;for(let r of t){let i=n.filter(a=>a.contextTokensEstimated!==void 0&&a.contextTokensEstimated>=r.min&&a.contextTokensEstimated<r.max);if(i.length>=5){let l=i.filter(c=>c.eventType==="stream_complete").length/i.length;l>s&&(s=l,e=r,o=i.length)}}return{optimalRange:o>=5?e:void 0,optimalSuccessRate:s,optimalSampleSize:o}}function xt(n){let t=n.filter(s=>s.budgetViolationType==="soft"),e=n.filter(s=>s.budgetViolationType==="hard");return{softViolationCount:t.length,softViolationSuccessRate:t.length>=5?t.filter(s=>s.eventType==="stream_complete").length/t.length:void 0,hardViolationCount:e.length,hardViolationSuccessRate:e.length>=5?e.filter(s=>s.eventType==="stream_complete").length/e.length:void 0}}function St(n,t,e){let s={sampleCount:e,confidence:gt(e),lastUpdated:new Date().toISOString(),version:1};return t.optimalRange&&(s.globalSoftLimit=t.optimalRange.max,s.globalHardLimit=Math.round(t.optimalRange.max*1.3)),s}function vt(n,t,e=.3){if(!t.hasEnoughData)return n;let s={...n},o=t.suggestedThresholds;return o.globalSoftLimit!==void 0&&(s.globalSoftLimit=Math.round(n.globalSoftLimit*(1-e)+o.globalSoftLimit*e)),o.globalHardLimit!==void 0&&(s.globalHardLimit=Math.round(n.globalHardLimit*(1-e)+o.globalHardLimit*e)),o.sampleCount!==void 0&&(s.sampleCount=o.sampleCount),o.confidence!==void 0&&(s.confidence=o.confidence),s.lastUpdated=new Date().toISOString(),s}function xe(n){return F.join(n,".orchex","learn","thresholds.json")}async function $t(n,t){let e=xe(n),s=F.dirname(e);await b.mkdir(s,{recursive:!0}),await b.writeFile(e,JSON.stringify(t,null,2),"utf-8")}async function Ct(n){let t=xe(n);try{let e=await b.readFile(t,"utf-8"),s=JSON.parse(e);return s.version!==1?(z.warn({version:s.version},"unknown_thresholds_version"),null):s}catch{return null}}async function Se(n){return await Ct(n)??{...B}}function bt(n,t,e){switch(e){case"owns":return n.maxOwnsCount[t]??B.maxOwnsCount.other;case"reads":return n.maxReadsCount[t]??B.maxReadsCount.other;case"tokens":return n.maxContextTokens[t]??n.globalSoftLimit}}function ve(n){return F.join(n,".orchex","learn","events.jsonl")}function kt(n,t,e){return{id:`learn-${Date.now()}-${n.id}`,sessionHash:"local",eventType:n.status==="complete"?"stream_complete":"stream_failed",timestamp:new Date().toISOString(),durationMs:n.executionTimeMs,success:n.status==="complete",tokensInput:n.tokensUsed?.input,tokensOutput:n.tokensUsed?.output,provider:t,model:e,contextTokensEstimated:n.contextMetrics?.estimatedTokens,contextTokensActual:n.contextMetrics?.actualTokens,contextBudgetUtilization:n.contextMetrics?.budgetUtilization,budgetViolationType:n.contextMetrics?.violationType}}async function Tt(n,t){if(t.length===0)return;let e=ve(n),s=F.dirname(e);await b.mkdir(s,{recursive:!0});let o=t.map(r=>JSON.stringify(r)).join(`
101
+ `)}),e}function xe(n,t){let e=mt(n),s=t??e.id??"",o=e.name??"";if(!s&&!o){at.warn({block:n.slice(0,100)},"Malformed YAML block skipped \u2014 no id or name found");return}let r={id:s,name:o};return e.deps&&(r.deps=Array.isArray(e.deps)?e.deps:[e.deps]),e.owns&&(r.owns=Array.isArray(e.owns)?e.owns:[e.owns]),e.reads&&(r.reads=Array.isArray(e.reads)?e.reads:[e.reads]),e.plan&&(r.plan=e.plan),e.verify&&(r.verify=Array.isArray(e.verify)?e.verify:[e.verify]),e.setup&&(r.setup=Array.isArray(e.setup)?e.setup:[e.setup]),r}function te(n){let t=[];for(let e of n.codeBlocks){if(e.language!=="yaml"&&e.language!=="yml")continue;let s=ht(e.code);if(s.length>0){for(let{id:r,block:i}of s){let a=xe(i,r);a&&t.push(a)}continue}if(!e.code.includes("id:")&&!e.code.includes("name:"))continue;let o=xe(e.code);o&&t.push(o)}return t}function gt(n){return n.includes("ORCHEX PLAN TEMPLATE")}import*as T from"fs/promises";import*as F from"path";import{createLogger as wt}from"../logging.js";var H=wt("learning-engine"),B={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},ne=20,yt=100,xt=50;function St(n){return n>=yt?"high":n>=xt?"medium":"low"}function q(n,t){let e=`${n} ${t??""}`.toLowerCase();return e.includes("test")||e.includes("spec")?"test":e.includes("migration")||e.includes("migrate")||e.includes("refactor")||e.includes("restructure")?"migration":e.includes("integration")&&(e.includes("guide")||e.includes("doc"))?"integration-guide":e.includes("tutorial")||e.includes("getting-started")||e.includes("getting started")?"tutorial":e.includes("api")&&(e.includes("ref")||e.includes("doc"))?"api-reference":e.includes("doc")||e.includes("readme")||e.includes("md")||e.includes("guide")?"docs":"code"}function $t(n,t=ne){let e=[],s=[],o=n.filter(u=>(u.eventType==="stream_complete"||u.eventType==="stream_failed")&&u.contextTokensEstimated!==void 0);if(o.length<t)return{correlations:[],suggestedThresholds:{},insights:[`Not enough data for learning. Have ${o.length}, need ${t} 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=vt(o);a.optimalRange&&(e.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(e[e.length-1].recommendation));let l=Ct(o);l.softViolationSuccessRate!==void 0&&e.push({factor:"softViolation",successRate:l.softViolationSuccessRate,sampleSize:l.softViolationCount,threshold:0,recommendation:l.softViolationSuccessRate<.7?"Soft limit violations have low success rate - consider lowering soft limit":"Soft limit violations acceptable - current threshold is appropriate"});let c=bt(e,a,o.length);return{correlations:e,suggestedThresholds:c,insights:s,hasEnoughData:!0}}function vt(n){let t=[{min:0,max:5e4},{min:5e4,max:1e5},{min:1e5,max:15e4},{min:15e4,max:2e5}],e=t[0],s=0,o=0;for(let r of t){let i=n.filter(a=>a.contextTokensEstimated!==void 0&&a.contextTokensEstimated>=r.min&&a.contextTokensEstimated<r.max);if(i.length>=5){let l=i.filter(c=>c.eventType==="stream_complete").length/i.length;l>s&&(s=l,e=r,o=i.length)}}return{optimalRange:o>=5?e:void 0,optimalSuccessRate:s,optimalSampleSize:o}}function Ct(n){let t=n.filter(s=>s.budgetViolationType==="soft"),e=n.filter(s=>s.budgetViolationType==="hard");return{softViolationCount:t.length,softViolationSuccessRate:t.length>=5?t.filter(s=>s.eventType==="stream_complete").length/t.length:void 0,hardViolationCount:e.length,hardViolationSuccessRate:e.length>=5?e.filter(s=>s.eventType==="stream_complete").length/e.length:void 0}}function bt(n,t,e){let s={sampleCount:e,confidence:St(e),lastUpdated:new Date().toISOString(),version:1};return t.optimalRange&&(s.globalSoftLimit=t.optimalRange.max,s.globalHardLimit=Math.round(t.optimalRange.max*1.3)),s}function kt(n,t,e=.3){if(!t.hasEnoughData)return n;let s={...n},o=t.suggestedThresholds;return o.globalSoftLimit!==void 0&&(s.globalSoftLimit=Math.round(n.globalSoftLimit*(1-e)+o.globalSoftLimit*e)),o.globalHardLimit!==void 0&&(s.globalHardLimit=Math.round(n.globalHardLimit*(1-e)+o.globalHardLimit*e)),o.sampleCount!==void 0&&(s.sampleCount=o.sampleCount),o.confidence!==void 0&&(s.confidence=o.confidence),s.lastUpdated=new Date().toISOString(),s}function Se(n){return F.join(n,".orchex","learn","thresholds.json")}async function Tt(n,t){let e=Se(n),s=F.dirname(e);await T.mkdir(s,{recursive:!0}),await T.writeFile(e,JSON.stringify(t,null,2),"utf-8")}async function Et(n){let t=Se(n);try{let e=await T.readFile(t,"utf-8"),s=JSON.parse(e);return s.version!==1?(H.warn({version:s.version},"unknown_thresholds_version"),null):s}catch{return null}}async function $e(n){return await Et(n)??{...B}}function Ot(n,t,e){switch(e){case"owns":return n.maxOwnsCount[t]??B.maxOwnsCount.other;case"reads":return n.maxReadsCount[t]??B.maxReadsCount.other;case"tokens":return n.maxContextTokens[t]??n.globalSoftLimit}}function ve(n){return F.join(n,".orchex","learn","events.jsonl")}function Pt(n,t,e){return{id:`learn-${Date.now()}-${n.id}`,sessionHash:"local",eventType:n.status==="complete"?"stream_complete":"stream_failed",timestamp:new Date().toISOString(),durationMs:n.executionTimeMs,success:n.status==="complete",tokensInput:n.tokensUsed?.input,tokensOutput:n.tokensUsed?.output,provider:t,model:e,contextTokensEstimated:n.contextMetrics?.estimatedTokens,contextTokensActual:n.contextMetrics?.actualTokens,contextBudgetUtilization:n.contextMetrics?.budgetUtilization,budgetViolationType:n.contextMetrics?.violationType}}async function Mt(n,t){if(t.length===0)return;let e=ve(n),s=F.dirname(e);await T.mkdir(s,{recursive:!0});let o=t.map(r=>JSON.stringify(r)).join(`
92
102
  `)+`
93
- `;await b.appendFile(e,o,"utf-8")}async function Et(n){let t=ve(n);try{let e=await b.readFile(t,"utf-8"),s=[];for(let o of e.split(`
94
- `))if(o.trim())try{s.push(JSON.parse(o))}catch{}return s}catch{return[]}}async function Ot(n){let t=await Et(n);if(t.length<ne)return z.debug({eventCount:t.length,minRequired:ne},"learning_skipped_insufficient_data"),null;let e=wt(t);if(!e.hasEnoughData)return z.debug({insights:e.insights},"learning_insufficient_context_data"),e;let s=await Se(n),o=vt(s,e);return await $t(n,o),z.info({sampleCount:o.sampleCount,confidence:o.confidence,globalSoftLimit:o.globalSoftLimit,globalHardLimit:o.globalHardLimit},"learning_cycle_completed"),e}var Pt=["tests","migrations","docs","types","styles","core"],Mt=["types","migrations","styles","core","tests","docs"];function _t(n){let t=n.toLowerCase(),e=t.split("/").pop()??t;for(let s of Pt)switch(s){case"tests":if(t.includes("/test")||t.includes("/__tests__/")||e.includes(".test.")||e.includes(".spec.")||e.startsWith("test_")||e.endsWith("_test.ts")||e.endsWith("_test.js"))return"tests";break;case"migrations":if(t.includes("/migration")||e.includes("migration")||e.endsWith(".sql"))return"migrations";break;case"docs":if(t.endsWith(".md")||t.includes("/docs/")||t.includes("/documentation/"))return"docs";break;case"types":if(e.includes("types")||e.includes("schema")||e.includes("interface")||e==="index.d.ts")return"types";break;case"styles":if(t.endsWith(".css")||t.endsWith(".scss")||t.endsWith(".less")||t.endsWith(".sass")||t.includes("/styles/"))return"styles";break}return"core"}var It={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 Rt(n,t,e){let s=n.split(`
95
- `),o=It[t],r=e.map(a=>(a.split("/").pop()??a).toLowerCase().replace(/\.[^.]+$/,"")),i=s.filter(a=>{let l=a.toLowerCase();return!!(o.some(c=>l.includes(c))||r.some(c=>l.includes(c)))});return i.length>0?i.join(`
103
+ `;await T.appendFile(e,o,"utf-8")}async function It(n){let t=ve(n);try{let e=await T.readFile(t,"utf-8"),s=[];for(let o of e.split(`
104
+ `))if(o.trim())try{s.push(JSON.parse(o))}catch{}return s}catch{return[]}}async function Rt(n){let t=await It(n);if(t.length<ne)return H.debug({eventCount:t.length,minRequired:ne},"learning_skipped_insufficient_data"),null;let e=$t(t);if(!e.hasEnoughData)return H.debug({insights:e.insights},"learning_insufficient_context_data"),e;let s=await $e(n),o=kt(s,e);return await Tt(n,o),H.info({sampleCount:o.sampleCount,confidence:o.confidence,globalSoftLimit:o.globalSoftLimit,globalHardLimit:o.globalHardLimit},"learning_cycle_completed"),e}var _t=["tests","migrations","docs","types","styles","core"],Ft=["types","migrations","styles","core","tests","docs"];function jt(n){let t=n.toLowerCase(),e=t.split("/").pop()??t;for(let s of _t)switch(s){case"tests":if(t.includes("/test")||t.includes("/__tests__/")||e.includes(".test.")||e.includes(".spec.")||e.startsWith("test_")||e.endsWith("_test.ts")||e.endsWith("_test.js"))return"tests";break;case"migrations":if(t.includes("/migration")||e.includes("migration")||e.endsWith(".sql"))return"migrations";break;case"docs":if(t.endsWith(".md")||t.includes("/docs/")||t.includes("/documentation/"))return"docs";break;case"types":if(e.includes("types")||e.includes("schema")||e.includes("interface")||e==="index.d.ts")return"types";break;case"styles":if(t.endsWith(".css")||t.endsWith(".scss")||t.endsWith(".less")||t.endsWith(".sass")||t.includes("/styles/"))return"styles";break}return"core"}var At={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 Dt(n,t,e){let s=n.split(`
105
+ `),o=At[t],r=e.map(a=>(a.split("/").pop()??a).toLowerCase().replace(/\.[^.]+$/,"")),i=s.filter(a=>{let l=a.toLowerCase();return!!(o.some(c=>l.includes(c))||r.some(c=>l.includes(c)))});return i.length>0?i.join(`
96
106
  `):`${n}
97
107
 
98
- Files: ${e.join(", ")}`}function Ft(n,t){let e=n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return t?`${t}-${e}`:e}function Ce(n){let t=[],e=[],s=/^\s*[-*]?\s*(?:Create|Modify|Test):\s*`([^`]+)`/gim,o;for(;(o=s.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}let r=/\*\*(?:New\s+)?[Ff]ile:\*\*\s*`([^`]+)`/gi;for(;(o=r.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}let i=/^\s*[-*]?\s*(?:Reads?|Imports?):\s*`([^`]+)`/gim;for(;(o=i.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&e.push(a)}return{owned:t,reads:e}}function be(n,t){let e=new Set,s=new Set(t),o=/(?:import\s+(?:[\s\S]*?\s+from\s+)?|import\s*\()['"]([^'"]+)['"]/g,r=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(let i of n){let a=[],l;for(o.lastIndex=0;(l=o.exec(i.code))!==null;)a.push(l[1]);for(r.lastIndex=0;(l=r.exec(i.code))!==null;)a.push(l[1]);for(let c of a){let u=jt(c,i.filename);u&&(s.has(u)||t.some(d=>d.endsWith("/"+u))||e.add(u))}}return[...e]}function jt(n,t){if(!n.startsWith(".")&&!n.startsWith("src/")&&!n.startsWith("tests/")&&!n.startsWith("lib/")||n.startsWith("node:"))return null;let e;if(n.startsWith(".")){if(!t)return null;let s=t.split("/");s.pop();let o=s.join("/"),r=[...o?o.split("/"):[]];for(let i of n.split("/"))i!=="."&&(i===".."?r.pop():r.push(i));e=r.join("/")}else e=n;return e.endsWith(".js")&&(e=e.replace(/\.js$/,".ts")),e.includes(".")||(e=e+".ts"),e}function At(n,t){let e=new Set,s=new Set,o=n.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=L(n),i=ke(r),a=Ce(i);for(let d of a.owned)s.has(d)||e.add(d);let l=V(n,t);for(let d of l)d.filename&&d.filename.includes(".")&&!s.has(d.filename)&&e.add(d.filename);let c=/owns:\s*\[([^\]]+)\]/gi,u;for(;(u=c.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)&&e.add(f)}return[...e]}function ke(n){return n.replace(/^```[^\n]*\n[\s\S]*?^```\s*$/gm,"")}function L(n){let t=n.content;for(let e of n.children)t+=`
108
+ Files: ${e.join(", ")}`}function Lt(n,t){let e=n.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return t?`${t}-${e}`:e}function be(n){let t=[],e=[],s=/^\s*[-*]?\s*(?:Create|Modify|Test):\s*`([^`]+)`/gim,o;for(;(o=s.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}let r=/\*\*(?:New\s+)?[Ff]ile:\*\*\s*`([^`]+)`/gi;for(;(o=r.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&t.push(a)}let i=/^\s*[-*]?\s*(?:Reads?|Imports?):\s*`([^`]+)`/gim;for(;(o=i.exec(n))!==null;){let a=o[1].replace(/:\d+(-\d+)?$/,"").trim();a&&a.includes(".")&&e.push(a)}return{owned:t,reads:e}}function ke(n,t){let e=new Set,s=new Set(t),o=/(?:import\s+(?:[\s\S]*?\s+from\s+)?|import\s*\()['"]([^'"]+)['"]/g,r=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(let i of n){let a=[],l;for(o.lastIndex=0;(l=o.exec(i.code))!==null;)a.push(l[1]);for(r.lastIndex=0;(l=r.exec(i.code))!==null;)a.push(l[1]);for(let c of a){let u=Nt(c,i.filename);u&&(s.has(u)||t.some(d=>d.endsWith("/"+u))||e.add(u))}}return[...e]}function Nt(n,t){if(!n.startsWith(".")&&!n.startsWith("src/")&&!n.startsWith("tests/")&&!n.startsWith("lib/")||n.startsWith("node:"))return null;let e;if(n.startsWith(".")){if(!t)return null;let s=t.split("/");s.pop();let o=s.join("/"),r=[...o?o.split("/"):[]];for(let i of n.split("/"))i!=="."&&(i===".."?r.pop():r.push(i));e=r.join("/")}else e=n;return e.endsWith(".js")&&(e=e.replace(/\.js$/,".ts")),e.includes(".")||(e=e+".ts"),e}function Wt(n,t){let e=new Set,s=new Set,o=n.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=L(n),i=Te(r),a=be(i);for(let d of a.owned)s.has(d)||e.add(d);let l=V(n,t);for(let d of l)d.filename&&d.filename.includes(".")&&!s.has(d.filename)&&e.add(d.filename);let c=/owns:\s*\[([^\]]+)\]/gi,u;for(;(u=c.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)&&e.add(f)}return[...e]}function Te(n){return n.replace(/^```[^\n]*\n[\s\S]*?^```\s*$/gm,"")}function L(n){let t=n.content;for(let e of n.children)t+=`
99
109
  `+e.title+`
100
- `+L(e);return t}function V(n,t){let e=[...t];for(let s of n.children){e.push(...s.codeBlocks);for(let o of s.children)e.push(...V(o,[]))}return e}function Dt(n){let t=n.split(`
101
- `);for(let e of t){let s=e.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 Lt(n,t,e=3e3){let s=L(n);if(s.length<=e||n.children.length<3)return s.slice(0,e);let o=[],r=n.content.trim();r&&o.push(r.slice(0,300));for(let l=0;l<n.children.length;l++){let c=n.children[l],u=c.title,d=Dt(c.content),p=(c.fileReferences||[]).filter(h=>t.includes(h)),m=`${l+1}. ${u}`;p.length>0&&(m+=` (${p.join(", ")})`),d&&(m+=` \u2014 ${d}`),o.push(m)}let i=0,a=[];for(let l of o){if(i+l.length+1>e&&a.length>0)break;a.push(l),i+=l.length+1}return a.join(`
102
- `)}function Nt(n,t){let e=new Set,s=L(n),o=ke(s),r=o.match(/reads:\s*\[([^\]]+)\]/i);if(r){let c=r[1].split(",").map(u=>u.trim().replace(/[`"']/g,""));for(let u of c)u&&u.includes(".")&&!t.includes(u)&&e.add(u)}let i=Ce(o);for(let c of i.reads)t.includes(c)||e.add(c);let a=V(n,n.codeBlocks),l=be(a,t);for(let c of l)t.includes(c)||e.add(c);return[...e]}function Te(n){let t=new Map;for(let e of n){let s=_t(e);t.has(s)||t.set(s,[]),t.get(s).push(e)}return t}function Ee(n){if(n._fromYaml)return{split:!1,reasons:[]};let e=[];n.ownedFiles.length>4&&e.push(`Owns ${n.ownedFiles.length} files (max recommended: 4)`);let s=(n.description.match(/\band\b/gi)??[]).length;if(s>2&&e.push(`Description has ${s} "and" conjunctions (suggests multiple tasks)`),n.ownedFiles.length>1){let o=Te(n.ownedFiles);if(o.size>1){let r=[...o.keys()].join(", ");e.push(`Files belong to ${o.size} different concerns (${r})`)}}return{split:e.length>0,reasons:e}}function Wt(n){let t=q(n.name,n.plan||"");return{id:n.id,name:n.name,description:n.plan||"",category:t,ownedFiles:n.owns||[],readFiles:n.reads||[],explicitDeps:n.deps||[],codeExamples:[],isAtomic:!0,_fromYaml:!0,_verify:n.verify,_setup:n.setup}}function Ut(n,t,e){let s=[],o=H(n.sections);for(let r of o){let i=te(r);if(e){let a=r.codeBlocks.filter(l=>l.language==="yaml"||l.language==="yml");e.yamlBlocksFound+=a.length,e.yamlBlocksParsed+=i.length}for(let a of i){t&&!a.id.startsWith(t)&&(a.id=`${t}-${a.id}`);let l=Wt(a),c=Ee(l);c.split&&(l.isAtomic=!1,l.suggestedSplit=c.reasons),s.push(l)}}return s}function Ht(n){let t=H(n.sections);for(let e of t)if(te(e).length>0)return!0;return!1}function zt(n){if(["test plan","implementation order","security checklist","gap inventory","task order","dependency order","execution order","deployment order","wave order"].some(r=>n.includes(r)))return!0;let e=["checklist","inventory","roadmap","timeline","schedule"],s=n.split(/[\s:]+/).filter(r=>r.length>0),o=s[s.length-1]??"";return!!e.includes(o)}function Bt(n,t={}){let{deliverableLevel:e=2,prefix:s,preferYaml:o=!0,diagnostics:r}=t;if(o&&Ht(n)){r&&(r.extractionPath="yaml");let c=Ut(n,s,r);return r&&(r.deliverableCount=c.length),c}if(r){let c=H(n.sections);for(let u of c)r.yamlBlocksFound+=u.codeBlocks.filter(d=>d.language==="yaml"||d.language==="yml").length;r.extractionPath="markdown"}let i=[],a=U(n.sections,e);if(r)for(let c of[2,3,4])r.sectionsFound[c]=U(n.sections,c).length;for(let c of a){let g=function(_){for(let I of _.fileReferences)m.includes(I)||h.includes(I)||T&&!O.has(I)||h.push(I);for(let I of _.children)g(I)};var l=g;let u=c.title.toLowerCase(),f=u.split(/[\s:]+/).filter(_=>_.length>0)[0]??"";if(u.includes("overview")&&a.indexOf(c)===0||f==="summary"||u==="summary: task order"||f==="conclusion"||f==="introduction"||f==="context"||f==="background"||f==="appendix"||f==="references"||f==="changelog"||f==="prerequisites"||zt(u)){r&&r.sectionsFilteredAsMeta.push(c.title);continue}let p=Ft(c.title,s),m=At(c,c.codeBlocks),h=Nt(c,m),y=V(c,c.codeBlocks),O=new Set(be(y,m)),T=O.size>0;for(let _ of c.children)g(_);let w=L(c),x=q(c.title,w),S={id:p,name:c.title,description:Lt(c,m),category:x,ownedFiles:m,readFiles:h,explicitDeps:c.explicitDeps,codeExamples:y,isAtomic:!0,childCount:c.children.length},me=Ee(S);me.split&&(S.isAtomic=!1,S.suggestedSplit=me.reasons),i.push(S)}return r&&(r.deliverableCount=i.length),i}function qt(n,t){let e=(n.language||"").toLowerCase(),s=n.code.toLowerCase();switch(t){case"migrations":return e==="sql"||s.includes("create table")||s.includes("alter table");case"types":return(e==="typescript"||e==="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 e==="markdown"||e==="md";case"styles":return e==="css"||e==="scss"||e==="less"||e==="sass";case"core":return(e==="typescript"||e==="ts"||e==="javascript"||e==="js")&&!s.includes("export type ")&&!s.includes("export interface ")&&!s.includes("describe(")&&!s.includes("it(");default:return!1}}function Vt(n){if(n._fromYaml)return[{...n,isAtomic:!0}];let e=Te(n.ownedFiles);if(e.size<=1)return[{...n,isAtomic:!0}];let s=[],o=null,r=0;for(let i of Mt){let a=e.get(i);if(!a||a.length===0)continue;r++;let l=`${n.id}-${i}`,c=`${n.name} (${i})`,u=Rt(n.description,i,a),d=[];r===1&&n.explicitDeps.length>0&&d.push(...n.explicitDeps),o&&d.push(o);let f=[];switch(i){case"types":break;case"core":case"migrations":f=[...n.readFiles];break;case"tests":f=[...e.get("core")||[]];break;case"docs":f=[...e.get("core")||e.get("types")||[]];break}let p=n.codeExamples.filter(m=>m.filename&&a.some(h=>m.filename===h)?!0:m.filename?!1:qt(m,i));s.push({id:l,name:c,description:u,category:n.category,ownedFiles:a,readFiles:f,explicitDeps:d,codeExamples:p,isAtomic:!0}),o=l}return s}function Yt(n){let t=[];for(let e of n)e.isAtomic?t.push(e):t.push(...Vt(e));return t}function $e(n){let t=[];return t.push(`${n.id}:`),t.push(` Name: ${n.name}`),t.push(` Category: ${n.category}`),t.push(` Owns: ${n.ownedFiles.join(", ")||"(none)"}`),n.readFiles.length>0&&t.push(` Reads: ${n.readFiles.join(", ")}`),n.explicitDeps.length>0&&t.push(` Deps: ${n.explicitDeps.join(", ")}`),n.isAtomic||t.push(` \u26A0\uFE0F Should split: ${n.suggestedSplit?.join("; ")}`),t.join(`
103
- `)}function Gt(n){let t=n.filter(o=>o.isAtomic),e=n.filter(o=>!o.isAtomic),s=`=== Deliverables Report ===
110
+ `+L(e);return t}function V(n,t){let e=[...t];for(let s of n.children){e.push(...s.codeBlocks);for(let o of s.children)e.push(...V(o,[]))}return e}function Ut(n){let t=n.split(`
111
+ `);for(let e of t){let s=e.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 zt(n,t,e=3e3){let s=L(n);if(s.length<=e||n.children.length<3)return s.slice(0,e);let o=[],r=n.content.trim();r&&o.push(r.slice(0,300));for(let l=0;l<n.children.length;l++){let c=n.children[l],u=c.title,d=Ut(c.content),p=(c.fileReferences||[]).filter(g=>t.includes(g)),m=`${l+1}. ${u}`;p.length>0&&(m+=` (${p.join(", ")})`),d&&(m+=` \u2014 ${d}`),o.push(m)}let i=0,a=[];for(let l of o){if(i+l.length+1>e&&a.length>0)break;a.push(l),i+=l.length+1}return a.join(`
112
+ `)}function Ht(n,t){let e=new Set,s=L(n),o=Te(s),r=o.match(/reads:\s*\[([^\]]+)\]/i);if(r){let c=r[1].split(",").map(u=>u.trim().replace(/[`"']/g,""));for(let u of c)u&&u.includes(".")&&!t.includes(u)&&e.add(u)}let i=be(o);for(let c of i.reads)t.includes(c)||e.add(c);let a=V(n,n.codeBlocks),l=ke(a,t);for(let c of l)t.includes(c)||e.add(c);return[...e]}function Ee(n){let t=new Map;for(let e of n){let s=jt(e);t.has(s)||t.set(s,[]),t.get(s).push(e)}return t}function Oe(n){if(n._fromYaml)return{split:!1,reasons:[]};let e=[];n.ownedFiles.length>4&&e.push(`Owns ${n.ownedFiles.length} files (max recommended: 4)`);let s=(n.description.match(/\band\b/gi)??[]).length;if(s>2&&e.push(`Description has ${s} "and" conjunctions (suggests multiple tasks)`),n.ownedFiles.length>1){let o=Ee(n.ownedFiles);if(o.size>1){let r=[...o.keys()].join(", ");e.push(`Files belong to ${o.size} different concerns (${r})`)}}return{split:e.length>0,reasons:e}}function Bt(n){let t=q(n.name,n.plan||"");return{id:n.id,name:n.name,description:n.plan||"",category:t,ownedFiles:n.owns||[],readFiles:n.reads||[],explicitDeps:n.deps||[],codeExamples:[],isAtomic:!0,_fromYaml:!0,_verify:n.verify,_setup:n.setup}}function qt(n,t,e){let s=[],o=z(n.sections);for(let r of o){let i=te(r);if(e){let a=r.codeBlocks.filter(l=>l.language==="yaml"||l.language==="yml");e.yamlBlocksFound+=a.length,e.yamlBlocksParsed+=i.length}for(let a of i){t&&!a.id.startsWith(t)&&(a.id=`${t}-${a.id}`);let l=Bt(a),c=Oe(l);c.split&&(l.isAtomic=!1,l.suggestedSplit=c.reasons),s.push(l)}}return s}function Vt(n){let t=z(n.sections);for(let e of t)if(te(e).length>0)return!0;return!1}function Yt(n){if(["test plan","implementation order","security checklist","gap inventory","task order","dependency order","execution order","deployment order","wave order"].some(r=>n.includes(r)))return!0;let e=["checklist","inventory","roadmap","timeline","schedule"],s=n.split(/[\s:]+/).filter(r=>r.length>0),o=s[s.length-1]??"";return!!e.includes(o)}function Gt(n,t={}){let{deliverableLevel:e=2,prefix:s,preferYaml:o=!0,diagnostics:r}=t;if(o&&Vt(n)){r&&(r.extractionPath="yaml");let c=qt(n,s,r);return r&&(r.deliverableCount=c.length),c}if(r){let c=z(n.sections);for(let u of c)r.yamlBlocksFound+=u.codeBlocks.filter(d=>d.language==="yaml"||d.language==="yml").length;r.extractionPath="markdown"}let i=[],a=U(n.sections,e);if(r)for(let c of[2,3,4])r.sectionsFound[c]=U(n.sections,c).length;for(let c of a){let S=function(I){for(let R of I.fileReferences)m.includes(R)||g.includes(R)||k&&!v.has(R)||g.push(R);for(let R of I.children)S(R)};var l=S;let u=c.title.toLowerCase(),f=u.split(/[\s:]+/).filter(I=>I.length>0)[0]??"";if(u.includes("overview")&&a.indexOf(c)===0||f==="summary"||u==="summary: task order"||f==="conclusion"||f==="introduction"||f==="context"||f==="background"||f==="appendix"||f==="references"||f==="changelog"||f==="prerequisites"||Yt(u)){r&&r.sectionsFilteredAsMeta.push(c.title);continue}let p=Lt(c.title,s),m=Wt(c,c.codeBlocks),g=Ht(c,m),y=V(c,c.codeBlocks),v=new Set(ke(y,m)),k=v.size>0;for(let I of c.children)S(I);let x=L(c),h=q(c.title,x),w={id:p,name:c.title,description:zt(c,m),category:h,ownedFiles:m,readFiles:g,explicitDeps:c.explicitDeps,codeExamples:y,isAtomic:!0,childCount:c.children.length},he=Oe(w);he.split&&(w.isAtomic=!1,w.suggestedSplit=he.reasons),i.push(w)}return r&&(r.deliverableCount=i.length),i}function Kt(n,t){let e=(n.language||"").toLowerCase(),s=n.code.toLowerCase();switch(t){case"migrations":return e==="sql"||s.includes("create table")||s.includes("alter table");case"types":return(e==="typescript"||e==="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 e==="markdown"||e==="md";case"styles":return e==="css"||e==="scss"||e==="less"||e==="sass";case"core":return(e==="typescript"||e==="ts"||e==="javascript"||e==="js")&&!s.includes("export type ")&&!s.includes("export interface ")&&!s.includes("describe(")&&!s.includes("it(");default:return!1}}function Jt(n){if(n._fromYaml)return[{...n,isAtomic:!0}];let e=Ee(n.ownedFiles);if(e.size<=1)return[{...n,isAtomic:!0}];let s=[],o=null,r=0;for(let i of Ft){let a=e.get(i);if(!a||a.length===0)continue;r++;let l=`${n.id}-${i}`,c=`${n.name} (${i})`,u=Dt(n.description,i,a),d=[];r===1&&n.explicitDeps.length>0&&d.push(...n.explicitDeps),o&&d.push(o);let f=[];switch(i){case"types":break;case"core":case"migrations":f=[...n.readFiles];break;case"tests":f=[...e.get("core")||[]];break;case"docs":f=[...e.get("core")||e.get("types")||[]];break}let p=n.codeExamples.filter(m=>m.filename&&a.some(g=>m.filename===g)?!0:m.filename?!1:Kt(m,i));s.push({id:l,name:c,description:u,category:n.category,ownedFiles:a,readFiles:f,explicitDeps:d,codeExamples:p,isAtomic:!0}),o=l}return s}function Qt(n){let t=[];for(let e of n)e.isAtomic?t.push(e):t.push(...Jt(e));return t}function Ce(n){let t=[];return t.push(`${n.id}:`),t.push(` Name: ${n.name}`),t.push(` Category: ${n.category}`),t.push(` Owns: ${n.ownedFiles.join(", ")||"(none)"}`),n.readFiles.length>0&&t.push(` Reads: ${n.readFiles.join(", ")}`),n.explicitDeps.length>0&&t.push(` Deps: ${n.explicitDeps.join(", ")}`),n.isAtomic||t.push(` \u26A0\uFE0F Should split: ${n.suggestedSplit?.join("; ")}`),t.join(`
113
+ `)}function Xt(n){let t=n.filter(o=>o.isAtomic),e=n.filter(o=>!o.isAtomic),s=`=== Deliverables Report ===
104
114
 
105
115
  `;if(s+=`Total: ${n.length} deliverables
106
116
  `,s+=` ${t.length} atomic (ready for streams)
@@ -108,26 +118,28 @@ Files: ${e.join(", ")}`}function Ft(n,t){let e=n.toLowerCase().replace(/[^a-z0-9
108
118
 
109
119
  `,e.length>0){s+=`--- Needs Splitting ---
110
120
 
111
- `;for(let o of e)s+=$e(o)+`
121
+ `;for(let o of e)s+=Ce(o)+`
112
122
 
113
123
  `}s+=`--- Atomic Deliverables ---
114
124
 
115
- `;for(let o of t)s+=$e(o)+`
125
+ `;for(let o of t)s+=Ce(o)+`
116
126
 
117
- `;return s}var Oe=["-types","-migrations","-core","-tests","-docs"];function se(n,t){let e=Oe.find(a=>n.id.endsWith(a));if(!e)return n;let s=n.id.slice(0,-e.length),o=t.filter(a=>Oe.some(l=>a.id===`${s}${l}`));if(o.length<=1)return n;let r=o.find(a=>a.id===`${s}-core`);if(r)return r;let i=["-migrations","-types"];for(let a of i){let l=o.find(c=>c.id===`${s}${a}`);if(l)return l}return n}function Kt(n,t){let e=n.toLowerCase().trim(),s=t.find(l=>l.id===n);if(s)return s;let o=t.find(l=>l.name.toLowerCase()===e);if(o)return se(o,t);let r=t.find(l=>l.id.includes(e)||e.includes(l.id));if(r)return se(r,t);let i=e.split(/[\s-_]+/).filter(l=>l.length>2),a=t.find(l=>{let c=l.name.toLowerCase().split(/[\s-_]+/);return i.filter(d=>c.some(f=>f.includes(d)||d.includes(f))).length>=i.length*.5});if(a)return se(a,t)}function Jt(n){let t=`${n.name} ${n.description}`.toLowerCase();return/\b(cleanup|clean\s*up|remove|delete|drop)\b/.test(t)}function Qt(n){let t=[],e=new Map;for(let r of n)if(!Jt(r))for(let i of r.ownedFiles)e.set(i,r);for(let r of n)for(let i of r.readFiles){let a=e.get(i);a&&a.id!==r.id&&t.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(t.map(r=>`${r.from}\u2192${r.to}`)),o=new Set;for(let r of t){let i=`${r.to}\u2192${r.from}`;s.has(i)&&(o.add(`${r.from}\u2192${r.to}`),o.add(i))}return t.filter(r=>!o.has(`${r.from}\u2192${r.to}`))}function Xt(n){let t=[];for(let e of n){if(e.category==="test"){let s=e.id.replace(/-tests?$/,"").replace(/^tests?-/,""),o=n.find(r=>r.id!==e.id&&r.category==="code"&&(r.id===s||r.id===`${s}-core`||r.id===`${s}-service`||r.id===`${s}-implementation`));o&&t.push({from:e.id,to:o.id,reason:"content-pattern",explanation:`${e.id} (test) depends on ${o.id} (implementation)`})}if(e.category==="docs"||e.category==="tutorial"){let s=e.id.replace(/^docs?-/,"").replace(/-docs?$/,"").replace(/^tutorials?-/,"").replace(/-tutorials?$/,""),o=n.filter(i=>i.id!==e.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&&t.push({from:e.id,to:r.id,reason:"content-pattern",explanation:`${e.id} (${e.category}) documents ${r.id}`})}}return t}function Zt(n,t){let e=[];for(let s of n)for(let o of s.explicitDeps){let r=Kt(o,n);if(r&&r.id!==s.id)e.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}'`;t?.diagnostics?.unmatchedDeps.push(i),t?.diagnostics?.warnings.push(i)}}return e}function Pe(n){let t=[],e=new Set,s=new Set,o=[];function r(i){e.add(i),s.add(i),o.push(i);let a=n.get(i)||[];for(let l of a)if(!e.has(l))r(l);else if(s.has(l)){let c=o.indexOf(l);if(c!==-1){let u=[...o.slice(c),l];t.push(u)}}o.pop(),s.delete(i)}for(let i of n.keys())e.has(i)||r(i);return t}function en(n,t,e){let s=0,o=new Set;for(let r of n){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=t.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 c=a.reduce((f,p)=>{let m=e.get(f.from)?.length??0,h=e.get(p.from)?.length??0;return h<m||h===m&&p.from<f.from?p:f}),u=t.indexOf(c);u!==-1&&t.splice(u,1);let d=e.get(c.from);if(d){let f=d.indexOf(c.to);f!==-1&&d.splice(f,1)}o.add(`${c.from}\u2192${c.to}`),s++}return{broken:s}}function tn(n,t){let e=[...Zt(n,t),...Qt(n),...Xt(n)],s=new Set,o=[];for(let a of e){let l=`${a.from}\u2192${a.to}`;s.has(l)||(s.add(l),o.push(a))}let r=new Map;for(let a of n)r.set(a.id,[]);for(let a of o){let l=r.get(a.from)||[];l.includes(a.to)||l.push(a.to),r.set(a.from,l)}let i=Pe(r);if(i.length>0){let{broken:a}=en(i,o,r);a>0&&(i=Pe(r))}return{dependencies:r,edges:o,cycles:i,isAcyclic:i.length===0}}function nn(n){let t=["=== Dependency Analysis ===",""];if(t.push(`Total edges: ${n.edges.length}`),t.push(`Acyclic: ${n.isAcyclic?"Yes \u2713":"No \u26A0\uFE0F"}`),n.cycles.length>0){t.push(""),t.push("--- Cycles Detected ---");for(let e of n.cycles)t.push(` ${e.join(" \u2192 ")}`)}t.push(""),t.push("--- Dependencies by Deliverable ---");for(let[e,s]of n.dependencies)s.length>0&&t.push(`${e}: ${s.join(", ")}`);t.push(""),t.push("--- Edge Details ---");for(let e of n.edges)t.push(`${e.from} \u2192 ${e.to} (${e.reason})`),t.push(` ${e.explanation}`);return t.join(`
118
- `)}import*as $ from"node:fs";import*as v from"node:path";var Me={maxOwnsCount:4,maxReadsCount:4,maxDirectories:2,maxPlanConjunctions:4,warnOnMixedActions:!0,warnOnMixedFileTypes:!0,requireVerifyCommands:!0},oe=class{config;constructor(t=Me){this.config=t}analyzeStream(t,e){let s=[],o=e.owns||[],r=e.reads||[],i=e.plan||"",a=e.verify||[],l=o.length,c=r.length,u=this.countDirectories(o),d=this.countConjunctions(i),f=a.length,p=this.detectActionTypes(i),m=this.detectFileTypes([...o,...r]),h={ownsCount:l,readsCount:c,directoriesAffected:u,planConjunctions:d,verifyCommands:f,actionTypes:p,fileTypes:m};l>this.config.maxOwnsCount&&u>this.config.maxDirectories?s.push({type:"high_owns_complexity",severity:"error",message:`Stream owns ${l} files across ${u} directories`,details:`Consider splitting into smaller streams. Threshold: ${this.config.maxOwnsCount} files across ${this.config.maxDirectories} directories`,streamName:t}):l>this.config.maxOwnsCount&&s.push({type:"high_owns_count",severity:"warning",message:`Stream owns ${l} files (threshold: ${this.config.maxOwnsCount})`,details:"Consider splitting into smaller, more focused streams",streamName:t}),c>this.config.maxReadsCount&&s.push({type:"high_reads_count",severity:"warning",message:`Stream reads ${c} files (threshold: ${this.config.maxReadsCount})`,details:"Too many dependencies may indicate unclear scope or context bloat",streamName:t}),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:t}),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:t}),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:t}),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:t}),this.config.requireVerifyCommands&&f===0&&l>0&&s.push({type:"no_verify",severity:"warning",message:"Stream has no verify commands",details:"Add verify commands to ensure implementation correctness",streamName:t}),(!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:t}),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:t});let y=this.calculateQualityScore(s,h);return{streamName:t,qualityScore:y,issues:s,metrics:h}}analyzeStreams(t){let e=[];for(let[r,i]of Object.entries(t))e.push(this.analyzeStream(r,i));let s=this.countIssuesBySeverity(e),o=this.calculateOverallScore(e);return{streams:e,overallScore:o,totalIssues:s}}countDirectories(t){let e=new Set;for(let s of t){let o=s.substring(0,s.lastIndexOf("/"));o?e.add(o):e.add(".")}return e.size}countConjunctions(t){let s=t.toLowerCase().match(/\band\b/g);return s?s.length:0}detectActionTypes(t){let e=t.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(e)&&s.push(r);return s}detectFileTypes(t){let e=new Set;for(let s of t){let o=s.substring(s.lastIndexOf(".")+1).toLowerCase();o&&o!==s&&e.add(o)}return e}hasMixedActions(t){let e=["create","delete","configure"],s=["update","document"],o=t.some(i=>e.includes(i)),r=t.some(i=>s.includes(i));return o&&r}hasUnboundedTutorial(t,e){let s=t.toLowerCase();return/\b(tutorial|guide|documentation|example)\b/.test(s)&&e.length===0}hasVaguePlan(t){let e=t.toLowerCase(),s=["various","some","multiple","general","misc","other","stuff","things"];for(let o of s)if(e.includes(o))return!0;return t.trim().split(/\s+/).length<5}calculateQualityScore(t,e){let s=100;for(let o of t)switch(o.severity){case"error":s-=20;break;case"warning":s-=10;break;case"info":s-=5;break}return e.verifyCommands>0&&(s+=5),e.ownsCount>0&&e.ownsCount<=3&&(s+=5),e.planConjunctions===0&&(s+=5),Math.max(0,Math.min(100,s))}calculateOverallScore(t){if(t.length===0)return 0;let e=t.reduce((s,o)=>s+o.qualityScore,0);return Math.round(e/t.length)}countIssuesBySeverity(t){let e={errors:0,warnings:0,info:0};for(let s of t)for(let o of s.issues)switch(o.severity){case"error":e.errors++;break;case"warning":e.warnings++;break;case"info":e.info++;break}return e}};function N(n){return new oe({...Me,...n})}import{createLogger as sn}from"../logging.js";var on=sn("topology-optimizer");function rn(n){let t=new Map,e=[...n.keys()];function s(o,r){let i=new Set,a=[o];for(;a.length>0;){let l=a.shift();if(!i.has(l)){i.add(l);for(let c of n.get(l)??[])c!==r&&!i.has(c)&&a.push(c)}}return i}for(let o of e){let r=n.get(o)??[],i=[];for(let a of r){let l=r.filter(u=>u!==a),c=!1;for(let u of l)if(s(u,o).has(a)){c=!0;break}c||i.push(a)}t.set(o,i)}return t}function an(n){let t=new Map,e=new Map;for(let r of n){t.set(r.id,r.deps.length);for(let i of r.deps)e.has(i)||e.set(i,[]),e.get(i).push(r.id);e.has(r.id)||e.set(r.id,[])}let s=n.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 e.get(r)??[])t.set(i,(t.get(i)??1)-1),t.get(i)===0&&s.push(i)}return o===n.length}function cn(n){let t=[],e=new Set,s=new Map(n.map(o=>[o.id,[...o.deps]]));for(;s.size>0;){let o=[];for(let[r,i]of s)i.every(a=>e.has(a))&&o.push(r);if(o.length===0)break;for(let r of o)s.delete(r),e.add(r);t.push(o)}return t}function re(n){let t=[],e=n.reduce((f,p)=>f+p.deps.length,0),s=new Map(n.map(f=>[f.id,[...f.deps]])),o=rn(s);t.push("transitive-reduction");let r=n.map(f=>({...f,deps:o.get(f.id)??f.deps})),i=r.reduce((f,p)=>f+p.deps.length,0),a=e-i;a>0&&on.info({edgesRemoved:a,original:e},"transitive_reduction_applied");let l=cn(r),c=an(r),u=Math.max(0,...l.map(f=>f.length)),d=l.length===1?"parallel":u===1?"sequential":"mixed";return{streams:r,waves:l,report:{originalEdgeCount:e,edgesRemoved:a,waveCount:l.length,classification:d,passesApplied:t},isValid:c}}var ln={code:12e4,test:9e4,docs:6e4,tutorial:9e4,"integration-guide":9e4,"api-reference":6e4,migration:18e4,other:12e4};function un(n,t=5,e=4e3){let s=n.description.trim();if(s.split(/\s+/).filter(r=>r.length>0).length<t){let r=dn(n.category),i=n.ownedFiles.join(", ")||"the target files";s=`${r} ${n.name}. ${s}. Target: ${i}`}if(n.codeExamples.length>0){let r=[],i=0;for(let a of n.codeExamples){let l=`\`\`\`${a.language||""}
127
+ `;return s}var Pe=["-types","-migrations","-core","-tests","-docs"];function se(n,t){let e=Pe.find(a=>n.id.endsWith(a));if(!e)return n;let s=n.id.slice(0,-e.length),o=t.filter(a=>Pe.some(l=>a.id===`${s}${l}`));if(o.length<=1)return n;let r=o.find(a=>a.id===`${s}-core`);if(r)return r;let i=["-migrations","-types"];for(let a of i){let l=o.find(c=>c.id===`${s}${a}`);if(l)return l}return n}function Zt(n,t){let e=n.toLowerCase().trim(),s=t.find(l=>l.id===n);if(s)return s;let o=t.find(l=>l.name.toLowerCase()===e);if(o)return se(o,t);let r=t.find(l=>l.id.includes(e)||e.includes(l.id));if(r)return se(r,t);let i=e.split(/[\s-_]+/).filter(l=>l.length>2),a=t.find(l=>{let c=l.name.toLowerCase().split(/[\s-_]+/);return i.filter(d=>c.some(f=>f.includes(d)||d.includes(f))).length>=i.length*.5});if(a)return se(a,t)}function en(n){let t=`${n.name} ${n.description}`.toLowerCase();return/\b(cleanup|clean\s*up|remove|delete|drop)\b/.test(t)}function tn(n){let t=[],e=new Map;for(let r of n)if(!en(r))for(let i of r.ownedFiles)e.set(i,r);for(let r of n)for(let i of r.readFiles){let a=e.get(i);a&&a.id!==r.id&&t.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(t.map(r=>`${r.from}\u2192${r.to}`)),o=new Set;for(let r of t){let i=`${r.to}\u2192${r.from}`;s.has(i)&&(o.add(`${r.from}\u2192${r.to}`),o.add(i))}return t.filter(r=>!o.has(`${r.from}\u2192${r.to}`))}function nn(n){let t=[];for(let e of n){if(e.category==="test"){let s=e.id.replace(/-tests?$/,"").replace(/^tests?-/,""),o=n.find(r=>r.id!==e.id&&r.category==="code"&&(r.id===s||r.id===`${s}-core`||r.id===`${s}-service`||r.id===`${s}-implementation`));o&&t.push({from:e.id,to:o.id,reason:"content-pattern",explanation:`${e.id} (test) depends on ${o.id} (implementation)`})}if(e.category==="docs"||e.category==="tutorial"){let s=e.id.replace(/^docs?-/,"").replace(/-docs?$/,"").replace(/^tutorials?-/,"").replace(/-tutorials?$/,""),o=n.filter(i=>i.id!==e.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&&t.push({from:e.id,to:r.id,reason:"content-pattern",explanation:`${e.id} (${e.category}) documents ${r.id}`})}}return t}function sn(n,t){let e=[];for(let s of n)for(let o of s.explicitDeps){let r=Zt(o,n);if(r&&r.id!==s.id)e.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}'`;t?.diagnostics?.unmatchedDeps.push(i),t?.diagnostics?.warnings.push(i)}}return e}function Me(n){let t=[],e=new Set,s=new Set,o=[];function r(i){e.add(i),s.add(i),o.push(i);let a=n.get(i)||[];for(let l of a)if(!e.has(l))r(l);else if(s.has(l)){let c=o.indexOf(l);if(c!==-1){let u=[...o.slice(c),l];t.push(u)}}o.pop(),s.delete(i)}for(let i of n.keys())e.has(i)||r(i);return t}function on(n,t,e){let s=0,o=new Set;for(let r of n){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=t.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 c=a.reduce((f,p)=>{let m=e.get(f.from)?.length??0,g=e.get(p.from)?.length??0;return g<m||g===m&&p.from<f.from?p:f}),u=t.indexOf(c);u!==-1&&t.splice(u,1);let d=e.get(c.from);if(d){let f=d.indexOf(c.to);f!==-1&&d.splice(f,1)}o.add(`${c.from}\u2192${c.to}`),s++}return{broken:s}}function rn(n,t){let e=[...sn(n,t),...tn(n),...nn(n)],s=new Set,o=[];for(let a of e){let l=`${a.from}\u2192${a.to}`;s.has(l)||(s.add(l),o.push(a))}let r=new Map;for(let a of n)r.set(a.id,[]);for(let a of o){let l=r.get(a.from)||[];l.includes(a.to)||l.push(a.to),r.set(a.from,l)}let i=Me(r);if(i.length>0){let{broken:a}=on(i,o,r);a>0&&(i=Me(r))}return{dependencies:r,edges:o,cycles:i,isAcyclic:i.length===0}}function an(n){let t=["=== Dependency Analysis ===",""];if(t.push(`Total edges: ${n.edges.length}`),t.push(`Acyclic: ${n.isAcyclic?"Yes \u2713":"No \u26A0\uFE0F"}`),n.cycles.length>0){t.push(""),t.push("--- Cycles Detected ---");for(let e of n.cycles)t.push(` ${e.join(" \u2192 ")}`)}t.push(""),t.push("--- Dependencies by Deliverable ---");for(let[e,s]of n.dependencies)s.length>0&&t.push(`${e}: ${s.join(", ")}`);t.push(""),t.push("--- Edge Details ---");for(let e of n.edges)t.push(`${e.from} \u2192 ${e.to} (${e.reason})`),t.push(` ${e.explanation}`);return t.join(`
128
+ `)}import*as C from"node:fs";import*as $ from"node:path";var Ie={maxOwnsCount:4,maxReadsCount:4,maxDirectories:2,maxPlanConjunctions:4,warnOnMixedActions:!0,warnOnMixedFileTypes:!0,requireVerifyCommands:!0},oe=class{config;constructor(t=Ie){this.config=t}analyzeStream(t,e){let s=[],o=e.owns||[],r=e.reads||[],i=e.plan||"",a=e.verify||[],l=o.length,c=r.length,u=this.countDirectories(o),d=this.countConjunctions(i),f=a.length,p=this.detectActionTypes(i),m=this.detectFileTypes([...o,...r]),g={ownsCount:l,readsCount:c,directoriesAffected:u,planConjunctions:d,verifyCommands:f,actionTypes:p,fileTypes:m};l>this.config.maxOwnsCount&&u>this.config.maxDirectories?s.push({type:"high_owns_complexity",severity:"error",message:`Stream owns ${l} files across ${u} directories`,details:`Consider splitting into smaller streams. Threshold: ${this.config.maxOwnsCount} files across ${this.config.maxDirectories} directories`,streamName:t}):l>this.config.maxOwnsCount&&s.push({type:"high_owns_count",severity:"warning",message:`Stream owns ${l} files (threshold: ${this.config.maxOwnsCount})`,details:"Consider splitting into smaller, more focused streams",streamName:t}),c>this.config.maxReadsCount&&s.push({type:"high_reads_count",severity:"warning",message:`Stream reads ${c} files (threshold: ${this.config.maxReadsCount})`,details:"Too many dependencies may indicate unclear scope or context bloat",streamName:t}),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:t}),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:t}),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:t}),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:t}),this.config.requireVerifyCommands&&f===0&&l>0&&s.push({type:"no_verify",severity:"warning",message:"Stream has no verify commands",details:"Add verify commands to ensure implementation correctness",streamName:t}),(!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:t}),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:t});let y=this.calculateQualityScore(s,g);return{streamName:t,qualityScore:y,issues:s,metrics:g}}analyzeStreams(t){let e=[];for(let[r,i]of Object.entries(t))e.push(this.analyzeStream(r,i));let s=this.countIssuesBySeverity(e),o=this.calculateOverallScore(e);return{streams:e,overallScore:o,totalIssues:s}}countDirectories(t){let e=new Set;for(let s of t){let o=s.substring(0,s.lastIndexOf("/"));o?e.add(o):e.add(".")}return e.size}countConjunctions(t){let s=t.toLowerCase().match(/\band\b/g);return s?s.length:0}detectActionTypes(t){let e=t.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(e)&&s.push(r);return s}detectFileTypes(t){let e=new Set;for(let s of t){let o=s.substring(s.lastIndexOf(".")+1).toLowerCase();o&&o!==s&&e.add(o)}return e}hasMixedActions(t){let e=["create","delete","configure"],s=["update","document"],o=t.some(i=>e.includes(i)),r=t.some(i=>s.includes(i));return o&&r}hasUnboundedTutorial(t,e){let s=t.toLowerCase();return/\b(tutorial|guide|documentation|example)\b/.test(s)&&e.length===0}hasVaguePlan(t){let e=t.toLowerCase(),s=["various","some","multiple","general","misc","other","stuff","things"];for(let o of s)if(e.includes(o))return!0;return t.trim().split(/\s+/).length<5}calculateQualityScore(t,e){let s=100;for(let o of t)switch(o.severity){case"error":s-=20;break;case"warning":s-=10;break;case"info":s-=5;break}return e.verifyCommands>0&&(s+=5),e.ownsCount>0&&e.ownsCount<=3&&(s+=5),e.planConjunctions===0&&(s+=5),Math.max(0,Math.min(100,s))}calculateOverallScore(t){if(t.length===0)return 0;let e=t.reduce((s,o)=>s+o.qualityScore,0);return Math.round(e/t.length)}countIssuesBySeverity(t){let e={errors:0,warnings:0,info:0};for(let s of t)for(let o of s.issues)switch(o.severity){case"error":e.errors++;break;case"warning":e.warnings++;break;case"info":e.info++;break}return e}};function N(n){return new oe({...Ie,...n})}import{createLogger as cn}from"../logging.js";var ln=cn("topology-optimizer");function un(n){let t=new Map,e=[...n.keys()];function s(o,r){let i=new Set,a=[o];for(;a.length>0;){let l=a.shift();if(!i.has(l)){i.add(l);for(let c of n.get(l)??[])c!==r&&!i.has(c)&&a.push(c)}}return i}for(let o of e){let r=n.get(o)??[],i=[];for(let a of r){let l=r.filter(u=>u!==a),c=!1;for(let u of l)if(s(u,o).has(a)){c=!0;break}c||i.push(a)}t.set(o,i)}return t}function dn(n){let t=new Map,e=new Map;for(let r of n){t.set(r.id,r.deps.length);for(let i of r.deps)e.has(i)||e.set(i,[]),e.get(i).push(r.id);e.has(r.id)||e.set(r.id,[])}let s=n.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 e.get(r)??[])t.set(i,(t.get(i)??1)-1),t.get(i)===0&&s.push(i)}return o===n.length}function fn(n){let t=[],e=new Set,s=new Map(n.map(o=>[o.id,[...o.deps]]));for(;s.size>0;){let o=[];for(let[r,i]of s)i.every(a=>e.has(a))&&o.push(r);if(o.length===0)break;for(let r of o)s.delete(r),e.add(r);t.push(o)}return t}function re(n){let t=[],e=n.reduce((f,p)=>f+p.deps.length,0),s=new Map(n.map(f=>[f.id,[...f.deps]])),o=un(s);t.push("transitive-reduction");let r=n.map(f=>({...f,deps:o.get(f.id)??f.deps})),i=r.reduce((f,p)=>f+p.deps.length,0),a=e-i;a>0&&ln.info({edgesRemoved:a,original:e},"transitive_reduction_applied");let l=fn(r),c=dn(r),u=Math.max(0,...l.map(f=>f.length)),d=l.length===1?"parallel":u===1?"sequential":"mixed";return{streams:r,waves:l,report:{originalEdgeCount:e,edgesRemoved:a,waveCount:l.length,classification:d,passesApplied:t},isValid:c}}var pn={code:12e4,test:9e4,docs:6e4,tutorial:9e4,"integration-guide":9e4,"api-reference":6e4,migration:18e4,other:12e4};function mn(n,t=5,e=4e3){let s=n.description.trim();if(s.split(/\s+/).filter(r=>r.length>0).length<t){let r=hn(n.category),i=n.ownedFiles.join(", ")||"the target files";s=`${r} ${n.name}. ${s}. Target: ${i}`}if(n.codeExamples.length>0){let r=[],i=0;for(let a of n.codeExamples){let l=`\`\`\`${a.language||""}
119
129
  ${a.code}
120
130
  \`\`\``;if(i+l.length>e)break;r.push(l),i+=l.length}r.length>0&&(s+=`
121
131
 
122
132
  Reference code:
123
133
  `+r.join(`
124
134
 
125
- `))}return s}function dn(n){switch(n){case"code":return"Implement";case"test":return"Write tests for";case"docs":return"Document";case"tutorial":return"Create tutorial for";case"integration-guide":return"Write integration guide for";case"api-reference":return"Generate API reference for";case"migration":return"Migrate";default:return"Complete"}}function fn(n){let t=[];if(n.ownedFiles.some(s=>s.endsWith(".ts")||s.endsWith(".tsx")||s.endsWith(".js")||s.endsWith(".jsx"))&&t.push("npm run build"),n.category==="test"){let s=n.ownedFiles.find(o=>o.includes(".test."));s?t.push(`npm test -- ${s}`):t.push("npm test")}return t}function pn(n,t,e={}){let{minPlanLength:s=5,estimateTimeout:o=!0,defaultVerify:r}=e,i=n,a=i._verify||r||fn(n),l=i._setup,u=(i._verify!==void 0||i._setup!==void 0)&&n.description.length>=s?n.description:un(n,s),d={name:n.name,deps:t.length>0?t:void 0,owns:n.ownedFiles.length>0?n.ownedFiles:void 0,reads:n.readFiles.length>0?n.readFiles:void 0,plan:u,verify:a.length>0?a:void 0,setup:l&&l.length>0?l:void 0};if(o){let f=ln[n.category],p=Math.max(1,Math.ceil(n.ownedFiles.length/2));d.timeoutMs=f*p}return d}function mn(n,t,e={}){let{validateAntiPatterns:s=!0}=e,o={},r=[],i=[];t.isAcyclic||r.push(`Dependency graph has cycles: ${t.cycles.map(c=>c.join(" \u2192 ")).join("; ")}`);let a=s?N():null;for(let c of n){let u=t.dependencies.get(c.id)||[],d=pn(c,u,e);if(a){let h=a.analyzeStream(c.id,{name:d.name,deps:d.deps||[],owns:d.owns||[],reads:d.reads||[],plan:d.plan,verify:d.verify||[]});if(h.issues.length>0){i.push(h);for(let y of h.issues)r.push(`${c.id}: ${y.type} - ${y.message}`)}}let f=c.childCount,p=d.plan?.length??0,m=(d.owns||[]).length;if(f!==void 0&&f>=5&&p>2500?r.push(`${c.id}: too_complex - ${f} sub-sections, ${m} owned files, ~${p} char plan. Consider: use YAML stream definitions for manual decomposition, or set deliverable_level: 3`):f!==void 0&&f>=3&&p>3500&&r.push(`${c.id}: too_complex - ${f} sub-sections, ~${p} char plan. Consider: use YAML stream definitions for finer control`),e.projectDir){let h=d.owns||[];for(let y of h)try{let O=v.join(e.projectDir,y),g=$.readFileSync(O,"utf-8").split(`
126
- `).length;if(g>800){let w=`${c.id}: large_file_critical - ${y} is ${g} lines (>800). Consider splitting this stream to reduce file scope`;r.push(w),e.diagnostics&&e.diagnostics.warnings.push(w)}else if(g>500&&h.length>=3){let w=`${c.id}: large_file_risk - ${y} is ${g} lines, stream owns ${h.length} files. Consider splitting to reduce complexity`;r.push(w),e.diagnostics&&e.diagnostics.warnings.push(w)}}catch{}}if(c.ownedFiles.length===0){let h=`Stream '${c.id}' has no owned files. It can read but not write. If this is unintentional, check your Create:/Modify: syntax (must use backtick-quoted paths).`;r.push(h),e.diagnostics&&e.diagnostics.warnings.push(h)}o[c.id]=d}if(e.projectDir){let c=yn(o,e.projectDir);r.push(...c.warnings);for(let[u,d]of Object.entries(c.streams))o[u]=d}let l=Object.entries(o).map(([c,u])=>({id:c,owns:u.owns??[],reads:u.reads??[],deps:u.deps??[]}));if(l.length>0){let c=re(l);e.diagnostics&&(e.diagnostics.topologyReport=c.report);for(let u of c.streams)o[u.id]&&(o[u.id]={...o[u.id],deps:u.deps.length>0?u.deps:void 0});c.report.edgesRemoved>0&&r.push(`Topology optimization: removed ${c.report.edgesRemoved} redundant edge(s)`)}return{streams:o,warnings:r,antiPatterns:s?i:void 0,count:n.length}}function hn(n){let t=["=== Generated Streams ===",""];if(t.push(`Total: ${n.count} streams`),n.warnings.length>0){t.push(""),t.push("--- Warnings ---");for(let e of n.warnings)t.push(`\u26A0\uFE0F ${e}`)}t.push(""),t.push("--- Stream Definitions ---");for(let[e,s]of Object.entries(n.streams))t.push(""),t.push(`${e}:`),t.push(` name: ${s.name}`),s.deps&&s.deps.length>0&&t.push(` deps: [${s.deps.join(", ")}]`),s.owns&&s.owns.length>0&&t.push(` owns: [${s.owns.join(", ")}]`),s.reads&&s.reads.length>0&&t.push(` reads: [${s.reads.join(", ")}]`),s.plan&&t.push(` plan: ${s.plan.slice(0,80)}${s.plan.length>80?"...":""}`),s.verify&&s.verify.length>0&&t.push(` verify: [${s.verify.join(", ")}]`),s.timeoutMs&&t.push(` timeoutMs: ${s.timeoutMs}`);return t.join(`
127
- `)}function gn(n){return n.streams}var _e=/(?:npm\s+install|pnpm\s+add|yarn\s+add|pip\s+install|bun\s+add)\s+(.+)/gi,Ie=/install\s+(?:dependencies|packages)\s*:\s*\n((?:\s+[-*]\s+.+\n?)+)/gi;function Re(n){let t=n.replace(/^\s*[-*]\s*/,"").trim();return t=t.replace(/\s*\(.*?\)\s*$/,"").trim(),t=t.replace(/[`"']/g,"").trim(),/^@?[a-z0-9][\w./-]*$/i.test(t)?t:null}function wn(n){let t=new Set;for(let e of Object.values(n)){let s=e.plan??"",o;for(_e.lastIndex=0;(o=_e.exec(s))!==null;){let r=o[1].split(/\s+/).filter(i=>i&&!i.startsWith("-"));for(let i of r){let a=Re(i);a&&t.add(a)}}for(Ie.lastIndex=0;(o=Ie.exec(s))!==null;){let r=o[1].split(`
128
- `);for(let i of r){let a=Re(i);a&&t.add(a)}}}return t.size===0?[]:[`npm install ${[...t].join(" ")}`]}function yn(n,t){let e=[];if(!t)return{streams:n,warnings:e};let s={},o=new Set;for(let r of Object.values(n))for(let i of r.owns||[])o.add(i);for(let[r,i]of Object.entries(n)){let a=[...i.owns||[]],l=[...i.reads||[]];for(let u of a){let d=v.join(t,u);if(!$.existsSync(d)){let f=v.dirname(d);$.existsSync(f)||e.push(`${r}: path_not_found - owns path "${u}" not found and parent directory does not exist`)}}let c=[];for(let u=0;u<l.length;u++){let d=l[u];if(o.has(d))continue;let f=v.join(t,d);if(!$.existsSync(f)){let p=v.basename(d),m=xn(t,p);m.matches===1&&m.path?(e.push(`${r}: path_corrected - reads path "${d}" corrected to "${m.path}" (only match found)`),l[u]=m.path):m.matches>1?e.push(`${r}: path_ambiguous - reads path "${d}" not found, ${m.matches} candidates exist`):(e.push(`${r}: path_removed - reads path "${d}" not found on disk, removed from reads`),c.push(u))}}for(let u=c.length-1;u>=0;u--)l.splice(c[u],1);s[r]={...i,owns:a,reads:l}}return{streams:s,warnings:e}}function xn(n,t){let e=[],s=["src","tests","lib","scripts"];for(let r of s){let i=v.join(n,r);$.existsSync(i)&&Fe(i,t,e)}let o=v.join(n,t);return $.existsSync(o)&&$.statSync(o).isFile()&&e.push(t),e.length===1?{matches:1,path:e[0]}:{matches:e.length}}function Fe(n,t,e,s){let o=s||v.dirname(n);try{let r=$.readdirSync(n,{withFileTypes:!0});for(let i of r){if(i.name==="node_modules"||i.name===".git"||i.name==="dist")continue;let a=v.join(n,i.name);i.isDirectory()?Fe(a,t,e,o):i.name===t&&e.push(v.relative(o,a))}}catch{}}function Sn(n,t,e,s,o){let r=new Set;for(let d of Object.values(n))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=t.map(d=>({number:d.number,streams:d.streams.map(f=>{let p=n[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}})})),l=[...e];if(s)for(let d of s)l.push(`Sequential edit conflict: ${d.suggestion}`);if(o)for(let[d,f]of Object.entries(o))f.fallback&&l.push(`${d}: ${f.fallback}`);let c=100;l.length>0&&(c-=l.length*5);let u=Object.values(n).filter(d=>!d.owns||d.owns.length===0).length;return c-=u*10,c=Math.max(0,Math.min(100,c)),{summary:{streamCount:Object.keys(n).length,waveCount:t.length,fileCount:r.size,estimatedCostUsd:i>0?i:void 0},waves:a,warnings:l,qualityScore:c}}function vn(n){return!n||n===0?"":n<.01?" ~< $0.01":` ~$${n.toFixed(2)}`}function $n(n){let t=[],e=n.summary.estimatedCostUsd?`, est. ~$${n.summary.estimatedCostUsd.toFixed(2)}`:"";t.push(`Plan Preview: ${n.summary.streamCount} streams, ${n.summary.waveCount} waves, ${n.summary.fileCount} files${e}`),t.push(`Quality Score: ${n.qualityScore}/100`),t.push("");for(let s of n.waves){t.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=vn(o.estimatedCostUsd);t.push(` ${o.id}: ${o.name}${i}${a}${r}`),o.owns.length>0&&t.push(` owns: ${o.owns.join(", ")}`),o.reads.length>0&&t.push(` reads: ${o.reads.join(", ")}`)}t.push("")}if(n.warnings.length>0){t.push("Warnings:");for(let s of n.warnings)t.push(` - ${s}`);t.push("")}return t.join(`
129
- `)}function je(n){let t=new Map;for(let[r,i]of Object.entries(n))for(let a of i.owns??[]){let l=t.get(a)??[];l.push(r),t.set(a,l)}let e=new Map;function s(r,i=new Set){if(e.has(r))return e.get(r);if(i.has(r))return new Set;i.add(r);let a=n[r]?.deps??[],l=new Set(a);for(let c of a)for(let u of s(c,i))l.add(u);return e.set(r,l),l}for(let r of Object.keys(n))s(r);let o=[];for(let[r,i]of t){if(i.length<2)continue;let a=[];for(let l=0;l<i.length;l++){let c=!1;for(let u=0;u<i.length;u++){if(l===u)continue;let d=e.get(i[l])??new Set,f=e.get(i[u])??new Set;if(d.has(i[u])||f.has(i[l])){c=!0;break}}c||a.push(i[l])}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 Cn(n){let t=je(n),e=0,s=[];for(let o of t)for(let r=1;r<o.streams.length;r++){let i=n[o.streams[r]],a=o.streams[r-1],l=i.deps??[];l.includes(a)||(l.push(a),i.deps=l,e++,s.push(`Added dep: ${o.streams[r]} \u2192 ${a} (shared file: ${o.file})`))}return{edgesAdded:e,fixes:s}}function bn(){return{yamlBlocksFound:0,yamlBlocksParsed:0,yamlParseErrors:[],extractionPath:null,sectionsFound:{},sectionsFilteredAsMeta:[],deliverableCount:0,splitCount:0,unmatchedDeps:[],ownershipConflicts:[],warnings:[]}}function kn(n){let t=new Map;for(let[s,o]of Object.entries(n))for(let r of o.owns||[]){let i=t.get(r)||[];i.push(s),t.set(r,i)}let e=[];for(let[s,o]of t)o.length>1&&e.push(`${s} owned by: ${o.join(", ")}`);return e}import{randomUUID as Tn}from"crypto";function En(n,t,e){let s=100,o=n.filter(r=>r.status==="failed").length;return s-=o*20,s-=e*10,s+=t*5,Math.max(0,Math.min(100,s))}function On(n,t,e){let s=n.runId??Tn(),o=new Date().toISOString(),r=[];for(let g of t)r.push(...g.streams);let i=new Set;for(let g of t)if(g.fixStreamsGenerated)for(let w of g.fixStreamsGenerated)i.add(w);for(let[g,w]of Object.entries(n.streams))w.parentStreamId&&i.add(g);let a=new Map;for(let g of r)a.set(g.id,g);let l=[...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,provider:g.provider,model:g.model,filesChanged:g.filesChanged})),c=0,u=0,d={};for(let g of r)if(g.tokensUsed){c+=g.tokensUsed.input,u+=g.tokensUsed.output;let w=g.provider??"unknown";d[w]||(d[w]={input:0,output:0}),d[w].input+=g.tokensUsed.input,d[w].output+=g.tokensUsed.output}let f=0,p=0;for(let g of t)g.timing&&(f+=g.timing.parallelMs,p+=g.timing.sequentialMs);let m=new Set;for(let g of r)if(g.filesChanged)for(let w of g.filesChanged)m.add(w);let h=0;for(let g of t)g.streams.length>0&&g.streams.every(w=>w.status==="complete")&&h++;let y={};for(let g of r)if(g.status==="failed"&&g.errorDetail?.category){let w=g.errorDetail.category;y[w]=(y[w]??0)+1}let O=i.size,T=En(r,h,O);return{runId:s,timestamp:o,feature:n.feature,planQualityScore:T,streamResults:l,waveEfficiency:{parallelMs:f,sequentialMs:p,timeSavedMs:Math.max(0,p-f)},autoPlanAccuracy:e?.autoPlanEdits!==void 0?{editsBeforeApproval:e.autoPlanEdits}:void 0,tokenUsage:{totalInput:c,totalOutput:u,byProvider:d},fileChangeImpact:{filesCreated:0,filesModified:m.size,totalFilesChanged:m.size},failurePatterns:y,totalWaves:t.length,totalStreams:a.size}}async function Pn(n,t){let{mkdir:e,writeFile:s}=await import("fs/promises"),{join:o}=await import("path"),r=o(n,".orchex","reports");await e(r,{recursive:!0});let i=o(r,`${t.runId}.json`);return await s(i,JSON.stringify(t,null,2),"utf-8"),i}import{formatDuration as Mn}from"../types.js";function _n(n,t){let e=[];if(n.waveEfficiency.timeSavedMs>0&&n.totalStreams>1){let r=Mn(n.waveEfficiency.timeSavedMs),i=n.waveEfficiency.sequentialMs>0?Math.round(n.waveEfficiency.timeSavedMs/n.waveEfficiency.sequentialMs*100):0;e.push(`${n.totalStreams} streams ran in parallel across ${n.totalWaves} wave(s), saving ${r} (${i}%).`)}else n.totalStreams>1&&e.push(`${n.totalStreams} streams executed across ${n.totalWaves} wave(s).`);let s=Object.entries(n.failurePatterns);if(s.length>0){s.sort((l,c)=>c[1]-l[1]);let[r,i]=s[0],a=s.reduce((l,[,c])=>l+c,0);r==="type_error"?e.push(`${r} was the most common failure (${i}/${a}). Consider adding a types-only stream first.`):e.push(`${r} was the most common failure (${i}/${a}).`)}if(t&&t.length>0){let r=t.reduce((a,l)=>a+l.planQualityScore,0)/t.length,i=n.planQualityScore-r;i>10?e.push(`Plan quality improved from ${Math.round(r)} to ${n.planQualityScore} \u2014 orchex is learning your patterns.`):i<-10?e.push(`Plan quality dropped from ${Math.round(r)} to ${n.planQualityScore}. Review the failure patterns above.`):e.push(`Plan quality score: ${n.planQualityScore}/100 (consistent with previous runs at ~${Math.round(r)}).`)}else e.push(`Plan quality score: ${n.planQualityScore}/100.`);let o=n.tokenUsage.totalInput+n.tokenUsage.totalOutput;if(o>0&&e.length<3){let r=Object.keys(n.tokenUsage.byProvider);r.length>1&&e.push(`Used ${r.length} providers: ${r.join(", ")} \u2014 total ${o.toLocaleString()} tokens.`)}return e.slice(0,3)}import*as C from"fs/promises";import*as M from"path";var Ae=".first-run-complete";async function In(n){let t=M.join(n,".orchex");try{await C.access(t)}catch{return!0}try{return await C.access(M.join(t,Ae)),!1}catch{}try{let e=M.join(t,"archive");if((await C.readdir(e)).length>0)return!1}catch{}try{let e=M.join(t,"reports");if((await C.readdir(e)).some(o=>o.endsWith(".json")))return!1}catch{}try{let e=M.join(t,"learn","events.jsonl");if((await C.stat(e)).size>0)return!1}catch{}return!0}async function Rn(n){let t=M.join(n,".orchex");await C.mkdir(t,{recursive:!0}),await C.writeFile(M.join(t,Ae),new Date().toISOString(),"utf-8")}function Fn(){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(`
130
- `)}import*as W from"fs/promises";import*as k from"path";async function jn(n,t){if(!t.confirm)throw new Error("Reset learning requires --confirm flag. This permanently deletes learning data.");let e=[],s=k.join(n,".orchex","learn"),o=k.join(n,".orchex","reports");t.patternsOnly?await Y(k.join(s,"patterns.json"),e):t.reportsOnly?await De(o,e,".json"):(await Y(k.join(s,"thresholds.json"),e),await Y(k.join(s,"events.jsonl"),e),await Y(k.join(s,"patterns.json"),e),await De(o,e,".json"));let r=t.patternsOnly?"patterns":t.reportsOnly?"reports":"all learning data";return{deleted:e,totalDeleted:e.length,message:e.length>0?`Reset ${r}: ${e.length} file(s) deleted.`:`No ${r} found to delete.`}}async function Y(n,t){try{await W.unlink(n),t.push(k.basename(n))}catch(e){if(e.code!=="ENOENT")throw e}}async function De(n,t,e){try{let s=await W.readdir(n);for(let o of s)e&&!o.endsWith(e)||(await W.unlink(k.join(n,o)),t.push(o))}catch(s){if(s.code!=="ENOENT")throw s}}var An=[{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."}];function ie(n,t){for(let{pattern:s,category:o,retryable:r,selfHealable:i,suggestion:a}of An)if(s.test(n))return{category:o,retryable:r,selfHealable:i,suggestion:a};let e=t==="artifact"||t==="verify";return{category:"unknown",retryable:e,selfHealable:e,suggestion:e?"Unknown code error. Retry with the full error message included in the prompt.":`Unknown infrastructure error (origin: ${t??"unspecified"}). Check API key, model availability, and network connectivity.`}}import{createLogger as Dn}from"../logging.js";var Ln=Dn("iteration-evaluator");function Nn(n){let{streamResults:t,iterationNumber:e,maxIterations:s,intent:o}=n;if(e>=s){let d=t.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?t.filter(f=>f.status==="failed").map(f=>`${f.id}: ${f.error}`).join("; "):void 0}}let r=t.filter(d=>d.status==="failed"),i=t.filter(d=>d.status==="complete"&&!d.verifyPassed);if(r.length===0&&i.length===0)return{complete:!0,reason:`All ${t.length} stream(s) completed and verified successfully`};let l=[];for(let d of r)l.push(`Stream "${d.id}" failed: ${d.error??"unknown error"}`);for(let d of i)l.push(`Stream "${d.id}" verify failed: ${d.verifyError??"verification error"}`);let c=l.join("; "),u=`Fix the following issues from the previous attempt to "${o}": ${c}`;return Ln.info({iteration:e,failed:r.length,verifyFailed:i.length},"iteration_incomplete"),{complete:!1,reason:`${r.length} stream(s) failed, ${i.length} verification(s) failed`,nextIntent:u,failureSummary:c}}var Wn={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"]},Un={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"]},Hn={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"]},zn={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"]},Bn={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"]},qn=[Wn,Un,Hn,zn,Bn];function G(n){let t=n.toLowerCase(),e=null;for(let s of qn){let o=0;for(let r of s.keywords)t.includes(r.toLowerCase())&&(o+=2);for(let r of s.patterns){let i=r.toLowerCase().split(/[\s/,]+/).filter(l=>l.length>2);i.filter(l=>t.includes(l)).length>=i.length/2&&(o+=1)}o>0&&(!e||o>e.score)&&(e={template:s,score:o})}return e&&e.score>=3?e.template:null}function ae(n,t){let e=[];if(n.id==="documentation-set"){let s=t.topics||[];for(let o of s)e.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(n.id==="code-feature"){let s=t.featureName;e.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(n.id==="migration"){let s=t.featureName,o=t.components||[];e.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)e.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"});e.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(n.id==="tutorial"){let s=t.topics||[];for(let o of s)e.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(n.id==="api-reference"){let s=t.modules||[];for(let o of s)e.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 e}function Vn(n){let t=n.owns||[],e=n.reads||[];if(t.length>5)return{originalStream:n.name,reason:`Stream owns ${t.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(e.length>10)return{originalStream:n.name,reason:`Stream reads ${e.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=`${n.name} ${n.plan||""}`,o=G(s);return o&&["multiple","all","complete","full","entire"].some(a=>n.name.toLowerCase().includes(a))?{originalStream:n.name,reason:"Stream name suggests broad scope that could be split",template:o,guidance:o.guidelines,suggestedStreams:[]}:null}function Yn(n,t,e){if(e.issues.length===0)return null;let s=e.issues.some(c=>c.severity==="error"),o=e.issues.some(c=>c.severity==="warning"),r=`${t.name??n} ${t.plan??""}`,i=G(r),a=null;if(i){let c=n.replace(/-/g,"_");a=ae(i,{featureName:c})}let l="";s?l=`Stream "${n}" has critical issues:
135
+ `))}return s}function hn(n){switch(n){case"code":return"Implement";case"test":return"Write tests for";case"docs":return"Document";case"tutorial":return"Create tutorial for";case"integration-guide":return"Write integration guide for";case"api-reference":return"Generate API reference for";case"migration":return"Migrate";default:return"Complete"}}function gn(n){let t=[];if(n.ownedFiles.some(s=>s.endsWith(".ts")||s.endsWith(".tsx")||s.endsWith(".js")||s.endsWith(".jsx"))&&t.push("npm run build"),n.category==="test"){let s=n.ownedFiles.find(o=>o.includes(".test."));s?t.push(`npm test -- ${s}`):t.push("npm test")}return t}function wn(n,t,e){let s=[];for(let o of n){t!=="test"&&/vitest|jest/.test(o)&&!/build|tsc/.test(o)&&s.push(`Verify command '${o}' uses a test runner but stream category is '${t}'. Consider using 'npm run build' or 'npx tsc --noEmit' instead.`);let r=o.match(/(?:vitest|jest)\s+(?:run\s+)?(\S+\.(?:ts|tsx|js|jsx))/);if(r){let i=r[1];e.some(l=>i.includes(l)||l.includes(i))||s.push(`Verify command references '${i}' which is not in this stream's owned files.`)}}return s}function yn(n,t,e={}){let{minPlanLength:s=5,estimateTimeout:o=!0,defaultVerify:r}=e,i=n,a=i._verify||r||gn(n),l=i._setup,c=wn(a,n.category,n.ownedFiles);if(c.length>0&&e.diagnostics)for(let p of c)e.diagnostics.warnings.push(`${n.id}: verify_warning - ${p}`);let d=(i._verify!==void 0||i._setup!==void 0)&&n.description.length>=s?n.description:mn(n,s),f={name:n.name,deps:t.length>0?t:void 0,owns:n.ownedFiles.length>0?n.ownedFiles:void 0,reads:n.readFiles.length>0?n.readFiles:void 0,plan:d,verify:a.length>0?a:void 0,setup:l&&l.length>0?l:void 0};if(o){let p=pn[n.category],m=Math.max(1,Math.ceil(n.ownedFiles.length/2));f.timeoutMs=p*m}return f}function xn(n,t,e={}){let{validateAntiPatterns:s=!0}=e,o={},r=[],i=[];t.isAcyclic||r.push(`Dependency graph has cycles: ${t.cycles.map(c=>c.join(" \u2192 ")).join("; ")}`);let a=s?N():null;for(let c of n){let u=t.dependencies.get(c.id)||[],d=yn(c,u,e);if(a){let g=a.analyzeStream(c.id,{name:d.name,deps:d.deps||[],owns:d.owns||[],reads:d.reads||[],plan:d.plan,verify:d.verify||[]});if(g.issues.length>0){i.push(g);for(let y of g.issues)r.push(`${c.id}: ${y.type} - ${y.message}`)}}let f=c.childCount,p=d.plan?.length??0,m=(d.owns||[]).length;if(f!==void 0&&f>=5&&p>2500?r.push(`${c.id}: too_complex - ${f} sub-sections, ${m} owned files, ~${p} char plan. Consider: use YAML stream definitions for manual decomposition, or set deliverable_level: 3`):f!==void 0&&f>=3&&p>3500&&r.push(`${c.id}: too_complex - ${f} sub-sections, ~${p} char plan. Consider: use YAML stream definitions for finer control`),e.projectDir){let g=d.owns||[];for(let y of g)try{let v=$.join(e.projectDir,y),S=C.readFileSync(v,"utf-8").split(`
136
+ `).length;if(S>800){let x=`${c.id}: large_file_critical - ${y} is ${S} lines (>800). Consider splitting this stream to reduce file scope`;r.push(x),e.diagnostics&&e.diagnostics.warnings.push(x)}else if(S>500&&g.length>=3){let x=`${c.id}: large_file_risk - ${y} is ${S} lines, stream owns ${g.length} files. Consider splitting to reduce complexity`;r.push(x),e.diagnostics&&e.diagnostics.warnings.push(x)}}catch{}}if(c.ownedFiles.length===0){let g=`Stream '${c.id}' has no owned files. It can read but not write. If this is unintentional, check your Create:/Modify: syntax (must use backtick-quoted paths).`;r.push(g),e.diagnostics&&e.diagnostics.warnings.push(g)}o[c.id]=d}if(e.projectDir){let c=Cn(o,e.projectDir);r.push(...c.warnings);for(let[u,d]of Object.entries(c.streams))o[u]=d}let l=Object.entries(o).map(([c,u])=>({id:c,owns:u.owns??[],reads:u.reads??[],deps:u.deps??[]}));if(l.length>0){let c=re(l);e.diagnostics&&(e.diagnostics.topologyReport=c.report);for(let u of c.streams)o[u.id]&&(o[u.id]={...o[u.id],deps:u.deps.length>0?u.deps:void 0});c.report.edgesRemoved>0&&r.push(`Topology optimization: removed ${c.report.edgesRemoved} redundant edge(s)`)}return{streams:o,warnings:r,antiPatterns:s?i:void 0,count:n.length}}function Sn(n){let t=["=== Generated Streams ===",""];if(t.push(`Total: ${n.count} streams`),n.warnings.length>0){t.push(""),t.push("--- Warnings ---");for(let e of n.warnings)t.push(`\u26A0\uFE0F ${e}`)}t.push(""),t.push("--- Stream Definitions ---");for(let[e,s]of Object.entries(n.streams))t.push(""),t.push(`${e}:`),t.push(` name: ${s.name}`),s.deps&&s.deps.length>0&&t.push(` deps: [${s.deps.join(", ")}]`),s.owns&&s.owns.length>0&&t.push(` owns: [${s.owns.join(", ")}]`),s.reads&&s.reads.length>0&&t.push(` reads: [${s.reads.join(", ")}]`),s.plan&&t.push(` plan: ${s.plan.slice(0,80)}${s.plan.length>80?"...":""}`),s.verify&&s.verify.length>0&&t.push(` verify: [${s.verify.join(", ")}]`),s.timeoutMs&&t.push(` timeoutMs: ${s.timeoutMs}`);return t.join(`
137
+ `)}function $n(n){return n.streams}var Re=/(?:npm\s+install|pnpm\s+add|yarn\s+add|pip\s+install|bun\s+add)\s+(.+)/gi,_e=/install\s+(?:dependencies|packages)\s*:\s*\n((?:\s+[-*]\s+.+\n?)+)/gi;function Fe(n){let t=n.replace(/^\s*[-*]\s*/,"").trim();return t=t.replace(/\s*\(.*?\)\s*$/,"").trim(),t=t.replace(/[`"']/g,"").trim(),/^@?[a-z0-9][\w./-]*$/i.test(t)?t:null}function vn(n){let t=new Set;for(let e of Object.values(n)){let s=e.plan??"",o;for(Re.lastIndex=0;(o=Re.exec(s))!==null;){let r=o[1].split(/\s+/).filter(i=>i&&!i.startsWith("-"));for(let i of r){let a=Fe(i);a&&t.add(a)}}for(_e.lastIndex=0;(o=_e.exec(s))!==null;){let r=o[1].split(`
138
+ `);for(let i of r){let a=Fe(i);a&&t.add(a)}}}return t.size===0?[]:[`npm install ${[...t].join(" ")}`]}function Cn(n,t){let e=[];if(!t)return{streams:n,warnings:e};let s={},o=new Set;for(let r of Object.values(n))for(let i of r.owns||[])o.add(i);for(let[r,i]of Object.entries(n)){let a=[...i.owns||[]],l=[...i.reads||[]];for(let u of a){let d=$.join(t,u);if(!C.existsSync(d)){let f=$.dirname(d);C.existsSync(f)||e.push(`${r}: path_not_found - owns path "${u}" not found and parent directory does not exist`)}}let c=[];for(let u=0;u<l.length;u++){let d=l[u];if(o.has(d))continue;let f=$.join(t,d);if(!C.existsSync(f)){let p=$.basename(d),m=bn(t,p);m.matches===1&&m.path?(e.push(`${r}: path_corrected - reads path "${d}" corrected to "${m.path}" (only match found)`),l[u]=m.path):m.matches>1?e.push(`${r}: path_ambiguous - reads path "${d}" not found, ${m.matches} candidates exist`):(e.push(`${r}: path_removed - reads path "${d}" not found on disk, removed from reads`),c.push(u))}}for(let u=c.length-1;u>=0;u--)l.splice(c[u],1);s[r]={...i,owns:a,reads:l}}return{streams:s,warnings:e}}function bn(n,t){let e=[],s=["src","tests","lib","scripts"];for(let r of s){let i=$.join(n,r);C.existsSync(i)&&je(i,t,e)}let o=$.join(n,t);return C.existsSync(o)&&C.statSync(o).isFile()&&e.push(t),e.length===1?{matches:1,path:e[0]}:{matches:e.length}}function je(n,t,e,s){let o=s||$.dirname(n);try{let r=C.readdirSync(n,{withFileTypes:!0});for(let i of r){if(i.name==="node_modules"||i.name===".git"||i.name==="dist")continue;let a=$.join(n,i.name);i.isDirectory()?je(a,t,e,o):i.name===t&&e.push($.relative(o,a))}}catch{}}function kn(n,t,e,s,o){let r=new Set;for(let d of Object.values(n))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=t.map(d=>({number:d.number,streams:d.streams.map(f=>{let p=n[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}})})),l=[...e];if(s)for(let d of s)l.push(`Sequential edit conflict: ${d.suggestion}`);if(o)for(let[d,f]of Object.entries(o))f.fallback&&l.push(`${d}: ${f.fallback}`);let c=100;l.length>0&&(c-=l.length*5);let u=Object.values(n).filter(d=>!d.owns||d.owns.length===0).length;return c-=u*10,c=Math.max(0,Math.min(100,c)),{summary:{streamCount:Object.keys(n).length,waveCount:t.length,fileCount:r.size,estimatedCostUsd:i>0?i:void 0},waves:a,warnings:l,qualityScore:c}}function Tn(n){return!n||n===0?"":n<.01?" ~< $0.01":` ~$${n.toFixed(2)}`}function En(n){let t=[],e=n.summary.estimatedCostUsd?`, est. ~$${n.summary.estimatedCostUsd.toFixed(2)}`:"";t.push(`Plan Preview: ${n.summary.streamCount} streams, ${n.summary.waveCount} waves, ${n.summary.fileCount} files${e}`),t.push(`Quality Score: ${n.qualityScore}/100`),t.push("");for(let s of n.waves){t.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=Tn(o.estimatedCostUsd);t.push(` ${o.id}: ${o.name}${i}${a}${r}`),o.owns.length>0&&t.push(` owns: ${o.owns.join(", ")}`),o.reads.length>0&&t.push(` reads: ${o.reads.join(", ")}`)}t.push("")}if(n.warnings.length>0){t.push("Warnings:");for(let s of n.warnings)t.push(` - ${s}`);t.push("")}return t.join(`
139
+ `)}function Ae(n){let t=new Map;for(let[r,i]of Object.entries(n))for(let a of i.owns??[]){let l=t.get(a)??[];l.push(r),t.set(a,l)}let e=new Map;function s(r,i=new Set){if(e.has(r))return e.get(r);if(i.has(r))return new Set;i.add(r);let a=n[r]?.deps??[],l=new Set(a);for(let c of a)for(let u of s(c,i))l.add(u);return e.set(r,l),l}for(let r of Object.keys(n))s(r);let o=[];for(let[r,i]of t){if(i.length<2)continue;let a=[];for(let l=0;l<i.length;l++){let c=!1;for(let u=0;u<i.length;u++){if(l===u)continue;let d=e.get(i[l])??new Set,f=e.get(i[u])??new Set;if(d.has(i[u])||f.has(i[l])){c=!0;break}}c||a.push(i[l])}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 On(n){let t=Ae(n),e=0,s=[];for(let o of t)for(let r=1;r<o.streams.length;r++){let i=n[o.streams[r]],a=o.streams[r-1],l=i.deps??[];l.includes(a)||(l.push(a),i.deps=l,e++,s.push(`Added dep: ${o.streams[r]} \u2192 ${a} (shared file: ${o.file})`))}return{edgesAdded:e,fixes:s}}function Pn(){return{yamlBlocksFound:0,yamlBlocksParsed:0,yamlParseErrors:[],extractionPath:null,sectionsFound:{},sectionsFilteredAsMeta:[],deliverableCount:0,splitCount:0,unmatchedDeps:[],ownershipConflicts:[],warnings:[]}}function Mn(n){let t=new Map;for(let[s,o]of Object.entries(n))for(let r of o.owns||[]){let i=t.get(r)||[];i.push(s),t.set(r,i)}let e=[];for(let[s,o]of t)o.length>1&&e.push(`${s} owned by: ${o.join(", ")}`);return e}import{randomUUID as zn}from"crypto";var In=[{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."}];function ie(n,t){for(let{pattern:s,category:o,retryable:r,selfHealable:i,suggestion:a}of In)if(s.test(n))return{category:o,retryable:r,selfHealable:i,suggestion:a};let e=t==="artifact"||t==="verify";return{category:"unknown",retryable:e,selfHealable:e,suggestion:e?"Unknown code error. Retry with the full error message included in the prompt.":`Unknown infrastructure error (origin: ${t??"unspecified"}). Check API key, model availability, and network connectivity.`}}import{loadManifest as De,saveManifest as Le}from"../manifest.js";import{createLogger as Rn}from"../logging.js";var ae=Rn("fix-stream-manager");async function _n(n){let t=await De(n),e={skipped:[],warnings:[]},s=Object.entries(t.streams).filter(([o,r])=>r.parentStreamId!==void 0);for(let[o,r]of s)r.status==="pending"&&Dn(t,r.parentStreamId)&&(t.streams[o].status="skipped",t.streams[o].error="Parent stream completed; fix no longer needed",e.skipped.push(o));return e.skipped.length>0&&await Le(n,t),e}async function Fn(n,t){let e=await De(n),s={skipped:[],warnings:[]},o=Ln(e,t);for(let a of o){let l=e.streams[a];l.status==="pending"?(e.streams[a].status="skipped",e.streams[a].error=`Ancestor '${t}' completed; fix no longer needed`,s.skipped.push(a)):l.status==="in_progress"&&(e.streams[a].status="skipped",e.streams[a].error=`Sibling fix already resolved this stream (completed: '${t}')`,s.skipped.push(a))}let r=!1,i=e.streams[t];if(i?.parentStreamId){let a=i.parentStreamId;for(;e.streams[a]?.parentStreamId;)a=e.streams[a].parentStreamId;let l=e.streams[a];l&&l.status==="failed"&&(e.streams[a].status="complete",delete e.streams[a].error,r=!0,ae.info({fixStreamId:t,rootStreamId:a},"fix_stream_propagated_completion_to_root"))}return(s.skipped.length>0||r)&&await Le(n,e),s}function Y(n,t){let e=n.streams[t];if(!e||!e.parentStreamId)return null;let s=[t],o=e.parentStreamId,r=new Set;for(;o&&!r.has(o);){r.add(o);let i=n.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 jn(n,t){return n.streams[t]?.parentStreamId!==void 0}function An(n,t){return Y(n,t)?.rootStreamId??t}function Dn(n,t){let e=t,s=new Set;for(;e;){if(s.has(e)){ae.warn({streamId:e},"circular_reference_in_fix_chain");break}s.add(e);let o=n.streams[e];if(!o){ae.warn({parentId:e},"fix_stream_orphaned_parent");break}if(o.status==="complete")return!0;e=o.parentStreamId}return!1}function Ln(n,t){let e=[];for(let[s,o]of Object.entries(n.streams))o.parentStreamId&&Nn(n,s,t)&&e.push(s);return e}function Nn(n,t,e){let s=n.streams[t]?.parentStreamId,o=new Set;for(;s&&!o.has(s);){if(o.add(s),s===e)return!0;s=n.streams[s]?.parentStreamId}return!1}var We=3;function Ue(n,t){let e=0,s=t;for(;s;){let o=n.streams[s];if(!o)break;e+=o.attempts??0,s=o.parentStreamId}return e}function Ne(n,t){return Y(n,t)?.rootStreamId??t}function ze(n,t){let e=Ne(n,t);for(let[s,o]of Object.entries(n.streams)){if(s===t||!o.parentStreamId||o.status!=="pending"&&o.status!=="in_progress")continue;if(Ne(n,s)===e)return!0}return!1}function Wn(n,t,e){let s=n.streams[t];if(!s||s.status==="failed"&&s.error?.startsWith("Setup failed:"))return null;let o=s.error??"",r=e??ie(o);if(!r.selfHealable||ze(n,t)||Ue(n,t)>=We)return null;let l=(s.attempts??0)+1,c=`${t}-fix-${l}`,u=t,d=[`## Fix Attempt #${l} for "${s.name}"`,"","### Original Plan",s.plan??"(no plan)","","### Error That Occurred","```",o,"```","",`### Error Category: ${r.category}`,"",`### Suggestion: ${r.suggestion}`,"","### Instructions",`This is a retry of the failed stream "${t}".`,"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."].join(`
140
+ `),f={name:`${s.name} (Fix #${l})`,deps:s.deps??[],owns:s.owns??[],reads:s.reads??[],plan:d,setup:s.setup??[],verify:s.verify??[],status:"pending",attempts:0,parentStreamId:u};return{fixStreamId:c,fixStream:f,analysis:{category:r.category,suggestion:r.suggestion}}}function ce(n,t){if(t.length<2)return null;let e=new Map;for(let d of t){let f=n.streams[d];f?.error&&e.set(d,f.error)}if(e.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 e){let p=new RegExp(s,"gi"),m,g=new Set;for(;(m=p.exec(f))!==null;){let y=m[1]||m[2]||m[3]||m[0];g.add(y)}for(let y of g){let v=o.get(y)??[];v.push(d),o.set(y,v)}}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),l=new Map;for(let d of a){let f=n.streams[d];for(let p of f?.deps??[])l.set(p,(l.get(p)??0)+1)}let c="",u=0;for(let[d,f]of l)n.streams[d]?.status==="complete"&&f>u&&(c=d,u=f);return c?{rootCauseStreamId:c,reason:`Stream '${c}' completed but ${a.length} downstream streams failed with errors referencing '${r}'`,affectedStreamIds:a,commonErrorPattern:r}:null}function Un(n,t){let e=t.rootCauseStreamId,s=n.streams[e];if(!s||s.status!=="failed"||Ue(n,e)>=We||ze(n,e))return null;let i=(s.attempts??0)+1,a=`${e}-fix-${i}`,l=[];for(let d of t.affectedStreamIds.slice(0,3)){let f=n.streams[d];f?.error&&l.push(`- ${f.name}: ${f.error.slice(0,200)}`)}let c=[`## Root Cause Fix #${i} for "${s.name}"`,"","### Original Plan",s.plan??"(no plan)","","### Problem Identified",`This stream completed but its output caused ${t.affectedStreamIds.length} downstream streams to fail.`,`All downstream errors reference: **${t.commonErrorPattern}**`,"","### Downstream Error Samples",...l,"","### Instructions",`This stream's output is incorrect. The code you produce must define '${t.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."].join(`
141
+ `),u={name:`${s.name} (Root Cause Fix #${i})`,deps:s.deps??[],owns:s.owns??[],reads:s.reads??[],plan:c,setup:s.setup??[],verify:s.verify??[],status:"pending",attempts:0,parentStreamId:e};return{fixStreamId:a,fixStream:u,analysis:{category:"runtime_error",suggestion:t.reason}}}function Hn(n,t,e){let s=100,o=n.filter(r=>r.status==="failed").length;return s-=o*20,s-=e*10,s+=t*5,Math.max(0,Math.min(100,s))}function Bn(n,t,e){let s=n.runId??zn(),o=new Date().toISOString(),r=[];for(let h of t)r.push(...h.streams);let i=new Set;for(let h of t)if(h.fixStreamsGenerated)for(let w of h.fixStreamsGenerated)i.add(w);for(let[h,w]of Object.entries(n.streams))w.parentStreamId&&i.add(h);let a=new Map;for(let h of r)a.set(h.id,h);let l=[...a.values()].map(h=>({id:h.id,name:h.name,status:h.status,tokensUsed:h.tokensUsed,executionTimeMs:h.executionTimeMs,selfHealCount:i.has(h.id)?1:0,errorCategory:h.errorDetail?.category,errorMessage:h.error,errorSuggestion:h.errorDetail?.suggestion,provider:h.provider,model:h.model,filesChanged:h.filesChanged})),c=0,u=0,d={};for(let h of r)if(h.tokensUsed){c+=h.tokensUsed.input,u+=h.tokensUsed.output;let w=h.provider??"unknown";d[w]||(d[w]={input:0,output:0}),d[w].input+=h.tokensUsed.input,d[w].output+=h.tokensUsed.output}let f=0,p=0;for(let h of t)h.timing&&(f+=h.timing.parallelMs,p+=h.timing.sequentialMs);let m=new Set;for(let h of r)if(h.filesChanged)for(let w of h.filesChanged)m.add(w);let g=0;for(let h of t)h.streams.length>0&&h.streams.every(w=>w.status==="complete")&&g++;let y={};for(let h of r)if(h.status==="failed"&&h.errorDetail?.category){let w=h.errorDetail.category;y[w]=(y[w]??0)+1}let v,k=r.filter(h=>h.status==="failed").map(h=>h.id);if(k.length>=2){let h=ce(n,k);h&&(v=h)}let S=i.size,x=Hn(r,g,S);return{runId:s,timestamp:o,feature:n.feature,planQualityScore:x,streamResults:l,waveEfficiency:{parallelMs:f,sequentialMs:p,timeSavedMs:Math.max(0,p-f)},autoPlanAccuracy:e?.autoPlanEdits!==void 0?{editsBeforeApproval:e.autoPlanEdits}:void 0,tokenUsage:{totalInput:c,totalOutput:u,byProvider:d},fileChangeImpact:{filesCreated:0,filesModified:m.size,totalFilesChanged:m.size},failurePatterns:y,failureCorrelation:v,totalWaves:t.length,totalStreams:a.size}}async function qn(n,t){let{mkdir:e,writeFile:s}=await import("fs/promises"),{join:o}=await import("path"),r=o(n,".orchex","reports");await e(r,{recursive:!0});let i=o(r,`${t.runId}.json`);return await s(i,JSON.stringify(t,null,2),"utf-8"),i}import{formatDuration as Vn}from"../types.js";function Yn(n,t){let e=[];if(n.waveEfficiency.timeSavedMs>0&&n.totalStreams>1){let r=Vn(n.waveEfficiency.timeSavedMs),i=n.waveEfficiency.sequentialMs>0?Math.round(n.waveEfficiency.timeSavedMs/n.waveEfficiency.sequentialMs*100):0;e.push(`${n.totalStreams} streams ran in parallel across ${n.totalWaves} wave(s), saving ${r} (${i}%).`)}else n.totalStreams>1&&e.push(`${n.totalStreams} streams executed across ${n.totalWaves} wave(s).`);let s=Object.entries(n.failurePatterns);if(s.length>0){s.sort((l,c)=>c[1]-l[1]);let[r,i]=s[0],a=s.reduce((l,[,c])=>l+c,0);r==="type_error"?e.push(`${r} was the most common failure (${i}/${a}). Consider adding a types-only stream first.`):e.push(`${r} was the most common failure (${i}/${a}).`)}if(t&&t.length>0){let r=t.reduce((a,l)=>a+l.planQualityScore,0)/t.length,i=n.planQualityScore-r;i>10?e.push(`Plan quality improved from ${Math.round(r)} to ${n.planQualityScore} \u2014 orchex is learning your patterns.`):i<-10?e.push(`Plan quality dropped from ${Math.round(r)} to ${n.planQualityScore}. Review the failure patterns above.`):e.push(`Plan quality score: ${n.planQualityScore}/100 (consistent with previous runs at ~${Math.round(r)}).`)}else e.push(`Plan quality score: ${n.planQualityScore}/100.`);let o=n.tokenUsage.totalInput+n.tokenUsage.totalOutput;if(o>0&&e.length<3){let r=Object.keys(n.tokenUsage.byProvider);r.length>1&&e.push(`Used ${r.length} providers: ${r.join(", ")} \u2014 total ${o.toLocaleString()} tokens.`)}return e.slice(0,3)}import*as b from"fs/promises";import*as M from"path";var He=".first-run-complete";async function Gn(n){let t=M.join(n,".orchex");try{await b.access(t)}catch{return!0}try{return await b.access(M.join(t,He)),!1}catch{}try{let e=M.join(t,"archive");if((await b.readdir(e)).length>0)return!1}catch{}try{let e=M.join(t,"reports");if((await b.readdir(e)).some(o=>o.endsWith(".json")))return!1}catch{}try{let e=M.join(t,"learn","events.jsonl");if((await b.stat(e)).size>0)return!1}catch{}return!0}async function Kn(n){let t=M.join(n,".orchex");await b.mkdir(t,{recursive:!0}),await b.writeFile(M.join(t,He),new Date().toISOString(),"utf-8")}function Jn(){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(`
142
+ `)}import*as W from"fs/promises";import*as E from"path";async function Qn(n,t){if(!t.confirm)throw new Error("Reset learning requires --confirm flag. This permanently deletes learning data.");let e=[],s=E.join(n,".orchex","learn"),o=E.join(n,".orchex","reports");t.patternsOnly?await G(E.join(s,"patterns.json"),e):t.reportsOnly?await Be(o,e,".json"):(await G(E.join(s,"thresholds.json"),e),await G(E.join(s,"events.jsonl"),e),await G(E.join(s,"patterns.json"),e),await Be(o,e,".json"));let r=t.patternsOnly?"patterns":t.reportsOnly?"reports":"all learning data";return{deleted:e,totalDeleted:e.length,message:e.length>0?`Reset ${r}: ${e.length} file(s) deleted.`:`No ${r} found to delete.`}}async function G(n,t){try{await W.unlink(n),t.push(E.basename(n))}catch(e){if(e.code!=="ENOENT")throw e}}async function Be(n,t,e){try{let s=await W.readdir(n);for(let o of s)e&&!o.endsWith(e)||(await W.unlink(E.join(n,o)),t.push(o))}catch(s){if(s.code!=="ENOENT")throw s}}import{createLogger as Xn}from"../logging.js";var Zn=Xn("iteration-evaluator");function es(n){let{streamResults:t,iterationNumber:e,maxIterations:s,intent:o}=n;if(e>=s){let d=t.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?t.filter(f=>f.status==="failed").map(f=>`${f.id}: ${f.error}`).join("; "):void 0}}let r=t.filter(d=>d.status==="failed"),i=t.filter(d=>d.status==="complete"&&!d.verifyPassed);if(r.length===0&&i.length===0)return{complete:!0,reason:`All ${t.length} stream(s) completed and verified successfully`};let l=[];for(let d of r)l.push(`Stream "${d.id}" failed: ${d.error??"unknown error"}`);for(let d of i)l.push(`Stream "${d.id}" verify failed: ${d.verifyError??"verification error"}`);let c=l.join("; "),u=`Fix the following issues from the previous attempt to "${o}": ${c}`;return Zn.info({iteration:e,failed:r.length,verifyFailed:i.length},"iteration_incomplete"),{complete:!1,reason:`${r.length} stream(s) failed, ${i.length} verification(s) failed`,nextIntent:u,failureSummary:c}}var ts={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"]},ns={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"]},ss={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"]},os={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"]},rs={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"]},is=[ts,ns,ss,os,rs];function K(n){let t=n.toLowerCase(),e=null;for(let s of is){let o=0;for(let r of s.keywords)t.includes(r.toLowerCase())&&(o+=2);for(let r of s.patterns){let i=r.toLowerCase().split(/[\s/,]+/).filter(l=>l.length>2);i.filter(l=>t.includes(l)).length>=i.length/2&&(o+=1)}o>0&&(!e||o>e.score)&&(e={template:s,score:o})}return e&&e.score>=3?e.template:null}function le(n,t){let e=[];if(n.id==="documentation-set"){let s=t.topics||[];for(let o of s)e.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(n.id==="code-feature"){let s=t.featureName;e.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(n.id==="migration"){let s=t.featureName,o=t.components||[];e.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)e.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"});e.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(n.id==="tutorial"){let s=t.topics||[];for(let o of s)e.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(n.id==="api-reference"){let s=t.modules||[];for(let o of s)e.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 e}function as(n){let t=n.owns||[],e=n.reads||[];if(t.length>5)return{originalStream:n.name,reason:`Stream owns ${t.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(e.length>10)return{originalStream:n.name,reason:`Stream reads ${e.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=`${n.name} ${n.plan||""}`,o=K(s);return o&&["multiple","all","complete","full","entire"].some(a=>n.name.toLowerCase().includes(a))?{originalStream:n.name,reason:"Stream name suggests broad scope that could be split",template:o,guidance:o.guidelines,suggestedStreams:[]}:null}function cs(n,t,e){if(e.issues.length===0)return null;let s=e.issues.some(c=>c.severity==="error"),o=e.issues.some(c=>c.severity==="warning"),r=`${t.name??n} ${t.plan??""}`,i=K(r),a=null;if(i){let c=n.replace(/-/g,"_");a=le(i,{featureName:c})}let l="";s?l=`Stream "${n}" has critical issues:
131
143
  `:o?l=`Stream "${n}" has potential issues:
132
144
  `:l=`Stream "${n}" has suggestions:
133
145
  `;for(let c of e.issues){let u=c.severity==="error"?"\u274C":c.severity==="warning"?"\u26A0\uFE0F":"\u2139\uFE0F";l+=` ${u} ${c.message}
@@ -137,24 +149,23 @@ Reference code:
137
149
  `;for(let c of a){let u=c.owns?.join(", ")??"TBD";l+=` \u2022 ${c.name}: ${u}
138
150
  `}l+=`
139
151
  Accept suggested split? [Y/n/edit]`}else l+=`
140
- No template match. Consider manual split or ignore.`;return{streamId:n,violations:e.issues,qualityScore:e.qualityScore,templateMatch:i,suggestedSplit:a,message:l,action:s?"accept_split":o?"modify":"ignore"}}function Gn(n,t){let e=t??N(),s=[];for(let[o,r]of Object.entries(n)){let i=e.analyzeStream(o,r),a=Yn(o,r,i);a&&s.push(a)}return s.sort((o,r)=>{let i=o.violations.some(u=>u.severity==="error"),a=r.violations.some(u=>u.severity==="error");if(i&&!a)return-1;if(!i&&a)return 1;let l=o.violations.some(u=>u.severity==="warning"),c=r.violations.some(u=>u.severity==="warning");return l&&!c?-1:!l&&c?1:0}),s}function Kn(n){let t=n.filter(r=>r.violations.some(i=>i.severity==="error")).length,e=n.filter(r=>r.violations.some(i=>i.severity==="warning")&&!r.violations.some(i=>i.severity==="error")).length,s=n.filter(r=>r.templateMatch!==null).length,o="";if(n.length===0)o="\u2705 All streams passed validation. No issues detected.";else if(o=`Stream Validation Summary:
152
+ No template match. Consider manual split or ignore.`;return{streamId:n,violations:e.issues,qualityScore:e.qualityScore,templateMatch:i,suggestedSplit:a,message:l,action:s?"accept_split":o?"modify":"ignore"}}function ls(n,t){let e=t??N(),s=[];for(let[o,r]of Object.entries(n)){let i=e.analyzeStream(o,r),a=cs(o,r,i);a&&s.push(a)}return s.sort((o,r)=>{let i=o.violations.some(u=>u.severity==="error"),a=r.violations.some(u=>u.severity==="error");if(i&&!a)return-1;if(!i&&a)return 1;let l=o.violations.some(u=>u.severity==="warning"),c=r.violations.some(u=>u.severity==="warning");return l&&!c?-1:!l&&c?1:0}),s}function us(n){let t=n.filter(r=>r.violations.some(i=>i.severity==="error")).length,e=n.filter(r=>r.violations.some(i=>i.severity==="warning")&&!r.violations.some(i=>i.severity==="error")).length,s=n.filter(r=>r.templateMatch!==null).length,o="";if(n.length===0)o="\u2705 All streams passed validation. No issues detected.";else if(o=`Stream Validation Summary:
141
153
  `,o+=` ${t} stream${t!==1?"s":""} with errors
142
154
  `,o+=` ${e} stream${e!==1?"s":""} with warnings
143
155
  `,o+=` ${s} template match${s!==1?"es":""} found
144
156
  `,t>0){o+=`
145
157
  \u274C Critical issues (must fix):
146
158
  `;for(let r of n.filter(i=>i.violations.some(a=>a.severity==="error"))){let i=r.violations.filter(a=>a.severity==="error").map(a=>a.type);o+=` \u2022 ${r.streamId}: ${i.join(", ")}
147
- `}}return{totalStreams:n.length,errorCount:t,warningCount:e,templateMatches:s,summary:o}}function Jn(n){let t=new Map;for(let[c,u]of Object.entries(n))for(let d of u.owns??[]){let f=t.get(d)??[];f.push(c),t.set(d,f)}let e=new Map;function s(c){return e.has(c)||e.set(c,c),e.get(c)!==c&&e.set(c,s(e.get(c))),e.get(c)}function o(c,u){let d=s(c),f=s(u);d!==f&&(d<f?e.set(f,d):e.set(d,f))}for(let[,c]of t)if(!(c.length<2))for(let u=1;u<c.length;u++)o(c[0],c[u]);let r=new Map;for(let c of Object.keys(n)){let u=s(c),d=r.get(u)??[];d.push(c),r.set(u,d)}let i={},a=[],l=new Map;for(let[,c]of r){if(c.length===1){let w=c[0];i[w]=n[w],l.set(w,w);continue}c.sort();let u=c[0],d=[],f=new Set,p=new Set,m=new Set,h=[],y=[];for(let w of c){let x=n[w];d.push(x.name);for(let S of x.owns??[])f.add(S);for(let S of x.reads??[])p.add(S);for(let S of x.deps??[])m.add(S);for(let S of x.verify??[])h.includes(S)||h.push(S);x.plan&&y.push(`## ${x.name}
159
+ `}}return{totalStreams:n.length,errorCount:t,warningCount:e,templateMatches:s,summary:o}}function ds(n){let t=new Map;for(let[c,u]of Object.entries(n))for(let d of u.owns??[]){let f=t.get(d)??[];f.push(c),t.set(d,f)}let e=new Map;function s(c){return e.has(c)||e.set(c,c),e.get(c)!==c&&e.set(c,s(e.get(c))),e.get(c)}function o(c,u){let d=s(c),f=s(u);d!==f&&(d<f?e.set(f,d):e.set(d,f))}for(let[,c]of t)if(!(c.length<2))for(let u=1;u<c.length;u++)o(c[0],c[u]);let r=new Map;for(let c of Object.keys(n)){let u=s(c),d=r.get(u)??[];d.push(c),r.set(u,d)}let i={},a=[],l=new Map;for(let[,c]of r){if(c.length===1){let x=c[0];i[x]=n[x],l.set(x,x);continue}c.sort();let u=c[0],d=[],f=new Set,p=new Set,m=new Set,g=[],y=[];for(let x of c){let h=n[x];d.push(h.name);for(let w of h.owns??[])f.add(w);for(let w of h.reads??[])p.add(w);for(let w of h.deps??[])m.add(w);for(let w of h.verify??[])g.includes(w)||g.push(w);h.plan&&y.push(`## ${h.name}
148
160
 
149
- ${x.plan}`),l.set(w,u)}for(let w of f)p.delete(w);let O=new Set(c);for(let w of O)m.delete(w);let T,g=[];for(let w of c){let x=n[w];x.timeoutMs&&(!T||x.timeoutMs>T)&&(T=x.timeoutMs);for(let S of x.setup??[])g.includes(S)||g.push(S)}i[u]={name:d.join(" + "),owns:[...f],reads:[...p],deps:[...m],plan:y.join(`
161
+ ${h.plan}`),l.set(x,u)}for(let x of f)p.delete(x);let v=new Set(c);for(let x of v)m.delete(x);let k,S=[];for(let x of c){let h=n[x];h.timeoutMs&&(!k||h.timeoutMs>k)&&(k=h.timeoutMs);for(let w of h.setup??[])S.includes(w)||S.push(w)}i[u]={name:d.join(" + "),owns:[...f],reads:[...p],deps:[...m],plan:y.join(`
150
162
 
151
163
  ---
152
164
 
153
- `),verify:h,setup:g.length>0?g:void 0,timeoutMs:T},a.push(`Merged [${c.join(", ")}] \u2192 ${u} (shared files: ${[...f].filter(w=>(t.get(w)??[]).length>1).join(", ")})`)}for(let[c,u]of Object.entries(i)){let d=u.deps??[],f=[...new Set(d.map(p=>l.get(p)??p))].filter(p=>p!==c);u.deps=f}return{streams:i,merges:a}}function Qn(n){return n.isTestGeneration?{provider:void 0,confidence:.3,reason:"Test generation works well with any provider \u2014 use your default."}:n.isStructuralChange&&(n.totalOwnedLines>500||n.fileCount>4)?{provider:"anthropic",confidence:.7,reason:`Structural edits across ${n.fileCount} files (${n.totalOwnedLines} lines) \u2014 Claude handles complex multi-file reasoning best.`}:!n.isStructuralChange&&n.totalOwnedLines<200&&n.fileCount<=2?{provider:"openai",model:"gpt-4.1-mini",confidence:.6,reason:`Simple transform (${n.totalOwnedLines} lines, ${n.fileCount} files) \u2014 GPT-4.1-mini is cost-effective for small tasks.`}:n.isStructuralChange?{provider:"anthropic",confidence:.5,reason:`Structural changes across ${n.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 Xn(n,t,e){let s=n.toLowerCase(),o=s.includes("test")||s.includes("spec")||t.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:e,isStructuralChange:i,isTestGeneration:o,fileCount:t.length}}import*as j from"fs/promises";import*as ce from"path";import*as K from"yaml";import{exec as Zn}from"child_process";import{promisify as es}from"util";var Le=es(Zn);async function ts(n,t){let e=ce.join(n,".orchex","active","manifest.yaml"),s=await j.readFile(e,"utf-8"),o=K.parse(s),r=new Set(t);for(let[i,a]of Object.entries(o.streams))a.status==="pending"&&(r.has(i)||(o.streams[i].status="skipped"));await j.writeFile(e,K.stringify(o,{indent:2,lineWidth:0}),"utf-8")}async function ns(n,t,e){let s=[],o=[];for(let r of e){let i=ce.join(n,r);try{let{stdout:a}=await Le(`git ls-files "${r}"`,{cwd:n});if(a.trim())await Le(`git checkout HEAD -- "${r}"`,{cwd:n}),s.push(r);else try{await j.unlink(i),s.push(r)}catch(l){l.code!=="ENOENT"&&o.push(`Failed to delete ${r}: ${l.message}`)}}catch(a){if(a.message?.includes("did not match any"))continue;o.push(`Failed to rollback ${r}: ${a.message}`)}}return{streamId:t,reverted:s,errors:o}}import{loadManifest as Ne,saveManifest as We}from"../manifest.js";import{createLogger as ss}from"../logging.js";var le=ss("fix-stream-manager");async function os(n){let t=await Ne(n),e={skipped:[],warnings:[]},s=Object.entries(t.streams).filter(([o,r])=>r.parentStreamId!==void 0);for(let[o,r]of s)r.status==="pending"&&cs(t,r.parentStreamId)&&(t.streams[o].status="skipped",t.streams[o].error="Parent stream completed; fix no longer needed",e.skipped.push(o));return e.skipped.length>0&&await We(n,t),e}async function rs(n,t){let e=await Ne(n),s={skipped:[],warnings:[]},o=ls(e,t);for(let a of o){let l=e.streams[a];l.status==="pending"?(e.streams[a].status="skipped",e.streams[a].error=`Ancestor '${t}' completed; fix no longer needed`,s.skipped.push(a)):l.status==="in_progress"&&(e.streams[a].status="skipped",e.streams[a].error=`Sibling fix already resolved this stream (completed: '${t}')`,s.skipped.push(a))}let r=!1,i=e.streams[t];if(i?.parentStreamId){let a=i.parentStreamId;for(;e.streams[a]?.parentStreamId;)a=e.streams[a].parentStreamId;let l=e.streams[a];l&&l.status==="failed"&&(e.streams[a].status="complete",delete e.streams[a].error,r=!0,le.info({fixStreamId:t,rootStreamId:a},"fix_stream_propagated_completion_to_root"))}return(s.skipped.length>0||r)&&await We(n,e),s}function J(n,t){let e=n.streams[t];if(!e||!e.parentStreamId)return null;let s=[t],o=e.parentStreamId,r=new Set;for(;o&&!r.has(o);){r.add(o);let i=n.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 is(n,t){return n.streams[t]?.parentStreamId!==void 0}function as(n,t){return J(n,t)?.rootStreamId??t}function cs(n,t){let e=t,s=new Set;for(;e;){if(s.has(e)){le.warn({streamId:e},"circular_reference_in_fix_chain");break}s.add(e);let o=n.streams[e];if(!o){le.warn({parentId:e},"fix_stream_orphaned_parent");break}if(o.status==="complete")return!0;e=o.parentStreamId}return!1}function ls(n,t){let e=[];for(let[s,o]of Object.entries(n.streams))o.parentStreamId&&us(n,s,t)&&e.push(s);return e}function us(n,t,e){let s=n.streams[t]?.parentStreamId,o=new Set;for(;s&&!o.has(s);){if(o.add(s),s===e)return!0;s=n.streams[s]?.parentStreamId}return!1}var ds=3;function fs(n,t){let e=0,s=t;for(;s;){let o=n.streams[s];if(!o)break;e+=o.attempts??0,s=o.parentStreamId}return e}function Ue(n,t){return J(n,t)?.rootStreamId??t}function ps(n,t){let e=Ue(n,t);for(let[s,o]of Object.entries(n.streams)){if(s===t||!o.parentStreamId||o.status!=="pending"&&o.status!=="in_progress")continue;if(Ue(n,s)===e)return!0}return!1}function ms(n,t,e){let s=n.streams[t];if(!s||s.status==="failed"&&s.error?.startsWith("Setup failed:"))return null;let o=s.error??"",r=e??ie(o);if(!r.selfHealable||ps(n,t)||fs(n,t)>=ds)return null;let l=(s.attempts??0)+1,c=`${t}-fix-${l}`,u=t,d=[`## Fix Attempt #${l} for "${s.name}"`,"","### Original Plan",s.plan??"(no plan)","","### Error That Occurred","```",o,"```","",`### Error Category: ${r.category}`,"",`### Suggestion: ${r.suggestion}`,"","### Instructions",`This is a retry of the failed stream "${t}".`,"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."].join(`
154
- `),f={name:`${s.name} (Fix #${l})`,deps:s.deps??[],owns:s.owns??[],reads:s.reads??[],plan:d,setup:s.setup??[],verify:s.verify??[],status:"pending",attempts:0,parentStreamId:u};return{fixStreamId:c,fixStream:f,analysis:{category:r.category,suggestion:r.suggestion}}}import*as qe from"fs";import*as ue from"path";import{createLogger as ws}from"../logging.js";var Q={"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},"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}},hs=.9;function He(n){if(Q[n])return Q[n];let t=n.toLowerCase();for(let[e,s]of Object.entries(Q))if(e!=="default"&&t.includes(e.split("-").slice(0,2).join("-")))return s;return Q.default}function ze(n,t,e,s){let o=He(e),r=n/1e3*o.input,i=t/1e3*o.output,a=r+i,l;s&&s>0&&(l=s/1e3*o.input*hs);let c=a-(l??0);return{inputTokens:n,outputTokens:t,inputCost:r,outputCost:i,totalCost:a,cacheHitTokens:s,cacheDiscount:l,finalCost:c,model:e}}function gs(n,t,e=.3){let s=Math.ceil(n*e);return ze(n,s,t)}var Uo=ws("smart-router"),Be={anthropic:"claude-sonnet-4-5-20250929",openai:"gpt-4.1",google:"gemini-2.5-pro",deepseek:"deepseek-chat",ollama:"llama3.3:70b"};function ys(n){let t=[...n.owns,...n.reads??[]],e=n.name.toLowerCase(),s=(n.plan??"").toLowerCase();return t.some(o=>o.match(/\.(md|mdx|txt|rst)$/))||e.includes("doc")||e.includes("readme")?"docs":t.some(o=>o.includes(".test.")||o.includes(".spec.")||o.includes("__tests__"))||e.includes("test")?"test":t.some(o=>o.includes("migration"))||e.includes("migrat")?"migration":n.owns.length>=3||(n.estimatedLines??0)>500||s.includes("refactor")||s.includes("restructur")?"complex-code":"simple-code"}function xs(n,t){switch(n){case"docs":return{provider:"deepseek",model:"deepseek-chat",reasoning:`Routed documentation stream "${t.name}" to cheapest provider (DeepSeek)`};case"test":return{provider:"openai",model:"gpt-4o",reasoning:`Routed test stream "${t.name}" to mid-tier provider (GPT-4o)`};case"migration":return{provider:"google",model:"gemini-2.5-pro",reasoning:`Routed migration stream "${t.name}" to cost-effective provider (Gemini)`};case"complex-code":return{provider:"anthropic",model:"claude-sonnet-4-5-20250929",reasoning:`Routed complex code stream "${t.name}" (${t.owns.length} files${(t.estimatedLines??0)>500?", large file edits":""}) to premium provider (Claude)`};default:return{provider:"openai",model:"gpt-4o",reasoning:`Routed simple code stream "${t.name}" to balanced provider (GPT-4o)`}}}function Ss(n){switch(n){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 vs(n,t,e){let s=e?.availableProviders,o=e?.registryModels,r=(l,c)=>o?.[l]?.length?o[l].includes(c)?c:o[l][0]:c;if(t.overrides?.[n.id]){let l=t.overrides[n.id];return{provider:l.provider,model:l.model,reasoning:"User override"}}if(t.defaultProvider){let l=t.defaultModel??Be[t.defaultProvider]??t.defaultProvider,c=r(t.defaultProvider,l);return{provider:t.defaultProvider,model:c,reasoning:"User default provider preference"}}let i=ys(n),a=xs(i,n);if(s&&!s.has(a.provider)){let l=Ss(i);for(let c of l)if(s.has(c)){let u=r(c,Be[c]??c);return{provider:c,model:u,reasoning:`${a.reasoning} \u2014 ${a.provider} not available, fell back to ${c}`}}}return a.model=r(a.provider,a.model),a}function $s(n){let t=n??ue.join(process.env.HOME??"",".orchex"),e=ue.join(t,"config.json");try{let s=qe.readFileSync(e,"utf-8"),o=JSON.parse(s);return{defaultProvider:o.routing?.defaultProvider,defaultModel:o.routing?.defaultModel,overrides:o.routing?.overrides}}catch{return{}}}import*as A from"fs/promises";import*as X from"path";var E;(function(n){n.STREAM_COUNT_SWEET_SPOT="stream-count-sweet-spot",n.DEPENDENCY_ORDERING="dependency-ordering",n.FILE_PER_STREAM="file-per-stream",n.WAVE_EFFICIENCY="wave-efficiency",n.PROVIDER_PERFORMANCE="provider-performance",n.SELF_HEAL_PATTERN="self-heal-pattern",n.TIME_OF_DAY="time-of-day"})(E||(E={}));function Cs(n){let t=n.streamResults.filter(r=>r.status==="complete").length,e=n.streamResults.filter(r=>r.status==="failed").length,s=n.streamResults.filter(r=>r.status==="skipped").length,o=n.streamResults.reduce((r,i)=>r+(i.executionTimeMs??0),0);return{id:n.runId,feature:n.feature,timestamp:n.timestamp,success:n.planQualityScore>=80,totalStreams:n.totalStreams,completedStreams:t,failedStreams:e,skippedStreams:s,totalWaves:n.totalWaves,executionTimeMs:o,streams:n.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}))}}var bs=5;function ks(n){if(n.length<bs)return[];let t=[],e=[Ts,Es,Os,Ps,Ms,_s,Is];for(let s of e){let o=s(n);o&&t.push(o)}return t}function Ts(n){let t={low:{total:0,success:0,ids:[]},mid:{total:0,success:0,ids:[]},high:{total:0,success:0,ids:[]}};for(let u of n){let d=u.totalStreams<=5?"low":u.totalStreams<=8?"mid":"high";t[d].total++,u.success&&t[d].success++,t[d].ids.push(u.id)}if(t.low.total<3&&t.mid.total<3||t.high.total<2&&t.mid.total<2)return null;let e=t.low.total>0?t.low.success/t.low.total:0,s=t.high.total>0?t.high.success/t.high.total:0,o=t.mid.total>0?t.mid.success/t.mid.total:0,r=Math.max(e,o),i=Math.min(e,o,s);if(r-i<.2)return null;let a=e>=o?"low (1-5 streams)":"mid (6-8 streams)",l=Math.max(e,o),c=[...t.low.ids,...t.mid.ids,...t.high.ids];return{type:E.STREAM_COUNT_SWEET_SPOT,description:`Plans with ${a} succeed ${(l*100).toFixed(0)}% of the time`,confidence:Math.min(n.length/20,1),recommendation:`Prefer ${a.includes("low")?"3-5":"6-8"} streams per plan. Larger plans (${t.high.total>0?`>8 streams: ${(s*100).toFixed(0)}% success`:"not enough data"}) tend to fail more.`,evidence:{reportIds:c,metric:"streamCount",values:{"low_1-5_rate":`${(e*100).toFixed(0)}%`,"mid_6-8_rate":`${(o*100).toFixed(0)}%`,"high_9+_rate":`${(s*100).toFixed(0)}%`,low_count:t.low.total,high_count:t.high.total}}}}function Es(n){let t=0,e=0,s=0,o=0,r=[];for(let l of n){for(let c of l.streams)c.filesOwned<=4?(e++,c.status==="complete"&&t++):(o++,c.status==="complete"&&s++);r.push(l.id)}if(e<5||o<3)return null;let i=t/e,a=s/o;return i-a<.15?null:{type:E.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((e+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:e,high_files_count:o}}}}function Os(n){let t={},e=0,s=[];for(let l of n){for(let c of l.streams)c.status==="failed"&&c.errorCategory&&(t[c.errorCategory]=(t[c.errorCategory]||0)+1,e++);l.failedStreams>0&&s.push(l.id)}if(e<3)return null;let o=Object.entries(t).sort((l,c)=>c[1]-l[1]),[r,i]=o[0],a=i/e*100;return{type:E.SELF_HEAL_PATTERN,description:`${r} errors are the most common failure (${a.toFixed(0)}% of all errors)`,confidence:Math.min(e/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(([l,c])=>[l,`${c} (${(c/e*100).toFixed(0)}%)`]))}}}function Ps(n){let t=0,e=0,s=0,o=0,r=[];for(let l of n){let c=new Set(l.streams.filter(u=>!u.name.toLowerCase().includes("test")).map(u=>u.id));for(let u of l.streams){if(!u.name.toLowerCase().includes("test"))continue;u.deps&&u.deps.some(p=>c.has(p))?(t++,u.status==="complete"&&e++):(s++,u.status==="complete"&&o++)}r.push(l.id)}if(t<3||s<3)return null;let i=e/t,a=o/s;return i-a<.15?null:{type:E.DEPENDENCY_ORDERING,description:`Test streams with impl dependencies succeed ${(i*100).toFixed(0)}%, without: ${(a*100).toFixed(0)}%`,confidence:Math.min((t+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:t,without_deps_count:s}}}}function Ms(n){let t={low:{total:0,success:0},high:{total:0,success:0}},e=[];for(let l of n){let c=l.totalWaves<=3?"low":"high";t[c].total++,l.success&&t[c].success++,e.push(l.id)}if(t.low.total<3||t.high.total<3)return null;let s=t.low.success/t.low.total,o=t.high.success/t.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:E.WAVE_EFFICIENCY,description:`Orchestrations with ${a} waves succeed ${(i*100).toFixed(0)}%`,confidence:Math.min(n.length/15,1),recommendation:`Prefer ${a} waves for best results. ${r==="low"?"Keep dependency depth shallow.":"More waves indicates better dependency structure."}`,evidence:{reportIds:e,metric:"waveCount",values:{"low_1-3_rate":`${(s*100).toFixed(0)}%`,"high_4+_rate":`${(o*100).toFixed(0)}%`,low_count:t.low.total,high_count:t.high.total}}}}function _s(n){let t={},e=[];for(let l of n){for(let c of l.streams){let u=c.provider??l.provider??"unknown";u!=="unknown"&&(t[u]||(t[u]={total:0,success:0}),t[u].total++,c.status==="complete"&&t[u].success++)}e.push(l.id)}let s=Object.entries(t).filter(([l,c])=>c.total>=3);if(s.length<2)return null;let o=s.map(([l,c])=>({name:l,rate:c.success/c.total,total:c.total})),r=o.sort((l,c)=>c.rate-l.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.1?null:{type:E.PROVIDER_PERFORMANCE,description:`${i.name} succeeds ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(s.reduce((l,[c,u])=>l+u.total,0)/30,1),recommendation:`${i.name} performs best in your project. Consider using it as the default provider.`,evidence:{reportIds:e,metric:"providerPerformance",values:Object.fromEntries(o.map(l=>[l.name,`${(l.rate*100).toFixed(0)}% (n=${l.total})`]))}}}function Is(n){let t={morning:{total:0,success:0},afternoon:{total:0,success:0},evening:{total:0,success:0},night:{total:0,success:0}},e=[];for(let l of n){let c=new Date(l.timestamp).getHours(),u=c<6?"night":c<12?"morning":c<18?"afternoon":"evening";t[u].total++,l.success&&t[u].success++,e.push(l.id)}let s=Object.entries(t).filter(([l,c])=>c.total>=3);if(s.length<2)return null;let o=s.map(([l,c])=>({name:l,rate:c.success/c.total,total:c.total})),r=o.sort((l,c)=>c.rate-l.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.2?null:{type:E.TIME_OF_DAY,description:`${i.name} runs succeed ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(n.length/20,1),recommendation:`Orchestrations during ${i.name} hours have the highest success rate. This may correlate with API rate limit availability.`,evidence:{reportIds:e,metric:"timeOfDay",values:Object.fromEntries(o.map(l=>[l.name,`${(l.rate*100).toFixed(0)}% (n=${l.total})`]))}}}function Rs(n){if(n.length===0)return"No significant patterns detected yet. Need more execution history.";let t=["=== Detected Patterns ===",""];for(let e of n){let s=e.confidence>=.7?"HIGH":e.confidence>=.4?"MEDIUM":"LOW";t.push(`[${s}] ${e.description}`),t.push(` Recommendation: ${e.recommendation}`),t.push("")}return t.join(`
155
- `)}function Fs(n){if(n.length===0)return"";let t=n.filter(e=>e.confidence>=.4).map(e=>`- ${e.recommendation}`).join(`
165
+ `),verify:g,setup:S.length>0?S:void 0,timeoutMs:k},a.push(`Merged [${c.join(", ")}] \u2192 ${u} (shared files: ${[...f].filter(x=>(t.get(x)??[]).length>1).join(", ")})`)}for(let[c,u]of Object.entries(i)){let d=u.deps??[],f=[...new Set(d.map(p=>l.get(p)??p))].filter(p=>p!==c);u.deps=f}return{streams:i,merges:a}}function fs(n){return n.isTestGeneration?{provider:void 0,confidence:.3,reason:"Test generation works well with any provider \u2014 use your default."}:n.isStructuralChange&&(n.totalOwnedLines>500||n.fileCount>4)?{provider:"anthropic",confidence:.7,reason:`Structural edits across ${n.fileCount} files (${n.totalOwnedLines} lines) \u2014 Claude handles complex multi-file reasoning best.`}:!n.isStructuralChange&&n.totalOwnedLines<200&&n.fileCount<=2?{provider:"openai",model:"gpt-4.1-mini",confidence:.6,reason:`Simple transform (${n.totalOwnedLines} lines, ${n.fileCount} files) \u2014 GPT-4.1-mini is cost-effective for small tasks.`}:n.isStructuralChange?{provider:"anthropic",confidence:.5,reason:`Structural changes across ${n.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(n,t,e){let s=n.toLowerCase(),o=s.includes("test")||s.includes("spec")||t.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:e,isStructuralChange:i,isTestGeneration:o,fileCount:t.length}}import*as j from"fs/promises";import*as ue from"path";import*as J from"yaml";import{exec as ms}from"child_process";import{promisify as hs}from"util";var qe=hs(ms);async function gs(n,t){let e=ue.join(n,".orchex","active","manifest.yaml"),s=await j.readFile(e,"utf-8"),o=J.parse(s),r=new Set(t);for(let[i,a]of Object.entries(o.streams))a.status==="pending"&&(r.has(i)||(o.streams[i].status="skipped"));await j.writeFile(e,J.stringify(o,{indent:2,lineWidth:0}),"utf-8")}async function ws(n,t,e){let s=[],o=[];for(let r of e){let i=ue.join(n,r);try{let{stdout:a}=await qe(`git ls-files "${r}"`,{cwd:n});if(a.trim())await qe(`git checkout HEAD -- "${r}"`,{cwd:n}),s.push(r);else try{await j.unlink(i),s.push(r)}catch(l){l.code!=="ENOENT"&&o.push(`Failed to delete ${r}: ${l.message}`)}}catch(a){if(a.message?.includes("did not match any"))continue;o.push(`Failed to rollback ${r}: ${a.message}`)}}return{streamId:t,reverted:s,errors:o}}import*as Ke from"fs";import*as de from"path";import{createLogger as Ss}from"../logging.js";var Q={"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},"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}},ys=.9;function Ve(n){if(Q[n])return Q[n];let t=n.toLowerCase();for(let[e,s]of Object.entries(Q))if(e!=="default"&&t.includes(e.split("-").slice(0,2).join("-")))return s;return Q.default}function Ye(n,t,e,s){let o=Ve(e),r=n/1e3*o.input,i=t/1e3*o.output,a=r+i,l;s&&s>0&&(l=s/1e3*o.input*ys);let c=a-(l??0);return{inputTokens:n,outputTokens:t,inputCost:r,outputCost:i,totalCost:a,cacheHitTokens:s,cacheDiscount:l,finalCost:c,model:e}}function xs(n,t,e=.3){let s=Math.ceil(n*e);return Ye(n,s,t)}var qo=Ss("smart-router"),Ge={anthropic:"claude-sonnet-4-5-20250929",openai:"gpt-4.1",google:"gemini-2.5-pro",deepseek:"deepseek-chat",ollama:"llama3.3:70b"};function $s(n){let t=[...n.owns,...n.reads??[]],e=n.name.toLowerCase(),s=(n.plan??"").toLowerCase();return t.some(o=>o.match(/\.(md|mdx|txt|rst)$/))||e.includes("doc")||e.includes("readme")?"docs":t.some(o=>o.includes(".test.")||o.includes(".spec.")||o.includes("__tests__"))||e.includes("test")?"test":t.some(o=>o.includes("migration"))||e.includes("migrat")?"migration":n.owns.length>=3||(n.estimatedLines??0)>500||s.includes("refactor")||s.includes("restructur")?"complex-code":"simple-code"}function vs(n,t){switch(n){case"docs":return{provider:"deepseek",model:"deepseek-chat",reasoning:`Routed documentation stream "${t.name}" to cheapest provider (DeepSeek)`};case"test":return{provider:"openai",model:"gpt-4o",reasoning:`Routed test stream "${t.name}" to mid-tier provider (GPT-4o)`};case"migration":return{provider:"google",model:"gemini-2.5-pro",reasoning:`Routed migration stream "${t.name}" to cost-effective provider (Gemini)`};case"complex-code":return{provider:"anthropic",model:"claude-sonnet-4-5-20250929",reasoning:`Routed complex code stream "${t.name}" (${t.owns.length} files${(t.estimatedLines??0)>500?", large file edits":""}) to premium provider (Claude)`};default:return{provider:"openai",model:"gpt-4o",reasoning:`Routed simple code stream "${t.name}" to balanced provider (GPT-4o)`}}}function Cs(n){switch(n){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 bs(n,t,e){let s=e?.availableProviders,o=e?.registryModels,r=(l,c)=>o?.[l]?.length?o[l].includes(c)?c:o[l][0]:c;if(t.overrides?.[n.id]){let l=t.overrides[n.id];return{provider:l.provider,model:l.model,reasoning:"User override"}}if(t.defaultProvider){let l=t.defaultModel??Ge[t.defaultProvider]??t.defaultProvider,c=r(t.defaultProvider,l);return{provider:t.defaultProvider,model:c,reasoning:"User default provider preference"}}let i=$s(n),a=vs(i,n);if(s&&!s.has(a.provider)){let l=Cs(i);for(let c of l)if(s.has(c)){let u=r(c,Ge[c]??c);return{provider:c,model:u,reasoning:`${a.reasoning} \u2014 ${a.provider} not available, fell back to ${c}`}}}return a.model=r(a.provider,a.model),a}function ks(n){let t=n??de.join(process.env.HOME??"",".orchex"),e=de.join(t,"config.json");try{let s=Ke.readFileSync(e,"utf-8"),o=JSON.parse(s);return{defaultProvider:o.routing?.defaultProvider,defaultModel:o.routing?.defaultModel,overrides:o.routing?.overrides}}catch{return{}}}import*as A from"fs/promises";import*as X from"path";var O;(function(n){n.STREAM_COUNT_SWEET_SPOT="stream-count-sweet-spot",n.DEPENDENCY_ORDERING="dependency-ordering",n.FILE_PER_STREAM="file-per-stream",n.WAVE_EFFICIENCY="wave-efficiency",n.PROVIDER_PERFORMANCE="provider-performance",n.SELF_HEAL_PATTERN="self-heal-pattern",n.TIME_OF_DAY="time-of-day"})(O||(O={}));function Ts(n){let t=n.streamResults.filter(r=>r.status==="complete").length,e=n.streamResults.filter(r=>r.status==="failed").length,s=n.streamResults.filter(r=>r.status==="skipped").length,o=n.streamResults.reduce((r,i)=>r+(i.executionTimeMs??0),0);return{id:n.runId,feature:n.feature,timestamp:n.timestamp,success:n.planQualityScore>=80,totalStreams:n.totalStreams,completedStreams:t,failedStreams:e,skippedStreams:s,totalWaves:n.totalWaves,executionTimeMs:o,streams:n.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}))}}var Es=5;function Os(n){if(n.length<Es)return[];let t=[],e=[Ps,Ms,Is,Rs,_s,Fs,js];for(let s of e){let o=s(n);o&&t.push(o)}return t}function Ps(n){let t={low:{total:0,success:0,ids:[]},mid:{total:0,success:0,ids:[]},high:{total:0,success:0,ids:[]}};for(let u of n){let d=u.totalStreams<=5?"low":u.totalStreams<=8?"mid":"high";t[d].total++,u.success&&t[d].success++,t[d].ids.push(u.id)}if(t.low.total<3&&t.mid.total<3||t.high.total<2&&t.mid.total<2)return null;let e=t.low.total>0?t.low.success/t.low.total:0,s=t.high.total>0?t.high.success/t.high.total:0,o=t.mid.total>0?t.mid.success/t.mid.total:0,r=Math.max(e,o),i=Math.min(e,o,s);if(r-i<.2)return null;let a=e>=o?"low (1-5 streams)":"mid (6-8 streams)",l=Math.max(e,o),c=[...t.low.ids,...t.mid.ids,...t.high.ids];return{type:O.STREAM_COUNT_SWEET_SPOT,description:`Plans with ${a} succeed ${(l*100).toFixed(0)}% of the time`,confidence:Math.min(n.length/20,1),recommendation:`Prefer ${a.includes("low")?"3-5":"6-8"} streams per plan. Larger plans (${t.high.total>0?`>8 streams: ${(s*100).toFixed(0)}% success`:"not enough data"}) tend to fail more.`,evidence:{reportIds:c,metric:"streamCount",values:{"low_1-5_rate":`${(e*100).toFixed(0)}%`,"mid_6-8_rate":`${(o*100).toFixed(0)}%`,"high_9+_rate":`${(s*100).toFixed(0)}%`,low_count:t.low.total,high_count:t.high.total}}}}function Ms(n){let t=0,e=0,s=0,o=0,r=[];for(let l of n){for(let c of l.streams)c.filesOwned<=4?(e++,c.status==="complete"&&t++):(o++,c.status==="complete"&&s++);r.push(l.id)}if(e<5||o<3)return null;let i=t/e,a=s/o;return i-a<.15?null:{type:O.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((e+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:e,high_files_count:o}}}}function Is(n){let t={},e=0,s=[];for(let l of n){for(let c of l.streams)c.status==="failed"&&c.errorCategory&&(t[c.errorCategory]=(t[c.errorCategory]||0)+1,e++);l.failedStreams>0&&s.push(l.id)}if(e<3)return null;let o=Object.entries(t).sort((l,c)=>c[1]-l[1]),[r,i]=o[0],a=i/e*100;return{type:O.SELF_HEAL_PATTERN,description:`${r} errors are the most common failure (${a.toFixed(0)}% of all errors)`,confidence:Math.min(e/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(([l,c])=>[l,`${c} (${(c/e*100).toFixed(0)}%)`]))}}}function Rs(n){let t=0,e=0,s=0,o=0,r=[];for(let l of n){let c=new Set(l.streams.filter(u=>!u.name.toLowerCase().includes("test")).map(u=>u.id));for(let u of l.streams){if(!u.name.toLowerCase().includes("test"))continue;u.deps&&u.deps.some(p=>c.has(p))?(t++,u.status==="complete"&&e++):(s++,u.status==="complete"&&o++)}r.push(l.id)}if(t<3||s<3)return null;let i=e/t,a=o/s;return i-a<.15?null:{type:O.DEPENDENCY_ORDERING,description:`Test streams with impl dependencies succeed ${(i*100).toFixed(0)}%, without: ${(a*100).toFixed(0)}%`,confidence:Math.min((t+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:t,without_deps_count:s}}}}function _s(n){let t={low:{total:0,success:0},high:{total:0,success:0}},e=[];for(let l of n){let c=l.totalWaves<=3?"low":"high";t[c].total++,l.success&&t[c].success++,e.push(l.id)}if(t.low.total<3||t.high.total<3)return null;let s=t.low.success/t.low.total,o=t.high.success/t.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:O.WAVE_EFFICIENCY,description:`Orchestrations with ${a} waves succeed ${(i*100).toFixed(0)}%`,confidence:Math.min(n.length/15,1),recommendation:`Prefer ${a} waves for best results. ${r==="low"?"Keep dependency depth shallow.":"More waves indicates better dependency structure."}`,evidence:{reportIds:e,metric:"waveCount",values:{"low_1-3_rate":`${(s*100).toFixed(0)}%`,"high_4+_rate":`${(o*100).toFixed(0)}%`,low_count:t.low.total,high_count:t.high.total}}}}function Fs(n){let t={},e=[];for(let l of n){for(let c of l.streams){let u=c.provider??l.provider??"unknown";u!=="unknown"&&(t[u]||(t[u]={total:0,success:0}),t[u].total++,c.status==="complete"&&t[u].success++)}e.push(l.id)}let s=Object.entries(t).filter(([l,c])=>c.total>=3);if(s.length<2)return null;let o=s.map(([l,c])=>({name:l,rate:c.success/c.total,total:c.total})),r=o.sort((l,c)=>c.rate-l.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.1?null:{type:O.PROVIDER_PERFORMANCE,description:`${i.name} succeeds ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(s.reduce((l,[c,u])=>l+u.total,0)/30,1),recommendation:`${i.name} performs best in your project. Consider using it as the default provider.`,evidence:{reportIds:e,metric:"providerPerformance",values:Object.fromEntries(o.map(l=>[l.name,`${(l.rate*100).toFixed(0)}% (n=${l.total})`]))}}}function js(n){let t={morning:{total:0,success:0},afternoon:{total:0,success:0},evening:{total:0,success:0},night:{total:0,success:0}},e=[];for(let l of n){let c=new Date(l.timestamp).getHours(),u=c<6?"night":c<12?"morning":c<18?"afternoon":"evening";t[u].total++,l.success&&t[u].success++,e.push(l.id)}let s=Object.entries(t).filter(([l,c])=>c.total>=3);if(s.length<2)return null;let o=s.map(([l,c])=>({name:l,rate:c.success/c.total,total:c.total})),r=o.sort((l,c)=>c.rate-l.rate),i=r[0],a=r[r.length-1];return i.rate-a.rate<.2?null:{type:O.TIME_OF_DAY,description:`${i.name} runs succeed ${(i.rate*100).toFixed(0)}%, ${a.name}: ${(a.rate*100).toFixed(0)}%`,confidence:Math.min(n.length/20,1),recommendation:`Orchestrations during ${i.name} hours have the highest success rate. This may correlate with API rate limit availability.`,evidence:{reportIds:e,metric:"timeOfDay",values:Object.fromEntries(o.map(l=>[l.name,`${(l.rate*100).toFixed(0)}% (n=${l.total})`]))}}}function As(n){if(n.length===0)return"No significant patterns detected yet. Need more execution history.";let t=["=== Detected Patterns ===",""];for(let e of n){let s=e.confidence>=.7?"HIGH":e.confidence>=.4?"MEDIUM":"LOW";t.push(`[${s}] ${e.description}`),t.push(` Recommendation: ${e.recommendation}`),t.push("")}return t.join(`
166
+ `)}function Ds(n){if(n.length===0)return"";let t=n.filter(e=>e.confidence>=.4).map(e=>`- ${e.recommendation}`).join(`
156
167
  `);return t?["## Project-Specific Guidance (from execution history)","","Based on this project's past orchestration runs:",t,"","Apply these recommendations when generating the plan."].join(`
157
- `):""}function Ve(n){return X.join(n,".orchex","learn","patterns.json")}async function js(n,t){let e=Ve(n),s=X.dirname(e);await A.mkdir(s,{recursive:!0}),await A.writeFile(e,JSON.stringify(t,null,2),"utf-8")}async function As(n){let t=Ve(n);try{let e=await A.readFile(t,"utf-8");return JSON.parse(e)}catch{return[]}}function de(n){let t=[],e=/(?:import|export)\s+.*?from\s+['"](.+?)['"]/g,s;for(;(s=e.exec(n))!==null;)t.push(s[1]);let o=/require\s*\(\s*['"](.+?)['"]\s*\)/g;for(;(s=o.exec(n))!==null;)t.push(s[1]);return t}function fe(n,t){if(!t.startsWith("."))return null;let e=n.substring(0,n.lastIndexOf("/")),s=t.replace(/\.js$/,""),o=[...e.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 D={CODE:3.5,COMMENTS:4.5,WHITESPACE:6,JSON:3.8,MARKDOWN:4.2};function Ds(n,t,e){let s=new Set([...n]),o=new Set,r=[...n],i=[],a=new Map;for(let c of n)a.set(c,[]);for(;r.length>0;){let c=r.shift();if(o.has(c))continue;o.add(c);let u=e[c];if(!u)continue;let d=de(u);for(let f of d){let p=fe(c,f);if(p&&e[p]){if(o.has(p)){let m=a.get(c)||[];i.push(`Circular dependency detected: ${[...m,c,p].join(" \u2192 ")}`)}else if(!s.has(p)){s.add(p),r.push(p);let m=a.get(c)||[];a.set(p,[...m,c])}}}}for(let c of t)s.add(c);let l=Object.keys(e).filter(c=>!s.has(c));return{needed:[...s],pruned:l,warnings:i.length>0?i:void 0}}function Ls(n,t,e){let s=[];return e.length>100&&s.push({content:e,type:"system_prompt",reusable:!0,estimatedTokens:Z(e)}),n.length>500&&s.push({content:n,type:"project_context",reusable:!0,estimatedTokens:Z(n)}),t.length>500&&s.push({content:t,type:"stream_context",reusable:!0,estimatedTokens:Z(t)}),s}function Z(n){if(!n||n.length===0)return 0;let t=n.trim().startsWith("{")||n.trim().startsWith("["),e=/^#+\s|^-\s|^\*\s|^\d+\.\s/m.test(n);if(t)return Math.ceil(n.length/D.JSON);if(e)return Math.ceil(n.length/D.MARKDOWN);let s=n.split(`
158
- `),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 l=Math.ceil(r/D.CODE),c=Math.ceil(i/D.COMMENTS),u=Math.ceil(a/D.WHITESPACE),d=Math.ceil((o-r-i-a)/D.COMMENTS);return l+c+u+d}var Ye={anthropic:2e5,openai:128e3,gemini:1e6,deepseek:128e3,ollama:128e3,default:1e5},Ge={"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,"llama3.3:70b":128e3,"llama3.2:latest":128e3,"mistral:latest":32e3},Ns=.7,Ws=.9,Us=.8;function Ke(n,t){return t&&Ge[t]?Ge[t]:Ye[n]??Ye.default}function Hs(n,t,e){let s=Ke(t,e),o=n?.softLimitTokens??Math.floor(s*Ns),r=n?.hardLimitTokens??Math.floor(s*Ws),i=n?.enforcementLevel??"warn",a=n?.warningThreshold??Us;return{enforcementLevel:i,softLimitTokens:o,hardLimitTokens:r,warningThreshold:a,provider:t,model:e}}function zs(n,t,e){let s=t-e,o=Math.round(s/e*100);if(n==="none")return"";let r=[`Context is ${o}% over the ${n} 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 n==="hard"&&r.push(" - Or increase the hard limit in contextBudget settings"),r.join(`
159
- `)}function Bs(n,t){let e=Ke(t.provider,t.model),{softLimitTokens:s,hardLimitTokens:o,warningThreshold:r,enforcementLevel:i}=t,a="none",l=s;n>=o?(a="hard",l=o):n>=s&&(a="soft",l=s);let c=n/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 (${n.toLocaleString()} tokens) exceeds ${p} (${l.toLocaleString()} tokens)`,u||(d+=". Execution blocked.")}else c>=r&&(d=`Context size at ${Math.round(c*100)}% of soft limit (${n.toLocaleString()} / ${s.toLocaleString()} tokens)`);let f=a!=="none"?zs(a,n,l):void 0;return{allowed:u,violationType:a,estimatedTokens:n,budgetLimit:l,utilizationRatio:c,warning:d,suggestion:f,providerLimit:e}}var pe=class extends Error{checkResult;streamId;constructor(t,e){let s=e?` for stream "${e}"`:"";super(`Context budget exceeded${s}: ${t.warning}`),this.checkResult=t,this.streamId=e,this.name="ContextBudgetExceededError"}};function qs(n,t,e=300,s=10,o=120,r=!1){let i=n.split(/\r?\n/);if(i.length<e||t.length===0)return n;let a=t.map(h=>new RegExp(Vs(h),"i")),l=[];for(let h=0;h<i.length;++h)a.some(y=>y.test(i[h]))&&l.push(h);let c=new Set;for(let h of l)for(let y=Math.max(0,h-s);y<=Math.min(i.length-1,h+s);++y)c.add(y);if(c.size<Math.min(20,s*2)){for(let h=0;h<Math.min(s*2,i.length);++h)c.add(h);for(let h=Math.max(0,i.length-s*2);h<i.length;++h)c.add(h)}let d=Array.from(c).sort((h,y)=>h-y).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(`
160
- `)}function Vs(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{pe as ContextBudgetExceededError,B as DEFAULT_THRESHOLDS,Cs as adaptReport,ie as analyzeError,Tt as appendLocalEvents,ts as applyPartialApproval,ae as applyTemplate,Cn as autoFixSequentialEdits,Jn as autoMergeOwnershipConflicts,tn as buildDependencyGraph,q as categorizeStream,Bs as checkBudget,Xn as classifyTask,os as cleanupOrphanFixStreams,Hs as createBudgetConfig,N as createDetector,bn as createDiagnostics,kn as detectOwnershipConflicts,ks as detectPatterns,je as detectSequentialEdits,gs as estimatePlannedCost,Z as estimateTokens,Nn as evaluateCompletion,Bt as extractDeliverables,de as extractImports,wn as extractPrerequisites,qs as extractRelevantChunks,G as findMatchingTemplate,Gt as formatDeliverablesReport,nn as formatDependencyReport,Rs as formatPatterns,Sn as formatPlanPreview,$n as formatPlanPreviewText,hn as formatStreamsForReview,we as gatherProjectContext,Gn as generateAllSuggestions,Ls as generateCachingHints,ms as generateFixStream,_n as generateLearningSummary,tt as generatePlan,On as generateReport,mn as generateStreams,Fn as getFirstRunSuggestion,J as getFixChainInfo,He as getModelCosts,as as getOriginalStreamId,bt as getRecommendedLimit,U as getSectionsAtLevel,Kn as getSuggestionsSummary,Se as getThresholds,In as isFirstRun,is as isFixStream,ft as isUnpopulatedTemplate,As as loadPatterns,$s as loadRoutingRules,Rn as markFirstRunComplete,rs as onStreamComplete,re as optimizeTopology,lt as parsePlanDocument,Fs as patternsToPromptHints,Yt as processDeliverables,Ds as pruneUnusedFiles,jn as resetLearning,fe as resolveImportPath,ns as rollbackStream,vs as routeStream,Ot as runLearningCycle,js as savePatterns,Pn as saveReportLocally,kt as streamResultToTelemetryEvent,Qn as suggestProvider,Vn as suggestSplit,gn as toInitFormat};
168
+ `):""}function Je(n){return X.join(n,".orchex","learn","patterns.json")}async function Ls(n,t){let e=Je(n),s=X.dirname(e);await A.mkdir(s,{recursive:!0}),await A.writeFile(e,JSON.stringify(t,null,2),"utf-8")}async function Ns(n){let t=Je(n);try{let e=await A.readFile(t,"utf-8");return JSON.parse(e)}catch{return[]}}function fe(n){let t=[],e=/(?:import|export)\s+.*?from\s+['"](.+?)['"]/g,s;for(;(s=e.exec(n))!==null;)t.push(s[1]);let o=/require\s*\(\s*['"](.+?)['"]\s*\)/g;for(;(s=o.exec(n))!==null;)t.push(s[1]);return t}function pe(n,t){if(!t.startsWith("."))return null;let e=n.substring(0,n.lastIndexOf("/")),s=t.replace(/\.js$/,""),o=[...e.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 D={CODE:3.5,COMMENTS:4.5,WHITESPACE:6,JSON:3.8,MARKDOWN:4.2};function Ws(n,t,e){let s=new Set([...n]),o=new Set,r=[...n],i=[],a=new Map;for(let c of n)a.set(c,[]);for(;r.length>0;){let c=r.shift();if(o.has(c))continue;o.add(c);let u=e[c];if(!u)continue;let d=fe(u);for(let f of d){let p=pe(c,f);if(p&&e[p]){if(o.has(p)){let m=a.get(c)||[];i.push(`Circular dependency detected: ${[...m,c,p].join(" \u2192 ")}`)}else if(!s.has(p)){s.add(p),r.push(p);let m=a.get(c)||[];a.set(p,[...m,c])}}}}for(let c of t)s.add(c);let l=Object.keys(e).filter(c=>!s.has(c));return{needed:[...s],pruned:l,warnings:i.length>0?i:void 0}}function Us(n,t,e){let s=[];return e.length>100&&s.push({content:e,type:"system_prompt",reusable:!0,estimatedTokens:Z(e)}),n.length>500&&s.push({content:n,type:"project_context",reusable:!0,estimatedTokens:Z(n)}),t.length>500&&s.push({content:t,type:"stream_context",reusable:!0,estimatedTokens:Z(t)}),s}function Z(n){if(!n||n.length===0)return 0;let t=n.trim().startsWith("{")||n.trim().startsWith("["),e=/^#+\s|^-\s|^\*\s|^\d+\.\s/m.test(n);if(t)return Math.ceil(n.length/D.JSON);if(e)return Math.ceil(n.length/D.MARKDOWN);let s=n.split(`
169
+ `),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 l=Math.ceil(r/D.CODE),c=Math.ceil(i/D.COMMENTS),u=Math.ceil(a/D.WHITESPACE),d=Math.ceil((o-r-i-a)/D.COMMENTS);return l+c+u+d}var Qe={anthropic:2e5,openai:128e3,gemini:1e6,deepseek:128e3,ollama:128e3,default:1e5},Xe={"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,"llama3.3:70b":128e3,"llama3.2:latest":128e3,"mistral:latest":32e3},zs=.7,Hs=.9,Bs=.8;function Ze(n,t){return t&&Xe[t]?Xe[t]:Qe[n]??Qe.default}function qs(n,t,e){let s=Ze(t,e),o=n?.softLimitTokens??Math.floor(s*zs),r=n?.hardLimitTokens??Math.floor(s*Hs),i=n?.enforcementLevel??"warn",a=n?.warningThreshold??Bs;return{enforcementLevel:i,softLimitTokens:o,hardLimitTokens:r,warningThreshold:a,provider:t,model:e}}function Vs(n,t,e){let s=t-e,o=Math.round(s/e*100);if(n==="none")return"";let r=[`Context is ${o}% over the ${n} 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 n==="hard"&&r.push(" - Or increase the hard limit in contextBudget settings"),r.join(`
170
+ `)}function Ys(n,t){let e=Ze(t.provider,t.model),{softLimitTokens:s,hardLimitTokens:o,warningThreshold:r,enforcementLevel:i}=t,a="none",l=s;n>=o?(a="hard",l=o):n>=s&&(a="soft",l=s);let c=n/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 (${n.toLocaleString()} tokens) exceeds ${p} (${l.toLocaleString()} tokens)`,u||(d+=". Execution blocked.")}else c>=r&&(d=`Context size at ${Math.round(c*100)}% of soft limit (${n.toLocaleString()} / ${s.toLocaleString()} tokens)`);let f=a!=="none"?Vs(a,n,l):void 0;return{allowed:u,violationType:a,estimatedTokens:n,budgetLimit:l,utilizationRatio:c,warning:d,suggestion:f,providerLimit:e}}var me=class extends Error{checkResult;streamId;constructor(t,e){let s=e?` for stream "${e}"`:"";super(`Context budget exceeded${s}: ${t.warning}`),this.checkResult=t,this.streamId=e,this.name="ContextBudgetExceededError"}};function Gs(n,t,e=300,s=10,o=120,r=!1){let i=n.split(/\r?\n/);if(i.length<e||t.length===0)return n;let a=t.map(g=>new RegExp(Ks(g),"i")),l=[];for(let g=0;g<i.length;++g)a.some(y=>y.test(i[g]))&&l.push(g);let c=new Set;for(let g of l)for(let y=Math.max(0,g-s);y<=Math.min(i.length-1,g+s);++y)c.add(y);if(c.size<Math.min(20,s*2)){for(let g=0;g<Math.min(s*2,i.length);++g)c.add(g);for(let g=Math.max(0,i.length-s*2);g<i.length;++g)c.add(g)}let d=Array.from(c).sort((g,y)=>g-y).slice(0,o),f=-2,p=[],m=r?String(i.length).length:0;for(let g of d)g>f+1&&p.length>0&&p.push("..."),r?p.push(`${String(g+1).padStart(m)}: ${i[g]}`):p.push(i[g]),f=g;return p.join(`
171
+ `)}function Ks(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{me as ContextBudgetExceededError,B as DEFAULT_THRESHOLDS,Ts as adaptReport,ie as analyzeError,ce as analyzeFailureCorrelation,Mt as appendLocalEvents,gs as applyPartialApproval,le as applyTemplate,On as autoFixSequentialEdits,ds as autoMergeOwnershipConflicts,rn as buildDependencyGraph,q as categorizeStream,Ys as checkBudget,ps as classifyTask,_n as cleanupOrphanFixStreams,qs as createBudgetConfig,N as createDetector,Pn as createDiagnostics,Mn as detectOwnershipConflicts,Os as detectPatterns,Ae as detectSequentialEdits,xs as estimatePlannedCost,Z as estimateTokens,es as evaluateCompletion,Gt as extractDeliverables,fe as extractImports,vn as extractPrerequisites,Gs as extractRelevantChunks,K as findMatchingTemplate,Xt as formatDeliverablesReport,an as formatDependencyReport,As as formatPatterns,kn as formatPlanPreview,En as formatPlanPreviewText,Sn as formatStreamsForReview,ye as gatherProjectContext,ls as generateAllSuggestions,Us as generateCachingHints,Wn as generateFixStream,Yn as generateLearningSummary,rt as generatePlan,Bn as generateReport,Un as generateRootCauseFixStream,xn as generateStreams,Jn as getFirstRunSuggestion,Y as getFixChainInfo,Ve as getModelCosts,An as getOriginalStreamId,Ot as getRecommendedLimit,U as getSectionsAtLevel,us as getSuggestionsSummary,$e as getThresholds,Gn as isFirstRun,jn as isFixStream,gt as isUnpopulatedTemplate,Ns as loadPatterns,ks as loadRoutingRules,Kn as markFirstRunComplete,Fn as onStreamComplete,re as optimizeTopology,pt as parsePlanDocument,Ds as patternsToPromptHints,Qt as processDeliverables,Ws as pruneUnusedFiles,Qn as resetLearning,pe as resolveImportPath,ws as rollbackStream,bs as routeStream,Rt as runLearningCycle,Ls as savePatterns,qn as saveReportLocally,Pt as streamResultToTelemetryEvent,fs as suggestProvider,as as suggestSplit,$n as toInitFormat};
@@ -1 +1 @@
1
- export declare const ORCHEX_INSTRUCTIONS = "Orchex is a multi-LLM orchestration tool that coordinates parallel AI agents to implement features across multiple files with zero merge conflicts.\n\n## Core Concepts\n\n\u2022 **Streams**: File ownership units \u2014 each stream owns 1-3 files exclusively\n\u2022 **Waves**: Parallel execution groups \u2014 streams in same wave run simultaneously \n\u2022 **Ownership**: Strict isolation \u2014 no two streams can modify the same file\n\u2022 **Self-Healing**: Auto-recovery from failures (max 3 attempts per stream)\n\u2022 **Learning**: System improves with every run, adapting to your codebase\n\u2022 **Model Registry**: Dynamic model discovery \u2014 available models auto-updated from providers daily\n\n## How to Start\n\nAlways use `auto`. It handles everything:\n- Short intent: \"Add user auth with JWT\"\n- Full PRD or spec document: paste the content as the intent\n- Bug report: \"Fix the login timeout on mobile\"\n- Refactoring request: \"Extract payment logic into service layer\"\n\nDo NOT use `learn` directly \u2014 it expects a structured implementation plan with code deliverables, not a PRD or spec.\nDo NOT parse user documents into sections yourself \u2014 `auto` does this automatically.\n\n## Available Tools\n\n### Getting Started:\n\u2022 `auto` \u2014 **Start here.** Takes any input (intent, PRD, spec, bug report) \u2192 generates implementation plan \u2192 previews \u2192 executes.\n\u2022 `init-plan` \u2014 Generate plan template for manual editing (advanced \u2014 use `auto` for most cases)\n\u2022 `init` + `add_stream` \u2014 Manual stream-by-stream control (advanced)\n\n### During Execution:\n\u2022 `status` \u2014 Check current state and progress\n\u2022 `execute` \u2014 Run all pending streams\n\u2022 `recover` \u2014 Auto-heal failed streams\n\u2022 `rollback-stream` \u2014 Undo changes from a specific stream\n\u2022 `reload` \u2014 Refresh state from disk\n\n### After Execution:\n\u2022 `complete` \u2014 Mark orchestration as done and cleanup\n\u2022 `reset-learning` \u2014 Clear learned patterns\n\n### Internal (rarely called directly):\n\u2022 `learn` \u2014 Parse a structured implementation plan into stream definitions. Prefer `auto`.\n\n## Error Recovery\n\nIf execute fails, call status to check stream states, then recover to self-heal failed streams automatically.\n\n## Available Resources\n\n\u2022 orchex://quickstart \u2014 Getting started guide and setup\n\u2022 orchex://concepts/streams \u2014 Stream ownership model\n\u2022 orchex://concepts/waves \u2014 Parallel execution system\n\u2022 orchex://concepts/ownership \u2014 File isolation rules\n\u2022 orchex://concepts/self-healing \u2014 Auto-recovery mechanics\n\u2022 orchex://concepts/providers \u2014 LLM provider configuration\n\u2022 orchex://examples \u2014 Real-world orchestration examples\n\u2022 orchex://api-reference \u2014 Stream definition schema\n\n## API Keys\n\nANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY (for Bedrock)\n\n## Supported Providers\n\nClaude (Anthropic), OpenAI, Gemini, DeepSeek, Ollama (local), AWS Bedrock \u2014 models auto-discovered via registry\n\n**Note:** Cloud mode (`mode: \"cloud\"`) currently uses Anthropic as the execution provider. All 6 providers are available in local mode.\n\n## Cloud Trial\n\nGet 10 free cloud runs (no expiry, no credit card required) \u2014 run `npx @wundam/orchex login`\n\n## Tiers\n\n\u2022 **Free**: 5 streams, 2 waves, all 6 providers (BYOK)\n\u2022 **Pro** ($19/mo): 15 streams, 10 waves\n\u2022 **Team** ($49/user/mo): 25 streams, 25 waves";
1
+ export declare const ORCHEX_INSTRUCTIONS = "Orchex is a multi-LLM orchestration tool that coordinates parallel AI agents to implement features across multiple files with zero merge conflicts.\n\n## Core Concepts\n\n\u2022 **Streams**: File ownership units \u2014 each stream owns 1-3 files exclusively\n\u2022 **Waves**: Parallel execution groups \u2014 streams in same wave run simultaneously \n\u2022 **Ownership**: Strict isolation \u2014 no two streams can modify the same file\n\u2022 **Self-Healing**: Auto-recovery from failures (max 3 attempts per stream)\n\u2022 **Learning**: System improves with every run, adapting to your codebase\n\u2022 **Model Registry**: Dynamic model discovery \u2014 available models auto-updated from providers daily\n\n## How to Start\n\nAlways use `auto`. It handles everything:\n- Short intent: \"Add user auth with JWT\"\n- Full PRD or spec document: paste the content as the intent\n- Bug report: \"Fix the login timeout on mobile\"\n- Refactoring request: \"Extract payment logic into service layer\"\n\nDo NOT use `learn` directly \u2014 it expects a structured implementation plan with code deliverables, not a PRD or spec.\nDo NOT parse user documents into sections yourself \u2014 `auto` does this automatically.\n\n## Available Tools\n\n### Getting Started:\n\u2022 `auto` \u2014 **Start here.** Takes any input (intent, PRD, spec, bug report) \u2192 generates implementation plan \u2192 previews \u2192 executes.\n\u2022 `init-plan` \u2014 Generate plan template for manual editing (advanced \u2014 use `auto` for most cases)\n\u2022 `init` + `add_stream` \u2014 Manual stream-by-stream control (advanced)\n\n### During Execution:\n\u2022 `status` \u2014 Check current state and progress. **Call every 15-30 seconds during execution and relay the executionProgress to the user** \u2014 they cannot see progress otherwise.\n\u2022 `execute` \u2014 Run all pending streams\n\u2022 `recover` \u2014 Auto-heal failed streams\n\u2022 `rollback-stream` \u2014 Undo changes from a specific stream\n\u2022 `reload` \u2014 Refresh state from disk\n\n### After Execution:\n\u2022 `complete` \u2014 Mark orchestration as done and cleanup\n\u2022 `reset-learning` \u2014 Clear learned patterns\n\n### Internal (rarely called directly):\n\u2022 `learn` \u2014 Parse a structured implementation plan into stream definitions. Prefer `auto`.\n\n## Error Recovery\n\nIf execute fails, call status to check stream states, then recover to self-heal failed streams automatically.\n\n## Available Resources\n\n\u2022 orchex://quickstart \u2014 Getting started guide and setup\n\u2022 orchex://concepts/streams \u2014 Stream ownership model\n\u2022 orchex://concepts/waves \u2014 Parallel execution system\n\u2022 orchex://concepts/ownership \u2014 File isolation rules\n\u2022 orchex://concepts/self-healing \u2014 Auto-recovery mechanics\n\u2022 orchex://concepts/providers \u2014 LLM provider configuration\n\u2022 orchex://examples \u2014 Real-world orchestration examples\n\u2022 orchex://api-reference \u2014 Stream definition schema\n\n## API Keys\n\nANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY (for Bedrock)\n\n## Supported Providers\n\nClaude (Anthropic), OpenAI, Gemini, DeepSeek, Ollama (local), AWS Bedrock \u2014 models auto-discovered via registry\n\n**Note:** Cloud mode (`mode: \"cloud\"`) currently uses Anthropic as the execution provider. All 6 providers are available in local mode.\n\n## Cloud Trial\n\nGet 10 free cloud runs (no expiry, no credit card required) \u2014 run `npx @wundam/orchex login`\n\n## Tiers\n\n\u2022 **Free**: 5 streams, 2 waves, all 6 providers (BYOK)\n\u2022 **Pro** ($19/mo): 15 streams, 10 waves\n\u2022 **Team** ($49/user/mo): 25 streams, 25 waves";
@@ -30,7 +30,7 @@ Do NOT parse user documents into sections yourself — \`auto\` does this automa
30
30
  • \`init\` + \`add_stream\` — Manual stream-by-stream control (advanced)
31
31
 
32
32
  ### During Execution:
33
- • \`status\` — Check current state and progress
33
+ • \`status\` — Check current state and progress. **Call every 15-30 seconds during execution and relay the executionProgress to the user** — they cannot see progress otherwise.
34
34
  • \`execute\` — Run all pending streams
35
35
  • \`recover\` — Auto-heal failed streams
36
36
  • \`rollback-stream\` — Undo changes from a specific stream
@@ -2,7 +2,7 @@ import { loadManifest, saveManifest, updateStreamStatus, addStream, recoverStuck
2
2
  import { createLogger, clearExecutionLog } from './logger.js';
3
3
  import { createLogger as createPinoLogger } from './logging.js';
4
4
  const log = createPinoLogger('orchestrator');
5
- import { generateFixStream, analyzeError, cleanupOrphanFixStreams, streamResultToTelemetryEvent, appendLocalEvents, runLearningCycle, routeStream, loadRoutingRules, } from './intelligence/index.js';
5
+ import { generateFixStream, generateRootCauseFixStream, analyzeFailureCorrelation, analyzeError, cleanupOrphanFixStreams, streamResultToTelemetryEvent, appendLocalEvents, runLearningCycle, routeStream, loadRoutingRules, } from './intelligence/index.js';
6
6
  import { calculateWaves } from './waves.js';
7
7
  import { buildFullPrompt, buildFullPromptOptimized } from './context-builder.js';
8
8
  import { applyArtifact, writeArtifact, validateArtifactSanity, createStreamBackup, revertStreamBackup, withStreamIsolation, writeBackup, readAllBackups, deleteBackup, recoverFromIsolationCrash } from './artifacts.js';
@@ -540,8 +540,9 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
540
540
  };
541
541
  }
542
542
  catch (error) {
543
- const catchError = error.message;
544
- const catchAnalysis = analyzeError(catchError, 'transport');
543
+ const err = error;
544
+ const catchError = err.name && err.name !== 'Error' ? `${err.name}: ${err.message}` : err.message;
545
+ const catchAnalysis = analyzeError(err.stack ?? catchError, 'transport');
545
546
  await logger.error('stream_failed', {
546
547
  id: stream.id,
547
548
  phase: 'execution',
@@ -568,21 +569,28 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
568
569
  }
569
570
  });
570
571
  // Wrap each promise with stream ID so rejections are identifiable
571
- const taggedPromises = executePromises.map((p, i) => p.catch(err => ({
572
- id: activeStreams[i]?.id ?? `wave-${targetWave.number}-idx-${i}`,
573
- name: activeStreams[i]?.name ?? 'unknown',
574
- status: 'failed',
575
- error: err.message ?? String(err),
576
- errorDetail: { category: 'unknown', retryable: true, selfHealable: false, suggestion: 'Check orchestrator logs' },
577
- tokensUsed: { input: 0, output: 0 },
578
- })));
572
+ const taggedPromises = executePromises.map((p, i) => p.catch(err => {
573
+ const errorMsg = err.message ?? String(err);
574
+ const errorStack = err.stack;
575
+ const fullError = errorStack ? `${errorMsg}\n${errorStack}` : errorMsg;
576
+ const analysis = analyzeError(fullError, 'transport');
577
+ return {
578
+ id: activeStreams[i]?.id ?? `wave-${targetWave.number}-idx-${i}`,
579
+ name: activeStreams[i]?.name ?? 'unknown',
580
+ status: 'failed',
581
+ error: errorMsg,
582
+ errorDetail: { category: analysis.category, retryable: analysis.retryable, selfHealable: analysis.selfHealable, suggestion: analysis.suggestion },
583
+ tokensUsed: { input: 0, output: 0 },
584
+ };
585
+ }));
579
586
  // Promise.allSettled — one failure doesn't kill the wave
580
587
  const settled = await Promise.allSettled(taggedPromises);
581
588
  // Calculate parallel execution time (wall clock)
582
589
  const waveEndTime = Date.now();
583
590
  const waveCompletedAt = new Date().toISOString();
584
591
  const parallelMs = waveEndTime - waveStartTime;
585
- for (const result of settled) {
592
+ for (let idx = 0; idx < settled.length; idx++) {
593
+ const result = settled[idx];
586
594
  if (result.status === 'fulfilled') {
587
595
  streamResults.push(result.value);
588
596
  }
@@ -590,8 +598,8 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
590
598
  const rejectedError = result.reason?.message ?? 'Unknown error';
591
599
  const rejectedAnalysis = analyzeError(rejectedError, 'transport');
592
600
  streamResults.push({
593
- id: 'unknown',
594
- name: 'unknown',
601
+ id: activeStreams[idx]?.id ?? `wave-${targetWave.number}-idx-${idx}`,
602
+ name: activeStreams[idx]?.name ?? 'unknown',
595
603
  status: 'failed',
596
604
  error: rejectedError,
597
605
  errorDetail: { category: rejectedAnalysis.category, retryable: rejectedAnalysis.retryable, selfHealable: rejectedAnalysis.selfHealable, suggestion: rejectedAnalysis.suggestion },
@@ -669,7 +677,7 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
669
677
  .filter(s => s && s.trim())
670
678
  .join('\n')
671
679
  || 'unknown error';
672
- const errorSummary = `Verify failed: ${failed.command}: ${verifyError.slice(0, 500)}`;
680
+ let errorSummary = `Verify failed: ${failed.command}: ${verifyError.slice(0, 500)}`;
673
681
  const verifyAnalysis = analyzeError(verifyError, 'verify');
674
682
  verifyDetails.push(`${sr.id}: ${errorSummary}`);
675
683
  await updateStreamStatus(projectDir, sr.id, 'failed', errorSummary);
@@ -681,6 +689,7 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
681
689
  isolated: otherBackups.length > 0,
682
690
  });
683
691
  // Rollback file changes for failed verify — prevents leaving orphan files on disk
692
+ let rollbackFailed = false;
684
693
  const streamBackup = successBackups.find(b => b.streamId === sr.id);
685
694
  if (streamBackup) {
686
695
  try {
@@ -688,12 +697,18 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
688
697
  await logger.info('verify_rollback', { stream: sr.id, files: streamBackup.entries.length + streamBackup.createdFiles.length });
689
698
  }
690
699
  catch (rollbackErr) {
691
- await logger.warn('verify_rollback_failed', { stream: sr.id, error: rollbackErr.message });
700
+ rollbackFailed = true;
701
+ const rollbackMsg = rollbackErr.message;
702
+ await logger.warn('verify_rollback_failed', { stream: sr.id, error: rollbackMsg });
703
+ errorSummary += ` [ROLLBACK FAILED: ${rollbackMsg} — files may remain on disk]`;
692
704
  }
693
705
  }
694
706
  sr.status = 'failed';
695
707
  sr.error = errorSummary;
696
- sr.errorDetail = { category: verifyAnalysis.category, retryable: verifyAnalysis.retryable, selfHealable: verifyAnalysis.selfHealable, suggestion: verifyAnalysis.suggestion };
708
+ const suggestion = rollbackFailed
709
+ ? `${verifyAnalysis.suggestion}. WARNING: Rollback failed — manually check files owned by this stream.`
710
+ : verifyAnalysis.suggestion;
711
+ sr.errorDetail = { category: verifyAnalysis.category, retryable: verifyAnalysis.retryable, selfHealable: verifyAnalysis.selfHealable && !rollbackFailed, suggestion };
697
712
  }
698
713
  else {
699
714
  verifyPassed++;
@@ -753,9 +768,75 @@ async function executeWaveInternal(projectDir, executor, options, logger) {
753
768
  // When all streams fail with a selfHealable category (code errors), fix streams are still useful.
754
769
  const cbBlocksHealing = circuitBreaker.tripped && !(circuitBreaker.selfHealable ?? false);
755
770
  if (tier.selfHealing === 'full' && !cbBlocksHealing) {
771
+ // Root-cause correlation: when multiple downstream streams fail with the same error,
772
+ // fix the root-cause stream instead of retrying each downstream independently.
773
+ const failedIds = streamResults.filter(sr => sr.status === 'failed' && sr.id !== 'unknown').map(sr => sr.id);
774
+ const correlation = failedIds.length >= 2 ? analyzeFailureCorrelation(currentManifest, failedIds) : null;
775
+ const correlatedSkipSet = new Set();
776
+ if (correlation) {
777
+ const rootId = correlation.rootCauseStreamId;
778
+ await logger.info('root_cause_correlation_detected', {
779
+ rootCauseStream: rootId,
780
+ affectedStreams: correlation.affectedStreamIds,
781
+ commonPattern: correlation.commonErrorPattern,
782
+ });
783
+ // Mark root-cause stream as failed so it gets a fix stream
784
+ const rootError = `Root cause: ${correlation.affectedStreamIds.length} downstream streams failed with errors referencing '${correlation.commonErrorPattern}'`;
785
+ currentManifest.streams[rootId].status = 'failed';
786
+ currentManifest.streams[rootId].error = rootError;
787
+ // Reset attempts so the original successful run doesn't count against MAX_ATTEMPTS
788
+ currentManifest.streams[rootId].attempts = 0;
789
+ // Revert root-cause stream's files — its output is wrong
790
+ // Try in-memory backups first, fall back to disk (root may have completed in a previous wave)
791
+ let rootBackup = successBackups.find(b => b.streamId === rootId);
792
+ if (!rootBackup) {
793
+ const diskBackups = await readAllBackups(projectDir);
794
+ rootBackup = diskBackups.find(b => b.streamId === rootId);
795
+ }
796
+ if (rootBackup) {
797
+ try {
798
+ await revertStreamBackup(projectDir, rootBackup);
799
+ await logger.info('root_cause_reverted', { stream: rootId, files: rootBackup.entries.length + rootBackup.createdFiles.length });
800
+ }
801
+ catch (revertErr) {
802
+ await logger.warn('root_cause_revert_failed', { stream: rootId, error: revertErr.message });
803
+ }
804
+ }
805
+ // Skip orphaned fix streams for affected downstream streams before resetting them.
806
+ // Without this, previous fix streams (e.g., B-fix-1) remain pending and conflict
807
+ // with the root-cause fix approach.
808
+ for (const affectedId of correlation.affectedStreamIds) {
809
+ for (const [id, stream] of Object.entries(currentManifest.streams)) {
810
+ if (stream.parentStreamId === affectedId && stream.status === 'pending') {
811
+ currentManifest.streams[id].status = 'skipped';
812
+ currentManifest.streams[id].error = `Root cause identified: '${rootId}' — fix stream no longer needed`;
813
+ }
814
+ }
815
+ }
816
+ // Reset correlated downstream streams to pending — they'll re-run after root is fixed
817
+ for (const affectedId of correlation.affectedStreamIds) {
818
+ currentManifest.streams[affectedId].status = 'pending';
819
+ delete currentManifest.streams[affectedId].error;
820
+ correlatedSkipSet.add(affectedId);
821
+ }
822
+ // Save all status mutations BEFORE addStream() — addStream internally reloads
823
+ // the manifest, so it must see the latest state to compute waves correctly.
824
+ await saveManifest(projectDir, currentManifest);
825
+ // Generate fix stream for root cause (after save so addStream sees current state)
826
+ const rootFix = generateRootCauseFixStream(currentManifest, correlation);
827
+ if (rootFix) {
828
+ await addStream(projectDir, rootFix.fixStreamId, rootFix.fixStream);
829
+ fixStreamsGenerated.push(rootFix.fixStreamId);
830
+ }
831
+ }
832
+ // Generate fix streams for remaining (non-correlated) failures
756
833
  for (const sr of streamResults) {
757
834
  if (sr.status !== 'failed' || sr.id === 'unknown')
758
835
  continue;
836
+ if (correlatedSkipSet.has(sr.id))
837
+ continue; // Already handled by root-cause fix
838
+ if (sr.id === correlation?.rootCauseStreamId)
839
+ continue; // Root cause gets its own fix above
759
840
  // Pass the in-memory errorDetail (computed with origin hint) so generateFixStream
760
841
  // can use the correct selfHealable flag rather than re-analyzing without origin.
761
842
  const fixResult = generateFixStream(currentManifest, sr.id, sr.errorDetail);
package/dist/ownership.js CHANGED
@@ -107,8 +107,12 @@ export function checkOwnership(operations, owns, options = {}) {
107
107
  }
108
108
  return { violations, warnings, allowed };
109
109
  }
110
+ function normalizePath(p) {
111
+ // Strip leading "./" — LLM artifacts may include it inconsistently
112
+ return p.startsWith('./') ? p.slice(2) : p;
113
+ }
110
114
  function checkSingleOperation(op, owns, options) {
111
- const filePath = op.path;
115
+ const filePath = normalizePath(op.path);
112
116
  // SECURITY: Block path traversal (non-negotiable, checked first)
113
117
  if (filePath.includes('..')) {
114
118
  return {
@@ -141,26 +145,28 @@ function checkSingleOperation(op, owns, options) {
141
145
  warning: `Common file '${filePath}' created (not in owns list)`,
142
146
  };
143
147
  }
144
- // Not allowed
148
+ // Not allowed — include owns list for debuggability
145
149
  return {
146
- violation: `${op.type} on '${filePath}' is outside owned files`,
150
+ violation: `${op.type} on '${filePath}' is outside owned files [${owns.join(', ')}]`,
147
151
  };
148
152
  }
149
153
  /**
150
154
  * Check if a path is explicitly covered by an ownership pattern.
151
155
  */
152
156
  function isExplicitlyOwned(filePath, owns) {
157
+ const normalizedFile = normalizePath(filePath);
153
158
  return owns.some((pattern) => {
159
+ const normalizedPattern = normalizePath(pattern);
154
160
  // Directory pattern: "src/" matches "src/foo.ts"
155
- if (pattern.endsWith('/')) {
156
- return filePath.startsWith(pattern);
161
+ if (normalizedPattern.endsWith('/')) {
162
+ return normalizedFile.startsWith(normalizedPattern);
157
163
  }
158
164
  // Glob pattern: "src/*.ts" matches "src/foo.ts"
159
- if (pattern.includes('*')) {
160
- return matchGlobPattern(pattern, filePath);
165
+ if (normalizedPattern.includes('*')) {
166
+ return matchGlobPattern(normalizedPattern, normalizedFile);
161
167
  }
162
168
  // Exact match
163
- return filePath === pattern;
169
+ return normalizedFile === normalizedPattern;
164
170
  });
165
171
  }
166
172
  /**
package/dist/tools.js CHANGED
@@ -497,7 +497,7 @@ export function registerTools(server, executor, context) {
497
497
  // --------------------------------------------------------------------------
498
498
  server.registerTool('status', {
499
499
  title: 'Orchestration Status',
500
- description: 'Get the current orchestration status and progress.',
500
+ description: 'Get the current orchestration status and progress. Call every 15-30 seconds during execution to show the user real-time progress.',
501
501
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
502
502
  inputSchema: {
503
503
  project_dir: z.string().optional().describe('Project directory'),
@@ -659,7 +659,40 @@ export function registerTools(server, executor, context) {
659
659
  hint: 'Fix the root cause, then run recover with include_failed: true to resume.',
660
660
  };
661
661
  }
662
- return ok(`Orchestration: "${manifest.feature}"`, responseData);
662
+ // Build execution progress block when streams are actively running
663
+ const inProgressStreams = streams.filter(s => s.status === 'in_progress');
664
+ const isExecuting = inProgressStreams.length > 0;
665
+ if (isExecuting) {
666
+ // Build per-stream status lines for LLM to relay to user
667
+ const streamLines = streams.map(s => {
668
+ const icon = s.status === 'complete' ? '✓'
669
+ : s.status === 'failed' ? '✗'
670
+ : s.status === 'in_progress' ? '⟳'
671
+ : s.status === 'skipped' ? '⊘'
672
+ : '·';
673
+ const detail = s.status === 'failed' && s.error ? ` — ${s.error.slice(0, 80)}` : '';
674
+ return ` ${icon} ${s.name ?? s.id} — ${s.status}${detail}`;
675
+ });
676
+ responseData.executionProgress = {
677
+ executing: true,
678
+ summary: `Wave ${currentWave?.number ?? '?'}/${waves.length} in progress — ${completed}/${total} complete, ${failed} failed, ${inProgressStreams.length} running`,
679
+ streamStatus: streamLines,
680
+ hint: 'Relay the above progress to the user. Call status again in 15-30 seconds for updates.',
681
+ };
682
+ }
683
+ else if (completed + failed === total && total > 0) {
684
+ responseData.executionProgress = {
685
+ executing: false,
686
+ summary: `Execution complete — ${completed}/${total} succeeded, ${failed} failed`,
687
+ hint: failed > 0
688
+ ? 'Some streams failed. Use recover to retry, or complete to finish.'
689
+ : 'All streams succeeded. Use complete to finalize.',
690
+ };
691
+ }
692
+ const statusMessage = isExecuting
693
+ ? `Orchestration "${manifest.feature}" — executing (${completed}/${total} complete, ${inProgressStreams.length} running)`
694
+ : `Orchestration: "${manifest.feature}"`;
695
+ return ok(statusMessage, responseData);
663
696
  });
664
697
  });
665
698
  // --------------------------------------------------------------------------
@@ -1011,7 +1044,8 @@ export function registerTools(server, executor, context) {
1011
1044
  eventsEnabled: true,
1012
1045
  totalWaves: waves.length,
1013
1046
  totalStreams: Object.keys(manifest.streams).length,
1014
- hint: 'Use orchex.status to monitor progress. Tail .orchex/active/execution.log for live updates.',
1047
+ pollIntervalSeconds: 20,
1048
+ hint: 'IMPORTANT: The user cannot see execution progress unless you poll and relay it. Call orchex.status every 15-30 seconds and show the user the executionProgress block until execution completes.',
1015
1049
  });
1016
1050
  }
1017
1051
  // Wave mode: execute one wave in background
@@ -1140,7 +1174,8 @@ export function registerTools(server, executor, context) {
1140
1174
  wave: currentWave.number,
1141
1175
  totalWaves: waves.length,
1142
1176
  streams: currentWave.streams.map((s) => s.id),
1143
- hint: 'Use orchex.status to monitor progress. Tail .orchex/active/execution.log for live updates.',
1177
+ pollIntervalSeconds: 20,
1178
+ hint: 'IMPORTANT: The user cannot see execution progress unless you poll and relay it. Call orchex.status every 15-30 seconds and show the user the executionProgress block until execution completes.',
1144
1179
  });
1145
1180
  });
1146
1181
  });
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.21",
4
+ "version": "1.0.0-rc.23",
5
5
  "description": "Autopilot AI orchestration — auto-plan, parallelize, and execute with ownership enforcement",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -20,11 +20,11 @@
20
20
  "author": "Wundam LLC",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://orchex.dev"
23
+ "url": "https://github.com/wundam/orchex-community"
24
24
  },
25
25
  "homepage": "https://orchex.dev",
26
26
  "bugs": {
27
- "url": "https://orchex.dev/support"
27
+ "url": "https://github.com/wundam/orchex-community/discussions"
28
28
  },
29
29
  "keywords": [
30
30
  "mcp",