@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
@@ -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/todos",
3
- "version": "0.1.3-beta.1",
3
+ "version": "0.1.3-beta.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -163414,9 +163414,14 @@ var config = projectSchema.table("config", {
163414
163414
  // now keyed per-project on `project_id` (the effective PK). `id` is retained
163415
163415
  // for column-shape parity (always 1) but is no longer the PK and no longer
163416
163416
  // CHECK-constrained. Single-project / SQLite-parity callers leave project_id
163417
- // at its '' default (one row), preserving the pre-isolation behavior.
163417
+ // through the database ownership trigger, preserving the pre-isolation behavior.
163418
+ /*
163419
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
163420
+ Migration 0006 owns config's project_id default and leaves its catalog PK as (project_id).
163421
+ Drizzle emits DEFAULT while the database GUC/trigger selects the effective ownership partition.
163422
+ */
163418
163423
  id: integer("id").default(1),
163419
- projectId: text("project_id").notNull().default("").primaryKey(),
163424
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`).primaryKey(),
163420
163425
  nextId: integer("next_id").default(1),
163421
163426
  nextWorkflowStepId: integer("next_workflow_step_id").default(1),
163422
163427
  // FNXC:SqliteFinalRemoval 2026-06-28:
@@ -163810,9 +163815,13 @@ var taskCommitAssociations = projectSchema.table("task_commit_associations", {
163810
163815
  var automations = projectSchema.table("automations", {
163811
163816
  /*
163812
163817
  * FNXC:AutomationIsolation 2026-07-13-22:37:
163813
- * 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.
163818
+ * 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.
163819
+ *
163820
+ * FNXC:MultiProjectIsolation 2026-08-12-15:43:
163821
+ * Migration 0006 owns the default through the database GUC/trigger; Drizzle emits DEFAULT
163822
+ * without replacing the physical legacy fallback or the fail-closed bound writer contract.
163814
163823
  */
163815
- projectId: text("project_id").notNull().default(""),
163824
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
163816
163825
  id: text("id").notNull(),
163817
163826
  name: text("name").notNull(),
163818
163827
  description: text("description"),
@@ -164111,7 +164120,8 @@ var taskDocuments = projectSchema.table("task_documents", {
164111
164120
  index("idxTaskDocumentsTaskId").on(t.taskId)
164112
164121
  ]);
164113
164122
  var artifacts = projectSchema.table("artifacts", {
164114
- id: text("id").primaryKey(),
164123
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164124
+ id: text("id").notNull(),
164115
164125
  type: text("type").notNull(),
164116
164126
  title: text("title").notNull(),
164117
164127
  description: text("description"),
@@ -164126,7 +164136,8 @@ var artifacts = projectSchema.table("artifacts", {
164126
164136
  createdAt: text("created_at").notNull(),
164127
164137
  updatedAt: text("updated_at").notNull()
164128
164138
  }, (t) => [
164129
- foreignKey({ columns: [t.taskId], foreignColumns: [tasks.id] }).onDelete("cascade"),
164139
+ primaryKey({ columns: [t.projectId, t.id] }),
164140
+ foreignKey({ name: "artifacts_task_id_fkey", columns: [t.projectId, t.taskId], foreignColumns: [tasks.projectId, tasks.id] }).onDelete("cascade"),
164130
164141
  index("idxArtifactsTaskId").on(t.taskId),
164131
164142
  index("idxArtifactsAuthorId").on(t.authorId),
164132
164143
  index("idxArtifactsType").on(t.type),
@@ -164316,7 +164327,8 @@ var evalRunEvents = projectSchema.table("eval_run_events", {
164316
164327
  index("idxEvalRunEventsRunIdSeq").on(t.runId, t.seq)
164317
164328
  ]);
164318
164329
  var secrets = projectSchema.table("secrets", {
164319
- id: text("id").primaryKey(),
164330
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164331
+ id: text("id").notNull(),
164320
164332
  key: text("key").notNull(),
164321
164333
  valueCiphertext: bytea("value_ciphertext").notNull(),
164322
164334
  nonce: bytea("nonce").notNull(),
@@ -164329,7 +164341,8 @@ var secrets = projectSchema.table("secrets", {
164329
164341
  lastReadAt: text("last_read_at"),
164330
164342
  lastReadBy: text("last_read_by")
164331
164343
  }, (t) => [
164332
- unique("secrets_key_unique").on(t.key),
164344
+ primaryKey({ columns: [t.projectId, t.id] }),
164345
+ unique("secrets_key_unique").on(t.projectId, t.key),
164333
164346
  check("secrets_access_policy_check", sql`${t.accessPolicy} IN ('auto', 'prompt', 'deny')`),
164334
164347
  check("secrets_env_exportable_check", sql`${t.envExportable} IN (0, 1)`)
164335
164348
  ]);
@@ -164371,10 +164384,11 @@ var missions = projectSchema.table("missions", {
164371
164384
  updatedAt: text("updated_at").notNull()
164372
164385
  }, (t) => [primaryKey({ columns: [t.projectId, t.id] })]);
164373
164386
  var branchGroups = projectSchema.table("branch_groups", {
164374
- id: text("id").primaryKey(),
164387
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164388
+ id: text("id").notNull(),
164375
164389
  sourceType: text("source_type").notNull(),
164376
164390
  sourceId: text("source_id").notNull(),
164377
- branchName: text("branch_name").notNull().unique(),
164391
+ branchName: text("branch_name").notNull(),
164378
164392
  worktreePath: text("worktree_path"),
164379
164393
  autoMerge: integer("auto_merge").notNull().default(0),
164380
164394
  prState: text("pr_state").notNull().default("none"),
@@ -164390,6 +164404,8 @@ var branchGroups = projectSchema.table("branch_groups", {
164390
164404
  updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
164391
164405
  closedAt: bigint("closed_at", { mode: "number" })
164392
164406
  }, (t) => [
164407
+ primaryKey({ columns: [t.projectId, t.id] }),
164408
+ unique("branch_groups_branch_name_key").on(t.projectId, t.branchName),
164393
164409
  check("branch_groups_source_type_check", sql`${t.sourceType} IN ('mission','planning','new-task')`),
164394
164410
  check("branch_groups_pr_state_check", sql`${t.prState} IN ('none','open','merged','closed')`),
164395
164411
  check("branch_groups_status_check", sql`${t.status} IN ('open','finalized','abandoned')`),
@@ -164791,12 +164807,14 @@ var usageEvents = projectSchema.table("usage_events", {
164791
164807
  index("idxUsageEventsKindTs").on(t.kind, t.ts)
164792
164808
  ]);
164793
164809
  var pluginActivations = projectSchema.table("plugin_activations", {
164794
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
164810
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164811
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
164795
164812
  pluginId: text("plugin_id").notNull(),
164796
164813
  source: text("source").notNull(),
164797
164814
  pluginVersion: text("plugin_version"),
164798
164815
  activatedAt: text("activated_at").notNull()
164799
164816
  }, (t) => [
164817
+ primaryKey({ columns: [t.projectId, t.id] }),
164800
164818
  index("idxPluginActivationsActivatedAt").on(t.activatedAt),
164801
164819
  index("idxPluginActivationsPluginId").on(t.pluginId)
164802
164820
  ]);
@@ -164821,8 +164839,13 @@ var knowledgePages = projectSchema.table("knowledge_pages", {
164821
164839
  index("idxKnowledgePagesUpdatedAt").on(t.updatedAt)
164822
164840
  ]);
164823
164841
  var deployments = projectSchema.table("deployments", {
164824
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
164825
- projectId: text("project_id").notNull().default(""),
164842
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
164843
+ /*
164844
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
164845
+ Migration 0006 rebuilt deployments_pkey as (project_id, id). Drizzle emits DEFAULT while the
164846
+ database GUC/trigger keeps ownership stamping and the physical legacy fallback authoritative.
164847
+ */
164848
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164826
164849
  deploymentId: text("deployment_id").notNull(),
164827
164850
  service: text("service"),
164828
164851
  environment: text("environment"),
@@ -164833,6 +164856,7 @@ var deployments = projectSchema.table("deployments", {
164833
164856
  meta: jsonb("meta"),
164834
164857
  createdAt: text("created_at").notNull()
164835
164858
  }, (t) => [
164859
+ primaryKey({ columns: [t.projectId, t.id], name: "deployments_pkey" }),
164836
164860
  uniqueIndex("idxDeploymentsProjectDeploymentId").on(t.projectId, t.deploymentId),
164837
164861
  index("idxDeploymentsProjectDeployedAt").on(t.projectId, t.deployedAt),
164838
164862
  index("idxDeploymentsDeployedAt").on(t.deployedAt),
@@ -164840,7 +164864,12 @@ var deployments = projectSchema.table("deployments", {
164840
164864
  ]);
164841
164865
  var githubCheckStates = projectSchema.table("github_check_states", {
164842
164866
  id: integer("id").generatedAlwaysAsIdentity().notNull(),
164843
- projectId: text("project_id").notNull().default(""),
164867
+ /*
164868
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
164869
+ Migration 0048 post-dated 0006, so FN-9004 reconciles its physical default to the ownership
164870
+ expression. Drizzle emits DEFAULT while the database GUC/trigger remains the stamping authority.
164871
+ */
164872
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164844
164873
  repo: text("repo").notNull(),
164845
164874
  headSha: text("head_sha").notNull(),
164846
164875
  checkName: text("check_name").notNull(),
@@ -164860,9 +164889,14 @@ var githubCheckStates = projectSchema.table("github_check_states", {
164860
164889
  index("idxGithubCheckStatesProjectReceived").on(t.projectId, t.receivedAt)
164861
164890
  ]);
164862
164891
  var incidents = projectSchema.table("incidents", {
164863
- id: integer("id").generatedAlwaysAsIdentity().primaryKey(),
164864
- projectId: text("project_id").notNull().default(""),
164865
- incidentId: text("incident_id").notNull().unique(),
164892
+ id: integer("id").generatedAlwaysAsIdentity().notNull(),
164893
+ /*
164894
+ FNXC:MultiProjectIsolation 2026-08-12-15:43:
164895
+ Migration 0006 rebuilt incident keys with project_id first. Drizzle emits DEFAULT while the
164896
+ database GUC/trigger retains ownership stamping and its physical legacy fallback.
164897
+ */
164898
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
164899
+ incidentId: text("incident_id").notNull(),
164866
164900
  groupingKey: text("grouping_key").notNull(),
164867
164901
  title: text("title").notNull(),
164868
164902
  severity: text("severity"),
@@ -164876,6 +164910,8 @@ var incidents = projectSchema.table("incidents", {
164876
164910
  createdAt: text("created_at").notNull(),
164877
164911
  updatedAt: text("updated_at").notNull()
164878
164912
  }, (t) => [
164913
+ primaryKey({ columns: [t.projectId, t.id], name: "incidents_pkey" }),
164914
+ unique("incidents_incident_id_key").on(t.projectId, t.incidentId),
164879
164915
  index("idxIncidentsProjectOpenedAt").on(t.projectId, t.openedAt),
164880
164916
  index("idxIncidentsProjectStatus").on(t.projectId, t.status),
164881
164917
  index("idxIncidentsGroupingKey").on(t.groupingKey),
@@ -164930,12 +164966,14 @@ var messages = projectSchema.table("messages", {
164930
164966
  content: text("content").notNull(),
164931
164967
  type: text("type").notNull(),
164932
164968
  read: integer("read").default(0),
164969
+ archived: integer("archived").default(0),
164933
164970
  metadata: jsonb("metadata"),
164934
164971
  createdAt: text("created_at").notNull(),
164935
164972
  updatedAt: text("updated_at").notNull()
164936
164973
  }, (t) => [
164937
164974
  primaryKey({ columns: [t.projectId, t.id] }),
164938
164975
  index("idxMessagesTo").on(t.toId, t.toType, t.read),
164976
+ index("idxMessagesToArchived").on(t.toId, t.toType, t.archived),
164939
164977
  index("idxMessagesFrom").on(t.fromId, t.fromType),
164940
164978
  index("idxMessagesCreatedAt").on(t.createdAt)
164941
164979
  ]);
@@ -165036,7 +165074,8 @@ var cliSessions = projectSchema.table("cli_sessions", {
165036
165074
  index("idx_cli_sessions_project_state").on(t.projectId, t.agentState)
165037
165075
  ]);
165038
165076
  var chatMessages = projectSchema.table("chat_messages", {
165039
- id: text("id").primaryKey(),
165077
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
165078
+ id: text("id").notNull(),
165040
165079
  sessionId: text("session_id").notNull(),
165041
165080
  role: text("role").notNull(),
165042
165081
  content: text("content").notNull(),
@@ -165045,6 +165084,7 @@ var chatMessages = projectSchema.table("chat_messages", {
165045
165084
  createdAt: text("created_at").notNull(),
165046
165085
  attachments: jsonb("attachments")
165047
165086
  }, (t) => [
165087
+ primaryKey({ columns: [t.projectId, t.id] }),
165048
165088
  index("idxChatMessagesSessionId").on(t.sessionId),
165049
165089
  index("idxChatMessagesCreatedAt").on(t.createdAt)
165050
165090
  ]);
@@ -165070,7 +165110,8 @@ var chatTokenUsage = projectSchema.table("chat_token_usage", {
165070
165110
  index("idxChatTokenUsageCreatedAt").on(t.createdAt)
165071
165111
  ]);
165072
165112
  var runAuditEvents = projectSchema.table("run_audit_events", {
165073
- id: text("id").primaryKey(),
165113
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
165114
+ id: text("id").notNull(),
165074
165115
  timestamp: text("timestamp").notNull(),
165075
165116
  taskId: text("task_id"),
165076
165117
  agentId: text("agent_id").notNull(),
@@ -165080,6 +165121,7 @@ var runAuditEvents = projectSchema.table("run_audit_events", {
165080
165121
  target: text("target").notNull(),
165081
165122
  metadata: jsonb("metadata")
165082
165123
  }, (t) => [
165124
+ primaryKey({ columns: [t.projectId, t.id] }),
165083
165125
  index("idxRunAuditEventsRunIdTimestamp").on(t.runId, t.timestamp),
165084
165126
  index("idxRunAuditEventsTaskIdTimestamp").on(t.taskId, t.timestamp),
165085
165127
  index("idxRunAuditEventsTimestamp").on(t.timestamp)
@@ -165180,13 +165222,14 @@ var missionLineageStops = projectSchema.table("mission_lineage_stops", {
165180
165222
  index("idxMissionLineageStopsMissionId").on(t.projectId, t.missionId)
165181
165223
  ]);
165182
165224
  var verificationCache = projectSchema.table("verification_cache", {
165225
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
165183
165226
  treeSha: text("tree_sha").notNull(),
165184
165227
  testCommand: text("test_command").notNull().default(""),
165185
165228
  buildCommand: text("build_command").notNull().default(""),
165186
165229
  recordedAt: text("recorded_at").notNull(),
165187
165230
  taskId: text("task_id")
165188
165231
  }, (t) => [
165189
- primaryKey({ columns: [t.treeSha, t.testCommand, t.buildCommand] }),
165232
+ primaryKey({ columns: [t.projectId, t.treeSha, t.testCommand, t.buildCommand] }),
165190
165233
  index("idxVerificationCacheRecordedAt").on(t.recordedAt)
165191
165234
  ]);
165192
165235
  var importTranslationCache = projectSchema.table("import_translation_cache", {
@@ -165219,7 +165262,8 @@ var importTranslationCache = projectSchema.table("import_translation_cache", {
165219
165262
  index("idxImportTranslationCacheRecordedAt").on(t.recordedAt)
165220
165263
  ]);
165221
165264
  var approvalRequests = projectSchema.table("approval_requests", {
165222
- id: text("id").primaryKey(),
165265
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
165266
+ id: text("id").notNull(),
165223
165267
  status: text("status").notNull(),
165224
165268
  requesterActorId: text("requester_actor_id").notNull(),
165225
165269
  requesterActorType: text("requester_actor_type").notNull(),
@@ -165238,13 +165282,14 @@ var approvalRequests = projectSchema.table("approval_requests", {
165238
165282
  createdAt: text("created_at").notNull(),
165239
165283
  updatedAt: text("updated_at").notNull()
165240
165284
  }, (t) => [
165285
+ primaryKey({ columns: [t.projectId, t.id] }),
165241
165286
  index("idxApprovalRequestsStatusCreatedAt").on(t.status, t.createdAt),
165242
165287
  index("idxApprovalRequestsRequesterCreatedAt").on(t.requesterActorId, t.createdAt),
165243
165288
  index("idxApprovalRequestsTaskCreatedAt").on(t.taskId, t.createdAt)
165244
165289
  ]);
165245
165290
  var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_events", {
165246
- projectId: text("project_id").notNull().default(""),
165247
- id: text("id").primaryKey(),
165291
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
165292
+ id: text("id").notNull(),
165248
165293
  requestId: text("request_id").notNull(),
165249
165294
  eventType: text("event_type").notNull(),
165250
165295
  actorId: text("actor_id").notNull(),
@@ -165253,6 +165298,7 @@ var approvalRequestAuditEvents = projectSchema.table("approval_request_audit_eve
165253
165298
  note: text("note"),
165254
165299
  createdAt: text("created_at").notNull()
165255
165300
  }, (t) => [
165301
+ primaryKey({ columns: [t.projectId, t.id] }),
165256
165302
  index("idxApprovalRequestAuditRequestCreatedAt").on(t.requestId, t.createdAt, t.id),
165257
165303
  index("idxApprovalRequestAuditProjectCreatedAt").on(t.projectId, t.createdAt)
165258
165304
  ]);
@@ -166379,6 +166425,8 @@ var DEFAULT_GLOBAL_SETTINGS = {
166379
166425
  var DEFAULT_PROJECT_SETTINGS = {
166380
166426
  // FNXC:TaskRecommendations 2026-08-08-05:02: completion follows-ups stay bounded by default; 0 disables writing them.
166381
166427
  maxRecommendationsPerTask: 3,
166428
+ // FNXC:TaskRecommendations 2026-08-13-03:56: surface completed-task proposals by default; operators can suppress the notice without suppressing capture.
166429
+ recommendationMailboxNoticeEnabled: true,
166382
166430
  globalPause: false,
166383
166431
  globalPauseReason: void 0,
166384
166432
  defaultWorkflowId: void 0,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.54-beta.1",
3
+ "version": "0.1.54-beta.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.76.0-beta.1",
3
+ "version": "0.76.0-beta.3",
4
4
  "license": "MIT",
5
5
  "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
6
6
  "homepage": "https://github.com/Runfusion/Fusion#readme",
@@ -49,8 +49,8 @@
49
49
  "dependencies": {
50
50
  "@agentclientprotocol/sdk": "0.24.0",
51
51
  "agent-browser": "0.26.0",
52
- "@earendil-works/pi-ai": "0.82.1",
53
- "@earendil-works/pi-coding-agent": "0.82.1",
52
+ "@earendil-works/pi-ai": "0.84.1",
53
+ "@earendil-works/pi-coding-agent": "0.84.1",
54
54
  "claude-code-cli-acp": "0.1.1",
55
55
  "dockerode": "^4.0.12",
56
56
  "electron": "^33.4.11",
@@ -32,7 +32,7 @@ Mission → Milestone → Slice → Feature → Task
32
32
  - **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
33
33
  - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_list_goals`, `fn_mission_link_goal`, `fn_mission_unlink_goal`, `fn_mission_backfill_assertions`, `fn_mission_delete`, `fn_mission_set_status`, `fn_mission_clear_blocked`, `fn_mission_update`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_feature_delete`, `fn_slice_delete`, `fn_milestone_delete`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_set_status`, `fn_mission_reconcile`, `fn_feature_repair_validation`, `fn_feature_update`, `fn_milestone_update`
