@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
|
@@ -2145,6 +2145,8 @@ var init_settings_schema = __esm({
|
|
|
2145
2145
|
DEFAULT_PROJECT_SETTINGS = {
|
|
2146
2146
|
// FNXC:TaskRecommendations 2026-08-08-05:02: completion follows-ups stay bounded by default; 0 disables writing them.
|
|
2147
2147
|
maxRecommendationsPerTask: 3,
|
|
2148
|
+
// FNXC:TaskRecommendations 2026-08-13-03:56: surface completed-task proposals by default; operators can suppress the notice without suppressing capture.
|
|
2149
|
+
recommendationMailboxNoticeEnabled: true,
|
|
2148
2150
|
globalPause: false,
|
|
2149
2151
|
globalPauseReason: void 0,
|
|
2150
2152
|
defaultWorkflowId: void 0,
|
|
@@ -68718,20 +68720,32 @@ async function replaceActiveTaskWorkflowContinuation(layer, input) {
|
|
|
68718
68720
|
return upsertWorkflowWorkItem(layer, input, tx);
|
|
68719
68721
|
}));
|
|
68720
68722
|
}
|
|
68721
|
-
async function seedStrandedPlanReviewContinuation(layer, input) {
|
|
68723
|
+
async function seedStrandedPlanReviewContinuation(layer, input, options = {}) {
|
|
68722
68724
|
return layer.transactionImmediate(async (tx) => withTaskWorkflowSerialization(tx, layer.projectId, input.taskId, async () => {
|
|
68723
68725
|
const active2 = await tx.select({ id: project_exports.workflowWorkItems.id }).from(project_exports.workflowWorkItems).where(and(
|
|
68724
68726
|
projectScopeFor(project_exports.workflowWorkItems.projectId, layer.projectId),
|
|
68725
68727
|
eq(project_exports.workflowWorkItems.taskId, input.taskId),
|
|
68726
68728
|
inArray(project_exports.workflowWorkItems.state, [...ACTIVE_WORKFLOW_WORK_ITEM_STATES])
|
|
68727
68729
|
));
|
|
68728
|
-
|
|
68730
|
+
const blocking = options.retirePredecessorId ? active2.filter((row) => row.id !== options.retirePredecessorId) : active2;
|
|
68731
|
+
if (blocking.length > 0) return { seeded: false, reason: "active-continuation" };
|
|
68729
68732
|
const taskRows = await tx.select({ workflowStepResults: project_exports.tasks.workflowStepResults }).from(project_exports.tasks).where(and(
|
|
68730
68733
|
projectScopeFor(project_exports.tasks.projectId, layer.projectId),
|
|
68731
68734
|
eq(project_exports.tasks.id, input.taskId)
|
|
68732
68735
|
)).limit(1);
|
|
68733
68736
|
const results = taskRows[0]?.workflowStepResults;
|
|
68734
68737
|
if (results?.some(isPlanReviewSatisfied)) return { seeded: false, reason: "plan-review-passed" };
|
|
68738
|
+
if (options.retirePredecessorId) {
|
|
68739
|
+
const predRows = await tx.select().from(project_exports.workflowWorkItems).where(and(
|
|
68740
|
+
projectScopeFor(project_exports.workflowWorkItems.projectId, layer.projectId),
|
|
68741
|
+
eq(project_exports.workflowWorkItems.id, options.retirePredecessorId),
|
|
68742
|
+
eq(project_exports.workflowWorkItems.taskId, input.taskId)
|
|
68743
|
+
)).limit(1);
|
|
68744
|
+
const pred = predRows[0];
|
|
68745
|
+
if (pred && !isTerminalWorkflowWorkItemState(normalizeWorkflowWorkItemState(pred.state))) {
|
|
68746
|
+
await transitionWorkflowWorkItem(layer, pred.id, "succeeded", { leaseOwner: null, leaseExpiresAt: null, lastError: null }, tx);
|
|
68747
|
+
}
|
|
68748
|
+
}
|
|
68735
68749
|
const item = await upsertWorkflowWorkItem(layer, input, tx);
|
|
68736
68750
|
return { seeded: true, workItemId: item.id };
|
|
68737
68751
|
}));
|
|
@@ -97109,8 +97123,8 @@ async function upsertWorkflowWorkItemImpl(store, input, tx) {
|
|
|
97109
97123
|
async function replaceActiveTaskWorkflowContinuationImpl(store, input) {
|
|
97110
97124
|
return replaceActiveTaskWorkflowContinuation(store.asyncLayer, input);
|
|
97111
97125
|
}
|
|
97112
|
-
async function seedStrandedPlanReviewContinuationImpl(store, input) {
|
|
97113
|
-
return seedStrandedPlanReviewContinuation(store.asyncLayer, input);
|
|
97126
|
+
async function seedStrandedPlanReviewContinuationImpl(store, input, options = {}) {
|
|
97127
|
+
return seedStrandedPlanReviewContinuation(store.asyncLayer, input, options);
|
|
97114
97128
|
}
|
|
97115
97129
|
async function transitionWorkflowWorkItemImpl(store, id, state, patch = {}, tx) {
|
|
97116
97130
|
return transitionWorkflowWorkItem(store.asyncLayer, id, state, patch, tx);
|
|
@@ -101253,6 +101267,37 @@ async function getTaskVerificationRequestAsyncImpl(store, taskId) {
|
|
|
101253
101267
|
const row = rows[0];
|
|
101254
101268
|
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;
|
|
101255
101269
|
}
|
|
101270
|
+
async function listTaskRecommendationsImpl(store, options) {
|
|
101271
|
+
const layer = store.asyncLayer;
|
|
101272
|
+
const completeColumns = options?.completeColumns ?? await resolveProjectColumnsForRoles(store, ["complete"]);
|
|
101273
|
+
const rawLimit = options?.limit;
|
|
101274
|
+
const rawOffset = options?.offset;
|
|
101275
|
+
const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? Math.min(200, Math.max(1, Math.trunc(rawLimit))) : 50;
|
|
101276
|
+
const offset = typeof rawOffset === "number" && Number.isFinite(rawOffset) ? Math.max(0, Math.trunc(rawOffset)) : 0;
|
|
101277
|
+
const columns = [...completeColumns];
|
|
101278
|
+
if (columns.length === 0) return { items: [], rowOffset: offset, rowLimit: limit, returnedRowCount: 0, totalRowCount: 0, hasMore: false };
|
|
101279
|
+
const filter = and(
|
|
101280
|
+
taskProjectScope(layer),
|
|
101281
|
+
isNull(project_exports.tasks.deletedAt),
|
|
101282
|
+
inArray(project_exports.tasks.column, columns),
|
|
101283
|
+
isNotNull(project_exports.tasks.recommendations),
|
|
101284
|
+
sql`jsonb_array_length(${project_exports.tasks.recommendations}) > 0`
|
|
101285
|
+
);
|
|
101286
|
+
const [countRows, rows] = await Promise.all([
|
|
101287
|
+
layer.db.select({ count: sql`count(*)` }).from(project_exports.tasks).where(filter),
|
|
101288
|
+
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)
|
|
101289
|
+
]);
|
|
101290
|
+
const items = [];
|
|
101291
|
+
for (const row of rows) {
|
|
101292
|
+
if (!Array.isArray(row.recommendations) || row.recommendations.length === 0) continue;
|
|
101293
|
+
for (const recommendation of row.recommendations) {
|
|
101294
|
+
items.push({ taskId: row.id, taskTitle: row.title ?? void 0, taskColumn: row.column, updatedAt: row.updatedAt, recommendation });
|
|
101295
|
+
}
|
|
101296
|
+
}
|
|
101297
|
+
const totalRowCount = Number(countRows[0]?.count ?? 0);
|
|
101298
|
+
const returnedRowCount = rows.length;
|
|
101299
|
+
return { items, rowOffset: offset, rowLimit: limit, returnedRowCount, totalRowCount, hasMore: offset + returnedRowCount < totalRowCount };
|
|
101300
|
+
}
|
|
101256
101301
|
var LEGACY_REVIEW_LANES5, LEGACY_ARCHIVE_LANES2;
|
|
101257
101302
|
var init_reads = __esm({
|
|
101258
101303
|
"../core/src/task-store/reads.ts"() {
|
|
@@ -101275,6 +101320,7 @@ var init_reads = __esm({
|
|
|
101275
101320
|
init_retry_summary();
|
|
101276
101321
|
init_errors3();
|
|
101277
101322
|
init_project_lane_vocabulary();
|
|
101323
|
+
init_data_layer();
|
|
101278
101324
|
init_async_persistence();
|
|
101279
101325
|
init_async_search();
|
|
101280
101326
|
init_async_archive_db();
|
|
@@ -103381,6 +103427,9 @@ var init_store = __esm({
|
|
|
103381
103427
|
async clearWorkflowRunStepInstancesAsync(taskId, keepRunId) {
|
|
103382
103428
|
return clearWorkflowRunStepInstancesAsyncImpl(this, taskId, keepRunId);
|
|
103383
103429
|
}
|
|
103430
|
+
async listTaskRecommendations(options) {
|
|
103431
|
+
return listTaskRecommendationsImpl(this, options);
|
|
103432
|
+
}
|
|
103384
103433
|
async listTasksForGithubTrackingReconcile(options) {
|
|
103385
103434
|
return listTasksForGithubTrackingReconcileImpl(this, options);
|
|
103386
103435
|
}
|
|
@@ -104107,8 +104156,8 @@ var init_store = __esm({
|
|
|
104107
104156
|
async replaceActiveTaskWorkflowContinuation(input) {
|
|
104108
104157
|
return replaceActiveTaskWorkflowContinuationImpl(this, input);
|
|
104109
104158
|
}
|
|
104110
|
-
async seedStrandedPlanReviewContinuation(input) {
|
|
104111
|
-
return seedStrandedPlanReviewContinuationImpl(this, input);
|
|
104159
|
+
async seedStrandedPlanReviewContinuation(input, options = {}) {
|
|
104160
|
+
return seedStrandedPlanReviewContinuationImpl(this, input, options);
|
|
104112
104161
|
}
|
|
104113
104162
|
async transitionWorkflowWorkItem(id, state, patch = {}, tx) {
|
|
104114
104163
|
return transitionWorkflowWorkItemImpl(this, id, state, patch, tx);
|
|
@@ -133246,6 +133295,77 @@ var init_task_timing = __esm({
|
|
|
133246
133295
|
}
|
|
133247
133296
|
});
|
|
133248
133297
|
|
|
133298
|
+
// ../core/src/task-recommendation-notice.ts
|
|
133299
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
133300
|
+
function registerTaskRecommendationNoticeMailbox(store, mailbox) {
|
|
133301
|
+
mailboxes2.set(store, mailbox);
|
|
133302
|
+
return () => {
|
|
133303
|
+
if (mailboxes2.get(store) === mailbox) mailboxes2.delete(store);
|
|
133304
|
+
};
|
|
133305
|
+
}
|
|
133306
|
+
function getTaskRecommendationNoticeMailbox(store) {
|
|
133307
|
+
return mailboxes2.get(store);
|
|
133308
|
+
}
|
|
133309
|
+
function buildTaskRecommendationNoticeContent(task, recommendations) {
|
|
133310
|
+
const title = task.title?.trim();
|
|
133311
|
+
const heading = title ? `## Recommendations from ${task.id} \u2014 ${title}` : `## Recommendations from ${task.id}`;
|
|
133312
|
+
return [
|
|
133313
|
+
heading,
|
|
133314
|
+
"",
|
|
133315
|
+
"These are optional, non-blocking out-of-scope proposals that were **not** executed.",
|
|
133316
|
+
"",
|
|
133317
|
+
...recommendations.map((recommendation) => `- **${recommendation.title}** \u2014 \`${recommendation.category}\`: ${recommendation.description}`),
|
|
133318
|
+
"",
|
|
133319
|
+
`Open ${task.id}'s **Recommendations** tab to review them. **Create task** files one through normal guarded intake.`
|
|
133320
|
+
].join("\n");
|
|
133321
|
+
}
|
|
133322
|
+
function buildTaskRecommendationNoticeIdempotencyKey(taskId, recommendations) {
|
|
133323
|
+
const ids = recommendations.map(({ id }) => id).sort().join("\n");
|
|
133324
|
+
const digest = createHash20("sha256").update(ids, "utf8").digest("hex").slice(0, 16);
|
|
133325
|
+
return `task-recommendation-notice:${taskId}:${digest}`;
|
|
133326
|
+
}
|
|
133327
|
+
async function notifyOperatorOfTaskRecommendations(store, task, recommendations, settings) {
|
|
133328
|
+
try {
|
|
133329
|
+
if (settings.recommendationMailboxNoticeEnabled === false || !recommendations?.length) return false;
|
|
133330
|
+
const mailbox = mailboxes2.get(store);
|
|
133331
|
+
if (!mailbox) return false;
|
|
133332
|
+
await mailbox.sendMessageOnce(
|
|
133333
|
+
{
|
|
133334
|
+
fromId: "system",
|
|
133335
|
+
fromType: "system",
|
|
133336
|
+
toId: DASHBOARD_USER_ID,
|
|
133337
|
+
toType: "user",
|
|
133338
|
+
type: "system",
|
|
133339
|
+
content: buildTaskRecommendationNoticeContent(task, recommendations),
|
|
133340
|
+
metadata: {
|
|
133341
|
+
kind: "task-recommendation-notice",
|
|
133342
|
+
taskId: task.id,
|
|
133343
|
+
recommendationCount: recommendations.length,
|
|
133344
|
+
recommendationIds: recommendations.map(({ id }) => id),
|
|
133345
|
+
categories: recommendations.map(({ category }) => category)
|
|
133346
|
+
}
|
|
133347
|
+
},
|
|
133348
|
+
buildTaskRecommendationNoticeIdempotencyKey(task.id, recommendations)
|
|
133349
|
+
);
|
|
133350
|
+
return true;
|
|
133351
|
+
} catch (error2) {
|
|
133352
|
+
noticeLog2.warn(
|
|
133353
|
+
`Operator recommendation notice failed for ${task.id}: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
133354
|
+
);
|
|
133355
|
+
return false;
|
|
133356
|
+
}
|
|
133357
|
+
}
|
|
133358
|
+
var noticeLog2, mailboxes2;
|
|
133359
|
+
var init_task_recommendation_notice = __esm({
|
|
133360
|
+
"../core/src/task-recommendation-notice.ts"() {
|
|
133361
|
+
"use strict";
|
|
133362
|
+
init_logger2();
|
|
133363
|
+
init_types();
|
|
133364
|
+
noticeLog2 = createLogger2("task-recommendation-notice");
|
|
133365
|
+
mailboxes2 = /* @__PURE__ */ new WeakMap();
|
|
133366
|
+
}
|
|
133367
|
+
});
|
|
133368
|
+
|
|
133249
133369
|
// ../core/src/session-identity-registry.ts
|
|
133250
133370
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
133251
133371
|
import { resolve as resolve23 } from "node:path";
|
|
@@ -134095,6 +134215,8 @@ __export(src_exports, {
|
|
|
134095
134215
|
buildTaskDeleteNoticeContent: () => buildTaskDeleteNoticeContent,
|
|
134096
134216
|
buildTaskDeleteNoticeIdempotencyKey: () => buildTaskDeleteNoticeIdempotencyKey,
|
|
134097
134217
|
buildTaskLineageTrailer: () => buildTaskLineageTrailer,
|
|
134218
|
+
buildTaskRecommendationNoticeContent: () => buildTaskRecommendationNoticeContent,
|
|
134219
|
+
buildTaskRecommendationNoticeIdempotencyKey: () => buildTaskRecommendationNoticeIdempotencyKey,
|
|
134098
134220
|
buildToolOutputTruncationMarker: () => buildToolOutputTruncationMarker,
|
|
134099
134221
|
buildTriageHeartbeatGuidance: () => buildTriageHeartbeatGuidance,
|
|
134100
134222
|
buildTriageMemoryInstructions: () => buildTriageMemoryInstructions,
|
|
@@ -134425,6 +134547,7 @@ __export(src_exports, {
|
|
|
134425
134547
|
getTaskMergeBlocker: () => getTaskMergeBlocker,
|
|
134426
134548
|
getTaskMoveDisposer: () => getTaskMoveDisposer,
|
|
134427
134549
|
getTaskPriorityRank: () => getTaskPriorityRank,
|
|
134550
|
+
getTaskRecommendationNoticeMailbox: () => getTaskRecommendationNoticeMailbox,
|
|
134428
134551
|
getTemplatesForRole: () => getTemplatesForRole,
|
|
134429
134552
|
getTotalAgentActiveMs: () => getTotalAgentActiveMs,
|
|
134430
134553
|
getTrait: () => getTrait,
|
|
@@ -134675,6 +134798,7 @@ __export(src_exports, {
|
|
|
134675
134798
|
normalizeWorkflowPromptOverrides: () => normalizeWorkflowPromptOverrides,
|
|
134676
134799
|
normalizeWorkflowReviewFindings: () => normalizeWorkflowReviewFindings,
|
|
134677
134800
|
notifyOperatorOfNonOperatorDelete: () => notifyOperatorOfNonOperatorDelete,
|
|
134801
|
+
notifyOperatorOfTaskRecommendations: () => notifyOperatorOfTaskRecommendations,
|
|
134678
134802
|
overseerAdviceSeverityRank: () => overseerAdviceSeverityRank,
|
|
134679
134803
|
parseAgentManifest: () => parseAgentManifest,
|
|
134680
134804
|
parseCompanyArchive: () => parseCompanyArchive,
|
|
@@ -134784,6 +134908,7 @@ __export(src_exports, {
|
|
|
134784
134908
|
registerStepParser: () => registerStepParser,
|
|
134785
134909
|
registerTaskDeleteNoticeMailbox: () => registerTaskDeleteNoticeMailbox,
|
|
134786
134910
|
registerTaskMoveDisposer: () => registerTaskMoveDisposer,
|
|
134911
|
+
registerTaskRecommendationNoticeMailbox: () => registerTaskRecommendationNoticeMailbox,
|
|
134787
134912
|
registerTraitHookImpl: () => registerTraitHookImpl,
|
|
134788
134913
|
rekeyFallbackProjectPartition: () => rekeyFallbackProjectPartition,
|
|
134789
134914
|
releaseEmbeddedRuntimeLease: () => releaseEmbeddedRuntimeLease,
|
|
@@ -135411,6 +135536,7 @@ var init_src2 = __esm({
|
|
|
135411
135536
|
init_task_document_concurrency();
|
|
135412
135537
|
init_task_delete_attribution();
|
|
135413
135538
|
init_task_delete_notice();
|
|
135539
|
+
init_task_recommendation_notice();
|
|
135414
135540
|
init_session_identity_registry();
|
|
135415
135541
|
init_task_lifecycle_event_retention();
|
|
135416
135542
|
init_task_lifecycle_consumer_identity();
|
|
@@ -138781,7 +138907,7 @@ ${getErrorStderr(error2) ?? ""}`;
|
|
|
138781
138907
|
});
|
|
138782
138908
|
|
|
138783
138909
|
// ../engine/src/worktree/secrets-env-writer.ts
|
|
138784
|
-
import { createHash as
|
|
138910
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
138785
138911
|
import { execFile as execFile7 } from "node:child_process";
|
|
138786
138912
|
import { promises as fs5 } from "node:fs";
|
|
138787
138913
|
import path2 from "node:path";
|
|
@@ -138790,7 +138916,7 @@ function isValidFilename(filename) {
|
|
|
138790
138916
|
return !!filename && !filename.includes("/") && !filename.includes("\\") && !filename.includes("..") && !filename.includes("\0") && filename !== FINGERPRINT_FILE;
|
|
138791
138917
|
}
|
|
138792
138918
|
function sha2562(content) {
|
|
138793
|
-
return
|
|
138919
|
+
return createHash21("sha256").update(Buffer.from(content, "utf8")).digest("hex");
|
|
138794
138920
|
}
|
|
138795
138921
|
function quote(value) {
|
|
138796
138922
|
return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll(" ", "\\t")}"`;
|
|
@@ -141453,11 +141579,11 @@ var init_planning_handoff_recovery = __esm({
|
|
|
141453
141579
|
// ../engine/src/plan-review-continuation.ts
|
|
141454
141580
|
async function seedPreReleasePlanReviewContinuation(store, task, ir2, options = {}) {
|
|
141455
141581
|
const node = resolvePreReleasePlanReviewNode(ir2);
|
|
141456
|
-
if (!node || node.column !== task.column) return { seeded: false };
|
|
141582
|
+
if (!node || node.column !== task.column) return { seeded: false, reason: "no-pre-release-plan-review" };
|
|
141457
141583
|
if (isTaskBlockedOnApproval(task)) return { seeded: false, reason: "awaiting-approval" };
|
|
141458
141584
|
if (task.paused === true || task.userPaused === true) return { seeded: false, reason: "paused" };
|
|
141459
141585
|
const items = await store.listWorkflowWorkItemsForTask(task.id);
|
|
141460
|
-
const active2 = items.filter((item2) => ACTIVE_WORKFLOW_WORK_ITEM_STATES.includes(item2.state));
|
|
141586
|
+
const active2 = items.filter((item2) => ACTIVE_WORKFLOW_WORK_ITEM_STATES.includes(item2.state) && item2.id !== options.retirePredecessorId);
|
|
141461
141587
|
if (active2.length > 0) return { seeded: false, reason: "active-continuation" };
|
|
141462
141588
|
const continuationSequence = items.length;
|
|
141463
141589
|
const input = {
|
|
@@ -141473,6 +141599,9 @@ async function seedPreReleasePlanReviewContinuation(store, task, ir2, options =
|
|
|
141473
141599
|
targetColumn: task.column,
|
|
141474
141600
|
irHash: computeWorkflowIrPin(ir2, node.id).irHash
|
|
141475
141601
|
};
|
|
141602
|
+
if (options.retirePredecessorId) {
|
|
141603
|
+
return store.seedStrandedPlanReviewContinuation(input, { retirePredecessorId: options.retirePredecessorId });
|
|
141604
|
+
}
|
|
141476
141605
|
if (options.atomic) return store.seedStrandedPlanReviewContinuation(input);
|
|
141477
141606
|
const item = await store.replaceActiveTaskWorkflowContinuation(input);
|
|
141478
141607
|
return { seeded: true, workItemId: item.id };
|
|
@@ -141512,7 +141641,7 @@ var init_plan_review_continuation = __esm({
|
|
|
141512
141641
|
});
|
|
141513
141642
|
|
|
141514
141643
|
// ../engine/src/execution/hold-release.ts
|
|
141515
|
-
import { createHash as
|
|
141644
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
141516
141645
|
import { readFile as readFile33 } from "node:fs/promises";
|
|
141517
141646
|
function findColumn2(ir2, columnId) {
|
|
141518
141647
|
if (ir2.version !== "v2") return void 0;
|
|
@@ -141550,9 +141679,9 @@ async function checkAndRecordUnplannedExecutionBlock(store, task, ir2) {
|
|
|
141550
141679
|
promptContent = "";
|
|
141551
141680
|
}
|
|
141552
141681
|
}
|
|
141553
|
-
const promptMarker = promptContent.length > 0 ?
|
|
141682
|
+
const promptMarker = promptContent.length > 0 ? createHash22("sha256").update(promptContent).digest("hex") : "missing";
|
|
141554
141683
|
const dependencies = [...task.dependencies ?? []].sort();
|
|
141555
|
-
const episode =
|
|
141684
|
+
const episode = createHash22("sha256").update(JSON.stringify({
|
|
141556
141685
|
planReviewNode,
|
|
141557
141686
|
promptMarker,
|
|
141558
141687
|
dependencies,
|
|
@@ -144593,7 +144722,7 @@ var init_scheduler = __esm({
|
|
|
144593
144722
|
});
|
|
144594
144723
|
|
|
144595
144724
|
// ../engine/src/agents/agent-logger.ts
|
|
144596
|
-
import { createHash as
|
|
144725
|
+
import { createHash as createHash23 } from "node:crypto";
|
|
144597
144726
|
function truncateToolResultDetail(value) {
|
|
144598
144727
|
if (value.length <= TOOL_RESULT_DETAIL_LIMIT) return value;
|
|
144599
144728
|
return `${value.slice(0, TOOL_RESULT_DETAIL_LIMIT)}${TOOL_RESULT_DETAIL_TRUNCATION_NOTICE}`;
|
|
@@ -144682,7 +144811,7 @@ function summarizeToolArgs(name2, args) {
|
|
|
144682
144811
|
const json2 = JSON.stringify(args);
|
|
144683
144812
|
if (!json2 || json2 === "{}" || json2 === "[]") return void 0;
|
|
144684
144813
|
if (json2.length <= STRUCTURED_ARG_SUMMARY_MAX) return json2;
|
|
144685
|
-
const hash3 =
|
|
144814
|
+
const hash3 = createHash23("sha256").update(json2).digest("hex").slice(0, STRUCTURED_ARG_HASH_HEX_LEN);
|
|
144686
144815
|
const suffix = `\u2026#${hash3}`;
|
|
144687
144816
|
const keep = Math.max(0, STRUCTURED_ARG_SUMMARY_MAX - suffix.length);
|
|
144688
144817
|
return `${json2.slice(0, keep)}${suffix}`;
|
|
@@ -149126,7 +149255,7 @@ var init_gating_classifications = __esm({
|
|
|
149126
149255
|
});
|
|
149127
149256
|
|
|
149128
149257
|
// ../engine/src/agents/agent-action-gate.ts
|
|
149129
|
-
import { createHash as
|
|
149258
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
149130
149259
|
function getExemptTools() {
|
|
149131
149260
|
if (!_exemptTools) {
|
|
149132
149261
|
_exemptTools = new Set(DEFAULT_EXEMPT_TOOLS);
|
|
@@ -149160,7 +149289,7 @@ function evaluateAgentActionGate(params) {
|
|
|
149160
149289
|
if (params.toolName === "bash") {
|
|
149161
149290
|
const command = extractShellCommand(args);
|
|
149162
149291
|
const git7 = classifyGitCommand(command);
|
|
149163
|
-
resourceId = command ? `cmd:${
|
|
149292
|
+
resourceId = command ? `cmd:${createHash24("sha256").update(command).digest("hex").slice(0, 16)}` : void 0;
|
|
149164
149293
|
if (git7?.write) {
|
|
149165
149294
|
category = "git_write";
|
|
149166
149295
|
operation = git7.operation;
|
|
@@ -177682,7 +177811,7 @@ var init_code_node_runner = __esm({
|
|
|
177682
177811
|
// ../engine/src/agent-tools.ts
|
|
177683
177812
|
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";
|
|
177684
177813
|
import { existsSync as existsSync52 } from "node:fs";
|
|
177685
|
-
import { createHash as
|
|
177814
|
+
import { createHash as createHash25, randomUUID as randomUUID46 } from "node:crypto";
|
|
177686
177815
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
177687
177816
|
import { extname as extname4, isAbsolute as isAbsolute14, join as join66, relative as relative14, resolve as resolve37, sep as sep10 } from "node:path";
|
|
177688
177817
|
import { Type as Type2 } from "@earendil-works/pi-ai";
|
|
@@ -177726,7 +177855,7 @@ async function readAgentMemoryWorkspaceLongTerm(rootDir, agentId) {
|
|
|
177726
177855
|
}
|
|
177727
177856
|
}
|
|
177728
177857
|
function qmdAgentMemoryCollectionName2(rootDir, agentId) {
|
|
177729
|
-
const hash3 =
|
|
177858
|
+
const hash3 = createHash25("sha1").update(`${rootDir}:${agentId}`).digest("hex").slice(0, 12);
|
|
177730
177859
|
return `fusion-agent-memory-${sanitizeAgentMemoryId(agentId).toLowerCase()}-${hash3}`;
|
|
177731
177860
|
}
|
|
177732
177861
|
function buildQmdAgentMemoryCollectionAddArgs(rootDir, agentId) {
|
|
@@ -187841,7 +187970,7 @@ var init_verification_utils = __esm({
|
|
|
187841
187970
|
|
|
187842
187971
|
// ../engine/src/merge/merge-dependency-sync.ts
|
|
187843
187972
|
import { exec as exec25 } from "node:child_process";
|
|
187844
|
-
import { createHash as
|
|
187973
|
+
import { createHash as createHash27 } from "node:crypto";
|
|
187845
187974
|
import { existsSync as existsSync54, readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "node:fs";
|
|
187846
187975
|
import { join as join68 } from "node:path";
|
|
187847
187976
|
import { promisify as promisify35 } from "node:util";
|
|
@@ -187868,7 +187997,7 @@ function computeLockfileHash(rootDir) {
|
|
|
187868
187997
|
const p2 = join68(rootDir, name2);
|
|
187869
187998
|
if (existsSync54(p2)) {
|
|
187870
187999
|
try {
|
|
187871
|
-
return
|
|
188000
|
+
return createHash27("sha256").update(readFileSync17(p2)).digest("hex");
|
|
187872
188001
|
} catch {
|
|
187873
188002
|
return null;
|
|
187874
188003
|
}
|
|
@@ -190405,7 +190534,7 @@ var init_mesh_lease_manager = __esm({
|
|
|
190405
190534
|
});
|
|
190406
190535
|
|
|
190407
190536
|
// ../engine/src/merge/merger-integration-worktree.ts
|
|
190408
|
-
import { createHash as
|
|
190537
|
+
import { createHash as createHash28 } from "node:crypto";
|
|
190409
190538
|
import { exec as exec31, execFile as execFile22 } from "node:child_process";
|
|
190410
190539
|
import { promisify as promisify45 } from "node:util";
|
|
190411
190540
|
function quoteAutostashArg(value) {
|
|
@@ -190528,7 +190657,7 @@ async function gitDirtyFingerprintLocal(rootDir) {
|
|
|
190528
190657
|
)
|
|
190529
190658
|
]);
|
|
190530
190659
|
if (!diffOut && !statusOut) return "";
|
|
190531
|
-
return
|
|
190660
|
+
return createHash28("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
190532
190661
|
} catch {
|
|
190533
190662
|
return "";
|
|
190534
190663
|
}
|
|
@@ -191514,7 +191643,7 @@ import { execSync as execSync5, exec as exec33 } from "node:child_process";
|
|
|
191514
191643
|
import * as childProcess4 from "node:child_process";
|
|
191515
191644
|
import { promisify as promisify48 } from "node:util";
|
|
191516
191645
|
import { existsSync as existsSync57, readFileSync as readFileSync20, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
191517
|
-
import { createHash as
|
|
191646
|
+
import { createHash as createHash29 } from "node:crypto";
|
|
191518
191647
|
import { join as join72, resolve as resolve43 } from "node:path";
|
|
191519
191648
|
import { hostname as hostname2 } from "node:os";
|
|
191520
191649
|
import { Type as Type4 } from "typebox";
|
|
@@ -191762,7 +191891,7 @@ async function gitDirtyFingerprint(rootDir) {
|
|
|
191762
191891
|
)
|
|
191763
191892
|
]);
|
|
191764
191893
|
if (!diffOut && !statusOut) return "";
|
|
191765
|
-
return
|
|
191894
|
+
return createHash29("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
191766
191895
|
} catch {
|
|
191767
191896
|
return "";
|
|
191768
191897
|
}
|
|
@@ -200649,7 +200778,7 @@ import { promisify as promisify79 } from "node:util";
|
|
|
200649
200778
|
// ../engine/src/runtimes/in-process-runtime.ts
|
|
200650
200779
|
init_src2();
|
|
200651
200780
|
init_scheduler();
|
|
200652
|
-
import { createHash as
|
|
200781
|
+
import { createHash as createHash32 } from "node:crypto";
|
|
200653
200782
|
import { EventEmitter as EventEmitter27 } from "node:events";
|
|
200654
200783
|
|
|
200655
200784
|
// ../engine/src/executor/public-reexports.ts
|
|
@@ -203376,7 +203505,7 @@ init_agent_tools();
|
|
|
203376
203505
|
init_agent_logger();
|
|
203377
203506
|
init_agent_usage_telemetry();
|
|
203378
203507
|
import { Type as Type3 } from "@earendil-works/pi-ai";
|
|
203379
|
-
import { createHash as
|
|
203508
|
+
import { createHash as createHash26 } from "node:crypto";
|
|
203380
203509
|
|
|
203381
203510
|
// ../engine/src/agents/approval-mail.ts
|
|
203382
203511
|
init_src2();
|
|
@@ -205004,7 +205133,7 @@ function truncatePrompt(text2, maxChars) {
|
|
|
205004
205133
|
... (truncated, ${text2.length} chars)`;
|
|
205005
205134
|
}
|
|
205006
205135
|
function shortContentHash(value) {
|
|
205007
|
-
return
|
|
205136
|
+
return createHash26("sha256").update(value).digest("hex").slice(0, 8);
|
|
205008
205137
|
}
|
|
205009
205138
|
function buildIdentitySnapshot(args) {
|
|
205010
205139
|
const { agent, resolvedInstructions, workspaceMemory } = args;
|
|
@@ -233492,6 +233621,34 @@ init_effective_settings();
|
|
|
233492
233621
|
init_run_audit();
|
|
233493
233622
|
init_logger();
|
|
233494
233623
|
init_lifecycle_columns();
|
|
233624
|
+
|
|
233625
|
+
// ../engine/src/executor/completion-recommendation-notice.ts
|
|
233626
|
+
init_src2();
|
|
233627
|
+
var pendingNotices = /* @__PURE__ */ new Set();
|
|
233628
|
+
function dispatchAcceptedCompletionRecommendationNotice(args) {
|
|
233629
|
+
if (!args.recommendations?.length) return;
|
|
233630
|
+
const pending = (async () => {
|
|
233631
|
+
const settings = args.settings ?? await args.store.getSettings();
|
|
233632
|
+
const task = await args.store.getTask(args.taskId);
|
|
233633
|
+
if (!task || task.deletedAt) return;
|
|
233634
|
+
await notifyOperatorOfTaskRecommendations(
|
|
233635
|
+
args.store,
|
|
233636
|
+
{ id: args.taskId, title: args.taskTitle ?? task.title },
|
|
233637
|
+
args.recommendations,
|
|
233638
|
+
settings
|
|
233639
|
+
);
|
|
233640
|
+
})();
|
|
233641
|
+
pendingNotices.add(pending);
|
|
233642
|
+
void pending.catch((error2) => {
|
|
233643
|
+
args.log?.warn(
|
|
233644
|
+
`Failed to dispatch recommendation mailbox notice for ${args.taskId}: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
233645
|
+
);
|
|
233646
|
+
}).finally(() => {
|
|
233647
|
+
pendingNotices.delete(pending);
|
|
233648
|
+
});
|
|
233649
|
+
}
|
|
233650
|
+
|
|
233651
|
+
// ../engine/src/executor/create-task-done-tool.ts
|
|
233495
233652
|
function createTaskDoneTool(deps, taskId, worktreePath, promptContent, codeReviewVerdicts, onDone, audit) {
|
|
233496
233653
|
const store = deps.store;
|
|
233497
233654
|
return {
|
|
@@ -233826,6 +233983,16 @@ ${rerunSuffix}`
|
|
|
233826
233983
|
bulkCompletionRefusalAt: null
|
|
233827
233984
|
});
|
|
233828
233985
|
await store.logEntry(taskId, "Task marked done by agent", void 0, deps.getRunContextFor(taskId));
|
|
233986
|
+
if (completionRecommendations !== void 0) {
|
|
233987
|
+
dispatchAcceptedCompletionRecommendationNotice({
|
|
233988
|
+
store,
|
|
233989
|
+
taskId,
|
|
233990
|
+
taskTitle: task.title,
|
|
233991
|
+
recommendations: completionRecommendations,
|
|
233992
|
+
settings,
|
|
233993
|
+
log: executorLog
|
|
233994
|
+
});
|
|
233995
|
+
}
|
|
233829
233996
|
const latestTask = await store.getTask(taskId);
|
|
233830
233997
|
let latestColumn = latestTask.column;
|
|
233831
233998
|
if (latestColumn === await resolveReboundColumnFor(store, taskId)) {
|
|
@@ -245658,6 +245825,16 @@ ${rerunSuffix}` });
|
|
|
245658
245825
|
if (latestColumn === await resolveWipTargetForTask(deps.store, task.id) && !hardPauseActive && beforeWatchdog && !beforeWatchdog.deletedAt && !(rejectIfPaused && (beforeWatchdog.paused || beforeWatchdog.userPaused))) {
|
|
245659
245826
|
deps.scheduleCompletedTaskWatchdog(task.id, "fn_task_done");
|
|
245660
245827
|
}
|
|
245828
|
+
if (recommendations !== void 0) {
|
|
245829
|
+
dispatchAcceptedCompletionRecommendationNotice({
|
|
245830
|
+
store: deps.store,
|
|
245831
|
+
taskId: task.id,
|
|
245832
|
+
taskTitle: task.title,
|
|
245833
|
+
recommendations,
|
|
245834
|
+
settings,
|
|
245835
|
+
log: executorLog
|
|
245836
|
+
});
|
|
245837
|
+
}
|
|
245661
245838
|
return { completed: true, hardPauseActive };
|
|
245662
245839
|
} catch (error2) {
|
|
245663
245840
|
await restoreNoCommitsExpected();
|
|
@@ -250871,7 +251048,7 @@ init_notifier();
|
|
|
250871
251048
|
|
|
250872
251049
|
// ../engine/src/healing/stuck-task-detector.ts
|
|
250873
251050
|
init_logger();
|
|
250874
|
-
import { createHash as
|
|
251051
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
250875
251052
|
var stuckLog = createLogger("stuck-detector");
|
|
250876
251053
|
var LOOP_ACTIVITY_THRESHOLD = 60;
|
|
250877
251054
|
var LOOP_IGNORED_STEP_MIN = 10;
|
|
@@ -250882,7 +251059,7 @@ var TOOL_DETAIL_HASH_HEX_LEN = 16;
|
|
|
250882
251059
|
var NO_PROGRESS_CHURN_THRESHOLD = 25;
|
|
250883
251060
|
var VERIFICATION_DEADLINE_GRACE_MS = 5e3;
|
|
250884
251061
|
function hashToolDetail(detail) {
|
|
250885
|
-
return
|
|
251062
|
+
return createHash30("sha256").update(detail).digest("hex").slice(0, TOOL_DETAIL_HASH_HEX_LEN);
|
|
250886
251063
|
}
|
|
250887
251064
|
function buildToolFingerprint(toolName, toolDetail) {
|
|
250888
251065
|
const name2 = toolName.trim().toLowerCase() || "tool";
|
|
@@ -253632,7 +253809,7 @@ var MissionAutopilot = class {
|
|
|
253632
253809
|
// ../engine/src/missions/mission-execution-loop.ts
|
|
253633
253810
|
init_src2();
|
|
253634
253811
|
import { EventEmitter as EventEmitter26 } from "node:events";
|
|
253635
|
-
import { createHash as
|
|
253812
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
253636
253813
|
|
|
253637
253814
|
// ../engine/src/missions/mission-verification.ts
|
|
253638
253815
|
init_sandbox();
|
|
@@ -253704,7 +253881,7 @@ var MAX_VALIDATION_RESPONSE_BYTES = 256 * 1024;
|
|
|
253704
253881
|
var MAX_VALIDATION_JSON_CANDIDATES = 8;
|
|
253705
253882
|
var VALIDATION_FAILURE_BUDGET_PER_FINGERPRINT = 3;
|
|
253706
253883
|
function fingerprintMissionValidationInput(landedSha, provider, modelId, systemPrompt, userPrompt) {
|
|
253707
|
-
return
|
|
253884
|
+
return createHash31("sha256").update(Buffer.from(JSON.stringify(["mission-validation-input-v1", landedSha, provider, modelId, systemPrompt, userPrompt]), "utf8")).digest("hex");
|
|
253708
253885
|
}
|
|
253709
253886
|
var MissionExecutionLoop = class extends EventEmitter26 {
|
|
253710
253887
|
running = false;
|
|
@@ -257420,7 +257597,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
257420
257597
|
}
|
|
257421
257598
|
return;
|
|
257422
257599
|
}
|
|
257423
|
-
const duplicateReport = { outcome: "parked" };
|
|
257600
|
+
const duplicateReport = { outcome: "parked", planningWorkItemId };
|
|
257424
257601
|
if (await this.tryFinalizeExplicitDuplicateMarker(task, written, settings, {
|
|
257425
257602
|
isReplan,
|
|
257426
257603
|
feedback
|
|
@@ -257439,6 +257616,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
|
|
|
257439
257616
|
isReplan,
|
|
257440
257617
|
feedback
|
|
257441
257618
|
});
|
|
257619
|
+
finalizeReport.planningWorkItemId = planningWorkItemId;
|
|
257442
257620
|
this.options.onSpecifyComplete?.(task, finalizeReport);
|
|
257443
257621
|
} finally {
|
|
257444
257622
|
this.activeSessions.delete(task.id);
|
|
@@ -259013,11 +259191,46 @@ async function reactToSpecificationComplete(deps) {
|
|
|
259013
259191
|
return;
|
|
259014
259192
|
}
|
|
259015
259193
|
deps.log(`Specified ${deps.taskId} \u2192 todo`);
|
|
259016
|
-
const
|
|
259017
|
-
|
|
259018
|
-
|
|
259019
|
-
|
|
259020
|
-
|
|
259194
|
+
const sleep7 = deps.sleep ?? ((ms2) => new Promise((resolve47) => setTimeout(resolve47, ms2)));
|
|
259195
|
+
const QUIET_PARK_REASONS = /* @__PURE__ */ new Set([
|
|
259196
|
+
"no-pre-release-plan-review",
|
|
259197
|
+
"awaiting-approval",
|
|
259198
|
+
"paused",
|
|
259199
|
+
"plan-review-passed"
|
|
259200
|
+
]);
|
|
259201
|
+
const RETRY_DELAYS_MS2 = [1e3, 5e3];
|
|
259202
|
+
for (let attempt = 0; ; attempt++) {
|
|
259203
|
+
let failure = null;
|
|
259204
|
+
try {
|
|
259205
|
+
const live = await deps.getTask(deps.taskId);
|
|
259206
|
+
if (!live || live.paused || live.userPaused) return;
|
|
259207
|
+
if (live.status === "needs-replan") {
|
|
259208
|
+
deps.log(`Plan Review handoff for ${deps.taskId} not armed (needs-replan)`);
|
|
259209
|
+
return;
|
|
259210
|
+
}
|
|
259211
|
+
const ir2 = await deps.resolveIr(live.id);
|
|
259212
|
+
const result = await deps.seed(live, ir2);
|
|
259213
|
+
if (result.seeded) {
|
|
259214
|
+
deps.kick();
|
|
259215
|
+
return;
|
|
259216
|
+
}
|
|
259217
|
+
if (result.reason && QUIET_PARK_REASONS.has(result.reason)) {
|
|
259218
|
+
deps.log(`Plan Review handoff for ${deps.taskId} not armed (${result.reason})`);
|
|
259219
|
+
return;
|
|
259220
|
+
}
|
|
259221
|
+
failure = result.reason ?? "not-seeded";
|
|
259222
|
+
} catch (error2) {
|
|
259223
|
+
failure = error2 instanceof Error ? error2.message : String(error2);
|
|
259224
|
+
}
|
|
259225
|
+
if (attempt >= RETRY_DELAYS_MS2.length) {
|
|
259226
|
+
deps.warn(
|
|
259227
|
+
`Plan Review handoff for ${deps.taskId} failed after ${attempt + 1} attempts (${failure}) \u2014 stranded-continuation self-healing will recover it`
|
|
259228
|
+
);
|
|
259229
|
+
return;
|
|
259230
|
+
}
|
|
259231
|
+
deps.warn(`Plan Review handoff for ${deps.taskId} did not seed (${failure}) \u2014 retrying`);
|
|
259232
|
+
await sleep7(RETRY_DELAYS_MS2[attempt]);
|
|
259233
|
+
}
|
|
259021
259234
|
}
|
|
259022
259235
|
async function drainDuePlanningContinuations(deps) {
|
|
259023
259236
|
const items = await deps.listDue();
|
|
@@ -259154,7 +259367,7 @@ function stableNotificationJson(value) {
|
|
|
259154
259367
|
return `{${fields.join(",")}}`;
|
|
259155
259368
|
}
|
|
259156
259369
|
function buildCliAgentNotificationDedupeKey(input) {
|
|
259157
|
-
const notificationFingerprint =
|
|
259370
|
+
const notificationFingerprint = createHash32("sha256").update(stableNotificationJson(input.info.notification ?? null)).digest("hex").slice(0, 16);
|
|
259158
259371
|
const waitingEpoch = input.session?.updatedAt ?? "unknown-waiting-epoch";
|
|
259159
259372
|
return [
|
|
259160
259373
|
"cli-agent",
|
|
@@ -259266,6 +259479,8 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
259266
259479
|
messageStore;
|
|
259267
259480
|
/** FNXC:TaskDeleteNotice 2026-07-26-16:10: identity-guarded teardown for the delete-notice mailbox seam. */
|
|
259268
259481
|
unregisterTaskDeleteNoticeMailbox;
|
|
259482
|
+
/** FNXC:TaskRecommendations 2026-08-13-03:56: identity-guarded teardown for the store-scoped recommendation notice seam. */
|
|
259483
|
+
unregisterTaskRecommendationNoticeMailbox;
|
|
259269
259484
|
chatStore;
|
|
259270
259485
|
detachAgentLinkSync;
|
|
259271
259486
|
/**
|
|
@@ -259324,7 +259539,8 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
259324
259539
|
createTaskStoreForBackend: createTaskStoreForBackend2,
|
|
259325
259540
|
buildConsumerId: buildConsumerId2,
|
|
259326
259541
|
createProjectScopedPluginMcpProvider: createProjectScopedPluginMcpProvider2,
|
|
259327
|
-
registerTaskDeleteNoticeMailbox: registerTaskDeleteNoticeMailbox2
|
|
259542
|
+
registerTaskDeleteNoticeMailbox: registerTaskDeleteNoticeMailbox2,
|
|
259543
|
+
registerTaskRecommendationNoticeMailbox: registerTaskRecommendationNoticeMailbox2
|
|
259328
259544
|
} = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
259329
259545
|
if (this.config.externalTaskStore) {
|
|
259330
259546
|
this.taskStore = this.config.externalTaskStore;
|
|
@@ -259383,6 +259599,10 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
259383
259599
|
this.taskStore,
|
|
259384
259600
|
this.messageStore
|
|
259385
259601
|
);
|
|
259602
|
+
this.unregisterTaskRecommendationNoticeMailbox = registerTaskRecommendationNoticeMailbox2(
|
|
259603
|
+
this.taskStore,
|
|
259604
|
+
this.messageStore
|
|
259605
|
+
);
|
|
259386
259606
|
await yieldEventLoop4();
|
|
259387
259607
|
const pluginLayer = this.taskStore.getAsyncLayer();
|
|
259388
259608
|
if (!pluginLayer) {
|
|
@@ -259874,9 +260094,19 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
259874
260094
|
outcome: report2.outcome,
|
|
259875
260095
|
getTask: (id) => Promise.resolve(this.taskStore.getTask(id)),
|
|
259876
260096
|
resolveIr: (id) => resolveWorkflowIrForTask(this.taskStore, id),
|
|
259877
|
-
|
|
260097
|
+
/*
|
|
260098
|
+
FNXC:PlanningHandoffAtomicity 2026-08-13-03:49:
|
|
260099
|
+
The report carries the planning session's own durable work item id so the
|
|
260100
|
+
seeder can retire that exact predecessor row atomically with the successor
|
|
260101
|
+
install. Without it the seeder raced triage's finally-block terminal
|
|
260102
|
+
transition and bailed on its own caller (529 stranded cards in 18 days).
|
|
260103
|
+
*/
|
|
260104
|
+
seed: (task, ir2) => seedPreReleasePlanReviewContinuation(this.taskStore, task, ir2, {
|
|
260105
|
+
retirePredecessorId: report2.planningWorkItemId
|
|
260106
|
+
}),
|
|
259878
260107
|
kick: () => this.kickWorkflowContinuationProcessor(),
|
|
259879
|
-
log: (message) => runtimeLog.log(message)
|
|
260108
|
+
log: (message) => runtimeLog.log(message),
|
|
260109
|
+
warn: (message) => runtimeLog.warn(message)
|
|
259880
260110
|
}).catch((error2) => {
|
|
259881
260111
|
runtimeLog.error(`Failed to start Todo plan review for ${t.id}:`, error2);
|
|
259882
260112
|
});
|
|
@@ -260164,6 +260394,8 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
260164
260394
|
this.backendShutdown = void 0;
|
|
260165
260395
|
this.unregisterTaskDeleteNoticeMailbox?.();
|
|
260166
260396
|
this.unregisterTaskDeleteNoticeMailbox = void 0;
|
|
260397
|
+
this.unregisterTaskRecommendationNoticeMailbox?.();
|
|
260398
|
+
this.unregisterTaskRecommendationNoticeMailbox = void 0;
|
|
260167
260399
|
let stopError;
|
|
260168
260400
|
try {
|
|
260169
260401
|
if (this.workflowContinuationTimer) {
|