chainlesschain 0.162.33 → 0.162.34
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/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-3TazCYWE.js → AIOps-BYfi9NYS.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DUPN0PST.js → ActionButton-BiS_tAN7.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CemvhkzD.js → Analytics-jiWl_p-B.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BL_tAU3M.js → AppLayout-m4sIzDot.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-Dl9l-cxF.js → Audit-CPla3Erm.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BKDDX75m.js → Backup-BGeQzTaB.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CDYePvMI.js → BaseInput-DTf7Z1iU.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CGtR0sg3.js → Chat-DPTlQlD-.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BgRXce4e.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CwYIHOOo.js → Checkbox-DY-XuQMu.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CIF5tbtd.js → Codegen-B6oxPiZI.js} +1 -1
- package/src/assets/web-panel/assets/{Col-z7d4kxeP.js → Col-Dqxb4wSE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DUlDrqF7.js → Community-DCIX514p.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CJ1o8QQR.js → Compact-BGtCzDoJ.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D3i9d_uO.js → Compliance-zcOYd55o.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Wm7JTkfB.js → Cowork-DVTtdIdM.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-B0QnHhZx.js → Cron-CPUaR69k.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-3yPrnNgd.js → Crosschain-DnjUS6QH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-cfdkiDWF.js → DID-Dnz8VDmx.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DFkgM4gT.js → Dashboard-CtWf27j7.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-YYWE81DL.js → Dropdown-B4GC1ZV4.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BXfHK1Bn.js → EmailListRenderer-wjij3kzr.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DInUxJ2G.js → FamilyGuardDashboard-rS-2W4u5.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DNUYeFsv.js → Federation-90p5Tnoz.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Cr7eVEBB.js → FormItemContext-Cnrw7gzq.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-_gF4cmDa.js → GenericCardRenderer-C85NsWa3.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BqldmUbO.js → Git-BFAVM9F8.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BF59ZiQ8.js → Governance-DBoRonpq.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Cy7y1eb9.js → Inference-DHRyD66j.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B3fVocTO.js → KnowledgeGraph-CTvUKecD.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BDirsUVk.js → Logs-CB0dv_Ts.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-GhXpZgp2.js → Marketplace-CN7Hm5Uw.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-0VvfIhKx.js → McpTools-q5H25_8L.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CJLBgAUT.js → Memory-BCV3pZ1d.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BMedY9Yg.js → MobileBridge-C04Mngt4.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-CUxONYre.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CgEuUg0g.js → Mtc-ByAMz2DN.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-1pWNe_xi.js → MtcAudit-B7V7byJq.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DPIQ7oZL.js → Multisig-DtKmcVQV.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-W__P_P4Z.js → NLProgramming-CaMbT5SC.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C_MCDhFk.js → Notes-DRjbSTCU.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-CDFotapL.js → NotificationSettings-B9YbJID5.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BcI_-vGS.js +1 -0
- package/src/assets/web-panel/assets/{Organization-D6lMumhD.js → Organization-oTask4BE.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BMOvUMW6.js → Overflow-Bab06ey7.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DsQTEw1t.js → P2P--wlBeU0N.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CncRtN1Z.js → PdhVaultBrowser-D4t77Pwc.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DDC-DkUl.js → Permissions-B3sf6CJ3.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DVKY_NnT.js → PersonalDataHub-BXOojk63.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-C7oDVTl-.js → Pipeline-DReqtBFN.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DReGvTEJ.js → Privacy-cT1GwKLx.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C-j2dzxJ.js → ProjectInit-BhTAzVhH.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DcUsvFnc.js → ProjectSettings-CK-D8Fyj.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CbHiwen6.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DIpohWG5.js → Providers-B-ftiXa8.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DdvLtpEU.js → QuickAsk-CT5XPwTF.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DPAi2zo3.js → Recommend-CohhlBZ_.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-DJD7qXSI.js → Reputation-CrgbixFz.js} +1 -1
- package/src/assets/web-panel/assets/{Row-XERdPDHk.js → Row-ClExmBn3.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Cl_VlCLg.js → RssFeed-VV0qizCJ.js} +2 -2
- package/src/assets/web-panel/assets/{Search-C-poG9P5.js → Search-CqJapSiL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DjjCrw8v.js → Security-DY66Zie6.js} +2 -2
- package/src/assets/web-panel/assets/{Services-BuWeB4YJ.js → Services-RQwxat7-.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-VZXOKwC_.js → Skeleton-0v37UTU_.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-B76ONTfP.js → Skills-B4Vm4DxN.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DIj1KREq.js → Sla-CggphTlo.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BrAp3Yk3.js → SpeechSettings-BAOU08C7.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings--mJcpccF.js → SyncSettings-DmtC4J1w.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DM8cMr83.js → Tasks-CExqxzL6.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-kOBK6m1Z.js → Templates-C1QK0YoU.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BjSzYPzn.js → Tenant-CieOfmqp.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DwpY-Ay7.js → Terminal-DWdhrxRq.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-aoI0DazM.js → TimelineRenderer-CjFVUUDU.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-YwE0LqSZ.js → Tokens-Bwbk3id9.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CwSKzvlX.js → Trigger-uJle_yj4.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B__Jqdzn.js → Trust-BcOuxAA5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-mty0jwmx.js → UkeySign-DUu7Ufg6.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Ddsx_OQ6.js → VideoEditing-Ck8JtQ2n.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D4Q8yXZm.js → Wallet-B3jw43on.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-CLUaKUr5.js → WebAuthn-Baf9K0y7.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-Di5pOaeC.js → WorkflowEditor-CTEDl_83.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CELatHkT.js → chat-CKV51quV.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CawDLjXV.js → colors-BO_RP_yz.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DeMp-K0j.js → compact-item-BZsxw_ZG.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-zY9kXivd.js → createContext-CAbvtzVL.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DQYatsRR.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-VEBMW8E4.js → hasIn-QmHT8zDz.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjctklSd.js → index-5hlO2-JQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DClGYjBM.js → index-8BMLlHCv.js} +1 -1
- package/src/assets/web-panel/assets/{index-KcOEkUCM.js → index-9IqJODII.js} +1 -1
- package/src/assets/web-panel/assets/{index-fBNVDEf2.js → index-B2aiE8jk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqJ2r12F.js → index-B3fwyCjJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-VJnHvkv2.js → index-B5zhcul9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHqvj9uz.js → index-B9Z83FTS.js} +1 -1
- package/src/assets/web-panel/assets/{index-8kqE_cVD.js → index-BCsZiq4i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr7lnIeI.js → index-BEJa1FiF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSiL_W2n.js → index-BL7gQAuB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPHe9NYG.js → index-BNvTNZ1V.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8AZpx7d.js → index-BPZHeug4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DALuVdhu.js → index-BRNYA0BV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHxHLv2b.js → index-BnPBG3Tr.js} +1 -1
- package/src/assets/web-panel/assets/index-Bv_y1Ud7.js +1 -0
- package/src/assets/web-panel/assets/{index-CbJZzK9B.js → index-C3K1eHDd.js} +1 -1
- package/src/assets/web-panel/assets/{index-V3K9gvKR.js → index-C6AA-xB2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfGGKoo8.js → index-C6i3reUS.js} +1 -1
- package/src/assets/web-panel/assets/{index-GRNVdvoA.js → index-CEh2Ry_A.js} +1 -1
- package/src/assets/web-panel/assets/{index-TfXODan7.js → index-CSaI8R_7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWbbB1MI.js → index-CVoYeZ5Q.js} +1 -1
- package/src/assets/web-panel/assets/index-CZZnSJEX.js +1 -0
- package/src/assets/web-panel/assets/{index-u_1aiNTA.js → index-CqiKnXtL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtoauqWt.js → index-CsBx0u5G.js} +1 -1
- package/src/assets/web-panel/assets/{index-b3ZuAreb.js → index-D8CHQnPl.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVkrfyuk.js → index-DBCYOypV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXNe_zIP.js → index-DC1CFfQU.js} +1 -1
- package/src/assets/web-panel/assets/{index-S9JZDSaa.js → index-DKnngF_f.js} +1 -1
- package/src/assets/web-panel/assets/{index-XFyv3Sg_.js → index-DKquNxL2.js} +3 -3
- package/src/assets/web-panel/assets/{index-vaD1iHg5.js → index-DRK0oAV5.js} +1 -1
- package/src/assets/web-panel/assets/{index-SrQIPYq8.js → index-DeC7lehI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFc0vBN9.js → index-DjrDGJP2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfZV3FXN.js → index-Dln_vjSY.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0GhuYLk.js → index-Dob6B6qS.js} +1 -1
- package/src/assets/web-panel/assets/{index-JseP3-5X.js → index-GPY0LjCu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhsfyHcg.js → index-Ha2_56mf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtLZammH.js → index-fnDgExTu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyeYs7SG.js → index-jd2r-T4p.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dna2psGz.js → index-qPafbZmr.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Sd7Eayz4.js → initDefaultProps-Bc2GWeWe.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DlToY72q.js → motion-BI-Rxw6o.js} +1 -1
- package/src/assets/web-panel/assets/{move-DvS7EmAP.js → move-DRPdwDQB.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CzLq4QKW.js → omit-B4XTl3jW.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BcM75Jx_.js → pickAttrs-Do5d86Wr.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B7xXXiwd.js → placementArrow-B8VGZ0ZF.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CrYPRB-g.js → responsiveObserve-Cf0kI_vN.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CSYTtsRt.js → slide-Cb0psjSL.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CeSuOVT_.js → statusUtils-Bjuo5Oal.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-KiQethca.js → styleChecker-BLMhoHJ5.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CSQnQdiv.js → useFlexGapSupport-BdCwAfNU.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Br8Kr1pr.js → useFs-9Jhaz5gG.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DGJtDcMm.js → usePersonalDataHub-xYFyXKwD.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C-jVtGka.js → vnode-CVhepE6Z.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CeWySTPF.js → zoom-IbbtJ4Zr.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +19 -0
- package/src/commands/command.js +187 -0
- package/src/commands/context.js +189 -0
- package/src/index.js +4 -0
- package/src/lib/slash-commands.js +197 -0
- package/src/repl/agent-repl.js +42 -1
- package/src/runtime/agent-core.js +253 -0
- package/src/runtime/headless-runner.js +30 -1
- package/src/runtime/headless-stream.js +65 -0
- package/src/runtime/mcp-config.js +100 -0
- package/src/runtime/policies/agent-policy.js +1 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DZjc9uKn.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-mdohgRlL.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Dtht0cEs.js +0 -1
- package/src/assets/web-panel/assets/Projects-jSjWnmr6.js +0 -1
- package/src/assets/web-panel/assets/devWarning-zLjV7g6r.js +0 -1
- package/src/assets/web-panel/assets/index-CDtUWCtX.js +0 -1
- package/src/assets/web-panel/assets/index-d_RPqH7u.js +0 -1
|
@@ -1729,6 +1729,19 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
1729
1729
|
? baseUrl
|
|
1730
1730
|
: "https://api.anthropic.com/v1";
|
|
1731
1731
|
|
|
1732
|
+
// Real token streaming (--include-partial-messages): stream the SSE response
|
|
1733
|
+
// and forward text deltas live, assembling tool_use blocks back into the
|
|
1734
|
+
// same {message, usage} shape the non-streaming path returns.
|
|
1735
|
+
if (typeof options.onToken === "function") {
|
|
1736
|
+
return await _chatAnthropicStreaming(
|
|
1737
|
+
`${url}/messages`,
|
|
1738
|
+
{ ...body, stream: true },
|
|
1739
|
+
{ "x-api-key": key, "anthropic-version": "2023-06-01" },
|
|
1740
|
+
options.onToken,
|
|
1741
|
+
signal,
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1732
1745
|
const response = await fetch(`${url}/messages`, {
|
|
1733
1746
|
method: "POST",
|
|
1734
1747
|
headers: {
|
|
@@ -1798,6 +1811,27 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
1798
1811
|
volcengine: "doubao-seed-1-6-251015",
|
|
1799
1812
|
};
|
|
1800
1813
|
|
|
1814
|
+
// Real token streaming (--include-partial-messages) for every OpenAI-compatible
|
|
1815
|
+
// provider (openai / deepseek / dashscope / mistral / gemini / volcengine):
|
|
1816
|
+
// stream the SSE response, forward content deltas live, and reassemble the
|
|
1817
|
+
// delta-fragmented tool_calls into the standard {message, usage} shape.
|
|
1818
|
+
if (typeof options.onToken === "function") {
|
|
1819
|
+
return await _chatOpenAIStreaming(
|
|
1820
|
+
`${url}/chat/completions`,
|
|
1821
|
+
{
|
|
1822
|
+
model: model || defaultModels[provider] || "gpt-4o-mini",
|
|
1823
|
+
messages,
|
|
1824
|
+
tools,
|
|
1825
|
+
stream: true,
|
|
1826
|
+
stream_options: { include_usage: true },
|
|
1827
|
+
},
|
|
1828
|
+
key,
|
|
1829
|
+
options.onToken,
|
|
1830
|
+
signal,
|
|
1831
|
+
provider,
|
|
1832
|
+
);
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1801
1835
|
const response = await fetch(`${url}/chat/completions`, {
|
|
1802
1836
|
method: "POST",
|
|
1803
1837
|
headers: {
|
|
@@ -1934,6 +1968,225 @@ async function _chatOllamaStreaming(apiUrl, body, onToken, signal) {
|
|
|
1934
1968
|
return _ollamaFinalize(state);
|
|
1935
1969
|
}
|
|
1936
1970
|
|
|
1971
|
+
// ─── Anthropic streaming (SSE → {message, usage}, tool_use reassembled) ──────
|
|
1972
|
+
//
|
|
1973
|
+
// Anthropic /messages with stream:true emits SSE: message_start (input usage),
|
|
1974
|
+
// content_block_start (text or tool_use header), content_block_delta
|
|
1975
|
+
// (text_delta → onToken, or input_json_delta accumulating a tool's JSON args),
|
|
1976
|
+
// message_delta (output usage). We reduce per `data:` line and finalize into
|
|
1977
|
+
// the same shape chatWithTools returns non-streamed.
|
|
1978
|
+
|
|
1979
|
+
function _anthropicInitState() {
|
|
1980
|
+
return { text: "", blocks: {}, inputTokens: 0, outputTokens: 0 };
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
function _anthropicReduceLine(state, raw, onToken) {
|
|
1984
|
+
const line = (raw || "").trim();
|
|
1985
|
+
if (!line.startsWith("data:")) return state;
|
|
1986
|
+
const payload = line.slice(5).trim();
|
|
1987
|
+
if (!payload) return state;
|
|
1988
|
+
let obj;
|
|
1989
|
+
try {
|
|
1990
|
+
obj = JSON.parse(payload);
|
|
1991
|
+
} catch {
|
|
1992
|
+
return state;
|
|
1993
|
+
}
|
|
1994
|
+
if (obj.type === "message_start") {
|
|
1995
|
+
state.inputTokens =
|
|
1996
|
+
Number(obj.message?.usage?.input_tokens) || state.inputTokens;
|
|
1997
|
+
} else if (obj.type === "content_block_start") {
|
|
1998
|
+
const cb = obj.content_block || {};
|
|
1999
|
+
state.blocks[obj.index] =
|
|
2000
|
+
cb.type === "tool_use"
|
|
2001
|
+
? { type: "tool_use", id: cb.id, name: cb.name, json: "" }
|
|
2002
|
+
: { type: "text" };
|
|
2003
|
+
} else if (obj.type === "content_block_delta") {
|
|
2004
|
+
const d = obj.delta || {};
|
|
2005
|
+
if (d.type === "text_delta" && d.text) {
|
|
2006
|
+
state.text += d.text;
|
|
2007
|
+
if (typeof onToken === "function") {
|
|
2008
|
+
try {
|
|
2009
|
+
onToken(d.text);
|
|
2010
|
+
} catch {
|
|
2011
|
+
// a failing UI hook must never break the run
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
} else if (d.type === "input_json_delta" && state.blocks[obj.index]) {
|
|
2015
|
+
state.blocks[obj.index].json += d.partial_json || "";
|
|
2016
|
+
}
|
|
2017
|
+
} else if (obj.type === "message_delta") {
|
|
2018
|
+
state.outputTokens = Number(obj.usage?.output_tokens) || state.outputTokens;
|
|
2019
|
+
}
|
|
2020
|
+
return state;
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
function _anthropicFinalize(state) {
|
|
2024
|
+
const toolCalls = [];
|
|
2025
|
+
for (const k of Object.keys(state.blocks)) {
|
|
2026
|
+
const b = state.blocks[k];
|
|
2027
|
+
if (b.type === "tool_use") {
|
|
2028
|
+
let input = {};
|
|
2029
|
+
try {
|
|
2030
|
+
input = b.json ? JSON.parse(b.json) : {};
|
|
2031
|
+
} catch {
|
|
2032
|
+
input = {};
|
|
2033
|
+
}
|
|
2034
|
+
toolCalls.push({
|
|
2035
|
+
id: b.id,
|
|
2036
|
+
type: "function",
|
|
2037
|
+
function: { name: b.name, arguments: JSON.stringify(input) },
|
|
2038
|
+
});
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
const message = { role: "assistant", content: state.text };
|
|
2042
|
+
if (toolCalls.length) message.tool_calls = toolCalls;
|
|
2043
|
+
const out = { message };
|
|
2044
|
+
if (state.inputTokens || state.outputTokens) {
|
|
2045
|
+
out.usage = {
|
|
2046
|
+
input_tokens: state.inputTokens,
|
|
2047
|
+
output_tokens: state.outputTokens,
|
|
2048
|
+
};
|
|
2049
|
+
}
|
|
2050
|
+
return out;
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
/** Pure reducer over Anthropic SSE lines — exported for tests (no HTTP). */
|
|
2054
|
+
export function _accumulateAnthropicStream(lines, onToken) {
|
|
2055
|
+
const state = _anthropicInitState();
|
|
2056
|
+
for (const line of lines) _anthropicReduceLine(state, line, onToken);
|
|
2057
|
+
return _anthropicFinalize(state);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
async function _chatAnthropicStreaming(apiUrl, body, extraHeaders, onToken, signal) {
|
|
2061
|
+
const response = await fetch(apiUrl, {
|
|
2062
|
+
method: "POST",
|
|
2063
|
+
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
2064
|
+
signal,
|
|
2065
|
+
body: JSON.stringify(body),
|
|
2066
|
+
});
|
|
2067
|
+
if (!response.ok) {
|
|
2068
|
+
throw new Error(`Anthropic error: ${response.status}`);
|
|
2069
|
+
}
|
|
2070
|
+
const state = _anthropicInitState();
|
|
2071
|
+
const reader = response.body.getReader();
|
|
2072
|
+
const decoder = new TextDecoder();
|
|
2073
|
+
let buf = "";
|
|
2074
|
+
for (;;) {
|
|
2075
|
+
const { done, value } = await reader.read();
|
|
2076
|
+
if (done) break;
|
|
2077
|
+
buf += decoder.decode(value, { stream: true });
|
|
2078
|
+
const lines = buf.split("\n");
|
|
2079
|
+
buf = lines.pop() || "";
|
|
2080
|
+
for (const line of lines) _anthropicReduceLine(state, line, onToken);
|
|
2081
|
+
}
|
|
2082
|
+
if (buf.trim()) _anthropicReduceLine(state, buf, onToken);
|
|
2083
|
+
return _anthropicFinalize(state);
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
// ─── OpenAI-compatible streaming (SSE → {message, usage}) ────────────────────
|
|
2087
|
+
//
|
|
2088
|
+
// `data:` lines carry choices[0].delta.{content, tool_calls[]}; tool_calls
|
|
2089
|
+
// arrive fragmented and keyed by `index` (name in the first chunk, arguments
|
|
2090
|
+
// concatenated across chunks). usage rides the terminal chunk when
|
|
2091
|
+
// stream_options.include_usage was requested. Terminator: `data: [DONE]`.
|
|
2092
|
+
|
|
2093
|
+
function _openaiInitState() {
|
|
2094
|
+
return { text: "", tools: [], inputTokens: 0, outputTokens: 0 };
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
function _openaiReduceLine(state, raw, onToken) {
|
|
2098
|
+
const line = (raw || "").trim();
|
|
2099
|
+
if (!line.startsWith("data:")) return state;
|
|
2100
|
+
const payload = line.slice(5).trim();
|
|
2101
|
+
if (!payload || payload === "[DONE]") return state;
|
|
2102
|
+
let obj;
|
|
2103
|
+
try {
|
|
2104
|
+
obj = JSON.parse(payload);
|
|
2105
|
+
} catch {
|
|
2106
|
+
return state;
|
|
2107
|
+
}
|
|
2108
|
+
const delta = obj.choices?.[0]?.delta;
|
|
2109
|
+
if (delta?.content) {
|
|
2110
|
+
state.text += delta.content;
|
|
2111
|
+
if (typeof onToken === "function") {
|
|
2112
|
+
try {
|
|
2113
|
+
onToken(delta.content);
|
|
2114
|
+
} catch {
|
|
2115
|
+
// a failing UI hook must never break the run
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
if (Array.isArray(delta?.tool_calls)) {
|
|
2120
|
+
for (const tc of delta.tool_calls) {
|
|
2121
|
+
const idx = tc.index ?? 0;
|
|
2122
|
+
if (!state.tools[idx]) state.tools[idx] = { id: undefined, name: "", args: "" };
|
|
2123
|
+
if (tc.id) state.tools[idx].id = tc.id;
|
|
2124
|
+
if (tc.function?.name) state.tools[idx].name = tc.function.name;
|
|
2125
|
+
if (tc.function?.arguments) state.tools[idx].args += tc.function.arguments;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
if (obj.usage) {
|
|
2129
|
+
state.inputTokens = Number(obj.usage.prompt_tokens) || state.inputTokens;
|
|
2130
|
+
state.outputTokens =
|
|
2131
|
+
Number(obj.usage.completion_tokens) || state.outputTokens;
|
|
2132
|
+
}
|
|
2133
|
+
return state;
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
function _openaiFinalize(state) {
|
|
2137
|
+
const toolCalls = state.tools.filter(Boolean).map((t) => ({
|
|
2138
|
+
id: t.id || `call_${t.name || "tool"}`,
|
|
2139
|
+
type: "function",
|
|
2140
|
+
function: { name: t.name, arguments: t.args || "{}" },
|
|
2141
|
+
}));
|
|
2142
|
+
const message = { role: "assistant", content: state.text };
|
|
2143
|
+
if (toolCalls.length) message.tool_calls = toolCalls;
|
|
2144
|
+
const out = { message };
|
|
2145
|
+
if (state.inputTokens || state.outputTokens) {
|
|
2146
|
+
out.usage = {
|
|
2147
|
+
input_tokens: state.inputTokens,
|
|
2148
|
+
output_tokens: state.outputTokens,
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2151
|
+
return out;
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
/** Pure reducer over OpenAI-compatible SSE lines — exported for tests. */
|
|
2155
|
+
export function _accumulateOpenAIStream(lines, onToken) {
|
|
2156
|
+
const state = _openaiInitState();
|
|
2157
|
+
for (const line of lines) _openaiReduceLine(state, line, onToken);
|
|
2158
|
+
return _openaiFinalize(state);
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
async function _chatOpenAIStreaming(apiUrl, body, apiKey, onToken, signal, provider) {
|
|
2162
|
+
const response = await fetch(apiUrl, {
|
|
2163
|
+
method: "POST",
|
|
2164
|
+
headers: {
|
|
2165
|
+
"Content-Type": "application/json",
|
|
2166
|
+
Authorization: `Bearer ${apiKey}`,
|
|
2167
|
+
},
|
|
2168
|
+
signal,
|
|
2169
|
+
body: JSON.stringify(body),
|
|
2170
|
+
});
|
|
2171
|
+
if (!response.ok) {
|
|
2172
|
+
throw new Error(`${provider} API error: ${response.status}`);
|
|
2173
|
+
}
|
|
2174
|
+
const state = _openaiInitState();
|
|
2175
|
+
const reader = response.body.getReader();
|
|
2176
|
+
const decoder = new TextDecoder();
|
|
2177
|
+
let buf = "";
|
|
2178
|
+
for (;;) {
|
|
2179
|
+
const { done, value } = await reader.read();
|
|
2180
|
+
if (done) break;
|
|
2181
|
+
buf += decoder.decode(value, { stream: true });
|
|
2182
|
+
const lines = buf.split("\n");
|
|
2183
|
+
buf = lines.pop() || "";
|
|
2184
|
+
for (const line of lines) _openaiReduceLine(state, line, onToken);
|
|
2185
|
+
}
|
|
2186
|
+
if (buf.trim()) _openaiReduceLine(state, buf, onToken);
|
|
2187
|
+
return _openaiFinalize(state);
|
|
2188
|
+
}
|
|
2189
|
+
|
|
1937
2190
|
function _normalizeAnthropicResponse(data) {
|
|
1938
2191
|
const content = data.content || [];
|
|
1939
2192
|
const textBlocks = content.filter((b) => b.type === "text");
|
|
@@ -26,7 +26,11 @@ import {
|
|
|
26
26
|
agentLoop as coreAgentLoop,
|
|
27
27
|
formatToolArgs,
|
|
28
28
|
} from "./agent-core.js";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
loadMcpConfig,
|
|
31
|
+
resolvePermissionPromptTool,
|
|
32
|
+
makePermissionPromptConfirmer,
|
|
33
|
+
} from "./mcp-config.js";
|
|
30
34
|
import { IterationBudget } from "../lib/iteration-budget.js";
|
|
31
35
|
import {
|
|
32
36
|
startSession as jsonlStartSession,
|
|
@@ -390,6 +394,31 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
390
394
|
}
|
|
391
395
|
}
|
|
392
396
|
|
|
397
|
+
// --permission-prompt-tool: route every CONFIRM-tier approval to an MCP tool
|
|
398
|
+
// (loaded via --mcp-config) instead of headless fail-closed. Overrides the
|
|
399
|
+
// permission-mode confirmer on the gate for this session.
|
|
400
|
+
if (options.permissionPromptTool) {
|
|
401
|
+
let ppt;
|
|
402
|
+
try {
|
|
403
|
+
ppt = resolvePermissionPromptTool(mcp, options.permissionPromptTool);
|
|
404
|
+
} catch (err) {
|
|
405
|
+
writeErr(`Error: ${err.message}\n`);
|
|
406
|
+
if (mcp?.mcpClient) await mcp.mcpClient.disconnectAll().catch(() => {});
|
|
407
|
+
return { exitCode: 1, result: err.message, isError: true };
|
|
408
|
+
}
|
|
409
|
+
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
410
|
+
approvalGate.setConfirmer(
|
|
411
|
+
makePermissionPromptConfirmer({
|
|
412
|
+
mcpClient: mcp.mcpClient,
|
|
413
|
+
server: ppt.server,
|
|
414
|
+
tool: ppt.tool,
|
|
415
|
+
writeErr,
|
|
416
|
+
isText,
|
|
417
|
+
}),
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
393
422
|
const loopOptions = {
|
|
394
423
|
model,
|
|
395
424
|
provider,
|
|
@@ -20,6 +20,11 @@ import { bootstrap } from "./bootstrap.js";
|
|
|
20
20
|
import { buildSystemPrompt, agentLoop as coreAgentLoop } from "./agent-core.js";
|
|
21
21
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
22
22
|
import { expandFileRefs } from "./file-ref-expander.js";
|
|
23
|
+
import {
|
|
24
|
+
loadMcpConfig,
|
|
25
|
+
resolvePermissionPromptTool,
|
|
26
|
+
makePermissionPromptConfirmer,
|
|
27
|
+
} from "./mcp-config.js";
|
|
23
28
|
import { IterationBudget } from "../lib/iteration-budget.js";
|
|
24
29
|
import {
|
|
25
30
|
resolvePermissionMode,
|
|
@@ -227,6 +232,52 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
227
232
|
}
|
|
228
233
|
}
|
|
229
234
|
|
|
235
|
+
// --mcp-config: connect ad-hoc MCP servers for the whole stream session and
|
|
236
|
+
// expose their tools to the LLM (Claude-Code parity). Best-effort connect; a
|
|
237
|
+
// missing/empty config fails the session up front.
|
|
238
|
+
let mcp = null;
|
|
239
|
+
if (options.mcpConfig) {
|
|
240
|
+
const doLoadMcp = deps.loadMcpConfig || loadMcpConfig;
|
|
241
|
+
try {
|
|
242
|
+
mcp = await doLoadMcp(options.mcpConfig, { writeErr });
|
|
243
|
+
} catch (err) {
|
|
244
|
+
emit({
|
|
245
|
+
type: "result",
|
|
246
|
+
subtype: "error",
|
|
247
|
+
is_error: true,
|
|
248
|
+
error: err.message,
|
|
249
|
+
});
|
|
250
|
+
return { exitCode: 1, turns: 0 };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// --permission-prompt-tool: defer CONFIRM-tier approvals to an MCP tool
|
|
255
|
+
// (loaded via --mcp-config) instead of headless fail-closed.
|
|
256
|
+
if (options.permissionPromptTool) {
|
|
257
|
+
let ppt;
|
|
258
|
+
try {
|
|
259
|
+
ppt = resolvePermissionPromptTool(mcp, options.permissionPromptTool);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
emit({
|
|
262
|
+
type: "result",
|
|
263
|
+
subtype: "error",
|
|
264
|
+
is_error: true,
|
|
265
|
+
error: err.message,
|
|
266
|
+
});
|
|
267
|
+
if (mcp?.mcpClient) await mcp.mcpClient.disconnectAll().catch(() => {});
|
|
268
|
+
return { exitCode: 1, turns: 0 };
|
|
269
|
+
}
|
|
270
|
+
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
271
|
+
approvalGate.setConfirmer(
|
|
272
|
+
makePermissionPromptConfirmer({
|
|
273
|
+
mcpClient: mcp.mcpClient,
|
|
274
|
+
server: ppt.server,
|
|
275
|
+
tool: ppt.tool,
|
|
276
|
+
}),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
230
281
|
const loopOptionsBase = {
|
|
231
282
|
model,
|
|
232
283
|
provider,
|
|
@@ -240,6 +291,11 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
240
291
|
enabledToolNames,
|
|
241
292
|
disabledTools,
|
|
242
293
|
prepareCall: goalPrepareCallFn,
|
|
294
|
+
// --mcp-config wiring (tool defs + dispatch map + live client).
|
|
295
|
+
mcpClient: mcp?.mcpClient || null,
|
|
296
|
+
extraToolDefinitions: mcp?.extraToolDefinitions || undefined,
|
|
297
|
+
externalToolExecutors: mcp?.externalToolExecutors || undefined,
|
|
298
|
+
externalToolDescriptors: mcp?.externalToolDescriptors || undefined,
|
|
243
299
|
chatFn: deps.chatFn || options.chatFn || undefined,
|
|
244
300
|
signal: options.signal || undefined,
|
|
245
301
|
// --include-partial-messages: stream live assistant-text deltas as
|
|
@@ -331,6 +387,15 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
331
387
|
});
|
|
332
388
|
}
|
|
333
389
|
|
|
390
|
+
// Tear down ad-hoc MCP servers (--mcp-config) when stdin closes.
|
|
391
|
+
if (mcp?.mcpClient) {
|
|
392
|
+
try {
|
|
393
|
+
await mcp.mcpClient.disconnectAll();
|
|
394
|
+
} catch {
|
|
395
|
+
// ignore — disconnect is best-effort
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
334
399
|
emit({ type: "system", subtype: "end", session_id: sessionId, turns });
|
|
335
400
|
return { exitCode: sawError ? 1 : 0, turns };
|
|
336
401
|
}
|
|
@@ -137,3 +137,103 @@ export async function loadMcpConfig(filePath, deps = {}) {
|
|
|
137
137
|
}
|
|
138
138
|
return setupMcpFromConfig(servers, deps);
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
// ─── --permission-prompt-tool (programmable headless approval) ──────────────
|
|
142
|
+
//
|
|
143
|
+
// Claude-Code parity: instead of headless fail-closed (auto-deny risky tools),
|
|
144
|
+
// route every CONFIRM-tier decision to an MCP tool that returns the verdict.
|
|
145
|
+
// The named tool must come from a server loaded via --mcp-config.
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Resolve a `mcp__<server>__<tool>` permission-prompt-tool name to its server +
|
|
149
|
+
* tool, validating it was actually loaded. Throws (fail fast) otherwise.
|
|
150
|
+
*/
|
|
151
|
+
export function resolvePermissionPromptTool(mcp, toolName) {
|
|
152
|
+
if (!mcp || !mcp.externalToolExecutors) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
`--permission-prompt-tool "${toolName}" requires --mcp-config ` +
|
|
155
|
+
`(the tool must come from a loaded MCP server).`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
const exec = mcp.externalToolExecutors[toolName];
|
|
159
|
+
if (!exec || exec.kind !== "mcp") {
|
|
160
|
+
const avail = Object.keys(mcp.externalToolExecutors).join(", ") || "(none)";
|
|
161
|
+
throw new Error(
|
|
162
|
+
`--permission-prompt-tool "${toolName}" not found among loaded MCP ` +
|
|
163
|
+
`tools. Available: ${avail}`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
return { server: exec.serverName, tool: exec.toolName };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Interpret an MCP `tools/call` result as an allow/deny verdict. Liberal: reads
|
|
171
|
+
* a JSON `{behavior:"allow"|"deny"}` (Claude-Code shape) from a text content
|
|
172
|
+
* block, or a top-level `behavior`/`decision`/`allow`. Anything not clearly an
|
|
173
|
+
* allow is treated as deny (fail-closed).
|
|
174
|
+
*/
|
|
175
|
+
export function parsePermissionDecision(result) {
|
|
176
|
+
if (!result || result.isError) {
|
|
177
|
+
return { allow: false, reason: "permission tool returned no/err result" };
|
|
178
|
+
}
|
|
179
|
+
let payload = result;
|
|
180
|
+
if (Array.isArray(result.content)) {
|
|
181
|
+
const textBlock = result.content.find(
|
|
182
|
+
(b) => b && b.type === "text" && typeof b.text === "string",
|
|
183
|
+
);
|
|
184
|
+
if (textBlock) {
|
|
185
|
+
try {
|
|
186
|
+
payload = JSON.parse(textBlock.text);
|
|
187
|
+
} catch {
|
|
188
|
+
payload = { behavior: textBlock.text.trim() };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const behavior =
|
|
193
|
+
payload?.behavior ??
|
|
194
|
+
payload?.decision ??
|
|
195
|
+
(payload?.allow === true ? "allow" : undefined);
|
|
196
|
+
const allow = behavior === "allow" || payload?.allow === true;
|
|
197
|
+
return {
|
|
198
|
+
allow,
|
|
199
|
+
reason: payload?.message || payload?.reason || null,
|
|
200
|
+
updatedInput: payload?.updatedInput,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Build an ApprovalGate confirmer that defers each CONFIRM-tier decision to the
|
|
206
|
+
* given MCP tool. Fail-closed: any tool error → deny.
|
|
207
|
+
*
|
|
208
|
+
* @param {object} args { mcpClient, server, tool, writeErr?, isText? }
|
|
209
|
+
* @returns {(ctx:{tool:string,args:object})=>Promise<boolean>}
|
|
210
|
+
*/
|
|
211
|
+
export function makePermissionPromptConfirmer({
|
|
212
|
+
mcpClient,
|
|
213
|
+
server,
|
|
214
|
+
tool,
|
|
215
|
+
writeErr = () => {},
|
|
216
|
+
isText = false,
|
|
217
|
+
}) {
|
|
218
|
+
return async (ctx) => {
|
|
219
|
+
try {
|
|
220
|
+
const result = await mcpClient.callTool(server, tool, {
|
|
221
|
+
tool_name: ctx?.tool,
|
|
222
|
+
input: ctx?.args || {},
|
|
223
|
+
});
|
|
224
|
+
const { allow, reason } = parsePermissionDecision(result);
|
|
225
|
+
if (isText) {
|
|
226
|
+
writeErr(
|
|
227
|
+
` permission(${ctx?.tool}): ${allow ? "allow" : "deny"}` +
|
|
228
|
+
`${reason ? " — " + reason : ""}\n`,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
return allow;
|
|
232
|
+
} catch (err) {
|
|
233
|
+
if (isText) {
|
|
234
|
+
writeErr(` permission(${ctx?.tool}): deny (tool error: ${err.message})\n`);
|
|
235
|
+
}
|
|
236
|
+
return false; // fail-closed
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-BvqAck49.js";import{_ as k}from"./index-XFyv3Sg_.js";import"./icons-DP3uiYxy.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:i}){i();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),d=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:d,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function D(c,i,t,r,d,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",R,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const z=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-ziCoh9/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{z as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-BvqAck49.js";import{_ as v,b as m}from"./index-XFyv3Sg_.js";import{a7 as y,M}from"./icons-DP3uiYxy.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},k={class:"subtitle"},w={class:"explainer"};function T(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-ziCoh9/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as w,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as o}from"./vendor-BvqAck49.js";import{_ as S}from"./index-XFyv3Sg_.js";import"./icons-DP3uiYxy.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const a=p,e=o(()=>a.event.content||{}),d=o(()=>a.event.extra||{}),m=o(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=o(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=o(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=o(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=o(()=>e.value.status||e.value.state),h=o(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),b=o(()=>{if(!a.event.occurredAt)return"";const t=new Date(a.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:a,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:h,formattedTime:b,computed:o};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},B={class:"row"},D={class:"val"},I={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,a,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(a.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(a.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",I,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const J=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-ziCoh9/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{J as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as i,J as A,U as I,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-BvqAck49.js";import{_ as we,b as re,u as ie,d}from"./index-XFyv3Sg_.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aM as ke,aN as Fe,aO as be,f as je,a4 as Ce,a7 as xe,as as Oe,R as Se}from"./icons-DP3uiYxy.js";const Pe={__name:"Projects",setup(se,{expose:l}){l();const{t:te}=re(),e=ie(),{isEmbedded:W}=de();async function w(o,f,ye,ae=8e3){if(W){const Z=await e.sendRaw({...f,type:o},ae);if(!Z?.ok){const $=Z?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Z.result}return e.executeJson(ye,ae)}const B=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),U=u([]),k=u(!1),E=u(!1),L=u(!1),F=u({name:"",description:"",type:"document",rootPath:""}),z=[{title:"ID",key:"id",width:110},{title:"名称",key:"name"},{title:"类型",key:"project_type",width:120},{title:"状态",key:"status",width:100},{title:"同步",key:"sync_status",width:100},{title:"更新",key:"updated_at",width:160},{title:"操作",key:"actions",width:180,fixed:"right"}],M=ee(()=>{const o={active:0,draft:0,completed:0,archived:0};for(const f of y.value)o[f.status]!==void 0&&(o[f.status]+=1);return o}),J=ee(()=>y.value.filter(o=>!(O.value&&o.status!==O.value||S.value&&!o.name.toLowerCase().includes(S.value.toLowerCase()))));function g(o){switch(o){case"active":return"green";case"draft":return"default";case"completed":return"cyan";case"archived":return"gold";default:return"default"}}function K(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function Q(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){B.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{B.value=!1}}function G(o){return{onClick:()=>V(o)}}async function V(o){v.value=o,P.value=!0,k.value=!0,U.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);U.value=Array.isArray(f?.files)?f.files:[]}catch{U.value=[]}finally{k.value=!1}}async function H(o){try{(await w("project.delete",{id:o.id},`project delete ${o.id} --json`,8e3))?.ok?(d.success(`已删除项目 '${o.name}'`),P.value=!1,await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}function X(){F.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function T(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:F.value.name.trim(),description:F.value.description||null,projectType:F.value.type,rootPath:F.value.rootPath||null},`project init "${F.value.name.trim()}" --type ${F.value.type} --json`,8e3);o?.id?(d.success(`已创建项目 '${o.name}'`),E.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{L.value=!1}}const b=u(!1),D=u(!1),j=u({path:"",content:""}),h=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),q=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},h.value=!0}async function N(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);U.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await N(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),h.value=!1,await N(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await N(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,q.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){Y.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:q.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await N()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{Y.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:W,callProjectTopic:w,loading:B,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:U,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:M,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:G,openDetail:V,onDelete:H,onShowCreate:X,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:h,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:N,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},he={class:"page-title"},Ae={class:"page-sub"},Ie={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},Ue={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Te={key:1,style:{color:"#888"}},Be=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const B=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),U=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),M=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),G=i("a-list-item"),V=i("a-list"),H=i("a-spin"),X=i("a-drawer"),T=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),h=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),A("div",null,[I("div",ze,[I("div",null,[I("h2",he,s(e.t("projects.title")),1),I("p",Ae,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(B,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(U,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),I("div",Ie,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(J,{key:1,columns:e.columns,"data-source":e.filteredProjects,loading:e.loading,pagination:{pageSize:20,showSizeChanger:!0},"row-key":"id","custom-row":e.onRowClick},{bodyCell:a(({column:n,record:c})=>[n.key==="id"?(p(),A("code",Ue,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),A(ne,{key:1},[I("strong",null,s(c.name),1),c.description?(p(),A("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),A(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:q=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(M,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:q=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(X,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[I("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),A("code",Re,s(e.detail.root_path),1)):(p(),A("span",Te,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(H,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(V,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(G,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),A("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(M,{title:`删除 ${n.is_folder?"文件夹":"文件"} '${n.file_name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:c=>e.onDeleteFile(n)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[31]||(l[31]=[r("×",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)]),default:a(()=>[I("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Be)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(h,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(b,{label:"初始内容(可选)"},{default:a(()=>[t(D,{value:e.newFile.content,"onUpdate:value":l[5]||(l[5]=n=>e.newFile.content=n),rows:6,placeholder:"留空创建空文件"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Create folder modal "),t(h,{open:e.createFolderOpen,"onUpdate:open":l[8]||(l[8]=n=>e.createFolderOpen=n),title:"新建文件夹","confirm-loading":e.creatingFolder,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFolder},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(h,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(h,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"项目名称",required:""},{default:a(()=>[t(T,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(b,{label:"描述"},{default:a(()=>[t(D,{value:e.newProject.description,"onUpdate:value":l[12]||(l[12]=n=>e.newProject.description=n),rows:2},null,8,["value"])]),_:1}),t(b,{label:"类型"},{default:a(()=>[t(R,{value:e.newProject.type,"onUpdate:value":l[13]||(l[13]=n=>e.newProject.type=n)},{default:a(()=>[t(m,{value:"document"},{default:a(()=>[...l[32]||(l[32]=[r("文档 (document)",-1)])]),_:1}),t(m,{value:"data"},{default:a(()=>[...l[33]||(l[33]=[r("数据 (data)",-1)])]),_:1}),t(m,{value:"web"},{default:a(()=>[...l[34]||(l[34]=[r("Web",-1)])]),_:1}),t(m,{value:"app"},{default:a(()=>[...l[35]||(l[35]=[r("应用 (app)",-1)])]),_:1}),t(m,{value:"presentation"},{default:a(()=>[...l[36]||(l[36]=[r("演示文稿",-1)])]),_:1}),t(m,{value:"spreadsheet"},{default:a(()=>[...l[37]||(l[37]=[r("表格",-1)])]),_:1}),t(m,{value:"design"},{default:a(()=>[...l[38]||(l[38]=[r("设计",-1)])]),_:1}),t(m,{value:"code"},{default:a(()=>[...l[39]||(l[39]=[r("代码",-1)])]),_:1}),t(m,{value:"workflow"},{default:a(()=>[...l[40]||(l[40]=[r("工作流",-1)])]),_:1}),t(m,{value:"knowledge"},{default:a(()=>[...l[41]||(l[41]=[r("知识库",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(b,{label:"根路径 (可选)"},{default:a(()=>[t(T,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-ziCoh9/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-XFyv3Sg_.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-XERdPDHk.js";import{U as t}from"./index-XFyv3Sg_.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-CrYPRB-g.js";import"./useFlexGapSupport-CSQnQdiv.js";import"./styleChecker-KiQethca.js";import"./index-BjctklSd.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-z7d4kxeP.js";import{U as t}from"./index-XFyv3Sg_.js";import"./vendor-BvqAck49.js";import"./index-BjctklSd.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|