@covro/covro 0.2.1-dev.3 → 0.2.1-dev.5

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 (115) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  3. package/dist/codex/adapter.js +8 -1
  4. package/dist/codex/adapter.js.map +2 -2
  5. package/dist/drizzle/0005_session_workspaces.sql +24 -0
  6. package/dist/drizzle/meta/0005_snapshot.json +480 -0
  7. package/dist/drizzle/meta/_journal.json +7 -0
  8. package/dist/server/db/operations.js +14 -1
  9. package/dist/server/db/operations.js.map +2 -2
  10. package/dist/server/db/schema.js +9 -1
  11. package/dist/server/db/schema.js.map +2 -2
  12. package/dist/server/http.js +41 -0
  13. package/dist/server/http.js.map +2 -2
  14. package/dist/server/local-files.js +2 -2
  15. package/dist/server/local-files.js.map +2 -2
  16. package/dist/server/main.js +1 -0
  17. package/dist/server/main.js.map +2 -2
  18. package/dist/server/project-clones.js +296 -0
  19. package/dist/server/project-clones.js.map +7 -0
  20. package/dist/server/service.js +116 -51
  21. package/dist/server/service.js.map +2 -2
  22. package/dist/server/workspaces.js +142 -0
  23. package/dist/server/workspaces.js.map +7 -0
  24. package/dist/shared/validation.js +5 -0
  25. package/dist/shared/validation.js.map +2 -2
  26. package/dist/shared/workspace-scope.js +9 -0
  27. package/dist/shared/workspace-scope.js.map +7 -0
  28. package/dist/web/assets/{abnfDiagram-WEYOIA3C-6n1mVJ0V.js → abnfDiagram-WEYOIA3C-CwLX554E.js} +1 -1
  29. package/dist/web/assets/{arc-DFIzIYgQ.js → arc-DAaDyyqc.js} +1 -1
  30. package/dist/web/assets/{architecture-WOLXFQ4H-CoZpoP0F.js → architecture-WOLXFQ4H-y6MnEqN0.js} +1 -1
  31. package/dist/web/assets/{architectureDiagram-ZHVYKT53-LcqVhgRh.js → architectureDiagram-ZHVYKT53-_B_4k-Pp.js} +1 -1
  32. package/dist/web/assets/{blockDiagram-RJAE7QA3-CnVQsmM8.js → blockDiagram-RJAE7QA3-C9jZ7FHy.js} +1 -1
  33. package/dist/web/assets/{c4Diagram-XDPPPE54-C38UO-rV.js → c4Diagram-XDPPPE54-DQAtMvqN.js} +1 -1
  34. package/dist/web/assets/channel-ByzMCsOB.js +1 -0
  35. package/dist/web/assets/{chunk-2E7WHVMD-SlpXCVVC.js → chunk-2E7WHVMD-Bu427yab.js} +1 -1
  36. package/dist/web/assets/{chunk-4EMNKR2T-BPJa0lfJ.js → chunk-4EMNKR2T-BrGrBG7B.js} +1 -1
  37. package/dist/web/assets/{chunk-55XCU76K-CkP_cE5N.js → chunk-55XCU76K-l4f0OZWA.js} +1 -1
  38. package/dist/web/assets/{chunk-7S6XSTFO-BnrWU32l.js → chunk-7S6XSTFO-D7ixF313.js} +1 -1
  39. package/dist/web/assets/{chunk-AQDTSKZB-J2M9tBY-.js → chunk-AQDTSKZB-Cesd-BF2.js} +1 -1
  40. package/dist/web/assets/{chunk-DSNLSHJZ-ClfNpgVO.js → chunk-DSNLSHJZ-B7dim5uT.js} +1 -1
  41. package/dist/web/assets/{chunk-HAGFOTED-k7XcZqWB.js → chunk-HAGFOTED-B-f2I7TA.js} +1 -1
  42. package/dist/web/assets/{chunk-HNE4Q36P-DHHenyG4.js → chunk-HNE4Q36P-CoIvaeX6.js} +1 -1
  43. package/dist/web/assets/{chunk-NQOKRVIF-CkA3TLYc.js → chunk-NQOKRVIF-BybRxR7n.js} +1 -1
  44. package/dist/web/assets/{chunk-UHW7PFBP-DSLKZJoJ.js → chunk-UHW7PFBP-CV5WG4tq.js} +1 -1
  45. package/dist/web/assets/{chunk-VQ5W62QI-BBkSWILl.js → chunk-VQ5W62QI-BO4AjXi1.js} +1 -1
  46. package/dist/web/assets/{chunk-WQQL4CDK-BeKgda0U.js → chunk-WQQL4CDK-CADNDGXO.js} +1 -1
  47. package/dist/web/assets/{chunk-XXDRQBXY-BC-ozzjn.js → chunk-XXDRQBXY-C6QZT7KW.js} +1 -1
  48. package/dist/web/assets/{chunk-YZO67HFG-C19e3AP5.js → chunk-YZO67HFG-Cm6eGReX.js} +1 -1
  49. package/dist/web/assets/{chunk-ZAUX2LTX-C03NsQfr.js → chunk-ZAUX2LTX-CUBoGbKg.js} +1 -1
  50. package/dist/web/assets/{chunk-ZCHMQSOR-CrXzPEWh.js → chunk-ZCHMQSOR-B0ImOOtq.js} +1 -1
  51. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-DCbxTUm6.js → classDiagram-v2-4MYWR3UA-D5NWZ9vm.js} +1 -1
  52. package/dist/web/assets/{cose-bilkent-JH36ORCC-CQZjK1BR.js → cose-bilkent-JH36ORCC-BzckEyjA.js} +1 -1
  53. package/dist/web/assets/{cynefin-EF2NZ3EQ-i1jWxeqI.js → cynefin-EF2NZ3EQ-Da_J6-Jb.js} +1 -1
  54. package/dist/web/assets/{cynefinDiagram-WF24UDRP-DfVYiPE9.js → cynefinDiagram-WF24UDRP-b4g_B1A-.js} +1 -1
  55. package/dist/web/assets/{dagre-NK4GIZVX-OhkyZBvK.js → dagre-NK4GIZVX-89H2mfs9.js} +1 -1
  56. package/dist/web/assets/{diagram-CBK3MWTC-CXdVEIne.js → diagram-CBK3MWTC-CW4f_P0l.js} +1 -1
  57. package/dist/web/assets/{diagram-I5XIIV2D-BjrxVPW0.js → diagram-I5XIIV2D-Cv5Qndgc.js} +1 -1
  58. package/dist/web/assets/{diagram-ODIL2UCW-C5BpAqPG.js → diagram-ODIL2UCW-LrXxeoCt.js} +1 -1
  59. package/dist/web/assets/{diagram-PFBEJUXE-3yWOE5ZP.js → diagram-PFBEJUXE-uJV2PooB.js} +1 -1
  60. package/dist/web/assets/{diagram-RJA3I4VV-DdRZojn9.js → diagram-RJA3I4VV-DlY0PGRs.js} +1 -1
  61. package/dist/web/assets/{diagram-TYUNFSNR-m_gnI0-3.js → diagram-TYUNFSNR-B1KoXBEE.js} +1 -1
  62. package/dist/web/assets/{dist-DMGebNoK.js → dist-B4eX4BCP.js} +1 -1
  63. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-CVwc9K-O.js → ebnfDiagram-V4P3TTPT-xCvQVbdj.js} +1 -1
  64. package/dist/web/assets/{elk-QONTBCTQ-BDC-J8E3.js → elk-QONTBCTQ-Cl8Hu-Uy.js} +1 -1
  65. package/dist/web/assets/{erDiagram-KYQIGQAA-D-dqUb0a.js → erDiagram-KYQIGQAA-Xp-AvSwE.js} +1 -1
  66. package/dist/web/assets/{eventmodeling-K75KTNOO-ByZ_MfSZ.js → eventmodeling-K75KTNOO-C0truZGU.js} +1 -1
  67. package/dist/web/assets/flowDiagram-IUGLLWBU-T67jQ-T_.js +1 -0
  68. package/dist/web/assets/{ganttDiagram-R7GPNTJY-BHzyPnqV.js → ganttDiagram-R7GPNTJY-rPaYp-D7.js} +1 -1
  69. package/dist/web/assets/{gitGraph-VSP46ZUC-DQhxrj3o.js → gitGraph-VSP46ZUC-Bgfpho41.js} +1 -1
  70. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-8M2oNXTx.js → gitGraphDiagram-PDYL7XHY-kDcmuv6k.js} +1 -1
  71. package/dist/web/assets/index-3DUP8YCe.js +142 -0
  72. package/dist/web/assets/index-B7tnf28H.css +1 -0
  73. package/dist/web/assets/{info-OHQRW6UA-717A6Kfa.js → info-OHQRW6UA-CAWg5k9R.js} +1 -1
  74. package/dist/web/assets/{infoDiagram-MVDRKAX5-D-fxOvE-.js → infoDiagram-MVDRKAX5-Cd08ebhn.js} +1 -1
  75. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-CKrXOGrR.js → ishikawaDiagram-HPEHV2GE-tAXBLt9k.js} +1 -1
  76. package/dist/web/assets/{journeyDiagram-BOSHW7O7-BLD4lmI6.js → journeyDiagram-BOSHW7O7-ZgnWqXkg.js} +1 -1
  77. package/dist/web/assets/{kanban-definition-FNSA4HC5-Mj1GI5Fb.js → kanban-definition-FNSA4HC5-BUjtjd-h.js} +1 -1
  78. package/dist/web/assets/{line-DotNyRbu.js → line-DG48HRVK.js} +1 -1
  79. package/dist/web/assets/{linear-DQ0Uvp2K.js → linear-CqnXVCVw.js} +1 -1
  80. package/dist/web/assets/{mermaid-parser.core-BtFC_UVn.js → mermaid-parser.core-gIvgB9WK.js} +3 -3
  81. package/dist/web/assets/{mermaid.core-DHL14mKq.js → mermaid.core-C_R7Y1XB.js} +4 -4
  82. package/dist/web/assets/{mindmap-definition-6OY57UG3-CMCguBhk.js → mindmap-definition-6OY57UG3-CwUEEl_y.js} +1 -1
  83. package/dist/web/assets/{packet-JDAUHWVQ-CGyEqUmo.js → packet-JDAUHWVQ-BrXmpRQ3.js} +1 -1
  84. package/dist/web/assets/{pegDiagram-ECIUJNBX-DPgLxTHJ.js → pegDiagram-ECIUJNBX-lLApO85Q.js} +1 -1
  85. package/dist/web/assets/{pie-XZMESJXO-Ddsl6geS.js → pie-XZMESJXO-C_8kR5WX.js} +1 -1
  86. package/dist/web/assets/{pieDiagram-GNMPY74T-BJdkqrU_.js → pieDiagram-GNMPY74T-CawGmJZn.js} +1 -1
  87. package/dist/web/assets/{quadrantDiagram-D57K4MC3-47l23gov.js → quadrantDiagram-D57K4MC3-Dg6Yq3s_.js} +1 -1
  88. package/dist/web/assets/{radar-ABXABTNO-DAyB1li0.js → radar-ABXABTNO-Bs1xY09D.js} +1 -1
  89. package/dist/web/assets/{railroad-I3PHUGI6-BZYuBfPR.js → railroad-I3PHUGI6-Bw_qS6e3.js} +1 -1
  90. package/dist/web/assets/{railroad-abnf-LNEFI6M7-PBkoxIWP.js → railroad-abnf-LNEFI6M7-CQr33CuI.js} +1 -1
  91. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-Bl_rTgpR.js → railroad-ebnf-DWYD2UWJ-BY9nk5pg.js} +1 -1
  92. package/dist/web/assets/{railroad-peg-JR7BVNR7-U9kj7aP3.js → railroad-peg-JR7BVNR7-CcFsAEI4.js} +1 -1
  93. package/dist/web/assets/{railroadDiagram-Y72NRBL7-Dpq4us5_.js → railroadDiagram-Y72NRBL7-rkZbchmc.js} +1 -1
  94. package/dist/web/assets/{requirementDiagram-EQYSW5RA-CCqQbcTz.js → requirementDiagram-EQYSW5RA-CSOcijj5.js} +1 -1
  95. package/dist/web/assets/{sankeyDiagram-SY24JHO5-DDwytZM3.js → sankeyDiagram-SY24JHO5-E0uo0rRp.js} +1 -1
  96. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-C-z57Y06.js → sequenceDiagram-BLEHNHQU-BKWAAcRu.js} +1 -1
  97. package/dist/web/assets/{src-CK51kAyQ.js → src-F6L8HcEC.js} +1 -1
  98. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-DgTp0O6g.js → stateDiagram-v2-A6IESKWZ-BBk2tpPh.js} +1 -1
  99. package/dist/web/assets/{swimlanes-B3ENRKFQ-BiyS7wH3.js → swimlanes-B3ENRKFQ-CAUrhGwF.js} +1 -1
  100. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BCnJymLL.js +8 -0
  101. package/dist/web/assets/{timeline-definition-JXYKGLGB-D_PAPA8Z.js → timeline-definition-JXYKGLGB-D0FWj9fa.js} +1 -1
  102. package/dist/web/assets/{treeView-D4JQ5SDB-m1fbOydD.js → treeView-D4JQ5SDB-CkJOmf93.js} +1 -1
  103. package/dist/web/assets/{treemap-SAJKECNS-Bxt7Udu9.js → treemap-SAJKECNS-BSFsardB.js} +1 -1
  104. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-BTrMcoPL.js → usecaseDiagram-WPOLBNNX-B2U-2o4g.js} +1 -1
  105. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-C_kOOxPJ.js → vennDiagram-Q3Y3IDCW-BijTH0fT.js} +1 -1
  106. package/dist/web/assets/{wardley-7MLQ67FV-C33rdYbB.js → wardley-7MLQ67FV-DDOa5RzL.js} +1 -1
  107. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-DpG2rl09.js → wardleyDiagram-IVAIDKWA-mbb5GvW5.js} +1 -1
  108. package/dist/web/assets/{xychartDiagram-4URNHDU4-5a7LnsSZ.js → xychartDiagram-4URNHDU4-DHd60D_Y.js} +1 -1
  109. package/dist/web/index.html +2 -2
  110. package/package.json +3 -3
  111. package/dist/web/assets/channel-CV6Myu73.js +0 -1
  112. package/dist/web/assets/flowDiagram-IUGLLWBU-CiUTloqN.js +0 -1
  113. package/dist/web/assets/index-DYwdlB-_.js +0 -142
  114. package/dist/web/assets/index-TP24ydrn.css +0 -1
  115. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-DJ90Jhqq.js +0 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/server/db/schema.ts"],
