@runfusion/fusion 0.76.0-beta.1 → 0.76.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +503 -213
- package/dist/child-process-worker.js +466 -207
- package/dist/client/.vite/manifest.json +260 -260
- package/dist/client/assets/{AgentDetailView-Cbl1sw6i.js → AgentDetailView-gak4EWTI.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-DD1U5M9p.js → AgentPermissionPolicyEditor-DP1QbZL-.js} +1 -1
- package/dist/client/assets/{AgentsView-BMcCbple.js → AgentsView-DAMRTKzI.js} +3 -3
- package/dist/client/assets/ChatView-iE-2gf5P.js +13 -0
- package/dist/client/assets/{CommandCenter-D7mcD61V.js → CommandCenter-B6RnkLYm.js} +1 -1
- package/dist/client/assets/{DevServerView-DaqCn0p5.js → DevServerView-DcFL_LzK.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-CLdqqqYN.js → DirectoryPicker-CtjqrYoO.js} +1 -1
- package/dist/client/assets/{DocumentsView-BOROVxPm.js → DocumentsView-BkAe2S4H.js} +1 -1
- package/dist/client/assets/{EvalsView-BQMXRUlQ.js → EvalsView-CbGA9dMn.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-1GNeCIQT.js → ExperimentalAgentOnboardingModal-CMgO_S8T.js} +1 -1
- package/dist/client/assets/{GoalsView-Cr3c_2GC.js → GoalsView-_3P9J5sf.js} +1 -1
- package/dist/client/assets/{InsightsView-DgVBVQM4.js → InsightsView-DOhO7xH5.js} +1 -1
- package/dist/client/assets/{MemoryView-C0VzzMSw.js → MemoryView-DwJas8vi.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-D1kkkVtP.js → PiExtensionsManager-B_LiW_e9.js} +1 -1
- package/dist/client/assets/{PluginManager-BW-_Zyo5.js → PluginManager-BkB6WLQc.js} +1 -1
- package/dist/client/assets/{PullRequestView-Cmlo4nWA.js → PullRequestView-DcH5tmYc.js} +1 -1
- package/dist/client/assets/{ReportModal-BWuaroTF.js → ReportModal-BOEbqtqG.js} +1 -1
- package/dist/client/assets/{ResearchView-BmkF_vZU.js → ResearchView-Dp6V42pI.js} +1 -1
- package/dist/client/assets/{SecretsView-DVc8Hky0.js → SecretsView-BCqXHB2L.js} +1 -1
- package/dist/client/assets/{SessionTerminal-DCXrxA57.js → SessionTerminal-CkdoQv4y.js} +1 -1
- package/dist/client/assets/{SettingsModal-DZ32F1c-.js → SettingsModal-D4Fn4GlS.js} +3 -3
- package/dist/client/assets/{SettingsModal-DqwpLnDU.js → SettingsModal-Dc7YG6KB.js} +1 -1
- package/dist/client/assets/{SettingsTextareaRow-B5spAoOY.js → SettingsTextareaRow-WSkBoAOO.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-VTBLyFzr.js → SetupWizardModal-VTrJAsKd.js} +2 -2
- package/dist/client/assets/{SkillsView-CR91ey9d.js → SkillsView-CXeXOxfF.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-BzGh_Fd9.js → WorkflowNodeEditor-DoxLGPRF.js} +1 -1
- package/dist/client/assets/{agent-import-generation-D27NKQsr.js → agent-import-generation-upc0yw-M.js} +1 -1
- package/dist/client/assets/{agentsOrgChartLayout-C2K_M3x3.js → agentsOrgChartLayout-C3iumMrW.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BQy8UcRx.js → architectureDiagram-3BPJPVTR-D6jqc3fJ.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CZG1bqFQ.js → blockDiagram-GPEHLZMM-DY3AKuPD.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CZmO_kg3.js → c4Diagram-AAUBKEIU-CpD52V4g.js} +1 -1
- package/dist/client/assets/channel-CaxOu15c.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-jsad6DTE.js → chunk-2J33WTMH-CPeIHyAX.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-DX7SuvwP.js → chunk-4BX2VUAB-ivAwI4xM.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-De20xFgU.js → chunk-55IACEB6-BtVQ5XaZ.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CNiri9yW.js → chunk-727SXJPM-1eap1vDU.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DvDqG-ax.js → chunk-AQP2D5EJ-B2NB3BW9.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DkMdKaUq.js → chunk-FMBD7UC4-Hk_smNYv.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-Do5BwIrI.js → chunk-ND2GUHAM-BmGCAojk.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BnJgt9vl.js → chunk-QZHKN3VN-D0aXZ8CV.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DXIkGbsl.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DXIkGbsl.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-D-ivAzzF.js → cose-bilkent-S5V4N54A-DAbu_gnF.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-Bpd9L0or.js → dagre-BM42HDAG-BdmLlrDJ.js} +1 -1
- package/dist/client/assets/{dashboard-view-DSvVO6Vr.js → dashboard-view-BoFBSXUn.js} +1 -1
- package/dist/client/assets/{dashboard-view-CgBo8Ctn.js → dashboard-view-CULL1yhL.js} +1 -1
- package/dist/client/assets/{dashboard-view-C-XU9CVv.js → dashboard-view-CxXMDfNY.js} +1 -1
- package/dist/client/assets/{dashboard-view-DbaRE8Ma.js → dashboard-view-PRCWCSLm.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-B6TT1NWU.js → diagram-2AECGRRQ-PpqLbVUA.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-DpRS2yRw.js → diagram-5GNKFQAL-9rkGmTwh.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BVbZr02C.js → diagram-KO2AKTUF-BT-efOMo.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DzENbfal.js → diagram-LMA3HP47-w79OWFxg.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BIePG5SY.js → diagram-OG6HWLK6-Bye9I5IO.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CQo3WBwo.js → erDiagram-TEJ5UH35-aodREgDf.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-Ct2H4jYo.js → flowDiagram-I6XJVG4X-D0DKItY3.js} +1 -1
- package/dist/client/assets/{folder-open-DAh8mpTX.js → folder-open-CqvaMJvx.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DyOLCG4B.js → ganttDiagram-6RSMTGT7-CZVApkvw.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-sC28-su3.js → gitGraphDiagram-PVQCEYII-D_ynwJ4p.js} +1 -1
- package/dist/client/assets/index-DWRJyaa3.js +2818 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Q81_5aBZ.js → infoDiagram-5YYISTIA-pJG6zxjk.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-Cwkjs0z5.js → ishikawaDiagram-YF4QCWOH-nFZ5laUo.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BXcBV1Bc.js → journeyDiagram-JHISSGLW-CWpCaAIe.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BI7hW892.js → kanban-definition-UN3LZRKU-ATkPspKa.js} +1 -1
- package/dist/client/assets/{mermaid.core-B8oDA6jj.js → mermaid.core-CDXPNs7a.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-COG6_9eD.js → mindmap-definition-RKZ34NQL-BkqS9tpe.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-D11brZ_N.js → pieDiagram-4H26LBE5-DEUyVLs-.js} +1 -1
- package/dist/client/assets/{puzzle-D3_Z_rlW.js → puzzle-DQ0y1-XK.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-jmhDVZcv.js → quadrantDiagram-W4KKPZXB-ESBJNK5c.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-BKCUWI1E.js → requirementDiagram-4Y6WPE33-CqPs7zcv.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-HsZdEl2t.js → sankeyDiagram-5OEKKPKP-CkFN0m14.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CsDf7Fup.js → sequenceDiagram-3UESZ5HK-Dx2nDuMO.js} +1 -1
- package/dist/client/assets/{shield-alert-C16k8wNu.js → shield-alert-BS05s4RM.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-BqAyftqe.js → standing-instructions-template-xprxYNHm.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-fvzWhltB.js → stateDiagram-AJRCARHV-EUPmRFGd.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-cnt42Sr_.js → stateDiagram-v2-BHNVJYJU-DcQ2mhi5.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DsZFCSMb.js → timeline-definition-PNZ67QCA-D4YO_3V-.js} +1 -1
- package/dist/client/assets/{upload-_s5sL5Pq.js → upload-BjyBtxo7.js} +1 -1
- package/dist/client/assets/{users-DH1U5ISc.js → users-D5ogZ7WQ.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-B3KDWS-e.js → vennDiagram-CIIHVFJN-BT5_XuQL.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-BKs5MtQS.js → wardley-L42UT6IY-X_ZMW457.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CNsEoXVB.js → wardleyDiagram-YWT4CUSO-GK9nONHU.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-kq_gW4QC.js → xychartDiagram-2RQKCTM6-Dw3zXHAq.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +647 -207
- package/dist/migrations/0057_fn_9004_project_ownership_default_reconciliation.sql +13 -0
- package/dist/migrations/0058_fn_9014_message_archive.sql +13 -0
- package/dist/pi-claude-cli/package.json +5 -5
- package/dist/plugin-sdk/index.js +69 -23
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +71 -25
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +69 -23
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +3 -3
- package/skill/fusion/SKILL.md +1 -1
- package/skill/fusion/references/extension-tools.md +22 -0
- package/skill/fusion/references/fusion-capabilities.md +2 -0
- package/dist/client/assets/ChatView-DcM-ARpZ.js +0 -13
- package/dist/client/assets/channel-Cwl9FefC.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BZtWCoHC.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BZtWCoHC.js +0 -1
- package/dist/client/assets/index-BlGpMJSZ.js +0 -2818
package/dist/bin.js
CHANGED
|
@@ -21756,9 +21756,14 @@ var init_project = __esm({
|
|
|
21756
21756
|
// now keyed per-project on `project_id` (the effective PK). `id` is retained
|
|
21757
21757
|
// for column-shape parity (always 1) but is no longer the PK and no longer
|
|
21758
21758
|
// CHECK-constrained. Single-project / SQLite-parity callers leave project_id
|
|
21759
|
-
//
|
|
21759
|
+
// through the database ownership trigger, preserving the pre-isolation behavior.
|
|
21760
|
+
/*
|
|
21761
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
21762
|
+
Migration 0006 owns config's project_id default and leaves its catalog PK as (project_id).
|
|
21763
|
+
Drizzle emits DEFAULT while the database GUC/trigger selects the effective ownership partition.
|
|
21764
|
+
*/
|
|
21760
21765
|
id: integer("id").default(1),
|
|
21761
|
-
projectId: text("project_id").notNull().default(
|
|
21766
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`).primaryKey(),
|
|
21762
21767
|
nextId: integer("next_id").default(1),
|
|
21763
21768
|
nextWorkflowStepId: integer("next_workflow_step_id").default(1),
|
|
21764
21769
|
// FNXC:SqliteFinalRemoval 2026-06-28:
|
|
@@ -22152,9 +22157,13 @@ var init_project = __esm({
|
|
|
22152
22157
|
automations = projectSchema.table("automations", {
|
|
22153
22158
|
/*
|
|
22154
22159
|
* FNXC:AutomationIsolation 2026-07-13-22:37:
|
|
22155
|
-
* 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.
|
|
22160
|
+
* 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.
|
|
22161
|
+
*
|
|
22162
|
+
* FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
22163
|
+
* Migration 0006 owns the default through the database GUC/trigger; Drizzle emits DEFAULT
|
|
22164
|
+
* without replacing the physical legacy fallback or the fail-closed bound writer contract.
|
|
22156
22165
|
*/
|
|
22157
|
-
projectId: text("project_id").notNull().default(
|
|
22166
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22158
22167
|
id: text("id").notNull(),
|
|
22159
22168
|
name: text("name").notNull(),
|
|
22160
22169
|
description: text("description"),
|
|
@@ -22453,7 +22462,8 @@ var init_project = __esm({
|
|
|
22453
22462
|
index("idxTaskDocumentsTaskId").on(t.taskId)
|
|
22454
22463
|
]);
|
|
22455
22464
|
artifacts = projectSchema.table("artifacts", {
|
|
22456
|
-
|
|
22465
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22466
|
+
id: text("id").notNull(),
|
|
22457
22467
|
type: text("type").notNull(),
|
|
22458
22468
|
title: text("title").notNull(),
|
|
22459
22469
|
description: text("description"),
|
|
@@ -22468,7 +22478,8 @@ var init_project = __esm({
|
|
|
22468
22478
|
createdAt: text("created_at").notNull(),
|
|
22469
22479
|
updatedAt: text("updated_at").notNull()
|
|
22470
22480
|
}, (t) => [
|
|
22471
|
-
|
|
22481
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22482
|
+
foreignKey({ name: "artifacts_task_id_fkey", columns: [t.projectId, t.taskId], foreignColumns: [tasks.projectId, tasks.id] }).onDelete("cascade"),
|
|
22472
22483
|
index("idxArtifactsTaskId").on(t.taskId),
|
|
22473
22484
|
index("idxArtifactsAuthorId").on(t.authorId),
|
|
22474
22485
|
index("idxArtifactsType").on(t.type),
|
|
@@ -22658,7 +22669,8 @@ var init_project = __esm({
|
|
|
22658
22669
|
index("idxEvalRunEventsRunIdSeq").on(t.runId, t.seq)
|
|
22659
22670
|
]);
|
|
22660
22671
|
secrets = projectSchema.table("secrets", {
|
|
22661
|
-
|
|
22672
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22673
|
+
id: text("id").notNull(),
|
|
22662
22674
|
key: text("key").notNull(),
|
|
22663
22675
|
valueCiphertext: bytea("value_ciphertext").notNull(),
|
|
22664
22676
|
nonce: bytea("nonce").notNull(),
|
|
@@ -22671,7 +22683,8 @@ var init_project = __esm({
|
|
|
22671
22683
|
lastReadAt: text("last_read_at"),
|
|
22672
22684
|
lastReadBy: text("last_read_by")
|
|
22673
22685
|
}, (t) => [
|
|
22674
|
-
|
|
22686
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22687
|
+
unique("secrets_key_unique").on(t.projectId, t.key),
|
|
22675
22688
|
check("secrets_access_policy_check", sql`${t.accessPolicy} IN ('auto', 'prompt', 'deny')`),
|
|
22676
22689
|
check("secrets_env_exportable_check", sql`${t.envExportable} IN (0, 1)`)
|
|
22677
22690
|
]);
|
|
@@ -22713,10 +22726,11 @@ var init_project = __esm({
|
|
|
22713
22726
|
updatedAt: text("updated_at").notNull()
|
|
22714
22727
|
}, (t) => [primaryKey({ columns: [t.projectId, t.id] })]);
|
|
22715
22728
|
branchGroups = projectSchema.table("branch_groups", {
|
|
22716
|
-
|
|
22729
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22730
|
+
id: text("id").notNull(),
|
|
22717
22731
|
sourceType: text("source_type").notNull(),
|
|
22718
22732
|
sourceId: text("source_id").notNull(),
|
|
22719
|
-
branchName: text("branch_name").notNull()
|
|
22733
|
+
branchName: text("branch_name").notNull(),
|
|
22720
22734
|
worktreePath: text("worktree_path"),
|
|
22721
22735
|
autoMerge: integer("auto_merge").notNull().default(0),
|
|
22722
22736
|
prState: text("pr_state").notNull().default("none"),
|
|
@@ -22732,6 +22746,8 @@ var init_project = __esm({
|
|
|
22732
22746
|
updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
|
|
22733
22747
|
closedAt: bigint("closed_at", { mode: "number" })
|
|
22734
22748
|
}, (t) => [
|
|
22749
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22750
|
+
unique("branch_groups_branch_name_key").on(t.projectId, t.branchName),
|
|
22735
22751
|
check("branch_groups_source_type_check", sql`${t.sourceType} IN ('mission','planning','new-task')`),
|
|
22736
22752
|
check("branch_groups_pr_state_check", sql`${t.prState} IN ('none','open','merged','closed')`),
|
|
22737
22753
|
check("branch_groups_status_check", sql`${t.status} IN ('open','finalized','abandoned')`),
|
|
@@ -23133,12 +23149,14 @@ var init_project = __esm({
|
|
|
23133
23149
|
index("idxUsageEventsKindTs").on(t.kind, t.ts)
|
|
23134
23150
|
]);
|
|
23135
23151
|
pluginActivations = projectSchema.table("plugin_activations", {
|
|
23136
|
-
|
|
23152
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23153
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23137
23154
|
pluginId: text("plugin_id").notNull(),
|
|
23138
23155
|
source: text("source").notNull(),
|
|
23139
23156
|
pluginVersion: text("plugin_version"),
|
|
23140
23157
|
activatedAt: text("activated_at").notNull()
|
|
23141
23158
|
}, (t) => [
|
|
23159
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23142
23160
|
index("idxPluginActivationsActivatedAt").on(t.activatedAt),
|
|
23143
23161
|
index("idxPluginActivationsPluginId").on(t.pluginId)
|
|
23144
23162
|
]);
|
|
@@ -23163,8 +23181,13 @@ var init_project = __esm({
|
|
|
23163
23181
|
index("idxKnowledgePagesUpdatedAt").on(t.updatedAt)
|
|
23164
23182
|
]);
|
|
23165
23183
|
deployments = projectSchema.table("deployments", {
|
|
23166
|
-
id: integer("id").generatedAlwaysAsIdentity().
|
|
23167
|
-
|
|
23184
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23185
|
+
/*
|
|
23186
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23187
|
+
Migration 0006 rebuilt deployments_pkey as (project_id, id). Drizzle emits DEFAULT while the
|
|
23188
|
+
database GUC/trigger keeps ownership stamping and the physical legacy fallback authoritative.
|
|
23189
|
+
*/
|
|
23190
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23168
23191
|
deploymentId: text("deployment_id").notNull(),
|
|
23169
23192
|
service: text("service"),
|
|
23170
23193
|
environment: text("environment"),
|
|
@@ -23175,6 +23198,7 @@ var init_project = __esm({
|
|
|
23175
23198
|
meta: jsonb("meta"),
|
|
23176
23199
|
createdAt: text("created_at").notNull()
|
|
23177
23200
|
}, (t) => [
|
|
23201
|
+
primaryKey({ columns: [t.projectId, t.id], name: "deployments_pkey" }),
|
|
23178
23202
|
uniqueIndex("idxDeploymentsProjectDeploymentId").on(t.projectId, t.deploymentId),
|
|
23179
23203
|
index("idxDeploymentsProjectDeployedAt").on(t.projectId, t.deployedAt),
|
|
23180
23204
|
index("idxDeploymentsDeployedAt").on(t.deployedAt),
|
|
@@ -23182,7 +23206,12 @@ var init_project = __esm({
|
|
|
23182
23206
|
]);
|
|
23183
23207
|
githubCheckStates = projectSchema.table("github_check_states", {
|
|
23184
23208
|
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23185
|
-
|
|
23209
|
+
/*
|
|
23210
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23211
|
+
Migration 0048 post-dated 0006, so FN-9004 reconciles its physical default to the ownership
|
|
23212
|
+
expression. Drizzle emits DEFAULT while the database GUC/trigger remains the stamping authority.
|
|
23213
|
+
*/
|
|
23214
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23186
23215
|
repo: text("repo").notNull(),
|
|
23187
23216
|
headSha: text("head_sha").notNull(),
|
|
23188
23217
|
checkName: text("check_name").notNull(),
|
|
@@ -23202,9 +23231,14 @@ var init_project = __esm({
|
|
|
23202
23231
|
index("idxGithubCheckStatesProjectReceived").on(t.projectId, t.receivedAt)
|
|
23203
23232
|
]);
|
|
23204
23233
|
incidents = projectSchema.table("incidents", {
|
|
23205
|
-
id: integer("id").generatedAlwaysAsIdentity().
|
|
23206
|
-
|
|
23207
|
-
|
|
23234
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23235
|
+
/*
|
|
23236
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23237
|
+
Migration 0006 rebuilt incident keys with project_id first. Drizzle emits DEFAULT while the
|
|
23238
|
+
database GUC/trigger retains ownership stamping and its physical legacy fallback.
|
|
23239
|
+
*/
|
|
23240
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23241
|
+
incidentId: text("incident_id").notNull(),
|
|
23208
23242
|
groupingKey: text("grouping_key").notNull(),
|
|
23209
23243
|
title: text("title").notNull(),
|
|
23210
23244
|
severity: text("severity"),
|
|
@@ -23218,6 +23252,8 @@ var init_project = __esm({
|
|
|
23218
23252
|
createdAt: text("created_at").notNull(),
|
|
23219
23253
|
updatedAt: text("updated_at").notNull()
|
|
23220
23254
|
}, (t) => [
|
|
23255
|
+
primaryKey({ columns: [t.projectId, t.id], name: "incidents_pkey" }),
|
|
23256
|
+
unique("incidents_incident_id_key").on(t.projectId, t.incidentId),
|
|
23221
23257
|
index("idxIncidentsProjectOpenedAt").on(t.projectId, t.openedAt),
|
|
23222
23258
|
index("idxIncidentsProjectStatus").on(t.projectId, t.status),
|
|
23223
23259
|
index("idxIncidentsGroupingKey").on(t.groupingKey),
|
|
@@ -23272,12 +23308,14 @@ var init_project = __esm({
|
|
|
23272
23308
|
content: text("content").notNull(),
|
|
23273
23309
|
type: text("type").notNull(),
|
|
23274
23310
|
read: integer("read").default(0),
|
|
23311
|
+
archived: integer("archived").default(0),
|
|
23275
23312
|
metadata: jsonb("metadata"),
|
|
23276
23313
|
createdAt: text("created_at").notNull(),
|
|
23277
23314
|
updatedAt: text("updated_at").notNull()
|
|
23278
23315
|
}, (t) => [
|
|
23279
23316
|
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23280
23317
|
index("idxMessagesTo").on(t.toId, t.toType, t.read),
|
|
23318
|
+
index("idxMessagesToArchived").on(t.toId, t.toType, t.archived),
|
|
23281
23319
|
index("idxMessagesFrom").on(t.fromId, t.fromType),
|
|
23282
23320
|
index("idxMessagesCreatedAt").on(t.createdAt)
|
|
23283
23321
|
]);
|
|
@@ -23378,7 +23416,8 @@ var init_project = __esm({
|
|
|
23378
23416
|
index("idx_cli_sessions_project_state").on(t.projectId, t.agentState)
|
|
23379
23417
|
]);
|
|
23380
23418
|
chatMessages = projectSchema.table("chat_messages", {
|
|
23381
|
-
|
|
23419
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23420
|
+
id: text("id").notNull(),
|
|
23382
23421
|
sessionId: text("session_id").notNull(),
|
|
23383
23422
|
role: text("role").notNull(),
|
|
23384
23423
|
content: text("content").notNull(),
|
|
@@ -23387,6 +23426,7 @@ var init_project = __esm({
|
|
|
23387
23426
|
createdAt: text("created_at").notNull(),
|
|
23388
23427
|
attachments: jsonb("attachments")
|
|
23389
23428
|
}, (t) => [
|
|
23429
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23390
23430
|
index("idxChatMessagesSessionId").on(t.sessionId),
|
|
23391
23431
|
index("idxChatMessagesCreatedAt").on(t.createdAt)
|
|
23392
23432
|
]);
|
|
@@ -23412,7 +23452,8 @@ var init_project = __esm({
|
|
|
23412
23452
|
index("idxChatTokenUsageCreatedAt").on(t.createdAt)
|
|
23413
23453
|
]);
|
|
23414
23454
|
runAuditEvents = projectSchema.table("run_audit_events", {
|
|
23415
|
-
|
|
23455
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23456
|
+
id: text("id").notNull(),
|
|
23416
23457
|
timestamp: text("timestamp").notNull(),
|
|
23417
23458
|
taskId: text("task_id"),
|
|
23418
23459
|
agentId: text("agent_id").notNull(),
|
|
@@ -23422,6 +23463,7 @@ var init_project = __esm({
|
|
|
23422
23463
|
target: text("target").notNull(),
|
|
23423
23464
|
metadata: jsonb("metadata")
|
|
23424
23465
|
}, (t) => [
|
|
23466
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23425
23467
|
index("idxRunAuditEventsRunIdTimestamp").on(t.runId, t.timestamp),
|
|
23426
23468
|
index("idxRunAuditEventsTaskIdTimestamp").on(t.taskId, t.timestamp),
|
|
23427
23469
|
index("idxRunAuditEventsTimestamp").on(t.timestamp)
|
|
@@ -23522,13 +23564,14 @@ var init_project = __esm({
|
|
|
23522
23564
|
index("idxMissionLineageStopsMissionId").on(t.projectId, t.missionId)
|
|
23523
23565
|
]);
|
|
23524
23566
|
verificationCache = projectSchema.table("verification_cache", {
|
|
23567
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23525
23568
|
treeSha: text("tree_sha").notNull(),
|
|
23526
23569
|
testCommand: text("test_command").notNull().default(""),
|
|
23527
23570
|
buildCommand: text("build_command").notNull().default(""),
|
|
23528
23571
|
recordedAt: text("recorded_at").notNull(),
|
|
23529
23572
|
taskId: text("task_id")
|
|
23530
23573
|
}, (t) => [
|
|
23531
|
-
primaryKey({ columns: [t.treeSha, t.testCommand, t.buildCommand] }),
|
|
23574
|
+
primaryKey({ columns: [t.projectId, t.treeSha, t.testCommand, t.buildCommand] }),
|
|
23532
23575
|
index("idxVerificationCacheRecordedAt").on(t.recordedAt)
|
|
23533
23576
|
]);
|
|
23534
23577
|
importTranslationCache = projectSchema.table("import_translation_cache", {
|
|
@@ -23561,7 +23604,8 @@ var init_project = __esm({
|
|
|
23561
23604
|
index("idxImportTranslationCacheRecordedAt").on(t.recordedAt)
|
|
23562
23605
|
]);
|
|
23563
23606
|
approvalRequests = projectSchema.table("approval_requests", {
|
|
23564
|
-
|
|
23607
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23608
|
+
id: text("id").notNull(),
|
|
23565
23609
|
status: text("status").notNull(),
|
|
23566
23610
|
requesterActorId: text("requester_actor_id").notNull(),
|
|
23567
23611
|
requesterActorType: text("requester_actor_type").notNull(),
|
|
@@ -23580,13 +23624,14 @@ var init_project = __esm({
|
|
|
23580
23624
|
createdAt: text("created_at").notNull(),
|
|
23581
23625
|
updatedAt: text("updated_at").notNull()
|
|
23582
23626
|
}, (t) => [
|
|
23627
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23583
23628
|
index("idxApprovalRequestsStatusCreatedAt").on(t.status, t.createdAt),
|
|
23584
23629
|
index("idxApprovalRequestsRequesterCreatedAt").on(t.requesterActorId, t.createdAt),
|
|
23585
23630
|
index("idxApprovalRequestsTaskCreatedAt").on(t.taskId, t.createdAt)
|
|
23586
23631
|
]);
|
|
23587
23632
|
approvalRequestAuditEvents = projectSchema.table("approval_request_audit_events", {
|
|
23588
|
-
projectId: text("project_id").notNull().default(
|
|
23589
|
-
id: text("id").
|
|
23633
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23634
|
+
id: text("id").notNull(),
|
|
23590
23635
|
requestId: text("request_id").notNull(),
|
|
23591
23636
|
eventType: text("event_type").notNull(),
|
|
23592
23637
|
actorId: text("actor_id").notNull(),
|
|
@@ -23595,6 +23640,7 @@ var init_project = __esm({
|
|
|
23595
23640
|
note: text("note"),
|
|
23596
23641
|
createdAt: text("created_at").notNull()
|
|
23597
23642
|
}, (t) => [
|
|
23643
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23598
23644
|
index("idxApprovalRequestAuditRequestCreatedAt").on(t.requestId, t.createdAt, t.id),
|
|
23599
23645
|
index("idxApprovalRequestAuditProjectCreatedAt").on(t.projectId, t.createdAt)
|
|
23600
23646
|
]);
|
|
@@ -27084,6 +27130,27 @@ var init_grok_provider = __esm({
|
|
|
27084
27130
|
apiKey: "$GROK_API_KEY",
|
|
27085
27131
|
api: "openai-completions",
|
|
27086
27132
|
models: [
|
|
27133
|
+
/*
|
|
27134
|
+
FNXC:ModelRegistry 2026-08-12-20:17:
|
|
27135
|
+
FN-9008 requires Grok 4.6 to be selectable in every model area. Keep it in this shared
|
|
27136
|
+
catalog because pi's registerProvider() replaces provider model lists wholesale, while every
|
|
27137
|
+
Fusion host seeds and re-merges this export. xAI's model docs verify grok-4.6, its 500k-token
|
|
27138
|
+
context window, and configurable reasoning; max output and per-model image input remain
|
|
27139
|
+
upstream-pending-verification, so retain the conservative text-only and 65536-token defaults.
|
|
27140
|
+
Source: https://docs.x.ai/developers/models
|
|
27141
|
+
*/
|
|
27142
|
+
{
|
|
27143
|
+
id: "grok-4.6",
|
|
27144
|
+
name: "Grok 4.6",
|
|
27145
|
+
reasoning: true,
|
|
27146
|
+
input: ["text"],
|
|
27147
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
27148
|
+
contextWindow: 5e5,
|
|
27149
|
+
maxTokens: 65536,
|
|
27150
|
+
compat: {
|
|
27151
|
+
supportsDeveloperRole: false
|
|
27152
|
+
}
|
|
27153
|
+
},
|
|
27087
27154
|
{
|
|
27088
27155
|
id: "grok-4.5",
|
|
27089
27156
|
name: "Grok 4.5",
|
|
@@ -35042,6 +35109,7 @@ function rowToMessage(row) {
|
|
|
35042
35109
|
content: row.content,
|
|
35043
35110
|
type: row.type,
|
|
35044
35111
|
read: (row.read ?? 0) === 1,
|
|
35112
|
+
archived: (row.archived ?? 0) === 1,
|
|
35045
35113
|
metadata: row.metadata ?? void 0,
|
|
35046
35114
|
createdAt: row.createdAt,
|
|
35047
35115
|
updatedAt: row.updatedAt
|
|
@@ -35053,6 +35121,11 @@ function participantIdsForLookup(ownerId, ownerType) {
|
|
|
35053
35121
|
}
|
|
35054
35122
|
return [ownerId];
|
|
35055
35123
|
}
|
|
35124
|
+
function archivedCondition(archived) {
|
|
35125
|
+
if (archived === true) return eq(project_exports.messages.archived, 1);
|
|
35126
|
+
if (archived === false) return or(eq(project_exports.messages.archived, 0), sql`${project_exports.messages.archived} IS NULL`);
|
|
35127
|
+
return or(eq(project_exports.messages.archived, 0), sql`${project_exports.messages.archived} IS NULL`);
|
|
35128
|
+
}
|
|
35056
35129
|
async function sendMessage(handle, message) {
|
|
35057
35130
|
const sanitizedContent = sanitizeTextValue(message.content);
|
|
35058
35131
|
const sanitizedMetadata = sanitizeJsonbValue(message.metadata);
|
|
@@ -35065,6 +35138,7 @@ async function sendMessage(handle, message) {
|
|
|
35065
35138
|
content: sanitizedContent,
|
|
35066
35139
|
type: message.type,
|
|
35067
35140
|
read: message.read ? 1 : 0,
|
|
35141
|
+
archived: message.archived ? 1 : 0,
|
|
35068
35142
|
metadata: sanitizedMetadata,
|
|
35069
35143
|
createdAt: message.createdAt,
|
|
35070
35144
|
updatedAt: message.updatedAt
|
|
@@ -35073,7 +35147,8 @@ async function sendMessage(handle, message) {
|
|
|
35073
35147
|
...message,
|
|
35074
35148
|
content: sanitizedContent,
|
|
35075
35149
|
metadata: sanitizedMetadata,
|
|
35076
|
-
read: message.read ? 1 : 0
|
|
35150
|
+
read: message.read ? 1 : 0,
|
|
35151
|
+
archived: message.archived ? 1 : 0
|
|
35077
35152
|
});
|
|
35078
35153
|
}
|
|
35079
35154
|
async function sendMessageOnce(handle, message) {
|
|
@@ -35086,6 +35161,7 @@ async function sendMessageOnce(handle, message) {
|
|
|
35086
35161
|
content: message.content,
|
|
35087
35162
|
type: message.type,
|
|
35088
35163
|
read: message.read ? 1 : 0,
|
|
35164
|
+
archived: message.archived ? 1 : 0,
|
|
35089
35165
|
metadata: message.metadata,
|
|
35090
35166
|
createdAt: message.createdAt,
|
|
35091
35167
|
updatedAt: message.updatedAt
|
|
@@ -35137,6 +35213,7 @@ async function queryMessagesByParticipant(handle, direction, ownerId, ownerType,
|
|
|
35137
35213
|
if (filter2?.read !== void 0) {
|
|
35138
35214
|
conditions.push(eq(project_exports.messages.read, filter2.read ? 1 : 0));
|
|
35139
35215
|
}
|
|
35216
|
+
conditions.push(archivedCondition(filter2?.archived));
|
|
35140
35217
|
const limit2 = filter2?.limit ?? 100;
|
|
35141
35218
|
const offset = filter2?.offset ?? 0;
|
|
35142
35219
|
const rows = await handle.select(messageColumns).from(project_exports.messages).where(and(...conditions)).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id)).limit(limit2).offset(offset);
|
|
@@ -35150,6 +35227,13 @@ async function markMessageAsRead(handle, messageId) {
|
|
|
35150
35227
|
await handle.update(project_exports.messages).set({ read: 1, updatedAt: now }).where(eq(project_exports.messages.id, messageId));
|
|
35151
35228
|
return await getMessage(handle, messageId);
|
|
35152
35229
|
}
|
|
35230
|
+
async function setMessageArchived(handle, id, archived) {
|
|
35231
|
+
const existing = await getMessage(handle, id);
|
|
35232
|
+
if (!existing) return null;
|
|
35233
|
+
if (existing.archived === archived) return existing;
|
|
35234
|
+
const rows = await handle.update(project_exports.messages).set({ archived: archived ? 1 : 0, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq(project_exports.messages.id, id)).returning(messageColumns);
|
|
35235
|
+
return rows[0] ? rowToMessage(rows[0]) : null;
|
|
35236
|
+
}
|
|
35153
35237
|
async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
35154
35238
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
35155
35239
|
const participantIds = participantIdsForLookup(ownerId, ownerType);
|
|
@@ -35157,7 +35241,8 @@ async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
|
35157
35241
|
and(
|
|
35158
35242
|
inArray(project_exports.messages.toId, participantIds),
|
|
35159
35243
|
eq(project_exports.messages.toType, ownerType),
|
|
35160
|
-
eq(project_exports.messages.read, 0)
|
|
35244
|
+
eq(project_exports.messages.read, 0),
|
|
35245
|
+
archivedCondition()
|
|
35161
35246
|
)
|
|
35162
35247
|
);
|
|
35163
35248
|
const count2 = countRows[0]?.count ?? 0;
|
|
@@ -35165,7 +35250,8 @@ async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
|
35165
35250
|
and(
|
|
35166
35251
|
inArray(project_exports.messages.toId, participantIds),
|
|
35167
35252
|
eq(project_exports.messages.toType, ownerType),
|
|
35168
|
-
eq(project_exports.messages.read, 0)
|
|
35253
|
+
eq(project_exports.messages.read, 0),
|
|
35254
|
+
archivedCondition()
|
|
35169
35255
|
)
|
|
35170
35256
|
);
|
|
35171
35257
|
return count2;
|
|
@@ -35187,19 +35273,22 @@ async function getConversation(handle, participantA, participantB, options) {
|
|
|
35187
35273
|
const aIds = participantIdsForLookup(participantA.id, participantA.type);
|
|
35188
35274
|
const bIds = participantIdsForLookup(participantB.id, participantB.type);
|
|
35189
35275
|
const rows = await handle.select(messageColumns).from(project_exports.messages).where(
|
|
35190
|
-
|
|
35191
|
-
|
|
35192
|
-
|
|
35193
|
-
|
|
35194
|
-
|
|
35195
|
-
|
|
35276
|
+
and(
|
|
35277
|
+
or(
|
|
35278
|
+
and(
|
|
35279
|
+
inArray(project_exports.messages.fromId, aIds),
|
|
35280
|
+
eq(project_exports.messages.fromType, participantA.type),
|
|
35281
|
+
inArray(project_exports.messages.toId, bIds),
|
|
35282
|
+
eq(project_exports.messages.toType, participantB.type)
|
|
35283
|
+
),
|
|
35284
|
+
and(
|
|
35285
|
+
inArray(project_exports.messages.fromId, bIds),
|
|
35286
|
+
eq(project_exports.messages.fromType, participantB.type),
|
|
35287
|
+
inArray(project_exports.messages.toId, aIds),
|
|
35288
|
+
eq(project_exports.messages.toType, participantA.type)
|
|
35289
|
+
)
|
|
35196
35290
|
),
|
|
35197
|
-
|
|
35198
|
-
inArray(project_exports.messages.fromId, bIds),
|
|
35199
|
-
eq(project_exports.messages.fromType, participantB.type),
|
|
35200
|
-
inArray(project_exports.messages.toId, aIds),
|
|
35201
|
-
eq(project_exports.messages.toType, participantA.type)
|
|
35202
|
-
)
|
|
35291
|
+
archivedCondition(options?.archived)
|
|
35203
35292
|
)
|
|
35204
35293
|
).orderBy(desc(project_exports.messages.createdAt)).limit(limit2);
|
|
35205
35294
|
return rows.reverse().map((row) => rowToMessage(row));
|
|
@@ -35210,14 +35299,16 @@ async function getMailbox(handle, ownerId, ownerType) {
|
|
|
35210
35299
|
and(
|
|
35211
35300
|
inArray(project_exports.messages.toId, participantIds),
|
|
35212
35301
|
eq(project_exports.messages.toType, ownerType),
|
|
35213
|
-
eq(project_exports.messages.read, 0)
|
|
35302
|
+
eq(project_exports.messages.read, 0),
|
|
35303
|
+
archivedCondition()
|
|
35214
35304
|
)
|
|
35215
35305
|
);
|
|
35216
35306
|
const unreadCount = unreadRows[0]?.count ?? 0;
|
|
35217
35307
|
const lastRows = await handle.select(messageColumns).from(project_exports.messages).where(
|
|
35218
35308
|
and(
|
|
35219
35309
|
inArray(project_exports.messages.toId, participantIds),
|
|
35220
|
-
eq(project_exports.messages.toType, ownerType)
|
|
35310
|
+
eq(project_exports.messages.toType, ownerType),
|
|
35311
|
+
archivedCondition()
|
|
35221
35312
|
)
|
|
35222
35313
|
).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id)).limit(1);
|
|
35223
35314
|
return {
|
|
@@ -35227,15 +35318,16 @@ async function getMailbox(handle, ownerId, ownerType) {
|
|
|
35227
35318
|
lastMessage: lastRows[0] ? rowToMessage(lastRows[0]) : void 0
|
|
35228
35319
|
};
|
|
35229
35320
|
}
|
|
35230
|
-
async function getAllAgentToAgentMessages(handle) {
|
|
35231
|
-
const rows = await handle.select(messageColumns).from(project_exports.messages).where(eq(project_exports.messages.type, "agent-to-agent")).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id));
|
|
35321
|
+
async function getAllAgentToAgentMessages(handle, filter2) {
|
|
35322
|
+
const rows = await handle.select(messageColumns).from(project_exports.messages).where(and(eq(project_exports.messages.type, "agent-to-agent"), archivedCondition(filter2?.archived))).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id));
|
|
35232
35323
|
return rows.map((row) => rowToMessage(row));
|
|
35233
35324
|
}
|
|
35234
35325
|
async function getUnreadAgentToAgentCount(handle) {
|
|
35235
35326
|
const rows = await handle.select({ count: sql`count(*)::int` }).from(project_exports.messages).where(
|
|
35236
35327
|
and(
|
|
35237
35328
|
eq(project_exports.messages.type, "agent-to-agent"),
|
|
35238
|
-
eq(project_exports.messages.read, 0)
|
|
35329
|
+
eq(project_exports.messages.read, 0),
|
|
35330
|
+
archivedCondition()
|
|
35239
35331
|
)
|
|
35240
35332
|
);
|
|
35241
35333
|
return rows[0]?.count ?? 0;
|
|
@@ -35257,6 +35349,7 @@ var init_async_message_store = __esm({
|
|
|
35257
35349
|
content: project_exports.messages.content,
|
|
35258
35350
|
type: project_exports.messages.type,
|
|
35259
35351
|
read: project_exports.messages.read,
|
|
35352
|
+
archived: project_exports.messages.archived,
|
|
35260
35353
|
metadata: project_exports.messages.metadata,
|
|
35261
35354
|
createdAt: project_exports.messages.createdAt,
|
|
35262
35355
|
updatedAt: project_exports.messages.updatedAt
|
|
@@ -35442,12 +35535,12 @@ var init_message_store = __esm({
|
|
|
35442
35535
|
}
|
|
35443
35536
|
const sqliteDb = this.db;
|
|
35444
35537
|
this.stmtInsert = sqliteDb.prepare(`
|
|
35445
|
-
INSERT INTO messages (id, fromId, fromType, toId, toType, content, type, read, metadata, createdAt, updatedAt)
|
|
35446
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35538
|
+
INSERT INTO messages (id, fromId, fromType, toId, toType, content, type, read, archived, metadata, createdAt, updatedAt)
|
|
35539
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35447
35540
|
`);
|
|
35448
35541
|
this.stmtInsertOnce = sqliteDb.prepare(`
|
|
35449
|
-
INSERT OR IGNORE INTO messages (id, fromId, fromType, toId, toType, content, type, read, metadata, createdAt, updatedAt)
|
|
35450
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35542
|
+
INSERT OR IGNORE INTO messages (id, fromId, fromType, toId, toType, content, type, read, archived, metadata, createdAt, updatedAt)
|
|
35543
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35451
35544
|
`);
|
|
35452
35545
|
this.stmtGetById = sqliteDb.prepare(`
|
|
35453
35546
|
SELECT * FROM messages WHERE id = ?
|
|
@@ -35485,6 +35578,7 @@ var init_message_store = __esm({
|
|
|
35485
35578
|
content: row.content,
|
|
35486
35579
|
type: row.type,
|
|
35487
35580
|
read: row.read === 1,
|
|
35581
|
+
archived: (row.archived ?? 0) === 1,
|
|
35488
35582
|
metadata: fromJson(row.metadata),
|
|
35489
35583
|
createdAt: row.createdAt,
|
|
35490
35584
|
updatedAt: row.updatedAt
|
|
@@ -35518,6 +35612,7 @@ var init_message_store = __esm({
|
|
|
35518
35612
|
content: sanitizeTextValue(input.content),
|
|
35519
35613
|
type: input.type,
|
|
35520
35614
|
read: false,
|
|
35615
|
+
archived: false,
|
|
35521
35616
|
metadata: sanitizeJsonbValue(input.metadata),
|
|
35522
35617
|
createdAt: now,
|
|
35523
35618
|
updatedAt: now
|
|
@@ -35533,6 +35628,7 @@ var init_message_store = __esm({
|
|
|
35533
35628
|
content: message.content,
|
|
35534
35629
|
type: message.type,
|
|
35535
35630
|
read: message.read,
|
|
35631
|
+
archived: message.archived,
|
|
35536
35632
|
metadata: message.metadata ?? null,
|
|
35537
35633
|
createdAt: message.createdAt,
|
|
35538
35634
|
updatedAt: message.updatedAt
|
|
@@ -35547,6 +35643,7 @@ var init_message_store = __esm({
|
|
|
35547
35643
|
message.content,
|
|
35548
35644
|
message.type,
|
|
35549
35645
|
message.read ? 1 : 0,
|
|
35646
|
+
message.archived ? 1 : 0,
|
|
35550
35647
|
toJsonNullable(message.metadata),
|
|
35551
35648
|
message.createdAt,
|
|
35552
35649
|
message.updatedAt
|
|
@@ -35605,6 +35702,7 @@ var init_message_store = __esm({
|
|
|
35605
35702
|
content: sanitizeTextValue(input.content),
|
|
35606
35703
|
type: input.type,
|
|
35607
35704
|
read: false,
|
|
35705
|
+
archived: false,
|
|
35608
35706
|
metadata: sanitizeJsonbValue(input.metadata),
|
|
35609
35707
|
createdAt: now,
|
|
35610
35708
|
updatedAt: now
|
|
@@ -35625,6 +35723,7 @@ var init_message_store = __esm({
|
|
|
35625
35723
|
message.content,
|
|
35626
35724
|
message.type,
|
|
35627
35725
|
0,
|
|
35726
|
+
0,
|
|
35628
35727
|
toJsonNullable(message.metadata),
|
|
35629
35728
|
message.createdAt,
|
|
35630
35729
|
message.updatedAt
|
|
@@ -35756,6 +35855,7 @@ var init_message_store = __esm({
|
|
|
35756
35855
|
whereClauses.push("read = ?");
|
|
35757
35856
|
params.push(filter2.read ? 1 : 0);
|
|
35758
35857
|
}
|
|
35858
|
+
whereClauses.push(filter2?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)");
|
|
35759
35859
|
const whereSql = whereClauses.join(" AND ");
|
|
35760
35860
|
const limit2 = filter2?.limit ?? 100;
|
|
35761
35861
|
const offset = filter2?.offset ?? 0;
|
|
@@ -35806,15 +35906,39 @@ var init_message_store = __esm({
|
|
|
35806
35906
|
const participantIds = this.getParticipantIdsForLookup(ownerId, ownerType);
|
|
35807
35907
|
const toIdPredicate = participantIds.length === 1 ? "toId = ?" : `toId IN (${participantIds.map(() => "?").join(", ")})`;
|
|
35808
35908
|
const unreadRow = this.db.prepare(`
|
|
35809
|
-
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
35909
|
+
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35810
35910
|
`).get(...participantIds, ownerType);
|
|
35811
35911
|
const count2 = unreadRow?.count ?? 0;
|
|
35812
35912
|
this.db.prepare(`
|
|
35813
|
-
UPDATE messages SET read = 1, updatedAt = ? WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
35913
|
+
UPDATE messages SET read = 1, updatedAt = ? WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35814
35914
|
`).run(now, ...participantIds, ownerType);
|
|
35815
35915
|
this.db.bumpLastModified();
|
|
35816
35916
|
return count2;
|
|
35817
35917
|
}
|
|
35918
|
+
/** Archive a message without destroying its correspondence history. */
|
|
35919
|
+
async archiveMessage(id) {
|
|
35920
|
+
return this.setMessageArchived(id, true);
|
|
35921
|
+
}
|
|
35922
|
+
/** Restore a previously archived message to default mailbox lists. */
|
|
35923
|
+
async unarchiveMessage(id) {
|
|
35924
|
+
return this.setMessageArchived(id, false);
|
|
35925
|
+
}
|
|
35926
|
+
async setMessageArchived(id, archived) {
|
|
35927
|
+
if (this.asyncLayer) {
|
|
35928
|
+
const updated2 = await setMessageArchived(this.asyncLayer.db, id, archived);
|
|
35929
|
+
if (!updated2) throw new Error(`Message ${id} not found`);
|
|
35930
|
+
this.emit(archived ? "message:archived" : "message:unarchived", updated2);
|
|
35931
|
+
return updated2;
|
|
35932
|
+
}
|
|
35933
|
+
const existing = await this.getMessage(id);
|
|
35934
|
+
if (!existing) throw new Error(`Message ${id} not found`);
|
|
35935
|
+
if (existing.archived === archived) return existing;
|
|
35936
|
+
this.db.prepare("UPDATE messages SET archived = ?, updatedAt = ? WHERE id = ?").run(archived ? 1 : 0, (/* @__PURE__ */ new Date()).toISOString(), id);
|
|
35937
|
+
this.db.bumpLastModified();
|
|
35938
|
+
const updated = await this.getMessage(id);
|
|
35939
|
+
this.emit(archived ? "message:archived" : "message:unarchived", updated);
|
|
35940
|
+
return updated;
|
|
35941
|
+
}
|
|
35818
35942
|
/**
|
|
35819
35943
|
* Delete a message by ID.
|
|
35820
35944
|
* @param id - The message ID
|
|
@@ -35905,7 +36029,7 @@ var init_message_store = __esm({
|
|
|
35905
36029
|
(${participantAFromPredicate} AND fromType = ? AND ${participantBToPredicate} AND toType = ?)
|
|
35906
36030
|
OR
|
|
35907
36031
|
(${participantBFromPredicate} AND fromType = ? AND ${participantAToPredicate} AND toType = ?)
|
|
35908
|
-
)
|
|
36032
|
+
) AND ${options?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)"}
|
|
35909
36033
|
ORDER BY createdAt DESC
|
|
35910
36034
|
LIMIT ?
|
|
35911
36035
|
`).all(
|
|
@@ -35940,11 +36064,11 @@ var init_message_store = __esm({
|
|
|
35940
36064
|
const participantIds = this.getParticipantIdsForLookup(ownerId, ownerType);
|
|
35941
36065
|
const toIdPredicate = participantIds.length === 1 ? "toId = ?" : `toId IN (${participantIds.map(() => "?").join(", ")})`;
|
|
35942
36066
|
const unreadRow = this.db.prepare(`
|
|
35943
|
-
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
36067
|
+
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35944
36068
|
`).get(...participantIds, ownerType);
|
|
35945
36069
|
const unreadCount = unreadRow?.count ?? 0;
|
|
35946
36070
|
const lastRow = this.db.prepare(`
|
|
35947
|
-
SELECT * FROM messages WHERE ${toIdPredicate} AND toType = ? ORDER BY createdAt DESC, rowid DESC LIMIT 1
|
|
36071
|
+
SELECT * FROM messages WHERE ${toIdPredicate} AND toType = ? AND (archived = 0 OR archived IS NULL) ORDER BY createdAt DESC, rowid DESC LIMIT 1
|
|
35948
36072
|
`).get(...participantIds, ownerType);
|
|
35949
36073
|
const lastMessage = lastRow ? this.rowToMessage(lastRow) : void 0;
|
|
35950
36074
|
return {
|
|
@@ -35958,13 +36082,13 @@ var init_message_store = __esm({
|
|
|
35958
36082
|
* Get all agent-to-agent messages across all agents.
|
|
35959
36083
|
* @returns Array of messages (newest first)
|
|
35960
36084
|
*/
|
|
35961
|
-
async getAllAgentToAgentMessages() {
|
|
36085
|
+
async getAllAgentToAgentMessages(filter2) {
|
|
35962
36086
|
if (this.asyncLayer) {
|
|
35963
|
-
return getAllAgentToAgentMessages(this.asyncLayer.db);
|
|
36087
|
+
return getAllAgentToAgentMessages(this.asyncLayer.db, filter2);
|
|
35964
36088
|
}
|
|
35965
36089
|
const rows = this.db.prepare(`
|
|
35966
36090
|
SELECT * FROM messages
|
|
35967
|
-
WHERE type = ?
|
|
36091
|
+
WHERE type = ? AND ${filter2?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)"}
|
|
35968
36092
|
ORDER BY createdAt DESC, rowid DESC
|
|
35969
36093
|
`).all("agent-to-agent");
|
|
35970
36094
|
return rows.map((row) => this.rowToMessage(row));
|
|
@@ -35978,7 +36102,7 @@ var init_message_store = __esm({
|
|
|
35978
36102
|
}
|
|
35979
36103
|
const row = this.db.prepare(`
|
|
35980
36104
|
SELECT COUNT(*) as count FROM messages
|
|
35981
|
-
WHERE type = ? AND read = 0
|
|
36105
|
+
WHERE type = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35982
36106
|
`).get("agent-to-agent");
|
|
35983
36107
|
return row?.count ?? 0;
|
|
35984
36108
|
}
|
|
@@ -36077,6 +36201,7 @@ async function createApprovalRequest(layer, input) {
|
|
|
36077
36201
|
};
|
|
36078
36202
|
await layer.transactionImmediate(async (tx) => {
|
|
36079
36203
|
await tx.insert(project_exports.approvalRequests).values({
|
|
36204
|
+
...layer.projectId?.trim() ? { projectId: layer.projectId } : {},
|
|
36080
36205
|
id: request3.id,
|
|
36081
36206
|
status: request3.status,
|
|
36082
36207
|
requesterActorId: request3.requester.actorId,
|
|
@@ -36100,12 +36225,12 @@ async function createApprovalRequest(layer, input) {
|
|
|
36100
36225
|
});
|
|
36101
36226
|
return request3;
|
|
36102
36227
|
}
|
|
36103
|
-
async function getApprovalRequest(handle, id) {
|
|
36104
|
-
const rows = await handle.select().from(project_exports.approvalRequests).where(eq(project_exports.approvalRequests.id, id));
|
|
36228
|
+
async function getApprovalRequest(handle, id, projectId2) {
|
|
36229
|
+
const rows = await handle.select().from(project_exports.approvalRequests).where(and(eq(project_exports.approvalRequests.id, id), projectScopeFor(project_exports.approvalRequests.projectId, projectId2)));
|
|
36105
36230
|
return rows[0] ? rowToRequest(rows[0]) : null;
|
|
36106
36231
|
}
|
|
36107
|
-
async function listApprovalRequests(handle, input = {}) {
|
|
36108
|
-
const conditions = [];
|
|
36232
|
+
async function listApprovalRequests(handle, input = {}, projectId2) {
|
|
36233
|
+
const conditions = [projectScopeFor(project_exports.approvalRequests.projectId, projectId2)];
|
|
36109
36234
|
if (input.status) conditions.push(eq(project_exports.approvalRequests.status, input.status));
|
|
36110
36235
|
if (input.requesterActorId) conditions.push(eq(project_exports.approvalRequests.requesterActorId, input.requesterActorId));
|
|
36111
36236
|
if (input.taskId) conditions.push(eq(project_exports.approvalRequests.taskId, input.taskId));
|
|
@@ -36119,7 +36244,7 @@ async function listApprovalRequests(handle, input = {}) {
|
|
|
36119
36244
|
async function decideApprovalRequest(layer, requestId, status, input) {
|
|
36120
36245
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
36121
36246
|
return layer.transactionImmediate(async (tx) => {
|
|
36122
|
-
const existing = await getApprovalRequest(tx, requestId);
|
|
36247
|
+
const existing = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36123
36248
|
if (!existing) throw new Error(`Approval request ${requestId} not found`);
|
|
36124
36249
|
if (!isValidApprovalRequestTransition(existing.status, status)) {
|
|
36125
36250
|
throw new Error(`Invalid approval request transition: ${existing.status} -> ${status}`);
|
|
@@ -36130,23 +36255,24 @@ async function decideApprovalRequest(layer, requestId, status, input) {
|
|
|
36130
36255
|
const updatedRows = await tx.update(project_exports.approvalRequests).set({ status, decidedAt: now, updatedAt: now }).where(
|
|
36131
36256
|
and(
|
|
36132
36257
|
eq(project_exports.approvalRequests.id, requestId),
|
|
36133
|
-
eq(project_exports.approvalRequests.status, existing.status)
|
|
36258
|
+
eq(project_exports.approvalRequests.status, existing.status),
|
|
36259
|
+
projectScopeFor(project_exports.approvalRequests.projectId, layer.projectId)
|
|
36134
36260
|
)
|
|
36135
36261
|
).returning({ id: project_exports.approvalRequests.id });
|
|
36136
36262
|
if (updatedRows.length === 0) {
|
|
36137
|
-
const raced = await getApprovalRequest(tx, requestId);
|
|
36263
|
+
const raced = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36138
36264
|
throw new Error(
|
|
36139
36265
|
`Invalid approval request transition: ${raced?.status ?? existing.status} -> ${status}`
|
|
36140
36266
|
);
|
|
36141
36267
|
}
|
|
36142
36268
|
await appendAuditEvent(tx, layer.projectId ?? "", requestId, status, input.actor, now, input.note);
|
|
36143
|
-
return await getApprovalRequest(tx, requestId);
|
|
36269
|
+
return await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36144
36270
|
});
|
|
36145
36271
|
}
|
|
36146
36272
|
async function markApprovalRequestCompleted(layer, requestId, input) {
|
|
36147
36273
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
36148
36274
|
return layer.transactionImmediate(async (tx) => {
|
|
36149
|
-
const existing = await getApprovalRequest(tx, requestId);
|
|
36275
|
+
const existing = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36150
36276
|
if (!existing) throw new Error(`Approval request ${requestId} not found`);
|
|
36151
36277
|
if (!isValidApprovalRequestTransition(existing.status, "completed")) {
|
|
36152
36278
|
throw new Error(`Invalid approval request transition: ${existing.status} -> completed`);
|
|
@@ -36160,21 +36286,22 @@ async function markApprovalRequestCompleted(layer, requestId, input) {
|
|
|
36160
36286
|
const updatedRows = await tx.update(project_exports.approvalRequests).set({ status: "completed", completedAt: now, updatedAt: now }).where(
|
|
36161
36287
|
and(
|
|
36162
36288
|
eq(project_exports.approvalRequests.id, requestId),
|
|
36163
|
-
eq(project_exports.approvalRequests.status, existing.status)
|
|
36289
|
+
eq(project_exports.approvalRequests.status, existing.status),
|
|
36290
|
+
projectScopeFor(project_exports.approvalRequests.projectId, layer.projectId)
|
|
36164
36291
|
)
|
|
36165
36292
|
).returning({ id: project_exports.approvalRequests.id });
|
|
36166
36293
|
if (updatedRows.length === 0) {
|
|
36167
|
-
const raced = await getApprovalRequest(tx, requestId);
|
|
36294
|
+
const raced = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36168
36295
|
throw new Error(
|
|
36169
36296
|
`Invalid approval request transition: ${raced?.status ?? existing.status} -> completed`
|
|
36170
36297
|
);
|
|
36171
36298
|
}
|
|
36172
36299
|
await appendAuditEvent(tx, layer.projectId ?? "", requestId, "completed", input.actor, now, input.note);
|
|
36173
|
-
return await getApprovalRequest(tx, requestId);
|
|
36300
|
+
return await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36174
36301
|
});
|
|
36175
36302
|
}
|
|
36176
|
-
async function getApprovalAuditHistory(handle, requestId) {
|
|
36177
|
-
const rows = await handle.select().from(project_exports.approvalRequestAuditEvents).where(eq(project_exports.approvalRequestAuditEvents.requestId, requestId)).orderBy(
|
|
36303
|
+
async function getApprovalAuditHistory(handle, requestId, projectId2) {
|
|
36304
|
+
const rows = await handle.select().from(project_exports.approvalRequestAuditEvents).where(and(eq(project_exports.approvalRequestAuditEvents.requestId, requestId), projectScopeFor(project_exports.approvalRequestAuditEvents.projectId, projectId2))).orderBy(
|
|
36178
36305
|
sql`${project_exports.approvalRequestAuditEvents.createdAt} ASC, ${project_exports.approvalRequestAuditEvents.id} ASC`
|
|
36179
36306
|
);
|
|
36180
36307
|
return rows.map((row) => rowToAuditEvent(row));
|
|
@@ -36184,6 +36311,7 @@ var init_async_approval_request_store = __esm({
|
|
|
36184
36311
|
"use strict";
|
|
36185
36312
|
init_drizzle_orm();
|
|
36186
36313
|
init_schema2();
|
|
36314
|
+
init_data_layer();
|
|
36187
36315
|
init_agents();
|
|
36188
36316
|
init_types();
|
|
36189
36317
|
}
|
|
@@ -36197,6 +36325,7 @@ var init_approval_request_store = __esm({
|
|
|
36197
36325
|
"use strict";
|
|
36198
36326
|
init_drizzle_orm();
|
|
36199
36327
|
init_db2();
|
|
36328
|
+
init_data_layer();
|
|
36200
36329
|
init_async_approval_request_store();
|
|
36201
36330
|
init_schema2();
|
|
36202
36331
|
init_async_agent_activity();
|
|
@@ -36325,23 +36454,26 @@ var init_approval_request_store = __esm({
|
|
|
36325
36454
|
return created;
|
|
36326
36455
|
}
|
|
36327
36456
|
async get(id) {
|
|
36328
|
-
return getApprovalRequest(this.asyncLayer.db, id);
|
|
36457
|
+
return getApprovalRequest(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
36329
36458
|
}
|
|
36330
36459
|
async list(input = {}) {
|
|
36331
|
-
return listApprovalRequests(this.asyncLayer.db, input);
|
|
36460
|
+
return listApprovalRequests(this.asyncLayer.db, input, this.asyncLayer.projectId);
|
|
36332
36461
|
}
|
|
36333
36462
|
async getPendingCountsByActor() {
|
|
36334
36463
|
const table = project_exports.approvalRequests;
|
|
36335
36464
|
const rows = await this.asyncLayer.db.select({
|
|
36336
36465
|
actorId: table.requesterActorId,
|
|
36337
36466
|
requestCount: count()
|
|
36338
|
-
}).from(table).where(eq(table.status, "pending")).groupBy(table.requesterActorId);
|
|
36467
|
+
}).from(table).where(and(eq(table.status, "pending"), projectScopeFor(table.projectId, this.asyncLayer.projectId))).groupBy(table.requesterActorId);
|
|
36339
36468
|
return new Map(rows.map((row) => [row.actorId, Number(row.requestCount)]));
|
|
36340
36469
|
}
|
|
36341
36470
|
async findLatestByDedupeKey(input) {
|
|
36342
36471
|
if (this.backendMode) {
|
|
36343
36472
|
const table = project_exports.approvalRequests;
|
|
36344
|
-
const conditions = [
|
|
36473
|
+
const conditions = [
|
|
36474
|
+
eq(table.requesterActorId, input.requesterActorId),
|
|
36475
|
+
projectScopeFor(table.projectId, this.asyncLayer.projectId)
|
|
36476
|
+
];
|
|
36345
36477
|
if (input.taskId !== void 0) {
|
|
36346
36478
|
conditions.push(eq(table.taskId, input.taskId));
|
|
36347
36479
|
}
|
|
@@ -36380,7 +36512,7 @@ var init_approval_request_store = __esm({
|
|
|
36380
36512
|
return markApprovalRequestCompleted(this.asyncLayer, requestId, input);
|
|
36381
36513
|
}
|
|
36382
36514
|
async getAuditHistory(requestId) {
|
|
36383
|
-
return getApprovalAuditHistory(this.asyncLayer.db, requestId);
|
|
36515
|
+
return getApprovalAuditHistory(this.asyncLayer.db, requestId, this.asyncLayer.projectId);
|
|
36384
36516
|
}
|
|
36385
36517
|
};
|
|
36386
36518
|
}
|
|
@@ -40566,6 +40698,8 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
40566
40698
|
const agentRatingProjectIsolationAlreadyApplied = applied.includes(AGENT_RATING_PROJECT_ISOLATION_VERSION);
|
|
40567
40699
|
const agentRatingsProjectPartitionAlreadyApplied = applied.includes(AGENT_RATINGS_PROJECT_PARTITION_VERSION);
|
|
40568
40700
|
const projectOwnershipDeclarationDriftAlreadyApplied = applied.includes(PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION);
|
|
40701
|
+
const projectOwnershipDefaultReconciliationAlreadyApplied = applied.includes(PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION);
|
|
40702
|
+
const messageArchiveSchemaAlreadyApplied = applied.includes(MESSAGE_ARCHIVE_SCHEMA_VERSION);
|
|
40569
40703
|
assertBinaryNotOlderThanDatabase(applied);
|
|
40570
40704
|
let schemaChanged = false;
|
|
40571
40705
|
if (!baselineAlreadyApplied) {
|
|
@@ -41049,17 +41183,29 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
41049
41183
|
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
41050
41184
|
schemaChanged = true;
|
|
41051
41185
|
}
|
|
41186
|
+
if (!projectOwnershipDefaultReconciliationAlreadyApplied) {
|
|
41187
|
+
const migrationSql = await readFile4(PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_MIGRATION_PATH, "utf8");
|
|
41188
|
+
await tx.execute(sql.raw(migrationSql));
|
|
41189
|
+
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
41190
|
+
schemaChanged = true;
|
|
41191
|
+
}
|
|
41192
|
+
if (!messageArchiveSchemaAlreadyApplied) {
|
|
41193
|
+
const migrationSql = await readFile4(MESSAGE_ARCHIVE_SCHEMA_MIGRATION_PATH, "utf8");
|
|
41194
|
+
await tx.execute(sql.raw(migrationSql));
|
|
41195
|
+
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${MESSAGE_ARCHIVE_SCHEMA_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
41196
|
+
schemaChanged = true;
|
|
41197
|
+
}
|
|
41052
41198
|
return { applied: schemaChanged, pluginHooksRun: pluginHooks.length };
|
|
41053
41199
|
});
|
|
41054
41200
|
}
|
|
41055
|
-
var SCHEMA_BASELINE_VERSION, TASK_DECLARED_SYMBOLS_VERSION, INITIAL_SCHEMA_VERSION, AUTOMATION_ISOLATION_SCHEMA_VERSION, ANALYTICS_ISOLATION_SCHEMA_VERSION, MONITOR_APPROVAL_ISOLATION_SCHEMA_VERSION, LEGACY_CUTOVER_PRESERVATION_SCHEMA_VERSION, MULTI_PROJECT_CUTOVER_SCHEMA_VERSION, PROJECT_OWNERSHIP_SCHEMA_VERSION, SQLITE_SCHEMA_PARITY_VERSION, SESSION_ADVISOR_ENABLED_SCHEMA_VERSION, MISSION_FIX_IDEMPOTENCY_VERSION, IMPORT_TRANSLATION_CACHE_VERSION, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_VERSION, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_VERSION, OWNER_PROJECT_ID_SPLIT_VERSION, CHAT_SESSION_PINS_VERSION, EXECUTOR_TOOL_FAILURE_RETRY_VERSION, EXECUTOR_ESCALATION_ATTEMPT_VERSION, GLOBAL_ROUTINES_SCHEMA_VERSION, TASK_MERGER_MODEL_LANE_VERSION, BULK_COMPLETION_REFUSAL_AT_VERSION, TASK_PROPOSAL_CLAIM_VERSION, CONFIGURATION_REVISIONS_VERSION, IDEATION_SCHEMA_VERSION, RESEARCH_FEATURE_PROVENANCE_VERSION, TASK_VERIFICATION_REQUEST_VERSION, SYMBOL_LOCKS_SCHEMA_VERSION, BIGINT_COUNTERS_VERSION, PLANNING_ACTIVE_TIMING_VERSION, SQLITE_MIGRATION_RUNTIME_READ_VERSION, WORKFLOW_TASK_CONTINUATIONS_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_VERSION, TASK_WEDGE_NOTIFICATION_VERSION, MILESTONE_ASSERTION_PROVENANCE_VERSION, MISSION_LINEAGE_STOP_VERSION, CHAT_SESSION_TAGS_VERSION, DROP_GLOBAL_CONCURRENCY_VERSION, MISSION_TASK_PREFIX_VERSION, CREDENTIAL_INSTANCE_SELECTION_VERSION, TASK_LIFECYCLE_OUTBOX_VERSION, TASK_LIFECYCLE_CONSUMERS_VERSION, VALIDATOR_INPUT_FINGERPRINT_VERSION, UNPLANNED_EXECUTION_BLOCK_DEDUPE_VERSION, QUEUED_EPISODE_SIGNATURE_VERSION, MULTI_ROLE_WORKFLOW_AGENTS_VERSION, WORKFLOW_PRINCIPAL_FENCE_VERSION, TASK_RECOMMENDATIONS_VERSION, GITHUB_CHECK_STATES_VERSION, AGENT_ACTIVITY_EVENTS_VERSION, SPEC_LOCK_DRIFT_REPORT_VERSION, SPEC_LOCK_SOURCE_REVISION_BIGINT_VERSION, MEMORY_RECALL_RECORDS_VERSION, MISSION_FEATURE_SPEC_ALIGNMENT_VERSION, AGENT_RATING_PROJECT_ISOLATION_VERSION, AGENT_RATINGS_PROJECT_PARTITION_VERSION, PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION, StaleBinarySchemaError, MIGRATION_BOOKKEEPING_TABLE, LEGACY_ADOPTION_DRAINED_MARKER, __dirname, MIGRATIONS_DIR, BASELINE_MIGRATION_PATH, AUTOMATION_ISOLATION_MIGRATION_PATH, ANALYTICS_ISOLATION_MIGRATION_PATH, MONITOR_APPROVAL_ISOLATION_MIGRATION_PATH, LEGACY_CUTOVER_PRESERVATION_MIGRATION_PATH, MULTI_PROJECT_CUTOVER_MIGRATION_PATH, PROJECT_OWNERSHIP_MIGRATION_PATH, SQLITE_SCHEMA_PARITY_MIGRATION_PATH, SESSION_ADVISOR_ENABLED_MIGRATION_PATH, MISSION_FIX_IDEMPOTENCY_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_MIGRATION_PATH, OWNER_PROJECT_ID_SPLIT_MIGRATION_PATH, CHAT_SESSION_PINS_MIGRATION_PATH, EXECUTOR_TOOL_FAILURE_RETRY_MIGRATION_PATH, EXECUTOR_ESCALATION_ATTEMPT_MIGRATION_PATH, GLOBAL_ROUTINES_MIGRATION_PATH, TASK_MERGER_MODEL_LANE_MIGRATION_PATH, BULK_COMPLETION_REFUSAL_AT_MIGRATION_PATH, TASK_PROPOSAL_CLAIM_MIGRATION_PATH, CONFIGURATION_REVISIONS_MIGRATION_PATH, IDEATION_MIGRATION_PATH, RESEARCH_FEATURE_PROVENANCE_MIGRATION_PATH, TASK_VERIFICATION_REQUEST_MIGRATION_PATH, SYMBOL_LOCKS_MIGRATION_PATH, BIGINT_COUNTERS_MIGRATION_PATH, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_VERSION, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_MIGRATION_PATH, PLANNING_ACTIVE_TIMING_MIGRATION_PATH, TASK_DECLARED_SYMBOLS_MIGRATION_PATH, SQLITE_MIGRATION_RUNTIME_READ_PATH, WORKFLOW_TASK_CONTINUATIONS_PATH, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_PATH, TASK_WEDGE_NOTIFICATION_MIGRATION_PATH, MILESTONE_ASSERTION_PROVENANCE_MIGRATION_PATH, MISSION_LINEAGE_STOP_MIGRATION_PATH, CHAT_SESSION_TAGS_MIGRATION_PATH, DROP_GLOBAL_CONCURRENCY_MIGRATION_PATH, MISSION_TASK_PREFIX_MIGRATION_PATH, CREDENTIAL_INSTANCE_SELECTION_MIGRATION_PATH, TASK_LIFECYCLE_OUTBOX_MIGRATION_PATH, TASK_LIFECYCLE_CONSUMERS_MIGRATION_PATH, VALIDATOR_INPUT_FINGERPRINT_MIGRATION_PATH, UNPLANNED_EXECUTION_BLOCK_DEDUPE_MIGRATION_PATH, QUEUED_EPISODE_SIGNATURE_MIGRATION_PATH, MULTI_ROLE_WORKFLOW_AGENTS_MIGRATION_PATH, WORKFLOW_PRINCIPAL_FENCE_MIGRATION_PATH, TASK_RECOMMENDATIONS_MIGRATION_PATH, GITHUB_CHECK_STATES_MIGRATION_PATH, AGENT_ACTIVITY_EVENTS_MIGRATION_PATH, SPEC_LOCK_DRIFT_REPORT_MIGRATION_PATH, SPEC_LOCK_SOURCE_REVISION_BIGINT_MIGRATION_PATH, MEMORY_RECALL_RECORDS_MIGRATION_PATH, MISSION_FEATURE_SPEC_ALIGNMENT_MIGRATION_PATH, AGENT_RATING_PROJECT_ISOLATION_MIGRATION_PATH, AGENT_RATINGS_PROJECT_PARTITION_MIGRATION_PATH, PROJECT_OWNERSHIP_DECLARATION_DRIFT_MIGRATION_PATH;
|
|
41201
|
+
var SCHEMA_BASELINE_VERSION, TASK_DECLARED_SYMBOLS_VERSION, INITIAL_SCHEMA_VERSION, AUTOMATION_ISOLATION_SCHEMA_VERSION, ANALYTICS_ISOLATION_SCHEMA_VERSION, MONITOR_APPROVAL_ISOLATION_SCHEMA_VERSION, LEGACY_CUTOVER_PRESERVATION_SCHEMA_VERSION, MULTI_PROJECT_CUTOVER_SCHEMA_VERSION, PROJECT_OWNERSHIP_SCHEMA_VERSION, SQLITE_SCHEMA_PARITY_VERSION, SESSION_ADVISOR_ENABLED_SCHEMA_VERSION, MISSION_FIX_IDEMPOTENCY_VERSION, IMPORT_TRANSLATION_CACHE_VERSION, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_VERSION, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_VERSION, OWNER_PROJECT_ID_SPLIT_VERSION, CHAT_SESSION_PINS_VERSION, EXECUTOR_TOOL_FAILURE_RETRY_VERSION, EXECUTOR_ESCALATION_ATTEMPT_VERSION, GLOBAL_ROUTINES_SCHEMA_VERSION, TASK_MERGER_MODEL_LANE_VERSION, BULK_COMPLETION_REFUSAL_AT_VERSION, TASK_PROPOSAL_CLAIM_VERSION, CONFIGURATION_REVISIONS_VERSION, IDEATION_SCHEMA_VERSION, RESEARCH_FEATURE_PROVENANCE_VERSION, TASK_VERIFICATION_REQUEST_VERSION, SYMBOL_LOCKS_SCHEMA_VERSION, BIGINT_COUNTERS_VERSION, PLANNING_ACTIVE_TIMING_VERSION, SQLITE_MIGRATION_RUNTIME_READ_VERSION, WORKFLOW_TASK_CONTINUATIONS_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_VERSION, TASK_WEDGE_NOTIFICATION_VERSION, MILESTONE_ASSERTION_PROVENANCE_VERSION, MISSION_LINEAGE_STOP_VERSION, CHAT_SESSION_TAGS_VERSION, DROP_GLOBAL_CONCURRENCY_VERSION, MISSION_TASK_PREFIX_VERSION, CREDENTIAL_INSTANCE_SELECTION_VERSION, TASK_LIFECYCLE_OUTBOX_VERSION, TASK_LIFECYCLE_CONSUMERS_VERSION, VALIDATOR_INPUT_FINGERPRINT_VERSION, UNPLANNED_EXECUTION_BLOCK_DEDUPE_VERSION, QUEUED_EPISODE_SIGNATURE_VERSION, MULTI_ROLE_WORKFLOW_AGENTS_VERSION, WORKFLOW_PRINCIPAL_FENCE_VERSION, TASK_RECOMMENDATIONS_VERSION, GITHUB_CHECK_STATES_VERSION, AGENT_ACTIVITY_EVENTS_VERSION, SPEC_LOCK_DRIFT_REPORT_VERSION, SPEC_LOCK_SOURCE_REVISION_BIGINT_VERSION, MEMORY_RECALL_RECORDS_VERSION, MISSION_FEATURE_SPEC_ALIGNMENT_VERSION, AGENT_RATING_PROJECT_ISOLATION_VERSION, AGENT_RATINGS_PROJECT_PARTITION_VERSION, PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION, PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION, MESSAGE_ARCHIVE_SCHEMA_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION, StaleBinarySchemaError, MIGRATION_BOOKKEEPING_TABLE, LEGACY_ADOPTION_DRAINED_MARKER, __dirname, MIGRATIONS_DIR, BASELINE_MIGRATION_PATH, AUTOMATION_ISOLATION_MIGRATION_PATH, ANALYTICS_ISOLATION_MIGRATION_PATH, MONITOR_APPROVAL_ISOLATION_MIGRATION_PATH, LEGACY_CUTOVER_PRESERVATION_MIGRATION_PATH, MULTI_PROJECT_CUTOVER_MIGRATION_PATH, PROJECT_OWNERSHIP_MIGRATION_PATH, SQLITE_SCHEMA_PARITY_MIGRATION_PATH, SESSION_ADVISOR_ENABLED_MIGRATION_PATH, MISSION_FIX_IDEMPOTENCY_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_MIGRATION_PATH, OWNER_PROJECT_ID_SPLIT_MIGRATION_PATH, CHAT_SESSION_PINS_MIGRATION_PATH, EXECUTOR_TOOL_FAILURE_RETRY_MIGRATION_PATH, EXECUTOR_ESCALATION_ATTEMPT_MIGRATION_PATH, GLOBAL_ROUTINES_MIGRATION_PATH, TASK_MERGER_MODEL_LANE_MIGRATION_PATH, BULK_COMPLETION_REFUSAL_AT_MIGRATION_PATH, TASK_PROPOSAL_CLAIM_MIGRATION_PATH, CONFIGURATION_REVISIONS_MIGRATION_PATH, IDEATION_MIGRATION_PATH, RESEARCH_FEATURE_PROVENANCE_MIGRATION_PATH, TASK_VERIFICATION_REQUEST_MIGRATION_PATH, SYMBOL_LOCKS_MIGRATION_PATH, BIGINT_COUNTERS_MIGRATION_PATH, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_VERSION, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_MIGRATION_PATH, PLANNING_ACTIVE_TIMING_MIGRATION_PATH, TASK_DECLARED_SYMBOLS_MIGRATION_PATH, SQLITE_MIGRATION_RUNTIME_READ_PATH, WORKFLOW_TASK_CONTINUATIONS_PATH, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_PATH, TASK_WEDGE_NOTIFICATION_MIGRATION_PATH, MILESTONE_ASSERTION_PROVENANCE_MIGRATION_PATH, MISSION_LINEAGE_STOP_MIGRATION_PATH, CHAT_SESSION_TAGS_MIGRATION_PATH, DROP_GLOBAL_CONCURRENCY_MIGRATION_PATH, MISSION_TASK_PREFIX_MIGRATION_PATH, CREDENTIAL_INSTANCE_SELECTION_MIGRATION_PATH, TASK_LIFECYCLE_OUTBOX_MIGRATION_PATH, TASK_LIFECYCLE_CONSUMERS_MIGRATION_PATH, VALIDATOR_INPUT_FINGERPRINT_MIGRATION_PATH, UNPLANNED_EXECUTION_BLOCK_DEDUPE_MIGRATION_PATH, QUEUED_EPISODE_SIGNATURE_MIGRATION_PATH, MULTI_ROLE_WORKFLOW_AGENTS_MIGRATION_PATH, WORKFLOW_PRINCIPAL_FENCE_MIGRATION_PATH, TASK_RECOMMENDATIONS_MIGRATION_PATH, GITHUB_CHECK_STATES_MIGRATION_PATH, AGENT_ACTIVITY_EVENTS_MIGRATION_PATH, SPEC_LOCK_DRIFT_REPORT_MIGRATION_PATH, SPEC_LOCK_SOURCE_REVISION_BIGINT_MIGRATION_PATH, MEMORY_RECALL_RECORDS_MIGRATION_PATH, MISSION_FEATURE_SPEC_ALIGNMENT_MIGRATION_PATH, AGENT_RATING_PROJECT_ISOLATION_MIGRATION_PATH, AGENT_RATINGS_PROJECT_PARTITION_MIGRATION_PATH, PROJECT_OWNERSHIP_DECLARATION_DRIFT_MIGRATION_PATH, PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_MIGRATION_PATH, MESSAGE_ARCHIVE_SCHEMA_MIGRATION_PATH;
|
|
41056
41202
|
var init_schema_applier = __esm({
|
|
41057
41203
|
"../core/src/postgres/schema-applier.ts"() {
|
|
41058
41204
|
"use strict";
|
|
41059
41205
|
init_drizzle_orm();
|
|
41060
41206
|
init_plugin_schema_hook();
|
|
41061
41207
|
init_advisory_locks();
|
|
41062
|
-
SCHEMA_BASELINE_VERSION = "
|
|
41208
|
+
SCHEMA_BASELINE_VERSION = "0058";
|
|
41063
41209
|
TASK_DECLARED_SYMBOLS_VERSION = "0028";
|
|
41064
41210
|
INITIAL_SCHEMA_VERSION = "0000";
|
|
41065
41211
|
AUTOMATION_ISOLATION_SCHEMA_VERSION = "0001";
|
|
@@ -41116,6 +41262,8 @@ var init_schema_applier = __esm({
|
|
|
41116
41262
|
AGENT_RATING_PROJECT_ISOLATION_VERSION = "0054";
|
|
41117
41263
|
AGENT_RATINGS_PROJECT_PARTITION_VERSION = "0055";
|
|
41118
41264
|
PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION = "0056";
|
|
41265
|
+
PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION = "0057";
|
|
41266
|
+
MESSAGE_ARCHIVE_SCHEMA_VERSION = "0058";
|
|
41119
41267
|
LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION = "fusion_mark_legacy_adoption_drained";
|
|
41120
41268
|
StaleBinarySchemaError = class extends Error {
|
|
41121
41269
|
constructor(databaseVersion, binaryVersion) {
|
|
@@ -41252,6 +41400,8 @@ var init_schema_applier = __esm({
|
|
|
41252
41400
|
AGENT_RATING_PROJECT_ISOLATION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0054_fn_8957_agent_rating_project_isolation.sql");
|
|
41253
41401
|
AGENT_RATINGS_PROJECT_PARTITION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0055_fn_8988_agent_ratings_project_partition.sql");
|
|
41254
41402
|
PROJECT_OWNERSHIP_DECLARATION_DRIFT_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0056_fn_8997_project_ownership_declaration_drift.sql");
|
|
41403
|
+
PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0057_fn_9004_project_ownership_default_reconciliation.sql");
|
|
41404
|
+
MESSAGE_ARCHIVE_SCHEMA_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0058_fn_9014_message_archive.sql");
|
|
41255
41405
|
}
|
|
41256
41406
|
});
|
|
41257
41407
|
|
|
@@ -68784,8 +68934,10 @@ function safeJsonParse(value2) {
|
|
|
68784
68934
|
return null;
|
|
68785
68935
|
}
|
|
68786
68936
|
}
|
|
68787
|
-
async function queryRunAuditEvents(db, filter2 = {}) {
|
|
68788
|
-
const conditions = []
|
|
68937
|
+
async function queryRunAuditEvents(db, filter2 = {}, projectId2) {
|
|
68938
|
+
const conditions = [projectScopeFor(project_exports.runAuditEvents.projectId, projectId2)].filter(
|
|
68939
|
+
(condition) => condition !== void 0
|
|
68940
|
+
);
|
|
68789
68941
|
if (filter2.runId) {
|
|
68790
68942
|
conditions.push(eq(project_exports.runAuditEvents.runId, filter2.runId));
|
|
68791
68943
|
}
|
|
@@ -68931,6 +69083,7 @@ var init_async_audit = __esm({
|
|
|
68931
69083
|
init_drizzle_orm();
|
|
68932
69084
|
init_schema2();
|
|
68933
69085
|
init_data_layer();
|
|
69086
|
+
init_data_layer();
|
|
68934
69087
|
LEGACY_REVIEW_LANES3 = ["in-review"];
|
|
68935
69088
|
LEGACY_COMPLETE_LANES = ["done"];
|
|
68936
69089
|
}
|
|
@@ -69320,7 +69473,10 @@ async function insertArtifactRow(layer, input, stored, archivedColumns) {
|
|
|
69320
69473
|
createdAt: now,
|
|
69321
69474
|
updatedAt: now
|
|
69322
69475
|
});
|
|
69323
|
-
const rows = await tx.select().from(project_exports.artifacts).where(
|
|
69476
|
+
const rows = await tx.select().from(project_exports.artifacts).where(and(
|
|
69477
|
+
eq(project_exports.artifacts.id, id),
|
|
69478
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
69479
|
+
)).limit(1);
|
|
69324
69480
|
const row = rows[0];
|
|
69325
69481
|
if (!row) throw new Error(`Failed to register artifact ${id}`);
|
|
69326
69482
|
return rowToArtifact2(row);
|
|
@@ -69328,7 +69484,7 @@ async function insertArtifactRow(layer, input, stored, archivedColumns) {
|
|
|
69328
69484
|
}
|
|
69329
69485
|
async function updateArtifactRow(layer, id, updates, archivedColumns) {
|
|
69330
69486
|
return layer.transactionImmediate(async (tx) => {
|
|
69331
|
-
const existing = await getArtifact(tx, id);
|
|
69487
|
+
const existing = await getArtifact(tx, id, layer.projectId);
|
|
69332
69488
|
if (!existing) {
|
|
69333
69489
|
throw new Error(`Artifact ${id} not found`);
|
|
69334
69490
|
}
|
|
@@ -69348,29 +69504,38 @@ async function updateArtifactRow(layer, id, updates, archivedColumns) {
|
|
|
69348
69504
|
description: updates.description !== void 0 ? updates.description : existing.description ?? null,
|
|
69349
69505
|
content: updates.content !== void 0 ? updates.content : existing.content ?? null,
|
|
69350
69506
|
updatedAt: now
|
|
69351
|
-
}).where(
|
|
69352
|
-
|
|
69507
|
+
}).where(and(
|
|
69508
|
+
eq(project_exports.artifacts.id, id),
|
|
69509
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
69510
|
+
));
|
|
69511
|
+
const updated = await getArtifact(tx, id, layer.projectId);
|
|
69353
69512
|
if (!updated) {
|
|
69354
69513
|
throw new Error(`Failed to update artifact ${id}`);
|
|
69355
69514
|
}
|
|
69356
69515
|
return updated;
|
|
69357
69516
|
});
|
|
69358
69517
|
}
|
|
69359
|
-
async function getArtifact(db, id) {
|
|
69360
|
-
const rows = await db.select().from(project_exports.artifacts).where(
|
|
69518
|
+
async function getArtifact(db, id, projectId2) {
|
|
69519
|
+
const rows = await db.select().from(project_exports.artifacts).where(and(
|
|
69520
|
+
eq(project_exports.artifacts.id, id),
|
|
69521
|
+
projectScopeFor(project_exports.artifacts.projectId, projectId2)
|
|
69522
|
+
)).limit(1);
|
|
69361
69523
|
const row = rows[0];
|
|
69362
69524
|
return row ? rowToArtifact2(row) : null;
|
|
69363
69525
|
}
|
|
69364
69526
|
async function getArtifacts(db, taskId, projectId2, archivedColumns) {
|
|
69365
69527
|
const column = await getLiveTaskColumn(db, taskId, projectId2, archivedColumns);
|
|
69366
69528
|
if (column === null || column === "archived") return [];
|
|
69367
|
-
const rows = await db.select().from(project_exports.artifacts).where(
|
|
69529
|
+
const rows = await db.select().from(project_exports.artifacts).where(and(
|
|
69530
|
+
eq(project_exports.artifacts.taskId, taskId),
|
|
69531
|
+
projectScopeFor(project_exports.artifacts.projectId, projectId2)
|
|
69532
|
+
)).orderBy(desc(project_exports.artifacts.createdAt));
|
|
69368
69533
|
return rows.map((row) => rowToArtifact2(row));
|
|
69369
69534
|
}
|
|
69370
|
-
async function listArtifacts(db, options) {
|
|
69535
|
+
async function listArtifacts(db, options, projectId2) {
|
|
69371
69536
|
const limit2 = Math.min(Math.max(1, options?.limit ?? 200), 1e3);
|
|
69372
69537
|
const offset = Math.max(0, options?.offset ?? 0);
|
|
69373
|
-
const conditions = [];
|
|
69538
|
+
const conditions = [projectScopeFor(project_exports.artifacts.projectId, projectId2)];
|
|
69374
69539
|
if (options?.type) {
|
|
69375
69540
|
conditions.push(eq(project_exports.artifacts.type, options.type));
|
|
69376
69541
|
}
|
|
@@ -69409,7 +69574,10 @@ async function listArtifacts(db, options) {
|
|
|
69409
69574
|
taskColumn: project_exports.tasks.column
|
|
69410
69575
|
}).from(project_exports.artifacts).leftJoin(
|
|
69411
69576
|
project_exports.tasks,
|
|
69412
|
-
|
|
69577
|
+
and(
|
|
69578
|
+
eq(project_exports.artifacts.taskId, project_exports.tasks.id),
|
|
69579
|
+
eq(project_exports.artifacts.projectId, project_exports.tasks.projectId)
|
|
69580
|
+
)
|
|
69413
69581
|
).where(and(...conditions)).orderBy(desc(project_exports.artifacts.createdAt)).limit(limit2).offset(offset);
|
|
69414
69582
|
return rows.map((row) => {
|
|
69415
69583
|
const artifact = rowToArtifact2(row);
|
|
@@ -70574,7 +70742,7 @@ function rowToBranchGroup2(row) {
|
|
|
70574
70742
|
closedAt: row.closedAt ?? void 0
|
|
70575
70743
|
};
|
|
70576
70744
|
}
|
|
70577
|
-
async function createBranchGroup(db, input) {
|
|
70745
|
+
async function createBranchGroup(db, input, projectId2) {
|
|
70578
70746
|
validateBranchGroupBranchName(input.branchName);
|
|
70579
70747
|
const now = Date.now();
|
|
70580
70748
|
const id = generateBranchGroupId2();
|
|
@@ -70593,44 +70761,52 @@ async function createBranchGroup(db, input) {
|
|
|
70593
70761
|
updatedAt: now,
|
|
70594
70762
|
closedAt: input.closedAt ?? null
|
|
70595
70763
|
});
|
|
70596
|
-
const created = await getBranchGroup(db, id);
|
|
70764
|
+
const created = await getBranchGroup(db, id, projectId2);
|
|
70597
70765
|
if (!created) throw new Error(`Failed to read branch group ${id} after create`);
|
|
70598
70766
|
return created;
|
|
70599
70767
|
}
|
|
70600
|
-
async function getBranchGroup(db, id) {
|
|
70601
|
-
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70768
|
+
async function getBranchGroup(db, id, projectId2) {
|
|
70769
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(
|
|
70770
|
+
eq(project_exports.branchGroups.id, id),
|
|
70771
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70772
|
+
)).limit(1);
|
|
70602
70773
|
const row = rows[0];
|
|
70603
70774
|
return row ? rowToBranchGroup2(row) : null;
|
|
70604
70775
|
}
|
|
70605
|
-
async function getBranchGroupBySource(db, sourceType, sourceId) {
|
|
70776
|
+
async function getBranchGroupBySource(db, sourceType, sourceId, projectId2) {
|
|
70606
70777
|
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70607
70778
|
and(
|
|
70608
70779
|
eq(project_exports.branchGroups.sourceType, sourceType),
|
|
70609
|
-
eq(project_exports.branchGroups.sourceId, sourceId)
|
|
70780
|
+
eq(project_exports.branchGroups.sourceId, sourceId),
|
|
70781
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70610
70782
|
)
|
|
70611
70783
|
).limit(1);
|
|
70612
70784
|
const row = rows[0];
|
|
70613
70785
|
return row ? rowToBranchGroup2(row) : null;
|
|
70614
70786
|
}
|
|
70615
|
-
async function getBranchGroupByBranchName(db, branchName) {
|
|
70616
|
-
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70787
|
+
async function getBranchGroupByBranchName(db, branchName, projectId2) {
|
|
70788
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(
|
|
70789
|
+
eq(project_exports.branchGroups.branchName, branchName),
|
|
70790
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70791
|
+
)).orderBy(sql`${project_exports.branchGroups.createdAt} DESC`).limit(1);
|
|
70617
70792
|
const row = rows[0];
|
|
70618
70793
|
return row ? rowToBranchGroup2(row) : null;
|
|
70619
70794
|
}
|
|
70620
|
-
async function ensureBranchGroupForSource(db, sourceType, sourceId, init) {
|
|
70621
|
-
const existing = await getBranchGroupBySource(db, sourceType, sourceId);
|
|
70795
|
+
async function ensureBranchGroupForSource(db, sourceType, sourceId, init, projectId2) {
|
|
70796
|
+
const existing = await getBranchGroupBySource(db, sourceType, sourceId, projectId2);
|
|
70622
70797
|
if (existing) return existing;
|
|
70623
|
-
const existingByBranch = await getBranchGroupByBranchName(db, init.branchName);
|
|
70798
|
+
const existingByBranch = await getBranchGroupByBranchName(db, init.branchName, projectId2);
|
|
70624
70799
|
if (existingByBranch) return existingByBranch;
|
|
70625
|
-
return createBranchGroup(db, { sourceType, sourceId, ...init });
|
|
70800
|
+
return createBranchGroup(db, { sourceType, sourceId, ...init }, projectId2);
|
|
70626
70801
|
}
|
|
70627
|
-
async function listBranchGroups(db, options) {
|
|
70628
|
-
const
|
|
70629
|
-
|
|
70802
|
+
async function listBranchGroups(db, options, projectId2) {
|
|
70803
|
+
const conditions = [projectScopeFor(project_exports.branchGroups.projectId, projectId2)];
|
|
70804
|
+
if (options?.status) conditions.push(eq(project_exports.branchGroups.status, options.status));
|
|
70805
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(...conditions)).orderBy(asc(project_exports.branchGroups.createdAt));
|
|
70630
70806
|
return rows.map((row) => rowToBranchGroup2(row));
|
|
70631
70807
|
}
|
|
70632
|
-
async function updateBranchGroup(db, id, patch) {
|
|
70633
|
-
const current = await getBranchGroup(db, id);
|
|
70808
|
+
async function updateBranchGroup(db, id, patch, projectId2) {
|
|
70809
|
+
const current = await getBranchGroup(db, id, projectId2);
|
|
70634
70810
|
if (!current) throw new Error(`Branch group ${id} not found`);
|
|
70635
70811
|
if (patch.branchName !== void 0) {
|
|
70636
70812
|
validateBranchGroupBranchName(patch.branchName);
|
|
@@ -70649,8 +70825,11 @@ async function updateBranchGroup(db, id, patch) {
|
|
|
70649
70825
|
status: nextStatus,
|
|
70650
70826
|
updatedAt: now,
|
|
70651
70827
|
closedAt: nextClosedAt
|
|
70652
|
-
}).where(
|
|
70653
|
-
|
|
70828
|
+
}).where(and(
|
|
70829
|
+
eq(project_exports.branchGroups.id, id),
|
|
70830
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70831
|
+
));
|
|
70832
|
+
const updated = await getBranchGroup(db, id, projectId2);
|
|
70654
70833
|
if (!updated) throw new Error(`Branch group ${id} disappeared after update`);
|
|
70655
70834
|
return updated;
|
|
70656
70835
|
}
|
|
@@ -70807,6 +70986,7 @@ var init_async_branch_groups = __esm({
|
|
|
70807
70986
|
"use strict";
|
|
70808
70987
|
init_drizzle_orm();
|
|
70809
70988
|
init_schema2();
|
|
70989
|
+
init_data_layer();
|
|
70810
70990
|
init_branch_assignment();
|
|
70811
70991
|
}
|
|
70812
70992
|
});
|
|
@@ -80620,6 +80800,9 @@ import { randomUUID as randomUUID21 } from "node:crypto";
|
|
|
80620
80800
|
function tableForScope(scope) {
|
|
80621
80801
|
return scope === "project" ? project_exports.secrets : central_exports.secretsGlobal;
|
|
80622
80802
|
}
|
|
80803
|
+
function scopeForSecretTable(scope, table, projectId2) {
|
|
80804
|
+
return scope === "project" ? projectScopeFor(table.projectId, projectId2) : void 0;
|
|
80805
|
+
}
|
|
80623
80806
|
function isAccessPolicy(value2) {
|
|
80624
80807
|
return value2 === "auto" || value2 === "prompt" || value2 === "deny";
|
|
80625
80808
|
}
|
|
@@ -80642,23 +80825,23 @@ function rowToRecord2(row, scope) {
|
|
|
80642
80825
|
lastReadBy: row.lastReadBy
|
|
80643
80826
|
};
|
|
80644
80827
|
}
|
|
80645
|
-
async function getSecretMetadata(handle, id, scope) {
|
|
80828
|
+
async function getSecretMetadata(handle, id, scope, projectId2) {
|
|
80646
80829
|
const table = tableForScope(scope);
|
|
80647
|
-
const rows = await handle.select(metadataColumns(table)).from(table).where(eq(table.id, id)).limit(1);
|
|
80830
|
+
const rows = await handle.select(metadataColumns(table)).from(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2))).limit(1);
|
|
80648
80831
|
const row = rows[0];
|
|
80649
80832
|
return row ? rowToRecord2(row, scope) : null;
|
|
80650
80833
|
}
|
|
80651
|
-
async function listSecrets(handle, scope) {
|
|
80834
|
+
async function listSecrets(handle, scope, projectId2) {
|
|
80652
80835
|
if (scope) {
|
|
80653
80836
|
const table = tableForScope(scope);
|
|
80654
|
-
const rows = await handle.select(metadataColumns(table)).from(table).orderBy(asc(sql`lower(${table.key})`));
|
|
80837
|
+
const rows = await handle.select(metadataColumns(table)).from(table).where(scopeForSecretTable(scope, table, projectId2)).orderBy(asc(sql`lower(${table.key})`));
|
|
80655
80838
|
return rows.map((row) => rowToRecord2(row, scope));
|
|
80656
80839
|
}
|
|
80657
|
-
const project = await listSecrets(handle, "project");
|
|
80658
|
-
const global2 = await listSecrets(handle, "global");
|
|
80840
|
+
const project = await listSecrets(handle, "project", projectId2);
|
|
80841
|
+
const global2 = await listSecrets(handle, "global", projectId2);
|
|
80659
80842
|
return [...project, ...global2];
|
|
80660
80843
|
}
|
|
80661
|
-
async function createSecret(handle, cipher, input) {
|
|
80844
|
+
async function createSecret(handle, cipher, input, projectId2) {
|
|
80662
80845
|
const key = input.key.trim();
|
|
80663
80846
|
if (!key) {
|
|
80664
80847
|
throw new SecretsStoreError({ code: "invalid-key", message: "Secret key is required" });
|
|
@@ -80672,6 +80855,7 @@ async function createSecret(handle, cipher, input) {
|
|
|
80672
80855
|
const table = tableForScope(input.scope);
|
|
80673
80856
|
try {
|
|
80674
80857
|
await handle.insert(table).values({
|
|
80858
|
+
...input.scope === "project" && projectId2?.trim() ? { projectId: projectId2 } : {},
|
|
80675
80859
|
id,
|
|
80676
80860
|
key,
|
|
80677
80861
|
valueCiphertext: encrypted.ciphertext,
|
|
@@ -80691,14 +80875,14 @@ async function createSecret(handle, cipher, input) {
|
|
|
80691
80875
|
}
|
|
80692
80876
|
throw error3;
|
|
80693
80877
|
}
|
|
80694
|
-
const created = await getSecretMetadata(handle, id, input.scope);
|
|
80878
|
+
const created = await getSecretMetadata(handle, id, input.scope, projectId2);
|
|
80695
80879
|
if (!created) {
|
|
80696
80880
|
throw new SecretsStoreError({ code: "not-found", message: "Secret insert succeeded but row could not be read back" });
|
|
80697
80881
|
}
|
|
80698
80882
|
return created;
|
|
80699
80883
|
}
|
|
80700
|
-
async function updateSecret(handle, cipher, id, scope, patch) {
|
|
80701
|
-
const existing = await getSecretMetadata(handle, id, scope);
|
|
80884
|
+
async function updateSecret(handle, cipher, id, scope, patch, projectId2) {
|
|
80885
|
+
const existing = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80702
80886
|
if (!existing) {
|
|
80703
80887
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
80704
80888
|
}
|
|
@@ -80732,34 +80916,34 @@ async function updateSecret(handle, cipher, id, scope, patch) {
|
|
|
80732
80916
|
updates.nonce = encrypted.nonce;
|
|
80733
80917
|
}
|
|
80734
80918
|
try {
|
|
80735
|
-
await handle.update(table).set(updates).where(eq(table.id, id));
|
|
80919
|
+
await handle.update(table).set(updates).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80736
80920
|
} catch (error3) {
|
|
80737
80921
|
if (isPostgresUniqueError(error3)) {
|
|
80738
80922
|
throw new SecretsStoreError({ code: "duplicate-key", message: "Secret key already exists" });
|
|
80739
80923
|
}
|
|
80740
80924
|
throw error3;
|
|
80741
80925
|
}
|
|
80742
|
-
const updated = await getSecretMetadata(handle, id, scope);
|
|
80926
|
+
const updated = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80743
80927
|
if (!updated) {
|
|
80744
80928
|
throw new SecretsStoreError({ code: "not-found", message: "Secret update succeeded but row could not be read back" });
|
|
80745
80929
|
}
|
|
80746
80930
|
return updated;
|
|
80747
80931
|
}
|
|
80748
|
-
async function deleteSecret(handle, id, scope) {
|
|
80749
|
-
const existing = await getSecretMetadata(handle, id, scope);
|
|
80932
|
+
async function deleteSecret(handle, id, scope, projectId2) {
|
|
80933
|
+
const existing = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80750
80934
|
if (!existing) {
|
|
80751
80935
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
80752
80936
|
}
|
|
80753
80937
|
const table = tableForScope(scope);
|
|
80754
|
-
await handle.delete(table).where(eq(table.id, id));
|
|
80938
|
+
await handle.delete(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80755
80939
|
}
|
|
80756
|
-
async function revealSecret(handle, cipher, id, scope, reader) {
|
|
80940
|
+
async function revealSecret(handle, cipher, id, scope, reader, projectId2) {
|
|
80757
80941
|
const table = tableForScope(scope);
|
|
80758
80942
|
const rows = await handle.select({
|
|
80759
80943
|
...metadataColumns(table),
|
|
80760
80944
|
valueCiphertext: table.valueCiphertext,
|
|
80761
80945
|
nonce: table.nonce
|
|
80762
|
-
}).from(table).where(eq(table.id, id)).limit(1);
|
|
80946
|
+
}).from(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2))).limit(1);
|
|
80763
80947
|
const row = rows[0];
|
|
80764
80948
|
if (!row) {
|
|
80765
80949
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
@@ -80778,7 +80962,7 @@ async function revealSecret(handle, cipher, id, scope, reader) {
|
|
|
80778
80962
|
}
|
|
80779
80963
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
80780
80964
|
const lastReadBy = reader.userId ?? reader.agentId ?? null;
|
|
80781
|
-
await handle.update(table).set({ lastReadAt: now, lastReadBy, updatedAt: now }).where(eq(table.id, id));
|
|
80965
|
+
await handle.update(table).set({ lastReadAt: now, lastReadBy, updatedAt: now }).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80782
80966
|
return { key: row.key, plaintextValue };
|
|
80783
80967
|
}
|
|
80784
80968
|
var severityAuditLog10, SecretsStoreError, metadataColumns;
|
|
@@ -80789,6 +80973,7 @@ var init_async_secrets_store = __esm({
|
|
|
80789
80973
|
init_drizzle_orm();
|
|
80790
80974
|
init_postgres_errors();
|
|
80791
80975
|
init_schema2();
|
|
80976
|
+
init_data_layer();
|
|
80792
80977
|
init_secrets_crypto();
|
|
80793
80978
|
severityAuditLog10 = createLogger("core-async-secrets-store");
|
|
80794
80979
|
SecretsStoreError = class extends Error {
|
|
@@ -80884,7 +81069,7 @@ var init_secrets_store = __esm({
|
|
|
80884
81069
|
};
|
|
80885
81070
|
}
|
|
80886
81071
|
async listSecrets(scope) {
|
|
80887
|
-
return listSecrets(this.asyncLayer.db, scope);
|
|
81072
|
+
return listSecrets(this.asyncLayer.db, scope, this.asyncLayer.projectId);
|
|
80888
81073
|
}
|
|
80889
81074
|
async listEnvExportable(opts) {
|
|
80890
81075
|
const keyPrefix = opts?.keyPrefix;
|
|
@@ -80927,7 +81112,7 @@ var init_secrets_store = __esm({
|
|
|
80927
81112
|
return [...exported.values()];
|
|
80928
81113
|
}
|
|
80929
81114
|
async getSecretMetadata(id, scope) {
|
|
80930
|
-
return getSecretMetadata(this.asyncLayer.db, id, scope);
|
|
81115
|
+
return getSecretMetadata(this.asyncLayer.db, id, scope, this.asyncLayer.projectId);
|
|
80931
81116
|
}
|
|
80932
81117
|
async createSecret(input) {
|
|
80933
81118
|
const key = input.key.trim();
|
|
@@ -80937,12 +81122,12 @@ var init_secrets_store = __esm({
|
|
|
80937
81122
|
if (input.accessPolicy && !isAccessPolicy2(input.accessPolicy)) {
|
|
80938
81123
|
throw new SecretsStoreError2({ code: "invalid-policy", message: "Invalid access policy" });
|
|
80939
81124
|
}
|
|
80940
|
-
const created = await createSecret(this.asyncLayer.db, this.cipher, input);
|
|
81125
|
+
const created = await createSecret(this.asyncLayer.db, this.cipher, input, this.asyncLayer.projectId);
|
|
80941
81126
|
this.emitAudit({ mutationType: "secret:create", scope: input.scope, secretId: created.id, key: created.key });
|
|
80942
81127
|
return created;
|
|
80943
81128
|
}
|
|
80944
81129
|
async updateSecret(id, scope, patch) {
|
|
80945
|
-
const updated = await updateSecret(this.asyncLayer.db, this.cipher, id, scope, patch);
|
|
81130
|
+
const updated = await updateSecret(this.asyncLayer.db, this.cipher, id, scope, patch, this.asyncLayer.projectId);
|
|
80946
81131
|
this.emitAudit({ mutationType: "secret:update", scope, secretId: updated.id, key: updated.key });
|
|
80947
81132
|
return updated;
|
|
80948
81133
|
}
|
|
@@ -80951,12 +81136,12 @@ var init_secrets_store = __esm({
|
|
|
80951
81136
|
if (!existing) {
|
|
80952
81137
|
throw new SecretsStoreError2({ code: "not-found", message: "Secret not found" });
|
|
80953
81138
|
}
|
|
80954
|
-
await deleteSecret(this.asyncLayer.db, id, scope);
|
|
81139
|
+
await deleteSecret(this.asyncLayer.db, id, scope, this.asyncLayer.projectId);
|
|
80955
81140
|
this.emitAudit({ mutationType: "secret:delete", scope, secretId: id, key: existing.key });
|
|
80956
81141
|
return;
|
|
80957
81142
|
}
|
|
80958
81143
|
async revealSecret(id, scope, reader) {
|
|
80959
|
-
const revealed = await revealSecret(this.asyncLayer.db, this.cipher, id, scope, reader);
|
|
81144
|
+
const revealed = await revealSecret(this.asyncLayer.db, this.cipher, id, scope, reader, this.asyncLayer.projectId);
|
|
80960
81145
|
this.emitAudit({ mutationType: "secret:read", scope, secretId: id, key: revealed.key, actor: reader });
|
|
80961
81146
|
return revealed;
|
|
80962
81147
|
}
|
|
@@ -82057,6 +82242,7 @@ async function getVerificationCacheHitImpl(store, treeSha, testCommand, buildCom
|
|
|
82057
82242
|
const normalizedBuild = buildCommand2 ?? "";
|
|
82058
82243
|
const table = project_exports.verificationCache;
|
|
82059
82244
|
const rows = await store.asyncLayer.db.select({ recordedAt: table.recordedAt, taskId: table.taskId }).from(table).where(and(
|
|
82245
|
+
projectScopeFor(table.projectId, store.asyncLayer.projectId),
|
|
82060
82246
|
eq(table.treeSha, treeSha),
|
|
82061
82247
|
eq(table.testCommand, normalizedTest),
|
|
82062
82248
|
eq(table.buildCommand, normalizedBuild)
|
|
@@ -82799,7 +82985,7 @@ async function invokeTaskCreatedHookImpl(store, task) {
|
|
|
82799
82985
|
}
|
|
82800
82986
|
async function createBranchGroupImpl(store, input) {
|
|
82801
82987
|
const layer = store.asyncLayer;
|
|
82802
|
-
return createBranchGroup(layer.db, input);
|
|
82988
|
+
return createBranchGroup(layer.db, input, layer.projectId);
|
|
82803
82989
|
}
|
|
82804
82990
|
var init_task_id_integrity2 = __esm({
|
|
82805
82991
|
"../core/src/task-store/task-id-integrity.ts"() {
|
|
@@ -82884,22 +83070,23 @@ import { readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises
|
|
|
82884
83070
|
import { join as join23 } from "node:path";
|
|
82885
83071
|
async function getBranchGroupImpl(store, id) {
|
|
82886
83072
|
const layer = store.asyncLayer;
|
|
82887
|
-
return getBranchGroup(layer.db, id);
|
|
83073
|
+
return getBranchGroup(layer.db, id, layer.projectId);
|
|
82888
83074
|
}
|
|
82889
83075
|
async function getBranchGroupBySourceImpl(store, sourceType, sourceId) {
|
|
82890
83076
|
const layer = store.asyncLayer;
|
|
82891
|
-
return getBranchGroupBySource(layer.db, sourceType, sourceId);
|
|
83077
|
+
return getBranchGroupBySource(layer.db, sourceType, sourceId, layer.projectId);
|
|
82892
83078
|
}
|
|
82893
83079
|
async function getBranchGroupByBranchNameImpl(store, branchName) {
|
|
82894
83080
|
const layer = store.asyncLayer;
|
|
82895
|
-
return getBranchGroupByBranchName(layer.db, branchName);
|
|
83081
|
+
return getBranchGroupByBranchName(layer.db, branchName, layer.projectId);
|
|
82896
83082
|
}
|
|
82897
83083
|
async function ensureBranchGroupForSourceImpl(store, sourceType, sourceId, init) {
|
|
82898
|
-
|
|
83084
|
+
const layer = store.asyncLayer;
|
|
83085
|
+
return ensureBranchGroupForSource(layer.db, sourceType, sourceId, init, layer.projectId);
|
|
82899
83086
|
}
|
|
82900
83087
|
async function listBranchGroupsImpl(store, options) {
|
|
82901
83088
|
const layer = store.asyncLayer;
|
|
82902
|
-
return listBranchGroups(layer.db, options);
|
|
83089
|
+
return listBranchGroups(layer.db, options, layer.projectId);
|
|
82903
83090
|
}
|
|
82904
83091
|
async function listTasksByBranchGroupImpl(store, groupId) {
|
|
82905
83092
|
const tasks2 = await store.listTasks({ includeArchived: true, slim: false });
|
|
@@ -84441,7 +84628,7 @@ function insertArtifactRowImpl(store, input, id, now, stored) {
|
|
|
84441
84628
|
}
|
|
84442
84629
|
async function getArtifactImpl(store, id) {
|
|
84443
84630
|
const layer = store.asyncLayer;
|
|
84444
|
-
return getArtifact(layer.db, id);
|
|
84631
|
+
return getArtifact(layer.db, id, layer.projectId);
|
|
84445
84632
|
}
|
|
84446
84633
|
async function updateArtifactImpl(store, id, updates) {
|
|
84447
84634
|
const layer = store.asyncLayer;
|
|
@@ -89310,6 +89497,7 @@ var init_async_archive_lineage = __esm({
|
|
|
89310
89497
|
"use strict";
|
|
89311
89498
|
init_drizzle_orm();
|
|
89312
89499
|
init_schema2();
|
|
89500
|
+
init_data_layer();
|
|
89313
89501
|
init_async_persistence();
|
|
89314
89502
|
init_async_lifecycle();
|
|
89315
89503
|
init_lineage_approval_invalidation();
|
|
@@ -92777,7 +92965,7 @@ async function _maybeAutoArchiveSameAgentDuplicateBackendImpl(store, task, input
|
|
|
92777
92965
|
}
|
|
92778
92966
|
async function updateBranchGroupImpl(store, id, patch) {
|
|
92779
92967
|
const layer = store.asyncLayer;
|
|
92780
|
-
return updateBranchGroup(layer.db, id, patch);
|
|
92968
|
+
return updateBranchGroup(layer.db, id, patch, layer.projectId);
|
|
92781
92969
|
}
|
|
92782
92970
|
async function updatePrEntityImpl(store, id, patch) {
|
|
92783
92971
|
const layer = store.asyncLayer;
|
|
@@ -93287,13 +93475,19 @@ async function deleteAttachmentArtifactRows(store, taskId, filename) {
|
|
|
93287
93475
|
const linkedArtifactIds = artifacts2.filter((artifact) => artifact.metadata?.source === "attachment" && artifact.metadata.attachmentFilename === filename).map((artifact) => artifact.id);
|
|
93288
93476
|
if (linkedArtifactIds.length === 0) return;
|
|
93289
93477
|
for (const artifactId of linkedArtifactIds) {
|
|
93290
|
-
await layer.db.delete(project_exports.artifacts).where(
|
|
93478
|
+
await layer.db.delete(project_exports.artifacts).where(and(
|
|
93479
|
+
eq(project_exports.artifacts.id, artifactId),
|
|
93480
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
93481
|
+
));
|
|
93291
93482
|
}
|
|
93292
93483
|
return;
|
|
93293
93484
|
}
|
|
93294
93485
|
async function getArtifactsForAttachmentCleanup(store, taskId) {
|
|
93295
93486
|
const layer = store.asyncLayer;
|
|
93296
|
-
const rows = await layer.db.select().from(project_exports.artifacts).where(
|
|
93487
|
+
const rows = await layer.db.select().from(project_exports.artifacts).where(and(
|
|
93488
|
+
eq(project_exports.artifacts.taskId, taskId),
|
|
93489
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
93490
|
+
));
|
|
93297
93491
|
return rows;
|
|
93298
93492
|
}
|
|
93299
93493
|
async function deleteAttachmentImpl(store, id, filename) {
|
|
@@ -95709,7 +95903,7 @@ function clearLinkedAgentTaskIdsImpl(store, taskId, updatedAt = (/* @__PURE__ */
|
|
|
95709
95903
|
`).run(updatedAt, updatedAt, taskId);
|
|
95710
95904
|
}
|
|
95711
95905
|
async function listArtifactsImpl(store, options) {
|
|
95712
|
-
return listArtifacts(store.asyncLayer.db, options);
|
|
95906
|
+
return listArtifacts(store.asyncLayer.db, options, store.asyncLayer.projectId);
|
|
95713
95907
|
}
|
|
95714
95908
|
async function rehomeOccupantImpl(store, taskId, targetColumn, reason, metadata) {
|
|
95715
95909
|
let current;
|
|
@@ -104036,7 +104230,11 @@ var init_store = __esm({
|
|
|
104036
104230
|
/** PostgreSQL-authoritative audit reader; sync fallback remains for test doubles. */
|
|
104037
104231
|
async getRunAuditEventsAsync(options = {}) {
|
|
104038
104232
|
if (this.asyncLayer) {
|
|
104039
|
-
const events = await queryRunAuditEvents(
|
|
104233
|
+
const events = await queryRunAuditEvents(
|
|
104234
|
+
this.asyncLayer.db,
|
|
104235
|
+
options,
|
|
104236
|
+
this.asyncLayer.projectId
|
|
104237
|
+
);
|
|
104040
104238
|
return events.map((event) => ({
|
|
104041
104239
|
...event,
|
|
104042
104240
|
taskId: event.taskId ?? void 0,
|
|
@@ -107614,7 +107812,9 @@ function rangeWhere(query) {
|
|
|
107614
107812
|
async function aggregatePluginActivations(dbOrLayer, query = {}) {
|
|
107615
107813
|
if ("ping" in dbOrLayer) {
|
|
107616
107814
|
const layer = dbOrLayer;
|
|
107617
|
-
const conditions = []
|
|
107815
|
+
const conditions = [projectScopeFor(project_exports.pluginActivations.projectId, layer.projectId)].filter(
|
|
107816
|
+
(condition) => condition !== void 0
|
|
107817
|
+
);
|
|
107618
107818
|
if (query.from !== void 0) conditions.push(gte(project_exports.pluginActivations.activatedAt, query.from));
|
|
107619
107819
|
if (query.to !== void 0) conditions.push(lte(project_exports.pluginActivations.activatedAt, query.to));
|
|
107620
107820
|
const where2 = conditions.length > 0 ? and(...conditions) : void 0;
|
|
@@ -107653,6 +107853,7 @@ async function aggregatePluginActivations(dbOrLayer, query = {}) {
|
|
|
107653
107853
|
var init_plugin_activation_analytics = __esm({
|
|
107654
107854
|
"../core/src/plugins/plugin-activation-analytics.ts"() {
|
|
107655
107855
|
"use strict";
|
|
107856
|
+
init_data_layer();
|
|
107656
107857
|
init_drizzle_orm();
|
|
107657
107858
|
init_schema2();
|
|
107658
107859
|
}
|
|
@@ -130650,6 +130851,18 @@ function rowToMessage2(row) {
|
|
|
130650
130851
|
createdAt: row.createdAt
|
|
130651
130852
|
};
|
|
130652
130853
|
}
|
|
130854
|
+
function chatMessageProjectConditions(handle, projectId2) {
|
|
130855
|
+
const messageScope = projectScopeFor(project_exports.chatMessages.projectId, projectId2);
|
|
130856
|
+
const sessionScope = projectScopeFor(project_exports.chatSessions.projectId, projectId2);
|
|
130857
|
+
if (!messageScope || !sessionScope) return [];
|
|
130858
|
+
return [
|
|
130859
|
+
messageScope,
|
|
130860
|
+
exists(handle.select({ id: project_exports.chatSessions.id }).from(project_exports.chatSessions).where(and(
|
|
130861
|
+
eq(project_exports.chatSessions.id, project_exports.chatMessages.sessionId),
|
|
130862
|
+
sessionScope
|
|
130863
|
+
)))
|
|
130864
|
+
];
|
|
130865
|
+
}
|
|
130653
130866
|
function rowToRoom(row) {
|
|
130654
130867
|
return {
|
|
130655
130868
|
id: row.id,
|
|
@@ -130821,7 +131034,7 @@ async function replaceChatSessionTags(layer, sessionId, projectId2, tagIds) {
|
|
|
130821
131034
|
return attachTags(tx, session);
|
|
130822
131035
|
});
|
|
130823
131036
|
}
|
|
130824
|
-
async function addChatMessage(handle, message) {
|
|
131037
|
+
async function addChatMessage(handle, message, projectId2) {
|
|
130825
131038
|
const sanitizedAttachments = message.attachments === void 0 ? void 0 : sanitizeJsonbValue(message.attachments);
|
|
130826
131039
|
const sanitized = {
|
|
130827
131040
|
...message,
|
|
@@ -130840,15 +131053,24 @@ async function addChatMessage(handle, message) {
|
|
|
130840
131053
|
attachments: sanitizedAttachments ?? null,
|
|
130841
131054
|
createdAt: sanitized.createdAt
|
|
130842
131055
|
});
|
|
130843
|
-
await handle.update(project_exports.chatSessions).set({ updatedAt: sanitized.createdAt }).where(
|
|
131056
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: sanitized.createdAt }).where(and(
|
|
131057
|
+
eq(project_exports.chatSessions.id, sanitized.sessionId),
|
|
131058
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
131059
|
+
));
|
|
130844
131060
|
return sanitized;
|
|
130845
131061
|
}
|
|
130846
|
-
async function getChatMessage(handle, id) {
|
|
130847
|
-
const rows = await handle.select().from(project_exports.chatMessages).where(
|
|
131062
|
+
async function getChatMessage(handle, id, projectId2) {
|
|
131063
|
+
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
131064
|
+
eq(project_exports.chatMessages.id, id),
|
|
131065
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131066
|
+
));
|
|
130848
131067
|
return rows[0] ? rowToMessage2(rows[0]) : void 0;
|
|
130849
131068
|
}
|
|
130850
|
-
async function getChatMessages(handle, sessionId, filter2) {
|
|
130851
|
-
const conditions = [
|
|
131069
|
+
async function getChatMessages(handle, sessionId, filter2, projectId2) {
|
|
131070
|
+
const conditions = [
|
|
131071
|
+
eq(project_exports.chatMessages.sessionId, sessionId),
|
|
131072
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131073
|
+
];
|
|
130852
131074
|
if (filter2?.before) {
|
|
130853
131075
|
conditions.push(lte(project_exports.chatMessages.createdAt, filter2.before));
|
|
130854
131076
|
}
|
|
@@ -130858,9 +131080,12 @@ async function getChatMessages(handle, sessionId, filter2) {
|
|
|
130858
131080
|
const rows = await handle.select().from(project_exports.chatMessages).where(and(...conditions)).orderBy(filter2?.order === "desc" ? desc(orderCol) : asc(orderCol)).limit(limit2).offset(offset);
|
|
130859
131081
|
return rows.map(rowToMessage2);
|
|
130860
131082
|
}
|
|
130861
|
-
async function getLastMessageForSessions(handle, sessionIds) {
|
|
131083
|
+
async function getLastMessageForSessions(handle, sessionIds, projectId2) {
|
|
130862
131084
|
if (sessionIds.length === 0) return /* @__PURE__ */ new Map();
|
|
130863
|
-
const rows = await handle.select().from(project_exports.chatMessages).where(
|
|
131085
|
+
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
131086
|
+
inArray(project_exports.chatMessages.sessionId, sessionIds),
|
|
131087
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131088
|
+
)).orderBy(
|
|
130864
131089
|
desc(project_exports.chatMessages.createdAt),
|
|
130865
131090
|
desc(project_exports.chatMessages.id)
|
|
130866
131091
|
);
|
|
@@ -131026,8 +131251,8 @@ async function setInFlightGeneration(handle, id, inFlightGeneration) {
|
|
|
131026
131251
|
await handle.update(project_exports.chatSessions).set({ inFlightGeneration: sanitizedInFlightGeneration }).where(eq(project_exports.chatSessions.id, id));
|
|
131027
131252
|
return getChatSession(handle, id);
|
|
131028
131253
|
}
|
|
131029
|
-
async function addChatMessageAttachment(handle, sessionId, messageId, attachment) {
|
|
131030
|
-
const message = await getChatMessage(handle, messageId);
|
|
131254
|
+
async function addChatMessageAttachment(handle, sessionId, messageId, attachment, projectId2) {
|
|
131255
|
+
const message = await getChatMessage(handle, messageId, projectId2);
|
|
131031
131256
|
if (!message || message.sessionId !== sessionId) {
|
|
131032
131257
|
throw new Error(`Message ${messageId} not found in session ${sessionId}`);
|
|
131033
131258
|
}
|
|
@@ -131035,25 +131260,35 @@ async function addChatMessageAttachment(handle, sessionId, messageId, attachment
|
|
|
131035
131260
|
...message.attachments ?? [],
|
|
131036
131261
|
attachment
|
|
131037
131262
|
]);
|
|
131038
|
-
await handle.update(project_exports.chatMessages).set({ attachments: updatedAttachments }).where(
|
|
131039
|
-
|
|
131263
|
+
await handle.update(project_exports.chatMessages).set({ attachments: updatedAttachments }).where(and(
|
|
131264
|
+
eq(project_exports.chatMessages.id, messageId),
|
|
131265
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131266
|
+
));
|
|
131267
|
+
const updated = await getChatMessage(handle, messageId, projectId2);
|
|
131040
131268
|
if (!updated) throw new Error(`Failed to update message ${messageId}`);
|
|
131041
131269
|
return updated;
|
|
131042
131270
|
}
|
|
131043
|
-
async function deleteChatMessage(handle, id) {
|
|
131044
|
-
const existing = await getChatMessage(handle, id);
|
|
131271
|
+
async function deleteChatMessage(handle, id, projectId2) {
|
|
131272
|
+
const existing = await getChatMessage(handle, id, projectId2);
|
|
131045
131273
|
if (!existing) return false;
|
|
131046
|
-
await handle.delete(project_exports.chatMessages).where(
|
|
131047
|
-
|
|
131274
|
+
await handle.delete(project_exports.chatMessages).where(and(
|
|
131275
|
+
eq(project_exports.chatMessages.id, id),
|
|
131276
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131277
|
+
));
|
|
131278
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(
|
|
131279
|
+
eq(project_exports.chatSessions.id, existing.sessionId),
|
|
131280
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
131281
|
+
));
|
|
131048
131282
|
return true;
|
|
131049
131283
|
}
|
|
131050
|
-
async function searchChatSessionsByMessageContent(handle, query, sessionIds) {
|
|
131284
|
+
async function searchChatSessionsByMessageContent(handle, query, sessionIds, projectId2) {
|
|
131051
131285
|
const trimmed = query.trim();
|
|
131052
131286
|
if (!trimmed || sessionIds.length === 0) return /* @__PURE__ */ new Map();
|
|
131053
131287
|
const escaped = trimmed.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
131054
131288
|
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
131055
131289
|
inArray(project_exports.chatMessages.sessionId, sessionIds),
|
|
131056
|
-
ilike(project_exports.chatMessages.content, `%${escaped}%`)
|
|
131290
|
+
ilike(project_exports.chatMessages.content, `%${escaped}%`),
|
|
131291
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131057
131292
|
)).orderBy(
|
|
131058
131293
|
desc(project_exports.chatMessages.createdAt),
|
|
131059
131294
|
desc(project_exports.chatMessages.id)
|
|
@@ -131067,13 +131302,16 @@ async function searchChatSessionsByMessageContent(handle, query, sessionIds) {
|
|
|
131067
131302
|
}
|
|
131068
131303
|
return result2;
|
|
131069
131304
|
}
|
|
131070
|
-
async function deleteChatMessagesFrom(handle, sessionId, fromMessageId) {
|
|
131071
|
-
const orderedRows = await handle.select().from(project_exports.chatMessages).where(
|
|
131305
|
+
async function deleteChatMessagesFrom(handle, sessionId, fromMessageId, projectId2) {
|
|
131306
|
+
const orderedRows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
131307
|
+
eq(project_exports.chatMessages.sessionId, sessionId),
|
|
131308
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131309
|
+
)).orderBy(
|
|
131072
131310
|
asc(project_exports.chatMessages.createdAt),
|
|
131073
131311
|
asc(project_exports.chatMessages.id)
|
|
131074
131312
|
);
|
|
131075
131313
|
const ordered2 = orderedRows.map(rowToMessage2);
|
|
131076
|
-
const target = await getChatMessage(handle, fromMessageId);
|
|
131314
|
+
const target = await getChatMessage(handle, fromMessageId, projectId2);
|
|
131077
131315
|
if (!target || target.sessionId !== sessionId) {
|
|
131078
131316
|
return { deletedIds: [], retained: ordered2 };
|
|
131079
131317
|
}
|
|
@@ -131086,19 +131324,28 @@ async function deleteChatMessagesFrom(handle, sessionId, fromMessageId) {
|
|
|
131086
131324
|
if (deletedIds.length === 0) {
|
|
131087
131325
|
return { deletedIds: [], retained };
|
|
131088
131326
|
}
|
|
131089
|
-
await handle.delete(project_exports.chatMessages).where(
|
|
131090
|
-
|
|
131327
|
+
await handle.delete(project_exports.chatMessages).where(and(
|
|
131328
|
+
inArray(project_exports.chatMessages.id, deletedIds),
|
|
131329
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131330
|
+
));
|
|
131331
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(
|
|
131332
|
+
eq(project_exports.chatSessions.id, sessionId),
|
|
131333
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
131334
|
+
));
|
|
131091
131335
|
return { deletedIds, retained };
|
|
131092
131336
|
}
|
|
131093
|
-
async function updateChatMessageMetadata(handle, messageId, metadata, options) {
|
|
131094
|
-
const existing = await getChatMessage(handle, messageId);
|
|
131337
|
+
async function updateChatMessageMetadata(handle, messageId, metadata, options, projectId2) {
|
|
131338
|
+
const existing = await getChatMessage(handle, messageId, projectId2);
|
|
131095
131339
|
if (!existing) {
|
|
131096
131340
|
throw new Error(`Message ${messageId} not found`);
|
|
131097
131341
|
}
|
|
131098
131342
|
const merge2 = options?.merge !== false;
|
|
131099
131343
|
const nextMetadata = metadata === null ? merge2 ? existing.metadata : null : merge2 ? { ...existing.metadata ?? {}, ...metadata } : metadata;
|
|
131100
|
-
await handle.update(project_exports.chatMessages).set({ metadata: sanitizeJsonbValue(nextMetadata) ?? null }).where(
|
|
131101
|
-
|
|
131344
|
+
await handle.update(project_exports.chatMessages).set({ metadata: sanitizeJsonbValue(nextMetadata) ?? null }).where(and(
|
|
131345
|
+
eq(project_exports.chatMessages.id, messageId),
|
|
131346
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131347
|
+
));
|
|
131348
|
+
const updated = await getChatMessage(handle, messageId, projectId2);
|
|
131102
131349
|
if (!updated) {
|
|
131103
131350
|
throw new Error(`Failed to update message ${messageId}`);
|
|
131104
131351
|
}
|
|
@@ -131480,7 +131727,7 @@ var init_chat_store = __esm({
|
|
|
131480
131727
|
attachments: input.attachments,
|
|
131481
131728
|
createdAt: now
|
|
131482
131729
|
};
|
|
131483
|
-
const created = await addChatMessage(this.asyncLayer.db, message);
|
|
131730
|
+
const created = await addChatMessage(this.asyncLayer.db, message, this.asyncLayer.projectId);
|
|
131484
131731
|
this.emit("chat:message:added", created);
|
|
131485
131732
|
return created;
|
|
131486
131733
|
}
|
|
@@ -131488,7 +131735,7 @@ var init_chat_store = __esm({
|
|
|
131488
131735
|
* Append a file attachment metadata record to an existing message.
|
|
131489
131736
|
*/
|
|
131490
131737
|
async addMessageAttachment(sessionId, messageId, attachment) {
|
|
131491
|
-
const updated = await addChatMessageAttachment(this.asyncLayer.db, sessionId, messageId, attachment);
|
|
131738
|
+
const updated = await addChatMessageAttachment(this.asyncLayer.db, sessionId, messageId, attachment, this.asyncLayer.projectId);
|
|
131492
131739
|
this.emit("chat:message:updated", updated);
|
|
131493
131740
|
return updated;
|
|
131494
131741
|
}
|
|
@@ -131500,7 +131747,7 @@ var init_chat_store = __esm({
|
|
|
131500
131747
|
* @returns Array of messages ordered by createdAt ASC (default) or DESC
|
|
131501
131748
|
*/
|
|
131502
131749
|
async getMessages(sessionId, filter2) {
|
|
131503
|
-
return getChatMessages(this.asyncLayer.db, sessionId, filter2);
|
|
131750
|
+
return getChatMessages(this.asyncLayer.db, sessionId, filter2, this.asyncLayer.projectId);
|
|
131504
131751
|
}
|
|
131505
131752
|
/**
|
|
131506
131753
|
* Get a message by ID.
|
|
@@ -131509,7 +131756,7 @@ var init_chat_store = __esm({
|
|
|
131509
131756
|
* @returns The message, or undefined if not found
|
|
131510
131757
|
*/
|
|
131511
131758
|
async getMessage(id) {
|
|
131512
|
-
return getChatMessage(this.asyncLayer.db, id);
|
|
131759
|
+
return getChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131513
131760
|
}
|
|
131514
131761
|
/**
|
|
131515
131762
|
* Get the latest message for each session in the provided list.
|
|
@@ -131519,10 +131766,10 @@ var init_chat_store = __esm({
|
|
|
131519
131766
|
* @returns Map of sessionId -> latest ChatMessage for that session
|
|
131520
131767
|
*/
|
|
131521
131768
|
async getLastMessageForSessions(sessionIds) {
|
|
131522
|
-
return getLastMessageForSessions(this.asyncLayer.db, sessionIds);
|
|
131769
|
+
return getLastMessageForSessions(this.asyncLayer.db, sessionIds, this.asyncLayer.projectId);
|
|
131523
131770
|
}
|
|
131524
131771
|
async hasMessages(sessionId) {
|
|
131525
|
-
return (await getChatMessages(this.asyncLayer.db, sessionId, { limit: 1 })).length > 0;
|
|
131772
|
+
return (await getChatMessages(this.asyncLayer.db, sessionId, { limit: 1 }, this.asyncLayer.projectId)).length > 0;
|
|
131526
131773
|
}
|
|
131527
131774
|
/**
|
|
131528
131775
|
* Search sessions by message content (not just title/agentId).
|
|
@@ -131550,7 +131797,7 @@ var init_chat_store = __esm({
|
|
|
131550
131797
|
if (!trimmed || !sessionIds || sessionIds.length === 0) {
|
|
131551
131798
|
return /* @__PURE__ */ new Map();
|
|
131552
131799
|
}
|
|
131553
|
-
return searchChatSessionsByMessageContent(this.asyncLayer.db, trimmed, sessionIds);
|
|
131800
|
+
return searchChatSessionsByMessageContent(this.asyncLayer.db, trimmed, sessionIds, this.asyncLayer.projectId);
|
|
131554
131801
|
}
|
|
131555
131802
|
/**
|
|
131556
131803
|
* Delete a message by ID.
|
|
@@ -131559,9 +131806,9 @@ var init_chat_store = __esm({
|
|
|
131559
131806
|
* @returns true if deleted, false if not found
|
|
131560
131807
|
*/
|
|
131561
131808
|
async deleteMessage(id) {
|
|
131562
|
-
const existing = await getChatMessage(this.asyncLayer.db, id);
|
|
131809
|
+
const existing = await getChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131563
131810
|
if (!existing) return false;
|
|
131564
|
-
const deleted = await deleteChatMessage(this.asyncLayer.db, id);
|
|
131811
|
+
const deleted = await deleteChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131565
131812
|
if (deleted) {
|
|
131566
131813
|
this.emit("chat:message:deleted", id);
|
|
131567
131814
|
const updatedSession = await this.getSession(existing.sessionId);
|
|
@@ -131584,7 +131831,7 @@ var init_chat_store = __esm({
|
|
|
131584
131831
|
* @returns deletedIds (in ASC order) and retained messages (pre-edit history, ASC order)
|
|
131585
131832
|
*/
|
|
131586
131833
|
async deleteMessagesFrom(sessionId, fromMessageId) {
|
|
131587
|
-
const result2 = await deleteChatMessagesFrom(this.asyncLayer.db, sessionId, fromMessageId);
|
|
131834
|
+
const result2 = await deleteChatMessagesFrom(this.asyncLayer.db, sessionId, fromMessageId, this.asyncLayer.projectId);
|
|
131588
131835
|
if (result2.deletedIds.length > 0) {
|
|
131589
131836
|
for (const id of result2.deletedIds) {
|
|
131590
131837
|
this.emit("chat:message:deleted", id);
|
|
@@ -131602,7 +131849,7 @@ var init_chat_store = __esm({
|
|
|
131602
131849
|
* is what lets a later edit rewind losslessly via SessionManager.branch()/resetLeaf().
|
|
131603
131850
|
*/
|
|
131604
131851
|
async updateMessageMetadata(messageId, metadata, options) {
|
|
131605
|
-
const updated = await updateChatMessageMetadata(this.asyncLayer.db, messageId, metadata, options);
|
|
131852
|
+
const updated = await updateChatMessageMetadata(this.asyncLayer.db, messageId, metadata, options, this.asyncLayer.projectId);
|
|
131606
131853
|
this.emit("chat:message:updated", updated);
|
|
131607
131854
|
return updated;
|
|
131608
131855
|
}
|
|
@@ -136817,7 +137064,13 @@ var init_gating_classifications = __esm({
|
|
|
136817
137064
|
"fn_post_room_message",
|
|
136818
137065
|
"fn_update_identity",
|
|
136819
137066
|
"fn_reflect_on_performance",
|
|
136820
|
-
|
|
137067
|
+
/*
|
|
137068
|
+
FNXC:ToolGovernance 2026-08-12-22:11:
|
|
137069
|
+
fn_agent_read_evaluations is a subtree-scoped read. Authorization is enforced by
|
|
137070
|
+
the extension tool's getChainOfCommand boundary, not by this action classifier.
|
|
137071
|
+
*/
|
|
137072
|
+
"fn_read_evaluations",
|
|
137073
|
+
"fn_agent_read_evaluations"
|
|
136821
137074
|
]);
|
|
136822
137075
|
COORDINATION_EXEMPT_TOOLS = [
|
|
136823
137076
|
"read",
|
|
@@ -136877,6 +137130,8 @@ var init_gating_classifications = __esm({
|
|
|
136877
137130
|
"fn_post_room_message",
|
|
136878
137131
|
"fn_memory_append",
|
|
136879
137132
|
"fn_read_evaluations",
|
|
137133
|
+
// FNXC:ToolGovernance 2026-08-12-22:11: The manager read is subtree-authorized in extension.ts; follow-up remains absent so it falls back to task_agent_mutation policy.
|
|
137134
|
+
"fn_agent_read_evaluations",
|
|
136880
137135
|
"fn_update_identity",
|
|
136881
137136
|
"fn_reflect_on_performance"
|
|
136882
137137
|
];
|
|
@@ -178866,32 +179121,36 @@ var init_scheduler = __esm({
|
|
|
178866
179121
|
const hierarchy = await missionStore.getMissionWithHierarchy(mission.id);
|
|
178867
179122
|
if (!hierarchy) continue;
|
|
178868
179123
|
for (const slice of hierarchy.milestones.flatMap((milestone) => milestone.slices).filter((slice2) => slice2.status === "active")) {
|
|
178869
|
-
|
|
178870
|
-
|
|
178871
|
-
|
|
178872
|
-
|
|
178873
|
-
|
|
178874
|
-
|
|
178875
|
-
|
|
179124
|
+
try {
|
|
179125
|
+
const superseded = await missionStore.reconcileSupersededGeneratedFixFeatures(slice.id);
|
|
179126
|
+
fixed += superseded.supersededCount;
|
|
179127
|
+
if (superseded.supersededCount > 0) {
|
|
179128
|
+
const refreshed = await missionStore.getSlice(slice.id);
|
|
179129
|
+
if (refreshed?.status === "complete") {
|
|
179130
|
+
await this.onSliceComplete(refreshed);
|
|
179131
|
+
continue;
|
|
179132
|
+
}
|
|
178876
179133
|
}
|
|
178877
|
-
|
|
178878
|
-
|
|
178879
|
-
|
|
178880
|
-
|
|
178881
|
-
|
|
178882
|
-
|
|
178883
|
-
|
|
178884
|
-
|
|
178885
|
-
|
|
179134
|
+
const listFeatures2 = missionStore.listFeatures;
|
|
179135
|
+
const features = listFeatures2 ? await listFeatures2.call(missionStore, slice.id) : slice.features;
|
|
179136
|
+
const supersededFeatureIds = new Set(superseded.featureIds ?? []);
|
|
179137
|
+
const autoTriage = mission.autopilotEnabled === true || mission.autoAdvance === true;
|
|
179138
|
+
for (const feature of features) {
|
|
179139
|
+
if (supersededFeatureIds.has(feature.id) || feature.taskId || !autoTriage || feature.status === "blocked") continue;
|
|
179140
|
+
if (feature.status !== "defined" && this.isGeneratedFixFeature(feature)) {
|
|
179141
|
+
await missionStore.updateFeature(feature.id, { status: "blocked", loopState: "blocked", taskId: void 0 });
|
|
179142
|
+
fixed++;
|
|
179143
|
+
continue;
|
|
179144
|
+
}
|
|
179145
|
+
if (feature.status !== "defined" && feature.status !== "triaged" && feature.status !== "in-progress") continue;
|
|
179146
|
+
const ready = feature.status === "defined" ? feature : await missionStore.updateFeature(feature.id, { status: "defined", loopState: "idle", taskId: void 0 });
|
|
179147
|
+
if (ready !== feature) fixed++;
|
|
179148
|
+
const triaged = await missionStore.triageFeature(ready.id);
|
|
178886
179149
|
fixed++;
|
|
178887
|
-
|
|
179150
|
+
if (triaged.taskId) await this.emitStrandedFeatureTriageAudit(mission.id, slice.id, triaged.id, triaged.taskId);
|
|
178888
179151
|
}
|
|
178889
|
-
|
|
178890
|
-
|
|
178891
|
-
if (ready !== feature) fixed++;
|
|
178892
|
-
const triaged = await missionStore.triageFeature(ready.id);
|
|
178893
|
-
fixed++;
|
|
178894
|
-
if (triaged.taskId) await this.emitStrandedFeatureTriageAudit(mission.id, slice.id, triaged.id, triaged.taskId);
|
|
179152
|
+
} catch (error3) {
|
|
179153
|
+
schedulerLog.error(`Error during active mission recovery reconciliation for slice ${slice.id}:`, error3);
|
|
178895
179154
|
}
|
|
178896
179155
|
}
|
|
178897
179156
|
}
|
|
@@ -293422,6 +293681,13 @@ function sseDebug(message) {
|
|
|
293422
293681
|
if (!isSseDebugEnabled()) return;
|
|
293423
293682
|
sseLog.debug(message);
|
|
293424
293683
|
}
|
|
293684
|
+
function resolveAgentActivityPollMs() {
|
|
293685
|
+
const raw = process.env.FUSION_AGENT_ACTIVITY_POLL_MS?.trim();
|
|
293686
|
+
if (!raw) return 2e3;
|
|
293687
|
+
const parsed = Number(raw);
|
|
293688
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return 2e3;
|
|
293689
|
+
return Math.max(10, Math.floor(parsed));
|
|
293690
|
+
}
|
|
293425
293691
|
function normalizeSSEClientId(value2) {
|
|
293426
293692
|
const raw = Array.isArray(value2) ? value2[0] : value2;
|
|
293427
293693
|
if (typeof raw !== "string") return void 0;
|
|
@@ -293729,7 +293995,7 @@ data: ${JSON.stringify(payload)}
|
|
|
293729
293995
|
}
|
|
293730
293996
|
void drainAgentActivity();
|
|
293731
293997
|
};
|
|
293732
|
-
const agentActivityPoll = setInterval(onAgentActivityNudge,
|
|
293998
|
+
const agentActivityPoll = setInterval(onAgentActivityNudge, resolveAgentActivityPollMs());
|
|
293733
293999
|
agentActivityPoll.unref?.();
|
|
293734
294000
|
const onCreated = (task) => {
|
|
293735
294001
|
send(`event: task:created
|
|
@@ -326179,6 +326445,7 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326179
326445
|
limit: parseInt(req.query.limit) || 20,
|
|
326180
326446
|
offset: parseInt(req.query.offset) || 0,
|
|
326181
326447
|
read: req.query.unreadOnly === "true" ? false : void 0,
|
|
326448
|
+
archived: req.query.archived === "true",
|
|
326182
326449
|
type: req.query.type
|
|
326183
326450
|
};
|
|
326184
326451
|
const messages3 = await msgStore.getInbox(DASHBOARD_USER_ID, "user", filter2);
|
|
@@ -326197,6 +326464,7 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326197
326464
|
const filter2 = {
|
|
326198
326465
|
limit: parseInt(req.query.limit) || 20,
|
|
326199
326466
|
offset: parseInt(req.query.offset) || 0,
|
|
326467
|
+
archived: req.query.archived === "true",
|
|
326200
326468
|
type: req.query.type
|
|
326201
326469
|
};
|
|
326202
326470
|
const messages3 = await msgStore.getOutbox(DASHBOARD_USER_ID, "user", filter2);
|
|
@@ -326313,7 +326581,8 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326313
326581
|
const msgStore = await getMessageStore(req);
|
|
326314
326582
|
const messages3 = await msgStore.getConversation(
|
|
326315
326583
|
{ id: DASHBOARD_USER_ID, type: "user" },
|
|
326316
|
-
{ id: participantId, type: participantType }
|
|
326584
|
+
{ id: participantId, type: participantType },
|
|
326585
|
+
{ archived: req.query.archived === "true" }
|
|
326317
326586
|
);
|
|
326318
326587
|
res.json(messages3);
|
|
326319
326588
|
} catch (err) {
|
|
@@ -326405,6 +326674,26 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326405
326674
|
rethrowAsApiError8(err);
|
|
326406
326675
|
}
|
|
326407
326676
|
});
|
|
326677
|
+
router.post("/messages/:id/archive", async (req, res) => {
|
|
326678
|
+
try {
|
|
326679
|
+
const message = await (await getMessageStore(req)).archiveMessage(req.params.id);
|
|
326680
|
+
res.json(message);
|
|
326681
|
+
} catch (err) {
|
|
326682
|
+
if (err instanceof ApiError) throw err;
|
|
326683
|
+
if ((err instanceof Error ? err.message : String(err)).includes("not found")) throw notFound(err instanceof Error ? err.message : String(err));
|
|
326684
|
+
rethrowAsApiError8(err);
|
|
326685
|
+
}
|
|
326686
|
+
});
|
|
326687
|
+
router.post("/messages/:id/unarchive", async (req, res) => {
|
|
326688
|
+
try {
|
|
326689
|
+
const message = await (await getMessageStore(req)).unarchiveMessage(req.params.id);
|
|
326690
|
+
res.json(message);
|
|
326691
|
+
} catch (err) {
|
|
326692
|
+
if (err instanceof ApiError) throw err;
|
|
326693
|
+
if ((err instanceof Error ? err.message : String(err)).includes("not found")) throw notFound(err instanceof Error ? err.message : String(err));
|
|
326694
|
+
rethrowAsApiError8(err);
|
|
326695
|
+
}
|
|
326696
|
+
});
|
|
326408
326697
|
router.post("/messages/:id/read", async (req, res) => {
|
|
326409
326698
|
try {
|
|
326410
326699
|
const msgStore = await getMessageStore(req);
|
|
@@ -326438,7 +326727,7 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326438
326727
|
router.get("/agents/mailbox/all", async (req, res) => {
|
|
326439
326728
|
try {
|
|
326440
326729
|
const msgStore = await getMessageStore(req);
|
|
326441
|
-
const messages3 = await msgStore.getAllAgentToAgentMessages();
|
|
326730
|
+
const messages3 = await msgStore.getAllAgentToAgentMessages({ archived: req.query.archived === "true" });
|
|
326442
326731
|
const unreadCount = await msgStore.getUnreadAgentToAgentCount();
|
|
326443
326732
|
res.json({ messages: messages3, total: messages3.length, unreadCount });
|
|
326444
326733
|
} catch (err) {
|
|
@@ -326453,8 +326742,9 @@ function registerMessagingScriptRoutes(ctx) {
|
|
|
326453
326742
|
const msgStore = await getMessageStore(req);
|
|
326454
326743
|
const agentId = req.params.id;
|
|
326455
326744
|
const mailbox = await msgStore.getMailbox(agentId, "agent");
|
|
326456
|
-
const
|
|
326457
|
-
const
|
|
326745
|
+
const archived = req.query.archived === "true";
|
|
326746
|
+
const inbox = await msgStore.getInbox(agentId, "agent", { archived });
|
|
326747
|
+
const outbox = await msgStore.getOutbox(agentId, "agent", { archived });
|
|
326458
326748
|
res.json({ ...mailbox, messages: inbox, inbox, outbox });
|
|
326459
326749
|
} catch (err) {
|
|
326460
326750
|
if (err instanceof ApiError) {
|
|
@@ -400841,7 +401131,7 @@ data: ${JSON.stringify({ type: event.type, data: event.data })}
|
|
|
400841
401131
|
const endIso = new Date(nowMs).toISOString();
|
|
400842
401132
|
const auditFilter = { startTime: startIso, endTime: endIso, limit: 5e4 };
|
|
400843
401133
|
const asyncLayer = scopedStore.getAsyncLayer();
|
|
400844
|
-
const runAuditEventsPromise = asyncLayer ? queryRunAuditEvents(asyncLayer.db, auditFilter).then((events) => events.map((event) => ({
|
|
401134
|
+
const runAuditEventsPromise = asyncLayer ? queryRunAuditEvents(asyncLayer.db, auditFilter, asyncLayer.projectId).then((events) => events.map((event) => ({
|
|
400845
401135
|
...event,
|
|
400846
401136
|
domain: event.domain,
|
|
400847
401137
|
mutationType: event.mutationType,
|