@runfusion/fusion 0.74.0-beta.7 → 0.74.0-beta.8
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/bin.js +339 -473
- package/dist/child-process-worker.js +144 -278
- package/dist/client/.vite/manifest.json +254 -254
- package/dist/client/assets/{AgentDetailView-CTdyQL11.js → AgentDetailView-CnzGIxqj.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-DBa7nIQV.js → AgentPermissionPolicyEditor-DMnyR96M.js} +1 -1
- package/dist/client/assets/{AgentsView-B5tss2oK.js → AgentsView-CzFtICwM.js} +3 -3
- package/dist/client/assets/{ChatView-DAKt1a2L.js → ChatView-Cs6B3fNf.js} +1 -1
- package/dist/client/assets/{CommandCenter-yPvRo9F6.js → CommandCenter-DADvho3z.js} +1 -1
- package/dist/client/assets/{DevServerView-BTyS2owH.js → DevServerView-Bzrzfs8Z.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-BjGIupNU.js → DirectoryPicker-rmip5GcI.js} +1 -1
- package/dist/client/assets/{DocumentsView-CuxfbpSZ.js → DocumentsView-BEM4nmJT.js} +1 -1
- package/dist/client/assets/{EvalsView-DGuy8SHR.js → EvalsView-Du7NaYMJ.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-lK407ZAq.js → ExperimentalAgentOnboardingModal-BpIMiZOi.js} +1 -1
- package/dist/client/assets/{GoalsView-DAVN0ObR.js → GoalsView-BxKRyXM3.js} +1 -1
- package/dist/client/assets/{InsightsView-BXQKcNof.js → InsightsView-Dauq6b3M.js} +1 -1
- package/dist/client/assets/{MemoryView-D7RKEtV7.js → MemoryView-DRD9Xvwx.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-CrOJ57R2.js → PiExtensionsManager-DJKE1iAX.js} +1 -1
- package/dist/client/assets/{PluginManager-D7_evt4j.js → PluginManager-CScwY-Ib.js} +1 -1
- package/dist/client/assets/{PullRequestView-C0lRUbth.js → PullRequestView-uAu5_4__.js} +1 -1
- package/dist/client/assets/{ReportModal-Cy5fRNDK.js → ReportModal-nNUcGxYj.js} +1 -1
- package/dist/client/assets/{ResearchView-e8st2Sxu.js → ResearchView-BX1kGbWP.js} +1 -1
- package/dist/client/assets/{SecretsView-BLzckrzb.js → SecretsView-U_itETHx.js} +1 -1
- package/dist/client/assets/{SessionTerminal-F_GIj4gh.js → SessionTerminal-_b15vcd9.js} +1 -1
- package/dist/client/assets/SettingsModal-B30rPfYC.css +1 -0
- package/dist/client/assets/{SettingsModal-XAddgWkF.js → SettingsModal-DkpUKf4k.js} +1 -1
- package/dist/client/assets/{SettingsModal-eQbxbkLU.js → SettingsModal-DpbYR3Co.js} +4 -4
- package/dist/client/assets/{SettingsTextareaRow-DVjUHNQp.js → SettingsTextareaRow-Dbv-oqsF.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-xID9yIff.js → SetupWizardModal-n_kcJfIP.js} +2 -2
- package/dist/client/assets/{SkillsView-BNdMGu6E.js → SkillsView-Bv2uqBre.js} +1 -1
- package/dist/client/assets/{TodoView-xcOjHZm1.js → TodoView-y11oUvjw.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-DZ2WZ-ve.js → WorkflowNodeEditor-DwY4XzNB.js} +1 -1
- package/dist/client/assets/{agent-import-generation-0tkW9WMt.js → agent-import-generation-B_UNOAWY.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DP9_UvPn.js → architectureDiagram-3BPJPVTR-BpA9_eoq.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-EgKwYMgQ.js → blockDiagram-GPEHLZMM-DFFA8tCG.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-Dzv0-_xt.js → c4Diagram-AAUBKEIU-Fzhn0dG7.js} +1 -1
- package/dist/client/assets/channel-C9C9Rxgn.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-CNmFmJlQ.js → chunk-2J33WTMH-Bi3oPWBJ.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-DwtF2sl5.js → chunk-4BX2VUAB-UmeI_To2.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DoDurT6F.js → chunk-55IACEB6-BvNWeThd.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DB87A9uH.js → chunk-727SXJPM-OHmjSQwz.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-ClTDkMp1.js → chunk-AQP2D5EJ-DCi9eQaE.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BhY2wlYr.js → chunk-FMBD7UC4-CelGyE3R.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-BB8mzlmk.js → chunk-ND2GUHAM-DespM-6E.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-D81qQMGf.js → chunk-QZHKN3VN-DLkr_Pz0.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BGVE_u03.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BGVE_u03.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-CCFUHBJX.js → cose-bilkent-S5V4N54A-I7MlbwDq.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-xr9MLhRA.js → dagre-BM42HDAG-DRwLRj5m.js} +1 -1
- package/dist/client/assets/{dashboard-view-oTFt91I3.js → dashboard-view-CIwO3ODB.js} +1 -1
- package/dist/client/assets/{dashboard-view-RXKFv3QV.js → dashboard-view-CSxVzmpI.js} +1 -1
- package/dist/client/assets/{dashboard-view-lqwQ-pMo.js → dashboard-view-Gb436HIO.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-mN_tYnBs.js → diagram-2AECGRRQ-BuWGDbh_.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-xznlq-5C.js → diagram-5GNKFQAL-hG6N6ArX.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-ClRlj1ZA.js → diagram-KO2AKTUF-BSXKqQJA.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CNiPIQqT.js → diagram-LMA3HP47-wNefeM2W.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-DwQD-W0P.js → diagram-OG6HWLK6-nA8v_k_H.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-ZXkiCm8S.js → erDiagram-TEJ5UH35-Dwnvvp2x.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DI5haEH9.js → flowDiagram-I6XJVG4X-FS4W3U0O.js} +1 -1
- package/dist/client/assets/{folder-open-NenyCkrb.js → folder-open-C3GXrzUo.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-BRHJpfOZ.js → ganttDiagram-6RSMTGT7-D95bgKFE.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-iXT_YBAZ.js → gitGraphDiagram-PVQCEYII-zqFbK6on.js} +1 -1
- package/dist/client/assets/{index-CrAJA2v0.js → index-BWRNl9tu.js} +274 -274
- package/dist/client/assets/index-DRZtPb3i.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-BzkuQtqZ.js → infoDiagram-5YYISTIA-BBELQBNE.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-5hnPG_98.js → ishikawaDiagram-YF4QCWOH-bSZkIXd-.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Co3fnxbr.js → journeyDiagram-JHISSGLW-8wIimXRT.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-PZFl_y-h.js → kanban-definition-UN3LZRKU-DMj6kFc5.js} +1 -1
- package/dist/client/assets/{mermaid.core-CJRKeU9s.js → mermaid.core-UDKENpfo.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-B15e2rkx.js → mindmap-definition-RKZ34NQL-CJGH0VYQ.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-kGF592D_.js → pieDiagram-4H26LBE5-B3cZLcOe.js} +1 -1
- package/dist/client/assets/{puzzle-Dgc4yzjO.js → puzzle-D85LM19g.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CUShcj70.js → quadrantDiagram-W4KKPZXB-bR1CBrVi.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-D2k4nLqQ.js → requirementDiagram-4Y6WPE33-DnyJ74cE.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CA03BxhT.js → sankeyDiagram-5OEKKPKP-ttv4kq0z.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DDuFN2Pi.js → sequenceDiagram-3UESZ5HK-FiUBFoWw.js} +1 -1
- package/dist/client/assets/{shield-alert-BlYWqolM.js → shield-alert-D3IVOJV1.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-ujl7UARV.js → standing-instructions-template-CWY_pFh6.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-yJOkHK4Q.js → stateDiagram-AJRCARHV-BcsYRB77.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-BgErHdAN.js → stateDiagram-v2-BHNVJYJU-DsBPFwnG.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-BUiDQw21.js → timeline-definition-PNZ67QCA-B8rOOxEj.js} +1 -1
- package/dist/client/assets/{upload-DmlZvpMp.js → upload-WqSaqC__.js} +1 -1
- package/dist/client/assets/{users-Cx6ACt-W.js → users-CPP-3wxQ.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DqyIjBY8.js → vennDiagram-CIIHVFJN-CO0LSFj2.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-C93tXAKH.js → wardley-L42UT6IY-QHbclXGi.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DmH6-GJV.js → wardleyDiagram-YWT4CUSO-DAsnTuM9.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-BPwjE4Su.js → xychartDiagram-2RQKCTM6-BmG5EEoO.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +216 -350
- package/package.json +1 -1
- package/dist/client/assets/SettingsModal-KnUd0942.css +0 -1
- package/dist/client/assets/channel-BdTAZBkX.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CuoGzmwo.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CuoGzmwo.js +0 -1
- package/dist/client/assets/index-CITV-wDq.css +0 -1
package/dist/bin.js
CHANGED
|
@@ -136278,7 +136278,8 @@ function wrapPluginRuntime(instance, runtimeId, runtimeName) {
|
|
|
136278
136278
|
const result2 = await adapter.createSession(options);
|
|
136279
136279
|
return {
|
|
136280
136280
|
session: result2.session ?? result2,
|
|
136281
|
-
sessionFile: result2.sessionFile
|
|
136281
|
+
sessionFile: result2.sessionFile,
|
|
136282
|
+
settleFallbackDispatch: result2.settleFallbackDispatch
|
|
136282
136283
|
};
|
|
136283
136284
|
}
|
|
136284
136285
|
throw new Error(`Plugin runtime "${runtimeId}" does not implement createSession`);
|
|
@@ -136387,11 +136388,15 @@ var init_runtime_resolution = __esm({
|
|
|
136387
136388
|
name = "Default PI Runtime";
|
|
136388
136389
|
async createSession(options) {
|
|
136389
136390
|
const { toolOutputMaxChars, mcpServers, ...agentOptions } = options;
|
|
136390
|
-
|
|
136391
|
+
const result2 = await createFnAgent2({
|
|
136391
136392
|
...agentOptions,
|
|
136392
136393
|
toolOutputMaxChars,
|
|
136393
136394
|
mcpServers: normalizeAgentRuntimeMcpServers(mcpServers)
|
|
136394
136395
|
});
|
|
136396
|
+
return {
|
|
136397
|
+
...result2,
|
|
136398
|
+
settleFallbackDispatch: result2.settleFallbackDispatch ?? (async () => void 0)
|
|
136399
|
+
};
|
|
136395
136400
|
}
|
|
136396
136401
|
async promptWithFallback(session, prompt, options) {
|
|
136397
136402
|
return promptWithFallback(session, prompt, options);
|
|
@@ -137273,6 +137278,7 @@ async function createResolvedAgentSession(options) {
|
|
|
137273
137278
|
return {
|
|
137274
137279
|
session: result2.session,
|
|
137275
137280
|
sessionFile: result2.sessionFile,
|
|
137281
|
+
settleFallbackDispatch: result2.settleFallbackDispatch,
|
|
137276
137282
|
runtimeId: resolved.runtimeId,
|
|
137277
137283
|
wasConfigured: resolved.wasConfigured
|
|
137278
137284
|
};
|
|
@@ -159268,7 +159274,11 @@ async function createFnAgent2(options) {
|
|
|
159268
159274
|
}
|
|
159269
159275
|
});
|
|
159270
159276
|
attachSessionIdentity(promptableSession);
|
|
159271
|
-
return {
|
|
159277
|
+
return {
|
|
159278
|
+
session: promptableSession,
|
|
159279
|
+
sessionFile: promptableSession.sessionFile,
|
|
159280
|
+
settleFallbackDispatch: async () => void 0
|
|
159281
|
+
};
|
|
159272
159282
|
}
|
|
159273
159283
|
var execAsync, RTK_ACCEPTED_REWRITE_EXIT_CODES, RTK_EXPECTED_PASSTHROUGH_EXIT_CODES, RTK_EXPECTED_FAIL_OPEN_ERROR_CODES, RTK_REWRITE_MAX_BUFFER_BYTES, hostExtensionPaths, FN_MEMORY_APPEND_TOOL_NAME, FUSION_SHUTDOWN_WRAP_FLAG, promptWithFallbackInFlight, COMPACTION_FALLBACK_INSTRUCTIONS, MAX_COMPACTED_PROMPT_MEMORY_CHARS, MAX_COMPACTED_SUBTASK_GUIDANCE_CHARS, MAX_COMPACTED_ATTACHMENTS_CHARS, MAX_COMPACTED_EXISTING_SPEC_CHARS, MAX_COMPACTED_TASK_PROMPT_CHARS, MAX_COMPACTED_USER_COMMENTS_CHARS, ModelFallbackExhaustedError, GATE_BYPASS_TOOL_NAMES, TOOL_OUTPUT_BUDGET_OVERRIDES;
|
|
159274
159284
|
var init_pi = __esm({
|
|
@@ -185757,6 +185767,25 @@ var init_scheduler = __esm({
|
|
|
185757
185767
|
});
|
|
185758
185768
|
}
|
|
185759
185769
|
}
|
|
185770
|
+
if (from === parked.wip && to2 === parked.hold) {
|
|
185771
|
+
if (source === "engine") {
|
|
185772
|
+
this.recentEngineTodoRequeues.set(task.id, task.columnMovedAt ?? (/* @__PURE__ */ new Date()).toISOString());
|
|
185773
|
+
} else {
|
|
185774
|
+
this.recentEngineTodoRequeues.delete(task.id);
|
|
185775
|
+
}
|
|
185776
|
+
} else if (to2 === parked.review || parked.terminal.has(to2)) {
|
|
185777
|
+
this.recentEngineTodoRequeues.delete(task.id);
|
|
185778
|
+
if (task.dispatchStormCount != null || task.lastDispatchAt != null || task.executeRequeueLoopCount != null || task.executeRequeueLoopSignature != null) {
|
|
185779
|
+
void this.store.updateTask(task.id, {
|
|
185780
|
+
dispatchStormCount: null,
|
|
185781
|
+
lastDispatchAt: null,
|
|
185782
|
+
executeRequeueLoopCount: null,
|
|
185783
|
+
executeRequeueLoopSignature: null
|
|
185784
|
+
}).catch((error3) => {
|
|
185785
|
+
schedulerLog.warn(`Failed to reset dispatch oscillation state for ${task.id} on move to ${to2}: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
185786
|
+
});
|
|
185787
|
+
}
|
|
185788
|
+
}
|
|
185760
185789
|
const resolvedParked = mergeParkedColumns(await resolveTaskParkedColumns(this.store, task.id), lanes);
|
|
185761
185790
|
if (resolvedParked.terminal.has(to2)) {
|
|
185762
185791
|
try {
|
|
@@ -185817,25 +185846,6 @@ var init_scheduler = __esm({
|
|
|
185817
185846
|
schedulerLog.error(`Failed event-driven blocker reconciliation for ${task.id}`, error3);
|
|
185818
185847
|
}
|
|
185819
185848
|
}
|
|
185820
|
-
if (from === resolvedParked.wip && to2 === resolvedParked.hold) {
|
|
185821
|
-
if (source === "engine") {
|
|
185822
|
-
this.recentEngineTodoRequeues.set(task.id, task.columnMovedAt ?? (/* @__PURE__ */ new Date()).toISOString());
|
|
185823
|
-
} else {
|
|
185824
|
-
this.recentEngineTodoRequeues.delete(task.id);
|
|
185825
|
-
}
|
|
185826
|
-
} else if (to2 === resolvedParked.review || resolvedParked.terminal.has(to2)) {
|
|
185827
|
-
this.recentEngineTodoRequeues.delete(task.id);
|
|
185828
|
-
if (task.dispatchStormCount != null || task.lastDispatchAt != null || task.executeRequeueLoopCount != null || task.executeRequeueLoopSignature != null) {
|
|
185829
|
-
void this.store.updateTask(task.id, {
|
|
185830
|
-
dispatchStormCount: null,
|
|
185831
|
-
lastDispatchAt: null,
|
|
185832
|
-
executeRequeueLoopCount: null,
|
|
185833
|
-
executeRequeueLoopSignature: null
|
|
185834
|
-
}).catch((error3) => {
|
|
185835
|
-
schedulerLog.warn(`Failed to reset dispatch oscillation state for ${task.id} on move to ${to2}: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
185836
|
-
});
|
|
185837
|
-
}
|
|
185838
|
-
}
|
|
185839
185849
|
if (resolvedParked.terminal.has(to2) || to2 === resolvedParked.hold) {
|
|
185840
185850
|
schedulerLog.log(`Task moved to ${to2} \u2014 triggering scheduling`);
|
|
185841
185851
|
this.schedule();
|
|
@@ -204093,7 +204103,6 @@ var init_self_healing = __esm({
|
|
|
204093
204103
|
{ name: "reconcile-done-task-integrity", fn: () => this.reconcileDoneTaskIntegrity() },
|
|
204094
204104
|
{ name: "reconcile-stale-merger-status", fn: () => this.reconcileStaleMergerStatus() },
|
|
204095
204105
|
{ name: "reconcile-stale-duplicate-decision", fn: () => this.reconcileStaleDuplicateDecisionPause() },
|
|
204096
|
-
{ name: "reconcile-external-pr-blockers", fn: () => this.reconcileExternalPrBlockers() },
|
|
204097
204106
|
// FNXC:OrphanedPendingSteps 2026-07-22-16:35 (FN-8492 review follow-up): also
|
|
204098
204107
|
// steady-state — a step session can die without an engine restart, and startup-only
|
|
204099
204108
|
// cadence left that case riding the 3×30-min stall escalator to a deadlock park.
|
|
@@ -212990,71 +212999,12 @@ var init_self_healing = __esm({
|
|
|
212990
212999
|
}
|
|
212991
213000
|
}
|
|
212992
213001
|
/*
|
|
212993
|
-
FNXC:HonestBlockedExit 2026-08-02-
|
|
212994
|
-
|
|
212995
|
-
|
|
212996
|
-
|
|
213002
|
+
FNXC:HonestBlockedExit 2026-08-02-23:59 (operator decision — FN-8728 vs PR #2398):
|
|
213003
|
+
The FN-8700 `reconcile-external-pr-blockers` sweep (gh-backed clearing of PR-claim parks)
|
|
213004
|
+
is REMOVED with the whole PR/file-claim blocking mechanism. Open PRs are never blockers;
|
|
213005
|
+
file-scope conflicts are arbitrated only by Fusion's own board. Legacy PR-claim parks are
|
|
213006
|
+
no longer honored by isDurableBlockedTask, so normal recovery paths reclaim them.
|
|
212997
213007
|
*/
|
|
212998
|
-
async reconcileExternalPrBlockers() {
|
|
212999
|
-
try {
|
|
213000
|
-
if (!await isGhAvailable()) {
|
|
213001
|
-
log33.debug("reconcile-external-pr-blockers skipped \u2014 gh unavailable");
|
|
213002
|
-
return 0;
|
|
213003
|
-
}
|
|
213004
|
-
const tasks2 = await this.store.listTasks({ slim: true, includeArchived: false, limit: 500 });
|
|
213005
|
-
let cleared = 0;
|
|
213006
|
-
for (const task of tasks2.slice(0, 80)) {
|
|
213007
|
-
if (task.status !== "failed" || !task.error?.startsWith("BLOCKED:")) continue;
|
|
213008
|
-
const meta2 = task.sourceMetadata;
|
|
213009
|
-
const blockers = meta2?.externalBlockers;
|
|
213010
|
-
if (!Array.isArray(blockers) || blockers.length === 0) continue;
|
|
213011
|
-
const prNumbers = blockers.map((b3) => b3 && typeof b3 === "object" && b3.kind === "github-pr" ? Number(b3.number) : NaN).filter((n) => Number.isFinite(n) && n > 0);
|
|
213012
|
-
if (prNumbers.length === 0) continue;
|
|
213013
|
-
let allResolved = true;
|
|
213014
|
-
for (const n of prNumbers) {
|
|
213015
|
-
try {
|
|
213016
|
-
const pr2 = await runGhJsonAsync(
|
|
213017
|
-
["pr", "view", String(n), "--json", "state,mergedAt"],
|
|
213018
|
-
{ timeoutMs: 15e3 }
|
|
213019
|
-
);
|
|
213020
|
-
const state = String(pr2?.state ?? "").toUpperCase();
|
|
213021
|
-
const merged = Boolean(pr2?.mergedAt) || state === "MERGED";
|
|
213022
|
-
const closed = state === "CLOSED" || state === "MERGED";
|
|
213023
|
-
if (!merged && !closed) {
|
|
213024
|
-
allResolved = false;
|
|
213025
|
-
break;
|
|
213026
|
-
}
|
|
213027
|
-
} catch {
|
|
213028
|
-
allResolved = false;
|
|
213029
|
-
break;
|
|
213030
|
-
}
|
|
213031
|
-
}
|
|
213032
|
-
if (!allResolved) continue;
|
|
213033
|
-
await this.store.updateTask(task.id, {
|
|
213034
|
-
status: null,
|
|
213035
|
-
error: null,
|
|
213036
|
-
sourceMetadataPatch: {
|
|
213037
|
-
externalBlockers: [],
|
|
213038
|
-
blockedClass: null,
|
|
213039
|
-
blockedThrashSignature: null,
|
|
213040
|
-
blockedThrashCount: null,
|
|
213041
|
-
externalPrBlockersClearedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
213042
|
-
externalPrBlockersCleared: prNumbers
|
|
213043
|
-
}
|
|
213044
|
-
});
|
|
213045
|
-
await this.store.logEntry(
|
|
213046
|
-
task.id,
|
|
213047
|
-
`Auto-recovered: external PR blocker(s) ${prNumbers.map((n) => `#${n}`).join(", ")} merged/closed \u2014 cleared durable BLOCKED park for re-dispatch`
|
|
213048
|
-
);
|
|
213049
|
-
log33.log(`Cleared durable PR block for ${task.id} (prs=${prNumbers.join(",")})`);
|
|
213050
|
-
cleared += 1;
|
|
213051
|
-
}
|
|
213052
|
-
return cleared;
|
|
213053
|
-
} catch (error3) {
|
|
213054
|
-
log33.warn(`reconcile-external-pr-blockers failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
213055
|
-
return 0;
|
|
213056
|
-
}
|
|
213057
|
-
}
|
|
213058
213008
|
async resolveExplicitDuplicateMarkerTasks() {
|
|
213059
213009
|
try {
|
|
213060
213010
|
const settings = await this.store.getSettings();
|
|
@@ -213808,6 +213758,7 @@ var init_self_healing = __esm({
|
|
|
213808
213758
|
// ../engine/src/triage.ts
|
|
213809
213759
|
import { Type as Type5 } from "@earendil-works/pi-ai";
|
|
213810
213760
|
import { exec as exec34 } from "node:child_process";
|
|
213761
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
213811
213762
|
import { readFile as readFile38, writeFile as writeFile27, rm as rm8 } from "node:fs/promises";
|
|
213812
213763
|
import { join as join72 } from "node:path";
|
|
213813
213764
|
import { promisify as promisify48 } from "node:util";
|
|
@@ -214314,6 +214265,8 @@ var init_triage = __esm({
|
|
|
214314
214265
|
unregisterAdmissionProvider = null;
|
|
214315
214266
|
/** Timestamps when tasks entered the `processing` set, for staleness detection. */
|
|
214316
214267
|
processingSince = /* @__PURE__ */ new Map();
|
|
214268
|
+
/** Monotonic provenance token for attempt-local planner fallback observation. */
|
|
214269
|
+
planningAttemptSequence = 0;
|
|
214317
214270
|
wasGlobalPaused = false;
|
|
214318
214271
|
wasEnginePaused = false;
|
|
214319
214272
|
idleSemaphoreLeakCandidateSince = null;
|
|
@@ -215609,7 +215562,28 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
215609
215562
|
}
|
|
215610
215563
|
await this.store.logEntry(task.id, `Planning session running in task worktree ${planningCwd}`).catch(() => void 0);
|
|
215611
215564
|
}
|
|
215612
|
-
const
|
|
215565
|
+
const authoritativePromptPath = join72(this.rootDir, promptPath);
|
|
215566
|
+
const planningAttemptBaseline = existsSync60(authoritativePromptPath) ? await readFile38(authoritativePromptPath, "utf-8").catch(() => void 0) : void 0;
|
|
215567
|
+
const planningAttempt = {
|
|
215568
|
+
id: `${task.id}:${++this.planningAttemptSequence}`,
|
|
215569
|
+
baseline: planningAttemptBaseline,
|
|
215570
|
+
fallbackEngaged: false,
|
|
215571
|
+
fallbackSettlements: []
|
|
215572
|
+
};
|
|
215573
|
+
const fallbackObserver = createFallbackModelObserver({
|
|
215574
|
+
agent: "triage",
|
|
215575
|
+
label: "triage",
|
|
215576
|
+
store: this.store,
|
|
215577
|
+
taskId: task.id,
|
|
215578
|
+
taskTitle: task.title
|
|
215579
|
+
});
|
|
215580
|
+
const onFallbackModelUsed = (payload) => {
|
|
215581
|
+
planningAttempt.fallbackEngaged = true;
|
|
215582
|
+
const settlement = Promise.resolve(fallbackObserver(payload));
|
|
215583
|
+
planningAttempt.fallbackSettlements.push(settlement);
|
|
215584
|
+
return settlement;
|
|
215585
|
+
};
|
|
215586
|
+
const { session, settleFallbackDispatch, runtimeId } = await createResolvedAgentSession({
|
|
215613
215587
|
sessionPurpose: "triage",
|
|
215614
215588
|
runtimeHint: triageRuntimeHint,
|
|
215615
215589
|
pluginRunner: this.options.pluginRunner,
|
|
@@ -215648,13 +215622,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
215648
215622
|
taskTitle: task.title,
|
|
215649
215623
|
actionGateContext: this.buildActionGateContext(task.id, triageRunContext.runId, assignedAgent, settings.defaultAgentPermissionPolicy),
|
|
215650
215624
|
permanentAgentGating: this.buildPermanentAgentGatingContext(task.id, triageRunContext.runId, assignedAgent, settings.defaultAgentPermissionPolicy),
|
|
215651
|
-
onFallbackModelUsed
|
|
215652
|
-
agent: "triage",
|
|
215653
|
-
label: "triage",
|
|
215654
|
-
store: this.store,
|
|
215655
|
-
taskId: task.id,
|
|
215656
|
-
taskTitle: task.title
|
|
215657
|
-
})
|
|
215625
|
+
onFallbackModelUsed
|
|
215658
215626
|
});
|
|
215659
215627
|
const modelDesc = formatModelMarkerDetails(describeModel(session), resolvePlanningThinkingLevel(settings, task.planningThinkingLevel ?? task.thinkingLevel));
|
|
215660
215628
|
planLog.debug(`${task.id}: using model ${modelDesc}`);
|
|
@@ -215724,6 +215692,10 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
215724
215692
|
agentPrompt,
|
|
215725
215693
|
imageContents.length > 0 ? { images: imageContents } : void 0
|
|
215726
215694
|
);
|
|
215695
|
+
const fallbackDispatchBoundaryMissing = typeof settleFallbackDispatch !== "function";
|
|
215696
|
+
if (!fallbackDispatchBoundaryMissing) {
|
|
215697
|
+
await settleFallbackDispatch();
|
|
215698
|
+
}
|
|
215727
215699
|
checkSessionError(session);
|
|
215728
215700
|
if (this.pauseAborted.has(task.id)) {
|
|
215729
215701
|
this.pauseAborted.delete(task.id);
|
|
@@ -215816,12 +215788,42 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
215816
215788
|
}
|
|
215817
215789
|
}
|
|
215818
215790
|
}
|
|
215819
|
-
|
|
215820
|
-
|
|
215821
|
-
|
|
215822
|
-
|
|
215823
|
-
|
|
215824
|
-
|
|
215791
|
+
let settledFallbackCount = 0;
|
|
215792
|
+
while (settledFallbackCount < planningAttempt.fallbackSettlements.length) {
|
|
215793
|
+
const pendingSettlements = planningAttempt.fallbackSettlements.slice(settledFallbackCount);
|
|
215794
|
+
settledFallbackCount = planningAttempt.fallbackSettlements.length;
|
|
215795
|
+
await Promise.all(pendingSettlements);
|
|
215796
|
+
}
|
|
215797
|
+
const artifactChangedByAttempt = planningAttempt.baseline !== written;
|
|
215798
|
+
if (fallbackDispatchBoundaryMissing || planningAttempt.fallbackEngaged || !artifactChangedByAttempt) {
|
|
215799
|
+
const failure = fallbackDispatchBoundaryMissing ? `Planner runtime ${runtimeId} did not provide a fallback-dispatch settlement boundary for attempt ${planningAttempt.id}` : planningAttempt.fallbackEngaged ? `Planner fallback engaged during attempt ${planningAttempt.id}` : `Planner did not update the authoritative PROMPT.md during attempt ${planningAttempt.id}`;
|
|
215800
|
+
const decision = computeRecoveryDecision({
|
|
215801
|
+
recoveryRetryCount: task.recoveryRetryCount,
|
|
215802
|
+
nextRecoveryAt: task.nextRecoveryAt
|
|
215803
|
+
});
|
|
215804
|
+
if (decision.shouldRetry) {
|
|
215805
|
+
const retryMessage = `${failure} \u2014 retry ${decision.nextState.recoveryRetryCount}/${MAX_RECOVERY_RETRIES} in ${formatDelay(decision.delayMs)}.`;
|
|
215806
|
+
planLog.warn(`${task.id} ${retryMessage}`);
|
|
215807
|
+
await this.store.logEntry(task.id, retryMessage);
|
|
215808
|
+
await this.updatePlanningStateIfStillCurrent(task, {
|
|
215809
|
+
status: this.restoreStatusAfterInterruptedTriageWork(task),
|
|
215810
|
+
error: null,
|
|
215811
|
+
recoveryRetryCount: decision.nextState.recoveryRetryCount,
|
|
215812
|
+
nextRecoveryAt: decision.nextState.nextRecoveryAt
|
|
215813
|
+
});
|
|
215814
|
+
return;
|
|
215815
|
+
}
|
|
215816
|
+
const failureMessage = `${failure} after ${MAX_RECOVERY_RETRIES} retries. Retry after adjusting the task prompt or model.`;
|
|
215817
|
+
planLog.error(`${task.id} clean planning attempt retry budget exhausted`);
|
|
215818
|
+
await this.store.logEntry(task.id, failureMessage);
|
|
215819
|
+
if (await this.updatePlanningStateIfStillCurrent(task, {
|
|
215820
|
+
status: "failed",
|
|
215821
|
+
error: failureMessage,
|
|
215822
|
+
recoveryRetryCount: null,
|
|
215823
|
+
nextRecoveryAt: null
|
|
215824
|
+
})) {
|
|
215825
|
+
await this.backfillBlankTitleAfterTerminalTriageFailure(task);
|
|
215826
|
+
}
|
|
215825
215827
|
return;
|
|
215826
215828
|
}
|
|
215827
215829
|
const deterministicSpecFailure = await this.validateGeneratedPrompt(task.id, written);
|
|
@@ -215863,6 +215865,21 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
215863
215865
|
}
|
|
215864
215866
|
return;
|
|
215865
215867
|
}
|
|
215868
|
+
const duplicateReport = { outcome: "parked" };
|
|
215869
|
+
if (await this.tryFinalizeExplicitDuplicateMarker(task, written, settings, {
|
|
215870
|
+
isReplan,
|
|
215871
|
+
feedback
|
|
215872
|
+
}, duplicateReport)) {
|
|
215873
|
+
this.options.onSpecifyComplete?.(task, duplicateReport);
|
|
215874
|
+
return;
|
|
215875
|
+
}
|
|
215876
|
+
if (task.recoveryRetryCount != null || task.nextRecoveryAt != null) {
|
|
215877
|
+
await this.updatePlanningStateIfStillCurrent(task, {
|
|
215878
|
+
error: null,
|
|
215879
|
+
recoveryRetryCount: null,
|
|
215880
|
+
nextRecoveryAt: null
|
|
215881
|
+
});
|
|
215882
|
+
}
|
|
215866
215883
|
const finalizeReport = await this.finalizeApprovedTask(task, written, settings, {
|
|
215867
215884
|
isReplan,
|
|
215868
215885
|
feedback
|
|
@@ -216899,103 +216916,35 @@ Remove or replace these ids and call fn_task_create again.`
|
|
|
216899
216916
|
// ../engine/src/execution-block-classifier.ts
|
|
216900
216917
|
function partitionBlockedByRefs(blockedBy) {
|
|
216901
216918
|
const taskIds = [];
|
|
216902
|
-
const prNumbers = [];
|
|
216903
216919
|
for (const raw of blockedBy) {
|
|
216904
216920
|
const id = raw.trim();
|
|
216905
216921
|
if (!id) continue;
|
|
216906
|
-
|
|
216907
|
-
if (prMatch) {
|
|
216908
|
-
prNumbers.push(Number(prMatch[1]));
|
|
216909
|
-
continue;
|
|
216910
|
-
}
|
|
216922
|
+
if (LEGACY_PR_REF_RE.test(id)) continue;
|
|
216911
216923
|
if (TASK_ID_RE.test(id)) {
|
|
216912
216924
|
const m2 = id.toUpperCase().match(/^([A-Z][A-Z0-9]*)-(\d+)$/);
|
|
216913
216925
|
taskIds.push(m2 ? `${m2[1]}-${m2[2]}` : id.toUpperCase());
|
|
216914
|
-
continue;
|
|
216915
216926
|
}
|
|
216916
216927
|
}
|
|
216917
|
-
return {
|
|
216918
|
-
taskIds: [...new Set(taskIds)],
|
|
216919
|
-
prNumbers: [...new Set(prNumbers.filter((n) => Number.isFinite(n) && n > 0))]
|
|
216920
|
-
};
|
|
216928
|
+
return { taskIds: [...new Set(taskIds)] };
|
|
216921
216929
|
}
|
|
216922
|
-
function
|
|
216923
|
-
const
|
|
216924
|
-
|
|
216925
|
-
const n = Number(match[1]);
|
|
216926
|
-
if (Number.isFinite(n) && n > 0) found.push(n);
|
|
216927
|
-
}
|
|
216928
|
-
return [...new Set(found)];
|
|
216929
|
-
}
|
|
216930
|
-
function isFileClaimBlockedReason(reason) {
|
|
216931
|
-
return CLAIM_REASON_RE.test(reason);
|
|
216932
|
-
}
|
|
216933
|
-
function classifyBlockedExit(reason, blockedBy = []) {
|
|
216934
|
-
const trimmed = reason.trim();
|
|
216935
|
-
const partitioned = partitionBlockedByRefs(blockedBy);
|
|
216936
|
-
const prFromText = extractPrNumbersFromText(trimmed);
|
|
216937
|
-
const prNumbers = [.../* @__PURE__ */ new Set([...partitioned.prNumbers, ...prFromText])];
|
|
216938
|
-
const isClaim = isFileClaimBlockedReason(trimmed) || prNumbers.length > 0 && /claim/i.test(trimmed);
|
|
216939
|
-
if (isClaim || prNumbers.length > 0 && isFileClaimBlockedReason(trimmed)) {
|
|
216940
|
-
const externalBlockers = [
|
|
216941
|
-
...prNumbers.map((number4) => ({ kind: "github-pr", number: number4 }))
|
|
216942
|
-
];
|
|
216943
|
-
if (externalBlockers.length === 0 && isClaim) {
|
|
216944
|
-
externalBlockers.push({
|
|
216945
|
-
kind: "file-claim",
|
|
216946
|
-
prNumber: prNumbers[0]
|
|
216947
|
-
});
|
|
216948
|
-
} else if (isClaim) {
|
|
216949
|
-
for (const n of prNumbers) {
|
|
216950
|
-
if (!externalBlockers.some((b3) => b3.kind === "github-pr" && b3.number === n)) {
|
|
216951
|
-
externalBlockers.push({ kind: "github-pr", number: n });
|
|
216952
|
-
}
|
|
216953
|
-
}
|
|
216954
|
-
if (prNumbers.length === 0) {
|
|
216955
|
-
externalBlockers.push({ kind: "file-claim" });
|
|
216956
|
-
}
|
|
216957
|
-
}
|
|
216958
|
-
const thrashSignature = [
|
|
216959
|
-
"file-claim",
|
|
216960
|
-
...prNumbers.map((n) => `pr:${n}`).sort(),
|
|
216961
|
-
...partitioned.taskIds.slice().sort()
|
|
216962
|
-
].join("|");
|
|
216963
|
-
return {
|
|
216964
|
-
allowAutoReplan: false,
|
|
216965
|
-
class: "file-claim",
|
|
216966
|
-
externalBlockers,
|
|
216967
|
-
thrashSignature: thrashSignature || "file-claim",
|
|
216968
|
-
prNumbers
|
|
216969
|
-
};
|
|
216970
|
-
}
|
|
216971
|
-
if (partitioned.taskIds.length > 0) {
|
|
216972
|
-
return {
|
|
216973
|
-
allowAutoReplan: false,
|
|
216974
|
-
class: "external",
|
|
216975
|
-
externalBlockers: [],
|
|
216976
|
-
thrashSignature: `tasks:${partitioned.taskIds.slice().sort().join(",")}`,
|
|
216977
|
-
prNumbers
|
|
216978
|
-
};
|
|
216979
|
-
}
|
|
216980
|
-
if (prNumbers.length > 0) {
|
|
216930
|
+
function classifyBlockedExit(_reason, blockedBy = []) {
|
|
216931
|
+
const { taskIds } = partitionBlockedByRefs(blockedBy);
|
|
216932
|
+
if (taskIds.length > 0) {
|
|
216981
216933
|
return {
|
|
216982
216934
|
allowAutoReplan: false,
|
|
216983
216935
|
class: "external",
|
|
216984
|
-
|
|
216985
|
-
thrashSignature: prNumbers.map((n) => `pr:${n}`).sort().join("|"),
|
|
216986
|
-
prNumbers
|
|
216936
|
+
thrashSignature: `tasks:${taskIds.slice().sort().join(",")}`
|
|
216987
216937
|
};
|
|
216988
216938
|
}
|
|
216989
216939
|
return {
|
|
216990
216940
|
allowAutoReplan: true,
|
|
216991
216941
|
class: "plan-defect",
|
|
216992
|
-
|
|
216993
|
-
thrashSignature: "plan-defect",
|
|
216994
|
-
prNumbers: []
|
|
216942
|
+
thrashSignature: "plan-defect"
|
|
216995
216943
|
};
|
|
216996
216944
|
}
|
|
216997
216945
|
function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs = BLOCKED_THRASH_WINDOW_MS) {
|
|
216998
216946
|
if (!log43?.length) return 0;
|
|
216947
|
+
if (signature === "plan-defect") return 0;
|
|
216999
216948
|
const cutoff = nowMs - windowMs;
|
|
217000
216949
|
let count2 = 0;
|
|
217001
216950
|
for (const entry of log43) {
|
|
@@ -217007,18 +216956,7 @@ function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs =
|
|
|
217007
216956
|
continue;
|
|
217008
216957
|
}
|
|
217009
216958
|
}
|
|
217010
|
-
if (signature === "plan-defect") continue;
|
|
217011
|
-
if (signature.includes("file-claim") || signature.startsWith("pr:") || signature.includes("|pr:")) {
|
|
217012
|
-
if (isFileClaimBlockedReason(action) || /PR\s*#?\s*\d+/i.test(action) || action.includes("durable external block")) {
|
|
217013
|
-
count2 += 1;
|
|
217014
|
-
continue;
|
|
217015
|
-
}
|
|
217016
|
-
}
|
|
217017
216959
|
for (const part of signature.split("|")) {
|
|
217018
|
-
if (part.startsWith("pr:") && action.includes(`PR #${part.slice(3)}`)) {
|
|
217019
|
-
count2 += 1;
|
|
217020
|
-
break;
|
|
217021
|
-
}
|
|
217022
216960
|
if (part.startsWith("tasks:") && part.slice(6).split(",").some((id) => id && action.includes(id))) {
|
|
217023
216961
|
count2 += 1;
|
|
217024
216962
|
break;
|
|
@@ -217027,38 +216965,26 @@ function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs =
|
|
|
217027
216965
|
}
|
|
217028
216966
|
return count2;
|
|
217029
216967
|
}
|
|
217030
|
-
function isDurableBlockedError(error3) {
|
|
217031
|
-
if (!error3?.startsWith("BLOCKED:")) return false;
|
|
217032
|
-
const reason = error3.slice("BLOCKED:".length).trim();
|
|
217033
|
-
const classification = classifyBlockedExit(reason, []);
|
|
217034
|
-
return !classification.allowAutoReplan;
|
|
217035
|
-
}
|
|
217036
216968
|
function isDurableBlockedTask(task) {
|
|
217037
|
-
if (task.status === "failed" && isDurableBlockedError(task.error)) return true;
|
|
217038
216969
|
const meta2 = task.sourceMetadata;
|
|
217039
216970
|
if (!meta2 || typeof meta2 !== "object") return false;
|
|
217040
|
-
if (meta2.blockedClass
|
|
217041
|
-
|
|
217042
|
-
}
|
|
217043
|
-
const blockers = meta2.externalBlockers;
|
|
217044
|
-
return Array.isArray(blockers) && blockers.length > 0 && task.status === "failed";
|
|
216971
|
+
if (meta2.blockedClass !== "external") return false;
|
|
216972
|
+
return task.status === "failed" || task.status === "needs-replan";
|
|
217045
216973
|
}
|
|
217046
216974
|
function buildExternalBlockMetadataPatch(classification, thrashCount) {
|
|
217047
216975
|
return {
|
|
217048
216976
|
blockedClass: classification.class,
|
|
217049
216977
|
blockedThrashSignature: classification.thrashSignature,
|
|
217050
216978
|
blockedThrashCount: thrashCount,
|
|
217051
|
-
externalBlockers:
|
|
216979
|
+
externalBlockers: []
|
|
217052
216980
|
};
|
|
217053
216981
|
}
|
|
217054
|
-
var TASK_ID_RE,
|
|
216982
|
+
var TASK_ID_RE, LEGACY_PR_REF_RE, BLOCKED_THRASH_LIMIT, BLOCKED_THRASH_WINDOW_MS;
|
|
217055
216983
|
var init_execution_block_classifier = __esm({
|
|
217056
216984
|
"../engine/src/execution-block-classifier.ts"() {
|
|
217057
216985
|
"use strict";
|
|
217058
216986
|
TASK_ID_RE = /^[A-Z][A-Z0-9]*-\d+$/i;
|
|
217059
|
-
|
|
217060
|
-
PR_IN_TEXT_RE = /\bPR\s*#?\s*(\d+)\b/gi;
|
|
217061
|
-
CLAIM_REASON_RE = /check-file-claimed|actively claimed|file[- ]claim|claimed by (?:open )?pr|open pr\s*#?\s*\d+|collision policy|claimed paths?|file claims?/i;
|
|
216987
|
+
LEGACY_PR_REF_RE = /^(?:pr[:#-]|#|PR-)(\d+)$/i;
|
|
217062
216988
|
BLOCKED_THRASH_LIMIT = 3;
|
|
217063
216989
|
BLOCKED_THRASH_WINDOW_MS = 60 * 60 * 1e3;
|
|
217064
216990
|
}
|
|
@@ -219876,7 +219802,7 @@ var init_workflow_completion_summary = __esm({
|
|
|
219876
219802
|
|
|
219877
219803
|
// ../engine/src/review-checkout.ts
|
|
219878
219804
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
219879
|
-
import { existsSync as
|
|
219805
|
+
import { existsSync as existsSync61, realpathSync as realpathSync9, statSync as statSync11 } from "node:fs";
|
|
219880
219806
|
import { isAbsolute as isAbsolute15 } from "node:path";
|
|
219881
219807
|
function readMetadataPath(value) {
|
|
219882
219808
|
if (!value || typeof value !== "object") return void 0;
|
|
@@ -219900,7 +219826,7 @@ function resolveReviewCheckoutCwd(task, fallbackCwd) {
|
|
|
219900
219826
|
const candidate = getTaskReviewCheckoutPath(task);
|
|
219901
219827
|
if (!candidate || !isAbsolute15(candidate)) return fallbackCwd;
|
|
219902
219828
|
try {
|
|
219903
|
-
if (!
|
|
219829
|
+
if (!existsSync61(candidate) || !statSync11(candidate).isDirectory()) return fallbackCwd;
|
|
219904
219830
|
const realCandidate = realpathSync9(candidate);
|
|
219905
219831
|
const topLevel = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
|
|
219906
219832
|
cwd: realCandidate,
|
|
@@ -222506,7 +222432,7 @@ var init_external_integration_evidence = __esm({
|
|
|
222506
222432
|
|
|
222507
222433
|
// ../engine/src/step-runner.ts
|
|
222508
222434
|
import { exec as exec35 } from "node:child_process";
|
|
222509
|
-
import { existsSync as
|
|
222435
|
+
import { existsSync as existsSync63, statSync as statSync12 } from "node:fs";
|
|
222510
222436
|
import { promisify as promisify50 } from "node:util";
|
|
222511
222437
|
async function runTaskStep(deps, task, stepIndex, opts = {}) {
|
|
222512
222438
|
const { store, worktreePath } = deps;
|
|
@@ -222660,7 +222586,7 @@ function makeAncestryBlastRadiusGuard(opts) {
|
|
|
222660
222586
|
function isUsableWorktreeDirectory(candidate) {
|
|
222661
222587
|
if (!candidate) return false;
|
|
222662
222588
|
try {
|
|
222663
|
-
return
|
|
222589
|
+
return existsSync63(candidate) && statSync12(candidate).isDirectory();
|
|
222664
222590
|
} catch {
|
|
222665
222591
|
return false;
|
|
222666
222592
|
}
|
|
@@ -222697,7 +222623,7 @@ var init_step_runner = __esm({
|
|
|
222697
222623
|
|
|
222698
222624
|
// ../engine/src/auto-recovery-handlers/branch-worktree.ts
|
|
222699
222625
|
import { exec as exec36 } from "node:child_process";
|
|
222700
|
-
import { existsSync as
|
|
222626
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
222701
222627
|
import { promisify as promisify51 } from "node:util";
|
|
222702
222628
|
var execAsync33, baseLog2, GIT_TIMEOUT_MS8, GIT_MAX_BUFFER6, BranchWorktreeAutoRecoveryHandler;
|
|
222703
222629
|
var init_branch_worktree = __esm({
|
|
@@ -222888,7 +222814,7 @@ var init_branch_worktree = __esm({
|
|
|
222888
222814
|
if (inspection.kind === "stale-resolved" || inspection.kind === "fully-subsumed" || inspection.kind === "tip-already-merged") {
|
|
222889
222815
|
await this.requeueAfterRecovery(ctx.task, failure, inspection.kind, {
|
|
222890
222816
|
branchExists: await this.hasBranchRef(repoDir, branchName),
|
|
222891
|
-
worktreePresent:
|
|
222817
|
+
worktreePresent: existsSync64(conflictingWorktreePath),
|
|
222892
222818
|
tipSha: "tipSha" in inspection ? inspection.tipSha : void 0,
|
|
222893
222819
|
inspectionKind: inspection.kind
|
|
222894
222820
|
});
|
|
@@ -222958,7 +222884,7 @@ var init_branch_worktree = __esm({
|
|
|
222958
222884
|
let branchDeleted = false;
|
|
222959
222885
|
let worktreeRemoved = false;
|
|
222960
222886
|
if (!isLiveOwned) {
|
|
222961
|
-
if (
|
|
222887
|
+
if (existsSync64(conflictingWorktreePath)) {
|
|
222962
222888
|
try {
|
|
222963
222889
|
await execAsync33(`git worktree remove --force ${this.quote(conflictingWorktreePath)}`, {
|
|
222964
222890
|
cwd: repoDir,
|
|
@@ -223006,7 +222932,7 @@ var init_branch_worktree = __esm({
|
|
|
223006
222932
|
});
|
|
223007
222933
|
await this.requeueAfterRecovery(ctx.task, failure, "live-foreign-discard-and-recreate", {
|
|
223008
222934
|
branchExists: !branchDeleted,
|
|
223009
|
-
worktreePresent: !worktreeRemoved &&
|
|
222935
|
+
worktreePresent: !worktreeRemoved && existsSync64(conflictingWorktreePath),
|
|
223010
222936
|
tipSha: tipSha2,
|
|
223011
222937
|
inspectionKind: inspection.kind
|
|
223012
222938
|
});
|
|
@@ -223019,7 +222945,7 @@ var init_branch_worktree = __esm({
|
|
|
223019
222945
|
conflictingWorktreePath,
|
|
223020
222946
|
inspectionKind: inspection.kind,
|
|
223021
222947
|
branchExists,
|
|
223022
|
-
worktreePresent:
|
|
222948
|
+
worktreePresent: existsSync64(conflictingWorktreePath),
|
|
223023
222949
|
tipSha
|
|
223024
222950
|
});
|
|
223025
222951
|
}
|
|
@@ -223180,7 +223106,7 @@ var init_file_scope2 = __esm({
|
|
|
223180
223106
|
});
|
|
223181
223107
|
|
|
223182
223108
|
// ../engine/src/run-verification-tool.ts
|
|
223183
|
-
import { existsSync as
|
|
223109
|
+
import { existsSync as existsSync65, readdirSync as readdirSync11, readFileSync as readFileSync23 } from "node:fs";
|
|
223184
223110
|
import { isAbsolute as isAbsolute16, join as join77, relative as relative14 } from "node:path";
|
|
223185
223111
|
import { Type as Type6 } from "@earendil-works/pi-ai";
|
|
223186
223112
|
function shellSplit(input) {
|
|
@@ -223740,7 +223666,7 @@ function createRunVerificationTool(opts) {
|
|
|
223740
223666
|
}
|
|
223741
223667
|
if (effectiveCommand.trimStart().startsWith("pnpm --filter")) {
|
|
223742
223668
|
const modulesYaml = join77(rootDir, "node_modules", ".modules.yaml");
|
|
223743
|
-
if (!
|
|
223669
|
+
if (!existsSync65(modulesYaml)) {
|
|
223744
223670
|
const installCmd = "pnpm install --prefer-offline";
|
|
223745
223671
|
const msg = `node_modules/.modules.yaml not found in workspace root \u2014 auto-prepending \`${installCmd}\` before running the command.`;
|
|
223746
223672
|
warnings.push(msg);
|
|
@@ -224101,7 +224027,7 @@ import { exec as exec39, execFile as execFile26, execSync as execSync7 } from "n
|
|
|
224101
224027
|
import { promisify as promisify54 } from "node:util";
|
|
224102
224028
|
import { setImmediate as setImmediateCb3 } from "node:timers";
|
|
224103
224029
|
import { basename as basename19, delimiter as delimiter2, isAbsolute as isAbsolute18, join as join78, relative as relative16, resolve as resolvePath3 } from "node:path";
|
|
224104
|
-
import { existsSync as
|
|
224030
|
+
import { existsSync as existsSync66, lstatSync as lstatSync3, realpathSync as realpathSync10 } from "node:fs";
|
|
224105
224031
|
import { readFile as readFile40, rm as rm12, writeFile as writeFile29 } from "node:fs/promises";
|
|
224106
224032
|
import { Type as Type7 } from "@earendil-works/pi-ai";
|
|
224107
224033
|
import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
|
|
@@ -224119,7 +224045,7 @@ function isWorkflowStepSkillDiscoverable(skillName, additionalSkillPaths, ceSkil
|
|
|
224119
224045
|
return false;
|
|
224120
224046
|
}
|
|
224121
224047
|
return (additionalSkillPaths ?? []).some(
|
|
224122
|
-
(skillPath) => basename19(skillPath) === bareSkillName2 &&
|
|
224048
|
+
(skillPath) => basename19(skillPath) === bareSkillName2 && existsSync66(join78(skillPath, "SKILL.md")) || existsSync66(join78(skillPath, bareSkillName2, "SKILL.md"))
|
|
224123
224049
|
);
|
|
224124
224050
|
}
|
|
224125
224051
|
function getPromptSection(prompt, heading) {
|
|
@@ -225092,7 +225018,7 @@ If you have just finished a step's work, immediately call \`fn_task_update\` to
|
|
|
225092
225018
|
|
|
225093
225019
|
The user is not watching this conversation in real-time. They will read the final result. Asking permission wastes a full retry cycle and may orphan committed work.
|
|
225094
225020
|
|
|
225095
|
-
**Cannot proceed \u2014 the honest blocked exit.** If the work genuinely cannot be finished (an upstream API break, a missing prerequisite task, an unresolvable external error
|
|
225021
|
+
**Cannot proceed \u2014 the honest blocked exit.** If the work genuinely cannot be finished (an upstream API break, a missing prerequisite task, or an unresolvable external error), call \`fn_task_done(outcome="blocked", reason="<concrete blocker + what would unblock it>", blockedBy=["FN-XXXX"])\`. That parks durable failed WITHOUT auto-replan so the engine does not thrash; task IDs requeue when those tasks complete. Blockers must be Fusion board tasks \u2014 do NOT treat open GitHub PRs touching the same files as blockers; other PRs are not claims on your file scope. Do NOT skip remaining steps to fake completion.
|
|
225096
225022
|
This is THE correct action when you are stuck \u2014 do NOT instead mark the remaining steps \`skipped\` and call \`fn_task_done\` to make the task look finished. Skipping steps to escape a blocker launders a failure into \`done\` and is never the right move. (\`skipped\` remains valid only for the stale-premise path below, when the requested work is already present on HEAD.) Never write the blocker as plain prose.
|
|
225097
225023
|
|
|
225098
225024
|
## How to work
|
|
@@ -227681,7 +227607,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
|
|
|
227681
227607
|
);
|
|
227682
227608
|
return false;
|
|
227683
227609
|
}
|
|
227684
|
-
if (task.worktree &&
|
|
227610
|
+
if (task.worktree && existsSync66(task.worktree)) {
|
|
227685
227611
|
const modifiedFiles = await this.captureModifiedFiles(task.worktree, task.baseCommitSha, task.id, void 0, "recovery");
|
|
227686
227612
|
if (modifiedFiles.length > 0) {
|
|
227687
227613
|
await this.store.updateTask(task.id, { modifiedFiles });
|
|
@@ -230643,7 +230569,7 @@ ${info.feedback}`, revisionKey),
|
|
|
230643
230569
|
if (live.firstExecutionAt || live.executionStartedAt) return false;
|
|
230644
230570
|
if (activeSessionRegistry.isPathActive(live.worktree) || activeSessionRegistry.isPathActive(resolvePath3(live.worktree))) return false;
|
|
230645
230571
|
if (this.hasLiveTaskSessionSurface(taskId) || executingTaskLock.has(taskId)) return false;
|
|
230646
|
-
if (
|
|
230572
|
+
if (existsSync66(live.worktree)) {
|
|
230647
230573
|
if (await this.preExecutionWorktreeHasWork(live.worktree)) {
|
|
230648
230574
|
executorLog.log(`${taskId}: keeping pre-execution worktree ${live.worktree} \u2014 it carries commits or uncommitted changes`);
|
|
230649
230575
|
return false;
|
|
@@ -230685,7 +230611,7 @@ ${info.feedback}`, revisionKey),
|
|
|
230685
230611
|
}
|
|
230686
230612
|
if (this.workspaceConfig && (this.workspaceConfig.repos.length ?? 0) > 0) return null;
|
|
230687
230613
|
const live = await this.store.getTask(taskId);
|
|
230688
|
-
if (live.worktree &&
|
|
230614
|
+
if (live.worktree && existsSync66(live.worktree)) return live.worktree;
|
|
230689
230615
|
const settings = await this.store.getSettings();
|
|
230690
230616
|
const acquisitionTask = live.worktree ? { ...live, worktree: void 0, sessionFile: void 0 } : live;
|
|
230691
230617
|
const acquired = await this.ensureGraphCustomNodeWorktree(acquisitionTask, settings, "planning");
|
|
@@ -230699,8 +230625,8 @@ ${info.feedback}`, revisionKey),
|
|
|
230699
230625
|
if (!requirement.requiresWorktree) return;
|
|
230700
230626
|
const live = await this.store.getTask(nodeTask.id);
|
|
230701
230627
|
const executionCodeNode = node.kind === "code";
|
|
230702
|
-
if (live.worktree &&
|
|
230703
|
-
const taskForAcquisition = live.worktree && !
|
|
230628
|
+
if (live.worktree && existsSync66(live.worktree) && !executionCodeNode) return;
|
|
230629
|
+
const taskForAcquisition = live.worktree && !existsSync66(live.worktree) ? { ...live, worktree: void 0, sessionFile: void 0 } : live;
|
|
230704
230630
|
if (live.worktree) {
|
|
230705
230631
|
await this.store.logEntry(
|
|
230706
230632
|
live.id,
|
|
@@ -230826,7 +230752,7 @@ ${info.feedback}`, revisionKey),
|
|
|
230826
230752
|
const nodeDisplayName = typeof cfg.name === "string" && cfg.name.trim() ? cfg.name.trim() : node.id;
|
|
230827
230753
|
const isPlanReviewNode = node.id === "plan-review-step" || nodeDisplayName === "Plan Review" || optionalGroupId === "plan-review";
|
|
230828
230754
|
if (!this.workspaceConfig) {
|
|
230829
|
-
const recordedWorktreeMissing = Boolean(executionTarget.worktree) && !
|
|
230755
|
+
const recordedWorktreeMissing = Boolean(executionTarget.worktree) && !existsSync66(executionTarget.worktree);
|
|
230830
230756
|
const shouldAcquire = !executionTarget.worktree || recordedWorktreeMissing && isPlanReviewNode;
|
|
230831
230757
|
if (shouldAcquire) {
|
|
230832
230758
|
if (recordedWorktreeMissing) {
|
|
@@ -232500,75 +232426,16 @@ Graph value: ${failureValue}` : ""}`, budget.key),
|
|
|
232500
232426
|
);
|
|
232501
232427
|
}
|
|
232502
232428
|
}
|
|
232503
|
-
/*
|
|
232504
|
-
FNXC:HonestBlockedExit 2026-08-02-01:30:
|
|
232505
|
-
Agents often log `BLOCKED: … actively claimed by PR #N` without calling fn_task_done.
|
|
232506
|
-
Without promotion, incomplete-step graph resume requeues the card and thrash restarts
|
|
232507
|
-
(FN-8700). Promote claim/external blocks to a durable failed park here.
|
|
232508
|
-
*/
|
|
232509
|
-
async parkDurableBlockedFromRecentLog(live) {
|
|
232510
|
-
const recent = [...live.log ?? []].reverse().find((entry) => {
|
|
232511
|
-
const action = entry.action ?? "";
|
|
232512
|
-
return action.startsWith("BLOCKED:") || action.includes("durable external block");
|
|
232513
|
-
});
|
|
232514
|
-
if (!recent?.action) return false;
|
|
232515
|
-
const reason = recent.action.startsWith("BLOCKED:") ? recent.action.slice("BLOCKED:".length).trim() : recent.action;
|
|
232516
|
-
const classification = classifyBlockedExit(reason, []);
|
|
232517
|
-
if (classification.allowAutoReplan) return false;
|
|
232518
|
-
const thrashCount = countBlockedThrashHits(live.log, classification.thrashSignature) + 1;
|
|
232519
|
-
const thrashExhausted = thrashCount >= BLOCKED_THRASH_LIMIT;
|
|
232520
|
-
const parkError = thrashExhausted ? `BLOCKED: ${reason} [thrash-exhausted after ${thrashCount} identical durable blocks]` : `BLOCKED: ${reason}`;
|
|
232521
|
-
const metaPatch = buildExternalBlockMetadataPatch(classification, thrashCount);
|
|
232522
|
-
await this.store.updateTask(live.id, {
|
|
232523
|
-
status: "failed",
|
|
232524
|
-
error: parkError,
|
|
232525
|
-
paused: false,
|
|
232526
|
-
pausedByAgentId: null,
|
|
232527
|
-
sourceMetadataPatch: metaPatch
|
|
232528
|
-
}, this.getRunContextFor(live.id));
|
|
232529
|
-
await this.store.logEntry(
|
|
232530
|
-
live.id,
|
|
232531
|
-
thrashExhausted ? `${parkError} \u2014 promoted from session log; thrash-exhausted, no auto-requeue` : `${parkError} \u2014 promoted from session log to durable external block park (class=${classification.class})`,
|
|
232532
|
-
void 0,
|
|
232533
|
-
this.getRunContextFor(live.id)
|
|
232534
|
-
);
|
|
232535
|
-
await this.store.recordRunAuditEvent?.({
|
|
232536
|
-
taskId: live.id,
|
|
232537
|
-
agentId: "executor",
|
|
232538
|
-
runId: generateSyntheticRunId("execution-blocked-log-promote", live.id),
|
|
232539
|
-
domain: "database",
|
|
232540
|
-
mutationType: "task:execution-blocked-parked",
|
|
232541
|
-
target: live.id,
|
|
232542
|
-
metadata: {
|
|
232543
|
-
taskId: live.id,
|
|
232544
|
-
blockedBy: [],
|
|
232545
|
-
hasReason: true,
|
|
232546
|
-
parkedAs: "failed",
|
|
232547
|
-
blockedClass: classification.class,
|
|
232548
|
-
thrashCount,
|
|
232549
|
-
thrashExhausted,
|
|
232550
|
-
prNumbers: classification.prNumbers,
|
|
232551
|
-
source: "session-log-promote"
|
|
232552
|
-
}
|
|
232553
|
-
});
|
|
232554
|
-
executorLog.warn(
|
|
232555
|
-
`${live.id}: promoted durable BLOCKED from session log (class=${classification.class}; thrash=${thrashCount})`
|
|
232556
|
-
);
|
|
232557
|
-
return true;
|
|
232558
|
-
}
|
|
232559
232429
|
async routeGraphFailureToExecutionResume(live, failedNode, failureValue, resumeLanesMemo) {
|
|
232560
232430
|
if (live.deletedAt) return false;
|
|
232561
232431
|
if (live.paused || live.userPaused === true) return false;
|
|
232562
232432
|
if ((await resolveTerminalColumnsFor(this.store, live.id)).includes(live.column)) return false;
|
|
232563
|
-
if (isDurableBlockedTask(live)
|
|
232433
|
+
if (isDurableBlockedTask(live)) {
|
|
232564
232434
|
executorLog.log(
|
|
232565
|
-
`${live.id}: graph failure resume skipped \u2014 durable BLOCKED park honored (
|
|
232435
|
+
`${live.id}: graph failure resume skipped \u2014 durable BLOCKED park honored (task-dependency block)`
|
|
232566
232436
|
);
|
|
232567
232437
|
return false;
|
|
232568
232438
|
}
|
|
232569
|
-
if (await this.parkDurableBlockedFromRecentLog(live)) {
|
|
232570
|
-
return false;
|
|
232571
|
-
}
|
|
232572
232439
|
if (failedNode === COMPLETION_SUMMARY_NODE_ID) return false;
|
|
232573
232440
|
const incompleteSteps = hasNonTerminalWorkflowSteps(live);
|
|
232574
232441
|
const implementationIncompleteMergeFailure = this.isMergeGraphFailure(failedNode) && failureValue === "implementation-incomplete";
|
|
@@ -233749,7 +233616,7 @@ ${summary}`,
|
|
|
233749
233616
|
executorLog.warn(`\u26A1 ${task.id} transient error \u2014 retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}: ${errorMessage5}`);
|
|
233750
233617
|
await this.store.logEntry(task.id, `Transient error (retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}): ${errorMessage5}`, void 0, this.getRunContextFor(task.id));
|
|
233751
233618
|
}
|
|
233752
|
-
if (worktreePath &&
|
|
233619
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
233753
233620
|
try {
|
|
233754
233621
|
const settings2 = await this.store.getSettings();
|
|
233755
233622
|
await removeWorktree({
|
|
@@ -233830,7 +233697,7 @@ ${summary}`,
|
|
|
233830
233697
|
const settings2 = await this.store.getSettings();
|
|
233831
233698
|
const preserveProgress = settings2.preserveProgressOnStuckRequeue !== false;
|
|
233832
233699
|
await this.resetStepsIfWorkLost(latestTask);
|
|
233833
|
-
if (worktreePath &&
|
|
233700
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
233834
233701
|
try {
|
|
233835
233702
|
await removeWorktree({
|
|
233836
233703
|
worktreePath,
|
|
@@ -234113,7 +233980,7 @@ ${summary}`,
|
|
|
234113
233980
|
nodeId: detail.effectiveNodeId ?? detail.nodeId ?? null,
|
|
234114
233981
|
agentId: engineRunContext.agentId ?? null
|
|
234115
233982
|
});
|
|
234116
|
-
let isResuming = !!task.sessionFile &&
|
|
233983
|
+
let isResuming = !!task.sessionFile && existsSync66(task.sessionFile);
|
|
234117
233984
|
if (isResuming) {
|
|
234118
233985
|
const persistedWorktreePath = await extractPersistedSessionWorktreePath(task.sessionFile, this.rootDir, settings);
|
|
234119
233986
|
if (!isSessionWorktreeCompatible(persistedWorktreePath, worktreePath)) {
|
|
@@ -234894,7 +234761,7 @@ ${summary}`,
|
|
|
234894
234761
|
return;
|
|
234895
234762
|
} else {
|
|
234896
234763
|
executorLog.log(`${task.id} paused \u2014 moving to todo`);
|
|
234897
|
-
if (worktreePath &&
|
|
234764
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
234898
234765
|
try {
|
|
234899
234766
|
const settings2 = await this.store.getSettings();
|
|
234900
234767
|
await removeWorktree({
|
|
@@ -235291,7 +235158,7 @@ ${summary}`,
|
|
|
235291
235158
|
executorLog.warn(`\u26A1 ${task.id} transient error \u2014 retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}: ${errorMessage5}`);
|
|
235292
235159
|
await this.store.logEntry(task.id, `Transient error (retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}): ${errorMessage5}`, void 0, this.getRunContextFor(task.id));
|
|
235293
235160
|
}
|
|
235294
|
-
if (worktreePath &&
|
|
235161
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
235295
235162
|
try {
|
|
235296
235163
|
const settings2 = await this.store.getSettings();
|
|
235297
235164
|
await removeWorktree({
|
|
@@ -235427,7 +235294,7 @@ ${summary}`,
|
|
|
235427
235294
|
const settings2 = await this.store.getSettings();
|
|
235428
235295
|
const preserveProgress = settings2.preserveProgressOnStuckRequeue !== false;
|
|
235429
235296
|
await this.resetStepsIfWorkLost(latestTask);
|
|
235430
|
-
if (worktreePath &&
|
|
235297
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
235431
235298
|
try {
|
|
235432
235299
|
await removeWorktree({
|
|
235433
235300
|
worktreePath,
|
|
@@ -235854,7 +235721,7 @@ ${summary}`,
|
|
|
235854
235721
|
for (const repoRel of Object.keys(workspaceWorktrees).sort()) {
|
|
235855
235722
|
const repo = workspaceWorktrees[repoRel];
|
|
235856
235723
|
const expectedBranch = repo.branch || canonicalFusionBranchName(task.id);
|
|
235857
|
-
if (!
|
|
235724
|
+
if (!existsSync66(repo.worktreePath)) {
|
|
235858
235725
|
executorLog.log(`${task.id}: workspace worktree for ${repoRel} not found at ${repo.worktreePath} \u2014 skipping git validation`);
|
|
235859
235726
|
continue;
|
|
235860
235727
|
}
|
|
@@ -235986,7 +235853,7 @@ ${summary}`,
|
|
|
235986
235853
|
expected: `resolvable task worktree under ${resolveWorktreesDir(this.rootDir, settings)}/*`
|
|
235987
235854
|
};
|
|
235988
235855
|
}
|
|
235989
|
-
if (!
|
|
235856
|
+
if (!existsSync66(worktreePath)) {
|
|
235990
235857
|
executorLog.log(
|
|
235991
235858
|
`${task.id}: worktree directory not found at ${worktreePath} \u2014 skipping git validation for task completion`
|
|
235992
235859
|
);
|
|
@@ -236315,10 +236182,10 @@ ${summary}`,
|
|
|
236315
236182
|
{ description: '"completed" (default) finishes the task; "blocked" honestly parks it as failed because the work cannot proceed. Use "blocked" instead of skipping steps + completing when you are stuck.' }
|
|
236316
236183
|
)),
|
|
236317
236184
|
blockedBy: Type7.Optional(Type7.Array(Type7.String(), {
|
|
236318
|
-
description: 'When outcome="blocked": task IDs (e.g. ["FN-8145"])
|
|
236185
|
+
description: 'When outcome="blocked": Fusion task IDs (e.g. ["FN-8145"]) that must complete before this task can proceed. Task IDs become real dependency edges. Open GitHub PRs are not valid blockers.'
|
|
236319
236186
|
})),
|
|
236320
236187
|
reason: Type7.Optional(Type7.String({
|
|
236321
|
-
description: 'Required when outcome="blocked": concrete explanation of what is blocking the work and what is needed to unblock it.
|
|
236188
|
+
description: 'Required when outcome="blocked": concrete explanation of what is blocking the work and what is needed to unblock it.'
|
|
236322
236189
|
}))
|
|
236323
236190
|
}),
|
|
236324
236191
|
execute: async (_id, params) => {
|
|
@@ -236377,7 +236244,7 @@ ${summary}`,
|
|
|
236377
236244
|
}, this.getRunContextFor(taskId));
|
|
236378
236245
|
await store.logEntry(
|
|
236379
236246
|
taskId,
|
|
236380
|
-
thrashExhausted ? `${parkError} \u2014 durable external block thrash-exhausted (signature=${classification.thrashSignature}); parked failed, no auto-requeue` :
|
|
236247
|
+
thrashExhausted ? `${parkError} \u2014 durable external block thrash-exhausted (signature=${classification.thrashSignature}); parked failed, no auto-requeue` : `${parkError} \u2014 recorded dependencies: ${blockedByIds.join(", ")} \u2014 parked failed (honest blocked exit; steps preserved)`,
|
|
236381
236248
|
void 0,
|
|
236382
236249
|
this.getRunContextFor(taskId)
|
|
236383
236250
|
);
|
|
@@ -236396,18 +236263,17 @@ ${summary}`,
|
|
|
236396
236263
|
parkedAs: autoReplanPark ? "auto-replan" : "failed",
|
|
236397
236264
|
blockedClass: classification.class,
|
|
236398
236265
|
thrashCount,
|
|
236399
|
-
thrashExhausted
|
|
236400
|
-
prNumbers: classification.prNumbers
|
|
236266
|
+
thrashExhausted
|
|
236401
236267
|
}
|
|
236402
236268
|
});
|
|
236403
236269
|
await this.persistTokenUsage(taskId);
|
|
236404
236270
|
executorLog.log(
|
|
236405
|
-
`\u26D4 ${taskId} ${autoReplanPark ? "parked for automatic replan via blocked exit (plan defect, no dependencies)" : thrashExhausted ? `parked failed via blocked thrash-exhaustion (class=${classification.class})` : `parked failed via durable blocked exit (class=${classification.class}; blockedBy tasks: ${blockedByIds.join(", ") || "none"}
|
|
236271
|
+
`\u26D4 ${taskId} ${autoReplanPark ? "parked for automatic replan via blocked exit (plan defect, no dependencies)" : thrashExhausted ? `parked failed via blocked thrash-exhaustion (class=${classification.class})` : `parked failed via durable blocked exit (class=${classification.class}; blockedBy tasks: ${blockedByIds.join(", ") || "none"})`}`
|
|
236406
236272
|
);
|
|
236407
236273
|
return {
|
|
236408
236274
|
content: [{
|
|
236409
236275
|
type: "text",
|
|
236410
|
-
text: autoReplanPark ? "Task parked as blocked with no
|
|
236276
|
+
text: autoReplanPark ? "Task parked as blocked with no blocking task dependencies \u2014 queued for automatic replan so the plan can resolve the conflict. Steps left in their true statuses; no completion recorded." : thrashExhausted ? "Task parked as blocked (failed) after repeated identical durable blocks \u2014 no further automatic retries. Resolve the blocking tasks or replan manually." : `Task parked as blocked (failed). Recorded ${blockedByIds.length} blocking task dependency(ies); it will requeue once they complete. Steps left in their true statuses; no completion recorded.`
|
|
236411
236277
|
}],
|
|
236412
236278
|
details: {}
|
|
236413
236279
|
};
|
|
@@ -238465,7 +238331,7 @@ ${detectedQuestion}
|
|
|
238465
238331
|
* rather than fail the task permanently.
|
|
238466
238332
|
*/
|
|
238467
238333
|
async resolveWorktreeStartPoint(startPoint, taskId) {
|
|
238468
|
-
const command = isAbsolute18(startPoint) &&
|
|
238334
|
+
const command = isAbsolute18(startPoint) && existsSync66(startPoint) ? `git -C "${startPoint}" rev-parse --verify HEAD^{commit}` : `git rev-parse --verify "${startPoint}^{commit}"`;
|
|
238469
238335
|
try {
|
|
238470
238336
|
const { stdout } = await execAsync36(command, { cwd: this.rootDir });
|
|
238471
238337
|
return stdout.trim() || startPoint;
|
|
@@ -238688,7 +238554,7 @@ ${detectedQuestion}
|
|
|
238688
238554
|
throw error3;
|
|
238689
238555
|
}
|
|
238690
238556
|
};
|
|
238691
|
-
if (
|
|
238557
|
+
if (existsSync66(path14)) {
|
|
238692
238558
|
const isRegistered = await this.isRegisteredWorktree(path14);
|
|
238693
238559
|
if (!isRegistered) {
|
|
238694
238560
|
await this.store.logEntry(
|
|
@@ -239304,7 +239170,7 @@ ${detectedQuestion}
|
|
|
239304
239170
|
const stillRegistered = await isRegisteredGitWorktree2(this.rootDir, worktreePath).catch(() => true);
|
|
239305
239171
|
const activeOwner2 = await this.findActiveWorktreeOwner(worktreePath, taskId).catch(() => "unknown");
|
|
239306
239172
|
let safeToRemove = isInsideWorktreesDir(this.rootDir, worktreePath, settings) && !stillRegistered && activeOwner2 === null;
|
|
239307
|
-
if (safeToRemove &&
|
|
239173
|
+
if (safeToRemove && existsSync66(worktreePath)) {
|
|
239308
239174
|
try {
|
|
239309
239175
|
if (lstatSync3(worktreePath).isSymbolicLink()) {
|
|
239310
239176
|
safeToRemove = false;
|
|
@@ -239332,7 +239198,7 @@ ${detectedQuestion}
|
|
|
239332
239198
|
const pruneMsg = pruneErr instanceof Error ? pruneErr.message : String(pruneErr);
|
|
239333
239199
|
executorLog.warn(`${taskId}: git worktree prune failed during stale-path cleanup of ${worktreePath}: ${pruneMsg}`);
|
|
239334
239200
|
}
|
|
239335
|
-
if (
|
|
239201
|
+
if (existsSync66(worktreePath)) {
|
|
239336
239202
|
try {
|
|
239337
239203
|
await rm12(worktreePath, { recursive: true, force: true });
|
|
239338
239204
|
} catch (rmErr) {
|
|
@@ -239779,7 +239645,7 @@ ${detectedQuestion}
|
|
|
239779
239645
|
this.clearPausedAborted(taskId);
|
|
239780
239646
|
await this.resetStepsIfWorkLost(latestTask);
|
|
239781
239647
|
let cleanupFailed = false;
|
|
239782
|
-
if (worktreePath &&
|
|
239648
|
+
if (worktreePath && existsSync66(worktreePath)) {
|
|
239783
239649
|
try {
|
|
239784
239650
|
await removeWorktree({
|
|
239785
239651
|
worktreePath,
|
|
@@ -243866,7 +243732,7 @@ var init_overseer_noop_finalize_veto = __esm({
|
|
|
243866
243732
|
|
|
243867
243733
|
// ../engine/src/merger-ai-worktree.ts
|
|
243868
243734
|
import { execFile as execFile27 } from "node:child_process";
|
|
243869
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
243735
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync67, mkdirSync as mkdirSync11, readdirSync as readdirSync12, readFileSync as readFileSync24, realpathSync as realpathSync11, rmSync as rmSync9, statSync as statSync13 } from "node:fs";
|
|
243870
243736
|
import { rm as rm13 } from "node:fs/promises";
|
|
243871
243737
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
243872
243738
|
import { isAbsolute as isAbsolute19, join as join79, relative as relative17 } from "node:path";
|
|
@@ -243901,7 +243767,7 @@ function isBenignAbsentWorktreeError(err) {
|
|
|
243901
243767
|
}
|
|
243902
243768
|
function ensureAiMergeRootIgnored(projectRootDir, settings) {
|
|
243903
243769
|
const excludePath = join79(projectRootDir, ".git", "info", "exclude");
|
|
243904
|
-
if (!
|
|
243770
|
+
if (!existsSync67(excludePath)) return;
|
|
243905
243771
|
try {
|
|
243906
243772
|
const current = readFileSync24(excludePath, "utf-8");
|
|
243907
243773
|
const legacyAiMergeRoot = resolveLegacyAiMergeRootPath(projectRootDir);
|
|
@@ -244032,7 +243898,7 @@ async function cleanupAiMergeWorktree(input) {
|
|
|
244032
243898
|
const cleanupMetadata = { taskId, mergeRoot: canonicalRoot, requestedMergeRoot: mergeRoot };
|
|
244033
243899
|
let alreadyAbsent = false;
|
|
244034
243900
|
if (worktreeAdded) {
|
|
244035
|
-
if (!
|
|
243901
|
+
if (!existsSync67(canonicalRoot) && !existsSync67(mergeRoot)) {
|
|
244036
243902
|
alreadyAbsent = true;
|
|
244037
243903
|
await log43(`AI merge cleanup: worktree ${canonicalRoot} was already absent before git removal; treating cleanup as idempotent`);
|
|
244038
243904
|
await audit.git({ type: "merge:ai-worktree-cleanup", target: canonicalRoot, metadata: { ...cleanupMetadata, phase: "git-remove", success: true, alreadyAbsent: true, idempotent: true, code: "ENOENT" } });
|
|
@@ -250354,12 +250220,12 @@ The note must be specific (what/where/why). Prefer citing File Scope, PROMPT, a
|
|
|
250354
250220
|
});
|
|
250355
250221
|
|
|
250356
250222
|
// ../engine/src/overseer-watchdog.ts
|
|
250357
|
-
import { existsSync as
|
|
250223
|
+
import { existsSync as existsSync68, readFileSync as readFileSync25 } from "node:fs";
|
|
250358
250224
|
import { dirname as dirname34, join as join82, relative as relative18, resolve as resolve40, sep as sep11 } from "node:path";
|
|
250359
250225
|
import { homedir as homedir12 } from "node:os";
|
|
250360
250226
|
function defaultReadText(path14) {
|
|
250361
250227
|
try {
|
|
250362
|
-
if (!
|
|
250228
|
+
if (!existsSync68(path14)) return null;
|
|
250363
250229
|
return readFileSync25(path14, "utf8");
|
|
250364
250230
|
} catch {
|
|
250365
250231
|
return null;
|
|
@@ -256160,7 +256026,7 @@ var init_adapters = __esm({
|
|
|
256160
256026
|
});
|
|
256161
256027
|
|
|
256162
256028
|
// ../engine/src/cli-agent/resume-coordinator.ts
|
|
256163
|
-
import { existsSync as
|
|
256029
|
+
import { existsSync as existsSync69 } from "node:fs";
|
|
256164
256030
|
import { execFile as execFile30 } from "node:child_process";
|
|
256165
256031
|
import { promisify as promisify62 } from "node:util";
|
|
256166
256032
|
async function defaultIsWorktreeDirty(worktreePath) {
|
|
@@ -256205,7 +256071,7 @@ var init_resume_coordinator = __esm({
|
|
|
256205
256071
|
this.reattachTelemetry = opts.reattachTelemetry;
|
|
256206
256072
|
this.maxResumeAttempts = opts.maxResumeAttempts ?? DEFAULT_MAX_RESUME_ATTEMPTS;
|
|
256207
256073
|
this.resumeBackoffBaseMs = opts.resumeBackoffBaseMs ?? DEFAULT_RESUME_BACKOFF_BASE_MS;
|
|
256208
|
-
this.worktreeExists = opts.worktreeExists ?? ((p2) =>
|
|
256074
|
+
this.worktreeExists = opts.worktreeExists ?? ((p2) => existsSync69(p2));
|
|
256209
256075
|
this.isWorktreeDirty = opts.isWorktreeDirty ?? defaultIsWorktreeDirty;
|
|
256210
256076
|
this.log = opts.log ?? (() => {
|
|
256211
256077
|
});
|
|
@@ -280583,11 +280449,11 @@ var init_task_lookup_error = __esm({
|
|
|
280583
280449
|
});
|
|
280584
280450
|
|
|
280585
280451
|
// ../dashboard/src/cli-package-version.ts
|
|
280586
|
-
import { existsSync as
|
|
280452
|
+
import { existsSync as existsSync70, readFileSync as readFileSync26 } from "node:fs";
|
|
280587
280453
|
import { dirname as dirname37, resolve as resolve43 } from "node:path";
|
|
280588
280454
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
280589
280455
|
function readPackageVersion(pkgPath, packageNames) {
|
|
280590
|
-
if (!
|
|
280456
|
+
if (!existsSync70(pkgPath)) {
|
|
280591
280457
|
return null;
|
|
280592
280458
|
}
|
|
280593
280459
|
try {
|
|
@@ -294043,7 +293909,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
|
|
|
294043
293909
|
};
|
|
294044
293910
|
router.get("/tasks/:id/stranded-refinement", async (req, res) => {
|
|
294045
293911
|
try {
|
|
294046
|
-
const { existsSync:
|
|
293912
|
+
const { existsSync: existsSync119 } = await import("node:fs");
|
|
294047
293913
|
const { join: join153 } = await import("node:path");
|
|
294048
293914
|
const { store: scopedStore } = await getProjectContext2(req);
|
|
294049
293915
|
const task = await scopedStore.getTask(req.params.id);
|
|
@@ -294062,7 +293928,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
|
|
|
294062
293928
|
ageMs: Math.max(0, Date.now() - Date.parse(task.createdAt))
|
|
294063
293929
|
};
|
|
294064
293930
|
const promptPath = join153(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
|
|
294065
|
-
const promptExists =
|
|
293931
|
+
const promptExists = existsSync119(promptPath);
|
|
294066
293932
|
const dependencyDetails = await Promise.all((task.dependencies ?? []).map(async (dependencyId) => {
|
|
294067
293933
|
try {
|
|
294068
293934
|
const depTask = await scopedStore.getTask(dependencyId);
|
|
@@ -298823,7 +298689,7 @@ __export(chat_exports, {
|
|
|
298823
298689
|
});
|
|
298824
298690
|
import { EventEmitter as EventEmitter40 } from "node:events";
|
|
298825
298691
|
import { randomUUID as randomUUID50 } from "node:crypto";
|
|
298826
|
-
import { existsSync as
|
|
298692
|
+
import { existsSync as existsSync71 } from "node:fs";
|
|
298827
298693
|
import { join as join90, resolve as resolve48, relative as relative20 } from "node:path";
|
|
298828
298694
|
import { SessionManager as SessionManager3 } from "@earendil-works/pi-coding-agent";
|
|
298829
298695
|
function __getChatDiagnostics() {
|
|
@@ -299030,7 +298896,7 @@ function createTaskVerificationTools(taskStore, actionGateContext) {
|
|
|
299030
298896
|
const profile = typeof raw.profile === "string" ? raw.profile : "verify:fast";
|
|
299031
298897
|
if (!taskId || !profiles.has(profile)) return { content: [{ type: "text", text: "ERROR: task_id and an allowlisted profile are required; raw commands are not accepted." }], isError: true, details: {} };
|
|
299032
298898
|
const task = await taskStore.getTask(taskId);
|
|
299033
|
-
if (!task || !(await wipColumnsForTask(taskStore, taskId)).has(task.column) || !task.worktree || !
|
|
298899
|
+
if (!task || !(await wipColumnsForTask(taskStore, taskId)).has(task.column) || !task.worktree || !existsSync71(task.worktree)) return { content: [{ type: "text", text: "ERROR: verification requires an in-progress task with a live executor worktree." }], isError: true, details: {} };
|
|
299034
298900
|
const settings = await taskStore.getSettings();
|
|
299035
298901
|
const command = profile === "verify:fast" ? "pnpm verify:fast" : typeof settings.testCommand === "string" ? settings.testCommand : "";
|
|
299036
298902
|
if (!command) return { content: [{ type: "text", text: "ERROR: the selected verification profile is not configured." }], isError: true, details: {} };
|
|
@@ -299861,7 +299727,7 @@ When you need structured input, or whenever you present options, choices, or a d
|
|
|
299861
299727
|
* keep the CLI session stable across user messages.
|
|
299862
299728
|
*/
|
|
299863
299729
|
async resolveCliSessionManager(session) {
|
|
299864
|
-
if (session.cliSessionFile &&
|
|
299730
|
+
if (session.cliSessionFile && existsSync71(session.cliSessionFile)) {
|
|
299865
299731
|
try {
|
|
299866
299732
|
return SessionManager3.open(session.cliSessionFile);
|
|
299867
299733
|
} catch (err) {
|
|
@@ -351746,7 +351612,7 @@ var init_cli_spawn = __esm({
|
|
|
351746
351612
|
// ../../plugins/fusion-plugin-hermes-runtime/src/fusion-skill-install.ts
|
|
351747
351613
|
import {
|
|
351748
351614
|
cpSync as cpSync2,
|
|
351749
|
-
existsSync as
|
|
351615
|
+
existsSync as existsSync73,
|
|
351750
351616
|
lstatSync as lstatSync4,
|
|
351751
351617
|
mkdirSync as mkdirSync13,
|
|
351752
351618
|
readFileSync as readFileSync28,
|
|
@@ -351776,7 +351642,7 @@ function getFusionSkillSourceCandidates(moduleUrl = import.meta.url) {
|
|
|
351776
351642
|
function resolveBundledFusionSkillSource() {
|
|
351777
351643
|
const candidates = getFusionSkillSourceCandidates();
|
|
351778
351644
|
for (const candidate of candidates) {
|
|
351779
|
-
if (
|
|
351645
|
+
if (existsSync73(join97(candidate, "SKILL.md"))) return candidate;
|
|
351780
351646
|
}
|
|
351781
351647
|
return null;
|
|
351782
351648
|
}
|
|
@@ -351794,7 +351660,7 @@ function installFusionSkillIntoHermesHome(options = {}) {
|
|
|
351794
351660
|
try {
|
|
351795
351661
|
mkdirSync13(dirname40(targetDir), { recursive: true });
|
|
351796
351662
|
let replaced = false;
|
|
351797
|
-
if (
|
|
351663
|
+
if (existsSync73(targetDir) || isBrokenSymlink(targetDir)) {
|
|
351798
351664
|
const stat20 = lstatSync4(targetDir);
|
|
351799
351665
|
if (stat20.isSymbolicLink()) {
|
|
351800
351666
|
const currentTarget = safeReadlink(targetDir);
|
|
@@ -351865,14 +351731,14 @@ function safeReadlink(path14) {
|
|
|
351865
351731
|
function isBrokenSymlink(path14) {
|
|
351866
351732
|
try {
|
|
351867
351733
|
const stat20 = lstatSync4(path14);
|
|
351868
|
-
return stat20.isSymbolicLink() && !
|
|
351734
|
+
return stat20.isSymbolicLink() && !existsSync73(path14);
|
|
351869
351735
|
} catch {
|
|
351870
351736
|
return false;
|
|
351871
351737
|
}
|
|
351872
351738
|
}
|
|
351873
351739
|
function looksLikePriorFusionInstall(path14) {
|
|
351874
351740
|
const skillMd = join97(path14, "SKILL.md");
|
|
351875
|
-
if (!
|
|
351741
|
+
if (!existsSync73(skillMd)) return false;
|
|
351876
351742
|
try {
|
|
351877
351743
|
const body = readFileSync28(skillMd, "utf-8");
|
|
351878
351744
|
return /\bfusion\b/i.test(body) && /\bskill\b/i.test(body);
|
|
@@ -351883,7 +351749,7 @@ function looksLikePriorFusionInstall(path14) {
|
|
|
351883
351749
|
function looksLikeFusionSkillTarget(path14) {
|
|
351884
351750
|
if (!path14) return false;
|
|
351885
351751
|
if (basename28(path14).toLowerCase() === FUSION_SKILL_NAME) return true;
|
|
351886
|
-
return
|
|
351752
|
+
return existsSync73(join97(path14, "SKILL.md"));
|
|
351887
351753
|
}
|
|
351888
351754
|
var FUSION_SKILL_NAME;
|
|
351889
351755
|
var init_fusion_skill_install = __esm({
|
|
@@ -354906,7 +354772,7 @@ var init_provider2 = __esm({
|
|
|
354906
354772
|
});
|
|
354907
354773
|
|
|
354908
354774
|
// ../../plugins/fusion-plugin-grok-runtime/src/acp/cli-spawn.ts
|
|
354909
|
-
import { existsSync as
|
|
354775
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
354910
354776
|
import { dirname as dirname42, isAbsolute as isAbsolute28, join as join101, resolve as resolve59 } from "node:path";
|
|
354911
354777
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
354912
354778
|
function asTrimmedString(value) {
|
|
@@ -354929,7 +354795,7 @@ function bundledClaudeBridgeBinPath(pluginRoot = pluginRootDir()) {
|
|
|
354929
354795
|
}
|
|
354930
354796
|
function resolveBundledClaudeBridgeBinary(options = {}) {
|
|
354931
354797
|
const root = options.pluginRoot ?? pluginRootDir();
|
|
354932
|
-
const exists2 = options.exists ??
|
|
354798
|
+
const exists2 = options.exists ?? existsSync75;
|
|
354933
354799
|
const candidate = bundledClaudeBridgeBinPath(root);
|
|
354934
354800
|
if (!exists2(candidate)) {
|
|
354935
354801
|
return {
|
|
@@ -356278,7 +356144,7 @@ var init_mcp_forwarding = __esm({
|
|
|
356278
356144
|
// ../../plugins/fusion-plugin-grok-runtime/src/skill-loader.ts
|
|
356279
356145
|
import {
|
|
356280
356146
|
cpSync as cpSync3,
|
|
356281
|
-
existsSync as
|
|
356147
|
+
existsSync as existsSync76,
|
|
356282
356148
|
mkdirSync as mkdirSync14,
|
|
356283
356149
|
mkdtempSync as mkdtempSync3,
|
|
356284
356150
|
readdirSync as readdirSync14,
|
|
@@ -356291,7 +356157,7 @@ import { tmpdir as tmpdir16 } from "node:os";
|
|
|
356291
356157
|
import { basename as basename30, dirname as dirname44, join as join103, resolve as resolve61 } from "node:path";
|
|
356292
356158
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
356293
356159
|
function isSkillDir(dir2) {
|
|
356294
|
-
return
|
|
356160
|
+
return existsSync76(join103(dir2, "SKILL.md"));
|
|
356295
356161
|
}
|
|
356296
356162
|
function pushUnique(out, candidate) {
|
|
356297
356163
|
if (!candidate) return;
|
|
@@ -356355,7 +356221,7 @@ function resolveBundledFusionSkillSource2(moduleUrl = import.meta.url) {
|
|
|
356355
356221
|
function installSkillDir(sourceDir, targetDir) {
|
|
356356
356222
|
if (!isSkillDir(sourceDir)) return false;
|
|
356357
356223
|
mkdirSync14(dirname44(targetDir), { recursive: true });
|
|
356358
|
-
if (
|
|
356224
|
+
if (existsSync76(targetDir)) {
|
|
356359
356225
|
rmSync11(targetDir, { recursive: true, force: true });
|
|
356360
356226
|
}
|
|
356361
356227
|
try {
|
|
@@ -356371,7 +356237,7 @@ function installSkillDir(sourceDir, targetDir) {
|
|
|
356371
356237
|
}
|
|
356372
356238
|
}
|
|
356373
356239
|
function collectSkillsFromRoot(root, out) {
|
|
356374
|
-
if (!
|
|
356240
|
+
if (!existsSync76(root)) return;
|
|
356375
356241
|
if (isSkillDir(root)) {
|
|
356376
356242
|
out.set(basename30(root), root);
|
|
356377
356243
|
return;
|
|
@@ -356410,7 +356276,7 @@ function stageGrokSessionSkills(options = {}) {
|
|
|
356410
356276
|
installSkillDir(source, join103(skillsDir, name2));
|
|
356411
356277
|
}
|
|
356412
356278
|
for (const [name2, source] of installed) {
|
|
356413
|
-
if (!
|
|
356279
|
+
if (!existsSync76(join103(skillsDir, name2))) {
|
|
356414
356280
|
installSkillDir(source, join103(skillsDir, name2));
|
|
356415
356281
|
}
|
|
356416
356282
|
}
|
|
@@ -356479,7 +356345,7 @@ var init_skill_loader = __esm({
|
|
|
356479
356345
|
|
|
356480
356346
|
// ../../plugins/fusion-plugin-grok-runtime/src/tool-bridge.ts
|
|
356481
356347
|
import { createServer as createServer2 } from "node:http";
|
|
356482
|
-
import { existsSync as
|
|
356348
|
+
import { existsSync as existsSync77, writeFileSync as writeFileSync15 } from "node:fs";
|
|
356483
356349
|
import { tmpdir as tmpdir17 } from "node:os";
|
|
356484
356350
|
import { dirname as dirname45, join as join104 } from "node:path";
|
|
356485
356351
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
@@ -356525,7 +356391,7 @@ async function startFusionToolBridge(tools) {
|
|
|
356525
356391
|
const defs = toolsToMcpToolDefs2(tools);
|
|
356526
356392
|
if (defs.length === 0) return null;
|
|
356527
356393
|
const serverPath = fusionToolsMcpServerPath();
|
|
356528
|
-
if (!
|
|
356394
|
+
if (!existsSync77(serverPath)) {
|
|
356529
356395
|
throw missingMcpSchemaServerError(serverPath);
|
|
356530
356396
|
}
|
|
356531
356397
|
const byName = /* @__PURE__ */ new Map();
|
|
@@ -356966,7 +356832,7 @@ var init_src11 = __esm({
|
|
|
356966
356832
|
});
|
|
356967
356833
|
|
|
356968
356834
|
// ../../plugins/fusion-plugin-claude-runtime/src/acp/cli-spawn.ts
|
|
356969
|
-
import { existsSync as
|
|
356835
|
+
import { existsSync as existsSync78 } from "node:fs";
|
|
356970
356836
|
import { dirname as dirname46, isAbsolute as isAbsolute29, join as join105, resolve as resolve62 } from "node:path";
|
|
356971
356837
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
356972
356838
|
function asTrimmedString2(value) {
|
|
@@ -356989,7 +356855,7 @@ function bundledClaudeBridgeBinPath2(pluginRoot = pluginRootDir2()) {
|
|
|
356989
356855
|
}
|
|
356990
356856
|
function resolveBundledClaudeBridgeBinary2(options = {}) {
|
|
356991
356857
|
const root = options.pluginRoot ?? pluginRootDir2();
|
|
356992
|
-
const exists2 = options.exists ??
|
|
356858
|
+
const exists2 = options.exists ?? existsSync78;
|
|
356993
356859
|
const candidate = bundledClaudeBridgeBinPath2(root);
|
|
356994
356860
|
if (!exists2(candidate)) {
|
|
356995
356861
|
return {
|
|
@@ -358224,7 +358090,7 @@ var init_acp2 = __esm({
|
|
|
358224
358090
|
|
|
358225
358091
|
// ../../plugins/fusion-plugin-claude-runtime/src/cli-spawn.ts
|
|
358226
358092
|
import { spawn as spawn21 } from "node:child_process";
|
|
358227
|
-
import { existsSync as
|
|
358093
|
+
import { existsSync as existsSync79 } from "node:fs";
|
|
358228
358094
|
import { basename as basename32, dirname as dirname48, isAbsolute as isAbsolute30, join as join107, resolve as resolve64 } from "node:path";
|
|
358229
358095
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
358230
358096
|
function pluginRootDir3() {
|
|
@@ -358236,7 +358102,7 @@ function bundledClaudeBridgeBinPath3(pluginRoot = pluginRootDir3()) {
|
|
|
358236
358102
|
}
|
|
358237
358103
|
function resolveBundledClaudeBridgeBinary3(options = {}) {
|
|
358238
358104
|
const candidate = bundledClaudeBridgeBinPath3(options.pluginRoot ?? pluginRootDir3());
|
|
358239
|
-
const exists2 = options.exists ??
|
|
358105
|
+
const exists2 = options.exists ?? existsSync79;
|
|
358240
358106
|
if (!exists2(candidate) || !isAbsolute30(candidate)) return { kind: "not_resolved", requested: CLAUDE_CODE_CLI_ACP_BINARY3, path: candidate, reason: `Staged ${CLAUDE_CODE_CLI_ACP_BINARY3} bridge was not found at ${candidate}` };
|
|
358241
358107
|
return { kind: "resolved", requested: CLAUDE_CODE_CLI_ACP_BINARY3, path: candidate };
|
|
358242
358108
|
}
|
|
@@ -358399,7 +358265,7 @@ var init_mcp_forwarding2 = __esm({
|
|
|
358399
358265
|
// ../../plugins/fusion-plugin-claude-runtime/src/skill-loader.ts
|
|
358400
358266
|
import {
|
|
358401
358267
|
cpSync as cpSync4,
|
|
358402
|
-
existsSync as
|
|
358268
|
+
existsSync as existsSync80,
|
|
358403
358269
|
mkdirSync as mkdirSync15,
|
|
358404
358270
|
mkdtempSync as mkdtempSync4,
|
|
358405
358271
|
readdirSync as readdirSync15,
|
|
@@ -358412,7 +358278,7 @@ import { tmpdir as tmpdir18 } from "node:os";
|
|
|
358412
358278
|
import { basename as basename33, dirname as dirname49, join as join108, resolve as resolve65 } from "node:path";
|
|
358413
358279
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
358414
358280
|
function isSkillDir2(dir2) {
|
|
358415
|
-
return
|
|
358281
|
+
return existsSync80(join108(dir2, "SKILL.md"));
|
|
358416
358282
|
}
|
|
358417
358283
|
function pushUnique2(out, candidate) {
|
|
358418
358284
|
if (!candidate) return;
|
|
@@ -358476,7 +358342,7 @@ function resolveBundledFusionSkillSource3(moduleUrl = import.meta.url) {
|
|
|
358476
358342
|
function installSkillDir2(sourceDir, targetDir) {
|
|
358477
358343
|
if (!isSkillDir2(sourceDir)) return false;
|
|
358478
358344
|
mkdirSync15(dirname49(targetDir), { recursive: true });
|
|
358479
|
-
if (
|
|
358345
|
+
if (existsSync80(targetDir)) {
|
|
358480
358346
|
rmSync12(targetDir, { recursive: true, force: true });
|
|
358481
358347
|
}
|
|
358482
358348
|
try {
|
|
@@ -358492,7 +358358,7 @@ function installSkillDir2(sourceDir, targetDir) {
|
|
|
358492
358358
|
}
|
|
358493
358359
|
}
|
|
358494
358360
|
function collectSkillsFromRoot2(root, out) {
|
|
358495
|
-
if (!
|
|
358361
|
+
if (!existsSync80(root)) return;
|
|
358496
358362
|
if (isSkillDir2(root)) {
|
|
358497
358363
|
out.set(basename33(root), root);
|
|
358498
358364
|
return;
|
|
@@ -358531,7 +358397,7 @@ function stageClaudeSessionSkills(options = {}) {
|
|
|
358531
358397
|
installSkillDir2(source, join108(skillsDir, name2));
|
|
358532
358398
|
}
|
|
358533
358399
|
for (const [name2, source] of installed) {
|
|
358534
|
-
if (!
|
|
358400
|
+
if (!existsSync80(join108(skillsDir, name2))) {
|
|
358535
358401
|
installSkillDir2(source, join108(skillsDir, name2));
|
|
358536
358402
|
}
|
|
358537
358403
|
}
|
|
@@ -358600,7 +358466,7 @@ var init_skill_loader2 = __esm({
|
|
|
358600
358466
|
|
|
358601
358467
|
// ../../plugins/fusion-plugin-claude-runtime/src/tool-bridge.ts
|
|
358602
358468
|
import { createServer as createServer3 } from "node:http";
|
|
358603
|
-
import { existsSync as
|
|
358469
|
+
import { existsSync as existsSync81, rmSync as rmSync13, writeFileSync as writeFileSync17 } from "node:fs";
|
|
358604
358470
|
import { tmpdir as tmpdir19 } from "node:os";
|
|
358605
358471
|
import { dirname as dirname50, join as join109 } from "node:path";
|
|
358606
358472
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
@@ -358646,7 +358512,7 @@ async function startFusionToolBridge2(tools, options = {}) {
|
|
|
358646
358512
|
const defs = toolsToMcpToolDefs3(tools);
|
|
358647
358513
|
if (defs.length === 0) return null;
|
|
358648
358514
|
const serverPath = fusionToolsMcpServerPath2();
|
|
358649
|
-
if (!
|
|
358515
|
+
if (!existsSync81(serverPath)) {
|
|
358650
358516
|
throw missingMcpSchemaServerError2(serverPath);
|
|
358651
358517
|
}
|
|
358652
358518
|
const byName = /* @__PURE__ */ new Map();
|
|
@@ -359458,7 +359324,7 @@ var init_provider6 = __esm({
|
|
|
359458
359324
|
});
|
|
359459
359325
|
|
|
359460
359326
|
// ../../plugins/fusion-plugin-omp-runtime/src/acp/cli-spawn.ts
|
|
359461
|
-
import { existsSync as
|
|
359327
|
+
import { existsSync as existsSync82 } from "node:fs";
|
|
359462
359328
|
import { dirname as dirname51, isAbsolute as isAbsolute31, join as join110, resolve as resolve66 } from "node:path";
|
|
359463
359329
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
359464
359330
|
function asTrimmedString3(value) {
|
|
@@ -359481,7 +359347,7 @@ function bundledClaudeBridgeBinPath4(pluginRoot = pluginRootDir4()) {
|
|
|
359481
359347
|
}
|
|
359482
359348
|
function resolveBundledClaudeBridgeBinary4(options = {}) {
|
|
359483
359349
|
const root = options.pluginRoot ?? pluginRootDir4();
|
|
359484
|
-
const exists2 = options.exists ??
|
|
359350
|
+
const exists2 = options.exists ?? existsSync82;
|
|
359485
359351
|
const candidate = bundledClaudeBridgeBinPath4(root);
|
|
359486
359352
|
if (!exists2(candidate)) {
|
|
359487
359353
|
return {
|
|
@@ -360793,7 +360659,7 @@ var init_mcp_forwarding3 = __esm({
|
|
|
360793
360659
|
|
|
360794
360660
|
// ../../plugins/fusion-plugin-omp-runtime/src/tool-bridge.ts
|
|
360795
360661
|
import { createServer as createServer4 } from "node:http";
|
|
360796
|
-
import { existsSync as
|
|
360662
|
+
import { existsSync as existsSync83, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
|
|
360797
360663
|
import { tmpdir as tmpdir20 } from "node:os";
|
|
360798
360664
|
import { dirname as dirname53, join as join112 } from "node:path";
|
|
360799
360665
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
@@ -360820,7 +360686,7 @@ function fusionToolsMcpServerPath3() {
|
|
|
360820
360686
|
join112(here, "..", "mcp-schema-server.cjs")
|
|
360821
360687
|
];
|
|
360822
360688
|
for (const candidate of candidates) {
|
|
360823
|
-
if (
|
|
360689
|
+
if (existsSync83(candidate)) return candidate;
|
|
360824
360690
|
}
|
|
360825
360691
|
return null;
|
|
360826
360692
|
}
|
|
@@ -360958,7 +360824,7 @@ var init_tool_bridge3 = __esm({
|
|
|
360958
360824
|
});
|
|
360959
360825
|
|
|
360960
360826
|
// ../../plugins/fusion-plugin-omp-runtime/src/runtime-adapter.ts
|
|
360961
|
-
import { existsSync as
|
|
360827
|
+
import { existsSync as existsSync84 } from "node:fs";
|
|
360962
360828
|
function compactDiagnostic3(value) {
|
|
360963
360829
|
return value.replace(/\s+/g, " ").trim();
|
|
360964
360830
|
}
|
|
@@ -361149,7 +361015,7 @@ var init_runtime_adapter9 = __esm({
|
|
|
361149
361015
|
const command = server.command.trim();
|
|
361150
361016
|
if (!command) return false;
|
|
361151
361017
|
if (command.includes("/") || command.includes("\\")) {
|
|
361152
|
-
return
|
|
361018
|
+
return existsSync84(command);
|
|
361153
361019
|
}
|
|
361154
361020
|
return true;
|
|
361155
361021
|
});
|
|
@@ -368063,7 +367929,7 @@ var init_auth_provider_catalog = __esm({
|
|
|
368063
367929
|
// ../dashboard/src/routes/register-auth-routes.ts
|
|
368064
367930
|
import { tmpdir as tmpdir21 } from "node:os";
|
|
368065
367931
|
import { join as join116 } from "node:path";
|
|
368066
|
-
import { existsSync as
|
|
367932
|
+
import { existsSync as existsSync85, readFileSync as readFileSync29 } from "node:fs";
|
|
368067
367933
|
function parseGitHubCopilotDeviceCode(instructions) {
|
|
368068
367934
|
const match = instructions.match(/Enter code:\s*([A-Z0-9-]+)\b/i);
|
|
368069
367935
|
return match?.[1];
|
|
@@ -368821,7 +368687,7 @@ var init_register_auth_routes = __esm({
|
|
|
368821
368687
|
let acpAuthReason;
|
|
368822
368688
|
try {
|
|
368823
368689
|
const signalPath = join116(tmpdir21(), "fusion-acp-bridge-auth.json");
|
|
368824
|
-
if (
|
|
368690
|
+
if (existsSync85(signalPath)) {
|
|
368825
368691
|
const sig = JSON.parse(readFileSync29(signalPath, "utf8"));
|
|
368826
368692
|
if (sig?.authFailed) {
|
|
368827
368693
|
acpAuthFailed = true;
|
|
@@ -370920,7 +370786,7 @@ import { spawn as spawn27 } from "node:child_process";
|
|
|
370920
370786
|
import {
|
|
370921
370787
|
chmodSync as chmodSync4,
|
|
370922
370788
|
cpSync as cpSync5,
|
|
370923
|
-
existsSync as
|
|
370789
|
+
existsSync as existsSync86,
|
|
370924
370790
|
lstatSync as lstatSync5,
|
|
370925
370791
|
mkdirSync as mkdirSync16,
|
|
370926
370792
|
readlinkSync as readlinkSync3,
|
|
@@ -371035,20 +370901,20 @@ function runStreamingCommand(command, args, options) {
|
|
|
371035
370901
|
function resolveBunExecutable() {
|
|
371036
370902
|
if (process.env.BUN_INSTALL) {
|
|
371037
370903
|
const candidate = join119(process.env.BUN_INSTALL, "bin", process.platform === "win32" ? "bun.exe" : "bun");
|
|
371038
|
-
if (
|
|
370904
|
+
if (existsSync86(candidate)) return candidate;
|
|
371039
370905
|
}
|
|
371040
370906
|
const homeBun = join119(homedir19(), ".bun", "bin", process.platform === "win32" ? "bun.exe" : "bun");
|
|
371041
|
-
if (
|
|
370907
|
+
if (existsSync86(homeBun)) return homeBun;
|
|
371042
370908
|
return "bun";
|
|
371043
370909
|
}
|
|
371044
370910
|
function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths()) {
|
|
371045
370911
|
const srcBinary = join119(distDir, process.platform === "win32" ? "fn.exe" : "fn");
|
|
371046
370912
|
const srcClient = join119(distDir, "client");
|
|
371047
370913
|
const srcRuntime = join119(distDir, "runtime");
|
|
371048
|
-
if (!
|
|
370914
|
+
if (!existsSync86(srcBinary)) {
|
|
371049
370915
|
throw new Error(`Built binary missing at ${srcBinary}. Did the Bun compile step fail?`);
|
|
371050
370916
|
}
|
|
371051
|
-
if (!
|
|
370917
|
+
if (!existsSync86(srcClient)) {
|
|
371052
370918
|
throw new Error(`Dashboard client assets missing at ${srcClient}.`);
|
|
371053
370919
|
}
|
|
371054
370920
|
mkdirSync16(paths2.installDir, { recursive: true });
|
|
@@ -371062,14 +370928,14 @@ function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths
|
|
|
371062
370928
|
onLog("system", `Installing client assets \u2192 ${join119(paths2.installDir, "client")}`);
|
|
371063
370929
|
rmSync14(join119(paths2.installDir, "client"), { recursive: true, force: true });
|
|
371064
370930
|
cpSync5(srcClient, join119(paths2.installDir, "client"), { recursive: true });
|
|
371065
|
-
if (
|
|
370931
|
+
if (existsSync86(srcRuntime)) {
|
|
371066
370932
|
onLog("system", `Installing runtime assets \u2192 ${join119(paths2.installDir, "runtime")}`);
|
|
371067
370933
|
rmSync14(join119(paths2.installDir, "runtime"), { recursive: true, force: true });
|
|
371068
370934
|
cpSync5(srcRuntime, join119(paths2.installDir, "runtime"), { recursive: true });
|
|
371069
370935
|
}
|
|
371070
370936
|
for (const shim of [paths2.fnShimPath, paths2.fusionShimPath]) {
|
|
371071
370937
|
try {
|
|
371072
|
-
if (
|
|
370938
|
+
if (existsSync86(shim) || isSymlink(shim)) {
|
|
371073
370939
|
unlinkSync6(shim);
|
|
371074
370940
|
}
|
|
371075
370941
|
} catch {
|
|
@@ -371091,7 +370957,7 @@ function removeLocalFnShims(onLog, paths2 = resolveFnBinaryLocalPaths()) {
|
|
|
371091
370957
|
const installReal = resolve69(paths2.binaryPath);
|
|
371092
370958
|
for (const shim of [paths2.fnShimPath, paths2.fusionShimPath]) {
|
|
371093
370959
|
try {
|
|
371094
|
-
if (!
|
|
370960
|
+
if (!existsSync86(shim) && !isSymlink(shim)) {
|
|
371095
370961
|
onLog("system", `No shim at ${shim}`);
|
|
371096
370962
|
continue;
|
|
371097
370963
|
}
|
|
@@ -371123,10 +370989,10 @@ async function runLinkLocalFnBinary(sourceRoot, onLog) {
|
|
|
371123
370989
|
const buildScript = join119(sourceRoot, "scripts", "build-workspace.mjs");
|
|
371124
370990
|
const cliBuild = join119(sourceRoot, "packages", "cli", "build.ts");
|
|
371125
370991
|
const distDir = join119(sourceRoot, "packages", "cli", "dist");
|
|
371126
|
-
if (!
|
|
370992
|
+
if (!existsSync86(buildScript)) {
|
|
371127
370993
|
return { success: false, error: `Build script missing: ${buildScript}` };
|
|
371128
370994
|
}
|
|
371129
|
-
if (!
|
|
370995
|
+
if (!existsSync86(cliBuild)) {
|
|
371130
370996
|
return { success: false, error: `CLI build entry missing: ${cliBuild}` };
|
|
371131
370997
|
}
|
|
371132
370998
|
onLog("system", "Step 1/3 \u2014 full workspace package build\u2026");
|
|
@@ -371202,7 +371068,7 @@ var init_fn_binary_local_install = __esm({
|
|
|
371202
371068
|
|
|
371203
371069
|
// ../dashboard/src/routes/register-system-routes.ts
|
|
371204
371070
|
import { randomUUID as randomUUID66 } from "node:crypto";
|
|
371205
|
-
import { existsSync as
|
|
371071
|
+
import { existsSync as existsSync87 } from "node:fs";
|
|
371206
371072
|
import { join as join120 } from "node:path";
|
|
371207
371073
|
function rejectCrossOrigin(req, res) {
|
|
371208
371074
|
const origin = req.headers.origin;
|
|
@@ -371394,7 +371260,7 @@ function registerSystemRoutes(ctx, deps) {
|
|
|
371394
371260
|
const restartAfter = body.restart !== false && scope !== "plugins";
|
|
371395
371261
|
const { args, label } = rebuildScopes[scope];
|
|
371396
371262
|
const scriptPath = join120(root, args[0]);
|
|
371397
|
-
if (!
|
|
371263
|
+
if (!existsSync87(scriptPath)) {
|
|
371398
371264
|
throw new ApiError(409, `Build script missing: ${scriptPath}`);
|
|
371399
371265
|
}
|
|
371400
371266
|
const job = {
|
|
@@ -382634,7 +382500,7 @@ var init_reliability_metrics = __esm({
|
|
|
382634
382500
|
});
|
|
382635
382501
|
|
|
382636
382502
|
// ../dashboard/src/view-chunk-manifest.ts
|
|
382637
|
-
import { existsSync as
|
|
382503
|
+
import { existsSync as existsSync88, readFileSync as readFileSync31, statSync as statSync15 } from "node:fs";
|
|
382638
382504
|
import { join as join124, resolve as resolve73 } from "node:path";
|
|
382639
382505
|
function warnOnce(set, key, message) {
|
|
382640
382506
|
if (set.has(key)) {
|
|
@@ -382656,7 +382522,7 @@ function loadViewChunkManifest(clientDir) {
|
|
|
382656
382522
|
if (cached2 && cached2.mtimeMs === mtimeMs) {
|
|
382657
382523
|
return cached2.entries;
|
|
382658
382524
|
}
|
|
382659
|
-
if (!
|
|
382525
|
+
if (!existsSync88(manifestPath)) {
|
|
382660
382526
|
warnOnce(warnedMissingManifest, cacheKey, `[dashboard] View chunk manifest missing: ${manifestPath}`);
|
|
382661
382527
|
const empty = {};
|
|
382662
382528
|
manifestCache.set(cacheKey, { entries: empty, mtimeMs });
|
|
@@ -383234,7 +383100,7 @@ var init_provider_health_monitor = __esm({
|
|
|
383234
383100
|
import express3 from "express";
|
|
383235
383101
|
import { randomUUID as randomUUID67 } from "node:crypto";
|
|
383236
383102
|
import { join as join125, dirname as dirname57 } from "node:path";
|
|
383237
|
-
import { existsSync as
|
|
383103
|
+
import { existsSync as existsSync89, readFileSync as readFileSync32, statSync as statSync16 } from "node:fs";
|
|
383238
383104
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
383239
383105
|
import { createSecureServer as createHttp2SecureServer } from "node:http2";
|
|
383240
383106
|
import { WebSocketServer as WebSocketServer2 } from "ws";
|
|
@@ -383556,7 +383422,7 @@ function createServer5(store, options) {
|
|
|
383556
383422
|
getTerminalService(store.getRootDir());
|
|
383557
383423
|
const isHeadless = options?.headless === true;
|
|
383558
383424
|
const execDir = dirname57(process.execPath);
|
|
383559
|
-
const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR :
|
|
383425
|
+
const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync89(join125(execDir, "client", "index.html")) ? join125(execDir, "client") : existsSync89(join125(__dirname2, "..", "dist", "client")) ? join125(__dirname2, "..", "dist", "client") : join125(__dirname2, "..", "client");
|
|
383560
383426
|
let cachedIndexClientDir = null;
|
|
383561
383427
|
let cachedIndexHtml = null;
|
|
383562
383428
|
let cachedIndexMtimeMs = null;
|
|
@@ -383611,7 +383477,7 @@ ${injection}`) : cachedIndexHtml.replace("</head>", `${injection}</head>`);
|
|
|
383611
383477
|
}
|
|
383612
383478
|
});
|
|
383613
383479
|
});
|
|
383614
|
-
if (
|
|
383480
|
+
if (existsSync89(join125(clientDir, "index.html"))) {
|
|
383615
383481
|
app.get(["/", "/index.html"], serveIndexHtml);
|
|
383616
383482
|
app.use(express3.static(clientDir, { index: false }));
|
|
383617
383483
|
}
|
|
@@ -385670,7 +385536,7 @@ var init_src15 = __esm({
|
|
|
385670
385536
|
import { Type as Type9 } from "typebox";
|
|
385671
385537
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
385672
385538
|
import { resolve as resolve75, relative as relative25, isAbsolute as isAbsolute33, sep as sep22, basename as basename36, extname as extname5, join as join127 } from "node:path";
|
|
385673
|
-
import { existsSync as
|
|
385539
|
+
import { existsSync as existsSync90 } from "node:fs";
|
|
385674
385540
|
import { AsyncLocalStorage as AsyncLocalStorage8 } from "node:async_hooks";
|
|
385675
385541
|
function resolveProjectRoot2(cwd) {
|
|
385676
385542
|
const worktreeProjectRoot = typeof getProjectRootFromWorktree === "function" ? getProjectRootFromWorktree(cwd) : null;
|
|
@@ -385678,12 +385544,12 @@ function resolveProjectRoot2(cwd) {
|
|
|
385678
385544
|
warnedMissingProjectRootResolver = true;
|
|
385679
385545
|
console.warn("[fusion-extension] @fusion/core.getProjectRootFromWorktree is unavailable; using filesystem fallback resolution.");
|
|
385680
385546
|
}
|
|
385681
|
-
if (worktreeProjectRoot &&
|
|
385547
|
+
if (worktreeProjectRoot && existsSync90(join127(worktreeProjectRoot, ".fusion"))) {
|
|
385682
385548
|
return worktreeProjectRoot;
|
|
385683
385549
|
}
|
|
385684
385550
|
let current = resolve75(cwd);
|
|
385685
385551
|
while (true) {
|
|
385686
|
-
if (
|
|
385552
|
+
if (existsSync90(join127(current, ".fusion"))) {
|
|
385687
385553
|
return current;
|
|
385688
385554
|
}
|
|
385689
385555
|
const parent2 = resolve75(current, "..");
|
|
@@ -386568,7 +386434,7 @@ var init_migration_holding_server = __esm({
|
|
|
386568
386434
|
|
|
386569
386435
|
// src/commands/ensure-project-registered.ts
|
|
386570
386436
|
import { exec as exec49 } from "node:child_process";
|
|
386571
|
-
import { existsSync as
|
|
386437
|
+
import { existsSync as existsSync91, mkdirSync as mkdirSync17 } from "node:fs";
|
|
386572
386438
|
import { basename as basename37, join as join128 } from "node:path";
|
|
386573
386439
|
import { promisify as promisify74 } from "node:util";
|
|
386574
386440
|
function stampProjectIdentityBestEffort(cwd, project, logPrefix) {
|
|
@@ -386596,7 +386462,7 @@ async function ensureCwdProjectRegistered(options) {
|
|
|
386596
386462
|
}
|
|
386597
386463
|
try {
|
|
386598
386464
|
const fusionDir = join128(cwd, ".fusion");
|
|
386599
|
-
if (!
|
|
386465
|
+
if (!existsSync91(fusionDir)) {
|
|
386600
386466
|
mkdirSync17(fusionDir, { recursive: true });
|
|
386601
386467
|
}
|
|
386602
386468
|
const projectName = await detectProjectName(cwd);
|
|
@@ -386626,7 +386492,7 @@ async function ensureCwdProjectRegistered(options) {
|
|
|
386626
386492
|
}
|
|
386627
386493
|
}
|
|
386628
386494
|
async function detectProjectName(dir2) {
|
|
386629
|
-
if (!
|
|
386495
|
+
if (!existsSync91(join128(dir2, ".git"))) {
|
|
386630
386496
|
return basename37(dir2) || "my-project";
|
|
386631
386497
|
}
|
|
386632
386498
|
try {
|
|
@@ -386658,7 +386524,7 @@ var init_ensure_project_registered = __esm({
|
|
|
386658
386524
|
});
|
|
386659
386525
|
|
|
386660
386526
|
// src/commands/provider-settings.ts
|
|
386661
|
-
import { existsSync as
|
|
386527
|
+
import { existsSync as existsSync92, readFileSync as readFileSync33, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18 } from "node:fs";
|
|
386662
386528
|
import { join as join129, dirname as dirname59, basename as basename38 } from "node:path";
|
|
386663
386529
|
function siblingAgentDir2(agentDir, siblingRoot) {
|
|
386664
386530
|
if (basename38(agentDir) !== "agent") {
|
|
@@ -386667,7 +386533,7 @@ function siblingAgentDir2(agentDir, siblingRoot) {
|
|
|
386667
386533
|
return join129(dirname59(dirname59(agentDir)), siblingRoot, "agent");
|
|
386668
386534
|
}
|
|
386669
386535
|
function readJsonObject4(path14) {
|
|
386670
|
-
if (!
|
|
386536
|
+
if (!existsSync92(path14)) {
|
|
386671
386537
|
return {};
|
|
386672
386538
|
}
|
|
386673
386539
|
try {
|
|
@@ -386712,7 +386578,7 @@ var init_provider_auth2 = __esm({
|
|
|
386712
386578
|
|
|
386713
386579
|
// src/commands/auth-paths.ts
|
|
386714
386580
|
import { homedir as homedir20 } from "node:os";
|
|
386715
|
-
import { existsSync as
|
|
386581
|
+
import { existsSync as existsSync93, readFileSync as readFileSync34 } from "node:fs";
|
|
386716
386582
|
import { join as join130 } from "node:path";
|
|
386717
386583
|
function getFusionAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir20()) {
|
|
386718
386584
|
return join130(home, ".fusion", "agent");
|
|
@@ -386731,13 +386597,13 @@ function getLegacyModelsPaths2(home = process.env.HOME || process.env.USERPROFIL
|
|
|
386731
386597
|
}
|
|
386732
386598
|
function getModelRegistryModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir20()) {
|
|
386733
386599
|
const fusionModelsPath = getFusionModelsPath2(home);
|
|
386734
|
-
if (
|
|
386600
|
+
if (existsSync93(fusionModelsPath)) {
|
|
386735
386601
|
return fusionModelsPath;
|
|
386736
386602
|
}
|
|
386737
|
-
return getLegacyModelsPaths2(home).find((modelsPath) =>
|
|
386603
|
+
return getLegacyModelsPaths2(home).find((modelsPath) => existsSync93(modelsPath)) ?? fusionModelsPath;
|
|
386738
386604
|
}
|
|
386739
386605
|
function readJsonObject5(path14) {
|
|
386740
|
-
if (!
|
|
386606
|
+
if (!existsSync93(path14)) {
|
|
386741
386607
|
return {};
|
|
386742
386608
|
}
|
|
386743
386609
|
try {
|
|
@@ -386755,13 +386621,13 @@ function getPackageManagerAgentDir2(home = process.env.HOME || process.env.USERP
|
|
|
386755
386621
|
const legacyAgentDir = getLegacyAgentDir(home);
|
|
386756
386622
|
const fusionSettings = readJsonObject5(join130(fusionAgentDir, "settings.json"));
|
|
386757
386623
|
const legacySettings = readJsonObject5(join130(legacyAgentDir, "settings.json"));
|
|
386758
|
-
if (hasPackageManagerSettings3(fusionSettings) || !
|
|
386624
|
+
if (hasPackageManagerSettings3(fusionSettings) || !existsSync93(legacyAgentDir)) {
|
|
386759
386625
|
return fusionAgentDir;
|
|
386760
386626
|
}
|
|
386761
386627
|
if (hasPackageManagerSettings3(legacySettings)) {
|
|
386762
386628
|
return legacyAgentDir;
|
|
386763
386629
|
}
|
|
386764
|
-
return
|
|
386630
|
+
return existsSync93(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
|
|
386765
386631
|
}
|
|
386766
386632
|
var init_auth_paths2 = __esm({
|
|
386767
386633
|
"src/commands/auth-paths.ts"() {
|
|
@@ -387008,7 +386874,7 @@ var init_project_context = __esm({
|
|
|
387008
386874
|
// src/commands/claude-skills.ts
|
|
387009
386875
|
import {
|
|
387010
386876
|
cpSync as cpSync6,
|
|
387011
|
-
existsSync as
|
|
386877
|
+
existsSync as existsSync94,
|
|
387012
386878
|
lstatSync as lstatSync6,
|
|
387013
386879
|
mkdirSync as mkdirSync19,
|
|
387014
386880
|
readlinkSync as readlinkSync4,
|
|
@@ -387037,7 +386903,7 @@ function isPiClaudeCliConfigured(globalSettings) {
|
|
|
387037
386903
|
function resolveFusionSkillSource() {
|
|
387038
386904
|
const here = fileURLToPath19(import.meta.url);
|
|
387039
386905
|
const candidate = resolve77(dirname61(here), "..", "..", "skill", FUSION_SKILL_NAME4);
|
|
387040
|
-
return
|
|
386906
|
+
return existsSync94(candidate) ? candidate : null;
|
|
387041
386907
|
}
|
|
387042
386908
|
function installFusionSkillIntoProject(projectPath, options = {}) {
|
|
387043
386909
|
const target = join131(projectPath, ".claude", "skills", FUSION_SKILL_NAME4);
|
|
@@ -387055,7 +386921,7 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
|
|
|
387055
386921
|
try {
|
|
387056
386922
|
mkdirSync19(dirname61(target), { recursive: true });
|
|
387057
386923
|
let replaced = false;
|
|
387058
|
-
if (
|
|
386924
|
+
if (existsSync94(target) || isBrokenSymlink2(target)) {
|
|
387059
386925
|
const stat20 = lstatSync6(target);
|
|
387060
386926
|
if (stat20.isSymbolicLink()) {
|
|
387061
386927
|
const current = safeReadlink2(target);
|
|
@@ -387066,7 +386932,7 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
|
|
|
387066
386932
|
replaced = true;
|
|
387067
386933
|
} else {
|
|
387068
386934
|
const skillMd = join131(target, "SKILL.md");
|
|
387069
|
-
if (!
|
|
386935
|
+
if (!existsSync94(skillMd)) {
|
|
387070
386936
|
return {
|
|
387071
386937
|
outcome: "failed",
|
|
387072
386938
|
target,
|
|
@@ -387125,7 +386991,7 @@ function isBrokenSymlink2(path14) {
|
|
|
387125
386991
|
try {
|
|
387126
386992
|
const stat20 = lstatSync6(path14);
|
|
387127
386993
|
if (!stat20.isSymbolicLink()) return false;
|
|
387128
|
-
return !
|
|
386994
|
+
return !existsSync94(path14);
|
|
387129
386995
|
} catch {
|
|
387130
386996
|
return false;
|
|
387131
386997
|
}
|
|
@@ -387222,7 +387088,7 @@ var init_claude_skills_runner = __esm({
|
|
|
387222
387088
|
});
|
|
387223
387089
|
|
|
387224
387090
|
// src/commands/claude-cli-extension.ts
|
|
387225
|
-
import { existsSync as
|
|
387091
|
+
import { existsSync as existsSync95, readFileSync as readFileSync35 } from "node:fs";
|
|
387226
387092
|
import { createRequire as createRequire10 } from "node:module";
|
|
387227
387093
|
import { dirname as dirname62, resolve as resolve78 } from "node:path";
|
|
387228
387094
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
@@ -387231,7 +387097,7 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
|
|
|
387231
387097
|
const here = dirname62(fileURLToPath20(moduleUrl));
|
|
387232
387098
|
for (const rel of ["pi-claude-cli", "../pi-claude-cli", "../../pi-claude-cli"]) {
|
|
387233
387099
|
const candidate = resolve78(here, rel, "package.json");
|
|
387234
|
-
if (
|
|
387100
|
+
if (existsSync95(candidate)) {
|
|
387235
387101
|
pkgJsonPath = candidate;
|
|
387236
387102
|
break;
|
|
387237
387103
|
}
|
|
@@ -387267,7 +387133,7 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
|
|
|
387267
387133
|
};
|
|
387268
387134
|
}
|
|
387269
387135
|
const entryPath = resolve78(dirname62(pkgJsonPath), rawEntry);
|
|
387270
|
-
if (!
|
|
387136
|
+
if (!existsSync95(entryPath)) {
|
|
387271
387137
|
return {
|
|
387272
387138
|
status: "missing-entry",
|
|
387273
387139
|
reason: `@fusion/pi-claude-cli extension file not found at ${entryPath}`
|
|
@@ -387318,7 +387184,7 @@ var init_claude_cli_extension = __esm({
|
|
|
387318
387184
|
});
|
|
387319
387185
|
|
|
387320
387186
|
// src/commands/droid-cli-extension.ts
|
|
387321
|
-
import { existsSync as
|
|
387187
|
+
import { existsSync as existsSync96, readFileSync as readFileSync36 } from "node:fs";
|
|
387322
387188
|
import { createRequire as createRequire11 } from "node:module";
|
|
387323
387189
|
import { dirname as dirname63, resolve as resolve79 } from "node:path";
|
|
387324
387190
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
@@ -387327,7 +387193,7 @@ function resolveDroidCliExtensionFromModuleUrl(moduleUrl) {
|
|
|
387327
387193
|
const here = dirname63(fileURLToPath21(moduleUrl));
|
|
387328
387194
|
for (const rel of ["droid-cli", "../droid-cli", "../../droid-cli"]) {
|
|
387329
387195
|
const candidate = resolve79(here, rel, "package.json");
|
|
387330
|
-
if (
|
|
387196
|
+
if (existsSync96(candidate)) {
|
|
387331
387197
|
pkgJsonPath = candidate;
|
|
387332
387198
|
break;
|
|
387333
387199
|
}
|
|
@@ -387363,7 +387229,7 @@ function resolveDroidCliExtensionFromModuleUrl(moduleUrl) {
|
|
|
387363
387229
|
};
|
|
387364
387230
|
}
|
|
387365
387231
|
const entryPath = resolve79(dirname63(pkgJsonPath), rawEntry);
|
|
387366
|
-
if (!
|
|
387232
|
+
if (!existsSync96(entryPath)) {
|
|
387367
387233
|
return {
|
|
387368
387234
|
status: "missing-entry",
|
|
387369
387235
|
reason: `@fusion/droid-cli extension file not found at ${entryPath}`
|
|
@@ -387414,7 +387280,7 @@ var init_droid_cli_extension = __esm({
|
|
|
387414
387280
|
});
|
|
387415
387281
|
|
|
387416
387282
|
// src/commands/llama-cpp-extension.ts
|
|
387417
|
-
import { existsSync as
|
|
387283
|
+
import { existsSync as existsSync97, readFileSync as readFileSync37 } from "node:fs";
|
|
387418
387284
|
import { createRequire as createRequire12 } from "node:module";
|
|
387419
387285
|
import { dirname as dirname64, resolve as resolve80 } from "node:path";
|
|
387420
387286
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
@@ -387423,7 +387289,7 @@ function resolveLlamaCppExtensionFromModuleUrl(moduleUrl) {
|
|
|
387423
387289
|
const here = dirname64(fileURLToPath22(moduleUrl));
|
|
387424
387290
|
for (const rel of ["pi-llama-cpp", "../pi-llama-cpp", "../../pi-llama-cpp", "../../../pi-llama-cpp"]) {
|
|
387425
387291
|
const candidate = resolve80(here, rel, "package.json");
|
|
387426
|
-
if (
|
|
387292
|
+
if (existsSync97(candidate)) {
|
|
387427
387293
|
pkgJsonPath = candidate;
|
|
387428
387294
|
break;
|
|
387429
387295
|
}
|
|
@@ -387459,7 +387325,7 @@ function resolveLlamaCppExtensionFromModuleUrl(moduleUrl) {
|
|
|
387459
387325
|
};
|
|
387460
387326
|
}
|
|
387461
387327
|
const entryPath = resolve80(dirname64(pkgJsonPath), rawEntry);
|
|
387462
|
-
if (!
|
|
387328
|
+
if (!existsSync97(entryPath)) {
|
|
387463
387329
|
return {
|
|
387464
387330
|
status: "missing-entry",
|
|
387465
387331
|
reason: `@fusion/pi-llama-cpp extension file not found at ${entryPath}`
|
|
@@ -387558,7 +387424,7 @@ var init_update_cache = __esm({
|
|
|
387558
387424
|
});
|
|
387559
387425
|
|
|
387560
387426
|
// src/commands/self-extension.ts
|
|
387561
|
-
import { existsSync as
|
|
387427
|
+
import { existsSync as existsSync98, readFileSync as readFileSync39 } from "node:fs";
|
|
387562
387428
|
import { dirname as dirname65, resolve as resolve81 } from "node:path";
|
|
387563
387429
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
387564
387430
|
function resolveSelfExtension() {
|
|
@@ -387566,7 +387432,7 @@ function resolveSelfExtension() {
|
|
|
387566
387432
|
let pkgDir;
|
|
387567
387433
|
let cur = here;
|
|
387568
387434
|
for (let i = 0; i < 5; i++) {
|
|
387569
|
-
if (
|
|
387435
|
+
if (existsSync98(resolve81(cur, "package.json"))) {
|
|
387570
387436
|
try {
|
|
387571
387437
|
const parsed = JSON.parse(readFileSync39(resolve81(cur, "package.json"), "utf-8"));
|
|
387572
387438
|
if (parsed.name === "@runfusion/fusion") {
|
|
@@ -387590,7 +387456,7 @@ function resolveSelfExtension() {
|
|
|
387590
387456
|
return { status: "missing", reason: `Failed to read @runfusion/fusion package.json: ${err instanceof Error ? err.message : String(err)}` };
|
|
387591
387457
|
}
|
|
387592
387458
|
const srcEntry = resolve81(pkgDir, "src", "extension.ts");
|
|
387593
|
-
if (
|
|
387459
|
+
if (existsSync98(srcEntry)) {
|
|
387594
387460
|
return { status: "ok", path: srcEntry, packageVersion: pkgJson.version ?? "unknown" };
|
|
387595
387461
|
}
|
|
387596
387462
|
const extensions = pkgJson.pi?.extensions;
|
|
@@ -387602,7 +387468,7 @@ function resolveSelfExtension() {
|
|
|
387602
387468
|
return { status: "missing", reason: "@runfusion/fusion pi.extensions[0] is not a valid path string" };
|
|
387603
387469
|
}
|
|
387604
387470
|
const entryPath = resolve81(pkgDir, rawEntry);
|
|
387605
|
-
if (!
|
|
387471
|
+
if (!existsSync98(entryPath)) {
|
|
387606
387472
|
return { status: "missing", reason: `@runfusion/fusion extension file not found at ${entryPath}` };
|
|
387607
387473
|
}
|
|
387608
387474
|
return { status: "ok", path: entryPath, packageVersion: pkgJson.version ?? "unknown" };
|
|
@@ -396064,7 +395930,7 @@ import { join as join134, resolve as pathResolve2 } from "node:path";
|
|
|
396064
395930
|
import { execFile as execFileCb, spawn as spawn31 } from "node:child_process";
|
|
396065
395931
|
import { promisify as promisify75 } from "node:util";
|
|
396066
395932
|
import { stat as stat18, readdir as readdir16, readFile as fsReadFile4 } from "node:fs/promises";
|
|
396067
|
-
import { existsSync as
|
|
395933
|
+
import { existsSync as existsSync99, readFileSync as readFileSync40 } from "node:fs";
|
|
396068
395934
|
import { fileURLToPath as fileURLToPath25 } from "node:url";
|
|
396069
395935
|
import { DefaultPackageManager as DefaultPackageManager2, discoverAndLoadExtensions as discoverAndLoadExtensions2, createExtensionRuntime as createExtensionRuntime2 } from "@earendil-works/pi-coding-agent";
|
|
396070
395936
|
async function countActiveTasks(store, tasks2) {
|
|
@@ -398366,7 +398232,7 @@ function resolveFusionSourceWorkspaceRoot() {
|
|
|
398366
398232
|
try {
|
|
398367
398233
|
let dir2 = pathResolve2(fileURLToPath25(import.meta.url), "..");
|
|
398368
398234
|
for (let i = 0; i < 10; i++) {
|
|
398369
|
-
if (
|
|
398235
|
+
if (existsSync99(join134(dir2, "pnpm-workspace.yaml"))) {
|
|
398370
398236
|
try {
|
|
398371
398237
|
const pkg = JSON.parse(readFileSync40(join134(dir2, "package.json"), "utf8"));
|
|
398372
398238
|
return pkg?.name === "fusion-workspace" ? dir2 : void 0;
|
|
@@ -400768,7 +400634,7 @@ __export(desktop_exports, {
|
|
|
400768
400634
|
});
|
|
400769
400635
|
import { spawn as spawn32 } from "node:child_process";
|
|
400770
400636
|
import { once as once2 } from "node:events";
|
|
400771
|
-
import { existsSync as
|
|
400637
|
+
import { existsSync as existsSync100 } from "node:fs";
|
|
400772
400638
|
import { dirname as dirname67, isAbsolute as isAbsolute34, join as join137, resolve as resolve83 } from "node:path";
|
|
400773
400639
|
import { createRequire as createRequire13 } from "node:module";
|
|
400774
400640
|
import { fileURLToPath as fileURLToPath26 } from "node:url";
|
|
@@ -400877,7 +400743,7 @@ function terminateProcess(child, signal = "SIGTERM") {
|
|
|
400877
400743
|
}
|
|
400878
400744
|
function resolveDevDesktopEntry(rootDir) {
|
|
400879
400745
|
const desktopEntry = join137(rootDir, "packages", "desktop", "dist", "main.js");
|
|
400880
|
-
if (
|
|
400746
|
+
if (existsSync100(desktopEntry)) {
|
|
400881
400747
|
return desktopEntry;
|
|
400882
400748
|
}
|
|
400883
400749
|
throw new Error(
|
|
@@ -400888,17 +400754,17 @@ function resolvePackagedDesktopEntry() {
|
|
|
400888
400754
|
const override = process.env.FUSION_DESKTOP_ENTRY;
|
|
400889
400755
|
if (override) {
|
|
400890
400756
|
const resolvedOverride = isAbsolute34(override) ? override : resolve83(process.cwd(), override);
|
|
400891
|
-
if (
|
|
400757
|
+
if (existsSync100(resolvedOverride)) {
|
|
400892
400758
|
return resolvedOverride;
|
|
400893
400759
|
}
|
|
400894
400760
|
throw new Error(`Fusion desktop runtime override is missing: ${resolvedOverride}`);
|
|
400895
400761
|
}
|
|
400896
400762
|
const packagedEntry = resolve83(cliModuleDir, "desktop", "main.js");
|
|
400897
|
-
if (
|
|
400763
|
+
if (existsSync100(packagedEntry)) {
|
|
400898
400764
|
return packagedEntry;
|
|
400899
400765
|
}
|
|
400900
400766
|
const sourceCheckoutEntry = resolve83(cliModuleDir, "..", "..", "dist", "desktop", "main.js");
|
|
400901
|
-
if (
|
|
400767
|
+
if (existsSync100(sourceCheckoutEntry)) {
|
|
400902
400768
|
return sourceCheckoutEntry;
|
|
400903
400769
|
}
|
|
400904
400770
|
throw new Error(
|
|
@@ -401530,7 +401396,7 @@ __export(task_exports, {
|
|
|
401530
401396
|
runTaskUpdate: () => runTaskUpdate
|
|
401531
401397
|
});
|
|
401532
401398
|
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
401533
|
-
import { watchFile, unwatchFile, statSync as statSync17, existsSync as
|
|
401399
|
+
import { watchFile, unwatchFile, statSync as statSync17, existsSync as existsSync101, readFileSync as readFileSync41 } from "node:fs";
|
|
401534
401400
|
import { basename as basename40, join as join138 } from "node:path";
|
|
401535
401401
|
function columnLabel2(column) {
|
|
401536
401402
|
return COLUMN_LABELS[column] ?? column;
|
|
@@ -402104,7 +401970,7 @@ async function runTaskLogs(id, options = {}, projectName) {
|
|
|
402104
401970
|
if (options.follow) {
|
|
402105
401971
|
const projectPath = context.projectPath ?? process.cwd();
|
|
402106
401972
|
const logPath = join138(projectPath, ".fusion", "tasks", id, "agent.log");
|
|
402107
|
-
if (!
|
|
401973
|
+
if (!existsSync101(logPath)) {
|
|
402108
401974
|
console.log(`
|
|
402109
401975
|
Waiting for log file to be created...`);
|
|
402110
401976
|
}
|
|
@@ -403788,7 +403654,7 @@ var settings_import_exports = {};
|
|
|
403788
403654
|
__export(settings_import_exports, {
|
|
403789
403655
|
runSettingsImport: () => runSettingsImport
|
|
403790
403656
|
});
|
|
403791
|
-
import { existsSync as
|
|
403657
|
+
import { existsSync as existsSync102 } from "node:fs";
|
|
403792
403658
|
import { resolve as resolve85 } from "node:path";
|
|
403793
403659
|
async function runSettingsImport(filePath, options = {}) {
|
|
403794
403660
|
const scope = options.scope ?? "both";
|
|
@@ -403807,7 +403673,7 @@ async function runSettingsImport(filePath, options = {}) {
|
|
|
403807
403673
|
};
|
|
403808
403674
|
try {
|
|
403809
403675
|
const resolvedPath = resolve85(filePath);
|
|
403810
|
-
if (!
|
|
403676
|
+
if (!existsSync102(resolvedPath)) {
|
|
403811
403677
|
console.error(`Error: File not found: ${filePath}`);
|
|
403812
403678
|
await exitWithStore(1);
|
|
403813
403679
|
return;
|
|
@@ -403915,7 +403781,7 @@ __export(mcp_exports, {
|
|
|
403915
403781
|
runMcpRemove: () => runMcpRemove,
|
|
403916
403782
|
runMcpValidate: () => runMcpValidate
|
|
403917
403783
|
});
|
|
403918
|
-
import { existsSync as
|
|
403784
|
+
import { existsSync as existsSync103 } from "node:fs";
|
|
403919
403785
|
import { readFile as readFile60, writeFile as writeFile41 } from "node:fs/promises";
|
|
403920
403786
|
import { resolve as resolve86 } from "node:path";
|
|
403921
403787
|
async function createGlobalSettingsStore() {
|
|
@@ -404253,7 +404119,7 @@ async function runMcpImport(filePath, opts = {}) {
|
|
|
404253
404119
|
const scope = normalizeScope(opts.scope);
|
|
404254
404120
|
context = await loadContext(opts.projectName, scope === "project");
|
|
404255
404121
|
const resolvedPath = resolve86(filePath);
|
|
404256
|
-
if (!
|
|
404122
|
+
if (!existsSync103(resolvedPath)) throw new Error(`File not found: ${filePath}`);
|
|
404257
404123
|
const imported = importMcpServersJson(await readFile60(resolvedPath, "utf-8"), { scope });
|
|
404258
404124
|
if (imported.errors.length > 0) throw new Error(`Invalid MCP import file:
|
|
404259
404125
|
${imported.errors.map((error3) => ` - ${error3}`).join("\n")}`);
|
|
@@ -404370,7 +404236,7 @@ var init_mcp = __esm({
|
|
|
404370
404236
|
});
|
|
404371
404237
|
|
|
404372
404238
|
// src/project-resolver.ts
|
|
404373
|
-
import { existsSync as
|
|
404239
|
+
import { existsSync as existsSync104, statSync as statSync18 } from "node:fs";
|
|
404374
404240
|
import { basename as basename41, dirname as dirname68, join as join140, normalize as normalize9, resolve as resolve87 } from "node:path";
|
|
404375
404241
|
import { createInterface as createInterface4 } from "node:readline/promises";
|
|
404376
404242
|
async function getCentralCore() {
|
|
@@ -404453,7 +404319,7 @@ async function resolveProject2(options = {}) {
|
|
|
404453
404319
|
{ searchedName: options.project, availableProjects: projects2.map((p2) => p2.name) }
|
|
404454
404320
|
);
|
|
404455
404321
|
}
|
|
404456
|
-
if (!
|
|
404322
|
+
if (!existsSync104(match.path)) {
|
|
404457
404323
|
throw new ProjectResolutionError(
|
|
404458
404324
|
`Project "${match.name}" is registered but the directory no longer exists: ${match.path}
|
|
404459
404325
|
|
|
@@ -404471,7 +404337,7 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
|
|
|
404471
404337
|
const normalizedKbDir = normalize9(fusionDir);
|
|
404472
404338
|
const match = allProjects2.find((p2) => normalize9(p2.path) === normalizedKbDir);
|
|
404473
404339
|
if (match) {
|
|
404474
|
-
if (!
|
|
404340
|
+
if (!existsSync104(match.path)) {
|
|
404475
404341
|
throw new ProjectResolutionError(
|
|
404476
404342
|
`Project "${match.name}" is registered but the directory no longer exists: ${match.path}
|
|
404477
404343
|
|
|
@@ -404597,7 +404463,7 @@ Run \`fn project add ` + fusionDir + "` to register it, or use --project <name>.
|
|
|
404597
404463
|
}
|
|
404598
404464
|
if (allProjects.length === 1) {
|
|
404599
404465
|
const project = allProjects[0];
|
|
404600
|
-
if (!
|
|
404466
|
+
if (!existsSync104(project.path)) {
|
|
404601
404467
|
throw new ProjectResolutionError(
|
|
404602
404468
|
`The only registered project "${project.name}" has a missing directory: ${project.path}
|
|
404603
404469
|
|
|
@@ -405587,7 +405453,7 @@ __export(db_exports, {
|
|
|
405587
405453
|
runDbMigrate: () => runDbMigrate,
|
|
405588
405454
|
runDbVacuum: () => runDbVacuum
|
|
405589
405455
|
});
|
|
405590
|
-
import { existsSync as
|
|
405456
|
+
import { existsSync as existsSync105 } from "node:fs";
|
|
405591
405457
|
import { copyFile as copyFile3, mkdir as mkdir41 } from "node:fs/promises";
|
|
405592
405458
|
import { join as join141 } from "node:path";
|
|
405593
405459
|
function formatBytes9(bytes) {
|
|
@@ -405668,7 +405534,7 @@ async function runDbMigrate(projectName, opts = {}) {
|
|
|
405668
405534
|
const fusionDir = join141(projectRoot, ".fusion");
|
|
405669
405535
|
const globalDir = resolveGlobalDir();
|
|
405670
405536
|
const sources = defaultMigrationSources(fusionDir, globalDir);
|
|
405671
|
-
const presentSources = sources.filter((s3) =>
|
|
405537
|
+
const presentSources = sources.filter((s3) => existsSync105(s3.sqlitePath));
|
|
405672
405538
|
if (presentSources.length === 0) {
|
|
405673
405539
|
console.error(
|
|
405674
405540
|
`fn db migrate: no legacy SQLite files found under ${fusionDir} (or ${globalDir}). Nothing to migrate.`
|
|
@@ -405795,7 +405661,7 @@ async function createPreMigrationBackup(fusionDir, globalDir, sources) {
|
|
|
405795
405661
|
const backupDir = join141(globalDir, "migration-backups", `pre-migrate-${ts2}`);
|
|
405796
405662
|
await mkdir41(backupDir, { recursive: true });
|
|
405797
405663
|
for (const s3 of sources) {
|
|
405798
|
-
if (
|
|
405664
|
+
if (existsSync105(s3.sqlitePath)) {
|
|
405799
405665
|
const dest = join141(backupDir, s3.sqlitePath.split("/").pop() ?? "source.db");
|
|
405800
405666
|
await copyFile3(s3.sqlitePath, dest);
|
|
405801
405667
|
}
|
|
@@ -406691,7 +406557,7 @@ __export(project_exports2, {
|
|
|
406691
406557
|
runProjectShow: () => runProjectShow
|
|
406692
406558
|
});
|
|
406693
406559
|
import { resolve as resolve89, isAbsolute as isAbsolute35, relative as relative26, basename as basename42, join as join142 } from "node:path";
|
|
406694
|
-
import { existsSync as
|
|
406560
|
+
import { existsSync as existsSync106, statSync as statSync19 } from "node:fs";
|
|
406695
406561
|
import { createInterface as createInterface8 } from "node:readline/promises";
|
|
406696
406562
|
function formatDisplayPath(projectPath) {
|
|
406697
406563
|
const rel = relative26(process.cwd(), projectPath);
|
|
@@ -406845,7 +406711,7 @@ async function runProjectAdd(name2, path14, options = {}) {
|
|
|
406845
406711
|
projectPath = pathInput.trim() || defaultPath;
|
|
406846
406712
|
}
|
|
406847
406713
|
const absolutePath2 = isAbsolute35(projectPath) ? projectPath : resolve89(process.cwd(), projectPath);
|
|
406848
|
-
if (!
|
|
406714
|
+
if (!existsSync106(absolutePath2)) {
|
|
406849
406715
|
console.error(`
|
|
406850
406716
|
\u2717 Path does not exist: ${projectPath}`);
|
|
406851
406717
|
rl.close();
|
|
@@ -406895,7 +406761,7 @@ async function runProjectAdd(name2, path14, options = {}) {
|
|
|
406895
406761
|
process.exit(1);
|
|
406896
406762
|
}
|
|
406897
406763
|
const absolutePath = isAbsolute35(projectPath) ? projectPath : resolve89(process.cwd(), projectPath);
|
|
406898
|
-
if (!
|
|
406764
|
+
if (!existsSync106(absolutePath)) {
|
|
406899
406765
|
console.error(`
|
|
406900
406766
|
\u2717 Path does not exist: ${projectPath}
|
|
406901
406767
|
`);
|
|
@@ -407180,7 +407046,7 @@ var init_project2 = __esm({
|
|
|
407180
407046
|
});
|
|
407181
407047
|
|
|
407182
407048
|
// src/commands/skill-installation.ts
|
|
407183
|
-
import { cpSync as cpSync7, existsSync as
|
|
407049
|
+
import { cpSync as cpSync7, existsSync as existsSync107, mkdirSync as mkdirSync20 } from "node:fs";
|
|
407184
407050
|
import { homedir as homedir21 } from "node:os";
|
|
407185
407051
|
import { dirname as dirname69, join as join143, resolve as resolve90 } from "node:path";
|
|
407186
407052
|
import { fileURLToPath as fileURLToPath27 } from "node:url";
|
|
@@ -407194,7 +407060,7 @@ function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.e
|
|
|
407194
407060
|
function resolveBundledFusionSkillSource4() {
|
|
407195
407061
|
const here = fileURLToPath27(import.meta.url);
|
|
407196
407062
|
const source = resolve90(dirname69(here), "..", "..", "skill", FUSION_SKILL_NAME5);
|
|
407197
|
-
return
|
|
407063
|
+
return existsSync107(source) ? source : null;
|
|
407198
407064
|
}
|
|
407199
407065
|
function installBundledFusionSkill(options = {}) {
|
|
407200
407066
|
const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource4();
|
|
@@ -407212,7 +407078,7 @@ function installBundledFusionSkill(options = {}) {
|
|
|
407212
407078
|
}
|
|
407213
407079
|
const results = targets.map((target) => {
|
|
407214
407080
|
try {
|
|
407215
|
-
if (
|
|
407081
|
+
if (existsSync107(target.targetDir)) {
|
|
407216
407082
|
return {
|
|
407217
407083
|
client: target.client,
|
|
407218
407084
|
targetDir: target.targetDir,
|
|
@@ -407251,7 +407117,7 @@ var init_exports = {};
|
|
|
407251
407117
|
__export(init_exports, {
|
|
407252
407118
|
runInit: () => runInit
|
|
407253
407119
|
});
|
|
407254
|
-
import { existsSync as
|
|
407120
|
+
import { existsSync as existsSync108, mkdirSync as mkdirSync21, writeFileSync as writeFileSync20, readFileSync as readFileSync42 } from "node:fs";
|
|
407255
407121
|
import { join as join144, resolve as resolve91, basename as basename43 } from "node:path";
|
|
407256
407122
|
import { exec as exec51 } from "node:child_process";
|
|
407257
407123
|
import { promisify as promisify77 } from "node:util";
|
|
@@ -407259,10 +407125,10 @@ async function runInit(options = {}) {
|
|
|
407259
407125
|
const cwd = options.path ? resolve91(options.path) : process.cwd();
|
|
407260
407126
|
const fusionDir = join144(cwd, ".fusion");
|
|
407261
407127
|
const dbPath = join144(fusionDir, "fusion.db");
|
|
407262
|
-
const hasDbPath =
|
|
407128
|
+
const hasDbPath = existsSync108(dbPath);
|
|
407263
407129
|
const hasValidDb = hasDbPath && isValidSqliteDatabaseFile(dbPath);
|
|
407264
407130
|
const hasIdentity = hasProjectIdentity(fusionDir);
|
|
407265
|
-
if (
|
|
407131
|
+
if (existsSync108(fusionDir) && (hasIdentity || hasValidDb)) {
|
|
407266
407132
|
const central2 = new CentralCore();
|
|
407267
407133
|
await central2.init();
|
|
407268
407134
|
const existing = await central2.getProjectByPath(cwd);
|
|
@@ -407291,7 +407157,7 @@ async function runInit(options = {}) {
|
|
|
407291
407157
|
await central2.close();
|
|
407292
407158
|
return;
|
|
407293
407159
|
}
|
|
407294
|
-
if (
|
|
407160
|
+
if (existsSync108(fusionDir) && !hasIdentity && hasDbPath && !hasValidDb) {
|
|
407295
407161
|
throw new Error(
|
|
407296
407162
|
`Existing database at ${dbPath} is not a valid SQLite database. Restore it from .fusion/backups or move it aside before re-running fn init.`
|
|
407297
407163
|
);
|
|
@@ -407299,7 +407165,7 @@ async function runInit(options = {}) {
|
|
|
407299
407165
|
const projectName = options.name ?? await detectProjectName2(cwd);
|
|
407300
407166
|
console.log(`Initializing fn project: "${projectName}"`);
|
|
407301
407167
|
console.log(` Path: ${cwd}`);
|
|
407302
|
-
if (!
|
|
407168
|
+
if (!existsSync108(fusionDir)) {
|
|
407303
407169
|
mkdirSync21(fusionDir, { recursive: true });
|
|
407304
407170
|
console.log(` \u2713 Created .fusion/ directory`);
|
|
407305
407171
|
}
|
|
@@ -407380,7 +407246,7 @@ async function runInit(options = {}) {
|
|
|
407380
407246
|
}
|
|
407381
407247
|
}
|
|
407382
407248
|
async function detectProjectName2(dir2) {
|
|
407383
|
-
if (!
|
|
407249
|
+
if (!existsSync108(join144(dir2, ".git"))) {
|
|
407384
407250
|
return basename43(dir2) || "my-project";
|
|
407385
407251
|
}
|
|
407386
407252
|
try {
|
|
@@ -407402,7 +407268,7 @@ async function detectProjectName2(dir2) {
|
|
|
407402
407268
|
async function addLocalStorageToGitignore(cwd) {
|
|
407403
407269
|
const gitignorePath = join144(cwd, ".gitignore");
|
|
407404
407270
|
let content = "";
|
|
407405
|
-
if (
|
|
407271
|
+
if (existsSync108(gitignorePath)) {
|
|
407406
407272
|
try {
|
|
407407
407273
|
content = readFileSync42(gitignorePath, "utf-8");
|
|
407408
407274
|
} catch {
|
|
@@ -407444,7 +407310,7 @@ async function initializeGitRepo(cwd) {
|
|
|
407444
407310
|
await ensureGitConfig(cwd, "user.name", "Fusion");
|
|
407445
407311
|
await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
|
|
407446
407312
|
const gitkeepPath = join144(cwd, ".gitkeep");
|
|
407447
|
-
if (!
|
|
407313
|
+
if (!existsSync108(gitkeepPath)) {
|
|
407448
407314
|
writeFileSync20(gitkeepPath, "\n");
|
|
407449
407315
|
}
|
|
407450
407316
|
await execAsync48("git add .gitkeep", { cwd, timeout: 1e4 });
|
|
@@ -407510,7 +407376,7 @@ __export(onboard_exports, {
|
|
|
407510
407376
|
persistLocalProviderRegistry: () => persistLocalProviderRegistry,
|
|
407511
407377
|
runOnboard: () => runOnboard
|
|
407512
407378
|
});
|
|
407513
|
-
import { existsSync as
|
|
407379
|
+
import { existsSync as existsSync109, mkdirSync as mkdirSync22, readFileSync as readFileSync43, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "node:fs";
|
|
407514
407380
|
import { dirname as dirname70 } from "node:path";
|
|
407515
407381
|
import { createInterface as createInterface9 } from "node:readline";
|
|
407516
407382
|
function createPromptSession(input = process.stdin) {
|
|
@@ -407639,7 +407505,7 @@ function composeLocalProviderRegistry(existing, config3) {
|
|
|
407639
407505
|
return { ...existing, providers };
|
|
407640
407506
|
}
|
|
407641
407507
|
function registryHasProvider(path14, providerId) {
|
|
407642
|
-
if (!
|
|
407508
|
+
if (!existsSync109(path14)) return false;
|
|
407643
407509
|
try {
|
|
407644
407510
|
const registry3 = JSON.parse(readFileSync43(path14, "utf8"));
|
|
407645
407511
|
return isObject2(registry3) && isObject2(registry3.providers) && isObject2(registry3.providers[providerId]);
|
|
@@ -407649,7 +407515,7 @@ function registryHasProvider(path14, providerId) {
|
|
|
407649
407515
|
}
|
|
407650
407516
|
function persistLocalProviderRegistry(path14, config3) {
|
|
407651
407517
|
let existing = {};
|
|
407652
|
-
if (
|
|
407518
|
+
if (existsSync109(path14)) {
|
|
407653
407519
|
try {
|
|
407654
407520
|
existing = JSON.parse(readFileSync43(path14, "utf8"));
|
|
407655
407521
|
} catch {
|
|
@@ -407664,7 +407530,7 @@ function persistLocalProviderRegistry(path14, config3) {
|
|
|
407664
407530
|
`, { mode: 384 });
|
|
407665
407531
|
renameSync6(tempPath, path14);
|
|
407666
407532
|
} finally {
|
|
407667
|
-
if (
|
|
407533
|
+
if (existsSync109(tempPath)) unlinkSync8(tempPath);
|
|
407668
407534
|
}
|
|
407669
407535
|
}
|
|
407670
407536
|
function validateMaxConcurrent(input) {
|
|
@@ -407699,7 +407565,7 @@ async function runOnboard(options = {}) {
|
|
|
407699
407565
|
const prompts = createPromptSession(options.input);
|
|
407700
407566
|
try {
|
|
407701
407567
|
const centralDbPath = getDefaultCentralDbPath();
|
|
407702
|
-
if (
|
|
407568
|
+
if (existsSync109(centralDbPath)) {
|
|
407703
407569
|
console.log(`\u2713 Central DB already exists: ${centralDbPath}`);
|
|
407704
407570
|
} else {
|
|
407705
407571
|
const ranCentralDb = await runSkippableStep(prompts, "Central DB", async () => {
|
|
@@ -407996,7 +407862,7 @@ var agent_import_exports = {};
|
|
|
407996
407862
|
__export(agent_import_exports, {
|
|
407997
407863
|
runAgentImport: () => runAgentImport
|
|
407998
407864
|
});
|
|
407999
|
-
import { existsSync as
|
|
407865
|
+
import { existsSync as existsSync110, mkdirSync as mkdirSync23, readFileSync as readFileSync44, statSync as statSync20, writeFileSync as writeFileSync22 } from "node:fs";
|
|
408000
407866
|
import { resolve as resolve92 } from "node:path";
|
|
408001
407867
|
function slugifyPathSegment(input) {
|
|
408002
407868
|
if (!input || typeof input !== "string") {
|
|
@@ -408055,7 +407921,7 @@ async function importSkillsToProject(projectPath, skills, companySlug, dryRun) {
|
|
|
408055
407921
|
const skillSlug = slugifyPathSegment(skill.name);
|
|
408056
407922
|
const skillDir = resolve92(baseSkillsDir, skillSlug);
|
|
408057
407923
|
const skillPath = resolve92(skillDir, "SKILL.md");
|
|
408058
|
-
if (
|
|
407924
|
+
if (existsSync110(skillPath)) {
|
|
408059
407925
|
result2.skipped.push(skill.name);
|
|
408060
407926
|
continue;
|
|
408061
407927
|
}
|
|
@@ -408116,7 +407982,7 @@ async function runAgentImport(source, options) {
|
|
|
408116
407982
|
const dryRun = options?.dryRun ?? false;
|
|
408117
407983
|
const skipExisting = options?.skipExisting ?? false;
|
|
408118
407984
|
const sourcePath = resolve92(source);
|
|
408119
|
-
if (!
|
|
407985
|
+
if (!existsSync110(sourcePath)) {
|
|
408120
407986
|
console.error(`Path not found: ${sourcePath}`);
|
|
408121
407987
|
process.exit(1);
|
|
408122
407988
|
}
|
|
@@ -408990,7 +408856,7 @@ __export(plugin_exports2, {
|
|
|
408990
408856
|
runPluginSetupStatus: () => runPluginSetupStatus,
|
|
408991
408857
|
runPluginUninstall: () => runPluginUninstall
|
|
408992
408858
|
});
|
|
408993
|
-
import { existsSync as
|
|
408859
|
+
import { existsSync as existsSync111 } from "node:fs";
|
|
408994
408860
|
import { dirname as dirname71, extname as extname6, join as join145, resolve as resolve96 } from "node:path";
|
|
408995
408861
|
import { readFile as readFile63, stat as stat19 } from "node:fs/promises";
|
|
408996
408862
|
import * as readline from "node:readline";
|
|
@@ -409085,7 +408951,7 @@ async function resolvePluginEntryFile(pluginDir) {
|
|
|
409085
408951
|
}
|
|
409086
408952
|
const packageJsonPath = join145(absoluteInputPath, "package.json");
|
|
409087
408953
|
let selectedCandidate;
|
|
409088
|
-
if (
|
|
408954
|
+
if (existsSync111(packageJsonPath)) {
|
|
409089
408955
|
const packageJson = JSON.parse(await readFile63(packageJsonPath, "utf-8"));
|
|
409090
408956
|
const exportsRecord = asRecord6(packageJson.exports);
|
|
409091
408957
|
const dotExport = exportsRecord?.["."];
|
|
@@ -409134,7 +409000,7 @@ async function loadManifestFromPath(pluginPath) {
|
|
|
409134
409000
|
const inputStats = await statPath(absoluteInputPath);
|
|
409135
409001
|
const manifestDir = inputStats?.isFile() ? dirname71(absoluteInputPath) : absoluteInputPath;
|
|
409136
409002
|
const manifestPath = join145(manifestDir, "manifest.json");
|
|
409137
|
-
if (!
|
|
409003
|
+
if (!existsSync111(manifestPath)) {
|
|
409138
409004
|
throw new Error(`Plugin manifest not found at: ${manifestPath}`);
|
|
409139
409005
|
}
|
|
409140
409006
|
const content = await readFile63(manifestPath, "utf-8");
|
|
@@ -409192,7 +409058,7 @@ async function runPluginInstall(source, options) {
|
|
|
409192
409058
|
console.error("Please provide a local path to the plugin directory.");
|
|
409193
409059
|
process.exit(1);
|
|
409194
409060
|
}
|
|
409195
|
-
if (!
|
|
409061
|
+
if (!existsSync111(source)) {
|
|
409196
409062
|
console.error(`Plugin path does not exist: ${source}`);
|
|
409197
409063
|
process.exit(1);
|
|
409198
409064
|
}
|
|
@@ -409515,7 +409381,7 @@ __export(plugin_scaffold_exports, {
|
|
|
409515
409381
|
runPluginCreate: () => runPluginCreate,
|
|
409516
409382
|
runPluginNew: () => runPluginNew
|
|
409517
409383
|
});
|
|
409518
|
-
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, existsSync as
|
|
409384
|
+
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, existsSync as existsSync112, readFileSync as readFileSync45 } from "node:fs";
|
|
409519
409385
|
import { join as join146, dirname as dirname72, resolve as resolve97 } from "node:path";
|
|
409520
409386
|
import { fileURLToPath as fileURLToPath28 } from "node:url";
|
|
409521
409387
|
function toTitleCase(str) {
|
|
@@ -409536,7 +409402,7 @@ function resolveTargetPath(name2, output) {
|
|
|
409536
409402
|
};
|
|
409537
409403
|
}
|
|
409538
409404
|
function ensureTargetPathAvailable(targetDir, targetPath) {
|
|
409539
|
-
if (
|
|
409405
|
+
if (existsSync112(targetPath)) {
|
|
409540
409406
|
console.error(`Error: Directory '${targetDir}' already exists.`);
|
|
409541
409407
|
console.error("Please choose a different name or remove the existing directory.");
|
|
409542
409408
|
process.exit(1);
|
|
@@ -409551,7 +409417,7 @@ function readOwnCliVersion() {
|
|
|
409551
409417
|
}
|
|
409552
409418
|
for (let i = 0; i < 8; i += 1) {
|
|
409553
409419
|
const pkgPath = resolve97(currentDir, "package.json");
|
|
409554
|
-
if (
|
|
409420
|
+
if (existsSync112(pkgPath)) {
|
|
409555
409421
|
try {
|
|
409556
409422
|
const parsed = JSON.parse(readFileSync45(pkgPath, "utf-8"));
|
|
409557
409423
|
if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
|
|
@@ -409913,7 +409779,7 @@ var plugin_dev_exports = {};
|
|
|
409913
409779
|
__export(plugin_dev_exports, {
|
|
409914
409780
|
runPluginDev: () => runPluginDev
|
|
409915
409781
|
});
|
|
409916
|
-
import { existsSync as
|
|
409782
|
+
import { existsSync as existsSync113, watch as watch2 } from "node:fs";
|
|
409917
409783
|
import { join as join147, resolve as resolve98 } from "node:path";
|
|
409918
409784
|
async function runSupervisedCommand(command, cwd, timeoutMs = 12e4) {
|
|
409919
409785
|
await new Promise((resolvePromise, rejectPromise) => {
|
|
@@ -409959,7 +409825,7 @@ async function defaultBuildFn(pluginDir) {
|
|
|
409959
409825
|
await runSupervisedCommand("npm run build", pluginDir);
|
|
409960
409826
|
}
|
|
409961
409827
|
function defaultWatchFn(pluginDir, onChange) {
|
|
409962
|
-
const watchPath =
|
|
409828
|
+
const watchPath = existsSync113(join147(pluginDir, "src")) ? join147(pluginDir, "src") : pluginDir;
|
|
409963
409829
|
try {
|
|
409964
409830
|
const watcher = watch2(watchPath, { recursive: true }, onChange);
|
|
409965
409831
|
return { close: () => watcher.close() };
|
|
@@ -409975,7 +409841,7 @@ function shouldUseWatcher(options) {
|
|
|
409975
409841
|
return Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
409976
409842
|
}
|
|
409977
409843
|
async function runPluginDev(source, options) {
|
|
409978
|
-
if (!
|
|
409844
|
+
if (!existsSync113(source)) {
|
|
409979
409845
|
console.error(`Plugin path does not exist: ${source}`);
|
|
409980
409846
|
process.exit(1);
|
|
409981
409847
|
}
|
|
@@ -410095,7 +409961,7 @@ __export(plugin_publish_exports, {
|
|
|
410095
409961
|
collectPluginPreflight: () => collectPluginPreflight,
|
|
410096
409962
|
runPluginPublish: () => runPluginPublish
|
|
410097
409963
|
});
|
|
410098
|
-
import { existsSync as
|
|
409964
|
+
import { existsSync as existsSync114 } from "node:fs";
|
|
410099
409965
|
import { readFile as readFile64 } from "node:fs/promises";
|
|
410100
409966
|
import { join as join148, resolve as resolve99 } from "node:path";
|
|
410101
409967
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
@@ -410256,7 +410122,7 @@ function statusIcon(status) {
|
|
|
410256
410122
|
return "\u2717";
|
|
410257
410123
|
}
|
|
410258
410124
|
async function runPluginPublish(source, options) {
|
|
410259
|
-
if (!
|
|
410125
|
+
if (!existsSync114(source)) {
|
|
410260
410126
|
console.error(`Plugin path does not exist: ${source}`);
|
|
410261
410127
|
process.exit(1);
|
|
410262
410128
|
}
|
|
@@ -410825,7 +410691,7 @@ __export(update_exports, {
|
|
|
410825
410691
|
runUpdate: () => runUpdate
|
|
410826
410692
|
});
|
|
410827
410693
|
import { exec as exec52 } from "node:child_process";
|
|
410828
|
-
import { existsSync as
|
|
410694
|
+
import { existsSync as existsSync115, readFileSync as readFileSync46 } from "node:fs";
|
|
410829
410695
|
import { promisify as promisify78 } from "node:util";
|
|
410830
410696
|
import { dirname as dirname73, resolve as resolve102 } from "node:path";
|
|
410831
410697
|
import { fileURLToPath as fileURLToPath29 } from "node:url";
|
|
@@ -410888,7 +410754,7 @@ function readOwnCliVersion2() {
|
|
|
410888
410754
|
}
|
|
410889
410755
|
for (let i = 0; i < 8; i += 1) {
|
|
410890
410756
|
const pkgPath = resolve102(currentDir, "package.json");
|
|
410891
|
-
if (
|
|
410757
|
+
if (existsSync115(pkgPath)) {
|
|
410892
410758
|
try {
|
|
410893
410759
|
const parsed = JSON.parse(readFileSync46(pkgPath, "utf-8"));
|
|
410894
410760
|
if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
|
|
@@ -411169,7 +411035,7 @@ __export(onboard_autolaunch_exports, {
|
|
|
411169
411035
|
maybeAutoLaunchOnboarding: () => maybeAutoLaunchOnboarding,
|
|
411170
411036
|
shouldAutoLaunchOnboarding: () => shouldAutoLaunchOnboarding
|
|
411171
411037
|
});
|
|
411172
|
-
import { existsSync as
|
|
411038
|
+
import { existsSync as existsSync116 } from "node:fs";
|
|
411173
411039
|
import { join as join150 } from "node:path";
|
|
411174
411040
|
function shouldAutoLaunchOnboarding(input) {
|
|
411175
411041
|
const env = input.env ?? process.env;
|
|
@@ -411234,7 +411100,7 @@ async function maybeAutoLaunchOnboarding(deps) {
|
|
|
411234
411100
|
let centralDbExists = true;
|
|
411235
411101
|
let projectInitialized = false;
|
|
411236
411102
|
try {
|
|
411237
|
-
const pathExists4 = deps.pathExists ??
|
|
411103
|
+
const pathExists4 = deps.pathExists ?? existsSync116;
|
|
411238
411104
|
const centralDbPath = deps.centralDbPath ?? getDefaultCentralDbPath();
|
|
411239
411105
|
const cwd = deps.cwd ?? process.cwd();
|
|
411240
411106
|
const projectMarkerPath = join150(cwd, ".fusion", "project.json");
|
|
@@ -411295,7 +411161,7 @@ __export(native_patch_exports, {
|
|
|
411295
411161
|
setupNativeResolution: () => setupNativeResolution
|
|
411296
411162
|
});
|
|
411297
411163
|
import { join as join151, basename as basename44, dirname as dirname74 } from "node:path";
|
|
411298
|
-
import { existsSync as
|
|
411164
|
+
import { existsSync as existsSync117, copyFileSync as copyFileSync2, mkdirSync as mkdirSync25, symlinkSync as symlinkSync7, rmSync as rmSync16, lstatSync as lstatSync7, readlinkSync as readlinkSync5 } from "node:fs";
|
|
411299
411165
|
import { tmpdir as tmpdir22 } from "node:os";
|
|
411300
411166
|
function findStagedNativeDir2() {
|
|
411301
411167
|
const platform6 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
|
|
@@ -411303,12 +411169,12 @@ function findStagedNativeDir2() {
|
|
|
411303
411169
|
const prebuildName = `${platform6}-${arch}`;
|
|
411304
411170
|
const execDir = dirname74(process.execPath);
|
|
411305
411171
|
const nextToBinary = join151(execDir, "runtime", prebuildName);
|
|
411306
|
-
if (
|
|
411172
|
+
if (existsSync117(join151(nextToBinary, "pty.node"))) {
|
|
411307
411173
|
return nextToBinary;
|
|
411308
411174
|
}
|
|
411309
411175
|
if (process.env.FUSION_RUNTIME_DIR) {
|
|
411310
411176
|
const envPath = join151(process.env.FUSION_RUNTIME_DIR, prebuildName);
|
|
411311
|
-
if (
|
|
411177
|
+
if (existsSync117(join151(envPath, "pty.node"))) {
|
|
411312
411178
|
return envPath;
|
|
411313
411179
|
}
|
|
411314
411180
|
}
|
|
@@ -411318,11 +411184,11 @@ function cleanupStaleBunfsLinks() {
|
|
|
411318
411184
|
if (process.platform === "win32") return;
|
|
411319
411185
|
const bunfsRoot = "/$bunfs/root";
|
|
411320
411186
|
try {
|
|
411321
|
-
if (
|
|
411187
|
+
if (existsSync117(bunfsRoot)) {
|
|
411322
411188
|
const stats = lstatSync7(bunfsRoot);
|
|
411323
411189
|
if (stats.isSymbolicLink()) {
|
|
411324
411190
|
const target = readlinkSync5(bunfsRoot);
|
|
411325
|
-
if (target.includes("fn-bunfs-") && !
|
|
411191
|
+
if (target.includes("fn-bunfs-") && !existsSync117(target)) {
|
|
411326
411192
|
rmSync16(bunfsRoot);
|
|
411327
411193
|
console.log("[fn-native-patch] Cleaned up stale /$bunfs/root symlink");
|
|
411328
411194
|
}
|
|
@@ -411350,14 +411216,14 @@ function setupNativeResolution() {
|
|
|
411350
411216
|
mkdirSync25(platformDir, { recursive: true });
|
|
411351
411217
|
const ptyNodeDest = join151(platformDir, "pty.node");
|
|
411352
411218
|
copyFileSync2(join151(nativeDir, "pty.node"), ptyNodeDest);
|
|
411353
|
-
if (
|
|
411219
|
+
if (existsSync117(join151(nativeDir, "spawn-helper"))) {
|
|
411354
411220
|
copyFileSync2(join151(nativeDir, "spawn-helper"), join151(platformDir, "spawn-helper"));
|
|
411355
411221
|
}
|
|
411356
411222
|
process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
|
|
411357
411223
|
if (process.platform !== "win32") {
|
|
411358
411224
|
const bunfsRoot = "/$bunfs/root";
|
|
411359
411225
|
try {
|
|
411360
|
-
if (
|
|
411226
|
+
if (existsSync117(bunfsRoot)) {
|
|
411361
411227
|
const stats = lstatSync7(bunfsRoot);
|
|
411362
411228
|
if (stats.isSymbolicLink()) {
|
|
411363
411229
|
rmSync16(bunfsRoot);
|
|
@@ -411380,7 +411246,7 @@ function setupNativeResolution() {
|
|
|
411380
411246
|
function cleanupNativeResolution() {
|
|
411381
411247
|
if (bunfsSymlinkPath && process.platform !== "win32") {
|
|
411382
411248
|
try {
|
|
411383
|
-
if (
|
|
411249
|
+
if (existsSync117(bunfsSymlinkPath)) {
|
|
411384
411250
|
const stats = lstatSync7(bunfsSymlinkPath);
|
|
411385
411251
|
if (stats.isSymbolicLink()) {
|
|
411386
411252
|
rmSync16(bunfsSymlinkPath);
|
|
@@ -411427,7 +411293,7 @@ var init_native_patch = __esm({
|
|
|
411427
411293
|
|
|
411428
411294
|
// src/bin.ts
|
|
411429
411295
|
init_output();
|
|
411430
|
-
import { existsSync as
|
|
411296
|
+
import { existsSync as existsSync118, mkdtempSync as mkdtempSync5, readFileSync as readFileSync47, symlinkSync as symlinkSync8, writeFileSync as writeFileSync24 } from "node:fs";
|
|
411431
411297
|
import { createRequire as createRequire14 } from "node:module";
|
|
411432
411298
|
import { join as join152, dirname as dirname75, resolve as resolve103 } from "node:path";
|
|
411433
411299
|
import { tmpdir as tmpdir23 } from "node:os";
|
|
@@ -411452,7 +411318,7 @@ function configurePiPackage() {
|
|
|
411452
411318
|
packageJson = JSON.parse(readFileSync47(piPackagePath, "utf-8"));
|
|
411453
411319
|
for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
|
|
411454
411320
|
const source = join152(piPackageDir, entry);
|
|
411455
|
-
if (
|
|
411321
|
+
if (existsSync118(source)) {
|
|
411456
411322
|
symlinkSync8(source, join152(tmp, entry));
|
|
411457
411323
|
}
|
|
411458
411324
|
}
|
|
@@ -411472,7 +411338,7 @@ setInterval(() => {
|
|
|
411472
411338
|
performance4.clearResourceTimings();
|
|
411473
411339
|
}, 1e3).unref();
|
|
411474
411340
|
function loadEnvFile(path14) {
|
|
411475
|
-
if (!
|
|
411341
|
+
if (!existsSync118(path14)) return;
|
|
411476
411342
|
const contents = readFileSync47(path14, "utf-8");
|
|
411477
411343
|
for (const rawLine of contents.split(/\r?\n/)) {
|
|
411478
411344
|
const line2 = rawLine.trim();
|
|
@@ -411995,7 +411861,7 @@ function readOwnCliVersion3() {
|
|
|
411995
411861
|
}
|
|
411996
411862
|
for (let i = 0; i < 8; i += 1) {
|
|
411997
411863
|
const pkgPath = resolve103(currentDir, "package.json");
|
|
411998
|
-
if (
|
|
411864
|
+
if (existsSync118(pkgPath)) {
|
|
411999
411865
|
try {
|
|
412000
411866
|
const parsed = JSON.parse(readFileSync47(pkgPath, "utf-8"));
|
|
412001
411867
|
if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
|