@runfusion/fusion 0.76.0-beta.1 → 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.
Files changed (151) hide show
  1. package/dist/bin.js +826 -272
  2. package/dist/child-process-worker.js +740 -249
  3. package/dist/client/.vite/manifest.json +261 -261
  4. package/dist/client/assets/{AgentDetailView-Cbl1sw6i.js → AgentDetailView-T767kKTg.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-DD1U5M9p.js → AgentPermissionPolicyEditor--u9jyUf2.js} +1 -1
  6. package/dist/client/assets/{AgentsView-BMcCbple.js → AgentsView-6Ifu7qDr.js} +5 -5
  7. package/dist/client/assets/ChatView-BV3lixQi.js +13 -0
  8. package/dist/client/assets/{CommandCenter-D7mcD61V.js → CommandCenter-CSRYoveB.js} +1 -1
  9. package/dist/client/assets/{DevServerView-DaqCn0p5.js → DevServerView-B9So_oYx.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-CLdqqqYN.js → DirectoryPicker-BhyDL_2m.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-BOROVxPm.js → DocumentsView-pbERA7O-.js} +1 -1
  12. package/dist/client/assets/{EvalsView-BQMXRUlQ.js → EvalsView-DJQ4ltCg.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-1GNeCIQT.js → ExperimentalAgentOnboardingModal-BwJuzkzB.js} +1 -1
  14. package/dist/client/assets/{GoalsView-Cr3c_2GC.js → GoalsView-B6X5_0Ve.js} +1 -1
  15. package/dist/client/assets/InsightsView-CJgI0J7S.js +11 -0
  16. package/dist/client/assets/{InsightsView-Gn5lOBA0.css → InsightsView-DAAXuX4v.css} +1 -1
  17. package/dist/client/assets/{MemoryView-C0VzzMSw.js → MemoryView-BHq1AHPu.js} +1 -1
  18. package/dist/client/assets/{PiExtensionsManager-D1kkkVtP.js → PiExtensionsManager-B8At6fO8.js} +1 -1
  19. package/dist/client/assets/{PluginManager-BW-_Zyo5.js → PluginManager-k7hV7_9e.js} +1 -1
  20. package/dist/client/assets/{PullRequestView-Cmlo4nWA.js → PullRequestView-B1hZFrWo.js} +1 -1
  21. package/dist/client/assets/{ReportModal-BWuaroTF.js → ReportModal-C46V_zEa.js} +1 -1
  22. package/dist/client/assets/{ResearchView-BmkF_vZU.js → ResearchView-D8G85BYN.js} +2 -2
  23. package/dist/client/assets/{SecretsView-DVc8Hky0.js → SecretsView-CTri9LRK.js} +1 -1
  24. package/dist/client/assets/{SessionTerminal-DCXrxA57.js → SessionTerminal-BRf6r4Vp.js} +1 -1
  25. package/dist/client/assets/SettingsModal-D0RBeZik.js +21 -0
  26. package/dist/client/assets/{SettingsModal-DqwpLnDU.js → SettingsModal-rUQcSTJp.js} +1 -1
  27. package/dist/client/assets/{SettingsTextareaRow-B5spAoOY.js → SettingsTextareaRow-BirlBcem.js} +1 -1
  28. package/dist/client/assets/{SetupWizardModal-VTBLyFzr.js → SetupWizardModal-xnCBM9EL.js} +2 -2
  29. package/dist/client/assets/{SkillsView-CR91ey9d.js → SkillsView-O5U0ep50.js} +1 -1
  30. package/dist/client/assets/{WorkflowNodeEditor-BzGh_Fd9.js → WorkflowNodeEditor-BX4d2qqF.js} +3 -3
  31. package/dist/client/assets/{agent-import-generation-D27NKQsr.js → agent-import-generation-DnqVkPkz.js} +1 -1
  32. package/dist/client/assets/{agentsOrgChartLayout-C2K_M3x3.js → agentsOrgChartLayout-CKuzbhFf.js} +1 -1
  33. package/dist/client/assets/app-B2FwULu2.js +5 -0
  34. package/dist/client/assets/{app-BA9gw9hx.js → app-B6nJaqAl.js} +2 -2
  35. package/dist/client/assets/{app-B_lScKc1.js → app-CGXZeIRc.js} +2 -2
  36. package/dist/client/assets/{app-DG_vjDw5.js → app-CGtkeBF5.js} +3 -3
  37. package/dist/client/assets/{app-GBgoY-oh.js → app-CNzN1Plu.js} +2 -2
  38. package/dist/client/assets/{app-B0KFGP8D.js → app-DLs-f5yM.js} +3 -3
  39. package/dist/client/assets/{app-DeHIOCEP.js → app-DsvtcRUG.js} +2 -2
  40. package/dist/client/assets/{architectureDiagram-3BPJPVTR-BQy8UcRx.js → architectureDiagram-3BPJPVTR-gi467xY0.js} +1 -1
  41. package/dist/client/assets/{blockDiagram-GPEHLZMM-CZG1bqFQ.js → blockDiagram-GPEHLZMM-B_gpcYiR.js} +1 -1
  42. package/dist/client/assets/{c4Diagram-AAUBKEIU-CZmO_kg3.js → c4Diagram-AAUBKEIU-DeylEYsQ.js} +1 -1
  43. package/dist/client/assets/channel-BoE8DeM4.js +1 -0
  44. package/dist/client/assets/{chunk-2J33WTMH-jsad6DTE.js → chunk-2J33WTMH-BL2WY0HN.js} +1 -1
  45. package/dist/client/assets/{chunk-4BX2VUAB-DX7SuvwP.js → chunk-4BX2VUAB-BkLExGMe.js} +1 -1
  46. package/dist/client/assets/{chunk-55IACEB6-De20xFgU.js → chunk-55IACEB6-CSTvCF5T.js} +1 -1
  47. package/dist/client/assets/{chunk-727SXJPM-CNiri9yW.js → chunk-727SXJPM-9J8pKk4x.js} +1 -1
  48. package/dist/client/assets/{chunk-AQP2D5EJ-DvDqG-ax.js → chunk-AQP2D5EJ-DXC1vPWr.js} +1 -1
  49. package/dist/client/assets/{chunk-FMBD7UC4-DkMdKaUq.js → chunk-FMBD7UC4-CFRUb-zD.js} +1 -1
  50. package/dist/client/assets/{chunk-ND2GUHAM-Do5BwIrI.js → chunk-ND2GUHAM-B87HFYS8.js} +1 -1
  51. package/dist/client/assets/{chunk-QZHKN3VN-BnJgt9vl.js → chunk-QZHKN3VN-CTjHiGbd.js} +1 -1
  52. package/dist/client/assets/classDiagram-4FO5ZUOK-qnbLX_9_.js +1 -0
  53. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-qnbLX_9_.js +1 -0
  54. package/dist/client/assets/{cose-bilkent-S5V4N54A-D-ivAzzF.js → cose-bilkent-S5V4N54A-D3Edq3L9.js} +1 -1
  55. package/dist/client/assets/{dagre-BM42HDAG-Bpd9L0or.js → dagre-BM42HDAG-CwwbeQfN.js} +1 -1
  56. package/dist/client/assets/{dashboard-view-CgBo8Ctn.js → dashboard-view-BLAoW3D4.js} +1 -1
  57. package/dist/client/assets/{dashboard-view-DbaRE8Ma.js → dashboard-view-DAlJxqiJ.js} +1 -1
  58. package/dist/client/assets/{dashboard-view-DSvVO6Vr.js → dashboard-view-QxQwJFLz.js} +1 -1
  59. package/dist/client/assets/{dashboard-view-C-XU9CVv.js → dashboard-view-aPzfv99T.js} +1 -1
  60. package/dist/client/assets/{diagram-2AECGRRQ-B6TT1NWU.js → diagram-2AECGRRQ-koJWWXE4.js} +1 -1
  61. package/dist/client/assets/{diagram-5GNKFQAL-DpRS2yRw.js → diagram-5GNKFQAL-Yob5cOKT.js} +1 -1
  62. package/dist/client/assets/{diagram-KO2AKTUF-BVbZr02C.js → diagram-KO2AKTUF-DelvFSkK.js} +1 -1
  63. package/dist/client/assets/{diagram-LMA3HP47-DzENbfal.js → diagram-LMA3HP47-CMput2h2.js} +1 -1
  64. package/dist/client/assets/{diagram-OG6HWLK6-BIePG5SY.js → diagram-OG6HWLK6-04VXDl79.js} +1 -1
  65. package/dist/client/assets/{erDiagram-TEJ5UH35-CQo3WBwo.js → erDiagram-TEJ5UH35-C9iP8Uyp.js} +1 -1
  66. package/dist/client/assets/{flowDiagram-I6XJVG4X-Ct2H4jYo.js → flowDiagram-I6XJVG4X-DENQvu_t.js} +1 -1
  67. package/dist/client/assets/{folder-open-DAh8mpTX.js → folder-open-D-554oji.js} +1 -1
  68. package/dist/client/assets/{ganttDiagram-6RSMTGT7-DyOLCG4B.js → ganttDiagram-6RSMTGT7-BqOttZAT.js} +1 -1
  69. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-sC28-su3.js → gitGraphDiagram-PVQCEYII-CDcydi-5.js} +1 -1
  70. package/dist/client/assets/{index-BzAldNrK.css → index-CXTd3LAB.css} +1 -1
  71. package/dist/client/assets/index-CtYRoouR.js +2818 -0
  72. package/dist/client/assets/{infoDiagram-5YYISTIA-Q81_5aBZ.js → infoDiagram-5YYISTIA-B5LQQnxt.js} +1 -1
  73. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-Cwkjs0z5.js → ishikawaDiagram-YF4QCWOH-DpFEt7D2.js} +1 -1
  74. package/dist/client/assets/{journeyDiagram-JHISSGLW-BXcBV1Bc.js → journeyDiagram-JHISSGLW-MELtgu22.js} +1 -1
  75. package/dist/client/assets/{kanban-definition-UN3LZRKU-BI7hW892.js → kanban-definition-UN3LZRKU-h33PLATd.js} +1 -1
  76. package/dist/client/assets/{mermaid.core-B8oDA6jj.js → mermaid.core-Dk2mUPOq.js} +4 -4
  77. package/dist/client/assets/{mindmap-definition-RKZ34NQL-COG6_9eD.js → mindmap-definition-RKZ34NQL-B_T4O2-B.js} +1 -1
  78. package/dist/client/assets/{pieDiagram-4H26LBE5-D11brZ_N.js → pieDiagram-4H26LBE5-B1YIFkRl.js} +1 -1
  79. package/dist/client/assets/{puzzle-D3_Z_rlW.js → puzzle-hvecxlpJ.js} +1 -1
  80. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-jmhDVZcv.js → quadrantDiagram-W4KKPZXB-BoGQR_hO.js} +1 -1
  81. package/dist/client/assets/{requirementDiagram-4Y6WPE33-BKCUWI1E.js → requirementDiagram-4Y6WPE33-BSDmUBIx.js} +1 -1
  82. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-HsZdEl2t.js → sankeyDiagram-5OEKKPKP-Dz_GqOa5.js} +1 -1
  83. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CsDf7Fup.js → sequenceDiagram-3UESZ5HK-B6twjYUH.js} +1 -1
  84. package/dist/client/assets/{shield-alert-C16k8wNu.js → shield-alert-BX4WRJOv.js} +1 -1
  85. package/dist/client/assets/{standing-instructions-template-BqAyftqe.js → standing-instructions-template-BJY317CC.js} +1 -1
  86. package/dist/client/assets/{stateDiagram-AJRCARHV-fvzWhltB.js → stateDiagram-AJRCARHV-DuwqWLx-.js} +1 -1
  87. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-cnt42Sr_.js → stateDiagram-v2-BHNVJYJU-Bu8Sk187.js} +1 -1
  88. package/dist/client/assets/{timeline-definition-PNZ67QCA-DsZFCSMb.js → timeline-definition-PNZ67QCA-BS6VnqSI.js} +1 -1
  89. package/dist/client/assets/{upload-_s5sL5Pq.js → upload-CaDoyaMW.js} +1 -1
  90. package/dist/client/assets/{users-DH1U5ISc.js → users-C5uCLwVM.js} +1 -1
  91. package/dist/client/assets/{vennDiagram-CIIHVFJN-B3KDWS-e.js → vennDiagram-CIIHVFJN-CUbzqT5Y.js} +1 -1
  92. package/dist/client/assets/{wardley-L42UT6IY-BKs5MtQS.js → wardley-L42UT6IY-Mv-NotFS.js} +1 -1
  93. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CNsEoXVB.js → wardleyDiagram-YWT4CUSO-DuYpvLZX.js} +1 -1
  94. package/dist/client/assets/{xychartDiagram-2RQKCTM6-kq_gW4QC.js → xychartDiagram-2RQKCTM6-24_7QXdw.js} +1 -1
  95. package/dist/client/index.html +2 -2
  96. package/dist/client/version.json +1 -1
  97. package/dist/droid-cli/package.json +1 -1
  98. package/dist/extension.js +932 -254
  99. package/dist/migrations/0057_fn_9004_project_ownership_default_reconciliation.sql +13 -0
  100. package/dist/migrations/0058_fn_9014_message_archive.sql +13 -0
  101. package/dist/pi-claude-cli/package.json +5 -5
  102. package/dist/plugin-sdk/index.d.ts +23 -0
  103. package/dist/plugin-sdk/index.js +71 -23
  104. package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +71 -23
  105. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  106. package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +71 -23
  107. package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
  108. package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +71 -23
  109. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  110. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +71 -23
  111. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  112. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +71 -23
  113. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  114. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +71 -23
  115. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  116. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +73 -25
  117. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  118. package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +71 -23
  119. package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
  120. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +71 -23
  121. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  122. package/dist/plugins/fusion-plugin-linear-import/bundled.js +71 -23
  123. package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
  124. package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +71 -23
  125. package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
  126. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +71 -23
  127. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  128. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +71 -23
  129. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  130. package/dist/plugins/fusion-plugin-quality/bundled.js +71 -23
  131. package/dist/plugins/fusion-plugin-quality/package.json +1 -1
  132. package/dist/plugins/fusion-plugin-reports/bundled.js +71 -23
  133. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  134. package/dist/plugins/fusion-plugin-roadmap/bundled.js +71 -23
  135. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  136. package/dist/plugins/fusion-plugin-todos/bundled.js +71 -23
  137. package/dist/plugins/fusion-plugin-todos/package.json +1 -1
  138. package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +71 -23
  139. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  140. package/package.json +3 -3
  141. package/skill/fusion/SKILL.md +1 -1
  142. package/skill/fusion/references/extension-tools.md +22 -0
  143. package/skill/fusion/references/fusion-capabilities.md +2 -0
  144. package/dist/client/assets/ChatView-DcM-ARpZ.js +0 -13
  145. package/dist/client/assets/InsightsView-DgVBVQM4.js +0 -11
  146. package/dist/client/assets/SettingsModal-DZ32F1c-.js +0 -21
  147. package/dist/client/assets/app-DBCGrz-f.js +0 -5
  148. package/dist/client/assets/channel-Cwl9FefC.js +0 -1
  149. package/dist/client/assets/classDiagram-4FO5ZUOK-BZtWCoHC.js +0 -1
  150. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BZtWCoHC.js +0 -1
  151. package/dist/client/assets/index-BlGpMJSZ.js +0 -2818
