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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +59 -18
  2. package/dist/cloud-executor.d.ts +71 -0
  3. package/dist/cloud-executor.js +335 -0
  4. package/dist/cloud-sync.d.ts +8 -0
  5. package/dist/cloud-sync.js +52 -0
  6. package/dist/config.d.ts +30 -4
  7. package/dist/config.js +61 -2
  8. package/dist/context-builder.d.ts +2 -0
  9. package/dist/context-builder.js +11 -3
  10. package/dist/cost.js +1 -1
  11. package/dist/entitlements/jwt.d.ts +7 -0
  12. package/dist/entitlements/jwt.js +78 -0
  13. package/dist/entitlements/resolve.d.ts +17 -0
  14. package/dist/entitlements/resolve.js +49 -0
  15. package/dist/entitlements/types.d.ts +21 -0
  16. package/dist/entitlements/types.js +4 -0
  17. package/dist/executors/base.d.ts +1 -1
  18. package/dist/executors/bedrock-executor.d.ts +39 -0
  19. package/dist/executors/bedrock-executor.js +197 -0
  20. package/dist/executors/index.d.ts +1 -0
  21. package/dist/executors/index.js +24 -1
  22. package/dist/index.js +468 -23
  23. package/dist/intelligence/index.d.ts +44 -0
  24. package/dist/intelligence/index.js +160 -0
  25. package/dist/key-cache.d.ts +31 -0
  26. package/dist/key-cache.js +84 -0
  27. package/dist/login-helpers.d.ts +25 -0
  28. package/dist/login-helpers.js +54 -0
  29. package/dist/manifest.js +18 -1
  30. package/dist/mcp-instructions.d.ts +1 -0
  31. package/dist/mcp-instructions.js +84 -0
  32. package/dist/mcp-resources.d.ts +8 -0
  33. package/dist/mcp-resources.js +420 -0
  34. package/dist/model-cache.d.ts +18 -0
  35. package/dist/model-cache.js +62 -0
  36. package/dist/model-validator.d.ts +20 -0
  37. package/dist/model-validator.js +125 -0
  38. package/dist/orchestrator.d.ts +14 -0
  39. package/dist/orchestrator.js +191 -32
  40. package/dist/setup/ide-registry.d.ts +13 -0
  41. package/dist/setup/ide-registry.js +51 -0
  42. package/dist/setup/index.d.ts +1 -0
  43. package/dist/setup/index.js +111 -0
  44. package/dist/tier-gating.js +0 -16
  45. package/dist/tiers.d.ts +35 -5
  46. package/dist/tiers.js +39 -3
  47. package/dist/tools.d.ts +6 -1
  48. package/dist/tools.js +852 -95
  49. package/dist/types.d.ts +71 -60
  50. package/dist/types.js +3 -0
  51. package/dist/waves.d.ts +1 -1
  52. package/dist/waves.js +29 -2
  53. package/package.json +41 -5
  54. package/src/entitlements/public-key.pem +9 -0
  55. package/dist/intelligence/anti-pattern-detector.d.ts +0 -117
  56. package/dist/intelligence/anti-pattern-detector.js +0 -327
  57. package/dist/intelligence/budget-enforcer.d.ts +0 -119
  58. package/dist/intelligence/budget-enforcer.js +0 -226
  59. package/dist/intelligence/context-optimizer.d.ts +0 -111
  60. package/dist/intelligence/context-optimizer.js +0 -282
  61. package/dist/intelligence/cost-tracker.d.ts +0 -114
  62. package/dist/intelligence/cost-tracker.js +0 -183
  63. package/dist/intelligence/deliverable-extractor.d.ts +0 -134
  64. package/dist/intelligence/deliverable-extractor.js +0 -909
  65. package/dist/intelligence/dependency-inferrer.d.ts +0 -87
  66. package/dist/intelligence/dependency-inferrer.js +0 -403
  67. package/dist/intelligence/diagnostics.d.ts +0 -33
  68. package/dist/intelligence/diagnostics.js +0 -64
  69. package/dist/intelligence/error-analyzer.d.ts +0 -7
  70. package/dist/intelligence/error-analyzer.js +0 -76
  71. package/dist/intelligence/file-chunker.d.ts +0 -15
  72. package/dist/intelligence/file-chunker.js +0 -64
  73. package/dist/intelligence/fix-stream-manager.d.ts +0 -59
  74. package/dist/intelligence/fix-stream-manager.js +0 -212
  75. package/dist/intelligence/heuristics.d.ts +0 -23
  76. package/dist/intelligence/heuristics.js +0 -124
  77. package/dist/intelligence/learning-engine.d.ts +0 -157
  78. package/dist/intelligence/learning-engine.js +0 -433
  79. package/dist/intelligence/learning-feedback.d.ts +0 -96
  80. package/dist/intelligence/learning-feedback.js +0 -202
  81. package/dist/intelligence/pattern-analyzer.d.ts +0 -35
  82. package/dist/intelligence/pattern-analyzer.js +0 -189
  83. package/dist/intelligence/plan-parser.d.ts +0 -124
  84. package/dist/intelligence/plan-parser.js +0 -498
  85. package/dist/intelligence/planner.d.ts +0 -29
  86. package/dist/intelligence/planner.js +0 -86
  87. package/dist/intelligence/self-healer.d.ts +0 -16
  88. package/dist/intelligence/self-healer.js +0 -84
  89. package/dist/intelligence/slicing-metrics.d.ts +0 -62
  90. package/dist/intelligence/slicing-metrics.js +0 -202
  91. package/dist/intelligence/slicing-templates.d.ts +0 -81
  92. package/dist/intelligence/slicing-templates.js +0 -420
  93. package/dist/intelligence/split-suggester.d.ts +0 -69
  94. package/dist/intelligence/split-suggester.js +0 -176
  95. package/dist/intelligence/stream-generator.d.ts +0 -90
  96. package/dist/intelligence/stream-generator.js +0 -452
  97. package/dist/telemetry/telemetry-types.d.ts +0 -85
  98. package/dist/telemetry/telemetry-types.js +0 -1
