@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/extension.js
CHANGED
|
@@ -21639,9 +21639,14 @@ var init_project = __esm({
|
|
|
21639
21639
|
// now keyed per-project on `project_id` (the effective PK). `id` is retained
|
|
21640
21640
|
// for column-shape parity (always 1) but is no longer the PK and no longer
|
|
21641
21641
|
// CHECK-constrained. Single-project / SQLite-parity callers leave project_id
|
|
21642
|
-
//
|
|
21642
|
+
// through the database ownership trigger, preserving the pre-isolation behavior.
|
|
21643
|
+
/*
|
|
21644
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
21645
|
+
Migration 0006 owns config's project_id default and leaves its catalog PK as (project_id).
|
|
21646
|
+
Drizzle emits DEFAULT while the database GUC/trigger selects the effective ownership partition.
|
|
21647
|
+
*/
|
|
21643
21648
|
id: integer("id").default(1),
|
|
21644
|
-
projectId: text("project_id").notNull().default(
|
|
21649
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`).primaryKey(),
|
|
21645
21650
|
nextId: integer("next_id").default(1),
|
|
21646
21651
|
nextWorkflowStepId: integer("next_workflow_step_id").default(1),
|
|
21647
21652
|
// FNXC:SqliteFinalRemoval 2026-06-28:
|
|
@@ -22035,9 +22040,13 @@ var init_project = __esm({
|
|
|
22035
22040
|
automations = projectSchema.table("automations", {
|
|
22036
22041
|
/*
|
|
22037
22042
|
* FNXC:AutomationIsolation 2026-07-13-22:37:
|
|
22038
|
-
* 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.
|
|
22043
|
+
* 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.
|
|
22044
|
+
*
|
|
22045
|
+
* FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
22046
|
+
* Migration 0006 owns the default through the database GUC/trigger; Drizzle emits DEFAULT
|
|
22047
|
+
* without replacing the physical legacy fallback or the fail-closed bound writer contract.
|
|
22039
22048
|
*/
|
|
22040
|
-
projectId: text("project_id").notNull().default(
|
|
22049
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22041
22050
|
id: text("id").notNull(),
|
|
22042
22051
|
name: text("name").notNull(),
|
|
22043
22052
|
description: text("description"),
|
|
@@ -22336,7 +22345,8 @@ var init_project = __esm({
|
|
|
22336
22345
|
index("idxTaskDocumentsTaskId").on(t.taskId)
|
|
22337
22346
|
]);
|
|
22338
22347
|
artifacts = projectSchema.table("artifacts", {
|
|
22339
|
-
|
|
22348
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22349
|
+
id: text("id").notNull(),
|
|
22340
22350
|
type: text("type").notNull(),
|
|
22341
22351
|
title: text("title").notNull(),
|
|
22342
22352
|
description: text("description"),
|
|
@@ -22351,7 +22361,8 @@ var init_project = __esm({
|
|
|
22351
22361
|
createdAt: text("created_at").notNull(),
|
|
22352
22362
|
updatedAt: text("updated_at").notNull()
|
|
22353
22363
|
}, (t) => [
|
|
22354
|
-
|
|
22364
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22365
|
+
foreignKey({ name: "artifacts_task_id_fkey", columns: [t.projectId, t.taskId], foreignColumns: [tasks.projectId, tasks.id] }).onDelete("cascade"),
|
|
22355
22366
|
index("idxArtifactsTaskId").on(t.taskId),
|
|
22356
22367
|
index("idxArtifactsAuthorId").on(t.authorId),
|
|
22357
22368
|
index("idxArtifactsType").on(t.type),
|
|
@@ -22541,7 +22552,8 @@ var init_project = __esm({
|
|
|
22541
22552
|
index("idxEvalRunEventsRunIdSeq").on(t.runId, t.seq)
|
|
22542
22553
|
]);
|
|
22543
22554
|
secrets = projectSchema.table("secrets", {
|
|
22544
|
-
|
|
22555
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22556
|
+
id: text("id").notNull(),
|
|
22545
22557
|
key: text("key").notNull(),
|
|
22546
22558
|
valueCiphertext: bytea("value_ciphertext").notNull(),
|
|
22547
22559
|
nonce: bytea("nonce").notNull(),
|
|
@@ -22554,7 +22566,8 @@ var init_project = __esm({
|
|
|
22554
22566
|
lastReadAt: text("last_read_at"),
|
|
22555
22567
|
lastReadBy: text("last_read_by")
|
|
22556
22568
|
}, (t) => [
|
|
22557
|
-
|
|
22569
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22570
|
+
unique("secrets_key_unique").on(t.projectId, t.key),
|
|
22558
22571
|
check("secrets_access_policy_check", sql`${t.accessPolicy} IN ('auto', 'prompt', 'deny')`),
|
|
22559
22572
|
check("secrets_env_exportable_check", sql`${t.envExportable} IN (0, 1)`)
|
|
22560
22573
|
]);
|
|
@@ -22596,10 +22609,11 @@ var init_project = __esm({
|
|
|
22596
22609
|
updatedAt: text("updated_at").notNull()
|
|
22597
22610
|
}, (t) => [primaryKey({ columns: [t.projectId, t.id] })]);
|
|
22598
22611
|
branchGroups = projectSchema.table("branch_groups", {
|
|
22599
|
-
|
|
22612
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
22613
|
+
id: text("id").notNull(),
|
|
22600
22614
|
sourceType: text("source_type").notNull(),
|
|
22601
22615
|
sourceId: text("source_id").notNull(),
|
|
22602
|
-
branchName: text("branch_name").notNull()
|
|
22616
|
+
branchName: text("branch_name").notNull(),
|
|
22603
22617
|
worktreePath: text("worktree_path"),
|
|
22604
22618
|
autoMerge: integer("auto_merge").notNull().default(0),
|
|
22605
22619
|
prState: text("pr_state").notNull().default("none"),
|
|
@@ -22615,6 +22629,8 @@ var init_project = __esm({
|
|
|
22615
22629
|
updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
|
|
22616
22630
|
closedAt: bigint("closed_at", { mode: "number" })
|
|
22617
22631
|
}, (t) => [
|
|
22632
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
22633
|
+
unique("branch_groups_branch_name_key").on(t.projectId, t.branchName),
|
|
22618
22634
|
check("branch_groups_source_type_check", sql`${t.sourceType} IN ('mission','planning','new-task')`),
|
|
22619
22635
|
check("branch_groups_pr_state_check", sql`${t.prState} IN ('none','open','merged','closed')`),
|
|
22620
22636
|
check("branch_groups_status_check", sql`${t.status} IN ('open','finalized','abandoned')`),
|
|
@@ -23016,12 +23032,14 @@ var init_project = __esm({
|
|
|
23016
23032
|
index("idxUsageEventsKindTs").on(t.kind, t.ts)
|
|
23017
23033
|
]);
|
|
23018
23034
|
pluginActivations = projectSchema.table("plugin_activations", {
|
|
23019
|
-
|
|
23035
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23036
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23020
23037
|
pluginId: text("plugin_id").notNull(),
|
|
23021
23038
|
source: text("source").notNull(),
|
|
23022
23039
|
pluginVersion: text("plugin_version"),
|
|
23023
23040
|
activatedAt: text("activated_at").notNull()
|
|
23024
23041
|
}, (t) => [
|
|
23042
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23025
23043
|
index("idxPluginActivationsActivatedAt").on(t.activatedAt),
|
|
23026
23044
|
index("idxPluginActivationsPluginId").on(t.pluginId)
|
|
23027
23045
|
]);
|
|
@@ -23046,8 +23064,13 @@ var init_project = __esm({
|
|
|
23046
23064
|
index("idxKnowledgePagesUpdatedAt").on(t.updatedAt)
|
|
23047
23065
|
]);
|
|
23048
23066
|
deployments = projectSchema.table("deployments", {
|
|
23049
|
-
id: integer("id").generatedAlwaysAsIdentity().
|
|
23050
|
-
|
|
23067
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23068
|
+
/*
|
|
23069
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23070
|
+
Migration 0006 rebuilt deployments_pkey as (project_id, id). Drizzle emits DEFAULT while the
|
|
23071
|
+
database GUC/trigger keeps ownership stamping and the physical legacy fallback authoritative.
|
|
23072
|
+
*/
|
|
23073
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23051
23074
|
deploymentId: text("deployment_id").notNull(),
|
|
23052
23075
|
service: text("service"),
|
|
23053
23076
|
environment: text("environment"),
|
|
@@ -23058,6 +23081,7 @@ var init_project = __esm({
|
|
|
23058
23081
|
meta: jsonb("meta"),
|
|
23059
23082
|
createdAt: text("created_at").notNull()
|
|
23060
23083
|
}, (t) => [
|
|
23084
|
+
primaryKey({ columns: [t.projectId, t.id], name: "deployments_pkey" }),
|
|
23061
23085
|
uniqueIndex("idxDeploymentsProjectDeploymentId").on(t.projectId, t.deploymentId),
|
|
23062
23086
|
index("idxDeploymentsProjectDeployedAt").on(t.projectId, t.deployedAt),
|
|
23063
23087
|
index("idxDeploymentsDeployedAt").on(t.deployedAt),
|
|
@@ -23065,7 +23089,12 @@ var init_project = __esm({
|
|
|
23065
23089
|
]);
|
|
23066
23090
|
githubCheckStates = projectSchema.table("github_check_states", {
|
|
23067
23091
|
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23068
|
-
|
|
23092
|
+
/*
|
|
23093
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23094
|
+
Migration 0048 post-dated 0006, so FN-9004 reconciles its physical default to the ownership
|
|
23095
|
+
expression. Drizzle emits DEFAULT while the database GUC/trigger remains the stamping authority.
|
|
23096
|
+
*/
|
|
23097
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23069
23098
|
repo: text("repo").notNull(),
|
|
23070
23099
|
headSha: text("head_sha").notNull(),
|
|
23071
23100
|
checkName: text("check_name").notNull(),
|
|
@@ -23085,9 +23114,14 @@ var init_project = __esm({
|
|
|
23085
23114
|
index("idxGithubCheckStatesProjectReceived").on(t.projectId, t.receivedAt)
|
|
23086
23115
|
]);
|
|
23087
23116
|
incidents = projectSchema.table("incidents", {
|
|
23088
|
-
id: integer("id").generatedAlwaysAsIdentity().
|
|
23089
|
-
|
|
23090
|
-
|
|
23117
|
+
id: integer("id").generatedAlwaysAsIdentity().notNull(),
|
|
23118
|
+
/*
|
|
23119
|
+
FNXC:MultiProjectIsolation 2026-08-12-15:43:
|
|
23120
|
+
Migration 0006 rebuilt incident keys with project_id first. Drizzle emits DEFAULT while the
|
|
23121
|
+
database GUC/trigger retains ownership stamping and its physical legacy fallback.
|
|
23122
|
+
*/
|
|
23123
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23124
|
+
incidentId: text("incident_id").notNull(),
|
|
23091
23125
|
groupingKey: text("grouping_key").notNull(),
|
|
23092
23126
|
title: text("title").notNull(),
|
|
23093
23127
|
severity: text("severity"),
|
|
@@ -23101,6 +23135,8 @@ var init_project = __esm({
|
|
|
23101
23135
|
createdAt: text("created_at").notNull(),
|
|
23102
23136
|
updatedAt: text("updated_at").notNull()
|
|
23103
23137
|
}, (t) => [
|
|
23138
|
+
primaryKey({ columns: [t.projectId, t.id], name: "incidents_pkey" }),
|
|
23139
|
+
unique("incidents_incident_id_key").on(t.projectId, t.incidentId),
|
|
23104
23140
|
index("idxIncidentsProjectOpenedAt").on(t.projectId, t.openedAt),
|
|
23105
23141
|
index("idxIncidentsProjectStatus").on(t.projectId, t.status),
|
|
23106
23142
|
index("idxIncidentsGroupingKey").on(t.groupingKey),
|
|
@@ -23155,12 +23191,14 @@ var init_project = __esm({
|
|
|
23155
23191
|
content: text("content").notNull(),
|
|
23156
23192
|
type: text("type").notNull(),
|
|
23157
23193
|
read: integer("read").default(0),
|
|
23194
|
+
archived: integer("archived").default(0),
|
|
23158
23195
|
metadata: jsonb("metadata"),
|
|
23159
23196
|
createdAt: text("created_at").notNull(),
|
|
23160
23197
|
updatedAt: text("updated_at").notNull()
|
|
23161
23198
|
}, (t) => [
|
|
23162
23199
|
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23163
23200
|
index("idxMessagesTo").on(t.toId, t.toType, t.read),
|
|
23201
|
+
index("idxMessagesToArchived").on(t.toId, t.toType, t.archived),
|
|
23164
23202
|
index("idxMessagesFrom").on(t.fromId, t.fromType),
|
|
23165
23203
|
index("idxMessagesCreatedAt").on(t.createdAt)
|
|
23166
23204
|
]);
|
|
@@ -23261,7 +23299,8 @@ var init_project = __esm({
|
|
|
23261
23299
|
index("idx_cli_sessions_project_state").on(t.projectId, t.agentState)
|
|
23262
23300
|
]);
|
|
23263
23301
|
chatMessages = projectSchema.table("chat_messages", {
|
|
23264
|
-
|
|
23302
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23303
|
+
id: text("id").notNull(),
|
|
23265
23304
|
sessionId: text("session_id").notNull(),
|
|
23266
23305
|
role: text("role").notNull(),
|
|
23267
23306
|
content: text("content").notNull(),
|
|
@@ -23270,6 +23309,7 @@ var init_project = __esm({
|
|
|
23270
23309
|
createdAt: text("created_at").notNull(),
|
|
23271
23310
|
attachments: jsonb("attachments")
|
|
23272
23311
|
}, (t) => [
|
|
23312
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23273
23313
|
index("idxChatMessagesSessionId").on(t.sessionId),
|
|
23274
23314
|
index("idxChatMessagesCreatedAt").on(t.createdAt)
|
|
23275
23315
|
]);
|
|
@@ -23295,7 +23335,8 @@ var init_project = __esm({
|
|
|
23295
23335
|
index("idxChatTokenUsageCreatedAt").on(t.createdAt)
|
|
23296
23336
|
]);
|
|
23297
23337
|
runAuditEvents = projectSchema.table("run_audit_events", {
|
|
23298
|
-
|
|
23338
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23339
|
+
id: text("id").notNull(),
|
|
23299
23340
|
timestamp: text("timestamp").notNull(),
|
|
23300
23341
|
taskId: text("task_id"),
|
|
23301
23342
|
agentId: text("agent_id").notNull(),
|
|
@@ -23305,6 +23346,7 @@ var init_project = __esm({
|
|
|
23305
23346
|
target: text("target").notNull(),
|
|
23306
23347
|
metadata: jsonb("metadata")
|
|
23307
23348
|
}, (t) => [
|
|
23349
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23308
23350
|
index("idxRunAuditEventsRunIdTimestamp").on(t.runId, t.timestamp),
|
|
23309
23351
|
index("idxRunAuditEventsTaskIdTimestamp").on(t.taskId, t.timestamp),
|
|
23310
23352
|
index("idxRunAuditEventsTimestamp").on(t.timestamp)
|
|
@@ -23405,13 +23447,14 @@ var init_project = __esm({
|
|
|
23405
23447
|
index("idxMissionLineageStopsMissionId").on(t.projectId, t.missionId)
|
|
23406
23448
|
]);
|
|
23407
23449
|
verificationCache = projectSchema.table("verification_cache", {
|
|
23450
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23408
23451
|
treeSha: text("tree_sha").notNull(),
|
|
23409
23452
|
testCommand: text("test_command").notNull().default(""),
|
|
23410
23453
|
buildCommand: text("build_command").notNull().default(""),
|
|
23411
23454
|
recordedAt: text("recorded_at").notNull(),
|
|
23412
23455
|
taskId: text("task_id")
|
|
23413
23456
|
}, (t) => [
|
|
23414
|
-
primaryKey({ columns: [t.treeSha, t.testCommand, t.buildCommand] }),
|
|
23457
|
+
primaryKey({ columns: [t.projectId, t.treeSha, t.testCommand, t.buildCommand] }),
|
|
23415
23458
|
index("idxVerificationCacheRecordedAt").on(t.recordedAt)
|
|
23416
23459
|
]);
|
|
23417
23460
|
importTranslationCache = projectSchema.table("import_translation_cache", {
|
|
@@ -23444,7 +23487,8 @@ var init_project = __esm({
|
|
|
23444
23487
|
index("idxImportTranslationCacheRecordedAt").on(t.recordedAt)
|
|
23445
23488
|
]);
|
|
23446
23489
|
approvalRequests = projectSchema.table("approval_requests", {
|
|
23447
|
-
|
|
23490
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23491
|
+
id: text("id").notNull(),
|
|
23448
23492
|
status: text("status").notNull(),
|
|
23449
23493
|
requesterActorId: text("requester_actor_id").notNull(),
|
|
23450
23494
|
requesterActorType: text("requester_actor_type").notNull(),
|
|
@@ -23463,13 +23507,14 @@ var init_project = __esm({
|
|
|
23463
23507
|
createdAt: text("created_at").notNull(),
|
|
23464
23508
|
updatedAt: text("updated_at").notNull()
|
|
23465
23509
|
}, (t) => [
|
|
23510
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23466
23511
|
index("idxApprovalRequestsStatusCreatedAt").on(t.status, t.createdAt),
|
|
23467
23512
|
index("idxApprovalRequestsRequesterCreatedAt").on(t.requesterActorId, t.createdAt),
|
|
23468
23513
|
index("idxApprovalRequestsTaskCreatedAt").on(t.taskId, t.createdAt)
|
|
23469
23514
|
]);
|
|
23470
23515
|
approvalRequestAuditEvents = projectSchema.table("approval_request_audit_events", {
|
|
23471
|
-
projectId: text("project_id").notNull().default(
|
|
23472
|
-
id: text("id").
|
|
23516
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
23517
|
+
id: text("id").notNull(),
|
|
23473
23518
|
requestId: text("request_id").notNull(),
|
|
23474
23519
|
eventType: text("event_type").notNull(),
|
|
23475
23520
|
actorId: text("actor_id").notNull(),
|
|
@@ -23478,6 +23523,7 @@ var init_project = __esm({
|
|
|
23478
23523
|
note: text("note"),
|
|
23479
23524
|
createdAt: text("created_at").notNull()
|
|
23480
23525
|
}, (t) => [
|
|
23526
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
23481
23527
|
index("idxApprovalRequestAuditRequestCreatedAt").on(t.requestId, t.createdAt, t.id),
|
|
23482
23528
|
index("idxApprovalRequestAuditProjectCreatedAt").on(t.projectId, t.createdAt)
|
|
23483
23529
|
]);
|
|
@@ -26967,6 +27013,27 @@ var init_grok_provider = __esm({
|
|
|
26967
27013
|
apiKey: "$GROK_API_KEY",
|
|
26968
27014
|
api: "openai-completions",
|
|
26969
27015
|
models: [
|
|
27016
|
+
/*
|
|
27017
|
+
FNXC:ModelRegistry 2026-08-12-20:17:
|
|
27018
|
+
FN-9008 requires Grok 4.6 to be selectable in every model area. Keep it in this shared
|
|
27019
|
+
catalog because pi's registerProvider() replaces provider model lists wholesale, while every
|
|
27020
|
+
Fusion host seeds and re-merges this export. xAI's model docs verify grok-4.6, its 500k-token
|
|
27021
|
+
context window, and configurable reasoning; max output and per-model image input remain
|
|
27022
|
+
upstream-pending-verification, so retain the conservative text-only and 65536-token defaults.
|
|
27023
|
+
Source: https://docs.x.ai/developers/models
|
|
27024
|
+
*/
|
|
27025
|
+
{
|
|
27026
|
+
id: "grok-4.6",
|
|
27027
|
+
name: "Grok 4.6",
|
|
27028
|
+
reasoning: true,
|
|
27029
|
+
input: ["text"],
|
|
27030
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
27031
|
+
contextWindow: 5e5,
|
|
27032
|
+
maxTokens: 65536,
|
|
27033
|
+
compat: {
|
|
27034
|
+
supportsDeveloperRole: false
|
|
27035
|
+
}
|
|
27036
|
+
},
|
|
26970
27037
|
{
|
|
26971
27038
|
id: "grok-4.5",
|
|
26972
27039
|
name: "Grok 4.5",
|
|
@@ -34925,6 +34992,7 @@ function rowToMessage(row) {
|
|
|
34925
34992
|
content: row.content,
|
|
34926
34993
|
type: row.type,
|
|
34927
34994
|
read: (row.read ?? 0) === 1,
|
|
34995
|
+
archived: (row.archived ?? 0) === 1,
|
|
34928
34996
|
metadata: row.metadata ?? void 0,
|
|
34929
34997
|
createdAt: row.createdAt,
|
|
34930
34998
|
updatedAt: row.updatedAt
|
|
@@ -34936,6 +35004,11 @@ function participantIdsForLookup(ownerId, ownerType) {
|
|
|
34936
35004
|
}
|
|
34937
35005
|
return [ownerId];
|
|
34938
35006
|
}
|
|
35007
|
+
function archivedCondition(archived) {
|
|
35008
|
+
if (archived === true) return eq(project_exports.messages.archived, 1);
|
|
35009
|
+
if (archived === false) return or(eq(project_exports.messages.archived, 0), sql`${project_exports.messages.archived} IS NULL`);
|
|
35010
|
+
return or(eq(project_exports.messages.archived, 0), sql`${project_exports.messages.archived} IS NULL`);
|
|
35011
|
+
}
|
|
34939
35012
|
async function sendMessage(handle, message) {
|
|
34940
35013
|
const sanitizedContent = sanitizeTextValue(message.content);
|
|
34941
35014
|
const sanitizedMetadata = sanitizeJsonbValue(message.metadata);
|
|
@@ -34948,6 +35021,7 @@ async function sendMessage(handle, message) {
|
|
|
34948
35021
|
content: sanitizedContent,
|
|
34949
35022
|
type: message.type,
|
|
34950
35023
|
read: message.read ? 1 : 0,
|
|
35024
|
+
archived: message.archived ? 1 : 0,
|
|
34951
35025
|
metadata: sanitizedMetadata,
|
|
34952
35026
|
createdAt: message.createdAt,
|
|
34953
35027
|
updatedAt: message.updatedAt
|
|
@@ -34956,7 +35030,8 @@ async function sendMessage(handle, message) {
|
|
|
34956
35030
|
...message,
|
|
34957
35031
|
content: sanitizedContent,
|
|
34958
35032
|
metadata: sanitizedMetadata,
|
|
34959
|
-
read: message.read ? 1 : 0
|
|
35033
|
+
read: message.read ? 1 : 0,
|
|
35034
|
+
archived: message.archived ? 1 : 0
|
|
34960
35035
|
});
|
|
34961
35036
|
}
|
|
34962
35037
|
async function sendMessageOnce(handle, message) {
|
|
@@ -34969,6 +35044,7 @@ async function sendMessageOnce(handle, message) {
|
|
|
34969
35044
|
content: message.content,
|
|
34970
35045
|
type: message.type,
|
|
34971
35046
|
read: message.read ? 1 : 0,
|
|
35047
|
+
archived: message.archived ? 1 : 0,
|
|
34972
35048
|
metadata: message.metadata,
|
|
34973
35049
|
createdAt: message.createdAt,
|
|
34974
35050
|
updatedAt: message.updatedAt
|
|
@@ -35020,6 +35096,7 @@ async function queryMessagesByParticipant(handle, direction, ownerId, ownerType,
|
|
|
35020
35096
|
if (filter?.read !== void 0) {
|
|
35021
35097
|
conditions.push(eq(project_exports.messages.read, filter.read ? 1 : 0));
|
|
35022
35098
|
}
|
|
35099
|
+
conditions.push(archivedCondition(filter?.archived));
|
|
35023
35100
|
const limit = filter?.limit ?? 100;
|
|
35024
35101
|
const offset = filter?.offset ?? 0;
|
|
35025
35102
|
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(limit).offset(offset);
|
|
@@ -35033,6 +35110,13 @@ async function markMessageAsRead(handle, messageId) {
|
|
|
35033
35110
|
await handle.update(project_exports.messages).set({ read: 1, updatedAt: now }).where(eq(project_exports.messages.id, messageId));
|
|
35034
35111
|
return await getMessage(handle, messageId);
|
|
35035
35112
|
}
|
|
35113
|
+
async function setMessageArchived(handle, id, archived) {
|
|
35114
|
+
const existing = await getMessage(handle, id);
|
|
35115
|
+
if (!existing) return null;
|
|
35116
|
+
if (existing.archived === archived) return existing;
|
|
35117
|
+
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);
|
|
35118
|
+
return rows[0] ? rowToMessage(rows[0]) : null;
|
|
35119
|
+
}
|
|
35036
35120
|
async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
35037
35121
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
35038
35122
|
const participantIds = participantIdsForLookup(ownerId, ownerType);
|
|
@@ -35040,7 +35124,8 @@ async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
|
35040
35124
|
and(
|
|
35041
35125
|
inArray(project_exports.messages.toId, participantIds),
|
|
35042
35126
|
eq(project_exports.messages.toType, ownerType),
|
|
35043
|
-
eq(project_exports.messages.read, 0)
|
|
35127
|
+
eq(project_exports.messages.read, 0),
|
|
35128
|
+
archivedCondition()
|
|
35044
35129
|
)
|
|
35045
35130
|
);
|
|
35046
35131
|
const count2 = countRows[0]?.count ?? 0;
|
|
@@ -35048,7 +35133,8 @@ async function markAllMessagesAsRead(handle, ownerId, ownerType) {
|
|
|
35048
35133
|
and(
|
|
35049
35134
|
inArray(project_exports.messages.toId, participantIds),
|
|
35050
35135
|
eq(project_exports.messages.toType, ownerType),
|
|
35051
|
-
eq(project_exports.messages.read, 0)
|
|
35136
|
+
eq(project_exports.messages.read, 0),
|
|
35137
|
+
archivedCondition()
|
|
35052
35138
|
)
|
|
35053
35139
|
);
|
|
35054
35140
|
return count2;
|
|
@@ -35070,19 +35156,22 @@ async function getConversation(handle, participantA, participantB, options) {
|
|
|
35070
35156
|
const aIds = participantIdsForLookup(participantA.id, participantA.type);
|
|
35071
35157
|
const bIds = participantIdsForLookup(participantB.id, participantB.type);
|
|
35072
35158
|
const rows = await handle.select(messageColumns).from(project_exports.messages).where(
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35159
|
+
and(
|
|
35160
|
+
or(
|
|
35161
|
+
and(
|
|
35162
|
+
inArray(project_exports.messages.fromId, aIds),
|
|
35163
|
+
eq(project_exports.messages.fromType, participantA.type),
|
|
35164
|
+
inArray(project_exports.messages.toId, bIds),
|
|
35165
|
+
eq(project_exports.messages.toType, participantB.type)
|
|
35166
|
+
),
|
|
35167
|
+
and(
|
|
35168
|
+
inArray(project_exports.messages.fromId, bIds),
|
|
35169
|
+
eq(project_exports.messages.fromType, participantB.type),
|
|
35170
|
+
inArray(project_exports.messages.toId, aIds),
|
|
35171
|
+
eq(project_exports.messages.toType, participantA.type)
|
|
35172
|
+
)
|
|
35079
35173
|
),
|
|
35080
|
-
|
|
35081
|
-
inArray(project_exports.messages.fromId, bIds),
|
|
35082
|
-
eq(project_exports.messages.fromType, participantB.type),
|
|
35083
|
-
inArray(project_exports.messages.toId, aIds),
|
|
35084
|
-
eq(project_exports.messages.toType, participantA.type)
|
|
35085
|
-
)
|
|
35174
|
+
archivedCondition(options?.archived)
|
|
35086
35175
|
)
|
|
35087
35176
|
).orderBy(desc(project_exports.messages.createdAt)).limit(limit);
|
|
35088
35177
|
return rows.reverse().map((row) => rowToMessage(row));
|
|
@@ -35093,14 +35182,16 @@ async function getMailbox(handle, ownerId, ownerType) {
|
|
|
35093
35182
|
and(
|
|
35094
35183
|
inArray(project_exports.messages.toId, participantIds),
|
|
35095
35184
|
eq(project_exports.messages.toType, ownerType),
|
|
35096
|
-
eq(project_exports.messages.read, 0)
|
|
35185
|
+
eq(project_exports.messages.read, 0),
|
|
35186
|
+
archivedCondition()
|
|
35097
35187
|
)
|
|
35098
35188
|
);
|
|
35099
35189
|
const unreadCount = unreadRows[0]?.count ?? 0;
|
|
35100
35190
|
const lastRows = await handle.select(messageColumns).from(project_exports.messages).where(
|
|
35101
35191
|
and(
|
|
35102
35192
|
inArray(project_exports.messages.toId, participantIds),
|
|
35103
|
-
eq(project_exports.messages.toType, ownerType)
|
|
35193
|
+
eq(project_exports.messages.toType, ownerType),
|
|
35194
|
+
archivedCondition()
|
|
35104
35195
|
)
|
|
35105
35196
|
).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id)).limit(1);
|
|
35106
35197
|
return {
|
|
@@ -35110,15 +35201,16 @@ async function getMailbox(handle, ownerId, ownerType) {
|
|
|
35110
35201
|
lastMessage: lastRows[0] ? rowToMessage(lastRows[0]) : void 0
|
|
35111
35202
|
};
|
|
35112
35203
|
}
|
|
35113
|
-
async function getAllAgentToAgentMessages(handle) {
|
|
35114
|
-
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));
|
|
35204
|
+
async function getAllAgentToAgentMessages(handle, filter) {
|
|
35205
|
+
const rows = await handle.select(messageColumns).from(project_exports.messages).where(and(eq(project_exports.messages.type, "agent-to-agent"), archivedCondition(filter?.archived))).orderBy(desc(project_exports.messages.createdAt), desc(project_exports.messages.id));
|
|
35115
35206
|
return rows.map((row) => rowToMessage(row));
|
|
35116
35207
|
}
|
|
35117
35208
|
async function getUnreadAgentToAgentCount(handle) {
|
|
35118
35209
|
const rows = await handle.select({ count: sql`count(*)::int` }).from(project_exports.messages).where(
|
|
35119
35210
|
and(
|
|
35120
35211
|
eq(project_exports.messages.type, "agent-to-agent"),
|
|
35121
|
-
eq(project_exports.messages.read, 0)
|
|
35212
|
+
eq(project_exports.messages.read, 0),
|
|
35213
|
+
archivedCondition()
|
|
35122
35214
|
)
|
|
35123
35215
|
);
|
|
35124
35216
|
return rows[0]?.count ?? 0;
|
|
@@ -35140,6 +35232,7 @@ var init_async_message_store = __esm({
|
|
|
35140
35232
|
content: project_exports.messages.content,
|
|
35141
35233
|
type: project_exports.messages.type,
|
|
35142
35234
|
read: project_exports.messages.read,
|
|
35235
|
+
archived: project_exports.messages.archived,
|
|
35143
35236
|
metadata: project_exports.messages.metadata,
|
|
35144
35237
|
createdAt: project_exports.messages.createdAt,
|
|
35145
35238
|
updatedAt: project_exports.messages.updatedAt
|
|
@@ -35325,12 +35418,12 @@ var init_message_store = __esm({
|
|
|
35325
35418
|
}
|
|
35326
35419
|
const sqliteDb = this.db;
|
|
35327
35420
|
this.stmtInsert = sqliteDb.prepare(`
|
|
35328
|
-
INSERT INTO messages (id, fromId, fromType, toId, toType, content, type, read, metadata, createdAt, updatedAt)
|
|
35329
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35421
|
+
INSERT INTO messages (id, fromId, fromType, toId, toType, content, type, read, archived, metadata, createdAt, updatedAt)
|
|
35422
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35330
35423
|
`);
|
|
35331
35424
|
this.stmtInsertOnce = sqliteDb.prepare(`
|
|
35332
|
-
INSERT OR IGNORE INTO messages (id, fromId, fromType, toId, toType, content, type, read, metadata, createdAt, updatedAt)
|
|
35333
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35425
|
+
INSERT OR IGNORE INTO messages (id, fromId, fromType, toId, toType, content, type, read, archived, metadata, createdAt, updatedAt)
|
|
35426
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35334
35427
|
`);
|
|
35335
35428
|
this.stmtGetById = sqliteDb.prepare(`
|
|
35336
35429
|
SELECT * FROM messages WHERE id = ?
|
|
@@ -35368,6 +35461,7 @@ var init_message_store = __esm({
|
|
|
35368
35461
|
content: row.content,
|
|
35369
35462
|
type: row.type,
|
|
35370
35463
|
read: row.read === 1,
|
|
35464
|
+
archived: (row.archived ?? 0) === 1,
|
|
35371
35465
|
metadata: fromJson(row.metadata),
|
|
35372
35466
|
createdAt: row.createdAt,
|
|
35373
35467
|
updatedAt: row.updatedAt
|
|
@@ -35401,6 +35495,7 @@ var init_message_store = __esm({
|
|
|
35401
35495
|
content: sanitizeTextValue(input.content),
|
|
35402
35496
|
type: input.type,
|
|
35403
35497
|
read: false,
|
|
35498
|
+
archived: false,
|
|
35404
35499
|
metadata: sanitizeJsonbValue(input.metadata),
|
|
35405
35500
|
createdAt: now,
|
|
35406
35501
|
updatedAt: now
|
|
@@ -35416,6 +35511,7 @@ var init_message_store = __esm({
|
|
|
35416
35511
|
content: message.content,
|
|
35417
35512
|
type: message.type,
|
|
35418
35513
|
read: message.read,
|
|
35514
|
+
archived: message.archived,
|
|
35419
35515
|
metadata: message.metadata ?? null,
|
|
35420
35516
|
createdAt: message.createdAt,
|
|
35421
35517
|
updatedAt: message.updatedAt
|
|
@@ -35430,6 +35526,7 @@ var init_message_store = __esm({
|
|
|
35430
35526
|
message.content,
|
|
35431
35527
|
message.type,
|
|
35432
35528
|
message.read ? 1 : 0,
|
|
35529
|
+
message.archived ? 1 : 0,
|
|
35433
35530
|
toJsonNullable(message.metadata),
|
|
35434
35531
|
message.createdAt,
|
|
35435
35532
|
message.updatedAt
|
|
@@ -35488,6 +35585,7 @@ var init_message_store = __esm({
|
|
|
35488
35585
|
content: sanitizeTextValue(input.content),
|
|
35489
35586
|
type: input.type,
|
|
35490
35587
|
read: false,
|
|
35588
|
+
archived: false,
|
|
35491
35589
|
metadata: sanitizeJsonbValue(input.metadata),
|
|
35492
35590
|
createdAt: now,
|
|
35493
35591
|
updatedAt: now
|
|
@@ -35508,6 +35606,7 @@ var init_message_store = __esm({
|
|
|
35508
35606
|
message.content,
|
|
35509
35607
|
message.type,
|
|
35510
35608
|
0,
|
|
35609
|
+
0,
|
|
35511
35610
|
toJsonNullable(message.metadata),
|
|
35512
35611
|
message.createdAt,
|
|
35513
35612
|
message.updatedAt
|
|
@@ -35639,6 +35738,7 @@ var init_message_store = __esm({
|
|
|
35639
35738
|
whereClauses.push("read = ?");
|
|
35640
35739
|
params.push(filter.read ? 1 : 0);
|
|
35641
35740
|
}
|
|
35741
|
+
whereClauses.push(filter?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)");
|
|
35642
35742
|
const whereSql = whereClauses.join(" AND ");
|
|
35643
35743
|
const limit = filter?.limit ?? 100;
|
|
35644
35744
|
const offset = filter?.offset ?? 0;
|
|
@@ -35689,15 +35789,39 @@ var init_message_store = __esm({
|
|
|
35689
35789
|
const participantIds = this.getParticipantIdsForLookup(ownerId, ownerType);
|
|
35690
35790
|
const toIdPredicate = participantIds.length === 1 ? "toId = ?" : `toId IN (${participantIds.map(() => "?").join(", ")})`;
|
|
35691
35791
|
const unreadRow = this.db.prepare(`
|
|
35692
|
-
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
35792
|
+
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35693
35793
|
`).get(...participantIds, ownerType);
|
|
35694
35794
|
const count2 = unreadRow?.count ?? 0;
|
|
35695
35795
|
this.db.prepare(`
|
|
35696
|
-
UPDATE messages SET read = 1, updatedAt = ? WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
35796
|
+
UPDATE messages SET read = 1, updatedAt = ? WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35697
35797
|
`).run(now, ...participantIds, ownerType);
|
|
35698
35798
|
this.db.bumpLastModified();
|
|
35699
35799
|
return count2;
|
|
35700
35800
|
}
|
|
35801
|
+
/** Archive a message without destroying its correspondence history. */
|
|
35802
|
+
async archiveMessage(id) {
|
|
35803
|
+
return this.setMessageArchived(id, true);
|
|
35804
|
+
}
|
|
35805
|
+
/** Restore a previously archived message to default mailbox lists. */
|
|
35806
|
+
async unarchiveMessage(id) {
|
|
35807
|
+
return this.setMessageArchived(id, false);
|
|
35808
|
+
}
|
|
35809
|
+
async setMessageArchived(id, archived) {
|
|
35810
|
+
if (this.asyncLayer) {
|
|
35811
|
+
const updated2 = await setMessageArchived(this.asyncLayer.db, id, archived);
|
|
35812
|
+
if (!updated2) throw new Error(`Message ${id} not found`);
|
|
35813
|
+
this.emit(archived ? "message:archived" : "message:unarchived", updated2);
|
|
35814
|
+
return updated2;
|
|
35815
|
+
}
|
|
35816
|
+
const existing = await this.getMessage(id);
|
|
35817
|
+
if (!existing) throw new Error(`Message ${id} not found`);
|
|
35818
|
+
if (existing.archived === archived) return existing;
|
|
35819
|
+
this.db.prepare("UPDATE messages SET archived = ?, updatedAt = ? WHERE id = ?").run(archived ? 1 : 0, (/* @__PURE__ */ new Date()).toISOString(), id);
|
|
35820
|
+
this.db.bumpLastModified();
|
|
35821
|
+
const updated = await this.getMessage(id);
|
|
35822
|
+
this.emit(archived ? "message:archived" : "message:unarchived", updated);
|
|
35823
|
+
return updated;
|
|
35824
|
+
}
|
|
35701
35825
|
/**
|
|
35702
35826
|
* Delete a message by ID.
|
|
35703
35827
|
* @param id - The message ID
|
|
@@ -35788,7 +35912,7 @@ var init_message_store = __esm({
|
|
|
35788
35912
|
(${participantAFromPredicate} AND fromType = ? AND ${participantBToPredicate} AND toType = ?)
|
|
35789
35913
|
OR
|
|
35790
35914
|
(${participantBFromPredicate} AND fromType = ? AND ${participantAToPredicate} AND toType = ?)
|
|
35791
|
-
)
|
|
35915
|
+
) AND ${options?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)"}
|
|
35792
35916
|
ORDER BY createdAt DESC
|
|
35793
35917
|
LIMIT ?
|
|
35794
35918
|
`).all(
|
|
@@ -35823,11 +35947,11 @@ var init_message_store = __esm({
|
|
|
35823
35947
|
const participantIds = this.getParticipantIdsForLookup(ownerId, ownerType);
|
|
35824
35948
|
const toIdPredicate = participantIds.length === 1 ? "toId = ?" : `toId IN (${participantIds.map(() => "?").join(", ")})`;
|
|
35825
35949
|
const unreadRow = this.db.prepare(`
|
|
35826
|
-
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0
|
|
35950
|
+
SELECT COUNT(*) as count FROM messages WHERE ${toIdPredicate} AND toType = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35827
35951
|
`).get(...participantIds, ownerType);
|
|
35828
35952
|
const unreadCount = unreadRow?.count ?? 0;
|
|
35829
35953
|
const lastRow = this.db.prepare(`
|
|
35830
|
-
SELECT * FROM messages WHERE ${toIdPredicate} AND toType = ? ORDER BY createdAt DESC, rowid DESC LIMIT 1
|
|
35954
|
+
SELECT * FROM messages WHERE ${toIdPredicate} AND toType = ? AND (archived = 0 OR archived IS NULL) ORDER BY createdAt DESC, rowid DESC LIMIT 1
|
|
35831
35955
|
`).get(...participantIds, ownerType);
|
|
35832
35956
|
const lastMessage = lastRow ? this.rowToMessage(lastRow) : void 0;
|
|
35833
35957
|
return {
|
|
@@ -35841,13 +35965,13 @@ var init_message_store = __esm({
|
|
|
35841
35965
|
* Get all agent-to-agent messages across all agents.
|
|
35842
35966
|
* @returns Array of messages (newest first)
|
|
35843
35967
|
*/
|
|
35844
|
-
async getAllAgentToAgentMessages() {
|
|
35968
|
+
async getAllAgentToAgentMessages(filter) {
|
|
35845
35969
|
if (this.asyncLayer) {
|
|
35846
|
-
return getAllAgentToAgentMessages(this.asyncLayer.db);
|
|
35970
|
+
return getAllAgentToAgentMessages(this.asyncLayer.db, filter);
|
|
35847
35971
|
}
|
|
35848
35972
|
const rows = this.db.prepare(`
|
|
35849
35973
|
SELECT * FROM messages
|
|
35850
|
-
WHERE type = ?
|
|
35974
|
+
WHERE type = ? AND ${filter?.archived === true ? "archived = 1" : "(archived = 0 OR archived IS NULL)"}
|
|
35851
35975
|
ORDER BY createdAt DESC, rowid DESC
|
|
35852
35976
|
`).all("agent-to-agent");
|
|
35853
35977
|
return rows.map((row) => this.rowToMessage(row));
|
|
@@ -35861,7 +35985,7 @@ var init_message_store = __esm({
|
|
|
35861
35985
|
}
|
|
35862
35986
|
const row = this.db.prepare(`
|
|
35863
35987
|
SELECT COUNT(*) as count FROM messages
|
|
35864
|
-
WHERE type = ? AND read = 0
|
|
35988
|
+
WHERE type = ? AND read = 0 AND (archived = 0 OR archived IS NULL)
|
|
35865
35989
|
`).get("agent-to-agent");
|
|
35866
35990
|
return row?.count ?? 0;
|
|
35867
35991
|
}
|
|
@@ -35960,6 +36084,7 @@ async function createApprovalRequest(layer, input) {
|
|
|
35960
36084
|
};
|
|
35961
36085
|
await layer.transactionImmediate(async (tx) => {
|
|
35962
36086
|
await tx.insert(project_exports.approvalRequests).values({
|
|
36087
|
+
...layer.projectId?.trim() ? { projectId: layer.projectId } : {},
|
|
35963
36088
|
id: request2.id,
|
|
35964
36089
|
status: request2.status,
|
|
35965
36090
|
requesterActorId: request2.requester.actorId,
|
|
@@ -35983,12 +36108,12 @@ async function createApprovalRequest(layer, input) {
|
|
|
35983
36108
|
});
|
|
35984
36109
|
return request2;
|
|
35985
36110
|
}
|
|
35986
|
-
async function getApprovalRequest(handle, id) {
|
|
35987
|
-
const rows = await handle.select().from(project_exports.approvalRequests).where(eq(project_exports.approvalRequests.id, id));
|
|
36111
|
+
async function getApprovalRequest(handle, id, projectId2) {
|
|
36112
|
+
const rows = await handle.select().from(project_exports.approvalRequests).where(and(eq(project_exports.approvalRequests.id, id), projectScopeFor(project_exports.approvalRequests.projectId, projectId2)));
|
|
35988
36113
|
return rows[0] ? rowToRequest(rows[0]) : null;
|
|
35989
36114
|
}
|
|
35990
|
-
async function listApprovalRequests(handle, input = {}) {
|
|
35991
|
-
const conditions = [];
|
|
36115
|
+
async function listApprovalRequests(handle, input = {}, projectId2) {
|
|
36116
|
+
const conditions = [projectScopeFor(project_exports.approvalRequests.projectId, projectId2)];
|
|
35992
36117
|
if (input.status) conditions.push(eq(project_exports.approvalRequests.status, input.status));
|
|
35993
36118
|
if (input.requesterActorId) conditions.push(eq(project_exports.approvalRequests.requesterActorId, input.requesterActorId));
|
|
35994
36119
|
if (input.taskId) conditions.push(eq(project_exports.approvalRequests.taskId, input.taskId));
|
|
@@ -36002,7 +36127,7 @@ async function listApprovalRequests(handle, input = {}) {
|
|
|
36002
36127
|
async function decideApprovalRequest(layer, requestId, status, input) {
|
|
36003
36128
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
36004
36129
|
return layer.transactionImmediate(async (tx) => {
|
|
36005
|
-
const existing = await getApprovalRequest(tx, requestId);
|
|
36130
|
+
const existing = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36006
36131
|
if (!existing) throw new Error(`Approval request ${requestId} not found`);
|
|
36007
36132
|
if (!isValidApprovalRequestTransition(existing.status, status)) {
|
|
36008
36133
|
throw new Error(`Invalid approval request transition: ${existing.status} -> ${status}`);
|
|
@@ -36013,23 +36138,24 @@ async function decideApprovalRequest(layer, requestId, status, input) {
|
|
|
36013
36138
|
const updatedRows = await tx.update(project_exports.approvalRequests).set({ status, decidedAt: now, updatedAt: now }).where(
|
|
36014
36139
|
and(
|
|
36015
36140
|
eq(project_exports.approvalRequests.id, requestId),
|
|
36016
|
-
eq(project_exports.approvalRequests.status, existing.status)
|
|
36141
|
+
eq(project_exports.approvalRequests.status, existing.status),
|
|
36142
|
+
projectScopeFor(project_exports.approvalRequests.projectId, layer.projectId)
|
|
36017
36143
|
)
|
|
36018
36144
|
).returning({ id: project_exports.approvalRequests.id });
|
|
36019
36145
|
if (updatedRows.length === 0) {
|
|
36020
|
-
const raced = await getApprovalRequest(tx, requestId);
|
|
36146
|
+
const raced = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36021
36147
|
throw new Error(
|
|
36022
36148
|
`Invalid approval request transition: ${raced?.status ?? existing.status} -> ${status}`
|
|
36023
36149
|
);
|
|
36024
36150
|
}
|
|
36025
36151
|
await appendAuditEvent(tx, layer.projectId ?? "", requestId, status, input.actor, now, input.note);
|
|
36026
|
-
return await getApprovalRequest(tx, requestId);
|
|
36152
|
+
return await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36027
36153
|
});
|
|
36028
36154
|
}
|
|
36029
36155
|
async function markApprovalRequestCompleted(layer, requestId, input) {
|
|
36030
36156
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
36031
36157
|
return layer.transactionImmediate(async (tx) => {
|
|
36032
|
-
const existing = await getApprovalRequest(tx, requestId);
|
|
36158
|
+
const existing = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36033
36159
|
if (!existing) throw new Error(`Approval request ${requestId} not found`);
|
|
36034
36160
|
if (!isValidApprovalRequestTransition(existing.status, "completed")) {
|
|
36035
36161
|
throw new Error(`Invalid approval request transition: ${existing.status} -> completed`);
|
|
@@ -36043,21 +36169,22 @@ async function markApprovalRequestCompleted(layer, requestId, input) {
|
|
|
36043
36169
|
const updatedRows = await tx.update(project_exports.approvalRequests).set({ status: "completed", completedAt: now, updatedAt: now }).where(
|
|
36044
36170
|
and(
|
|
36045
36171
|
eq(project_exports.approvalRequests.id, requestId),
|
|
36046
|
-
eq(project_exports.approvalRequests.status, existing.status)
|
|
36172
|
+
eq(project_exports.approvalRequests.status, existing.status),
|
|
36173
|
+
projectScopeFor(project_exports.approvalRequests.projectId, layer.projectId)
|
|
36047
36174
|
)
|
|
36048
36175
|
).returning({ id: project_exports.approvalRequests.id });
|
|
36049
36176
|
if (updatedRows.length === 0) {
|
|
36050
|
-
const raced = await getApprovalRequest(tx, requestId);
|
|
36177
|
+
const raced = await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36051
36178
|
throw new Error(
|
|
36052
36179
|
`Invalid approval request transition: ${raced?.status ?? existing.status} -> completed`
|
|
36053
36180
|
);
|
|
36054
36181
|
}
|
|
36055
36182
|
await appendAuditEvent(tx, layer.projectId ?? "", requestId, "completed", input.actor, now, input.note);
|
|
36056
|
-
return await getApprovalRequest(tx, requestId);
|
|
36183
|
+
return await getApprovalRequest(tx, requestId, layer.projectId);
|
|
36057
36184
|
});
|
|
36058
36185
|
}
|
|
36059
|
-
async function getApprovalAuditHistory(handle, requestId) {
|
|
36060
|
-
const rows = await handle.select().from(project_exports.approvalRequestAuditEvents).where(eq(project_exports.approvalRequestAuditEvents.requestId, requestId)).orderBy(
|
|
36186
|
+
async function getApprovalAuditHistory(handle, requestId, projectId2) {
|
|
36187
|
+
const rows = await handle.select().from(project_exports.approvalRequestAuditEvents).where(and(eq(project_exports.approvalRequestAuditEvents.requestId, requestId), projectScopeFor(project_exports.approvalRequestAuditEvents.projectId, projectId2))).orderBy(
|
|
36061
36188
|
sql`${project_exports.approvalRequestAuditEvents.createdAt} ASC, ${project_exports.approvalRequestAuditEvents.id} ASC`
|
|
36062
36189
|
);
|
|
36063
36190
|
return rows.map((row) => rowToAuditEvent(row));
|
|
@@ -36067,6 +36194,7 @@ var init_async_approval_request_store = __esm({
|
|
|
36067
36194
|
"use strict";
|
|
36068
36195
|
init_drizzle_orm();
|
|
36069
36196
|
init_schema2();
|
|
36197
|
+
init_data_layer();
|
|
36070
36198
|
init_agents();
|
|
36071
36199
|
init_types();
|
|
36072
36200
|
}
|
|
@@ -36080,6 +36208,7 @@ var init_approval_request_store = __esm({
|
|
|
36080
36208
|
"use strict";
|
|
36081
36209
|
init_drizzle_orm();
|
|
36082
36210
|
init_db2();
|
|
36211
|
+
init_data_layer();
|
|
36083
36212
|
init_async_approval_request_store();
|
|
36084
36213
|
init_schema2();
|
|
36085
36214
|
init_async_agent_activity();
|
|
@@ -36208,23 +36337,26 @@ var init_approval_request_store = __esm({
|
|
|
36208
36337
|
return created;
|
|
36209
36338
|
}
|
|
36210
36339
|
async get(id) {
|
|
36211
|
-
return getApprovalRequest(this.asyncLayer.db, id);
|
|
36340
|
+
return getApprovalRequest(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
36212
36341
|
}
|
|
36213
36342
|
async list(input = {}) {
|
|
36214
|
-
return listApprovalRequests(this.asyncLayer.db, input);
|
|
36343
|
+
return listApprovalRequests(this.asyncLayer.db, input, this.asyncLayer.projectId);
|
|
36215
36344
|
}
|
|
36216
36345
|
async getPendingCountsByActor() {
|
|
36217
36346
|
const table = project_exports.approvalRequests;
|
|
36218
36347
|
const rows = await this.asyncLayer.db.select({
|
|
36219
36348
|
actorId: table.requesterActorId,
|
|
36220
36349
|
requestCount: count()
|
|
36221
|
-
}).from(table).where(eq(table.status, "pending")).groupBy(table.requesterActorId);
|
|
36350
|
+
}).from(table).where(and(eq(table.status, "pending"), projectScopeFor(table.projectId, this.asyncLayer.projectId))).groupBy(table.requesterActorId);
|
|
36222
36351
|
return new Map(rows.map((row) => [row.actorId, Number(row.requestCount)]));
|
|
36223
36352
|
}
|
|
36224
36353
|
async findLatestByDedupeKey(input) {
|
|
36225
36354
|
if (this.backendMode) {
|
|
36226
36355
|
const table = project_exports.approvalRequests;
|
|
36227
|
-
const conditions = [
|
|
36356
|
+
const conditions = [
|
|
36357
|
+
eq(table.requesterActorId, input.requesterActorId),
|
|
36358
|
+
projectScopeFor(table.projectId, this.asyncLayer.projectId)
|
|
36359
|
+
];
|
|
36228
36360
|
if (input.taskId !== void 0) {
|
|
36229
36361
|
conditions.push(eq(table.taskId, input.taskId));
|
|
36230
36362
|
}
|
|
@@ -36263,7 +36395,7 @@ var init_approval_request_store = __esm({
|
|
|
36263
36395
|
return markApprovalRequestCompleted(this.asyncLayer, requestId, input);
|
|
36264
36396
|
}
|
|
36265
36397
|
async getAuditHistory(requestId) {
|
|
36266
|
-
return getApprovalAuditHistory(this.asyncLayer.db, requestId);
|
|
36398
|
+
return getApprovalAuditHistory(this.asyncLayer.db, requestId, this.asyncLayer.projectId);
|
|
36267
36399
|
}
|
|
36268
36400
|
};
|
|
36269
36401
|
}
|
|
@@ -40449,6 +40581,8 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
40449
40581
|
const agentRatingProjectIsolationAlreadyApplied = applied.includes(AGENT_RATING_PROJECT_ISOLATION_VERSION);
|
|
40450
40582
|
const agentRatingsProjectPartitionAlreadyApplied = applied.includes(AGENT_RATINGS_PROJECT_PARTITION_VERSION);
|
|
40451
40583
|
const projectOwnershipDeclarationDriftAlreadyApplied = applied.includes(PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION);
|
|
40584
|
+
const projectOwnershipDefaultReconciliationAlreadyApplied = applied.includes(PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION);
|
|
40585
|
+
const messageArchiveSchemaAlreadyApplied = applied.includes(MESSAGE_ARCHIVE_SCHEMA_VERSION);
|
|
40452
40586
|
assertBinaryNotOlderThanDatabase(applied);
|
|
40453
40587
|
let schemaChanged = false;
|
|
40454
40588
|
if (!baselineAlreadyApplied) {
|
|
@@ -40932,17 +41066,29 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
40932
41066
|
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
40933
41067
|
schemaChanged = true;
|
|
40934
41068
|
}
|
|
41069
|
+
if (!projectOwnershipDefaultReconciliationAlreadyApplied) {
|
|
41070
|
+
const migrationSql = await readFile4(PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_MIGRATION_PATH, "utf8");
|
|
41071
|
+
await tx.execute(sql.raw(migrationSql));
|
|
41072
|
+
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
41073
|
+
schemaChanged = true;
|
|
41074
|
+
}
|
|
41075
|
+
if (!messageArchiveSchemaAlreadyApplied) {
|
|
41076
|
+
const migrationSql = await readFile4(MESSAGE_ARCHIVE_SCHEMA_MIGRATION_PATH, "utf8");
|
|
41077
|
+
await tx.execute(sql.raw(migrationSql));
|
|
41078
|
+
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${MESSAGE_ARCHIVE_SCHEMA_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
41079
|
+
schemaChanged = true;
|
|
41080
|
+
}
|
|
40935
41081
|
return { applied: schemaChanged, pluginHooksRun: pluginHooks.length };
|
|
40936
41082
|
});
|
|
40937
41083
|
}
|
|
40938
|
-
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;
|
|
41084
|
+
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;
|
|
40939
41085
|
var init_schema_applier = __esm({
|
|
40940
41086
|
"../core/src/postgres/schema-applier.ts"() {
|
|
40941
41087
|
"use strict";
|
|
40942
41088
|
init_drizzle_orm();
|
|
40943
41089
|
init_plugin_schema_hook();
|
|
40944
41090
|
init_advisory_locks();
|
|
40945
|
-
SCHEMA_BASELINE_VERSION = "
|
|
41091
|
+
SCHEMA_BASELINE_VERSION = "0058";
|
|
40946
41092
|
TASK_DECLARED_SYMBOLS_VERSION = "0028";
|
|
40947
41093
|
INITIAL_SCHEMA_VERSION = "0000";
|
|
40948
41094
|
AUTOMATION_ISOLATION_SCHEMA_VERSION = "0001";
|
|
@@ -40999,6 +41145,8 @@ var init_schema_applier = __esm({
|
|
|
40999
41145
|
AGENT_RATING_PROJECT_ISOLATION_VERSION = "0054";
|
|
41000
41146
|
AGENT_RATINGS_PROJECT_PARTITION_VERSION = "0055";
|
|
41001
41147
|
PROJECT_OWNERSHIP_DECLARATION_DRIFT_VERSION = "0056";
|
|
41148
|
+
PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_VERSION = "0057";
|
|
41149
|
+
MESSAGE_ARCHIVE_SCHEMA_VERSION = "0058";
|
|
41002
41150
|
LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION = "fusion_mark_legacy_adoption_drained";
|
|
41003
41151
|
StaleBinarySchemaError = class extends Error {
|
|
41004
41152
|
constructor(databaseVersion, binaryVersion) {
|
|
@@ -41135,6 +41283,8 @@ var init_schema_applier = __esm({
|
|
|
41135
41283
|
AGENT_RATING_PROJECT_ISOLATION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0054_fn_8957_agent_rating_project_isolation.sql");
|
|
41136
41284
|
AGENT_RATINGS_PROJECT_PARTITION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0055_fn_8988_agent_ratings_project_partition.sql");
|
|
41137
41285
|
PROJECT_OWNERSHIP_DECLARATION_DRIFT_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0056_fn_8997_project_ownership_declaration_drift.sql");
|
|
41286
|
+
PROJECT_OWNERSHIP_DEFAULT_RECONCILIATION_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0057_fn_9004_project_ownership_default_reconciliation.sql");
|
|
41287
|
+
MESSAGE_ARCHIVE_SCHEMA_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0058_fn_9014_message_archive.sql");
|
|
41138
41288
|
}
|
|
41139
41289
|
});
|
|
41140
41290
|
|
|
@@ -68667,8 +68817,10 @@ function safeJsonParse(value) {
|
|
|
68667
68817
|
return null;
|
|
68668
68818
|
}
|
|
68669
68819
|
}
|
|
68670
|
-
async function queryRunAuditEvents(db, filter = {}) {
|
|
68671
|
-
const conditions = []
|
|
68820
|
+
async function queryRunAuditEvents(db, filter = {}, projectId2) {
|
|
68821
|
+
const conditions = [projectScopeFor(project_exports.runAuditEvents.projectId, projectId2)].filter(
|
|
68822
|
+
(condition) => condition !== void 0
|
|
68823
|
+
);
|
|
68672
68824
|
if (filter.runId) {
|
|
68673
68825
|
conditions.push(eq(project_exports.runAuditEvents.runId, filter.runId));
|
|
68674
68826
|
}
|
|
@@ -68814,6 +68966,7 @@ var init_async_audit = __esm({
|
|
|
68814
68966
|
init_drizzle_orm();
|
|
68815
68967
|
init_schema2();
|
|
68816
68968
|
init_data_layer();
|
|
68969
|
+
init_data_layer();
|
|
68817
68970
|
LEGACY_REVIEW_LANES3 = ["in-review"];
|
|
68818
68971
|
LEGACY_COMPLETE_LANES = ["done"];
|
|
68819
68972
|
}
|
|
@@ -69203,7 +69356,10 @@ async function insertArtifactRow(layer, input, stored, archivedColumns) {
|
|
|
69203
69356
|
createdAt: now,
|
|
69204
69357
|
updatedAt: now
|
|
69205
69358
|
});
|
|
69206
|
-
const rows = await tx.select().from(project_exports.artifacts).where(
|
|
69359
|
+
const rows = await tx.select().from(project_exports.artifacts).where(and(
|
|
69360
|
+
eq(project_exports.artifacts.id, id),
|
|
69361
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
69362
|
+
)).limit(1);
|
|
69207
69363
|
const row = rows[0];
|
|
69208
69364
|
if (!row) throw new Error(`Failed to register artifact ${id}`);
|
|
69209
69365
|
return rowToArtifact2(row);
|
|
@@ -69211,7 +69367,7 @@ async function insertArtifactRow(layer, input, stored, archivedColumns) {
|
|
|
69211
69367
|
}
|
|
69212
69368
|
async function updateArtifactRow(layer, id, updates, archivedColumns) {
|
|
69213
69369
|
return layer.transactionImmediate(async (tx) => {
|
|
69214
|
-
const existing = await getArtifact(tx, id);
|
|
69370
|
+
const existing = await getArtifact(tx, id, layer.projectId);
|
|
69215
69371
|
if (!existing) {
|
|
69216
69372
|
throw new Error(`Artifact ${id} not found`);
|
|
69217
69373
|
}
|
|
@@ -69231,29 +69387,38 @@ async function updateArtifactRow(layer, id, updates, archivedColumns) {
|
|
|
69231
69387
|
description: updates.description !== void 0 ? updates.description : existing.description ?? null,
|
|
69232
69388
|
content: updates.content !== void 0 ? updates.content : existing.content ?? null,
|
|
69233
69389
|
updatedAt: now
|
|
69234
|
-
}).where(
|
|
69235
|
-
|
|
69390
|
+
}).where(and(
|
|
69391
|
+
eq(project_exports.artifacts.id, id),
|
|
69392
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
69393
|
+
));
|
|
69394
|
+
const updated = await getArtifact(tx, id, layer.projectId);
|
|
69236
69395
|
if (!updated) {
|
|
69237
69396
|
throw new Error(`Failed to update artifact ${id}`);
|
|
69238
69397
|
}
|
|
69239
69398
|
return updated;
|
|
69240
69399
|
});
|
|
69241
69400
|
}
|
|
69242
|
-
async function getArtifact(db, id) {
|
|
69243
|
-
const rows = await db.select().from(project_exports.artifacts).where(
|
|
69401
|
+
async function getArtifact(db, id, projectId2) {
|
|
69402
|
+
const rows = await db.select().from(project_exports.artifacts).where(and(
|
|
69403
|
+
eq(project_exports.artifacts.id, id),
|
|
69404
|
+
projectScopeFor(project_exports.artifacts.projectId, projectId2)
|
|
69405
|
+
)).limit(1);
|
|
69244
69406
|
const row = rows[0];
|
|
69245
69407
|
return row ? rowToArtifact2(row) : null;
|
|
69246
69408
|
}
|
|
69247
69409
|
async function getArtifacts(db, taskId, projectId2, archivedColumns) {
|
|
69248
69410
|
const column = await getLiveTaskColumn(db, taskId, projectId2, archivedColumns);
|
|
69249
69411
|
if (column === null || column === "archived") return [];
|
|
69250
|
-
const rows = await db.select().from(project_exports.artifacts).where(
|
|
69412
|
+
const rows = await db.select().from(project_exports.artifacts).where(and(
|
|
69413
|
+
eq(project_exports.artifacts.taskId, taskId),
|
|
69414
|
+
projectScopeFor(project_exports.artifacts.projectId, projectId2)
|
|
69415
|
+
)).orderBy(desc(project_exports.artifacts.createdAt));
|
|
69251
69416
|
return rows.map((row) => rowToArtifact2(row));
|
|
69252
69417
|
}
|
|
69253
|
-
async function listArtifacts(db, options) {
|
|
69418
|
+
async function listArtifacts(db, options, projectId2) {
|
|
69254
69419
|
const limit = Math.min(Math.max(1, options?.limit ?? 200), 1e3);
|
|
69255
69420
|
const offset = Math.max(0, options?.offset ?? 0);
|
|
69256
|
-
const conditions = [];
|
|
69421
|
+
const conditions = [projectScopeFor(project_exports.artifacts.projectId, projectId2)];
|
|
69257
69422
|
if (options?.type) {
|
|
69258
69423
|
conditions.push(eq(project_exports.artifacts.type, options.type));
|
|
69259
69424
|
}
|
|
@@ -69292,7 +69457,10 @@ async function listArtifacts(db, options) {
|
|
|
69292
69457
|
taskColumn: project_exports.tasks.column
|
|
69293
69458
|
}).from(project_exports.artifacts).leftJoin(
|
|
69294
69459
|
project_exports.tasks,
|
|
69295
|
-
|
|
69460
|
+
and(
|
|
69461
|
+
eq(project_exports.artifacts.taskId, project_exports.tasks.id),
|
|
69462
|
+
eq(project_exports.artifacts.projectId, project_exports.tasks.projectId)
|
|
69463
|
+
)
|
|
69296
69464
|
).where(and(...conditions)).orderBy(desc(project_exports.artifacts.createdAt)).limit(limit).offset(offset);
|
|
69297
69465
|
return rows.map((row) => {
|
|
69298
69466
|
const artifact = rowToArtifact2(row);
|
|
@@ -70457,7 +70625,7 @@ function rowToBranchGroup2(row) {
|
|
|
70457
70625
|
closedAt: row.closedAt ?? void 0
|
|
70458
70626
|
};
|
|
70459
70627
|
}
|
|
70460
|
-
async function createBranchGroup(db, input) {
|
|
70628
|
+
async function createBranchGroup(db, input, projectId2) {
|
|
70461
70629
|
validateBranchGroupBranchName(input.branchName);
|
|
70462
70630
|
const now = Date.now();
|
|
70463
70631
|
const id = generateBranchGroupId2();
|
|
@@ -70476,44 +70644,52 @@ async function createBranchGroup(db, input) {
|
|
|
70476
70644
|
updatedAt: now,
|
|
70477
70645
|
closedAt: input.closedAt ?? null
|
|
70478
70646
|
});
|
|
70479
|
-
const created = await getBranchGroup(db, id);
|
|
70647
|
+
const created = await getBranchGroup(db, id, projectId2);
|
|
70480
70648
|
if (!created) throw new Error(`Failed to read branch group ${id} after create`);
|
|
70481
70649
|
return created;
|
|
70482
70650
|
}
|
|
70483
|
-
async function getBranchGroup(db, id) {
|
|
70484
|
-
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70651
|
+
async function getBranchGroup(db, id, projectId2) {
|
|
70652
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(
|
|
70653
|
+
eq(project_exports.branchGroups.id, id),
|
|
70654
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70655
|
+
)).limit(1);
|
|
70485
70656
|
const row = rows[0];
|
|
70486
70657
|
return row ? rowToBranchGroup2(row) : null;
|
|
70487
70658
|
}
|
|
70488
|
-
async function getBranchGroupBySource(db, sourceType, sourceId) {
|
|
70659
|
+
async function getBranchGroupBySource(db, sourceType, sourceId, projectId2) {
|
|
70489
70660
|
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70490
70661
|
and(
|
|
70491
70662
|
eq(project_exports.branchGroups.sourceType, sourceType),
|
|
70492
|
-
eq(project_exports.branchGroups.sourceId, sourceId)
|
|
70663
|
+
eq(project_exports.branchGroups.sourceId, sourceId),
|
|
70664
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70493
70665
|
)
|
|
70494
70666
|
).limit(1);
|
|
70495
70667
|
const row = rows[0];
|
|
70496
70668
|
return row ? rowToBranchGroup2(row) : null;
|
|
70497
70669
|
}
|
|
70498
|
-
async function getBranchGroupByBranchName(db, branchName) {
|
|
70499
|
-
const rows = await db.select().from(project_exports.branchGroups).where(
|
|
70670
|
+
async function getBranchGroupByBranchName(db, branchName, projectId2) {
|
|
70671
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(
|
|
70672
|
+
eq(project_exports.branchGroups.branchName, branchName),
|
|
70673
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70674
|
+
)).orderBy(sql`${project_exports.branchGroups.createdAt} DESC`).limit(1);
|
|
70500
70675
|
const row = rows[0];
|
|
70501
70676
|
return row ? rowToBranchGroup2(row) : null;
|
|
70502
70677
|
}
|
|
70503
|
-
async function ensureBranchGroupForSource(db, sourceType, sourceId, init) {
|
|
70504
|
-
const existing = await getBranchGroupBySource(db, sourceType, sourceId);
|
|
70678
|
+
async function ensureBranchGroupForSource(db, sourceType, sourceId, init, projectId2) {
|
|
70679
|
+
const existing = await getBranchGroupBySource(db, sourceType, sourceId, projectId2);
|
|
70505
70680
|
if (existing) return existing;
|
|
70506
|
-
const existingByBranch = await getBranchGroupByBranchName(db, init.branchName);
|
|
70681
|
+
const existingByBranch = await getBranchGroupByBranchName(db, init.branchName, projectId2);
|
|
70507
70682
|
if (existingByBranch) return existingByBranch;
|
|
70508
|
-
return createBranchGroup(db, { sourceType, sourceId, ...init });
|
|
70683
|
+
return createBranchGroup(db, { sourceType, sourceId, ...init }, projectId2);
|
|
70509
70684
|
}
|
|
70510
|
-
async function listBranchGroups(db, options) {
|
|
70511
|
-
const
|
|
70512
|
-
|
|
70685
|
+
async function listBranchGroups(db, options, projectId2) {
|
|
70686
|
+
const conditions = [projectScopeFor(project_exports.branchGroups.projectId, projectId2)];
|
|
70687
|
+
if (options?.status) conditions.push(eq(project_exports.branchGroups.status, options.status));
|
|
70688
|
+
const rows = await db.select().from(project_exports.branchGroups).where(and(...conditions)).orderBy(asc(project_exports.branchGroups.createdAt));
|
|
70513
70689
|
return rows.map((row) => rowToBranchGroup2(row));
|
|
70514
70690
|
}
|
|
70515
|
-
async function updateBranchGroup(db, id, patch) {
|
|
70516
|
-
const current = await getBranchGroup(db, id);
|
|
70691
|
+
async function updateBranchGroup(db, id, patch, projectId2) {
|
|
70692
|
+
const current = await getBranchGroup(db, id, projectId2);
|
|
70517
70693
|
if (!current) throw new Error(`Branch group ${id} not found`);
|
|
70518
70694
|
if (patch.branchName !== void 0) {
|
|
70519
70695
|
validateBranchGroupBranchName(patch.branchName);
|
|
@@ -70532,8 +70708,11 @@ async function updateBranchGroup(db, id, patch) {
|
|
|
70532
70708
|
status: nextStatus,
|
|
70533
70709
|
updatedAt: now,
|
|
70534
70710
|
closedAt: nextClosedAt
|
|
70535
|
-
}).where(
|
|
70536
|
-
|
|
70711
|
+
}).where(and(
|
|
70712
|
+
eq(project_exports.branchGroups.id, id),
|
|
70713
|
+
projectScopeFor(project_exports.branchGroups.projectId, projectId2)
|
|
70714
|
+
));
|
|
70715
|
+
const updated = await getBranchGroup(db, id, projectId2);
|
|
70537
70716
|
if (!updated) throw new Error(`Branch group ${id} disappeared after update`);
|
|
70538
70717
|
return updated;
|
|
70539
70718
|
}
|
|
@@ -70690,6 +70869,7 @@ var init_async_branch_groups = __esm({
|
|
|
70690
70869
|
"use strict";
|
|
70691
70870
|
init_drizzle_orm();
|
|
70692
70871
|
init_schema2();
|
|
70872
|
+
init_data_layer();
|
|
70693
70873
|
init_branch_assignment();
|
|
70694
70874
|
}
|
|
70695
70875
|
});
|
|
@@ -80503,6 +80683,9 @@ import { randomUUID as randomUUID21 } from "node:crypto";
|
|
|
80503
80683
|
function tableForScope(scope) {
|
|
80504
80684
|
return scope === "project" ? project_exports.secrets : central_exports.secretsGlobal;
|
|
80505
80685
|
}
|
|
80686
|
+
function scopeForSecretTable(scope, table, projectId2) {
|
|
80687
|
+
return scope === "project" ? projectScopeFor(table.projectId, projectId2) : void 0;
|
|
80688
|
+
}
|
|
80506
80689
|
function isAccessPolicy(value) {
|
|
80507
80690
|
return value === "auto" || value === "prompt" || value === "deny";
|
|
80508
80691
|
}
|
|
@@ -80525,23 +80708,23 @@ function rowToRecord2(row, scope) {
|
|
|
80525
80708
|
lastReadBy: row.lastReadBy
|
|
80526
80709
|
};
|
|
80527
80710
|
}
|
|
80528
|
-
async function getSecretMetadata(handle, id, scope) {
|
|
80711
|
+
async function getSecretMetadata(handle, id, scope, projectId2) {
|
|
80529
80712
|
const table = tableForScope(scope);
|
|
80530
|
-
const rows = await handle.select(metadataColumns(table)).from(table).where(eq(table.id, id)).limit(1);
|
|
80713
|
+
const rows = await handle.select(metadataColumns(table)).from(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2))).limit(1);
|
|
80531
80714
|
const row = rows[0];
|
|
80532
80715
|
return row ? rowToRecord2(row, scope) : null;
|
|
80533
80716
|
}
|
|
80534
|
-
async function listSecrets(handle, scope) {
|
|
80717
|
+
async function listSecrets(handle, scope, projectId2) {
|
|
80535
80718
|
if (scope) {
|
|
80536
80719
|
const table = tableForScope(scope);
|
|
80537
|
-
const rows = await handle.select(metadataColumns(table)).from(table).orderBy(asc(sql`lower(${table.key})`));
|
|
80720
|
+
const rows = await handle.select(metadataColumns(table)).from(table).where(scopeForSecretTable(scope, table, projectId2)).orderBy(asc(sql`lower(${table.key})`));
|
|
80538
80721
|
return rows.map((row) => rowToRecord2(row, scope));
|
|
80539
80722
|
}
|
|
80540
|
-
const project = await listSecrets(handle, "project");
|
|
80541
|
-
const global2 = await listSecrets(handle, "global");
|
|
80723
|
+
const project = await listSecrets(handle, "project", projectId2);
|
|
80724
|
+
const global2 = await listSecrets(handle, "global", projectId2);
|
|
80542
80725
|
return [...project, ...global2];
|
|
80543
80726
|
}
|
|
80544
|
-
async function createSecret(handle, cipher, input) {
|
|
80727
|
+
async function createSecret(handle, cipher, input, projectId2) {
|
|
80545
80728
|
const key = input.key.trim();
|
|
80546
80729
|
if (!key) {
|
|
80547
80730
|
throw new SecretsStoreError({ code: "invalid-key", message: "Secret key is required" });
|
|
@@ -80555,6 +80738,7 @@ async function createSecret(handle, cipher, input) {
|
|
|
80555
80738
|
const table = tableForScope(input.scope);
|
|
80556
80739
|
try {
|
|
80557
80740
|
await handle.insert(table).values({
|
|
80741
|
+
...input.scope === "project" && projectId2?.trim() ? { projectId: projectId2 } : {},
|
|
80558
80742
|
id,
|
|
80559
80743
|
key,
|
|
80560
80744
|
valueCiphertext: encrypted.ciphertext,
|
|
@@ -80574,14 +80758,14 @@ async function createSecret(handle, cipher, input) {
|
|
|
80574
80758
|
}
|
|
80575
80759
|
throw error3;
|
|
80576
80760
|
}
|
|
80577
|
-
const created = await getSecretMetadata(handle, id, input.scope);
|
|
80761
|
+
const created = await getSecretMetadata(handle, id, input.scope, projectId2);
|
|
80578
80762
|
if (!created) {
|
|
80579
80763
|
throw new SecretsStoreError({ code: "not-found", message: "Secret insert succeeded but row could not be read back" });
|
|
80580
80764
|
}
|
|
80581
80765
|
return created;
|
|
80582
80766
|
}
|
|
80583
|
-
async function updateSecret(handle, cipher, id, scope, patch) {
|
|
80584
|
-
const existing = await getSecretMetadata(handle, id, scope);
|
|
80767
|
+
async function updateSecret(handle, cipher, id, scope, patch, projectId2) {
|
|
80768
|
+
const existing = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80585
80769
|
if (!existing) {
|
|
80586
80770
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
80587
80771
|
}
|
|
@@ -80615,34 +80799,34 @@ async function updateSecret(handle, cipher, id, scope, patch) {
|
|
|
80615
80799
|
updates.nonce = encrypted.nonce;
|
|
80616
80800
|
}
|
|
80617
80801
|
try {
|
|
80618
|
-
await handle.update(table).set(updates).where(eq(table.id, id));
|
|
80802
|
+
await handle.update(table).set(updates).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80619
80803
|
} catch (error3) {
|
|
80620
80804
|
if (isPostgresUniqueError(error3)) {
|
|
80621
80805
|
throw new SecretsStoreError({ code: "duplicate-key", message: "Secret key already exists" });
|
|
80622
80806
|
}
|
|
80623
80807
|
throw error3;
|
|
80624
80808
|
}
|
|
80625
|
-
const updated = await getSecretMetadata(handle, id, scope);
|
|
80809
|
+
const updated = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80626
80810
|
if (!updated) {
|
|
80627
80811
|
throw new SecretsStoreError({ code: "not-found", message: "Secret update succeeded but row could not be read back" });
|
|
80628
80812
|
}
|
|
80629
80813
|
return updated;
|
|
80630
80814
|
}
|
|
80631
|
-
async function deleteSecret(handle, id, scope) {
|
|
80632
|
-
const existing = await getSecretMetadata(handle, id, scope);
|
|
80815
|
+
async function deleteSecret(handle, id, scope, projectId2) {
|
|
80816
|
+
const existing = await getSecretMetadata(handle, id, scope, projectId2);
|
|
80633
80817
|
if (!existing) {
|
|
80634
80818
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
80635
80819
|
}
|
|
80636
80820
|
const table = tableForScope(scope);
|
|
80637
|
-
await handle.delete(table).where(eq(table.id, id));
|
|
80821
|
+
await handle.delete(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80638
80822
|
}
|
|
80639
|
-
async function revealSecret(handle, cipher, id, scope, reader) {
|
|
80823
|
+
async function revealSecret(handle, cipher, id, scope, reader, projectId2) {
|
|
80640
80824
|
const table = tableForScope(scope);
|
|
80641
80825
|
const rows = await handle.select({
|
|
80642
80826
|
...metadataColumns(table),
|
|
80643
80827
|
valueCiphertext: table.valueCiphertext,
|
|
80644
80828
|
nonce: table.nonce
|
|
80645
|
-
}).from(table).where(eq(table.id, id)).limit(1);
|
|
80829
|
+
}).from(table).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2))).limit(1);
|
|
80646
80830
|
const row = rows[0];
|
|
80647
80831
|
if (!row) {
|
|
80648
80832
|
throw new SecretsStoreError({ code: "not-found", message: "Secret not found" });
|
|
@@ -80661,7 +80845,7 @@ async function revealSecret(handle, cipher, id, scope, reader) {
|
|
|
80661
80845
|
}
|
|
80662
80846
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
80663
80847
|
const lastReadBy = reader.userId ?? reader.agentId ?? null;
|
|
80664
|
-
await handle.update(table).set({ lastReadAt: now, lastReadBy, updatedAt: now }).where(eq(table.id, id));
|
|
80848
|
+
await handle.update(table).set({ lastReadAt: now, lastReadBy, updatedAt: now }).where(and(eq(table.id, id), scopeForSecretTable(scope, table, projectId2)));
|
|
80665
80849
|
return { key: row.key, plaintextValue };
|
|
80666
80850
|
}
|
|
80667
80851
|
var severityAuditLog10, SecretsStoreError, metadataColumns;
|
|
@@ -80672,6 +80856,7 @@ var init_async_secrets_store = __esm({
|
|
|
80672
80856
|
init_drizzle_orm();
|
|
80673
80857
|
init_postgres_errors();
|
|
80674
80858
|
init_schema2();
|
|
80859
|
+
init_data_layer();
|
|
80675
80860
|
init_secrets_crypto();
|
|
80676
80861
|
severityAuditLog10 = createLogger("core-async-secrets-store");
|
|
80677
80862
|
SecretsStoreError = class extends Error {
|
|
@@ -80767,7 +80952,7 @@ var init_secrets_store = __esm({
|
|
|
80767
80952
|
};
|
|
80768
80953
|
}
|
|
80769
80954
|
async listSecrets(scope) {
|
|
80770
|
-
return listSecrets(this.asyncLayer.db, scope);
|
|
80955
|
+
return listSecrets(this.asyncLayer.db, scope, this.asyncLayer.projectId);
|
|
80771
80956
|
}
|
|
80772
80957
|
async listEnvExportable(opts) {
|
|
80773
80958
|
const keyPrefix = opts?.keyPrefix;
|
|
@@ -80810,7 +80995,7 @@ var init_secrets_store = __esm({
|
|
|
80810
80995
|
return [...exported.values()];
|
|
80811
80996
|
}
|
|
80812
80997
|
async getSecretMetadata(id, scope) {
|
|
80813
|
-
return getSecretMetadata(this.asyncLayer.db, id, scope);
|
|
80998
|
+
return getSecretMetadata(this.asyncLayer.db, id, scope, this.asyncLayer.projectId);
|
|
80814
80999
|
}
|
|
80815
81000
|
async createSecret(input) {
|
|
80816
81001
|
const key = input.key.trim();
|
|
@@ -80820,12 +81005,12 @@ var init_secrets_store = __esm({
|
|
|
80820
81005
|
if (input.accessPolicy && !isAccessPolicy2(input.accessPolicy)) {
|
|
80821
81006
|
throw new SecretsStoreError2({ code: "invalid-policy", message: "Invalid access policy" });
|
|
80822
81007
|
}
|
|
80823
|
-
const created = await createSecret(this.asyncLayer.db, this.cipher, input);
|
|
81008
|
+
const created = await createSecret(this.asyncLayer.db, this.cipher, input, this.asyncLayer.projectId);
|
|
80824
81009
|
this.emitAudit({ mutationType: "secret:create", scope: input.scope, secretId: created.id, key: created.key });
|
|
80825
81010
|
return created;
|
|
80826
81011
|
}
|
|
80827
81012
|
async updateSecret(id, scope, patch) {
|
|
80828
|
-
const updated = await updateSecret(this.asyncLayer.db, this.cipher, id, scope, patch);
|
|
81013
|
+
const updated = await updateSecret(this.asyncLayer.db, this.cipher, id, scope, patch, this.asyncLayer.projectId);
|
|
80829
81014
|
this.emitAudit({ mutationType: "secret:update", scope, secretId: updated.id, key: updated.key });
|
|
80830
81015
|
return updated;
|
|
80831
81016
|
}
|
|
@@ -80834,12 +81019,12 @@ var init_secrets_store = __esm({
|
|
|
80834
81019
|
if (!existing) {
|
|
80835
81020
|
throw new SecretsStoreError2({ code: "not-found", message: "Secret not found" });
|
|
80836
81021
|
}
|
|
80837
|
-
await deleteSecret(this.asyncLayer.db, id, scope);
|
|
81022
|
+
await deleteSecret(this.asyncLayer.db, id, scope, this.asyncLayer.projectId);
|
|
80838
81023
|
this.emitAudit({ mutationType: "secret:delete", scope, secretId: id, key: existing.key });
|
|
80839
81024
|
return;
|
|
80840
81025
|
}
|
|
80841
81026
|
async revealSecret(id, scope, reader) {
|
|
80842
|
-
const revealed = await revealSecret(this.asyncLayer.db, this.cipher, id, scope, reader);
|
|
81027
|
+
const revealed = await revealSecret(this.asyncLayer.db, this.cipher, id, scope, reader, this.asyncLayer.projectId);
|
|
80843
81028
|
this.emitAudit({ mutationType: "secret:read", scope, secretId: id, key: revealed.key, actor: reader });
|
|
80844
81029
|
return revealed;
|
|
80845
81030
|
}
|
|
@@ -81940,6 +82125,7 @@ async function getVerificationCacheHitImpl(store, treeSha, testCommand, buildCom
|
|
|
81940
82125
|
const normalizedBuild = buildCommand2 ?? "";
|
|
81941
82126
|
const table = project_exports.verificationCache;
|
|
81942
82127
|
const rows = await store.asyncLayer.db.select({ recordedAt: table.recordedAt, taskId: table.taskId }).from(table).where(and(
|
|
82128
|
+
projectScopeFor(table.projectId, store.asyncLayer.projectId),
|
|
81943
82129
|
eq(table.treeSha, treeSha),
|
|
81944
82130
|
eq(table.testCommand, normalizedTest),
|
|
81945
82131
|
eq(table.buildCommand, normalizedBuild)
|
|
@@ -82682,7 +82868,7 @@ async function invokeTaskCreatedHookImpl(store, task) {
|
|
|
82682
82868
|
}
|
|
82683
82869
|
async function createBranchGroupImpl(store, input) {
|
|
82684
82870
|
const layer = store.asyncLayer;
|
|
82685
|
-
return createBranchGroup(layer.db, input);
|
|
82871
|
+
return createBranchGroup(layer.db, input, layer.projectId);
|
|
82686
82872
|
}
|
|
82687
82873
|
var init_task_id_integrity2 = __esm({
|
|
82688
82874
|
"../core/src/task-store/task-id-integrity.ts"() {
|
|
@@ -82767,22 +82953,23 @@ import { readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises
|
|
|
82767
82953
|
import { join as join23 } from "node:path";
|
|
82768
82954
|
async function getBranchGroupImpl(store, id) {
|
|
82769
82955
|
const layer = store.asyncLayer;
|
|
82770
|
-
return getBranchGroup(layer.db, id);
|
|
82956
|
+
return getBranchGroup(layer.db, id, layer.projectId);
|
|
82771
82957
|
}
|
|
82772
82958
|
async function getBranchGroupBySourceImpl(store, sourceType, sourceId) {
|
|
82773
82959
|
const layer = store.asyncLayer;
|
|
82774
|
-
return getBranchGroupBySource(layer.db, sourceType, sourceId);
|
|
82960
|
+
return getBranchGroupBySource(layer.db, sourceType, sourceId, layer.projectId);
|
|
82775
82961
|
}
|
|
82776
82962
|
async function getBranchGroupByBranchNameImpl(store, branchName) {
|
|
82777
82963
|
const layer = store.asyncLayer;
|
|
82778
|
-
return getBranchGroupByBranchName(layer.db, branchName);
|
|
82964
|
+
return getBranchGroupByBranchName(layer.db, branchName, layer.projectId);
|
|
82779
82965
|
}
|
|
82780
82966
|
async function ensureBranchGroupForSourceImpl(store, sourceType, sourceId, init) {
|
|
82781
|
-
|
|
82967
|
+
const layer = store.asyncLayer;
|
|
82968
|
+
return ensureBranchGroupForSource(layer.db, sourceType, sourceId, init, layer.projectId);
|
|
82782
82969
|
}
|
|
82783
82970
|
async function listBranchGroupsImpl(store, options) {
|
|
82784
82971
|
const layer = store.asyncLayer;
|
|
82785
|
-
return listBranchGroups(layer.db, options);
|
|
82972
|
+
return listBranchGroups(layer.db, options, layer.projectId);
|
|
82786
82973
|
}
|
|
82787
82974
|
async function listTasksByBranchGroupImpl(store, groupId) {
|
|
82788
82975
|
const tasks2 = await store.listTasks({ includeArchived: true, slim: false });
|
|
@@ -84324,7 +84511,7 @@ function insertArtifactRowImpl(store, input, id, now, stored) {
|
|
|
84324
84511
|
}
|
|
84325
84512
|
async function getArtifactImpl(store, id) {
|
|
84326
84513
|
const layer = store.asyncLayer;
|
|
84327
|
-
return getArtifact(layer.db, id);
|
|
84514
|
+
return getArtifact(layer.db, id, layer.projectId);
|
|
84328
84515
|
}
|
|
84329
84516
|
async function updateArtifactImpl(store, id, updates) {
|
|
84330
84517
|
const layer = store.asyncLayer;
|
|
@@ -89193,6 +89380,7 @@ var init_async_archive_lineage = __esm({
|
|
|
89193
89380
|
"use strict";
|
|
89194
89381
|
init_drizzle_orm();
|
|
89195
89382
|
init_schema2();
|
|
89383
|
+
init_data_layer();
|
|
89196
89384
|
init_async_persistence();
|
|
89197
89385
|
init_async_lifecycle();
|
|
89198
89386
|
init_lineage_approval_invalidation();
|
|
@@ -92660,7 +92848,7 @@ async function _maybeAutoArchiveSameAgentDuplicateBackendImpl(store, task, input
|
|
|
92660
92848
|
}
|
|
92661
92849
|
async function updateBranchGroupImpl(store, id, patch) {
|
|
92662
92850
|
const layer = store.asyncLayer;
|
|
92663
|
-
return updateBranchGroup(layer.db, id, patch);
|
|
92851
|
+
return updateBranchGroup(layer.db, id, patch, layer.projectId);
|
|
92664
92852
|
}
|
|
92665
92853
|
async function updatePrEntityImpl(store, id, patch) {
|
|
92666
92854
|
const layer = store.asyncLayer;
|
|
@@ -93170,13 +93358,19 @@ async function deleteAttachmentArtifactRows(store, taskId, filename) {
|
|
|
93170
93358
|
const linkedArtifactIds = artifacts2.filter((artifact) => artifact.metadata?.source === "attachment" && artifact.metadata.attachmentFilename === filename).map((artifact) => artifact.id);
|
|
93171
93359
|
if (linkedArtifactIds.length === 0) return;
|
|
93172
93360
|
for (const artifactId of linkedArtifactIds) {
|
|
93173
|
-
await layer.db.delete(project_exports.artifacts).where(
|
|
93361
|
+
await layer.db.delete(project_exports.artifacts).where(and(
|
|
93362
|
+
eq(project_exports.artifacts.id, artifactId),
|
|
93363
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
93364
|
+
));
|
|
93174
93365
|
}
|
|
93175
93366
|
return;
|
|
93176
93367
|
}
|
|
93177
93368
|
async function getArtifactsForAttachmentCleanup(store, taskId) {
|
|
93178
93369
|
const layer = store.asyncLayer;
|
|
93179
|
-
const rows = await layer.db.select().from(project_exports.artifacts).where(
|
|
93370
|
+
const rows = await layer.db.select().from(project_exports.artifacts).where(and(
|
|
93371
|
+
eq(project_exports.artifacts.taskId, taskId),
|
|
93372
|
+
projectScopeFor(project_exports.artifacts.projectId, layer.projectId)
|
|
93373
|
+
));
|
|
93180
93374
|
return rows;
|
|
93181
93375
|
}
|
|
93182
93376
|
async function deleteAttachmentImpl(store, id, filename) {
|
|
@@ -95592,7 +95786,7 @@ function clearLinkedAgentTaskIdsImpl(store, taskId, updatedAt = (/* @__PURE__ */
|
|
|
95592
95786
|
`).run(updatedAt, updatedAt, taskId);
|
|
95593
95787
|
}
|
|
95594
95788
|
async function listArtifactsImpl(store, options) {
|
|
95595
|
-
return listArtifacts(store.asyncLayer.db, options);
|
|
95789
|
+
return listArtifacts(store.asyncLayer.db, options, store.asyncLayer.projectId);
|
|
95596
95790
|
}
|
|
95597
95791
|
async function rehomeOccupantImpl(store, taskId, targetColumn, reason, metadata) {
|
|
95598
95792
|
let current;
|
|
@@ -103919,7 +104113,11 @@ var init_store = __esm({
|
|
|
103919
104113
|
/** PostgreSQL-authoritative audit reader; sync fallback remains for test doubles. */
|
|
103920
104114
|
async getRunAuditEventsAsync(options = {}) {
|
|
103921
104115
|
if (this.asyncLayer) {
|
|
103922
|
-
const events = await queryRunAuditEvents(
|
|
104116
|
+
const events = await queryRunAuditEvents(
|
|
104117
|
+
this.asyncLayer.db,
|
|
104118
|
+
options,
|
|
104119
|
+
this.asyncLayer.projectId
|
|
104120
|
+
);
|
|
103923
104121
|
return events.map((event) => ({
|
|
103924
104122
|
...event,
|
|
103925
104123
|
taskId: event.taskId ?? void 0,
|
|
@@ -107497,7 +107695,9 @@ function rangeWhere(query) {
|
|
|
107497
107695
|
async function aggregatePluginActivations(dbOrLayer, query = {}) {
|
|
107498
107696
|
if ("ping" in dbOrLayer) {
|
|
107499
107697
|
const layer = dbOrLayer;
|
|
107500
|
-
const conditions = []
|
|
107698
|
+
const conditions = [projectScopeFor(project_exports.pluginActivations.projectId, layer.projectId)].filter(
|
|
107699
|
+
(condition) => condition !== void 0
|
|
107700
|
+
);
|
|
107501
107701
|
if (query.from !== void 0) conditions.push(gte(project_exports.pluginActivations.activatedAt, query.from));
|
|
107502
107702
|
if (query.to !== void 0) conditions.push(lte(project_exports.pluginActivations.activatedAt, query.to));
|
|
107503
107703
|
const where2 = conditions.length > 0 ? and(...conditions) : void 0;
|
|
@@ -107536,6 +107736,7 @@ async function aggregatePluginActivations(dbOrLayer, query = {}) {
|
|
|
107536
107736
|
var init_plugin_activation_analytics = __esm({
|
|
107537
107737
|
"../core/src/plugins/plugin-activation-analytics.ts"() {
|
|
107538
107738
|
"use strict";
|
|
107739
|
+
init_data_layer();
|
|
107539
107740
|
init_drizzle_orm();
|
|
107540
107741
|
init_schema2();
|
|
107541
107742
|
}
|
|
@@ -130533,6 +130734,18 @@ function rowToMessage2(row) {
|
|
|
130533
130734
|
createdAt: row.createdAt
|
|
130534
130735
|
};
|
|
130535
130736
|
}
|
|
130737
|
+
function chatMessageProjectConditions(handle, projectId2) {
|
|
130738
|
+
const messageScope = projectScopeFor(project_exports.chatMessages.projectId, projectId2);
|
|
130739
|
+
const sessionScope = projectScopeFor(project_exports.chatSessions.projectId, projectId2);
|
|
130740
|
+
if (!messageScope || !sessionScope) return [];
|
|
130741
|
+
return [
|
|
130742
|
+
messageScope,
|
|
130743
|
+
exists(handle.select({ id: project_exports.chatSessions.id }).from(project_exports.chatSessions).where(and(
|
|
130744
|
+
eq(project_exports.chatSessions.id, project_exports.chatMessages.sessionId),
|
|
130745
|
+
sessionScope
|
|
130746
|
+
)))
|
|
130747
|
+
];
|
|
130748
|
+
}
|
|
130536
130749
|
function rowToRoom(row) {
|
|
130537
130750
|
return {
|
|
130538
130751
|
id: row.id,
|
|
@@ -130704,7 +130917,7 @@ async function replaceChatSessionTags(layer, sessionId, projectId2, tagIds) {
|
|
|
130704
130917
|
return attachTags(tx, session);
|
|
130705
130918
|
});
|
|
130706
130919
|
}
|
|
130707
|
-
async function addChatMessage(handle, message) {
|
|
130920
|
+
async function addChatMessage(handle, message, projectId2) {
|
|
130708
130921
|
const sanitizedAttachments = message.attachments === void 0 ? void 0 : sanitizeJsonbValue(message.attachments);
|
|
130709
130922
|
const sanitized = {
|
|
130710
130923
|
...message,
|
|
@@ -130723,15 +130936,24 @@ async function addChatMessage(handle, message) {
|
|
|
130723
130936
|
attachments: sanitizedAttachments ?? null,
|
|
130724
130937
|
createdAt: sanitized.createdAt
|
|
130725
130938
|
});
|
|
130726
|
-
await handle.update(project_exports.chatSessions).set({ updatedAt: sanitized.createdAt }).where(
|
|
130939
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: sanitized.createdAt }).where(and(
|
|
130940
|
+
eq(project_exports.chatSessions.id, sanitized.sessionId),
|
|
130941
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
130942
|
+
));
|
|
130727
130943
|
return sanitized;
|
|
130728
130944
|
}
|
|
130729
|
-
async function getChatMessage(handle, id) {
|
|
130730
|
-
const rows = await handle.select().from(project_exports.chatMessages).where(
|
|
130945
|
+
async function getChatMessage(handle, id, projectId2) {
|
|
130946
|
+
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
130947
|
+
eq(project_exports.chatMessages.id, id),
|
|
130948
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
130949
|
+
));
|
|
130731
130950
|
return rows[0] ? rowToMessage2(rows[0]) : void 0;
|
|
130732
130951
|
}
|
|
130733
|
-
async function getChatMessages(handle, sessionId, filter) {
|
|
130734
|
-
const conditions = [
|
|
130952
|
+
async function getChatMessages(handle, sessionId, filter, projectId2) {
|
|
130953
|
+
const conditions = [
|
|
130954
|
+
eq(project_exports.chatMessages.sessionId, sessionId),
|
|
130955
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
130956
|
+
];
|
|
130735
130957
|
if (filter?.before) {
|
|
130736
130958
|
conditions.push(lte(project_exports.chatMessages.createdAt, filter.before));
|
|
130737
130959
|
}
|
|
@@ -130741,9 +130963,12 @@ async function getChatMessages(handle, sessionId, filter) {
|
|
|
130741
130963
|
const rows = await handle.select().from(project_exports.chatMessages).where(and(...conditions)).orderBy(filter?.order === "desc" ? desc(orderCol) : asc(orderCol)).limit(limit).offset(offset);
|
|
130742
130964
|
return rows.map(rowToMessage2);
|
|
130743
130965
|
}
|
|
130744
|
-
async function getLastMessageForSessions(handle, sessionIds) {
|
|
130966
|
+
async function getLastMessageForSessions(handle, sessionIds, projectId2) {
|
|
130745
130967
|
if (sessionIds.length === 0) return /* @__PURE__ */ new Map();
|
|
130746
|
-
const rows = await handle.select().from(project_exports.chatMessages).where(
|
|
130968
|
+
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
130969
|
+
inArray(project_exports.chatMessages.sessionId, sessionIds),
|
|
130970
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
130971
|
+
)).orderBy(
|
|
130747
130972
|
desc(project_exports.chatMessages.createdAt),
|
|
130748
130973
|
desc(project_exports.chatMessages.id)
|
|
130749
130974
|
);
|
|
@@ -130909,8 +131134,8 @@ async function setInFlightGeneration(handle, id, inFlightGeneration) {
|
|
|
130909
131134
|
await handle.update(project_exports.chatSessions).set({ inFlightGeneration: sanitizedInFlightGeneration }).where(eq(project_exports.chatSessions.id, id));
|
|
130910
131135
|
return getChatSession(handle, id);
|
|
130911
131136
|
}
|
|
130912
|
-
async function addChatMessageAttachment(handle, sessionId, messageId, attachment) {
|
|
130913
|
-
const message = await getChatMessage(handle, messageId);
|
|
131137
|
+
async function addChatMessageAttachment(handle, sessionId, messageId, attachment, projectId2) {
|
|
131138
|
+
const message = await getChatMessage(handle, messageId, projectId2);
|
|
130914
131139
|
if (!message || message.sessionId !== sessionId) {
|
|
130915
131140
|
throw new Error(`Message ${messageId} not found in session ${sessionId}`);
|
|
130916
131141
|
}
|
|
@@ -130918,25 +131143,35 @@ async function addChatMessageAttachment(handle, sessionId, messageId, attachment
|
|
|
130918
131143
|
...message.attachments ?? [],
|
|
130919
131144
|
attachment
|
|
130920
131145
|
]);
|
|
130921
|
-
await handle.update(project_exports.chatMessages).set({ attachments: updatedAttachments }).where(
|
|
130922
|
-
|
|
131146
|
+
await handle.update(project_exports.chatMessages).set({ attachments: updatedAttachments }).where(and(
|
|
131147
|
+
eq(project_exports.chatMessages.id, messageId),
|
|
131148
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131149
|
+
));
|
|
131150
|
+
const updated = await getChatMessage(handle, messageId, projectId2);
|
|
130923
131151
|
if (!updated) throw new Error(`Failed to update message ${messageId}`);
|
|
130924
131152
|
return updated;
|
|
130925
131153
|
}
|
|
130926
|
-
async function deleteChatMessage(handle, id) {
|
|
130927
|
-
const existing = await getChatMessage(handle, id);
|
|
131154
|
+
async function deleteChatMessage(handle, id, projectId2) {
|
|
131155
|
+
const existing = await getChatMessage(handle, id, projectId2);
|
|
130928
131156
|
if (!existing) return false;
|
|
130929
|
-
await handle.delete(project_exports.chatMessages).where(
|
|
130930
|
-
|
|
131157
|
+
await handle.delete(project_exports.chatMessages).where(and(
|
|
131158
|
+
eq(project_exports.chatMessages.id, id),
|
|
131159
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131160
|
+
));
|
|
131161
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(
|
|
131162
|
+
eq(project_exports.chatSessions.id, existing.sessionId),
|
|
131163
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
131164
|
+
));
|
|
130931
131165
|
return true;
|
|
130932
131166
|
}
|
|
130933
|
-
async function searchChatSessionsByMessageContent(handle, query, sessionIds) {
|
|
131167
|
+
async function searchChatSessionsByMessageContent(handle, query, sessionIds, projectId2) {
|
|
130934
131168
|
const trimmed = query.trim();
|
|
130935
131169
|
if (!trimmed || sessionIds.length === 0) return /* @__PURE__ */ new Map();
|
|
130936
131170
|
const escaped = trimmed.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
130937
131171
|
const rows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
130938
131172
|
inArray(project_exports.chatMessages.sessionId, sessionIds),
|
|
130939
|
-
ilike(project_exports.chatMessages.content, `%${escaped}%`)
|
|
131173
|
+
ilike(project_exports.chatMessages.content, `%${escaped}%`),
|
|
131174
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
130940
131175
|
)).orderBy(
|
|
130941
131176
|
desc(project_exports.chatMessages.createdAt),
|
|
130942
131177
|
desc(project_exports.chatMessages.id)
|
|
@@ -130950,13 +131185,16 @@ async function searchChatSessionsByMessageContent(handle, query, sessionIds) {
|
|
|
130950
131185
|
}
|
|
130951
131186
|
return result2;
|
|
130952
131187
|
}
|
|
130953
|
-
async function deleteChatMessagesFrom(handle, sessionId, fromMessageId) {
|
|
130954
|
-
const orderedRows = await handle.select().from(project_exports.chatMessages).where(
|
|
131188
|
+
async function deleteChatMessagesFrom(handle, sessionId, fromMessageId, projectId2) {
|
|
131189
|
+
const orderedRows = await handle.select().from(project_exports.chatMessages).where(and(
|
|
131190
|
+
eq(project_exports.chatMessages.sessionId, sessionId),
|
|
131191
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131192
|
+
)).orderBy(
|
|
130955
131193
|
asc(project_exports.chatMessages.createdAt),
|
|
130956
131194
|
asc(project_exports.chatMessages.id)
|
|
130957
131195
|
);
|
|
130958
131196
|
const ordered2 = orderedRows.map(rowToMessage2);
|
|
130959
|
-
const target = await getChatMessage(handle, fromMessageId);
|
|
131197
|
+
const target = await getChatMessage(handle, fromMessageId, projectId2);
|
|
130960
131198
|
if (!target || target.sessionId !== sessionId) {
|
|
130961
131199
|
return { deletedIds: [], retained: ordered2 };
|
|
130962
131200
|
}
|
|
@@ -130969,19 +131207,28 @@ async function deleteChatMessagesFrom(handle, sessionId, fromMessageId) {
|
|
|
130969
131207
|
if (deletedIds.length === 0) {
|
|
130970
131208
|
return { deletedIds: [], retained };
|
|
130971
131209
|
}
|
|
130972
|
-
await handle.delete(project_exports.chatMessages).where(
|
|
130973
|
-
|
|
131210
|
+
await handle.delete(project_exports.chatMessages).where(and(
|
|
131211
|
+
inArray(project_exports.chatMessages.id, deletedIds),
|
|
131212
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131213
|
+
));
|
|
131214
|
+
await handle.update(project_exports.chatSessions).set({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(
|
|
131215
|
+
eq(project_exports.chatSessions.id, sessionId),
|
|
131216
|
+
projectScopeFor(project_exports.chatSessions.projectId, projectId2)
|
|
131217
|
+
));
|
|
130974
131218
|
return { deletedIds, retained };
|
|
130975
131219
|
}
|
|
130976
|
-
async function updateChatMessageMetadata(handle, messageId, metadata, options) {
|
|
130977
|
-
const existing = await getChatMessage(handle, messageId);
|
|
131220
|
+
async function updateChatMessageMetadata(handle, messageId, metadata, options, projectId2) {
|
|
131221
|
+
const existing = await getChatMessage(handle, messageId, projectId2);
|
|
130978
131222
|
if (!existing) {
|
|
130979
131223
|
throw new Error(`Message ${messageId} not found`);
|
|
130980
131224
|
}
|
|
130981
131225
|
const merge2 = options?.merge !== false;
|
|
130982
131226
|
const nextMetadata = metadata === null ? merge2 ? existing.metadata : null : merge2 ? { ...existing.metadata ?? {}, ...metadata } : metadata;
|
|
130983
|
-
await handle.update(project_exports.chatMessages).set({ metadata: sanitizeJsonbValue(nextMetadata) ?? null }).where(
|
|
130984
|
-
|
|
131227
|
+
await handle.update(project_exports.chatMessages).set({ metadata: sanitizeJsonbValue(nextMetadata) ?? null }).where(and(
|
|
131228
|
+
eq(project_exports.chatMessages.id, messageId),
|
|
131229
|
+
...chatMessageProjectConditions(handle, projectId2)
|
|
131230
|
+
));
|
|
131231
|
+
const updated = await getChatMessage(handle, messageId, projectId2);
|
|
130985
131232
|
if (!updated) {
|
|
130986
131233
|
throw new Error(`Failed to update message ${messageId}`);
|
|
130987
131234
|
}
|
|
@@ -131363,7 +131610,7 @@ var init_chat_store = __esm({
|
|
|
131363
131610
|
attachments: input.attachments,
|
|
131364
131611
|
createdAt: now
|
|
131365
131612
|
};
|
|
131366
|
-
const created = await addChatMessage(this.asyncLayer.db, message);
|
|
131613
|
+
const created = await addChatMessage(this.asyncLayer.db, message, this.asyncLayer.projectId);
|
|
131367
131614
|
this.emit("chat:message:added", created);
|
|
131368
131615
|
return created;
|
|
131369
131616
|
}
|
|
@@ -131371,7 +131618,7 @@ var init_chat_store = __esm({
|
|
|
131371
131618
|
* Append a file attachment metadata record to an existing message.
|
|
131372
131619
|
*/
|
|
131373
131620
|
async addMessageAttachment(sessionId, messageId, attachment) {
|
|
131374
|
-
const updated = await addChatMessageAttachment(this.asyncLayer.db, sessionId, messageId, attachment);
|
|
131621
|
+
const updated = await addChatMessageAttachment(this.asyncLayer.db, sessionId, messageId, attachment, this.asyncLayer.projectId);
|
|
131375
131622
|
this.emit("chat:message:updated", updated);
|
|
131376
131623
|
return updated;
|
|
131377
131624
|
}
|
|
@@ -131383,7 +131630,7 @@ var init_chat_store = __esm({
|
|
|
131383
131630
|
* @returns Array of messages ordered by createdAt ASC (default) or DESC
|
|
131384
131631
|
*/
|
|
131385
131632
|
async getMessages(sessionId, filter) {
|
|
131386
|
-
return getChatMessages(this.asyncLayer.db, sessionId, filter);
|
|
131633
|
+
return getChatMessages(this.asyncLayer.db, sessionId, filter, this.asyncLayer.projectId);
|
|
131387
131634
|
}
|
|
131388
131635
|
/**
|
|
131389
131636
|
* Get a message by ID.
|
|
@@ -131392,7 +131639,7 @@ var init_chat_store = __esm({
|
|
|
131392
131639
|
* @returns The message, or undefined if not found
|
|
131393
131640
|
*/
|
|
131394
131641
|
async getMessage(id) {
|
|
131395
|
-
return getChatMessage(this.asyncLayer.db, id);
|
|
131642
|
+
return getChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131396
131643
|
}
|
|
131397
131644
|
/**
|
|
131398
131645
|
* Get the latest message for each session in the provided list.
|
|
@@ -131402,10 +131649,10 @@ var init_chat_store = __esm({
|
|
|
131402
131649
|
* @returns Map of sessionId -> latest ChatMessage for that session
|
|
131403
131650
|
*/
|
|
131404
131651
|
async getLastMessageForSessions(sessionIds) {
|
|
131405
|
-
return getLastMessageForSessions(this.asyncLayer.db, sessionIds);
|
|
131652
|
+
return getLastMessageForSessions(this.asyncLayer.db, sessionIds, this.asyncLayer.projectId);
|
|
131406
131653
|
}
|
|
131407
131654
|
async hasMessages(sessionId) {
|
|
131408
|
-
return (await getChatMessages(this.asyncLayer.db, sessionId, { limit: 1 })).length > 0;
|
|
131655
|
+
return (await getChatMessages(this.asyncLayer.db, sessionId, { limit: 1 }, this.asyncLayer.projectId)).length > 0;
|
|
131409
131656
|
}
|
|
131410
131657
|
/**
|
|
131411
131658
|
* Search sessions by message content (not just title/agentId).
|
|
@@ -131433,7 +131680,7 @@ var init_chat_store = __esm({
|
|
|
131433
131680
|
if (!trimmed || !sessionIds || sessionIds.length === 0) {
|
|
131434
131681
|
return /* @__PURE__ */ new Map();
|
|
131435
131682
|
}
|
|
131436
|
-
return searchChatSessionsByMessageContent(this.asyncLayer.db, trimmed, sessionIds);
|
|
131683
|
+
return searchChatSessionsByMessageContent(this.asyncLayer.db, trimmed, sessionIds, this.asyncLayer.projectId);
|
|
131437
131684
|
}
|
|
131438
131685
|
/**
|
|
131439
131686
|
* Delete a message by ID.
|
|
@@ -131442,9 +131689,9 @@ var init_chat_store = __esm({
|
|
|
131442
131689
|
* @returns true if deleted, false if not found
|
|
131443
131690
|
*/
|
|
131444
131691
|
async deleteMessage(id) {
|
|
131445
|
-
const existing = await getChatMessage(this.asyncLayer.db, id);
|
|
131692
|
+
const existing = await getChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131446
131693
|
if (!existing) return false;
|
|
131447
|
-
const deleted = await deleteChatMessage(this.asyncLayer.db, id);
|
|
131694
|
+
const deleted = await deleteChatMessage(this.asyncLayer.db, id, this.asyncLayer.projectId);
|
|
131448
131695
|
if (deleted) {
|
|
131449
131696
|
this.emit("chat:message:deleted", id);
|
|
131450
131697
|
const updatedSession = await this.getSession(existing.sessionId);
|
|
@@ -131467,7 +131714,7 @@ var init_chat_store = __esm({
|
|
|
131467
131714
|
* @returns deletedIds (in ASC order) and retained messages (pre-edit history, ASC order)
|
|
131468
131715
|
*/
|
|
131469
131716
|
async deleteMessagesFrom(sessionId, fromMessageId) {
|
|
131470
|
-
const result2 = await deleteChatMessagesFrom(this.asyncLayer.db, sessionId, fromMessageId);
|
|
131717
|
+
const result2 = await deleteChatMessagesFrom(this.asyncLayer.db, sessionId, fromMessageId, this.asyncLayer.projectId);
|
|
131471
131718
|
if (result2.deletedIds.length > 0) {
|
|
131472
131719
|
for (const id of result2.deletedIds) {
|
|
131473
131720
|
this.emit("chat:message:deleted", id);
|
|
@@ -131485,7 +131732,7 @@ var init_chat_store = __esm({
|
|
|
131485
131732
|
* is what lets a later edit rewind losslessly via SessionManager.branch()/resetLeaf().
|
|
131486
131733
|
*/
|
|
131487
131734
|
async updateMessageMetadata(messageId, metadata, options) {
|
|
131488
|
-
const updated = await updateChatMessageMetadata(this.asyncLayer.db, messageId, metadata, options);
|
|
131735
|
+
const updated = await updateChatMessageMetadata(this.asyncLayer.db, messageId, metadata, options, this.asyncLayer.projectId);
|
|
131489
131736
|
this.emit("chat:message:updated", updated);
|
|
131490
131737
|
return updated;
|
|
131491
131738
|
}
|
|
@@ -135954,7 +136201,13 @@ var init_gating_classifications = __esm({
|
|
|
135954
136201
|
"fn_post_room_message",
|
|
135955
136202
|
"fn_update_identity",
|
|
135956
136203
|
"fn_reflect_on_performance",
|
|
135957
|
-
|
|
136204
|
+
/*
|
|
136205
|
+
FNXC:ToolGovernance 2026-08-12-22:11:
|
|
136206
|
+
fn_agent_read_evaluations is a subtree-scoped read. Authorization is enforced by
|
|
136207
|
+
the extension tool's getChainOfCommand boundary, not by this action classifier.
|
|
136208
|
+
*/
|
|
136209
|
+
"fn_read_evaluations",
|
|
136210
|
+
"fn_agent_read_evaluations"
|
|
135958
136211
|
]);
|
|
135959
136212
|
COORDINATION_EXEMPT_TOOLS = [
|
|
135960
136213
|
"read",
|
|
@@ -136014,6 +136267,8 @@ var init_gating_classifications = __esm({
|
|
|
136014
136267
|
"fn_post_room_message",
|
|
136015
136268
|
"fn_memory_append",
|
|
136016
136269
|
"fn_read_evaluations",
|
|
136270
|
+
// 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.
|
|
136271
|
+
"fn_agent_read_evaluations",
|
|
136017
136272
|
"fn_update_identity",
|
|
136018
136273
|
"fn_reflect_on_performance"
|
|
136019
136274
|
];
|
|
@@ -178003,32 +178258,36 @@ var init_scheduler = __esm({
|
|
|
178003
178258
|
const hierarchy = await missionStore.getMissionWithHierarchy(mission.id);
|
|
178004
178259
|
if (!hierarchy) continue;
|
|
178005
178260
|
for (const slice of hierarchy.milestones.flatMap((milestone) => milestone.slices).filter((slice2) => slice2.status === "active")) {
|
|
178006
|
-
|
|
178007
|
-
|
|
178008
|
-
|
|
178009
|
-
|
|
178010
|
-
|
|
178011
|
-
|
|
178012
|
-
|
|
178261
|
+
try {
|
|
178262
|
+
const superseded = await missionStore.reconcileSupersededGeneratedFixFeatures(slice.id);
|
|
178263
|
+
fixed += superseded.supersededCount;
|
|
178264
|
+
if (superseded.supersededCount > 0) {
|
|
178265
|
+
const refreshed = await missionStore.getSlice(slice.id);
|
|
178266
|
+
if (refreshed?.status === "complete") {
|
|
178267
|
+
await this.onSliceComplete(refreshed);
|
|
178268
|
+
continue;
|
|
178269
|
+
}
|
|
178013
178270
|
}
|
|
178014
|
-
|
|
178015
|
-
|
|
178016
|
-
|
|
178017
|
-
|
|
178018
|
-
|
|
178019
|
-
|
|
178020
|
-
|
|
178021
|
-
|
|
178022
|
-
|
|
178271
|
+
const listFeatures2 = missionStore.listFeatures;
|
|
178272
|
+
const features = listFeatures2 ? await listFeatures2.call(missionStore, slice.id) : slice.features;
|
|
178273
|
+
const supersededFeatureIds = new Set(superseded.featureIds ?? []);
|
|
178274
|
+
const autoTriage = mission.autopilotEnabled === true || mission.autoAdvance === true;
|
|
178275
|
+
for (const feature of features) {
|
|
178276
|
+
if (supersededFeatureIds.has(feature.id) || feature.taskId || !autoTriage || feature.status === "blocked") continue;
|
|
178277
|
+
if (feature.status !== "defined" && this.isGeneratedFixFeature(feature)) {
|
|
178278
|
+
await missionStore.updateFeature(feature.id, { status: "blocked", loopState: "blocked", taskId: void 0 });
|
|
178279
|
+
fixed++;
|
|
178280
|
+
continue;
|
|
178281
|
+
}
|
|
178282
|
+
if (feature.status !== "defined" && feature.status !== "triaged" && feature.status !== "in-progress") continue;
|
|
178283
|
+
const ready = feature.status === "defined" ? feature : await missionStore.updateFeature(feature.id, { status: "defined", loopState: "idle", taskId: void 0 });
|
|
178284
|
+
if (ready !== feature) fixed++;
|
|
178285
|
+
const triaged = await missionStore.triageFeature(ready.id);
|
|
178023
178286
|
fixed++;
|
|
178024
|
-
|
|
178287
|
+
if (triaged.taskId) await this.emitStrandedFeatureTriageAudit(mission.id, slice.id, triaged.id, triaged.taskId);
|
|
178025
178288
|
}
|
|
178026
|
-
|
|
178027
|
-
|
|
178028
|
-
if (ready !== feature) fixed++;
|
|
178029
|
-
const triaged = await missionStore.triageFeature(ready.id);
|
|
178030
|
-
fixed++;
|
|
178031
|
-
if (triaged.taskId) await this.emitStrandedFeatureTriageAudit(mission.id, slice.id, triaged.id, triaged.taskId);
|
|
178289
|
+
} catch (error3) {
|
|
178290
|
+
schedulerLog.error(`Error during active mission recovery reconciliation for slice ${slice.id}:`, error3);
|
|
178032
178291
|
}
|
|
178033
178292
|
}
|
|
178034
178293
|
}
|
|
@@ -312361,6 +312620,50 @@ async function getAgentStore(cwd) {
|
|
|
312361
312620
|
const projectStore = await getStore(cwd);
|
|
312362
312621
|
return new AgentStore({ rootDir: getFusionDir(cwd), asyncLayer: requireProjectLayer(projectStore, "CLI AgentStore") });
|
|
312363
312622
|
}
|
|
312623
|
+
async function resolveManagerEvaluationTarget(agentStore, agentId, ctx) {
|
|
312624
|
+
const target = await agentStore.resolveAgent(agentId);
|
|
312625
|
+
if (!target) {
|
|
312626
|
+
return {
|
|
312627
|
+
kind: "error",
|
|
312628
|
+
response: {
|
|
312629
|
+
content: [{ type: "text", text: `Agent '${agentId}' not found` }],
|
|
312630
|
+
isError: true,
|
|
312631
|
+
details: { outcome: "not_found", error: "Agent not found", agentId }
|
|
312632
|
+
}
|
|
312633
|
+
};
|
|
312634
|
+
}
|
|
312635
|
+
if (isEphemeralAgent(target)) {
|
|
312636
|
+
return {
|
|
312637
|
+
kind: "error",
|
|
312638
|
+
response: {
|
|
312639
|
+
content: [{ type: "text", text: `ERROR: Cannot evaluate ephemeral/runtime agent ${target.id}` }],
|
|
312640
|
+
isError: true,
|
|
312641
|
+
details: { outcome: "invalid", field: "agent_id", agentId: target.id }
|
|
312642
|
+
}
|
|
312643
|
+
};
|
|
312644
|
+
}
|
|
312645
|
+
const callerAgentId = typeof ctx.agentId === "string" && ctx.agentId ? ctx.agentId : void 0;
|
|
312646
|
+
if (callerAgentId) {
|
|
312647
|
+
const chain = await agentStore.getChainOfCommand(target.id);
|
|
312648
|
+
const callerIndex = chain.findIndex((agent) => agent.id === callerAgentId);
|
|
312649
|
+
if (callerAgentId === target.id || callerIndex < 1) {
|
|
312650
|
+
return {
|
|
312651
|
+
kind: "error",
|
|
312652
|
+
response: {
|
|
312653
|
+
content: [{ type: "text", text: "ERROR: You can only access evaluations for your own direct or indirect reports." }],
|
|
312654
|
+
isError: true,
|
|
312655
|
+
details: {
|
|
312656
|
+
outcome: "denied",
|
|
312657
|
+
agentId: target.id,
|
|
312658
|
+
callerAgentId,
|
|
312659
|
+
rule: "direct-or-indirect-reports-only"
|
|
312660
|
+
}
|
|
312661
|
+
}
|
|
312662
|
+
};
|
|
312663
|
+
}
|
|
312664
|
+
}
|
|
312665
|
+
return { kind: "allowed", target, callerAgentId };
|
|
312666
|
+
}
|
|
312364
312667
|
function emitSecretAudit(store, ctx, mutationType, target, metadata) {
|
|
312365
312668
|
if (!ctx.runId || !ctx.agentId) return;
|
|
312366
312669
|
try {
|
|
@@ -316433,6 +316736,143 @@ Status: ${updated.status}`
|
|
|
316433
316736
|
};
|
|
316434
316737
|
}
|
|
316435
316738
|
});
|
|
316739
|
+
pi2.registerTool({
|
|
316740
|
+
name: "fn_agent_read_evaluations",
|
|
316741
|
+
label: "fn: Read Report Evaluations",
|
|
316742
|
+
description: "Read ratings, feedback, reflections, and performance data for a direct or indirect report.",
|
|
316743
|
+
promptSnippet: "Review evaluation and reflection results for an agent in your management subtree",
|
|
316744
|
+
promptGuidelines: [
|
|
316745
|
+
"Use to review evaluation data for a direct or indirect report in your management subtree",
|
|
316746
|
+
"Agent callers cannot target themselves, peers, ancestors, or agents outside their subtree",
|
|
316747
|
+
"Operator and CLI calls are privileged and may read any durable agent"
|
|
316748
|
+
],
|
|
316749
|
+
parameters: Type12.Object({
|
|
316750
|
+
agent_id: Type12.String({ description: "Target agent ID or resolvable name" }),
|
|
316751
|
+
rating_limit: Type12.Optional(Type12.Number({ minimum: 1, maximum: 50, description: "Maximum ratings to return (default 10)" })),
|
|
316752
|
+
reflection_limit: Type12.Optional(Type12.Number({ minimum: 1, maximum: 20, description: "Maximum reflections to return (default 5)" }))
|
|
316753
|
+
}),
|
|
316754
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
316755
|
+
const agentStore = await getAgentStore(ctx.cwd);
|
|
316756
|
+
await agentStore.init();
|
|
316757
|
+
const resolved = await resolveManagerEvaluationTarget(agentStore, params.agent_id, ctx);
|
|
316758
|
+
if (resolved.kind === "error") return resolved.response;
|
|
316759
|
+
const ratingLimit = params.rating_limit ?? 10;
|
|
316760
|
+
const reflectionLimit = params.reflection_limit ?? 5;
|
|
316761
|
+
const reflectionStore = new ReflectionStore({ rootDir: getFusionDir(ctx.cwd) });
|
|
316762
|
+
await reflectionStore.init();
|
|
316763
|
+
const [summary, ratings, latestReflection, reflections, performance4] = await Promise.all([
|
|
316764
|
+
agentStore.getRatingSummary(resolved.target.id),
|
|
316765
|
+
agentStore.getRatings(resolved.target.id, { limit: ratingLimit }),
|
|
316766
|
+
reflectionStore.getLatestReflection(resolved.target.id),
|
|
316767
|
+
reflectionStore.getReflections(resolved.target.id, reflectionLimit),
|
|
316768
|
+
reflectionStore.getPerformanceSummary(resolved.target.id)
|
|
316769
|
+
]);
|
|
316770
|
+
const hasRatings = ratings.length > 0 || summary.totalRatings > 0;
|
|
316771
|
+
const hasReflections = Boolean(latestReflection) || reflections.length > 0;
|
|
316772
|
+
if (!hasRatings && !hasReflections) {
|
|
316773
|
+
return {
|
|
316774
|
+
content: [{ type: "text", text: `${resolved.target.name} (${resolved.target.id})
|
|
316775
|
+
|
|
316776
|
+
No evaluation data available yet.` }],
|
|
316777
|
+
details: { outcome: "empty", agentId: resolved.target.id, agentName: resolved.target.name, summary, ratings, reflections, latestReflection, performance: performance4 }
|
|
316778
|
+
};
|
|
316779
|
+
}
|
|
316780
|
+
const formatScore2 = (score) => typeof score === "number" && Number.isFinite(score) ? score.toFixed(2) : "n/a";
|
|
316781
|
+
const lines = [
|
|
316782
|
+
`Evaluation Summary: ${resolved.target.name} (${resolved.target.id})`,
|
|
316783
|
+
`- Average score: ${formatScore2(summary.averageScore)}`,
|
|
316784
|
+
`- Trend: ${summary.trend}`,
|
|
316785
|
+
`- Total ratings: ${summary.totalRatings}`
|
|
316786
|
+
];
|
|
316787
|
+
const categoryEntries = Object.entries(summary.categoryAverages ?? {});
|
|
316788
|
+
if (categoryEntries.length > 0) {
|
|
316789
|
+
lines.push("", "Category averages:");
|
|
316790
|
+
categoryEntries.forEach(([category, score]) => lines.push(`- ${category}: ${formatScore2(score)}`));
|
|
316791
|
+
}
|
|
316792
|
+
const commentedRatings = ratings.filter((rating) => rating.comment?.trim());
|
|
316793
|
+
if (commentedRatings.length > 0) {
|
|
316794
|
+
lines.push("", "Recent rating comments:");
|
|
316795
|
+
commentedRatings.slice(0, 5).forEach((rating) => lines.push(`- [${rating.score}/5] ${rating.comment.trim()}`));
|
|
316796
|
+
}
|
|
316797
|
+
if (latestReflection) {
|
|
316798
|
+
lines.push("", "Latest reflection:", `- Summary: ${latestReflection.summary}`);
|
|
316799
|
+
if (latestReflection.insights.length > 0) {
|
|
316800
|
+
lines.push("- Insights:");
|
|
316801
|
+
latestReflection.insights.forEach((insight) => lines.push(` - ${insight}`));
|
|
316802
|
+
}
|
|
316803
|
+
if (latestReflection.suggestedImprovements.length > 0) {
|
|
316804
|
+
lines.push("- Suggested improvements:");
|
|
316805
|
+
latestReflection.suggestedImprovements.forEach((item) => lines.push(` - ${item}`));
|
|
316806
|
+
}
|
|
316807
|
+
}
|
|
316808
|
+
if (reflections.length > 0) {
|
|
316809
|
+
lines.push("", "Recent reflection history:");
|
|
316810
|
+
reflections.slice(0, 5).forEach((reflection) => lines.push(`- ${reflection.timestamp}: ${reflection.summary}`));
|
|
316811
|
+
}
|
|
316812
|
+
return {
|
|
316813
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
316814
|
+
details: { outcome: "read", agentId: resolved.target.id, agentName: resolved.target.name, summary, ratings, reflections, latestReflection, performance: performance4 }
|
|
316815
|
+
};
|
|
316816
|
+
}
|
|
316817
|
+
});
|
|
316818
|
+
pi2.registerTool({
|
|
316819
|
+
name: "fn_agent_evaluation_followup",
|
|
316820
|
+
label: "fn: Record Evaluation Follow-up",
|
|
316821
|
+
description: "Record a coaching evaluation follow-up for a direct or indirect report to read through its self-improvement loop.",
|
|
316822
|
+
promptSnippet: "Record coaching feedback for an agent in your management subtree",
|
|
316823
|
+
promptGuidelines: [
|
|
316824
|
+
"Use to record actionable coaching feedback for a direct or indirect report",
|
|
316825
|
+
"Agent callers cannot target themselves, peers, ancestors, or agents outside their subtree",
|
|
316826
|
+
"Create or delegate separate implementation work with fn_task_create or fn_delegate_task"
|
|
316827
|
+
],
|
|
316828
|
+
parameters: Type12.Object({
|
|
316829
|
+
agent_id: Type12.String({ description: "Target agent ID or resolvable name" }),
|
|
316830
|
+
score: Type12.Number({ minimum: 1, maximum: 5, description: "Evaluation score from 1 to 5" }),
|
|
316831
|
+
comment: Type12.String({ minLength: 1, maxLength: 4e3, description: "Coaching or follow-up note" }),
|
|
316832
|
+
category: Type12.Optional(Type12.String({ maxLength: 100, description: "Optional evaluation category" })),
|
|
316833
|
+
task_id: Type12.Optional(Type12.String({ description: "Optional related task ID" }))
|
|
316834
|
+
}),
|
|
316835
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
316836
|
+
const gated = await applyAgentPolicyGateForExtensionTool(
|
|
316837
|
+
"fn_agent_evaluation_followup",
|
|
316838
|
+
params,
|
|
316839
|
+
ctx
|
|
316840
|
+
);
|
|
316841
|
+
if (gated) return gated;
|
|
316842
|
+
const agentStore = await getAgentStore(ctx.cwd);
|
|
316843
|
+
await agentStore.init();
|
|
316844
|
+
const resolved = await resolveManagerEvaluationTarget(agentStore, params.agent_id, ctx);
|
|
316845
|
+
if (resolved.kind === "error") return resolved.response;
|
|
316846
|
+
if (!Number.isFinite(params.score) || params.score < 1 || params.score > 5) {
|
|
316847
|
+
return {
|
|
316848
|
+
content: [{ type: "text", text: "ERROR: score must be a finite value from 1 to 5" }],
|
|
316849
|
+
isError: true,
|
|
316850
|
+
details: { outcome: "invalid", field: "score" }
|
|
316851
|
+
};
|
|
316852
|
+
}
|
|
316853
|
+
const comment = params.comment.trim();
|
|
316854
|
+
if (!comment) {
|
|
316855
|
+
return {
|
|
316856
|
+
content: [{ type: "text", text: "ERROR: comment must not be empty" }],
|
|
316857
|
+
isError: true,
|
|
316858
|
+
details: { outcome: "invalid", field: "comment" }
|
|
316859
|
+
};
|
|
316860
|
+
}
|
|
316861
|
+
const raterType = resolved.callerAgentId ? "agent" : "user";
|
|
316862
|
+
const rating = await agentStore.addRating(resolved.target.id, {
|
|
316863
|
+
raterType,
|
|
316864
|
+
...resolved.callerAgentId ? { raterId: resolved.callerAgentId } : {},
|
|
316865
|
+
score: params.score,
|
|
316866
|
+
...params.category !== void 0 ? { category: params.category } : {},
|
|
316867
|
+
comment,
|
|
316868
|
+
...params.task_id !== void 0 ? { taskId: params.task_id } : {}
|
|
316869
|
+
});
|
|
316870
|
+
return {
|
|
316871
|
+
content: [{ type: "text", text: `Recorded evaluation follow-up for ${resolved.target.name} (${resolved.target.id}).` }],
|
|
316872
|
+
details: { outcome: "recorded", agentId: resolved.target.id, ratingId: rating.id, score: rating.score, raterType }
|
|
316873
|
+
};
|
|
316874
|
+
}
|
|
316875
|
+
});
|
|
316436
316876
|
pi2.registerTool({
|
|
316437
316877
|
name: "fn_agent_delete",
|
|
316438
316878
|
label: "fn: Delete Agent",
|