4
- "sourcesContent": ["import { sql } from 'drizzle-orm';\nimport {\n check,\n index,\n integer,\n primaryKey,\n sqliteTable,\n text,\n uniqueIndex,\n} from 'drizzle-orm/sqlite-core';\nimport type { ApiError } from '../../shared/types.js';\n\nexport const operations = sqliteTable(\n 'operations',\n {\n clientOperationId: text('client_operation_id').primaryKey(),\n kind: text('kind').notNull(),\n target: text('target').notNull(),\n projectId: text('project_id'),\n requestDigest: text('request_digest').notNull(),\n state: text('state', {\n enum: ['accepted', 'dispatching', 'acknowledged', 'failed', 'unknown'],\n }).notNull(),\n result: text('result', { mode: 'json' }).$type<unknown>(),\n error: text('error', { mode: 'json' }).$type<ApiError>(),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n reconciledAt: integer('reconciled_at'),\n reconciliationDecision: text('reconciliation_decision'),\n },\n (table) => [\n check(\n 'operations_state_check',\n sql`${table.state} in ('accepted', 'dispatching', 'acknowledged', 'failed', 'unknown')`,\n ),\n index('operations_state_idx').on(table.state),\n ],\n);\n\nexport const executionMarkers = sqliteTable(\n 'execution_markers',\n {\n operationId: text('operation_id')\n .primaryKey()\n .references(() => operations.clientOperationId),\n threadId: text('thread_id').notNull(),\n turnId: text('turn_id'),\n workspaceKey: text('workspace_key').notNull(),\n codexEpoch: text('codex_epoch').notNull(),\n state: text('state', { enum: ['active', 'unknown', 'terminal', 'reconciled'] }).notNull(),\n createdAt: integer('created_at').notNull(),\n endedAt: integer('ended_at'),\n reconciledAt: integer('reconciled_at'),\n reconciliationOperationId: text('reconciliation_operation_id').references(\n () => operations.clientOperationId,\n ),\n },\n (table) => [\n check(\n 'execution_markers_state_check',\n sql`${table.state} in ('active', 'unknown', 'terminal', 'reconciled')`,\n ),\n uniqueIndex('execution_markers_active_thread')\n .on(table.threadId)\n .where(sql`${table.endedAt} is null`),\n ],\n);\n\nexport const threadLinks = sqliteTable('thread_links', {\n threadId: text('thread_id').primaryKey(),\n projectId: text('project_id').notNull(),\n cwd: text('cwd').notNull(),\n source: text('source').notNull(),\n managedEpoch: text('managed_epoch'),\n updatedAt: integer('updated_at').notNull(),\n});\n\nexport const preferences = sqliteTable('preferences', {\n key: text('key').primaryKey(),\n value: text('value', { mode: 'json' }).$type<unknown>().notNull(),\n});\n\n/** Locally observed turn totals; upstream turn history does not include token usage. */\nexport const turnUsage = sqliteTable(\n 'turn_usage',\n {\n threadId: text('thread_id').notNull(),\n turnId: text('turn_id').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n },\n (table) => [primaryKey({ columns: [table.threadId, table.turnId] })],\n);\n\n/** Removing a registration retains its identity and all existing thread links. */\nexport const projectRegistrations = sqliteTable('project_registrations', {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n path: text('path').notNull(),\n canonicalRoot: text('canonical_root'),\n removedAt: integer('removed_at'),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { sql } from 'drizzle-orm';\nimport {\n check,\n index,\n integer,\n primaryKey,\n sqliteTable,\n text,\n uniqueIndex,\n} from 'drizzle-orm/sqlite-core';\nimport type { ApiError } from '../../shared/types.js';\n\nexport const operations = sqliteTable(\n 'operations',\n {\n clientOperationId: text('client_operation_id').primaryKey(),\n kind: text('kind').notNull(),\n target: text('target').notNull(),\n projectId: text('project_id'),\n requestDigest: text('request_digest').notNull(),\n state: text('state', {\n enum: ['accepted', 'dispatching', 'acknowledged', 'failed', 'unknown'],\n }).notNull(),\n result: text('result', { mode: 'json' }).$type<unknown>(),\n error: text('error', { mode: 'json' }).$type<ApiError>(),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n reconciledAt: integer('reconciled_at'),\n reconciliationDecision: text('reconciliation_decision'),\n },\n (table) => [\n check(\n 'operations_state_check',\n sql`${table.state} in ('accepted', 'dispatching', 'acknowledged', 'failed', 'unknown')`,\n ),\n index('operations_state_idx').on(table.state),\n ],\n);\n\nexport const executionMarkers = sqliteTable(\n 'execution_markers',\n {\n operationId: text('operation_id')\n .primaryKey()\n .references(() => operations.clientOperationId),\n threadId: text('thread_id').notNull(),\n turnId: text('turn_id'),\n workspaceKey: text('workspace_key').notNull(),\n codexEpoch: text('codex_epoch').notNull(),\n state: text('state', { enum: ['active', 'unknown', 'terminal', 'reconciled'] }).notNull(),\n createdAt: integer('created_at').notNull(),\n endedAt: integer('ended_at'),\n reconciledAt: integer('reconciled_at'),\n reconciliationOperationId: text('reconciliation_operation_id').references(\n () => operations.clientOperationId,\n ),\n },\n (table) => [\n check(\n 'execution_markers_state_check',\n sql`${table.state} in ('active', 'unknown', 'terminal', 'reconciled')`,\n ),\n uniqueIndex('execution_markers_active_thread')\n .on(table.threadId)\n .where(sql`${table.endedAt} is null`),\n ],\n);\n\nexport const threadLinks = sqliteTable('thread_links', {\n threadId: text('thread_id').primaryKey(),\n projectId: text('project_id'),\n cwd: text('cwd').notNull(),\n source: text('source').notNull(),\n managedEpoch: text('managed_epoch'),\n updatedAt: integer('updated_at').notNull(),\n});\n\n/** Allocations survive failed/unknown RPCs; names and archive state remain in Codex. */\nexport const sessionWorkspaces = sqliteTable('session_workspaces', {\n operationId: text('operation_id').primaryKey(),\n threadId: text('thread_id').unique(),\n rootPath: text('root_path').notNull(),\n canonicalRoot: text('canonical_root').notNull().unique(),\n createdAt: integer('created_at').notNull(),\n});\n\nexport const preferences = sqliteTable('preferences', {\n key: text('key').primaryKey(),\n value: text('value', { mode: 'json' }).$type<unknown>().notNull(),\n});\n\n/** Locally observed turn totals; upstream turn history does not include token usage. */\nexport const turnUsage = sqliteTable(\n 'turn_usage',\n {\n threadId: text('thread_id').notNull(),\n turnId: text('turn_id').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n },\n (table) => [primaryKey({ columns: [table.threadId, table.turnId] })],\n);\n\n/** Removing a registration retains its identity and all existing thread links. */\nexport const projectRegistrations = sqliteTable('project_registrations', {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n path: text('path').notNull(),\n canonicalRoot: text('canonical_root'),\n removedAt: integer('removed_at'),\n createdAt: integer('created_at').notNull(),\n updatedAt: integer('updated_at').notNull(),\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -131,6 +131,47 @@ function createApp({
131
131
  return c.json(op, status(op));
132
132
  });