34
34
  - **Goal tools** — `fn_goal_list`, `fn_goal_create`, `fn_goal_archive`, `fn_goal_show`
35
- - **Agent tools** — `fn_agent_stop`, `fn_agent_start`, `fn_agent_create`, `fn_agent_update`, `fn_agent_set_instructions`, `fn_agent_delete`, `fn_list_agents`, `fn_delegate_task`, `fn_agent_show`, `fn_agent_org_chart`
35
+ - **Agent tools** — `fn_agent_stop`, `fn_agent_start`, `fn_agent_create`, `fn_agent_update`, `fn_agent_set_instructions`, `fn_agent_read_evaluations`, `fn_agent_evaluation_followup`, `fn_agent_delete`, `fn_list_agents`, `fn_delegate_task`, `fn_agent_show`, `fn_agent_org_chart`
36
36
  - **Skills tools** — `fn_skills_search`, `fn_skills_install`
37
37
  - **Insight tools** — `fn_insight_list`, `fn_insight_show`, `fn_insight_run_list`, `fn_insight_run_show`
38
38
  - **Other tools** — `fn_web_fetch`, `fn_secret_get`, `fn_experiment_finalize`
@@ -680,6 +680,28 @@ Set the instructionsText and/or instructionsPath of one of the caller's direct o
680
680
  | `instructions_text` | string | — | Inline instructions. Pass an empty string to clear. |
