@runfusion/fusion 0.44.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/bin.js +6902 -2143
- package/dist/client/.vite/manifest.json +1115 -328
- package/dist/client/assets/AgentDetailView-CgbB51Iw.css +1 -0
- package/dist/client/assets/AgentDetailView-DJTi6hKC.js +18 -0
- package/dist/client/assets/{AgentPermissionPolicyEditor--YS4iMUY.js → AgentPermissionPolicyEditor-C5DR9dUS.js} +2 -2
- package/dist/client/assets/AgentsView-BNd90PSx.js +29 -0
- package/dist/client/assets/AgentsView-CzMa5Olf.css +1 -0
- package/dist/client/assets/ChatView-B7JaZCL_.js +19 -0
- package/dist/client/assets/ChatView-BtjkE0V7.css +1 -0
- package/dist/client/assets/CommandCenter-CHO21xEW.js +74 -0
- package/dist/client/assets/CommandCenter-Xs5Ftv8s.css +1 -0
- package/dist/client/assets/DevServerView-B_p91Mj_.css +1 -0
- package/dist/client/assets/DevServerView-H9OkT1ld.js +1 -0
- package/dist/client/assets/DirectoryPicker-DegxT8ia.js +1 -0
- package/dist/client/assets/DocumentsView-kVVQYISc.js +1 -0
- package/dist/client/assets/EvalsView-C9-iTSat.js +1 -0
- package/dist/client/assets/EvalsView-CTbgPUne.css +1 -0
- package/dist/client/assets/ExperimentalAgentOnboardingModal-3ZEFv8sr.css +1 -0
- package/dist/client/assets/ExperimentalAgentOnboardingModal-DjP_xNkc.js +1 -0
- package/dist/client/assets/GoalsView-CUh8JBnJ.css +1 -0
- package/dist/client/assets/GoalsView-VoIHJJ5l.js +2 -0
- package/dist/client/assets/InsightsView-BIZaUcpd.js +11 -0
- package/dist/client/assets/InsightsView-C7yRTMPn.css +1 -0
- package/dist/client/assets/MemoryView-7v7rv6ns.js +2 -0
- package/dist/client/assets/MemoryView-CBDUr2Jy.css +1 -0
- package/dist/client/assets/PiExtensionsManager-CB89rV4U.js +11 -0
- package/dist/client/assets/PluginManager-BNSuW_R4.js +1 -0
- package/dist/client/assets/PullRequestView-CI5jdKBL.js +6 -0
- package/dist/client/assets/PullRequestView-CpdE3Yo_.css +1 -0
- package/dist/client/assets/ResearchView-BT5dR_m8.js +1 -0
- package/dist/client/assets/ResearchView-DIVNQF4_.css +1 -0
- package/dist/client/assets/SecretsView-CvFioX7R.css +1 -0
- package/dist/client/assets/SecretsView-WPYI58Uo.js +1 -0
- package/dist/client/assets/SessionTerminal-C6gyOWLt.js +2 -0
- package/dist/client/assets/SessionTerminal-D4R3ScvQ.css +1 -0
- package/dist/client/assets/SettingsModal-BESN59Ao.css +1 -0
- package/dist/client/assets/SettingsModal-BZokaNyx.css +1 -0
- package/dist/client/assets/SettingsModal-Bq_3AbaB.js +1 -0
- package/dist/client/assets/SettingsModal-JHACoQJe.js +21 -0
- package/dist/client/assets/SetupWizardModal-CrgbnR_d.js +2 -0
- package/dist/client/assets/ShadcnColorPicker-1icHuwhC.js +11 -0
- package/dist/client/assets/ShadcnColorPicker-pqVWCC5-.css +1 -0
- package/dist/client/assets/SkillsView-CJ8snrma.css +1 -0
- package/dist/client/assets/SkillsView-byuSe3e0.js +1 -0
- package/dist/client/assets/TodoView-CIsL_uvQ.css +1 -0
- package/dist/client/assets/TodoView-CQ9GjYBg.js +6 -0
- package/dist/client/assets/WorkflowNodeEditor-DW7sJZUX.js +8 -0
- package/dist/client/assets/WorkflowNodeEditor-f_XPV5Jd.css +1 -0
- package/dist/client/assets/{addon-fit-SnYDEvGm.js → addon-fit-C1WQXRvu.js} +1 -1
- package/dist/client/assets/{addon-unicode11-s5GoZCpi.js → addon-unicode11-BVmNDUBM.js} +1 -1
- package/dist/client/assets/{addon-web-links-jjt2f_oV.js → addon-web-links-CkVew5xs.js} +1 -1
- package/dist/client/assets/{addon-webgl-Icn-RnEx.js → addon-webgl-uLc0RKcC.js} +1 -1
- package/dist/client/assets/agentSkills-CeytXLHF.js +1 -0
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CZ_jbgep.css → agentSkills-bQJ4X1gH.css} +1 -1
- package/dist/client/assets/agentsOrgChartLayout-BMvyuaLA.js +1 -0
- package/dist/client/assets/app-3wbZ08YC.js +13 -0
- package/dist/client/assets/app-7-5DWLtg.js +13 -0
- package/dist/client/assets/app-CSvE5Noc.js +13 -0
- package/dist/client/assets/app-CZ2LTFce.js +13 -0
- package/dist/client/assets/app-Cv9xEnll.js +13 -0
- package/dist/client/assets/app-x_yPcO5Y.js +13 -0
- package/dist/client/assets/arc-cxkkNsnK.js +1 -0
- package/dist/client/assets/architectureDiagram-3BPJPVTR-BRI0QwDf.js +36 -0
- package/dist/client/assets/band-CquvqAHh.js +1 -0
- package/dist/client/assets/blockDiagram-GPEHLZMM-BXkN8Hv_.js +132 -0
- package/dist/client/assets/c4Diagram-AAUBKEIU-C_Kcokep.js +10 -0
- package/dist/client/assets/channel-Clzpzu32.js +1 -0
- package/dist/client/assets/chunk-2J33WTMH-BGeuCz9C.js +1 -0
- package/dist/client/assets/chunk-4BX2VUAB-DcVdctr0.js +1 -0
- package/dist/client/assets/chunk-55IACEB6-Dg6gDigQ.js +1 -0
- package/dist/client/assets/chunk-727SXJPM-B9B-vlEb.js +206 -0
- package/dist/client/assets/chunk-AQP2D5EJ-LrWQ-2yi.js +231 -0
- package/dist/client/assets/chunk-FMBD7UC4-Bnd6hAED.js +15 -0
- package/dist/client/assets/chunk-ND2GUHAM-nAw93UB5.js +1 -0
- package/dist/client/assets/chunk-QZHKN3VN-CgprKcZo.js +1 -0
- package/dist/client/assets/classDiagram-4FO5ZUOK-CzYHP-af.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CzYHP-af.js +1 -0
- package/dist/client/assets/common-BDp2y6CF.js +1 -0
- package/dist/client/assets/common-BnEo5fLN.js +1 -0
- package/dist/client/assets/common-Bzr_Y8h4.js +1 -0
- package/dist/client/assets/common-CvwyFzfv.js +1 -0
- package/dist/client/assets/common-CztCXRkz.js +1 -0
- package/dist/client/assets/common-DPe2mbb7.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-Bhn0g_iK.js +1 -0
- package/dist/client/assets/cytoscape.esm-OyMbaexL.js +331 -0
- package/dist/client/assets/dagre-BM42HDAG-CP4kfwqd.js +4 -0
- package/dist/client/assets/{dashboard-view-B4LXCv5H.js → dashboard-view-CM6Xin_H.js} +1680 -1620
- package/dist/client/assets/dashboard-view-DV1nEhh9.js +1 -0
- package/dist/client/assets/dashboard-view-D_zsA-kz.css +1 -0
- package/dist/client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/client/assets/diagram-2AECGRRQ-DPhzVEUf.js +43 -0
- package/dist/client/assets/diagram-5GNKFQAL-8QOC3K_L.js +10 -0
- package/dist/client/assets/diagram-KO2AKTUF-C1twgEch.js +3 -0
- package/dist/client/assets/diagram-LMA3HP47-3bEegSuf.js +24 -0
- package/dist/client/assets/diagram-OG6HWLK6-BJ_x0rm6.js +24 -0
- package/dist/client/assets/erDiagram-TEJ5UH35-DNiiS5q6.js +85 -0
- package/dist/client/assets/flowDiagram-I6XJVG4X-DoouPklt.js +162 -0
- package/dist/client/assets/{folder-open-33WGVnbp.js → folder-open-CuUs2W7f.js} +1 -1
- package/dist/client/assets/ganttDiagram-6RSMTGT7-BrR6VnP5.js +292 -0
- package/dist/client/assets/gitGraphDiagram-PVQCEYII-BV8_J6Ee.js +106 -0
- package/dist/client/assets/graph--OzhPTMs.js +1 -0
- package/dist/client/assets/index-BZBQ_KsL.css +1 -0
- package/dist/client/assets/index-CZcWjLAb.js +1459 -0
- package/dist/client/assets/infoDiagram-5YYISTIA-DGwIIFkR.js +2 -0
- package/dist/client/assets/init-Dmth1JHB.js +1 -0
- package/dist/client/assets/ishikawaDiagram-YF4QCWOH-D5dEH4RE.js +70 -0
- package/dist/client/assets/journeyDiagram-JHISSGLW-BuuSWPw5.js +139 -0
- package/dist/client/assets/kanban-definition-UN3LZRKU-DA34uUla.js +89 -0
- package/dist/client/assets/katex-HP8lGamR.js +257 -0
- package/dist/client/assets/layout-SsrduOYp.js +1 -0
- package/dist/client/assets/linear-dXivciGL.js +1 -0
- package/dist/client/assets/mermaid.core-Ch4HatqA.js +309 -0
- package/dist/client/assets/mindmap-definition-RKZ34NQL-DUCG-qD3.js +96 -0
- package/dist/client/assets/ordinal-DILIJJjt.js +1 -0
- package/dist/client/assets/pieDiagram-4H26LBE5-DWvFGiLa.js +30 -0
- package/dist/client/assets/quadrantDiagram-W4KKPZXB-OPTVW3WT.js +7 -0
- package/dist/client/assets/requirementDiagram-4Y6WPE33-D7feZvlU.js +84 -0
- package/dist/client/assets/sankeyDiagram-5OEKKPKP-AtnSsEX1.js +40 -0
- package/dist/client/assets/sequenceDiagram-3UESZ5HK-BZjHUeI5.js +162 -0
- package/dist/client/assets/{shield-alert-CqeGWBUK.js → shield-alert-CzaF9ROV.js} +1 -1
- package/dist/client/assets/stateDiagram-AJRCARHV-C8j23Pvn.js +1 -0
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CiZR_S5-.js +1 -0
- package/dist/client/assets/step-yuy0qJer.js +1 -0
- package/dist/client/assets/time-DoDTxsna.js +1 -0
- package/dist/client/assets/timeline-definition-PNZ67QCA-DvfNz25n.js +120 -0
- package/dist/client/assets/{upload-C11J2diI.js → upload-DTsYywhN.js} +1 -1
- package/dist/client/assets/{users-a-ELbyyZ.js → users-yAd09tKP.js} +1 -1
- package/dist/client/assets/{vendor-i18n-DYlSUfot.js → vendor-i18n-GF3RlKbq.js} +2 -2
- package/dist/client/assets/{vendor-react-BTgM5bbZ.js → vendor-react-SZ_qB27O.js} +1 -1
- package/dist/client/assets/vendor-reactflow-Bg-Qjzh8.js +15 -0
- package/dist/client/assets/{vendor-xterm-ea7-K05z.js → vendor-xterm-BNq00GSj.js} +1 -1
- package/dist/client/assets/vennDiagram-CIIHVFJN-CG2aMt3v.js +34 -0
- package/dist/client/assets/wardley-L42UT6IY-BnhBteen.js +173 -0
- package/dist/client/assets/wardleyDiagram-YWT4CUSO-DwqTzM3T.js +78 -0
- package/dist/client/assets/xychartDiagram-2RQKCTM6-5Cv2ZKMV.js +7 -0
- package/dist/client/assets/zoom-out-NWbVkreR.js +41 -0
- package/dist/client/index.html +30 -10
- package/dist/client/sw.js +1 -1
- package/dist/client/theme-data.css +3082 -206
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/index.ts +56 -40
- package/dist/droid-cli/package.json +1 -1
- package/dist/droid-cli/src/__tests__/index.test.ts +47 -21
- package/dist/droid-cli/src/__tests__/process-manager.test.ts +50 -33
- package/dist/extension.js +4935 -827
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +25 -0
- package/dist/pi-claude-cli/src/process-manager.ts +11 -1
- package/dist/plugin-sdk/index.d.ts +126 -4
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +68 -44
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +5 -11
- package/dist/plugins/fusion-plugin-roadmap/manifest.json +1 -11
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +3 -3
- package/skill/fusion/SKILL.md +1 -1
- package/skill/fusion/references/cli-commands.md +2 -1
- package/skill/fusion/references/extension-tools.md +10 -0
- package/skill/fusion/references/fusion-capabilities.md +3 -1
- package/dist/client/assets/AgentDetailView-CanIeYHg.css +0 -1
- package/dist/client/assets/AgentDetailView-DxV8pFHX.js +0 -18
- package/dist/client/assets/AgentsView-BVILQjdS.css +0 -1
- package/dist/client/assets/AgentsView-CTzbcvhK.js +0 -29
- package/dist/client/assets/ChatView-COygcnyk.js +0 -6
- package/dist/client/assets/ChatView-DwJAd5G1.css +0 -1
- package/dist/client/assets/CommandCenter-CTaopaC0.css +0 -1
- package/dist/client/assets/CommandCenter-DoKX2HWm.js +0 -56
- package/dist/client/assets/DevServerView-Cyevyvqx.js +0 -1
- package/dist/client/assets/DevServerView-VTQY28P7.css +0 -1
- package/dist/client/assets/DirectoryPicker-DBdyXEhR.js +0 -1
- package/dist/client/assets/DocumentsView-BzSMyrns.js +0 -1
- package/dist/client/assets/DocumentsView-WfVoTZt8.css +0 -1
- package/dist/client/assets/EvalsView-CUNJ1TLc.css +0 -1
- package/dist/client/assets/EvalsView-ikz00o9g.js +0 -1
- package/dist/client/assets/ExperimentalAgentOnboardingModal-D-rzCCET.js +0 -499
- package/dist/client/assets/GoalsView-Bfu1Oy2-.js +0 -2
- package/dist/client/assets/GoalsView-rg9VSIza.css +0 -1
- package/dist/client/assets/InsightsView-Cgmf5nES.js +0 -11
- package/dist/client/assets/InsightsView-LMv1M1dU.css +0 -1
- package/dist/client/assets/MemoryView-DkEuDKQs.js +0 -2
- package/dist/client/assets/MemoryView-zaXewZzi.css +0 -1
- package/dist/client/assets/NodesView-7VInxyf_.css +0 -1
- package/dist/client/assets/NodesView-B_KYfS4o.js +0 -14
- package/dist/client/assets/PiExtensionsManager-Dz69kkKs.js +0 -11
- package/dist/client/assets/PluginManager-LHCVcduP.js +0 -1
- package/dist/client/assets/PullRequestView-3AdbS2a1.css +0 -1
- package/dist/client/assets/PullRequestView-DBJutLLl.js +0 -6
- package/dist/client/assets/ResearchView-DTh8FLUm.css +0 -1
- package/dist/client/assets/ResearchView-gpn1XcVy.js +0 -1
- package/dist/client/assets/SecretsView-B7YqIowt.js +0 -1
- package/dist/client/assets/SecretsView-Djo1rahi.css +0 -1
- package/dist/client/assets/SessionTerminal-9l4bdKcn.js +0 -2
- package/dist/client/assets/SessionTerminal-BNgtmXb3.css +0 -1
- package/dist/client/assets/SettingsModal-BGEK9_9A.js +0 -31
- package/dist/client/assets/SettingsModal-CKv0TJfM.css +0 -1
- package/dist/client/assets/SettingsModal-CXogw-Er.css +0 -1
- package/dist/client/assets/SettingsModal-DIIoHGUH.js +0 -1
- package/dist/client/assets/SetupWizardModal-BcVeMxeX.js +0 -1
- package/dist/client/assets/SetupWizardModal-CIqFbkrD.css +0 -1
- package/dist/client/assets/SkillsView-3bhGyWs1.css +0 -1
- package/dist/client/assets/SkillsView-BxSJ4PHL.js +0 -1
- package/dist/client/assets/StashRecoveryView-B_8WIQEo.css +0 -1
- package/dist/client/assets/StashRecoveryView-BhFQ2FsP.js +0 -1
- package/dist/client/assets/TodoView-7xIh-Fmi.css +0 -1
- package/dist/client/assets/TodoView-BZpewjy0.js +0 -6
- package/dist/client/assets/WorkflowNodeEditor-Yn1FRF2v.css +0 -1
- package/dist/client/assets/WorkflowNodeEditor-tWsgCdVt.js +0 -8
- package/dist/client/assets/app-BmGA0Hiz.js +0 -13
- package/dist/client/assets/app-CEVYlVuJ.js +0 -13
- package/dist/client/assets/app-CbBFax2C.js +0 -13
- package/dist/client/assets/app-DORKrGAz.js +0 -13
- package/dist/client/assets/app-DQibuQ9z.js +0 -13
- package/dist/client/assets/app-k76GrQP0.js +0 -13
- package/dist/client/assets/common-BRyX4VxB.js +0 -1
- package/dist/client/assets/common-CN9QPI2d.js +0 -1
- package/dist/client/assets/common-CNbjPELi.js +0 -1
- package/dist/client/assets/common-DFDqu_n0.js +0 -1
- package/dist/client/assets/common-DgWWKG8Z.js +0 -1
- package/dist/client/assets/common-X6PzBnVA.js +0 -1
- package/dist/client/assets/createLucideIcon-DmVITl5d.js +0 -21
- package/dist/client/assets/dashboard-view-BFoyhTYF.js +0 -3
- package/dist/client/assets/dashboard-view-Cxzm_eqc.js +0 -1
- package/dist/client/assets/dashboard-view-DdGlfuu-.css +0 -1
- package/dist/client/assets/dashboard-view-_8yfNwju.css +0 -1
- package/dist/client/assets/index-Bglw05rM.js +0 -791
- package/dist/client/assets/index-FYgnflWD.css +0 -1
- package/dist/client/assets/vendor-reactflow-ZasuEfF9.js +0 -15
- package/dist/client/assets/x-PItWc-wQ.js +0 -61
- package/dist/client/assets/zoom-out-CzlHv0Kj.js +0 -21
package/dist/client/version.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"192a2f2e9-7a1b1370"}
|
package/dist/droid-cli/index.ts
CHANGED
|
@@ -24,31 +24,27 @@ type StreamSimpleHandler = NonNullable<Parameters<ExtensionAPI["registerProvider
|
|
|
24
24
|
function runCliValidationOnce(): Promise<void> {
|
|
25
25
|
if (cliValidationPromise) return cliValidationPromise;
|
|
26
26
|
cliValidationPromise = (async () => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
try {
|
|
28
|
+
const presence = await validateCliPresenceAsync();
|
|
29
|
+
if (!presence.ok) {
|
|
30
|
+
console.warn(`[droid-cli] ${presence.error.message}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
await validateCliAuthAsync();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.warn("[droid-cli] CLI validation failed; continuing without blocking the session", error);
|
|
31
36
|
}
|
|
32
|
-
await validateCliAuthAsync();
|
|
33
37
|
})();
|
|
34
38
|
return cliValidationPromise;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
async function
|
|
41
|
+
export async function discoverDroidProviderModels() {
|
|
38
42
|
if (!discoveredModelsPromise) {
|
|
39
43
|
discoveredModelsPromise = (async () => {
|
|
40
44
|
try {
|
|
41
45
|
const ids = Array.from(new Set(await discoverDroidModels()));
|
|
42
46
|
if (ids.length === 0) return [];
|
|
43
|
-
return ids
|
|
44
|
-
id,
|
|
45
|
-
name: id,
|
|
46
|
-
reasoning: true,
|
|
47
|
-
input: ["text", "image"] as Array<"text" | "image">,
|
|
48
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
49
|
-
contextWindow: 200_000,
|
|
50
|
-
maxTokens: 8_192,
|
|
51
|
-
}));
|
|
47
|
+
return toProviderModels(ids);
|
|
52
48
|
} catch (error) {
|
|
53
49
|
console.warn("[droid-cli] model auto-discovery failed; registering provider with empty model list", error);
|
|
54
50
|
return [];
|
|
@@ -60,6 +56,18 @@ async function getDiscoveredModels() {
|
|
|
60
56
|
|
|
61
57
|
let cachedMcpConfig: { hash: string; configPath: string } | undefined;
|
|
62
58
|
|
|
59
|
+
function toProviderModels(ids: string[]): DiscoveredModel[] {
|
|
60
|
+
return ids.map((id) => ({
|
|
61
|
+
id,
|
|
62
|
+
name: id,
|
|
63
|
+
reasoning: true,
|
|
64
|
+
input: ["text", "image"] as Array<"text" | "image">,
|
|
65
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
66
|
+
contextWindow: 200_000,
|
|
67
|
+
maxTokens: 8_192,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
|
|
63
71
|
function ensureMcpConfig(
|
|
64
72
|
pi: ExtensionAPI,
|
|
65
73
|
contextTools?: ReadonlyArray<{
|
|
@@ -93,8 +101,35 @@ function ensureMcpConfig(
|
|
|
93
101
|
}
|
|
94
102
|
}
|
|
95
103
|
|
|
104
|
+
function registerDroidProvider(pi: ExtensionAPI, models: DiscoveredModel[]) {
|
|
105
|
+
pi.registerProvider(PROVIDER_ID, {
|
|
106
|
+
baseUrl: "droid-cli",
|
|
107
|
+
apiKey: "unused",
|
|
108
|
+
api: "droid-cli",
|
|
109
|
+
models,
|
|
110
|
+
streamSimple: ((model, context, options) => {
|
|
111
|
+
void runCliValidationOnce();
|
|
112
|
+
const configPath = ensureMcpConfig(
|
|
113
|
+
pi,
|
|
114
|
+
(context as { tools?: ReadonlyArray<{ name: string; description: string; parameters: Record<string, unknown> }> }).tools,
|
|
115
|
+
);
|
|
116
|
+
return streamViaCli(
|
|
117
|
+
model,
|
|
118
|
+
context as never,
|
|
119
|
+
{ ...(options ?? {}), mcpConfigPath: configPath } as never,
|
|
120
|
+
) as unknown as ReturnType<StreamSimpleHandler>;
|
|
121
|
+
}) as StreamSimpleHandler,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
96
125
|
export default function (pi: ExtensionAPI) {
|
|
97
|
-
|
|
126
|
+
/*
|
|
127
|
+
FNXC:CliRuntime 2026-06-21-18:43:
|
|
128
|
+
Engine and dashboard startup must not start the local Droid CLI merely because the optional extension loaded. Register the provider synchronously with an empty model list, defer validation until an actual droid stream starts, and leave model discovery to explicit picker/status callers so boot with `useDroidCli` enabled still performs zero `droid` spawns.
|
|
129
|
+
|
|
130
|
+
FNXC:CliRuntime 2026-06-21-12:00:
|
|
131
|
+
Engine and dashboard startup must not wait for local Droid CLI probes. Every surviving validation/discovery helper remains fire-and-forget, bounded, non-interactive, and resolve-only so a missing or wedged `droid` binary cannot stall extension loading or a session start.
|
|
132
|
+
*/
|
|
98
133
|
|
|
99
134
|
pi.on("session_start", async () => {
|
|
100
135
|
const allTools = pi.getAllTools();
|
|
@@ -103,28 +138,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
103
138
|
}
|
|
104
139
|
});
|
|
105
140
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
apiKey: "unused",
|
|
112
|
-
api: "droid-cli",
|
|
113
|
-
models,
|
|
114
|
-
streamSimple: ((model, context, options) => {
|
|
115
|
-
const configPath = ensureMcpConfig(
|
|
116
|
-
pi,
|
|
117
|
-
(context as { tools?: ReadonlyArray<{ name: string; description: string; parameters: Record<string, unknown> }> }).tools,
|
|
118
|
-
);
|
|
119
|
-
return streamViaCli(
|
|
120
|
-
model,
|
|
121
|
-
context as never,
|
|
122
|
-
{ ...(options ?? {}), mcpConfigPath: configPath } as never,
|
|
123
|
-
) as unknown as ReturnType<StreamSimpleHandler>;
|
|
124
|
-
}) as StreamSimpleHandler,
|
|
125
|
-
});
|
|
126
|
-
} catch (err) {
|
|
127
|
-
console.error("[droid-cli] Failed to register provider:", err);
|
|
128
|
-
}
|
|
129
|
-
})();
|
|
141
|
+
try {
|
|
142
|
+
registerDroidProvider(pi, []);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.error("[droid-cli] Failed to register provider:", err);
|
|
145
|
+
}
|
|
130
146
|
}
|
|
@@ -58,7 +58,7 @@ describe("droid-cli extension entrypoint", () => {
|
|
|
58
58
|
vi.restoreAllMocks();
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
it("registers provider droid-cli
|
|
61
|
+
it("registers provider droid-cli synchronously without starting droid probes or discovery", async () => {
|
|
62
62
|
const registerProvider = vi.fn();
|
|
63
63
|
const mockPi = {
|
|
64
64
|
registerProvider,
|
|
@@ -68,19 +68,20 @@ describe("droid-cli extension entrypoint", () => {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
const mod = await import("../../index");
|
|
71
|
-
mod.default(mockPi as never);
|
|
71
|
+
const result = mod.default(mockPi as never);
|
|
72
72
|
await flushAsyncRegistration();
|
|
73
73
|
|
|
74
|
-
expect(
|
|
75
|
-
expect(runtimeMocks.
|
|
76
|
-
expect(runtimeMocks.
|
|
74
|
+
expect(result).toBeUndefined();
|
|
75
|
+
expect(runtimeMocks.validateCliPresenceAsync).not.toHaveBeenCalled();
|
|
76
|
+
expect(runtimeMocks.validateCliAuthAsync).not.toHaveBeenCalled();
|
|
77
|
+
expect(runtimeMocks.discoverDroidModels).not.toHaveBeenCalled();
|
|
77
78
|
|
|
78
79
|
expect(registerProvider).toHaveBeenCalledTimes(1);
|
|
79
80
|
const [providerId, config] = registerProvider.mock.calls[0] as [string, {
|
|
80
81
|
baseUrl: string;
|
|
81
82
|
api: string;
|
|
82
83
|
apiKey: string;
|
|
83
|
-
models:
|
|
84
|
+
models: unknown[];
|
|
84
85
|
streamSimple: Function;
|
|
85
86
|
}];
|
|
86
87
|
|
|
@@ -88,11 +89,43 @@ describe("droid-cli extension entrypoint", () => {
|
|
|
88
89
|
expect(config.baseUrl).toBe("droid-cli");
|
|
89
90
|
expect(config.api).toBe("droid-cli");
|
|
90
91
|
expect(config.apiKey).toBe("unused");
|
|
91
|
-
expect(config.models).toEqual([
|
|
92
|
+
expect(config.models).toEqual([]);
|
|
93
|
+
expect(typeof config.streamSimple).toBe("function");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("runs validation once when a droid stream is actually used", async () => {
|
|
97
|
+
const registerProvider = vi.fn();
|
|
98
|
+
const mockPi = {
|
|
99
|
+
registerProvider,
|
|
100
|
+
on: vi.fn(),
|
|
101
|
+
getAllTools: vi.fn(() => []),
|
|
102
|
+
setActiveTools: vi.fn(),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const mod = await import("../../index");
|
|
106
|
+
mod.default(mockPi as never);
|
|
107
|
+
const config = registerProvider.mock.calls[0]?.[1] as {
|
|
108
|
+
streamSimple: (model: unknown, context: unknown, options?: Record<string, unknown>) => unknown;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
config.streamSimple({ id: "droid-pro" }, { messages: [] }, {});
|
|
112
|
+
config.streamSimple({ id: "droid-pro" }, { messages: [] }, {});
|
|
113
|
+
await flushAsyncRegistration();
|
|
114
|
+
|
|
115
|
+
expect(runtimeMocks.validateCliPresenceAsync).toHaveBeenCalledTimes(1);
|
|
116
|
+
expect(runtimeMocks.validateCliAuthAsync).toHaveBeenCalledTimes(1);
|
|
117
|
+
expect(runtimeMocks.discoverDroidModels).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("discovers provider models only when explicitly requested", async () => {
|
|
121
|
+
const mod = await import("../../index");
|
|
122
|
+
|
|
123
|
+
await expect(mod.discoverDroidProviderModels()).resolves.toEqual([
|
|
92
124
|
expect.objectContaining({ id: "droid-pro", name: "droid-pro", contextWindow: 200_000, maxTokens: 8_192 }),
|
|
93
125
|
expect.objectContaining({ id: "droid-max", name: "droid-max", contextWindow: 200_000, maxTokens: 8_192 }),
|
|
94
126
|
]);
|
|
95
|
-
|
|
127
|
+
|
|
128
|
+
expect(runtimeMocks.discoverDroidModels).toHaveBeenCalledTimes(1);
|
|
96
129
|
});
|
|
97
130
|
|
|
98
131
|
it("activates all registered tools on session_start", async () => {
|
|
@@ -132,31 +165,24 @@ describe("droid-cli extension entrypoint", () => {
|
|
|
132
165
|
|
|
133
166
|
const mod = await import("../../index");
|
|
134
167
|
mod.default(mockPi as never);
|
|
168
|
+
const config = mockPi.registerProvider.mock.calls[0]?.[1] as {
|
|
169
|
+
streamSimple: (model: unknown, context: unknown, options?: Record<string, unknown>) => unknown;
|
|
170
|
+
};
|
|
171
|
+
config.streamSimple({ id: "droid-pro" }, { messages: [] }, {});
|
|
135
172
|
await flushAsyncRegistration();
|
|
136
173
|
|
|
137
174
|
expect(warnSpy).toHaveBeenCalledWith("[droid-cli] droid CLI missing");
|
|
138
175
|
expect(runtimeMocks.validateCliAuthAsync).not.toHaveBeenCalled();
|
|
139
|
-
expect(mockPi.registerProvider).
|
|
176
|
+
expect(mockPi.registerProvider).toHaveBeenCalledWith("droid-cli", expect.objectContaining({ models: [] }));
|
|
140
177
|
});
|
|
141
178
|
|
|
142
179
|
it("falls back to empty models when discovery throws", async () => {
|
|
143
180
|
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
144
181
|
runtimeMocks.discoverDroidModels.mockRejectedValue(new Error("boom"));
|
|
145
182
|
|
|
146
|
-
const registerProvider = vi.fn();
|
|
147
|
-
const mockPi = {
|
|
148
|
-
registerProvider,
|
|
149
|
-
on: vi.fn(),
|
|
150
|
-
getAllTools: vi.fn(() => []),
|
|
151
|
-
setActiveTools: vi.fn(),
|
|
152
|
-
};
|
|
153
|
-
|
|
154
183
|
const mod = await import("../../index");
|
|
155
|
-
mod.
|
|
156
|
-
await flushAsyncRegistration();
|
|
184
|
+
await expect(mod.discoverDroidProviderModels()).resolves.toEqual([]);
|
|
157
185
|
|
|
158
|
-
const config = registerProvider.mock.calls[0]?.[1] as { models: unknown[] };
|
|
159
|
-
expect(config.models).toEqual([]);
|
|
160
186
|
expect(warnSpy).toHaveBeenCalledWith(
|
|
161
187
|
"[droid-cli] model auto-discovery failed; registering provider with empty model list",
|
|
162
188
|
expect.any(Error),
|
|
@@ -415,6 +415,16 @@ describe("validateCliPresenceAsync", () => {
|
|
|
415
415
|
const result = await validateCliPresenceAsync();
|
|
416
416
|
expect(result.ok).toBe(false);
|
|
417
417
|
});
|
|
418
|
+
|
|
419
|
+
it("resolves ok=false instead of rejecting when droid spawn throws synchronously", async () => {
|
|
420
|
+
(spawn as any).mockImplementationOnce(() => {
|
|
421
|
+
throw new Error("Real AI CLI launch blocked during tests: droid --version");
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
await expect(validateCliPresenceAsync()).resolves.toMatchObject({
|
|
425
|
+
ok: false,
|
|
426
|
+
});
|
|
427
|
+
});
|
|
418
428
|
});
|
|
419
429
|
|
|
420
430
|
describe("validateCliAuthAsync", () => {
|
|
@@ -452,6 +462,21 @@ describe("validateCliAuthAsync", () => {
|
|
|
452
462
|
);
|
|
453
463
|
warnSpy.mockRestore();
|
|
454
464
|
});
|
|
465
|
+
|
|
466
|
+
it("resolves false instead of rejecting when droid auth spawn throws synchronously", async () => {
|
|
467
|
+
(spawn as any).mockImplementationOnce(() => {
|
|
468
|
+
throw new Error(
|
|
469
|
+
"Real AI CLI launch blocked during tests: droid auth status",
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
473
|
+
|
|
474
|
+
await expect(validateCliAuthAsync()).resolves.toBe(false);
|
|
475
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
476
|
+
expect.stringContaining("not authenticated"),
|
|
477
|
+
);
|
|
478
|
+
warnSpy.mockRestore();
|
|
479
|
+
});
|
|
455
480
|
});
|
|
456
481
|
|
|
457
482
|
describe("CLI flags", () => {
|
|
@@ -723,52 +748,44 @@ describe("discoverDroidModels", () => {
|
|
|
723
748
|
vi.clearAllMocks();
|
|
724
749
|
});
|
|
725
750
|
|
|
726
|
-
it("parses model ids from
|
|
751
|
+
it("parses model ids from droid exec --help output", async () => {
|
|
727
752
|
(spawn as any).mockImplementationOnce(() => {
|
|
728
753
|
const EventEmitter = require("node:events");
|
|
729
754
|
const proc = new EventEmitter();
|
|
730
755
|
proc.stdout = new EventEmitter();
|
|
731
756
|
proc.stderr = new EventEmitter();
|
|
732
757
|
setTimeout(() => {
|
|
733
|
-
proc.stdout.emit("data", Buffer.from(
|
|
758
|
+
proc.stdout.emit("data", Buffer.from(`Usage: droid exec [options] [prompt]
|
|
759
|
+
|
|
760
|
+
Available Models:
|
|
761
|
+
droid-pro Droid Pro
|
|
762
|
+
droid-max Droid Max
|
|
763
|
+
|
|
764
|
+
Model details:
|
|
765
|
+
- Droid Pro: prose, not a model id
|
|
766
|
+
`));
|
|
734
767
|
proc.emit("exit", 0);
|
|
735
768
|
}, 0);
|
|
736
769
|
return proc;
|
|
737
770
|
});
|
|
738
771
|
|
|
739
772
|
await expect(discoverDroidModels()).resolves.toEqual(["droid-pro", "droid-max"]);
|
|
773
|
+
expect(spawn).toHaveBeenCalledWith("droid", ["exec", "--help"], expect.anything());
|
|
740
774
|
});
|
|
741
775
|
|
|
742
|
-
it("
|
|
743
|
-
(spawn as any)
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
})
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
proc.stderr = new EventEmitter();
|
|
757
|
-
setTimeout(() => proc.emit("exit", 1), 0);
|
|
758
|
-
return proc;
|
|
759
|
-
})
|
|
760
|
-
.mockImplementationOnce(() => {
|
|
761
|
-
const EventEmitter = require("node:events");
|
|
762
|
-
const proc = new EventEmitter();
|
|
763
|
-
proc.stdout = new EventEmitter();
|
|
764
|
-
proc.stderr = new EventEmitter();
|
|
765
|
-
setTimeout(() => {
|
|
766
|
-
proc.stdout.emit("data", Buffer.from("droid-lite\ndroid-lite\ndroid-pro\n"));
|
|
767
|
-
proc.emit("exit", 0);
|
|
768
|
-
}, 0);
|
|
769
|
-
return proc;
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
await expect(discoverDroidModels()).resolves.toEqual(["droid-lite", "droid-pro"]);
|
|
776
|
+
it("returns [] when droid exec --help exits without a model section", async () => {
|
|
777
|
+
(spawn as any).mockImplementationOnce(() => {
|
|
778
|
+
const EventEmitter = require("node:events");
|
|
779
|
+
const proc = new EventEmitter();
|
|
780
|
+
proc.stdout = new EventEmitter();
|
|
781
|
+
proc.stderr = new EventEmitter();
|
|
782
|
+
setTimeout(() => {
|
|
783
|
+
proc.stdout.emit("data", Buffer.from("Usage: droid exec\n\nOptions:\n --help\n"));
|
|
784
|
+
proc.emit("exit", 0);
|
|
785
|
+
}, 0);
|
|
786
|
+
return proc;
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
await expect(discoverDroidModels()).resolves.toEqual([]);
|
|
773
790
|
});
|
|
774
791
|
});
|