knodin 0.7.6 → 0.8.2

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 (130) hide show
  1. package/README.md +19 -7
  2. package/benchmarks/competitors/SYNTHESIS.md +66 -0
  3. package/dist/bin/cli.js +2164 -108
  4. package/dist/bin/launcher.js +25 -3
  5. package/dist/src/agent-integration.js +304 -0
  6. package/dist/src/artifact-refresh.js +82 -0
  7. package/dist/src/cli-args.js +292 -0
  8. package/dist/src/cli-model.js +384 -0
  9. package/dist/src/codeflow-replay.js +81 -0
  10. package/dist/src/compact-structural.js +96 -0
  11. package/dist/src/compare.js +39 -0
  12. package/dist/src/competitive-cold-mcp.js +40 -0
  13. package/dist/src/competitive-constraints.js +21 -0
  14. package/dist/src/competitive-manifest.js +411 -0
  15. package/dist/src/competitive-measurement.js +183 -0
  16. package/dist/src/competitive-runner.js +487 -0
  17. package/dist/src/competitive-sandbox.js +108 -0
  18. package/dist/src/context-export.js +423 -0
  19. package/dist/src/context.js +102 -0
  20. package/dist/src/deterministic-random.js +34 -0
  21. package/dist/src/diagnostics-write-helper.js +473 -0
  22. package/dist/src/diagnostics.js +1476 -0
  23. package/dist/src/docs-sections.js +141 -0
  24. package/dist/src/doctor.js +382 -0
  25. package/dist/src/engine/ann-hnsw.js +261 -0
  26. package/dist/src/engine/embeddings.js +193 -0
  27. package/dist/src/engine/file-walker.js +49 -0
  28. package/dist/src/engine/git-history.js +289 -0
  29. package/dist/src/engine/index.js +14238 -0
  30. package/dist/src/engine/perf.js +115 -0
  31. package/dist/src/engine/prune.js +112 -0
  32. package/dist/src/engine/sarif-import.js +341 -0
  33. package/dist/src/engine/scip-import.js +423 -0
  34. package/dist/src/engine/source-policy.js +85 -0
  35. package/dist/src/engine/sqlite.js +71 -0
  36. package/dist/src/engine/state-paths.js +175 -0
  37. package/dist/src/engine/symbol-delete.js +58 -0
  38. package/dist/src/execution-profile.js +208 -0
  39. package/dist/src/failure-diagnosis.js +655 -0
  40. package/dist/src/fleet.js +7 -0
  41. package/dist/src/git-executable.js +31 -0
  42. package/dist/src/graph-layout.js +173 -0
  43. package/dist/src/graph-query-health.js +115 -0
  44. package/dist/src/hook-manager-integration.js +156 -0
  45. package/dist/src/index-activity.js +126 -0
  46. package/dist/src/init-progress-worker.js +106 -2
  47. package/dist/src/init-progress.js +155 -0
  48. package/dist/src/init.js +1295 -0
  49. package/dist/src/lifecycle-health.js +282 -0
  50. package/dist/src/lsp-readonly.js +217 -0
  51. package/dist/src/mcp-graph-worker.js +69 -0
  52. package/dist/src/mcp-reliability.js +154 -0
  53. package/dist/src/mcp-worker-supervisor.js +350 -0
  54. package/dist/src/mirror.js +290 -0
  55. package/dist/src/node-runtime.js +157 -0
  56. package/dist/src/output-compression.js +630 -0
  57. package/dist/src/output-telemetry.js +368 -0
  58. package/dist/src/pr-triage.js +638 -0
  59. package/dist/src/progressive-evidence.js +477 -0
  60. package/dist/src/pure-compression-cli.js +102 -0
  61. package/dist/src/relationship-adapters.js +377 -0
  62. package/dist/src/release-attestation.js +533 -0
  63. package/dist/src/release-preflight.js +513 -0
  64. package/dist/src/repair-lease.js +85 -0
  65. package/dist/src/repair-progress-worker.js +120 -2
  66. package/dist/src/repair-progress.js +262 -0
  67. package/dist/src/repository-init-process.js +177 -0
  68. package/dist/src/repository-management.js +1261 -0
  69. package/dist/src/response-budget.js +196 -0
  70. package/dist/src/server.js +217 -0
  71. package/dist/src/structural-fast-path.js +344 -0
  72. package/dist/src/structural-snapshot.js +37 -0
  73. package/dist/src/system-config.js +638 -0
  74. package/dist/src/terminal-help.js +83 -0
  75. package/dist/src/tools/knodin-tools.js +1640 -0
  76. package/dist/src/update-ceremony.js +162 -0
  77. package/dist/src/update-policy.js +944 -0
  78. package/dist/src/update-trust.js +504 -0
  79. package/dist/src/version.js +13 -0
  80. package/dist/src/visualization.js +515 -0
  81. package/dist/src/wait-for-fresh.js +98 -0
  82. package/dist/src/worktree-lifecycle.js +234 -0
  83. package/docs/BEHAVIORAL-CONTRACT.md +72 -0
  84. package/docs/CLI.md +20 -1
  85. package/docs/COMPARISON.md +403 -0
  86. package/docs/COMPETITIVE-LANDSCAPE-2026-08.md +267 -0
  87. package/docs/CONTAINED-EXECUTION.md +77 -0
  88. package/docs/DIAGNOSTICS.md +80 -0
  89. package/docs/GIT-HISTORY-REVIEW.md +39 -0
  90. package/docs/HANDOFF.md +180 -0
  91. package/docs/INSTALLATION.md +21 -18
  92. package/docs/MCP.md +59 -8
  93. package/docs/PROGRESSIVE-EVIDENCE.md +37 -0
  94. package/docs/PT-ACCESS-RECOMMENDATION.md +89 -0
  95. package/docs/RELEASE-0.3-EVIDENCE.md +73 -0
  96. package/docs/REPOSITORIES-AND-WORKTREES.md +18 -6
  97. package/docs/SCIP-IMPORT.md +62 -0
  98. package/docs/SIGNED-UPDATES.md +151 -0
  99. package/docs/TELEMETRY.md +46 -0
  100. package/docs/TOKEN-OPTIMIZER-SCORECARD.md +79 -0
  101. package/docs/assets/knodin-favicon.svg +4 -0
  102. package/docs/releases/0.3.0.md +46 -0
  103. package/docs/releases/0.4.0.md +68 -0
  104. package/docs/releases/0.4.1.md +28 -0
  105. package/docs/releases/0.4.2.md +27 -0
  106. package/docs/releases/0.4.3.md +23 -0
  107. package/docs/releases/0.5.0.md +29 -0
  108. package/docs/releases/0.5.1.md +17 -0
  109. package/docs/releases/0.6.0.md +18 -0
  110. package/docs/releases/0.7.0.md +24 -0
  111. package/docs/releases/0.7.1.md +21 -0
  112. package/docs/releases/0.7.2.md +21 -0
  113. package/docs/releases/0.7.3.md +23 -0
  114. package/docs/releases/0.7.4.md +17 -0
  115. package/docs/releases/0.7.5.md +20 -0
  116. package/docs/releases/0.8.0.md +74 -0
  117. package/docs/releases/0.8.2.md +34 -0
  118. package/package.json +127 -4
  119. package/roadmap/competitive-roadmap.md +3801 -0
  120. package/schemas/release-attestation-v1.schema.json +210 -0
  121. package/schemas/support-bundle-v2.schema.json +212 -0
  122. package/dist/chunks/chunk-DMQAGX77.js +0 -654
  123. package/dist/chunks/chunk-F4Z3Z766.js +0 -4
  124. package/dist/chunks/chunk-SIJAQVSX.js +0 -3
  125. package/dist/chunks/chunk-X6M4HUUE.js +0 -2
  126. package/dist/chunks/chunk-YPRMY2LP.js +0 -8
  127. package/dist/chunks/pure-compression-cli-4TA2TQD5.js +0 -5
  128. package/dist/chunks/server-7EDF4CBY.js +0 -14
  129. package/dist/chunks/structural-fast-path-KD5KQSPX.js +0 -4
  130. package/docs/releases/0.7.6.md +0 -25
@@ -1,4 +0,0 @@
1
- var R="\r\x1B[2K",b=new Set(["completed","cancelled","failed"]),S=new Set(["--bytes","--tokens","--items"]);function x(e){let s=/^(\d+(?:\.\d+)?)(ms|s|m)$/.exec(e.trim());if(!s)throw new Error("knodin repair: --progress-interval must be a positive duration such as 750ms, 30s, or 2m");let l=Number(s[1]),o=s[2]==="ms"?1:s[2]==="s"?1e3:6e4,r=l*o;if(!Number.isFinite(r)||r<=0)throw new Error("knodin repair: --progress-interval must be a positive duration");return r}function $(e){let s="auto",l=!1,o=3e4,r=!1,d=!1,n=!1,f=new Set,c=a=>{if(f.has(a))throw new Error(`knodin repair: repeated ${a} argument`);f.add(a)},p=(a,t)=>{let u=e[t+1];if(!u||u.startsWith("--"))throw new Error(`knodin repair: ${a} requires a value`);return u};for(let a=0;a<e.length;a++){let t=e[a];if(t==="--plan"){c(t),n=!0;continue}if(t==="--json"||t==="--jsonl"){c(t),t==="--json"?r=!0:d=!0;continue}if(t==="--progress"||t.startsWith("--progress=")){c("--progress");let u=t==="--progress"?p("--progress",a++):t.slice(11);if(!u)throw new Error("knodin repair: --progress requires a value");if(!["auto","tty","plain","none"].includes(u))throw new Error("knodin repair: --progress must be auto, tty, plain, or none");s=u,l=!0;continue}if(t==="--progress-interval"||t.startsWith("--progress-interval=")){c("--progress-interval");let u=t==="--progress-interval"?p("--progress-interval",a++):t.slice(20);if(!u)throw new Error("knodin repair: --progress-interval requires a value");o=x(u);continue}if(S.has(t)){c(t),p(t,a++);continue}throw t.startsWith("--")?new Error(`knodin repair: unknown argument ${t}`):new Error(`knodin repair: unexpected positional argument ${t}`)}if(r&&d)throw new Error("knodin repair: --json and --jsonl are mutually exclusive");return{progress:s,progressExplicit:l,progressIntervalMs:o,output:d?"jsonl":r?"json":"human",plan:n}}function P(e){let s=e.missing.records.filter(n=>/^(indexed file no longer exists|indexed file is no longer eligible): /.test(n)),l=e.missing.records.filter(n=>n.startsWith("indexed snapshot differs from disk: ")),o=e.missing.records.filter(n=>n.includes("post-processing is incomplete")),r=new Set([...e.missing.files,...s.map(n=>n.slice(n.indexOf(": ")+2)),...l.map(n=>n.slice(n.indexOf(": ")+2))]),d=Object.values(e.orphaned).filter(n=>n>0).length;return{schemaVersion:1,mutating:!1,healthFindings:{missingFiles:e.missing.files.length,damagedSnapshots:l.length,staleOrIneligibleRecords:s.length,orphanedEmbeddings:e.orphaned.embeddings,orphanedReferences:e.orphaned.references,orphanedDependencies:e.orphaned.dependencies,incompletePostProcessing:o.length,total:e.missing.files.length+e.missing.records.length+Object.values(e.orphaned).reduce((n,f)=>n+f,0)},operations:{fileReconciliations:r.size,removals:s.length,identityPasses:r.size>0?1:0,embeddingCandidates:r.size,orphanCleanupGroups:d,verification:1,total:r.size+s.length+(r.size>0?1:0)+r.size+d+1},explanation:"Health findings count observed problems; operations count bounded repair actions, so the totals need not match one-to-one.",health:e}}function j(e,s,l){if(e.output==="jsonl")return"jsonl";if(e.output==="json"&&!e.progressExplicit)return"none";if(e.progress!=="auto")return e.progress;let o=s.CI,r=o!==void 0&&o!==""&&o!=="0"&&o.toLowerCase()!=="false";return l&&!r&&s.TERM?.toLowerCase()!=="dumb"?"tty":"plain"}function g(e){let s=e.phaseTotal===void 0?`${e.phaseCompleted}`:`${e.phaseCompleted}/${e.phaseTotal}`,l=[e.currentFamily,e.currentPath].filter(Boolean).join(" "),o=l?` \u2014 ${l}`:"";return`[repair:${e.phase}] ${s} ${e.message}${o}`}function k(e){let s=e.now??Date.now,l=e.setTimeout??((i,m)=>setTimeout(i,m)),o=e.clearTimeout??(i=>clearTimeout(i)),r,d=!1,n=!1,f=!1,c=Number.NEGATIVE_INFINITY,p,a,t=-1,u=()=>{if(e.mode!=="plain"&&e.mode!=="tty")return;r!==void 0&&o(r);let i=e.mode==="tty"?Math.max(e.intervalMs,100):e.intervalMs;r=l(()=>{r=void 0,!n&&(p&&(e.mode==="plain"?h(`${g(p)} (heartbeat)`):w(`${g(p)} (heartbeat)`)),u())},i),typeof r=="object"&&r!==null&&"unref"in r&&r.unref()},h=i=>{e.stderr.write(`${i}
2
- `),c=s(),u()},w=i=>{e.stderr.write(`${R}${i}`),f=!0,c=s(),u()};return{start(){d||n||(d=!0,e.mode==="tty"?w("Starting repair\u2026"):e.mode==="plain"&&h("[repair] Starting repair"))},onProgress(i){if(n||(d||this.start(),p=i,e.mode==="none"))return;if(e.mode==="jsonl"){e.stdout.write(_("progress",i));return}if(e.mode==="tty"){if(s()-c<100&&!b.has(i.phase))return;w(g(i));return}let m=i.phase!==a,E=i.phaseTotal&&i.phaseTotal>0?Math.floor(i.phaseCompleted/i.phaseTotal*100):void 0,T=E===void 0?-1:Math.floor(E/5);(m||T>t)&&(h(g(i)),m?t=T:t=Math.max(t,T),a=i.phase)},stop(){n||(n=!0,r!==void 0&&o(r),e.mode==="tty"&&f&&e.stderr.write(`
3
- `))}}}function _(e,s){return`${JSON.stringify(e==="progress"?{type:e,event:s}:{type:e,result:s})}
4
- `}export{$ as a,P as b,j as c,g as d,k as e,_ as f};
@@ -1,3 +0,0 @@
1
- var E=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],C="\r\x1B[2K";function H(e,r){return Number.isFinite(e)&&(e??0)>0?Math.floor(e):r}function L(e){return e.toLocaleString()}function N(e){return e<1024*1024?`${Math.round(e/1024)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function y(e){return e<1?"<1s":e<60?`${Math.ceil(e)}s`:`${Math.floor(e/60)}m ${Math.ceil(e%60)}s`}function B(e,r,n="init"){let f=e.modelFile?` (${e.modelFile})`:"",s=e.phaseTotal;if(s===void 0)return`[${n}:${e.phase}] ${e.message}${f}`;let l=e.phase==="embedding-model"?`${N(e.phaseCompleted)} / ${N(s)}`:`${L(e.phaseCompleted)} / ${L(s)}`,u=s>0?` (${Math.floor(e.phaseCompleted/s*100)}%)`:"",a=r&&s>e.phaseCompleted?` \u2022 ~${y((s-e.phaseCompleted)/r)} remaining`:"",p=r&&e.phase!=="embedding-model"?` \u2022 ${r.toFixed(r>=10?0:1)}/s`:"";return`[${n}:${e.phase}] ${l}${u} ${e.message}${f}${p}${a}`}function Y(e){let r=e.operation??"init",n=e.now??Date.now,f=e.setTimeout??((t,d)=>setTimeout(t,d)),s=e.clearTimeout??(t=>clearTimeout(t)),l=e.stderr.isTTY===!0,u=!1,a=!1,p=!1,h=0,o,i,c=0,m=`[${r}:starting] Opening local graph database`,_=Number.NEGATIVE_INFINITY,b="starting",$=-1,w=0,T=0,A=()=>{o!==void 0||a||(o=f(()=>{o=void 0,!a&&(M(`${m} (still working; ${Math.floor((n()-h)/1e3)}s elapsed)`,!1),A())},15e3),typeof o=="object"&&o!==null&&"unref"in o&&o.unref())},R=()=>{!l||i!==void 0||a||(i=f(()=>{i=void 0,!a&&(c=(c+1)%E.length,e.stderr.write(`${C}${E[c]} ${m} (${Math.floor((n()-h)/1e3)}s elapsed)`),p=!0,R())},100),typeof i=="object"&&i!==null&&"unref"in i&&i.unref())},M=(t,d=!0)=>{d&&(m=t),l?(e.stderr.write(`${C}${E[c]} ${t} (${Math.floor((n()-h)/1e3)}s elapsed)`),p=!0):e.stderr.write(`${t}
2
- `),_=n(),A()};return{start(){u||a||(u=!0,h=n(),R(),M(m))},onProgress(t){if(a)return;u||this.start();let d=t.phaseTotal&&t.phaseTotal>0?Math.floor(t.phaseCompleted/t.phaseTotal*100):void 0,S=d===void 0?-1:Math.floor(d/5),g=t.phase!==b;g&&(w=t.elapsedMs,T=t.phaseCompleted);let x=Math.max(0,t.elapsedMs-w)/1e3,I=x>0&&t.phaseCompleted>T?(t.phaseCompleted-T)/x:void 0,F=t.phaseTotal!==void 0&&t.phaseCompleted>=t.phaseTotal;l&&!g&&!F&&n()-_<100||!l&&!g&&S<=$&&!F||(M(B(t,I,r)),b=t.phase,$=Math.max($,S))},stop(){a||(a=!0,o!==void 0&&s(o),i!==void 0&&s(i),l&&p&&e.stderr.write(`${C}
3
- `))}}}export{H as a,B as b,Y as c};
@@ -1,2 +0,0 @@
1
- import S from"node:crypto";import e from"node:fs";import o from"node:path";var s=1;function d(t){return`sha256:${S.createHash("sha256").update(t).digest("hex")}`}function i(t){return o.join(o.resolve(t),".knodin","structural-v1.json")}function f(t,r){let n=i(t);e.mkdirSync(o.dirname(n),{recursive:!0});let c={schemaVersion:s,generatedAt:new Date().toISOString(),files:[...r].sort((p,u)=>p.path.localeCompare(u.path))},a=`${n}.${process.pid}.tmp`;e.writeFileSync(a,`${JSON.stringify(c)}
2
- `,{mode:384}),e.renameSync(a,n)}function y(t){try{let r=JSON.parse(e.readFileSync(i(t),"utf8"));return r?.schemaVersion===s&&Array.isArray(r.files)?r:null}catch{return null}}export{d as a,f as b,y as c};
@@ -1,8 +0,0 @@
1
- import j from"node:crypto";import c from"node:fs";import h from"node:path";var U=200,_=16384,G=16*1024*1024,F=64*1024*1024,Y=F*6+1024*1024,J=1e4,R=4*1024*1024,V=/^[a-f0-9]{64}$/,D=27,X=7;function b(t,e,s,n,i){if(e===void 0)return i;if(!Number.isInteger(e)||e<s||e>n)throw new Error(`knodin compress: ${t} must be an integer from ${s} to ${n}`);return e}function K(t){let e=t.text!==void 0,s=t.events!==void 0;if(e===s)throw new Error("knodin compress: provide exactly one of text or events");if(e)return[{stream:"combined",text:t.text??""}];if(!Array.isArray(t.events)||t.events.some(n=>!n||!["combined","stdout","stderr"].includes(n.stream)||typeof n.text!="string"))throw new Error("knodin compress: events must contain valid stream/text records");return t.events.map(({stream:n,text:i})=>({stream:n,text:i}))}function Z(t){return t.reduce((e,s)=>e+Buffer.byteLength(s.text),0)}function N(t){return b("maxInputBytes",t,1,F,G)}function H(t,e){if(!e||h.isAbsolute(e))throw new Error("knodin compress: input file must be a repo-relative path");let s=c.realpathSync(t),n=h.resolve(s,e),i=h.relative(s,n);if(i===".."||i.startsWith(`..${h.sep}`)||h.isAbsolute(i))throw new Error("knodin compress: input file escapes the repository");if(c.lstatSync(n).isSymbolicLink())throw new Error("knodin compress: refusing symlinked input file");let r=c.realpathSync(n),o=h.relative(s,r);if(o===".."||o.startsWith(`..${h.sep}`)||h.isAbsolute(o))throw new Error("knodin compress: input file resolves outside the repository");if(!c.statSync(r).isFile())throw new Error("knodin compress: input path is not a regular file");return r}function Q(t){let e=[],s=0,n=0;for(;n<t.text.length;){let i=t.text[n];if(i!=="\r"&&i!==`
2
- `){n++;continue}let r=i==="\r"&&t.text[n+1]===`
3
- `?2:1,o=n+r;e.push({raw:t.text.slice(s,n),sourceBytes:Buffer.byteLength(t.text.slice(s,o))}),s=o,n=o}return s<t.text.length&&e.push({raw:t.text.slice(s),sourceBytes:Buffer.byteLength(t.text.slice(s))}),e.length===0&&e.push({raw:"",sourceBytes:0}),e}function q(t){let e=0,s=(n,i)=>{t=t.replace(n,(...r)=>(e++,typeof i=="string"?i:i(...r)))};return s(/\b(authorization|password|passwd|secret|token|api[_-]?key)\s*([:=])\s*([^\s,;]+)/gi,(n,i,r)=>`${i}${r}[REDACTED:credential]`),s(/\bAKIA[A-Z0-9]{16}\b/g,"[REDACTED:aws-access-key]"),s(/\bgh[pousr]_\w{20,}\b/g,"[REDACTED:github-token]"),s(/\bBearer\s+[-\w.~+/]{12,}=*\b/gi,"Bearer [REDACTED:bearer-token]"),s(/\beyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]{8,}\b/g,"[REDACTED:jwt]"),{text:t,count:e}}function tt(t,e){for(let s=e+2;s<t.length;s++){let n=t.codePointAt(s)??0;if(n>=64&&n<=126)return s+1}return null}function et(t,e){for(let s=e+2;s<t.length;s++){let n=t.codePointAt(s);if(n===X)return s+1;if(n===D&&t[s+1]==="\\")return s+2}return null}function nt(t,e){let s=t.codePointAt(e+1),n=null;return s===91?n=tt(t,e):s===93&&(n=et(t,e)),n??e+1}function st(t){let e="";for(let s=0;s<t.length;){let n=t.codePointAt(s)??0;if(n===D){s=nt(t,s);continue}let i=n>65535?2:1,r=n<=8||n===11||n===12||n>=14&&n<=31||n===127;e+=r?`<0x${n.toString(16)}>`:t.slice(s,s+i),s+=i}return e}function rt(t,e){let s=st(t);return e?q(s):{text:s,count:0}}function it(t){return/\b(?:0|zero|no)\s+errors?\b/i.test(t)||/\berror\s+(?:budget|handling|rate|page|message|type)\b/i.test(t)}var T=t=>["test files","tests","snapshots","time"].some(e=>t.toLowerCase().startsWith(e))?"summary":null,ot=t=>t.startsWith("=")&&t.endsWith("=")&&/\b(?:failed|passed|errors?)\b/i.test(t)?"summary":null,ct=t=>t.startsWith("--- FAIL:")||t==="FAIL"||t.startsWith("FAIL ")?"error":null,at=t=>t.startsWith("[ERROR]")?"error":t.startsWith("[WARNING]")?"warning":null,lt=t=>(t.startsWith("> Task ")||t.startsWith("BUILD FAILED"))&&t.includes("FAILED")||t.startsWith("FAILURE:")?"error":null,ut=t=>/\berror [A-Z]{1,4}\d+\b/i.test(t)||t.startsWith("Failed! -")?"error":null,dt=t=>t.startsWith("test result:")?"summary":/^error(?:\[E\d+\])?:/i.test(t)?"error":null,ft={generic:()=>null,vitest:T,jest:T,pytest:ot,"go-test":ct,maven:at,gradle:lt,dotnet:ut,cargo:dt};function pt(t,e){return ft[e](t.trimStart())}function ht(t,e){let s=t.trimStart();return/^at\s+\S/i.test(s)||/^File\s+"/i.test(s)&&/",\s+line\s+\d+/i.test(s)||s.startsWith("Caused by:")||s.startsWith("Suppressed:")||/^\.\.\. \d+ more/i.test(s)||e==="error"&&s!==t&&s.length>0}function yt(t){return it(t)?!1:/(?:^|\W)(?:error|exception|fatal|panic|failed|failure|assertion|segmentation fault|caused by|erro|fehler|erreur|エラー)(?:\W|$)/i.test(t)?!0:/(?:^(?:[ \t]*(?:FAIL\b|✗|✕|×))|(?:\b(?:test|tests|suite|suites)\s+failed\b))/i.test(t)}function gt(t){return/(?:^|\W)(?:warn(?:ing)?|deprecated|avertissement|advertencia|警告)(?:\W|$)/i.test(t)}function mt(t){return/\b(?:tests?|suites?|passed|skipped)\s*[:=]/i.test(t)||/\b(?:duration|time|total|summary|failures?|warnings?|errors?)\s*[:=]/i.test(t)||/\b\d+\s+(?:passed|failed|skipped)\b/i.test(t)||/\b(?:0|zero|no)\s+errors?\b/i.test(t)}function bt(t,e,s){let n=pt(t,s);return n||(ht(t,e)?"stack":yt(t)?"error":gt(t)?"warning":mt(t)?"summary":null)}function $(t,e){if(e!=="auto")return e;let s=t.map(({text:r})=>r).join(`
4
- `).slice(0,256e3),n=s.toLowerCase(),i=s.split(/\r\n|\r|\n/).map(r=>r.trimStart());return n.includes("vitest")||i.some(r=>r.startsWith("Test Files "))?"vitest":n.includes("jest")||i.some(r=>r.startsWith("Snapshots:"))?"jest":n.includes("pytest")||i.some(r=>r.startsWith("=")&&r.endsWith("=")&&/\sin\s\d+(?:\.\d+)?s\s/.test(r))?"pytest":i.some(r=>r.startsWith("ok ")||r.startsWith("FAIL ")||r.startsWith("--- PASS:")||r.startsWith("--- FAIL:"))?"go-test":i.some(r=>(r.startsWith("[INFO]")||r.startsWith("[ERROR]")||r.startsWith("[WARNING]"))&&(r.toLowerCase().includes("maven")||r.includes("BUILD")))?"maven":i.some(r=>r.startsWith("> Task ")||r.startsWith("* What went wrong:"))?"gradle":i.some(r=>/\berror [A-Z]{1,4}\d+\b/i.test(r)||r.startsWith("Failed! -"))?"dotnet":i.some(r=>/^error\[E\d+\]:/.test(r)||r.startsWith("test result:"))?"cargo":"generic"}function M(t,e,s){let n=[],i=null;for(let r of t)for(let{raw:o,sourceBytes:f}of Q(r)){let p=rt(o,e),g=bt(p.text,i,s);n.push({line:n.length+1,stream:r.stream,raw:o,sourceBytes:f,display:p.text,kind:g,secretRedactions:p.count}),i=g}return n}function L(t){return t.stream==="combined"?t.display:`[${t.stream} L${t.line}] ${t.display}`}function A(t){return Buffer.byteLength(t.map(L).join(`
5
- `))}function O(t,e,s){let n=[],i=[],r=()=>{i.length!==0&&(n.push({startLine:i[0].line,endLine:i.at(-1)?.line??i[0].line,lineCount:i.length,byteCount:i.reduce((o,f)=>o+f.sourceBytes,0)}),i=[])};for(let o of t)e.has(o.line)===s?i.push(o):r();return r(),n}function wt(t,e){return t===0?0:Math.round((1-e/t)*1e4)/100}function Et(t){let e=c.realpathSync(t),s=h.join(e,".knodin"),n=h.join(s,"output");for(let i of[s,n])if(c.existsSync(i)&&c.lstatSync(i).isSymbolicLink())throw new Error(`knodin compress: refusing symlinked artifact directory ${i}`);return c.mkdirSync(n,{recursive:!0,mode:448}),c.chmodSync(n,448),n}function x(t,e){if(!V.test(e))throw new Error("knodin compress: invalid artifact id");return h.join(Et(t),`${e}.json`)}function I(t,e){return j.createHash("sha256").update(JSON.stringify({events:t,exit:e})).digest("hex")}function St(t,e,s){let n=I(e,s),i=x(t,n);if(!c.existsSync(i)){let r={schemaVersion:1,id:n,createdAt:new Date().toISOString(),exit:s,events:e},o=c.openSync(i,c.constants.O_WRONLY|c.constants.O_CREAT|c.constants.O_EXCL|(c.constants.O_NOFOLLOW??0),384);try{c.writeFileSync(o,`${JSON.stringify(r)}
6
- `),c.fsyncSync(o)}finally{c.closeSync(o)}}if(!c.lstatSync(i).isFile())throw new Error("knodin compress: artifact target is not a regular file");return C(t,n),c.chmodSync(i,384),{id:n,relativePath:h.relative(c.realpathSync(t),i).split(h.sep).join("/"),bytes:c.statSync(i).size}}function C(t,e){let s=x(t,e),n=c.lstatSync(s);if(!n.isFile())throw new Error("knodin compress: artifact target is not a regular file");if(n.size>Y)throw new Error("knodin compress: retained artifact exceeds the bounded storage limit");let i=c.openSync(s,c.constants.O_RDONLY|(c.constants.O_NOFOLLOW??0));try{let r=JSON.parse(c.readFileSync(i,"utf-8"));if(r.schemaVersion!==1||r.id!==e||!r.exit||!(r.exit.code===null||typeof r.exit.code=="number"&&Number.isInteger(r.exit.code))||!(r.exit.signal===null||typeof r.exit.signal=="string")||!Array.isArray(r.events)||r.events.some(o=>!o||!["combined","stdout","stderr"].includes(o.stream)||typeof o.text!="string"))throw new Error("knodin compress: invalid retained artifact");if(I(r.events,r.exit)!==e)throw new Error("knodin compress: retained artifact identity mismatch");return r}finally{c.closeSync(i)}}function w(t,e,s){t.set(e,Math.max(s,t.get(e)??0))}function Lt(t,e,s,n){for(let i of s){w(t,i,1e3);for(let r=1;r<=n;r++)i-r>=1&&w(t,i-r,600-r),i+r<=e.length&&w(t,i+r,600-r)}}function At(t,e,s){for(let n=1;n<=Math.min(s,e);n++)w(t,n,300-n);for(let n=Math.max(1,e-s+1);n<=e;n++)w(t,n,300-(e-n))}function xt(t,e){let s=Math.min(10,Math.ceil(e/2));for(let n=1;n<=s;n++)w(t,n,400-n);for(let n=Math.max(1,e-s+1);n<=e;n++)w(t,n,400-(e-n))}function It(t,e,s,n){let i=new Map;return Lt(i,t,e,n),(s!=="errors-only"||e.size===0)&&At(i,t.length,e.size>0?1:3),s==="head-tail"&&xt(i,t.length),i}function Wt(t,e,s,n,i,r){let o=new Set,f=l=>{let a=[...o,l.line].sort((u,d)=>u-d).map(u=>t[u-1]);return a.length<=n&&A(a)<=i};for(let l of[...e].sort((a,u)=>a-u)){let a=t[l-1];a&&f(a)&&o.add(l)}let g=[...It(t,e,s,r)].filter(([l])=>!o.has(l)).sort(([l,a],[u,d])=>a!==d?d-a:l-u);for(let[l]of g){let a=t[l-1];a&&f(a)&&o.add(l)}return{selected:o,unpreservedSignals:[...e].filter(l=>!o.has(l)).sort((l,a)=>l-a)}}function kt(t,e){let s=K(e),n=b("lineBudget",e.lineBudget,1,J,U),i=b("byteBudget",e.byteBudget,256,R,_),r=b("contextLines",e.contextLines,0,10,1),o=N(e.maxInputBytes),f=Z(s);if(f>o)throw new Error(`knodin compress: input is ${f} bytes; bounded retention limit is ${o}`);let p=e.strategy??"smart";if(!["smart","head-tail","errors-only"].includes(p))throw new Error("knodin compress: invalid strategy");let g=e.adapter??"auto";if(!["auto","generic","vitest","jest","pytest","go-test","maven","gradle","dotnet","cargo"].includes(g))throw new Error("knodin compress: invalid adapter");let l=$(s,g),a={code:e.exitCode??null,signal:e.signal??null},u=e.retain===!1?null:St(t,s,{...a}),d=M(s,e.redactSecrets!==!1,l),E=new Set(d.filter(({kind:y})=>y!==null).map(({line:y})=>y)),m=d.length<=n&&A(d)<=i?{selected:new Set(d.map(({line:y})=>y)),unpreservedSignals:[]}:Wt(d,E,p,n,i,r),W=d.filter(({line:y})=>m.selected.has(y)),k=W.map(L).join(`
7
- `),v=Buffer.byteLength(k),B=m.selected.size===d.length,P=m.unpreservedSignals.length>0,S="compressed";return B?S="complete":P&&(S="insufficient-budget"),{schemaVersion:1,status:S,complete:B,strategy:p,adapter:l,content:k,exit:a,artifact:{id:u?.id??I(s,a),retained:u!==null,path:u?.relativePath??null,bytes:u?.bytes??0},input:{lines:d.length,bytes:f,streams:[...new Set(s.map(({stream:y})=>y))]},output:{lines:W.length,bytes:v,lineBudget:n,byteBudget:i,budgetAppliesTo:"content-utf8",reductionPercent:wt(f,v)},fidelity:{detectedSignals:E.size,preservedSignals:E.size-m.unpreservedSignals.length,unpreservedSignals:m.unpreservedSignals,secretRedactions:d.reduce((y,z)=>y+z.secretRedactions,0),unknownFormat:E.size===0},includedRanges:O(d,m.selected,!0),omittedRanges:O(d,m.selected,!1),continuation:u?{operation:"compress",compressionAction:"read",artifactId:u.id}:null}}function _t(t,e,s={}){let n=H(t,e),i=N(s.maxInputBytes),r=c.statSync(n).size;if(r>i)throw new Error(`knodin compress: input is ${r} bytes; bounded retention limit is ${i}`);return kt(t,{...s,text:c.readFileSync(n,"utf-8"),maxInputBytes:i})}function Ft(t,e,s={}){let n=C(t,e),i=b("byteBudget",s.byteBudget,256,R,_),r=M(n.events,s.raw!==!0,$(n.events,"auto")),o=b("startLine",s.startLine,1,Math.max(1,r.length),1),f=b("endLine",s.endLine,o,Math.max(o,r.length),Math.min(r.length,o+199)),p=[];for(let a of r.slice(o-1,f)){let u=[...p,a];if(A(u)>i)break;p.push(a)}let g=p.map(L).join(`
8
- `),l=p.at(-1)?.line??o-1;return{schemaVersion:1,artifactId:e,content:g,raw:s.raw===!0,range:{startLine:o,endLine:l,totalLines:r.length},bytes:Buffer.byteLength(g),byteBudget:i,complete:o===1&&l===r.length,secretRedactions:r.reduce((a,u)=>a+u.secretRedactions,0)}}function Rt(t,e){let s=x(t,e);try{let n=c.openSync(s,c.constants.O_RDONLY|(c.constants.O_NOFOLLOW??0));return c.closeSync(n),c.unlinkSync(s),{deleted:!0,artifactId:e}}catch(n){if(n.code==="ENOENT")return{deleted:!1,artifactId:e};throw n}}export{kt as a,_t as b,Ft as c,Rt as d};
@@ -1,5 +0,0 @@
1
- import{a as m,b as y}from"./chunk-YPRMY2LP.js";import x from"node:fs";import b from"node:path";function c(t,i){let e=t.indexOf(i);return e>=0?t[e+1]:t.find(n=>n.startsWith(`${i}=`))?.slice(i.length+1)}function d(t,i,e,n,o){let s=c(t,i),r=s===void 0?e:Number(s);if(!Number.isInteger(r)||r<n||r>o)throw new Error(`knodin compress: ${i} must be an integer from ${n} to ${o}`);return r}async function g(t){let i=[],e=0;for await(let n of process.stdin){let o=Buffer.isBuffer(n)?n:Buffer.from(String(n));if(e+=o.byteLength,e>t)throw new Error(`knodin compress: input exceeded bounded retention limit of ${t} bytes`);i.push(o)}return Buffer.concat(i).toString("utf8")}function w(t){let e=`Compressed output; ${t.omittedRanges.reduce((o,s)=>o+s.lineCount,0)} line(s) omitted.`;t.status==="insufficient-budget"?e=`INSUFFICIENT BUDGET: ${t.fidelity.unpreservedSignals.length} detected signal line(s) are available only through retained drill-down.`:t.complete&&(e="Complete output; nothing omitted.");let n=t.artifact.retained?` Retained artifact: ${t.artifact.id} (${t.artifact.path}).`:" Raw retention disabled; omitted regions cannot be retrieved.";return`${t.content?`${t.content}
2
- `:""}---
3
- ${e} ${t.output.lines}/${t.input.lines} lines, ${t.output.bytes}/${t.input.bytes} bytes; exit=${t.exit.code??"unknown"}, signal=${t.exit.signal??"none"}.${n}
4
- `}async function I(t,i=process.cwd()){if(t[0]!=="compress")return!1;let e=new Set(["--strategy","--adapter","--lines","--max-output-bytes","--context","--exit-code","--signal","--max-input-bytes","--repo"]),n=t.slice(1),o=n.filter(($,h)=>!$.startsWith("--")&&!e.has(n[h-1]));if(["read","diagnose","delete"].includes(o[0]??""))return!1;let s=c(t,"--strategy")??"smart";if(!["smart","head-tail","errors-only"].includes(s))return!1;let r=c(t,"--adapter")??"auto";if(!["auto","generic","vitest","jest","pytest","go-test","maven","gradle","dotnet","cargo"].includes(r))return!1;let u=b.resolve(c(t,"--repo")??i),f=d(t,"--max-input-bytes",16*1024*1024,1,64*1024*1024),p={exitCode:c(t,"--exit-code")?d(t,"--exit-code",0,0,255):void 0,signal:c(t,"--signal"),strategy:s,adapter:r,lineBudget:d(t,"--lines",200,1,1e4),byteBudget:d(t,"--max-output-bytes",16384,256,4*1024*1024),contextLines:d(t,"--context",1,0,10),maxInputBytes:f,retain:!t.includes("--no-retain"),redactSecrets:!t.includes("--no-redact")},a=o[0]==="create"?o[1]??"-":o[0]??"-";if(a!=="-"&&!x.existsSync(b.resolve(u,a)))return!1;let l=a==="-"?m(u,{...p,text:await g(f)}):y(u,a,p);return process.stdout.write(t.includes("--json")?`${JSON.stringify(l)}
5
- `:w(l)),!0}export{I as tryPureCompressionFastPath};
@@ -1,14 +0,0 @@
1
- import{$ as st,Aa as ue,Ba as Et,C as Qe,Ca as Pt,H as ce,J as Je,K as Ye,L as Xe,N as de,O as Ze,P as Z,Q as et,R as tt,S as it,W as nt,Z as rt,_ as ot,aa as at,ba as ct,c as Me,ca as dt,da as lt,ea as ut,fa as pt,ga as mt,ha as ft,ia as yt,j as Fe,ja as gt,k as je,ka as wt,l as He,m as ze,n as Ke,oa as bt,r as Ue,ra as le,sa as vt,ta as xt,v as Ge,va as H,w as Ve,wa as kt,x as j,xa as _t,y as We,ya as ee,za as St}from"./chunk-DMQAGX77.js";import{b as ht}from"./chunk-F4Z3Z766.js";import"./chunk-X6M4HUUE.js";import{a as U,b as Oe,c as Ne,d as De}from"./chunk-YPRMY2LP.js";import yn from"node:path";import{fileURLToPath as hn}from"node:url";import{Server as gn}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as wn}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as bn,ListToolsRequestSchema as vn}from"@modelcontextprotocol/sdk/types.js";import Di from"node:fs";import O from"node:path";import{fileURLToPath as Mi}from"node:url";var pe="sym_";function te(e){return e?`~${(e.startsWith(pe)?e.slice(pe.length):e).slice(0,6)}`:"~?"}function fe(e){return e?.startsWith("~")?`${pe}${e.slice(1)}*`:e}function ie(e){return e==="reconciled"?"reconciled":e==="unknown"?"unknown":"fresh"}function Li(e){let t=e.signature?.replace(/\s+/g," ").trim()??"";return t?/^(.*?:)(?:\s|$)/.exec(t)?.[1]??t:""}function Ti(e,t){let i=e.parent?.symbol?`${e.parent.symbol}/`:"",r=`${t?`${e.file??"?"}:`:""}${e.line??"?"}`,o=Li(e),s=o?` ${o}`:"";return`${te(e.identity)} ${e.kind??"?"} ${i}${e.symbol??"?"}@${r}${s}`}function me(e,t,i){let n=t;if(i!==void 0)for(;n.length>0&&Buffer.byteLength([e(n.length),...n].join(`
2
- `),"utf8")>i;)n=n.slice(0,-1);let r=[e(n.length),...n].join(`
3
- `);return i!==void 0&&Buffer.byteLength(r,"utf8")>i?"":r}function qt(e,t){if(e.ambiguity)return Lt(e.ambiguity.candidates,e.staleness);let i=e.count,n=ie(e.staleness);if(e.pattern==="project_overview"){let s=e.results.map(a=>`${a.symbol??a.file??"."} ${a.fileCount??0} ${a.sizeBytes??0}B`);return me(a=>`${n} ${a}/${i}`,s,t)}let r=e.pattern==="batch_outline",o=e.results.map(s=>Ti(s,r));return me(s=>{let a=e.hasMore?"+":"",d=e.target?` ${e.target}`:"";return`${n} ${s}/${i}${a}${d}`},o,t)}function Rt(e,t,i){let n=d=>d.toLocaleLowerCase().replace(/[^a-z0-9]/g,""),r=n(t),o=e.results.filter(d=>n(d.symbol).includes(r)),s=ie(o[0]?.staleness??e.results[0]?.staleness),a=o.map(d=>{let y=d.source?` ${d.source}`:"";return`${te(d.identity)} ${d.kind} @${d.filePath}${y}`});return me(d=>`${s} ${d}/${o.length}${e.hasMore?"+":""} ${t}`,a,i)}function $t(e,t,i){if(e.ambiguity)return Lt(e.ambiguity.candidates,e.staleness);let n=e.source??"",r=Number(/^(\d+): /.exec(n)?.[1]??0),o=n.split(`
4
- `).map(y=>y.replace(/^\d+: /,"")).join(`
5
- `),s=`${ie(e.staleness)} ${te(e.identity)} ${t??"?"}:${r||"?"}`,a=`${s}
6
- ${o}`;if(i===void 0||Buffer.byteLength(a,"utf8")<=i)return a;let d=`${s}
7
- omitted ${Buffer.byteLength(o,"utf8")}B`;return Buffer.byteLength(d,"utf8")<=i?d:""}function Lt(e,t){return[`ambiguous ${ie(t)} ${e.length}`,...e.map(i=>`${te(i.identity)} ${i.kind} ${i.file}:${i.line}`)].join(`
8
- `)}import Ai from"node:child_process";import I from"node:fs";import Bi from"node:os";import B from"node:path";function Ci(){let e=process.env.XDG_CONFIG_HOME?B.resolve(process.env.XDG_CONFIG_HOME):B.join(Bi.homedir(),".config");return B.join(e,"knodin","execution.json")}function Tt(e){try{return JSON.parse(I.readFileSync(e,"utf8"))}catch{return null}}function At(e){return`"${e.replaceAll("\\","\\\\").replaceAll('"','\\"')}"`}function Ii(e,t){return["(version 1)","(allow default)","(deny network*)","(deny process-fork)",`(deny file-read* ${["/Users","/Volumes","/Network","/private/tmp","/private/var/folders"].map(n=>`(subpath ${At(n)})`).join(" ")})`,"(deny file-write*)",`(allow file-read* file-write* (subpath ${At(e)}) (literal "/dev/null"))`].join(" ")}function ye(e,t){return{schemaVersion:1,status:"unavailable",profile:e,exit:{code:null,signal:null},containment:{level:"containment-unavailable",platform:process.platform,adapter:"unavailable",filesystem:"unavailable",network:"unavailable",processes:"unavailable",warning:t},limits:{timeoutMs:0,maxOutputBytes:0,maxProcesses:1},output:null,audit:{commandTextRecorded:!1,profileRecorded:!0}}}function Oi(e,t){if(!t||typeof t!="object")throw new Error(`execution profile ${e} is invalid`);let i=t;if(!B.isAbsolute(i.executable??""))throw new Error(`execution profile ${e}: executable must be absolute`);if(!Array.isArray(i.args)||i.args.some(n=>typeof n!="string"||n.includes("\0")))throw new Error(`execution profile ${e}: args must be a NUL-free string array`);if(i.network!=="deny")throw new Error(`execution profile ${e}: network must be deny`);if(!Number.isInteger(i.timeoutMs)||(i.timeoutMs??0)<1||(i.timeoutMs??0)>3e5)throw new Error(`execution profile ${e}: timeoutMs must be 1..300000`);if(!Number.isInteger(i.maxOutputBytes)||(i.maxOutputBytes??0)<256||(i.maxOutputBytes??0)>16*1024*1024)throw new Error(`execution profile ${e}: maxOutputBytes must be 256..16777216`);if(i.maxProcesses!==1)throw new Error(`execution profile ${e}: maxProcesses must be 1 for hard fork denial`);if(i.containment!==void 0&&i.containment!=="fully-contained")throw new Error(`execution profile ${e}: only fully-contained is supported`);return i}function Ni(e,t){let i=B.join(e,".knodin","execution-audit.jsonl");I.mkdirSync(B.dirname(i),{recursive:!0}),I.appendFileSync(i,`${JSON.stringify(t)}
9
- `,{mode:384})}async function Bt(e){let t=I.realpathSync(e.repo);if(!/^[a-z][a-z0-9_-]{0,63}$/.test(e.profile))throw new Error("execution profile identity must match [a-z][a-z0-9_-]{0,63}");let i=Tt(e.globalConfigPath??Ci()),n=Tt(B.join(t,".knodin","execution.json"));if(i?.execution?.enabled!==!0)return ye(e.profile,"execution is disabled globally");if(n?.execution?.enabled!==!0)return ye(e.profile,"execution is disabled for this repository");let r=n.execution.profiles?.[e.profile];if(!r)throw new Error(`execution profile not found: ${e.profile}`);let o=Oi(e.profile,r);if(process.platform!=="darwin"||!I.existsSync("/usr/bin/sandbox-exec"))return ye(e.profile,"no certified containment adapter is available on this platform");let s=I.realpathSync(o.executable),a=I.mkdtempSync(B.join(t,".knodin","execution-tmp-")),d={PATH:`${B.dirname(s)}:/usr/bin:/bin`,LANG:"C.UTF-8",LC_ALL:"C.UTF-8",TMPDIR:a},y=Ii(t,s),g=Ai.spawn("/usr/bin/sandbox-exec",["-p",y,s,...o.args],{cwd:t,env:d,shell:!1,detached:!0,stdio:["ignore","pipe","pipe"]}),l=Buffer.alloc(0),b=Buffer.alloc(0),w="exit",x=!1,E=p=>{if(!(x||w!=="exit")&&(w=p,g.pid))try{process.kill(-g.pid,"SIGKILL")}catch{}},P=(p,$)=>{let v=Math.max(0,o.maxOutputBytes-l.length-b.length),D=$.subarray(0,v);p==="stdout"?l=Buffer.concat([l,D]):b=Buffer.concat([b,D]),D.length<$.length&&E("output-limit")};g.stdout.on("data",p=>P("stdout",p)),g.stderr.on("data",p=>P("stderr",p));let _=setTimeout(()=>E("timeout"),o.timeoutMs),q=await new Promise((p,$)=>{g.once("error",$),g.once("close",(v,D)=>p({code:v,signal:D}))});x=!0,clearTimeout(_),I.rmSync(a,{recursive:!0,force:!0});let z=[...l.length?[{stream:"stdout",text:l.toString("utf8")}]:[],...b.length?[{stream:"stderr",text:b.toString("utf8")}]:[]],A=U(t,{events:z,exitCode:q.code,signal:q.signal,lineBudget:200,byteBudget:Math.min(o.maxOutputBytes,16384),retain:!0}),N=w,R=N==="timeout"?"timed-out":N==="output-limit"?"output-limit":q.code===0?"completed":"failed",S={schemaVersion:1,status:R,profile:e.profile,exit:q,containment:{level:"fully-contained",platform:process.platform,adapter:"macos-sandbox-exec",filesystem:"repository-write-user-data-read-bounded",network:"deny",processes:"fork-denied",warning:"macOS sandbox-exec is deprecated. Writes are repository-bound; system runtime paths remain readable while user homes, mounted volumes, network paths, and shared temporary roots are read-denied outside the repository."},limits:{timeoutMs:o.timeoutMs,maxOutputBytes:o.maxOutputBytes,maxProcesses:1},output:A,audit:{commandTextRecorded:!1,profileRecorded:!0}};return Ni(t,{timestamp:new Date().toISOString(),profile:e.profile,status:R,exitCode:q.code,signal:q.signal,containment:S.containment.level,outputArtifactId:A.artifact.id}),S}var Ct=null;function It(){return Ct??=Xe(),Ct}var f=new Proxy({},{get(e,t){let i=It()[t];return typeof i=="function"?i.bind(It()):i}});function Fi(){let e=import.meta.url.endsWith(".ts")?"ts":"js",t=Mi(import.meta.url),i=O.dirname(t);for(;!Di.existsSync(O.join(i,"package.json"))&&i!==O.parse(i).root;)i=O.dirname(i);let n=e==="ts"?O.resolve(O.dirname(t),"../../bin/cli.ts"):O.resolve(i,"dist/bin/cli.js");return Me({argv:[process.argv[0]??process.execPath,n],cwd:()=>process.cwd(),execArgv:process.execArgv,execPath:process.execPath})}var G=[],Ot=new Set,Nt;function ji(){return Nt??=rt(JSON.stringify(ge()[0]?.inputSchema??{})),Nt}function V(e){return Ze(e,async t=>j(t,await f.status(t,{audit:"cached"})))}async function Hi(e){let t=O.resolve(e);if(Ot.has(t))return null;let i=await V(e);return i.available?(Ot.add(t),null):i}async function Dt(e){try{return await e()}catch(t){return{error:t.message}}}var Ft=["lsp_diagnostics","lsp_definitions","lsp_declarations","lsp_implementations","callers_of","callees_of","imports_of","importers_of","import_cycles","inheritors_of","structural_implementations_of","tests_for","file_summary","batch_outline","project_overview","shortest_path","impact","dead_code","large_functions","large_files","rename_preview","flows","flow_of","stats","traverse","feature_path","flow_analysis","knowledge_gaps","surprising_connections","suggested_questions","architecture_overview","triggers_of","publishers_of","listeners_of","handlers_of","endpoints_for","consumers_of","children_of","community","federated_repos","mcp_tools","api_contract_mismatches"],zi=new Set(["lsp_diagnostics","lsp_definitions","lsp_declarations","lsp_implementations"]);function ge(){return[{name:"knodin",description:"Primary local code-intelligence gateway. Start with context when unsure; use explain before editing a symbol, review for diffs, map for boundaries, search for fuzzy discovery, query for structured graph questions/outlines, pack for bounded source context, compress for hard-budgeted recoverable diagnostic output, and prs for authenticated GitHub audits. Explain/source results are already Read-equivalent. Prefer grep for exact literals and direct reads for non-code or just-edited files. Every graph answer carries freshness evidence.",inputSchema:{type:"object",properties:{operation:{type:"string",enum:["explain","review","map","search","query","prs","context","wiki","docs","doctor","pack","evidence","compress","execute","status","wait","worktrees","repair","repositories","system","telemetry"],description:"Which knodin capability to run. context: call this FIRST when starting any investigation and unsure which operation to reach for \u2014 one ultra-compact orientation (repo stats + top subsystems/hubs/flows + a risk score if there's a diff + a heuristic next-operation suggestion); the suggestion is only a hint and never blocks calling any operation directly. explain: use when orienting on a symbol/file or before editing it \u2014 returns edit-ready source + call paths + blast radius. review: use before writing a PR description or approving a diff \u2014 risk-scored context (changed symbols, affected flows, test gaps). map: use before a cross-cutting refactor or to understand subsystem boundaries \u2014 communities + hub/bridge nodes + confidence-tagged edges. search: use when you don't know the exact symbol name \u2014 hybrid semantic + keyword lookup over code symbols. query: use for a structured question about a known symbol \u2014 callers_of, tests_for, shortest_path, dead_code, rename_preview, flows, and more (see `pattern`). pack: create deterministic Markdown/JSON/XML source context under hard budgets, or bounded-read/exact-regex-grep a saved artifact. compress: reduce already-produced diagnostic text under exact line/content-byte budgets, preserve exit metadata and detected signals, retain private local drill-down data by default, and never label insufficient-fidelity output complete. execute: run one immutable repository-defined profile only when independently enabled globally and locally; no executable or argv is accepted from the caller, unsupported containment fails closed, and output is compressed then diagnosed. prs: use to triage open GitHub PRs (via your local authenticated `gh`) \u2014 per-PR status, CI, and blast radius sorted ready-small-impact first; pass `prNumber` for one PR's impacted files + community names. wiki: write a static markdown documentation site for the repository's logical subsystems to `.knodin/wiki/`. Generates an index plus one page per mapped community. Reuses the `map` output. Idempotent: unchanged pages are untouched on disk unless `force` is true. docs: call this to retrieve curated, focused markdown usage guidance directly over MCP."},profile:{type:"string",pattern:"^[a-z][a-z0-9_-]{0,63}$",description:"execute only: immutable repository-defined profile identity. The caller cannot supply executable, argv, cwd, environment, or limits."},symbol:{type:"string",description:"explain: the symbol (function/class/file) to explain. query: the target symbol/file (symbol selector for impact by default; comma-separated files only with impactMode=file; file-substring filter for dead_code/large_functions/large_files; entry-point name for flow_of; unused for flows)."},identity:{type:"string",description:"Stable identity selecting one same-named definition."},file:{type:"string",description:"Repo-relative definition file selector."},evidenceLevel:{type:"string",enum:["locate","outline","evidence","expand"],description:"evidence only: deterministic progressive-delivery level."},continuation:{type:"string",description:"evidence only: integrity-checked continuation returned by the prior level/page."},baselineHash:{type:"string",description:"evidence only: SHA-256 of the complete baseline; omission requires an exact current match."},baselineBytes:{type:"number",minimum:0,description:"evidence only: complete baseline UTF-8 byte length; required with baselineHash."},kind:{type:"string",description:"Definition kind selector (function, class, method, etc.)."},toIdentity:{type:"string",description:"shortest_path destination identity selector."},toFile:{type:"string",description:"shortest_path destination file selector."},toKind:{type:"string",description:"shortest_path destination kind selector."},pattern:{type:"string",enum:[...Ft],description:"feature_path \u2014 deterministic downstream DFS over resolved source references. It is bounded by depth and item limits, source-evidenced per hop, cycle-guarded, and never claims runtime execution; dynamic dispatch and unresolved calls are omitted. lsp_diagnostics accepts a repo-relative TypeScript/JavaScript file; lsp_definitions, lsp_declarations, and lsp_implementations accept file:line:column. These use an optional local TypeScript language-service adapter, never start a daemon or write files, and return an explicit unavailable result when no local adapter supports the file type. api_contract_mismatches \u2014 bounded, source-evidenced static mismatch findings for literal Express/Fastify routes and literal fetch/Axios clients. Matching requires method and normalized path, and requires exact origin equality when a client uses an absolute origin; dynamic routes remain explicitly unresolved. mcp_tools \u2014 list indexed TypeScript MCP SDK tool registrations, or pass symbol to look up one exact tool name; returns description/schema/handler/file and exact versus heuristic confidence. import_cycles \u2014 repo-wide canonical directed file-import cycles; no symbol required, type-only imports included, non-import lineage/ORM edges excluded, and limit/truncated bounds output. query: the graph pattern to run (callers_of, callees_of, imports_of, importers_of, inheritors_of, structural_implementations_of, tests_for, file_summary, shortest_path, impact, dead_code, large_functions, large_files, rename_preview, flows, flow_of, stats, traverse, knowledge_gaps, community, federated_repos). structural_implementations_of returns TypeScript structurally typed object implementations separately from nominal extends/implements results. federated_repos \u2014 discover and list all registered/configured repository paths that this engine federates queries across. community \u2014 fetch a single community's full detail (name, size, cohesion, files, and symbols) by name or substring filter; empty `symbol` = all communities. large_files \u2014 whole-file line counts (min 200), sorted descending \u2014 the file-level counterpart to large_functions, for spotting god files rather than god functions; same optional path-substring filter, empty `symbol` = all files. stats \u2014 repo-level index size + health in one call (per-repo symbol/reference/dependency/embedding/file counts, per-kind and per-language breakdowns, orphaned-embedding count, schema version, last-indexed HEAD, and cached community/hub/bridge/flow totals); federated, empty `symbol`. traverse \u2014 typed BFS from `symbol` within `depth` hops (default 3, 1\u20136), selectable upstream/downstream/both and explicit edge kinds; every discovered edge includes direction, kind, provenance, confidence, files, and source line, with optional Tree-sitter-grounded argument expressions honestly marked heuristic. Sets `truncated` when the `limit` cap binds; single-repo. knowledge_gaps \u2014 repo-health weaknesses in one call: thin communities (<3 symbols), single-file communities, isolated (zero-degree) symbols, and untested hub/bridge hotspots; sourced from the cached map(), federated, empty `symbol`, one row carrying a `knowledgeGaps` block. surprising_connections \u2014 resolved edges scored by a composite surprise formula (cross-community, cross-language, peripheral-to-hub, cross-test-boundary, unusual edge kind) to surface unexpected coupling; sorted highest-first, top 15 by default, federated, empty `symbol`, each row carrying a `surprise` block. suggested_questions \u2014 prioritized, human-readable review prompts synthesized from knowledge_gaps + surprising_connections (untested hotspots first, then surprising edges, then thin/single-file communities); federated, empty `symbol`, each row a `question` string citing the real symbol/file, top 10 by default. architecture_overview \u2014 a federated architecture view with scoped community coupling and independently selectable packages, layers, boundaries, hotspots, entry points, and language facets; `path` is segment-safe and applies consistently. `detailLevel` 'minimal' omits per-edge coupling; 'standard' includes it. Spring/event patterns (Java): triggers_of \u2014 the schedule edge between a @Scheduled method and its synthetic scheduler (pass the method to get its scheduler, or the scheduler to list scheduled methods). publishers_of \u2014 methods that publish a given event type (ApplicationEventPublisher.publishEvent). listeners_of \u2014 @EventListener methods that listen for a given event type. handlers_of \u2014 methods that handle a given HTTP endpoint path (Spring @*Mapping + the existing JS/Python endpoints). endpoints_for \u2014 the inverse: endpoint path(s) a given method handles. consumers_of \u2014 classes/methods consuming a given @Value config property. children_of \u2014 symbols contained in a file path (same as file_summary) or, for a class name, its member symbols by line-range containment. All seven require `symbol` (the target); single-repo, not federated."},depth:{type:"number",description:"query traverse/feature_path/impact: maximum hops from `symbol` (default 3, clamped to 1\u20136)."},impactMode:{type:"string",enum:["symbol","file"],description:"query impact only: stable symbol reach (default) or explicitly labeled changed-file blast radius."},direction:{type:"string",enum:["upstream","downstream","both"],description:"query impact/traverse: inbound/upstream, outbound/downstream, or both (default)."},architectureFacets:{type:"array",items:{type:"string",enum:["packages","layers","boundaries","hotspots","entryPoints","languages"]},description:"query architecture_overview: independently select architecture dimensions; omitted selects all."},relationKinds:{type:"array",items:{type:"string"},description:"query impact/traverse/feature_path: only include these exact edge kinds (for example call)."},minConfidence:{type:"number",minimum:0,maximum:1,description:"query impact: minimum edge confidence (extracted calls are 1.0)."},includeTests:{type:"boolean",description:"query impact: include test/spec files (default true)."},includeDataFlow:{type:"boolean",description:"query impact/traverse: attach bounded call-site argument evidence when parsed syntax supports it; never claims runtime proof."},flowVariable:{type:"string",description:"query flow_analysis only: optional simple local variable name to filter compact source-evidenced facts."},to:{type:"string",description:"query shortest_path: destination symbol (start symbol goes in `symbol`). query rename_preview: the new name (old name goes in `symbol`). Read-only by default (returns edit sites + a unified diff); pass `apply: true` to write the rename to disk."},apply:{type:"boolean",description:"query rename_preview only: when true, perform the rename on disk (line-scoped word-boundary edits, atomic writes, reindex of touched files). Omitted/false is a dry-run that returns the preview plus a unified diff of what would change. Refuses (no writes) on ambiguous definitions, out-of-repo paths, or a name collision with an existing symbol."},base:{type:"string",description:"review/context: compatibility base ref (default HEAD~1). For review this maps to scope=all versus the base; compare uses it as the default older ref. context uses it only for risk."},diffScope:{type:"string",enum:["unstaged","staged","all","compare"],description:"review: unstaged=index vs worktree; staged=HEAD vs index; all=base (default HEAD~1) vs worktree; compare=base/from vs HEAD/to."},from:{type:"string",description:"review: older ref of an explicit revision pair; requires `to`."},toRevision:{type:"string",description:"review: newer ref of an explicit revision pair; requires `from`."},reviewFiles:{type:"array",items:{type:"string"},description:"review: explicit repo-relative file list, independent of live git state."},force:{type:"boolean",description:"wiki only: force rewriting all wiki pages even if unchanged."},detailLevel:{type:"string",enum:["standard","minimal","source","compact"],description:"Structural explain/search/file_summary/batch_outline/project_overview: 'compact' returns the terse stable-identity contract. explain/review: 'minimal' caps each list and returns total counts for a token-efficient structured summary; 'standard' returns fuller arrays. compress: compact auditable metadata is the default; 'standard' returns the complete compression/omission envelope. query architecture_overview: 'minimal' aggregates cross-community edges; 'standard' adds the full per-edge list. map: 'minimal' drops member lists and aggregates edges; 'standard' returns the full map."},query:{type:"string",description:"search: natural language query or keyword to find code symbols (e.g., 'session verification' or 'auth')."},limit:{type:"number",description:"search: maximum number of search results to return (default is 5, capped at 100). prs: maximum number of open PRs to list (default 50)."},byteBudget:{type:"number",minimum:256,description:"Maximum serialized UTF-8 response bytes (operation defaults apply)."},tokenBudget:{type:"number",minimum:64,description:"Maximum estimated tokens, using a deterministic four-bytes-per-token estimate."},itemBudget:{type:"number",description:"Maximum items retained in every returned collection."},includeSource:{type:"boolean",description:"explain minimal only: explicitly opt in to verbatim source (false by default)."},languages:{type:"array",items:{type:"string"},description:"search: language filters."},extensions:{type:"array",items:{type:"string"},description:"search: file-extension filters."},kinds:{type:"array",items:{type:"string"},description:"search/large-code: symbol-kind filters."},path:{type:"string",description:"search/large-code path filter; architecture_overview path scope."},testScope:{type:"string",enum:["all","test","production"],description:"search: include all, test-only, or production-only symbols."},offset:{type:"number",minimum:0,description:"search pagination offset."},minLines:{type:"number",minimum:0,description:"large-code minimum line count."},minComplexity:{type:"number",minimum:0,description:"large-functions minimum cyclomatic complexity."},topN:{type:"number",minimum:1,maximum:1e3,description:"map/query drill-down top-N cap."},sort:{type:"string",enum:["relevance","name","size","degree","complexity"],description:"map/query drill-down sort."},prNumber:{type:"number",description:"prs only: when set, return that single PR's detailed impact (impacted file list + community names) instead of the ranked summary table."},prState:{type:"string",enum:["open","merged","closed","all"],description:"prs audit only: GitHub pull-request state to inspect."},branches:{type:"string",description:"prs audit only: bounded glob matched against head branches (`*` any text, `?` one character)."},auditRange:{type:"string",description:"prs audit only: inclusive pull-request number range such as 723..739."},auditBase:{type:"string",description:"prs audit only: base revision for merge-commit range filtering."},auditHead:{type:"string",description:"prs audit only: head revision for merge-commit range filtering."},expectedLogin:{type:"string",description:"prs audit only: require this GitHub login; a mismatch returns unavailable without changing gh account state."},worktreeAction:{type:"string",enum:["status","reconcile","remove"],description:"worktrees only: inspect, reconcile registry, or remove one linked checkout."},worktreePath:{type:"string",description:"worktrees remove only: exact linked-worktree path."},telemetryAction:{type:"string",enum:["records","status","report","export","clear"],description:"telemetry action."},telemetryRetentionDays:{type:"integer",description:"telemetry retention days; default 30."},task:{type:"string",description:"context only (required): free-text description of what you're doing (e.g. 'review PR #42', 'debug login timeout', 'how does auth work'). Drives a keyword heuristic that suggests which operation to run next \u2014 a hint only, never a constraint."},changedFiles:{type:"array",items:{type:"string"},description:"context only (optional): repo-relative paths the caller already knows changed. The engine's risk-score path always re-derives the diff from `git diff base`, so this is only a hint \u2014 an explicit empty array means 'no changes, skip the risk score'; omit it to auto-detect from git."},repoPath:{type:"string",description:"Absolute path to the repo. Defaults to the current working directory."},section:{type:"string",enum:["quickstart","query-patterns","federation","rename-safety","language-support","troubleshooting","installation","mcp","repositories","systems","provenance","dead-code","doctor"],description:"docs only (required): which documentation section to retrieve."},systemAction:{type:"string",enum:["list","show","validate","query"],description:"system only: list configured systems, show or validate one system, or query its declared relationships."},repositoryAction:{type:"string",enum:["discover","init","status","doctor","search"],description:"repositories only: discover, initialize, inspect, diagnose, or independently search local checkouts."},roots:{type:"array",items:{type:"string"},description:"repositories only: local discovery roots; defaults to repoPath/current directory."},linkedWorktrees:{type:"string",enum:["skip","include"],description:"repositories only: explicit linked-worktree discovery policy."},cursor:{type:"string",description:"repositories search only: opaque continuation cursor."},allowPartial:{type:"boolean",description:"system/repository query: return partial results and name omissions."},dryRun:{type:"boolean",description:"repositories init only: report planned changes without writing repositories."},manifestPath:{type:"string",description:"repositories init: resumability manifest path for matching retries."},packAction:{type:"string",enum:["export","read","grep"],description:"pack only: export context (default), read a bounded artifact range, or exact-regex grep an artifact."},compressionAction:{type:"string",enum:["create","read","diagnose","delete"],description:"compress: create, read, graph-diagnose, or delete a retained output artifact."},text:{type:"string",description:"compress create: already-produced combined diagnostic text. Prefer artifactPath when the data is already on disk so it does not cross the tool boundary first."},exitCode:{type:["number","null"],description:"compress create: original process exit code, preserved as metadata."},lineBudget:{type:"number",minimum:1,maximum:1e4,description:"compress create: hard maximum rendered content lines."},compressionByteBudget:{type:"number",minimum:256,maximum:4194304,description:"compress create/read: hard UTF-8 content budget, separate from byteBudget for the whole gateway envelope."},artifactId:{type:"string",description:"compress read/diagnose/delete: retained SHA-256 artifact identity."},format:{type:"string",enum:["markdown","json","xml"],description:"pack export: deterministic artifact format."},include:{type:"array",items:{type:"string"},description:"pack export: composable repo-relative glob includes."},exclude:{type:"array",items:{type:"string"},description:"pack export: composable repo-relative glob excludes."},filePolicies:{type:"object",additionalProperties:{type:"string",enum:["full","summary","structure-only"]},description:"pack export: glob-to-policy map."},alreadyPresent:{type:"array",items:{type:"string"},description:"pack export: files already in caller context; omitted from source."},chatFiles:{type:"array",items:{type:"string"},description:"pack export: chat-mentioned file paths to omit."},lineNumbers:{type:"boolean",description:"pack export: prefix source with line numbers."},includeTree:{type:"boolean",description:"pack export: include deterministic relative-path tree."},outputPath:{type:"string",description:"pack export: optional repo-contained artifact path."},artifactPath:{type:"string",description:"pack read/grep: repo-contained artifact path. compress create: repo-contained regular input file; symlinks are refused."},startLine:{type:"number",minimum:1,description:"pack read: first line (1-based)."},endLine:{type:"number",minimum:1,description:"pack read: last line (max 1000 lines)."},regex:{type:"string",description:"pack grep: exact JavaScript regular expression."},regexFlags:{type:"string",description:"pack grep: optional gimsuy flags."},gitDiffScope:{type:"string",enum:["unstaged","staged","all","compare"],description:"pack export: optional C5-compatible diff scope."},gitLog:{type:"number",minimum:0,maximum:100,description:"pack export: optional number of local one-line commits."},statusAudit:{type:"string",enum:["cached","deep"],description:"status only: cached (default) reuses a warm deep audit only after a bounded freshness probe; deep forces a complete filesystem/schema/orphan audit."},timeoutMs:{type:"number",minimum:0,maximum:3e5,description:"wait: maximum milliseconds to wait for freshness."},client:{type:"string",enum:["claude","codex","gemini","antigravity"],description:"doctor: optionally return one client-specific integration diagnosis."},repairPlan:{type:"boolean",description:"repair: return a non-mutating auditable plan instead of applying it."},persistTelemetry:{type:"boolean",description:"Opt in to local metadata-only JSONL persistence at .knodin-telemetry.jsonl; never records source."}},required:["operation"]}}]}var Ki="Local code intelligence.",Ui={operation:"Capability.",symbol:"Target.",pattern:"Query pattern.",impactMode:"Symbol or file impact.",apply:"Apply verified edits.",diffScope:"Review diff scope.",section:"Documentation section.",persistTelemetry:"Persist metadata telemetry."};function Gi(e,t){return Ui[e]}function jt(){let e=ge();for(let t of e){t.description=Ki;let i=t.inputSchema.properties;for(let[n,r]of Object.entries(i))r.description=Gi(n,r.description)}return e}function Vi(){let[e]=ge(),t=e.inputSchema.properties,i=["# knodin operation and parameter reference","",e.description??"",""];for(let[n,r]of Object.entries(t))i.push(`## ${n}`,"",r.description??"No additional guidance.","");return i.join(`
10
- `)}var Mt={explain:{bytes:65536,tokens:16384,items:200},"explain:minimal":{bytes:16384,tokens:4096,items:25},map:{bytes:131072,tokens:32768,items:200},"map:minimal":{bytes:32768,tokens:8192,items:15},default:{bytes:65536,tokens:16384,items:100}};async function Wi(e,t,i){t.length=0;for(let n of e)try{let r=j(n.path,await f.status(n.path,{audit:"deep"})),o=await le(n,{status:async()=>r,systemMemberships:s=>ee(H(i),s)});t.push({...o,diagnosis:await ce(n.path,{currentVersion:r.version,runtimeCommand:[process.execPath,process.argv[1]??"","serve"],graph:r})})}catch(r){t.push({schemaVersion:1,path:n.path,classification:n.classification,health:"unknown",errors:[r instanceof Error?r.message:String(r)],remediation:["knodin doctor"]})}}async function Qi(e){let{repositoryAction:t,roots:i,repo:n,depth:r,linkedWorktrees:o,query:s,include:a,exclude:d,allowPartial:y,dryRun:g,manifestPath:l,itemBudget:b,byteBudget:w,tokenBudget:x,cursor:E,bounded:P}=e,_=i?.length?i:[n],q={depth:r,linkedWorktrees:o??"skip"},z=async()=>{let R=await bt(_,q),S=H(_[0]??n),p=[];for(let $ of R.repositories)p.push(await le($,{status:async v=>j(v,await f.status(v,{audit:"cached"})),systemMemberships:v=>ee(S,v)}));return{discovery:R,repositories:p}};if(t==="init"){let R=Fi(),S=H(_[0]??n),p=await xt(_,{command:R,index:v=>f.index(v),status:v=>f.status(v),depth:r,worktrees:o,dryRun:g,manifestPath:l,indexMode:v=>St(S,v),isolatedInitialize:v=>gt({repository:v,command:R})}),{repositories:$}=await z();return P({schemaVersion:1,...p,repositories:$},"repositories:init")}if(t==="search"){if(!s?.trim())throw new Error("knodin repositories search requires a non-empty `query`");let R=H(_[0]??n);return vt(_,s,{...q,include:a,exclude:d,allowPartial:y,itemBudget:b,byteBudget:w,tokenBudget:x,cursor:E,status:async S=>j(S,await f.status(S,{audit:"cached"})),search:(S,p,$,v)=>f.search(S,p,$,{offset:v,includeSource:!0,federate:!1}),systemMemberships:S=>ee(R,S)})}let{discovery:A,repositories:N}=await z();return t==="doctor"&&await Wi(A.repositories,N,_[0]??n),P({schemaVersion:1,linkedWorktrees:q.linkedWorktrees,repositories:N,issues:A.issues,emptyRoots:A.emptyRoots,staleLinkedWorktrees:A.staleLinkedWorktrees},`repositories:${t}`)}async function Ji(e){let{systemAction:t,symbol:i,repo:n,allowPartial:r,bounded:o}=e,s=await ue(H(n));if(t==="list")return o({schemaVersion:s.schemaVersion,systems:s.systems.map(({id:y,components:g})=>({id:y,componentCount:g.length}))},"system:list");if(!i)throw new Error(`knodin system ${t} requires \`symbol\``);let a=s.systems.find(({id:y})=>y===i);if(!a)return o({status:"not-found",systemId:i,available:s.systems.map(({id:y})=>y)},`system:${t}`);if(t==="show")return o({status:"ok",system:a,repositories:s.repositories},"system:show");let d=await kt(s,i,async y=>j(y,await f.status(y,{audit:"cached"})),n);return t==="validate"?o({systemId:i,...d},"system:validate"):o(_t(s,i,r===!0,d),"system:query")}async function Yi(e){let{repo:t,engine:i,limit:n,prNumber:r,prState:o,branches:s,auditRange:a,auditBase:d,auditHead:y,expectedLogin:g}=e,l=r==null?void 0:Number(r);if(l!==void 0&&Number.isNaN(l))return{error:"knodin prs: prNumber must be a number"};if(l!==void 0){let b=pt();return b?{error:b}:Dt(()=>mt(t,i,l,n))}return Dt(()=>ft(t,i,{state:o,limit:n,branches:s,range:a,base:d,head:y,expectedLogin:g}))}function Xi(e){let t=(i,n)=>{if(n!==void 0&&(!Array.isArray(n)||n.some(r=>typeof r!="string")))throw new Error(`knodin: ${i} must be an array of strings`)};for(let i of["languages","extensions","kinds","relationKinds","include","exclude","roots","alreadyPresent","chatFiles"])t(i,e[i]);if(t("architectureFacets",e.architectureFacets),e.direction!==void 0&&!["upstream","downstream","both"].includes(e.direction))throw new Error("knodin: invalid direction");if(e.architectureFacets?.some(i=>!["packages","layers","boundaries","hotspots","entryPoints","languages"].includes(i)))throw new Error("knodin: invalid architectureFacets");for(let[i,n,r]of[["offset",e.offset,0],["minLines",e.minLines,0],["minComplexity",e.minComplexity,0],["topN",e.topN,1]])if(n!==void 0&&(!Number.isInteger(n)||n<r))throw new Error(`knodin: ${i} must be an integer >= ${r}`);if(e.topN!==void 0&&e.topN>1e3)throw new Error("knodin: topN must be <= 1000");if(e.sort!==void 0&&!["relevance","name","size","degree","complexity"].includes(e.sort))throw new Error("knodin: invalid sort");if(e.testScope!==void 0&&!["all","test","production"].includes(e.testScope))throw new Error("knodin: invalid testScope");if(e.statusAudit!==void 0&&!["cached","deep"].includes(e.statusAudit))throw new Error("knodin: invalid statusAudit");if(e.timeoutMs!==void 0&&(!Number.isInteger(e.timeoutMs)||e.timeoutMs<0||e.timeoutMs>3e5))throw new Error("knodin: timeoutMs must be an integer between 0 and 300000");if(e.client!==void 0&&!["claude","codex","gemini","antigravity"].includes(e.client))throw new Error("knodin: invalid client")}function Zi(e){let t=e.source?.split(`
11
- `).map(i=>{let n=i.indexOf(": ");if(n<=0)return i;let r=i.slice(0,n);return/^\d+$/.test(r)?i.slice(n+2):i}).join(`
12
- `);return{mode:"source",identity:e.identity,symbol:e.symbol,source:t,staleness:e.staleness}}function en(e,t,i){if(!t.file||!t.evidenceLevel)throw new Error("knodin evidence requires `file` and `evidenceLevel`");return i(yt({repo:e,file:t.file,level:t.evidenceLevel,continuation:t.continuation,baselineHash:t.baselineHash,baselineBytes:t.baselineBytes,startLine:t.startLine,endLine:t.endLine,byteLimit:t.byteBudget,tokenLimit:t.tokenBudget,itemLimit:t.itemBudget}),"evidence")}function tn(e){return{status:e.status,content:e.content,exit:[e.exit.code,e.exit.signal],artifactId:e.artifact.retained?e.artifact.id:null,budget:[e.output.lines,e.output.lineBudget,e.output.bytes,e.output.byteBudget],fidelity:[e.fidelity.detectedSignals,e.fidelity.preservedSignals,e.fidelity.unpreservedSignals],omitted:e.omittedRanges.map(({startLine:t,endLine:i,byteCount:n})=>[t,i,n])}}function he(e){return[e.identity,e.symbol,e.file,e.kind,e.line,e.confidence]}function nn(e){return{status:e.status,input:[e.input.kind,e.input.artifactId,e.input.bytes,e.input.complete],diagnostics:e.diagnostics.map(t=>({reference:[t.reference.path,t.reference.line,t.reference.column],file:t.file,package:t.package?[t.package.name,t.package.manifest,t.package.kind]:null,owner:t.owner?[t.owner.identity,t.owner.symbol,t.owner.kind,t.owner.line,t.owner.endLine,t.owner.signature]:null,tests:t.tests.map(he),upstream:t.upstream.map(he),downstream:t.downstream.map(he),recent:t.recentChanges.map(({commit:i,at:n,subject:r})=>[i.slice(0,12),n,r])})),unresolved:e.unresolved,context:e.contextBundle,freshness:[e.freshness.state,e.freshness.indexedHead,e.freshness.currentHead],confidence:e.confidence,omissions:e.omissions,telemetry:e.telemetry,limitations:e.limitations}}function Ht(e){return e.byteBudget!==void 0||e.tokenBudget!==void 0||e.itemBudget!==void 0}async function rn(e,t,i,n){if([t.artifactId!==void 0,t.text!==void 0].filter(Boolean).length!==1)throw new Error("knodin compress diagnose requires exactly one of artifactId or text");return n("compress:diagnose",async()=>{let o=await de(i,e,{artifactId:t.artifactId,text:t.text,maxDiagnostics:t.limit??t.itemBudget,diagnosticOffset:t.startLine,contextLines:t.contextLines,contextByteBudget:t.compressionByteBudget});return t.detailLevel==="standard"?o:nn(o)},t.detailLevel!=="standard")}function on(e,t,i,n){if(!t.artifactId)throw new Error("knodin compress read requires `artifactId`");let r=Ne(e,t.artifactId,{startLine:t.startLine,endLine:t.endLine,byteBudget:t.compressionByteBudget,raw:t.raw});return Ht(t)?n(r,"compress:read"):i(r,"compress:read",!0)}function sn(e,t,i,n){let r={exitCode:t.exitCode,signal:t.signal,strategy:t.strategy,adapter:t.adapter,lineBudget:t.lineBudget,byteBudget:t.compressionByteBudget,contextLines:t.contextLines,retain:t.retain,redactSecrets:t.redactSecrets,maxInputBytes:t.maxInputBytes};if([t.text!==void 0,t.events!==void 0,t.artifactPath!==void 0].filter(Boolean).length!==1)throw new Error("knodin compress create requires exactly one of text, events, artifactPath");let s;t.artifactPath?s=Oe(e,t.artifactPath,r):t.events?s=U(e,{...r,events:t.events}):s=U(e,{...r,text:t.text});let a=t.detailLevel!=="standard",d=a?tn(s):s;return Ht(t)?n(d,"compress:create",a):i(d,"compress:create",a)}async function an(e,t,i,n,r,o){switch(t.compressionAction??"create"){case"diagnose":return rn(e,t,i,o);case"read":return on(e,t,n,r);case"delete":if(!t.artifactId)throw new Error("knodin compress delete requires `artifactId`");return n(De(e,t.artifactId),"compress:delete",!0);case"create":return sn(e,t,n,r);default:throw new Error("knodin compress: invalid compressionAction")}}async function cn(e,t,i,n){if(!t)throw new Error("knodin execute requires `profile`");let r=await Bt({repo:e,profile:t}),o=null;if(r.output?.artifact.retained&&r.status!=="completed")try{o=await de(i,e,{artifactId:r.output.artifact.id,maxDiagnostics:10,contextLines:2,contextByteBudget:16384})}catch(s){o={status:"unavailable",reason:s instanceof Error?s.message:String(s)}}return n({execution:r,diagnosis:o},"execute",!0)}async function dn(e,t,i,n,r){let o=await f.explain(e,t,"minimal",i),s=n;return!s&&o.identity&&!o.ambiguity&&(s=(await f.search(e,t,100,{includeSource:!1,structural:!0})).results.find(d=>d.identity===o.identity)?.filePath),$t(o,s,r)}async function ln(e,t,i,n,r){let o=await f.search(e,t,i,{...n,includeSource:!1,structural:!0});return Rt(o,e,r)}async function un(e,t,i,n,r,o,s){let a=await f.query(e,t,i,void 0,n,r,void 0,o,void 0,{});return qt(a,s)}var pn=Symbol("not-compact-structural");function mn(e,t){let i=Ge();if(!e)return t({error:`knodin docs requires \`section\` parameter. Valid sections: ${i.join(", ")}`},"docs");let n=Ve(e),r=e==="quickstart"&&n!==void 0?`${n}
13
-
14
- ${Vi()}`:n;return t(r===void 0?{error:`unknown docs section. Valid sections: ${i.join(", ")}`}:{status:"ok",section:e,content:r},"docs")}async function fn(e,t,i,n){let{operation:r,detailLevel:o,includeSource:s,symbol:a,file:d,byteBudget:y}=e,g=async w=>{let x=await Hi(t);return x?n(x,w,!0):null};if(r==="explain"&&o==="compact"&&s===!0&&a)return{handled:!0,value:await g("explain")??await dn(a,t,i,d,y)};if(r==="search"&&o==="compact"&&e.query)return{handled:!0,value:await g("search")??await ln(e.query,t,Math.min(e.limit??e.itemBudget??5,e.itemBudget??100),{languages:e.languages,extensions:e.extensions,kinds:e.kinds,path:e.path,testScope:e.testScope,offset:e.offset},y)};let l=r==="query"&&o==="compact"&&(e.pattern==="file_summary"||e.pattern==="batch_outline"||e.pattern==="project_overview")?e.pattern:null;return l?{handled:!0,value:await g(`query:${l}`)??await un(l,a??"",t,Math.min(e.limit??e.itemBudget??100,e.itemBudget??1e3),e.depth,i,y)}:{handled:!1,value:pn}}async function ne(e){let t=performance.now(),i=e??{},{operation:n,symbol:r,base:o,diffScope:s,from:a,toRevision:d,reviewFiles:y,query:g,pattern:l,to:b,limit:w,depth:x,impactMode:E,direction:P,relationKinds:_,minConfidence:q,includeTests:z,includeDataFlow:A,flowVariable:N,apply:R,force:S,detailLevel:p,prNumber:$,prState:v,branches:D,auditRange:zt,auditBase:Kt,auditHead:Ut,expectedLogin:Gt,worktreeAction:re,worktreePath:be,telemetryAction:Vt,telemetryRetentionDays:oe,task:ve,changedFiles:Wt,repoPath:Qt,section:Jt,systemAction:xe,repositoryAction:ke,roots:Yt,linkedWorktrees:Xt,cursor:Zt,allowPartial:_e,dryRun:Se,manifestPath:ei,identity:ti,file:ii,kind:ni,toIdentity:ri,toFile:oi,toKind:si,byteBudget:W,tokenBudget:se,itemBudget:K,includeSource:Ee,languages:ai,extensions:ci,kinds:Pe,path:qe,architectureFacets:di,testScope:li,offset:Q,minLines:ui,minComplexity:pi,topN:Re,sort:$e,packAction:J,format:mi,include:Le,exclude:Te,filePolicies:fi,alreadyPresent:yi,chatFiles:hi,lineNumbers:gi,includeTree:wi,outputPath:ae,artifactPath:M,startLine:bi,endLine:vi,regex:Ae,regexFlags:xi,gitDiffScope:Be,gitLog:Ce,statusAudit:ki,timeoutMs:_i,client:Si,repairPlan:Ei,persistTelemetry:Pi}=i,c=Qt??process.cwd(),Y={identity:fe(ti),file:ii,kind:ni,toIdentity:fe(ri),toFile:oi,toKind:si},qi={bytes:W,tokens:se,items:K},X=(u,h,T=!1)=>{let k=u,C=k.responseBudget;h==="review"&&Fe("review_serialization",()=>JSON.stringify(u));let L=ot({repo:c,operation:h,output:k,startedAt:t,detailMode:T?"minimal":p??"standard",truncated:C?.truncated===!0||k.telemetry?.truncated===!0,schemaTokens:ji()});return h==="execute"&&i.profile&&(L.executionProfile=i.profile),L.temperature=G.some(({operation:Ri,repositoryId:$i})=>Ri===h&&$i===L.repositoryId)?"warm":"cold",G.push(L),G.length>1e3&&G.shift(),Pi===!0&&ct(c,L,oe),k},m=(u,h=String(n),T=!1)=>{let k=`${h}${T?":minimal":""}`,C=wt(u,h,qi,Mt[k]??Mt.default);return X(C,h,T)},F=async(u,h,T=!1)=>{let k=await V(c);if(!k.available)return m(k,u,T);let C=await h(),L=await V(c);return L.available?m(Z(C,L.state,L.graph.freshness),u,T):m(L,u,T)};Xi(i);let Ie=await fn(i,c,Y,m);if(Ie.handled)return Ie.value;if(p==="compact")throw new Error("knodin: compact detail is unsupported here");switch(n){case"telemetry":{let u=Vt??"records";if(u==="records")return m({records:G.slice()},"telemetry");if(u==="status")return m(dt(c,M,oe),"telemetry:status");let h=at(c,M,oe);return u==="report"?m(st(c,h,ae),"telemetry:report"):u==="export"?m(lt(c,h,ae),"telemetry:export"):m(ut(c,M),"telemetry:clear")}case"doctor":{let u=await f.status(c);return m(await ce(c,{currentVersion:u.version,runtimeCommand:[process.execPath,process.argv[1]??"","serve"],graph:u,client:Si}),"doctor")}case"status":return f.status(c,{audit:ki}).then(u=>m({...j(c,u),integration:nt(c),update:Qe({currentVersion:u.version,installMethod:"unknown",env:process.env})},"status"));case"wait":return m(await Pt(f,c,_i),"wait");case"worktrees":if(!re||re==="status")return m(await et(c,u=>f.status(u,{audit:"cached"})),"worktrees:status");if(re==="reconcile")return m(tt(c),"worktrees:reconcile");if(!be)throw new Error("knodin worktrees remove requires `worktreePath`");return m(it(c,be,Se!==!1),"worktrees:remove");case"repair":return Ei?m(ht(await f.status(c,{audit:"deep"})),"repair:plan"):m(We(c,await f.repair(c)),"repair");case"repositories":{if(!ke)throw new Error("knodin repositories requires `repositoryAction`");return Qi({repositoryAction:ke,roots:Yt,repo:c,depth:x,linkedWorktrees:Xt,query:g,include:Le,exclude:Te,allowPartial:_e,dryRun:Se,manifestPath:ei,itemBudget:K,byteBudget:W,tokenBudget:se,cursor:Zt,bounded:m})}case"system":{if(!xe)throw new Error("knodin system requires `systemAction`");return Ji({systemAction:xe,symbol:r,repo:c,allowPartial:_e,bounded:m})}case"compress":return an(c,i,f,X,m,F);case"execute":return cn(c,i.profile,f,m);case"evidence":return en(c,i,X);case"pack":{if(J!==void 0&&!["export","read","grep"].includes(J))throw new Error("knodin pack: invalid packAction");if(J==="read"){if(!M)throw new Error("knodin pack read requires `artifactPath`");return m(ze(c,M,bi,vi,W),"pack:read")}if(J==="grep"){if(!M||!Ae)throw new Error("knodin pack grep requires `artifactPath` and `regex`");return m(Ke(c,M,Ae,xi,w),"pack:grep")}return X(He(c,{format:mi,include:Le,exclude:Te,policies:fi,alreadyPresent:yi,chatFiles:hi,lineNumbers:gi,includeTree:wi,outputPath:ae,byteBudget:W,tokenBudget:se,git:Be||Ce!==void 0?{diffScope:Be,from:a,to:d,log:Ce}:void 0}),"pack:export")}case"docs":return mn(Jt,m);case"explain":if(!r)throw new Error("knodin explain requires `symbol`");return F("explain",async()=>{let u=await f.explain(r,c,p==="minimal"?"minimal":"standard",Y);return p==="source"&&!u.ambiguity?Zi(u):(p==="minimal"&&Ee!==!0&&u&&!u.ambiguity&&(delete u.source,u.sourceOmitted=!0,u.sourceContinuation={operation:"explain",symbol:r,includeSource:!0}),u)},p==="minimal");case"review":return F("review",()=>f.review(o??"HEAD~1",c,p==="minimal"?"minimal":"standard",{scope:s,files:y,from:a,to:d}),p==="minimal");case"map":return F("map",()=>f.map(c,p==="standard"?"standard":"minimal",{topN:Re,sort:$e,relationKinds:_}));case"wiki":return F("wiki",()=>f.wiki(c,S));case"context":{if(!ve)throw new Error("knodin context requires `task`");return F("context",()=>je(f,ve,c,o,Wt))}case"search":if(!g)throw new Error("knodin search requires `query`");if(Q!==void 0&&(!Number.isInteger(Q)||Q<0))throw new Error("knodin search: offset must be a non-negative integer");return F("search",()=>f.search(g,c,Math.min(w??K??5,K??100),{languages:ai,extensions:ci,kinds:Pe,path:qe,testScope:li,includeSource:Ee,offset:Q}));case"prs":return m(await Yi({repo:c,engine:f,limit:w,prNumber:$,prState:v,branches:D,auditRange:zt,auditBase:Kt,auditHead:Ut,expectedLogin:Gt}),"prs");case"query":{if(!l)throw new Error("knodin query requires `pattern`");if(!Ft.includes(l))throw new Error(`knodin query: unknown pattern ${String(l)}`);if(w!==void 0&&(!Number.isFinite(w)||!Number.isInteger(w)||w<1))throw new Error("knodin query: limit must be a positive integer");let u=Ye.includes(l);if(!r&&!u)throw new Error(`knodin query ${l} requires \`symbol\``);if(l==="shortest_path"&&!b)throw new Error("knodin query shortest_path requires `to`");if(l==="rename_preview"&&!b)throw new Error("knodin query rename_preview requires `symbol` and `to`");let h=zi.has(l)?null:await V(c);if(h&&!h.available)return m(h,`query:${l}`);if(l==="rename_preview")return f.rename(r??"",b??"",c,R===!0,!0,Y).then(L=>m(Z(L,h?.available?h.state:"healthy",h?.available?h.graph.freshness:void 0),"query:rename_preview"));let T=await f.query(l,r??"",c,b,Math.min(w??K??100,K??1e3),x,p==="source"?void 0:p,Y,l==="impact"?{mode:E??"symbol",direction:P,relationKinds:_,minConfidence:q,includeTests:z,includeDataFlow:A}:void 0,{minLines:ui,minComplexity:pi,kinds:Pe,path:qe,direction:l==="traverse"?P:void 0,includeDataFlow:l==="traverse"?A:void 0,flowVariable:l==="flow_analysis"?N:void 0,architectureFacets:di,topN:Re,sort:$e,relationKinds:l==="impact"?void 0:_,detailLevel:p==="source"?void 0:p}),k=h?await V(c):null;if(k&&!k.available)return m(k,`query:${l}`);let C=l==="impact"||l==="dead_code"?Et(await ue(H(c)),c,l,r??"",T):T;return m(h?.available?Z(C,k?.available?k.state:h.state,k?.available?k.graph.freshness:h.graph.freshness):C,`query:${l}`)}default:throw new Error(`unknown knodin operation: ${String(n)}`)}}var xn=new Set(["architecture_overview","context","docs","explain","map","query","review","search","status"]),we=class{tail=Promise.resolve();pending=0;async run(t,i){let n=this.pending++,r=this.tail,o;this.tail=new Promise(s=>{o=s});try{if(await r,t.aborted)throw Object.assign(new Error("MCP request cancelled before dispatch"),{code:"KNODIN_REQUEST_CANCELLED"});return await i(n)}finally{this.pending--,o()}}};function kn(){}function _n(e,t,i){return setInterval(()=>{e(`${t} still running (${Math.round((Date.now()-i)/1e3)}s)`).catch(kn)},1e4)}function Sn(e,t,i=process.cwd()){let n=typeof e?.repoPath=="string"?e.repoPath:i,r=Ue(n,{surface:"mcp",operation:typeof e?.operation=="string"?e.operation:"unknown",phase:"dispatch",error:t});return r.recorded?new Error(`${t instanceof Error?t.message:String(t)} [diagnostic ${r.correlationId}]`,{cause:t}):t}function En(e=ne){let t=new we,i=new gn({name:"knodin",version:Je},{capabilities:{tools:{}},instructions:"Use knodin first for cold or unfamiliar codebase work: context to orient, explain for source-evidenced symbol context, query impact before meaningful edits, and review before handoff. Prefer direct reads for exact literals, non-code files, or files just edited this turn. If status reports repair-needed, follow its typed repair steps: repair graph damage or init displaced lifecycle routing before relying on graph evidence."});return i.setRequestHandler(vn,async()=>({tools:jt()})),i.setRequestHandler(bn,async(n,r)=>{let{name:o,arguments:s}=n.params;if(o!=="knodin")throw new Error(`unknown tool: ${o}`);let a=s,d=typeof a?.operation=="string"?a.operation:"unknown",y=r._meta?.progressToken,g=String(r.requestId),l=Date.now(),b;try{let w=await t.run(r.signal,async x=>{let E=async P=>{y!==void 0&&await r.sendNotification({method:"notifications/progress",params:{progressToken:y,progress:Date.now()-l,message:P}})};return await E(x>0?`Starting ${d} after waiting behind ${x} earlier request(s)`:`Starting ${d}`),b=_n(E,d,l),e===ne?await ne(s):await e(s)});return{content:[{type:"text",text:JSON.stringify(w,null,2)}]}}catch(w){let x=Sn(a,w),E=x instanceof Error?x.message:String(x),P=/\[diagnostic ([a-f0-9]{16})\]/.exec(E)?.[1]??`mcp-${g}`,_=xn.has(d);return{isError:!0,content:[{type:"text",text:JSON.stringify({code:w?.code==="KNODIN_REQUEST_CANCELLED"?"KNODIN_REQUEST_CANCELLED":"KNODIN_OPERATION_FAILED",message:E,traceId:P,requestId:g,operation:d,repository:typeof a?.repoPath=="string"?a.repoPath:process.cwd(),phase:"dispatch",retrySafe:_,diagnosticLog:".knodin/diagnostics/events.jsonl (only when opt-in diagnostics are enabled)",recovery:_?"Retry once. If the transport closes, restart the MCP client and run `knodin doctor`; include `knodin diagnostics export` when diagnostics are enabled.":"Do not retry automatically. Run `knodin doctor`, inspect repository state, and include `knodin diagnostics export` when diagnostics are enabled."},null,2)}]}}finally{b&&clearInterval(b)}}),i}async function Pn(){let e=En(),t=new wn;await e.connect(t),console.error("knodin MCP server running on stdio")}async function qn(){await Pn()}process.argv[1]&&hn(import.meta.url)===yn.resolve(process.argv[1])&&qn().catch(e=>{console.error(e),process.exit(1)});export{En as createServer,Sn as recordMcpDiagnosticFailure,qn as startServer};
@@ -1,4 +0,0 @@
1
- import{a as m,c as b}from"./chunk-X6M4HUUE.js";import y from"node:fs";import d from"node:path";function x(e,t){try{return m(y.readFileSync(d.resolve(e,t.path)))===t.contentFingerprint}catch{return!1}}var g=new Set([".cjs",".cs",".cts",".go",".java",".js",".jsx",".mjs",".mts",".py",".rs",".ts",".tsx"]);function S(e,t,i){if(i){let n=/^\s*/.exec(e[t])?.[0].length??0,o=t+1;for(let f=t+1;f<e.length;f++){let c=e[f];if(c.trim()&&(/^\s*/.exec(c)?.[0].length??0)<=n)break;o=f+1}return o}let u=0,l=!1;for(let n=t;n<e.length;n++){for(let o of e[n])o==="{"?(l=!0,u++):o==="}"&&u--;if(l&&u<=0||!l&&/[;}]\s*$/.test(e[n]))return n+1}return t+1}function w(e){let t=e.indexOf("(");if(t<=0)return null;let i=0,u=-1;for(let c=t;c<e.length;c+=1)if(e[c]==="("&&(i+=1),e[c]===")"&&(i-=1,i===0)){u=c;break}if(u<0)return null;let l=e.slice(u+1).trimStart();if(!l.startsWith("{")&&!l.startsWith("=>"))return null;let n=e.slice(0,t).trim();if(/[=;{}()]/.test(n))return null;let o=n.split(/\s+/),f=o.at(-1)??"";return o.length>=2&&/^[A-Za-z_$][\w$]*$/.test(f)?f:null}function _(e,t){for(let{kind:i,expression:u}of t){let l=u.exec(e);if(l)return{kind:i,symbol:l[1]}}return null}function $(e,t){let u=d.extname(e).toLowerCase()===".py",l=t.split(/\r?\n/),n=[],o=u?[{kind:"class",expression:/^\s*class\s+([A-Za-z_$][\w$]*)\b/},{kind:"function",expression:/^\s*(?:async\s+)?def\s+([A-Za-z_$][\w$]*)\s*\(/}]:[{kind:"class",expression:/^\s*(?:(?:export|public|private|protected|internal|abstract|final|sealed|static)\s+)*(?:class|interface|enum|struct|trait|record|type)\s+([A-Za-z_$][\w$]*)\b/},{kind:"function",expression:/^\s*(?:(?:export|public|private|protected|internal|async|static|final|pub(?:\([^)]*\))?)\s+)*(?:func|fn|function)\s+([A-Za-z_$][\w$]*)\s*\(/},{kind:"function",expression:/^\s*(?:(?:export|const|let|var|public|private|protected|static|readonly)\s+)*([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>/}];for(let[f,c]of l.entries()){let p=_(c,o);if(!p&&!u){let r=w(c);r&&(p={kind:"function",symbol:r})}if(p){let{kind:r,symbol:s}=p,a=c.match(/\b(public|private|protected|internal)\b/)?.[1]??(u&&s.startsWith("_")?"private":"default");n.push({identity:null,symbol:s,kind:r,line:f+1,endLine:S(l,f,u),signature:c.trim().split(/\s*(?:\{|=>)\s*/,1)[0].slice(0,500),visibility:a,exported:/\bexport\b/.test(c)||/\bpub\b/.test(c),evidenceQuality:"lexical-structural-fallback"})}}return n}function v(e,t){if(!g.has(d.extname(t).toLowerCase()))return null;let i=y.realpathSync(e),u=d.resolve(i,t),l;try{l=y.realpathSync(u)}catch{return null}let n=d.relative(i,l);if(n===".."||n.startsWith(`..${d.sep}`)||d.isAbsolute(n))return null;let o=y.readFileSync(l,"utf8");return{path:n.split(d.sep).join("/"),sizeBytes:Buffer.byteLength(o),mtimeMs:y.statSync(l).mtimeMs,contentFingerprint:m(o),symbols:$(t,o)}}function k(e,t,i,u=100){let l=b(e);if(!l&&t!=="file_summary")return null;let n=(l?.files??[]).filter(r=>!i||r.path.includes(i));if(t==="file_summary"){let r=n.find(s=>s.path===i);if(!r||!x(e,r)){let s=v(e,i);if(!s)return null;n=[s]}}else t==="batch_outline"&&(n=n.flatMap(r=>{if(x(e,r))return[r];let s=v(e,r.path);return s?[s]:[]}));let o=[],f,c=!1;if(t==="project_overview"){c=n.every(s=>{try{let a=y.statSync(d.resolve(e,s.path));return a.size===s.sizeBytes&&a.mtimeMs===s.mtimeMs}catch{return!1}});let r=new Map;for(let s of n){let a=s.path.includes("/")?s.path.split("/",1)[0]:".",h=r.get(a)??{fileCount:0,sizeBytes:0};h.fileCount+=1,h.sizeBytes+=s.sizeBytes,r.set(a,h)}o=[...r].sort(([s],[a])=>s.localeCompare(a)).map(([s,a])=>({symbol:s,kind:"directory",...a})),f=m(JSON.stringify(n.map(({path:s,contentFingerprint:a})=>[s,a])))}else{let r=t==="file_summary"?n.filter(s=>s.path===i):n;c=r.length>0&&r.every(s=>x(e,s)),f=r.length===1?r[0].contentFingerprint:m(JSON.stringify(r.map(s=>[s.path,s.contentFingerprint]))),o=r.flatMap(s=>s.symbols.map(a=>({...a,file:s.path})))}let p=o.slice(0,u);return{pattern:t,target:i,count:p.length,results:p,...o.length>p.length?{hasMore:!0}:{},staleness:c?"fresh":"unknown",graphEnriched:!1,evidence:{...t==="file_summary"?{path:i}:{},contentFingerprint:f,evidenceQuality:n.some(r=>r.symbols.some(s=>s.evidenceQuality==="lexical-structural-fallback"))?"direct-lexical-parser":"indexed-structural-snapshot",uniqueness:t==="project_overview"?"not-applicable":"file-scoped-only",evidenceGeneratedAt:l?.generatedAt??new Date().toISOString()},upgrade:t==="file_summary"?{operation:"explain",target:i}:t==="project_overview"?{operation:"query",pattern:"architecture_overview",target:""}:{operation:"query",pattern:"impact",target:i}}}function F(e,t,i){let u=b(e),l=u?.files.find(a=>a.path===i),n=l&&x(e,l)?l:v(e,i);if(!n)return null;let o=n.symbols.filter(a=>a.symbol===t);if(o.length===0)return null;let f=x(e,n),c={path:i,contentFingerprint:n.contentFingerprint,evidenceQuality:n.symbols.some(a=>a.evidenceQuality==="lexical-structural-fallback")?"direct-lexical-parser":"indexed-structural-snapshot",uniqueness:"file-scoped-only",evidenceGeneratedAt:u?.generatedAt??new Date().toISOString()};if(o.length>1)return{symbol:t,file:i,ambiguity:{candidates:o.map(a=>({identity:a.identity??"",file:i,kind:a.kind,line:a.line}))},staleness:f?"fresh":"unknown",graphEnriched:!1,evidence:c,upgrade:{operation:"explain",target:t}};let p=o[0],r=y.readFileSync(d.resolve(e,i),"utf8").split(/\r?\n/),s=f?r.slice(p.line-1,p.endLine).map((a,h)=>`${p.line+h}: ${a}`).join(`
2
- `):void 0;return{symbol:t,...p.identity?{identity:p.identity}:{},file:i,...s?{source:s}:{},staleness:f?"fresh":"unknown",graphEnriched:!1,evidence:c,upgrade:{operation:"explain",target:t}}}function E(e,t=process.cwd()){let i=c=>{let p=e.indexOf(c);return p>=0?e[p+1]:e.find(r=>r.startsWith(`${c}=`))?.slice(c.length+1)};if(e[0]==="explain"&&e[1]&&i("--file")){let c=d.resolve(i("--repo")??t),p=F(c,e[1],i("--file"));return p?(process.stdout.write(`${JSON.stringify(p)}
3
- `),!0):!1}if(e[0]!=="query"||!["file_summary","batch_outline","project_overview"].includes(e[1]??""))return!1;let u=e[1],l=d.resolve(i("--repo")??t),n=u==="project_overview"?"":e[2]??"",o=Number(i("--limit")??100);if(!n&&u!=="project_overview")return!1;let f=k(l,u,n,Number.isInteger(o)&&o>0?o:100);return f?(process.stdout.write(`${JSON.stringify(f)}
4
- `),!0):!1}export{F as runExactSymbolFastPath,k as runStructuralFastPath,E as tryStructuralFastPath};
@@ -1,25 +0,0 @@
1
- # knodin 0.7.6
2
-
3
- This patch release lets Knodin run inside repositories pinned to Node.js 20
4
- without weakening Knodin's Node.js 24+ runtime requirement.
5
-
6
- - Detects an unsupported active Node.js runtime before loading Node-24-only
7
- dependencies.
8
- - Finds and version-checks a suitable Node.js 24+ executable from absolute
9
- `PATH` entries, common version-manager installations, or Homebrew, then hands
10
- off the original command with inherited arguments, environment, and stdio.
11
- - Supports an explicit `KNODIN_NODE_RUNTIME=/absolute/path/to/node` override
12
- with actionable validation errors.
13
- - Rejects relative executable and version-manager roots so repository-local
14
- files cannot be introduced into automatic runtime discovery.
15
- - Adds a real Node.js 20-to-24 launcher acceptance job and packages the runtime
16
- selector in the published artifact.
17
-
18
- The analyzed repository may stay on Node.js 20. Knodin itself still executes on
19
- Node.js 24 or newer, and installation-time package-manager engine checks remain
20
- unchanged.
21
-
22
- The source package is marked private, preventing accidental publication to the
23
- public npm registry. Its repository metadata continues to identify the
24
- authoritative `knodin/knodin` GitHub repository; `Enterprise-Apps/knodin` is the
25
- internal GHES mirror.