@runfusion/fusion 0.73.0-beta.6 → 0.74.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/bin.js +524 -106
  2. package/dist/child-process-worker.js +252 -29
  3. package/dist/client/.vite/manifest.json +263 -263
  4. package/dist/client/assets/{AgentDetailView-jg-430Wv.js → AgentDetailView-CUXS0Odh.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-0iybC0Dg.js → AgentPermissionPolicyEditor-CzjHjB5r.js} +1 -1
  6. package/dist/client/assets/{AgentsView-DeVI7IJy.js → AgentsView-B5stgI5m.js} +3 -3
  7. package/dist/client/assets/ChatView-CpoOgZ4X.js +13 -0
  8. package/dist/client/assets/{CommandCenter-CPpYSmxm.js → CommandCenter-BdEQ_ZOX.js} +1 -1
  9. package/dist/client/assets/{DevServerView-C7Uib0ck.js → DevServerView-BHgAmF3y.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-Ba9x3E72.js → DirectoryPicker-BQXVc5YW.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-DkuxxEAC.js → DocumentsView-CxN0Ptrj.js} +1 -1
  12. package/dist/client/assets/{EvalsView-DwRsXihY.js → EvalsView-DAgJtpO5.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-C2g8TiAY.js → ExperimentalAgentOnboardingModal-NZcXkGrN.js} +1 -1
  14. package/dist/client/assets/{GoalsView-hQSajINq.js → GoalsView-Dwq7NW4j.js} +1 -1
  15. package/dist/client/assets/{InsightsView-p7j5T5a8.js → InsightsView-CUlL5NSC.js} +1 -1
  16. package/dist/client/assets/{MemoryView-DoVBk38U.js → MemoryView-WfHzJflp.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-DzT94cPg.js → PiExtensionsManager-BS1dkauB.js} +1 -1
  18. package/dist/client/assets/{PluginManager-5DK-HUkf.js → PluginManager-B1oLb0pn.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-c8_Nl91A.js → PullRequestView-Cdp662lx.js} +1 -1
  20. package/dist/client/assets/{ReportModal-BfNu73zb.js → ReportModal-C92wQO-k.js} +1 -1
  21. package/dist/client/assets/{ResearchView-Cc_DZq5v.js → ResearchView-4-SoxmQv.js} +1 -1
  22. package/dist/client/assets/{SecretsView-DMETxbnI.js → SecretsView-C5UQ1Mms.js} +1 -1
  23. package/dist/client/assets/SessionTerminal-BTjX9p3a.js +2 -0
  24. package/dist/client/assets/SettingsModal-BcnOOo9g.js +21 -0
  25. package/dist/client/assets/{SettingsModal-oTMDyzjF.js → SettingsModal-BfHAE14s.js} +1 -1
  26. package/dist/client/assets/{SettingsTextareaRow-B63cJNsI.js → SettingsTextareaRow-C2JqzQdD.js} +1 -1
  27. package/dist/client/assets/{SetupWizardModal-BZnyRPT7.js → SetupWizardModal-C1KmMVfU.js} +2 -2
  28. package/dist/client/assets/{SkillsView-DGwWIOqX.js → SkillsView-DyLNdfDy.js} +1 -1
  29. package/dist/client/assets/{TodoView-BoLH6qHP.js → TodoView-DyrniX19.js} +1 -1
  30. package/dist/client/assets/{WorkflowNodeEditor-DHqpPcSv.js → WorkflowNodeEditor-Bh-Hn1Kx.js} +1 -1
  31. package/dist/client/assets/{agent-import-generation-Dl3UAfFr.js → agent-import-generation-C5pyefIj.js} +1 -1
  32. package/dist/client/assets/{app-B4dURBVF.js → app-Bl764LdY.js} +1 -1
  33. package/dist/client/assets/{app-DxbSLeuH.js → app-DNrauoYS.js} +1 -1
  34. package/dist/client/assets/{app-DfQxLcCr.js → app-DdCnRHSe.js} +1 -1
  35. package/dist/client/assets/{app-R0cG-sq5.js → app-QmIotwFZ.js} +1 -1
  36. package/dist/client/assets/{app-DLG7AA6O.js → app-YM47G7Ks.js} +1 -1
  37. package/dist/client/assets/{app-JOLkwq4O.js → app-oUEtzFOj.js} +1 -1
  38. package/dist/client/assets/{architectureDiagram-3BPJPVTR-DRSMeXsR.js → architectureDiagram-3BPJPVTR-B6axGlaS.js} +1 -1
  39. package/dist/client/assets/{blockDiagram-GPEHLZMM-xBxQf_Gy.js → blockDiagram-GPEHLZMM-BENjJaZD.js} +1 -1
  40. package/dist/client/assets/{c4Diagram-AAUBKEIU-CememwlP.js → c4Diagram-AAUBKEIU-Cl2qKhuO.js} +1 -1
  41. package/dist/client/assets/channel-CktWdAhK.js +1 -0
  42. package/dist/client/assets/{chunk-2J33WTMH-B62t8Ow1.js → chunk-2J33WTMH-BWo7R8T7.js} +1 -1
  43. package/dist/client/assets/{chunk-4BX2VUAB-CHzxnH6A.js → chunk-4BX2VUAB-DiRoI7pq.js} +1 -1
  44. package/dist/client/assets/{chunk-55IACEB6-BXJotoWf.js → chunk-55IACEB6-DPtv1GVO.js} +1 -1
  45. package/dist/client/assets/{chunk-727SXJPM-DGFhyp03.js → chunk-727SXJPM-BVcm5ITs.js} +1 -1
  46. package/dist/client/assets/{chunk-AQP2D5EJ-C-nRZZBE.js → chunk-AQP2D5EJ-CFT4bmXK.js} +1 -1
  47. package/dist/client/assets/{chunk-FMBD7UC4-CFS2iW51.js → chunk-FMBD7UC4-BDcEHQ0o.js} +1 -1
  48. package/dist/client/assets/{chunk-ND2GUHAM-DFleK3tP.js → chunk-ND2GUHAM-CYlDBFdI.js} +1 -1
  49. package/dist/client/assets/{chunk-QZHKN3VN-E7rqTspj.js → chunk-QZHKN3VN-3Wv3WxYt.js} +1 -1
  50. package/dist/client/assets/classDiagram-4FO5ZUOK-CrUS4gHO.js +1 -0
  51. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CrUS4gHO.js +1 -0
  52. package/dist/client/assets/{cose-bilkent-S5V4N54A-VYcUIreA.js → cose-bilkent-S5V4N54A-BuMkKBMC.js} +1 -1
  53. package/dist/client/assets/{dagre-BM42HDAG-B4VeH0Nz.js → dagre-BM42HDAG-D1P4z_OM.js} +1 -1
  54. package/dist/client/assets/{dashboard-view-DoNpCbHQ.js → dashboard-view-BgQBLynI.js} +1 -1
  55. package/dist/client/assets/{dashboard-view-BpeWPcmh.js → dashboard-view-CcK2sH0v.js} +1 -1
  56. package/dist/client/assets/{dashboard-view-DGcOsOey.js → dashboard-view-DaRKU5oU.js} +1 -1
  57. package/dist/client/assets/{diagram-2AECGRRQ-BM8FU7fY.js → diagram-2AECGRRQ-hmY-reWF.js} +1 -1
  58. package/dist/client/assets/{diagram-5GNKFQAL-Do8IJG5T.js → diagram-5GNKFQAL-CGfRqm_0.js} +1 -1
  59. package/dist/client/assets/{diagram-KO2AKTUF-C_-zygdh.js → diagram-KO2AKTUF-BfKo4Jd4.js} +1 -1
  60. package/dist/client/assets/{diagram-LMA3HP47-CSPiBke9.js → diagram-LMA3HP47-BZqpNemd.js} +1 -1
  61. package/dist/client/assets/{diagram-OG6HWLK6-BVuoiZg-.js → diagram-OG6HWLK6-CxLTV4DH.js} +1 -1
  62. package/dist/client/assets/{erDiagram-TEJ5UH35-CIY48OYH.js → erDiagram-TEJ5UH35-vw3tx2tK.js} +1 -1
  63. package/dist/client/assets/{flowDiagram-I6XJVG4X-B6zav8SR.js → flowDiagram-I6XJVG4X-OEm-Us2U.js} +1 -1
  64. package/dist/client/assets/{folder-open-Dc23V8n6.js → folder-open-D_zgZHWi.js} +1 -1
  65. package/dist/client/assets/{ganttDiagram-6RSMTGT7-_F49rUcG.js → ganttDiagram-6RSMTGT7-C5bc1DG1.js} +1 -1
  66. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-Fk-V-buo.js → gitGraphDiagram-PVQCEYII-DEvcWRBq.js} +1 -1
  67. package/dist/client/assets/index-BinRUCFV.js +2661 -0
  68. package/dist/client/assets/index-DGmuyTtv.css +1 -0
  69. package/dist/client/assets/{infoDiagram-5YYISTIA-DvnBGHv4.js → infoDiagram-5YYISTIA-kFOE9wxd.js} +1 -1
  70. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-Df7TrITT.js → ishikawaDiagram-YF4QCWOH-DvLbzHmR.js} +1 -1
  71. package/dist/client/assets/{journeyDiagram-JHISSGLW-CieUO8Cz.js → journeyDiagram-JHISSGLW-ov6Tbcuz.js} +1 -1
  72. package/dist/client/assets/{kanban-definition-UN3LZRKU-BBR_Cj7I.js → kanban-definition-UN3LZRKU-Dr0foW2M.js} +1 -1
  73. package/dist/client/assets/{mermaid.core-whEVIkYk.js → mermaid.core-CM55309V.js} +4 -4
  74. package/dist/client/assets/{mindmap-definition-RKZ34NQL-utsoG884.js → mindmap-definition-RKZ34NQL-xNyB6Z6o.js} +1 -1
  75. package/dist/client/assets/{pieDiagram-4H26LBE5-B6_-ma_S.js → pieDiagram-4H26LBE5-DlS5Kpga.js} +1 -1
  76. package/dist/client/assets/{puzzle-CY7o6u4N.js → puzzle-BrEvi5DH.js} +1 -1
  77. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CCAEPNEU.js → quadrantDiagram-W4KKPZXB-D4z2CHAA.js} +1 -1
  78. package/dist/client/assets/{requirementDiagram-4Y6WPE33-C0rKKe1e.js → requirementDiagram-4Y6WPE33-Bcwt6-p9.js} +1 -1
  79. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DpeRsnkc.js → sankeyDiagram-5OEKKPKP-C54N76yk.js} +1 -1
  80. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DWYg86A1.js → sequenceDiagram-3UESZ5HK-DtqryztE.js} +1 -1
  81. package/dist/client/assets/{shield-alert-j_jHfoeI.js → shield-alert-DhxKVKek.js} +1 -1
  82. package/dist/client/assets/{standing-instructions-template-CCI99V8d.js → standing-instructions-template-CdHJwmLI.js} +1 -1
  83. package/dist/client/assets/{stateDiagram-AJRCARHV-CalOQ-6v.js → stateDiagram-AJRCARHV-DQAvSrHw.js} +1 -1
  84. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-Dd8RLebl.js → stateDiagram-v2-BHNVJYJU-BzIGKq7y.js} +1 -1
  85. package/dist/client/assets/{timeline-definition-PNZ67QCA-D1PZw-aB.js → timeline-definition-PNZ67QCA-GDj_48Um.js} +1 -1
  86. package/dist/client/assets/{upload-CFL3ZlNN.js → upload-B7GKZiF1.js} +1 -1
  87. package/dist/client/assets/{users-DGOPLxzy.js → users-CBtvFVLM.js} +1 -1
  88. package/dist/client/assets/{vennDiagram-CIIHVFJN-DKQAihMR.js → vennDiagram-CIIHVFJN-PQDmLFbj.js} +1 -1
  89. package/dist/client/assets/{wardley-L42UT6IY-B_XzYoGe.js → wardley-L42UT6IY-GmGtXctI.js} +1 -1
  90. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DBu7IvQK.js → wardleyDiagram-YWT4CUSO-Bv6slmsW.js} +1 -1
  91. package/dist/client/assets/{xychartDiagram-2RQKCTM6-CKrqMXvh.js → xychartDiagram-2RQKCTM6-CK1RJHwB.js} +1 -1
  92. package/dist/client/index.html +2 -2
  93. package/dist/client/version.json +1 -1
  94. package/dist/extension.js +349 -60
  95. package/dist/migrations/0036_chat_session_tags.sql +64 -0
  96. package/dist/plugin-sdk/index.js +27 -1
  97. package/dist/plugins/fusion-plugin-hermes-runtime/.bundled.reload-1.js +8835 -0
  98. package/package.json +3 -3
  99. package/dist/client/assets/ChatView-BWosYwf6.js +0 -8
  100. package/dist/client/assets/SessionTerminal-B4c2w5zb.js +0 -2
  101. package/dist/client/assets/SettingsModal-vpkxpahA.js +0 -21
  102. package/dist/client/assets/channel-DwxxVJWv.js +0 -1
  103. package/dist/client/assets/classDiagram-4FO5ZUOK-CU_MxE3u.js +0 -1
  104. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CU_MxE3u.js +0 -1
  105. package/dist/client/assets/index-C77ORgtm.css +0 -1
  106. package/dist/client/assets/index-D8TQBkB7.js +0 -2661
@@ -783,7 +783,7 @@ var init_merge_queue = __esm({
783
783
  function isLocale(value) {
784
784
  return typeof value === "string" && SUPPORTED_LOCALES.includes(value);
785
785
  }
786
- var HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, REVIEW_ARTIFACTS_MODES, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE;
786
+ var HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, REVIEW_ARTIFACTS_MODES, ANTHROPIC_AUTH_PREFERENCES, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE;
787
787
  var init_execution_and_ui = __esm({
788
788
  "../core/src/types/execution-and-ui.ts"() {
789
789
  "use strict";
@@ -794,6 +794,7 @@ var init_execution_and_ui = __esm({
794
794
  PLANNER_OVERSIGHT_LEVELS = ["off", "observe", "steer", "autonomous"];
795
795
  DEFAULT_PLANNER_OVERSIGHT_LEVEL = "autonomous";
796
796
  REVIEW_ARTIFACTS_MODES = ["off", "user-facing", "on"];
797
+ ANTHROPIC_AUTH_PREFERENCES = ["api-key", "subscription"];
797
798
  THEME_MODES = ["dark", "light", "system"];
798
799
  COLOR_THEMES = [
799
800
  "default",
@@ -1607,6 +1608,12 @@ var init_settings_schema = __esm({
1607
1608
  FNXC:DashboardTheming 2026-07-03-00:00:
1608
1609
  Fresh installs must follow the operating system theme until the user explicitly chooses Light, Dark, or System. Keep this global default aligned with dashboard and desktop pre-hydration fallbacks.
1609
1610
  */
1611
+ /*
1612
+ FNXC:ProviderAuth 2026-07-24-17:05:
1613
+ Default to the historical precedence (raw API key beats subscription OAuth, FN-7391/FN-7396)
1614
+ so upgrading never silently moves an operator's traffic from their key onto their subscription.
1615
+ */
1616
+ anthropicAuthPreference: "api-key",
1610
1617
  themeMode: "system",
1611
1618
  /*
1612
1619
  FNXC:DashboardTheming 2026-06-30-00:00:
@@ -12875,7 +12882,9 @@ __export(project_exports, {
12875
12882
  chatRoomMembers: () => chatRoomMembers,
12876
12883
  chatRoomMessages: () => chatRoomMessages,
12877
12884
  chatRooms: () => chatRooms,
12885
+ chatSessionTags: () => chatSessionTags,
12878
12886
  chatSessions: () => chatSessions,
12887
+ chatTags: () => chatTags,
12879
12888
  chatTokenUsage: () => chatTokenUsage,
12880
12889
  cliSessions: () => cliSessions,
12881
12890
  completionHandoffMarkers: () => completionHandoffMarkers,
@@ -12952,7 +12961,7 @@ __export(project_exports, {
12952
12961
  workflowWorkItems: () => workflowWorkItems,
12953
12962
  workflows: () => workflows
12954
12963
  });
12955
- var projectSchema, tasks, config, legacyBoards, legacyProjectAuthUsers, legacyProjectAuthMemberships, legacyProjectAuthProviders, legacyProjectAuthSessions, legacyTaskReviewerRuns, distributedTaskIdState, distributedTaskIdReservations, symbolLocks, workflowSteps, workflows, taskWorkflowSelection, taskVerificationRequests, activityLog, archivedTasks, taskCommitAssociations, automations, agents, agentHeartbeats, agentRuns, agentTaskSessions, agentApiKeys, agentConfigRevisions, agentBlockedStates, mergeQueue, mergeRequests, completionHandoffMarkers, workflowWorkItems, workflowRunBranches, workflowRunStepInstances, workflowSettings, workflowPromptOverrides, configurationRevisions, taskDocuments, artifacts, taskDocumentRevisions, researchRuns, researchExports, researchRunEvents, experimentSessions, experimentSessionRecords, evalRuns, evalTaskResults, evalRunEvents, secrets, projectMeta, missions, branchGroups, pullRequests, pullRequestThreadState, goals, missionGoals, goalCitations, milestones, slices, missionFeatures, ideationSessions, ideationCandidates, missionEvents, plugins, routines, projectInsights, projectInsightRuns, projectInsightRunEvents, todoLists, todoItems, usageEvents, pluginActivations, knowledgePages, deployments, incidents, aiSessions, messages, agentRatings, chatSessions, cliSessions, chatMessages, chatTokenUsage, runAuditEvents, missionContractAssertions, missionFeatureAssertions, missionValidatorRuns, missionValidatorFailures, missionFixFeatureLineage, missionLineageStops, verificationCache, importTranslationCache, approvalRequests, approvalRequestAuditEvents, chatRooms, chatRoomMembers, chatRoomMessages, projectTableNames;
12964
+ var projectSchema, tasks, config, legacyBoards, legacyProjectAuthUsers, legacyProjectAuthMemberships, legacyProjectAuthProviders, legacyProjectAuthSessions, legacyTaskReviewerRuns, distributedTaskIdState, distributedTaskIdReservations, symbolLocks, workflowSteps, workflows, taskWorkflowSelection, taskVerificationRequests, activityLog, archivedTasks, taskCommitAssociations, automations, agents, agentHeartbeats, agentRuns, agentTaskSessions, agentApiKeys, agentConfigRevisions, agentBlockedStates, mergeQueue, mergeRequests, completionHandoffMarkers, workflowWorkItems, workflowRunBranches, workflowRunStepInstances, workflowSettings, workflowPromptOverrides, configurationRevisions, taskDocuments, artifacts, taskDocumentRevisions, researchRuns, researchExports, researchRunEvents, experimentSessions, experimentSessionRecords, evalRuns, evalTaskResults, evalRunEvents, secrets, projectMeta, missions, branchGroups, pullRequests, pullRequestThreadState, goals, missionGoals, goalCitations, milestones, slices, missionFeatures, ideationSessions, ideationCandidates, missionEvents, plugins, routines, projectInsights, projectInsightRuns, projectInsightRunEvents, todoLists, todoItems, usageEvents, pluginActivations, knowledgePages, deployments, incidents, aiSessions, messages, agentRatings, chatSessions, chatTags, chatSessionTags, cliSessions, chatMessages, chatTokenUsage, runAuditEvents, missionContractAssertions, missionFeatureAssertions, missionValidatorRuns, missionValidatorFailures, missionFixFeatureLineage, missionLineageStops, verificationCache, importTranslationCache, approvalRequests, approvalRequestAuditEvents, chatRooms, chatRoomMembers, chatRoomMessages, projectTableNames;
12956
12965
  var init_project = __esm({
12957
12966
  "../core/src/postgres/schema/project.ts"() {
12958
12967
  "use strict";
@@ -14663,7 +14672,33 @@ var init_project = __esm({
14663
14672
  cliExecutorAdapterId: text("cli_executor_adapter_id")
14664
14673
  }, (t) => [
14665
14674
  index("idxChatSessionsAgentId").on(t.agentId),
14666
- index("idxChatSessionsProjectId").on(t.projectId)
14675
+ index("idxChatSessionsProjectId").on(t.projectId),
14676
+ uniqueIndex("uqChatSessionsProjectIdId").on(t.projectId, t.id)
14677
+ ]);
14678
+ chatTags = projectSchema.table("chat_tags", {
14679
+ id: text("id").notNull(),
14680
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
14681
+ ownerProjectId: text("owner_project_id").notNull(),
14682
+ name: text("name").notNull(),
14683
+ normalizedName: text("normalized_name").notNull(),
14684
+ createdAt: text("created_at").notNull(),
14685
+ updatedAt: text("updated_at").notNull()
14686
+ }, (t) => [
14687
+ primaryKey({ columns: [t.projectId, t.id] }),
14688
+ uniqueIndex("uqChatTagsScopeName").on(t.projectId, t.normalizedName),
14689
+ index("idxChatTagsScopeName").on(t.projectId, t.normalizedName)
14690
+ ]);
14691
+ chatSessionTags = projectSchema.table("chat_session_tags", {
14692
+ sessionId: text("session_id").notNull(),
14693
+ tagId: text("tag_id").notNull(),
14694
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
14695
+ assignedAt: text("assigned_at").notNull()
14696
+ }, (t) => [
14697
+ // FNXC:ChatTags 2026-08-05-12:15: both parents include the RLS partition, preventing bypass/admin access from joining a same-named ID in another project.
14698
+ primaryKey({ columns: [t.projectId, t.sessionId, t.tagId] }),
14699
+ foreignKey({ columns: [t.projectId, t.sessionId], foreignColumns: [chatSessions.projectId, chatSessions.id] }).onDelete("cascade"),
14700
+ foreignKey({ columns: [t.projectId, t.tagId], foreignColumns: [chatTags.projectId, chatTags.id] }).onDelete("cascade"),
14701
+ index("idxChatSessionTagsTag").on(t.projectId, t.tagId, t.sessionId)
14667
14702
  ]);
14668
14703
  cliSessions = projectSchema.table("cli_sessions", {
14669
14704
  id: text("id").primaryKey(),
@@ -36606,6 +36641,7 @@ async function applySchemaBaseline(db, options = {}) {
36606
36641
  const taskWedgeNotificationAlreadyApplied = applied.includes(TASK_WEDGE_NOTIFICATION_VERSION);
36607
36642
  const milestoneAssertionProvenanceAlreadyApplied = applied.includes(MILESTONE_ASSERTION_PROVENANCE_VERSION);
36608
36643
  const missionLineageStopAlreadyApplied = applied.includes(MISSION_LINEAGE_STOP_VERSION);
36644
+ const chatSessionTagsAlreadyApplied = applied.includes(CHAT_SESSION_TAGS_VERSION);
36609
36645
  assertBinaryNotOlderThanDatabase(applied);
36610
36646
  let schemaChanged = false;
36611
36647
  if (!baselineAlreadyApplied) {
@@ -36951,17 +36987,23 @@ async function applySchemaBaseline(db, options = {}) {
36951
36987
  await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${MISSION_LINEAGE_STOP_VERSION}) ON CONFLICT (version) DO NOTHING`);
36952
36988
  schemaChanged = true;
36953
36989
  }
36990
+ if (!chatSessionTagsAlreadyApplied) {
36991
+ const migrationSql = await readFile4(CHAT_SESSION_TAGS_MIGRATION_PATH, "utf8");
36992
+ await tx.execute(sql.raw(migrationSql));
36993
+ await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${CHAT_SESSION_TAGS_VERSION}) ON CONFLICT (version) DO NOTHING`);
36994
+ schemaChanged = true;
36995
+ }
36954
36996
  return { applied: schemaChanged, pluginHooksRun: pluginHooks.length };
36955
36997
  });
36956
36998
  }
36957
- 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, 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;
36999
+ 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, 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;
36958
37000
  var init_schema_applier = __esm({
36959
37001
  "../core/src/postgres/schema-applier.ts"() {
36960
37002
  "use strict";
36961
37003
  init_drizzle_orm();
36962
37004
  init_plugin_schema_hook();
36963
37005
  init_advisory_locks();
36964
- SCHEMA_BASELINE_VERSION = "0035";
37006
+ SCHEMA_BASELINE_VERSION = "0036";
36965
37007
  TASK_DECLARED_SYMBOLS_VERSION = "0028";
36966
37008
  INITIAL_SCHEMA_VERSION = "0000";
36967
37009
  AUTOMATION_ISOLATION_SCHEMA_VERSION = "0001";
@@ -36997,6 +37039,7 @@ var init_schema_applier = __esm({
36997
37039
  TASK_WEDGE_NOTIFICATION_VERSION = "0033";
36998
37040
  MILESTONE_ASSERTION_PROVENANCE_VERSION = "0034";
36999
37041
  MISSION_LINEAGE_STOP_VERSION = "0035";
37042
+ CHAT_SESSION_TAGS_VERSION = "0036";
37000
37043
  LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION = "fusion_mark_legacy_adoption_drained";
37001
37044
  StaleBinarySchemaError = class extends Error {
37002
37045
  constructor(databaseVersion, binaryVersion) {
@@ -37112,6 +37155,7 @@ var init_schema_applier = __esm({
37112
37155
  "0034_milestone_assertion_provenance.sql"
37113
37156
  );
37114
37157
  MISSION_LINEAGE_STOP_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0035_fn_8543_mission_lineage_stop.sql");
37158
+ CHAT_SESSION_TAGS_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0036_chat_session_tags.sql");
37115
37159
  }
37116
37160
  });
37117
37161
 
@@ -63337,6 +63381,14 @@ function archiveEntryToTask(entry, slim = false) {
63337
63381
  planningStartedAt: entry.planningStartedAt,
63338
63382
  executionStartedAt: entry.executionStartedAt,
63339
63383
  executionCompletedAt: entry.executionCompletedAt,
63384
+ /*
63385
+ FNXC:ArchiveLifecycle 2026-07-24-11:02:
63386
+ FN-8561 needs archived TaskCard completion fallback to use the immutable
63387
+ archive transition, not the pre-archive columnMovedAt snapshot or updatedAt.
63388
+ Preserve archivedAt on every slim and full archive read without changing
63389
+ restore persistence semantics.
63390
+ */
63391
+ archivedAt: entry.archivedAt,
63340
63392
  modelPresetId: entry.modelPresetId,
63341
63393
  modelProvider: entry.modelProvider,
63342
63394
  modelId: entry.modelId,
@@ -127078,9 +127130,14 @@ var init_org_bundle = __esm({
127078
127130
  });
127079
127131
 
127080
127132
  // ../core/src/async-chat-store.ts
127133
+ import { randomUUID as randomUUID41 } from "node:crypto";
127134
+ function rowToTag(row) {
127135
+ return { id: row.id, projectId: row.ownerProjectId === "__default__" ? null : row.ownerProjectId, name: row.name, createdAt: row.createdAt, updatedAt: row.updatedAt };
127136
+ }
127081
127137
  function rowToSession3(row) {
127082
127138
  return {
127083
127139
  id: row.id,
127140
+ tags: [],
127084
127141
  agentId: row.agentId,
127085
127142
  title: row.title ?? null,
127086
127143
  status: row.status,
@@ -127169,7 +127226,7 @@ async function createChatSession(handle, session) {
127169
127226
  }
127170
127227
  async function getChatSession(handle, id) {
127171
127228
  const rows = await handle.select().from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
127172
- return rows[0] ? rowToSession3(rows[0]) : void 0;
127229
+ return rows[0] ? attachTags(handle, rowToSession3(rows[0])) : void 0;
127173
127230
  }
127174
127231
  async function listChatSessions(handle, options) {
127175
127232
  const conditions = [];
@@ -127178,12 +127235,104 @@ async function listChatSessions(handle, options) {
127178
127235
  if (options?.status) conditions.push(eq(project_exports.chatSessions.status, options.status));
127179
127236
  const query = handle.select().from(project_exports.chatSessions).orderBy(desc(project_exports.chatSessions.updatedAt));
127180
127237
  const rows = conditions.length > 0 ? await query.where(and(...conditions)) : await query;
127181
- return rows.map(rowToSession3);
127238
+ return attachTagsToSessions(handle, rows.map(rowToSession3));
127182
127239
  }
127183
127240
  async function deleteChatSession(handle, id) {
127184
- const result = await handle.delete(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id)).returning({ id: project_exports.chatSessions.id });
127241
+ const [session] = await handle.select({ projectId: project_exports.chatSessions.projectId }).from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
127242
+ if (!session) return false;
127243
+ const sessionProjectId = session.projectId;
127244
+ if (!sessionProjectId) throw new Error("Chat session is missing its required project partition");
127245
+ await handle.delete(project_exports.chatSessionTags).where(and(
127246
+ eq(project_exports.chatSessionTags.sessionId, id),
127247
+ eq(project_exports.chatSessionTags.projectId, sessionProjectId)
127248
+ ));
127249
+ const result = await handle.delete(project_exports.chatSessions).where(and(eq(project_exports.chatSessions.id, id), eq(project_exports.chatSessions.projectId, sessionProjectId))).returning({ id: project_exports.chatSessions.id });
127185
127250
  return result.length > 0;
127186
127251
  }
127252
+ function tagScope(projectId) {
127253
+ return projectId ?? "__default__";
127254
+ }
127255
+ function normalizeTagName(name2) {
127256
+ const cleaned = name2.trim().replace(/\s+/g, " ");
127257
+ if (!cleaned || cleaned.length > 64) throw new Error("Tag name must be between 1 and 64 characters");
127258
+ return { name: cleaned, normalizedName: cleaned.toLocaleLowerCase() };
127259
+ }
127260
+ async function attachTags(handle, session) {
127261
+ const [attached] = await attachTagsToSessions(handle, [session]);
127262
+ return attached ?? session;
127263
+ }
127264
+ async function attachTagsToSessions(handle, sessions) {
127265
+ if (!sessions.length) return sessions;
127266
+ const rows = await handle.select({ sessionId: project_exports.chatSessionTags.sessionId, id: project_exports.chatTags.id, ownerProjectId: project_exports.chatTags.ownerProjectId, name: project_exports.chatTags.name, createdAt: project_exports.chatTags.createdAt, updatedAt: project_exports.chatTags.updatedAt }).from(project_exports.chatSessionTags).innerJoin(project_exports.chatTags, and(
127267
+ eq(project_exports.chatSessionTags.tagId, project_exports.chatTags.id),
127268
+ eq(project_exports.chatSessionTags.projectId, project_exports.chatTags.projectId)
127269
+ )).innerJoin(project_exports.chatSessions, and(
127270
+ eq(project_exports.chatSessionTags.sessionId, project_exports.chatSessions.id),
127271
+ eq(project_exports.chatSessionTags.projectId, project_exports.chatSessions.projectId)
127272
+ )).where(inArray(project_exports.chatSessionTags.sessionId, sessions.map((session) => session.id))).orderBy(asc(project_exports.chatTags.normalizedName), asc(project_exports.chatTags.id));
127273
+ const tagsBySession = /* @__PURE__ */ new Map();
127274
+ for (const row of rows) {
127275
+ const tags = tagsBySession.get(row.sessionId) ?? [];
127276
+ tags.push(rowToTag(row));
127277
+ tagsBySession.set(row.sessionId, tags);
127278
+ }
127279
+ return sessions.map((session) => ({ ...session, tags: tagsBySession.get(session.id) ?? [] }));
127280
+ }
127281
+ async function listChatTags(handle, projectId) {
127282
+ const rows = await handle.select().from(project_exports.chatTags).where(eq(project_exports.chatTags.ownerProjectId, tagScope(projectId))).orderBy(asc(project_exports.chatTags.normalizedName), asc(project_exports.chatTags.id));
127283
+ return rows.map(rowToTag);
127284
+ }
127285
+ async function createChatTag(layer, input) {
127286
+ const { name: name2, normalizedName } = normalizeTagName(input.name);
127287
+ const projectId = input.projectId ?? null;
127288
+ const now = (/* @__PURE__ */ new Date()).toISOString();
127289
+ return layer.transactionImmediate(async (tx) => {
127290
+ const id = `chat-tag-${randomUUID41().slice(0, 8)}`;
127291
+ const rows = await tx.insert(project_exports.chatTags).values({ id, ownerProjectId: tagScope(projectId), name: name2, normalizedName, createdAt: now, updatedAt: now }).onConflictDoNothing().returning();
127292
+ if (!rows[0]) throw new Error("A tag with that name already exists");
127293
+ return rowToTag(rows[0]);
127294
+ });
127295
+ }
127296
+ async function renameChatTag(layer, id, projectId, input) {
127297
+ const { name: name2, normalizedName } = normalizeTagName(input.name);
127298
+ return layer.transactionImmediate(async (tx) => {
127299
+ const rows = await tx.update(project_exports.chatTags).set({ name: name2, normalizedName, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.ownerProjectId, tagScope(projectId)))).returning();
127300
+ if (!rows[0]) return void 0;
127301
+ return rowToTag(rows[0]);
127302
+ });
127303
+ }
127304
+ async function deleteChatTag(layer, id, projectId) {
127305
+ return layer.transactionImmediate(async (tx) => {
127306
+ const [tag] = await tx.select({ projectId: project_exports.chatTags.projectId }).from(project_exports.chatTags).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.ownerProjectId, tagScope(projectId))));
127307
+ if (!tag?.projectId) return false;
127308
+ const tagProjectId = tag.projectId;
127309
+ await tx.delete(project_exports.chatSessionTags).where(and(
127310
+ eq(project_exports.chatSessionTags.tagId, id),
127311
+ eq(project_exports.chatSessionTags.projectId, tagProjectId)
127312
+ ));
127313
+ return (await tx.delete(project_exports.chatTags).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.projectId, tagProjectId))).returning({ id: project_exports.chatTags.id })).length > 0;
127314
+ });
127315
+ }
127316
+ async function replaceChatSessionTags(layer, sessionId, projectId, tagIds) {
127317
+ return layer.transactionImmediate(async (tx) => {
127318
+ const session = await getChatSessionForUpdate(tx, sessionId);
127319
+ if (!session || session.projectId !== projectId) return void 0;
127320
+ const ownerProjectCondition = projectId === null ? isNull(project_exports.chatSessions.ownerProjectId) : eq(project_exports.chatSessions.ownerProjectId, projectId);
127321
+ const [sessionPartition] = await tx.select({ projectId: project_exports.chatSessions.projectId }).from(project_exports.chatSessions).where(and(eq(project_exports.chatSessions.id, sessionId), ownerProjectCondition)).for("update");
127322
+ if (!sessionPartition?.projectId) return void 0;
127323
+ const sessionProjectId = sessionPartition.projectId;
127324
+ const uniqueIds = [...new Set(tagIds)];
127325
+ const tags = uniqueIds.length ? await tx.select().from(project_exports.chatTags).where(and(
127326
+ inArray(project_exports.chatTags.id, uniqueIds),
127327
+ eq(project_exports.chatTags.ownerProjectId, tagScope(projectId)),
127328
+ eq(project_exports.chatTags.projectId, sessionProjectId)
127329
+ )) : [];
127330
+ if (tags.length !== uniqueIds.length) throw new Error("One or more tags do not belong to this project");
127331
+ await tx.delete(project_exports.chatSessionTags).where(and(eq(project_exports.chatSessionTags.sessionId, sessionId), eq(project_exports.chatSessionTags.projectId, sessionProjectId)));
127332
+ if (uniqueIds.length) await tx.insert(project_exports.chatSessionTags).values(uniqueIds.map((tagId) => ({ projectId: sessionProjectId, sessionId, tagId, assignedAt: (/* @__PURE__ */ new Date()).toISOString() }))).onConflictDoNothing();
127333
+ return attachTags(tx, session);
127334
+ });
127335
+ }
127187
127336
  async function addChatMessage(handle, message) {
127188
127337
  const sanitizedAttachments = message.attachments === void 0 ? void 0 : sanitizeJsonbValue(message.attachments);
127189
127338
  const sanitized = {
@@ -127575,7 +127724,7 @@ var init_async_chat_store = __esm({
127575
127724
 
127576
127725
  // ../core/src/chat-store.ts
127577
127726
  import { EventEmitter as EventEmitter24 } from "node:events";
127578
- import { randomUUID as randomUUID41 } from "node:crypto";
127727
+ import { randomUUID as randomUUID42 } from "node:crypto";
127579
127728
  var ChatStore;
127580
127729
  var init_chat_store = __esm({
127581
127730
  "../core/src/chat-store.ts"() {
@@ -127610,8 +127759,9 @@ var init_chat_store = __esm({
127610
127759
  async createSession(input) {
127611
127760
  const now = (/* @__PURE__ */ new Date()).toISOString();
127612
127761
  const session = {
127613
- id: `chat-${randomUUID41().slice(0, 8)}`,
127762
+ id: `chat-${randomUUID42().slice(0, 8)}`,
127614
127763
  agentId: input.agentId,
127764
+ tags: [],
127615
127765
  title: input.title ?? null,
127616
127766
  status: "active",
127617
127767
  projectId: input.projectId ?? null,
@@ -127781,6 +127931,29 @@ var init_chat_store = __esm({
127781
127931
  }
127782
127932
  return deletedCount;
127783
127933
  }
127934
+ /*
127935
+ FNXC:ChatTags 2026-08-05-10:55:
127936
+ Direct-conversation tags are project-scoped by the session's owner project.
127937
+ Tag mutations are transactional and return an enriched session so SSE clients
127938
+ never receive an assignment update without its deterministic tag array.
127939
+ */
127940
+ async listTags(projectId = null) {
127941
+ return listChatTags(this.asyncLayer.db, projectId);
127942
+ }
127943
+ async createTag(input) {
127944
+ return createChatTag(this.asyncLayer, input);
127945
+ }
127946
+ async renameTag(id, projectId, input) {
127947
+ return renameChatTag(this.asyncLayer, id, projectId, input);
127948
+ }
127949
+ async deleteTag(id, projectId) {
127950
+ return deleteChatTag(this.asyncLayer, id, projectId);
127951
+ }
127952
+ async replaceSessionTags(id, projectId, tagIds) {
127953
+ const updated = await replaceChatSessionTags(this.asyncLayer, id, projectId, tagIds);
127954
+ if (updated) this.emit("chat:session:updated", updated);
127955
+ return updated;
127956
+ }
127784
127957
  // ── Message CRUD Operations ───────────────────────────────────────
127785
127958
  /**
127786
127959
  * Add a message to a chat session.
@@ -127797,7 +127970,7 @@ var init_chat_store = __esm({
127797
127970
  }
127798
127971
  const now = (/* @__PURE__ */ new Date()).toISOString();
127799
127972
  const message = {
127800
- id: `msg-${randomUUID41().slice(0, 8)}`,
127973
+ id: `msg-${randomUUID42().slice(0, 8)}`,
127801
127974
  sessionId,
127802
127975
  role: input.role,
127803
127976
  content: input.content,
@@ -127939,7 +128112,7 @@ var init_chat_store = __esm({
127939
128112
  if (!slug) throw new Error("Room name must include letters or numbers");
127940
128113
  const now = (/* @__PURE__ */ new Date()).toISOString();
127941
128114
  const room = {
127942
- id: `room-${randomUUID41().slice(0, 8)}`,
128115
+ id: `room-${randomUUID42().slice(0, 8)}`,
127943
128116
  name: normalizedName,
127944
128117
  slug,
127945
128118
  description: input.description ?? null,
@@ -128031,7 +128204,7 @@ var init_chat_store = __esm({
128031
128204
  }
128032
128205
  const now = (/* @__PURE__ */ new Date()).toISOString();
128033
128206
  const message = {
128034
- id: `rmsg-${randomUUID41().slice(0, 8)}`,
128207
+ id: `rmsg-${randomUUID42().slice(0, 8)}`,
128035
128208
  roomId,
128036
128209
  role: input.role,
128037
128210
  content: input.content,
@@ -128086,7 +128259,7 @@ var init_chat_store = __esm({
128086
128259
  return void 0;
128087
128260
  }
128088
128261
  const record2 = {
128089
- id: `chat-tokens-${randomUUID41().slice(0, 12)}`,
128262
+ id: `chat-tokens-${randomUUID42().slice(0, 12)}`,
128090
128263
  sourceKind: input.sourceKind,
128091
128264
  chatSessionId: input.chatSessionId ?? null,
128092
128265
  roomId: input.roomId ?? null,
@@ -128182,7 +128355,7 @@ var init_cli_session_types = __esm({
128182
128355
  });
128183
128356
 
128184
128357
  // ../core/src/cli-session-store.ts
128185
- import { randomUUID as randomUUID42 } from "node:crypto";
128358
+ import { randomUUID as randomUUID43 } from "node:crypto";
128186
128359
  import { EventEmitter as EventEmitter25 } from "node:events";
128187
128360
  function parsePosture(value) {
128188
128361
  return fromJson(value) ?? null;
@@ -128264,7 +128437,7 @@ var init_cli_session_store = __esm({
128264
128437
  if (!input.adapterId) throw new Error("CLI session requires an adapterId");
128265
128438
  const now = (/* @__PURE__ */ new Date()).toISOString();
128266
128439
  const session = {
128267
- id: input.id ?? `cli-${randomUUID42().slice(0, 8)}`,
128440
+ id: input.id ?? `cli-${randomUUID43().slice(0, 8)}`,
128268
128441
  taskId: input.taskId ?? null,
128269
128442
  chatSessionId: input.chatSessionId ?? null,
128270
128443
  purpose: input.purpose,
@@ -128657,7 +128830,7 @@ var init_task_prefix = __esm({
128657
128830
  });
128658
128831
 
128659
128832
  // ../core/src/task-store/async-monitor.ts
128660
- import { randomUUID as randomUUID43 } from "node:crypto";
128833
+ import { randomUUID as randomUUID44 } from "node:crypto";
128661
128834
  function monitorProjectPartition(projectId) {
128662
128835
  return projectId.trim() || "__legacy_unscoped__";
128663
128836
  }
@@ -128701,7 +128874,7 @@ function incidentFromRow(row) {
128701
128874
  }
128702
128875
  async function recordDeploymentAsync(db, input, projectId = "") {
128703
128876
  const ownerProjectId = monitorProjectPartition(projectId);
128704
- const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID43()}`;
128877
+ const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID44()}`;
128705
128878
  const now = (/* @__PURE__ */ new Date()).toISOString();
128706
128879
  const deployedAt = input.deployedAt ?? now;
128707
128880
  await db.insert(project_exports.deployments).values({
@@ -128759,7 +128932,7 @@ async function ingestIncidentSignalAsync(db, input, projectId = "") {
128759
128932
  const updated = await getIncidentAsync(db, existing.incidentId, ownerProjectId);
128760
128933
  return { incident: updated ?? existing, created: false };
128761
128934
  }
128762
- const incidentId = `inc-${randomUUID43()}`;
128935
+ const incidentId = `inc-${randomUUID44()}`;
128763
128936
  const meta2 = {
128764
128937
  ...input.meta ?? {},
128765
128938
  [OCCURRENCES_META_KEY]: 1,
@@ -129347,6 +129520,7 @@ __export(src_exports, {
129347
129520
  AGENT_PERMISSION_POLICY_PRESET_IDS: () => AGENT_PERMISSION_POLICY_PRESET_IDS,
129348
129521
  AGENT_PROVISIONING_APPROVAL_MODES: () => AGENT_PROVISIONING_APPROVAL_MODES,
129349
129522
  AGENT_VALID_TRANSITIONS: () => AGENT_VALID_TRANSITIONS,
129523
+ ANTHROPIC_AUTH_PREFERENCES: () => ANTHROPIC_AUTH_PREFERENCES,
129350
129524
  ANTHROPIC_PROVIDER_ID: () => ANTHROPIC_PROVIDER_ID,
129351
129525
  APPROVAL_REQUEST_AUDIT_EVENT_TYPES: () => APPROVAL_REQUEST_AUDIT_EVENT_TYPES,
129352
129526
  APPROVAL_REQUEST_STATUSES: () => APPROVAL_REQUEST_STATUSES,
@@ -138290,6 +138464,26 @@ function resolveStoredCredentialApiKey(providerId, credential) {
138290
138464
  }
138291
138465
  return void 0;
138292
138466
  }
138467
+ function getFusionGlobalSettingsPath(home = getHomeDir5()) {
138468
+ const candidates = [
138469
+ join60(home, ".fusion", "settings.json"),
138470
+ join60(home, ".pi", "fusion", "settings.json"),
138471
+ join60(home, ".pi", "kb", "settings.json")
138472
+ ];
138473
+ return candidates.find((candidate) => existsSync48(candidate)) ?? candidates[0];
138474
+ }
138475
+ function readAnthropicAuthPreference(home = getHomeDir5()) {
138476
+ const settingsPath = getFusionGlobalSettingsPath(home);
138477
+ if (!existsSync48(settingsPath)) {
138478
+ return "api-key";
138479
+ }
138480
+ try {
138481
+ const parsed = JSON.parse(readFileSync14(settingsPath, "utf-8"));
138482
+ return parsed?.anthropicAuthPreference === "subscription" ? "subscription" : "api-key";
138483
+ } catch {
138484
+ return "api-key";
138485
+ }
138486
+ }
138293
138487
  function readModelsJsonApiKeys(home = getHomeDir5()) {
138294
138488
  const apiKeys = /* @__PURE__ */ new Map();
138295
138489
  const modelsPath = getModelRegistryModelsPath(home);
@@ -138495,11 +138689,15 @@ function createFusionAuthStorage() {
138495
138689
  };
138496
138690
  const resolveAnthropicRuntimeApiKey = async () => {
138497
138691
  const rawProviderLoggedOut = isAnthropicRawProviderLoggedOut();
138498
- if (!rawProviderLoggedOut) {
138692
+ const preferSubscription = readAnthropicAuthPreference() === "subscription";
138693
+ const resolveRawApiKey = () => {
138694
+ if (rawProviderLoggedOut) return void 0;
138499
138695
  const anthropicApiKeyCredential = selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "api_key");
138500
- if (anthropicApiKeyCredential) {
138501
- return resolveStoredCredentialApiKey(ANTHROPIC_PROVIDER_ID2, anthropicApiKeyCredential);
138502
- }
138696
+ return anthropicApiKeyCredential ? resolveStoredCredentialApiKey(ANTHROPIC_PROVIDER_ID2, anthropicApiKeyCredential) : void 0;
138697
+ };
138698
+ if (!preferSubscription) {
138699
+ const rawKey = resolveRawApiKey();
138700
+ if (rawKey) return rawKey;
138503
138701
  }
138504
138702
  const subscriptionLoggedOut = loggedOutProviders.has(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
138505
138703
  const legacyAnthropicOAuthCredential = rawProviderLoggedOut ? void 0 : selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "oauth");
@@ -138514,6 +138712,10 @@ function createFusionAuthStorage() {
138514
138712
  if (subscriptionKey) return subscriptionKey;
138515
138713
  }
138516
138714
  }
138715
+ if (preferSubscription) {
138716
+ const rawKey = resolveRawApiKey();
138717
+ if (rawKey) return rawKey;
138718
+ }
138517
138719
  if (!rawProviderLoggedOut) {
138518
138720
  const modelsJsonApiKey = modelsJsonApiKeys.get(ANTHROPIC_PROVIDER_ID2);
138519
138721
  if (modelsJsonApiKey) return modelsJsonApiKey;
@@ -169285,8 +169487,12 @@ var init_provider_registry = __esm({
169285
169487
  const maxResults = Number(this.settings.researchGlobalMaxSearchResults ?? 10);
169286
169488
  const fetchTimeoutMs = Number(this.settings.researchGlobalFetchTimeoutMs ?? 3e4);
169287
169489
  const userAgent = this.settings.researchGlobalUserAgent ?? "FusionResearchBot/1.0";
169288
- const synthesisProvider = this.settings.researchGlobalDefaults?.synthesisProvider ?? this.settings.defaultProvider;
169289
- const synthesisModelId = this.settings.researchGlobalDefaults?.synthesisModelId ?? this.settings.defaultModelId;
169490
+ const researchSynthesisPair = this.settings.researchGlobalDefaults?.synthesisProvider && this.settings.researchGlobalDefaults?.synthesisModelId ? {
169491
+ provider: this.settings.researchGlobalDefaults.synthesisProvider,
169492
+ modelId: this.settings.researchGlobalDefaults.synthesisModelId
169493
+ } : void 0;
169494
+ const synthesisProvider = researchSynthesisPair?.provider ?? this.settings.defaultProvider;
169495
+ const synthesisModelId = researchSynthesisPair?.modelId ?? this.settings.defaultModelId;
169290
169496
  this.providers = /* @__PURE__ */ new Map([
169291
169497
  [
169292
169498
  "web-search",
@@ -170707,7 +170913,7 @@ var init_worktree_acquisition = __esm({
170707
170913
  // ../engine/src/agent-tools.ts
170708
170914
  import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile33, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile25 } from "node:fs/promises";
170709
170915
  import { existsSync as existsSync53 } from "node:fs";
170710
- import { createHash as createHash16, randomUUID as randomUUID44 } from "node:crypto";
170916
+ import { createHash as createHash16, randomUUID as randomUUID45 } from "node:crypto";
170711
170917
  import { tmpdir as tmpdir6 } from "node:os";
170712
170918
  import { extname as extname3, isAbsolute as isAbsolute13, join as join66, relative as relative11, resolve as resolve32, sep as sep9 } from "node:path";
170713
170919
  import { Type as Type2 } from "@earendil-works/pi-ai";
@@ -171314,7 +171520,7 @@ function createTaskCreateTool(store, provenance, options) {
171314
171520
  toType: "user",
171315
171521
  type: "agent-to-user",
171316
171522
  content: `Task proposal awaiting validation: ${title}`,
171317
- metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID44(), taskId: options.sourceTaskId, proposedTask: { title, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.dependencies } }
171523
+ metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID45(), taskId: options.sourceTaskId, proposedTask: { title, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.dependencies } }
171318
171524
  });
171319
171525
  return { content: [{ type: "text", text: "Task proposal submitted to the operator for validation; no task was created." }], details: { proposed: true } };
171320
171526
  }
@@ -189615,6 +189821,7 @@ var init_agent_reflection = __esm({
189615
189821
  "../engine/src/agent-reflection.ts"() {
189616
189822
  "use strict";
189617
189823
  init_logger();
189824
+ init_src2();
189618
189825
  init_pi();
189619
189826
  init_mcp_resolution();
189620
189827
  init_run_audit();
@@ -189655,6 +189862,22 @@ Rules:
189655
189862
  this.modelProvider = options.modelProvider;
189656
189863
  this.modelId = options.modelId;
189657
189864
  }
189865
+ async resolveReflectionModel() {
189866
+ if (this.modelProvider && this.modelId) {
189867
+ return { provider: this.modelProvider, modelId: this.modelId };
189868
+ }
189869
+ try {
189870
+ const settings = await this.taskStore.getSettings();
189871
+ const resolved = resolveProjectDefaultModel(settings);
189872
+ if (resolved.provider && resolved.modelId) {
189873
+ return { provider: resolved.provider, modelId: resolved.modelId };
189874
+ }
189875
+ } catch (error2) {
189876
+ reflectionLog.warn(`Failed to resolve reflection model from settings: ${String(error2)}`);
189877
+ }
189878
+ reflectionLog.warn("No provider/model pair resolved for reflection; the runtime will use its built-in default model");
189879
+ return {};
189880
+ }
189658
189881
  async generateReflection(agentId, trigger, options = {}) {
189659
189882
  const runContext = {
189660
189883
  runId: generateSyntheticRunId("reflection", agentId),
@@ -189675,12 +189898,12 @@ Rules:
189675
189898
  return null;
189676
189899
  }
189677
189900
  let responseText = "";
189901
+ const reflectionModel = await this.resolveReflectionModel();
189678
189902
  const { session } = await createFnAgent2({
189679
189903
  cwd: this.rootDir,
189680
189904
  systemPrompt: REFLECTION_SYSTEM_PROMPT,
189681
189905
  tools: "readonly",
189682
- defaultProvider: this.modelProvider,
189683
- defaultModelId: this.modelId,
189906
+ ...reflectionModel.provider && reflectionModel.modelId ? { defaultProvider: reflectionModel.provider, defaultModelId: reflectionModel.modelId } : {},
189684
189907
  mcpServers: (await resolveMcpServersForStore(this.taskStore, { agentId })).servers,
189685
189908
  onText: (delta) => {
189686
189909
  responseText += delta;