@@ -0,0 +1,160 @@
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.
3
+ Your task: generate a plan document in orchex format from the user's intent.
4
+
5
+ ## Output Format Rules
6
+
7
+ Your output must be a valid markdown document with this structure:
8
+
9
+ 1. Start with an H1 title describing the feature.
10
+ 2. Each H2 (##) section becomes ONE stream \u2014 one focused task for one LLM agent.
11
+ 3. Each H2 must include a YAML code block with stream definition:
12
+
13
+ \`\`\`yaml
14
+ streams:
15
+ stream-id:
16
+ name: "Human readable name"
17
+ owns: [src/path/to/file.ts]
18
+ reads: [src/path/to/existing-file.ts]
19
+ deps: [other-stream-id]
20
+ plan: |
21
+ Detailed implementation instructions.
22
+ Include exact function signatures, imports, and logic.
23
+ verify:
24
+ - npx vitest run tests/path/to/test.test.ts
25
+ \`\`\`
26
+
27
+ ## Key Rules
28
+ - Each stream should own 1-3 files maximum.
29
+ - Use \`reads:\` for any file the stream imports from but does not modify.
30
+ - Use \`deps:\` when one stream must complete before another can start.
31
+ - Use \`verify:\` with scoped commands (not bare \`npm test\` \u2014 scope to specific files).
32
+ - Tests streams should depend on their implementation streams.
33
+ - Types/interfaces should be in their own stream, depended upon by implementation streams.
34
+ - The \`plan:\` field is the LLM's ENTIRE instruction set. Be specific and complete.
35
+ - Do NOT create circular dependencies.
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(`
38
+ ## User Intent
39
+
40
+ ${n}`),s.push(`
41
+ ## Project File Tree
42
+
43
+ \`\`\`
44
+ ${t.fileTree||"(empty project)"}
45
+ \`\`\``),t.packageJson&&Object.keys(t.packageJson).length>0){let i={};for(let a of["name","type","files","dependencies","devDependencies","scripts"])t.packageJson[a]&&(i[a]=t.packageJson[a]);s.push(`
46
+ ## package.json (relevant fields)
47
+
48
+ \`\`\`json
49
+ ${JSON.stringify(i,null,2)}
50
+ \`\`\``)}if(t.tsconfig&&s.push(`
51
+ ## tsconfig.json
52
+
53
+ \`\`\`json
54
+ ${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
+
57
+ [... truncated]`:a;s.push(`
58
+ ## Referenced Document: ${i}
59
+
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
+ `).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
+ `).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
+ ## Project Conventions
64
+
65
+ ${o.join(`
66
+ `)}`),e?.maxStreams&&e.maxStreams>0&&e.maxStreams<25){let i=Math.min(e.maxStreams-2,Math.ceil(e.maxStreams*.8));s.push(`
67
+ ## Stream Budget
68
+
69
+ You have a hard limit of **${e.maxStreams} streams** maximum.
70
+ If your plan would require more, combine related tasks into fewer streams.
71
+ Aim for ~${i} streams for optimal parallelism with safety margin.
72
+ NEVER exceed ${e.maxStreams} streams \u2014 the plan will be rejected if you do.`)}return s.push(`
73
+ ## Instructions
74
+
75
+ Generate the plan document now. Output ONLY the markdown plan document \u2014 no preamble, no explanation.
76
+ 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+=`
78
+
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(`
81
+ `),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
+ `).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(`
84
+ `).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(`
86
+ `),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
+ `).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(`
89
+ `),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
+ `)}),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(`
92
+ `)+`
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(`
96
+ `):`${n}
97
+
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+=`
99
+ `+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 ===
104
+
105
+ `;if(s+=`Total: ${n.length} deliverables
106
+ `,s+=` ${t.length} atomic (ready for streams)
107
+ `,s+=` ${e.length} need splitting
108
+
109
+ `,e.length>0){s+=`--- Needs Splitting ---
110
+
111
+ `;for(let o of e)s+=$e(o)+`
112
+
113
+ `}s+=`--- Atomic Deliverables ---
114
+
115
+ `;for(let o of t)s+=$e(o)+`
116
+
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||""}
119
+ ${a.code}
120
+ \`\`\``;if(i+l.length>e)break;r.push(l),i+=l.length}r.length>0&&(s+=`
121
+
122
+ Reference code:
123
+ `+r.join(`
124
+
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:
131
+ `:o?l=`Stream "${n}" has potential issues:
132
+ `:l=`Stream "${n}" has suggestions:
133
+ `;for(let c of e.issues){let u=c.severity==="error"?"\u274C":c.severity==="warning"?"\u26A0\uFE0F":"\u2139\uFE0F";l+=` ${u} ${c.message}
134
+ `,c.details&&(l+=` ${c.details}
135
+ `)}if(i&&a&&a.length>0){l+=`
136
+ \u{1F4CB} Suggested split using "${i.name}" template:
137
+ `;for(let c of a){let u=c.owns?.join(", ")??"TBD";l+=` \u2022 ${c.name}: ${u}
138
+ `}l+=`
139
+ 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:
141
+ `,o+=` ${t} stream${t!==1?"s":""} with errors
142
+ `,o+=` ${e} stream${e!==1?"s":""} with warnings
143
+ `,o+=` ${s} template match${s!==1?"es":""} found
144
+ `,t>0){o+=`
145
+ \u274C Critical issues (must fix):
146
+ `;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}
148
+
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(`
150
+
151
+ ---
152
+
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(`
156
+ `);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};
@@ -0,0 +1,31 @@
1
+ export interface CachedKeyEntry {
2
+ provider: string;
3
+ apiKey: string;
4
+ }
5
+ export interface CachedKeys {
6
+ keys: CachedKeyEntry[];
7
+ fetchedAt: string;
8
+ entitlementJwt?: string;
9
+ }
10
+ export declare function writeKeyCache(data: CachedKeys): Promise<void>;
11
+ export declare function readKeyCache(): Promise<CachedKeys | null>;
12
+ export declare function clearKeyCache(): Promise<void>;
13
+ /**
14
+ * Resolve API key for a provider from local cache.
15
+ * Returns undefined if not cached or expired.
16
+ */
17
+ export declare function getCachedApiKey(provider: string): Promise<string | undefined>;
18
+ /**
19
+ * Read the raw cache file without TTL check.
20
+ * Used by login flow to merge JWT into existing cache without losing BYOK keys.
21
+ */
22
+ export declare function readKeyCacheRaw(): Promise<CachedKeys | null>;
23
+ /**
24
+ * Read cached entitlement JWT and verify it.
25
+ * Reads the cache file directly — does NOT use readKeyCache() which applies 1hr TTL.
26
+ * The JWT has its own 24hr TTL via the `exp` claim, verified by verifyEntitlement().
27
+ *
28
+ * @param publicKeyPem - PEM-encoded RSA public key for verification
29
+ * @returns Verified claims or null if expired/invalid/missing
30
+ */
31
+ export declare function getCachedEntitlement(publicKeyPem: string): Promise<import('./entitlements/types.js').EntitlementClaims | null>;
@@ -0,0 +1,84 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ /** TTL for cached keys — 1 hour. */
5
+ const CACHE_TTL_MS = 60 * 60 * 1000;
6
+ const CACHE_FILENAME = 'keys.json';
7
+ function cacheDir() {
8
+ return process.env.ORCHEX_CONFIG_DIR ?? path.join(os.homedir(), '.orchex');
9
+ }
10
+ function cachePath() {
11
+ return path.join(cacheDir(), CACHE_FILENAME);
12
+ }
13
+ export async function writeKeyCache(data) {
14
+ const dir = cacheDir();
15
+ await fs.mkdir(dir, { recursive: true });
16
+ await fs.writeFile(cachePath(), JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 });
17
+ }
18
+ export async function readKeyCache() {
19
+ try {
20
+ const raw = await fs.readFile(cachePath(), 'utf-8');
21
+ const data = JSON.parse(raw);
22
+ // TTL check
23
+ const age = Date.now() - new Date(data.fetchedAt).getTime();
24
+ if (age > CACHE_TTL_MS)
25
+ return null;
26
+ return data;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ export async function clearKeyCache() {
33
+ try {
34
+ await fs.unlink(cachePath());
35
+ }
36
+ catch (err) {
37
+ if (err.code !== 'ENOENT')
38
+ throw err;
39
+ }
40
+ }
41
+ /**
42
+ * Resolve API key for a provider from local cache.
43
+ * Returns undefined if not cached or expired.
44
+ */
45
+ export async function getCachedApiKey(provider) {
46
+ const cache = await readKeyCache();
47
+ if (!cache)
48
+ return undefined;
49
+ return cache.keys.find(k => k.provider === provider)?.apiKey;
50
+ }
51
+ /**
52
+ * Read the raw cache file without TTL check.
53
+ * Used by login flow to merge JWT into existing cache without losing BYOK keys.
54
+ */
55
+ export async function readKeyCacheRaw() {
56
+ try {
57
+ const raw = await fs.readFile(cachePath(), 'utf-8');
58
+ return JSON.parse(raw);
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ /**
65
+ * Read cached entitlement JWT and verify it.
66
+ * Reads the cache file directly — does NOT use readKeyCache() which applies 1hr TTL.
67
+ * The JWT has its own 24hr TTL via the `exp` claim, verified by verifyEntitlement().
68
+ *
69
+ * @param publicKeyPem - PEM-encoded RSA public key for verification
70
+ * @returns Verified claims or null if expired/invalid/missing
71
+ */
72
+ export async function getCachedEntitlement(publicKeyPem) {
73
+ try {
74
+ const raw = await fs.readFile(cachePath(), 'utf-8');
75
+ const data = JSON.parse(raw);
76
+ if (!data.entitlementJwt)
77
+ return null;
78
+ const { verifyEntitlement } = await import('./entitlements/jwt.js');
79
+ return verifyEntitlement(data.entitlementJwt, publicKeyPem);
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pure helper functions for orchex login/logout/status commands.
3
+ * No I/O, no side effects — fully unit-testable.
4
+ */
5
+ export interface DeviceAuthStartResponse {
6
+ device_code: string;
7
+ user_code: string;
8
+ verification_uri: string;
9
+ expires_in: number;
10
+ interval: number;
11
+ }
12
+ export interface ParsedApiResponse<T> {
13
+ ok: boolean;
14
+ data?: T;
15
+ error?: string;
16
+ }
17
+ export interface UserInfo {
18
+ email: string;
19
+ tier: string;
20
+ trialRunsRemaining: number;
21
+ subscriptionStatus: string | null;
22
+ }
23
+ export declare function buildVerificationMessage(data: Pick<DeviceAuthStartResponse, 'user_code' | 'verification_uri'>): string;
24
+ export declare function parseLoginApiResponse(status: number, body: unknown): ParsedApiResponse<DeviceAuthStartResponse>;
25
+ export declare function buildStatusMessage(user: UserInfo | null): string;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Pure helper functions for orchex login/logout/status commands.
3
+ * No I/O, no side effects — fully unit-testable.
4
+ */
5
+ export function buildVerificationMessage(data) {
6
+ return [
7
+ '',
8
+ ` Open this URL in your browser to authorize the orchex CLI:`,
9
+ ``,
10
+ ` ${data.verification_uri}`,
11
+ ``,
12
+ ` Confirm the code in your browser matches:`,
13
+ ``,
14
+ ` ${data.user_code}`,
15
+ ``,
16
+ ` Waiting for authorization... (Ctrl+C to cancel)`,
17
+ '',
18
+ ].join('\n');
19
+ }
20
+ export function parseLoginApiResponse(status, body) {
21
+ if (status !== 200 || !body || typeof body !== 'object') {
22
+ return { ok: false, error: `Server returned ${status}` };
23
+ }
24
+ const b = body;
25
+ if (!b.device_code || !b.user_code || !b.verification_uri) {
26
+ return { ok: false, error: 'Unexpected server response shape' };
27
+ }
28
+ return { ok: true, data: b };
29
+ }
30
+ export function buildStatusMessage(user) {
31
+ if (!user) {
32
+ return [
33
+ '',
34
+ ' Not logged in.',
35
+ ' Run `orchex login` to connect to orchex cloud.',
36
+ '',
37
+ ].join('\n');
38
+ }
39
+ const tierDisplay = user.tier.charAt(0).toUpperCase() + user.tier.slice(1);
40
+ const lines = [
41
+ '',
42
+ ` Email: ${user.email}`,
43
+ ` Tier: ${tierDisplay}`,
44
+ ];
45
+ if (user.tier === 'free' && typeof user.trialRunsRemaining === 'number') {
46
+ lines.push(` trial: ${user.trialRunsRemaining} cloud run${user.trialRunsRemaining !== 1 ? 's' : ''} remaining`);
47
+ }
48
+ if (user.subscriptionStatus && user.subscriptionStatus !== 'active') {
49
+ lines.push(` ⚠ Subscription: ${user.subscriptionStatus} — visit /dashboard/billing`);
50
+ }
51
+ lines.push(` Mode: cloud`);
52
+ lines.push('');
53
+ return lines.join('\n');
54
+ }
package/dist/manifest.js CHANGED
@@ -35,6 +35,23 @@ export async function manifestExists(projectDir) {
35
35
  * @param streams - Stream definitions (uses StreamDefinitionInput to allow partial definitions)
36
36
  */
37
37
  export async function initOrchestration(projectDir, feature, streams) {
38
+ // Hard gate: reject ownership conflicts
39
+ const fileOwners = new Map();
40
+ for (const [id, stream] of Object.entries(streams)) {
41
+ for (const file of stream.owns ?? []) {
42
+ const owners = fileOwners.get(file) ?? [];
43
+ owners.push(id);
44
+ fileOwners.set(file, owners);
45
+ }
46
+ }
47
+ const conflicts = [...fileOwners.entries()]
48
+ .filter(([, owners]) => owners.length > 1)
49
+ .map(([file, owners]) => `${file} owned by: ${owners.join(', ')}`);
50
+ if (conflicts.length > 0) {
51
+ throw new Error(`Ownership conflict detected — cannot initialize orchestration.\n` +
52
+ conflicts.join('\n') + '\n' +
53
+ 'Each file must be owned by exactly one stream. Merge conflicting streams or reassign ownership.');
54
+ }
38
55
  await fs.mkdir(artifactsPath(projectDir), { recursive: true });
39
56
  await fs.mkdir(path.join(projectDir, ORCHEX_DIR, 'archive'), { recursive: true });
40
57
  // Create a temporary manifest to calculate waves
@@ -118,7 +135,7 @@ export async function updateStreamStatus(projectDir, streamId, status, error) {
118
135
  // When a stream completes, clean up any orphan fix streams
119
136
  if (status === 'complete') {
120
137
  try {
121
- const { onStreamComplete } = await import('./intelligence/fix-stream-manager.js');
138
+ const { onStreamComplete } = await import('./intelligence/index.js');
122
139
  const cleanupResult = await onStreamComplete(projectDir, streamId);
123
140
  if (cleanupResult.skipped.length > 0) {
124
141
  log.info({ completedStream: streamId, skippedFixStreams: cleanupResult.skipped }, 'fix_streams_cleaned');