681
681
  | `instructions_path` | string | — | Path to a markdown instructions file. Pass an empty string to clear. |
682
682
 
683
+ ### fn_agent_read_evaluations
684
+
685
+ Read ratings, feedback, reflections, and performance data for a direct or indirect report.
686
+
687
+ | Parameter | Type | Required | Description |
688
+ |-----------|------|----------|-------------|
689
+ | `agent_id` | string | ✓ | Target agent ID or resolvable name |
690
+ | `rating_limit` | number | — | Maximum ratings to return (default 10) |
691
+ | `reflection_limit` | number | — | Maximum reflections to return (default 5) |
692
+
693
+ ### fn_agent_evaluation_followup
694
+
695
+ Record a coaching evaluation follow-up for a direct or indirect report to read through its self-improvement loop.
696
+
697
+ | Parameter | Type | Required | Description |
698
+ |-----------|------|----------|-------------|
699
+ | `agent_id` | string | ✓ | Target agent ID or resolvable name |
700
+ | `score` | number | ✓ | Evaluation score from 1 to 5 |
701
+ | `comment` | string | ✓ | Coaching or follow-up note |
702
+ | `category` | string | — | Optional evaluation category |
703
+ | `task_id` | string | — | Optional related task ID |
704
+
683
705
  ### fn_agent_delete
684
706
 
685
707
  Delete a non-ephemeral agent.