@doubao-dev/cli 0.0.19 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/2514.js +8 -8
- package/dist/2932.js +1 -1
- package/dist/318.js +1 -1
- package/dist/3494.js +284 -0
- package/dist/{1122.js.LICENSE.txt → 3494.js.LICENSE.txt} +6 -0
- package/dist/4931.js +1 -1
- package/dist/7410.js +1 -1
- package/dist/{1664.js → 8713.js} +3 -3
- package/dist/@byted-doubao-apps/create.js +1 -1
- package/dist/@byted-doubao-apps/login.js +1 -1
- package/dist/@byted-doubao-apps/login~1.js +1 -1
- package/dist/@byted-doubao-apps/template-empty/README.md +0 -2
- package/dist/@byted-doubao-apps/template-empty/package.json +3 -3
- package/dist/@byted-doubao-apps/template-starter/README.md +1 -1
- package/dist/@byted-doubao-apps/template-starter/package.json +3 -3
- package/dist/@byted-hdt/cli.js +1 -1
- package/dist/@inquirer/select.js +1 -1
- package/dist/@lynx-js/web-core-canary.js +2 -13
- package/dist/@lynx-js/web-core-canary~1.js +2 -0
- package/dist/app.js +1 -1
- package/dist/assets/web-sdk-debugger/chrome-devtools/entrypoints/devtools_app/devtools_app.js +9 -7
- package/dist/assets/web-sdk-debugger/chrome-devtools/panels/wsd-debug/WsdDebug.js +9 -7
- package/dist/assets/web-sdk-debugger/chrome-devtools/panels/wsd-debug/WsdDebugMeta.js +79 -77
- package/dist/assets/web-sdk-debugger/index.html +1 -1
- package/dist/assets/web-sdk-debugger/static/css/index.9952f4197c.css +1 -0
- package/dist/assets/web-sdk-debugger/static/js/{741.ece428827e.js → 48.8c158322ee.js} +60 -67
- package/dist/assets/web-sdk-debugger/static/js/48.8c158322ee.js.LICENSE.txt +5 -0
- package/dist/assets/web-sdk-debugger/static/js/async/257.4d55bd5ce8.js +1 -0
- package/dist/assets/web-sdk-debugger/static/js/async/{web-core-template-loader-thread.f9f3ef68b1.js → web-core-template-loader-thread.20d5b2a451.js} +2 -2
- package/dist/assets/web-sdk-debugger/static/js/async/{web-core-worker-chunk.002a4f7b9d.js → web-core-worker-chunk.71b9323071.js} +1 -1
- package/dist/assets/web-sdk-debugger/static/js/index.e5bc5f1bbd.js +26 -0
- package/dist/assets/web-sdk-debugger/static/js/{lib-polyfill.8cf763c414.js → lib-polyfill.4f00df8f2a.js} +1 -1
- package/dist/assets/web-sdk-debugger/wsd/doubao-apps-api.template.js +0 -0
- package/dist/assets/web-sdk-debugger/wsd/doubao-apps-framework.template.js +0 -0
- package/dist/auth.js +1 -1
- package/dist/browser.js +1 -1
- package/dist/csstree.esm.js +12 -0
- package/dist/dbx-demo.js +1 -1
- package/dist/dbx.js +1 -1
- package/dist/demo-server.js +1 -1
- package/dist/dev-config.js +1 -1
- package/dist/dev-service-client.js +6 -6
- package/dist/dev-shell.js +1 -1
- package/dist/dev.js +7 -7
- package/dist/eval.js +1 -1
- package/dist/gen-explore.js +1 -1
- package/dist/gen-trajectory.js +1 -1
- package/dist/get.js +1 -1
- package/dist/init.js +2 -2
- package/dist/ink.js +1 -1
- package/dist/json-file.js +1 -1
- package/dist/login.js +1 -1
- package/dist/main.js +1 -1
- package/dist/manifest-mcp-config.js +1 -1
- package/dist/ora.js +1 -1
- package/dist/portal.js +1 -1
- package/dist/project-layout.js +1 -1
- package/dist/prompt.js +1 -1
- package/dist/prompts.js +1 -1
- package/dist/report.js +1 -1
- package/dist/run-registry.js +1 -1
- package/dist/run.js +1 -1
- package/dist/sandbox.js +1 -1
- package/dist/sdk.js +67 -133
- package/dist/sdk~1.js +67 -133
- package/dist/server.js +1 -1
- package/dist/shared.js +1 -1
- package/dist/simulator-client.js +1 -1
- package/dist/skill.js +1 -1
- package/dist/skills~1.js +1 -1
- package/dist/static/assets/web-view-proxy-page-client.js +1 -0
- package/dist/static/assets/web-view-proxy-service-worker.js +1 -0
- package/dist/status.js +1 -1
- package/dist/status~1.js +1 -1
- package/dist/stop.js +1 -1
- package/dist/update.js +1 -1
- package/dist/upgrade.js +1 -1
- package/dist/upload.js +1 -1
- package/dist/validate.js +1 -1
- package/dist/workspace.js +1 -1
- package/dist/yaml.js +1 -1
- package/package.json +2 -2
- package/skills/doubao-agentic-service-development/references/dev-debug.md +6 -6
- package/skills/doubao-agentic-service-development/references/frontend/doubao-agentic-service-api/01-/345/237/272/347/241/200.md +105 -25
- package/skills/doubao-agentic-service-development/references/frontend/doubao-agentic-service-api/02-/347/263/273/347/273/237.md +118 -6
- package/skills/doubao-agentic-service-development/references/frontend/doubao-agentic-service-api/06-/344/272/244/344/272/222.md +18 -8
- package/skills/doubao-agentic-service-development/references/frontend/doubao-agentic-service-api/quick-reference.md +3 -3
- package/skills/doubao-agentic-service-development/references/frontend/examples/page-widget-basics.md +2 -3
- package/skills/doubao-agentic-service-development/references/frontend/guides/component-development.md +2 -1
- package/skills/doubao-agentic-service-development/references/frontend/guides/debugger-mcp.md +7 -1
- package/skills/doubao-agentic-service-development/references/frontend/rules/dos-and-donts.md +4 -7
- package/skills/doubao-agentic-service-development/references/frontend-dev.md +0 -1
- package/skills/doubao-agentic-service-development/references/manifest-guide.md +5 -4
- package/skills/doubao-agentic-service-development/references/mcp-protocol.md +4 -3
- package/dist/1122.js +0 -277
- package/dist/assets/web-sdk-debugger/static/css/index.fe34ed7927.css +0 -1
- package/dist/assets/web-sdk-debugger/static/js/index.da81c37197.js +0 -26
- package/dist/push-page.js +0 -1
- package/dist/push-widget.js +0 -1
package/dist/eval.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e;import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{isRecord as r,parseInteger as o,option_Option as n,command_Command as i,CliError as s,http_getApiBaseUrl as a,runCommand as l,chalk_source as c}from"./1664.js";import"./yaml.js";import{DBX_DEMO_NAMES as u,getDBXDemo as d,isDBXDemoName as m,readDBXDemoServerState as p}from"./dbx-demo.js";import{resolveProjectLayout as _}from"./project-layout.js";import{extractMCPHeadersFromManifest as f}from"./manifest-mcp-config.js";import{verifyYAML as g}from"./app.js";import{SimulatorStreamError as h,runSimulatorStream as y}from"./simulator-client.js";var v={};t.r(v),t.d(v,{default:()=>ey});let w=t("node:fs");var S=t.n(w);let $=t("node:path");var b=t.n($);let C=t("../../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/index.js"),x=new Set(["USER","ASSISTANT","TOOL"]);function P(e,t){if(!S().existsSync(e))throw E(`${t}_file_not_found`,`${t} file not found: ${e}`,`请检查 --${t} 路径;相对路径会按 --project-path 解析。`);if(!S().statSync(e).isFile())throw E(`${t}_path_not_file`,`${t} path must be a file: ${e}`,`请检查 --${t} 路径,不能传目录。`);return S().readFileSync(e,"utf8")}function E(e,t,r){let o=Error(t);return o.details={code:e,message:t,suggestion:r},o}function M(e,t){return b().isAbsolute(e)?e:b().resolve(t,e)}function j(e){return e.includes("/")||e.endsWith(".md")||e.endsWith(".json")||e.endsWith(".yaml")||e.endsWith(".yml")}function k(e){return"string"==typeof e&&e.trim()?e:void 0}function T(e){var t,o;let n=[],i=e.preflight.filter(e=>"error"===e.level);for(let r of(n.push(...i),n.push(...(t=e.result.trace_events,o=e.result.request_id,t.filter(e=>e.error).map(e=>({code:String(e.error?.code||"trace_error"),level:"error",message:String(e.error?.user_message||e.error?.message||e.summary||"trace error"),suggestion:O(e.error?.code,o),details:e.error})))),e.result.stream_errors??[]))n.push(function(e){var t;let r=String(e?.message||"stream error"),o=String(e?.code||"stream_error");return{code:o,level:"error",message:r,suggestion:"string"==typeof e?.suggestion?e.suggestion:O(o,"")||((t=r).includes("exceeded max step")?"模型在最大步数内没有收口。请检查 skill 是否让模型重复查询/重复调用工具,或临时调大 --max-step 辅助定位。":t.includes("mcp tool invalid response")?"MCP 工具返回未通过 context post-hook。请对照 manifest 检查 tool_name、entity_type、主键字段和 structuredContent。":void 0),details:e?.details??e}}(r));if(!n.some(e=>"error"===e.level)){let t=e.cardExpectation??"auto";n.push(...function(e,t,r){let o=[];for(let t of e){let e=t.result_preview||"";(t.result_error||e.includes("MCP error")||e.includes("Input validation error"))&&o.push({code:"mcp_tool_result_error",level:"error",message:`MCP tool ${t.tool_name} returned an error result`,suggestion:"工具已被模型调用,但 MCP tools/call 返回业务/参数错误。请检查 Agent Flow 里的 args 与工具入参 schema 是否一致;常见问题是模型传了字符串数字,可在 MCP server 用 z.coerce.number() 或自行兼容转换。",details:{tool_name:t.tool_name,tool_call_id:t.tool_call_id,arguments:t.arguments,result_preview:e}})}return"auto"===r&&e.length>0&&0===t&&0===o.length&&o.push({code:"tool_called_but_no_card",level:"warn",message:"Tool call finished, but no card_delta was emitted",suggestion:"如果这是出卡工具,请检查工具 result 是否包含 structuredContent.entities、entity_type 是否在 manifest.entities 声明、tool_card_binding 是否绑定该工具。"}),o}(e.result.tool_calls,e.result.cards.length,t));let r=e.result.tool_calls.map(e=>e.tool_name),o=e.evalCase.expect?.tool_calls??[];o.length>0&&!function(e,t){let r=0;for(let o of t)if(o===e[r]&&(r+=1),r===e.length)return!0;return 0===e.length}(o,r)&&n.push({code:"expectation_tool_chain_mismatch",level:"error",message:`expected tool chain ${o.join(" -> ")}, actual ${r.join(" -> ")||"-"}`,suggestion:"请检查 skill 的工具流程描述、query 是否表达了对应意图,以及 MCP tools 是否暴露了这些工具。"});let i=e.evalCase.expect?.card;if(i||"required"===t){let t=i?.min_count??1,r=i?.widget_id?e.result.cards.filter(e=>e.widget_id===i.widget_id):e.result.cards;r.length<t&&n.push({code:"card_not_emitted",level:"error",message:i?.widget_id?`expected at least ${t} card(s) with widget_id ${i.widget_id}, actual ${r.length}`:`expected at least ${t} card(s), actual ${e.result.cards.length}`,suggestion:"如果工具已成功,重点检查 manifest.tools、entities.*.tool_card_binding、MCP result structuredContent.entities 和模型是否在工具后触发出卡。"})}for(let r of("none"===t&&e.result.cards.length>0&&n.push({code:"unexpected_card_emitted",level:"error",message:`expected no card, actual ${e.result.cards.length}`,suggestion:"如果当前用例不应出卡,请检查工具是否返回了非空 structuredContent.entities,或检查 manifest 中该工具的 tool_card_binding。"}),e.result.tool_calls))!e.manifest.tools[r.tool_name]&&e.manifest.cardBindings[r.tool_name]&&n.push({code:"card_tool_not_declared",level:"error",message:`${r.tool_name} has card binding but is not declared in manifest.tools`,suggestion:`请在 manifest.tools.${r.tool_name} 中声明 output.entity_types。`})}let s=function(e){let t=new Set,o=[];for(let n of e){if(function(e,t){return"SIMULATOR_STREAM_ERROR"===e.code&&t.some(t=>{if(t.code===e.code)return!1;if(e.message.includes(t.message))return!0;let o=A(function(e,t){if(!r(e))return;let o=e[t];return r(o)?o:void 0}(t.details,"details"),"raw_error")||A(t.details,"raw_error");return void 0!==o&&e.message.includes(o)})}(n,o))continue;let e=`${n.level}\u0000${n.code}\u0000${n.message}`;t.has(e)||(t.add(e),o.push(n))}return o}(n),a=0===s.filter(e=>"error"===e.level).length;return{ok:a,verdict:a?"PASS":"FAIL",case:e.evalCase,context:{history_count:e.evalCase.history_messages?.length??0,query:e.evalCase.query,mcp_url:e.evalCase.mcp.url,gateway_origin:e.gatewayOrigin,max_step:e.evalCase.max_step},preflight:e.preflight,errors:s,...e.result}}function A(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function O(e,t){return"miniapp_mcp_result_invalid"===e?"MCP 工具返回未通过智能服务协议校验。请检查返回 JSON 是否包含 content/structuredContent,entity_type 是否在 manifest.entities 中声明,实体主键字段是否匹配 is_entity_id。":"agent_run_failed"===e?`Agent 运行失败。请查看 request_id=${t||"-"} 对应 trace,重点关注是否重复 tool call、max_step 不足或模型没有触发卡片输出。`:"tool_call_or_report_failed"===e?"工具调用或结果上报失败。请检查 MCP tools/call 是否可用,以及返回的 structuredContent/entities 是否符合 manifest 声明。":void 0}let q="2025-11-25",I=["application/json","text/event-stream"];async function N(e,t,r){return Z(e)?L(e,t,r):U(e,t,r)}async function R(t,r){var o,n;if(e&&(o=e.url,n=t,Q(o)===Q(n)))return function(e){var t;let r=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;let{_response_meta:t,...r}=e;return r}(e);if(!r||"object"!=typeof r){let e=String(r??"");return{content:e,raw_result_text:e,raw_mcp_result_json:e}}if("string"==typeof r.content||"raw_mcp_result_json"in r||"raw_result_text"in r||"structured"in r){let e="string"==typeof r.content?r.content:JSON.stringify(r.content??""),t=r.raw_mcp_result_json||r.raw_result_text||e;return{...r,content:e,raw_result_text:r.raw_result_text||t,raw_mcp_result_json:r.raw_mcp_result_json||t,structured:r.structured??r.structuredContent,is_error:r.is_error??r.isError}}let o=JSON.stringify(r);return{content:o,structured:r.structuredContent,raw_result_text:o,raw_mcp_result_json:o,is_error:!0===r.isError,miniapp:(t=r,Array.isArray(t?.content)&&t?.structuredContent&&"object"==typeof t.structuredContent)?{is_mini_app:!0,mcp_channel:"flow_miniapp"}:void 0}}("sse"===e.kind?await D(e,r):await H(e,r));throw Error("MCP session is not initialized. Please ensure fetchMCPDescriptor runs before tools/call.")}async function U(t,r,o){let n=G(t);try{let t=await B(n,{jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:q,capabilities:{},clientInfo:{name:"dbx-simulator-eval",version:"0.1.0"}}},{headers:o}),i=t.body.result?.protocolVersion??q,s=t.headers.get("mcp-session-id")??void 0;e={kind:"streamable",url:n,sessionID:s,protocolVersion:i,headers:o},await B(n,{jsonrpc:"2.0",method:"notifications/initialized",params:{}},{sessionID:s,protocolVersion:i,allowEmpty:!0,headers:o});let a=await B(n,{jsonrpc:"2.0",id:2,method:"tools/list",params:{}},{sessionID:s,protocolVersion:i,headers:o});return{tools:{server_id:ee(n),name:ee(n),description:"Standard MCP Streamable HTTP server",app_key:r,protocol:"streamable_http",tools:(a.body.result?.tools??[]).map(e=>({name:e.name,description:e.description??"",input_schema_json:JSON.stringify(e.inputSchema??e.input_schema??{})}))}}}catch(t){throw e=void 0,Error(`standard MCP Streamable HTTP initialize/tools/list failed: ${n}: ${t?.message||String(t)}`)}}async function L(t,r,o){let n=Y(t),i={kind:"sse",url:n,pending:new Map,headers:o};e=i;try{await K(i,{jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"dbx-simulator-eval",version:"0.1.0"}}},!1),await K(i,{jsonrpc:"2.0",method:"notifications/initialized",params:{}},!0);let e=await K(i,{jsonrpc:"2.0",id:2,method:"tools/list",params:{}},!1);return{tools:{server_id:ee(n),name:ee(n),description:"Standard MCP SSE server",app_key:r,protocol:"sse",tools:(e.result?.tools??[]).map(e=>({name:e.name,description:e.description??"",input_schema_json:JSON.stringify(e.inputSchema??e.input_schema??{})}))}}}catch(t){throw W(i),e=void 0,Error(`standard MCP SSE initialize/tools/list failed: ${n}: ${t?.message||String(t)}`)}}async function H(e,t){let r=ei(t.tool_name);if(!r)throw Error("MCP tool name is empty");return(await B(e.url,{jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:r,arguments:es(t.arguments)??ea(ei(t.arguments_json))??{}}},{sessionID:e.sessionID,protocolVersion:e.protocolVersion,headers:e.headers})).body.result}async function D(e,t){let r=ei(t.tool_name);if(!r)throw Error("MCP tool name is empty");return(await K(e,{jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:r,arguments:es(t.arguments)??ea(ei(t.arguments_json))??{}}},!1)).result}async function K(e,t,r){let o;if(await J(e),!e.endpointURL)throw Error("MCP SSE did not provide endpoint event");let n=et(t),i=er(t)||"unknown",s=eo(t),a=s?`${i}:${s}`:i,l=null!==n,c=l?new Promise((t,r)=>{let o=setTimeout(()=>{e.pending.delete(n),r(Error(`MCP SSE request timed out: ${a}`))},1e4);e.pending.set(n,{resolve:t,reject:r,timeout:o})}):void 0;try{var u;let r;o=await X(e.endpointURL,{method:"POST",headers:(u=e.headers,(r=new Headers(u)).set("Content-Type","application/json"),r),body:JSON.stringify(t)},1e4,`MCP SSE POST ${a}`)}catch(t){throw l&&V(e,n),t}let d=await o.text();if(!o.ok)throw l&&V(e,n),Error(`MCP SSE POST ${o.status}: ${d}`);if(!l)return{};let m=await c;if(!m&&!r)throw Error("MCP SSE returned empty response");if(m?.error)throw Error(`MCP SSE error: [${m.error.code}] ${m.error.message}`);return m}async function J(e){if(e.ready)return e.ready;let t=new AbortController;return e.abortController=t,e.ready=new Promise((r,o)=>{let n=!1,i=setTimeout(()=>{t.abort(),s(Error(`MCP SSE endpoint event timed out: ${e.url}`))},1e4),s=e=>{n||(n=!0,clearTimeout(i),o(e))};z(e,t,t=>{e.endpointURL=new URL(t,e.url).toString(),n||(n=!0,clearTimeout(i),r())},s)}).catch(t=>{throw W(e,t),t}),e.ready}async function z(e,t,r,o){try{var n;let i,s=await fetch(e.url,{method:"GET",headers:(n=e.headers,(i=new Headers(n)).set("Accept","text/event-stream"),i),signal:t.signal});if(!s.ok||!s.body){let e=await s.text();o(Error(`MCP SSE GET ${s.status}: ${e}`));return}if(!String(s.headers.get("content-type")??"").toLowerCase().includes("text/event-stream"))return void o(Error(`MCP SSE GET content-type=${s.headers.get("content-type")??"-"}`));await F(e,s.body,r),t.signal.aborted||W(e,Error("MCP SSE stream closed"))}catch(r){if(!t.signal.aborted){let t=r instanceof Error?r:Error(String(r));o(t),W(e,t)}}}async function F(e,t,r){let o=t.getReader(),n=new TextDecoder,i="",s="message",a=[],l=()=>{if(0===a.length){s="message";return}(function(e,t,r,o){let n;if("endpoint"===t)return o(r.trim());if(!r.trim())return;try{n=JSON.parse(r)}catch{return}let i=n.id;if(null==i)return;let s=e.pending.get(i);s&&(clearTimeout(s.timeout),e.pending.delete(i),s.resolve(n))})(e,s,a.join("\n"),r),s="message",a=[]};for(;;){let{done:e,value:t}=await o.read();if(e)break;let r=(i+=n.decode(t,{stream:!0})).search(/\r?\n/);for(;r>=0;){let e=i.slice(0,r).replace(/\r$/,"");i=i.slice(r+("\r"===i[r]&&"\n"===i[r+1]?2:1)),""===e?l():e.startsWith("event:")?s=e.slice(6).trim():e.startsWith("data:")&&a.push(e.slice(5).trimStart()),r=i.search(/\r?\n/)}}i&&a.push(i),l()}function V(e,t){if(null===t)return;let r=e.pending.get(t);r&&(clearTimeout(r.timeout),e.pending.delete(t))}function W(e,t=Error("MCP SSE session closed")){for(let[r,o]of(e.abortController?.abort(),e.abortController=void 0,e.endpointURL=void 0,e.ready=void 0,e.pending.entries()))clearTimeout(o.timeout),o.reject(t),e.pending.delete(r)}async function B(e,t,r){var o,n;let i,s,a,l=er(t)||"unknown",c=eo(t),u=c?`${l}:${c}`:l,d=await X(e,{method:"POST",headers:(o=t,(i=new Headers((n=r).headers)).set("Content-Type","application/json"),i.set("Accept",I.join(", ")),(s=er(o))&&i.set("Mcp-Method",s),(a=eo(o))&&i.set("Mcp-Name",a),n.protocolVersion&&i.set("MCP-Protocol-Version",n.protocolVersion),n.sessionID&&i.set("Mcp-Session-Id",n.sessionID),i),body:JSON.stringify(t)},1e4,`MCP Streamable HTTP ${u}`),m=await d.text();if(!d.ok)throw Error(`MCP Streamable HTTP ${d.status}: ${m}`);if(!m&&r.allowEmpty)return{body:{},headers:d.headers};if(!m)throw Error("MCP Streamable HTTP returned empty response");let p=function(e,t,r){if(t?.toLowerCase().includes("text/event-stream")){let t=function(e){let t=[],r=[],o=()=>{if(0===r.length)return;let e=r.join("\n");e.trim()&&t.push(JSON.parse(e)),r=[]};for(let t of e.split(/\r?\n/)){if(""===t){o();continue}t.startsWith("data:")&&r.push(t.slice(5).trimStart())}return o(),t}(e),o=t.find(e=>{var t,o;return t=e,null!==(o=r)&&en(t)&&t.id===o})??t.find(en);if(!o)throw Error("MCP SSE response has no JSON-RPC response");return o}return JSON.parse(e)}(m,d.headers.get("content-type"),et(t));if(p.error)throw Error(`MCP Streamable HTTP error: [${p.error.code}] ${p.error.message}`);return{body:p,headers:d.headers}}function G(e){let t=new URL(e);return("/"===t.pathname||""===t.pathname)&&(t.pathname="/mcp"),t.toString()}function Y(e){return new URL(e).toString()}function Z(e){return new URL(e).pathname.replace(/\/+$/,"").toLowerCase().endsWith("/sse")}function Q(e){return Z(e)?Y(e):G(e)}async function X(e,t,r,o){let n=new AbortController,i=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}catch(e){if(e instanceof Error&&"AbortError"===e.name)throw Error(`${o} timed out after ${r}ms`);throw e}finally{clearTimeout(i)}}function ee(e){let t=new URL(e);return`${t.hostname}_${t.port||t.protocol.replace(":","")}${t.pathname.replace(/[^A-Za-z0-9_-]/g,"_")}`}function et(e){return e&&"object"==typeof e&&"id"in e?e.id??null:null}function er(e){if(e&&"object"==typeof e&&"method"in e)return e.method}function eo(e){if(!e||"object"!=typeof e)return;let t=e.params;return t&&"object"==typeof t?"string"==typeof t.name?t.name:"string"==typeof t.uri?t.uri:void 0:void 0}function en(e){return!!(e&&"object"==typeof e&&"id"in e&&("result"in e||"error"in e))}function ei(e){return"string"==typeof e?e:""}function es(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function ea(e){if(e)try{return JSON.parse(e)}catch{return}}function el(e,t){return{code:e,level:"info",message:t}}function ec(e,t,r){return{code:e,level:"warn",message:t,suggestion:r}}function eu(e,t,r){return{code:e,level:"error",message:t,suggestion:r}}async function ed(t){try{let e,o=function(e){let t=b().resolve(e.projectPath),r=_(t),o=e.demo?function(e){try{return d(e).evalCase}catch{throw Error(`unknown simulator eval demo: ${e}. Supported demos: ${u.join(", ")}`)}}(e.demo):{},n=e.demo&&m(e.demo)?p(t,e.demo)?.streamableUrl:void 0,i={...o,...e.query?{query:e.query}:{},...void 0!==e.maxStep?{max_step:e.maxStep}:{}};if(e.historyPath&&(i.history_messages=function(e){if(!S().existsSync(e))throw E("history_file_not_found",`history file not found: ${e}`,"请检查 --history 路径;历史文件应为消息数组。");let t=function(e,t,r){try{return t.endsWith(".json")?JSON.parse(e):C.qg(e)}catch(e){throw E(`${r}_file_parse_failed`,`${r} file parse failed: ${e?.message||String(e)}`,`请检查 ${t} 的语法和缩进。`)}}(S().readFileSync(e,"utf8"),e,"history");if(!Array.isArray(t))throw E("history_file_invalid","history file must be an array","请把 history 文件写成数组,例如 [{ role: USER, content: hello }]。");return t}(M(e.historyPath,t))),e.skillPath)i.skill=P(M(e.skillPath,t),"skill");else if(i.skill&&j(i.skill))i.skill=P(M(i.skill,t),"skill");else if(!i.skill){let e=r.skillPath;S().existsSync(e)&&(i.skill=P(e,"skill"))}if(e.manifestPath)i.manifest=P(M(e.manifestPath,t),"manifest");else if(i.manifest&&j(i.manifest))i.manifest=P(M(i.manifest,t),"manifest");else if(!i.manifest){let e=r.manifestPath;S().existsSync(e)&&(i.manifest=P(e,"manifest"))}if(n&&(i.manifest=function(e,t){if("string"==typeof e)return e.trim()?[e.trimEnd(),"\nmcp_server:",` end_point: ${JSON.stringify(t)}`," mcp_config:\n protocol: Streamable\n"].join("\n"):e}(i.manifest,n)),function(e){if(!e.query||"string"!=typeof e.query||!e.query.trim())throw E("query_required","simulator eval requires query","请通过 --query 传入本轮用户问题。");if(!e.skill||"string"!=typeof e.skill)throw E("skill_required","simulator eval requires skill text or skill path","请在项目 skill/SKILL.md 放置 Skill,或通过 --skill 传入路径。");if(!e.manifest||"string"!=typeof e.manifest)throw E("manifest_required","simulator eval requires manifest YAML text or path","请在项目 manifest.yaml 放置 Manifest,或通过 --manifest 传入路径。")}(i),i.history_messages=(i.history_messages??[]).map((e,t)=>{if(!e||"object"!=typeof e)throw E("history_message_invalid",`history_messages[${t}] must be an object`,"请把每条历史消息写成 { role: USER|ASSISTANT|TOOL, content: string }。");let r=String(e.role||"").toUpperCase();if(!x.has(r))throw E("history_message_role_invalid",`history_messages[${t}].role must be USER, ASSISTANT or TOOL`,"请把 role 改成 USER、ASSISTANT 或 TOOL。");if("string"!=typeof e.content||!e.content.trim())throw E("history_message_content_invalid",`history_messages[${t}].content must be a non-empty string`,"请为该历史消息补充非空 content。");return{role:r,content:e.content}}),i.max_step=i.max_step??15,!Number.isInteger(i.max_step)||i.max_step<=0)throw E("max_step_invalid","max_step must be a positive integer","请删除 max_step 使用默认值 15,或通过 --max-step 传入正整数。");return i}(t),n=await g(o.manifest,"compatible");if(!n.data?.success||!n.data.manifest)throw new eh("manifest validation failed",{code:"manifest_validation_failed",message:"manifest validation failed",errors:n.data?.errors??[],warnings:n.data?.warnings??[],log_id:n.log_id});let i=function(e,t){if(!r(t))throw E("manifest_parse_result_missing","simulator eval requires parsed manifest from yaml verify","请先确认后端 /yaml/verify 返回 data.manifest。");let o=r(t.mcp_server)?t.mcp_server:void 0,n=k(t.app_key),i=k(o?.end_point);if(!n)throw E("app_id_required","simulator eval requires manifest AppID","请在 manifest.yaml 配置 app_key(该字段对外称 AppID)。");if(!i)throw E("mcp_url_required","simulator eval requires manifest mcp_server.end_point","请在 manifest.yaml 配置 mcp_server.end_point。");return function(e,t,r){try{let t=new URL(e);if("http:"===t.protocol||"https:"===t.protocol)return}catch{}throw E(t,`${r} must be an http(s) URL: ${e}`,`请把 ${r} 配置为 http:// 或 https:// 开头的 MCP endpoint。`)}(i,"mcp_url_invalid","manifest.mcp_server.end_point"),{...e,app_key:n,app_name:k(t.name),mcp:{url:i,description:k(o?.description),headers:f(t)}}}(o,n.data.manifest),s=function(e){if(!r(e)){var t;let e;throw t="manifest must be a parsed object",(e=Error(t)).details={code:"manifest_yaml_invalid",message:t,suggestion:"请先运行 `dbx app artifacts validate <manifest.yaml>`,确认后端能解析 manifest。"},e}let o=r(e.tools)?e.tools:{},n=r(e.entities)?e.entities:{},i={};for(let e of Object.values(n))if(r(e)&&r(e.tool_card_binding))for(let[t,r]of Object.entries(e.tool_card_binding))"string"==typeof r&&(i[t]=r);return{raw:e,appKey:"string"==typeof e.app_key?e.app_key:void 0,tools:o,entities:n,cardBindings:i}}(n.data.manifest),l=await N(i.mcp.url,i.app_key,i.mcp.headers).catch(e=>{var t,r,o;let n,s,a,l,c,u=(t=e,r=i.mcp.url,(c=(o=l=String(t?.message||t),s=(n=o.match(/<pre>([\s\S]*?)<\/pre>/i)?.[1])?n.replace(/<br\s*\/?>/gi,"\n").replace(/ /g," ").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"):o,(a=s.match(/(?:TypeError|ReferenceError|SyntaxError|Error):[^\n<]+/)?.[0])?a.trim():/HTTP 5\d\d/.test(o)?"MCP server returned HTTP 5xx":void 0))?{code:"mcp_server_internal_error",message:`MCP server returned an internal error while handling initialize/tools/list: ${c}`,suggestion:"CLI 已连上 MCP server,但 MCP server 在 initialize 或 tools/list 内部报错。请查看 MCP server 终端日志和报错堆栈,优先修 server 代码。",details:{url:r,raw_error:l,server_error:c}}:{code:"mcp_unreachable",message:l,suggestion:"请先启动标准 MCP server,并确认 manifest.mcp_server.end_point 指向 CLI 当前运行环境可访问的 Streamable HTTP /mcp 或 SSE /sse 地址;不要求公网 URL。",details:{url:r,raw_error:l}});throw new eh(`MCP server unreachable: ${i.mcp.url}`,u)}),c={...l.tools,server_id:i.mcp.server_id||l.tools.server_id,name:i.mcp.name||l.tools.name,description:i.mcp.description||l.tools.description},v=[...function(e){let t=[],{evalCase:o,manifest:n,mcp:i}=e,s=new Set(i.tools.map(e=>e.name).filter(Boolean)),a=Object.keys(n.tools),l=new Set(a);if(n.appKey===o.app_key?t.push(el("manifest_app_id_match",`manifest AppID matches request AppID (${o.app_key})`)):t.push(eu("manifest_app_id_mismatch",`manifest AppID (${n.appKey||"-"}) does not match request AppID (${o.app_key})`,"请保持请求 AppID 与 manifest.app_key 一致;如果走特殊测试链路会改写 AppID,需要确认后端映射规则。")),i.tools.length>0){let e="sse"===i.protocol?"SSE /sse":"Streamable HTTP /mcp";t.push(el("mcp_tools_loaded",`MCP exposes ${i.tools.length} tool(s) via ${e}`))}else t.push(eu("mcp_tools_empty","MCP did not expose any tool","请检查标准 MCP tools/list 是否返回 tools。Streamable HTTP 传 /mcp,SSE 传 /sse。"));for(let e of a)s.has(e)||t.push(eu("manifest_tool_missing_in_mcp",`manifest.tools declares ${e}, but MCP does not expose it`,"请确保会出卡的 tool 同时存在于 MCP tools 与 manifest.tools。"));for(let e of o.expect?.tool_calls??[])l.has(e)||t.push(eu("expected_tool_missing_in_manifest",`expect.tool_calls declares ${e}, but manifest.tools does not declare it`,`请在 manifest.tools.${e} 中声明该工具;非出卡工具也需要配置 output.kind,例如 execution_result。`)),s.has(e)||t.push(eu("expected_tool_missing_in_mcp",`expect.tool_calls declares ${e}, but MCP does not expose it`,"请确认 MCP tools/list 返回了期望调用的工具,或修正内置 demo 的 expect.tool_calls。"));let c=Object.keys(n.cardBindings);if(c.length>0)t.push(el("card_binding_found",`card binding found: ${c.map(e=>`${e} -> ${n.cardBindings[e]}`).join(", ")}`));else{var u,d;let e=(u=o,d=n,u.expect?.card||Object.values(d.tools).some(e=>r(e)&&r(e.output)&&"entities"===e.output.kind))?eu:ec;t.push(e("card_binding_missing","manifest.entities has no tool_card_binding","如果期望出卡,请在对应 entity 下配置 tool_card_binding,例如 Taxi_order: tpl.taxi_order。"))}for(let[e,o]of Object.entries(n.entities))r(o)&&r(o.schema)&&0===Object.entries(o.schema).filter(([,e])=>r(e)&&!0===e.is_entity_id).length&&t.push(eu("entity_id_missing",`manifest.entities.${e}.schema has no is_entity_id field`,"请为实体配置一个稳定主键字段,例如 product_id: { type: string, is_entity_id: true }。"));return t}({evalCase:i,manifest:s,mcp:c}),...function(e){let t=[];for(let o of e.tools){let e=eg(o.input_schema_json);if(e)for(let n of function e(t,o){let n=[];if(!r(t))return n;for(let e of["exclusiveMinimum","exclusiveMaximum"]){let r=t[e];"number"==typeof r&&n.push({path:`${o}/${e}`,value:r,message:`${e} is number ${r}, but simulator backend expects boolean`,suggestion:"如果使用 zod,避免 z.number().positive()/min()/max() 生成数值型 exclusiveMinimum/exclusiveMaximum;可改为 z.coerce.number() 并在工具内部校验业务范围。"})}for(let[i,s]of Object.entries(t))r(s)&&n.push(...e(s,`${o}/${i}`)),Array.isArray(s)&&s.forEach((t,r)=>{n.push(...e(t,`${o}/${i}/${r}`))});return n}(e,`tools/${o.name}/inputSchema`))t.push({code:"mcp_tool_schema_incompatible",level:"error",message:`MCP tool ${o.name} inputSchema is not compatible: ${n.message}`,suggestion:n.suggestion,details:{tool_name:o.name,path:n.path,value:n.value}})}return t}(c)],w=t.gatewayOrigin||a();if(!t.force&&v.some(e=>"error"===e.level))return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:em()});try{e=await y({evalCase:i,manifestYAML:i.manifest,mcp:c,gatewayOrigin:w,callbacks:{onToolCall:async(e,t)=>{var r,o;return R(i.mcp.url,(r=i,o=e,{request_id:t,app_key:o.app_key||r.app_key,server_id:o.server_id||r.mcp?.server_id||"",tool_call_id:o.tool_call_id,tool_name:o.tool_name,arguments:eg(o.arguments_json)||{},arguments_json:o.arguments_json||"{}"}))}}})}catch(e){if(e instanceof h)return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:ep(e.state,[e_(e)])});return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,result:{...em(),log_id:ef(e,"logId")||ef(e,"log_id"),stream_errors:[e_(e)]},cardExpectation:t.cardExpectation})}return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:ep(e)})}finally{e?.kind==="sse"&&W(e),e=void 0}}function em(){return{request_id:"",tool_calls:[],cards:[],answer:"",trace_events:[],stream_errors:[]}}function ep(e,t=[]){return{request_id:e.requestID,log_id:e.logID,trace_id:e.traceID,tool_calls:e.toolCalls.map(e=>{var t;return{tool_name:e.toolCall.tool_name,tool_call_id:e.toolCall.tool_call_id,app_key:e.toolCall.app_key,server_id:e.toolCall.server_id,arguments:eg(e.toolCall.arguments_json)??e.toolCall.arguments_json,report_code:"number"==typeof e.report?.code?e.report.code:void 0,report_message:"string"==typeof e.report?.message?e.report.message:void 0,result_error:e.result?.is_error,result_preview:(t=e.result?.raw_result_text||e.result?.content||"").length>240?`${t.slice(0,240)}...`:t}}),cards:e.cards,answer:e.answer,trace_events:e.traceEvents,stream_errors:[...e.streamErrors,...t]}}function e_(e){var t;let o=e instanceof Error?e.message:String(e);return{code:ef(e,"code")||"simulator_eval_runtime_error",level:"error",message:o,suggestion:(t=o).includes("fetch failed")||t.includes("ECONNREFUSED")||t.includes("ENOTFOUND")||t.includes("timed out")?"无法连接 Simulator gateway。请检查 --gateway-origin、网络/PPE 泳道、登录环境和代理配置。":t.includes("HTTP 400")||t.includes("HTTP 422")?"请求被 gateway 或 agent 拒绝。请检查 manifest YAML、mcp tools、AppID 和 query 是否匹配;可加 --verbose 查看更多 trace。":t.includes("HTTP 5")?"Simulator 服务端异常。请保留 log_id/request_id 给服务端排查。":t.includes("tool report failed")?"工具结果上报失败。请检查 MCP 返回的 structuredContent/entities 是否符合 manifest 声明。":void 0,details:r(e)?{...e,message:o}:o}}function ef(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function eg(e){if("string"==typeof e)try{return JSON.parse(e)}catch{return}}class eh extends Error{details;constructor(e,t){super(e),this.details=t}}function ey(){return new i("eval").description("评测 Agentic Service Simulator 后端链路").option("--project-path <path>","dbx 项目路径;相对路径参数会基于该目录解析",".").addOption(new n("--demo <name>","运行内置 demo").choices([...u])).option("--query <query>","当前轮用户 query").option("--history <path>","历史消息文件,支持 json/yaml 数组").option("--skill <path>","Skill md 文件路径;默认按项目布局自动解析").option("--manifest <path>","manifest yaml 文件路径;默认按项目布局自动解析").option("--gateway-origin <url>","Simulator 网关 origin;默认使用 CLI build config apiBaseUrl").addOption(new n("--max-step <count>","Agent 最大循环步数").argParser(o)).addOption(new n("--expect-card <expectation>","当前评测是否期望出卡;required 要求至少一张卡,none 要求不出卡,auto 使用默认诊断").choices(["auto","required","none"]).default("auto")).option("--force","即使 preflight 发现配置错误也继续请求 Simulator",!1).option("--verbose","输出更多 trace 和工具结果摘要",!1).action(async(e,t)=>l(t,t=>ev(t,e)))}async function ev(e,t){let o;try{o=await ed({projectPath:t.projectPath,demo:t.demo,query:t.query,historyPath:t.history,skillPath:t.skill,manifestPath:t.manifest,gatewayOrigin:t.gatewayOrigin,maxStep:t.maxStep,cardExpectation:t.expectCard,force:t.force,verbose:t.verbose})}catch(c){var n,i;let t,o,a;if(e.json)throw c;let l=(t=r(n=c)?n.details:void 0,{code:eS(o=r(t)?t:void 0,"code"),message:eS(o,"message")||(n instanceof Error&&n.message?n.message:String(n)),suggestion:eS(o,"suggestion"),logId:eS(o,"log_id")||eS(o,"logId")||eS(n,"log_id")||eS(n,"logId"),details:t});throw new s((a=["Agentic Service Simulator Eval failed before diagnostics could run","","Error",...(i=l).code?[`- code: ${i.code}`]:[],`- message: ${i.message}`,...i.logId?[`- log_id: ${i.logId}`]:[],...i.suggestion?[`- fix: ${i.suggestion}`]:[]],void 0!==i.details&&a.push("","Details",ew(i.details)),a.join("\n")),{details:l.details,logId:l.logId})}if(e.json||function(e,t,r,o){let n=t.ok?o.green("PASS"):o.red("FAIL");if(e.log(`${o.bold("Agentic Service Simulator Eval")} ${n}`),e.log(""),e.log(o.bold("Input")),e.log(`- app_id: ${t.case.app_key}`),e.log(`- query: ${t.context.query}`),e.log(`- history_messages: ${t.context.history_count}`),e.log(`- mcp_url: ${t.context.mcp_url||"-"}`),e.log(`- gateway_origin: ${t.context.gateway_origin||"-"}`),e.log(`- max_step: ${t.context.max_step??"-"}`),e.log(`- request_id: ${t.request_id||"-"}`),e.log(`- log_id: ${t.log_id||"-"}`),e.log(""),e$(e,"Preflight",t.preflight,r,o),e.log(""),e.log(o.bold("Agent Flow")),0===t.tool_calls.length?e.log("- no tool call"):t.tool_calls.forEach((t,n)=>{e.log(`${n+1}. ${o.cyan(t.tool_name)} ${0===t.report_code?o.green("reported"):o.yellow(`report=${t.report_code??"-"}`)}`),e.log(` tool_call_id: ${t.tool_call_id}`),t.app_key&&e.log(` app_id: ${t.app_key}`),e.log(` args: ${JSON.stringify(t.arguments??{})}`),r&&t.result_preview&&e.log(` result: ${t.result_preview}`)}),e.log(""),e.log(o.bold("Cards")),0===t.cards.length?e.log("- no card emitted"):t.cards.forEach((t,r)=>{e.log(`${r+1}. widget_id=${t.widget_id||"-"} entity_id=${t.entity_id||"-"} template=${t.template||"-"}`)}),e.log(""),t.answer&&(e.log(o.bold("Answer")),e.log(t.answer),e.log("")),r&&t.trace_events.length>0){for(let r of(e.log(o.bold("Trace")),t.trace_events))e.log(`- ${r.name||"-"} ${r.status||"-"} ${r.tool_name||""} ${r.summary||""}`);e.log("")}e$(e,"Diagnostics",t.errors,r,o),e.log(""),e.log(`${o.bold("Verdict")}: ${n}`)}(e,o,t.verbose,c),!o.ok)throw new s("simulator eval failed",{json:o,logId:o.log_id});return o}function ew(e){return"string"==typeof e?e:JSON.stringify(e,null,2)}function eS(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function e$(e,t,r,o,n){if(e.log(n.bold(t)),0===r.length)return void e.log("- none");for(let t of r){let r="error"===t.level?n.red("✗"):"warn"===t.level?n.yellow("!"):n.green("✓");e.log(`${r} ${t.code}: ${t.message}`),t.suggestion&&e.log(` fix: ${t.suggestion}`),o&&void 0!==t.details&&e.log(` details: ${ew(t.details)}`)}}export{v as eval_namespaceObject};
|
|
1
|
+
let e;import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{isRecord as r,parseInteger as o,option_Option as n,command_Command as i,CliError as s,http_getApiBaseUrl as a,runCommand as l,chalk_source as c}from"./8713.js";import"./yaml.js";import{DBX_DEMO_NAMES as u,getDBXDemo as d,isDBXDemoName as m,readDBXDemoServerState as p}from"./dbx-demo.js";import{resolveProjectLayout as _}from"./project-layout.js";import{extractMCPHeadersFromManifest as f}from"./manifest-mcp-config.js";import{verifyYAML as g}from"./app.js";import{SimulatorStreamError as h,runSimulatorStream as y}from"./simulator-client.js";var v={};t.r(v),t.d(v,{default:()=>ey});let w=t("node:fs");var S=t.n(w);let $=t("node:path");var b=t.n($);let C=t("../../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/index.js"),x=new Set(["USER","ASSISTANT","TOOL"]);function P(e,t){if(!S().existsSync(e))throw E(`${t}_file_not_found`,`${t} file not found: ${e}`,`请检查 --${t} 路径;相对路径会按 --project-path 解析。`);if(!S().statSync(e).isFile())throw E(`${t}_path_not_file`,`${t} path must be a file: ${e}`,`请检查 --${t} 路径,不能传目录。`);return S().readFileSync(e,"utf8")}function E(e,t,r){let o=Error(t);return o.details={code:e,message:t,suggestion:r},o}function M(e,t){return b().isAbsolute(e)?e:b().resolve(t,e)}function j(e){return e.includes("/")||e.endsWith(".md")||e.endsWith(".json")||e.endsWith(".yaml")||e.endsWith(".yml")}function k(e){return"string"==typeof e&&e.trim()?e:void 0}function T(e){var t,o;let n=[],i=e.preflight.filter(e=>"error"===e.level);for(let r of(n.push(...i),n.push(...(t=e.result.trace_events,o=e.result.request_id,t.filter(e=>e.error).map(e=>({code:String(e.error?.code||"trace_error"),level:"error",message:String(e.error?.user_message||e.error?.message||e.summary||"trace error"),suggestion:O(e.error?.code,o),details:e.error})))),e.result.stream_errors??[]))n.push(function(e){var t;let r=String(e?.message||"stream error"),o=String(e?.code||"stream_error");return{code:o,level:"error",message:r,suggestion:"string"==typeof e?.suggestion?e.suggestion:O(o,"")||((t=r).includes("exceeded max step")?"模型在最大步数内没有收口。请检查 skill 是否让模型重复查询/重复调用工具,或临时调大 --max-step 辅助定位。":t.includes("mcp tool invalid response")?"MCP 工具返回未通过 context post-hook。请对照 manifest 检查 tool_name、entity_type、主键字段和 structuredContent。":void 0),details:e?.details??e}}(r));if(!n.some(e=>"error"===e.level)){let t=e.cardExpectation??"auto";n.push(...function(e,t,r){let o=[];for(let t of e){let e=t.result_preview||"";(t.result_error||e.includes("MCP error")||e.includes("Input validation error"))&&o.push({code:"mcp_tool_result_error",level:"error",message:`MCP tool ${t.tool_name} returned an error result`,suggestion:"工具已被模型调用,但 MCP tools/call 返回业务/参数错误。请检查 Agent Flow 里的 args 与工具入参 schema 是否一致;常见问题是模型传了字符串数字,可在 MCP server 用 z.coerce.number() 或自行兼容转换。",details:{tool_name:t.tool_name,tool_call_id:t.tool_call_id,arguments:t.arguments,result_preview:e}})}return"auto"===r&&e.length>0&&0===t&&0===o.length&&o.push({code:"tool_called_but_no_card",level:"warn",message:"Tool call finished, but no card_delta was emitted",suggestion:"如果这是出卡工具,请检查工具 result 是否包含 structuredContent.entities、entity_type 是否在 manifest.entities 声明、tool_card_binding 是否绑定该工具。"}),o}(e.result.tool_calls,e.result.cards.length,t));let r=e.result.tool_calls.map(e=>e.tool_name),o=e.evalCase.expect?.tool_calls??[];o.length>0&&!function(e,t){let r=0;for(let o of t)if(o===e[r]&&(r+=1),r===e.length)return!0;return 0===e.length}(o,r)&&n.push({code:"expectation_tool_chain_mismatch",level:"error",message:`expected tool chain ${o.join(" -> ")}, actual ${r.join(" -> ")||"-"}`,suggestion:"请检查 skill 的工具流程描述、query 是否表达了对应意图,以及 MCP tools 是否暴露了这些工具。"});let i=e.evalCase.expect?.card;if(i||"required"===t){let t=i?.min_count??1,r=i?.widget_id?e.result.cards.filter(e=>e.widget_id===i.widget_id):e.result.cards;r.length<t&&n.push({code:"card_not_emitted",level:"error",message:i?.widget_id?`expected at least ${t} card(s) with widget_id ${i.widget_id}, actual ${r.length}`:`expected at least ${t} card(s), actual ${e.result.cards.length}`,suggestion:"如果工具已成功,重点检查 manifest.tools、entities.*.tool_card_binding、MCP result structuredContent.entities 和模型是否在工具后触发出卡。"})}for(let r of("none"===t&&e.result.cards.length>0&&n.push({code:"unexpected_card_emitted",level:"error",message:`expected no card, actual ${e.result.cards.length}`,suggestion:"如果当前用例不应出卡,请检查工具是否返回了非空 structuredContent.entities,或检查 manifest 中该工具的 tool_card_binding。"}),e.result.tool_calls))!e.manifest.tools[r.tool_name]&&e.manifest.cardBindings[r.tool_name]&&n.push({code:"card_tool_not_declared",level:"error",message:`${r.tool_name} has card binding but is not declared in manifest.tools`,suggestion:`请在 manifest.tools.${r.tool_name} 中声明 output.entity_types。`})}let s=function(e){let t=new Set,o=[];for(let n of e){if(function(e,t){return"SIMULATOR_STREAM_ERROR"===e.code&&t.some(t=>{if(t.code===e.code)return!1;if(e.message.includes(t.message))return!0;let o=A(function(e,t){if(!r(e))return;let o=e[t];return r(o)?o:void 0}(t.details,"details"),"raw_error")||A(t.details,"raw_error");return void 0!==o&&e.message.includes(o)})}(n,o))continue;let e=`${n.level}\u0000${n.code}\u0000${n.message}`;t.has(e)||(t.add(e),o.push(n))}return o}(n),a=0===s.filter(e=>"error"===e.level).length;return{ok:a,verdict:a?"PASS":"FAIL",case:e.evalCase,context:{history_count:e.evalCase.history_messages?.length??0,query:e.evalCase.query,mcp_url:e.evalCase.mcp.url,gateway_origin:e.gatewayOrigin,max_step:e.evalCase.max_step},preflight:e.preflight,errors:s,...e.result}}function A(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function O(e,t){return"miniapp_mcp_result_invalid"===e?"MCP 工具返回未通过智能服务协议校验。请检查返回 JSON 是否包含 content/structuredContent,entity_type 是否在 manifest.entities 中声明,实体主键字段是否匹配 is_entity_id。":"agent_run_failed"===e?`Agent 运行失败。请查看 request_id=${t||"-"} 对应 trace,重点关注是否重复 tool call、max_step 不足或模型没有触发卡片输出。`:"tool_call_or_report_failed"===e?"工具调用或结果上报失败。请检查 MCP tools/call 是否可用,以及返回的 structuredContent/entities 是否符合 manifest 声明。":void 0}let q="2025-11-25",I=["application/json","text/event-stream"];async function N(e,t,r){return Z(e)?L(e,t,r):U(e,t,r)}async function R(t,r){var o,n;if(e&&(o=e.url,n=t,Q(o)===Q(n)))return function(e){var t;let r=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;let{_response_meta:t,...r}=e;return r}(e);if(!r||"object"!=typeof r){let e=String(r??"");return{content:e,raw_result_text:e,raw_mcp_result_json:e}}if("string"==typeof r.content||"raw_mcp_result_json"in r||"raw_result_text"in r||"structured"in r){let e="string"==typeof r.content?r.content:JSON.stringify(r.content??""),t=r.raw_mcp_result_json||r.raw_result_text||e;return{...r,content:e,raw_result_text:r.raw_result_text||t,raw_mcp_result_json:r.raw_mcp_result_json||t,structured:r.structured??r.structuredContent,is_error:r.is_error??r.isError}}let o=JSON.stringify(r);return{content:o,structured:r.structuredContent,raw_result_text:o,raw_mcp_result_json:o,is_error:!0===r.isError,miniapp:(t=r,Array.isArray(t?.content)&&t?.structuredContent&&"object"==typeof t.structuredContent)?{is_mini_app:!0,mcp_channel:"flow_miniapp"}:void 0}}("sse"===e.kind?await D(e,r):await H(e,r));throw Error("MCP session is not initialized. Please ensure fetchMCPDescriptor runs before tools/call.")}async function U(t,r,o){let n=G(t);try{let t=await B(n,{jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:q,capabilities:{},clientInfo:{name:"dbx-simulator-eval",version:"0.1.0"}}},{headers:o}),i=t.body.result?.protocolVersion??q,s=t.headers.get("mcp-session-id")??void 0;e={kind:"streamable",url:n,sessionID:s,protocolVersion:i,headers:o},await B(n,{jsonrpc:"2.0",method:"notifications/initialized",params:{}},{sessionID:s,protocolVersion:i,allowEmpty:!0,headers:o});let a=await B(n,{jsonrpc:"2.0",id:2,method:"tools/list",params:{}},{sessionID:s,protocolVersion:i,headers:o});return{tools:{server_id:ee(n),name:ee(n),description:"Standard MCP Streamable HTTP server",app_key:r,protocol:"streamable_http",tools:(a.body.result?.tools??[]).map(e=>({name:e.name,description:e.description??"",input_schema_json:JSON.stringify(e.inputSchema??e.input_schema??{})}))}}}catch(t){throw e=void 0,Error(`standard MCP Streamable HTTP initialize/tools/list failed: ${n}: ${t?.message||String(t)}`)}}async function L(t,r,o){let n=Y(t),i={kind:"sse",url:n,pending:new Map,headers:o};e=i;try{await K(i,{jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"dbx-simulator-eval",version:"0.1.0"}}},!1),await K(i,{jsonrpc:"2.0",method:"notifications/initialized",params:{}},!0);let e=await K(i,{jsonrpc:"2.0",id:2,method:"tools/list",params:{}},!1);return{tools:{server_id:ee(n),name:ee(n),description:"Standard MCP SSE server",app_key:r,protocol:"sse",tools:(e.result?.tools??[]).map(e=>({name:e.name,description:e.description??"",input_schema_json:JSON.stringify(e.inputSchema??e.input_schema??{})}))}}}catch(t){throw W(i),e=void 0,Error(`standard MCP SSE initialize/tools/list failed: ${n}: ${t?.message||String(t)}`)}}async function H(e,t){let r=ei(t.tool_name);if(!r)throw Error("MCP tool name is empty");return(await B(e.url,{jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:r,arguments:es(t.arguments)??ea(ei(t.arguments_json))??{}}},{sessionID:e.sessionID,protocolVersion:e.protocolVersion,headers:e.headers})).body.result}async function D(e,t){let r=ei(t.tool_name);if(!r)throw Error("MCP tool name is empty");return(await K(e,{jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:r,arguments:es(t.arguments)??ea(ei(t.arguments_json))??{}}},!1)).result}async function K(e,t,r){let o;if(await J(e),!e.endpointURL)throw Error("MCP SSE did not provide endpoint event");let n=et(t),i=er(t)||"unknown",s=eo(t),a=s?`${i}:${s}`:i,l=null!==n,c=l?new Promise((t,r)=>{let o=setTimeout(()=>{e.pending.delete(n),r(Error(`MCP SSE request timed out: ${a}`))},1e4);e.pending.set(n,{resolve:t,reject:r,timeout:o})}):void 0;try{var u;let r;o=await X(e.endpointURL,{method:"POST",headers:(u=e.headers,(r=new Headers(u)).set("Content-Type","application/json"),r),body:JSON.stringify(t)},1e4,`MCP SSE POST ${a}`)}catch(t){throw l&&V(e,n),t}let d=await o.text();if(!o.ok)throw l&&V(e,n),Error(`MCP SSE POST ${o.status}: ${d}`);if(!l)return{};let m=await c;if(!m&&!r)throw Error("MCP SSE returned empty response");if(m?.error)throw Error(`MCP SSE error: [${m.error.code}] ${m.error.message}`);return m}async function J(e){if(e.ready)return e.ready;let t=new AbortController;return e.abortController=t,e.ready=new Promise((r,o)=>{let n=!1,i=setTimeout(()=>{t.abort(),s(Error(`MCP SSE endpoint event timed out: ${e.url}`))},1e4),s=e=>{n||(n=!0,clearTimeout(i),o(e))};z(e,t,t=>{e.endpointURL=new URL(t,e.url).toString(),n||(n=!0,clearTimeout(i),r())},s)}).catch(t=>{throw W(e,t),t}),e.ready}async function z(e,t,r,o){try{var n;let i,s=await fetch(e.url,{method:"GET",headers:(n=e.headers,(i=new Headers(n)).set("Accept","text/event-stream"),i),signal:t.signal});if(!s.ok||!s.body){let e=await s.text();o(Error(`MCP SSE GET ${s.status}: ${e}`));return}if(!String(s.headers.get("content-type")??"").toLowerCase().includes("text/event-stream"))return void o(Error(`MCP SSE GET content-type=${s.headers.get("content-type")??"-"}`));await F(e,s.body,r),t.signal.aborted||W(e,Error("MCP SSE stream closed"))}catch(r){if(!t.signal.aborted){let t=r instanceof Error?r:Error(String(r));o(t),W(e,t)}}}async function F(e,t,r){let o=t.getReader(),n=new TextDecoder,i="",s="message",a=[],l=()=>{if(0===a.length){s="message";return}(function(e,t,r,o){let n;if("endpoint"===t)return o(r.trim());if(!r.trim())return;try{n=JSON.parse(r)}catch{return}let i=n.id;if(null==i)return;let s=e.pending.get(i);s&&(clearTimeout(s.timeout),e.pending.delete(i),s.resolve(n))})(e,s,a.join("\n"),r),s="message",a=[]};for(;;){let{done:e,value:t}=await o.read();if(e)break;let r=(i+=n.decode(t,{stream:!0})).search(/\r?\n/);for(;r>=0;){let e=i.slice(0,r).replace(/\r$/,"");i=i.slice(r+("\r"===i[r]&&"\n"===i[r+1]?2:1)),""===e?l():e.startsWith("event:")?s=e.slice(6).trim():e.startsWith("data:")&&a.push(e.slice(5).trimStart()),r=i.search(/\r?\n/)}}i&&a.push(i),l()}function V(e,t){if(null===t)return;let r=e.pending.get(t);r&&(clearTimeout(r.timeout),e.pending.delete(t))}function W(e,t=Error("MCP SSE session closed")){for(let[r,o]of(e.abortController?.abort(),e.abortController=void 0,e.endpointURL=void 0,e.ready=void 0,e.pending.entries()))clearTimeout(o.timeout),o.reject(t),e.pending.delete(r)}async function B(e,t,r){var o,n;let i,s,a,l=er(t)||"unknown",c=eo(t),u=c?`${l}:${c}`:l,d=await X(e,{method:"POST",headers:(o=t,(i=new Headers((n=r).headers)).set("Content-Type","application/json"),i.set("Accept",I.join(", ")),(s=er(o))&&i.set("Mcp-Method",s),(a=eo(o))&&i.set("Mcp-Name",a),n.protocolVersion&&i.set("MCP-Protocol-Version",n.protocolVersion),n.sessionID&&i.set("Mcp-Session-Id",n.sessionID),i),body:JSON.stringify(t)},1e4,`MCP Streamable HTTP ${u}`),m=await d.text();if(!d.ok)throw Error(`MCP Streamable HTTP ${d.status}: ${m}`);if(!m&&r.allowEmpty)return{body:{},headers:d.headers};if(!m)throw Error("MCP Streamable HTTP returned empty response");let p=function(e,t,r){if(t?.toLowerCase().includes("text/event-stream")){let t=function(e){let t=[],r=[],o=()=>{if(0===r.length)return;let e=r.join("\n");e.trim()&&t.push(JSON.parse(e)),r=[]};for(let t of e.split(/\r?\n/)){if(""===t){o();continue}t.startsWith("data:")&&r.push(t.slice(5).trimStart())}return o(),t}(e),o=t.find(e=>{var t,o;return t=e,null!==(o=r)&&en(t)&&t.id===o})??t.find(en);if(!o)throw Error("MCP SSE response has no JSON-RPC response");return o}return JSON.parse(e)}(m,d.headers.get("content-type"),et(t));if(p.error)throw Error(`MCP Streamable HTTP error: [${p.error.code}] ${p.error.message}`);return{body:p,headers:d.headers}}function G(e){let t=new URL(e);return("/"===t.pathname||""===t.pathname)&&(t.pathname="/mcp"),t.toString()}function Y(e){return new URL(e).toString()}function Z(e){return new URL(e).pathname.replace(/\/+$/,"").toLowerCase().endsWith("/sse")}function Q(e){return Z(e)?Y(e):G(e)}async function X(e,t,r,o){let n=new AbortController,i=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}catch(e){if(e instanceof Error&&"AbortError"===e.name)throw Error(`${o} timed out after ${r}ms`);throw e}finally{clearTimeout(i)}}function ee(e){let t=new URL(e);return`${t.hostname}_${t.port||t.protocol.replace(":","")}${t.pathname.replace(/[^A-Za-z0-9_-]/g,"_")}`}function et(e){return e&&"object"==typeof e&&"id"in e?e.id??null:null}function er(e){if(e&&"object"==typeof e&&"method"in e)return e.method}function eo(e){if(!e||"object"!=typeof e)return;let t=e.params;return t&&"object"==typeof t?"string"==typeof t.name?t.name:"string"==typeof t.uri?t.uri:void 0:void 0}function en(e){return!!(e&&"object"==typeof e&&"id"in e&&("result"in e||"error"in e))}function ei(e){return"string"==typeof e?e:""}function es(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function ea(e){if(e)try{return JSON.parse(e)}catch{return}}function el(e,t){return{code:e,level:"info",message:t}}function ec(e,t,r){return{code:e,level:"warn",message:t,suggestion:r}}function eu(e,t,r){return{code:e,level:"error",message:t,suggestion:r}}async function ed(t){try{let e,o=function(e){let t=b().resolve(e.projectPath),r=_(t),o=e.demo?function(e){try{return d(e).evalCase}catch{throw Error(`unknown simulator eval demo: ${e}. Supported demos: ${u.join(", ")}`)}}(e.demo):{},n=e.demo&&m(e.demo)?p(t,e.demo)?.streamableUrl:void 0,i={...o,...e.query?{query:e.query}:{},...void 0!==e.maxStep?{max_step:e.maxStep}:{}};if(e.historyPath&&(i.history_messages=function(e){if(!S().existsSync(e))throw E("history_file_not_found",`history file not found: ${e}`,"请检查 --history 路径;历史文件应为消息数组。");let t=function(e,t,r){try{return t.endsWith(".json")?JSON.parse(e):C.qg(e)}catch(e){throw E(`${r}_file_parse_failed`,`${r} file parse failed: ${e?.message||String(e)}`,`请检查 ${t} 的语法和缩进。`)}}(S().readFileSync(e,"utf8"),e,"history");if(!Array.isArray(t))throw E("history_file_invalid","history file must be an array","请把 history 文件写成数组,例如 [{ role: USER, content: hello }]。");return t}(M(e.historyPath,t))),e.skillPath)i.skill=P(M(e.skillPath,t),"skill");else if(i.skill&&j(i.skill))i.skill=P(M(i.skill,t),"skill");else if(!i.skill){let e=r.skillPath;S().existsSync(e)&&(i.skill=P(e,"skill"))}if(e.manifestPath)i.manifest=P(M(e.manifestPath,t),"manifest");else if(i.manifest&&j(i.manifest))i.manifest=P(M(i.manifest,t),"manifest");else if(!i.manifest){let e=r.manifestPath;S().existsSync(e)&&(i.manifest=P(e,"manifest"))}if(n&&(i.manifest=function(e,t){if("string"==typeof e)return e.trim()?[e.trimEnd(),"\nmcp_server:",` end_point: ${JSON.stringify(t)}`," mcp_config:\n protocol: Streamable\n"].join("\n"):e}(i.manifest,n)),function(e){if(!e.query||"string"!=typeof e.query||!e.query.trim())throw E("query_required","simulator eval requires query","请通过 --query 传入本轮用户问题。");if(!e.skill||"string"!=typeof e.skill)throw E("skill_required","simulator eval requires skill text or skill path","请在项目 skill/SKILL.md 放置 Skill,或通过 --skill 传入路径。");if(!e.manifest||"string"!=typeof e.manifest)throw E("manifest_required","simulator eval requires manifest YAML text or path","请在项目 manifest.yaml 放置 Manifest,或通过 --manifest 传入路径。")}(i),i.history_messages=(i.history_messages??[]).map((e,t)=>{if(!e||"object"!=typeof e)throw E("history_message_invalid",`history_messages[${t}] must be an object`,"请把每条历史消息写成 { role: USER|ASSISTANT|TOOL, content: string }。");let r=String(e.role||"").toUpperCase();if(!x.has(r))throw E("history_message_role_invalid",`history_messages[${t}].role must be USER, ASSISTANT or TOOL`,"请把 role 改成 USER、ASSISTANT 或 TOOL。");if("string"!=typeof e.content||!e.content.trim())throw E("history_message_content_invalid",`history_messages[${t}].content must be a non-empty string`,"请为该历史消息补充非空 content。");return{role:r,content:e.content}}),i.max_step=i.max_step??15,!Number.isInteger(i.max_step)||i.max_step<=0)throw E("max_step_invalid","max_step must be a positive integer","请删除 max_step 使用默认值 15,或通过 --max-step 传入正整数。");return i}(t),n=await g(o.manifest,"compatible");if(!n.data?.success||!n.data.manifest)throw new eh("manifest validation failed",{code:"manifest_validation_failed",message:"manifest validation failed",errors:n.data?.errors??[],warnings:n.data?.warnings??[],log_id:n.log_id});let i=function(e,t){if(!r(t))throw E("manifest_parse_result_missing","simulator eval requires parsed manifest from yaml verify","请先确认后端 /yaml/verify 返回 data.manifest。");let o=r(t.mcp_server)?t.mcp_server:void 0,n=k(t.app_key),i=k(o?.end_point);if(!n)throw E("app_id_required","simulator eval requires manifest AppID","请在 manifest.yaml 配置 app_key(该字段对外称 AppID)。");if(!i)throw E("mcp_url_required","simulator eval requires manifest mcp_server.end_point","请在 manifest.yaml 配置 mcp_server.end_point。");return function(e,t,r){try{let t=new URL(e);if("http:"===t.protocol||"https:"===t.protocol)return}catch{}throw E(t,`${r} must be an http(s) URL: ${e}`,`请把 ${r} 配置为 http:// 或 https:// 开头的 MCP endpoint。`)}(i,"mcp_url_invalid","manifest.mcp_server.end_point"),{...e,app_key:n,app_name:k(t.name),mcp:{url:i,description:k(o?.description),headers:f(t)}}}(o,n.data.manifest),s=function(e){if(!r(e)){var t;let e;throw t="manifest must be a parsed object",(e=Error(t)).details={code:"manifest_yaml_invalid",message:t,suggestion:"请先运行 `dbx app artifacts validate <manifest.yaml>`,确认后端能解析 manifest。"},e}let o=r(e.tools)?e.tools:{},n=r(e.entities)?e.entities:{},i={};for(let e of Object.values(n))if(r(e)&&r(e.tool_card_binding))for(let[t,r]of Object.entries(e.tool_card_binding))"string"==typeof r&&(i[t]=r);return{raw:e,appKey:"string"==typeof e.app_key?e.app_key:void 0,tools:o,entities:n,cardBindings:i}}(n.data.manifest),l=await N(i.mcp.url,i.app_key,i.mcp.headers).catch(e=>{var t,r,o;let n,s,a,l,c,u=(t=e,r=i.mcp.url,(c=(o=l=String(t?.message||t),s=(n=o.match(/<pre>([\s\S]*?)<\/pre>/i)?.[1])?n.replace(/<br\s*\/?>/gi,"\n").replace(/ /g," ").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"):o,(a=s.match(/(?:TypeError|ReferenceError|SyntaxError|Error):[^\n<]+/)?.[0])?a.trim():/HTTP 5\d\d/.test(o)?"MCP server returned HTTP 5xx":void 0))?{code:"mcp_server_internal_error",message:`MCP server returned an internal error while handling initialize/tools/list: ${c}`,suggestion:"CLI 已连上 MCP server,但 MCP server 在 initialize 或 tools/list 内部报错。请查看 MCP server 终端日志和报错堆栈,优先修 server 代码。",details:{url:r,raw_error:l,server_error:c}}:{code:"mcp_unreachable",message:l,suggestion:"请先启动标准 MCP server,并确认 manifest.mcp_server.end_point 指向 CLI 当前运行环境可访问的 Streamable HTTP /mcp 或 SSE /sse 地址;不要求公网 URL。",details:{url:r,raw_error:l}});throw new eh(`MCP server unreachable: ${i.mcp.url}`,u)}),c={...l.tools,server_id:i.mcp.server_id||l.tools.server_id,name:i.mcp.name||l.tools.name,description:i.mcp.description||l.tools.description},v=[...function(e){let t=[],{evalCase:o,manifest:n,mcp:i}=e,s=new Set(i.tools.map(e=>e.name).filter(Boolean)),a=Object.keys(n.tools),l=new Set(a);if(n.appKey===o.app_key?t.push(el("manifest_app_id_match",`manifest AppID matches request AppID (${o.app_key})`)):t.push(eu("manifest_app_id_mismatch",`manifest AppID (${n.appKey||"-"}) does not match request AppID (${o.app_key})`,"请保持请求 AppID 与 manifest.app_key 一致;如果走特殊测试链路会改写 AppID,需要确认后端映射规则。")),i.tools.length>0){let e="sse"===i.protocol?"SSE /sse":"Streamable HTTP /mcp";t.push(el("mcp_tools_loaded",`MCP exposes ${i.tools.length} tool(s) via ${e}`))}else t.push(eu("mcp_tools_empty","MCP did not expose any tool","请检查标准 MCP tools/list 是否返回 tools。Streamable HTTP 传 /mcp,SSE 传 /sse。"));for(let e of a)s.has(e)||t.push(eu("manifest_tool_missing_in_mcp",`manifest.tools declares ${e}, but MCP does not expose it`,"请确保会出卡的 tool 同时存在于 MCP tools 与 manifest.tools。"));for(let e of o.expect?.tool_calls??[])l.has(e)||t.push(eu("expected_tool_missing_in_manifest",`expect.tool_calls declares ${e}, but manifest.tools does not declare it`,`请在 manifest.tools.${e} 中声明该工具;非出卡工具也需要配置 output.kind,例如 execution_result。`)),s.has(e)||t.push(eu("expected_tool_missing_in_mcp",`expect.tool_calls declares ${e}, but MCP does not expose it`,"请确认 MCP tools/list 返回了期望调用的工具,或修正内置 demo 的 expect.tool_calls。"));let c=Object.keys(n.cardBindings);if(c.length>0)t.push(el("card_binding_found",`card binding found: ${c.map(e=>`${e} -> ${n.cardBindings[e]}`).join(", ")}`));else{var u,d;let e=(u=o,d=n,u.expect?.card||Object.values(d.tools).some(e=>r(e)&&r(e.output)&&"entities"===e.output.kind))?eu:ec;t.push(e("card_binding_missing","manifest.entities has no tool_card_binding","如果期望出卡,请在对应 entity 下配置 tool_card_binding,例如 Taxi_order: tpl.taxi_order。"))}for(let[e,o]of Object.entries(n.entities))r(o)&&r(o.schema)&&0===Object.entries(o.schema).filter(([,e])=>r(e)&&!0===e.is_entity_id).length&&t.push(eu("entity_id_missing",`manifest.entities.${e}.schema has no is_entity_id field`,"请为实体配置一个稳定主键字段,例如 product_id: { type: string, is_entity_id: true }。"));return t}({evalCase:i,manifest:s,mcp:c}),...function(e){let t=[];for(let o of e.tools){let e=eg(o.input_schema_json);if(e)for(let n of function e(t,o){let n=[];if(!r(t))return n;for(let e of["exclusiveMinimum","exclusiveMaximum"]){let r=t[e];"number"==typeof r&&n.push({path:`${o}/${e}`,value:r,message:`${e} is number ${r}, but simulator backend expects boolean`,suggestion:"如果使用 zod,避免 z.number().positive()/min()/max() 生成数值型 exclusiveMinimum/exclusiveMaximum;可改为 z.coerce.number() 并在工具内部校验业务范围。"})}for(let[i,s]of Object.entries(t))r(s)&&n.push(...e(s,`${o}/${i}`)),Array.isArray(s)&&s.forEach((t,r)=>{n.push(...e(t,`${o}/${i}/${r}`))});return n}(e,`tools/${o.name}/inputSchema`))t.push({code:"mcp_tool_schema_incompatible",level:"error",message:`MCP tool ${o.name} inputSchema is not compatible: ${n.message}`,suggestion:n.suggestion,details:{tool_name:o.name,path:n.path,value:n.value}})}return t}(c)],w=t.gatewayOrigin||a();if(!t.force&&v.some(e=>"error"===e.level))return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:em()});try{e=await y({evalCase:i,manifestYAML:i.manifest,mcp:c,gatewayOrigin:w,callbacks:{onToolCall:async(e,t)=>{var r,o;return R(i.mcp.url,(r=i,o=e,{request_id:t,app_key:o.app_key||r.app_key,server_id:o.server_id||r.mcp?.server_id||"",tool_call_id:o.tool_call_id,tool_name:o.tool_name,arguments:eg(o.arguments_json)||{},arguments_json:o.arguments_json||"{}"}))}}})}catch(e){if(e instanceof h)return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:ep(e.state,[e_(e)])});return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,result:{...em(),log_id:ef(e,"logId")||ef(e,"log_id"),stream_errors:[e_(e)]},cardExpectation:t.cardExpectation})}return T({evalCase:i,manifest:s,preflight:v,gatewayOrigin:w,cardExpectation:t.cardExpectation,result:ep(e)})}finally{e?.kind==="sse"&&W(e),e=void 0}}function em(){return{request_id:"",tool_calls:[],cards:[],answer:"",trace_events:[],stream_errors:[]}}function ep(e,t=[]){return{request_id:e.requestID,log_id:e.logID,trace_id:e.traceID,tool_calls:e.toolCalls.map(e=>{var t;return{tool_name:e.toolCall.tool_name,tool_call_id:e.toolCall.tool_call_id,app_key:e.toolCall.app_key,server_id:e.toolCall.server_id,arguments:eg(e.toolCall.arguments_json)??e.toolCall.arguments_json,report_code:"number"==typeof e.report?.code?e.report.code:void 0,report_message:"string"==typeof e.report?.message?e.report.message:void 0,result_error:e.result?.is_error,result_preview:(t=e.result?.raw_result_text||e.result?.content||"").length>240?`${t.slice(0,240)}...`:t}}),cards:e.cards,answer:e.answer,trace_events:e.traceEvents,stream_errors:[...e.streamErrors,...t]}}function e_(e){var t;let o=e instanceof Error?e.message:String(e);return{code:ef(e,"code")||"simulator_eval_runtime_error",level:"error",message:o,suggestion:(t=o).includes("fetch failed")||t.includes("ECONNREFUSED")||t.includes("ENOTFOUND")||t.includes("timed out")?"无法连接 Simulator gateway。请检查 --gateway-origin、网络/PPE 泳道、登录环境和代理配置。":t.includes("HTTP 400")||t.includes("HTTP 422")?"请求被 gateway 或 agent 拒绝。请检查 manifest YAML、mcp tools、AppID 和 query 是否匹配;可加 --verbose 查看更多 trace。":t.includes("HTTP 5")?"Simulator 服务端异常。请保留 log_id/request_id 给服务端排查。":t.includes("tool report failed")?"工具结果上报失败。请检查 MCP 返回的 structuredContent/entities 是否符合 manifest 声明。":void 0,details:r(e)?{...e,message:o}:o}}function ef(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function eg(e){if("string"==typeof e)try{return JSON.parse(e)}catch{return}}class eh extends Error{details;constructor(e,t){super(e),this.details=t}}function ey(){return new i("eval").description("评测 Agentic Service Simulator 后端链路").option("--project-path <path>","dbx 项目路径;相对路径参数会基于该目录解析",".").addOption(new n("--demo <name>","运行内置 demo").choices([...u])).option("--query <query>","当前轮用户 query").option("--history <path>","历史消息文件,支持 json/yaml 数组").option("--skill <path>","Skill md 文件路径;默认按项目布局自动解析").option("--manifest <path>","manifest yaml 文件路径;默认按项目布局自动解析").option("--gateway-origin <url>","Simulator 网关 origin;默认使用 CLI build config apiBaseUrl").addOption(new n("--max-step <count>","Agent 最大循环步数").argParser(o)).addOption(new n("--expect-card <expectation>","当前评测是否期望出卡;required 要求至少一张卡,none 要求不出卡,auto 使用默认诊断").choices(["auto","required","none"]).default("auto")).option("--force","即使 preflight 发现配置错误也继续请求 Simulator",!1).option("--verbose","输出更多 trace 和工具结果摘要",!1).action(async(e,t)=>l(t,t=>ev(t,e)))}async function ev(e,t){let o;try{o=await ed({projectPath:t.projectPath,demo:t.demo,query:t.query,historyPath:t.history,skillPath:t.skill,manifestPath:t.manifest,gatewayOrigin:t.gatewayOrigin,maxStep:t.maxStep,cardExpectation:t.expectCard,force:t.force,verbose:t.verbose})}catch(c){var n,i;let t,o,a;if(e.json)throw c;let l=(t=r(n=c)?n.details:void 0,{code:eS(o=r(t)?t:void 0,"code"),message:eS(o,"message")||(n instanceof Error&&n.message?n.message:String(n)),suggestion:eS(o,"suggestion"),logId:eS(o,"log_id")||eS(o,"logId")||eS(n,"log_id")||eS(n,"logId"),details:t});throw new s((a=["Agentic Service Simulator Eval failed before diagnostics could run","","Error",...(i=l).code?[`- code: ${i.code}`]:[],`- message: ${i.message}`,...i.logId?[`- log_id: ${i.logId}`]:[],...i.suggestion?[`- fix: ${i.suggestion}`]:[]],void 0!==i.details&&a.push("","Details",ew(i.details)),a.join("\n")),{details:l.details,logId:l.logId})}if(e.json||function(e,t,r,o){let n=t.ok?o.green("PASS"):o.red("FAIL");if(e.log(`${o.bold("Agentic Service Simulator Eval")} ${n}`),e.log(""),e.log(o.bold("Input")),e.log(`- app_id: ${t.case.app_key}`),e.log(`- query: ${t.context.query}`),e.log(`- history_messages: ${t.context.history_count}`),e.log(`- mcp_url: ${t.context.mcp_url||"-"}`),e.log(`- gateway_origin: ${t.context.gateway_origin||"-"}`),e.log(`- max_step: ${t.context.max_step??"-"}`),e.log(`- request_id: ${t.request_id||"-"}`),e.log(`- log_id: ${t.log_id||"-"}`),e.log(""),e$(e,"Preflight",t.preflight,r,o),e.log(""),e.log(o.bold("Agent Flow")),0===t.tool_calls.length?e.log("- no tool call"):t.tool_calls.forEach((t,n)=>{e.log(`${n+1}. ${o.cyan(t.tool_name)} ${0===t.report_code?o.green("reported"):o.yellow(`report=${t.report_code??"-"}`)}`),e.log(` tool_call_id: ${t.tool_call_id}`),t.app_key&&e.log(` app_id: ${t.app_key}`),e.log(` args: ${JSON.stringify(t.arguments??{})}`),r&&t.result_preview&&e.log(` result: ${t.result_preview}`)}),e.log(""),e.log(o.bold("Cards")),0===t.cards.length?e.log("- no card emitted"):t.cards.forEach((t,r)=>{e.log(`${r+1}. widget_id=${t.widget_id||"-"} entity_id=${t.entity_id||"-"} template=${t.template||"-"}`)}),e.log(""),t.answer&&(e.log(o.bold("Answer")),e.log(t.answer),e.log("")),r&&t.trace_events.length>0){for(let r of(e.log(o.bold("Trace")),t.trace_events))e.log(`- ${r.name||"-"} ${r.status||"-"} ${r.tool_name||""} ${r.summary||""}`);e.log("")}e$(e,"Diagnostics",t.errors,r,o),e.log(""),e.log(`${o.bold("Verdict")}: ${n}`)}(e,o,t.verbose,c),!o.ok)throw new s("simulator eval failed",{json:o,logId:o.log_id});return o}function ew(e){return"string"==typeof e?e:JSON.stringify(e,null,2)}function eS(e,t){if(!r(e))return;let o=e[t];return"string"==typeof o&&o?o:void 0}function e$(e,t,r,o,n){if(e.log(n.bold(t)),0===r.length)return void e.log("- none");for(let t of r){let r="error"===t.level?n.red("✗"):"warn"===t.level?n.yellow("!"):n.green("✓");e.log(`${r} ${t.code}: ${t.message}`),t.suggestion&&e.log(` fix: ${t.suggestion}`),o&&void 0!==t.details&&e.log(` details: ${ew(t.details)}`)}}export{v as eval_namespaceObject};
|
package/dist/gen-explore.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{command_Command as o,runCommand as e}from"./
|
|
1
|
+
import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{command_Command as o,runCommand as e}from"./8713.js";import{genExplore as a}from"./2514.js";import{buildConfig as l}from"./shared.js";let p=t("node:fs"),r=t("node:path");export default function(){return new o("gen-explore").description("Explore all MCP tools systematically, collecting traces and entity pool").option("-c, --config <path>","Path to config YAML file").option("--project-path <path>","dbx project path",".").option("--mcp-url <url>","MCP server URL").option("--app-id <id>","App ID").option("--max-step <n>","Max steps per tool").option("--model <model>","Gateway alias or custom LLM model").option("--base-url <url>","Custom OpenAI-compatible LLM base URL").option("--api-key <key>","Custom LLM API key").option("-o, --output <path>","Output file path").action(async(t,o)=>e(o,async o=>{let e=await l(t);o.log(`Project Eval config: ${(0,r.resolve)(t.projectPath,".dbx","eval.yaml")}`);let n=await a(e,{referenceTime:new Date().toISOString()}),i=(0,r.resolve)("./data");(0,p.existsSync)(i)||(0,p.mkdirSync)(i,{recursive:!0});let s=t.output?(0,r.resolve)(t.output):(0,r.join)(i,`explore-${Date.now()}.json`);return(0,p.writeFileSync)(s,JSON.stringify(n,null,2)),o.log(`Explore written to: ${s}`),o.log(`Steps: ${n.metadata.total_steps}, Covered: ${n.metadata.tools_covered.length}/${n.metadata.tools_covered.length+n.metadata.tools_not_covered.length}`),n}))};
|
package/dist/gen-trajectory.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{command_Command as o,runCommand as e}from"./
|
|
1
|
+
import"node:module";import{__webpack_require__ as t}from"./rslib-runtime.js";import{command_Command as o,runCommand as e}from"./8713.js";import{genTrajectory as r}from"./2514.js";import{buildConfig as i}from"./shared.js";let n=t("node:fs"),a=t("node:path");export default function(){return new o("gen-trajectory").description("Generate multi-turn conversation trajectory via UA + Simulator").requiredOption("-i, --intent <text>","User intent / task description").option("-c, --config <path>","Path to config YAML file").option("--project-path <path>","dbx project path",".").option("--mcp-url <url>","MCP server URL").option("--app-id <id>","App ID").option("--gateway <url>","Gateway origin").option("--max-rounds <n>","Max conversation rounds").option("--max-step <n>","Max tool steps per round").option("--model <model>","Gateway alias or custom LLM model").option("--base-url <url>","Custom OpenAI-compatible LLM base URL").option("--api-key <key>","Custom LLM API key").option("--manifest <path>","Manifest YAML path").option("--skill <path>","Skill file path").option("-o, --output <path>","Output file path").action(async(t,o)=>e(o,async o=>{let e=await i(t);if(!e.app.appId)throw Error("app_id is required");o.log(`Project Eval config: ${(0,a.resolve)(t.projectPath,".dbx","eval.yaml")}`);let p=(0,a.resolve)("./data");(0,n.existsSync)(p)||(0,n.mkdirSync)(p,{recursive:!0});let s=t.output?(0,a.resolve)(t.output):(0,a.join)(p,`trajectory-${Date.now()}.json`);e.dev&&(e.dev.screenshotDir=(0,a.join)((0,a.resolve)(s,".."),"screenshot"));let l=await r(e,t.intent,{referenceTime:new Date().toISOString()});return(0,n.writeFileSync)(s,JSON.stringify(l,null,2)),o.log(`Trajectory written to: ${s}`),o.log(`Rounds: ${l.metadata.total_rounds}, Stop: ${l.metadata.stop_reason}`),l}))};
|
package/dist/get.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"node:module";import{command_Command as o,runCommand as _}from"./
|
|
1
|
+
import"node:module";import{command_Command as o,runCommand as _}from"./8713.js";import{fetchSandboxAppCredentials as a}from"./sandbox.js";async function p(o){let _=await a();return o.log(`sandbox_project_path: ${_.sandbox_project_path}`),_.sandbox_project_id&&o.log(`sandbox_project_id: ${_.sandbox_project_id}`),o.log(`sandbox_app_id: ${_.sandbox_app_id}`),o.log(`sandbox_app_secret: ${_.sandbox_app_secret}`),_.log_id&&o.log(`log_id: ${_.log_id}`),_}export default function(){return new o("get").description("获取 sandbox appid 和 appsecret").action(async(o,a)=>_(a,o=>p(o)))};
|
package/dist/init.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import"node:module";import{__webpack_require__ as e}from"./rslib-runtime.js";import{AGENTIC_SERVICE_SKILL_NAME as t,AGENTIC_SERVICE_DISPLAY_NAME as i,collectChoiceValues as r,chalk_source as n,version_version as s,command_Command as o,option_Option as a,types_TokenStatus as l,DEFAULT_FRONTEND_DIRECTORY as p,runCommand as d,execa as c}from"./
|
|
1
|
+
import"node:module";import{__webpack_require__ as e}from"./rslib-runtime.js";import{AGENTIC_SERVICE_SKILL_NAME as t,AGENTIC_SERVICE_DISPLAY_NAME as i,collectChoiceValues as r,chalk_source as n,version_version as s,command_Command as o,option_Option as a,types_TokenStatus as l,DEFAULT_FRONTEND_DIRECTORY as p,runCommand as d,execa as c}from"./8713.js";import"./ora.js";import"./yaml.js";import{resolveProjectLayout as u}from"./project-layout.js";import{writeDbxConfig as h,updateDbxConfigSkills as f}from"./dbx.js";import{INIT_AGENT_IDS as m,selectInitAgents as g,selectGitInitialization as _,inputProjectDirectory as y}from"./prompts.js";import{formatPollStatus as w,login as b,getAuthStatus as S}from"./auth.js";import{fetchSandboxAppCredentials as v}from"./sandbox.js";import{installSkills as x}from"./skills~1.js";import{openUrlInBrowser as k}from"./browser.js";import{SUPPORTED_AGENTS as j}from"./skills.js";var $={};e.r($),e.d($,{default:()=>es});let E=e("node:fs");var A=e.n(E);let P=e("node:path");var N=e.n(P);let R=new Set(["node_modules",".git"]);async function C(e){var t;let r=e.appId.trim();if(!r)throw Error("frontend scaffold requires a sandbox AppID");let n=e.directory?.trim()||".",s=N().resolve(e.projectPath),o=N().resolve(s,n),a=(t=o,N().basename(t)||p),l=!!(e.overwriteExisting&&(0,E.existsSync)(o));l&&o!==s&&(e.onStatus?.("clearing_existing_directory"),function(e){if(!(0,E.statSync)(e).isDirectory())throw Error(`frontend scaffold target is not a directory: ${e}`);for(let t of(0,E.readdirSync)(e))R.has(t)||(0,E.rmSync)(N().join(e,t),{recursive:!0,force:!0});(0,E.mkdirSync)(e,{recursive:!0})}(o)),e.onStatus?.("creating_scaffold");let{create:d}=await import("./@byted-doubao-apps/create.js");return await d({template:"starter",projectDir:o,public:!0,appId:r,name:i,packageName:a,overwrite:!0,git:e.initializeGit??!1,login:!0}),{directory:n,path:o,app_id:r,template:"starter",package_name:a,overwritten:l}}let I=`这是一个豆包智能服务工程,请结合 ${t} Skill 进行开发`,K=e("../../../node_modules/.pnpm/ora@5.4.1/node_modules/ora/index.js");var M=e.n(K);class q{options;spinner;constructor(e){this.options=e}header(e){if(!this.options.enabled)return;let t=this.options.useSpinner?n.bold.cyan(e):`== ${e} ==`;this.options.log(t)}card(e,t){if(!this.options.enabled)return;let i=Math.max(...t.map(([e])=>e.length),0),r=[` ${e} `,...t.map(([e,t])=>` ${e.padEnd(i)} ${t} `)],s=Math.max(...r.map(e=>e.length)),o=`+${"-".repeat(s)}+`;for(let e of[o,...r.map((e,t)=>{let i=`${e}${" ".repeat(s-e.length)}`;return`|${0===t&&this.options.useSpinner?n.bold(i):i}|`}),o])this.options.log(this.options.useSpinner?n.cyan(e):e)}section(e){if(!this.options.enabled)return;let t=this.options.useSpinner?n.bold(e):e;this.options.log(t)}blank(){this.options.enabled&&this.options.log("")}info(e,t){this.options.enabled&&this.options.log(function(e,t,i){if(void 0===t)return` ${e}`;let r=i?n.cyan(e):e;return` ${r}: ${t}`}(e,t,this.options.useSpinner))}note(e){this.options.enabled&&this.options.log(` - ${e}`)}warn(e){this.options.enabled&&(this.stopActive(),this.options.warn(e))}startStep(e){if(this.options.enabled){if(this.stopActive(),this.options.useSpinner){this.spinner=M()({text:e,color:"cyan",stream:process.stderr}).start();return}this.options.log(U("run",e,this.options.useSpinner))}}updateStep(e){if(this.options.enabled){if(!this.spinner)return void this.options.log(U("run",e,this.options.useSpinner));this.spinner.text=e}}succeedStep(e){if(this.options.enabled){if(this.spinner){this.spinner.succeed(e),this.spinner=void 0;return}this.options.log(U("ok",e,this.options.useSpinner))}}warnStep(e){if(this.options.enabled){if(this.spinner){this.spinner.warn(e),this.spinner=void 0;return}this.options.warn(U("warn",e,this.options.useSpinner))}}failStep(e){if(this.options.enabled){if(this.spinner){this.spinner.fail(e),this.spinner=void 0;return}this.options.warn(U("fail",e,this.options.useSpinner))}}stopActive(){this.spinner&&(this.spinner.stop(),this.spinner=void 0)}}function O(){return!!(process.stderr.isTTY&&!process.env.CI)}function U(e,t,i){let r=`[${e}]`;if(!i)return` ${r} ${t}`;let s="ok"===e?n.green:"warn"===e?n.yellow:"fail"===e?n.red:n.cyan;return` ${s(r)} ${t}`}let T=e("node:util"),V=["@swc/core","@speedy-js/esbuild","core-js","crc64-ecma182.js","esbuild"],D=["@byted-lynx/js-check-"],z={commandVersion:async e=>(await c(e,["--version"],{env:process.env,stdio:["ignore","pipe","pipe"]})).stdout.trim(),pnpmInstall:async(e,t={})=>W(["install"],e,{streamOutput:t.streamOutput??!1}),pnpmApproveBuilds:async(e,t)=>W("all"===t?["approve-builds","--all"]:["approve-builds",...t],e,{streamOutput:!1})};async function H(e=z){try{return{version:await e.commandVersion("npm")}}catch{throw Error("npm not found in PATH. dbx init requires npm. Please install Node.js/npm and retry.")}}async function F(e=z){try{return{version:await e.commandVersion("pnpm")}}catch{throw Error("pnpm not found in PATH. dbx init requires pnpm. Install pnpm and retry.")}}async function G(e,t={}){let i=t.runner??z,r=t.autoApproveBuilds??"known",n=0;try{return n+=1,await i.pnpmInstall(e,{streamOutput:t.streamOutput}),{dependencies_installed:!0,install_attempts:n,recovered_from_ignored_builds:!1,approved_builds:[]}}catch(a){let s;if(!1===r||!((s=Q(a)).includes("ERR_PNPM_IGNORED_BUILDS")||s.includes("Ignored build scripts:")))return Y(e,n,a);let o=function(e,t){var i;let r;if(t.pnpmVersion&&!L(t.pnpmVersion,"10.1.0"))return null;let n=(i=Q(e),(r=(0,T.stripVTControlCharacters)(i).match(/Ignored build scripts:\s*([\s\S]*?)(?:\n\s*\n|\nRun\s+"pnpm approve-builds"|$)/))?r[1].split(",").map(e=>(function(e){if(!e)return null;if(e.startsWith("@")){let t=e.indexOf("@",1);return t>0?e.slice(0,t):e}let t=e.lastIndexOf("@");return t>0?e.slice(0,t):e})(e.trim().replace(/[.。]$/,""))).filter(e=>!!e):[]),s="all-pending"===t.mode?n:n.filter(B);return s.length>0?[...new Set(s)]:"all-pending"===t.mode&&t.pnpmVersion&&L(t.pnpmVersion,"10.32.0")?"all":null}(a,{mode:r,pnpmVersion:t.pnpmVersion});if(!o)return Y(e,n,a);try{return await i.pnpmApproveBuilds(e,o),n+=1,await i.pnpmInstall(e,{streamOutput:t.streamOutput}),{dependencies_installed:!0,install_attempts:n,recovered_from_ignored_builds:!0,approved_builds:"all"===o?["*"]:[...o]}}catch(t){return Y(e,n,t,{approvedBuilds:"all"===o?["*"]:[...o]})}}}function B(e){return V.includes(e)||D.some(t=>e.startsWith(t))}function L(e,t){let i=J(e),r=J(t);if(!i||!r)return!1;for(let e=0;e<i.length&&!(i[e]>r[e]);e+=1)if(i[e]<r[e])return!1;return!0}function J(e){let t=e.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}function Y(e,t,i,r={}){return{dependencies_installed:!1,install_attempts:t,recovered_from_ignored_builds:!1,approved_builds:r.approvedBuilds??[],install_warning:`pnpm install did not complete in ${e}: ${X(i)}`}}async function W(e,t,i){var r;let n=c("pnpm",[...e],{cwd:t,env:process.env,stdio:["ignore","pipe","pipe"],all:!0});return i.streamOutput&&n.all?.pipe(process.stderr),{stdout:(r=await n).stdout??"",stderr:r.stderr??"",all:r.all??[r.stdout,r.stderr].filter(Boolean).join("\n")}}function X(e){if(e&&"object"==typeof e&&"shortMessage"in e){let t=e.shortMessage;if("string"==typeof t&&t.length>0)return t}return e instanceof Error&&e.message?e.message:String(e)}function Q(e){let t=[X(e)];return e&&"object"==typeof e&&("string"==typeof e.all&&t.push(e.all),"string"==typeof e.stdout&&t.push(e.stdout),"string"==typeof e.stderr&&t.push(e.stderr)),t.filter(Boolean).join("\n")}let Z=e("node:url"),ee=e("../../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/index.js"),et="__DBX_APP_KEY__";function ei(e,t){if(!A().statSync(e).isFile())throw Error(`project artifact path must be a file: ${t}`)}function er(e){let t=N().dirname((0,Z.fileURLToPath)(import.meta.url)),i=N().join(t,"templates",e);if(!A().existsSync(i))throw Error(`dbx init template not found: ${e}`);return A().readFileSync(i,"utf8")}let en="项目文件夹名";function es(){return new o("init").description("创建一个新的 dbx 项目").argument("[directory]","要创建的新项目目录名").option("-y, --yes","允许覆盖已有非软链 Skill 目录;覆盖前会自动备份",!1).addOption(new a("--skills-mode <mode>","内置 Skills 安装方式").choices(["link","copy"]).default("link")).addOption(new a("--agent <agent>","要初始化的 Agent,可重复传入;universal 会自动包含").default([]).argParser(r(m))).option("--install-deps","创建前端脚手架后安装依赖",!0).option("--no-install-deps","创建前端脚手架后不安装依赖").option("--git","在项目根目录初始化 Git 仓库").option("--no-prompt","缺少初始化决策时直接失败,不进入交互式提示",!1).option("--schema","输出 dbx init 的机器可读参数契约;不执行初始化",!1).addOption(new a("--auth <mode>","认证策略:login 允许交互登录,require 只接受已登录状态;skip 不适用于 init").choices(["login","require","skip"])).addHelpText("after",`
|
|
2
2
|
Examples:
|
|
3
3
|
${el().map(e=>` ${e}`).join("\n")}`).action(async(e,t,i)=>d(i,i=>new eo(i).run(e,t)))}class eo{context;initReporter;constructor(e){this.context=e}jsonEnabled(){return this.context.json}log(e){this.context.log(e)}warn(e){this.context.warn(e)}async run(e,t){var i,r,n,o,a,l,p,d,c,m,g,_,y;let w,b,S,v,k,$,P,R;if(t.schema)return this.emitSchema();let C=!(t.noPrompt||process.env.DBX_PROMPT_DISABLED)&&!this.context.json&&process.stdin.isTTY&&process.stderr.isTTY,K=await ea(e,C);!function(e){try{(0,E.lstatSync)(e)}catch(e){var t;if("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code)return;throw e}throw Error(`dbx init target directory already exists: ${e}. Choose a new directory name.`)}(K);let M={authMode:(i=t.auth,r=C,"require"===i||"login"===i?i:r?"login":"require"),installFrontendDependencies:t.installDeps,skillsMode:t.skillsMode,yes:t.yes};if("skip"===t.auth)throw Error("dbx init always creates a frontend project and requires authentication; use --auth login or --auth require.");let U=await this.collectInitPlan(t,C);this.initReporter=new q({enabled:!this.jsonEnabled(),useSpinner:O(),log:e=>this.log(e),warn:e=>this.warn(e)}),this.jsonEnabled()||this.emitInitStart(K,U);try{let e;w=await this.ensureRequiredRuntime(),b=await this.ensureAuthenticated(M.authMode),S=await this.executeFrontendProjectPlan(K,U.frontend,M.installFrontendDependencies),this.reporter().startStep("project artifacts: ensuring manifest.yaml and skill/SKILL.md"),v=function(e,t={}){let i=u(e,{kind:t.layout}),r=i.root,n=i.manifestPath,s=i.skillPath,o={app_key:"",layout:i.kind,manifest_path:n,skill_path:s,created:[],preserved:[]};return A().existsSync(n)?(ei(n,"manifest.yaml"),o.app_key=function(e){var t;let i=ee.qg(A().readFileSync(e,"utf8")),r=(t=i,"object"!=typeof t||null===t||Array.isArray(t))?void 0:i.app_key;if("string"==typeof r&&r.trim())return r.trim();throw Error(`manifest app_key is required: ${e}`)}(n),o.preserved.push(N().relative(r,n))):(o.app_key=t.appKey?.trim()||"db_app_xxxxxx",A().mkdirSync(N().dirname(n),{recursive:!0}),A().writeFileSync(n,function(e){let t=er("manifest.yaml");if(2!==t.split(et).length)throw Error(`dbx init manifest template must contain exactly one ${et}`);return t.replace(et,JSON.stringify(e))}(o.app_key),"utf8"),o.created.push(N().relative(r,n))),A().existsSync(s)?(ei(s,N().relative(r,s)),o.preserved.push(N().relative(r,s))):(A().mkdirSync(N().dirname(s),{recursive:!0}),A().writeFileSync(s,er(N().join("skill","SKILL.md")),"utf8"),o.created.push(N().relative(r,s))),o}(K,{appKey:S.scaffold.app_id,layout:"root"}),this.reporter().succeedStep(`project artifacts: created ${v.created.length}, preserved ${v.preserved.length}`),e=N().resolve(K,"README.md"),A().writeFileSync(e,er("README.md"),"utf8"),this.reporter().startStep("project files: writing .dbx/config.json and AGENTS.md"),h(K,U.agents,{frontendDirectory:S.directory}),k=function(e){let t=N().resolve(e,"AGENTS.md");if(!(0,E.existsSync)(t))return(0,E.writeFileSync)(t,`${I}
|
|
4
4
|
`,"utf8"),{path:t,created:!0,updated:!1,already_present:!1};let i=(0,E.readFileSync)(t,"utf8");if(i.includes(I))return{path:t,created:!1,updated:!1,already_present:!0};let r=0===i.length||i.endsWith("\n")?"":"\n";return(0,E.writeFileSync)(t,`${i}${r}${I}
|
|
5
|
-
`,"utf8"),{path:t,created:!1,updated:!0,already_present:!1}}(K),this.reporter().succeedStep("project files: wrote .dbx/config.json and AGENTS.md"),this.reporter().startStep("skills: syncing bundled skills"),$=await x({agents:U.agents,cwd:K,mode:M.skillsMode,cliVersion:s,yes:M.yes}),this.reporter().succeedStep(`skills: synced ${$.skillNames.length} bundled skill(s)`)}catch(e){throw this.reporter().failStep("dbx init failed"),e}f(K,$.skillNames,{source:"bundled",mode:$.mode,skillsVersion:$.skillsVersion,cliVersion:s});let T={success:!0,project_path:K,config_path:`${K.replace(/\/+$/,"")}/.dbx/config.json`,agent_response:(n=K,o=U,a=S,l=k,p=$.skillNames,{tone:"concise_user_facing",summary:(R=((P=(d=o.agents).filter(e=>"universal"!==e)).length>0?P:d).join(", "),`dbx 初始化完成,已为 ${R} 创建完整项目并配置内置 Skills。`),changes:(c=n,m=o,g=a,_=l,y=p,{config:`${c.replace(/\/+$/,"")}/.dbx/config.json`,agent_md:_.path,frontend:{directory:g.directory,description:"已在项目根目录创建前端工程"},skills:{names:y,targets:m.agents.map(e=>{let t=j.find(t=>t.id===e);return{id:e,skills_path:t?.projectPath??""}}).map(e=>({agent:e.id,path:`${c.replace(/\/+$/,"")}/${e.skills_path}`}))}}),notes:ep(a),response_guidance:["Lead with the outcome, not the command line.","Group generated paths by purpose instead of listing every raw file when that would be noisy.","Do not add unrelated git status notes unless the user asked or the git state changes the next step."]}),auth:b,environment:w,agents:U.agents,frontend:S,project_artifacts:v,agent_md:k,skills:$.skillNames,skills_mode:$.mode,skills_version:$.skillsVersion,bundled_root:$.bundledRoot,hosted_root:$.hostedRoot};return this.jsonEnabled()||this.emitInitSuccess(K,S),T}emitSchema(){let e={command:"dbx init",description:"Create a new dbx project with a frontend scaffold, project artifacts, AGENTS.md guidance, and bundled skills.",risk:"write",writes_project_files:!0,requires_interactive_confirmation_to_apply:!1,requires_complete_user_decisions_to_apply:!0,json_supported:!0,user_decisions:{must_ask_user_before_choosing_flags:!0,preferred_user_prompt_style:"Ask a short product question with choices first; keep raw CLI flags as secondary detail only.",project_directory:`${en}(默认:my-app)`,agent:"Ask which agent targets to install for, for example codex, trae, or claude-code. Universal is always included.",git:"Ask whether to initialize a Git repository at the project root. The recommended default is true."},agent_guidance:{recommended_flow:["Run `dbx init --schema --json` if you need the command contract.","For any uncertain user_decisions item, ask the user with the provided prompt and choices instead of exposing raw flags first.","Use `dbx init <directory> --agent <id> --json` to create and inspect a new project."],cautions:["The directory argument must name a new directory; dbx init never initializes the current directory.","--yes only allows replacing existing Skill directories; it does not choose unspecified init parameters.","Use --no-install-deps only when dependency installation should be deferred."]},flags:{path:{kind:"argument",type:"string",required_for_non_interactive_plan:!0,default:"my-app",description:"New project directory name under the current directory."},agent:{type:"array",repeatable:!0,options:[...m],auto_includes:["universal"],description:"Agent skill targets to initialize."},"install-deps":{type:"boolean",default:!0,description:"Install dependencies for the generated frontend project."},git:{type:"boolean",default:!1,description:"Initialize a Git repository at the project root."},"skills-mode":{type:"string",options:["link","copy"],default:"link"},auth:{type:"string",options:["login","require"],default:"login in interactive text mode; require when prompts are unavailable or JSON output is enabled"},yes:{type:"boolean",description:"Allows replacing existing non-symlink Skill directories only. Does not choose unspecified init parameters."},"no-prompt":{type:"boolean",description:"Fail instead of prompting when init decisions are missing."},json:{type:"boolean",description:"Output machine-readable JSON."}},examples:el()};return this.context.log(JSON.stringify(e,null,2)),e}reporter(){return this.initReporter||(this.initReporter=new q({enabled:!this.jsonEnabled(),useSpinner:O(),log:e=>this.log(e),warn:e=>this.warn(e)})),this.initReporter}async collectInitPlan(e,t){let i=function(e){var t;let i,r=function e(t){return Array.isArray(t)?t.flatMap(t=>e(t)):"string"!=typeof t?[]:t.split(",").map(e=>e.trim()).filter(Boolean)}(e);if(0===r.length)return;let n=new Set(m),s=r.filter(e=>!n.has(e));if(s.length>0)throw Error(`Unsupported init agent(s): ${s.join(", ")}. Supported agents: ${m.join(", ")}.`);return t=["universal",...r],i=new Set,t.filter(e=>!i.has(e)&&(i.add(e),!0))}(e.agent);return i||t||ed("dbx init needs --agent <id> when prompts are disabled or unavailable.",{code:"missing_init_decision",missing_flags:["--agent"],user_prompt:"要为哪个 Agent 安装 dbx Skills?",choices:m.filter(e=>"universal"!==e).map(e=>({value:e,label:e})),examples:el()}),{agents:i??await g(),frontend:{directory:".",initializeGit:e.git||!!t&&await _()}}}emitInitStart(e,t){let i=this.reporter();i.header("Initializing dbx project"),i.section("Plan"),i.info("project",eu(e)),i.info("agents",t.agents.join(", ")),i.info("git",t.frontend.initializeGit?"initialize at project root":"skip"),i.blank(),i.section("Progress")}emitInitSuccess(e,t){let i=this.reporter();i.blank(),i.header("dbx project initialized"),i.info("config",`${eu(e)}/.dbx/config.json`);let r=ep(t);if(r.length>0)for(let e of(i.blank(),i.info("notes"),r))i.note(e)}async ensureRequiredRuntime(){this.reporter().startStep("runtime: checking npm");try{let e=await H();return this.reporter().succeedStep(`runtime: npm ${e.version}`),{npm:e}}catch(e){throw this.reporter().failStep("runtime: npm check failed"),e}}async ensureAuthenticated(e){let t,i;this.reporter().startStep("auth: checking login status");try{t=await S({fetch:async(e,t)=>{let i=new AbortController,r=setTimeout(()=>i.abort(),5e3);try{return await fetch(e,{...t,signal:i.signal})}finally{clearTimeout(r)}}})}catch(e){this.reporter().warnStep(`auth: login status check failed, starting login: ${ec(e)}`),t={loggedIn:!1,tokenPath:""}}if(t.loggedIn)return this.reporter().succeedStep("auth: already logged in"),{already_logged_in:!0,login_performed:!1,uid:t.uid,expires_at:t.expiresAt,base_url:t.baseUrl};if("require"===e)throw this.reporter().failStep("auth: login required"),Error("dbx init requires an existing login when prompts are disabled or JSON output is enabled. Run `dbx auth login` first.");this.reporter().succeedStep("auth: not logged in, starting login"),this.reporter().startStep("auth: waiting for login");let r=await b({onVerification:e=>{this.jsonEnabled()||(this.reporter().info("auth visit",e.verificationUrl),this.reporter().info("auth expires in",`${e.expiresIn} seconds`),this.openVerificationUrl(e.verificationUrl),this.reporter().updateStep(`auth: ${w(l.Pending)}`),i=l.Pending)},onPoll:e=>{this.context.json||e.status!==i&&(i=e.status,this.reporter().updateStep(`auth: ${w(e.status)}`))}});return this.reporter().succeedStep(`auth: logged in, token expires at ${new Date(1e3*r.expiresAt).toISOString()}`),{already_logged_in:!1,login_performed:!0,uid:r.uid,expires_at:r.expiresAt,base_url:r.baseUrl,token_path:r.tokenPath}}async openVerificationUrl(e){this.reporter().info("auth","opening link in browser");try{await k(e)}catch(e){this.reporter().warn(`failed to open browser: ${ec(e)}`)}}async executeFrontendProjectPlan(e,t,i){let r,n;this.reporter().startStep("sandbox app: fetching AppID");let s=await v();this.reporter().succeedStep(`sandbox app: ready (${s.sandbox_app_id})`),this.reporter().startStep("frontend: creating scaffold in the new project root");let o=await C({projectPath:e,directory:t.directory,appId:s.sandbox_app_id,initializeGit:t.initializeGit,onStatus:e=>{"clearing_existing_directory"===e?this.reporter().updateStep("frontend: clearing existing scaffold files (keeping node_modules cache)"):this.reporter().updateStep("frontend: writing scaffold files in the new project root")}});if(this.reporter().succeedStep("frontend: scaffold ready in the new project root"),t.initializeGit&&(this.reporter().startStep("git: checking repository initialization"),(0,E.existsSync)((0,P.resolve)(o.path,".git"))?this.reporter().succeedStep("git: repository initialized at project root"):this.reporter().warnStep("git: repository initialization was requested but .git was not created")),!i)return{directory:t.directory,scaffold:o,package_manager:{dependencies:{dependencies_installed:!1,install_attempts:0,recovered_from_ignored_builds:!1,approved_builds:[],install_warning:"skipped by --no-install-deps"}}};this.reporter().startStep("dependencies: checking pnpm");try{r=await F()}catch(e){return n={dependencies_installed:!1,install_attempts:0,recovered_from_ignored_builds:!1,approved_builds:[],install_warning:ec(e)},this.reporter().warnStep(`frontend dependencies were not installed: ${n.install_warning}`),{directory:t.directory,scaffold:o,package_manager:{dependencies:n}}}if(this.reporter().startStep(`dependencies: installing frontend packages with pnpm ${r.version}`),(n=await G(o.path,{pnpmVersion:r.version,autoApproveBuilds:"all-pending",streamOutput:this.context.debug})).dependencies_installed?this.reporter().succeedStep(`dependencies: installed frontend packages with pnpm ${r.version}`):this.reporter().warnStep(`dependencies: install incomplete (${n.install_warning??"unknown reason"})`),!this.jsonEnabled()&&n.recovered_from_ignored_builds){let e=n.approved_builds.includes("*")?"all pending dependency build scripts":`${n.approved_builds.length} dependency build script package(s)`;this.reporter().warn(`pnpm blocked dependency build scripts; approved ${e} and retried install`)}return{directory:t.directory,scaffold:o,package_manager:{pnpm:r,dependencies:n}}}}async function ea(e,t){let i=e?.trim()||(t?await y():"");return i||ed("dbx init requires a new project directory when prompts are disabled or unavailable.",{code:"missing_project_directory",missing_flags:["directory"],user_prompt:en,examples:el()}),function(e){let t=e.trim().replace(/\\/g,"/").replace(/\/+$/,"");if(!t||"."===t)throw Error("dbx init requires a new project directory name.");if((0,P.isAbsolute)(t)||P.win32.isAbsolute(t))throw Error("dbx init project directory must be relative.");if(t.split("/").includes(".."))throw Error("dbx init project directory must stay inside the current directory.");return(0,P.resolve)(process.cwd(),t)}(i)}function el(){return["dbx init my-app --agent codex --json","dbx init my-app --agent codex --no-install-deps --json"]}function ep(e){let t=[];return e.package_manager?.dependencies.install_warning&&t.push(`前端依赖未完整安装:${e.package_manager.dependencies.install_warning}`),t}function ed(e,t){let i=Error(e);throw i.details=t,i}function ec(e){return e instanceof Error&&"AbortError"===e.name?"timed out":e instanceof Error&&e.message?e.message:String(e)}function eu(e){return(0,P.resolve)(e)}export{$ as init_namespaceObject};
|
|
5
|
+
`,"utf8"),{path:t,created:!1,updated:!0,already_present:!1}}(K),this.reporter().succeedStep("project files: wrote .dbx/config.json and AGENTS.md"),this.reporter().startStep("skills: syncing bundled skills"),$=await x({agents:U.agents,cwd:K,mode:M.skillsMode,cliVersion:s,yes:M.yes}),this.reporter().succeedStep(`skills: synced ${$.skillNames.length} bundled skill(s)`)}catch(e){throw this.reporter().failStep("dbx init failed"),e}f(K,$.skillNames,{source:"bundled",mode:$.mode,skillsVersion:$.skillsVersion,cliVersion:s});let T={success:!0,project_path:K,config_path:`${K.replace(/\/+$/,"")}/.dbx/config.json`,agent_response:(n=K,o=U,a=S,l=k,p=$.skillNames,{tone:"concise_user_facing",summary:(R=((P=(d=o.agents).filter(e=>"universal"!==e)).length>0?P:d).join(", "),`dbx 初始化完成,已为 ${R} 创建完整项目并配置内置 Skills。`),changes:(c=n,m=o,g=a,_=l,y=p,{config:`${c.replace(/\/+$/,"")}/.dbx/config.json`,agent_md:_.path,frontend:{directory:g.directory,description:"已在项目根目录创建前端工程"},skills:{names:y,targets:m.agents.map(e=>{let t=j.find(t=>t.id===e);return{id:e,skills_path:t?.projectPath??""}}).map(e=>({agent:e.id,path:`${c.replace(/\/+$/,"")}/${e.skills_path}`}))}}),notes:ep(a),response_guidance:["Lead with the outcome, not the command line.","Group generated paths by purpose instead of listing every raw file when that would be noisy.","Do not add unrelated git status notes unless the user asked or the git state changes the next step."]}),auth:b,environment:w,agents:U.agents,frontend:S,project_artifacts:v,agent_md:k,skills:$.skillNames,skills_mode:$.mode,skills_version:$.skillsVersion,bundled_root:$.bundledRoot,hosted_root:$.hostedRoot};return this.jsonEnabled()||this.emitInitSuccess(K,S),T}emitSchema(){let e={command:"dbx init",description:"Create a new dbx project with a frontend scaffold, project artifacts, AGENTS.md guidance, and bundled skills.",risk:"write",writes_project_files:!0,requires_interactive_confirmation_to_apply:!1,requires_complete_user_decisions_to_apply:!0,json_supported:!0,user_decisions:{must_ask_user_before_choosing_flags:!0,preferred_user_prompt_style:"Ask a short product question with choices first; keep raw CLI flags as secondary detail only.",project_directory:`${en}(默认:my-app)`,agent:"Ask which agent targets to install for, for example codex, trae, or claude-code. Universal is always included.",git:"Ask whether to initialize a Git repository at the project root. The recommended default is true."},agent_guidance:{recommended_flow:["Run `dbx init --schema --json` if you need the command contract.","For any uncertain user_decisions item, ask the user with the provided prompt and choices instead of exposing raw flags first.","Use `dbx init <directory> --agent <id> --json` to create and inspect a new project."],cautions:["The directory argument must name a new directory; dbx init never initializes the current directory.","--yes only allows replacing existing Skill directories; it does not choose unspecified init parameters.","Use --no-install-deps only when dependency installation should be deferred."]},flags:{path:{kind:"argument",type:"string",required_for_non_interactive_plan:!0,default:"my-app",description:"New project directory name under the current directory."},agent:{type:"array",repeatable:!0,options:[...m],auto_includes:["universal"],description:"Agent skill targets to initialize."},"install-deps":{type:"boolean",default:!0,description:"Install dependencies for the generated frontend project."},git:{type:"boolean",default:!1,description:"Initialize a Git repository at the project root."},"skills-mode":{type:"string",options:["link","copy"],default:"link"},auth:{type:"string",options:["login","require"],default:"login in interactive text mode; require when prompts are unavailable or JSON output is enabled"},yes:{type:"boolean",description:"Allows replacing existing non-symlink Skill directories only. Does not choose unspecified init parameters."},"no-prompt":{type:"boolean",description:"Fail instead of prompting when init decisions are missing."},json:{type:"boolean",description:"Output machine-readable JSON."}},examples:el()};return this.context.log(JSON.stringify(e,null,2)),e}reporter(){return this.initReporter||(this.initReporter=new q({enabled:!this.jsonEnabled(),useSpinner:O(),log:e=>this.log(e),warn:e=>this.warn(e)})),this.initReporter}async collectInitPlan(e,t){let i=function(e){var t;let i,r=function e(t){return Array.isArray(t)?t.flatMap(t=>e(t)):"string"!=typeof t?[]:t.split(",").map(e=>e.trim()).filter(Boolean)}(e);if(0===r.length)return;let n=new Set(m),s=r.filter(e=>!n.has(e));if(s.length>0)throw Error(`Unsupported init agent(s): ${s.join(", ")}. Supported agents: ${m.join(", ")}.`);return t=["universal",...r],i=new Set,t.filter(e=>!i.has(e)&&(i.add(e),!0))}(e.agent);return i||t||ed("dbx init needs --agent <id> when prompts are disabled or unavailable.",{code:"missing_init_decision",missing_flags:["--agent"],user_prompt:"要为哪个 Agent 安装 dbx Skills?",choices:m.filter(e=>"universal"!==e).map(e=>({value:e,label:e})),examples:el()}),{agents:i??await g(),frontend:{directory:".",initializeGit:e.git||!!t&&await _()}}}emitInitStart(e,t){let i=this.reporter();i.header("Initializing dbx project"),i.section("Plan"),i.info("project",eu(e)),i.info("agents",t.agents.join(", ")),i.info("git",t.frontend.initializeGit?"initialize at project root":"skip"),i.blank(),i.section("Progress")}emitInitSuccess(e,t){let i=this.reporter();i.blank(),i.header("dbx project initialized"),i.info("config",`${eu(e)}/.dbx/config.json`);let r=ep(t);if(r.length>0)for(let e of(i.blank(),i.info("notes"),r))i.note(e)}async ensureRequiredRuntime(){this.reporter().startStep("runtime: checking npm");try{let e=await H();return this.reporter().succeedStep(`runtime: npm ${e.version}`),{npm:e}}catch(e){throw this.reporter().failStep("runtime: npm check failed"),e}}async ensureAuthenticated(e){let t,i;this.reporter().startStep("auth: checking login status");try{t=await S({fetch:async(e,t)=>{let i=new AbortController,r=setTimeout(()=>i.abort(),5e3);try{return await fetch(e,{...t,signal:i.signal})}finally{clearTimeout(r)}}})}catch(e){this.reporter().warnStep(`auth: login status check failed, starting login: ${ec(e)}`),t={loggedIn:!1,tokenPath:""}}if(t.loggedIn)return this.reporter().succeedStep("auth: already logged in"),{already_logged_in:!0,login_performed:!1,uid:t.uid,expires_at:t.expiresAt,base_url:t.baseUrl};if("require"===e)throw this.reporter().failStep("auth: login required"),Error("dbx init requires an existing login when prompts are disabled or JSON output is enabled. Run `dbx auth login` first.");this.reporter().succeedStep("auth: not logged in, starting login"),this.reporter().startStep("auth: waiting for login");let r=await b({onVerification:e=>{this.jsonEnabled()||(this.reporter().info("auth visit",e.verificationUrl),this.reporter().info("auth expires in",`${e.expiresIn} seconds`),this.openVerificationUrl(e.verificationUrl),this.reporter().updateStep(`auth: ${w(l.Pending)}`),i=l.Pending)},onPoll:e=>{this.context.json||e.status!==i&&(i=e.status,this.reporter().updateStep(`auth: ${w(e.status)}`))}});return this.reporter().succeedStep(`auth: logged in, token expires at ${new Date(1e3*r.expiresAt).toISOString()}`),{already_logged_in:!1,login_performed:!0,uid:r.uid,expires_at:r.expiresAt,base_url:r.baseUrl,token_path:r.tokenPath}}async openVerificationUrl(e){this.reporter().info("auth","opening link in browser");try{await k(e)}catch(e){this.reporter().warn(`failed to open browser: ${ec(e)}`)}}async executeFrontendProjectPlan(e,t,i){let r,n;this.reporter().startStep("sandbox app: fetching AppID");let s=await v(e);this.reporter().succeedStep(`sandbox app: ready (${s.sandbox_app_id})`),this.reporter().startStep("frontend: creating scaffold in the new project root");let o=await C({projectPath:e,directory:t.directory,appId:s.sandbox_app_id,initializeGit:t.initializeGit,onStatus:e=>{"clearing_existing_directory"===e?this.reporter().updateStep("frontend: clearing existing scaffold files (keeping node_modules cache)"):this.reporter().updateStep("frontend: writing scaffold files in the new project root")}});if(this.reporter().succeedStep("frontend: scaffold ready in the new project root"),t.initializeGit&&(this.reporter().startStep("git: checking repository initialization"),(0,E.existsSync)((0,P.resolve)(o.path,".git"))?this.reporter().succeedStep("git: repository initialized at project root"):this.reporter().warnStep("git: repository initialization was requested but .git was not created")),!i)return{directory:t.directory,scaffold:o,package_manager:{dependencies:{dependencies_installed:!1,install_attempts:0,recovered_from_ignored_builds:!1,approved_builds:[],install_warning:"skipped by --no-install-deps"}}};this.reporter().startStep("dependencies: checking pnpm");try{r=await F()}catch(e){return n={dependencies_installed:!1,install_attempts:0,recovered_from_ignored_builds:!1,approved_builds:[],install_warning:ec(e)},this.reporter().warnStep(`frontend dependencies were not installed: ${n.install_warning}`),{directory:t.directory,scaffold:o,package_manager:{dependencies:n}}}if(this.reporter().startStep(`dependencies: installing frontend packages with pnpm ${r.version}`),(n=await G(o.path,{pnpmVersion:r.version,autoApproveBuilds:"all-pending",streamOutput:this.context.debug})).dependencies_installed?this.reporter().succeedStep(`dependencies: installed frontend packages with pnpm ${r.version}`):this.reporter().warnStep(`dependencies: install incomplete (${n.install_warning??"unknown reason"})`),!this.jsonEnabled()&&n.recovered_from_ignored_builds){let e=n.approved_builds.includes("*")?"all pending dependency build scripts":`${n.approved_builds.length} dependency build script package(s)`;this.reporter().warn(`pnpm blocked dependency build scripts; approved ${e} and retried install`)}return{directory:t.directory,scaffold:o,package_manager:{pnpm:r,dependencies:n}}}}async function ea(e,t){let i=e?.trim()||(t?await y():"");return i||ed("dbx init requires a new project directory when prompts are disabled or unavailable.",{code:"missing_project_directory",missing_flags:["directory"],user_prompt:en,examples:el()}),function(e){let t=e.trim().replace(/\\/g,"/").replace(/\/+$/,"");if(!t||"."===t)throw Error("dbx init requires a new project directory name.");if((0,P.isAbsolute)(t)||P.win32.isAbsolute(t))throw Error("dbx init project directory must be relative.");if(t.split("/").includes(".."))throw Error("dbx init project directory must stay inside the current directory.");return(0,P.resolve)(process.cwd(),t)}(i)}function el(){return["dbx init my-app --agent codex --json","dbx init my-app --agent codex --no-install-deps --json"]}function ep(e){let t=[];return e.package_manager?.dependencies.install_warning&&t.push(`前端依赖未完整安装:${e.package_manager.dependencies.install_warning}`),t}function ed(e,t){let i=Error(e);throw i.details=t,i}function ec(e){return e instanceof Error&&"AbortError"===e.name?"timed out":e instanceof Error&&e.message?e.message:String(e)}function eu(e){return(0,P.resolve)(e)}export{$ as init_namespaceObject};
|