@@ -6141,9 +6141,14 @@ var config = projectSchema.table("config", {
6141
6141
  // now keyed per-project on `project_id` (the effective PK). `id` is retained
6142
6142
  // for column-shape parity (always 1) but is no longer the PK and no longer
6143
6143
  // CHECK-constrained. Single-project / SQLite-parity callers leave project_id
6144
- // at its '' default (one row), preserving the pre-isolation behavior.
6144
+ // through the database ownership trigger, preserving the pre-isolation behavior.
6145
+ /*
6146
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
6147
+ Migration 0006 owns config's project_id default and leaves its catalog PK as (project_id).
6148
+ Drizzle emits DEFAULT while the database GUC/trigger selects the effective ownership partition.
6149
+ */
6145
6150
  id: integer("id").default(1),
6146
- projectId: text("project_id").notNull().default("").primaryKey(),
6151
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`).primaryKey(),
6147
6152
  nextId: integer("next_id").default(1),
6148
6153
  nextWorkflowStepId: integer("next_workflow_step_id").default(1),
6149
6154
  // FNXC:SqliteFinalRemoval 2026-06-28:
@@ -6537,9 +6542,13 @@ var taskCommitAssociations = projectSchema.table("task_commit_associations", {
6537
6542
  var automations = projectSchema.table("automations", {
6538
6543
  /*
6539
6544
  * FNXC:AutomationIsolation 2026-07-13-22:37:
6540
- * Automations are partitioned by the AsyncDataLayer's project ID because embedded PostgreSQL consolidates the per-project SQLite files into one table. The composite key deliberately permits the same automation ID in two projects without allowing either project's CRUD or cron-claim path to address the other row. The empty default preserves an explicit partition for legacy and project-agnostic callers until startup stamps migrated rows.
6545
+ * Automations are partitioned by the AsyncDataLayer's project ID because embedded PostgreSQL consolidates the per-project SQLite files into one table. The composite key deliberately permits the same automation ID in two projects without allowing either project's CRUD or cron-claim path to address the other row.
6546
+ *
6547
+ * FNXC:MultiProjectIsolation 2026-08-12-15:43:
6548
+ * Migration 0006 owns the default through the database GUC/trigger; Drizzle emits DEFAULT
6549
+ * without replacing the physical legacy fallback or the fail-closed bound writer contract.
6541
6550
  */
6542
- projectId: text("project_id").notNull().default(""),
6551
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
6543
6552
  id: text("id").notNull(),
6544
6553
  name: text("name").notNull(),
6545
6554
  description: text("description"),
@@ -6838,7 +6847,8 @@ var taskDocuments = projectSchema.table("task_documents", {
6838
6847
  index("idxTaskDocumentsTaskId").on(t.taskId)
6839
6848
  ]);
6840
6849
  var artifacts = projectSchema.table("artifacts", {
6841
- id: text("id").primaryKey(),
6850
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
6851
+ id: text("id").notNull(),
6842
6852
  type: text("type").notNull(),
6843
6853
  title: text("title").notNull(),
6844
6854
  description: text("description"),
@@ -6853,7 +6863,8 @@ var artifacts = projectSchema.table("artifacts", {
6853
6863
  createdAt: text("created_at").notNull(),
6854
6864
  updatedAt: text("updated_at").notNull()
6855
6865
  }, (t) => [
6856
- foreignKey({ columns: [t.taskId], foreignColumns: [tasks.id] }).onDelete("cascade"),
6866
+ primaryKey({ columns: [t.projectId, t.id] }),
6867
+ foreignKey({ name: "artifacts_task_id_fkey", columns: [t.projectId, t.taskId], foreignColumns: [tasks.projectId, tasks.id] }).onDelete("cascade"),
6857
6868
  index("idxArtifactsTaskId").on(t.taskId),
6858
6869
  index("idxArtifactsAuthorId").on(t.authorId),
6859
6870
  index("idxArtifactsType").on(t.type),
@@ -7043,7 +7054,8 @@ var evalRunEvents = projectSchema.table("eval_run_events", {
7043
7054
  index("idxEvalRunEventsRunIdSeq").on(t.runId, t.seq)
7044
7055
  ]);
7045
7056
  var secrets = projectSchema.table("secrets", {
7046
- id: text("id").primaryKey(),
7057
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7058
+ id: text("id").notNull(),
7047
7059
  key: text("key").notNull(),
7048
7060
  valueCiphertext: bytea("value_ciphertext").notNull(),
7049
7061
  nonce: bytea("nonce").notNull(),
@@ -7056,7 +7068,8 @@ var secrets = projectSchema.table("secrets", {
7056
7068
  lastReadAt: text("last_read_at"),
7057
7069
  lastReadBy: text("last_read_by")
7058
7070
  }, (t) => [
7059
- unique("secrets_key_unique").on(t.key),
7071
+ primaryKey({ columns: [t.projectId, t.id] }),
7072
+ unique("secrets_key_unique").on(t.projectId, t.key),
7060
7073
  check("secrets_access_policy_check", sql`${t.accessPolicy} IN ('auto', 'prompt', 'deny')`),
7061
7074
  check("secrets_env_exportable_check", sql`${t.envExportable} IN (0, 1)`)
7062
7075
  ]);
@@ -7098,10 +7111,11 @@ var missions = projectSchema.table("missions", {
7098
7111
  updatedAt: text("updated_at").notNull()
7099
7112
  }, (t) => [primaryKey({ columns: [t.projectId, t.id] })]);
7100
7113
  var branchGroups = projectSchema.table("branch_groups", {
7101
- id: text("id").primaryKey(),
7114
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7115
+ id: text("id").notNull(),
7102
7116
  sourceType: text("source_type").notNull(),
7103
7117
  sourceId: text("source_id").notNull(),
7104
- branchName: text("branch_name").notNull().unique(),
7118
+ branchName: text("branch_name").notNull(),
7105
7119
  worktreePath: text("worktree_path"),
7106
7120
  autoMerge: integer("auto_merge").notNull().default(0),
7107
7121
  prState: text("pr_state").notNull().default("none"),
@@ -7117,6 +7131,8 @@ var branchGroups = projectSchema.table("branch_groups", {
7117
7131
  updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
7118
7132
  closedAt: bigint("closed_at", { mode: "number" })
7119
7133
  }, (t) => [
7134
+ primaryKey({ columns: [t.projectId, t.id] }),
7135
+ unique("branch_groups_branch_name_key").on(t.projectId, t.branchName),
7120
7136
  check("branch_groups_source_type_check", sql`${t.sourceType} IN ('mission','planning','new-task')`),
7121
7137
  check("branch_groups_pr_state_check", sql`${t.prState} IN ('none','open','merged','closed')`),
7122
7138
  check("branch_groups_status_check", sql`${t.status} IN ('open','finalized','abandoned')`),
@@ -7518,12 +7534,14 @@ var usageEvents = projectSchema.table("usage_events", {
7518
7534
  index("idxUsageEventsKindTs").on(t.kind, t.ts)
7519
7535
  ]);
7520
7536
  var pluginActivations = projectSchema.table("plugin_activations", {
7521
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7537
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7538
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7522
7539
  pluginId: text("plugin_id").notNull(),
7523
7540
  source: text("source").notNull(),
7524
7541
  pluginVersion: text("plugin_version"),
7525
7542
  activatedAt: text("activated_at").notNull()
7526
7543
  }, (t) => [
7544
+ primaryKey({ columns: [t.projectId, t.id] }),
7527
7545
  index("idxPluginActivationsActivatedAt").on(t.activatedAt),
7528
7546
  index("idxPluginActivationsPluginId").on(t.pluginId)
7529
7547
  ]);
@@ -7548,8 +7566,13 @@ var knowledgePages = projectSchema.table("knowledge_pages", {
7548
7566
  index("idxKnowledgePagesUpdatedAt").on(t.updatedAt)
7549
7567
  ]);
7550
7568
  var deployments = projectSchema.table("deployments", {
7551
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7552
- projectId: text("project_id").notNull().default(""),
7569
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7570
+ /*
7571
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7572
+ Migration 0006 rebuilt deployments_pkey as (project_id, id). Drizzle emits DEFAULT while the
7573
+ database GUC/trigger keeps ownership stamping and the physical legacy fallback authoritative.
7574
+ */
7575
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7553
7576
  deploymentId: text("deployment_id").notNull(),
7554
7577
  service: text("service"),
7555
7578
  environment: text("environment"),
@@ -7560,6 +7583,7 @@ var deployments = projectSchema.table("deployments", {
7560
7583
  meta: jsonb("meta"),
7561
7584
  createdAt: text("created_at").notNull()
7562
7585
  }, (t) => [
7586
+ primaryKey({ columns: [t.projectId, t.id], name: "deployments_pkey" }),
7563
7587
  uniqueIndex("idxDeploymentsProjectDeploymentId").on(t.projectId, t.deploymentId),
7564
7588
  index("idxDeploymentsProjectDeployedAt").on(t.projectId, t.deployedAt),
7565
7589
  index("idxDeploymentsDeployedAt").on(t.deployedAt),
@@ -7567,7 +7591,12 @@ var deployments = projectSchema.table("deployments", {
7567
7591
  ]);
7568
7592
  var githubCheckStates = projectSchema.table("github_check_states", {
7569
7593
  id: integer("id").generatedAlwaysAsIdentity().notNull(),
7570
- projectId: text("project_id").notNull().default(""),
7594
+ /*
7595
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7596
+ Migration 0048 post-dated 0006, so FN-9004 reconciles its physical default to the ownership
7597
+ expression. Drizzle emits DEFAULT while the database GUC/trigger remains the stamping authority.
7598
+ */
7599
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7571
7600
  repo: text("repo").notNull(),
7572
7601
  headSha: text("head_sha").notNull(),
7573
7602
  checkName: text("check_name").notNull(),
@@ -7587,9 +7616,14 @@ var githubCheckStates = projectSchema.table("github_check_states", {
7587
7616
  index("idxGithubCheckStatesProjectReceived").on(t.projectId, t.receivedAt)
7588
7617
  ]);
7589
7618
  var incidents = projectSchema.table("incidents", {
7590
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7591
- projectId: text("project_id").notNull().default(""),
7592
- incidentId: text("incident_id").notNull().unique(),
7619
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7620
+ /*
7621
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7622
+ Migration 0006 rebuilt incident keys with project_id first. Drizzle emits DEFAULT while the
7623
+ database GUC/trigger retains ownership stamping and its physical legacy fallback.
7624
+ */
7625
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7626
+ incidentId: text("incident_id").notNull(),
7593
7627
  groupingKey: text("grouping_key").notNull(),
7594
7628
  title: text("title").notNull(),
7595
7629
  severity: text("severity"),
@@ -7603,6 +7637,8 @@ var incidents = projectSchema.table("incidents", {
7603
7637
  createdAt: text("created_at").notNull(),
7604
7638
  updatedAt: text("updated_at").notNull()
7605
7639
  }, (t) => [
7640
+ primaryKey({ columns: [t.projectId, t.id], name: "incidents_pkey" }),
7641
+ unique("incidents_incident_id_key").on(t.projectId, t.incidentId),
7606
7642
  index("idxIncidentsProjectOpenedAt").on(t.projectId, t.openedAt),
7607
7643
  index("idxIncidentsProjectStatus").on(t.projectId, t.status),
7608
7644
  index("idxIncidentsGroupingKey").on(t.groupingKey),
@@ -7657,12 +7693,14 @@ var messages = projectSchema.table("messages", {
7657
7693
  content: text("content").notNull(),
7658
7694
  type: text("type").notNull(),
7659
7695
  read: integer("read").default(0),
7696
+ archived: integer("archived").default(0),
7660
7697
  metadata: jsonb("metadata"),
7661
7698
  createdAt: text("created_at").notNull(),
7662
7699
  updatedAt: text("updated_at").notNull()
7663
7700
  }, (t) => [
7664
7701
  primaryKey({ columns: [t.projectId, t.id] }),
7665
7702
  index("idxMessagesTo").on(t.toId, t.toType, t.read),
7703
+ index("idxMessagesToArchived").on(t.toId, t.toType, t.archived),
7666
7704
  index("idxMessagesFrom").on(t.fromId, t.fromType),
7667
7705
  index("idxMessagesCreatedAt").on(t.createdAt)
7668
7706
  ]);
@@ -7763,7 +7801,8 @@ var cliSessions = projectSchema.table("cli_sessions", {
7763
7801
  index("idx_cli_sessions_project_state").on(t.projectId, t.agentState)
7764
7802
  ]);
7765
7803
  var chatMessages = projectSchema.table("chat_messages", {
7766
- id: text("id").primaryKey(),
7804
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7805
+ id: text("id").notNull(),
7767
7806
  sessionId: text("session_id").notNull(),
7768
7807
  role: text("role").notNull(),
7769
7808
  content: text("content").notNull(),
@@ -7772,6 +7811,7 @@ var chatMessages = projectSchema.table("chat_messages", {
7772
7811
  createdAt: text("created_at").notNull(),
7773
7812
  attachments: jsonb("attachments")
7774
7813
  }, (t) => [
7814
+ primaryKey({ columns: [t.projectId, t.id] }),
7775
7815
  index("idxChatMessagesSessionId").on(t.sessionId),
7776
7816
  index("idxChatMessagesCreatedAt").on(t.createdAt)
7777
7817
  ]);
@@ -7797,7 +7837,8 @@ var chatTokenUsage = projectSchema.table("chat_token_usage", {
7797
7837
  index("idxChatTokenUsageCreatedAt").on(t.createdAt)
7798
7838
  ]);
7799
7839
  var runAuditEvents = projectSchema.table("run_audit_events", {
7800
- id: text("id").primaryKey(),
7840
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7841
+ id: text("id").notNull(),
7801
7842
  timestamp: text("timestamp").notNull(),
7802
7843
  taskId: text("task_id"),
7803
7844
  agentId: text("agent_id").notNull(),
@@ -7807,6 +7848,7 @@ var runAuditEvents = projectSchema.table("run_audit_events", {
7807
7848
  target: text("target").notNull(),
7808
7849
  metadata: jsonb("metadata")
7809
7850
  }, (t) => [
7851
+ primaryKey({ columns: [t.projectId, t.id] }),
7810
7852
  index("idxRunAuditEventsRunIdTimestamp").on(t.runId, t.timestamp),
7811
7853
  index("idxRunAuditEventsTaskIdTimestamp").on(t.taskId, t.timestamp),
7812
7854
  index("idxRunAuditEventsTimestamp").on(t.timestamp)
@@ -7907,13 +7949,14 @@ var missionLineageStops = projectSchema.table("mission_lineage_stops", {
7907
7949
  index("idxMissionLineageStopsMissionId").on(t.projectId, t.missionId)
7908
7950
  ]);
7909
7951
  var verificationCache = projectSchema.table("verification_cache", {
7952
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7910
7953
  treeSha: text("tree_sha").notNull(),
7911
7954
  testCommand: text("test_command").notNull().default(""),
7912
7955
  buildCommand: text("build_command").notNull().default(""),
7913
7956
  recordedAt: text("recorded_at").notNull(),
7914
7957
  taskId: text("task_id")
7915
7958
  }, (t) => [
7916
- primaryKey({ columns: [t.treeSha, t.testCommand, t.buildCommand] }),
7959
+ primaryKey({ columns: [t.projectId, t.treeSha, t.testCommand, t.buildCommand] }),
7917
7960
  index("idxVerificationCacheRecordedAt").on(t.recordedAt)
7918
7961
  ]);
7919
7962
  var importTranslationCache = projectSchema.table("import_translation_cache", {
@@ -7946,7 +7989,8 @@ var importTranslationCache = projectSchema.table("import_translation_cache", {
7946
7989
  index("idxImportTranslationCacheRecordedAt").on(t.recordedAt)
7947
7990
  ]);
7948
7991
  var approvalRequests = projectSchema.table("approval_requests", {
7949
- id: text("id").primaryKey(),
7992
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7993
+ id: text("id").notNull(),
7950
7994
  status: text("status").notNull(),
7951
7995
  requesterActorId: text("requester_actor_id").notNull(),
7952
7996
  requesterActorType: text("requester_actor_type").notNull(),
@@ -7965,13 +8009,14 @@ var approvalRequests = projectSchema.table("approval_requests", {
7965
8009
  createdAt: text("created_at").notNull(),
7966
8010
  updatedAt: text("updated_at").notNull()
7967
8011
  }, (t) => [
8012
+ primaryKey({ columns: [t.projectId, t.id] }),
7968
8013
  index("idxApprovalRequestsStatusCreatedAt").on(t.status, t.createdAt),
7969
8014
  index("idxApprovalRequestsRequesterCreatedAt").on(t.requesterActorId, t.createdAt),
7970
8015
  index("idxApprovalRequestsTaskCreatedAt").on(t.taskId, t.createdAt)
7971
8016
  ]);
7972
8017
  var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_events", {
7973
- projectId: text("project_id").notNull().default(""),
7974
- id: text("id").primaryKey(),
8018
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
8019
+ id: text("id").notNull(),
7975
8020
  requestId: text("request_id").notNull(),
7976
8021
  eventType: text("event_type").notNull(),
7977
8022
  actorId: text("actor_id").notNull(),
@@ -7980,6 +8025,7 @@ var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_eve
7980
8025
  note: text("note"),
7981
8026
  createdAt: text("created_at").notNull()
7982
8027
  }, (t) => [
8028
+ primaryKey({ columns: [t.projectId, t.id] }),
7983
8029
  index("idxApprovalRequestAuditRequestCreatedAt").on(t.requestId, t.createdAt, t.id),
7984
8030
  index("idxApprovalRequestAuditProjectCreatedAt").on(t.projectId, t.createdAt)
7985
8031
  ]);
@@ -9198,6 +9244,8 @@ var DEFAULT_GLOBAL_SETTINGS = {
9198
9244
  var DEFAULT_PROJECT_SETTINGS = {
9199
9245
  // FNXC:TaskRecommendations 2026-08-08-05:02: completion follows-ups stay bounded by default; 0 disables writing them.
9200
9246
  maxRecommendationsPerTask: 3,
9247
+ // FNXC:TaskRecommendations 2026-08-13-03:56: surface completed-task proposals by default; operators can suppress the notice without suppressing capture.
9248
+ recommendationMailboxNoticeEnabled: true,
9201
9249
  globalPause: false,
9202
9250
  globalPauseReason: void 0,
9203
9251
  defaultWorkflowId: void 0,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/reports",
3
- "version": "0.1.54-beta.1",
3
+ "version": "0.1.54-beta.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -6113,9 +6113,14 @@ var config = projectSchema.table("config", {
6113
6113
  // now keyed per-project on `project_id` (the effective PK). `id` is retained
6114
6114
  // for column-shape parity (always 1) but is no longer the PK and no longer
6115
6115
  // CHECK-constrained. Single-project / SQLite-parity callers leave project_id
6116
- // at its '' default (one row), preserving the pre-isolation behavior.
6116
+ // through the database ownership trigger, preserving the pre-isolation behavior.
6117
+ /*
6118
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
6119
+ Migration 0006 owns config's project_id default and leaves its catalog PK as (project_id).
6120
+ Drizzle emits DEFAULT while the database GUC/trigger selects the effective ownership partition.
6121
+ */
6117
6122
  id: integer("id").default(1),
6118
- projectId: text("project_id").notNull().default("").primaryKey(),
6123
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`).primaryKey(),
6119
6124
  nextId: integer("next_id").default(1),
6120
6125
  nextWorkflowStepId: integer("next_workflow_step_id").default(1),
6121
6126
  // FNXC:SqliteFinalRemoval 2026-06-28:
@@ -6509,9 +6514,13 @@ var taskCommitAssociations = projectSchema.table("task_commit_associations", {
6509
6514
  var automations = projectSchema.table("automations", {
6510
6515
  /*
6511
6516
  * FNXC:AutomationIsolation 2026-07-13-22:37:
6512
- * Automations are partitioned by the AsyncDataLayer's project ID because embedded PostgreSQL consolidates the per-project SQLite files into one table. The composite key deliberately permits the same automation ID in two projects without allowing either project's CRUD or cron-claim path to address the other row. The empty default preserves an explicit partition for legacy and project-agnostic callers until startup stamps migrated rows.
6517
+ * Automations are partitioned by the AsyncDataLayer's project ID because embedded PostgreSQL consolidates the per-project SQLite files into one table. The composite key deliberately permits the same automation ID in two projects without allowing either project's CRUD or cron-claim path to address the other row.
6518
+ *
6519
+ * FNXC:MultiProjectIsolation 2026-08-12-15:43:
6520
+ * Migration 0006 owns the default through the database GUC/trigger; Drizzle emits DEFAULT
6521
+ * without replacing the physical legacy fallback or the fail-closed bound writer contract.
6513
6522
  */
6514
- projectId: text("project_id").notNull().default(""),
6523
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
6515
6524
  id: text("id").notNull(),
6516
6525
  name: text("name").notNull(),
6517
6526
  description: text("description"),
@@ -6810,7 +6819,8 @@ var taskDocuments = projectSchema.table("task_documents", {
6810
6819
  index("idxTaskDocumentsTaskId").on(t.taskId)
6811
6820
  ]);
6812
6821
  var artifacts = projectSchema.table("artifacts", {
6813
- id: text("id").primaryKey(),
6822
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
6823
+ id: text("id").notNull(),
6814
6824
  type: text("type").notNull(),
6815
6825
  title: text("title").notNull(),
6816
6826
  description: text("description"),
@@ -6825,7 +6835,8 @@ var artifacts = projectSchema.table("artifacts", {
6825
6835
  createdAt: text("created_at").notNull(),
6826
6836
  updatedAt: text("updated_at").notNull()
6827
6837
  }, (t) => [
6828
- foreignKey({ columns: [t.taskId], foreignColumns: [tasks.id] }).onDelete("cascade"),
6838
+ primaryKey({ columns: [t.projectId, t.id] }),
6839
+ foreignKey({ name: "artifacts_task_id_fkey", columns: [t.projectId, t.taskId], foreignColumns: [tasks.projectId, tasks.id] }).onDelete("cascade"),
6829
6840
  index("idxArtifactsTaskId").on(t.taskId),
6830
6841
  index("idxArtifactsAuthorId").on(t.authorId),
6831
6842
  index("idxArtifactsType").on(t.type),
@@ -7015,7 +7026,8 @@ var evalRunEvents = projectSchema.table("eval_run_events", {
7015
7026
  index("idxEvalRunEventsRunIdSeq").on(t.runId, t.seq)
7016
7027
  ]);
7017
7028
  var secrets = projectSchema.table("secrets", {
7018
- id: text("id").primaryKey(),
7029
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7030
+ id: text("id").notNull(),
7019
7031
  key: text("key").notNull(),
7020
7032
  valueCiphertext: bytea("value_ciphertext").notNull(),
7021
7033
  nonce: bytea("nonce").notNull(),
@@ -7028,7 +7040,8 @@ var secrets = projectSchema.table("secrets", {
7028
7040
  lastReadAt: text("last_read_at"),
7029
7041
  lastReadBy: text("last_read_by")
7030
7042
  }, (t) => [
7031
- unique("secrets_key_unique").on(t.key),
7043
+ primaryKey({ columns: [t.projectId, t.id] }),
7044
+ unique("secrets_key_unique").on(t.projectId, t.key),
7032
7045
  check("secrets_access_policy_check", sql`${t.accessPolicy} IN ('auto', 'prompt', 'deny')`),
7033
7046
  check("secrets_env_exportable_check", sql`${t.envExportable} IN (0, 1)`)
7034
7047
  ]);
@@ -7070,10 +7083,11 @@ var missions = projectSchema.table("missions", {
7070
7083
  updatedAt: text("updated_at").notNull()
7071
7084
  }, (t) => [primaryKey({ columns: [t.projectId, t.id] })]);
7072
7085
  var branchGroups = projectSchema.table("branch_groups", {
7073
- id: text("id").primaryKey(),
7086
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7087
+ id: text("id").notNull(),
7074
7088
  sourceType: text("source_type").notNull(),
7075
7089
  sourceId: text("source_id").notNull(),
7076
- branchName: text("branch_name").notNull().unique(),
7090
+ branchName: text("branch_name").notNull(),
7077
7091
  worktreePath: text("worktree_path"),
7078
7092
  autoMerge: integer("auto_merge").notNull().default(0),
7079
7093
  prState: text("pr_state").notNull().default("none"),
@@ -7089,6 +7103,8 @@ var branchGroups = projectSchema.table("branch_groups", {
7089
7103
  updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
7090
7104
  closedAt: bigint("closed_at", { mode: "number" })
7091
7105
  }, (t) => [
7106
+ primaryKey({ columns: [t.projectId, t.id] }),
7107
+ unique("branch_groups_branch_name_key").on(t.projectId, t.branchName),
7092
7108
  check("branch_groups_source_type_check", sql`${t.sourceType} IN ('mission','planning','new-task')`),
7093
7109
  check("branch_groups_pr_state_check", sql`${t.prState} IN ('none','open','merged','closed')`),
7094
7110
  check("branch_groups_status_check", sql`${t.status} IN ('open','finalized','abandoned')`),
@@ -7490,12 +7506,14 @@ var usageEvents = projectSchema.table("usage_events", {
7490
7506
  index("idxUsageEventsKindTs").on(t.kind, t.ts)
7491
7507
  ]);
7492
7508
  var pluginActivations = projectSchema.table("plugin_activations", {
7493
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7509
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7510
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7494
7511
  pluginId: text("plugin_id").notNull(),
7495
7512
  source: text("source").notNull(),
7496
7513
  pluginVersion: text("plugin_version"),
7497
7514
  activatedAt: text("activated_at").notNull()
7498
7515
  }, (t) => [
7516
+ primaryKey({ columns: [t.projectId, t.id] }),
7499
7517
  index("idxPluginActivationsActivatedAt").on(t.activatedAt),
7500
7518
  index("idxPluginActivationsPluginId").on(t.pluginId)
7501
7519
  ]);
@@ -7520,8 +7538,13 @@ var knowledgePages = projectSchema.table("knowledge_pages", {
7520
7538
  index("idxKnowledgePagesUpdatedAt").on(t.updatedAt)
7521
7539
  ]);
7522
7540
  var deployments = projectSchema.table("deployments", {
7523
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7524
- projectId: text("project_id").notNull().default(""),
7541
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7542
+ /*
7543
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7544
+ Migration 0006 rebuilt deployments_pkey as (project_id, id). Drizzle emits DEFAULT while the
7545
+ database GUC/trigger keeps ownership stamping and the physical legacy fallback authoritative.
7546
+ */
7547
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7525
7548
  deploymentId: text("deployment_id").notNull(),
7526
7549
  service: text("service"),
7527
7550
  environment: text("environment"),
@@ -7532,6 +7555,7 @@ var deployments = projectSchema.table("deployments", {
7532
7555
  meta: jsonb("meta"),
7533
7556
  createdAt: text("created_at").notNull()
7534
7557
  }, (t) => [
7558
+ primaryKey({ columns: [t.projectId, t.id], name: "deployments_pkey" }),
7535
7559
  uniqueIndex("idxDeploymentsProjectDeploymentId").on(t.projectId, t.deploymentId),
7536
7560
  index("idxDeploymentsProjectDeployedAt").on(t.projectId, t.deployedAt),
7537
7561
  index("idxDeploymentsDeployedAt").on(t.deployedAt),
@@ -7539,7 +7563,12 @@ var deployments = projectSchema.table("deployments", {
7539
7563
  ]);
7540
7564
  var githubCheckStates = projectSchema.table("github_check_states", {
7541
7565
  id: integer("id").generatedAlwaysAsIdentity().notNull(),
7542
- projectId: text("project_id").notNull().default(""),
7566
+ /*
7567
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7568
+ Migration 0048 post-dated 0006, so FN-9004 reconciles its physical default to the ownership
7569
+ expression. Drizzle emits DEFAULT while the database GUC/trigger remains the stamping authority.
7570
+ */
7571
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7543
7572
  repo: text("repo").notNull(),
7544
7573
  headSha: text("head_sha").notNull(),
7545
7574
  checkName: text("check_name").notNull(),
@@ -7559,9 +7588,14 @@ var githubCheckStates = projectSchema.table("github_check_states", {
7559
7588
  index("idxGithubCheckStatesProjectReceived").on(t.projectId, t.receivedAt)
7560
7589
  ]);
7561
7590
  var incidents = projectSchema.table("incidents", {
7562
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
7563
- projectId: text("project_id").notNull().default(""),
7564
- incidentId: text("incident_id").notNull().unique(),
7591
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
7592
+ /*
7593
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
7594
+ Migration 0006 rebuilt incident keys with project_id first. Drizzle emits DEFAULT while the
7595
+ database GUC/trigger retains ownership stamping and its physical legacy fallback.
7596
+ */
7597
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7598
+ incidentId: text("incident_id").notNull(),
7565
7599
  groupingKey: text("grouping_key").notNull(),
7566
7600
  title: text("title").notNull(),
7567
7601
  severity: text("severity"),
@@ -7575,6 +7609,8 @@ var incidents = projectSchema.table("incidents", {
7575
7609
  createdAt: text("created_at").notNull(),
7576
7610
  updatedAt: text("updated_at").notNull()
7577
7611
  }, (t) => [
7612
+ primaryKey({ columns: [t.projectId, t.id], name: "incidents_pkey" }),
7613
+ unique("incidents_incident_id_key").on(t.projectId, t.incidentId),
7578
7614
  index("idxIncidentsProjectOpenedAt").on(t.projectId, t.openedAt),
7579
7615
  index("idxIncidentsProjectStatus").on(t.projectId, t.status),
7580
7616
  index("idxIncidentsGroupingKey").on(t.groupingKey),
@@ -7629,12 +7665,14 @@ var messages = projectSchema.table("messages", {
7629
7665
  content: text("content").notNull(),
7630
7666
  type: text("type").notNull(),
7631
7667
  read: integer("read").default(0),
7668
+ archived: integer("archived").default(0),
7632
7669
  metadata: jsonb("metadata"),
7633
7670
  createdAt: text("created_at").notNull(),
7634
7671
  updatedAt: text("updated_at").notNull()
7635
7672
  }, (t) => [
7636
7673
  primaryKey({ columns: [t.projectId, t.id] }),
7637
7674
  index("idxMessagesTo").on(t.toId, t.toType, t.read),
7675
+ index("idxMessagesToArchived").on(t.toId, t.toType, t.archived),
7638
7676
  index("idxMessagesFrom").on(t.fromId, t.fromType),
7639
7677
  index("idxMessagesCreatedAt").on(t.createdAt)
7640
7678
  ]);
@@ -7735,7 +7773,8 @@ var cliSessions = projectSchema.table("cli_sessions", {
7735
7773
  index("idx_cli_sessions_project_state").on(t.projectId, t.agentState)
7736
7774
  ]);
7737
7775
  var chatMessages = projectSchema.table("chat_messages", {
7738
- id: text("id").primaryKey(),
7776
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7777
+ id: text("id").notNull(),
7739
7778
  sessionId: text("session_id").notNull(),
7740
7779
  role: text("role").notNull(),
7741
7780
  content: text("content").notNull(),
@@ -7744,6 +7783,7 @@ var chatMessages = projectSchema.table("chat_messages", {
7744
7783
  createdAt: text("created_at").notNull(),
7745
7784
  attachments: jsonb("attachments")
7746
7785
  }, (t) => [
7786
+ primaryKey({ columns: [t.projectId, t.id] }),
7747
7787
  index("idxChatMessagesSessionId").on(t.sessionId),
7748
7788
  index("idxChatMessagesCreatedAt").on(t.createdAt)
7749
7789
  ]);
@@ -7769,7 +7809,8 @@ var chatTokenUsage = projectSchema.table("chat_token_usage", {
7769
7809
  index("idxChatTokenUsageCreatedAt").on(t.createdAt)
7770
7810
  ]);
7771
7811
  var runAuditEvents = projectSchema.table("run_audit_events", {
7772
- id: text("id").primaryKey(),
7812
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7813
+ id: text("id").notNull(),
7773
7814
  timestamp: text("timestamp").notNull(),
7774
7815
  taskId: text("task_id"),
7775
7816
  agentId: text("agent_id").notNull(),
@@ -7779,6 +7820,7 @@ var runAuditEvents = projectSchema.table("run_audit_events", {
7779
7820
  target: text("target").notNull(),
7780
7821
  metadata: jsonb("metadata")
7781
7822
  }, (t) => [
7823
+ primaryKey({ columns: [t.projectId, t.id] }),
7782
7824
  index("idxRunAuditEventsRunIdTimestamp").on(t.runId, t.timestamp),
7783
7825
  index("idxRunAuditEventsTaskIdTimestamp").on(t.taskId, t.timestamp),
7784
7826
  index("idxRunAuditEventsTimestamp").on(t.timestamp)
@@ -7879,13 +7921,14 @@ var missionLineageStops = projectSchema.table("mission_lineage_stops", {
7879
7921
  index("idxMissionLineageStopsMissionId").on(t.projectId, t.missionId)
7880
7922
  ]);
7881
7923
  var verificationCache = projectSchema.table("verification_cache", {
7924
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7882
7925
  treeSha: text("tree_sha").notNull(),
7883
7926
  testCommand: text("test_command").notNull().default(""),
7884
7927
  buildCommand: text("build_command").notNull().default(""),
7885
7928
  recordedAt: text("recorded_at").notNull(),
7886
7929
  taskId: text("task_id")
7887
7930
  }, (t) => [
7888
- primaryKey({ columns: [t.treeSha, t.testCommand, t.buildCommand] }),
7931
+ primaryKey({ columns: [t.projectId, t.treeSha, t.testCommand, t.buildCommand] }),
7889
7932
  index("idxVerificationCacheRecordedAt").on(t.recordedAt)
7890
7933
  ]);
7891
7934
  var importTranslationCache = projectSchema.table("import_translation_cache", {
@@ -7918,7 +7961,8 @@ var importTranslationCache = projectSchema.table("import_translation_cache", {
7918
7961
  index("idxImportTranslationCacheRecordedAt").on(t.recordedAt)
7919
7962
  ]);
7920
7963
  var approvalRequests = projectSchema.table("approval_requests", {
7921
- id: text("id").primaryKey(),
7964
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7965
+ id: text("id").notNull(),
7922
7966
  status: text("status").notNull(),
7923
7967
  requesterActorId: text("requester_actor_id").notNull(),
7924
7968
  requesterActorType: text("requester_actor_type").notNull(),
@@ -7937,13 +7981,14 @@ var approvalRequests = projectSchema.table("approval_requests", {
7937
7981
  createdAt: text("created_at").notNull(),
7938
7982
  updatedAt: text("updated_at").notNull()
7939
7983
  }, (t) => [
7984
+ primaryKey({ columns: [t.projectId, t.id] }),
7940
7985
  index("idxApprovalRequestsStatusCreatedAt").on(t.status, t.createdAt),
7941
7986
  index("idxApprovalRequestsRequesterCreatedAt").on(t.requesterActorId, t.createdAt),
7942
7987
  index("idxApprovalRequestsTaskCreatedAt").on(t.taskId, t.createdAt)
7943
7988
  ]);
7944
7989
  var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_events", {
7945
- projectId: text("project_id").notNull().default(""),
7946
- id: text("id").primaryKey(),
7990
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
7991
+ id: text("id").notNull(),
7947
7992
  requestId: text("request_id").notNull(),
7948
7993
  eventType: text("event_type").notNull(),
7949
7994
  actorId: text("actor_id").notNull(),
@@ -7952,6 +7997,7 @@ var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_eve
7952
7997
  note: text("note"),
7953
7998
  createdAt: text("created_at").notNull()
7954
7999
  }, (t) => [
8000
+ primaryKey({ columns: [t.projectId, t.id] }),
7955
8001
  index("idxApprovalRequestAuditRequestCreatedAt").on(t.requestId, t.createdAt, t.id),
7956
8002
  index("idxApprovalRequestAuditProjectCreatedAt").on(t.projectId, t.createdAt)
7957
8003
  ]);
@@ -9078,6 +9124,8 @@ var DEFAULT_GLOBAL_SETTINGS = {
9078
9124
  var DEFAULT_PROJECT_SETTINGS = {
9079
9125
  // FNXC:TaskRecommendations 2026-08-08-05:02: completion follows-ups stay bounded by default; 0 disables writing them.
9080
9126
  maxRecommendationsPerTask: 3,
9127
+ // FNXC:TaskRecommendations 2026-08-13-03:56: surface completed-task proposals by default; operators can suppress the notice without suppressing capture.
9128
+ recommendationMailboxNoticeEnabled: true,
9081
9129
  globalPause: false,
9082
9130
  globalPauseReason: void 0,
9083
9131
  defaultWorkflowId: void 0,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.54-beta.1",
3
+ "version": "0.1.54-beta.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {