@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
package/dist/extension.js CHANGED
@@ -705,7 +705,7 @@ var init_merge_queue = __esm({
705
705
  function isLocale(value) {
706
706
  return typeof value === "string" && SUPPORTED_LOCALES.includes(value);
707
707
  }
708
- 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;
708
+ 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;
709
709
  var init_execution_and_ui = __esm({
710
710
  "../core/src/types/execution-and-ui.ts"() {
711
711
  "use strict";
@@ -716,6 +716,7 @@ var init_execution_and_ui = __esm({
716
716
  PLANNER_OVERSIGHT_LEVELS = ["off", "observe", "steer", "autonomous"];
717
717
  DEFAULT_PLANNER_OVERSIGHT_LEVEL = "autonomous";
718
718
  REVIEW_ARTIFACTS_MODES = ["off", "user-facing", "on"];
719
+ ANTHROPIC_AUTH_PREFERENCES = ["api-key", "subscription"];
719
720
  THEME_MODES = ["dark", "light", "system"];
720
721
  COLOR_THEMES = [
721
722
  "default",
@@ -1529,6 +1530,12 @@ var init_settings_schema = __esm({
1529
1530
  FNXC:DashboardTheming 2026-07-03-00:00:
1530
1531
  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.
1531
1532
  */
1533
+ /*
1534
+ FNXC:ProviderAuth 2026-07-24-17:05:
1535
+ Default to the historical precedence (raw API key beats subscription OAuth, FN-7391/FN-7396)
1536
+ so upgrading never silently moves an operator's traffic from their key onto their subscription.
1537
+ */
1538
+ anthropicAuthPreference: "api-key",
1532
1539
  themeMode: "system",
1533
1540
  /*
1534
1541
  FNXC:DashboardTheming 2026-06-30-00:00:
@@ -12797,7 +12804,9 @@ __export(project_exports, {
12797
12804
  chatRoomMembers: () => chatRoomMembers,
12798
12805
  chatRoomMessages: () => chatRoomMessages,
12799
12806
  chatRooms: () => chatRooms,
12807
+ chatSessionTags: () => chatSessionTags,
12800
12808
  chatSessions: () => chatSessions,
12809
+ chatTags: () => chatTags,
12801
12810
  chatTokenUsage: () => chatTokenUsage,
12802
12811
  cliSessions: () => cliSessions,
12803
12812
  completionHandoffMarkers: () => completionHandoffMarkers,
@@ -12874,7 +12883,7 @@ __export(project_exports, {
12874
12883
  workflowWorkItems: () => workflowWorkItems,
12875
12884
  workflows: () => workflows
12876
12885
  });
12877
- 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;
12886
+ 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;
12878
12887
  var init_project = __esm({
12879
12888
  "../core/src/postgres/schema/project.ts"() {
12880
12889
  "use strict";
@@ -14585,7 +14594,33 @@ var init_project = __esm({
14585
14594
  cliExecutorAdapterId: text("cli_executor_adapter_id")
14586
14595
  }, (t) => [
14587
14596
  index("idxChatSessionsAgentId").on(t.agentId),
14588
- index("idxChatSessionsProjectId").on(t.projectId)
14597
+ index("idxChatSessionsProjectId").on(t.projectId),
14598
+ uniqueIndex("uqChatSessionsProjectIdId").on(t.projectId, t.id)
14599
+ ]);
14600
+ chatTags = projectSchema.table("chat_tags", {
14601
+ id: text("id").notNull(),
14602
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
14603
+ ownerProjectId: text("owner_project_id").notNull(),
14604
+ name: text("name").notNull(),
14605
+ normalizedName: text("normalized_name").notNull(),
14606
+ createdAt: text("created_at").notNull(),
14607
+ updatedAt: text("updated_at").notNull()
14608
+ }, (t) => [
14609
+ primaryKey({ columns: [t.projectId, t.id] }),
14610
+ uniqueIndex("uqChatTagsScopeName").on(t.projectId, t.normalizedName),
14611
+ index("idxChatTagsScopeName").on(t.projectId, t.normalizedName)
14612
+ ]);
14613
+ chatSessionTags = projectSchema.table("chat_session_tags", {
14614
+ sessionId: text("session_id").notNull(),
14615
+ tagId: text("tag_id").notNull(),
14616
+ projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
14617
+ assignedAt: text("assigned_at").notNull()
14618
+ }, (t) => [
14619
+ // 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.
14620
+ primaryKey({ columns: [t.projectId, t.sessionId, t.tagId] }),
14621
+ foreignKey({ columns: [t.projectId, t.sessionId], foreignColumns: [chatSessions.projectId, chatSessions.id] }).onDelete("cascade"),
14622
+ foreignKey({ columns: [t.projectId, t.tagId], foreignColumns: [chatTags.projectId, chatTags.id] }).onDelete("cascade"),
14623
+ index("idxChatSessionTagsTag").on(t.projectId, t.tagId, t.sessionId)
14589
14624
  ]);
14590
14625
  cliSessions = projectSchema.table("cli_sessions", {
14591
14626
  id: text("id").primaryKey(),
@@ -36528,6 +36563,7 @@ async function applySchemaBaseline(db, options = {}) {
36528
36563
  const taskWedgeNotificationAlreadyApplied = applied.includes(TASK_WEDGE_NOTIFICATION_VERSION);
36529
36564
  const milestoneAssertionProvenanceAlreadyApplied = applied.includes(MILESTONE_ASSERTION_PROVENANCE_VERSION);
36530
36565
  const missionLineageStopAlreadyApplied = applied.includes(MISSION_LINEAGE_STOP_VERSION);
36566
+ const chatSessionTagsAlreadyApplied = applied.includes(CHAT_SESSION_TAGS_VERSION);
36531
36567
  assertBinaryNotOlderThanDatabase(applied);
36532
36568
  let schemaChanged = false;
36533
36569
  if (!baselineAlreadyApplied) {
@@ -36873,17 +36909,23 @@ async function applySchemaBaseline(db, options = {}) {
36873
36909
  await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${MISSION_LINEAGE_STOP_VERSION}) ON CONFLICT (version) DO NOTHING`);
36874
36910
  schemaChanged = true;
36875
36911
  }
36912
+ if (!chatSessionTagsAlreadyApplied) {
36913
+ const migrationSql = await readFile4(CHAT_SESSION_TAGS_MIGRATION_PATH, "utf8");
36914
+ await tx.execute(sql.raw(migrationSql));
36915
+ await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${CHAT_SESSION_TAGS_VERSION}) ON CONFLICT (version) DO NOTHING`);
36916
+ schemaChanged = true;
36917
+ }
36876
36918
  return { applied: schemaChanged, pluginHooksRun: pluginHooks.length };
36877
36919
  });
36878
36920
  }
36879
- 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;
36921
+ 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;
36880
36922
  var init_schema_applier = __esm({
36881
36923
  "../core/src/postgres/schema-applier.ts"() {
36882
36924
  "use strict";
36883
36925
  init_drizzle_orm();
36884
36926
  init_plugin_schema_hook();
36885
36927
  init_advisory_locks();
36886
- SCHEMA_BASELINE_VERSION = "0035";
36928
+ SCHEMA_BASELINE_VERSION = "0036";
36887
36929
  TASK_DECLARED_SYMBOLS_VERSION = "0028";
36888
36930
  INITIAL_SCHEMA_VERSION = "0000";
36889
36931
  AUTOMATION_ISOLATION_SCHEMA_VERSION = "0001";
@@ -36919,6 +36961,7 @@ var init_schema_applier = __esm({
36919
36961
  TASK_WEDGE_NOTIFICATION_VERSION = "0033";
36920
36962
  MILESTONE_ASSERTION_PROVENANCE_VERSION = "0034";
36921
36963
  MISSION_LINEAGE_STOP_VERSION = "0035";
36964
+ CHAT_SESSION_TAGS_VERSION = "0036";
36922
36965
  LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION = "fusion_mark_legacy_adoption_drained";
36923
36966
  StaleBinarySchemaError = class extends Error {
36924
36967
  constructor(databaseVersion, binaryVersion) {
@@ -37034,6 +37077,7 @@ var init_schema_applier = __esm({
37034
37077
  "0034_milestone_assertion_provenance.sql"
37035
37078
  );
37036
37079
  MISSION_LINEAGE_STOP_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0035_fn_8543_mission_lineage_stop.sql");
37080
+ CHAT_SESSION_TAGS_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0036_chat_session_tags.sql");
37037
37081
  }
37038
37082
  });
37039
37083
 
@@ -63259,6 +63303,14 @@ function archiveEntryToTask(entry, slim = false) {
63259
63303
  planningStartedAt: entry.planningStartedAt,
63260
63304
  executionStartedAt: entry.executionStartedAt,
63261
63305
  executionCompletedAt: entry.executionCompletedAt,
63306
+ /*
63307
+ FNXC:ArchiveLifecycle 2026-07-24-11:02:
63308
+ FN-8561 needs archived TaskCard completion fallback to use the immutable
63309
+ archive transition, not the pre-archive columnMovedAt snapshot or updatedAt.
63310
+ Preserve archivedAt on every slim and full archive read without changing
63311
+ restore persistence semantics.
63312
+ */
63313
+ archivedAt: entry.archivedAt,
63262
63314
  modelPresetId: entry.modelPresetId,
63263
63315
  modelProvider: entry.modelProvider,
63264
63316
  modelId: entry.modelId,
@@ -127000,9 +127052,14 @@ var init_org_bundle = __esm({
127000
127052
  });
127001
127053
 
127002
127054
  // ../core/src/async-chat-store.ts
127055
+ import { randomUUID as randomUUID41 } from "node:crypto";
127056
+ function rowToTag(row) {
127057
+ return { id: row.id, projectId: row.ownerProjectId === "__default__" ? null : row.ownerProjectId, name: row.name, createdAt: row.createdAt, updatedAt: row.updatedAt };
127058
+ }
127003
127059
  function rowToSession3(row) {
127004
127060
  return {
127005
127061
  id: row.id,
127062
+ tags: [],
127006
127063
  agentId: row.agentId,
127007
127064
  title: row.title ?? null,
127008
127065
  status: row.status,
@@ -127091,7 +127148,7 @@ async function createChatSession(handle, session) {
127091
127148
  }
127092
127149
  async function getChatSession(handle, id) {
127093
127150
  const rows = await handle.select().from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
127094
- return rows[0] ? rowToSession3(rows[0]) : void 0;
127151
+ return rows[0] ? attachTags(handle, rowToSession3(rows[0])) : void 0;
127095
127152
  }
127096
127153
  async function listChatSessions(handle, options) {
127097
127154
  const conditions = [];
@@ -127100,12 +127157,104 @@ async function listChatSessions(handle, options) {
127100
127157
  if (options?.status) conditions.push(eq(project_exports.chatSessions.status, options.status));
127101
127158
  const query = handle.select().from(project_exports.chatSessions).orderBy(desc(project_exports.chatSessions.updatedAt));
127102
127159
  const rows = conditions.length > 0 ? await query.where(and(...conditions)) : await query;
127103
- return rows.map(rowToSession3);
127160
+ return attachTagsToSessions(handle, rows.map(rowToSession3));
127104
127161
  }
127105
127162
  async function deleteChatSession(handle, id) {
127106
- const result = await handle.delete(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id)).returning({ id: project_exports.chatSessions.id });
127163
+ const [session] = await handle.select({ projectId: project_exports.chatSessions.projectId }).from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
127164
+ if (!session) return false;
127165
+ const sessionProjectId = session.projectId;
127166
+ if (!sessionProjectId) throw new Error("Chat session is missing its required project partition");
127167
+ await handle.delete(project_exports.chatSessionTags).where(and(
127168
+ eq(project_exports.chatSessionTags.sessionId, id),
127169
+ eq(project_exports.chatSessionTags.projectId, sessionProjectId)
127170
+ ));
127171
+ 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 });
127107
127172
  return result.length > 0;
127108
127173
  }
127174
+ function tagScope(projectId) {
127175
+ return projectId ?? "__default__";
127176
+ }
127177
+ function normalizeTagName(name2) {
127178
+ const cleaned = name2.trim().replace(/\s+/g, " ");
127179
+ if (!cleaned || cleaned.length > 64) throw new Error("Tag name must be between 1 and 64 characters");
127180
+ return { name: cleaned, normalizedName: cleaned.toLocaleLowerCase() };
127181
+ }
127182
+ async function attachTags(handle, session) {
127183
+ const [attached] = await attachTagsToSessions(handle, [session]);
127184
+ return attached ?? session;
127185
+ }
127186
+ async function attachTagsToSessions(handle, sessions6) {
127187
+ if (!sessions6.length) return sessions6;
127188
+ 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(
127189
+ eq(project_exports.chatSessionTags.tagId, project_exports.chatTags.id),
127190
+ eq(project_exports.chatSessionTags.projectId, project_exports.chatTags.projectId)
127191
+ )).innerJoin(project_exports.chatSessions, and(
127192
+ eq(project_exports.chatSessionTags.sessionId, project_exports.chatSessions.id),
127193
+ eq(project_exports.chatSessionTags.projectId, project_exports.chatSessions.projectId)
127194
+ )).where(inArray(project_exports.chatSessionTags.sessionId, sessions6.map((session) => session.id))).orderBy(asc(project_exports.chatTags.normalizedName), asc(project_exports.chatTags.id));
127195
+ const tagsBySession = /* @__PURE__ */ new Map();
127196
+ for (const row of rows) {
127197
+ const tags = tagsBySession.get(row.sessionId) ?? [];
127198
+ tags.push(rowToTag(row));
127199
+ tagsBySession.set(row.sessionId, tags);
127200
+ }
127201
+ return sessions6.map((session) => ({ ...session, tags: tagsBySession.get(session.id) ?? [] }));
127202
+ }
127203
+ async function listChatTags(handle, projectId) {
127204
+ 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));
127205
+ return rows.map(rowToTag);
127206
+ }
127207
+ async function createChatTag(layer, input) {
127208
+ const { name: name2, normalizedName } = normalizeTagName(input.name);
127209
+ const projectId = input.projectId ?? null;
127210
+ const now = (/* @__PURE__ */ new Date()).toISOString();
127211
+ return layer.transactionImmediate(async (tx) => {
127212
+ const id = `chat-tag-${randomUUID41().slice(0, 8)}`;
127213
+ const rows = await tx.insert(project_exports.chatTags).values({ id, ownerProjectId: tagScope(projectId), name: name2, normalizedName, createdAt: now, updatedAt: now }).onConflictDoNothing().returning();
127214
+ if (!rows[0]) throw new Error("A tag with that name already exists");
127215
+ return rowToTag(rows[0]);
127216
+ });
127217
+ }
127218
+ async function renameChatTag(layer, id, projectId, input) {
127219
+ const { name: name2, normalizedName } = normalizeTagName(input.name);
127220
+ return layer.transactionImmediate(async (tx) => {
127221
+ 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();
127222
+ if (!rows[0]) return void 0;
127223
+ return rowToTag(rows[0]);
127224
+ });
127225
+ }
127226
+ async function deleteChatTag(layer, id, projectId) {
127227
+ return layer.transactionImmediate(async (tx) => {
127228
+ 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))));
127229
+ if (!tag?.projectId) return false;
127230
+ const tagProjectId = tag.projectId;
127231
+ await tx.delete(project_exports.chatSessionTags).where(and(
127232
+ eq(project_exports.chatSessionTags.tagId, id),
127233
+ eq(project_exports.chatSessionTags.projectId, tagProjectId)
127234
+ ));
127235
+ 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;
127236
+ });
127237
+ }
127238
+ async function replaceChatSessionTags(layer, sessionId, projectId, tagIds) {
127239
+ return layer.transactionImmediate(async (tx) => {
127240
+ const session = await getChatSessionForUpdate(tx, sessionId);
127241
+ if (!session || session.projectId !== projectId) return void 0;
127242
+ const ownerProjectCondition = projectId === null ? isNull(project_exports.chatSessions.ownerProjectId) : eq(project_exports.chatSessions.ownerProjectId, projectId);
127243
+ 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");
127244
+ if (!sessionPartition?.projectId) return void 0;
127245
+ const sessionProjectId = sessionPartition.projectId;
127246
+ const uniqueIds = [...new Set(tagIds)];
127247
+ const tags = uniqueIds.length ? await tx.select().from(project_exports.chatTags).where(and(
127248
+ inArray(project_exports.chatTags.id, uniqueIds),
127249
+ eq(project_exports.chatTags.ownerProjectId, tagScope(projectId)),
127250
+ eq(project_exports.chatTags.projectId, sessionProjectId)
127251
+ )) : [];
127252
+ if (tags.length !== uniqueIds.length) throw new Error("One or more tags do not belong to this project");
127253
+ await tx.delete(project_exports.chatSessionTags).where(and(eq(project_exports.chatSessionTags.sessionId, sessionId), eq(project_exports.chatSessionTags.projectId, sessionProjectId)));
127254
+ if (uniqueIds.length) await tx.insert(project_exports.chatSessionTags).values(uniqueIds.map((tagId) => ({ projectId: sessionProjectId, sessionId, tagId, assignedAt: (/* @__PURE__ */ new Date()).toISOString() }))).onConflictDoNothing();
127255
+ return attachTags(tx, session);
127256
+ });
127257
+ }
127109
127258
  async function addChatMessage(handle, message) {
127110
127259
  const sanitizedAttachments = message.attachments === void 0 ? void 0 : sanitizeJsonbValue(message.attachments);
127111
127260
  const sanitized = {
@@ -127497,7 +127646,7 @@ var init_async_chat_store = __esm({
127497
127646
 
127498
127647
  // ../core/src/chat-store.ts
127499
127648
  import { EventEmitter as EventEmitter23 } from "node:events";
127500
- import { randomUUID as randomUUID41 } from "node:crypto";
127649
+ import { randomUUID as randomUUID42 } from "node:crypto";
127501
127650
  var ChatStore;
127502
127651
  var init_chat_store = __esm({
127503
127652
  "../core/src/chat-store.ts"() {
@@ -127532,8 +127681,9 @@ var init_chat_store = __esm({
127532
127681
  async createSession(input) {
127533
127682
  const now = (/* @__PURE__ */ new Date()).toISOString();
127534
127683
  const session = {
127535
- id: `chat-${randomUUID41().slice(0, 8)}`,
127684
+ id: `chat-${randomUUID42().slice(0, 8)}`,
127536
127685
  agentId: input.agentId,
127686
+ tags: [],
127537
127687
  title: input.title ?? null,
127538
127688
  status: "active",
127539
127689
  projectId: input.projectId ?? null,
@@ -127703,6 +127853,29 @@ var init_chat_store = __esm({
127703
127853
  }
127704
127854
  return deletedCount;
127705
127855
  }
127856
+ /*
127857
+ FNXC:ChatTags 2026-08-05-10:55:
127858
+ Direct-conversation tags are project-scoped by the session's owner project.
127859
+ Tag mutations are transactional and return an enriched session so SSE clients
127860
+ never receive an assignment update without its deterministic tag array.
127861
+ */
127862
+ async listTags(projectId = null) {
127863
+ return listChatTags(this.asyncLayer.db, projectId);
127864
+ }
127865
+ async createTag(input) {
127866
+ return createChatTag(this.asyncLayer, input);
127867
+ }
127868
+ async renameTag(id, projectId, input) {
127869
+ return renameChatTag(this.asyncLayer, id, projectId, input);
127870
+ }
127871
+ async deleteTag(id, projectId) {
127872
+ return deleteChatTag(this.asyncLayer, id, projectId);
127873
+ }
127874
+ async replaceSessionTags(id, projectId, tagIds) {
127875
+ const updated = await replaceChatSessionTags(this.asyncLayer, id, projectId, tagIds);
127876
+ if (updated) this.emit("chat:session:updated", updated);
127877
+ return updated;
127878
+ }
127706
127879
  // ── Message CRUD Operations ───────────────────────────────────────
127707
127880
  /**
127708
127881
  * Add a message to a chat session.
@@ -127719,7 +127892,7 @@ var init_chat_store = __esm({
127719
127892
  }
127720
127893
  const now = (/* @__PURE__ */ new Date()).toISOString();
127721
127894
  const message = {
127722
- id: `msg-${randomUUID41().slice(0, 8)}`,
127895
+ id: `msg-${randomUUID42().slice(0, 8)}`,
127723
127896
  sessionId,
127724
127897
  role: input.role,
127725
127898
  content: input.content,
@@ -127861,7 +128034,7 @@ var init_chat_store = __esm({
127861
128034
  if (!slug) throw new Error("Room name must include letters or numbers");
127862
128035
  const now = (/* @__PURE__ */ new Date()).toISOString();
127863
128036
  const room = {
127864
- id: `room-${randomUUID41().slice(0, 8)}`,
128037
+ id: `room-${randomUUID42().slice(0, 8)}`,
127865
128038
  name: normalizedName,
127866
128039
  slug,
127867
128040
  description: input.description ?? null,
@@ -127953,7 +128126,7 @@ var init_chat_store = __esm({
127953
128126
  }
127954
128127
  const now = (/* @__PURE__ */ new Date()).toISOString();
127955
128128
  const message = {
127956
- id: `rmsg-${randomUUID41().slice(0, 8)}`,
128129
+ id: `rmsg-${randomUUID42().slice(0, 8)}`,
127957
128130
  roomId,
127958
128131
  role: input.role,
127959
128132
  content: input.content,
@@ -128008,7 +128181,7 @@ var init_chat_store = __esm({
128008
128181
  return void 0;
128009
128182
  }
128010
128183
  const record2 = {
128011
- id: `chat-tokens-${randomUUID41().slice(0, 12)}`,
128184
+ id: `chat-tokens-${randomUUID42().slice(0, 12)}`,
128012
128185
  sourceKind: input.sourceKind,
128013
128186
  chatSessionId: input.chatSessionId ?? null,
128014
128187
  roomId: input.roomId ?? null,
@@ -128104,7 +128277,7 @@ var init_cli_session_types = __esm({
128104
128277
  });
128105
128278
 
128106
128279
  // ../core/src/cli-session-store.ts
128107
- import { randomUUID as randomUUID42 } from "node:crypto";
128280
+ import { randomUUID as randomUUID43 } from "node:crypto";
128108
128281
  import { EventEmitter as EventEmitter24 } from "node:events";
128109
128282
  function parsePosture(value) {
128110
128283
  return fromJson(value) ?? null;
@@ -128186,7 +128359,7 @@ var init_cli_session_store = __esm({
128186
128359
  if (!input.adapterId) throw new Error("CLI session requires an adapterId");
128187
128360
  const now = (/* @__PURE__ */ new Date()).toISOString();
128188
128361
  const session = {
128189
- id: input.id ?? `cli-${randomUUID42().slice(0, 8)}`,
128362
+ id: input.id ?? `cli-${randomUUID43().slice(0, 8)}`,
128190
128363
  taskId: input.taskId ?? null,
128191
128364
  chatSessionId: input.chatSessionId ?? null,
128192
128365
  purpose: input.purpose,
@@ -128579,7 +128752,7 @@ var init_task_prefix = __esm({
128579
128752
  });
128580
128753
 
128581
128754
  // ../core/src/task-store/async-monitor.ts
128582
- import { randomUUID as randomUUID43 } from "node:crypto";
128755
+ import { randomUUID as randomUUID44 } from "node:crypto";
128583
128756
  function monitorProjectPartition(projectId) {
128584
128757
  return projectId.trim() || "__legacy_unscoped__";
128585
128758
  }
@@ -128623,7 +128796,7 @@ function incidentFromRow(row) {
128623
128796
  }
128624
128797
  async function recordDeploymentAsync(db, input, projectId = "") {
128625
128798
  const ownerProjectId = monitorProjectPartition(projectId);
128626
- const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID43()}`;
128799
+ const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID44()}`;
128627
128800
  const now = (/* @__PURE__ */ new Date()).toISOString();
128628
128801
  const deployedAt = input.deployedAt ?? now;
128629
128802
  await db.insert(project_exports.deployments).values({
@@ -128681,7 +128854,7 @@ async function ingestIncidentSignalAsync(db, input, projectId = "") {
128681
128854
  const updated = await getIncidentAsync(db, existing.incidentId, ownerProjectId);
128682
128855
  return { incident: updated ?? existing, created: false };
128683
128856
  }
128684
- const incidentId = `inc-${randomUUID43()}`;
128857
+ const incidentId = `inc-${randomUUID44()}`;
128685
128858
  const meta2 = {
128686
128859
  ...input.meta ?? {},
128687
128860
  [OCCURRENCES_META_KEY]: 1,
@@ -129269,6 +129442,7 @@ __export(src_exports, {
129269
129442
  AGENT_PERMISSION_POLICY_PRESET_IDS: () => AGENT_PERMISSION_POLICY_PRESET_IDS,
129270
129443
  AGENT_PROVISIONING_APPROVAL_MODES: () => AGENT_PROVISIONING_APPROVAL_MODES,
129271
129444
  AGENT_VALID_TRANSITIONS: () => AGENT_VALID_TRANSITIONS,
129445
+ ANTHROPIC_AUTH_PREFERENCES: () => ANTHROPIC_AUTH_PREFERENCES,
129272
129446
  ANTHROPIC_PROVIDER_ID: () => ANTHROPIC_PROVIDER_ID,
129273
129447
  APPROVAL_REQUEST_AUDIT_EVENT_TYPES: () => APPROVAL_REQUEST_AUDIT_EVENT_TYPES,
129274
129448
  APPROVAL_REQUEST_STATUSES: () => APPROVAL_REQUEST_STATUSES,
@@ -133687,6 +133861,26 @@ function resolveStoredCredentialApiKey(providerId, credential) {
133687
133861
  }
133688
133862
  return void 0;
133689
133863
  }
133864
+ function getFusionGlobalSettingsPath(home = getHomeDir5()) {
133865
+ const candidates = [
133866
+ join54(home, ".fusion", "settings.json"),
133867
+ join54(home, ".pi", "fusion", "settings.json"),
133868
+ join54(home, ".pi", "kb", "settings.json")
133869
+ ];
133870
+ return candidates.find((candidate) => existsSync41(candidate)) ?? candidates[0];
133871
+ }
133872
+ function readAnthropicAuthPreference(home = getHomeDir5()) {
133873
+ const settingsPath = getFusionGlobalSettingsPath(home);
133874
+ if (!existsSync41(settingsPath)) {
133875
+ return "api-key";
133876
+ }
133877
+ try {
133878
+ const parsed = JSON.parse(readFileSync12(settingsPath, "utf-8"));
133879
+ return parsed?.anthropicAuthPreference === "subscription" ? "subscription" : "api-key";
133880
+ } catch {
133881
+ return "api-key";
133882
+ }
133883
+ }
133690
133884
  function readModelsJsonApiKeys(home = getHomeDir5()) {
133691
133885
  const apiKeys = /* @__PURE__ */ new Map();
133692
133886
  const modelsPath = getModelRegistryModelsPath(home);
@@ -133892,11 +134086,15 @@ function createFusionAuthStorage() {
133892
134086
  };
133893
134087
  const resolveAnthropicRuntimeApiKey = async () => {
133894
134088
  const rawProviderLoggedOut = isAnthropicRawProviderLoggedOut();
133895
- if (!rawProviderLoggedOut) {
134089
+ const preferSubscription = readAnthropicAuthPreference() === "subscription";
134090
+ const resolveRawApiKey = () => {
134091
+ if (rawProviderLoggedOut) return void 0;
133896
134092
  const anthropicApiKeyCredential = selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "api_key");
133897
- if (anthropicApiKeyCredential) {
133898
- return resolveStoredCredentialApiKey(ANTHROPIC_PROVIDER_ID2, anthropicApiKeyCredential);
133899
- }
134093
+ return anthropicApiKeyCredential ? resolveStoredCredentialApiKey(ANTHROPIC_PROVIDER_ID2, anthropicApiKeyCredential) : void 0;
134094
+ };
134095
+ if (!preferSubscription) {
134096
+ const rawKey = resolveRawApiKey();
134097
+ if (rawKey) return rawKey;
133900
134098
  }
133901
134099
  const subscriptionLoggedOut = loggedOutProviders.has(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
133902
134100
  const legacyAnthropicOAuthCredential = rawProviderLoggedOut ? void 0 : selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "oauth");
@@ -133911,6 +134109,10 @@ function createFusionAuthStorage() {
133911
134109
  if (subscriptionKey) return subscriptionKey;
133912
134110
  }
133913
134111
  }
134112
+ if (preferSubscription) {
134113
+ const rawKey = resolveRawApiKey();
134114
+ if (rawKey) return rawKey;
134115
+ }
133914
134116
  if (!rawProviderLoggedOut) {
133915
134117
  const modelsJsonApiKey = modelsJsonApiKeys.get(ANTHROPIC_PROVIDER_ID2);
133916
134118
  if (modelsJsonApiKey) return modelsJsonApiKey;
@@ -161089,8 +161291,12 @@ var init_provider_registry = __esm({
161089
161291
  const maxResults = Number(this.settings.researchGlobalMaxSearchResults ?? 10);
161090
161292
  const fetchTimeoutMs = Number(this.settings.researchGlobalFetchTimeoutMs ?? 3e4);
161091
161293
  const userAgent = this.settings.researchGlobalUserAgent ?? "FusionResearchBot/1.0";
161092
- const synthesisProvider = this.settings.researchGlobalDefaults?.synthesisProvider ?? this.settings.defaultProvider;
161093
- const synthesisModelId = this.settings.researchGlobalDefaults?.synthesisModelId ?? this.settings.defaultModelId;
161294
+ const researchSynthesisPair = this.settings.researchGlobalDefaults?.synthesisProvider && this.settings.researchGlobalDefaults?.synthesisModelId ? {
161295
+ provider: this.settings.researchGlobalDefaults.synthesisProvider,
161296
+ modelId: this.settings.researchGlobalDefaults.synthesisModelId
161297
+ } : void 0;
161298
+ const synthesisProvider = researchSynthesisPair?.provider ?? this.settings.defaultProvider;
161299
+ const synthesisModelId = researchSynthesisPair?.modelId ?? this.settings.defaultModelId;
161094
161300
  this.providers = /* @__PURE__ */ new Map([
161095
161301
  [
161096
161302
  "web-search",
@@ -168655,7 +168861,7 @@ var init_code_node_runner = __esm({
168655
168861
  // ../engine/src/agent-tools.ts
168656
168862
  import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile31, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile25 } from "node:fs/promises";
168657
168863
  import { existsSync as existsSync50 } from "node:fs";
168658
- import { createHash as createHash16, randomUUID as randomUUID44 } from "node:crypto";
168864
+ import { createHash as createHash16, randomUUID as randomUUID45 } from "node:crypto";
168659
168865
  import { tmpdir as tmpdir5 } from "node:os";
168660
168866
  import { extname as extname3, isAbsolute as isAbsolute12, join as join64, relative as relative11, resolve as resolve32, sep as sep9 } from "node:path";
168661
168867
  import { Type as Type2 } from "@earendil-works/pi-ai";
@@ -169262,7 +169468,7 @@ function createTaskCreateTool(store, provenance, options) {
169262
169468
  toType: "user",
169263
169469
  type: "agent-to-user",
169264
169470
  content: `Task proposal awaiting validation: ${title}`,
169265
- 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 } }
169471
+ 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 } }
169266
169472
  });
169267
169473
  return { content: [{ type: "text", text: "Task proposal submitted to the operator for validation; no task was created." }], details: { proposed: true } };
169268
169474
  }
@@ -243368,6 +243574,7 @@ var init_agent_reflection = __esm({
243368
243574
  "../engine/src/agent-reflection.ts"() {
243369
243575
  "use strict";
243370
243576
  init_logger3();
243577
+ init_src2();
243371
243578
  init_pi();
243372
243579
  init_mcp_resolution();
243373
243580
  init_run_audit();
@@ -243408,6 +243615,22 @@ Rules:
243408
243615
  this.modelProvider = options.modelProvider;
243409
243616
  this.modelId = options.modelId;
243410
243617
  }
243618
+ async resolveReflectionModel() {
243619
+ if (this.modelProvider && this.modelId) {
243620
+ return { provider: this.modelProvider, modelId: this.modelId };
243621
+ }
243622
+ try {
243623
+ const settings = await this.taskStore.getSettings();
243624
+ const resolved = resolveProjectDefaultModel(settings);
243625
+ if (resolved.provider && resolved.modelId) {
243626
+ return { provider: resolved.provider, modelId: resolved.modelId };
243627
+ }
243628
+ } catch (error2) {
243629
+ reflectionLog.warn(`Failed to resolve reflection model from settings: ${String(error2)}`);
243630
+ }
243631
+ reflectionLog.warn("No provider/model pair resolved for reflection; the runtime will use its built-in default model");
243632
+ return {};
243633
+ }
243411
243634
  async generateReflection(agentId, trigger, options = {}) {
243412
243635
  const runContext = {
243413
243636
  runId: generateSyntheticRunId("reflection", agentId),
@@ -243428,12 +243651,12 @@ Rules:
243428
243651
  return null;
243429
243652
  }
243430
243653
  let responseText = "";
243654
+ const reflectionModel = await this.resolveReflectionModel();
243431
243655
  const { session } = await createFnAgent2({
243432
243656
  cwd: this.rootDir,
243433
243657
  systemPrompt: REFLECTION_SYSTEM_PROMPT,
243434
243658
  tools: "readonly",
243435
- defaultProvider: this.modelProvider,
243436
- defaultModelId: this.modelId,
243659
+ ...reflectionModel.provider && reflectionModel.modelId ? { defaultProvider: reflectionModel.provider, defaultModelId: reflectionModel.modelId } : {},
243437
243660
  mcpServers: (await resolveMcpServersForStore(this.taskStore, { agentId })).servers,
243438
243661
  onText: (delta) => {
243439
243662
  responseText += delta;
@@ -244506,7 +244729,7 @@ var init_metric_parser = __esm({
244506
244729
  });
244507
244730
 
244508
244731
  // ../engine/src/experiment-executor.ts
244509
- import { randomUUID as randomUUID45 } from "node:crypto";
244732
+ import { randomUUID as randomUUID46 } from "node:crypto";
244510
244733
  var ExperimentMaxIterationsError, ExperimentGitNotConfiguredError, ExperimentExecutor;
244511
244734
  var init_experiment_executor = __esm({
244512
244735
  "../engine/src/experiment-executor.ts"() {
@@ -244574,7 +244797,7 @@ var init_experiment_executor = __esm({
244574
244797
  }
244575
244798
  await this.semaphore.acquire();
244576
244799
  const controller = new AbortController();
244577
- const runHandle = randomUUID45();
244800
+ const runHandle = randomUUID46();
244578
244801
  if (opts?.abortSignal) {
244579
244802
  opts.abortSignal.addEventListener("abort", () => controller.abort(), { once: true });
244580
244803
  }
@@ -263143,7 +263366,7 @@ var init_src5 = __esm({
263143
263366
  });
263144
263367
 
263145
263368
  // ../dashboard/src/ai-session-diagnostics.ts
263146
- import { randomUUID as randomUUID46 } from "node:crypto";
263369
+ import { randomUUID as randomUUID47 } from "node:crypto";
263147
263370
  function defaultSink(level, scope, message, context) {
263148
263371
  const prefix = `[${scope}]`;
263149
263372
  const logArgs = [prefix, message, context];
@@ -263187,7 +263410,7 @@ function emit(level, scope, message, context) {
263187
263410
  const fullContext = {
263188
263411
  ...context,
263189
263412
  _emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
263190
- _diagnosticsId: randomUUID46()
263413
+ _diagnosticsId: randomUUID47()
263191
263414
  };
263192
263415
  try {
263193
263416
  _sink(level, scope, message, fullContext);
@@ -263892,8 +264115,19 @@ var init_planning_board_tools = __esm({
263892
264115
  });
263893
264116
 
263894
264117
  // ../dashboard/src/planning.ts
263895
- import { randomUUID as randomUUID47 } from "node:crypto";
264118
+ import { randomUUID as randomUUID48 } from "node:crypto";
263896
264119
  import { EventEmitter as EventEmitter34 } from "node:events";
264120
+ async function createPlanningRuntimeSession(options) {
264121
+ const { pluginRunner, runtimeHint, settings, ...runtimeOptions } = options ?? {};
264122
+ const create = createResolvedAgentSession ?? createResolvedAgentSession;
264123
+ return create({
264124
+ sessionPurpose: "executor",
264125
+ ...runtimeHint ? { runtimeHint } : {},
264126
+ ...pluginRunner ? { pluginRunner } : {},
264127
+ ...settings ? { settings } : {},
264128
+ ...runtimeOptions
264129
+ });
264130
+ }
263897
264131
  function isThinkingLevel(value) {
263898
264132
  return THINKING_LEVELS.includes(value);
263899
264133
  }
@@ -264264,7 +264498,7 @@ async function createSession(ip, initialPlan, store, rootDir, promptOverrides, p
264264
264498
  if (!store) {
264265
264499
  throw new Error("store is required for AI-powered planning sessions");
264266
264500
  }
264267
- const sessionId = randomUUID47();
264501
+ const sessionId = randomUUID48();
264268
264502
  const session = {
264269
264503
  id: sessionId,
264270
264504
  ip,
@@ -264303,6 +264537,7 @@ async function runCreateSessionFirstTurn(session, rootDir, store, promptOverride
264303
264537
  await ensureEngineReady();
264304
264538
  }
264305
264539
  const skillContext = buildSessionSkillContextSync(null, "executor", rootDir, pluginRunner);
264540
+ const { provider: startProvider, modelId: startModelId } = await resolveSessionPlanningModel(session, store);
264306
264541
  const agentResult = await createFnAgent4({
264307
264542
  cwd: rootDir,
264308
264543
  systemPrompt,
@@ -264326,6 +264561,8 @@ async function runCreateSessionFirstTurn(session, rootDir, store, promptOverride
264326
264561
  ...createChatTaskDocumentTools(store),
264327
264562
  createChatTaskLogsReadTool(store)
264328
264563
  ],
264564
+ ...startProvider && startModelId ? { defaultProvider: startProvider, defaultModelId: startModelId } : {},
264565
+ ...pluginRunner ? { pluginRunner } : {},
264329
264566
  onThinking: () => {
264330
264567
  },
264331
264568
  onText: () => {
@@ -264495,6 +264732,8 @@ async function createPlanningAgent(session, rootDir, store, modelProvider, model
264495
264732
  defaultModelId: modelId
264496
264733
  } : {},
264497
264734
  ...thinkingLevel ? { defaultThinkingLevel: thinkingLevel } : {},
264735
+ // Runtime resolution needs the plugin runner to see plugin-provided runtimes.
264736
+ ...pluginRunner ? { pluginRunner } : {},
264498
264737
  onThinking: (delta) => {
264499
264738
  if (callbacksInvalidated()) return;
264500
264739
  markPlanningGenerationProgress(session.id, delta);
@@ -264528,6 +264767,31 @@ function buildHistoryReplayPrompt(history) {
264528
264767
  "Treat every recorded selection and Other answer as an accumulated durable decision. Rebuild affected plan fields around those decisions; do not preserve superseded or unselected alternatives as the plan backbone. Use this as context for the next response. Do not repeat prior questions unless necessary."
264529
264768
  ].join("\n\n");
264530
264769
  }
264770
+ async function resolveSessionPlanningModel(session, store) {
264771
+ if (session.draftModelProvider && session.draftModelId) {
264772
+ return { provider: session.draftModelProvider, modelId: session.draftModelId };
264773
+ }
264774
+ try {
264775
+ const settings = await store.getSettings();
264776
+ const resolved = resolvePlanningSettingsModel(settings);
264777
+ if (resolved.provider && resolved.modelId) {
264778
+ session.draftModelProvider = resolved.provider;
264779
+ session.draftModelId = resolved.modelId;
264780
+ return { provider: resolved.provider, modelId: resolved.modelId };
264781
+ }
264782
+ } catch (err) {
264783
+ diagnostics2.warn("Failed to resolve planning model for rebuilt agent", {
264784
+ sessionId: session.id,
264785
+ operation: "resolve-session-planning-model",
264786
+ error: String(err)
264787
+ });
264788
+ }
264789
+ diagnostics2.warn(
264790
+ "Rebuilt planning agent has no resolved provider/model pair; the runtime will use its built-in default model",
264791
+ { sessionId: session.id, operation: "resolve-session-planning-model" }
264792
+ );
264793
+ return {};
264794
+ }
264531
264795
  async function ensureSessionAgent(session, rootDir, historyForReplay, promptOverrides, store) {
264532
264796
  if (session.agent) {
264533
264797
  return;
@@ -264544,7 +264808,20 @@ async function ensureSessionAgent(session, rootDir, historyForReplay, promptOver
264544
264808
  "Planning session has no task store and cannot be resumed without project context"
264545
264809
  );
264546
264810
  }
264547
- session.agent = await createPlanningAgent(session, effectiveRootDir, effectiveStore, void 0, void 0, session.draftThinkingLevel, promptOverrides, session.pluginRunner);
264811
+ const { provider: resumeProvider, modelId: resumeModelId } = await resolveSessionPlanningModel(
264812
+ session,
264813
+ effectiveStore
264814
+ );
264815
+ session.agent = await createPlanningAgent(
264816
+ session,
264817
+ effectiveRootDir,
264818
+ effectiveStore,
264819
+ resumeProvider,
264820
+ resumeModelId,
264821
+ session.draftThinkingLevel,
264822
+ promptOverrides,
264823
+ session.pluginRunner
264824
+ );
264548
264825
  if (historyForReplay.length === 0) {
264549
264826
  return;
264550
264827
  }
@@ -264791,7 +265068,7 @@ function normalizePlanningQuestion(input, userInput = "") {
264791
265068
  const type = source.type === "multi_select" || source.type === "single_select" ? source.type : "single_select";
264792
265069
  const question = typeof source.question === "string" && source.question.trim() ? source.question.trim() : fallback.question;
264793
265070
  const normalized = {
264794
- id: typeof source.id === "string" && source.id.trim() ? source.id : randomUUID47(),
265071
+ id: typeof source.id === "string" && source.id.trim() ? source.id : randomUUID48(),
264795
265072
  type,
264796
265073
  question,
264797
265074
  ...typeof source.description === "string" && source.description.trim() ? { description: source.description.trim() } : {}
@@ -264817,7 +265094,7 @@ function normalizePlanningQuestion(input, userInput = "") {
264817
265094
  }
264818
265095
  function coerceQuestionResponse(response, session) {
264819
265096
  if (response.type === "question") return normalizePlanningQuestion(response.data, session.initialPlan);
264820
- return normalizePlanningQuestion({ id: randomUUID47(), type: "single_select", question: planningFallbackCopy(session.initialPlan).question }, session.initialPlan);
265097
+ return normalizePlanningQuestion({ id: randomUUID48(), type: "single_select", question: planningFallbackCopy(session.initialPlan).question }, session.initialPlan);
264821
265098
  }
264822
265099
  async function validateSession(sessionId) {
264823
265100
  const session = await getSession(sessionId);
@@ -265553,7 +265830,7 @@ async function createTaskFromPlanSession(sessionId, store, options) {
265553
265830
  throw new InvalidSessionStateError("PLANNING_CREATED_TASK_MISSING");
265554
265831
  }
265555
265832
  }
265556
- const claimOwnerToken = randomUUID47();
265833
+ const claimOwnerToken = randomUUID48();
265557
265834
  let claimed = await claimPlanningTaskCreation(sessionId, claimOwnerToken, (/* @__PURE__ */ new Date()).toISOString(), claimEpoch);
265558
265835
  if (!claimed) {
265559
265836
  session = await getDurablePlanningSession(sessionId).catch(() => void 0) ?? session;
@@ -265686,7 +265963,7 @@ var init_planning = __esm({
265686
265963
  init_planning_board_tools();
265687
265964
  PLANNING_NO_AMBIENT_TASK_ID = "";
265688
265965
  PLANNING_BUILTIN_WEB_TOOLS = ["WebSearch", "WebFetch"];
265689
- createFnAgent4 = createFnAgent2;
265966
+ createFnAgent4 = createPlanningRuntimeSession;
265690
265967
  diagnostics2 = createSessionDiagnostics("planning");
265691
265968
  PLANNING_SYSTEM_PROMPT = `## Collaborative Planning Mode
265692
265969
 
@@ -265984,6 +266261,14 @@ var init_ai_session_timeout = __esm({
265984
266261
  }
265985
266262
  });
265986
266263
 
266264
+ // ../dashboard/src/lane-session-model.ts
266265
+ var init_lane_session_model = __esm({
266266
+ "../dashboard/src/lane-session-model.ts"() {
266267
+ "use strict";
266268
+ init_src2();
266269
+ }
266270
+ });
266271
+
265987
266272
  // ../dashboard/src/subtask-breakdown.ts
265988
266273
  import { EventEmitter as EventEmitter35 } from "node:events";
265989
266274
  function cleanupInMemorySubtaskSession(sessionId) {
@@ -266017,6 +266302,7 @@ var init_subtask_breakdown = __esm({
266017
266302
  init_process_lifecycle();
266018
266303
  init_ai_session_diagnostics();
266019
266304
  init_ai_session_timeout();
266305
+ init_lane_session_model();
266020
266306
  init_src5();
266021
266307
  diagnostics3 = createSessionDiagnostics("subtask-breakdown");
266022
266308
  SESSION_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
@@ -266253,6 +266539,7 @@ var init_milestone_slice_interview = __esm({
266253
266539
  init_mission_interview();
266254
266540
  init_src5();
266255
266541
  init_planning_board_tools();
266542
+ init_lane_session_model();
266256
266543
  diagnostics5 = createSessionDiagnostics("milestone-slice-interview");
266257
266544
  SESSION_TTL_MS4 = 7 * 24 * 60 * 60 * 1e3;
266258
266545
  CLEANUP_INTERVAL_MS5 = 5 * 60 * 1e3;
@@ -271489,6 +271776,7 @@ var SESSION_PROMPT;
271489
271776
  var init_pr_conflict_resolver = __esm({
271490
271777
  "../dashboard/src/pr-conflict-resolver.ts"() {
271491
271778
  "use strict";
271779
+ init_src2();
271492
271780
  init_src5();
271493
271781
  init_resolve_diff_base();
271494
271782
  SESSION_PROMPT = [
@@ -278024,7 +278312,7 @@ var init_register_gitlab = __esm({
278024
278312
 
278025
278313
  // ../dashboard/src/terminal.ts
278026
278314
  import { spawn as spawn11 } from "node:child_process";
278027
- import { randomUUID as randomUUID48 } from "node:crypto";
278315
+ import { randomUUID as randomUUID49 } from "node:crypto";
278028
278316
  import { EventEmitter as EventEmitter41 } from "node:events";
278029
278317
  function extractBaseCommand(command) {
278030
278318
  let trimmed = command.trim();
@@ -278184,7 +278472,7 @@ var init_terminal = __esm({
278184
278472
  if (!validation.valid) {
278185
278473
  return { sessionId: "", error: validation.error };
278186
278474
  }
278187
- const sessionId = randomUUID48();
278475
+ const sessionId = randomUUID49();
278188
278476
  const childProcess5 = spawn11(command, [], {
278189
278477
  cwd,
278190
278478
  shell: true,
@@ -278602,6 +278890,7 @@ var init_agent_generation = __esm({
278602
278890
  "use strict";
278603
278891
  init_ai_session_diagnostics();
278604
278892
  init_process_lifecycle();
278893
+ init_lane_session_model();
278605
278894
  init_src5();
278606
278895
  resolvePrompt2 = () => "";
278607
278896
  promptCatalogReady = false;
@@ -279333,7 +279622,7 @@ var init_src8 = __esm({
279333
279622
 
279334
279623
  // ../../plugins/fusion-plugin-openclaw-runtime/src/pi-module.ts
279335
279624
  import { spawn as spawn13 } from "node:child_process";
279336
- import { randomUUID as randomUUID49 } from "node:crypto";
279625
+ import { randomUUID as randomUUID50 } from "node:crypto";
279337
279626
  import { readFile as readFile42 } from "node:fs/promises";
279338
279627
  function asString2(v2) {
279339
279628
  return typeof v2 === "string" && v2.trim() !== "" ? v2.trim() : void 0;
@@ -279393,7 +279682,7 @@ function extractStderrError(stderr, stdout) {
279393
279682
  }
279394
279683
  function createCliSession(opts) {
279395
279684
  return {
279396
- sessionId: randomUUID49(),
279685
+ sessionId: randomUUID50(),
279397
279686
  agentId: opts.agentId ?? DEFAULT_AGENT_ID,
279398
279687
  systemPrompt: opts.systemPrompt,
279399
279688
  messages: [{ role: "developer", content: opts.systemPrompt }],
@@ -279588,7 +279877,7 @@ var init_mcp_config2 = __esm({
279588
279877
  });
279589
279878
 
279590
279879
  // ../../plugins/fusion-plugin-openclaw-runtime/src/runtime-adapter.ts
279591
- import { randomUUID as randomUUID50 } from "node:crypto";
279880
+ import { randomUUID as randomUUID51 } from "node:crypto";
279592
279881
  var OpenClawRuntimeAdapter;
279593
279882
  var init_runtime_adapter2 = __esm({
279594
279883
  "../../plugins/fusion-plugin-openclaw-runtime/src/runtime-adapter.ts"() {
@@ -279611,8 +279900,8 @@ var init_runtime_adapter2 = __esm({
279611
279900
  let mcpProfile;
279612
279901
  let mcpConfigPath;
279613
279902
  if (toolDefs.length > 0) {
279614
- const bridge = writeOpenClawMcpBridgeFiles(toolDefs, randomUUID50());
279615
- mcpProfile = `fusion-${randomUUID50()}`;
279903
+ const bridge = writeOpenClawMcpBridgeFiles(toolDefs, randomUUID51());
279904
+ mcpProfile = `fusion-${randomUUID51()}`;
279616
279905
  mcpConfigPath = bridge.serverConfigPath;
279617
279906
  await configureOpenClawMcpServer({
279618
279907
  binaryPath: this.config.binaryPath,
@@ -282086,7 +282375,7 @@ import { existsSync as existsSync72, writeFileSync as writeFileSync15 } from "no
282086
282375
  import { tmpdir as tmpdir16 } from "node:os";
282087
282376
  import { dirname as dirname41, join as join95 } from "node:path";
282088
282377
  import { fileURLToPath as fileURLToPath9 } from "node:url";
282089
- import { randomUUID as randomUUID51 } from "node:crypto";
282378
+ import { randomUUID as randomUUID52 } from "node:crypto";
282090
282379
  function toolsToMcpToolDefs2(tools) {
282091
282380
  if (!Array.isArray(tools)) return [];
282092
282381
  return tools.filter((tool) => tool && typeof tool.name === "string" && tool.name.trim().length > 0 && !BUILT_IN_TOOL_NAMES2.has(tool.name)).map((tool) => ({
@@ -282137,7 +282426,7 @@ async function startFusionToolBridge(tools) {
282137
282426
  byName.set(tool.name, tool);
282138
282427
  }
282139
282428
  }
282140
- const schemaPath = join95(tmpdir16(), `fusion-grok-mcp-schemas-${process.pid}-${randomUUID51()}.json`);
282429
+ const schemaPath = join95(tmpdir16(), `fusion-grok-mcp-schemas-${process.pid}-${randomUUID52()}.json`);
282141
282430
  writeFileSync15(schemaPath, JSON.stringify(defs));
282142
282431
  const server = createServer2(async (req, res) => {
282143
282432
  if (req.method !== "POST" || req.url !== "/tool-call") {
@@ -282163,7 +282452,7 @@ async function startFusionToolBridge(tools) {
282163
282452
  return;
282164
282453
  }
282165
282454
  try {
282166
- const result = await tool.execute(`grok-mcp-${randomUUID51()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
282455
+ const result = await tool.execute(`grok-mcp-${randomUUID52()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
282167
282456
  res.statusCode = 200;
282168
282457
  res.setHeader("content-type", "application/json");
282169
282458
  res.end(
@@ -284207,7 +284496,7 @@ import { existsSync as existsSync76, rmSync as rmSync13, writeFileSync as writeF
284207
284496
  import { tmpdir as tmpdir18 } from "node:os";
284208
284497
  import { dirname as dirname46, join as join100 } from "node:path";
284209
284498
  import { fileURLToPath as fileURLToPath13 } from "node:url";
284210
- import { randomBytes as randomBytes7, randomUUID as randomUUID52 } from "node:crypto";
284499
+ import { randomBytes as randomBytes7, randomUUID as randomUUID53 } from "node:crypto";
284211
284500
  function toolsToMcpToolDefs3(tools) {
284212
284501
  if (!Array.isArray(tools)) return [];
284213
284502
  return tools.filter((tool) => tool && typeof tool.name === "string" && tool.name.trim().length > 0 && !BUILT_IN_TOOL_NAMES3.has(tool.name)).map((tool) => ({
@@ -284258,7 +284547,7 @@ async function startFusionToolBridge2(tools, options = {}) {
284258
284547
  byName.set(tool.name, tool);
284259
284548
  }
284260
284549
  }
284261
- const schemaPath = join100(tmpdir18(), `fusion-claude-mcp-schemas-${process.pid}-${randomUUID52()}.json`);
284550
+ const schemaPath = join100(tmpdir18(), `fusion-claude-mcp-schemas-${process.pid}-${randomUUID53()}.json`);
284262
284551
  writeFileSync17(schemaPath, JSON.stringify(defs));
284263
284552
  const capabilityToken = randomBytes7(32).toString("base64url");
284264
284553
  const server = createServer3(async (req, res) => {
@@ -284323,7 +284612,7 @@ async function startFusionToolBridge2(tools, options = {}) {
284323
284612
  return;
284324
284613
  }
284325
284614
  try {
284326
- const result = await tool.execute(`claude-mcp-${randomUUID52()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
284615
+ const result = await tool.execute(`claude-mcp-${randomUUID53()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
284327
284616
  res.statusCode = 200;
284328
284617
  res.setHeader("content-type", "application/json");
284329
284618
  res.end(
@@ -286400,7 +286689,7 @@ import { existsSync as existsSync78, unlinkSync as unlinkSync5, writeFileSync as
286400
286689
  import { tmpdir as tmpdir19 } from "node:os";
286401
286690
  import { dirname as dirname49, join as join103 } from "node:path";
286402
286691
  import { fileURLToPath as fileURLToPath15 } from "node:url";
286403
- import { randomUUID as randomUUID53 } from "node:crypto";
286692
+ import { randomUUID as randomUUID54 } from "node:crypto";
286404
286693
  function toolsToMcpToolDefs4(tools) {
286405
286694
  if (!Array.isArray(tools)) return [];
286406
286695
  return tools.filter(
@@ -286457,7 +286746,7 @@ async function startFusionToolBridge3(tools) {
286457
286746
  byName.set(tool.name, tool);
286458
286747
  }
286459
286748
  }
286460
- const schemaPath = join103(tmpdir19(), `fusion-omp-mcp-schemas-${process.pid}-${randomUUID53()}.json`);
286749
+ const schemaPath = join103(tmpdir19(), `fusion-omp-mcp-schemas-${process.pid}-${randomUUID54()}.json`);
286461
286750
  writeFileSync18(schemaPath, JSON.stringify(defs));
286462
286751
  const server = createServer4(async (req, res) => {
286463
286752
  if (req.method !== "POST" || req.url !== "/tool-call") {
@@ -286484,7 +286773,7 @@ async function startFusionToolBridge3(tools) {
286484
286773
  }
286485
286774
  try {
286486
286775
  const result = await tool.execute(
286487
- `omp-mcp-${randomUUID53()}`,
286776
+ `omp-mcp-${randomUUID54()}`,
286488
286777
  parsed.arguments ?? {},
286489
286778
  void 0,
286490
286779
  void 0,
@@ -287377,7 +287666,7 @@ var init_paperclip_client = __esm({
287377
287666
  });
287378
287667
 
287379
287668
  // ../../plugins/fusion-plugin-paperclip-runtime/src/runtime-adapter.ts
287380
- import { randomUUID as randomUUID54 } from "node:crypto";
287669
+ import { randomUUID as randomUUID55 } from "node:crypto";
287381
287670
  function sleep7(ms2) {
287382
287671
  return new Promise((resolve52) => setTimeout(resolve52, ms2));
287383
287672
  }
@@ -287506,7 +287795,7 @@ var init_runtime_adapter10 = __esm({
287506
287795
  apiKey: effectiveApiKey,
287507
287796
  agentId,
287508
287797
  companyId,
287509
- sessionId: randomUUID54(),
287798
+ sessionId: randomUUID55(),
287510
287799
  systemPrompt: options.systemPrompt,
287511
287800
  cwd: options.cwd,
287512
287801
  mode: normalizeMode3(this.config.mode),
@@ -291236,7 +291525,7 @@ init_src2();
291236
291525
  init_gh_cli();
291237
291526
  init_src5();
291238
291527
  init_src15();
291239
- import { randomUUID as randomUUID55 } from "node:crypto";
291528
+ import { randomUUID as randomUUID56 } from "node:crypto";
291240
291529
  import { Type as Type9 } from "typebox";
291241
291530
  import { StringEnum } from "@earendil-works/pi-ai";
291242
291531
  import { resolve as resolve51, relative as relative19, isAbsolute as isAbsolute26, sep as sep15, basename as basename30, extname as extname4, join as join106 } from "node:path";
@@ -291973,7 +292262,7 @@ function kbExtension(pi2) {
291973
292262
  const layer = store.getAsyncLayer();
291974
292263
  const messageStore = layer ? new MessageStore(null, { asyncLayer: layer }) : new MessageStore(store.getDatabase());
291975
292264
  const title = params.description.split(/\r?\n/, 1)[0]?.trim().slice(0, 80) || "Follow-up task";
291976
- await messageStore.sendMessage({ fromId: fnCtx.agentId ?? "ephemeral-worker", fromType: "agent", toId: DASHBOARD_USER_ID, toType: "user", type: "agent-to-user", content: `Task proposal awaiting validation: ${title}`, metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID55(), proposedTask: { title, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.depends } } });
292265
+ await messageStore.sendMessage({ fromId: fnCtx.agentId ?? "ephemeral-worker", fromType: "agent", toId: DASHBOARD_USER_ID, toType: "user", type: "agent-to-user", content: `Task proposal awaiting validation: ${title}`, metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID56(), proposedTask: { title, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.depends } } });
291977
292266
  return { content: [{ type: "text", text: "Task proposal submitted to the operator for validation; no task was created." }], details: { proposed: true } };
291978
292267
  }
291979
292268
  }