@straiffi/archon 1.10.10 → 1.11.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 (215) hide show
  1. package/README.md +9 -2
  2. package/dist/client/assets/{ActivityView-CRkM5TeN.js → ActivityView-BvXSn9Jw.js} +1 -1
  3. package/dist/client/assets/GitHubActionsDialog-BPZg_Wy3.js +1 -0
  4. package/dist/client/assets/VerificationDialog-D3mOY3z9.js +4 -0
  5. package/dist/client/assets/{architectureDiagram-3BPJPVTR-u0PSZlNP.js → architectureDiagram-3BPJPVTR-Bj7m5nzx.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-GPEHLZMM-DFXLHRIk.js → blockDiagram-GPEHLZMM-Dv4SrhZg.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-AAUBKEIU-Dvic8tCt.js → c4Diagram-AAUBKEIU-BKGsMo_n.js} +1 -1
  8. package/dist/client/assets/channel-DmiHuOD2.js +1 -0
  9. package/dist/client/assets/{chunk-2J33WTMH-t5CxhRXJ.js → chunk-2J33WTMH-oppoEflV.js} +1 -1
  10. package/dist/client/assets/{chunk-3OPIFGDE-YHT1dP8Q.js → chunk-3OPIFGDE-FoeHxEDL.js} +1 -1
  11. package/dist/client/assets/{chunk-5ZQYHXKU-DcxuI7lb.js → chunk-5ZQYHXKU-DFo7Hn8f.js} +1 -1
  12. package/dist/client/assets/{chunk-727SXJPM-D1F6DmrT.js → chunk-727SXJPM-BbM0ijwZ.js} +1 -1
  13. package/dist/client/assets/{chunk-AQP2D5EJ-BIx6Ohbk.js → chunk-AQP2D5EJ-hGswj21x.js} +1 -1
  14. package/dist/client/assets/{chunk-CSCIHK7Q-B355h6HA.js → chunk-CSCIHK7Q-k3Y3HBPl.js} +1 -1
  15. package/dist/client/assets/{chunk-KSCS5N6A-CLHGYOLQ.js → chunk-KSCS5N6A-D-fMWFHX.js} +1 -1
  16. package/dist/client/assets/{chunk-L5ZTLDWV-DFLYcMx8.js → chunk-L5ZTLDWV-Cp8034Xo.js} +1 -1
  17. package/dist/client/assets/{chunk-LZXEDZCA-DtljFujX.js → chunk-LZXEDZCA-DCmWwuZY.js} +2 -2
  18. package/dist/client/assets/{chunk-ND2GUHAM-CIuUQ86K.js → chunk-ND2GUHAM-CPxoYLrb.js} +1 -1
  19. package/dist/client/assets/{chunk-NZK2D7GU-CIwqlxek.js → chunk-NZK2D7GU-B1xsQ-Ge.js} +1 -1
  20. package/dist/client/assets/{chunk-O5CBEL6O-W42BEPu4.js → chunk-O5CBEL6O-CP_QLulv.js} +1 -1
  21. package/dist/client/assets/{chunk-WU5MYG2G-C_zuaNxV.js → chunk-WU5MYG2G-CqDmmASz.js} +1 -1
  22. package/dist/client/assets/classDiagram-4FO5ZUOK-GuChK9KD.js +1 -0
  23. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-ezsQe4jc.js +1 -0
  24. package/dist/client/assets/{dagre-BM42HDAG-UKfIUJTP.js → dagre-BM42HDAG-I60HgRr5.js} +1 -1
  25. package/dist/client/assets/{diagram-2AECGRRQ-Xn6yojqq.js → diagram-2AECGRRQ-DH7489lu.js} +1 -1
  26. package/dist/client/assets/{diagram-5GNKFQAL-BzpY1ZEl.js → diagram-5GNKFQAL-UG5kJveS.js} +1 -1
  27. package/dist/client/assets/{diagram-KO2AKTUF-Dyrvzvsg.js → diagram-KO2AKTUF-DLPd9cl-.js} +1 -1
  28. package/dist/client/assets/{diagram-LMA3HP47-AqImKwAr.js → diagram-LMA3HP47-gfoMHIE-.js} +1 -1
  29. package/dist/client/assets/{diagram-OG6HWLK6-CaQQ46mi.js → diagram-OG6HWLK6-D7zejHzo.js} +1 -1
  30. package/dist/client/assets/{erDiagram-TEJ5UH35-Dkw4Aa5u.js → erDiagram-TEJ5UH35-DB1R9rUd.js} +1 -1
  31. package/dist/client/assets/{flowDiagram-I6XJVG4X-CJTuGX9h.js → flowDiagram-I6XJVG4X-rSasRun9.js} +1 -1
  32. package/dist/client/assets/{ganttDiagram-6RSMTGT7-CidgOdS-.js → ganttDiagram-6RSMTGT7-ickt48MT.js} +1 -1
  33. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-Bj02mIQj.js → gitGraphDiagram-PVQCEYII-B2MWuej-.js} +1 -1
  34. package/dist/client/assets/index-4RQBXPuO.css +2 -0
  35. package/dist/client/assets/index-BN2UMUYo.js +276 -0
  36. package/dist/client/assets/{infoDiagram-5YYISTIA-GwJWfo_r.js → infoDiagram-5YYISTIA-ClB9-yBC.js} +1 -1
  37. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-rbrlWbUn.js → ishikawaDiagram-YF4QCWOH-CyUX0IyE.js} +1 -1
  38. package/dist/client/assets/{journeyDiagram-JHISSGLW-BLi_uzQM.js → journeyDiagram-JHISSGLW-CvZv1SZ7.js} +1 -1
  39. package/dist/client/assets/{kanban-definition-UN3LZRKU-ynlywm-_.js → kanban-definition-UN3LZRKU-C3MgzQMY.js} +1 -1
  40. package/dist/client/assets/{line-BNyTZBB4.js → line-Dpj7mkeR.js} +1 -1
  41. package/dist/client/assets/{mermaid-parser.core-CzUOsZAD.js → mermaid-parser.core-Ezn4UHHp.js} +1 -1
  42. package/dist/client/assets/{mermaid.core-K0QR6SzN.js → mermaid.core-GVI7XZqR.js} +3 -3
  43. package/dist/client/assets/{mindmap-definition-RKZ34NQL-BKcgqXm0.js → mindmap-definition-RKZ34NQL-Bu2cgOo4.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-4H26LBE5-Bjx0lvDI.js → pieDiagram-4H26LBE5-_WS41t2_.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CmUlgyUv.js → quadrantDiagram-W4KKPZXB-Urvq-XqI.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-4Y6WPE33-Dj2mzg1y.js → requirementDiagram-4Y6WPE33-bkmWG0rM.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DC--H6qf.js → sankeyDiagram-5OEKKPKP-DI0SArVz.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BkNrt6Ra.js → sequenceDiagram-3UESZ5HK-n7PKrHd3.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-AJRCARHV-BuxxRu1Y.js → stateDiagram-AJRCARHV-CxnEzrQA.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DXTMu4iJ.js +1 -0
  51. package/dist/client/assets/{timeline-definition-PNZ67QCA-Db3pCVSp.js → timeline-definition-PNZ67QCA-BFr88_A9.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-CIIHVFJN-BgBSGThQ.js → vennDiagram-CIIHVFJN-BNYs6tfr.js} +1 -1
  53. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BJhPdjYS.js → wardleyDiagram-YWT4CUSO-CaGZd3fe.js} +1 -1
  54. package/dist/client/assets/{xychartDiagram-2RQKCTM6-BY4Ra0kX.js → xychartDiagram-2RQKCTM6-CMyDrx2a.js} +1 -1
  55. package/dist/client/index.html +2 -2
  56. package/dist/server/db.js +181 -28
  57. package/dist/server/db.js.map +1 -1
  58. package/dist/server/index.js +118 -40
  59. package/dist/server/index.js.map +1 -1
  60. package/dist/server/lib/activeTool.js +23 -0
  61. package/dist/server/lib/activeTool.js.map +1 -0
  62. package/dist/server/lib/agent.js +291 -67
  63. package/dist/server/lib/agent.js.map +1 -1
  64. package/dist/server/lib/agentCatalog.js +92 -4
  65. package/dist/server/lib/agentCatalog.js.map +1 -1
  66. package/dist/server/lib/agentProvider.js +8 -11
  67. package/dist/server/lib/agentProvider.js.map +1 -1
  68. package/dist/server/lib/agentRuns.js +26 -2
  69. package/dist/server/lib/agentRuns.js.map +1 -1
  70. package/dist/server/lib/automationCheckGate.js +6 -0
  71. package/dist/server/lib/automationCheckGate.js.map +1 -1
  72. package/dist/server/lib/buildExecutionEnvironment.js +82 -29
  73. package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
  74. package/dist/server/lib/buildFlow.js +5 -4
  75. package/dist/server/lib/buildFlow.js.map +1 -1
  76. package/dist/server/lib/buildSequences.js +7 -29
  77. package/dist/server/lib/buildSequences.js.map +1 -1
  78. package/dist/server/lib/buildTicketCommit.js +82 -11
  79. package/dist/server/lib/buildTicketCommit.js.map +1 -1
  80. package/dist/server/lib/bundleReviewOperations.js +6 -0
  81. package/dist/server/lib/bundleReviewOperations.js.map +1 -1
  82. package/dist/server/lib/chatOperations.js +109 -93
  83. package/dist/server/lib/chatOperations.js.map +1 -1
  84. package/dist/server/lib/chatSessionTitle.js +66 -0
  85. package/dist/server/lib/chatSessionTitle.js.map +1 -0
  86. package/dist/server/lib/chats.js +20 -4
  87. package/dist/server/lib/chats.js.map +1 -1
  88. package/dist/server/lib/checkAutoFix.js +65 -61
  89. package/dist/server/lib/checkAutoFix.js.map +1 -1
  90. package/dist/server/lib/codexAgentProvider.js +320 -0
  91. package/dist/server/lib/codexAgentProvider.js.map +1 -0
  92. package/dist/server/lib/codexAppServer.js +678 -0
  93. package/dist/server/lib/codexAppServer.js.map +1 -0
  94. package/dist/server/lib/codexCatalogDiscoveryExecutionEnvironment.js +302 -0
  95. package/dist/server/lib/codexCatalogDiscoveryExecutionEnvironment.js.map +1 -0
  96. package/dist/server/lib/codexDiscovery.js +137 -0
  97. package/dist/server/lib/codexDiscovery.js.map +1 -0
  98. package/dist/server/lib/config.js.map +1 -1
  99. package/dist/server/lib/dockerSandboxEnvironmentOperations.js +2 -2
  100. package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
  101. package/dist/server/lib/dockerSandboxExecutionEnvironment.js +39 -10
  102. package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
  103. package/dist/server/lib/dockerSandboxExecutionProvider.js +3 -1
  104. package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
  105. package/dist/server/lib/dockerSandboxReleaseProfiles.js +8 -0
  106. package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -1
  107. package/dist/server/lib/executionCredentialCapabilities.js +39 -14
  108. package/dist/server/lib/executionCredentialCapabilities.js.map +1 -1
  109. package/dist/server/lib/executionEnvironment.js.map +1 -1
  110. package/dist/server/lib/executionEnvironmentContexts.js +1 -1
  111. package/dist/server/lib/executionEnvironmentContexts.js.map +1 -1
  112. package/dist/server/lib/executionEnvironmentLifecycle.js +1 -1
  113. package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
  114. package/dist/server/lib/executionEnvironmentReconciliation.js +22 -9
  115. package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -1
  116. package/dist/server/lib/executionEnvironmentRoutes.js +29 -25
  117. package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
  118. package/dist/server/lib/executionEnvironmentValidation.js +205 -20
  119. package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
  120. package/dist/server/lib/executionEnvironmentValidationOperations.js +34 -29
  121. package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
  122. package/dist/server/lib/executionEnvironments.js +74 -1
  123. package/dist/server/lib/executionEnvironments.js.map +1 -1
  124. package/dist/server/lib/executionProfiles.js +6 -3
  125. package/dist/server/lib/executionProfiles.js.map +1 -1
  126. package/dist/server/lib/executionRetryPredicates.js +2 -1
  127. package/dist/server/lib/executionRetryPredicates.js.map +1 -1
  128. package/dist/server/lib/executionRunAuthority.js +6 -1
  129. package/dist/server/lib/executionRunAuthority.js.map +1 -1
  130. package/dist/server/lib/genericToolCall.js +131 -9
  131. package/dist/server/lib/genericToolCall.js.map +1 -1
  132. package/dist/server/lib/hostExecutionEnvironment.js +5 -0
  133. package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
  134. package/dist/server/lib/lightweightPrompt.js +258 -18
  135. package/dist/server/lib/lightweightPrompt.js.map +1 -1
  136. package/dist/server/lib/mobileAccess.js +21 -13
  137. package/dist/server/lib/mobileAccess.js.map +1 -1
  138. package/dist/server/lib/modelResolutionErrors.js +4 -2
  139. package/dist/server/lib/modelResolutionErrors.js.map +1 -1
  140. package/dist/server/lib/models.js +15 -2
  141. package/dist/server/lib/models.js.map +1 -1
  142. package/dist/server/lib/oneShotAgent.js +11 -0
  143. package/dist/server/lib/oneShotAgent.js.map +1 -0
  144. package/dist/server/lib/projectAutoConfig.js +11 -5
  145. package/dist/server/lib/projectAutoConfig.js.map +1 -1
  146. package/dist/server/lib/projectMemory.js +3 -1
  147. package/dist/server/lib/projectMemory.js.map +1 -1
  148. package/dist/server/lib/projectMemoryScan.js +13 -3
  149. package/dist/server/lib/projectMemoryScan.js.map +1 -1
  150. package/dist/server/lib/projectMemoryTransfer.js +5 -2
  151. package/dist/server/lib/projectMemoryTransfer.js.map +1 -1
  152. package/dist/server/lib/projectTargets.js +10 -2
  153. package/dist/server/lib/projectTargets.js.map +1 -1
  154. package/dist/server/lib/promptSkills.js +1 -1
  155. package/dist/server/lib/promptSkills.js.map +1 -1
  156. package/dist/server/lib/run.js +32 -12
  157. package/dist/server/lib/run.js.map +1 -1
  158. package/dist/server/lib/runProcesses.js +13 -1
  159. package/dist/server/lib/runProcesses.js.map +1 -1
  160. package/dist/server/lib/runServices.js +5 -3
  161. package/dist/server/lib/runServices.js.map +1 -1
  162. package/dist/server/lib/runSessionLifecycle.js +10 -1
  163. package/dist/server/lib/runSessionLifecycle.js.map +1 -1
  164. package/dist/server/lib/runStatus.js +2 -1
  165. package/dist/server/lib/runStatus.js.map +1 -1
  166. package/dist/server/lib/serviceRunCleanup.js +70 -0
  167. package/dist/server/lib/serviceRunCleanup.js.map +1 -0
  168. package/dist/server/lib/serviceRuns.js +194 -12
  169. package/dist/server/lib/serviceRuns.js.map +1 -1
  170. package/dist/server/lib/skills.js +21 -4
  171. package/dist/server/lib/skills.js.map +1 -1
  172. package/dist/server/lib/specOperations.js +14 -10
  173. package/dist/server/lib/specOperations.js.map +1 -1
  174. package/dist/server/lib/specReviewOperations.js +20 -11
  175. package/dist/server/lib/specReviewOperations.js.map +1 -1
  176. package/dist/server/lib/specs.js +14 -4
  177. package/dist/server/lib/specs.js.map +1 -1
  178. package/dist/server/lib/ticketAutomationCommit.js +23 -7
  179. package/dist/server/lib/ticketAutomationCommit.js.map +1 -1
  180. package/dist/server/lib/ticketFollowUpOperations.js +7 -0
  181. package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
  182. package/dist/server/lib/ticketRunOperations.js +11 -1
  183. package/dist/server/lib/ticketRunOperations.js.map +1 -1
  184. package/dist/server/lib/ticketSettingsOperations.js +4 -1
  185. package/dist/server/lib/ticketSettingsOperations.js.map +1 -1
  186. package/dist/server/lib/toolUpgrade.js +1 -0
  187. package/dist/server/lib/toolUpgrade.js.map +1 -1
  188. package/dist/server/lib/transcriptRuns.js +4 -1
  189. package/dist/server/lib/transcriptRuns.js.map +1 -1
  190. package/dist/server/lib/types.js.map +1 -1
  191. package/dist/server/workers/build.js +9 -4
  192. package/dist/server/workers/build.js.map +1 -1
  193. package/dist/server/workers/chat.js +55 -11
  194. package/dist/server/workers/chat.js.map +1 -1
  195. package/dist/server/workers/followUp.js +6 -1
  196. package/dist/server/workers/followUp.js.map +1 -1
  197. package/dist/server/workers/plan.js +235 -68
  198. package/dist/server/workers/plan.js.map +1 -1
  199. package/dist/server/workers/planFollowUp.js +11 -4
  200. package/dist/server/workers/planFollowUp.js.map +1 -1
  201. package/dist/server/workers/review.js +15 -18
  202. package/dist/server/workers/review.js.map +1 -1
  203. package/dist/server/workers/specReview.js +7 -7
  204. package/dist/server/workers/specReview.js.map +1 -1
  205. package/dist/server/workers/specSession.js +8 -12
  206. package/dist/server/workers/specSession.js.map +1 -1
  207. package/package.json +1 -1
  208. package/dist/client/assets/GitHubActionsDialog-KFUiR00H.js +0 -1
  209. package/dist/client/assets/VerificationDialog-BIDttgiW.js +0 -4
  210. package/dist/client/assets/channel-Dhv_uSKx.js +0 -1
  211. package/dist/client/assets/classDiagram-4FO5ZUOK-9XKvSSLq.js +0 -1
  212. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Dbr5_49Y.js +0 -1
  213. package/dist/client/assets/index-ClRB9YWJ.css +0 -2
  214. package/dist/client/assets/index-DBMdsTvy.js +0 -276
  215. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Cyo85GPN.js +0 -1
