blade-code 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/blade.js +4 -3084
  2. package/dist/chunk-1en8fh5f.js +6 -0
  3. package/dist/chunk-2tpgtpcp.js +49 -0
  4. package/dist/chunk-3wnjpk9b.js +1 -0
  5. package/dist/chunk-3xqfqpa7.js +2 -0
  6. package/dist/chunk-4nsh53k6.js +4 -0
  7. package/dist/chunk-52k9k0w8.js +1 -0
  8. package/dist/chunk-5mtjqqav.js +8 -0
  9. package/dist/chunk-7ycmx7c2.js +2 -0
  10. package/dist/chunk-93b0x9b4.js +157 -0
  11. package/dist/chunk-akr185xe.js +2 -0
  12. package/dist/chunk-bhjw4b73.js +1 -0
  13. package/dist/chunk-d7zcd9xp.js +1 -0
  14. package/dist/chunk-dq65yfh6.js +1 -0
  15. package/dist/chunk-e2vtbvda.js +24 -0
  16. package/dist/chunk-ena4sxgr.js +41 -0
  17. package/dist/chunk-esnkk33h.js +21 -0
  18. package/dist/chunk-g5pasj7t.js +1 -0
  19. package/dist/chunk-j25kww7j.js +582 -0
  20. package/dist/chunk-j2ag7hh6.js +2 -0
  21. package/dist/chunk-j79jvd54.js +2063 -0
  22. package/dist/chunk-m99qhdkf.js +76 -0
  23. package/dist/chunk-n6e89s1v.js +6 -0
  24. package/dist/chunk-nx2zqct5.js +6 -0
  25. package/dist/chunk-q52j8tp4.js +1 -0
  26. package/dist/chunk-qwfywxs2.js +2 -0
  27. package/dist/chunk-set7v1rf.js +3 -0
  28. package/dist/chunk-t3zaj1t7.js +4 -0
  29. package/dist/chunk-th432d0b.js +1 -0
  30. package/dist/chunk-tmjmp9gq.js +1 -0
  31. package/dist/chunk-vd38synx.js +1 -0
  32. package/dist/chunk-vfdhz37s.js +3 -0
  33. package/dist/chunk-vwn39c84.js +2 -0
  34. package/dist/chunk-w7h3v075.js +10 -0
  35. package/dist/chunk-wr7w4af5.js +2 -0
  36. package/dist/chunk-wxp0yadf.js +1 -0
  37. package/dist/chunk-yddnm9n2.js +1 -0
  38. package/dist/chunk-z6tkw0b6.js +13 -0
  39. package/dist/chunk-zxf08z5f.js +34 -0
  40. package/dist/chunk-zyc1whnr.js +6 -0
  41. package/dist/web/assets/CodeBlockHighlighter-C86flFwh.js +1 -0
  42. package/dist/web/assets/FilePreview-BLcxez_T.js +7 -0
  43. package/dist/web/assets/MarkdownRenderer-BkQt-J8a.js +1 -0
  44. package/dist/web/assets/McpModal-B4ReoSE5.js +5 -0
  45. package/dist/web/assets/SettingsModal-QzwdsQwR.js +1 -0
  46. package/dist/web/assets/SettingsStore-E-aIqvyl.js +1 -0
  47. package/dist/web/assets/SkillsModal-CzE0m00G.js +1 -0
  48. package/dist/web/assets/TerminalPanel-DXA1C6Cg.js +1 -0
  49. package/dist/web/assets/dialog-CSpPttY0.js +1 -0
  50. package/dist/web/assets/index-DehGtSvJ.js +10 -0
  51. package/dist/web/assets/index-DmXmCQOW.css +1 -0
  52. package/dist/web/assets/useRequest-P_-JRihD.js +1 -0
  53. package/dist/web/assets/vendor-icons-DlzC8I7m.js +166 -0
  54. package/dist/web/assets/vendor-markdown-DIcugY1e.js +36 -0
  55. package/dist/web/assets/vendor-monaco-w6PwaWGP.js +11 -0
  56. package/dist/web/assets/vendor-radix-CKNFO4jS.js +45 -0
  57. package/dist/web/assets/vendor-react-Dm1xU4bP.js +49 -0
  58. package/dist/web/assets/vendor-xterm-9CEnUXvW.css +32 -0
  59. package/dist/web/assets/vendor-xterm-DuYZoU4T.js +49 -0
  60. package/dist/web/index.html +2 -2
  61. package/package.json +1 -1
  62. package/dist/web/assets/index-CVfbjhXj.js +0 -11
  63. package/dist/web/assets/index-C_uNajWk.js +0 -360
  64. package/dist/web/assets/index-QhJxewcm.css +0 -32
@@ -0,0 +1,6 @@
1
+ import{va as z}from"./chunk-m99qhdkf.js";import{Ia as w}from"./chunk-e2vtbvda.js";import{Bb as u}from"./chunk-set7v1rf.js";var q=u("General"),F=(b)=>{if(b.yolo){if(b.permissionMode&&b.permissionMode!=="yolo")throw Error("Cannot use both --yolo and --permission-mode with different values");b.permissionMode="yolo"}if(Array.isArray(b.allowedTools))b.allowedTools=b.allowedTools.flatMap((h)=>h.split(",").map((k)=>k.trim()).filter((k)=>k.length>0));if(Array.isArray(b.disallowedTools))b.disallowedTools=b.disallowedTools.flatMap((h)=>h.split(",").map((k)=>k.trim()).filter((k)=>k.length>0));if(Array.isArray(b.allowedTools)&&Array.isArray(b.disallowedTools)){let h=b.allowedTools.filter((k)=>b.disallowedTools.includes(k));if(h.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${h.join(", ")}`)}},G=async(b)=>{try{let k=await w.getInstance().initialize();if(z().config.actions.setConfig(k),b.debug)q.info("[CLI] 配置已加载到 Store")}catch(h){q.error("[CLI] [FAIL] 配置初始化失败",h instanceof Error?h.message:h),console.error(`
2
+ [FAIL] 配置初始化失败
3
+ `),console.error("原因:",h instanceof Error?h.message:"未知错误"),console.error(`
4
+ 请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
5
+ `),process.exit(1)}if(b.continue&&b.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},H=(b)=>{if(b.outputFormat&&b.outputFormat!=="text"&&!b.print&&!b.headless)throw Error("--output-format can only be used with --print or --headless");if(b.headless&&b.outputFormat&&!["text","jsonl"].includes(b.outputFormat))throw Error(`--headless only supports --output-format text|jsonl, but got "${b.outputFormat}". Use --print for json|stream-json support.`);if(b.print&&b.outputFormat&&!["text","json","stream-json"].includes(b.outputFormat))throw Error(`--print only supports --output-format text|json|stream-json, but got "${b.outputFormat}". Use --headless for jsonl support.`);if(b.inputFormat==="stream-json"&&b.print)q.warn("[WARN] Warning: stream-json input format may not work as expected with --print")};
6
+ export{F as v,G as w,H as x};
@@ -0,0 +1,49 @@
1
+ import{Ga as F,ra as $,ta as E,ua as q}from"./chunk-m99qhdkf.js";import{Bb as w}from"./chunk-set7v1rf.js";import{nanoid as O}from"nanoid";var Z=w("Spec");class X{static instance=null;fileManager=null;constructor(){}static getInstance(){if(!X.instance)X.instance=new X;return X.instance}static resetInstance(){X.instance=null}getStoreState(){return q.getState().spec}updateStoreState(z){q.setState((B)=>({spec:{...B.spec,...z}}))}async initialize(z){if(this.fileManager){Z.debug("SpecManager already initialized, skipping...");return}this.fileManager=new E(z),await this.fileManager.initializeDirectories();let B=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:B}),Z.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let z=this.getStoreState().steeringContext;if(!z)return null;let B=[];if(z.constitution)B.push(`## Constitution (Project Governance)
2
+
3
+ ${z.constitution}`);if(z.product)B.push(`## Product Vision
4
+
5
+ ${z.product}`);if(z.tech)B.push(`## Technology Stack
6
+
7
+ ${z.tech}`);if(z.structure)B.push(`## Code Structure
8
+
9
+ ${z.structure}`);return B.length>0?B.join(`
10
+
11
+ ---
12
+
13
+ `):null}async createSpec(z,B){let D=this.getFileManager();if(await D.changeExists(z))return{success:!1,message:`Spec "${z}" already exists`,error:"SPEC_EXISTS"};let K=await D.createChangeDir(z),J=D.createMetadata(z,B);await D.writeMetadata(z,J);let G=this.generateProposalTemplate(z,B);await D.writeSpecFile(z,"proposal",G);let U=this.getStoreState().recentSpecs.filter((Q)=>Q!==z);return U.unshift(z),this.updateStoreState({currentSpec:J,specPath:K,isActive:!0,recentSpecs:U.slice(0,10)}),{success:!0,message:`Spec "${z}" created successfully`,data:{spec:J,path:K}}}async loadSpec(z){let B=this.getFileManager(),D=await B.readMetadata(z);if(!D)return{success:!1,message:`Spec "${z}" not found`,error:"SPEC_NOT_FOUND"};let K=B.getChangePath(z),J=this.getStoreState().recentSpecs.filter((G)=>G!==z);return J.unshift(z),this.updateStoreState({currentSpec:D,specPath:K,isActive:!0,recentSpecs:J.slice(0,10)}),{success:!0,message:`Spec "${z}" loaded successfully`,data:{spec:D,path:K}}}closeSpec(){this.updateStoreState({currentSpec:null,specPath:null,isActive:!1})}exitSpecMode(){this.closeSpec()}async transitionPhase(z){let B=this.getCurrentSpec();if(!B)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};if(!$[B.phase].includes(z))return{success:!1,message:`Cannot transition from "${B.phase}" to "${z}"`,error:"INVALID_TRANSITION"};let J=await this.getFileManager().updatePhase(B.name,z);if(!J)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(this.updateStoreState({currentSpec:J}),z==="done")try{await F().setPermissionMode("default"),Z.info("Spec 已完成,已自动退出 Spec 模式")}catch(G){Z.error("自动退出 Spec 模式失败:",G)}return{success:!0,message:`Transitioned to "${z}" phase`,data:{spec:J,phase:z}}}getAllowedTransitions(){let z=this.getCurrentSpec();if(!z)return[];return $[z.phase]}async addTask(z,B,D){let K=this.getCurrentSpec();if(!K)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let J={id:O(8),title:z,description:B,status:"pending",dependencies:D?.dependencies||[],affectedFiles:D?.affectedFiles||[],complexity:D?.complexity||"medium"},G={...K,tasks:[...K.tasks,J],updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(K.name,G),this.updateStoreState({currentSpec:G}),{success:!0,message:`Task "${z}" added`,data:{task:J}}}async updateTaskStatus(z,B){let D=this.getCurrentSpec();if(!D)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let K=D.tasks.find((Q)=>Q.id===z);if(!K)return{success:!1,message:`Task "${z}" not found`,error:"TASK_NOT_FOUND"};let J={...K,status:B,completedAt:B==="completed"?new Date().toISOString():K.completedAt},G=D.tasks.map((Q)=>Q.id===z?J:Q),U={...D,tasks:G,currentTaskId:B==="in_progress"?z:D.currentTaskId===z?void 0:D.currentTaskId,updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(D.name,U),this.updateStoreState({currentSpec:U}),{success:!0,message:`Task status updated to "${B}"`,data:{task:J}}}getNextTask(){let z=this.getCurrentSpec();if(!z)return null;return z.tasks.find((B)=>{if(B.status!=="pending")return!1;return B.dependencies.every((D)=>{return z.tasks.find((J)=>J.id===D)?.status==="completed"})})||null}getTaskProgress(){let z=this.getCurrentSpec();if(!z||z.tasks.length===0)return{total:0,completed:0,percentage:0};let B=z.tasks.length,D=z.tasks.filter((J)=>J.status==="completed").length,K=Math.round(D/B*100);return{total:B,completed:D,percentage:K}}async listSpecs(z){let B=this.getFileManager(),D=[],K=await B.listActiveChanges();for(let J of K){let G=await B.readMetadata(J);if(!G)continue;if(z?.phase&&G.phase!==z.phase)continue;if(z?.tags&&!z.tags.some((Q)=>G.tags?.includes(Q)))continue;if(z?.query&&!G.name.toLowerCase().includes(z.query.toLowerCase())&&!G.description.toLowerCase().includes(z.query.toLowerCase()))continue;let U=this.calculateTaskProgress(G.tasks);D.push({name:G.name,description:G.description,phase:G.phase,updatedAt:G.updatedAt,path:B.getChangePath(J),isArchived:!1,taskProgress:U})}if(z?.includeArchived){let J=await B.listArchivedChanges();for(let G of J)D.push({name:G,description:"(archived)",phase:"done",updatedAt:"",path:`${B.getArchiveDir()}/${G}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return D.sort((J,G)=>{if(J.isArchived!==G.isArchived)return J.isArchived?1:-1;return new Date(G.updatedAt).getTime()-new Date(J.updatedAt).getTime()}),D}async archiveCurrentSpec(){let z=this.getCurrentSpec();if(!z)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let B=this.getFileManager(),D=await B.mergeSpecDeltas(z.name);return await B.updatePhase(z.name,"done"),await B.archiveChange(z.name),this.closeSpec(),{success:!0,message:`Spec "${z.name}" archived successfully`,data:{spec:{...z,phase:"done"}}}}async validateCurrentSpec(){let z=this.getCurrentSpec();if(!z)return{valid:!1,phase:"init",completeness:{proposal:!1,spec:!1,requirements:!1,design:!1,tasks:!1},issues:[{severity:"error",file:"meta",message:"No active spec"}],suggestions:["Create a new spec with /spec proposal <name>"]};let B=this.getFileManager(),D=[],K=[],[J,G,U,Q,V]=await Promise.all([B.readSpecFile(z.name,"proposal"),B.readSpecFile(z.name,"spec"),B.readSpecFile(z.name,"requirements"),B.readSpecFile(z.name,"design"),B.readSpecFile(z.name,"tasks")]),Y={proposal:!!J,spec:!!G,requirements:!!U,design:!!Q,tasks:!!V};if(z.phase==="requirements"&&!Y.requirements)D.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),K.push("Generate requirements using EARS format");if(z.phase==="design"&&!Y.design)D.push({severity:"warning",file:"design",message:"Design document is missing"}),K.push("Create architecture diagrams and API contracts");if(z.phase==="tasks"&&z.tasks.length===0)D.push({severity:"warning",file:"tasks",message:"No tasks defined"}),K.push("Break down the spec into atomic tasks");if(z.phase==="implementation"){let W=this.getTaskProgress();if(W.completed<W.total)D.push({severity:"info",file:"tasks",message:`${W.total-W.completed} tasks remaining`})}return{valid:D.filter((W)=>W.severity==="error").length===0,phase:z.phase,completeness:Y,issues:D,suggestions:K}}buildProgressContext(){if(!this.isActive())return null;let z=this.getCurrentSpec();if(!z||z.phase!=="implementation")return null;let B=z.tasks;if(B.length===0)return null;let D=B.filter((V)=>V.status==="completed").length,K=B.filter((V)=>V.status==="skipped").length,J=B.length,G=z.currentTaskId?B.find((V)=>V.id===z.currentTaskId):B.find((V)=>V.status==="in_progress"),U=B.find((V)=>{if(V.status!=="pending")return!1;return V.dependencies.every((Y)=>{return B.find((H)=>H.id===Y)?.status==="completed"})}),Q=[`当前正在执行 Spec: ${z.name} (${z.phase} 阶段)`,`进度: ${D}/${J} 任务已完成${K>0?`,${K} 个已跳过`:""}`];if(G)Q.push(`当前任务: #${B.indexOf(G)+1} - ${G.title}${G.description?` (${G.description})`:""}`);if(U&&U!==G)Q.push(`下一个任务: #${B.indexOf(U)+1} - ${U.title}`);if(D+K>=J)Q.push("所有任务已完成,可以进入验证和归档阶段。");return Q.join(`
14
+ `)}generateProposalTemplate(z,B){return`# ${z}
15
+
16
+ ## Summary
17
+
18
+ ${B}
19
+
20
+ ## Background
21
+
22
+ <!-- Why is this change needed? What problem does it solve? -->
23
+
24
+ ## Goals
25
+
26
+ <!-- What are the specific objectives of this change? -->
27
+
28
+ - [ ] Goal 1
29
+ - [ ] Goal 2
30
+
31
+ ## Non-Goals
32
+
33
+ <!-- What is explicitly out of scope? -->
34
+
35
+ ## Risks and Mitigations
36
+
37
+ <!-- What could go wrong? How will you address it? -->
38
+
39
+ | Risk | Mitigation |
40
+ |------|------------|
41
+ | | |
42
+
43
+ ## Open Questions
44
+
45
+ <!-- What needs to be clarified before proceeding? -->
46
+
47
+ 1.
48
+ `}calculateTaskProgress(z){let B=z.length,D=z.filter((K)=>K.status==="completed").length;return{total:B,completed:D}}}
49
+ export{X as ga};
@@ -0,0 +1 @@
1
+ import{a as y,b as A,c as C,d as D}from"./chunk-akr185xe.js";import"./chunk-vwn39c84.js";import"./chunk-j79jvd54.js";import"./chunk-zxf08z5f.js";import"./chunk-esnkk33h.js";import"./chunk-3xqfqpa7.js";import"./chunk-2tpgtpcp.js";import{Aa as q}from"./chunk-m99qhdkf.js";import"./chunk-e2vtbvda.js";import"./chunk-j25kww7j.js";import"./chunk-yddnm9n2.js";import"./chunk-ena4sxgr.js";import"./chunk-5mtjqqav.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";import H from"chalk";var R={command:"serve",describe:"Start a headless Blade server (no browser)",builder:y,handler:async(E)=>{let f=A(E);if(await q(),!process.env.BLADE_SERVER_PASSWORD)console.log(H.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let b=await D.listenAsync(f);if(console.log(`Blade server listening on http://${b.hostname}:${b.port}`),f.hostname==="0.0.0.0"){let F=C();for(let G of F)console.log(` Network: http://${G}:${b.port}`)}await new Promise(()=>{}),await b.stop()}};export{R as serveCommand};
@@ -0,0 +1,2 @@
1
+ var e={name:"blade-code",version:"0.4.2",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"node scripts/run-bun.js --watch src/blade.tsx","dev:serve":"node scripts/run-bun.js --watch src/blade.tsx serve --port 4097",build:"rm -rf dist && node scripts/run-bun.js run scripts/build.ts",start:"node scripts/run-bun.js run dist/blade.js",test:"node scripts/test.js","test:all":"vitest run --config vitest.config.ts","test:unit":"node scripts/test.js unit","test:integration":"node scripts/test.js integration","test:cli":"node scripts/test.js cli","test:headless-core":"node scripts/test.js headlessCore","test:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","benchmark:repo":"node scripts/run-bun.js run scripts/run-real-repo-benchmark.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=20.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0","bun-pty":"^0.4.8","node-pty":"1.0.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai":"^3.0.26","@ai-sdk/openai-compatible":"^2.0.4","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.6",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",hono:"^4.7.10",ink:"npm:@jrichman/ink@6.4.10","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",open:"^10.1.2",openai:"^6.2.0",picomatch:"^4.0.3",react:"^19.1.1","react-dom":"^19.1.1",semver:"^7.7.3","string-width":"^8.1.0",undici:"^7.16.0","write-file-atomic":"^7.0.0",ws:"^8.18.0",yaml:"^2.8.1",yargs:"^18.0.0",zod:"^3.24.2","zod-to-json-schema":"^3.24.6",zustand:"^5.0.9"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.1","@types/react-dom":"^19.1.1","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^3.0.0"}};function r(){return{name:e.name,version:e.version,description:e.description}}function n(){return e.version}function o(){return e.name}function d(){return e.description}function a(){return`v${e.version}`}function c(){return`v${e.version} © 2025 Blade Code`}
2
+ export{r as aa,n as ba,o as ca,d as da,a as ea,c as fa};
@@ -0,0 +1,4 @@
1
+ import{N as l,O as c,P as m,S as g,U as d}from"./chunk-j79jvd54.js";import{xb as u}from"./chunk-7ycmx7c2.js";async function C(){if((await l().initialize(u(),[])).plugins.length>0)await c()}async function h(t){let e=t.message||t._?.[0];if(typeof e==="string"&&e.trim())return e;let n=t.stdin??process.stdin;if(!n.isTTY){let a=[];for await(let i of n)a.push(i);return Buffer.concat(a).toString("utf-8").trim()}if(t.defaultMessage!==void 0)return t.defaultMessage;throw Error("No input provided")}async function R(t){if(!g(t))return{mode:"agent",content:t};let e=await d(t,{cwd:u(),workspaceRoot:u()});if(!e.success)return{mode:"output",content:`Error: ${e.error||"未知错误"}`,exitCode:1};let n=e.data;if(n?.action==="invoke_skill"){let{skillName:a,skillArgs:i}=n;return{mode:"agent",content:i?`Please use the "${a}" skill to help me with: ${i}`:`Please use the "${a}" skill.`}}if(n?.action==="invoke_custom_command"||n?.action==="invoke_plugin_command"){let a=n.processedContent;return{mode:"agent",content:`# Custom Command: /${n.commandName}
2
+
3
+ ${a}`}}return{mode:"output",content:e.content||e.message||"",exitCode:0}}function r(t){if(!(t instanceof Error))return!1;return t.message.includes("未找到会话")||t.message.includes("ENOENT")||t.message.includes("no such file")}async function s(t){try{return await m.loadSession(t,u())}catch(e){if(r(e))return null;throw e}}async function N(t){if(t.resume===!0||t.resume==="true")throw Error("--resume without a session ID is only supported in interactive UI mode");if(typeof t.resume==="string"&&t.resume.length>0)return{sessionId:t.resume,messages:await m.loadSession(t.resume)};if(t.continue){let e=await m.listSessions();if(e.length>0){let n=e[0].sessionId;return{sessionId:n,messages:await m.loadSession(n)}}}if(t.sessionId)return{sessionId:t.sessionId,messages:await s(t.sessionId)??[]};return{sessionId:`${t.fallbackSessionPrefix}-${Date.now()}`,messages:[]}}
4
+ export{C as p,h as q,R as r,N as s};
@@ -0,0 +1 @@
1
+ import{rb as a}from"./chunk-5mtjqqav.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as createChatServiceAsync};
@@ -0,0 +1,8 @@
1
+ import{Bb as R}from"./chunk-set7v1rf.js";var C=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],b={anthropic:"",openai:"","google-generative-ai":"",deepseek:"",groq:"",openrouter:"",azure:"",ollama:"",together:"",fireworks:"",mistral:"",cohere:"",perplexity:"",xai:"",default:""},f={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},h={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}},V=(F)=>{return h[F]||{}};import{createAnthropic as A}from"@ai-sdk/anthropic";import{createAzure as E}from"@ai-sdk/azure";import{createDeepSeek as k}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as P}from"@ai-sdk/google";import{createOpenAI as x}from"@ai-sdk/openai";import{createOpenAICompatible as z}from"@ai-sdk/openai-compatible";import{generateText as H,jsonSchema as T,streamText as K}from"ai";var B=R("Chat");function O(F){let q=new Set;for(let W of F)if(W.role==="assistant"&&W.tool_calls)for(let Q of W.tool_calls)q.add(Q.id);return F.filter((W)=>{if(W.role==="tool"){if(!W.tool_call_id)return!1;return q.has(W.tool_call_id)}return!0})}function N(F){if(typeof F==="string")return F;return F.filter((q)=>q.type==="text").map((q)=>q.text).join(`
2
+ `)}function L(F){let q=F;return q.text??q.textDelta??q.delta}function U(F,q={}){try{return JSON.parse(F)}catch{return B.warn("[VercelAIChatService] Failed to parse JSON, using fallback",{str:F}),q}}class D{model;config;constructor(F){this.config=F,this.model=this.createModel(F),B.debug("[VercelAIChatService] Initialized",{provider:F.provider,model:F.model})}createModel(F){let{provider:q,apiKey:W,baseUrl:Q,model:X,customHeaders:Z,apiVersion:$}=F;switch(q){case"openai":return x({apiKey:W,baseURL:Q||void 0,headers:Z})(X);case"anthropic":return A({apiKey:W,baseURL:Q||void 0,headers:Z})(X);case"gemini":{if(Q&&!this.isGeminiOfficialUrl(Q))return z({name:"gemini",apiKey:W,baseURL:Q,headers:Z})(X);return P({apiKey:W,baseURL:Q||void 0})(X)}case"google":case"google-generative-ai":case"google-vertex":{if(Q&&!this.isGeminiOfficialUrl(Q))return z({name:q,apiKey:W,baseURL:Q,headers:Z})(X);return P({apiKey:W,baseURL:Q||void 0})(X)}case"azure-openai":{let Y=this.extractAzureResourceName(Q);if(Y)return E({apiKey:W,resourceName:Y,apiVersion:$||"2024-08-01-preview"})(X);let J=this.buildAzureBaseUrl(Q,X);return z({name:"azure-openai",apiKey:W,baseURL:J,headers:{...Z,"api-key":W},queryParams:{"api-version":$||"2024-08-01-preview"}})(X)}case"azure":{let Y=this.extractAzureResourceName(Q);if(Y)return E({apiKey:W,resourceName:Y,apiVersion:$||"2024-08-01-preview"})(X);let J=this.buildAzureBaseUrl(Q,X);return z({name:"azure-openai",apiKey:W,baseURL:J,headers:{...Z,"api-key":W},queryParams:{"api-version":$||"2024-08-01-preview"}})(X)}case"deepseek":return k({apiKey:W,baseURL:Q||void 0,headers:Z})(X);default:return z({name:q,apiKey:W,baseURL:Q,headers:Z})(X)}}extractAzureResourceName(F){if(!F)return;let q=F.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return q?q[1]:void 0}buildAzureBaseUrl(F,q){if(!F)return"";let W=F.replace(/\/$/,"").replace(/\?.*$/,"");if(W.includes("/openai/deployments/"))return W;return`${W}/openai/deployments/${q}`}isGeminiOfficialUrl(F){return F.includes("generativelanguage.googleapis.com")||F.includes("aiplatform.googleapis.com")}needsThinkingReplayMetadata(){return/deepseek/i.test([this.config.provider,this.config.model,this.config.baseUrl].join(" "))}getThinkingReplayProviderOptions(F){let q=F?.trim();if(!q||!this.needsThinkingReplayMetadata())return;return{openaiCompatible:{reasoning_content:q}}}shouldFlattenDeepSeekThinkingToolHistory(){return this.needsThinkingReplayMetadata()}flattenDeepSeekThinkingToolHistory(F){let q=[],W,Q=()=>{if(!W)return;q.push({role:"assistant",content:N(W.content).trim()||"I will use the requested tool and continue from its result."}),W=void 0};for(let X of F){if(X.role==="system"){Q(),q.push({role:"user",content:`<system>
3
+ ${N(X.content)}
4
+ </system>`});continue}if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0&&X.reasoningContent?.trim()){Q(),W=X;continue}if(X.role==="tool"&&W){let Z=W.tool_calls?.find((Y)=>Y.id===X.tool_call_id),$=Z?.type==="function"?Z.function:void 0;q.push({role:"user",content:`Tool result for ${X.name||$?.name||"tool"}${$?.arguments?`(${$.arguments})`:""}:
5
+ ${N(X.content)}
6
+
7
+ Continue from this tool result.`});continue}Q(),q.push(X)}return Q(),q}convertMessages(F){let q=[],W=this.shouldFlattenDeepSeekThinkingToolHistory()?this.flattenDeepSeekThinkingToolHistory(F):F;for(let Q of W)if(Q.role==="system")if(Array.isArray(Q.content)){let X=Q.content.find(($)=>$.type==="text"),Z={role:"system",content:N(Q.content)};if(X?.providerOptions)Z.providerOptions=X.providerOptions;q.push(Z)}else q.push({role:"system",content:Q.content});else if(Q.role==="user")if(Array.isArray(Q.content)){let X=Q.content.map((Z)=>{if(Z.type==="text"){let $={type:"text",text:Z.text};if(Z.providerOptions)$.providerOptions=Z.providerOptions;return $}return{type:"image",image:Z.image_url.url}});q.push({role:"user",content:X})}else q.push({role:"user",content:Q.content});else if(Q.role==="assistant")if(Q.tool_calls&&Q.tool_calls.length>0){let X=Q.tool_calls.map((J)=>{let j=J.function;return{type:"tool-call",toolCallId:J.id,toolName:j?.name||"",input:U(j?.arguments||"{}",{})}}),Z=N(Q.content),$=Q.reasoningContent?.trim()?[{type:"reasoning",text:Q.reasoningContent}]:[],Y=this.getThinkingReplayProviderOptions(Q.reasoningContent);if(Z){let J={role:"assistant",content:[...$,{type:"text",text:Z},...X]};if(Y)J.providerOptions=Y;q.push(J)}else if($.length>0){let J={role:"assistant",content:[...$,...X]};if(Y)J.providerOptions=Y;q.push(J)}else q.push({role:"assistant",content:X})}else if(Q.reasoningContent?.trim()){let X=N(Q.content),Z=[{type:"reasoning",text:Q.reasoningContent}];if(X)Z.push({type:"text",text:X});let $={role:"assistant",content:Z},Y=this.getThinkingReplayProviderOptions(Q.reasoningContent);if(Y)$.providerOptions=Y;q.push($)}else q.push({role:"assistant",content:N(Q.content)});else if(Q.role==="tool")q.push({role:"tool",content:[{type:"tool-result",toolCallId:Q.tool_call_id,toolName:Q.name||"unknown",output:{type:"text",value:N(Q.content)}}]});return q}convertTools(F){if(!F||F.length===0)return;let q={};for(let W of F)q[W.name]={description:W.description,inputSchema:T(W.parameters)};return q}convertToolCalls(F){return F.map((q)=>({id:q.toolCallId,type:"function",function:{name:q.toolName,arguments:JSON.stringify(q.args??q.input??{})}}))}convertUsage(F,q){if(!F)return;let W=F.promptTokens??F.inputTokens??0,Q=F.completionTokens??F.outputTokens??0,X={promptTokens:W,completionTokens:Q,totalTokens:F.totalTokens??W+Q};if(q?.anthropic){if(q.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=q.anthropic.cacheCreationInputTokens;if(q.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=q.anthropic.cacheReadInputTokens}return X}isFallbackableError(F){if(!(F instanceof Error))return!1;let W=F.message.toLowerCase().match(/status[:\s]*(\d{3})/),Q=W?parseInt(W[1],10):F.status;return Q!==void 0&&[429,529,503].includes(Q)}async chat(F,q,W){let Q=Date.now();B.debug("[VercelAIChatService] Starting chat request");let X=O(F),Z=this.convertMessages(X),$=this.convertTools(q);try{let Y=await H({model:this.model,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),J=Date.now()-Q;B.debug("[VercelAIChatService] Response received in",J,"ms");let j=Y.toolCalls&&Y.toolCalls.length>0?this.convertToolCalls(Y.toolCalls):void 0,w=Array.isArray(Y.reasoning)?Y.reasoning.map((_)=>_.text).join(""):void 0;return{content:Y.text,reasoningContent:w,toolCalls:j,usage:this.convertUsage(Y.usage,Y.providerMetadata),finishReason:Y.finishReason}}catch(Y){let J=Date.now()-Q;if(B.error("[VercelAIChatService] Chat failed after",J,"ms"),this.isFallbackableError(Y)&&this.config.fallbackModel){B.warn(`[VercelAIChatService] Switching to fallback model (non-stream): ${this.config.fallbackModel}`);let j={...this.config,model:this.config.fallbackModel},w=this.createModel(j);try{let _=await H({model:w,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),S=_.toolCalls&&_.toolCalls.length>0?this.convertToolCalls(_.toolCalls):void 0,G=Array.isArray(_.reasoning)?_.reasoning.map((I)=>I.text).join(""):void 0;return{content:_.text||"",reasoningContent:G,toolCalls:S,usage:this.convertUsage(_.usage,_.providerMetadata),finishReason:_.finishReason}}catch(_){throw Error(`Fallback model (${this.config.fallbackModel}) also failed: ${_ instanceof Error?_.message:_}`,{cause:Y})}}throw Y}}async*streamChat(F,q,W){let Q=Date.now();B.debug("[VercelAIChatService] Starting stream request");let X=O(F),Z=this.convertMessages(X),$=this.convertTools(q);try{let Y=K({model:this.model,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}});B.debug("[VercelAIChatService] Stream started");let J=0;for await(let w of Y.fullStream)switch(w.type){case"text-delta":yield{content:L(w)};break;case"reasoning-delta":yield{reasoningContent:L(w)};break;case"tool-call":yield{toolCalls:[{index:J++,id:w.toolCallId,type:"function",function:{name:w.toolName,arguments:JSON.stringify(w.args??w.input??{})}}]};break;case"finish":yield{finishReason:w.finishReason,usage:this.convertUsage(w.totalUsage,w.providerMetadata)};break}let j=Date.now()-Q;B.debug("[VercelAIChatService] Stream completed in",j,"ms")}catch(Y){let J=Date.now()-Q;if(B.error("[VercelAIChatService] Stream failed after",J,"ms"),this.isFallbackableError(Y)&&this.config.fallbackModel){B.warn(`[VercelAIChatService] Switching to fallback model: ${this.config.fallbackModel}`),yield{modelFallback:!0};let j={...this.config,model:this.config.fallbackModel},w=this.createModel(j);try{let _=K({model:w,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),S=0;for await(let G of _.fullStream)switch(G.type){case"text-delta":yield{content:L(G)};break;case"reasoning-delta":yield{reasoningContent:L(G)};break;case"tool-call":yield{toolCalls:[{index:S++,id:G.toolCallId,type:"function",function:{name:G.toolName,arguments:JSON.stringify(G.args??G.input??{})}}]};break;case"finish":yield{finishReason:G.finishReason,usage:this.convertUsage(G.totalUsage,G.providerMetadata)};break}return}catch(_){throw Error(`Fallback model (${this.config.fallbackModel}) also failed: ${_ instanceof Error?_.message:_}`,{cause:Y})}}throw Y}}getConfig(){return{...this.config}}updateConfig(F){B.debug("[VercelAIChatService] Updating configuration"),this.config={...this.config,...F},this.model=this.createModel(this.config),B.debug("[VercelAIChatService] Configuration updated")}}var M=R("Service");async function s(F){let q=F;if(q.provider){let W=V(q.provider);if(Object.keys(W).length>0)q={...q,customHeaders:{...W,...q.customHeaders}},M.debug(`Injected ${q.provider} specific headers:`,Object.keys(W))}return v(q)}function v(F){return new D(F)}
8
+ export{C as ob,b as pb,f as qb,s as rb};
@@ -0,0 +1,2 @@
1
+ import{realpathSync as G}from"fs";import{cwd as K}from"process";var D=null;function N(){let q="";if(typeof process<"u"&&typeof process.cwd==="function"&&typeof G==="function"){let F=K();try{q=G(F).normalize("NFC")}catch{q=F.normalize("NFC")}}return{cwd:q,originalCwd:q,projectRoot:q}}function B(){if(!D)D=N();return D}function H(){return B().cwd}function Z(q){B().cwd=q.normalize("NFC")}function J(){return B().originalCwd}function $(){return B().projectRoot}function b(q){B().projectRoot=q.normalize("NFC")}var Q;((x)=>{x.DEFAULT="default";x.AUTO_EDIT="autoEdit";x.YOLO="yolo";x.PLAN="plan";x.SPEC="spec"})(Q||={});import{AsyncLocalStorage as R}from"async_hooks";var U=new R;function V(){return U.getStore()??H()}function W(){try{return V()}catch{return J()}}
2
+ export{Z as sb,J as tb,$ as ub,b as vb,Q as wb,W as xb};