@runfusion/fusion 0.76.0-beta.2 → 0.76.0-beta.3
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 +323 -59
- package/dist/child-process-worker.js +274 -42
- package/dist/client/.vite/manifest.json +273 -273
- package/dist/client/assets/{AgentDetailView-gak4EWTI.js → AgentDetailView-T767kKTg.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-DP1QbZL-.js → AgentPermissionPolicyEditor--u9jyUf2.js} +1 -1
- package/dist/client/assets/{AgentsView-DAMRTKzI.js → AgentsView-6Ifu7qDr.js} +5 -5
- package/dist/client/assets/{ChatView-iE-2gf5P.js → ChatView-BV3lixQi.js} +1 -1
- package/dist/client/assets/{CommandCenter-B6RnkLYm.js → CommandCenter-CSRYoveB.js} +1 -1
- package/dist/client/assets/{DevServerView-DcFL_LzK.js → DevServerView-B9So_oYx.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-CtjqrYoO.js → DirectoryPicker-BhyDL_2m.js} +1 -1
- package/dist/client/assets/{DocumentsView-BkAe2S4H.js → DocumentsView-pbERA7O-.js} +1 -1
- package/dist/client/assets/{EvalsView-CbGA9dMn.js → EvalsView-DJQ4ltCg.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CMgO_S8T.js → ExperimentalAgentOnboardingModal-BwJuzkzB.js} +1 -1
- package/dist/client/assets/{GoalsView-_3P9J5sf.js → GoalsView-B6X5_0Ve.js} +1 -1
- package/dist/client/assets/InsightsView-CJgI0J7S.js +11 -0
- package/dist/client/assets/{InsightsView-Gn5lOBA0.css → InsightsView-DAAXuX4v.css} +1 -1
- package/dist/client/assets/{MemoryView-DwJas8vi.js → MemoryView-BHq1AHPu.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-B_LiW_e9.js → PiExtensionsManager-B8At6fO8.js} +1 -1
- package/dist/client/assets/{PluginManager-BkB6WLQc.js → PluginManager-k7hV7_9e.js} +1 -1
- package/dist/client/assets/{PullRequestView-DcH5tmYc.js → PullRequestView-B1hZFrWo.js} +1 -1
- package/dist/client/assets/{ReportModal-BOEbqtqG.js → ReportModal-C46V_zEa.js} +1 -1
- package/dist/client/assets/{ResearchView-Dp6V42pI.js → ResearchView-D8G85BYN.js} +2 -2
- package/dist/client/assets/{SecretsView-BCqXHB2L.js → SecretsView-CTri9LRK.js} +1 -1
- package/dist/client/assets/{SessionTerminal-CkdoQv4y.js → SessionTerminal-BRf6r4Vp.js} +1 -1
- package/dist/client/assets/SettingsModal-D0RBeZik.js +21 -0
- package/dist/client/assets/{SettingsModal-Dc7YG6KB.js → SettingsModal-rUQcSTJp.js} +1 -1
- package/dist/client/assets/{SettingsTextareaRow-WSkBoAOO.js → SettingsTextareaRow-BirlBcem.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-VTrJAsKd.js → SetupWizardModal-xnCBM9EL.js} +2 -2
- package/dist/client/assets/{SkillsView-CXeXOxfF.js → SkillsView-O5U0ep50.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-DoxLGPRF.js → WorkflowNodeEditor-BX4d2qqF.js} +3 -3
- package/dist/client/assets/{agent-import-generation-upc0yw-M.js → agent-import-generation-DnqVkPkz.js} +1 -1
- package/dist/client/assets/{agentsOrgChartLayout-C3iumMrW.js → agentsOrgChartLayout-CKuzbhFf.js} +1 -1
- package/dist/client/assets/app-B2FwULu2.js +5 -0
- package/dist/client/assets/{app-BA9gw9hx.js → app-B6nJaqAl.js} +2 -2
- package/dist/client/assets/{app-B_lScKc1.js → app-CGXZeIRc.js} +2 -2
- package/dist/client/assets/{app-DG_vjDw5.js → app-CGtkeBF5.js} +3 -3
- package/dist/client/assets/{app-GBgoY-oh.js → app-CNzN1Plu.js} +2 -2
- package/dist/client/assets/{app-B0KFGP8D.js → app-DLs-f5yM.js} +3 -3
- package/dist/client/assets/{app-DeHIOCEP.js → app-DsvtcRUG.js} +2 -2
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-D6jqc3fJ.js → architectureDiagram-3BPJPVTR-gi467xY0.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-DY3AKuPD.js → blockDiagram-GPEHLZMM-B_gpcYiR.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CpD52V4g.js → c4Diagram-AAUBKEIU-DeylEYsQ.js} +1 -1
- package/dist/client/assets/channel-BoE8DeM4.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-CPeIHyAX.js → chunk-2J33WTMH-BL2WY0HN.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-ivAwI4xM.js → chunk-4BX2VUAB-BkLExGMe.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-BtVQ5XaZ.js → chunk-55IACEB6-CSTvCF5T.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-1eap1vDU.js → chunk-727SXJPM-9J8pKk4x.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-B2NB3BW9.js → chunk-AQP2D5EJ-DXC1vPWr.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Hk_smNYv.js → chunk-FMBD7UC4-CFRUb-zD.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-BmGCAojk.js → chunk-ND2GUHAM-B87HFYS8.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-D0aXZ8CV.js → chunk-QZHKN3VN-CTjHiGbd.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-qnbLX_9_.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-qnbLX_9_.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DAbu_gnF.js → cose-bilkent-S5V4N54A-D3Edq3L9.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-BdmLlrDJ.js → dagre-BM42HDAG-CwwbeQfN.js} +1 -1
- package/dist/client/assets/{dashboard-view-CULL1yhL.js → dashboard-view-BLAoW3D4.js} +1 -1
- package/dist/client/assets/{dashboard-view-PRCWCSLm.js → dashboard-view-DAlJxqiJ.js} +1 -1
- package/dist/client/assets/{dashboard-view-BoFBSXUn.js → dashboard-view-QxQwJFLz.js} +1 -1
- package/dist/client/assets/{dashboard-view-CxXMDfNY.js → dashboard-view-aPzfv99T.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-PpqLbVUA.js → diagram-2AECGRRQ-koJWWXE4.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-9rkGmTwh.js → diagram-5GNKFQAL-Yob5cOKT.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BT-efOMo.js → diagram-KO2AKTUF-DelvFSkK.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-w79OWFxg.js → diagram-LMA3HP47-CMput2h2.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-Bye9I5IO.js → diagram-OG6HWLK6-04VXDl79.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-aodREgDf.js → erDiagram-TEJ5UH35-C9iP8Uyp.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-D0DKItY3.js → flowDiagram-I6XJVG4X-DENQvu_t.js} +1 -1
- package/dist/client/assets/{folder-open-CqvaMJvx.js → folder-open-D-554oji.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CZVApkvw.js → ganttDiagram-6RSMTGT7-BqOttZAT.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-D_ynwJ4p.js → gitGraphDiagram-PVQCEYII-CDcydi-5.js} +1 -1
- package/dist/client/assets/{index-BzAldNrK.css → index-CXTd3LAB.css} +1 -1
- package/dist/client/assets/{index-DWRJyaa3.js → index-CtYRoouR.js} +264 -264
- package/dist/client/assets/{infoDiagram-5YYISTIA-pJG6zxjk.js → infoDiagram-5YYISTIA-B5LQQnxt.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-nFZ5laUo.js → ishikawaDiagram-YF4QCWOH-DpFEt7D2.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CWpCaAIe.js → journeyDiagram-JHISSGLW-MELtgu22.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-ATkPspKa.js → kanban-definition-UN3LZRKU-h33PLATd.js} +1 -1
- package/dist/client/assets/{mermaid.core-CDXPNs7a.js → mermaid.core-Dk2mUPOq.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BkqS9tpe.js → mindmap-definition-RKZ34NQL-B_T4O2-B.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DEUyVLs-.js → pieDiagram-4H26LBE5-B1YIFkRl.js} +1 -1
- package/dist/client/assets/{puzzle-DQ0y1-XK.js → puzzle-hvecxlpJ.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-ESBJNK5c.js → quadrantDiagram-W4KKPZXB-BoGQR_hO.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CqPs7zcv.js → requirementDiagram-4Y6WPE33-BSDmUBIx.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CkFN0m14.js → sankeyDiagram-5OEKKPKP-Dz_GqOa5.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Dx2nDuMO.js → sequenceDiagram-3UESZ5HK-B6twjYUH.js} +1 -1
- package/dist/client/assets/{shield-alert-BS05s4RM.js → shield-alert-BX4WRJOv.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-xprxYNHm.js → standing-instructions-template-BJY317CC.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-EUPmRFGd.js → stateDiagram-AJRCARHV-DuwqWLx-.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DcQ2mhi5.js → stateDiagram-v2-BHNVJYJU-Bu8Sk187.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-D4YO_3V-.js → timeline-definition-PNZ67QCA-BS6VnqSI.js} +1 -1
- package/dist/client/assets/{upload-BjyBtxo7.js → upload-CaDoyaMW.js} +1 -1
- package/dist/client/assets/{users-D5ogZ7WQ.js → users-C5uCLwVM.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-BT5_XuQL.js → vennDiagram-CIIHVFJN-CUbzqT5Y.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-X_ZMW457.js → wardley-L42UT6IY-Mv-NotFS.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-GK9nONHU.js → wardleyDiagram-YWT4CUSO-DuYpvLZX.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-Dw3zXHAq.js → xychartDiagram-2RQKCTM6-24_7QXdw.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +285 -47
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.d.ts +23 -0
- package/dist/plugin-sdk/index.js +2 -0
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +2 -0
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/InsightsView-DOhO7xH5.js +0 -11
- package/dist/client/assets/SettingsModal-D4Fn4GlS.js +0 -21
- package/dist/client/assets/app-DBCGrz-f.js +0 -5
- package/dist/client/assets/channel-CaxOu15c.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DXIkGbsl.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DXIkGbsl.js +0 -1
package/dist/extension.js
CHANGED
|
@@ -2067,6 +2067,8 @@ var init_settings_schema = __esm({
|
|
|
2067
2067
|
DEFAULT_PROJECT_SETTINGS = {
|
|
2068
2068
|
// FNXC:TaskRecommendations 2026-08-08-05:02: completion follows-ups stay bounded by default; 0 disables writing them.
|
|
2069
2069
|
maxRecommendationsPerTask: 3,
|
|
2070
|
+
// FNXC:TaskRecommendations 2026-08-13-03:56: surface completed-task proposals by default; operators can suppress the notice without suppressing capture.
|
|
2071
|
+
recommendationMailboxNoticeEnabled: true,
|
|
2070
2072
|
globalPause: false,
|
|
2071
2073
|
globalPauseReason: void 0,
|
|
2072
2074
|
defaultWorkflowId: void 0,
|
|
@@ -68640,20 +68642,32 @@ async function replaceActiveTaskWorkflowContinuation(layer, input) {
|
|
|
68640
68642
|
return upsertWorkflowWorkItem(layer, input, tx);
|
|
68641
68643
|
}));
|
|
68642
68644
|
}
|
|
68643
|
-
async function seedStrandedPlanReviewContinuation(layer, input) {
|
|
68645
|
+
async function seedStrandedPlanReviewContinuation(layer, input, options = {}) {
|
|
68644
68646
|
return layer.transactionImmediate(async (tx) => withTaskWorkflowSerialization(tx, layer.projectId, input.taskId, async () => {
|
|
68645
68647
|
const active2 = await tx.select({ id: project_exports.workflowWorkItems.id }).from(project_exports.workflowWorkItems).where(and(
|
|
68646
68648
|
projectScopeFor(project_exports.workflowWorkItems.projectId, layer.projectId),
|
|
68647
68649
|
eq(project_exports.workflowWorkItems.taskId, input.taskId),
|
|
68648
68650
|
inArray(project_exports.workflowWorkItems.state, [...ACTIVE_WORKFLOW_WORK_ITEM_STATES])
|
|
68649
68651
|
));
|
|
68650
|
-
|
|
68652
|
+
const blocking = options.retirePredecessorId ? active2.filter((row) => row.id !== options.retirePredecessorId) : active2;
|
|
68653
|
+
if (blocking.length > 0) return { seeded: false, reason: "active-continuation" };
|
|
68651
68654
|
const taskRows = await tx.select({ workflowStepResults: project_exports.tasks.workflowStepResults }).from(project_exports.tasks).where(and(
|
|
68652
68655
|
projectScopeFor(project_exports.tasks.projectId, layer.projectId),
|
|
68653
68656
|
eq(project_exports.tasks.id, input.taskId)
|
|
68654
68657
|
)).limit(1);
|
|
68655
68658
|
const results = taskRows[0]?.workflowStepResults;
|
|
68656
68659
|
if (results?.some(isPlanReviewSatisfied)) return { seeded: false, reason: "plan-review-passed" };
|
|
68660
|
+
if (options.retirePredecessorId) {
|
|
68661
|
+
const predRows = await tx.select().from(project_exports.workflowWorkItems).where(and(
|
|
68662
|
+
projectScopeFor(project_exports.workflowWorkItems.projectId, layer.projectId),
|
|
68663
|
+
eq(project_exports.workflowWorkItems.id, options.retirePredecessorId),
|
|
68664
|
+
eq(project_exports.workflowWorkItems.taskId, input.taskId)
|
|
68665
|
+
)).limit(1);
|
|
68666
|
+
const pred = predRows[0];
|
|
68667
|
+
if (pred && !isTerminalWorkflowWorkItemState(normalizeWorkflowWorkItemState(pred.state))) {
|
|
68668
|
+
await transitionWorkflowWorkItem(layer, pred.id, "succeeded", { leaseOwner: null, leaseExpiresAt: null, lastError: null }, tx);
|
|
68669
|
+
}
|
|
68670
|
+
}
|
|
68657
68671
|
const item = await upsertWorkflowWorkItem(layer, input, tx);
|
|
68658
68672
|
return { seeded: true, workItemId: item.id };
|
|
68659
68673
|
}));
|
|
@@ -97031,8 +97045,8 @@ async function upsertWorkflowWorkItemImpl(store, input, tx) {
|
|
|
97031
97045
|
async function replaceActiveTaskWorkflowContinuationImpl(store, input) {
|
|
97032
97046
|
return replaceActiveTaskWorkflowContinuation(store.asyncLayer, input);
|
|
97033
97047
|
}
|
|
97034
|
-
async function seedStrandedPlanReviewContinuationImpl(store, input) {
|
|
97035
|
-
return seedStrandedPlanReviewContinuation(store.asyncLayer, input);
|
|
97048
|
+
async function seedStrandedPlanReviewContinuationImpl(store, input, options = {}) {
|
|
97049
|
+
return seedStrandedPlanReviewContinuation(store.asyncLayer, input, options);
|
|
97036
97050
|
}
|
|
97037
97051
|
async function transitionWorkflowWorkItemImpl(store, id, state, patch = {}, tx) {
|
|
97038
97052
|
return transitionWorkflowWorkItem(store.asyncLayer, id, state, patch, tx);
|
|
@@ -101175,6 +101189,37 @@ async function getTaskVerificationRequestAsyncImpl(store, taskId) {
|
|
|
101175
101189
|
const row = rows[0];
|
|
101176
101190
|
return row ? { taskId: row.taskId, requestId: row.requestId, status: row.status, profile: row.profile, command: row.command, scope: row.scope, requestedBy: row.requestedBy, requestedAt: row.requestedAt, ...row.startedAt ? { startedAt: row.startedAt } : {}, ...row.completedAt ? { completedAt: row.completedAt } : {}, ...row.result ? { result: row.result } : {}, ...row.rejectionReason ? { rejectionReason: row.rejectionReason } : {} } : null;
|
|
101177
101191
|
}
|
|
101192
|
+
async function listTaskRecommendationsImpl(store, options) {
|
|
101193
|
+
const layer = store.asyncLayer;
|
|
101194
|
+
const completeColumns = options?.completeColumns ?? await resolveProjectColumnsForRoles(store, ["complete"]);
|
|
101195
|
+
const rawLimit = options?.limit;
|
|
101196
|
+
const rawOffset = options?.offset;
|
|
101197
|
+
const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? Math.min(200, Math.max(1, Math.trunc(rawLimit))) : 50;
|
|
101198
|
+
const offset = typeof rawOffset === "number" && Number.isFinite(rawOffset) ? Math.max(0, Math.trunc(rawOffset)) : 0;
|
|
101199
|
+
const columns = [...completeColumns];
|
|
101200
|
+
if (columns.length === 0) return { items: [], rowOffset: offset, rowLimit: limit, returnedRowCount: 0, totalRowCount: 0, hasMore: false };
|
|
101201
|
+
const filter = and(
|
|
101202
|
+
taskProjectScope(layer),
|
|
101203
|
+
isNull(project_exports.tasks.deletedAt),
|
|
101204
|
+
inArray(project_exports.tasks.column, columns),
|
|
101205
|
+
isNotNull(project_exports.tasks.recommendations),
|
|
101206
|
+
sql`jsonb_array_length(${project_exports.tasks.recommendations}) > 0`
|
|
101207
|
+
);
|
|
101208
|
+
const [countRows, rows] = await Promise.all([
|
|
101209
|
+
layer.db.select({ count: sql`count(*)` }).from(project_exports.tasks).where(filter),
|
|
101210
|
+
layer.db.select({ id: project_exports.tasks.id, title: project_exports.tasks.title, column: project_exports.tasks.column, updatedAt: project_exports.tasks.updatedAt, recommendations: project_exports.tasks.recommendations }).from(project_exports.tasks).where(filter).orderBy(desc(project_exports.tasks.updatedAt), desc(project_exports.tasks.id)).limit(limit).offset(offset)
|
|
101211
|
+
]);
|
|
101212
|
+
const items = [];
|
|
101213
|
+
for (const row of rows) {
|
|
101214
|
+
if (!Array.isArray(row.recommendations) || row.recommendations.length === 0) continue;
|
|
101215
|
+
for (const recommendation of row.recommendations) {
|
|
101216
|
+
items.push({ taskId: row.id, taskTitle: row.title ?? void 0, taskColumn: row.column, updatedAt: row.updatedAt, recommendation });
|
|
101217
|
+
}
|
|
101218
|
+
}
|
|
101219
|
+
const totalRowCount = Number(countRows[0]?.count ?? 0);
|
|
101220
|
+
const returnedRowCount = rows.length;
|
|
101221
|
+
return { items, rowOffset: offset, rowLimit: limit, returnedRowCount, totalRowCount, hasMore: offset + returnedRowCount < totalRowCount };
|
|
101222
|
+
}
|
|
101178
101223
|
var LEGACY_REVIEW_LANES5, LEGACY_ARCHIVE_LANES2;
|
|
101179
101224
|
var init_reads = __esm({
|
|
101180
101225
|
"../core/src/task-store/reads.ts"() {
|
|
@@ -101197,6 +101242,7 @@ var init_reads = __esm({
|
|
|
101197
101242
|
init_retry_summary();
|
|
101198
101243
|
init_errors3();
|
|
101199
101244
|
init_project_lane_vocabulary();
|
|
101245
|
+
init_data_layer();
|
|
101200
101246
|
init_async_persistence();
|
|
101201
101247
|
init_async_search();
|
|
101202
101248
|
init_async_archive_db();
|
|
@@ -103303,6 +103349,9 @@ var init_store = __esm({
|
|
|
103303
103349
|
async clearWorkflowRunStepInstancesAsync(taskId, keepRunId) {
|
|
103304
103350
|
return clearWorkflowRunStepInstancesAsyncImpl(this, taskId, keepRunId);
|
|
103305
103351
|
}
|
|
103352
|
+
async listTaskRecommendations(options) {
|
|
103353
|
+
return listTaskRecommendationsImpl(this, options);
|
|
103354
|
+
}
|
|
103306
103355
|
async listTasksForGithubTrackingReconcile(options) {
|
|
103307
103356
|
return listTasksForGithubTrackingReconcileImpl(this, options);
|
|
103308
103357
|
}
|
|
@@ -104029,8 +104078,8 @@ var init_store = __esm({
|
|
|
104029
104078
|
async replaceActiveTaskWorkflowContinuation(input) {
|
|
104030
104079
|
return replaceActiveTaskWorkflowContinuationImpl(this, input);
|
|
104031
104080
|
}
|
|
104032
|
-
async seedStrandedPlanReviewContinuation(input) {
|
|
104033
|
-
return seedStrandedPlanReviewContinuationImpl(this, input);
|
|
104081
|
+
async seedStrandedPlanReviewContinuation(input, options = {}) {
|
|
104082
|
+
return seedStrandedPlanReviewContinuationImpl(this, input, options);
|
|
104034
104083
|
}
|
|
104035
104084
|
async transitionWorkflowWorkItem(id, state, patch = {}, tx) {
|
|
104036
104085
|
return transitionWorkflowWorkItemImpl(this, id, state, patch, tx);
|
|
@@ -133168,6 +133217,77 @@ var init_task_timing = __esm({
|
|
|
133168
133217
|
}
|
|
133169
133218
|
});
|
|
133170
133219
|
|
|
133220
|
+
// ../core/src/task-recommendation-notice.ts
|
|
133221
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
133222
|
+
function registerTaskRecommendationNoticeMailbox(store, mailbox) {
|
|
133223
|
+
mailboxes2.set(store, mailbox);
|
|
133224
|
+
return () => {
|
|
133225
|
+
if (mailboxes2.get(store) === mailbox) mailboxes2.delete(store);
|
|
133226
|
+
};
|
|
133227
|
+
}
|
|
133228
|
+
function getTaskRecommendationNoticeMailbox(store) {
|
|
133229
|
+
return mailboxes2.get(store);
|
|
133230
|
+
}
|
|
133231
|
+
function buildTaskRecommendationNoticeContent(task, recommendations) {
|
|
133232
|
+
const title = task.title?.trim();
|
|
133233
|
+
const heading = title ? `## Recommendations from ${task.id} \u2014 ${title}` : `## Recommendations from ${task.id}`;
|
|
133234
|
+
return [
|
|
133235
|
+
heading,
|
|
133236
|
+
"",
|
|
133237
|
+
"These are optional, non-blocking out-of-scope proposals that were **not** executed.",
|
|
133238
|
+
"",
|
|
133239
|
+
...recommendations.map((recommendation) => `- **${recommendation.title}** \u2014 \`${recommendation.category}\`: ${recommendation.description}`),
|
|
133240
|
+
"",
|
|
133241
|
+
`Open ${task.id}'s **Recommendations** tab to review them. **Create task** files one through normal guarded intake.`
|
|
133242
|
+
].join("\n");
|
|
133243
|
+
}
|
|
133244
|
+
function buildTaskRecommendationNoticeIdempotencyKey(taskId, recommendations) {
|
|
133245
|
+
const ids = recommendations.map(({ id }) => id).sort().join("\n");
|
|
133246
|
+
const digest = createHash20("sha256").update(ids, "utf8").digest("hex").slice(0, 16);
|
|
133247
|
+
return `task-recommendation-notice:${taskId}:${digest}`;
|
|
133248
|
+
}
|
|
133249
|
+
async function notifyOperatorOfTaskRecommendations(store, task, recommendations, settings) {
|
|
133250
|
+
try {
|
|
133251
|
+
if (settings.recommendationMailboxNoticeEnabled === false || !recommendations?.length) return false;
|
|
133252
|
+
const mailbox = mailboxes2.get(store);
|
|
133253
|
+
if (!mailbox) return false;
|
|
133254
|
+
await mailbox.sendMessageOnce(
|
|
133255
|
+
{
|
|
133256
|
+
fromId: "system",
|
|
133257
|
+
fromType: "system",
|
|
133258
|
+
toId: DASHBOARD_USER_ID,
|
|
133259
|
+
toType: "user",
|
|
133260
|
+
type: "system",
|
|
133261
|
+
content: buildTaskRecommendationNoticeContent(task, recommendations),
|
|
133262
|
+
metadata: {
|
|
133263
|
+
kind: "task-recommendation-notice",
|
|
133264
|
+
taskId: task.id,
|
|
133265
|
+
recommendationCount: recommendations.length,
|
|
133266
|
+
recommendationIds: recommendations.map(({ id }) => id),
|
|
133267
|
+
categories: recommendations.map(({ category }) => category)
|
|
133268
|
+
}
|
|
133269
|
+
},
|
|
133270
|
+
buildTaskRecommendationNoticeIdempotencyKey(task.id, recommendations)
|
|
133271
|
+
);
|
|
133272
|
+
return true;
|
|
133273
|
+
} catch (error3) {
|
|
133274
|
+
noticeLog2.warn(
|
|
133275
|
+
`Operator recommendation notice failed for ${task.id}: ${error3 instanceof Error ? error3.message : String(error3)}`
|
|
133276
|
+
);
|
|
133277
|
+
return false;
|
|
133278
|
+
}
|
|
133279
|
+
}
|
|
133280
|
+
var noticeLog2, mailboxes2;
|
|
133281
|
+
var init_task_recommendation_notice = __esm({
|
|
133282
|
+
"../core/src/task-recommendation-notice.ts"() {
|
|
133283
|
+
"use strict";
|
|
133284
|
+
init_logger();
|
|
133285
|
+
init_types();
|
|
133286
|
+
noticeLog2 = createLogger("task-recommendation-notice");
|
|
133287
|
+
mailboxes2 = /* @__PURE__ */ new WeakMap();
|
|
133288
|
+
}
|
|
133289
|
+
});
|
|
133290
|
+
|
|
133171
133291
|
// ../core/src/session-identity-registry.ts
|
|
133172
133292
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
133173
133293
|
import { resolve as resolve23 } from "node:path";
|
|
@@ -134017,6 +134137,8 @@ __export(src_exports, {
|
|
|
134017
134137
|
buildTaskDeleteNoticeContent: () => buildTaskDeleteNoticeContent,
|
|
134018
134138
|
buildTaskDeleteNoticeIdempotencyKey: () => buildTaskDeleteNoticeIdempotencyKey,
|
|
134019
134139
|
buildTaskLineageTrailer: () => buildTaskLineageTrailer,
|
|
134140
|
+
buildTaskRecommendationNoticeContent: () => buildTaskRecommendationNoticeContent,
|
|
134141
|
+
buildTaskRecommendationNoticeIdempotencyKey: () => buildTaskRecommendationNoticeIdempotencyKey,
|
|
134020
134142
|
buildToolOutputTruncationMarker: () => buildToolOutputTruncationMarker,
|
|
134021
134143
|
buildTriageHeartbeatGuidance: () => buildTriageHeartbeatGuidance,
|
|
134022
134144
|
buildTriageMemoryInstructions: () => buildTriageMemoryInstructions,
|
|
@@ -134347,6 +134469,7 @@ __export(src_exports, {
|
|
|
134347
134469
|
getTaskMergeBlocker: () => getTaskMergeBlocker,
|
|
134348
134470
|
getTaskMoveDisposer: () => getTaskMoveDisposer,
|
|
134349
134471
|
getTaskPriorityRank: () => getTaskPriorityRank,
|
|
134472
|
+
getTaskRecommendationNoticeMailbox: () => getTaskRecommendationNoticeMailbox,
|
|
134350
134473
|
getTemplatesForRole: () => getTemplatesForRole,
|
|
134351
134474
|
getTotalAgentActiveMs: () => getTotalAgentActiveMs,
|
|
134352
134475
|
getTrait: () => getTrait,
|
|
@@ -134597,6 +134720,7 @@ __export(src_exports, {
|
|
|
134597
134720
|
normalizeWorkflowPromptOverrides: () => normalizeWorkflowPromptOverrides,
|
|
134598
134721
|
normalizeWorkflowReviewFindings: () => normalizeWorkflowReviewFindings,
|
|
134599
134722
|
notifyOperatorOfNonOperatorDelete: () => notifyOperatorOfNonOperatorDelete,
|
|
134723
|
+
notifyOperatorOfTaskRecommendations: () => notifyOperatorOfTaskRecommendations,
|
|
134600
134724
|
overseerAdviceSeverityRank: () => overseerAdviceSeverityRank,
|
|
134601
134725
|
parseAgentManifest: () => parseAgentManifest,
|
|
134602
134726
|
parseCompanyArchive: () => parseCompanyArchive,
|
|
@@ -134706,6 +134830,7 @@ __export(src_exports, {
|
|
|
134706
134830
|
registerStepParser: () => registerStepParser,
|
|
134707
134831
|
registerTaskDeleteNoticeMailbox: () => registerTaskDeleteNoticeMailbox,
|
|
134708
134832
|
registerTaskMoveDisposer: () => registerTaskMoveDisposer,
|
|
134833
|
+
registerTaskRecommendationNoticeMailbox: () => registerTaskRecommendationNoticeMailbox,
|
|
134709
134834
|
registerTraitHookImpl: () => registerTraitHookImpl,
|
|
134710
134835
|
rekeyFallbackProjectPartition: () => rekeyFallbackProjectPartition,
|
|
134711
134836
|
releaseEmbeddedRuntimeLease: () => releaseEmbeddedRuntimeLease,
|
|
@@ -135333,6 +135458,7 @@ var init_src2 = __esm({
|
|
|
135333
135458
|
init_task_document_concurrency();
|
|
135334
135459
|
init_task_delete_attribution();
|
|
135335
135460
|
init_task_delete_notice();
|
|
135461
|
+
init_task_recommendation_notice();
|
|
135336
135462
|
init_session_identity_registry();
|
|
135337
135463
|
init_task_lifecycle_event_retention();
|
|
135338
135464
|
init_task_lifecycle_consumer_identity();
|
|
@@ -135424,7 +135550,7 @@ var init_logger3 = __esm({
|
|
|
135424
135550
|
});
|
|
135425
135551
|
|
|
135426
135552
|
// ../engine/src/agents/agent-logger.ts
|
|
135427
|
-
import { createHash as
|
|
135553
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
135428
135554
|
function truncateToolResultDetail(value) {
|
|
135429
135555
|
if (value.length <= TOOL_RESULT_DETAIL_LIMIT) return value;
|
|
135430
135556
|
return `${value.slice(0, TOOL_RESULT_DETAIL_LIMIT)}${TOOL_RESULT_DETAIL_TRUNCATION_NOTICE}`;
|
|
@@ -135513,7 +135639,7 @@ function summarizeToolArgs(name2, args) {
|
|
|
135513
135639
|
const json2 = JSON.stringify(args);
|
|
135514
135640
|
if (!json2 || json2 === "{}" || json2 === "[]") return void 0;
|
|
135515
135641
|
if (json2.length <= STRUCTURED_ARG_SUMMARY_MAX) return json2;
|
|
135516
|
-
const hash3 =
|
|
135642
|
+
const hash3 = createHash21("sha256").update(json2).digest("hex").slice(0, STRUCTURED_ARG_HASH_HEX_LEN);
|
|
135517
135643
|
const suffix = `\u2026#${hash3}`;
|
|
135518
135644
|
const keep = Math.max(0, STRUCTURED_ARG_SUMMARY_MAX - suffix.length);
|
|
135519
135645
|
return `${json2.slice(0, keep)}${suffix}`;
|
|
@@ -136293,7 +136419,7 @@ var init_gating_classifications = __esm({
|
|
|
136293
136419
|
});
|
|
136294
136420
|
|
|
136295
136421
|
// ../engine/src/agents/agent-action-gate.ts
|
|
136296
|
-
import { createHash as
|
|
136422
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
136297
136423
|
function getExemptTools() {
|
|
136298
136424
|
if (!_exemptTools) {
|
|
136299
136425
|
_exemptTools = new Set(DEFAULT_EXEMPT_TOOLS);
|
|
@@ -136345,7 +136471,7 @@ function evaluateAgentActionGate(params) {
|
|
|
136345
136471
|
if (params.toolName === "bash") {
|
|
136346
136472
|
const command = extractShellCommand(args);
|
|
136347
136473
|
const git7 = classifyGitCommand(command);
|
|
136348
|
-
resourceId = command ? `cmd:${
|
|
136474
|
+
resourceId = command ? `cmd:${createHash22("sha256").update(command).digest("hex").slice(0, 16)}` : void 0;
|
|
136349
136475
|
if (git7?.write) {
|
|
136350
136476
|
category = "git_write";
|
|
136351
136477
|
operation = git7.operation;
|
|
@@ -139877,11 +140003,11 @@ var init_planning_handoff_recovery = __esm({
|
|
|
139877
140003
|
// ../engine/src/plan-review-continuation.ts
|
|
139878
140004
|
async function seedPreReleasePlanReviewContinuation(store, task, ir2, options = {}) {
|
|
139879
140005
|
const node = resolvePreReleasePlanReviewNode(ir2);
|
|
139880
|
-
if (!node || node.column !== task.column) return { seeded: false };
|
|
140006
|
+
if (!node || node.column !== task.column) return { seeded: false, reason: "no-pre-release-plan-review" };
|
|
139881
140007
|
if (isTaskBlockedOnApproval(task)) return { seeded: false, reason: "awaiting-approval" };
|
|
139882
140008
|
if (task.paused === true || task.userPaused === true) return { seeded: false, reason: "paused" };
|
|
139883
140009
|
const items = await store.listWorkflowWorkItemsForTask(task.id);
|
|
139884
|
-
const active2 = items.filter((item2) => ACTIVE_WORKFLOW_WORK_ITEM_STATES.includes(item2.state));
|
|
140010
|
+
const active2 = items.filter((item2) => ACTIVE_WORKFLOW_WORK_ITEM_STATES.includes(item2.state) && item2.id !== options.retirePredecessorId);
|
|
139885
140011
|
if (active2.length > 0) return { seeded: false, reason: "active-continuation" };
|
|
139886
140012
|
const continuationSequence = items.length;
|
|
139887
140013
|
const input = {
|
|
@@ -139897,6 +140023,9 @@ async function seedPreReleasePlanReviewContinuation(store, task, ir2, options =
|
|
|
139897
140023
|
targetColumn: task.column,
|
|
139898
140024
|
irHash: computeWorkflowIrPin(ir2, node.id).irHash
|
|
139899
140025
|
};
|
|
140026
|
+
if (options.retirePredecessorId) {
|
|
140027
|
+
return store.seedStrandedPlanReviewContinuation(input, { retirePredecessorId: options.retirePredecessorId });
|
|
140028
|
+
}
|
|
139900
140029
|
if (options.atomic) return store.seedStrandedPlanReviewContinuation(input);
|
|
139901
140030
|
const item = await store.replaceActiveTaskWorkflowContinuation(input);
|
|
139902
140031
|
return { seeded: true, workItemId: item.id };
|
|
@@ -139911,7 +140040,7 @@ async function resumeApprovedPlanReviewHandoff(store, task, ir2) {
|
|
|
139911
140040
|
if (seeded.seeded) return { resumed: true, reason: "seeded", workItemId: seeded.workItemId };
|
|
139912
140041
|
return {
|
|
139913
140042
|
resumed: false,
|
|
139914
|
-
reason: seeded.reason
|
|
140043
|
+
reason: seeded.reason === void 0 || seeded.reason === "no-pre-release-plan-review" ? "not-plan-in-place" : seeded.reason
|
|
139915
140044
|
};
|
|
139916
140045
|
}
|
|
139917
140046
|
function evaluateStrandedHoldContinuation(input) {
|
|
@@ -139949,7 +140078,7 @@ var init_plan_review_continuation = __esm({
|
|
|
139949
140078
|
});
|
|
139950
140079
|
|
|
139951
140080
|
// ../engine/src/execution/hold-release.ts
|
|
139952
|
-
import { createHash as
|
|
140081
|
+
import { createHash as createHash23 } from "node:crypto";
|
|
139953
140082
|
import { readFile as readFile31 } from "node:fs/promises";
|
|
139954
140083
|
function findColumn2(ir2, columnId) {
|
|
139955
140084
|
if (ir2.version !== "v2") return void 0;
|
|
@@ -139987,9 +140116,9 @@ async function checkAndRecordUnplannedExecutionBlock(store, task, ir2) {
|
|
|
139987
140116
|
promptContent = "";
|
|
139988
140117
|
}
|
|
139989
140118
|
}
|
|
139990
|
-
const promptMarker = promptContent.length > 0 ?
|
|
140119
|
+
const promptMarker = promptContent.length > 0 ? createHash23("sha256").update(promptContent).digest("hex") : "missing";
|
|
139991
140120
|
const dependencies = [...task.dependencies ?? []].sort();
|
|
139992
|
-
const episode =
|
|
140121
|
+
const episode = createHash23("sha256").update(JSON.stringify({
|
|
139993
140122
|
planReviewNode,
|
|
139994
140123
|
promptMarker,
|
|
139995
140124
|
dependencies,
|
|
@@ -170109,7 +170238,7 @@ ${getErrorStderr(error3) ?? ""}`;
|
|
|
170109
170238
|
});
|
|
170110
170239
|
|
|
170111
170240
|
// ../engine/src/worktree/secrets-env-writer.ts
|
|
170112
|
-
import { createHash as
|
|
170241
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
170113
170242
|
import { execFile as execFile8 } from "node:child_process";
|
|
170114
170243
|
import { promises as fs6 } from "node:fs";
|
|
170115
170244
|
import path2 from "node:path";
|
|
@@ -170118,7 +170247,7 @@ function isValidFilename(filename) {
|
|
|
170118
170247
|
return !!filename && !filename.includes("/") && !filename.includes("\\") && !filename.includes("..") && !filename.includes("\0") && filename !== FINGERPRINT_FILE;
|
|
170119
170248
|
}
|
|
170120
170249
|
function sha2562(content) {
|
|
170121
|
-
return
|
|
170250
|
+
return createHash24("sha256").update(Buffer.from(content, "utf8")).digest("hex");
|
|
170122
170251
|
}
|
|
170123
170252
|
function quote(value) {
|
|
170124
170253
|
return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll(" ", "\\t")}"`;
|
|
@@ -178525,7 +178654,7 @@ var init_mission_feature_sync = __esm({
|
|
|
178525
178654
|
// ../engine/src/agent-tools.ts
|
|
178526
178655
|
import { appendFile as appendFile3, mkdir as mkdir28, readFile as readFile38, readdir as readdir11, realpath as realpath2, stat as stat11, writeFile as writeFile26 } from "node:fs/promises";
|
|
178527
178656
|
import { existsSync as existsSync52 } from "node:fs";
|
|
178528
|
-
import { createHash as
|
|
178657
|
+
import { createHash as createHash25, randomUUID as randomUUID46 } from "node:crypto";
|
|
178529
178658
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
178530
178659
|
import { extname as extname4, isAbsolute as isAbsolute14, join as join66, relative as relative14, resolve as resolve37, sep as sep10 } from "node:path";
|
|
178531
178660
|
import { Type as Type2 } from "@earendil-works/pi-ai";
|
|
@@ -178569,7 +178698,7 @@ async function readAgentMemoryWorkspaceLongTerm(rootDir, agentId) {
|
|
|
178569
178698
|
}
|
|
178570
178699
|
}
|
|
178571
178700
|
function qmdAgentMemoryCollectionName2(rootDir, agentId) {
|
|
178572
|
-
const hash3 =
|
|
178701
|
+
const hash3 = createHash25("sha1").update(`${rootDir}:${agentId}`).digest("hex").slice(0, 12);
|
|
178573
178702
|
return `fusion-agent-memory-${sanitizeAgentMemoryId(agentId).toLowerCase()}-${hash3}`;
|
|
178574
178703
|
}
|
|
178575
178704
|
function buildQmdAgentMemoryCollectionAddArgs(rootDir, agentId) {
|
|
@@ -190146,7 +190275,7 @@ var init_agent_heartbeat_error_recovery = __esm({
|
|
|
190146
190275
|
|
|
190147
190276
|
// ../engine/src/agent-heartbeat.ts
|
|
190148
190277
|
import { Type as Type3 } from "@earendil-works/pi-ai";
|
|
190149
|
-
import { createHash as
|
|
190278
|
+
import { createHash as createHash26 } from "node:crypto";
|
|
190150
190279
|
async function resolveHeartbeatReboundColumn(taskStore, taskId) {
|
|
190151
190280
|
try {
|
|
190152
190281
|
return resolveReboundTarget(await resolveWorkflowIrForTask(taskStore, taskId)) ?? "todo";
|
|
@@ -190301,7 +190430,7 @@ function truncatePrompt(text2, maxChars) {
|
|
|
190301
190430
|
... (truncated, ${text2.length} chars)`;
|
|
190302
190431
|
}
|
|
190303
190432
|
function shortContentHash(value) {
|
|
190304
|
-
return
|
|
190433
|
+
return createHash26("sha256").update(value).digest("hex").slice(0, 8);
|
|
190305
190434
|
}
|
|
190306
190435
|
function buildIdentitySnapshot(args) {
|
|
190307
190436
|
const { agent, resolvedInstructions, workspaceMemory } = args;
|
|
@@ -198190,7 +198319,7 @@ var init_verification_utils = __esm({
|
|
|
198190
198319
|
|
|
198191
198320
|
// ../engine/src/merge/merge-dependency-sync.ts
|
|
198192
198321
|
import { exec as exec25 } from "node:child_process";
|
|
198193
|
-
import { createHash as
|
|
198322
|
+
import { createHash as createHash27 } from "node:crypto";
|
|
198194
198323
|
import { existsSync as existsSync55, readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "node:fs";
|
|
198195
198324
|
import { join as join69 } from "node:path";
|
|
198196
198325
|
import { promisify as promisify35 } from "node:util";
|
|
@@ -198217,7 +198346,7 @@ function computeLockfileHash(rootDir) {
|
|
|
198217
198346
|
const p2 = join69(rootDir, name2);
|
|
198218
198347
|
if (existsSync55(p2)) {
|
|
198219
198348
|
try {
|
|
198220
|
-
return
|
|
198349
|
+
return createHash27("sha256").update(readFileSync17(p2)).digest("hex");
|
|
198221
198350
|
} catch {
|
|
198222
198351
|
return null;
|
|
198223
198352
|
}
|
|
@@ -200759,7 +200888,7 @@ var init_mesh_lease_manager = __esm({
|
|
|
200759
200888
|
});
|
|
200760
200889
|
|
|
200761
200890
|
// ../engine/src/merge/merger-integration-worktree.ts
|
|
200762
|
-
import { createHash as
|
|
200891
|
+
import { createHash as createHash28 } from "node:crypto";
|
|
200763
200892
|
import { exec as exec31, execFile as execFile22 } from "node:child_process";
|
|
200764
200893
|
import { promisify as promisify45 } from "node:util";
|
|
200765
200894
|
function quoteAutostashArg(value) {
|
|
@@ -200882,7 +201011,7 @@ async function gitDirtyFingerprintLocal(rootDir) {
|
|
|
200882
201011
|
)
|
|
200883
201012
|
]);
|
|
200884
201013
|
if (!diffOut && !statusOut) return "";
|
|
200885
|
-
return
|
|
201014
|
+
return createHash28("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
200886
201015
|
} catch {
|
|
200887
201016
|
return "";
|
|
200888
201017
|
}
|
|
@@ -201868,7 +201997,7 @@ import { execSync as execSync5, exec as exec33 } from "node:child_process";
|
|
|
201868
201997
|
import * as childProcess4 from "node:child_process";
|
|
201869
201998
|
import { promisify as promisify48 } from "node:util";
|
|
201870
201999
|
import { existsSync as existsSync58, readFileSync as readFileSync20, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
201871
|
-
import { createHash as
|
|
202000
|
+
import { createHash as createHash29 } from "node:crypto";
|
|
201872
202001
|
import { join as join73, resolve as resolve43 } from "node:path";
|
|
201873
202002
|
import { hostname as hostname2 } from "node:os";
|
|
201874
202003
|
import { Type as Type4 } from "typebox";
|
|
@@ -202116,7 +202245,7 @@ async function gitDirtyFingerprint(rootDir) {
|
|
|
202116
202245
|
)
|
|
202117
202246
|
]);
|
|
202118
202247
|
if (!diffOut && !statusOut) return "";
|
|
202119
|
-
return
|
|
202248
|
+
return createHash29("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
202120
202249
|
} catch {
|
|
202121
202250
|
return "";
|
|
202122
202251
|
}
|
|
@@ -224539,7 +224668,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
224539
224668
|
}
|
|
224540
224669
|
return;
|
|
224541
224670
|
}
|
|
224542
|
-
const duplicateReport = { outcome: "parked" };
|
|
224671
|
+
const duplicateReport = { outcome: "parked", planningWorkItemId };
|
|
224543
224672
|
if (await this.tryFinalizeExplicitDuplicateMarker(task, written, settings, {
|
|
224544
224673
|
isReplan,
|
|
224545
224674
|
feedback
|
|
@@ -224558,6 +224687,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
224558
224687
|
isReplan,
|
|
224559
224688
|
feedback
|
|
224560
224689
|
});
|
|
224690
|
+
finalizeReport.planningWorkItemId = planningWorkItemId;
|
|
224561
224691
|
this.options.onSpecifyComplete?.(task, finalizeReport);
|
|
224562
224692
|
} finally {
|
|
224563
224693
|
this.activeSessions.delete(task.id);
|
|
@@ -240129,6 +240259,38 @@ var init_execution_block_classifier = __esm({
|
|
|
240129
240259
|
}
|
|
240130
240260
|
});
|
|
240131
240261
|
|
|
240262
|
+
// ../engine/src/executor/completion-recommendation-notice.ts
|
|
240263
|
+
function dispatchAcceptedCompletionRecommendationNotice(args) {
|
|
240264
|
+
if (!args.recommendations?.length) return;
|
|
240265
|
+
const pending = (async () => {
|
|
240266
|
+
const settings = args.settings ?? await args.store.getSettings();
|
|
240267
|
+
const task = await args.store.getTask(args.taskId);
|
|
240268
|
+
if (!task || task.deletedAt) return;
|
|
240269
|
+
await notifyOperatorOfTaskRecommendations(
|
|
240270
|
+
args.store,
|
|
240271
|
+
{ id: args.taskId, title: args.taskTitle ?? task.title },
|
|
240272
|
+
args.recommendations,
|
|
240273
|
+
settings
|
|
240274
|
+
);
|
|
240275
|
+
})();
|
|
240276
|
+
pendingNotices.add(pending);
|
|
240277
|
+
void pending.catch((error3) => {
|
|
240278
|
+
args.log?.warn(
|
|
240279
|
+
`Failed to dispatch recommendation mailbox notice for ${args.taskId}: ${error3 instanceof Error ? error3.message : String(error3)}`
|
|
240280
|
+
);
|
|
240281
|
+
}).finally(() => {
|
|
240282
|
+
pendingNotices.delete(pending);
|
|
240283
|
+
});
|
|
240284
|
+
}
|
|
240285
|
+
var pendingNotices;
|
|
240286
|
+
var init_completion_recommendation_notice = __esm({
|
|
240287
|
+
"../engine/src/executor/completion-recommendation-notice.ts"() {
|
|
240288
|
+
"use strict";
|
|
240289
|
+
init_src2();
|
|
240290
|
+
pendingNotices = /* @__PURE__ */ new Set();
|
|
240291
|
+
}
|
|
240292
|
+
});
|
|
240293
|
+
|
|
240132
240294
|
// ../engine/src/executor/create-task-done-tool.ts
|
|
240133
240295
|
import { Type as Type9 } from "@earendil-works/pi-ai";
|
|
240134
240296
|
function createTaskDoneTool(deps, taskId, worktreePath, promptContent, codeReviewVerdicts, onDone, audit) {
|
|
@@ -240465,6 +240627,16 @@ ${rerunSuffix}`
|
|
|
240465
240627
|
bulkCompletionRefusalAt: null
|
|
240466
240628
|
});
|
|
240467
240629
|
await store.logEntry(taskId, "Task marked done by agent", void 0, deps.getRunContextFor(taskId));
|
|
240630
|
+
if (completionRecommendations !== void 0) {
|
|
240631
|
+
dispatchAcceptedCompletionRecommendationNotice({
|
|
240632
|
+
store,
|
|
240633
|
+
taskId,
|
|
240634
|
+
taskTitle: task.title,
|
|
240635
|
+
recommendations: completionRecommendations,
|
|
240636
|
+
settings,
|
|
240637
|
+
log: executorLog
|
|
240638
|
+
});
|
|
240639
|
+
}
|
|
240468
240640
|
const latestTask = await store.getTask(taskId);
|
|
240469
240641
|
let latestColumn = latestTask.column;
|
|
240470
240642
|
if (latestColumn === await resolveReboundColumnFor(store, taskId)) {
|
|
@@ -240503,6 +240675,7 @@ var init_create_task_done_tool = __esm({
|
|
|
240503
240675
|
init_completion_predicates();
|
|
240504
240676
|
init_task_done_refusal_handler();
|
|
240505
240677
|
init_validate_completion_recommendations();
|
|
240678
|
+
init_completion_recommendation_notice();
|
|
240506
240679
|
}
|
|
240507
240680
|
});
|
|
240508
240681
|
|
|
@@ -251829,6 +252002,16 @@ ${rerunSuffix}` });
|
|
|
251829
252002
|
if (latestColumn === await resolveWipTargetForTask(deps.store, task.id) && !hardPauseActive && beforeWatchdog && !beforeWatchdog.deletedAt && !(rejectIfPaused && (beforeWatchdog.paused || beforeWatchdog.userPaused))) {
|
|
251830
252003
|
deps.scheduleCompletedTaskWatchdog(task.id, "fn_task_done");
|
|
251831
252004
|
}
|
|
252005
|
+
if (recommendations !== void 0) {
|
|
252006
|
+
dispatchAcceptedCompletionRecommendationNotice({
|
|
252007
|
+
store: deps.store,
|
|
252008
|
+
taskId: task.id,
|
|
252009
|
+
taskTitle: task.title,
|
|
252010
|
+
recommendations,
|
|
252011
|
+
settings,
|
|
252012
|
+
log: executorLog
|
|
252013
|
+
});
|
|
252014
|
+
}
|
|
251832
252015
|
return { completed: true, hardPauseActive };
|
|
251833
252016
|
} catch (error3) {
|
|
251834
252017
|
await restoreNoCommitsExpected();
|
|
@@ -251887,6 +252070,7 @@ var init_plan_review_no_op = __esm({
|
|
|
251887
252070
|
init_src2();
|
|
251888
252071
|
init_logger3();
|
|
251889
252072
|
init_lifecycle_columns();
|
|
252073
|
+
init_completion_recommendation_notice();
|
|
251890
252074
|
}
|
|
251891
252075
|
});
|
|
251892
252076
|
|
|
@@ -255395,14 +255579,14 @@ ${stdout.trim()}`);
|
|
|
255395
255579
|
|
|
255396
255580
|
// ../engine/src/missions/mission-execution-loop.ts
|
|
255397
255581
|
import { EventEmitter as EventEmitter25 } from "node:events";
|
|
255398
|
-
import { createHash as
|
|
255582
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
255399
255583
|
import { exec as exec56 } from "node:child_process";
|
|
255400
255584
|
import { promisify as promisify74 } from "node:util";
|
|
255401
255585
|
function quoteShellArg7(value) {
|
|
255402
255586
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
255403
255587
|
}
|
|
255404
255588
|
function fingerprintMissionValidationInput(landedSha, provider, modelId, systemPrompt, userPrompt) {
|
|
255405
|
-
return
|
|
255589
|
+
return createHash30("sha256").update(Buffer.from(JSON.stringify(["mission-validation-input-v1", landedSha, provider, modelId, systemPrompt, userPrompt]), "utf8")).digest("hex");
|
|
255406
255590
|
}
|
|
255407
255591
|
var execAsync53, loopLog, VALIDATION_TIMEOUT_MS, MAX_VALIDATION_RESPONSE_BYTES, MAX_VALIDATION_JSON_CANDIDATES, VALIDATION_FAILURE_BUDGET_PER_FINGERPRINT, MissionExecutionLoop;
|
|
255408
255592
|
var init_mission_execution_loop = __esm({
|
|
@@ -266941,9 +267125,9 @@ var init_routine_scheduler = __esm({
|
|
|
266941
267125
|
});
|
|
266942
267126
|
|
|
266943
267127
|
// ../engine/src/healing/stuck-task-detector.ts
|
|
266944
|
-
import { createHash as
|
|
267128
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
266945
267129
|
function hashToolDetail(detail) {
|
|
266946
|
-
return
|
|
267130
|
+
return createHash31("sha256").update(detail).digest("hex").slice(0, TOOL_DETAIL_HASH_HEX_LEN);
|
|
266947
267131
|
}
|
|
266948
267132
|
function buildToolFingerprint(toolName, toolDetail) {
|
|
266949
267133
|
const name2 = toolName.trim().toLowerCase() || "tool";
|
|
@@ -270521,7 +270705,7 @@ var init_node_dispatch_validation = __esm({
|
|
|
270521
270705
|
});
|
|
270522
270706
|
|
|
270523
270707
|
// ../engine/src/runtimes/in-process-runtime.ts
|
|
270524
|
-
import { createHash as
|
|
270708
|
+
import { createHash as createHash32 } from "node:crypto";
|
|
270525
270709
|
import { EventEmitter as EventEmitter26 } from "node:events";
|
|
270526
270710
|
import { setImmediate as setImmediateCb4 } from "node:timers";
|
|
270527
270711
|
function createDiscoveryPluginLoaderOptions(scopedStore) {
|
|
@@ -270612,11 +270796,46 @@ async function reactToSpecificationComplete(deps) {
|
|
|
270612
270796
|
return;
|
|
270613
270797
|
}
|
|
270614
270798
|
deps.log(`Specified ${deps.taskId} \u2192 todo`);
|
|
270615
|
-
const
|
|
270616
|
-
|
|
270617
|
-
|
|
270618
|
-
|
|
270619
|
-
|
|
270799
|
+
const sleep9 = deps.sleep ?? ((ms2) => new Promise((resolve60) => setTimeout(resolve60, ms2)));
|
|
270800
|
+
const QUIET_PARK_REASONS = /* @__PURE__ */ new Set([
|
|
270801
|
+
"no-pre-release-plan-review",
|
|
270802
|
+
"awaiting-approval",
|
|
270803
|
+
"paused",
|
|
270804
|
+
"plan-review-passed"
|
|
270805
|
+
]);
|
|
270806
|
+
const RETRY_DELAYS_MS2 = [1e3, 5e3];
|
|
270807
|
+
for (let attempt = 0; ; attempt++) {
|
|
270808
|
+
let failure = null;
|
|
270809
|
+
try {
|
|
270810
|
+
const live = await deps.getTask(deps.taskId);
|
|
270811
|
+
if (!live || live.paused || live.userPaused) return;
|
|
270812
|
+
if (live.status === "needs-replan") {
|
|
270813
|
+
deps.log(`Plan Review handoff for ${deps.taskId} not armed (needs-replan)`);
|
|
270814
|
+
return;
|
|
270815
|
+
}
|
|
270816
|
+
const ir2 = await deps.resolveIr(live.id);
|
|
270817
|
+
const result2 = await deps.seed(live, ir2);
|
|
270818
|
+
if (result2.seeded) {
|
|
270819
|
+
deps.kick();
|
|
270820
|
+
return;
|
|
270821
|
+
}
|
|
270822
|
+
if (result2.reason && QUIET_PARK_REASONS.has(result2.reason)) {
|
|
270823
|
+
deps.log(`Plan Review handoff for ${deps.taskId} not armed (${result2.reason})`);
|
|
270824
|
+
return;
|
|
270825
|
+
}
|
|
270826
|
+
failure = result2.reason ?? "not-seeded";
|
|
270827
|
+
} catch (error3) {
|
|
270828
|
+
failure = error3 instanceof Error ? error3.message : String(error3);
|
|
270829
|
+
}
|
|
270830
|
+
if (attempt >= RETRY_DELAYS_MS2.length) {
|
|
270831
|
+
deps.warn(
|
|
270832
|
+
`Plan Review handoff for ${deps.taskId} failed after ${attempt + 1} attempts (${failure}) \u2014 stranded-continuation self-healing will recover it`
|
|
270833
|
+
);
|
|
270834
|
+
return;
|
|
270835
|
+
}
|
|
270836
|
+
deps.warn(`Plan Review handoff for ${deps.taskId} did not seed (${failure}) \u2014 retrying`);
|
|
270837
|
+
await sleep9(RETRY_DELAYS_MS2[attempt]);
|
|
270838
|
+
}
|
|
270620
270839
|
}
|
|
270621
270840
|
async function drainDuePlanningContinuations(deps) {
|
|
270622
270841
|
const items = await deps.listDue();
|
|
@@ -270751,7 +270970,7 @@ function stableNotificationJson(value) {
|
|
|
270751
270970
|
return `{${fields.join(",")}}`;
|
|
270752
270971
|
}
|
|
270753
270972
|
function buildCliAgentNotificationDedupeKey(input) {
|
|
270754
|
-
const notificationFingerprint =
|
|
270973
|
+
const notificationFingerprint = createHash32("sha256").update(stableNotificationJson(input.info.notification ?? null)).digest("hex").slice(0, 16);
|
|
270755
270974
|
const waitingEpoch = input.session?.updatedAt ?? "unknown-waiting-epoch";
|
|
270756
270975
|
return [
|
|
270757
270976
|
"cli-agent",
|
|
@@ -270906,6 +271125,8 @@ var init_in_process_runtime = __esm({
|
|
|
270906
271125
|
messageStore;
|
|
270907
271126
|
/** FNXC:TaskDeleteNotice 2026-07-26-16:10: identity-guarded teardown for the delete-notice mailbox seam. */
|
|
270908
271127
|
unregisterTaskDeleteNoticeMailbox;
|
|
271128
|
+
/** FNXC:TaskRecommendations 2026-08-13-03:56: identity-guarded teardown for the store-scoped recommendation notice seam. */
|
|
271129
|
+
unregisterTaskRecommendationNoticeMailbox;
|
|
270909
271130
|
chatStore;
|
|
270910
271131
|
detachAgentLinkSync;
|
|
270911
271132
|
/**
|
|
@@ -270964,7 +271185,8 @@ var init_in_process_runtime = __esm({
|
|
|
270964
271185
|
createTaskStoreForBackend: createTaskStoreForBackend2,
|
|
270965
271186
|
buildConsumerId: buildConsumerId2,
|
|
270966
271187
|
createProjectScopedPluginMcpProvider: createProjectScopedPluginMcpProvider2,
|
|
270967
|
-
registerTaskDeleteNoticeMailbox: registerTaskDeleteNoticeMailbox2
|
|
271188
|
+
registerTaskDeleteNoticeMailbox: registerTaskDeleteNoticeMailbox2,
|
|
271189
|
+
registerTaskRecommendationNoticeMailbox: registerTaskRecommendationNoticeMailbox2
|
|
270968
271190
|
} = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
270969
271191
|
if (this.config.externalTaskStore) {
|
|
270970
271192
|
this.taskStore = this.config.externalTaskStore;
|
|
@@ -271023,6 +271245,10 @@ var init_in_process_runtime = __esm({
|
|
|
271023
271245
|
this.taskStore,
|
|
271024
271246
|
this.messageStore
|
|
271025
271247
|
);
|
|
271248
|
+
this.unregisterTaskRecommendationNoticeMailbox = registerTaskRecommendationNoticeMailbox2(
|
|
271249
|
+
this.taskStore,
|
|
271250
|
+
this.messageStore
|
|
271251
|
+
);
|
|
271026
271252
|
await yieldEventLoop4();
|
|
271027
271253
|
const pluginLayer = this.taskStore.getAsyncLayer();
|
|
271028
271254
|
if (!pluginLayer) {
|
|
@@ -271514,9 +271740,19 @@ var init_in_process_runtime = __esm({
|
|
|
271514
271740
|
outcome: report2.outcome,
|
|
271515
271741
|
getTask: (id) => Promise.resolve(this.taskStore.getTask(id)),
|
|
271516
271742
|
resolveIr: (id) => resolveWorkflowIrForTask(this.taskStore, id),
|
|
271517
|
-
|
|
271743
|
+
/*
|
|
271744
|
+
FNXC:PlanningHandoffAtomicity 2026-08-13-03:49:
|
|
271745
|
+
The report carries the planning session's own durable work item id so the
|
|
271746
|
+
seeder can retire that exact predecessor row atomically with the successor
|
|
271747
|
+
install. Without it the seeder raced triage's finally-block terminal
|
|
271748
|
+
transition and bailed on its own caller (529 stranded cards in 18 days).
|
|
271749
|
+
*/
|
|
271750
|
+
seed: (task, ir2) => seedPreReleasePlanReviewContinuation(this.taskStore, task, ir2, {
|
|
271751
|
+
retirePredecessorId: report2.planningWorkItemId
|
|
271752
|
+
}),
|
|
271518
271753
|
kick: () => this.kickWorkflowContinuationProcessor(),
|
|
271519
|
-
log: (message) => runtimeLog.log(message)
|
|
271754
|
+
log: (message) => runtimeLog.log(message),
|
|
271755
|
+
warn: (message) => runtimeLog.warn(message)
|
|
271520
271756
|
}).catch((error3) => {
|
|
271521
271757
|
runtimeLog.error(`Failed to start Todo plan review for ${t.id}:`, error3);
|
|
271522
271758
|
});
|
|
@@ -271804,6 +272040,8 @@ var init_in_process_runtime = __esm({
|
|
|
271804
272040
|
this.backendShutdown = void 0;
|
|
271805
272041
|
this.unregisterTaskDeleteNoticeMailbox?.();
|
|
271806
272042
|
this.unregisterTaskDeleteNoticeMailbox = void 0;
|
|
272043
|
+
this.unregisterTaskRecommendationNoticeMailbox?.();
|
|
272044
|
+
this.unregisterTaskRecommendationNoticeMailbox = void 0;
|
|
271807
272045
|
let stopError;
|
|
271808
272046
|
try {
|
|
271809
272047
|
if (this.workflowContinuationTimer) {
|
|
@@ -279597,9 +279835,9 @@ import { access as access10, unlink as unlink11, writeFile as writeFile33 } from
|
|
|
279597
279835
|
import net2 from "node:net";
|
|
279598
279836
|
import { platform as platform3, tmpdir as tmpdir12 } from "node:os";
|
|
279599
279837
|
import { join as join91 } from "node:path";
|
|
279600
|
-
import { createHash as
|
|
279838
|
+
import { createHash as createHash33 } from "node:crypto";
|
|
279601
279839
|
function projectHash(projectId2) {
|
|
279602
|
-
return
|
|
279840
|
+
return createHash33("sha1").update(projectId2).digest("hex").slice(0, 16);
|
|
279603
279841
|
}
|
|
279604
279842
|
function computeEngineSocketPath(projectId2) {
|
|
279605
279843
|
const hash3 = projectHash(projectId2);
|
|
@@ -308333,7 +308571,7 @@ var init_types5 = __esm({
|
|
|
308333
308571
|
});
|
|
308334
308572
|
|
|
308335
308573
|
// ../dashboard/src/stt/model-manager.ts
|
|
308336
|
-
import { createHash as
|
|
308574
|
+
import { createHash as createHash34, randomUUID as randomUUID57 } from "node:crypto";
|
|
308337
308575
|
import { mkdir as mkdir33, open as open4, readFile as readFile53, readdir as readdir13, rename as rename12, rm as rm20, stat as stat14, writeFile as writeFile35 } from "node:fs/promises";
|
|
308338
308576
|
import { join as join109, relative as relative23, resolve as resolve57, sep as sep17 } from "node:path";
|
|
308339
308577
|
function parseSafeTarListing(listing) {
|
|
@@ -308422,7 +308660,7 @@ function createVoiceModelManager(options = {}) {
|
|
|
308422
308660
|
if (!response.ok || !response.body) throw Object.assign(new Error("download failed"), { voiceReason: "network" });
|
|
308423
308661
|
if (!current(g2, signal)) return state;
|
|
308424
308662
|
const total = Number(response.headers.get("content-length")) || void 0;
|
|
308425
|
-
const hash3 =
|
|
308663
|
+
const hash3 = createHash34("sha256");
|
|
308426
308664
|
let bytes = 0;
|
|
308427
308665
|
for await (const chunk of response.body) {
|
|
308428
308666
|
if (!current(g2, signal)) return state;
|