133
133
  app.get("/api/projects", async (c) => c.json({ data: await service.listProjects() }));
134
+ app.get(
135
+ "/api/unassigned/runtime-settings",
136
+ async (c) => c.json(await service.readRuntimeSettings(null))
137
+ );
138
+ app.post("/api/unassigned/model-defaults", async (c) => {
139
+ const op = await service.saveModelDefaults(
140
+ null,
141
+ await parse(c, schemas.saveModelDefaultsSchema)
142
+ );
143
+ return c.json(op, status(op));
144
+ });
145
+ app.get(
146
+ "/api/unassigned/threads",
147
+ async (c) => c.json(
148
+ await service.listThreadSummaries(
149
+ null,
150
+ c.req.query("cursor") === void 0 ? void 0 : schemas.cursorSchema.parse(c.req.query("cursor")),
151
+ schemas.archivedQuerySchema.parse(c.req.query("archived"))
152
+ )
153
+ )
154
+ );
155
+ app.post("/api/unassigned/threads", async (c) => {
156
+ const op = await service.createThread(null, await parse(c, schemas.createThreadSchema));
157
+ return c.json(op, status(op));
158
+ });
159
+ app.post(
160
+ "/api/project-clones",
161
+ async (c) => c.json(service.cloneProject(await parse(c, schemas.cloneProjectSchema)), 202)
162
+ );
163
+ app.get(
164
+ "/api/project-clones/:cloneId",
165
+ (c) => c.json(service.projectClones.get(id(c.req.param("cloneId"))))
166
+ );
167
+ app.post("/api/project-clones/:cloneId/cancel", async (c) => {
168
+ await parse(c, schemas.removeProjectSchema);
169
+ return c.json(service.projectClones.cancel(id(c.req.param("cloneId"))));
170
+ });
171
+ app.post("/api/project-clones/:cloneId/register", async (c) => {
172
+ await parse(c, schemas.removeProjectSchema);
173
+ return c.json(service.projectClones.retryRegistration(id(c.req.param("cloneId"))));
174
+ });
134
175
  app.get(
135
176
  "/api/projects/:projectId/runtime-settings",
136
177
  async (c) => c.json(await service.readRuntimeSettings(id(c.req.param("projectId"))))
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/http.ts"],
4
- "sourcesContent": ["import { createHash } from 'node:crypto';\nimport { Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport { upgradeWebSocket, type HttpBindings } from '@hono/node-server';\nimport type { ZodType } from 'zod';\nimport { ZodError } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport { IMAGE_REQUEST_BYTES } from '../shared/images.js';\nimport * as schemas from '../shared/validation.js';\nimport type { Operation } from '../shared/types.js';\nimport type { AppConfig } from './config.js';\nimport { ConfigStore } from './config-store.js';\nimport { createAuthenticator, type Authenticator, type Identity } from './auth.js';\nimport type { GatewayService } from './service.js';\nimport { socketHandlers } from './websocket.js';\nimport { z } from 'zod';\nimport { releaseChannels, type UpdateController } from '../shared/updates.js';\nimport { settingsSchema, updateRequestSchema } from '../updates/manager.js';\nimport { startShellSchema } from '../shared/shell.js';\nexport interface HttpDependencies {\n config: AppConfig;\n service: GatewayService;\n staticDir: string;\n authenticate?: Authenticator;\n updates?: UpdateController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n}: HttpDependencies) {\n const app = new Hono<{\n Bindings: HttpBindings;\n Variables: { identity: Identity; operationId?: string };\n }>();\n app.onError((error, c) => {\n const failure =\n error instanceof AppError\n ? error\n : error instanceof ZodError || error instanceof SyntaxError\n ? new AppError('VALIDATION_FAILED', 'Invalid request data', 400)\n : new AppError('INTERNAL_ERROR', 'An internal error occurred', 500);\n return c.json({ error: failure.toJSON(c.get('operationId')) }, failure.status as 400);\n });\n app.get('/api/health', (c) => c.json({ ok: true }));\n app.use('*', async (c, next) => {\n c.set('identity', await authenticate(c.req.raw, c.req.path === '/ws'));\n await next();\n });\n app.use('/api/*', (c, next) =>\n bodyLimit({\n maxSize: /^\\/api\\/threads\\/[^/]+\\/(turns|steer)$/.test(c.req.path)\n ? IMAGE_REQUEST_BYTES\n : 512 * 1024,\n onError: () => {\n throw new AppError('BODY_TOO_LARGE', 'Request body exceeds limit', 413);\n },\n })(c, next),\n );\n app.use('/api/*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n if (\n service.isInMaintenance() &&\n !['GET', 'HEAD', 'OPTIONS'].includes(c.req.method) &&\n !c.req.path.startsWith('/api/updates')\n )\n throw new AppError('UPDATE_MAINTENANCE', '\u6B63\u5728\u5347\u7EA7\uFF0C\u8BF7\u7B49\u5F85\u670D\u52A1\u91CD\u65B0\u8FDE\u63A5', 503);\n await next();\n });\n if (updates) {\n app.get('/api/updates', async (c) => c.json(await updates.status()));\n app.post('/api/updates/check', async (c) => {\n const input = z\n .object({ channel: z.enum(releaseChannels).optional() })\n .strict()\n .parse(await c.req.json());\n return c.json(await updates.check(input.channel));\n });\n app.post('/api/updates/settings', async (c) =>\n c.json(await updates.configure(settingsSchema.parse(await c.req.json()))),\n );\n app.post('/api/updates/run', async (c) =>\n c.json(await updates.start(updateRequestSchema.parse(await c.req.json())), 202),\n );\n }\n const id = (value: string) => schemas.idSchema.parse(value);\n const parse = async <T>(\n c: { req: { json: () => Promise<unknown> }; set: (key: 'operationId', value: string) => void },\n schema: ZodType<T>,\n ): Promise<T> => {\n const value: unknown = await c.req.json();\n if (\n value &&\n typeof value === 'object' &&\n 'clientOperationId' in value &&\n typeof value.clientOperationId === 'string'\n )\n c.set('operationId', value.clientOperationId);\n return schema.parse(value);\n };\n const status = (op: Operation) =>\n op.status === 'dispatching' || op.status === 'accepted' ? (202 as const) : (200 as const);\n const configuration = new ConfigStore(config);\n app.use('/api/config*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n await next();\n });\n app.get('/api/config', async (c) => c.json(await configuration.snapshot()));\n app.post('/api/config', async (c) => c.json(await configuration.save(await c.req.json())));\n app.post('/api/config/import', async (c) =>\n c.json(await configuration.previewImport(await c.req.json())),\n );\n app.get('/api/config/export', async (c) => {\n c.header('Content-Disposition', 'attachment; filename=\"codex-web-config.json\"');\n return c.json(await configuration.export());\n });\n app.get('/api/history-cache-context', async (c) => {\n const identity = c.get('identity');\n if (config.auth.mode !== 'local' && !identity.subject)\n throw new AppError('UNAUTHENTICATED', '\u65E0\u6CD5\u786E\u8BA4\u7F13\u5B58\u6240\u5C5E\u7528\u6237', 401);\n const projects = await service.listProjects();\n // A restart, user change or project/permission change creates a new namespace.\n // The subject is hashed on the server and is never exposed to browser storage.\n const scope = createHash('sha256')\n .update(\n JSON.stringify([\n service.events.serverEpoch,\n service.getSystem().codexEpoch,\n config.auth.mode,\n identity.subject ?? 'local',\n projects.map((project) => [project.id, project.rootPath, project.available]),\n ]),\n )\n .digest('hex');\n return c.json({ scope });\n });\n app.get('/api/system', (c) => c.json(service.getSystem()));\n app.get('/api/shell', (c) =>\n c.json(\n service.shell.snapshot(\n c.req.query('epoch'),\n z.coerce\n .number()\n .int()\n .min(0)\n .max(Number.MAX_SAFE_INTEGER)\n .default(0)\n .parse(c.req.query('after')),\n ),\n ),\n );\n app.post('/api/projects/:projectId/shell', async (c) => {\n const op = await service.startShell(\n id(c.req.param('projectId')),\n await parse(c, startShellSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/shell/:commandId/interrupt', async (c) => {\n const op = await service.interruptShell(\n id(c.req.param('commandId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/system/compatibility/confirm', async (c) => {\n const op = await service.confirmCompatibility(\n await parse(c, schemas.confirmCompatibilitySchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/projects', async (c) => c.json({ data: await service.listProjects() }));\n app.get('/api/projects/:projectId/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(id(c.req.param('projectId')))),\n );\n app.post('/api/projects/:projectId/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n id(c.req.param('projectId')),\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/projects', async (c) =>\n c.json(service.addProject(await parse(c, schemas.createProjectSchema))),\n );\n app.post('/api/projects/:projectId/rename', async (c) =>\n c.json(\n service.renameProject(\n id(c.req.param('projectId')),\n await parse(c, schemas.renameProjectSchema),\n ),\n ),\n );\n app.post('/api/projects/:projectId/remove', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.removeProject(id(c.req.param('projectId'))));\n });\n app.get('/api/projects/:projectId/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n id(c.req.param('projectId')),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.get('/api/threads', async (c) =>\n c.json(\n await service.listThreads(\n id(c.req.query('projectId') ?? ''),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/threads/:threadId/archive', async (c) => {\n return c.json(\n await service.setThreadArchived(\n id(c.req.param('threadId')),\n await parse(c, schemas.archiveThreadSchema),\n ),\n );\n });\n app.get('/api/threads/:threadId', async (c) =>\n c.json(await service.getThread(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/history', async (c) =>\n c.json(await service.getThreadHistory(id(c.req.param('threadId')), c.req.query('cursor'))),\n );\n app.get('/api/threads/:threadId/metadata', async (c) =>\n c.json(await service.getThreadMetadata(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/export', async (c) => {\n const exported = await service.exportThread(id(c.req.param('threadId')));\n c.header('Content-Type', 'text/markdown; charset=utf-8');\n c.header('Content-Disposition', `attachment; filename=\"${exported.filename}\"`);\n c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Export-Completeness', exported.partial ? 'partial' : 'saved-history');\n return c.body(exported.markdown);\n });\n app.get('/api/threads/:threadId/images', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n c.header('Content-Security-Policy', \"default-src 'none'; sandbox\");\n const image = await service.getThreadImage(id(c.req.param('threadId')), c.req.query('path'));\n return c.body(image.bytes, 200, {\n 'Content-Type': image.contentType,\n 'Content-Length': String(image.bytes.length),\n });\n });\n app.get('/api/threads/:threadId/markdown', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(\n await service.getThreadMarkdown(id(c.req.param('threadId')), c.req.query('path')),\n );\n });\n app.get('/api/threads/:threadId/json', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadJson(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/operations/:operationId', (c) =>\n c.json(service.getOperation(id(c.req.param('operationId')))),\n );\n app.post('/api/projects/:projectId/threads', async (c) => {\n const op = await service.createThread(\n id(c.req.param('projectId')),\n await parse(c, schemas.createThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/resume', async (c) => {\n const op = await service.resumeThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.resumeThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/fork', async (c) => {\n const op = await service.forkThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.forkThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/rename', async (c) => {\n const op = await service.renameThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.renameThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/turns', async (c) => {\n const op = await service.startTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.startTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/review', async (c) => {\n const op = await service.startReview(\n id(c.req.param('threadId')),\n await parse(c, schemas.startReviewSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/steer', async (c) => {\n const op = await service.steer(\n id(c.req.param('threadId')),\n await parse(c, schemas.steerSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/compact', async (c) => {\n const op = await service.compactThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/interrupt', async (c) => {\n const op = await service.interrupt(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/actions/:actionId/resolve', async (c) => {\n const op = await service.resolveAction(\n id(c.req.param('actionId')),\n await parse(c, schemas.resolveActionSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/operations/:operationId/reconcile', async (c) => {\n const op = await service.reconcileOperation(\n id(c.req.param('operationId')),\n await parse(c, schemas.reconcileSchema),\n );\n return c.json(op, status(op));\n });\n app.get(\n '/ws',\n upgradeWebSocket((c) =>\n socketHandlers(service, config, c.get('identity'), c.req.query('overview') === '1'),\n ),\n );\n app.all('/api/*', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/api', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/ws/*', () => {\n throw new AppError('NOT_FOUND', 'WebSocket route not found', 404);\n });\n app.use('*', async (c, next) => {\n if (!c.req.path.startsWith('/assets/')) c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'same-origin');\n c.header(\n 'Content-Security-Policy',\n // Remote Markdown images load directly in the browser, including HTTPS redirects.\n // Keep scripts, connections and all other resource policies restricted as before.\n \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'\",\n );\n await next();\n });\n app.get('*', serveStatic({ root: staticDir }));\n app.get('*', async (c, next) => {\n if (!c.req.header('accept')?.includes('text/html') || /\\.[^/]+$/.test(c.req.path))\n return c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404);\n return serveStatic({ path: `${staticDir}/index.html` })(c, next);\n });\n app.notFound((c) => c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404));\n return app;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createHash } from 'node:crypto';\nimport { Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport { upgradeWebSocket, type HttpBindings } from '@hono/node-server';\nimport type { ZodType } from 'zod';\nimport { ZodError } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport { IMAGE_REQUEST_BYTES } from '../shared/images.js';\nimport * as schemas from '../shared/validation.js';\nimport type { Operation } from '../shared/types.js';\nimport type { AppConfig } from './config.js';\nimport { ConfigStore } from './config-store.js';\nimport { createAuthenticator, type Authenticator, type Identity } from './auth.js';\nimport type { GatewayService } from './service.js';\nimport { socketHandlers } from './websocket.js';\nimport { z } from 'zod';\nimport { releaseChannels, type UpdateController } from '../shared/updates.js';\nimport { settingsSchema, updateRequestSchema } from '../updates/manager.js';\nimport { startShellSchema } from '../shared/shell.js';\nexport interface HttpDependencies {\n config: AppConfig;\n service: GatewayService;\n staticDir: string;\n authenticate?: Authenticator;\n updates?: UpdateController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n}: HttpDependencies) {\n const app = new Hono<{\n Bindings: HttpBindings;\n Variables: { identity: Identity; operationId?: string };\n }>();\n app.onError((error, c) => {\n const failure =\n error instanceof AppError\n ? error\n : error instanceof ZodError || error instanceof SyntaxError\n ? new AppError('VALIDATION_FAILED', 'Invalid request data', 400)\n : new AppError('INTERNAL_ERROR', 'An internal error occurred', 500);\n return c.json({ error: failure.toJSON(c.get('operationId')) }, failure.status as 400);\n });\n app.get('/api/health', (c) => c.json({ ok: true }));\n app.use('*', async (c, next) => {\n c.set('identity', await authenticate(c.req.raw, c.req.path === '/ws'));\n await next();\n });\n app.use('/api/*', (c, next) =>\n bodyLimit({\n maxSize: /^\\/api\\/threads\\/[^/]+\\/(turns|steer)$/.test(c.req.path)\n ? IMAGE_REQUEST_BYTES\n : 512 * 1024,\n onError: () => {\n throw new AppError('BODY_TOO_LARGE', 'Request body exceeds limit', 413);\n },\n })(c, next),\n );\n app.use('/api/*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n if (\n service.isInMaintenance() &&\n !['GET', 'HEAD', 'OPTIONS'].includes(c.req.method) &&\n !c.req.path.startsWith('/api/updates')\n )\n throw new AppError('UPDATE_MAINTENANCE', '\u6B63\u5728\u5347\u7EA7\uFF0C\u8BF7\u7B49\u5F85\u670D\u52A1\u91CD\u65B0\u8FDE\u63A5', 503);\n await next();\n });\n if (updates) {\n app.get('/api/updates', async (c) => c.json(await updates.status()));\n app.post('/api/updates/check', async (c) => {\n const input = z\n .object({ channel: z.enum(releaseChannels).optional() })\n .strict()\n .parse(await c.req.json());\n return c.json(await updates.check(input.channel));\n });\n app.post('/api/updates/settings', async (c) =>\n c.json(await updates.configure(settingsSchema.parse(await c.req.json()))),\n );\n app.post('/api/updates/run', async (c) =>\n c.json(await updates.start(updateRequestSchema.parse(await c.req.json())), 202),\n );\n }\n const id = (value: string) => schemas.idSchema.parse(value);\n const parse = async <T>(\n c: { req: { json: () => Promise<unknown> }; set: (key: 'operationId', value: string) => void },\n schema: ZodType<T>,\n ): Promise<T> => {\n const value: unknown = await c.req.json();\n if (\n value &&\n typeof value === 'object' &&\n 'clientOperationId' in value &&\n typeof value.clientOperationId === 'string'\n )\n c.set('operationId', value.clientOperationId);\n return schema.parse(value);\n };\n const status = (op: Operation) =>\n op.status === 'dispatching' || op.status === 'accepted' ? (202 as const) : (200 as const);\n const configuration = new ConfigStore(config);\n app.use('/api/config*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n await next();\n });\n app.get('/api/config', async (c) => c.json(await configuration.snapshot()));\n app.post('/api/config', async (c) => c.json(await configuration.save(await c.req.json())));\n app.post('/api/config/import', async (c) =>\n c.json(await configuration.previewImport(await c.req.json())),\n );\n app.get('/api/config/export', async (c) => {\n c.header('Content-Disposition', 'attachment; filename=\"codex-web-config.json\"');\n return c.json(await configuration.export());\n });\n app.get('/api/history-cache-context', async (c) => {\n const identity = c.get('identity');\n if (config.auth.mode !== 'local' && !identity.subject)\n throw new AppError('UNAUTHENTICATED', '\u65E0\u6CD5\u786E\u8BA4\u7F13\u5B58\u6240\u5C5E\u7528\u6237', 401);\n const projects = await service.listProjects();\n // A restart, user change or project/permission change creates a new namespace.\n // The subject is hashed on the server and is never exposed to browser storage.\n const scope = createHash('sha256')\n .update(\n JSON.stringify([\n service.events.serverEpoch,\n service.getSystem().codexEpoch,\n config.auth.mode,\n identity.subject ?? 'local',\n projects.map((project) => [project.id, project.rootPath, project.available]),\n ]),\n )\n .digest('hex');\n return c.json({ scope });\n });\n app.get('/api/system', (c) => c.json(service.getSystem()));\n app.get('/api/shell', (c) =>\n c.json(\n service.shell.snapshot(\n c.req.query('epoch'),\n z.coerce\n .number()\n .int()\n .min(0)\n .max(Number.MAX_SAFE_INTEGER)\n .default(0)\n .parse(c.req.query('after')),\n ),\n ),\n );\n app.post('/api/projects/:projectId/shell', async (c) => {\n const op = await service.startShell(\n id(c.req.param('projectId')),\n await parse(c, startShellSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/shell/:commandId/interrupt', async (c) => {\n const op = await service.interruptShell(\n id(c.req.param('commandId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/system/compatibility/confirm', async (c) => {\n const op = await service.confirmCompatibility(\n await parse(c, schemas.confirmCompatibilitySchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/projects', async (c) => c.json({ data: await service.listProjects() }));\n app.get('/api/unassigned/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(null)),\n );\n app.post('/api/unassigned/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n null,\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/unassigned/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n null,\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/unassigned/threads', async (c) => {\n const op = await service.createThread(null, await parse(c, schemas.createThreadSchema));\n return c.json(op, status(op));\n });\n app.post('/api/project-clones', async (c) =>\n c.json(service.cloneProject(await parse(c, schemas.cloneProjectSchema)), 202),\n );\n app.get('/api/project-clones/:cloneId', (c) =>\n c.json(service.projectClones.get(id(c.req.param('cloneId')))),\n );\n app.post('/api/project-clones/:cloneId/cancel', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.cancel(id(c.req.param('cloneId'))));\n });\n app.post('/api/project-clones/:cloneId/register', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.retryRegistration(id(c.req.param('cloneId'))));\n });\n app.get('/api/projects/:projectId/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(id(c.req.param('projectId')))),\n );\n app.post('/api/projects/:projectId/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n id(c.req.param('projectId')),\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/projects', async (c) =>\n c.json(service.addProject(await parse(c, schemas.createProjectSchema))),\n );\n app.post('/api/projects/:projectId/rename', async (c) =>\n c.json(\n service.renameProject(\n id(c.req.param('projectId')),\n await parse(c, schemas.renameProjectSchema),\n ),\n ),\n );\n app.post('/api/projects/:projectId/remove', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.removeProject(id(c.req.param('projectId'))));\n });\n app.get('/api/projects/:projectId/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n id(c.req.param('projectId')),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.get('/api/threads', async (c) =>\n c.json(\n await service.listThreads(\n id(c.req.query('projectId') ?? ''),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/threads/:threadId/archive', async (c) => {\n return c.json(\n await service.setThreadArchived(\n id(c.req.param('threadId')),\n await parse(c, schemas.archiveThreadSchema),\n ),\n );\n });\n app.get('/api/threads/:threadId', async (c) =>\n c.json(await service.getThread(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/history', async (c) =>\n c.json(await service.getThreadHistory(id(c.req.param('threadId')), c.req.query('cursor'))),\n );\n app.get('/api/threads/:threadId/metadata', async (c) =>\n c.json(await service.getThreadMetadata(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/export', async (c) => {\n const exported = await service.exportThread(id(c.req.param('threadId')));\n c.header('Content-Type', 'text/markdown; charset=utf-8');\n c.header('Content-Disposition', `attachment; filename=\"${exported.filename}\"`);\n c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Export-Completeness', exported.partial ? 'partial' : 'saved-history');\n return c.body(exported.markdown);\n });\n app.get('/api/threads/:threadId/images', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n c.header('Content-Security-Policy', \"default-src 'none'; sandbox\");\n const image = await service.getThreadImage(id(c.req.param('threadId')), c.req.query('path'));\n return c.body(image.bytes, 200, {\n 'Content-Type': image.contentType,\n 'Content-Length': String(image.bytes.length),\n });\n });\n app.get('/api/threads/:threadId/markdown', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(\n await service.getThreadMarkdown(id(c.req.param('threadId')), c.req.query('path')),\n );\n });\n app.get('/api/threads/:threadId/json', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadJson(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/operations/:operationId', (c) =>\n c.json(service.getOperation(id(c.req.param('operationId')))),\n );\n app.post('/api/projects/:projectId/threads', async (c) => {\n const op = await service.createThread(\n id(c.req.param('projectId')),\n await parse(c, schemas.createThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/resume', async (c) => {\n const op = await service.resumeThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.resumeThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/fork', async (c) => {\n const op = await service.forkThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.forkThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/rename', async (c) => {\n const op = await service.renameThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.renameThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/turns', async (c) => {\n const op = await service.startTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.startTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/review', async (c) => {\n const op = await service.startReview(\n id(c.req.param('threadId')),\n await parse(c, schemas.startReviewSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/steer', async (c) => {\n const op = await service.steer(\n id(c.req.param('threadId')),\n await parse(c, schemas.steerSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/compact', async (c) => {\n const op = await service.compactThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/interrupt', async (c) => {\n const op = await service.interrupt(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/actions/:actionId/resolve', async (c) => {\n const op = await service.resolveAction(\n id(c.req.param('actionId')),\n await parse(c, schemas.resolveActionSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/operations/:operationId/reconcile', async (c) => {\n const op = await service.reconcileOperation(\n id(c.req.param('operationId')),\n await parse(c, schemas.reconcileSchema),\n );\n return c.json(op, status(op));\n });\n app.get(\n '/ws',\n upgradeWebSocket((c) =>\n socketHandlers(service, config, c.get('identity'), c.req.query('overview') === '1'),\n ),\n );\n app.all('/api/*', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/api', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/ws/*', () => {\n throw new AppError('NOT_FOUND', 'WebSocket route not found', 404);\n });\n app.use('*', async (c, next) => {\n if (!c.req.path.startsWith('/assets/')) c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'same-origin');\n c.header(\n 'Content-Security-Policy',\n // Remote Markdown images load directly in the browser, including HTTPS redirects.\n // Keep scripts, connections and all other resource policies restricted as before.\n \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'\",\n );\n await next();\n });\n app.get('*', serveStatic({ root: staticDir }));\n app.get('*', async (c, next) => {\n if (!c.req.header('accept')?.includes('text/html') || /\\.[^/]+$/.test(c.req.path))\n return c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404);\n return serveStatic({ path: `${staticDir}/index.html` })(c, next);\n });\n app.notFound((c) => c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404));\n return app;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -25,7 +25,7 @@ function temporaryFileRoots() {
25
25
  function outsideProject(policy) {
26
26
  return new AppError(
27
27
  `${policy.code}_OUTSIDE_PROJECT`,
28
- `\u53EA\u80FD\u9884\u89C8\u5F53\u524D\u4F1A\u8BDD\u6240\u5C5E\u9879\u76EE\u6216\u670D\u52A1\u5668\u4E34\u65F6\u76EE\u5F55\u5185\u7684${policy.label}`,
28
+ `\u53EA\u80FD\u9884\u89C8\u5F53\u524D\u4F1A\u8BDD\u5DE5\u4F5C\u533A\u6216\u5141\u8BB8\u7684\u670D\u52A1\u5668\u4E34\u65F6\u76EE\u5F55\u5185\u7684${policy.label}`,
29
29
  403
30
30
  );
31
31
  }
@@ -42,7 +42,7 @@ async function readLocalFile(path, scope, policy) {
42
42
  (root) => containsPath(root.canonicalRoot, candidate) || root.aliases.some((alias) => containsPath(alias, candidate))
43
43
  ))
44
44
  throw outsideProject(policy);
45
- const isAllowed = (path2) => scope.roots.some((root) => containsPath(root.canonicalRoot, path2));
45
+ const isAllowed = (path2) => !scope.excludedRoots?.some((root) => containsPath(root, path2)) && scope.roots.some((root) => containsPath(root.canonicalRoot, path2));
46
46
  policy.validatePath(candidate);
47
47
  try {
48
48
  const canonical = await realpath(candidate);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/local-files.ts"],
4
- "sourcesContent": ["import { constants, realpathSync, statSync } from 'node:fs';\nimport { open, realpath, stat } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { isAbsolute, parse, resolve } from 'node:path';\nimport { AppError } from '../shared/errors.js';\nimport { containsPath } from './projects.js';\n\nexport interface FileRoot {\n canonicalRoot: string;\n aliases: string[];\n}\n\nexport interface FileScope {\n cwd: string;\n roots: readonly FileRoot[];\n}\n\n/** Capture server-owned roots once; clients cannot nominate a temporary directory. */\nexport function temporaryFileRoots(): FileRoot[] {\n const roots = new Map<string, FileRoot>();\n for (const directory of [tmpdir(), ...(process.platform === 'win32' ? [] : ['/tmp'])]) {\n if (!isAbsolute(directory)) continue;\n const alias = resolve(directory);\n if (alias === parse(alias).root) continue;\n try {\n const canonicalRoot = realpathSync(alias);\n if (canonicalRoot === parse(canonicalRoot).root || !statSync(canonicalRoot).isDirectory())\n continue;\n const root = roots.get(canonicalRoot) ?? { canonicalRoot, aliases: [] };\n if (!root.aliases.includes(alias)) root.aliases.push(alias);\n roots.set(canonicalRoot, root);\n } catch {\n // Unavailable temp locations do not prevent previews in the remaining roots.\n }\n }\n return [...roots.values()];\n}\n\ninterface FilePolicy {\n code: 'IMAGE' | 'MARKDOWN' | 'JSON';\n label: string;\n maxBytes: number;\n sizeError: string;\n validatePath: (path: string) => void;\n}\n\nfunction outsideProject(policy: FilePolicy): AppError {\n return new AppError(\n `${policy.code}_OUTSIDE_PROJECT`,\n `\u53EA\u80FD\u9884\u89C8\u5F53\u524D\u4F1A\u8BDD\u6240\u5C5E\u9879\u76EE\u6216\u670D\u52A1\u5668\u4E34\u65F6\u76EE\u5F55\u5185\u7684${policy.label}`,\n 403,\n );\n}\n\nfunction changedFile(policy: FilePolicy): AppError {\n return new AppError(`${policy.code}_CHANGED`, `${policy.label}\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u9884\u89C8`, 409);\n}\n\n/** Shared project/temp authorization and bounded, verified file reads for previews. */\nexport async function readLocalFile(\n path: string | undefined,\n scope: FileScope,\n policy: FilePolicy,\n) {\n if (\n !path ||\n path.length > 4096 ||\n [...path].some(\n (character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127,\n ) ||\n /^[a-z][a-z\\d+.-]*:/i.test(path) ||\n path.startsWith('//') ||\n path.startsWith('\\\\\\\\')\n )\n throw new AppError(`INVALID_${policy.code}_PATH`, `${policy.label}\u8DEF\u5F84\u65E0\u6548`, 400);\n\n const candidate = resolve(scope.cwd, path);\n // Both spellings matter on systems where /tmp or the registered directory is an alias.\n if (\n !scope.roots.some(\n (root) =>\n containsPath(root.canonicalRoot, candidate) ||\n root.aliases.some((alias) => containsPath(alias, candidate)),\n )\n )\n throw outsideProject(policy);\n const isAllowed = (path: string) =>\n scope.roots.some((root) => containsPath(root.canonicalRoot, path));\n policy.validatePath(candidate);\n\n try {\n const canonical = await realpath(candidate);\n if (!isAllowed(canonical)) throw outsideProject(policy);\n // NOFOLLOW rejects a last-component symlink swapped in after realpath. NONBLOCK\n // ensures opening a substituted FIFO cannot leave the request waiting forever.\n const file = await open(\n canonical,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n try {\n const before = await file.stat();\n if (!before.isFile())\n throw new AppError(`${policy.code}_NOT_FILE`, `${policy.label}\u8DEF\u5F84\u4E0D\u662F\u666E\u901A\u6587\u4EF6`, 415);\n if (before.size > policy.maxBytes)\n throw new AppError(`${policy.code}_TOO_LARGE`, policy.sizeError, 413);\n\n // Recheck the path and opened inode to detect ordinary concurrent replacements.\n // Node's portable file API cannot make parent-directory traversal race-free.\n const verifyPath = async () => {\n const current = await realpath(candidate);\n if (!isAllowed(current)) throw outsideProject(policy);\n if (current !== canonical) throw changedFile(policy);\n const currentStat = await stat(current);\n if (currentStat.dev !== before.dev || currentStat.ino !== before.ino)\n throw changedFile(policy);\n };\n await verifyPath();\n // One extra byte detects growth without letting readFile allocate unbounded data.\n const data = Buffer.alloc(before.size + 1);\n let length = 0;\n while (length < data.length) {\n const { bytesRead } = await file.read(data, length, data.length - length, length);\n if (!bytesRead) break;\n length += bytesRead;\n }\n if (length > policy.maxBytes)\n throw new AppError(`${policy.code}_TOO_LARGE`, policy.sizeError, 413);\n const after = await file.stat();\n if (length !== before.size || after.size !== before.size || after.mtimeMs !== before.mtimeMs)\n throw changedFile(policy);\n await verifyPath();\n const bytes = data.subarray(0, length);\n return { bytes, path: canonical };\n } finally {\n await file.close();\n }\n } catch (error) {\n if (error instanceof AppError) throw error;\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT' || code === 'ENOTDIR')\n throw new AppError(`${policy.code}_NOT_FOUND`, `${policy.label}\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664`, 404);\n if (code === 'ELOOP') throw outsideProject(policy);\n throw new AppError(`${policy.code}_UNREADABLE`, `${policy.label}\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6`, 403);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { constants, realpathSync, statSync } from 'node:fs';\nimport { open, realpath, stat } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { isAbsolute, parse, resolve } from 'node:path';\nimport { AppError } from '../shared/errors.js';\nimport { containsPath } from './projects.js';\n\nexport interface FileRoot {\n canonicalRoot: string;\n aliases: string[];\n}\n\nexport interface FileScope {\n cwd: string;\n roots: readonly FileRoot[];\n excludedRoots?: readonly string[];\n}\n\n/** Capture server-owned roots once; clients cannot nominate a temporary directory. */\nexport function temporaryFileRoots(): FileRoot[] {\n const roots = new Map<string, FileRoot>();\n for (const directory of [tmpdir(), ...(process.platform === 'win32' ? [] : ['/tmp'])]) {\n if (!isAbsolute(directory)) continue;\n const alias = resolve(directory);\n if (alias === parse(alias).root) continue;\n try {\n const canonicalRoot = realpathSync(alias);\n if (canonicalRoot === parse(canonicalRoot).root || !statSync(canonicalRoot).isDirectory())\n continue;\n const root = roots.get(canonicalRoot) ?? { canonicalRoot, aliases: [] };\n if (!root.aliases.includes(alias)) root.aliases.push(alias);\n roots.set(canonicalRoot, root);\n } catch {\n // Unavailable temp locations do not prevent previews in the remaining roots.\n }\n }\n return [...roots.values()];\n}\n\ninterface FilePolicy {\n code: 'IMAGE' | 'MARKDOWN' | 'JSON';\n label: string;\n maxBytes: number;\n sizeError: string;\n validatePath: (path: string) => void;\n}\n\nfunction outsideProject(policy: FilePolicy): AppError {\n return new AppError(\n `${policy.code}_OUTSIDE_PROJECT`,\n `\u53EA\u80FD\u9884\u89C8\u5F53\u524D\u4F1A\u8BDD\u5DE5\u4F5C\u533A\u6216\u5141\u8BB8\u7684\u670D\u52A1\u5668\u4E34\u65F6\u76EE\u5F55\u5185\u7684${policy.label}`,\n 403,\n );\n}\n\nfunction changedFile(policy: FilePolicy): AppError {\n return new AppError(`${policy.code}_CHANGED`, `${policy.label}\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u9884\u89C8`, 409);\n}\n\n/** Shared project/temp authorization and bounded, verified file reads for previews. */\nexport async function readLocalFile(\n path: string | undefined,\n scope: FileScope,\n policy: FilePolicy,\n) {\n if (\n !path ||\n path.length > 4096 ||\n [...path].some(\n (character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127,\n ) ||\n /^[a-z][a-z\\d+.-]*:/i.test(path) ||\n path.startsWith('//') ||\n path.startsWith('\\\\\\\\')\n )\n throw new AppError(`INVALID_${policy.code}_PATH`, `${policy.label}\u8DEF\u5F84\u65E0\u6548`, 400);\n\n const candidate = resolve(scope.cwd, path);\n // Both spellings matter on systems where /tmp or the registered directory is an alias.\n if (\n !scope.roots.some(\n (root) =>\n containsPath(root.canonicalRoot, candidate) ||\n root.aliases.some((alias) => containsPath(alias, candidate)),\n )\n )\n throw outsideProject(policy);\n const isAllowed = (path: string) =>\n !scope.excludedRoots?.some((root) => containsPath(root, path)) &&\n scope.roots.some((root) => containsPath(root.canonicalRoot, path));\n policy.validatePath(candidate);\n\n try {\n const canonical = await realpath(candidate);\n if (!isAllowed(canonical)) throw outsideProject(policy);\n // NOFOLLOW rejects a last-component symlink swapped in after realpath. NONBLOCK\n // ensures opening a substituted FIFO cannot leave the request waiting forever.\n const file = await open(\n canonical,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n try {\n const before = await file.stat();\n if (!before.isFile())\n throw new AppError(`${policy.code}_NOT_FILE`, `${policy.label}\u8DEF\u5F84\u4E0D\u662F\u666E\u901A\u6587\u4EF6`, 415);\n if (before.size > policy.maxBytes)\n throw new AppError(`${policy.code}_TOO_LARGE`, policy.sizeError, 413);\n\n // Recheck the path and opened inode to detect ordinary concurrent replacements.\n // Node's portable file API cannot make parent-directory traversal race-free.\n const verifyPath = async () => {\n const current = await realpath(candidate);\n if (!isAllowed(current)) throw outsideProject(policy);\n if (current !== canonical) throw changedFile(policy);\n const currentStat = await stat(current);\n if (currentStat.dev !== before.dev || currentStat.ino !== before.ino)\n throw changedFile(policy);\n };\n await verifyPath();\n // One extra byte detects growth without letting readFile allocate unbounded data.\n const data = Buffer.alloc(before.size + 1);\n let length = 0;\n while (length < data.length) {\n const { bytesRead } = await file.read(data, length, data.length - length, length);\n if (!bytesRead) break;\n length += bytesRead;\n }\n if (length > policy.maxBytes)\n throw new AppError(`${policy.code}_TOO_LARGE`, policy.sizeError, 413);\n const after = await file.stat();\n if (length !== before.size || after.size !== before.size || after.mtimeMs !== before.mtimeMs)\n throw changedFile(policy);\n await verifyPath();\n const bytes = data.subarray(0, length);\n return { bytes, path: canonical };\n } finally {\n await file.close();\n }\n } catch (error) {\n if (error instanceof AppError) throw error;\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT' || code === 'ENOTDIR')\n throw new AppError(`${policy.code}_NOT_FOUND`, `${policy.label}\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664`, 404);\n if (code === 'ELOOP') throw outsideProject(policy);\n throw new AppError(`${policy.code}_UNREADABLE`, `${policy.label}\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6`, 403);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path"]
7
7
  }
@@ -32,6 +32,7 @@ async function startGateway(config, overrides = {}) {
32
32
  store: new OperationStore(db.database),
33
33
  projects: new ProjectRegistry(config.projects, db.database),
34
34
  codex,
35
+ workspacesRoot: join(config.dataDir, "workspaces"),
35
36
  limits: config.limits,
36
37
  authMode: config.auth.mode,
37
38
  demo: config.demo
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/main.ts"],
4
- "sourcesContent": ["import { fileURLToPath } from 'node:url';\nimport { join } from 'node:path';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { serve } from '@hono/node-server';\nimport { WebSocketServer } from 'ws';\nimport { CodexAdapter } from '../codex/adapter.js';\nimport type { CodexClient } from '../codex/types.js';\nimport { loadConfig, type AppConfig } from './config.js';\nimport { acquireInstanceLock } from './instance-lock.js';\nimport { openDatabase } from './db/index.js';\nimport { migrateDatabase } from './db/migrate.js';\nimport { OperationStore } from './db/operations.js';\nimport { ProjectRegistry } from './projects.js';\nimport { GatewayService } from './service.js';\nimport { createApp } from './http.js';\nimport { startHeartbeat } from './websocket.js';\nimport { UpdateManager } from '../updates/manager.js';\nimport type { UpdateController } from '../shared/updates.js';\nexport async function startGateway(\n config: AppConfig,\n overrides: {\n codex?: CodexClient;\n staticDir?: string;\n migrationsDir?: string;\n updates?: UpdateController;\n maintenance?: boolean;\n } = {},\n) {\n const release = await acquireInstanceLock(config.dataDir);\n let closeDatabase: (() => void) | undefined;\n let codex: CodexClient | undefined;\n const updates =\n overrides.updates ??\n new UpdateManager(undefined, undefined, () => codex?.diagnostics().codexVersion ?? null);\n try {\n const db = openDatabase(join(config.dataDir, 'app.sqlite'));\n closeDatabase = db.close;\n const packagedMigrations = fileURLToPath(new URL('../drizzle', import.meta.url));\n migrateDatabase(\n db.database,\n overrides.migrationsDir ?? (existsSync(packagedMigrations) ? packagedMigrations : undefined),\n );\n codex = overrides.codex ?? new CodexAdapter(config.codex);\n const service = new GatewayService({\n store: new OperationStore(db.database),\n projects: new ProjectRegistry(config.projects, db.database),\n codex,\n limits: config.limits,\n authMode: config.auth.mode,\n demo: config.demo,\n });\n service.setMaintenance(overrides.maintenance ?? false);\n try {\n await codex.start();\n } catch {\n /* Diagnostics remain available; never substitute a fixture. */\n }\n const wss = new WebSocketServer({ noServer: true, maxPayload: 8192 });\n const app = createApp({\n config,\n service,\n staticDir: overrides.staticDir ?? fileURLToPath(new URL('../web', import.meta.url)),\n updates,\n });\n const server = serve({\n fetch: app.fetch,\n hostname: config.host,\n port: config.port,\n websocket: { server: wss },\n });\n await new Promise<void>((resolveListening, reject) => {\n server.once('listening', resolveListening);\n server.once('error', reject);\n });\n const stopHeartbeat = startHeartbeat(wss);\n let closing: Promise<void> | undefined;\n const close = (): Promise<void> =>\n (closing ??= (async () => {\n stopHeartbeat();\n updates.close();\n const closed = new Promise<void>((resolveClosed) => server.close(() => resolveClosed()));\n for (const ws of wss.clients) {\n ws.close(1001, 'Gateway stopping');\n ws.terminate();\n }\n wss.close();\n try {\n await service.shutdown();\n } finally {\n if ('closeAllConnections' in server) server.closeAllConnections();\n await closed;\n try {\n db.close();\n } finally {\n await release();\n }\n }\n })());\n return { app, server, service, codex, close, updates };\n } catch (error) {\n updates.close();\n try {\n await codex?.stop();\n } finally {\n try {\n closeDatabase?.();\n } finally {\n await release();\n }\n }\n throw error;\n }\n}\nif (process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {\n try {\n const config = await loadConfig();\n const runtime = await startGateway(config);\n console.log(`Codex Web UI listening on ${config.host}:${config.port}`);\n console.log(`Allowed origins: ${config.publicOrigin.join(', ')}`);\n const stop = () => {\n void runtime.close().then(\n () => {\n process.exitCode = 0;\n },\n () => {\n process.exitCode = 1;\n },\n );\n };\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n } catch (error) {\n console.error(error instanceof Error ? error.message : 'Startup failed');\n process.exitCode = 1;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { fileURLToPath } from 'node:url';\nimport { join } from 'node:path';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { serve } from '@hono/node-server';\nimport { WebSocketServer } from 'ws';\nimport { CodexAdapter } from '../codex/adapter.js';\nimport type { CodexClient } from '../codex/types.js';\nimport { loadConfig, type AppConfig } from './config.js';\nimport { acquireInstanceLock } from './instance-lock.js';\nimport { openDatabase } from './db/index.js';\nimport { migrateDatabase } from './db/migrate.js';\nimport { OperationStore } from './db/operations.js';\nimport { ProjectRegistry } from './projects.js';\nimport { GatewayService } from './service.js';\nimport { createApp } from './http.js';\nimport { startHeartbeat } from './websocket.js';\nimport { UpdateManager } from '../updates/manager.js';\nimport type { UpdateController } from '../shared/updates.js';\nexport async function startGateway(\n config: AppConfig,\n overrides: {\n codex?: CodexClient;\n staticDir?: string;\n migrationsDir?: string;\n updates?: UpdateController;\n maintenance?: boolean;\n } = {},\n) {\n const release = await acquireInstanceLock(config.dataDir);\n let closeDatabase: (() => void) | undefined;\n let codex: CodexClient | undefined;\n const updates =\n overrides.updates ??\n new UpdateManager(undefined, undefined, () => codex?.diagnostics().codexVersion ?? null);\n try {\n const db = openDatabase(join(config.dataDir, 'app.sqlite'));\n closeDatabase = db.close;\n const packagedMigrations = fileURLToPath(new URL('../drizzle', import.meta.url));\n migrateDatabase(\n db.database,\n overrides.migrationsDir ?? (existsSync(packagedMigrations) ? packagedMigrations : undefined),\n );\n codex = overrides.codex ?? new CodexAdapter(config.codex);\n const service = new GatewayService({\n store: new OperationStore(db.database),\n projects: new ProjectRegistry(config.projects, db.database),\n codex,\n workspacesRoot: join(config.dataDir, 'workspaces'),\n limits: config.limits,\n authMode: config.auth.mode,\n demo: config.demo,\n });\n service.setMaintenance(overrides.maintenance ?? false);\n try {\n await codex.start();\n } catch {\n /* Diagnostics remain available; never substitute a fixture. */\n }\n const wss = new WebSocketServer({ noServer: true, maxPayload: 8192 });\n const app = createApp({\n config,\n service,\n staticDir: overrides.staticDir ?? fileURLToPath(new URL('../web', import.meta.url)),\n updates,\n });\n const server = serve({\n fetch: app.fetch,\n hostname: config.host,\n port: config.port,\n websocket: { server: wss },\n });\n await new Promise<void>((resolveListening, reject) => {\n server.once('listening', resolveListening);\n server.once('error', reject);\n });\n const stopHeartbeat = startHeartbeat(wss);\n let closing: Promise<void> | undefined;\n const close = (): Promise<void> =>\n (closing ??= (async () => {\n stopHeartbeat();\n updates.close();\n const closed = new Promise<void>((resolveClosed) => server.close(() => resolveClosed()));\n for (const ws of wss.clients) {\n ws.close(1001, 'Gateway stopping');\n ws.terminate();\n }\n wss.close();\n try {\n await service.shutdown();\n } finally {\n if ('closeAllConnections' in server) server.closeAllConnections();\n await closed;\n try {\n db.close();\n } finally {\n await release();\n }\n }\n })());\n return { app, server, service, codex, close, updates };\n } catch (error) {\n updates.close();\n try {\n await codex?.stop();\n } finally {\n try {\n closeDatabase?.();\n } finally {\n await release();\n }\n }\n throw error;\n }\n}\nif (process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {\n try {\n const config = await loadConfig();\n const runtime = await startGateway(config);\n console.log(`Codex Web UI listening on ${config.host}:${config.port}`);\n console.log(`Allowed origins: ${config.publicOrigin.join(', ')}`);\n const stop = () => {\n void runtime.close().then(\n () => {\n process.exitCode = 0;\n },\n () => {\n process.exitCode = 1;\n },\n );\n };\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n } catch (error) {\n console.error(error instanceof Error ? error.message : 'Startup failed');\n process.exitCode = 1;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }