agent-runtime-map 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/dist/cli.js +195 -0
- package/dist/licenses/classcat.txt +7 -0
- package/dist/licenses/d3-color.txt +13 -0
- package/dist/licenses/d3-dispatch.txt +13 -0
- package/dist/licenses/d3-drag.txt +13 -0
- package/dist/licenses/d3-ease.txt +28 -0
- package/dist/licenses/d3-interpolate.txt +13 -0
- package/dist/licenses/d3-selection.txt +13 -0
- package/dist/licenses/d3-timer.txt +13 -0
- package/dist/licenses/d3-transition.txt +13 -0
- package/dist/licenses/d3-zoom.txt +13 -0
- package/dist/licenses/elkjs.txt +264 -0
- package/dist/licenses/lucide-react.txt +15 -0
- package/dist/licenses/react-dom.txt +21 -0
- package/dist/licenses/react.txt +21 -0
- package/dist/licenses/scheduler.txt +21 -0
- package/dist/licenses/use-sync-external-store.txt +21 -0
- package/dist/licenses/xyflow__react.txt +21 -0
- package/dist/licenses/xyflow__system.txt +21 -0
- package/dist/licenses/zustand.txt +21 -0
- package/dist/python/extract.py +219 -0
- package/dist/viewer/assets/elk-DSSKxAlM.js +24 -0
- package/dist/viewer/assets/index-4tql6hvj.js +3 -0
- package/dist/viewer/assets/index-Dvsvzpjt.css +1 -0
- package/dist/viewer/assets/react-C8zC5XaP.js +9 -0
- package/dist/viewer/assets/xyflow-BnuhLJ6X.css +1 -0
- package/dist/viewer/assets/xyflow-NEmtYq4w.js +7 -0
- package/dist/viewer/index.html +17 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Agent Runtime Map contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Agent Runtime Map
|
|
2
|
+
|
|
3
|
+
Turn every Agent feature into an evidence-backed execution circuit you can inspect step by step.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx agent-runtime-map@latest .
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
GitHub Release fallback:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install --save-dev https://github.com/TheCrazyAnt/agent-runtime-map/releases/download/v0.2.0/agent-runtime-map-0.2.0.tgz
|
|
13
|
+
npx agent-runtime-map .
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The command analyzes the selected project, writes `.logic-map/graph.json`, starts a local viewer, and opens it in the browser. Choose a feature from the left to play, pause, single-step, replay, or switch between its inferred branches on one global Agent graph. Chain Doctor marks verified steps green, uncertainty yellow, and deterministic failures red with source evidence and a suggested repair.
|
|
17
|
+
|
|
18
|
+
Playback is an explicit simulation of the statically compiled code route; it does not claim that a live request is executing.
|
|
19
|
+
|
|
20
|
+
Analysis is local by default. The Project Reader safely uses README/docs/PRD,
|
|
21
|
+
prompts, package metadata, and `agent-runtime-map.config.json` together with
|
|
22
|
+
TypeScript/JavaScript AST evidence. It excludes environment files, credentials,
|
|
23
|
+
private keys, dependencies, build output, and VCS metadata, and never executes
|
|
24
|
+
the inspected project.
|
|
25
|
+
|
|
26
|
+
Optional semantic enrichment is explicit:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
OPENAI_API_KEY="..." npx agent-runtime-map . \
|
|
30
|
+
--semantic openai \
|
|
31
|
+
--semantic-model <model>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This mode sends a bounded evidence snapshot, not the absolute project root or
|
|
35
|
+
raw source files. It can improve names and descriptions for existing graph IDs,
|
|
36
|
+
but it cannot add topology or evidence.
|
|
37
|
+
|
|
38
|
+
Use `agent-runtime-map analyze .` to generate JSON without starting a server. The original `logic-map` command remains available as an alias. See the [project repository](https://github.com/TheCrazyAnt/agent-runtime-map) for supported frameworks, context limits, privacy behavior, and contribution guidelines.
|
|
39
|
+
|
|
40
|
+
The CLI and Viewer automatically use Chinese for Chinese locales and English for other locales. Pass `--locale zh-CN` or `--locale en` to override detection.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
The bundled Agent Runtime Map Viewer contains React, React DOM, React Flow, ELK.js, Lucide, Zustand, Classcat, D3 modules, Scheduler, and use-sync-external-store.
|
|
4
|
+
|
|
5
|
+
Exact upstream license texts are included under `dist/licenses/`.
|
|
6
|
+
|
|
7
|
+
- ELK.js — Eclipse Public License 2.0
|
|
8
|
+
- Lucide and D3 modules — ISC License
|
|
9
|
+
- React, React DOM, React Flow, Zustand, Classcat, Scheduler, and use-sync-external-store — MIT License
|
|
10
|
+
|
|
11
|
+
`ts-morph` is installed as a regular runtime dependency and carries its own MIT license in its npm package.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{parseArgs as rs}from"util";import{mkdir as Go,stat as Ho,writeFile as zo}from"fs/promises";import ke from"path";import{access as bn,readFile as ot}from"fs/promises";import j from"path";import{Node as f,Project as xn,ScriptTarget as Cn,SyntaxKind as S}from"ts-morph";var K="0.1.0";function F(e){return Number.isFinite(e)?Math.min(1,Math.max(0,e)):0}import{createHash as gn}from"crypto";import{readdir as pn}from"fs/promises";import ae from"path";var fn=new Set([".git",".next",".logic-map",".turbo",".venv","__mocks__","__pycache__","__tests__","build","coverage","dist","node_modules","out","site-packages","venv"]),mn=/(^|\/)(scripts?|tools?\/dev|examples?|fixtures?|benchmarks?)(\/|$)/i,tt=new Set(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),q=new Set(["agent","function","human_gate","route","service","tool","workflow"]),hn=/^(is|has|can|should|must|assert|ensure|validate|to|as|from|parse|stringify|format|normali[sz]e|seriali[sz]e|deseriali[sz]e|encode|decode|escape|unescape|clone|merge|equals|compare|coerce|cast|wrap|unwrap|optional|required|default)[A-Z_]/,wn=/^(boolean|string|number|bigint|symbol|void|null|undefined|unknown|any)(\s*\|\s*(null|undefined))*$/;function yn(e){if(hn.test(e.name))return!0;let n=e.returnType?.trim();return!!(n&&wn.test(n))}function se(e,n){let t=n.exec(e);return t!==null&&t.index>0}function Y(e){let n=e.relativeFile.toLowerCase(),t=e.name.toLowerCase(),i=!mn.test(n)&&!yn(e);return e.routeConvention?{kind:"route",confidence:.95,detail:"Framework route handler convention",method:"framework_convention"}:/(^|\/)(page|layout)\.[jt]sx?$/.test(n)&&/(page|layout)$/.test(t)?{kind:"function",confidence:1,detail:"Declared in source",method:"ast"}:e.internal?{kind:"function",confidence:1,detail:"Private class member, treated as an implementation detail",method:"ast"}:se(t,/(workflow|orchestrator|pipeline|graph|crew)$/)?{kind:"workflow",confidence:.84,detail:"Workflow or orchestrator naming convention",method:"name_heuristic"}:i&&/(^|\/)(workflows?|orchestrators?|pipelines?|graphs?|crews?)(\/|$)/.test(n)?{kind:"workflow",confidence:.72,detail:"Declared under a workflow or orchestrator directory",method:"path_heuristic"}:se(t,/agent$/)?{kind:"agent",confidence:.84,detail:"Agent naming convention",method:"name_heuristic"}:i&&/(^|\/)(agents?)(\/|$)/.test(n)?{kind:"agent",confidence:.72,detail:"Declared under an Agent directory",method:"path_heuristic"}:/(approve|approval|humanreview|human_review|confirm|moderate)/.test(t)?{kind:"human_gate",confidence:.68,detail:"Human approval or review naming convention",method:"name_heuristic"}:se(t,/(tool|action)$/)?{kind:"tool",confidence:.8,detail:"Tool or action naming convention",method:"name_heuristic"}:i&&/(^|\/)(tools?|actions?)(\/|$)/.test(n)?{kind:"tool",confidence:.65,detail:"Declared under a tool or action directory",method:"path_heuristic"}:se(t,/(service|usecase)$/)?{kind:"service",confidence:.8,detail:"Service naming convention",method:"name_heuristic"}:i&&/(^|\/)(services?|use-cases?|commands?)(\/|$)/.test(n)?{kind:"service",confidence:.7,detail:"Declared under a service or use-case directory",method:"path_heuristic"}:e.enclosingClass&&/(service|controller|repository)$/i.test(e.enclosingClass)?{kind:"service",confidence:.6,detail:"Public member of a service, controller, or repository class",method:"name_heuristic"}:/(handler|execute|process|generate|create|build)/.test(t)?{kind:"service",confidence:.5,detail:"Business verb in the declaration name",method:"name_heuristic"}:{kind:"function",confidence:1,detail:"Declared in source",method:"ast"}}function E(e,n,t,i,r,s,o){return{source:{file:e,startLine:n,endLine:o,symbol:s},method:t,detail:i,confidence:r}}function $(e,n,t,i,r={}){return{id:k("edge",`${e}:${t}:${n}:${r.control??"sequential"}:${r.label??""}`),source:e,target:n,kind:t,label:r.label,control:r.control,metadata:r.metadata,evidence:i}}function k(e,n){return`${e}_${gn("sha1").update(n).digest("hex").slice(0,12)}`}function P(e,n){return ae.relative(e,n).split(ae.sep).join("/")}function A(e){return/\.pyi?$/i.test(e)?"python":/\.[cm]?jsx?$/.test(e)?"javascript":"typescript"}function Te(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[-_]+/g," ").trim()}function M(e){return e.split(/(?<=[.!?])\s/)[0]?.trim().slice(0,240)??e.slice(0,240)}function Z(e){return[...new Set([...e.matchAll(/\{\{?\s*([a-zA-Z0-9_.]+)\s*\}?\}/g)].map(n=>n[1]))]}function U(e){let n=new Set;return e.filter(t=>n.has(t.id)?!1:(n.add(t.id),!0))}async function ce(e,n,t){let i=[];async function r(s){let o;try{o=await pn(s,{withFileTypes:!0})}catch{return}o.sort((a,d)=>a.name.localeCompare(d.name));for(let a of o){let d=ae.join(s,a.name);a.isDirectory()?!fn.has(a.name)&&!a.name.startsWith(".")&&await r(d):a.isFile()&&n.has(ae.extname(a.name))&&!t.test(a.name)&&i.push(d)}}return await r(e),i}var vn=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"]),En=/(\.(test|spec)\.[cm]?[jt]sx?|\.d\.[cm]?ts)$/i,$n=3,Sn=new Set(["get","post","put","patch","delete","use","all","options","head"]),st=[{pattern:/^(express\.Router|Router|express)$/,name:"express"},{pattern:/^Hono$/,name:"hono"},{pattern:/^Elysia$/,name:"elysia"},{pattern:/^(fastify|Fastify)$/,name:"fastify"},{pattern:/^Koa$/,name:"koa"}],kn=new Set(["aggregate","create","createMany","delete","deleteMany","deleteOne","execute","find","findFirst","findMany","findOne","findUnique","insert","insertMany","insertOne","query","save","select","update","updateMany","updateOne","upsert"]),Rn=new Set(["db","prisma","supabase","drizzle","knex","mongoose","sequelize"]),_n=/^(database|sql|pool|conn|connection|cursor|session|repo|repository|collection|table|store|dao|entityManager|queryRunner)$/i,Nn=new Set(["every","filter","flatmap","foreach","map","reduce","reduceright","some"]);async function at(e,n={}){let t=j.resolve(e),i=[],r=await ce(t,vn,En),s=n.maxFiles??2e3,o=r.slice(0,s);r.length>s&&i.push({level:"warning",code:"FILE_LIMIT_REACHED",message:`Found ${r.length} source files; only the first ${s} were analyzed.`});let a=await Pn(t),d=new xn({...a?{tsConfigFilePath:a}:{},skipAddingFilesFromTsConfig:!0,compilerOptions:{allowJs:!0,checkJs:!1,jsx:4,target:Cn.ES2022}});d.addSourceFilesAtPaths(o),await d.resolveSourceFileDependencies();let c=[],g=[],l=new Set(o.map(w=>j.resolve(w))),m=d.getSourceFiles().filter(w=>l.has(j.resolve(w.getFilePath()))),h=new Map,u=new Map;for(let w of m){let v=P(t,w.getFilePath()),R=k("file",v);h.set(w.getFilePath(),R);let _=gi(v)?"entrypoint":"file";c.push({id:R,kind:_,name:v,qualifiedName:v,language:A(v),evidence:[E(v,1,"path_heuristic",_==="entrypoint"?"Framework entrypoint convention":"Source file discovered",_==="entrypoint"?.86:1)]}),An(w,t,R,c,g,u)}for(let w of m){let v=h.get(w.getFilePath());v&&Ln(w,t,v,c,g,u)}let p=Xn(m);for(let w of m){let v=h.get(w.getFilePath());v&&Jn(w,t,v,c,g,u,p)}let y=Bn(m,u);for(let w of m)qn(w,t,u,c,g,y),Fn(w,t,u,c,g);for(let w of m)zn(w,t,h,g),Vn(w,t,u,c,g),jn(w,t,u,c,g),ei(w,t,u,c,g);let b=await hi(t,m.map(w=>P(t,w.getFilePath()))),C=[...new Set(m.map(w=>A(w.getFilePath())))];return m.length===0&&i.push({level:"warning",code:"NO_SOURCE_FILES",message:"No supported TypeScript or JavaScript source files were found."}),{schemaVersion:K,generatedAt:new Date().toISOString(),project:{name:await wi(t),root:t,languages:C,frameworks:b,filesScanned:m.length},nodes:U(c),edges:U(g).filter(w=>w.source!==w.target),diagnostics:i}}async function Pn(e){for(let n of["tsconfig.json","jsconfig.json"]){let t=j.join(e,n);try{return await bn(t),t}catch{}}}function An(e,n,t,i,r,s){let o=P(n,e.getFilePath()),a=[...e.getFunctions(),...e.getClasses().flatMap(d=>d.getMethods()),...e.getVariableDeclarations().filter(d=>{let c=d.getInitializer();return!!(c&&(f.isArrowFunction(c)||f.isFunctionExpression(c)))})];for(let d of a){let c=ai(d);if(!c)continue;let g=d.getStartLineNumber(),{kind:l,confidence:m,detail:h,method:u}=Y(ft(o,c,d)),p=k(l,`${o}:${c}:${g}`),y={id:p,kind:l,name:c,qualifiedName:`${o}#${c}`,language:A(o),evidence:[E(o,g,u,h,m,c,d.getEndLineNumber())],metadata:{...ct(d),...l==="route"?{method:c.toUpperCase(),path:li(o),framework:"nextjs"}:{}}};i.push(y),r.push($(t,p,"contains",y.evidence)),s.set(L(d),{node:y,declaration:d})}for(let d of e.getClasses()){let c=d.getName();if(!c)continue;let g=d.getStartLineNumber(),l=k("class",`${o}:${c}:${g}`),m=[E(o,g,"ast","Class declaration",1,c,d.getEndLineNumber())];i.push({id:l,kind:"class",name:c,qualifiedName:`${o}#${c}`,language:A(o),evidence:m}),r.push($(t,l,"contains",m))}}function de(e){if(f.isArrowFunction(e)||f.isFunctionExpression(e)||f.isFunctionDeclaration(e)||f.isMethodDeclaration(e))return e;let n=f.isExportAssignment(e)?e.getExpression():e.getInitializer();if(n)return f.isArrowFunction(n)||f.isFunctionExpression(n)?n:void 0}function ct(e){let n=de(e);if(!n)return{};let t=n.getParameters().map(r=>({name:r.getName(),type:r.getTypeNode()?.getText()??r.getType().getText(r),optional:r.isOptional()})),i=n.getReturnTypeNode()?.getText()??n.getReturnType().getText(n);return{parameters:t,returnType:i,async:n.hasModifier(S.AsyncKeyword),returnStatements:n.getDescendantsOfKind(S.ReturnStatement).length,throwStatements:n.getDescendantsOfKind(S.ThrowStatement).length,branches:n.getDescendantsOfKind(S.IfStatement).length+n.getDescendantsOfKind(S.SwitchStatement).length+n.getDescendantsOfKind(S.ConditionalExpression).length,loops:n.getDescendantsOfKind(S.ForStatement).length+n.getDescendantsOfKind(S.ForOfStatement).length+n.getDescendantsOfKind(S.ForInStatement).length+n.getDescendantsOfKind(S.WhileStatement).length+n.getDescendantsOfKind(S.DoStatement).length,catches:n.getDescendantsOfKind(S.CatchClause).length}}function Ln(e,n,t,i,r,s){let o=P(n,e.getFilePath());for(let a of e.getVariableDeclarations()){if(s.has(L(a)))continue;let d=a.getInitializer();if(!d)continue;let c=a.getName(),g=Dn(c,d);if(g){let R=k("prompt",`${o}:${c}:${a.getStartLineNumber()}`),_=[E(o,a.getStartLineNumber(),"name_heuristic","Prompt or instructions constant",.88,c,a.getEndLineNumber())],X={id:R,kind:"prompt",name:c,qualifiedName:`${o}#${c}`,description:M(g),language:A(o),metadata:{excerpt:g.slice(0,4e3),variables:Z(g)},evidence:_};i.push(X),r.push($(t,R,"contains",_)),s.set(L(a),{node:X,declaration:a});continue}let l=In(c,d,o);if(!l)continue;let m=a.getStartLineNumber(),h=k(l.kind,`${o}:${c}:${m}`),u=[E(o,m,l.method,l.detail,l.confidence,c,a.getEndLineNumber())],p=dt(d),y=p?z(p,"role"):void 0,b=p?z(p,"description")??z(p,"goal")??y:void 0,C=p?z(p,"instructions")??z(p,"systemPrompt")??z(p,"prompt"):void 0,w=p?z(p,"model"):void 0,v={id:h,kind:l.kind,name:p?z(p,"name")??c:c,qualifiedName:`${o}#${c}`,description:b??(C?M(C):void 0),language:A(o),metadata:{factory:l.factory,role:y,instructions:C?.slice(0,2e3),model:w,toolNames:p?nt(p,"tools"):[],taskNames:p?nt(p,"tasks"):[]},evidence:u};if(i.push(v),r.push($(t,h,"contains",u)),s.set(L(a),{node:v,declaration:a}),w){let R=k("model",w),_=[E(o,m,"framework_convention",`Configured model ${w}`,.94,c)];i.push({id:R,kind:"model",name:w,qualifiedName:`model:${w}`,language:A(o),metadata:{model:w},evidence:_}),r.push($(h,R,"requests",_,{label:"model"}))}if(C&&C.length>=24){let R=k("prompt",`${o}:${c}:inline-instructions`),_=[E(o,m,"framework_convention",`Inline instructions configured for ${c}`,.94,c)];i.push({id:R,kind:"prompt",name:`${c} instructions`,qualifiedName:`${o}#${c}:instructions`,description:M(C),language:A(o),metadata:{excerpt:C.slice(0,4e3),variables:Z(C)},evidence:_}),r.push($(h,R,"data_flow",_,{label:"instructions"}))}}}function In(e,n,t){let i=Tn(n),r=`${i} ${e}`.toLowerCase(),s=/stategraph|messagegraph|create(react)?agent|defineagent|new agent|agent\(|crew\(|crewai|task\(|tool\(|createtool|definetool|chatopenai|chatanthropic/.test(r),o=(a,d,c=s?.96:.82)=>({kind:a,factory:i,confidence:c,detail:d,method:s?"framework_convention":"name_heuristic"});if(/chatopenai|chatanthropic|azurechatopenai|generative(model|ai)|createmodel|language.?model/.test(r))return o("model",`Recognized model construction through ${i}`);if(/stategraph|messagegraph|workflow|orchestrator|pipeline|\bcrew\b/.test(r))return o("workflow",`Recognized workflow construction through ${i||e}`);if(/createtool|definetool|dynamicstructuredtool|\btool\b/.test(r))return o("tool",`Recognized tool construction through ${i||e}`);if(/human.?approval|human.?review|approval.?gate|confirm.?step|interruptbefore/.test(r))return o("human_gate",`Recognized human approval gate through ${i||e}`,.86);if(/create(react)?agent|defineagent|\bagent\b/.test(r))return o("agent",`Recognized Agent construction through ${i||e}`);if(/(^|\/)(agents?|crews?)\//i.test(t))return o("agent","Declared under an Agent directory",.72)}function Tn(e){return f.isCallExpression(e)||f.isNewExpression(e)?e.getExpression().getText():e.getKindName()}function dt(e){if(f.isObjectLiteralExpression(e))return e;if(f.isCallExpression(e)||f.isNewExpression(e))return e.getArguments().find(f.isObjectLiteralExpression)}function z(e,n){let t=e.getProperty(n);if(!t||!f.isPropertyAssignment(t))return;let i=t.getInitializer();if(i&&(f.isStringLiteral(i)||f.isNoSubstitutionTemplateLiteral(i)))return i.getLiteralText()}function nt(e,n){let t=e.getProperty(n);if(!t||!f.isPropertyAssignment(t))return[];let i=t.getInitializer();if(!i)return[];let r=f.isIdentifier(i)?[i]:i.getDescendantsOfKind(S.Identifier);return[...new Set(r.map(s=>s.getText()))]}function Dn(e,n){if(/(prompt|instructions?|system(message|text)?|persona)/i.test(e)){if(f.isStringLiteral(n)||f.isNoSubstitutionTemplateLiteral(n))return n.getLiteralText();if(f.isTemplateExpression(n))return n.getText().slice(1,-1)}}function jn(e,n,t,i,r){let s=P(n,e.getFilePath());for(let o of e.getVariableDeclarations()){let a=t.get(L(o)),d=o.getInitializer();if(!a||!d||!["agent","workflow","tool","human_gate"].includes(a.node.kind))continue;if(f.isArrayLiteralExpression(d)){for(let g of d.getElements()){if(!f.isIdentifier(g)&&!f.isPropertyAccessExpression(g))continue;let l=Q(g,t);if(!l||l.node.id===a.node.id||!q.has(l.node.kind))continue;let m=[E(s,g.getStartLineNumber(),"ast",`${a.node.name} lists ${l.node.name} as a step`,.8,o.getName())];r.push($(a.node.id,l.node.id,"calls",m,{label:"step",control:"sequential"}))}continue}let c=dt(d);if(c)for(let g of["tools","agents","tasks","handoffs","instructions","prompt","systemPrompt","model"]){let l=c.getProperty(g);if(!l||!f.isPropertyAssignment(l))continue;let m=l.getInitializer();if(!m)continue;let h=f.isIdentifier(m)?[m]:m.getDescendantsOfKind(S.Identifier);for(let u of h){let p=Q(u,t);if(!p||p.node.id===a.node.id)continue;let y=p.node.kind==="model"?"requests":p.node.kind==="prompt"?"data_flow":"calls",b=[E(s,l.getStartLineNumber(),"framework_convention",`${a.node.name} configures ${g} with ${p.node.name}`,.96,o.getName())];r.push($(a.node.id,p.node.id,y,b,{label:g,control:g==="handoffs"?"conditional":"sequential"}))}}}}function Fn(e,n,t,i,r){let s=P(n,e.getFilePath()),o=new Map,a=e.getDescendantsOfKind(S.CallExpression);for(let d of a){let c=d.getExpression();if(!f.isPropertyAccessExpression(c)||c.getName()!=="addNode")continue;let[g,l]=d.getArguments();if(!g||!f.isStringLiteral(g))continue;let m=g.getLiteralValue(),h=l&&f.isIdentifier(l)?D(l.getSymbol(),t):void 0,u=[E(s,d.getStartLineNumber(),"framework_convention",`Registers workflow node ${m}`,.98,m)],p=h?.node??Mn(m,s,d.getStartLineNumber(),u);h||i.push(p),!h&&l&&(f.isArrowFunction(l)||f.isFunctionExpression(l))&&t.set(L(l),{node:p,declaration:l}),p.metadata={...p.metadata,frameworkNodeName:m},o.set(m,p);let y=D(c.getExpression().getSymbol(),t);y&&y.node.id!==p.id&&r.push($(y.node.id,p.id,"calls",u,{label:"node",control:"sequential"}))}for(let d of a){let c=d.getExpression();if(!f.isPropertyAccessExpression(c))continue;let g=c.getName();if(!["addEdge","addConditionalEdges"].includes(g))continue;let l=D(c.getExpression().getSymbol(),t),[m,h,u]=d.getArguments(),p=it(m);if(!p)continue;let y=Gn(p)?l?.node:o.get(p);if(!y)continue;let b=it(h),C=g==="addConditionalEdges"?On(u):b?[b]:[];for(let w of C){if(Hn(w)){y.metadata={...y.metadata,terminal:!0,terminalReason:"workflow_end"};continue}let v=o.get(w);if(!v||y.id===v.id)continue;let R=g==="addConditionalEdges"?"conditional":"sequential",_=[E(s,d.getStartLineNumber(),"framework_convention",`${g} connects ${p} to ${w}`,.98,p)];r.push($(y.id,v.id,"calls",_,{label:g==="addConditionalEdges"?"branch":void 0,control:R}))}}}function Mn(e,n,t,i){let r=/(agent|research|writer|review|planner)/i.test(e)?"agent":"service";return{id:k(r,`${n}:framework-node:${e}:${t}`),kind:r,name:e,qualifiedName:`${n}#workflow:${e}`,language:A(n),metadata:{frameworkNodeName:e},evidence:i}}function On(e){return!e||!f.isObjectLiteralExpression(e)?[]:e.getProperties().flatMap(n=>{if(!f.isPropertyAssignment(n))return[];let t=n.getInitializer();return t&&f.isStringLiteral(t)?[t.getLiteralValue()]:[]})}function it(e){if(e)return f.isStringLiteral(e)?e.getLiteralValue():f.isIdentifier(e)?e.getText():void 0}function Gn(e){return["__start__","START","start"].includes(e)}function Hn(e){return["__end__","END","end"].includes(e)}function zn(e,n,t,i){let r=t.get(e.getFilePath());if(!r)return;let s=P(n,e.getFilePath());for(let o of e.getImportDeclarations()){let a=o.getModuleSpecifierSourceFile(),d=a?t.get(a.getFilePath()):void 0;if(!d)continue;let c=[E(s,o.getStartLineNumber(),"ast",`Imports ${o.getModuleSpecifierValue()}`,1)];i.push($(r,d,"imports",c))}}function Vn(e,n,t,i,r){let s=P(n,e.getFilePath());for(let o of e.getDescendantsOfKind(S.CallExpression)){let a=gt(o,t);if(!a)continue;let d=pt(o,t)??ii(o,t),c=o.getExpression().getText(),g=ui(o,c,i),l=d?.node.kind==="human_gate"?"human_approval":ri(o,c),m=oi(o,l),h=[E(s,o.getStartLineNumber(),"ast",`${l==="sequential"?"Calls":`${l} call to`} ${c}`,d||g?.96:.8)];d&&r.push($(a.node.id,d.node.id,"calls",h,{control:l,metadata:m})),d&&Kn(o,d,t,s,r),Zn(o,a,d,t,s,l,r),g&&r.push($(a.node.id,g.id,"requests",h,{control:l,metadata:m}));let u=fi(o,c);if(u){let y=k("external_api",u.key),b=[E(s,o.getStartLineNumber(),"name_heuristic",`Outbound request through ${c}`,u.confidence)];i.push({id:y,kind:"external_api",name:u.label,qualifiedName:u.key,language:A(s),metadata:u.metadata,evidence:b}),r.push($(a.node.id,y,"requests",b,{control:l,metadata:m}))}let p=mi(c);if(p){let y=k("database",p.key),b=[E(s,o.getStartLineNumber(),"name_heuristic",`Recognized database operation ${c}`,p.confidence)];i.push({id:y,kind:"database",name:p.label,qualifiedName:p.key,language:A(s),metadata:{operation:p.operation},evidence:b}),r.push($(a.node.id,y,p.edgeKind,b,{control:l,metadata:m}))}}}function Kn(e,n,t,i,r){for(let s of e.getArguments()){let o=f.isIdentifier(s)?[s]:s.getDescendantsOfKind(S.Identifier);for(let a of o)for(let d of a.getSymbol()?.getDeclarations()??[]){if(!f.isVariableDeclaration(d))continue;let c=d.getInitializer(),g=c&&f.isAwaitExpression(c)?c.getExpression():c;if(!g||!f.isCallExpression(g))continue;let l=pt(g,t);if(!l||l.node.id===n.node.id)continue;let m=[E(i,e.getStartLineNumber(),"ast",`${a.getText()} carries the result of ${l.node.name} into ${n.node.name}`,.97)];r.push($(l.node.id,n.node.id,"data_flow",m))}}}function qn(e,n,t,i,r,s){let o=P(n,e.getFilePath());for(let a of e.getDescendantsOfKind(S.CallExpression)){let d=De(a,t);if(!d)continue;let{method:c,owner:g,ownerKey:l,framework:m,confidence:h,evidenceMethod:u,detail:p}=d,y=a.getArguments()[0];if(!y||!f.isStringLiteral(y))continue;let b=a.getArguments().at(-1);if(c==="use"&&b&&f.isIdentifier(b))continue;let C=l?s.get(l):void 0,w=C?Wn(C,y.getLiteralValue()):y.getLiteralValue(),v=k("route",`${c}:${w}:${o}`),R=[E(o,a.getStartLineNumber(),u,C?`${p}, mounted under ${C}`:p,h)],_={id:v,kind:"route",name:`${c.toUpperCase()} ${w}`,qualifiedName:`${c}:${w}`,language:A(o),metadata:{method:c.toUpperCase(),path:w,framework:m,owner:g,mountedUnder:C},evidence:R};if(i.push(_),!!b){if(f.isArrowFunction(b)||f.isFunctionExpression(b)){t.set(L(b),{node:_,declaration:b});continue}if(f.isIdentifier(b)||f.isPropertyAccessExpression(b)){let X=D(b.getSymbol(),t);X&&r.push($(v,X.node.id,"handles",R))}}}}function De(e,n){let t=e.getExpression();if(!f.isPropertyAccessExpression(t))return;let i=t.getName().toLowerCase();if(!Sn.has(i))return;let r=e.getArguments()[0];if(!r||!f.isStringLiteral(r)||!r.getLiteralValue().startsWith("/"))return;let s=ut(t.getExpression(),n);return s?{...s,method:i}:void 0}function ut(e,n){if(f.isCallExpression(e)){let s=e.getExpression();return f.isPropertyAccessExpression(s)?ut(s.getExpression(),n):void 0}if(!f.isIdentifier(e))return;let t=e.getText();if(!/^(app|router|server|api)$/i.test(t)&&!/(router|app|server|routes)$/i.test(t))return Un(e,t);let i=je(e);if(i){let s=i.getInitializer(),o=s&&(f.isCallExpression(s)||f.isNewExpression(s))?s.getExpression().getText():void 0,a=o?st.find(d=>d.pattern.test(o)):void 0;if(a&&o)return{owner:t,ownerKey:L(i),framework:a.name,confidence:.96,evidenceMethod:"framework_convention",detail:`Route registered on a ${a.name} instance built by ${o}`}}let r=i?L(i):void 0;return/^(app|router|server|api)$/i.test(t)?{owner:t,ownerKey:r,framework:"hono_or_express",confidence:.94,evidenceMethod:"framework_convention",detail:`Recognized ${t}.* route registration`}:{owner:t,ownerKey:r,framework:"hono_or_express",confidence:.78,evidenceMethod:"name_heuristic",detail:`Route registered on ${t}, named as a router`}}function Q(e,n){let t=e.getParent();if(f.isShorthandPropertyAssignment(t)){let i=D(t.getValueSymbol(),n);if(i)return i}return D(e.getSymbol(),n)}function Un(e,n){let t=je(e),i=t?.getInitializer();if(!i||!f.isCallExpression(i)&&!f.isNewExpression(i))return;let r=i.getExpression().getText(),s=st.find(o=>o.pattern.test(r));if(!(!s||!t))return{owner:n,ownerKey:L(t),framework:s.name,confidence:.96,evidenceMethod:"framework_convention",detail:`Route registered on a ${s.name} instance built by ${r}`}}function je(e){let n=e.getSymbol();for(let t of[n,n?.getAliasedSymbol()].filter(i=>i!==void 0))for(let i of t.getDeclarations())if(f.isVariableDeclaration(i))return i}function Bn(e,n){let t=new Map;for(let i of e)for(let r of i.getDescendantsOfKind(S.CallExpression)){let s=De(r,n);if(!s||s.method!=="use")continue;let[o,a]=r.getArguments();if(!o||!f.isStringLiteral(o)||!a||!f.isIdentifier(a))continue;let d=je(a);d&&t.set(L(d),o.getLiteralValue())}return t}function Wn(e,n){let t=`${e.replace(/\/+$/,"")}/${n.replace(/^\/+/,"")}`.replace(/\/{2,}/g,"/");return t.length>1?t.replace(/\/$/,""):"/"}function Jn(e,n,t,i,r,s,o){let a=P(n,e.getFilePath()),d=(c,g,l,m=1)=>{if(s.has(L(c)))return;let h=c.getStartLineNumber(),u=Y(ft(a,g,c)),p=k(u.kind,`${a}:${g}:${h}`),y=[E(a,h,u.method,`${l}; ${u.detail.toLowerCase()}`,Math.min(u.confidence,m),g,c.getEndLineNumber())],b={id:p,kind:u.kind,name:g,qualifiedName:`${a}#${g}`,language:A(a),metadata:ct(c),evidence:y};i.push(b),r.push($(t,p,"contains",y)),s.set(L(c),{node:b,declaration:c})};for(let c of e.getVariableDeclarations()){let g=c.getInitializer();if(!g)continue;let l=c.getName();if(f.isObjectLiteralExpression(g)){for(let h of g.getProperties())f.isMethodDeclaration(h)?d(h,`${l}.${h.getName()}`,"Callable member of an object literal"):f.isPropertyAssignment(h)&&de(h)&&d(h,`${l}.${h.getName()}`,"Callable member of an object literal");continue}if(s.has(L(c))||!o.has(l))continue;let m=f.isAwaitExpression(g)?g.getExpression():g;f.isCallExpression(m)&&c.getType().getCallSignatures().length!==0&&d(c,l,`Callable produced by ${m.getExpression().getText()}`,.9)}for(let c of e.getExportAssignments())c.isExportEquals()||!de(c)||d(c,Yn(a),"Default-exported callable")}function Xn(e){let n=new Set;for(let t of e)for(let i of t.getDescendantsOfKind(S.CallExpression)){let r=i.getExpression();f.isIdentifier(r)?n.add(r.getText()):f.isPropertyAccessExpression(r)&&n.add(r.getName());for(let s of lt(i))n.add(f.isIdentifier(s)?s.getText():s.getName())}return n}function Yn(e){let n=j.basename(e).replace(/\.[cm]?[jt]sx?$/i,"");if(!/^(index|route)$/i.test(n))return n;let t=j.basename(j.dirname(e));return t&&t!=="."?`${t} ${n}`:n}function Zn(e,n,t,i,r,s,o){if(De(e,i))return;let a=e.getExpression().getText();for(let d of lt(e)){let c=Q(d,i);if(!c||c.node.id===n.node.id||c.node.id===t?.node.id)continue;let g=d.getStartLineNumber();if(q.has(c.node.kind)){let l=[E(r,g,"ast",`${c.node.name} is handed to ${a} as a callback`,.9)],m=c.node.kind==="human_gate"?"human_approval":ni(a,s);o.push($(n.node.id,c.node.id,"calls",l,{control:m}));continue}if(c.node.kind==="prompt"||c.node.kind==="model"){let l=[E(r,g,"ast",`${c.node.name} is passed into ${a}`,.94)];o.push($(c.node.id,n.node.id,"data_flow",l,{label:c.node.kind}))}}}var Qn=/^(generateText|streamText|generateObject|streamObject|embed|embedMany|create|complete|invoke)$/;function ei(e,n,t,i,r){let s=P(n,e.getFilePath());for(let o of e.getDescendantsOfKind(S.CallExpression)){let a=o.getExpression().getText();if(!Qn.test(a.split(".").at(-1)??""))continue;let d=o.getArguments().find(f.isObjectLiteralExpression);if(!d||!d.getProperty("model"))continue;let c=gt(o,t);if(!c)continue;let g=o.getStartLineNumber(),l=ti(d.getProperty("model"));if(l){let u=k("model",l.name),p=[E(s,g,"framework_convention",`${a} requests model ${l.name}`,.96,c.node.name)];i.push({id:u,kind:"model",name:l.name,qualifiedName:`model:${l.name}`,language:A(s),metadata:{model:l.name,provider:l.provider},evidence:p}),r.push($(c.node.id,u,"requests",p,{label:"model"}))}for(let u of["system","prompt","instructions","messages"]){let p=d.getProperty(u);if(!p||!f.isPropertyAssignment(p))continue;let y=p.getInitializer();if(y)for(let b of f.isIdentifier(y)?[y]:y.getDescendantsOfKind(S.Identifier)){let C=Q(b,t);if(C?.node.kind!=="prompt")continue;let w=[E(s,p.getStartLineNumber(),"framework_convention",`${c.node.name} sends ${C.node.name} as ${u}`,.96,c.node.name)];r.push($(C.node.id,c.node.id,"data_flow",w,{label:u}))}}let m=d.getProperty("tools");if(!m||!f.isPropertyAssignment(m))continue;let h=m.getInitializer();if(h)for(let u of h.getDescendantsOfKind(S.Identifier)){let p=Q(u,t);if(!p||p.node.id===c.node.id||!q.has(p.node.kind))continue;let y=[E(s,m.getStartLineNumber(),"framework_convention",`${c.node.name} offers ${p.node.name} as a tool to the model`,.94,c.node.name)];r.push($(c.node.id,p.node.id,"calls",y,{label:"tool",control:"conditional"}))}}}function ti(e){if(!e||!f.isPropertyAssignment(e))return;let n=e.getInitializer();if(n){if(f.isStringLiteral(n)||f.isNoSubstitutionTemplateLiteral(n))return{name:n.getLiteralText()};if(f.isCallExpression(n)){let t=n.getExpression().getText(),i=n.getArguments()[0];return i&&f.isStringLiteral(i)?{name:i.getLiteralValue(),provider:t}:{name:n.getText(),provider:t}}}}function lt(e){let n=[],t=i=>{(f.isIdentifier(i)||f.isPropertyAccessExpression(i))&&n.push(i)};for(let i of e.getArguments())f.isArrayLiteralExpression(i)?i.getElements().forEach(t):t(i);return n}function ni(e,n){if(/^promise\s*\.\s*(all|allsettled|race|any)$/i.test(e))return"parallel";let t=e.split(".").at(-1)?.toLowerCase()??"";return Nn.has(t)?"loop":t==="catch"?"fallback":n}function gt(e,n){let t=e;for(;t;){if(f.isFunctionDeclaration(t)||f.isMethodDeclaration(t)||f.isVariableDeclaration(t)||f.isPropertyAssignment(t)||f.isExportAssignment(t)||f.isArrowFunction(t)||f.isFunctionExpression(t)){let i=n.get(L(t));if(i)return i}t=t.getParent()}}function pt(e,n){let t=e.getExpression(),i=D(t.getSymbol(),n);if(i)return i;if(f.isPropertyAccessExpression(t))return D(t.getExpression().getSymbol(),n)}function ii(e,n){let t=e.getExpression().getText().toLowerCase();if(!/(^|\.)(run|runstreamed|invoke|execute)$/.test(t))return;let i=e.getArguments()[0];if(!i||!f.isIdentifier(i))return;let r=D(i.getSymbol(),n);return r&&["agent","workflow"].includes(r.node.kind)?r:void 0}function ri(e,n){if(/retry|backoff|withretry/i.test(n))return"retry";for(let t of e.getAncestors()){if(f.isFunctionDeclaration(t)||f.isMethodDeclaration(t)||f.isArrowFunction(t)||f.isFunctionExpression(t))break;if(f.isCallExpression(t)&&/^(Promise\.(all|allSettled|race|any)|parallel|all)$/.test(t.getExpression().getText()))return"parallel";if(f.isCatchClause(t))return"fallback";if(f.isForStatement(t)||f.isForOfStatement(t)||f.isForInStatement(t)||f.isWhileStatement(t)||f.isDoStatement(t))return/retry|attempt|backoff/i.test(t.getText().slice(0,240))?"retry":"loop";if(f.isIfStatement(t)||f.isSwitchStatement(t)||f.isConditionalExpression(t))return"conditional"}return"sequential"}function oi(e,n){if(n!=="retry")return;let t=[e.getText().slice(0,600)];for(let s of e.getAncestors())if(f.isFunctionDeclaration(s)||f.isMethodDeclaration(s)||f.isArrowFunction(s)||f.isFunctionExpression(s)||(t.push(s.getText().slice(0,600)),f.isForStatement(s)||f.isWhileStatement(s)||f.isDoStatement(s)))break;let i=t.join(" ");return{retryBounded:/max[A-Z_\s-]?(attempts?|retries)|retryLimit|attempt\s*[<>=!]+\s*\d+|retries\s*:\s*\d+|maxRetries\s*:\s*\d+/i.test(i)}}function D(e,n,t=0){if(!e||t>$n)return;let i=[e,e.getAliasedSymbol()].filter(r=>r!==void 0);for(let r of i.flatMap(s=>s.getDeclarations())){let s=n.get(L(r));if(s)return s;if(f.isBindingElement(r)){let o=si(r,n,t);if(o)return o}if(f.isPropertyAssignment(r)||f.isVariableDeclaration(r)){let o=r.getInitializer();if(o&&(f.isIdentifier(o)||f.isPropertyAccessExpression(o))){let a=D(o.getSymbol(),n,t+1);if(a)return a}}}}function si(e,n,t){let i=e.getParent();if(!f.isObjectBindingPattern(i))return;let r=i.getParent();if(!f.isVariableDeclaration(r))return;let s=r.getInitializer();if(!s)return;let o=e.getPropertyNameNode()?.getText()??e.getName();return D(s.getType().getProperty(o),n,t+1)}function ai(e){return e.getName()}function L(e){return`${e.getSourceFile().getFilePath()}:${e.getStart()}`}function ft(e,n,t){let i=f.isMethodDeclaration(t)?t:void 0,r=f.isFunctionDeclaration(t)||f.isMethodDeclaration(t)?t:f.isVariableDeclaration(t)||f.isPropertyAssignment(t)||f.isExportAssignment(t)?de(t):void 0;return{relativeFile:e,name:n,returnType:r?.getReturnTypeNode()?.getText(),internal:di(t),enclosingClass:i?ci(i):void 0,routeConvention:/\/app\/api\/.+\/route\.[jt]sx?$/.test(`/${e.toLowerCase()}`)&&tt.has(n.toUpperCase())}}function ci(e){let n=e.getParent();return f.isClassDeclaration(n)||f.isClassExpression(n)?n.getName()??"":""}function di(e){return f.isMethodDeclaration(e)?e.getName().startsWith("#")||e.getName().startsWith("_")?!0:e.hasModifier(S.PrivateKeyword)||e.hasModifier(S.ProtectedKeyword):!1}function ui(e,n,t){if(n!=="fetch")return;let[i,r]=e.getArguments();if(!i||!f.isStringLiteral(i))return;let s=i.getLiteralValue();if(!s.startsWith("/"))return;let o="GET";if(r&&f.isObjectLiteralExpression(r)){let a=r.getProperty("method");if(a&&f.isPropertyAssignment(a)){let d=a.getInitializer();d&&f.isStringLiteral(d)&&(o=d.getLiteralValue().toUpperCase())}}return t.find(a=>a.kind==="route"&&a.metadata?.path===s&&a.metadata?.method===o)}function li(e){let n=e.match(/(?:^|\/)app\/(api\/.+)\/route\.[jt]sx?$/);return n?`/${n[1]}`:e}function gi(e){return/(^|\/)(page|layout|route|index|main|server|app)\.[jt]sx?$/.test(e)||/(^|\/)pages\/api\//.test(e)}var pi=/^(fetch|nodeFetch|axios|got|ky|superagent|undici)(\.(get|post|put|patch|delete|head|request))?$/;function fi(e,n){let t=e.getArguments()[0];if(pi.test(n)){let r=n.split(".")[0],s=t&&f.isStringLiteral(t)?t.getLiteralValue():void 0;if(s&&/^https?:\/\//.test(s)){let o=yi(s);return{key:`http:${o}`,label:o,metadata:{provider:r,url:s},confidence:.92}}if(!s)return{key:`http:${r}`,label:`${Te(r)} request`,metadata:{provider:r,url:void 0},confidence:.68}}let i=[{pattern:/(^|\.)openai\.|\.responses\.create$|\.chat\.completions\.create$/,key:"sdk:openai",label:"OpenAI API"},{pattern:/(^|\.)anthropic\.|\.messages\.create$/,key:"sdk:anthropic",label:"Anthropic API"},{pattern:/(^|\.)stripe\./,key:"sdk:stripe",label:"Stripe API"}].find(r=>r.pattern.test(n.toLowerCase()));return i?{key:i.key,label:i.label,metadata:{provider:i.key.slice(4)},confidence:.9}:void 0}function mi(e){let n=e.split(".");if(n.length<2)return;let t=n.at(-1)??"",i=n[0]??"";if(!kn.has(t))return;let r=Rn.has(i.toLowerCase());if(!r&&!_n.test(i))return;let s=n.length>2?n.at(-2)??"data":"data",o=s==="data"?i:s,a=/^(find|select|query|aggregate)/.test(t);return{key:`${i.toLowerCase()}:${s}`,label:`${Te(o)} data`,operation:t,edgeKind:a?"reads":"writes",confidence:r?.88:.7}}async function hi(e,n){let t=new Set;try{let i=JSON.parse(await ot(j.join(e,"package.json"),"utf8")),r={...rt(i.dependencies),...rt(i.devDependencies)},s={next:"Next.js",react:"React",express:"Express",hono:"Hono","@nestjs/core":"NestJS","@langchain/langgraph":"LangGraph",langchain:"LangChain","@openai/agents":"OpenAI Agents SDK","@mastra/core":"Mastra",ai:"Vercel AI SDK",openai:"OpenAI SDK","@anthropic-ai/sdk":"Anthropic SDK","@temporalio/workflow":"Temporal",inngest:"Inngest"};for(let[o,a]of Object.entries(s))o in r&&t.add(a)}catch{}return n.some(i=>/(^|\/)app\/api\/.+\/route\.[jt]s$/.test(i))&&t.add("Next.js"),[...t]}async function wi(e){try{let n=JSON.parse(await ot(j.join(e,"package.json"),"utf8"));if(n.name)return n.name}catch{}return j.basename(e)}function yi(e){try{return new URL(e).hostname}catch{return e}}function rt(e){return e&&typeof e=="object"?e:{}}import{spawn as bi}from"child_process";import{readFile as mt}from"fs/promises";import B from"path";import{fileURLToPath as xi}from"url";var Ci=new Set([".py"]),vi=/(^test_.*\.py$|_test\.py$|^conftest\.py$|\.pyi$)/i,Ei=/^(app|router|api|server|[a-z_]*(?:router|app|api))\.(get|post|put|patch|delete|head|options)$/i,$i=/^(FastAPI|APIRouter|Flask|Blueprint|Quart|Starlette|Sanic)$/,Si=/(^|\.)((responses|chat\.completions|completions|messages|embeddings)\.create|generate_content|invoke|ainvoke)$/;async function ht(e,n={}){let t=B.resolve(e),i=[],r=await ce(t,Ci,vi),s=n.maxFiles??2e3,o=r.slice(0,s);r.length>s&&i.push({level:"warning",code:"FILE_LIMIT_REACHED",message:`Found ${r.length} Python files; only the first ${s} were analyzed.`});let a=[],d=[],c;o.length&&(c=await _i(o,n.pythonPath,i));let g=new Map;for(let l of c?.files??[]){if(l.error){i.push({level:"warning",code:"PYTHON_FILE_UNREADABLE",message:`${P(t,l.path)}: ${l.error}`});continue}ki(l,t,a,d,g)}for(let l of c?.files??[])l.error||Ri(l,t,a,d,g);return{schemaVersion:K,generatedAt:new Date().toISOString(),project:{name:B.basename(t),root:t,languages:o.length?["python"]:[],frameworks:await Hi(t,c),filesScanned:c?.files.filter(l=>!l.error).length??0},nodes:U(a),edges:U(d).filter(l=>l.source!==l.target),diagnostics:i}}function ki(e,n,t,i,r){let s=P(n,e.path),o=k("file",s),a=Gi(s),d=[E(s,1,"path_heuristic",a?"Framework entrypoint convention":"Source file discovered",a?.86:1)];t.push({id:o,kind:a?"entrypoint":"file",name:s,qualifiedName:s,language:"python",evidence:d});for(let c of e.classes){let g=k("class",`${s}:${c.name}:${c.line}`),l=[E(s,c.line,"ast","Class declaration",1,c.name,c.endLine)],m={id:g,kind:"class",name:c.name,qualifiedName:`${s}#${c.name}`,description:c.docstring?M(c.docstring):void 0,language:"python",metadata:{bases:c.bases},evidence:l};t.push(m),i.push($(o,g,"contains",l)),r.set(c.name,m)}for(let c of e.functions){let g=Ai(c.decorators,e),l=Y({relativeFile:s,name:c.name,internal:!!c.enclosingClass&&c.name.startsWith("_"),enclosingClass:c.enclosingClass??void 0,routeConvention:!!g,returnType:c.returns??void 0}),m=k(l.kind,`${s}:${c.name}:${c.line}`),h=[E(s,c.line,l.method,g?`${l.detail} via ${g.decorator}`:l.detail,l.confidence,c.name,c.endLine)],u={id:m,kind:l.kind,name:g?`${g.method} ${g.path}`:c.name,qualifiedName:`${s}#${c.name}`,description:c.docstring?M(c.docstring):void 0,language:"python",metadata:{...g?{method:g.method,path:g.path,framework:g.framework}:{},async:c.isAsync,parameters:c.parameters.filter(p=>p!=="self"&&p!=="cls"),returnType:c.returns??void 0,branches:c.branches,loops:c.loops,catches:c.catches},evidence:h};t.push(u),i.push($(o,m,"contains",h)),r.set(c.name,u)}for(let c of e.assignments){if(c.scope)continue;let g=Di(c.name,c.text);if(g){let C=k("prompt",`${s}:${c.name}:${c.line}`),w=[E(s,c.line,"name_heuristic","Prompt or instructions constant",.88,c.name,c.endLine)],v={id:C,kind:"prompt",name:c.name,qualifiedName:`${s}#${c.name}`,description:M(g),language:"python",metadata:{excerpt:g.slice(0,4e3),variables:Z(g)},evidence:w};t.push(v),i.push($(o,C,"contains",w)),r.set(c.name,v);continue}let l=Ii(c.name,c.factory);if(!l)continue;let m=k(l.kind,`${s}:${c.name}:${c.line}`),h=[E(s,c.line,l.method,l.detail,l.confidence,c.name,c.endLine)],u=c.options??{},p=O(u,"instructions")??O(u,"system_prompt")??O(u,"prompt"),y=O(u,"model"),b={id:m,kind:l.kind,name:O(u,"name")??c.name,qualifiedName:`${s}#${c.name}`,description:O(u,"description")??O(u,"goal")??(p?M(p):void 0),language:"python",metadata:{factory:c.factory??void 0,role:O(u,"role"),instructions:p?.slice(0,2e3),model:y,toolNames:ee(u,"tools"),taskNames:ee(u,"tasks")},evidence:h};t.push(b),i.push($(o,m,"contains",h)),r.set(c.name,b)}}function Ri(e,n,t,i,r){let s=P(n,e.path);for(let o of e.calls){let a=o.enclosingFunction?r.get(o.enclosingFunction):void 0;if(!a)continue;let d=Ti(o),c=[E(s,o.line,"ast",`Calls ${o.callee}`,.96,o.enclosingFunction??void 0)],g=Fe(r,o.callee);g&&g.id!==a.id&&(q.has(g.kind)?i.push($(a.id,g.id,"calls",c,{control:d})):(g.kind==="prompt"||g.kind==="model")&&i.push($(g.id,a.id,"data_flow",[E(s,o.line,"ast",`${g.name} is used by ${a.name}`,.92)],{label:g.kind})));for(let h of o.nameArguments){let u=Fe(r,h);if(!(!u||u.id===a.id||u.id===g?.id)){if(u.kind==="prompt"||u.kind==="model"){i.push($(u.id,a.id,"data_flow",[E(s,o.line,"ast",`${u.name} is passed into ${o.callee}`,.94)],{label:u.kind}));continue}i.push($(a.id,u.id,"calls",[E(s,o.line,"ast",`${u.name} is handed to ${o.callee} as a callback`,.9)],{control:d}))}}if(Si.test(o.callee)){let h=O(o.options,"model");if(h){let u=k("model",h),p=[E(s,o.line,"framework_convention",`${o.callee} requests model ${h}`,.96,o.enclosingFunction??void 0)];t.push({id:u,kind:"model",name:h,qualifiedName:`model:${h}`,language:"python",metadata:{model:h},evidence:p}),i.push($(a.id,u,"requests",p,{label:"model"}))}for(let u of ee(o.options,"input").concat(ee(o.options,"messages"),ee(o.options,"prompt"))){let p=Fe(r,u);p?.kind==="prompt"&&i.push($(p.id,a.id,"data_flow",[E(s,o.line,"framework_convention",`${a.name} sends ${p.name} to the model`,.96)],{label:"prompt"}))}}let l=Fi(o.callee);if(l){let h=k("database",l.key),u=[E(s,o.line,"name_heuristic",`Recognized database operation ${o.callee}`,.88)];t.push({id:h,kind:"database",name:l.label,qualifiedName:l.key,language:"python",metadata:{operation:l.operation},evidence:u}),i.push($(a.id,h,l.edgeKind,u,{control:d}))}let m=Mi(o);if(m){let h=k("external_api",m.key),u=[E(s,o.line,"name_heuristic",`Outbound request through ${o.callee}`,.9)];t.push({id:h,kind:"external_api",name:m.label,qualifiedName:m.key,language:"python",metadata:m.metadata,evidence:u}),i.push($(a.id,h,"requests",u,{control:d}))}}}async function _i(e,n,t){let i;try{i=await Pi()}catch(o){t.push({level:"warning",code:"PYTHON_EXTRACTOR_MISSING",message:o instanceof Error?o.message:String(o)});return}let r=n?[n]:["python3","python"],s="";for(let o of r)try{return await Ni(o,i,e)}catch(a){s=a instanceof Error?a.message:String(a)}t.push({level:"warning",code:"PYTHON_UNAVAILABLE",message:`Python source was found but no interpreter could analyze it (${s}). Install Python 3 or pass a path to analyze these files.`})}function Ni(e,n,t){return new Promise((i,r)=>{let s=bi(e,["-c",n],{stdio:["pipe","pipe","pipe"]}),o="",a="";s.stdout.setEncoding("utf8"),s.stdout.on("data",d=>{o+=d}),s.stderr.setEncoding("utf8"),s.stderr.on("data",d=>{a+=d}),s.on("error",d=>r(new Error(`${e}: ${d.message}`))),s.on("close",d=>{if(d!==0){r(new Error(`${e} exited with ${d}: ${a.trim().slice(0,200)}`));return}try{i(JSON.parse(o))}catch{r(new Error(`${e} returned output that was not valid JSON`))}}),s.stdin.end(JSON.stringify(t))})}async function Pi(){let e=B.dirname(xi(import.meta.url)),n=[B.join(e,"..","scripts","extract.py"),B.join(e,"python","extract.py")];for(let t of n)try{return await mt(t,"utf8")}catch{}throw new Error("the bundled Python extractor is missing from this installation")}function Ai(e,n){for(let t of e){let i=Ei.exec(t);if(!i)continue;let r=i[1],s=i[2].toUpperCase(),a=n.calls.find(d=>d.callee===t&&d.stringArguments.length)?.stringArguments[0]??"/";return{method:s,path:a,framework:Li(r,n),decorator:t}}}function Li(e,n){let t=n.assignments.find(i=>i.name===e&&i.factory&&$i.test(i.factory));return t?.factory?t.factory==="Flask"||t.factory==="Blueprint"?"flask":t.factory.toLowerCase():"python_http"}function Ii(e,n){let t=`${n??""} ${e}`.toLowerCase(),i=/stategraph|messagegraph|create_react_agent|createagent|\bagent\(|\bcrew\(|crewai|\btask\(|\btool\(|chatopenai|chatanthropic|assistant/.test(t),r=(s,o,a=i?.96:.82)=>({kind:s,confidence:a,detail:o,method:i?"framework_convention":"name_heuristic"});if(/chatopenai|chatanthropic|azurechatopenai|generativemodel|language_?model/.test(t))return r("model",`Recognized model construction through ${n}`);if(/stategraph|messagegraph|workflow|orchestrator|pipeline|\bcrew\b/.test(t))return r("workflow",`Recognized workflow construction through ${n??e}`);if(/structuredtool|\btool\b/.test(t))return r("tool",`Recognized tool construction through ${n??e}`);if(/human_?approval|human_?review|approval_?gate|interrupt_before/.test(t))return r("human_gate",`Recognized human approval gate through ${n??e}`,.86);if(/create_react_agent|createagent|\bagent\b/.test(t))return r("agent",`Recognized Agent construction through ${n??e}`)}function Ti(e){return/retry|backoff/i.test(e.callee)?"retry":"sequential"}function Di(e,n){if(!(!n||n.length<24))return/prompt|instruction|system|template|persona/i.test(e)?n:void 0}function O(e,n){let t=e?.[n];return t?.kind==="string"?t.value:void 0}function ee(e,n){let t=e?.[n];return t?.kind==="names"?t.value:[]}function ji(e){return e.split(".").at(-1)??e}function Fe(e,n){let t=n.split(".");return e.get(n)??e.get(t.at(-1)??n)??e.get(t[0]??n)}function Fi(e){let n=ji(e).toLowerCase(),t=["all","filter","first","get","query","scalar","select","fetchall","fetchone","find","find_one"],i=["add","bulk_save_objects","commit","create","delete","insert","save","update","upsert","insert_one","update_one"];if(!t.includes(n)&&!i.includes(n))return;let r=e.split(".").slice(0,-1).join(".")||"database";if(/session|db|database|repo|repository|table|collection|cursor|conn/i.test(r))return{key:`db:${r}`,label:`${r} data`,operation:n,edgeKind:i.includes(n)?"writes":"reads"}}function Mi(e){if(!/^(requests|httpx|aiohttp|urllib\.request)\.[a-z]+$/i.test(e.callee))return;let n=e.stringArguments.find(i=>/^https?:\/\//.test(i)),t=n?Oi(n):e.callee.split(".")[0];return{key:`http:${t}`,label:t,metadata:{host:t,url:n,client:e.callee.split(".")[0]}}}function Oi(e){try{return new URL(e).hostname}catch{return e}}function Gi(e){return/(^|\/)(main|app|__main__|server|asgi|wsgi|manage)\.py$/i.test(e)}async function Hi(e,n){let t=new Set,i={fastapi:"FastAPI",flask:"Flask",django:"Django",starlette:"Starlette",langgraph:"LangGraph",langchain:"LangChain",crewai:"CrewAI",llama_index:"LlamaIndex",autogen:"AutoGen",openai:"OpenAI SDK",anthropic:"Anthropic SDK",pydantic_ai:"Pydantic AI"};for(let r of n?.files??[])for(let s of r.imports??[]){let o=s.module.split(".")[0]?.toLowerCase()??"",a=i[o];a&&t.add(a)}for(let r of["requirements.txt","pyproject.toml"])try{let s=(await mt(B.join(e,r),"utf8")).toLowerCase();for(let[o,a]of Object.entries(i))(s.includes(o.replace("_","-"))||s.includes(o))&&t.add(a)}catch{}return[...t]}import{createHash as ir}from"crypto";import{createHash as zi}from"crypto";var bt=new Set(["data","external_system","model"]),ue=120,Ge=12,Oe=48;function He(e,n,t=[]){let i=new Map(e.map(l=>[l.id,l])),r=le(n),s=er(n),o=e.filter(l=>l.type==="user_action"),a=new Set(o.flatMap(l=>[...xt(l.id,r)])),d=e.filter(l=>l.type==="entrypoint"&&!a.has(l.id)),c=e.filter(l=>["ai_process","process"].includes(l.type)&&(s.get(l.id)?.length??0)===0&&(r.get(l.id)?.length??0)>0);return nr([...o,...d,...o.length||d.length?[]:c]).map(l=>Vi(l,n,i,r,t)).sort((l,m)=>yt(m.health)-yt(l.health)||l.label.localeCompare(m.label))}function Vi(e,n,t,i,r){let s=xt(e.id,i),o=[...s].slice(0,ue),a=new Set(o),d=n.filter(w=>a.has(w.source)&&a.has(w.target)),c=o.flatMap(w=>t.get(w)?[t.get(w)]:[]),g=c.filter(w=>!d.some(v=>v.source===w.id)),l=Xi(e.id,a,d,t),m=Bi(e,c,d,n,t,s.size,l.truncated),h=Wi(e.id,c,d,l,t),u=Zi(e.id,i,t),p=qi(c,r),y=c.length?F(Math.min(...c.map(w=>w.confidence))):e.confidence,b=tr(m),C=p?.capability.label??u?.label??e.label;return{id:`feature_${I(`${e.id}:${C}`)}`,label:C,description:p?.capability.description??`Simulates the code-backed execution chain that starts at ${C}.`,entryNodeIds:[e.id],resultNodeIds:g.map(w=>w.id),nodeIds:o,edgeIds:d.map(w=>w.id),variants:h,diagnostics:m,health:b,confidence:y,product:Ki(p)}}function Ki(e){if(e)return{capabilityId:e.capability.id,label:e.capability.label,origin:e.capability.origin,sources:e.capability.sources,match:F(Math.min(.95,.35+Math.min(e.score,24)*.025)*e.capability.confidence),matchedOn:e.matchedOn,matchedTerms:e.matchedTerms}}function qi(e,n){let t=Me(e.map(o=>`${o.label} ${o.metadata?.rawName??""}`).join(" ")),i=Me(e.filter(o=>o.type==="entrypoint"||o.type==="user_action").map(o=>`${o.label} ${o.metadata?.rawName??""}`).join(" ")),r=new Map;for(let o of e){let a=typeof o.metadata?.documentedCapabilityId=="string"?o.metadata.documentedCapabilityId:void 0;a&&r.set(a,(r.get(a)??0)+1)}let s;for(let o of n){let a=Me(`${o.label} ${o.keywords.join(" ")}`),d=[...a].filter(l=>i.has(l)).length,c=[...a].filter(l=>t.has(l)).length,g=d*8+c+(r.get(o.id)??0)*.5;g>0&&(!s||g>s.score||g===s.score&&o.confidence>s.capability.confidence)&&(s={capability:o,score:g,matchedOn:d>0?"entry_terms":"step_terms",matchedTerms:[...a].filter(l=>i.has(l)||t.has(l)).slice(0,4)})}return s}function Me(e){let n=e.toLowerCase().match(/[a-z][a-z0-9-]{2,}|[\u3400-\u9fff]{2,8}/g)??[];return new Set(n.map(t=>Ui(t).replace(/^(post|get|put|patch|delete)$/,"")).filter(t=>t.length>=3))}function Ui(e){return/(ations?|tion)$/.test(e)?e.replace(/ations?$/,"ate").replace(/tion$/,"te"):e.replace(/(ing|ed|es|s)$/i,"")}function Bi(e,n,t,i,r,s,o){let a=[],d=new Set(n.map(u=>u.id)),c=i.filter(u=>d.has(u.source)&&(!r.has(u.source)||!r.has(u.target)));for(let u of c)a.push({id:`diagnostic_${I(`broken:${u.id}`)}`,code:"CHAIN_BROKEN_REFERENCE",severity:"error",message:"The chain references a logic node that does not exist in the graph.",suggestion:"Check the unresolved call, import, or generated edge at this point.",edgeId:u.id,nodeId:u.source,sources:r.get(u.source)?.sources??[],confidence:1});t.length===0&&a.push({id:`diagnostic_${I(`downstream:${e.id}`)}`,code:"CHAIN_NO_DOWNSTREAM",severity:"error",message:"The feature entry has no resolvable downstream execution step.",suggestion:"Check whether the entry calls a workflow, agent, service, or tool that the analyzer can resolve.",nodeId:e.id,sources:e.sources,confidence:1});let g=Qi(n,t),l=n.filter(u=>!t.some(p=>p.source===u.id)).length;g&&a.push({id:`diagnostic_${I(`cycle:${g.id}`)}`,code:"CHAIN_CYCLE",severity:l===0?"error":"warning",message:l===0?"The feature chain contains a cycle with no resolvable exit.":"The feature chain contains a cycle; verify that its runtime exit condition is intentional.",suggestion:"Inspect the loop guard or add an explicit terminal path.",nodeId:g.id,sources:g.sources,confidence:l===0?.95:.75}),n.length>1&&l===0&&a.push({id:`diagnostic_${I(`result:${e.id}`)}`,code:"CHAIN_NO_RESULT",severity:"error",message:"The analyzer could not find a terminal result for this feature.",suggestion:"Add or expose a return, persistence, response, or handoff that completes the chain.",nodeId:e.id,sources:e.sources,confidence:.9});let m=n.filter(u=>u.confidence<.6);for(let u of m.slice(0,6))a.push({id:`diagnostic_${I(`confidence:${u.id}`)}`,code:"CHAIN_LOW_CONFIDENCE",severity:"warning",message:`The step \u201C${u.label}\u201D is inferred with ${Math.round(u.confidence*100)}% confidence.`,suggestion:"Confirm the call relationship or add a clearer workflow, agent, tool, or service name.",nodeId:u.id,sources:u.sources,confidence:u.confidence});for(let u of t.filter(p=>p.control==="retry"&&p.metadata?.retryBounded!==!0)){let p=r.get(u.source);a.push({id:`diagnostic_${I(`retry:${u.id}`)}`,code:"CHAIN_RETRY_WITHOUT_LIMIT",severity:"warning",message:"A retry path was detected without a statically resolvable attempt limit.",suggestion:"Set a maximum retry count, backoff policy, and explicit failure exit.",nodeId:u.source,edgeId:u.id,sources:p?.sources??[],confidence:.82})}let h=le(t);for(let u of n.filter(p=>p.type==="external_system")){let p=t.filter(b=>b.target===u.id).flatMap(b=>r.get(b.source)??[]),y=p.some(b=>Number(b.metadata?.catches??0)>0||(h.get(b.id)??[]).some(C=>C.control==="fallback"));p.length&&!y&&a.push({id:`diagnostic_${I(`fallback:${u.id}`)}`,code:"CHAIN_EXTERNAL_NO_FALLBACK",severity:"info",message:`The external call to ${u.label} has no statically resolvable fallback path.`,suggestion:"Add error handling, a bounded retry, or a degraded response for this dependency.",nodeId:u.id,sources:u.sources,confidence:.72})}for(let u of n.filter(p=>p.type==="ai_process")){let p=(h.get(u.id)??[]).filter(b=>{let C=r.get(b.target);return C&&!["data","external_system","model"].includes(C.type)}),y=typeof u.metadata?.returnType=="string"?u.metadata.returnType:"";!p.length&&/(^|<)(void|undefined)(>|$)/i.test(y)&&u.metadata?.terminal!==!0&&a.push({id:`diagnostic_${I(`agent-output:${u.id}`)}`,code:"CHAIN_AGENT_NO_OUTPUT",severity:"warning",message:`The Agent step \u201C${u.label}\u201D has no structured output or downstream handoff.`,suggestion:"Declare an output type or schema, persist a result, or connect the Agent to its next step.",nodeId:u.id,sources:u.sources,confidence:.86})}return(s>ue||o)&&a.push({id:`diagnostic_${I(`limit:${e.id}`)}`,code:"CHAIN_PATH_LIMIT",severity:"warning",message:o?`The feature has more than ${Ge} branches or exceeds ${Oe} steps; simulation uses a bounded path set.`:`The feature reaches ${s} nodes; simulation is limited to ${ue}.`,suggestion:"Increase graph compression or split the feature into explicit workflows.",nodeId:e.id,sources:e.sources,confidence:1}),a}function Wi(e,n,t,i,r){let s=n.map(d=>d.id),o=wt(`variant_${I(`${e}:all`)}`,i.paths.length>1?"All paths":"Default path",i.paths.length>1?"Checks every inferred branch in the feature.":"Checks the inferred execution path.",e,s,t.map(d=>d.id),t,r);if(i.paths.length<=1)return[o];let a=i.paths.slice(0,Ge).map((d,c)=>{let g=Yi(d.nodeIds,t,r),l=new Set(g),m=t.filter(u=>l.has(u.source)&&l.has(u.target)).map(u=>u.id),h=r.get(d.nodeIds.at(-1)??"");return wt(`variant_${I(`${e}:${d.edgeIds.join(":")}`)}`,`Path ${c+1}${h?` \xB7 ${h.label}`:""}`,`Checks the branch that reaches ${h?.label??"its terminal step"}.`,e,g,m,t,r)});return[o,...a]}function wt(e,n,t,i,r,s,o,a){let d=new Set(r),c=o.filter(u=>s.includes(u.id)),g=Ji(i,d,c),l=[...d].map(u=>a.get(u)).find(u=>u?.type==="result")??[...d].map(u=>a.get(u)).find(u=>u&&!c.some(p=>p.source===u.id)),m=[...d].flatMap(u=>a.get(u)?[a.get(u).confidence]:[]),h=m.length?F(Math.min(...m)):0;return{id:e,label:n,description:t,nodeIds:[...d],edgeIds:s,steps:g,resultNodeId:l?.id,confidence:h}}function Ji(e,n,t){let i=new Map([[e,0]]),r=[e];for(;r.length;){let o=r.shift();if(!o)continue;let a=i.get(o)??0;for(let d of t.filter(c=>c.source===o)){if(!n.has(d.target))continue;let c=a+1;(!i.has(d.target)||c<i.get(d.target))&&(i.set(d.target,c),r.push(d.target))}}let s=Math.max(0,...i.values());return Array.from({length:s+1},(o,a)=>{let d=[...n].filter(c=>i.get(c)===a);return{order:a,nodeIds:d,incomingEdgeIds:t.filter(c=>d.includes(c.target)&&i.has(c.source)).map(c=>c.id)}}).filter(o=>o.nodeIds.length>0)}function Xi(e,n,t,i){let r=[],s=!1,o=t.filter(c=>{let g=i.get(c.target);return g&&!bt.has(g.type)}),a=le(o);function d(c,g,l,m){if(r.length>=Ge){s=!0;return}let h=(a.get(c)??[]).filter(u=>n.has(u.target)&&!m.has(u.target));if(!h.length||g.length>=Oe){r.push({nodeIds:g,edgeIds:l}),g.length>=Oe&&(s=!0);return}for(let u of h)d(u.target,[...g,u.target],[...l,u.id],new Set([...m,u.target]))}return d(e,[e],[],new Set([e])),{paths:r.length?r:[{nodeIds:[e],edgeIds:[]}],truncated:s}}function Yi(e,n,t){let i=new Set(e);for(let r of n){let s=t.get(r.target);i.has(r.source)&&s&&bt.has(s.type)&&i.add(s.id)}return[...i]}function Zi(e,n,t){let i=[e],r=new Set;for(;i.length;){let s=i.shift();if(!s||r.has(s))continue;r.add(s);let o=t.get(s);if(o?.type==="entrypoint")return o;i.push(...(n.get(s)??[]).map(a=>a.target))}}function xt(e,n){let t=new Set,i=[e];for(;i.length&&t.size<ue+1;){let r=i.shift();!r||t.has(r)||(t.add(r),i.push(...(n.get(r)??[]).map(s=>s.target)))}return t}function Qi(e,n){let t=new Map(e.map(a=>[a.id,a])),i=le(n),r=new Set,s=new Set;function o(a){if(r.has(a))return t.get(a);if(!s.has(a)){r.add(a);for(let d of i.get(a)??[]){let c=o(d.target);if(c)return c}r.delete(a),s.add(a)}}for(let a of e){let d=o(a.id);if(d)return d}}function le(e){let n=new Map;for(let t of e)n.set(t.source,[...n.get(t.source)??[],t]);return n}function er(e){let n=new Map;for(let t of e)n.set(t.target,[...n.get(t.target)??[],t]);return n}function tr(e){return e.some(n=>n.severity==="error")?"error":e.some(n=>n.severity==="warning")?"warning":"healthy"}function yt(e){return e==="error"?2:e==="warning"?1:0}function nr(e){let n=new Set;return e.filter(t=>!n.has(t.id)&&!!n.add(t.id))}function I(e){return zi("sha1").update(e).digest("hex").slice(0,12)}var Ct=new Set(["calls","data_flow","handles","reads","writes","requests"]);function vt(e,n={}){let t=Math.max(4,n.maxNodes??40),i=[...e.diagnostics],r=ar(e.edges),s=e.nodes.filter(u=>sr(u,r.get(u.id)??0)),o=cr(s,r),a=o.slice(0,t),d=new Set(a.map(u=>u.id));o.length>a.length&&i.push({level:"info",code:"LOGIC_GRAPH_COMPRESSED",message:`Compressed ${o.length} business-relevant code nodes to the ${a.length} highest-signal logic nodes.`});let c=a.map(u=>dr(u,e.context?.capabilityHints??[])),g=new Map(c.map(u=>[u.rawNodeIds[0],u.id])),l=Sr(wr(e,d,g),c);kr(c,l),pr(c,l);let m=He(c,l,e.context?.capabilityHints??[]),h=n.graphType??"runtime_logic";return h==="product_logic"&&i.push({level:"info",code:"PRODUCT_LOGIC_CONTEXTUAL_INFERENCE",message:"Product logic combines code structure with README, docs, PRD, prompt, and configuration evidence when available; uncertain matches retain confidence scores."}),{schemaVersion:K,generatedAt:new Date().toISOString(),graphType:h,title:`${e.project.name} ${h==="runtime_logic"?"runtime logic":"product logic"}`,description:n.productDescription??e.context?.description??e.context?.documents.find(u=>u.kind==="readme")?.summary??(h==="runtime_logic"?"A static, evidence-backed view of how work flows through the codebase.":"A code-informed view of how user actions become product value."),project:e.project,understanding:Cr(e,c,n.productDescription),nodes:c,edges:l,features:m,diagnostics:i}}var rr=/^(assert|audit|cap|clamp|clone|debug|dedupe|ensure|equals|error|format|from|get|has|hash|id|is|log|map|merge|noop|normali[sz]e|now|parse|pick|print|require|serialize|set|sleep|sort|to|trace|trim|truncate|unique|validate|warn|wrap)([A-Z_]|$)/;function or(e){let n=e&&`${e[0].toLowerCase()}${e.slice(1)}`;return rr.test(n)}function sr(e,n){return e.kind==="route"||e.kind==="database"||e.kind==="external_api"?!0:["service","agent","workflow","tool","human_gate"].includes(e.kind)?n===0&&ge(e)<=.5?!1:n>0||!or(e.name):e.kind==="function"?/^(handle|on)(submit|click|upload|save|create|generate)|submit|upload/i.test(e.name):["model","prompt"].includes(e.kind)?n>0:!1}function ar(e){let n=new Map;for(let t of e)Ct.has(t.kind)&&(n.set(t.source,(n.get(t.source)??0)+1),n.set(t.target,(n.get(t.target)??0)+1));return n}function cr(e,n){let t={route:100,agent:95,workflow:98,tool:85,model:81,prompt:64,human_gate:92,database:82,external_api:80,service:75,function:60,entrypoint:30,class:20,file:0};return[...e].sort((i,r)=>{let s=t[i.kind]+(n.get(i.id)??0)*4+ge(i)*20;return t[r.kind]+(n.get(r.id)??0)*4+ge(r)*20-s||i.name.localeCompare(r.name)})}function dr(e,n){let t=ur(e),i=ge(e),r=e.evidence.some(a=>a.method.includes("heuristic")||a.method==="framework_convention"),s=Er(`${e.name} ${e.qualifiedName??""} ${e.description??""}`,n),o=$r(s);return{id:`logic_${e.id}`,type:t,label:lr(e),description:hr(e,t),sources:_r(e.evidence.map(a=>a.source)),confidence:F(i),inference:{method:r?"heuristic":"deterministic",explanation:e.evidence.map(a=>a.detail).join("; ")},rawNodeIds:[e.id],product:o,metadata:{rawKind:e.kind,rawName:e.name,documentedCapabilityId:s?.capability.id,documentedCapabilityLabel:s?.capability.label,generatedDescription:!e.description,...e.metadata}}}function ur(e){return e.kind==="function"&&/submit|click|upload/i.test(e.name)?"user_action":e.kind==="route"?"entrypoint":e.kind==="workflow"?"workflow":e.kind==="agent"?"ai_process":e.kind==="tool"?"tool":e.kind==="model"?"model":e.kind==="human_gate"?"human_gate":e.kind==="prompt"||e.kind==="database"?"data":e.kind==="external_api"?"external_system":"process"}function lr(e){if(e.kind==="route"){let n=typeof e.metadata?.method=="string"?e.metadata.method:void 0,t=typeof e.metadata?.path=="string"?e.metadata.path:void 0;if(n&&t)return`${n.toUpperCase()} ${t}`}return e.kind==="external_api"?e.name:Rr(pe(e.name).replace(/\b(agent|service|handler|controller|workflow|orchestrator)\b/gi,"").trim()||pe(e.name))}var gr=4;function pr(e,n){let t=new Map(e.map(i=>[i.id,i]));for(let i of e){let r={calls:[],branches:[],requests:[],data:[],feeds:[]};for(let o of n){if(o.source!==i.id)continue;let a=t.get(o.target);a&&(a.type==="model"||a.type==="external_system"?te(r.requests,a.id):a.type==="data"?te(r.data,a.id):o.control==="conditional"||o.control==="fallback"?te(r.branches,a.id):o.type==="data_flow"?te(r.feeds,a.id):te(r.calls,a.id))}if(i.behavior=r,i.metadata?.generatedDescription!==!0)continue;let s=fr(r,o=>t.get(o)?.label??o);s&&(i.description=s)}}function te(e,n){e.includes(n)||e.push(n)}function fr(e,n){let t=(a,d)=>mr(a.map(n),d),i=[e.calls.length?`calls ${t(e.calls,"and")}`:void 0,e.branches.length?`branches to ${t(e.branches,"or")}`:void 0,e.requests.length?`requests ${t(e.requests,"and")}`:void 0,e.data.length?`reads or writes ${t(e.data,"and")}`:void 0,e.feeds.length?`passes its result to ${t(e.feeds,"and")}`:void 0].filter(a=>!!a);if(!i.length)return;let[r,...s]=i,o=r.charAt(0).toUpperCase()+r.slice(1);return s.length?`${[o,...s.slice(0,-1)].join(", ")}, and ${s.at(-1)}.`:`${o}.`}function mr(e,n){let t=e.slice(0,gr),i=e.length>t.length?` and ${e.length-t.length} more`:"";return t.length===1?`${t[0]}${i}`:t.length===2&&!i?`${t[0]} ${n} ${t[1]}`:`${t.slice(0,-1).join(", ")}, ${n} ${t.at(-1)}${i}`}function hr(e,n){if(e.description)return e.description;let t=pe(e.name).replace(/\b(agent|service|handler|controller)\b/gi,"").replace(/\s+/g," ").trim().toLowerCase();return{user_action:`The user initiates ${t}.`,entrypoint:`The system receives work through ${e.name}.`,process:`The system runs ${t}.`,workflow:`The workflow coordinates ${t}.`,ai_process:`An AI workflow performs ${t}.`,tool:`An Agent uses the tool ${t}.`,model:`The Agent uses the model ${e.name}.`,human_gate:`A person reviews or approves ${t}.`,decision:`The system evaluates ${t}.`,data:`The system reads or changes ${t}.`,external_system:`The flow communicates with ${e.name}.`,result:`The flow produces ${t}.`}[n]}function wr(e,n,t){let i=new Map;for(let s of e.edges){if(!Ct.has(s.kind))continue;let o=i.get(s.source)??[];o.push(s),i.set(s.source,o)}let r=[];for(let s of n){let o=[...i.get(s)??[]].map(d=>({nodeId:d.target,path:[d]})),a=new Set;for(;o.length;){let d=o.shift();if(!(!d||a.has(d.nodeId))){if(a.add(d.nodeId),n.has(d.nodeId)){let c=t.get(s),g=t.get(d.nodeId);c&&g&&c!==g&&r.push(yr(c,g,d.path));continue}if(!(d.path.length>=8))for(let c of i.get(d.nodeId)??[])o.push({nodeId:c.target,path:[...d.path,c]})}}}return Nr(r)}function yr(e,n,t){let i=new Set(t.map(o=>o.kind)),r=br(t.map(o=>o.control)),s=i.has("data_flow")||i.has("reads")||i.has("writes")?"data_flow":r==="conditional"||r==="fallback"||r==="human_approval"?"branch":"flow";return{id:`logic_edge_${Pr(`${e}:${s}:${r??"sequential"}:${n}`)}`,source:e,target:n,type:s,label:t.find(o=>o.label)?.label??xr(r),control:r,metadata:r?{retryBounded:r==="retry"?t.some(o=>o.metadata?.retryBounded===!0):void 0,rawControls:[...new Set(t.flatMap(o=>o.control?[o.control]:[]))]}:void 0,confidence:F(Math.min(...t.flatMap(o=>o.evidence.map(a=>a.confidence)))),rawEdgeIds:t.map(o=>o.id)}}function br(e){return["human_approval","fallback","retry","loop","parallel","conditional","sequential"].find(t=>e.includes(t))}function xr(e){return e&&e!=="sequential"?e.replace("_"," "):void 0}function Cr(e,n,t){let i=e.context,r=t??i?.description??i?.documents.find(a=>a.kind==="readme")?.summary??`An evidence-backed understanding of ${e.project.name}.`,s=i?.capabilityHints??[],o=s.length?Math.min(1,s.reduce((a,d)=>a+d.confidence,0)/s.length):i?.documents.length?.7:.55;return{summary:r,capabilities:s,agentNodeIds:n.filter(a=>a.type==="ai_process").map(a=>a.id),workflowNodeIds:n.filter(a=>a.type==="workflow").map(a=>a.id),toolNodeIds:n.filter(a=>a.type==="tool").map(a=>a.id),modelNodeIds:n.filter(a=>a.type==="model").map(a=>a.id),documentsUsed:i?.documents.map(a=>a.path)??[],confidence:F(o)}}var vr=2;function Er(e,n){let t=ze(e),i;for(let r of n){let s=ze(r.label),o=r.keywords.filter(c=>t.includes(ze(c))),a=s.length>=3&&t.includes(s)?3:0,d=a+o.length;d>0&&(!i||d>i.score||d===i.score&&r.confidence>i.capability.confidence)&&(i={capability:r,score:d,matchedOn:a?"documented_name":"documented_terms",matchedTerms:a?[r.label]:o.slice(0,4)})}return i}function $r(e){if(!(!e||e.score<vr))return{capabilityId:e.capability.id,label:e.capability.label,origin:e.capability.origin,sources:e.capability.sources,match:F(Math.min(.95,.4+e.score*.15)*e.capability.confidence),matchedOn:e.matchedOn,matchedTerms:e.matchedTerms}}function ze(e){return pe(e).toLowerCase().replace(/\b(agent|api|handler|route|service|workflow)\b/g," ").replace(/\s+/g," ").trim()}function Sr(e,n){let t=new Map(n.map(i=>[i.id,i.type]));return e.filter(i=>{if(i.type!=="flow"||["external_system","data"].includes(t.get(i.target)??""))return!0;let r=new Map;for(let a of e){if(a.id===i.id)continue;let d=r.get(a.source)??[];d.push(a.target),r.set(a.source,d)}let s=[...r.get(i.source)??[]],o=new Set;for(;s.length;){let a=s.shift();if(!(!a||o.has(a))){if(a===i.target)return!1;o.add(a),s.push(...r.get(a)??[])}}return!0})}function kr(e,n){let t=new Set(n.map(i=>i.source));for(let i of e)!t.has(i.id)&&i.type==="process"&&!/save|store|persist/i.test(i.label)&&(i.type="result",i.description=`The flow produces ${i.label.toLowerCase()}.`)}function ge(e){return e.evidence.length?Math.max(...e.evidence.map(n=>n.confidence)):.5}function pe(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[-_/.]+/g," ").replace(/\s+/g," ").trim()}function Rr(e){return e.replace(/\b\w/g,n=>n.toUpperCase())}function _r(e){let n=new Set;return e.filter(t=>{let i=`${t.file}:${t.startLine}`;return n.has(i)?!1:(n.add(i),!0)})}function Nr(e){let n=new Set;return e.filter(t=>{let i=`${t.source}:${t.target}:${t.type}:${t.control??"sequential"}`;return n.has(i)?!1:(n.add(i),!0)})}function Pr(e){return ir("sha1").update(e).digest("hex").slice(0,12)}import{createHash as Ar}from"crypto";import{access as Lr,open as Ir,readFile as St,readdir as kt}from"fs/promises";import T from"path";var Tr=new Set([".git",".next",".logic-map",".turbo","build","coverage","dist","node_modules","out"]),Ve=new Set([".md",".mdx",".txt",".rst"]),Dr=new Set([".md",".mdx",".txt",".yaml",".yml",".json"]),jr=new Set(["agent-runtime-map.config.json","package.json","tsconfig.json","jsconfig.json","next.config.js","next.config.mjs","next.config.ts","vite.config.js","vite.config.ts","wrangler.json","wrangler.toml"]),Fr=/(^|\/)(?:\.env(?:\.[^\/]*)?|[^\/]*\.(?:pem|key|p12|pfx)|(?:credentials?|secrets?)(?:[._-][^\/]*)?)(?:\/|$)/i,Rt=/^(about|api|architecture|configuration|contents?|contributing|development|docs?|features?|getting started|installation|license|overview|quick ?start|roadmap|setup|tests?|usage|关于|功能|功能列表|安装|开始|开发|架构|概览|目录|配置|使用|路线图)$/i;async function _t(e,n={}){let t=T.resolve(e),i=[],r=n.maxDocuments??80,s=n.maxDocumentBytes??96e3,o=n.maxTotalBytes??75e4,a=await Yr(t,i),d=await Zr(t,i),c=(await Mr(t)).slice(0,r),g=[],l=[],m=0;for(let u of c){if(m>=o)break;let p=Math.min(s,o-m),y=await Gr(u.absolute,p);if(!y)continue;m+=y.bytesRead;let b=Wr(u.relative,y.text),C=Pt(y.text);g.push({path:u.relative,kind:u.kind,title:b,summary:Jr(y.text,b),headings:C.map(w=>w.label).slice(0,32),excerpt:$t(y.text,6e3),truncated:y.truncated}),u.kind==="prompt"&&l.push({path:u.relative,name:b,excerpt:$t(y.text,6e3),variables:Xr(y.text),source:"file"})}c.length>=r&&i.push({level:"warning",code:"PROJECT_CONTEXT_FILE_LIMIT",message:`Project context reading was limited to ${r} documentation and prompt files.`}),m>=o&&i.push({level:"warning",code:"PROJECT_CONTEXT_BYTE_LIMIT",message:`Project context reading reached the ${o}-byte safety limit.`});let h=Ur([...Kr(n.productDescription),...qr(d),...g.flatMap(Hr),...l.flatMap(Vr)]).slice(0,48);return{description:d.description??fe(a.description,600),packageManager:await to(t),scripts:Object.keys(W(a.scripts)).sort(),dependencies:Qr(a),documents:g,prompts:l,configurationFiles:await eo(t),capabilityHints:h,diagnostics:i}}async function Mr(e){let n=[];async function t(i,r){if(r>5)return;let s;try{s=await kt(i,{withFileTypes:!0})}catch{return}s.sort((o,a)=>o.name.localeCompare(a.name));for(let o of s){let a=T.join(i,o.name),d=io(e,a);if(o.isDirectory()){!Tr.has(o.name)&&!o.name.startsWith(".")&&await t(a,r+1);continue}if(!o.isFile()||Fr.test(d))continue;let c=Or(d);c&&n.push({absolute:a,relative:d,kind:c})}}return await t(e,0),n.sort((i,r)=>Et(i)-Et(r)||i.relative.localeCompare(r.relative))}function Or(e){let n=e.toLowerCase(),t=T.posix.basename(n),i=T.posix.extname(t);if(/^readme(?:\.|$)/.test(t)&&Ve.has(i))return"readme";if(/(^|\/)(prd|product[-_ ]?requirements?)(\.|\/)/.test(n)&&Ve.has(i))return"prd";if(/(^|\/)(prompts?|instructions?|system-prompts?)(\/|\.|$)/.test(n)&&Dr.has(i))return"prompt";if((n.startsWith("docs/")||n.includes("/docs/"))&&Ve.has(i))return"documentation"}function Et(e){return e.kind==="readme"?0:e.kind==="prd"?1:e.kind==="prompt"?2:3}async function Gr(e,n){let t;try{t=await Ir(e,"r");let i=await t.stat(),r=Math.min(i.size,Math.max(0,n)),s=Buffer.alloc(r),o=await t.read(s,0,r,0),a=s.subarray(0,o.bytesRead);return a.includes(0)?void 0:{text:a.toString("utf8"),bytesRead:o.bytesRead,truncated:i.size>o.bytesRead}}catch{return}finally{await t?.close().catch(()=>{})}}function Hr(e){let n=e.excerpt.split(/\r?\n/),t=[];for(let i=0;i<n.length;i+=1){let r=n[i]??"",s=/^(#{2,4})\s+(.+?)\s*$/.exec(r),o=/^\s*[-*+]\s+\*\*(.+?)\*\*\s*[::-]?\s*(.*)$/.exec(r),a=V(s?.[2]??o?.[1]??"");if(!Nt(a))continue;let d=V(o?.[2]||Br(n,i+1));t.push({id:`capability_${we(`${e.path}:${i+1}:${a}`)}`,label:a,description:d||`Project documentation describes ${a}.`,keywords:me(`${a} ${d}`),origin:zr(e.kind),sources:[{file:e.path,startLine:i+1}],confidence:e.kind==="prd"?.9:e.kind==="readme"?.8:.74})}return t}function zr(e){return e==="readme"?"readme":e==="prd"?"prd":e==="prompt"?"prompt":"docs"}function Vr(e){let n=V(e.name);if(!Nt(n))return[];let t=At(e.excerpt);return t?[{id:`capability_${we(`prompt:${e.path}:${n}`)}`,label:n,description:t,keywords:me(`${n} ${t}`),origin:"prompt",sources:[{file:e.path,startLine:1,symbol:e.name}],confidence:.7}]:[]}function Kr(e){let n=e?.trim();return n?[{id:`capability_${we(`user:${n}`)}`,label:V(At(n))||n.slice(0,80),description:n.slice(0,600),keywords:me(n),origin:"user",sources:[],confidence:1}]:[]}function qr(e){return Object.entries(e.features??{}).map(([n,t])=>{let i=t.label?.trim()||qe(n);return{id:`capability_${we(`config:${n}`)}`,label:i,description:t.description?.trim()||`Configured project capability ${i}.`,keywords:he([...t.keywords??[],...me(`${n} ${i} ${t.description??""}`)]),origin:"config",sources:[{file:"agent-runtime-map.config.json",startLine:1,symbol:n}],confidence:1}})}function Ur(e){let n=new Map;for(let t of e){let i=no(t.label),r=n.get(i);if(!r){n.set(i,t);continue}n.set(i,{...r,description:r.description.length>=t.description.length?r.description:t.description,keywords:he([...r.keywords,...t.keywords]),sources:oo([...r.sources,...t.sources]),confidence:Math.max(r.confidence,t.confidence)})}return[...n.values()]}function Nt(e){return!e||e.length<3||e.length>80||Rt.test(e)?!1:!/^(v?\d+(\.\d+)+|https?:|npm |pnpm |yarn )/i.test(e)}function Pt(e){return e.split(/\r?\n/).flatMap((n,t)=>{let i=/^(#{1,4})\s+(.+?)\s*$/.exec(n);return i?[{label:V(i[2]??""),line:t+1}]:[]})}function Br(e,n){for(let t=n;t<Math.min(e.length,n+5);t+=1){let i=e[t]?.trim()??"";if(i&&!i.startsWith("#")&&!i.startsWith("```")&&!/^[-*_]{3,}$/.test(i))return i}return""}function Wr(e,n){return Pt(n)[0]?.label||qe(T.posix.basename(e,T.posix.extname(e)))}function Jr(e,n){return(e.split(/\r?\n/).map(r=>V(r)).find(r=>r&&r!==n&&!Rt.test(r)&&!r.startsWith("```"))||n).slice(0,320)}function Xr(e){let n=[...e.matchAll(/\{\{\s*([A-Za-z_][\w.-]*)\s*\}\}/g),...e.matchAll(/\$\{\s*([A-Za-z_][\w.-]*)\s*\}/g)].map(t=>t[1]).filter(t=>!!t);return he(n).slice(0,40)}function $t(e,n){return e.replace(/\r\n/g,`
|
|
3
|
+
`).replace(/\n{4,}/g,`
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
`).trim().slice(0,n)}async function Yr(e,n){try{return W(JSON.parse(await St(T.join(e,"package.json"),"utf8")))}catch(t){return await Ke(T.join(e,"package.json"))&&n.push({level:"warning",code:"PROJECT_MANIFEST_INVALID",message:`Could not parse package.json: ${t instanceof Error?t.message:String(t)}`,source:{file:"package.json",startLine:1}}),{}}}async function Zr(e,n){let t=T.join(e,"agent-runtime-map.config.json");try{return ro(JSON.parse(await St(t,"utf8")))}catch(i){return await Ke(t)&&n.push({level:"warning",code:"PROJECT_READER_CONFIG_INVALID",message:`Could not parse agent-runtime-map.config.json: ${i instanceof Error?i.message:String(i)}`,source:{file:"agent-runtime-map.config.json",startLine:1}}),{}}}function Qr(e){return[["runtime",e.dependencies],["development",e.devDependencies],["peer",e.peerDependencies]].flatMap(([t,i])=>Object.entries(W(i)).map(([r,s])=>({name:r,version:String(s),category:t}))).sort((t,i)=>t.name.localeCompare(i.name))}async function eo(e){let n=[],t;try{t=await kt(e,{withFileTypes:!0})}catch{return n}for(let i of t)i.isFile()&&jr.has(i.name)&&n.push(i.name);return n.sort()}async function to(e){for(let[n,t]of[["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"],["bun.lockb","bun"],["bun.lock","bun"],["package-lock.json","npm"]])if(await Ke(T.join(e,n)))return t}async function Ke(e){try{return await Lr(e),!0}catch{return!1}}function At(e){let n=V(e.split(/\r?\n/).find(i=>i.trim().length>0)??"");return(/^(.{10,200}?[.!?。!?])\s/.exec(`${n} `)?.[1]??n).slice(0,200).trim()}function V(e){return e.replace(/<[^>]+>/g," ").replace(/\[([^\]]+)\]\([^\)]+\)/g,"$1").replace(/[*_`>#]/g,"").replace(/^[-+\d.()\s]+/,"").replace(/\s+/g," ").trim()}function me(e){let n=e.toLowerCase().match(/[a-z][a-z0-9-]{2,}/g)??[],t=e.match(/[\u3400-\u9fff]{2,8}/g)??[],i=new Set(["agent","agents","and","before","can","feature","features","for","from","into","its","later","project","returning","runtime","system","that","the","this","through","using","with","\u529F\u80FD","\u7CFB\u7EDF","\u9879\u76EE"]);return he([...n,...t].filter(r=>!i.has(r))).slice(0,24)}function qe(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[-_/.]+/g," ").replace(/\s+/g," ").trim()}function no(e){return qe(e).toLowerCase().replace(/\b(agent|service|workflow|feature)\b/g,"").replace(/\s+/g,"").trim()}function io(e,n){return T.relative(e,n).split(T.sep).join("/")}function W(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function ro(e){let n=W(e),t=Object.fromEntries(Object.entries(W(n.features)).flatMap(([i,r])=>{let s=W(r),o=fe(s.label,80),a=fe(s.description,600),d=Array.isArray(s.keywords)?s.keywords.flatMap(c=>typeof c=="string"&&c.trim()?[c.trim().slice(0,80)]:[]).slice(0,24):void 0;return!o&&!a&&!d?.length?[]:[[i.slice(0,120),{label:o,description:a,keywords:d}]]}));return{description:fe(n.description,600),features:t}}function fe(e,n){return typeof e=="string"&&e.trim()?e.trim().slice(0,n):void 0}function he(e){return[...new Set(e)]}function oo(e){let n=new Set;return e.filter(t=>{let i=`${t.file}:${t.startLine}:${t.symbol??""}`;return n.has(i)?!1:(n.add(i),!0)})}function we(e){return Ar("sha1").update(e).digest("hex").slice(0,12)}var so={type:"object",additionalProperties:!1,required:["summary","confidence","nodes","features"],properties:{summary:{type:"string",maxLength:600},confidence:{type:"number",minimum:0,maximum:1},nodes:{type:"array",maxItems:80,items:{type:"object",additionalProperties:!1,required:["id","label","description","confidence","reason"],properties:{id:{type:"string"},label:{type:"string",maxLength:80},description:{type:"string",maxLength:400},confidence:{type:"number",minimum:0,maximum:1},reason:{type:"string",maxLength:400}}}},features:{type:"array",maxItems:48,items:{type:"object",additionalProperties:!1,required:["id","label","description","confidence","reason"],properties:{id:{type:"string"},label:{type:"string",maxLength:80},description:{type:"string",maxLength:400},confidence:{type:"number",minimum:0,maximum:1},reason:{type:"string",maxLength:400}}}}}};async function Lt(e,n,t){if(!t.apiKey.trim())throw new Error("Semantic enrichment requires an API key.");if(!t.model.trim())throw new Error("Semantic enrichment requires an explicit model name.");let i=t.fetchImpl??fetch,r=(t.baseUrl??"https://api.openai.com/v1").replace(/\/$/,""),s=ao(e,n,t.maxDocumentCharacters??16e3),o=await i(`${r}/responses`,{method:"POST",headers:{authorization:`Bearer ${t.apiKey}`,"content-type":"application/json"},body:JSON.stringify({model:t.model,store:!1,instructions:["You are the semantic compiler for an evidence-backed Agent code map.","Translate technical names into concise product and runtime concepts.","Use only the supplied node and feature IDs. Never add nodes, edges, files, or capabilities.","Do not hide uncertainty: lower confidence when documentation and code evidence disagree.","Labels must describe observable business or Agent behavior, not implementation syntax."].join(" "),input:JSON.stringify(s),text:{format:{type:"json_schema",name:"agent_runtime_map_semantics",strict:!0,schema:so}}})}),a=await o.json();if(!o.ok)throw new Error(go(a,o.status));let d=lo(a);if(!d)throw new Error("Semantic enrichment returned no structured output.");return co(n,JSON.parse(d),t.model)}function ao(e,n,t=16e3){let i=Math.max(0,t),r=(e.context?.documents??[]).flatMap(o=>{if(i<=0)return[];let a=o.excerpt.slice(0,Math.min(i,2e3));return i-=a.length,[{path:o.path,kind:o.kind,title:o.title,summary:o.summary,excerpt:a}]}),s=(e.context?.prompts??[]).flatMap(o=>{if(i<=0)return[];let a=o.excerpt.slice(0,Math.min(i,1200));return i-=a.length,[{path:o.path,name:o.name,excerpt:a,variables:o.variables}]});return{project:{name:e.project.name,frameworks:e.project.frameworks,description:e.context?.description,dependencies:e.context?.dependencies.map(o=>o.name).slice(0,120)??[]},documentedCapabilities:e.context?.capabilityHints??[],documents:r,prompts:s,nodes:n.nodes.map(o=>({id:o.id,type:o.type,label:o.label,description:o.description,confidence:o.confidence,sources:o.sources,metadata:uo(o.metadata)})),edges:n.edges.map(o=>({id:o.id,source:o.source,target:o.target,type:o.type,control:o.control,label:o.label,confidence:o.confidence})),features:n.features.map(o=>({id:o.id,label:o.label,description:o.description,nodeIds:o.nodeIds,health:o.health,confidence:o.confidence}))}}function co(e,n,t){let i=new Set(e.nodes.map(c=>c.id)),r=new Set(e.features.map(c=>c.id)),s=new Map(n.nodes.filter(c=>i.has(c.id)&&J(c.label,80)&&J(c.description,400)).map(c=>[c.id,c])),o=new Map(n.features.filter(c=>r.has(c.id)&&J(c.label,80)&&J(c.description,400)).map(c=>[c.id,c])),a=e.nodes.map(c=>{let g=s.get(c.id);return g?{...c,label:g.label.trim(),description:g.description.trim(),confidence:Math.min(c.confidence,Ue(g.confidence)),inference:{method:"mixed",explanation:`${c.inference.explanation}; LLM semantic compression (${t}): ${g.reason.trim()}`},metadata:{...c.metadata,semanticModel:t,generatedDescription:!1}}:c}),d=e.features.map(c=>{let g=o.get(c.id);return g?{...c,label:g.label.trim(),description:g.description.trim(),confidence:Math.min(c.confidence,Ue(g.confidence))}:c});return{...e,description:J(n.summary,600)?n.summary.trim():e.description,understanding:e.understanding?{...e.understanding,summary:J(n.summary,600)?n.summary.trim():e.understanding.summary,confidence:Math.min(e.understanding.confidence,Ue(n.confidence))}:e.understanding,nodes:a,features:d,diagnostics:[...e.diagnostics,{level:"info",code:"SEMANTIC_ENRICHMENT_APPLIED",message:`Applied evidence-constrained semantic labels with ${t}; graph topology and source evidence were not changed.`}]}}function uo(e){if(!e)return{};let n=["rawKind","rawName","role","returnType","parameters","factory","model","toolNames","documentedCapabilityLabel"];return Object.fromEntries(Object.entries(e).filter(([t])=>n.includes(t)))}function lo(e){let n=Array.isArray(e.output)?e.output:[];for(let t of n){if(!t||typeof t!="object")continue;let i=Array.isArray(t.content)?t.content:[];for(let r of i)if(r&&typeof r=="object"&&r.type==="output_text"&&typeof r.text=="string")return r.text}}function go(e,n){let t=e.error,i=t&&typeof t=="object"&&typeof t.message=="string"?t.message:void 0;return`Semantic enrichment request failed (${n})${i?`: ${i}`:"."}`}function J(e,n){return typeof e=="string"&&e.trim().length>0&&e.trim().length<=n}function Ue(e){return Number.isFinite(e)?Math.min(1,Math.max(0,e)):0}import{createHash as po,randomBytes as fo}from"crypto";import{watch as It}from"fs";import{cp as Vt,mkdir as Xe,readFile as ne,readdir as Kt,rename as Be,rm as be,stat as ie,writeFile as xe}from"fs/promises";import x from"path";var mo=".agent-runtime-map",ho=["**/*.ts","**/*.tsx","**/*.js","**/*.jsx","**/*.mjs","**/*.cjs","**/*.py","**/*.md","**/*.mdx","**/*.txt","package.json","agent-runtime-map.config.json"],qt=new Set([".git",".hg",".svn",".next",".turbo",".venv",".logic-map","node_modules","dist","build","out","coverage","__pycache__","venv","site-packages"]);function Je(e){let n=e?.watch;return{outDir:typeof e?.outDir=="string"&&e.outDir.trim()?e.outDir.trim():mo,watch:{include:Ht(n?.include)??[...ho],exclude:Ht(n?.exclude)??[],debounceMs:zt(n?.debounceMs,50,6e4)??800},history:{limit:zt(e?.history?.limit,0,1e4)??30}}}async function Ye(e){let n=x.join(x.resolve(e),"agent-runtime-map.config.json");try{let t=JSON.parse(await ne(n,"utf8"));return{config:Je(t),configFile:n}}catch(t){let i=await ie(n).then(()=>!0,()=>!1);return{config:Je(),configFile:n,warning:i?`Could not parse agent-runtime-map.config.json (${t instanceof Error?t.message:String(t)}); using defaults.`:void 0}}}async function Ut(e){let n=x.resolve(e),t=x.join(n,"agent-runtime-map.config.json"),i=Je(),r={"map:build":"agent-runtime-map build .","map:watch":"agent-runtime-map watch ."},s;try{let d=JSON.parse(await ne(t,"utf8"));s=d&&typeof d=="object"&&!Array.isArray(d)?d:{}}catch(d){if(await ie(t).then(()=>!0,()=>!1))throw new Error(`agent-runtime-map.config.json exists but could not be parsed: ${d instanceof Error?d.message:String(d)}`)}let o=s?{...s}:{},a=[];return o.outDir===void 0&&(o.outDir=i.outDir,a.push("outDir")),o.watch===void 0&&(o.watch=i.watch,a.push("watch")),o.history===void 0&&(o.history=i.history,a.push("history")),(!s||a.length)&&await xe(t,`${JSON.stringify(o,null,2)}
|
|
7
|
+
`,"utf8"),{configFile:t,created:!s,addedKeys:a,suggestedScripts:r}}function Ce(e){let{generatedAt:n,...t}=e;return po("sha1").update(JSON.stringify(t)).digest("hex").slice(0,16)}function wo(e,n,t){let i=We(e?.nodes??[],n.nodes,yo),r=We(e?.edges??[],n.edges,bo),s=We(e?.features??[],n.features,Tt),o=new Set([...i.added.map(l=>l.id),...i.removed.map(l=>l.id),...i.modified.map(l=>l.id),...r.added.map(l=>l.id),...r.removed.map(l=>l.id),...r.modified.map(l=>l.id)]),a=new Set([...s.added.map(l=>l.id),...s.modified.map(l=>l.id)]),d=n.features.filter(l=>a.has(l.id)||l.nodeIds.some(m=>o.has(m))||l.edgeIds.some(m=>o.has(m))).map(Tt),c=e?Dt(e):new Map,g=Dt(n);return{schemaVersion:1,generatedAt:t.generatedAt,buildId:Ce(n),previousBuildId:e?Ce(e):void 0,initial:!e,trigger:t.trigger,nodes:i,edges:r,features:s,affectedFeatures:d,diagnostics:{appeared:[...g].filter(([l])=>!c.has(l)).map(([,l])=>l),resolved:[...c].filter(([l])=>!g.has(l)).map(([,l])=>l)}}}function We(e,n,t){let i=new Map(e.map(s=>[s.id,s])),r=new Map(n.map(s=>[s.id,s]));return{added:n.filter(s=>!i.has(s.id)).map(t),removed:e.filter(s=>!r.has(s.id)).map(t),modified:n.filter(s=>{let o=i.get(s.id);return o!==void 0&&JSON.stringify(o)!==JSON.stringify(s)}).map(t)}}function yo(e){return{id:e.id,label:e.label,type:e.type}}function bo(e){return{id:e.id,source:e.source,target:e.target,type:e.type}}function Tt(e){return{id:e.id,label:e.label}}function Dt(e){let n=new Map,t=i=>{n.set(`${i.featureId??""}|${i.level}|${i.code}|${i.message}`,i)};for(let i of e.diagnostics)t({level:i.level,code:i.code,message:i.message});for(let i of e.features)for(let r of i.diagnostics)t({level:r.severity,code:r.code,message:r.message,featureId:i.id,nodeId:r.nodeId});return n}var xo=["graph.json","manifest.json","status.json","changes.json","report.html"];async function ve(e,n,t={}){let i=x.resolve(e),r=x.isAbsolute(n.outDir)?n.outDir:x.join(i,n.outDir),s=x.join(r,"current"),o=t.now??(()=>new Date),a=t.trigger?.length?t.trigger:["manual"],d=t.analyze??$e,c=Date.now(),g=await ye(x.join(s,"graph.json")),l=await ye(x.join(s,"status.json")),m=await ye(x.join(s,"manifest.json")),h;try{h=await d(i,{...t.analyzeOptions,outputFile:!1,rawOutputFile:!1})}catch(v){let R=Date.now()-c,_=v instanceof Error?v.message:String(v);return await jt(s,{message:_.slice(0,2e3),failedAt:o().toISOString(),trigger:a,previous:l,toolVersion:t.toolVersion,source:t.source}),{ok:!1,currentDir:s,outDir:r,error:_,durationMs:R}}let u=Ce(h.graph),p=o().toISOString(),y=Date.now()-c;if(g&&Ce(g)===u)return await G(x.join(s,"status.json"),Ee({state:"updated",toolVersion:t.toolVersion,buildId:u,generatedAt:l?.generatedAt??p,lastSuccessAt:p,durationMs:y,trigger:a})),m&&await G(x.join(s,"manifest.json"),{...m,toolVersion:t.toolVersion??m.toolVersion,generatedAt:p,commit:t.source?{sha:t.source.commitSha,ref:t.source.ref,baselineSha:m.commit?.sha,baselineRestored:t.source.baselineRestored}:m.commit}),{ok:!0,unchanged:!0,buildId:u,graph:h.graph,currentDir:s,outDir:r,durationMs:y};let b=wo(g,h.graph,{trigger:a,generatedAt:p}),C={schemaVersion:1,name:"agent-runtime-map",toolVersion:t.toolVersion??"0.0.0",buildId:u,generatedAt:p,graphType:h.graph.graphType,project:{name:x.basename(i)},commit:t.source?{sha:t.source.commitSha,ref:t.source.ref,baselineSha:m?.commit?.sha,baselineRestored:t.source.baselineRestored}:void 0,files:{graph:"graph.json",rawGraph:"raw-graph.json",changes:"changes.json",status:"status.json",report:"report.html"}},w=x.join(r,`.staging-${fo(6).toString("hex")}`);try{await Xe(w,{recursive:!0}),await G(x.join(w,"graph.json"),h.graph),await G(x.join(w,"raw-graph.json"),h.rawGraph),await G(x.join(w,"changes.json"),b),await G(x.join(w,"manifest.json"),C),await G(x.join(w,"status.json"),Ee({state:"updated",toolVersion:t.toolVersion,buildId:u,generatedAt:p,lastSuccessAt:p,durationMs:y,trigger:a})),await So(w,h.graph,h.rawGraph,t.viewerAssetsDir),await Eo(r,w,p,n.history.limit),await Co(r,w)}catch(v){await be(w,{recursive:!0,force:!0});let R=v instanceof Error?v.message:String(v);return await jt(s,{message:R.slice(0,2e3),failedAt:o().toISOString(),trigger:a,previous:l,toolVersion:t.toolVersion,source:t.source}),{ok:!1,currentDir:s,outDir:r,error:R,durationMs:Date.now()-c}}return{ok:!0,buildId:u,graph:h.graph,changes:b,currentDir:s,outDir:r,durationMs:y}}async function Co(e,n){await vo(n);let t=x.join(e,"current"),i=x.join(e,".previous");await be(i,{recursive:!0,force:!0});let r=await ie(t).then(s=>s.isDirectory(),()=>!1);r&&await Be(t,i);try{await Be(n,t)}catch(s){throw r&&await Be(i,t).catch(()=>{}),s}await be(i,{recursive:!0,force:!0})}async function vo(e){for(let n of xo){let t=x.join(e,n),i=await ie(t).catch(()=>{});if(!i?.isFile()||i.size===0)throw new Error(`Staging is incomplete: ${n} is missing or empty. The current map was left untouched.`);n.endsWith(".json")&&JSON.parse(await ne(t,"utf8"))}}async function Eo(e,n,t,i){if(i<=0)return;let r=x.join(e,"history"),s=t.replace(/[:.]/g,"-"),o=x.join(r,s);await Xe(o,{recursive:!0});for(let d of["graph.json","changes.json","manifest.json"])await Vt(x.join(n,d),x.join(o,d));let a=(await Kt(r,{withFileTypes:!0})).filter(d=>d.isDirectory()).map(d=>d.name).sort();for(let d of a.slice(0,Math.max(0,a.length-i)))await be(x.join(r,d),{recursive:!0,force:!0})}async function $o(e,n,t=()=>new Date){let i=await ye(x.join(e,"status.json"));await G(x.join(e,"status.json"),Ee({state:"stale",buildId:i?.buildId,generatedAt:i?.generatedAt,lastSuccessAt:i?.lastSuccessAt,staleSince:t().toISOString(),trigger:n}))}async function jt(e,n){await G(x.join(e,"status.json"),Ee({state:"failed",toolVersion:n.toolVersion,buildId:n.previous?.buildId,generatedAt:n.previous?.generatedAt,lastSuccessAt:n.previous?.lastSuccessAt,trigger:n.trigger,error:{message:n.message,failedAt:n.failedAt},attemptedCommit:n.source?.commitSha,attemptedRef:n.source?.ref}))}function Ee(e){return{schemaVersion:1,...e}}async function So(e,n,t,i){let r=Ft(n),s=JSON.stringify(t).length<=4e6?Ft(t):void 0,o=`<script>window.__ARM_GRAPH__=${r};${s?`window.__ARM_RAW_GRAPH__=${s};`:""}</script>`;if(i){let a=await ne(x.join(i,"index.html"),"utf8"),c=a.replace(/<script type="module"/,`${o}
|
|
8
|
+
<script type="module"`).replace("</body>",`${Mt}
|
|
9
|
+
</body>`);if(c===a)throw new Error("Viewer index.html has an unexpected shape; report.html was not generated.");await xe(x.join(e,"report.html"),c,"utf8"),await Vt(x.join(i,"assets"),x.join(e,"assets"),{recursive:!0});return}await xe(x.join(e,"report.html"),["<!doctype html>",'<html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/>',`<title>Agent Runtime Map \xB7 ${ko(n.title??"Report")}</title></head>`,`<body><div id="root"></div>${o}${Mt}</body></html>`].join(`
|
|
10
|
+
`),"utf8")}function Ft(e){return JSON.stringify(e).replace(/</g,"\\u003c")}function ko(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var Mt=`<script>
|
|
11
|
+
(function () {
|
|
12
|
+
function ready(fn) { document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", fn) : fn(); }
|
|
13
|
+
ready(function () {
|
|
14
|
+
setTimeout(function () {
|
|
15
|
+
var root = document.getElementById("root");
|
|
16
|
+
if (!root || root.childElementCount > 0 || !window.__ARM_GRAPH__) return;
|
|
17
|
+
var graph = window.__ARM_GRAPH__;
|
|
18
|
+
var health = { healthy: "#3fb27f", warning: "#d99a2b", error: "#d4574e" };
|
|
19
|
+
var rows = (graph.features || []).map(function (feature) {
|
|
20
|
+
var diagnostics = (feature.diagnostics || []).map(function (item) {
|
|
21
|
+
return '<li><code>' + item.code + '</code> ' + item.message.replace(/</g, "<") + "</li>";
|
|
22
|
+
}).join("");
|
|
23
|
+
return '<section style="border:1px solid #2a3242;border-radius:8px;padding:12px 16px;margin:10px 0">'
|
|
24
|
+
+ '<h2 style="margin:0;font-size:16px"><span style="display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:8px;background:' + (health[feature.health] || "#888") + '"></span>'
|
|
25
|
+
+ feature.label.replace(/</g, "<") + " <small style=\\"color:#8a94a6;font-weight:400\\">" + Math.round((feature.confidence || 0) * 100) + "%</small></h2>"
|
|
26
|
+
+ (feature.description ? '<p style="color:#aeb6c4;margin:6px 0 0">' + feature.description.replace(/</g, "<") + "</p>" : "")
|
|
27
|
+
+ (diagnostics ? '<ul style="color:#d99a2b;margin:8px 0 0;padding-left:18px">' + diagnostics + "</ul>" : "")
|
|
28
|
+
+ "</section>";
|
|
29
|
+
}).join("");
|
|
30
|
+
root.innerHTML = '<main style="max-width:760px;margin:32px auto;padding:0 16px;font:14px/1.5 -apple-system,Segoe UI,sans-serif;color:#e8ebf1">'
|
|
31
|
+
+ '<h1 style="font-size:20px">' + (graph.title || "Agent Runtime Map").replace(/</g, "<") + "</h1>"
|
|
32
|
+
+ '<p style="color:#8a94a6">' + (graph.nodes || []).length + " steps \xB7 " + (graph.edges || []).length + " flows \xB7 generated " + (graph.generatedAt || "") + "</p>"
|
|
33
|
+
+ '<p style="color:#8a94a6">Static summary. For the interactive map, serve this folder over HTTP (for example: <code>npx serve .</code>) and open report.html again.</p>'
|
|
34
|
+
+ rows + "</main>";
|
|
35
|
+
document.body.style.background = "#0b0d12";
|
|
36
|
+
}, 1500);
|
|
37
|
+
});
|
|
38
|
+
})();
|
|
39
|
+
</script>`;function Ro(e,n){let t=e.replaceAll("\\","/").replace(/^\.\//,"");if(!t||t.startsWith(".."))return!1;let i=n.outDir.replaceAll("\\","/").replace(/\/+$/,"");return t===i||t.startsWith(`${i}/`)||t.split("/").some(s=>qt.has(s)||s.startsWith(".")&&s!==".")||n.watch.exclude.some(s=>Gt(s).test(t))?!1:n.watch.include.some(s=>Gt(s).test(t))}var Ot=new Map;function Gt(e){let n=Ot.get(e);if(n)return n;let t="";for(let r=0;r<e.length;r+=1){let s=e[r];s==="*"?e[r+1]==="*"?e[r+2]==="/"?(t+="(?:[^/]+/)*",r+=2):(t+=".*",r+=1):t+="[^/]*":s==="?"?t+="[^/]":t+=s.replace(/[.+^${}()|[\]\\]/g,"\\$&")}let i=new RegExp(`^${t}$`);return Ot.set(e,i),i}function _o(e,n,t){let i=x.resolve(e),r=new Map,s=new Set,o,a=!1,d=g=>{a||!Ro(g,n)||(s.add(g.replaceAll("\\","/")),o&&clearTimeout(o),o=setTimeout(()=>{o=void 0;let l=[...s].sort();s.clear(),!a&&l.length&&t(l)},n.watch.debounceMs))},c=async g=>{if(a||r.has(g))return;let l=x.relative(i,g).replaceAll(x.sep,"/");if(l&&!No(l,n))return;let m;try{m=It(g,(u,p)=>{if(!p)return;let y=x.join(l,p.toString()).replaceAll(x.sep,"/");d(y);let b=x.join(i,y);ie(b).then(C=>{C.isDirectory()&&c(b)}).catch(()=>{})})}catch{return}m.on("error",()=>{}),r.set(g,m);let h;try{h=await Kt(g,{withFileTypes:!0})}catch{return}for(let u of h)u.isDirectory()&&await c(x.join(g,u.name))};try{let g=It(i,{recursive:!0},(l,m)=>{m&&d(m.toString())});g.on("error",()=>{}),r.set(i,g)}catch{c(i)}return{close:async()=>{a=!0,o&&clearTimeout(o),o=void 0,s.clear();for(let g of r.values())g.close();r.clear()}}}function No(e,n){let t=n.outDir.replaceAll("\\","/").replace(/\/+$/,"");return e===t||e.startsWith(`${t}/`)?!1:!e.split("/").some(r=>qt.has(r)||r.startsWith("."))}async function Bt(e,n,t={}){let i=x.join(x.isAbsolute(n.outDir)?n.outDir:x.join(x.resolve(e),n.outDir),"current"),r=await ve(e,n,{...t,trigger:t.trigger??["watch-start"]});t.onBuild?.(r);let s=!1,o,a=!1,d=async g=>{s=!0;try{for(;!a;){let l=await ve(e,n,{...t,trigger:g});if(t.onBuild?.(l),!o)break;g=[...o].sort(),o=void 0}}finally{s=!1}},c=_o(e,n,g=>{if(!a){if(t.onChangesDetected?.(g),s){o=new Set([...o??[],...g]);return}$o(i,g).then(()=>d(g))}});return{initial:r,handle:{close:async()=>{a=!0,await c.close()}}}}async function ye(e){try{return JSON.parse(await ne(e,"utf8"))}catch{return}}async function G(e,n){await Xe(x.dirname(e),{recursive:!0}),await xe(e,`${JSON.stringify(n,null,2)}
|
|
40
|
+
`,"utf8")}function Ht(e){if(!Array.isArray(e))return;let n=e.filter(t=>typeof t=="string"&&t.trim().length>0);return n.length||e.length===0?n:void 0}function zt(e,n,t){if(!(typeof e!="number"||!Number.isFinite(e)))return Math.min(t,Math.max(n,Math.round(e)))}import{execFile as Po}from"child_process";import{createHash as Ao}from"crypto";import{mkdir as Lo,readFile as Io,writeFile as Wt}from"fs/promises";import Se from"path";import{promisify as To}from"util";var Do=To(Po),Ze="# agent-runtime-map-integrity: ",jo=".github/workflows/agent-runtime-map.yml";function Fo(e={}){let t=`# Generated by \`agent-runtime-map init --github\`.
|
|
41
|
+
# Re-running init updates this file only while it is unmodified; edits are yours to keep.
|
|
42
|
+
name: Agent Runtime Map
|
|
43
|
+
|
|
44
|
+
on:
|
|
45
|
+
${e.defaultBranch?`push:
|
|
46
|
+
branches: [${JSON.stringify(e.defaultBranch)}]`:"push:"}
|
|
47
|
+
pull_request:
|
|
48
|
+
workflow_dispatch:
|
|
49
|
+
schedule:
|
|
50
|
+
# Weekly, so a compatible analyzer update re-maps the repository even
|
|
51
|
+
# without a push. Remove this block if you only want push/PR builds.
|
|
52
|
+
- cron: "17 6 * * 1"
|
|
53
|
+
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read
|
|
56
|
+
|
|
57
|
+
concurrency:
|
|
58
|
+
group: agent-runtime-map-\${{ github.ref }}
|
|
59
|
+
cancel-in-progress: true
|
|
60
|
+
|
|
61
|
+
jobs:
|
|
62
|
+
map:
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/checkout@v4
|
|
66
|
+
with:
|
|
67
|
+
# Full history keeps the previous map's commit reachable, so the change
|
|
68
|
+
# report can name the files that actually changed instead of the event.
|
|
69
|
+
fetch-depth: 0
|
|
70
|
+
- uses: TheCrazyAnt/agent-runtime-map@v1
|
|
71
|
+
`;return`${Ze}${Jt(t)}
|
|
72
|
+
${t}`}async function Mo(e){let n=async(...t)=>(await Do("git",["-C",Se.resolve(e),...t])).stdout.trim();try{let t=await n("symbolic-ref","refs/remotes/origin/HEAD"),i=t.replace(/^refs\/remotes\/origin\//,"");if(i&&i!==t)return i}catch{}try{if((await n("remote")).split(`
|
|
73
|
+
`).map(i=>i.trim()).filter(Boolean).includes("origin"))return}catch{return}try{return await n("symbolic-ref","--short","HEAD")||void 0}catch{return}}function Jt(e){return Ao("sha256").update(e).digest("hex").slice(0,16)}function Oo(e){let n=e.indexOf(`
|
|
74
|
+
`);return n<0||!e.startsWith(Ze)?!1:e.slice(Ze.length,n).trim()===Jt(e.slice(n+1))}var re=class extends Error{constructor(t){super(`${t} exists and has local modifications; it was not touched. Re-run with --force to overwrite it.`);this.workflowFile=t;this.name="WorkflowModifiedError"}workflowFile};async function Xt(e,n={}){let t=Se.join(Se.resolve(e),jo),i=n.defaultBranch??await Mo(e),r=Fo({defaultBranch:i}),s;try{s=await Io(t,"utf8")}catch{s=void 0}if(s!==void 0){if(s===r)return{workflowFile:t,outcome:"unchanged",defaultBranch:i};let o=Oo(s);if(!o&&!n.force)throw new re(t);return await Wt(t,r,"utf8"),{workflowFile:t,outcome:o?"updated":"overwritten",defaultBranch:i}}return await Lo(Se.dirname(t),{recursive:!0}),await Wt(t,r,"utf8"),{workflowFile:t,outcome:"created",defaultBranch:i}}async function $e(e,n={}){let t=ke.resolve(e);if(!(await Ho(t).catch(()=>{}))?.isDirectory())throw new Error(`Project path does not exist or is not a directory: ${t}`);let r=n.outputFile===!1?void 0:Zt(t,n.outputFile??".logic-map/graph.json"),s=n.rawOutputFile===!1?void 0:Zt(t,n.rawOutputFile??".logic-map/raw-graph.json"),o=n.readContext===!1?void 0:await _t(t,{maxDocuments:n.maxContextFiles,maxTotalBytes:n.maxContextBytes,productDescription:n.productDescription}),[a,d]=await Promise.all([at(t,{maxFiles:n.maxFiles}),ht(t,{maxFiles:n.maxFiles,pythonPath:n.pythonPath})]),c=Vo(a,d);if(o){let l=c.nodes.filter(h=>h.kind==="prompt").flatMap(h=>{let u=h.evidence[0]?.source,p=typeof h.metadata?.excerpt=="string"?h.metadata.excerpt:void 0;return!u||!p?[]:[{path:u.file,name:h.name,excerpt:p,variables:Array.isArray(h.metadata?.variables)?h.metadata.variables.filter(y=>typeof y=="string"):[],source:"code"}]}),m=new Set(o.prompts.map(h=>`${h.path}:${h.name}`));o.prompts.push(...l.filter(h=>!m.has(`${h.path}:${h.name}`))),c.context=o,c.diagnostics.push(...o.diagnostics)}let g=vt(c,n);return n.semantic&&(g=await Lt(c,g,n.semantic)),r&&await Yt(r,g),s&&await Yt(s,c),{graph:g,rawGraph:c,outputFile:r,rawOutputFile:s}}async function Yt(e,n){await Go(ke.dirname(e),{recursive:!0}),await zo(e,`${JSON.stringify(n,null,2)}
|
|
75
|
+
`,"utf8")}function Zt(e,n){return ke.isAbsolute(n)?n:ke.resolve(e,n)}function Vo(e,n){return!n.nodes.length&&!n.diagnostics.length?e:{...e,project:{...e.project,languages:[...new Set([...e.project.languages,...n.project.languages])],frameworks:[...new Set([...e.project.frameworks,...n.project.frameworks])],filesScanned:e.project.filesScanned+n.project.filesScanned},nodes:[...e.nodes,...n.nodes],edges:[...e.edges,...n.edges],diagnostics:[...e.diagnostics,...n.diagnostics]}}import{createReadStream as Ko}from"fs";import{access as tn,readFile as qo,stat as nn}from"fs/promises";import{createServer as Uo}from"http";import N from"path";import{spawn as Bo}from"child_process";import{fileURLToPath as Wo}from"url";var Jo={".css":"text/css; charset=utf-8",".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".svg":"image/svg+xml",".woff":"font/woff",".woff2":"font/woff2"};async function Re(e){let n=e.viewerDirectory?N.resolve(e.viewerDirectory):await Ne();await tn(N.join(n,"index.html"));let t=e.host??"127.0.0.1",i=e.port??4173,r=Uo((d,c)=>{Xo(r,n,e,d.url??"/",d.method??"GET",c)}),s=await Qo(r,t,i);return{url:`http://${t==="0.0.0.0"||t==="::"?"localhost":t}:${s}`,port:s,close:()=>new Promise((d,c)=>r.close(g=>g?c(g):d()))}}function _e(e){let n=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",t=process.platform==="win32"?["/c","start","",e]:[e];try{let i=Bo(n,t,{detached:!0,stdio:"ignore"});return i.on("error",()=>{}),i.unref(),!0}catch{return!1}}async function Xo(e,n,t,i,r,s){if(Zo(s),r!=="GET"&&r!=="HEAD"){s.writeHead(405,{Allow:"GET, HEAD"}),s.end("Method Not Allowed");return}let o,a;try{o=new URL(i,"http://localhost"),a=decodeURIComponent(o.pathname)}catch{s.writeHead(400),s.end("Bad Request");return}if(a==="/healthz"){H(s,200,JSON.stringify({status:"ok"}),"application/json; charset=utf-8",r);return}if(a==="/graph.json"){await oe(s,t.graphFile,r,"no-store");return}if(a==="/raw-graph.json"){if(!t.rawGraphFile){H(s,404,"Raw graph was not generated.","text/plain; charset=utf-8",r);return}await oe(s,t.rawGraphFile,r,"no-store");return}if(a==="/source.json"){await Yo(s,t,o,r);return}if(t.currentDir&&(a==="/manifest.json"||a==="/status.json"||a==="/changes.json")){await oe(s,N.join(t.currentDir,a.slice(1)),r,"no-store");return}let d=a==="/"?"index.html":a.replace(/^\/+/,""),c=N.resolve(n,d);if(c!==n&&!c.startsWith(`${n}${N.sep}`)){H(s,403,"Forbidden","text/plain; charset=utf-8",r);return}await oe(s,c,r,d==="index.html"?"no-cache":"public, max-age=31536000, immutable",n)}async function Yo(e,n,t,i){let r=typeof n.sourceFiles=="function"?n.sourceFiles():n.sourceFiles;if(!n.projectRoot||!r?.length){H(e,404,"Source access is unavailable.","text/plain; charset=utf-8",i);return}let s=Qt(t.searchParams.get("file")??""),o=new Set(r.map(Qt));if(!s||N.isAbsolute(s)||s.startsWith("../")||!o.has(s)){H(e,403,"Source file is not part of this graph.","text/plain; charset=utf-8",i);return}let a=N.resolve(n.projectRoot),d=N.resolve(a,s);if(d===a||!d.startsWith(`${a}${N.sep}`)){H(e,403,"Forbidden","text/plain; charset=utf-8",i);return}try{let c=await nn(d);if(!c.isFile()||c.size>15e5)throw new Error("Unsupported source file");let l=(await qo(d,"utf8")).split(/\r?\n/),m=en(t.searchParams.get("start"),1),h=en(t.searchParams.get("end"),m),u=Math.min(m,Math.max(1,l.length)),p=Math.max(u,Math.min(h,u+119,l.length)),y=Math.max(1,u-6),b=Math.min(l.length,Math.max(p+8,y+24),y+159),C={file:s,startLine:y,endLine:b,highlightStart:u,highlightEnd:p,lines:l.slice(y-1,b).map((w,v)=>({number:y+v,text:w}))};H(e,200,JSON.stringify(C),"application/json; charset=utf-8",i)}catch{H(e,404,"Source file could not be read.","text/plain; charset=utf-8",i)}}function Qt(e){return N.posix.normalize(e.replaceAll("\\","/")).replace(/^\.\//,"")}function en(e,n){let t=Number(e);return Number.isInteger(t)&&t>0?t:n}async function oe(e,n,t,i,r){try{let s=await nn(n);if(!s.isFile())throw new Error("Not a file");e.writeHead(200,{"Cache-Control":i,"Content-Length":s.size,"Content-Type":Jo[N.extname(n)]??"application/octet-stream"}),t==="HEAD"?e.end():Ko(n).on("error",()=>e.destroy()).pipe(e)}catch{if(r){let s=N.join(r,"index.html");if(n!==s){await oe(e,s,t,"no-cache");return}}H(e,404,"Not Found","text/plain; charset=utf-8",t)}}function H(e,n,t,i,r){e.writeHead(n,{"Content-Type":i,"Content-Length":Buffer.byteLength(t)}),e.end(r==="HEAD"?void 0:t)}function Zo(e){e.setHeader("Content-Security-Policy","default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'self'"),e.setHeader("Referrer-Policy","no-referrer"),e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("X-Frame-Options","SAMEORIGIN")}async function Qo(e,n,t){if(t===0){await new Promise((r,s)=>{e.once("error",s),e.listen(0,n,()=>r())});let i=e.address();if(!i||typeof i=="string")throw new Error("Could not resolve the assigned viewer port.");return i.port}for(let i=t;i<Math.min(t+20,65536);i+=1)if(await new Promise((s,o)=>{let a=c=>{e.off("listening",d),c.code==="EADDRINUSE"?s("in-use"):o(c)},d=()=>{e.off("error",a),s("listening")};e.once("error",a),e.once("listening",d),e.listen(i,n)})==="listening")return i;throw new Error(`No available port found between ${t} and ${t+19}.`)}async function Ne(){let e=N.dirname(Wo(import.meta.url)),n=[N.join(e,"viewer"),N.resolve(e,"../../../apps/viewer/dist"),N.resolve(process.cwd(),"apps/viewer/dist")];for(let t of n)try{return await tn(N.join(t,"index.html")),t}catch{}throw new Error("Viewer assets are missing. Run `npm run build` before starting the viewer.")}import Ae from"path";var es={en:{analyzing:e=>`Analyzing ${e}...`,scanned:e=>`Scanned ${e} files.`,contextSummary:(e,n,t)=>`Read ${e} project documents, ${n} prompt files, and ${t} documented capability hints.`,found:(e,n)=>`Found ${e} code nodes and ${n} relationships.`,compiled:(e,n)=>`Compiled ${e} logic nodes and ${n} flows.`,featureSummary:(e,n,t)=>`Detected ${e} feature circuits (${n} errors, ${t} warnings).`,logicGraph:e=>`Logic graph: ${e}`,rawGraph:e=>`Raw graph: ${e}`,viewer:e=>`Viewer: ${e}`,unexpected:e=>`unexpected positional argument ${e}`,exposed:e=>`Warning: the viewer is exposed on ${e}; its graph may contain source paths and code structure.`,openFailed:e=>`Could not open a browser automatically. Open ${e} manually.`,graphTypeInvalid:"--graph-type must be runtime_logic or product_logic",localeInvalid:"--locale must be auto, zh-CN, or en",semanticProviderInvalid:"--semantic currently supports openai only",semanticModelRequired:"--semantic-model is required when --semantic openai is enabled",semanticApiKeyMissing:"OPENAI_API_KEY is required when --semantic openai is enabled",stop:"Press Ctrl+C to stop.",portInvalid:"--port must be an integer between 1 and 65535",positiveInteger:e=>`${e} must be a positive integer`,initCreated:e=>`Created ${e}.`,initCompleted:(e,n)=>`Completed ${e} (added: ${n}).`,initUnchanged:e=>`${e} already has every continuous-map setting; nothing changed.`,initScripts:e=>`Suggested package.json scripts (add them yourself if you want them):
|
|
76
|
+
${e}`,configWarning:e=>`Warning: ${e}`,buildUpdated:(e,n,t)=>`Map updated in ${e} (build ${n}, ${t}ms).`,buildUnchanged:e=>`Map is already current (build ${e}); nothing rewritten.`,buildFailed:e=>`Analysis failed; the last successful map was kept. Reason: ${e}`,changesSummary:(e,n,t,i)=>`Changes: +${e} / -${n} / ~${t} nodes, ${i} features affected.`,watchStarted:e=>`Watching for changes. Map: ${e}`,watchChanges:e=>`${e} file(s) changed; rebuilding...`,reportHint:e=>`Standalone report: ${e}`,githubWorkflowCreated:e=>`Created ${e}.`,githubWorkflowUpdated:e=>`Updated ${e} (it was an unmodified generated file).`,githubWorkflowOverwritten:e=>`Overwrote ${e} as requested by --force; your previous edits to it are gone.`,githubWorkflowUnchanged:e=>`${e} is already current; nothing changed.`,githubWorkflowModified:e=>`${e} exists and has local modifications, so it was NOT touched. Re-run with --force to overwrite it.`,githubNextSteps:`Next: commit agent-runtime-map.config.json and .github/workflows/agent-runtime-map.yml.
|
|
77
|
+
Every push, pull request, and a weekly schedule will then rebuild the map on GitHub:
|
|
78
|
+
the run's Summary shows what changed, and the full map (report.html) is attached as an artifact.`,forceRequiresGithub:"--force is only meaningful together with init --github"},"zh-CN":{analyzing:e=>`\u6B63\u5728\u5206\u6790 ${e}\u2026`,scanned:e=>`\u5DF2\u626B\u63CF ${e} \u4E2A\u4EE3\u7801\u6587\u4EF6\u3002`,contextSummary:(e,n,t)=>`\u5DF2\u8BFB\u53D6 ${e} \u4E2A\u9879\u76EE\u6587\u6863\u3001${n} \u4E2A Prompt \u6587\u4EF6\uFF0C\u5E76\u63D0\u53D6 ${t} \u6761\u529F\u80FD\u7EBF\u7D22\u3002`,found:(e,n)=>`\u53D1\u73B0 ${e} \u4E2A\u4EE3\u7801\u8282\u70B9\u548C ${n} \u6761\u5173\u7CFB\u3002`,compiled:(e,n)=>`\u5DF2\u7F16\u8BD1\u4E3A ${e} \u4E2A\u903B\u8F91\u8282\u70B9\u548C ${n} \u6761\u903B\u8F91\u6D41\u3002`,featureSummary:(e,n,t)=>`\u8BC6\u522B\u5230 ${e} \u4E2A\u529F\u80FD\u7535\u8DEF\uFF08${n} \u4E2A\u9519\u8BEF\uFF0C${t} \u4E2A\u8B66\u544A\uFF09\u3002`,logicGraph:e=>`\u903B\u8F91\u56FE\uFF1A${e}`,rawGraph:e=>`\u539F\u59CB\u4EE3\u7801\u56FE\uFF1A${e}`,viewer:e=>`\u67E5\u770B\u5730\u5740\uFF1A${e}`,unexpected:e=>`\u5B58\u5728\u65E0\u6CD5\u8BC6\u522B\u7684\u4F4D\u7F6E\u53C2\u6570\uFF1A${e}`,exposed:e=>`\u8B66\u544A\uFF1AViewer \u5DF2\u66B4\u9732\u5728 ${e}\uFF1B\u903B\u8F91\u56FE\u53EF\u80FD\u5305\u542B\u6E90\u7801\u8DEF\u5F84\u548C\u4EE3\u7801\u7ED3\u6784\u3002`,openFailed:e=>`\u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE ${e}\u3002`,graphTypeInvalid:"--graph-type \u5FC5\u987B\u662F runtime_logic \u6216 product_logic",localeInvalid:"--locale \u5FC5\u987B\u662F auto\u3001zh-CN \u6216 en",semanticProviderInvalid:"--semantic \u5F53\u524D\u53EA\u652F\u6301 openai",semanticModelRequired:"\u542F\u7528 --semantic openai \u65F6\u5FC5\u987B\u63D0\u4F9B --semantic-model",semanticApiKeyMissing:"\u542F\u7528 --semantic openai \u65F6\u5FC5\u987B\u8BBE\u7F6E OPENAI_API_KEY",stop:"\u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u3002",portInvalid:"--port \u5FC5\u987B\u662F 1 \u5230 65535 \u4E4B\u95F4\u7684\u6574\u6570",positiveInteger:e=>`${e} \u5FC5\u987B\u662F\u6B63\u6574\u6570`,initCreated:e=>`\u5DF2\u521B\u5EFA ${e}\u3002`,initCompleted:(e,n)=>`\u5DF2\u8865\u5168 ${e}\uFF08\u65B0\u589E\uFF1A${n}\uFF09\u3002`,initUnchanged:e=>`${e} \u5DF2\u5305\u542B\u5168\u90E8\u6301\u7EED\u5730\u56FE\u914D\u7F6E\uFF0C\u672A\u505A\u4FEE\u6539\u3002`,initScripts:e=>`\u5EFA\u8BAE\u6DFB\u52A0\u5230 package.json \u7684 scripts\uFF08\u9700\u8981\u8BF7\u81EA\u884C\u6DFB\u52A0\uFF09\uFF1A
|
|
79
|
+
${e}`,configWarning:e=>`\u8B66\u544A\uFF1A${e}`,buildUpdated:(e,n,t)=>`\u5730\u56FE\u5DF2\u66F4\u65B0\uFF1A${e}\uFF08\u6784\u5EFA ${n}\uFF0C\u8017\u65F6 ${t}ms\uFF09\u3002`,buildUnchanged:e=>`\u5730\u56FE\u5DF2\u662F\u6700\u65B0\uFF08\u6784\u5EFA ${e}\uFF09\uFF0C\u672A\u91CD\u5199\u4EFB\u4F55\u6587\u4EF6\u3002`,buildFailed:e=>`\u5206\u6790\u5931\u8D25\uFF0C\u5DF2\u4FDD\u7559\u6700\u540E\u4E00\u6B21\u6210\u529F\u7684\u5730\u56FE\u3002\u539F\u56E0\uFF1A${e}`,changesSummary:(e,n,t,i)=>`\u53D8\u66F4\uFF1A\u8282\u70B9 +${e} / -${n} / ~${t}\uFF0C${i} \u4E2A\u529F\u80FD\u53D7\u5F71\u54CD\u3002`,watchStarted:e=>`\u6B63\u5728\u76D1\u542C\u53D8\u5316\u3002\u5730\u56FE\u76EE\u5F55\uFF1A${e}`,watchChanges:e=>`\u68C0\u6D4B\u5230 ${e} \u4E2A\u6587\u4EF6\u53D8\u5316\uFF0C\u6B63\u5728\u91CD\u65B0\u5206\u6790\u2026`,reportHint:e=>`\u72EC\u7ACB\u62A5\u544A\u9875\uFF1A${e}`,githubWorkflowCreated:e=>`\u5DF2\u521B\u5EFA ${e}\u3002`,githubWorkflowUpdated:e=>`\u5DF2\u66F4\u65B0 ${e}\uFF08\u539F\u6587\u4EF6\u662F\u672A\u7ECF\u4FEE\u6539\u7684\u751F\u6210\u6587\u4EF6\uFF09\u3002`,githubWorkflowOverwritten:e=>`\u5DF2\u6309 --force \u8981\u6C42\u8986\u76D6 ${e}\uFF1B\u4F60\u4E4B\u524D\u5BF9\u5B83\u7684\u4FEE\u6539\u5DF2\u88AB\u4E22\u5F03\u3002`,githubWorkflowUnchanged:e=>`${e} \u5DF2\u662F\u6700\u65B0\uFF0C\u672A\u505A\u4FEE\u6539\u3002`,githubWorkflowModified:e=>`${e} \u5DF2\u5B58\u5728\u4E14\u5305\u542B\u4F60\u7684\u624B\u52A8\u4FEE\u6539\uFF0C\u56E0\u6B64\u6CA1\u6709\u6539\u52A8\u5B83\u3002\u5982\u9700\u8986\u76D6\uFF0C\u8BF7\u4F7F\u7528 --force \u91CD\u65B0\u6267\u884C\u3002`,githubNextSteps:`\u4E0B\u4E00\u6B65\uFF1A\u63D0\u4EA4 agent-runtime-map.config.json \u548C .github/workflows/agent-runtime-map.yml\u3002
|
|
80
|
+
\u4E4B\u540E\u6BCF\u6B21 push\u3001Pull Request \u4EE5\u53CA\u6BCF\u5468\u4E00\u6B21\u7684\u5B9A\u65F6\u4EFB\u52A1\u90FD\u4F1A\u5728 GitHub \u4E0A\u81EA\u52A8\u91CD\u5EFA\u5730\u56FE\uFF1A
|
|
81
|
+
\u8FD0\u884C\u7684 Summary \u4F1A\u663E\u793A\u53D8\u66F4\u6458\u8981\uFF0C\u5B8C\u6574\u5730\u56FE\uFF08report.html\uFF09\u4F1A\u4F5C\u4E3A artifact \u9644\u5728\u8FD0\u884C\u7ED3\u679C\u91CC\u3002`,forceRequiresGithub:"--force \u53EA\u80FD\u4E0E init --github \u4E00\u8D77\u4F7F\u7528"}};function rn(e){return es[e]}function on(e){let n=e.find(i=>i.startsWith("--locale="));if(n)return n.slice(9);let t=e.indexOf("--locale");return t>=0?e[t+1]:void 0}function sn(e){return e===void 0?!0:["auto","zh","zh-cn","en","en-us"].includes(e.toLowerCase())}function Qe(e,n=process.env){let t=ts(e);return t||([n.LC_ALL,n.LC_MESSAGES,n.LANG,Intl.DateTimeFormat().resolvedOptions().locale].filter(Boolean).join(" ").toLowerCase().includes("zh")?"zh-CN":"en")}function Pe(e,n){if(!n||n.toLowerCase()==="auto")return e;let t=Qe(n),i=new URL(e);return i.searchParams.set("locale",t),i.toString()}function et(e,n){return e==="zh-CN"?`Agent Runtime Map ${n}
|
|
82
|
+
|
|
83
|
+
\u5C06\u4EE3\u7801\u9879\u76EE\u8F6C\u6362\u6210\u4E00\u5F20\u6709\u6E90\u7801\u8BC1\u636E\u3001\u53EF\u9010\u6B65\u68C0\u67E5\u7684 Agent \u529F\u80FD\u7535\u8DEF\u56FE\u3002
|
|
84
|
+
|
|
85
|
+
\u7528\u6CD5\uFF1A
|
|
86
|
+
agent-runtime-map [\u9879\u76EE] [\u9009\u9879] \u5206\u6790\u9879\u76EE\u5E76\u6253\u5F00\u4EA4\u4E92\u5F0F Viewer
|
|
87
|
+
agent-runtime-map serve [\u9879\u76EE] [\u9009\u9879] \u5206\u6790\u9879\u76EE\u5E76\u6253\u5F00\u4EA4\u4E92\u5F0F Viewer
|
|
88
|
+
agent-runtime-map analyze [\u9879\u76EE] [\u9009\u9879] \u53EA\u751F\u6210 JSON\uFF0C\u4E0D\u542F\u52A8 Viewer
|
|
89
|
+
agent-runtime-map init [\u9879\u76EE] \u521B\u5EFA agent-runtime-map.config.json
|
|
90
|
+
agent-runtime-map init --github [\u9879\u76EE] \u540C\u65F6\u751F\u6210 GitHub Actions workflow\uFF0Cpush \u540E\u81EA\u52A8\u66F4\u65B0\u5730\u56FE
|
|
91
|
+
agent-runtime-map build [\u9879\u76EE] \u6784\u5EFA\u6301\u7EED\u5730\u56FE\u5230 .agent-runtime-map/current/
|
|
92
|
+
agent-runtime-map watch [\u9879\u76EE] \u6301\u7EED\u76D1\u542C\u5E76\u81EA\u52A8\u66F4\u65B0\u5730\u56FE\uFF0C\u540C\u65F6\u63D0\u4F9B Viewer
|
|
93
|
+
|
|
94
|
+
\u517C\u5BB9\u547D\u4EE4\uFF1Alogic-map
|
|
95
|
+
|
|
96
|
+
\u9009\u9879\uFF1A
|
|
97
|
+
-o, --out <\u6587\u4EF6> Logic Graph \u8F93\u51FA\u4F4D\u7F6E\uFF08\u9ED8\u8BA4\uFF1A.logic-map/graph.json\uFF09
|
|
98
|
+
--raw-out <\u6587\u4EF6> Raw Code Graph \u8F93\u51FA\u4F4D\u7F6E\uFF08\u9ED8\u8BA4\uFF1A.logic-map/raw-graph.json\uFF09
|
|
99
|
+
--no-raw \u4E0D\u751F\u6210 Raw Code Graph
|
|
100
|
+
--max-files <\u6570\u91CF> \u6700\u5927\u5206\u6790\u6587\u4EF6\u6570\uFF08\u9ED8\u8BA4\uFF1A2000\uFF09
|
|
101
|
+
--max-context-files <\u6570\u91CF> \u6700\u5927\u9879\u76EE\u6587\u6863\u6570\uFF08\u9ED8\u8BA4\uFF1A80\uFF09
|
|
102
|
+
--max-context-bytes <\u6570\u91CF> \u9879\u76EE\u6587\u6863\u8BFB\u53D6\u5B57\u8282\u4E0A\u9650\uFF08\u9ED8\u8BA4\uFF1A750000\uFF09
|
|
103
|
+
--no-context \u4E0D\u8BFB\u53D6 README\u3001docs\u3001PRD \u548C Prompt
|
|
104
|
+
--max-nodes <\u6570\u91CF> \u6700\u5927\u903B\u8F91\u8282\u70B9\u6570\uFF08\u9ED8\u8BA4\uFF1A40\uFF09
|
|
105
|
+
--graph-type <\u7C7B\u578B> runtime_logic \u6216 product_logic
|
|
106
|
+
--description <\u8BF4\u660E> \u53EF\u9009\u7684\u4EA7\u54C1\u80CC\u666F\u8BF4\u660E
|
|
107
|
+
--semantic openai \u663E\u5F0F\u542F\u7528\u53EF\u9009 LLM \u8BED\u4E49\u538B\u7F29\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09
|
|
108
|
+
--semantic-model <\u6A21\u578B> OpenAI \u6A21\u578B\u540D\u79F0\uFF08\u542F\u7528 semantic \u65F6\u5FC5\u586B\uFF09
|
|
109
|
+
--semantic-base-url <\u5730\u5740> \u53EF\u9009\u7684 Responses API \u57FA\u7840\u5730\u5740
|
|
110
|
+
--locale <\u8BED\u8A00> auto\u3001zh-CN \u6216 en\uFF08\u9ED8\u8BA4\uFF1A\u81EA\u52A8\u8BC6\u522B\uFF09
|
|
111
|
+
-p, --port <\u7AEF\u53E3> Viewer \u7AEF\u53E3\uFF08\u9ED8\u8BA4\uFF1A4173\uFF1B\u88AB\u5360\u7528\u65F6\u81EA\u52A8\u9012\u589E\uFF09
|
|
112
|
+
--host <\u4E3B\u673A> Viewer \u4E3B\u673A\uFF08\u9ED8\u8BA4\uFF1A127.0.0.1\uFF09
|
|
113
|
+
--no-open \u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668
|
|
114
|
+
--debug \u51FA\u9519\u65F6\u6253\u5370\u8C03\u7528\u6808
|
|
115
|
+
-h, --help \u663E\u793A\u5E2E\u52A9
|
|
116
|
+
-v, --version \u663E\u793A\u7248\u672C
|
|
117
|
+
`:`Agent Runtime Map ${n}
|
|
118
|
+
|
|
119
|
+
Turn your codebase into an evidence-backed, step-through Agent circuit map.
|
|
120
|
+
|
|
121
|
+
Usage:
|
|
122
|
+
agent-runtime-map [project] [options] Analyze and open the interactive viewer
|
|
123
|
+
agent-runtime-map serve [project] [options] Analyze and open the interactive viewer
|
|
124
|
+
agent-runtime-map analyze [project] [options] Generate JSON without starting a server
|
|
125
|
+
agent-runtime-map init [project] Create agent-runtime-map.config.json
|
|
126
|
+
agent-runtime-map init --github [project] Also generate the GitHub Actions workflow for automatic updates
|
|
127
|
+
agent-runtime-map build [project] Build the continuous map into .agent-runtime-map/current/
|
|
128
|
+
agent-runtime-map watch [project] Watch the project, keep the map updated, and serve the viewer
|
|
129
|
+
|
|
130
|
+
Alias: logic-map
|
|
131
|
+
|
|
132
|
+
Options:
|
|
133
|
+
-o, --out <file> Logic Graph output (default: .logic-map/graph.json)
|
|
134
|
+
--raw-out <file> Raw Code Graph output (default: .logic-map/raw-graph.json)
|
|
135
|
+
--no-raw Do not write the Raw Code Graph
|
|
136
|
+
--max-files <number> Maximum source files to analyze (default: 2000)
|
|
137
|
+
--max-context-files <number> Maximum project documents to read (default: 80)
|
|
138
|
+
--max-context-bytes <number> Project context byte limit (default: 750000)
|
|
139
|
+
--no-context Skip README, docs, PRD, and prompt reading
|
|
140
|
+
--max-nodes <number> Maximum compiled logic nodes (default: 40)
|
|
141
|
+
--graph-type <type> runtime_logic or product_logic
|
|
142
|
+
--description <text> Optional product context for the graph
|
|
143
|
+
--semantic openai Explicitly enable optional LLM semantic compression (off by default)
|
|
144
|
+
--semantic-model <model> OpenAI model name (required with semantic mode)
|
|
145
|
+
--semantic-base-url <url> Optional Responses API base URL
|
|
146
|
+
--locale <locale> auto, zh-CN, or en (default: auto)
|
|
147
|
+
-p, --port <number> Viewer port (default: 4173; increments if busy)
|
|
148
|
+
--host <host> Viewer host (default: 127.0.0.1)
|
|
149
|
+
--no-open Do not open the browser automatically
|
|
150
|
+
--debug Print stack traces for failures
|
|
151
|
+
-h, --help Show help
|
|
152
|
+
-v, --version Show version
|
|
153
|
+
`}function ts(e){if(!(!e||e.toLowerCase()==="auto"))return e.toLowerCase().startsWith("zh")?"zh-CN":e.toLowerCase().startsWith("en")?"en":void 0}async function an(e,n,t={}){let i=await Ut(e);i.created?process.stdout.write(`${n.initCreated(i.configFile)}
|
|
154
|
+
`):i.addedKeys.length?process.stdout.write(`${n.initCompleted(i.configFile,i.addedKeys.join(", "))}
|
|
155
|
+
`):process.stdout.write(`${n.initUnchanged(i.configFile)}
|
|
156
|
+
`);let r=Object.entries(i.suggestedScripts).map(([s,o])=>` "${s}": "${o}"`).join(`
|
|
157
|
+
`);if(process.stdout.write(`${n.initScripts(r)}
|
|
158
|
+
`),!t.github)return 0;try{let s=await Xt(e,{force:t.force}),o=s.outcome==="created"?n.githubWorkflowCreated(s.workflowFile):s.outcome==="unchanged"?n.githubWorkflowUnchanged(s.workflowFile):s.outcome==="overwritten"?n.githubWorkflowOverwritten(s.workflowFile):n.githubWorkflowUpdated(s.workflowFile);return process.stdout.write(`${o}
|
|
159
|
+
${n.githubNextSteps}
|
|
160
|
+
`),0}catch(s){if(s instanceof re)return process.stderr.write(`${n.githubWorkflowModified(s.workflowFile)}
|
|
161
|
+
`),1;throw s}}function ns(e=process.env){let n=e.AGENT_RUNTIME_MAP_COMMIT_SHA?.trim(),t=e.AGENT_RUNTIME_MAP_REF?.trim(),i=e.AGENT_RUNTIME_MAP_BASELINE_RESTORED?.trim(),r=e.AGENT_RUNTIME_MAP_TRIGGER?.split(`
|
|
162
|
+
`).map(s=>s.trim()).filter(Boolean);return{source:n||t||i!==void 0?{commitSha:n||void 0,ref:t||void 0,baselineRestored:i===void 0?void 0:i==="true"}:void 0,trigger:r?.length?r:void 0}}async function cn(e,n,t){let{config:i,warning:r}=await Ye(e);r&&process.stderr.write(`${t.configWarning(r)}
|
|
163
|
+
`);let s=process.env.AGENT_RUNTIME_MAP_SIMULATE_FAILURE,o=await ve(e,i,{...ns(),analyzeOptions:n.analyzeOptions,toolVersion:n.toolVersion,viewerAssetsDir:await Ne().catch(()=>{}),analyze:s?async()=>{throw new Error(`Simulated analysis failure: ${s}`)}:void 0});return un(o,t),o.ok&&!o.unchanged&&process.stdout.write(`${t.reportHint(Ae.join(o.currentDir,"report.html"))}
|
|
164
|
+
`),o.ok?0:1}async function dn(e,n,t){let{config:i,warning:r}=await Ye(e);r&&process.stderr.write(`${t.configWarning(r)}
|
|
165
|
+
`);let s=[],o=l=>{l.ok&&l.graph&&(s=is(l.graph)),un(l,t)},{handle:a,initial:d}=await Bt(e,i,{analyzeOptions:n.analyzeOptions,toolVersion:n.toolVersion,viewerAssetsDir:await Ne().catch(()=>{}),onChangesDetected:l=>process.stdout.write(`${t.watchChanges(l.length)}
|
|
166
|
+
`),onBuild:o});d.ok||process.stdout.write(`${t.watchStarted(d.currentDir)}
|
|
167
|
+
`);let c=await Re({graphFile:Ae.join(d.currentDir,"graph.json"),rawGraphFile:Ae.join(d.currentDir,"raw-graph.json"),currentDir:d.currentDir,projectRoot:Ae.resolve(e),sourceFiles:()=>s,host:n.host,port:n.port}),g=Pe(c.url,n.localeParam);return process.stdout.write(`${t.watchStarted(d.currentDir)}
|
|
168
|
+
${t.viewer(g)}
|
|
169
|
+
${t.stop}
|
|
170
|
+
`),n.open!==!1&&!_e(g)&&process.stdout.write(`${t.openFailed(g)}
|
|
171
|
+
`),await new Promise(l=>{let m=!1,h=()=>{m||(m=!0,a.close().then(()=>c.close()).then(l,l))};process.once("SIGINT",h),process.once("SIGTERM",h)}),0}function un(e,n){if(!e.ok){process.stderr.write(`${n.buildFailed(e.error??"unknown")}
|
|
172
|
+
`);return}if(e.unchanged){process.stdout.write(`${n.buildUnchanged(e.buildId??"")}
|
|
173
|
+
`);return}process.stdout.write(`${n.buildUpdated(e.currentDir,e.buildId??"",e.durationMs)}
|
|
174
|
+
`),e.changes&&!e.changes.initial&&process.stdout.write(`${n.changesSummary(e.changes.nodes.added.length,e.changes.nodes.removed.length,e.changes.nodes.modified.length,e.changes.affectedFeatures.length)}
|
|
175
|
+
`)}function is(e){return[...new Set([...e.nodes.flatMap(n=>n.sources.map(t=>t.file)),...e.nodes.flatMap(n=>n.product?.sources.map(t=>t.file)??[]),...e.features.flatMap(n=>n.product?.sources.map(t=>t.file)??[])])]}var Le="0.8.0";async function os(e=process.argv.slice(2)){let n=on(e),t=Qe(n),i=rn(t),r;try{r=rs({args:e,allowPositionals:!0,strict:!0,options:{help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"},out:{type:"string",short:"o"},"raw-out":{type:"string"},"no-raw":{type:"boolean"},"max-files":{type:"string"},"max-context-files":{type:"string"},"max-context-bytes":{type:"string"},"no-context":{type:"boolean"},"max-nodes":{type:"string"},"graph-type":{type:"string"},description:{type:"string"},semantic:{type:"string"},"semantic-model":{type:"string"},"semantic-base-url":{type:"string"},locale:{type:"string"},port:{type:"string",short:"p"},host:{type:"string"},"no-open":{type:"boolean"},github:{type:"boolean"},force:{type:"boolean"},debug:{type:"boolean"}}})}catch(u){return process.stderr.write(`agent-runtime-map: ${u instanceof Error?u.message:String(u)}
|
|
176
|
+
|
|
177
|
+
${et(t,Le)}`),1}if(r.values.help)return process.stdout.write(et(t,Le)),0;if(r.values.version)return process.stdout.write(`${Le}
|
|
178
|
+
`),0;let s=r.positionals[0],o=new Set(["analyze","serve","init","build","watch"]),a=s!==void 0&&o.has(s)?s:"serve",d=s!==void 0&&o.has(s),c=d?r.positionals[1]??".":s??".",g=d?r.positionals.slice(2):r.positionals.slice(1);if(g.length)return process.stderr.write(`agent-runtime-map: ${i.unexpected(g[0])}
|
|
179
|
+
`),1;if(!sn(r.values.locale))return process.stderr.write(`agent-runtime-map: ${i.localeInvalid}
|
|
180
|
+
`),1;let l=r.values["graph-type"]??"runtime_logic";if(l!=="runtime_logic"&&l!=="product_logic")return process.stderr.write(`agent-runtime-map: ${i.graphTypeInvalid}
|
|
181
|
+
`),1;let m=r.values.semantic;if(m!==void 0&&m!=="openai")return process.stderr.write(`agent-runtime-map: ${i.semanticProviderInvalid}
|
|
182
|
+
`),1;if(m==="openai"&&!r.values["semantic-model"])return process.stderr.write(`agent-runtime-map: ${i.semanticModelRequired}
|
|
183
|
+
`),1;if(m==="openai"&&!process.env.OPENAI_API_KEY)return process.stderr.write(`agent-runtime-map: ${i.semanticApiKeyMissing}
|
|
184
|
+
`),1;let h={maxFiles:Ie(r.values["max-files"],"--max-files",i),maxContextFiles:Ie(r.values["max-context-files"],"--max-context-files",i),maxContextBytes:Ie(r.values["max-context-bytes"],"--max-context-bytes",i),readContext:!r.values["no-context"],maxNodes:Ie(r.values["max-nodes"],"--max-nodes",i),graphType:l,productDescription:r.values.description,semantic:m==="openai"?{apiKey:process.env.OPENAI_API_KEY,model:r.values["semantic-model"],baseUrl:r.values["semantic-base-url"]}:void 0};if(a==="init"||a==="build"||a==="watch")try{if(a==="init")return await an(c,i,{github:!!r.values.github,force:!!r.values.force});if(r.values.force||r.values.github)return process.stderr.write(`agent-runtime-map: ${i.forceRequiresGithub}
|
|
185
|
+
`),1;process.stdout.write(`${i.analyzing(c)}
|
|
186
|
+
`);let u={analyzeOptions:h,toolVersion:Le,host:r.values.host??"127.0.0.1",port:ln(r.values.port,i),open:!r.values["no-open"],localeParam:r.values.locale};return a==="build"?await cn(c,u,i):await dn(c,u,i)}catch(u){let p=u instanceof Error?r.values.debug?u.stack??u.message:u.message:String(u);return process.stderr.write(`agent-runtime-map: ${p}
|
|
187
|
+
`),1}try{process.stdout.write(`${i.analyzing(c)}
|
|
188
|
+
`);let u=await $e(c,{...h,outputFile:r.values.out,rawOutputFile:r.values["no-raw"]?!1:r.values["raw-out"]});if(process.stdout.write([i.scanned(u.rawGraph.project.filesScanned),u.rawGraph.context?i.contextSummary(u.rawGraph.context.documents.length,u.rawGraph.context.prompts.length,u.rawGraph.context.capabilityHints.length):void 0,i.found(u.rawGraph.nodes.length,u.rawGraph.edges.length),i.compiled(u.graph.nodes.length,u.graph.edges.length),i.featureSummary(u.graph.features.length,u.graph.features.filter(w=>w.health==="error").length,u.graph.features.filter(w=>w.health==="warning").length),u.outputFile?i.logicGraph(u.outputFile):void 0,u.rawOutputFile?i.rawGraph(u.rawOutputFile):void 0].filter(Boolean).join(`
|
|
189
|
+
`)+`
|
|
190
|
+
`),a==="analyze")return 0;let p=r.values.host??"127.0.0.1",y=ln(r.values.port,i),b=await Re({graphFile:u.outputFile,rawGraphFile:u.rawOutputFile,projectRoot:u.rawGraph.project.root,sourceFiles:[...new Set([...u.graph.nodes.flatMap(w=>w.sources.map(v=>v.file)),...u.graph.nodes.flatMap(w=>w.product?.sources.map(v=>v.file)??[]),...u.graph.features.flatMap(w=>w.product?.sources.map(v=>v.file)??[])])],host:p,port:y}),C=Pe(b.url,r.values.locale);return process.stdout.write(`${i.viewer(C)}
|
|
191
|
+
${i.stop}
|
|
192
|
+
`),p!=="127.0.0.1"&&p!=="localhost"&&p!=="::1"&&process.stdout.write(`${i.exposed(p)}
|
|
193
|
+
`),!r.values["no-open"]&&!_e(C)&&process.stdout.write(`${i.openFailed(C)}
|
|
194
|
+
`),await ss(b.close),0}catch(u){let p=u instanceof Error?r.values.debug?u.stack??u.message:u.message:String(u);return process.stderr.write(`agent-runtime-map: ${p}
|
|
195
|
+
`),1}}function ln(e,n){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<1||t>65535)throw new Error(n.portInvalid);return t}async function ss(e){await new Promise(n=>{let t=!1,i=()=>{t||(t=!0,e().then(n,n))};process.once("SIGINT",i),process.once("SIGTERM",i)})}function Ie(e,n,t){if(e===void 0)return;let i=Number(e);if(!Number.isInteger(i)||i<=0)throw new Error(t.positiveInteger(n));return i}process.exitCode=await os();export{os as run};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright © Jorge Bucaran <<https://jorgebucaran.com>>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2010-2022 Mike Bostock
|
|
2
|
+
|
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
4
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
|
5
|
+
and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
11
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
12
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
13
|
+
THIS SOFTWARE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2010-2021 Mike Bostock
|
|
2
|
+
|
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
4
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
|
5
|
+
and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
11
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
12
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
13
|
+
THIS SOFTWARE.
|