package/dist/server/db.js CHANGED
@@ -8,6 +8,13 @@ import { hasConfiguredCheckPolicy } from './lib/executionProfileCheckPolicy.js';
8
8
  const dbPath = ensureParentDirectory(resolveArchonDbPath());
9
9
  const db = new Database(dbPath);
10
10
  db.pragma('foreign_keys = ON');
11
+ db.exec(`
12
+ CREATE TABLE IF NOT EXISTS app_settings (
13
+ key TEXT PRIMARY KEY,
14
+ value TEXT NOT NULL,
15
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
16
+ )
17
+ `);
11
18
  db.exec(`
12
19
  CREATE TABLE IF NOT EXISTS tickets (
13
20
  id TEXT PRIMARY KEY,
@@ -1588,6 +1595,7 @@ db.exec(`
1588
1595
  target_branch_snapshot TEXT,
1589
1596
  target_label_snapshot TEXT,
1590
1597
  claude_session_id TEXT,
1598
+ codex_session_id TEXT,
1591
1599
  opencode_session_id TEXT,
1592
1600
  usage_snapshot_context_window INTEGER,
1593
1601
  usage_snapshot_max_output_tokens INTEGER,
@@ -1713,6 +1721,7 @@ db.exec(`
1713
1721
  target_label_snapshot TEXT,
1714
1722
  latest_snapshot_id TEXT,
1715
1723
  claude_session_id TEXT,
1724
+ codex_session_id TEXT,
1716
1725
  opencode_session_id TEXT,
1717
1726
  usage_snapshot_context_window INTEGER,
1718
1727
  usage_snapshot_max_output_tokens INTEGER,
@@ -1739,6 +1748,7 @@ ensureColumn('spec_sessions', 'target_bundle_id', 'TEXT');
1739
1748
  ensureColumn('spec_sessions', 'target_branch_snapshot', 'TEXT');
1740
1749
  ensureColumn('spec_sessions', 'target_label_snapshot', 'TEXT');
1741
1750
  ensureColumn('spec_sessions', 'resume_source_run_id', 'TEXT');
1751
+ ensureColumn('spec_sessions', 'codex_session_id', 'TEXT');
1742
1752
  const backfillSpecSessionHasCompletedWork = () => {
1743
1753
  db.exec(`
1744
1754
  UPDATE spec_sessions
@@ -1874,28 +1884,6 @@ db.exec(`
1874
1884
  db.exec('CREATE INDEX IF NOT EXISTS idx_spec_sessions_project_updated_at ON spec_sessions(project_id, updated_at DESC)');
1875
1885
  db.exec('CREATE INDEX IF NOT EXISTS idx_spec_messages_session_created_at ON spec_messages(spec_session_id, created_at)');
1876
1886
  db.exec('CREATE INDEX IF NOT EXISTS idx_spec_message_attachments_spec_message_id_ordinal ON spec_message_attachments(spec_message_id, ordinal)');
1877
- db.exec(`
1878
- CREATE TRIGGER IF NOT EXISTS reject_attachment_insert_without_active_project
1879
- BEFORE INSERT ON attachments
1880
- WHEN NOT EXISTS (
1881
- SELECT 1
1882
- FROM chat_sessions
1883
- INNER JOIN projects ON projects.id = chat_sessions.project_id
1884
- WHERE NEW.owner_type = 'chat'
1885
- AND chat_sessions.id = NEW.owner_session_id
1886
- AND projects.deletion_started_at IS NULL
1887
- UNION ALL
1888
- SELECT 1
1889
- FROM spec_sessions
1890
- INNER JOIN projects ON projects.id = spec_sessions.project_id
1891
- WHERE NEW.owner_type = 'spec'
1892
- AND spec_sessions.id = NEW.owner_session_id
1893
- AND projects.deletion_started_at IS NULL
1894
- )
1895
- BEGIN
1896
- SELECT RAISE(ABORT, 'Attachment owner project was not found or is being deleted');
1897
- END;
1898
- `);
1899
1887
  ensureColumn('chat_sessions', 'usage_snapshot_context_window', 'INTEGER');
1900
1888
  ensureColumn('chat_sessions', 'usage_snapshot_max_output_tokens', 'INTEGER');
1901
1889
  ensureColumn('chat_sessions', 'usage_snapshot_total_tokens', 'INTEGER');
@@ -1923,6 +1911,7 @@ ensureColumn('chat_sessions', 'external_id', 'TEXT');
1923
1911
  ensureColumn('chat_sessions', 'external_key', 'TEXT');
1924
1912
  ensureColumn('chat_sessions', 'external_url', 'TEXT');
1925
1913
  ensureColumn('chat_sessions', 'external_metadata_json', 'TEXT');
1914
+ ensureColumn('chat_sessions', 'codex_session_id', 'TEXT');
1926
1915
  const createChatSessionsTableSql = `
1927
1916
  CREATE TABLE chat_sessions (
1928
1917
  id TEXT PRIMARY KEY,
@@ -1935,12 +1924,18 @@ const createChatSessionsTableSql = `
1935
1924
  skills_json TEXT,
1936
1925
  agent_status TEXT,
1937
1926
  agent_log TEXT,
1927
+ agent_message_id TEXT,
1928
+ previous_agent_log TEXT,
1929
+ previous_agent_message_id TEXT,
1938
1930
  streaming_response TEXT,
1931
+ post_build_source_run_id TEXT,
1932
+ resume_source_run_id TEXT,
1939
1933
  target_kind TEXT NOT NULL DEFAULT 'repo_root',
1940
1934
  target_bundle_id TEXT,
1941
1935
  target_branch_snapshot TEXT,
1942
1936
  target_label_snapshot TEXT,
1943
1937
  claude_session_id TEXT,
1938
+ codex_session_id TEXT,
1944
1939
  opencode_session_id TEXT,
1945
1940
  usage_snapshot_context_window INTEGER,
1946
1941
  usage_snapshot_max_output_tokens INTEGER,
@@ -1950,6 +1945,13 @@ const createChatSessionsTableSql = `
1950
1945
  usage_snapshot_cache_read_tokens INTEGER,
1951
1946
  usage_snapshot_reasoning_tokens INTEGER,
1952
1947
  usage_snapshot_cost REAL,
1948
+ origin_spec_session_id TEXT,
1949
+ origin_spec_snapshot_id TEXT,
1950
+ external_provider TEXT,
1951
+ external_id TEXT,
1952
+ external_key TEXT,
1953
+ external_url TEXT,
1954
+ external_metadata_json TEXT,
1953
1955
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
1954
1956
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
1955
1957
  FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
@@ -1965,12 +1967,17 @@ const migrateChatSessionsUsageSnapshotTable = () => {
1965
1967
  return;
1966
1968
  }
1967
1969
  const resolveColumn = (preferred, legacy) => {
1968
- if (legacy && columns.some(column => column.name === legacy)) {
1969
- return legacy;
1970
+ const hasPreferred = columns.some(column => column.name === preferred);
1971
+ const hasLegacy = legacy && columns.some(column => column.name === legacy);
1972
+ if (hasPreferred && hasLegacy) {
1973
+ return `COALESCE(${preferred}, ${legacy})`;
1970
1974
  }
1971
- if (columns.some(column => column.name === preferred)) {
1975
+ if (hasPreferred) {
1972
1976
  return preferred;
1973
1977
  }
1978
+ if (hasLegacy) {
1979
+ return legacy;
1980
+ }
1974
1981
  return 'NULL';
1975
1982
  };
1976
1983
  db.exec('PRAGMA foreign_keys = OFF');
@@ -1989,8 +1996,18 @@ const migrateChatSessionsUsageSnapshotTable = () => {
1989
1996
  skills_json,
1990
1997
  agent_status,
1991
1998
  agent_log,
1999
+ agent_message_id,
2000
+ previous_agent_log,
2001
+ previous_agent_message_id,
1992
2002
  streaming_response,
2003
+ post_build_source_run_id,
2004
+ resume_source_run_id,
2005
+ target_kind,
2006
+ target_bundle_id,
2007
+ target_branch_snapshot,
2008
+ target_label_snapshot,
1993
2009
  claude_session_id,
2010
+ codex_session_id,
1994
2011
  opencode_session_id,
1995
2012
  usage_snapshot_context_window,
1996
2013
  usage_snapshot_max_output_tokens,
@@ -1999,6 +2016,14 @@ const migrateChatSessionsUsageSnapshotTable = () => {
1999
2016
  usage_snapshot_output_tokens,
2000
2017
  usage_snapshot_cache_read_tokens,
2001
2018
  usage_snapshot_reasoning_tokens,
2019
+ usage_snapshot_cost,
2020
+ origin_spec_session_id,
2021
+ origin_spec_snapshot_id,
2022
+ external_provider,
2023
+ external_id,
2024
+ external_key,
2025
+ external_url,
2026
+ external_metadata_json,
2002
2027
  created_at,
2003
2028
  updated_at
2004
2029
  )
@@ -2013,8 +2038,18 @@ const migrateChatSessionsUsageSnapshotTable = () => {
2013
2038
  skills_json,
2014
2039
  agent_status,
2015
2040
  agent_log,
2041
+ ${resolveColumn('agent_message_id')},
2042
+ ${resolveColumn('previous_agent_log')},
2043
+ ${resolveColumn('previous_agent_message_id')},
2016
2044
  streaming_response,
2045
+ ${resolveColumn('post_build_source_run_id')},
2046
+ ${resolveColumn('resume_source_run_id')},
2047
+ ${resolveColumn('target_kind')},
2048
+ ${resolveColumn('target_bundle_id')},
2049
+ ${resolveColumn('target_branch_snapshot')},
2050
+ ${resolveColumn('target_label_snapshot')},
2017
2051
  claude_session_id,
2052
+ ${resolveColumn('codex_session_id')},
2018
2053
  opencode_session_id,
2019
2054
  ${resolveColumn('usage_snapshot_context_window', 'latest_turn_context_window')},
2020
2055
  ${resolveColumn('usage_snapshot_max_output_tokens', 'latest_turn_max_output_tokens')},
@@ -2023,6 +2058,14 @@ const migrateChatSessionsUsageSnapshotTable = () => {
2023
2058
  ${resolveColumn('usage_snapshot_output_tokens', 'latest_turn_output_tokens')},
2024
2059
  ${resolveColumn('usage_snapshot_cache_read_tokens', 'latest_turn_cache_read_tokens')},
2025
2060
  ${resolveColumn('usage_snapshot_reasoning_tokens', 'latest_turn_reasoning_tokens')},
2061
+ ${resolveColumn('usage_snapshot_cost')},
2062
+ ${resolveColumn('origin_spec_session_id')},
2063
+ ${resolveColumn('origin_spec_snapshot_id')},
2064
+ ${resolveColumn('external_provider')},
2065
+ ${resolveColumn('external_id')},
2066
+ ${resolveColumn('external_key')},
2067
+ ${resolveColumn('external_url')},
2068
+ ${resolveColumn('external_metadata_json')},
2026
2069
  created_at,
2027
2070
  updated_at
2028
2071
  FROM chat_sessions
@@ -2040,6 +2083,33 @@ const migrateChatSessionsUsageSnapshotTable = () => {
2040
2083
  }
2041
2084
  };
2042
2085
  migrateChatSessionsUsageSnapshotTable();
2086
+ db.exec(`
2087
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_chat_sessions_post_build_source
2088
+ ON chat_sessions(post_build_source_run_id)
2089
+ WHERE post_build_source_run_id IS NOT NULL
2090
+ `);
2091
+ db.exec(`
2092
+ CREATE TRIGGER IF NOT EXISTS reject_attachment_insert_without_active_project
2093
+ BEFORE INSERT ON attachments
2094
+ WHEN NOT EXISTS (
2095
+ SELECT 1
2096
+ FROM chat_sessions
2097
+ INNER JOIN projects ON projects.id = chat_sessions.project_id
2098
+ WHERE NEW.owner_type = 'chat'
2099
+ AND chat_sessions.id = NEW.owner_session_id
2100
+ AND projects.deletion_started_at IS NULL
2101
+ UNION ALL
2102
+ SELECT 1
2103
+ FROM spec_sessions
2104
+ INNER JOIN projects ON projects.id = spec_sessions.project_id
2105
+ WHERE NEW.owner_type = 'spec'
2106
+ AND spec_sessions.id = NEW.owner_session_id
2107
+ AND projects.deletion_started_at IS NULL
2108
+ )
2109
+ BEGIN
2110
+ SELECT RAISE(ABORT, 'Attachment owner project was not found or is being deleted');
2111
+ END;
2112
+ `);
2043
2113
  const migrateProjectMemorySuggestionsTable = () => {
2044
2114
  const columns = db.prepare('PRAGMA table_info(project_memory_suggestions)').all();
2045
2115
  if (columns.length === 0) {
@@ -2695,6 +2765,15 @@ db.exec(`
2695
2765
  service_snapshot_json TEXT NOT NULL,
2696
2766
  placement_json TEXT,
2697
2767
  interruption_scope TEXT,
2768
+ intended_status TEXT,
2769
+ intended_event_type TEXT,
2770
+ intended_message TEXT,
2771
+ cleanup_claim_id TEXT,
2772
+ cleanup_claimed_at DATETIME,
2773
+ cleanup_attempts INTEGER NOT NULL DEFAULT 0,
2774
+ cleanup_retry_at DATETIME,
2775
+ cleanup_error_message TEXT,
2776
+ force_released_at DATETIME,
2698
2777
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
2699
2778
  started_at DATETIME,
2700
2779
  completed_at DATETIME,
@@ -2712,7 +2791,11 @@ db.exec(`
2712
2791
  CHECK (environment_revision IS NULL OR environment_revision >= 1),
2713
2792
  CHECK (length(CAST(service_snapshot_json AS BLOB)) BETWEEN 2 AND 16384),
2714
2793
  CHECK (placement_json IS NULL OR length(CAST(placement_json AS BLOB)) BETWEEN 2 AND 16384),
2715
- CHECK (interruption_scope IS NULL OR interruption_scope IN ('local_processes', 'whole_environment'))
2794
+ CHECK (interruption_scope IS NULL OR interruption_scope IN ('local_processes', 'whole_environment')),
2795
+ CHECK (intended_status IS NULL OR intended_status IN ('completed', 'failed', 'cancelled', 'interrupted')),
2796
+ CHECK ((cleanup_claim_id IS NULL) = (cleanup_claimed_at IS NULL)),
2797
+ CHECK (cleanup_attempts >= 0),
2798
+ CHECK (cleanup_error_message IS NULL OR length(cleanup_error_message) <= 4000)
2716
2799
  );
2717
2800
 
2718
2801
  CREATE UNIQUE INDEX IF NOT EXISTS idx_active_service_run_context
@@ -2722,6 +2805,15 @@ db.exec(`
2722
2805
  CREATE INDEX IF NOT EXISTS idx_service_run_profile
2723
2806
  ON service_run_details(project_id, execution_profile_revision_id, created_at);
2724
2807
  `);
2808
+ ensureColumn('service_run_details', 'intended_status', 'TEXT');
2809
+ ensureColumn('service_run_details', 'intended_event_type', 'TEXT');
2810
+ ensureColumn('service_run_details', 'intended_message', 'TEXT');
2811
+ ensureColumn('service_run_details', 'cleanup_claim_id', 'TEXT');
2812
+ ensureColumn('service_run_details', 'cleanup_claimed_at', 'DATETIME');
2813
+ ensureColumn('service_run_details', 'cleanup_attempts', 'INTEGER NOT NULL DEFAULT 0');
2814
+ ensureColumn('service_run_details', 'cleanup_retry_at', 'DATETIME');
2815
+ ensureColumn('service_run_details', 'cleanup_error_message', 'TEXT');
2816
+ ensureColumn('service_run_details', 'force_released_at', 'DATETIME');
2725
2817
  const executionEnvironmentStates = "'queued', 'preparing', 'ready', 'running', 'stopped', 'retiring', 'cleanup_pending', 'retired', 'failed', 'unavailable'";
2726
2818
  db.exec(`
2727
2819
  CREATE TABLE IF NOT EXISTS execution_environments (
@@ -2789,7 +2881,7 @@ db.exec(`
2789
2881
  CHECK ((template_identity IS NULL) <> (template_digest IS NULL)),
2790
2882
  CHECK (template_identity IS NULL OR length(CAST(template_identity AS BLOB)) BETWEEN 1 AND 500),
2791
2883
  CHECK (template_digest IS NULL OR length(CAST(template_digest AS BLOB)) BETWEEN 1 AND 500),
2792
- CHECK (agent_identity IS NULL OR agent_identity IN ('opencode', 'claude')),
2884
+ CHECK (agent_identity IS NULL OR agent_identity IN ('opencode', 'claude', 'codex')),
2793
2885
  CHECK (length(CAST(compatible_agents_json AS BLOB)) BETWEEN 1 AND 100),
2794
2886
  CHECK (length(CAST(capabilities_json AS BLOB)) BETWEEN 2 AND 16384),
2795
2887
  CHECK (lifecycle_state IN (${executionEnvironmentStates})),
@@ -2920,6 +3012,63 @@ db.exec(`
2920
3012
  SELECT RAISE(ABORT, 'Execution environment run binding identity is immutable');
2921
3013
  END;
2922
3014
  `);
3015
+ const widenExecutionEnvironmentAgentIdentityCheck = () => {
3016
+ const tableSql = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'execution_environments'").get()?.sql ?? '';
3017
+ const agentIdentityCheck = /agent_identity\s+IN\s*\([^)]*\)/i.exec(tableSql)?.[0] ?? '';
3018
+ if (!agentIdentityCheck || /'codex'/i.test(agentIdentityCheck)) {
3019
+ return;
3020
+ }
3021
+ const widenedTableSql = tableSql.replace(/agent_identity\s+IN\s*\(\s*'opencode'\s*,\s*'claude'\s*\)/i, "agent_identity IN ('opencode', 'claude', 'codex')");
3022
+ if (widenedTableSql === tableSql) {
3023
+ throw new Error('Unable to widen execution environment agent identity constraint');
3024
+ }
3025
+ const replacementTableSql = widenedTableSql.replace(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:"execution_environments"|execution_environments)/i, 'CREATE TABLE execution_environments_agent_identity_v2');
3026
+ const columns = db.prepare('PRAGMA table_info(execution_environments)').all()
3027
+ .map(column => `"${column.name.replaceAll('"', '""')}"`)
3028
+ .join(', ');
3029
+ const schemaObjects = db.prepare(`
3030
+ SELECT type, name, sql FROM sqlite_master
3031
+ WHERE sql IS NOT NULL AND (
3032
+ (type = 'index' AND tbl_name = 'execution_environments')
3033
+ OR (type = 'trigger' AND instr(lower(sql), 'execution_environments') > 0)
3034
+ )
3035
+ ORDER BY type, name
3036
+ `).all();
3037
+ db.pragma('foreign_keys = OFF');
3038
+ try {
3039
+ db.exec('BEGIN');
3040
+ for (const object of schemaObjects) {
3041
+ if (object.type === 'trigger') {
3042
+ db.exec(`DROP TRIGGER "${object.name.replaceAll('"', '""')}"`);
3043
+ }
3044
+ }
3045
+ db.exec(replacementTableSql);
3046
+ db.exec(`
3047
+ INSERT INTO execution_environments_agent_identity_v2 (${columns})
3048
+ SELECT ${columns} FROM execution_environments
3049
+ `);
3050
+ db.exec('DROP TABLE execution_environments');
3051
+ db.exec('ALTER TABLE execution_environments_agent_identity_v2 RENAME TO execution_environments');
3052
+ for (const object of schemaObjects) {
3053
+ db.exec(object.sql);
3054
+ }
3055
+ const violations = db.prepare('PRAGMA foreign_key_check').all();
3056
+ if (violations.length > 0) {
3057
+ throw new Error('Execution environment agent identity migration violated foreign keys');
3058
+ }
3059
+ db.exec('COMMIT');
3060
+ }
3061
+ catch (error) {
3062
+ if (db.inTransaction) {
3063
+ db.exec('ROLLBACK');
3064
+ }
3065
+ throw error;
3066
+ }
3067
+ finally {
3068
+ db.pragma('foreign_keys = ON');
3069
+ }
3070
+ };
3071
+ widenExecutionEnvironmentAgentIdentityCheck();
2923
3072
  ensureColumn('execution_environments', 'execution_profile_revision_id', 'TEXT');
2924
3073
  ensureColumn('execution_environments', 'execution_profile_fingerprint', 'TEXT');
2925
3074
  ensureColumn('execution_environments', 'credential_requirements_fingerprint', 'TEXT');
@@ -2932,6 +3081,7 @@ ensureColumn('execution_environments', 'operation_claimed_at', 'DATETIME');
2932
3081
  ensureColumn('execution_environment_run_bindings', 'execution_profile_fingerprint', 'TEXT');
2933
3082
  ensureColumn('execution_environment_run_bindings', 'authority_json', 'TEXT');
2934
3083
  ensureColumn('execution_environment_run_bindings', 'placement_json', 'TEXT');
3084
+ db.exec('DROP TRIGGER IF EXISTS protect_service_project_target');
2935
3085
  db.exec(`
2936
3086
  CREATE VIEW IF NOT EXISTS active_project_service_authorities AS
2937
3087
  SELECT run.id AS execution_run_id, run.project_id
@@ -3102,7 +3252,10 @@ db.exec(`
3102
3252
 
3103
3253
  CREATE TRIGGER IF NOT EXISTS protect_service_project_target
3104
3254
  BEFORE UPDATE OF active_target_kind, active_target_bundle_id ON projects
3105
- WHEN EXISTS (SELECT 1 FROM active_project_service_authorities WHERE project_id = OLD.id)
3255
+ WHEN EXISTS (
3256
+ SELECT 1 FROM active_project_service_authorities active
3257
+ JOIN execution_runs run ON run.id = active.execution_run_id
3258
+ WHERE active.project_id = OLD.id AND (run.source_kind IS NULL OR run.source_kind <> 'ticket'))
3106
3259
  OR OLD.deletion_started_at IS NOT NULL
3107
3260
  BEGIN
3108
3261
  SELECT RAISE(ABORT, 'Cannot change project target while service authority or deletion is active');