@covro/covro 0.5.1-dev.3 → 0.5.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 (119) hide show
  1. package/README.md +14 -43
  2. package/README.zh-CN.md +14 -43
  3. package/dist/codex/adapter.js +62 -4
  4. package/dist/codex/adapter.js.map +2 -2
  5. package/dist/codex/collaboration.js +28 -0
  6. package/dist/codex/collaboration.js.map +7 -0
  7. package/dist/codex/guardian-denials.js +67 -0
  8. package/dist/codex/guardian-denials.js.map +7 -0
  9. package/dist/codex/thread-goals.js +15 -0
  10. package/dist/codex/thread-goals.js.map +7 -0
  11. package/dist/codex/thread-titles.js +135 -60
  12. package/dist/codex/thread-titles.js.map +2 -2
  13. package/dist/server/http.js +37 -0
  14. package/dist/server/http.js.map +2 -2
  15. package/dist/server/project-init.js +28 -0
  16. package/dist/server/project-init.js.map +7 -0
  17. package/dist/server/projection.js +1 -0
  18. package/dist/server/projection.js.map +2 -2
  19. package/dist/server/service.js +181 -3
  20. package/dist/server/service.js.map +2 -2
  21. package/dist/server/thread-recap.js +34 -0
  22. package/dist/server/thread-recap.js.map +7 -0
  23. package/dist/server/workspace-diff.js +149 -0
  24. package/dist/server/workspace-diff.js.map +7 -0
  25. package/dist/shared/guardian-denials.js +1 -0
  26. package/dist/shared/guardian-denials.js.map +7 -0
  27. package/dist/shared/thread-goal.js +1 -0
  28. package/dist/shared/thread-goal.js.map +7 -0
  29. package/dist/shared/validation.js +51 -3
  30. package/dist/shared/validation.js.map +2 -2
  31. package/dist/shared/workspace-diff.js +1 -0
  32. package/dist/shared/workspace-diff.js.map +7 -0
  33. package/dist/web/assets/{abnfDiagram-WEYOIA3C-ATf52olP.js → abnfDiagram-WEYOIA3C-BMy2AwDH.js} +1 -1
  34. package/dist/web/assets/{arc-ChLnTnZI.js → arc-DeUcXVmK.js} +1 -1
  35. package/dist/web/assets/{architecture-WOLXFQ4H-B2oEg329.js → architecture-WOLXFQ4H-B5DscTAH.js} +1 -1
  36. package/dist/web/assets/{architectureDiagram-ZHVYKT53-BzSXU9d0.js → architectureDiagram-ZHVYKT53-CwmVMMBS.js} +1 -1
  37. package/dist/web/assets/{blockDiagram-RJAE7QA3-xhCZ7iUm.js → blockDiagram-RJAE7QA3-CebOV20Y.js} +1 -1
  38. package/dist/web/assets/{c4Diagram-XDPPPE54-DZ8j79Mx.js → c4Diagram-XDPPPE54-ssP1dgbB.js} +1 -1
  39. package/dist/web/assets/channel-BONlMBPL.js +1 -0
  40. package/dist/web/assets/{chunk-2E7WHVMD-y5rSOViW.js → chunk-2E7WHVMD-BvN6p7-r.js} +1 -1
  41. package/dist/web/assets/{chunk-4EMNKR2T-B7WVoonr.js → chunk-4EMNKR2T-B5lsOa5d.js} +1 -1
  42. package/dist/web/assets/{chunk-55XCU76K-D-tlN44X.js → chunk-55XCU76K-C7v-VLmv.js} +1 -1
  43. package/dist/web/assets/{chunk-7S6XSTFO-31xOZx-Y.js → chunk-7S6XSTFO-DlQvFeJv.js} +1 -1
  44. package/dist/web/assets/{chunk-AQDTSKZB-CeCjUBmu.js → chunk-AQDTSKZB-DY66z9o6.js} +1 -1
  45. package/dist/web/assets/{chunk-DSNLSHJZ-DgzXTo3_.js → chunk-DSNLSHJZ-CNTCEJar.js} +1 -1
  46. package/dist/web/assets/{chunk-HAGFOTED-Dm22rez0.js → chunk-HAGFOTED-Ds8gP_pC.js} +1 -1
  47. package/dist/web/assets/{chunk-HNE4Q36P-CnFLQjbZ.js → chunk-HNE4Q36P-DmElQsSf.js} +1 -1
  48. package/dist/web/assets/{chunk-NQOKRVIF-7DXXp2d_.js → chunk-NQOKRVIF-PvGRAuAw.js} +1 -1
  49. package/dist/web/assets/{chunk-UHW7PFBP-Bw9-oVzV.js → chunk-UHW7PFBP-CtgMZDoT.js} +1 -1
  50. package/dist/web/assets/{chunk-VQ5W62QI-C9PHAHIJ.js → chunk-VQ5W62QI-6NJrEIzR.js} +1 -1
  51. package/dist/web/assets/{chunk-WQQL4CDK-C9nKxc0i.js → chunk-WQQL4CDK-DI2mRFvc.js} +1 -1
  52. package/dist/web/assets/{chunk-XXDRQBXY-DjdTeNXE.js → chunk-XXDRQBXY-CiBCRo3T.js} +1 -1
  53. package/dist/web/assets/{chunk-YZO67HFG-C1z77_dC.js → chunk-YZO67HFG-DtCoGutI.js} +1 -1
  54. package/dist/web/assets/{chunk-ZAUX2LTX-C7e41NBP.js → chunk-ZAUX2LTX-B7ylZUnx.js} +1 -1
  55. package/dist/web/assets/{chunk-ZCHMQSOR-Gv41Qgvd.js → chunk-ZCHMQSOR-BwN6F2pb.js} +1 -1
  56. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-PjZDyaSs.js → classDiagram-v2-4MYWR3UA-DI-dMW0L.js} +1 -1
  57. package/dist/web/assets/{cose-bilkent-JH36ORCC-CvwZK3HN.js → cose-bilkent-JH36ORCC-BqNb8Qsf.js} +1 -1
  58. package/dist/web/assets/{cynefin-EF2NZ3EQ-Yn6p93cE.js → cynefin-EF2NZ3EQ-B9F8Lxxt.js} +1 -1
  59. package/dist/web/assets/{cynefinDiagram-WF24UDRP-BXa5Guxe.js → cynefinDiagram-WF24UDRP-V8w1XJro.js} +1 -1
  60. package/dist/web/assets/{dagre-NK4GIZVX-Cnskqb30.js → dagre-NK4GIZVX-CrQEcCfE.js} +1 -1
  61. package/dist/web/assets/{diagram-CBK3MWTC-K8WEazkZ.js → diagram-CBK3MWTC-CPcuEQV3.js} +1 -1
  62. package/dist/web/assets/{diagram-I5XIIV2D-CLzouqUh.js → diagram-I5XIIV2D-_QhPHtw6.js} +1 -1
  63. package/dist/web/assets/{diagram-ODIL2UCW-B_9ysyHU.js → diagram-ODIL2UCW-RA65VX6F.js} +1 -1
  64. package/dist/web/assets/{diagram-PFBEJUXE-D1ge5Ebx.js → diagram-PFBEJUXE-9OI5etAn.js} +1 -1
  65. package/dist/web/assets/{diagram-RJA3I4VV-DWF6V26r.js → diagram-RJA3I4VV-B10DlhGR.js} +1 -1
  66. package/dist/web/assets/{diagram-TYUNFSNR-BNM1pCS4.js → diagram-TYUNFSNR-BLwN-9mB.js} +1 -1
  67. package/dist/web/assets/{dist-_uWZFvFF.js → dist-DwHukJTB.js} +1 -1
  68. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-Cge9YHFL.js → ebnfDiagram-V4P3TTPT-J7MBvK86.js} +1 -1
  69. package/dist/web/assets/{elk-QONTBCTQ-CY_393oL.js → elk-QONTBCTQ-DgtewEoX.js} +1 -1
  70. package/dist/web/assets/{erDiagram-KYQIGQAA-CCOr67SS.js → erDiagram-KYQIGQAA-Cn5kVne3.js} +1 -1
  71. package/dist/web/assets/{eventmodeling-K75KTNOO-BzNNWwRQ.js → eventmodeling-K75KTNOO-Cx1OdjIB.js} +1 -1
  72. package/dist/web/assets/flowDiagram-IUGLLWBU-HLbjrYlZ.js +1 -0
  73. package/dist/web/assets/{ganttDiagram-R7GPNTJY-8BewtZrJ.js → ganttDiagram-R7GPNTJY-x2B7XlcJ.js} +1 -1
  74. package/dist/web/assets/{gitGraph-VSP46ZUC-CrqJbic_.js → gitGraph-VSP46ZUC-CP1CGXSo.js} +1 -1
  75. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-Ddr5Q6Is.js → gitGraphDiagram-PDYL7XHY-B32E1dRa.js} +1 -1
  76. package/dist/web/assets/index-DXEj9ZMB.js +156 -0
  77. package/dist/web/assets/{index-C_i_PNi6.css → index-qYBdGqKM.css} +1 -1
  78. package/dist/web/assets/{info-OHQRW6UA-DgPvuC2J.js → info-OHQRW6UA-BqgII2wT.js} +1 -1
  79. package/dist/web/assets/{infoDiagram-MVDRKAX5-zlubFwKS.js → infoDiagram-MVDRKAX5-BV-WLQ_Y.js} +1 -1
  80. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-DdQfvqVi.js → ishikawaDiagram-HPEHV2GE-D2d2TDHI.js} +1 -1
  81. package/dist/web/assets/{journeyDiagram-BOSHW7O7-DZ4XswBd.js → journeyDiagram-BOSHW7O7-DdgHsdHz.js} +1 -1
  82. package/dist/web/assets/{kanban-definition-FNSA4HC5-B1BQdpKc.js → kanban-definition-FNSA4HC5-bzF0Iyr6.js} +1 -1
  83. package/dist/web/assets/{line-jQDqs207.js → line-DA04Ug-X.js} +1 -1
  84. package/dist/web/assets/{linear-DbYz4fU8.js → linear-DIrAIB_A.js} +1 -1
  85. package/dist/web/assets/{mermaid-parser.core-CY5CVNe8.js → mermaid-parser.core-DhCddf6t.js} +3 -3
  86. package/dist/web/assets/{mermaid.core-mETL7nBW.js → mermaid.core-sAbEeclG.js} +4 -4
  87. package/dist/web/assets/{mindmap-definition-6OY57UG3-CxgWFLxa.js → mindmap-definition-6OY57UG3-B7pbG4qr.js} +1 -1
  88. package/dist/web/assets/{packet-JDAUHWVQ-Czsr9kk7.js → packet-JDAUHWVQ-BpXWi4v7.js} +1 -1
  89. package/dist/web/assets/{pegDiagram-ECIUJNBX-BqYq-SA-.js → pegDiagram-ECIUJNBX-CnIz50ZX.js} +1 -1
  90. package/dist/web/assets/{pie-XZMESJXO-CRpxJzCy.js → pie-XZMESJXO-Cif1Ynbj.js} +1 -1
  91. package/dist/web/assets/{pieDiagram-GNMPY74T-Bt2wKk8z.js → pieDiagram-GNMPY74T-Ck5nOYI8.js} +1 -1
  92. package/dist/web/assets/{quadrantDiagram-D57K4MC3-VOKqYTgn.js → quadrantDiagram-D57K4MC3-DGWT1xA2.js} +1 -1
  93. package/dist/web/assets/{radar-ABXABTNO-wXmArQH-.js → radar-ABXABTNO-Cs5Evg0F.js} +1 -1
  94. package/dist/web/assets/{railroad-I3PHUGI6-CKPK4tQV.js → railroad-I3PHUGI6-bPE2bl6t.js} +1 -1
  95. package/dist/web/assets/{railroad-abnf-LNEFI6M7-BLEs3xqV.js → railroad-abnf-LNEFI6M7-Bf9uUUsQ.js} +1 -1
  96. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-DS5QZgky.js → railroad-ebnf-DWYD2UWJ-M2tmC6nN.js} +1 -1
  97. package/dist/web/assets/{railroad-peg-JR7BVNR7-DHWXNOSl.js → railroad-peg-JR7BVNR7-BLrv00Iy.js} +1 -1
  98. package/dist/web/assets/{railroadDiagram-Y72NRBL7-Cy4eWKH1.js → railroadDiagram-Y72NRBL7-BKzTLgo8.js} +1 -1
  99. package/dist/web/assets/{requirementDiagram-EQYSW5RA-Bvbk8wwe.js → requirementDiagram-EQYSW5RA-B99o2Aj1.js} +1 -1
  100. package/dist/web/assets/{sankeyDiagram-SY24JHO5-B4jGjMzu.js → sankeyDiagram-SY24JHO5-Bf5ZtsJ_.js} +1 -1
  101. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-BpgUogv_.js → sequenceDiagram-BLEHNHQU-BGuIX9o_.js} +1 -1
  102. package/dist/web/assets/{src-DigPeGm7.js → src-CohAWB0C.js} +1 -1
  103. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-tHq7e40Q.js → stateDiagram-v2-A6IESKWZ-26L-tE9O.js} +1 -1
  104. package/dist/web/assets/{swimlanes-B3ENRKFQ-DVUPAaDR.js → swimlanes-B3ENRKFQ-C15cbuwK.js} +1 -1
  105. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-CJVz2uN5.js +8 -0
  106. package/dist/web/assets/{timeline-definition-JXYKGLGB-BHMM9AHV.js → timeline-definition-JXYKGLGB-BeL4WpaZ.js} +1 -1
  107. package/dist/web/assets/{treeView-D4JQ5SDB-DZ7k_TTS.js → treeView-D4JQ5SDB-DizQY9xz.js} +1 -1
  108. package/dist/web/assets/{treemap-SAJKECNS-C1wGfVb4.js → treemap-SAJKECNS-D91-mGk5.js} +1 -1
  109. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-BTg0K_GO.js → usecaseDiagram-WPOLBNNX-Ba0T4eoq.js} +1 -1
  110. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-BTKShPx1.js → vennDiagram-Q3Y3IDCW-B0Q_6_0E.js} +1 -1
  111. package/dist/web/assets/{wardley-7MLQ67FV-DnYPM5OB.js → wardley-7MLQ67FV-BMqvKWF0.js} +1 -1
  112. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-Dzb67Boa.js → wardleyDiagram-IVAIDKWA-shZdkY_1.js} +1 -1
  113. package/dist/web/assets/{xychartDiagram-4URNHDU4-qijltKIO.js → xychartDiagram-4URNHDU4-DAt5ftPl.js} +1 -1
  114. package/dist/web/index.html +2 -2
  115. package/package.json +3 -3
  116. package/dist/web/assets/channel-COC5jFhc.js +0 -1
  117. package/dist/web/assets/flowDiagram-IUGLLWBU-C8dLq0uV.js +0 -1
  118. package/dist/web/assets/index-DHENTsqN.js +0 -148
  119. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-jJ6zDGAv.js +0 -8
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/codex/guardian-denials.ts"],
4
+ "sourcesContent": ["import type { GuardianDenial } from '../shared/guardian-denials.js';\nimport type { JsonValue } from './generated/serde_json/JsonValue.js';\nimport type { ItemGuardianApprovalReviewCompletedNotification } from './generated/v2/ItemGuardianApprovalReviewCompletedNotification.js';\nimport { mapAutoReview } from './auto-review.js';\nimport { AppError } from '../shared/errors.js';\n\n// v2 uses camelCase; the retry RPC expects the core protocol's snake_case event.\n// Convert keys only: command text, paths, argument values and IDs remain verbatim.\nfunction coreKeys(value: unknown): JsonValue {\n if (Array.isArray(value)) return value.map(coreKeys);\n if (value && typeof value === 'object')\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [\n key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`),\n coreKeys(item),\n ]),\n );\n return value as JsonValue;\n}\nexport class GuardianDenials {\n private readonly entries = new Map<\n string,\n Map<string, { view: GuardianDenial; event: JsonValue }>\n >();\n clear(): void {\n this.entries.clear();\n this.consumed.clear();\n }\n forget(threadId: string): void {\n this.entries.delete(threadId);\n }\n record(p: ItemGuardianApprovalReviewCompletedNotification): void {\n if (p.review.status !== 'denied') return;\n const entries = this.entries.get(p.threadId) ?? new Map();\n const action = coreKeys(p.action) as Record<string, JsonValue>;\n action.type = p.action.type.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n if ('source' in p.action)\n action.source = p.action.source === 'unifiedExec' ? 'unified_exec' : p.action.source;\n const event: JsonValue = {\n id: p.reviewId,\n target_item_id: p.targetItemId,\n turn_id: p.turnId,\n started_at_ms: p.startedAtMs,\n completed_at_ms: p.completedAtMs,\n status: 'denied',\n risk_level: p.review.riskLevel,\n user_authorization: p.review.userAuthorization,\n rationale: p.review.rationale,\n decision_source: p.decisionSource,\n action,\n };\n // Consumed identities cannot be reintroduced by a duplicate notification.\n if (!entries.has(p.reviewId))\n entries.set(p.reviewId, {\n view: { id: p.reviewId, turnId: p.turnId, review: mapAutoReview(p) },\n event,\n });\n while (entries.size > 10) entries.delete(entries.keys().next().value!);\n this.entries.set(p.threadId, entries);\n }\n private readonly consumed = new Set<string>();\n list(threadId: string): GuardianDenial[] {\n return [...(this.entries.get(threadId)?.values() ?? [])]\n .filter((entry) => !this.consumed.has(`${threadId}:${entry.view.id}`))\n .map((entry) => entry.view)\n .reverse();\n }\n take(threadId: string, id: string): JsonValue {\n const key = `${threadId}:${id}`;\n const entry = this.entries.get(threadId)?.get(id);\n if (!entry || this.consumed.has(key))\n throw new AppError('DENIAL_EXPIRED', '\u62D2\u7EDD\u8BB0\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u67E5\u770B\u5F53\u524D\u4F1A\u8BDD', 409);\n this.consumed.add(key);\n return entry.event;\n }\n}\n"],
5
+ "mappings": "AAGA,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AAIzB,SAAS,SAAS,OAA2B;AAC3C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,QAAQ;AACnD,MAAI,SAAS,OAAO,UAAU;AAC5B,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM;AAAA,QACzC,IAAI,QAAQ,UAAU,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC,EAAE;AAAA,QAC5D,SAAS,IAAI;AAAA,MACf,CAAC;AAAA,IACH;AACF,SAAO;AACT;AACO,MAAM,gBAAgB;AAAA,EACV,UAAU,oBAAI,IAG7B;AAAA,EACF,QAAc;AACZ,SAAK,QAAQ,MAAM;AACnB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EACA,OAAO,UAAwB;AAC7B,SAAK,QAAQ,OAAO,QAAQ;AAAA,EAC9B;AAAA,EACA,OAAO,GAA0D;AAC/D,QAAI,EAAE,OAAO,WAAW,SAAU;AAClC,UAAM,UAAU,KAAK,QAAQ,IAAI,EAAE,QAAQ,KAAK,oBAAI,IAAI;AACxD,UAAM,SAAS,SAAS,EAAE,MAAM;AAChC,WAAO,OAAO,EAAE,OAAO,KAAK,QAAQ,UAAU,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC,EAAE;AACpF,QAAI,YAAY,EAAE;AAChB,aAAO,SAAS,EAAE,OAAO,WAAW,gBAAgB,iBAAiB,EAAE,OAAO;AAChF,UAAM,QAAmB;AAAA,MACvB,IAAI,EAAE;AAAA,MACN,gBAAgB,EAAE;AAAA,MAClB,SAAS,EAAE;AAAA,MACX,eAAe,EAAE;AAAA,MACjB,iBAAiB,EAAE;AAAA,MACnB,QAAQ;AAAA,MACR,YAAY,EAAE,OAAO;AAAA,MACrB,oBAAoB,EAAE,OAAO;AAAA,MAC7B,WAAW,EAAE,OAAO;AAAA,MACpB,iBAAiB,EAAE;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,IAAI,EAAE,QAAQ;AACzB,cAAQ,IAAI,EAAE,UAAU;AAAA,QACtB,MAAM,EAAE,IAAI,EAAE,UAAU,QAAQ,EAAE,QAAQ,QAAQ,cAAc,CAAC,EAAE;AAAA,QACnE;AAAA,MACF,CAAC;AACH,WAAO,QAAQ,OAAO,GAAI,SAAQ,OAAO,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAM;AACrE,SAAK,QAAQ,IAAI,EAAE,UAAU,OAAO;AAAA,EACtC;AAAA,EACiB,WAAW,oBAAI,IAAY;AAAA,EAC5C,KAAK,UAAoC;AACvC,WAAO,CAAC,GAAI,KAAK,QAAQ,IAAI,QAAQ,GAAG,OAAO,KAAK,CAAC,CAAE,EACpD,OAAO,CAAC,UAAU,CAAC,KAAK,SAAS,IAAI,GAAG,QAAQ,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC,EACpE,IAAI,CAAC,UAAU,MAAM,IAAI,EACzB,QAAQ;AAAA,EACb;AAAA,EACA,KAAK,UAAkB,IAAuB;AAC5C,UAAM,MAAM,GAAG,QAAQ,IAAI,EAAE;AAC7B,UAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,GAAG,IAAI,EAAE;AAChD,QAAI,CAAC,SAAS,KAAK,SAAS,IAAI,GAAG;AACjC,YAAM,IAAI,SAAS,kBAAkB,0GAAqB,GAAG;AAC/D,SAAK,SAAS,IAAI,GAAG;AACrB,WAAO,MAAM;AAAA,EACf;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ import { CodexError, isRecord } from "./transport.js";
2
+ function readGoal(value, threadId) {
3
+ if (value === null) return null;
4
+ if (!isRecord(value) || value.threadId !== threadId || typeof value.objective !== "string" || !["active", "paused", "blocked", "usageLimited", "budgetLimited", "complete"].includes(
5
+ String(value.status)
6
+ ) || !["tokensUsed", "timeUsedSeconds", "createdAt", "updatedAt"].every(
7
+ (key) => typeof value[key] === "number" && Number.isFinite(value[key]) && value[key] >= 0
8
+ ) || value.tokenBudget !== null && (typeof value.tokenBudget !== "number" || !Number.isSafeInteger(value.tokenBudget) || value.tokenBudget <= 0))
9
+ throw new CodexError("PROTOCOL_INCOMPATIBLE", "Codex returned an invalid goal snapshot");
10
+ return value;
11
+ }
12
+ export {
13
+ readGoal
14
+ };
15
+ //# sourceMappingURL=thread-goals.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/codex/thread-goals.ts"],
4
+ "sourcesContent": ["import type { ThreadGoal } from '../shared/thread-goal.js';\nimport { CodexError, isRecord } from './transport.js';\nexport function readGoal(value: unknown, threadId: string): ThreadGoal | null {\n if (value === null) return null;\n if (\n !isRecord(value) ||\n value.threadId !== threadId ||\n typeof value.objective !== 'string' ||\n !['active', 'paused', 'blocked', 'usageLimited', 'budgetLimited', 'complete'].includes(\n String(value.status),\n ) ||\n !['tokensUsed', 'timeUsedSeconds', 'createdAt', 'updatedAt'].every(\n (key) => typeof value[key] === 'number' && Number.isFinite(value[key]) && value[key] >= 0,\n ) ||\n (value.tokenBudget !== null &&\n (typeof value.tokenBudget !== 'number' ||\n !Number.isSafeInteger(value.tokenBudget) ||\n value.tokenBudget <= 0))\n )\n throw new CodexError('PROTOCOL_INCOMPATIBLE', 'Codex returned an invalid goal snapshot');\n return value as unknown as ThreadGoal;\n}\n"],
5
+ "mappings": "AACA,SAAS,YAAY,gBAAgB;AAC9B,SAAS,SAAS,OAAgB,UAAqC;AAC5E,MAAI,UAAU,KAAM,QAAO;AAC3B,MACE,CAAC,SAAS,KAAK,KACf,MAAM,aAAa,YACnB,OAAO,MAAM,cAAc,YAC3B,CAAC,CAAC,UAAU,UAAU,WAAW,gBAAgB,iBAAiB,UAAU,EAAE;AAAA,IAC5E,OAAO,MAAM,MAAM;AAAA,EACrB,KACA,CAAC,CAAC,cAAc,mBAAmB,aAAa,WAAW,EAAE;AAAA,IAC3D,CAAC,QAAQ,OAAO,MAAM,GAAG,MAAM,YAAY,OAAO,SAAS,MAAM,GAAG,CAAC,KAAK,MAAM,GAAG,KAAK;AAAA,EAC1F,KACC,MAAM,gBAAgB,SACpB,OAAO,MAAM,gBAAgB,YAC5B,CAAC,OAAO,cAAc,MAAM,WAAW,KACvC,MAAM,eAAe;AAEzB,UAAM,IAAI,WAAW,yBAAyB,yCAAyC;AACzF,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -121,6 +121,136 @@ class ThreadTitles {
121
121
  call(method, params) {
122
122
  return this.rpc.request(method, params);
123
123
  }
124
+ async startTemporary(source, model, threadSource, permissions) {
125
+ const { config } = await this.call("config/read", {
126
+ cwd: source.cwd,
127
+ includeLayers: false
128
+ });
129
+ const overrides = {
130
+ web_search: "disabled",
131
+ "cloud.skills.enabled": false,
132
+ "skills.include_instructions": false,
133
+ "tools.experimental_request_user_input.enabled": false,
134
+ "tools.update_plan.enabled": false,
135
+ mcp_servers: Object.fromEntries(
136
+ Object.keys(isRecord(config.mcp_servers) ? config.mcp_servers : {}).map((name) => [
137
+ name,
138
+ { enabled: false }
139
+ ])
140
+ )
141
+ };
142
+ for (const feature of [
143
+ "shell_tool",
144
+ "shell_snapshot",
145
+ "apps",
146
+ "plugins",
147
+ "hooks",
148
+ "multi_agent",
149
+ "goals",
150
+ "memories",
151
+ "browser_use",
152
+ "browser_use_external",
153
+ "computer_use",
154
+ "image_generation",
155
+ "code_mode",
156
+ "code_mode_only",
157
+ "context_management",
158
+ "current_time_reminder",
159
+ "deferred_executor",
160
+ "enable_fanout",
161
+ "multi_agent_v2",
162
+ "request_permissions_tool",
163
+ "standalone_web_search",
164
+ "token_budget",
165
+ "tool_suggest",
166
+ "unified_exec",
167
+ "view_image"
168
+ ])
169
+ overrides[`features.${feature}`] = false;
170
+ if (!permissions) overrides.default_permissions = ":read-only";
171
+ const params = {
172
+ cwd: source.cwd,
173
+ model,
174
+ modelProvider: source.modelProvider,
175
+ ephemeral: true,
176
+ threadSource,
177
+ ...permissions ? { permissions } : { sandbox: "read-only" },
178
+ runtimeWorkspaceRoots: [],
179
+ environments: [],
180
+ dynamicTools: [],
181
+ selectedCapabilityRoots: [],
182
+ config: overrides
183
+ };
184
+ return this.call("thread/start", params);
185
+ }
186
+ /** Explicit user-requested recap. Separate inference; no writes to the source thread. */
187
+ async recap(id, prompt) {
188
+ const key = `recap:${id}`;
189
+ if (this.closed || this.jobs.has(key))
190
+ throw new CodexError("RECAP_BUSY", "Recap is already running");
191
+ let finish;
192
+ const completed = new Promise((resolve) => {
193
+ finish = resolve;
194
+ });
195
+ const job = { cancelled: false, terminal: false, finish };
196
+ this.jobs.set(key, job);
197
+ this.armTimeout(job);
198
+ try {
199
+ const source = await this.call("thread/read", { threadId: id, includeTurns: false });
200
+ if (job.cancelled || source.thread.id !== id)
201
+ throw new CodexError("RECAP_FAILED", "Recap was interrupted");
202
+ const generated = await this.startTemporary(
203
+ source.thread,
204
+ source.thread.model ?? "",
205
+ "recap"
206
+ );
207
+ job.threadId = generated.thread.id;
208
+ this.internal.set(job.threadId, job);
209
+ if (job.cancelled || generated.sandbox.type !== "readOnly")
210
+ throw new CodexError("RECAP_FAILED", "Recap isolation could not be confirmed");
211
+ const { turn } = await this.call("turn/start", {
212
+ threadId: job.threadId,
213
+ input: [{ type: "text", text: prompt, text_elements: [] }],
214
+ outputSchema: {
215
+ type: "object",
216
+ properties: { summary: { type: "string" } },
217
+ required: ["summary"],
218
+ additionalProperties: false
219
+ }
220
+ });
221
+ job.turnId = turn.id;
222
+ if (turn.status !== "inProgress") {
223
+ job.terminal = true;
224
+ job.finish(turn);
225
+ }
226
+ const result = await completed;
227
+ if (job.cancelled || result?.status !== "completed")
228
+ throw new CodexError("RECAP_FAILED", "Recap did not complete");
229
+ const output = result.items.filter((item) => item.type === "agentMessage").at(-1)?.text ?? job.output;
230
+ let value;
231
+ try {
232
+ value = JSON.parse(output ?? "");
233
+ } catch {
234
+ throw new CodexError("RECAP_FAILED", "Recap returned an invalid response");
235
+ }
236
+ if (!isRecord(value) || typeof value.summary !== "string" || !value.summary.trim() || Buffer.byteLength(value.summary) > TITLE_RESPONSE_MAX_BYTES)
237
+ throw new CodexError("RECAP_FAILED", "Recap returned an invalid response");
238
+ return value.summary.trim();
239
+ } finally {
240
+ clearTimeout(job.timer);
241
+ this.jobs.delete(key);
242
+ if (job.threadId && !this.closed) {
243
+ if (job.turnId && !job.terminal)
244
+ await this.call("turn/interrupt", { threadId: job.threadId, turnId: job.turnId }).catch(
245
+ () => {
246
+ }
247
+ );
248
+ await this.call("thread/unsubscribe", { threadId: job.threadId }).catch(() => {
249
+ });
250
+ this.internal.set(job.threadId, void 0);
251
+ }
252
+ }
253
+ }
124
254
  async generate(id, text, source, job, completed) {
125
255
  try {
126
256
  const before = await this.call("thread/read", { threadId: id, includeTurns: false });
@@ -137,67 +267,12 @@ class ThreadTitles {
137
267
  );
138
268
  const profile = source.activePermissionProfile?.id;
139
269
  const permissions = profile && !profile.startsWith(":") ? profile : void 0;
140
- const { config } = await this.call("config/read", {
141
- cwd: before.thread.cwd,
142
- includeLayers: false
143
- });
144
- if (job.cancelled) return;
145
- const overrides = {
146
- web_search: "disabled",
147
- "cloud.skills.enabled": false,
148
- "skills.include_instructions": false,
149
- "tools.experimental_request_user_input.enabled": false,
150
- "tools.update_plan.enabled": false,
151
- mcp_servers: Object.fromEntries(
152
- Object.keys(isRecord(config.mcp_servers) ? config.mcp_servers : {}).map((name) => [
153
- name,
154
- { enabled: false }
155
- ])
156
- )
157
- };
158
- for (const feature of [
159
- "shell_tool",
160
- "shell_snapshot",
161
- "apps",
162
- "plugins",
163
- "hooks",
164
- "multi_agent",
165
- "goals",
166
- "memories",
167
- "browser_use",
168
- "browser_use_external",
169
- "computer_use",
170
- "image_generation",
171
- "code_mode",
172
- "code_mode_only",
173
- "context_management",
174
- "current_time_reminder",
175
- "deferred_executor",
176
- "enable_fanout",
177
- "multi_agent_v2",
178
- "request_permissions_tool",
179
- "standalone_web_search",
180
- "token_budget",
181
- "tool_suggest",
182
- "unified_exec",
183
- "view_image"
184
- ])
185
- overrides[`features.${feature}`] = false;
186
- if (!permissions) overrides.default_permissions = ":read-only";
187
- const params = {
188
- cwd: before.thread.cwd,
270
+ const generated = await this.startTemporary(
271
+ before.thread,
189
272
  model,
190
- modelProvider: before.thread.modelProvider,
191
- ephemeral: true,
192
- threadSource: "thread_title",
193
- ...permissions ? { permissions } : { sandbox: "read-only" },
194
- runtimeWorkspaceRoots: [],
195
- environments: [],
196
- dynamicTools: [],
197
- selectedCapabilityRoots: [],
198
- config: overrides
199
- };
200
- const generated = await this.call("thread/start", params);
273
+ "thread_title",
274
+ permissions
275
+ );
201
276
  job.threadId = generated.thread.id;
202
277
  this.internal.set(job.threadId, job);
203
278
  if (job.cancelled) return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/codex/thread-titles.ts"],
4
- "sourcesContent": ["import type { ClientRequest } from './generated/ClientRequest.js';\nimport type { ServerNotification } from './generated/ServerNotification.js';\nimport type { ConfigReadResponse } from './generated/v2/ConfigReadResponse.js';\nimport type { ThreadReadResponse } from './generated/v2/ThreadReadResponse.js';\nimport type { ThreadStartResponse } from './generated/v2/ThreadStartResponse.js';\nimport type { TurnStartResponse } from './generated/v2/TurnStartResponse.js';\nimport type { Turn } from './generated/v2/Turn.js';\nimport type { JsonValue } from './generated/serde_json/JsonValue.js';\nimport type { ThreadStartParams } from './generated/v2/ThreadStartParams.js';\nimport {\n parseTitle,\n selectTitleModel,\n titlePrompt,\n titleOutputSchema,\n TITLE_MODEL,\n TITLE_RESPONSE_MAX_BYTES,\n} from './thread-title-policy.js';\nimport { CodexError, isRecord, type RpcNotification, type RpcTransport } from './transport.js';\n\n// These experimental fields are omitted by the stable protocol generator.\n// Their shapes match the verified CLI 0.164.0 app-server protocol.\ntype TitleSource = ThreadStartResponse & {\n activePermissionProfile?: { id: string } | null;\n};\ntype TemporaryThreadParams = ThreadStartParams & {\n permissions?: string;\n runtimeWorkspaceRoots: [];\n environments: [];\n dynamicTools: [];\n selectedCapabilityRoots: [];\n};\ntype Job = {\n cancelled: boolean;\n threadId?: string;\n turnId?: string;\n terminal: boolean;\n output?: string;\n timer?: NodeJS.Timeout;\n finish: (turn: Turn | null) => void;\n};\ntype Responses = {\n 'config/read': ConfigReadResponse;\n 'thread/read': ThreadReadResponse;\n 'thread/start': TitleSource;\n 'turn/start': TurnStartResponse;\n 'thread/name/set': unknown;\n 'thread/unsubscribe': unknown;\n 'turn/interrupt': unknown;\n};\n\n/** Optional naming work, scoped to one transport lifetime and never exposed as a user task. */\nexport class ThreadTitles {\n private readonly candidates = new Map<string, TitleSource>();\n private readonly jobs = new Map<string, Job>();\n private readonly internal = new Map<string, Job | undefined>();\n private readonly manualNames = new Set<string>();\n private readonly nameWrites = new Map<string, Promise<unknown>>();\n private closed = false;\n private hasChatgptAccount = false;\n private models: string[] = [];\n\n constructor(\n private readonly rpc: RpcTransport,\n private readonly timeoutMs = 30_000,\n ) {\n rpc.once('failure', () => {\n this.closed = true;\n this.candidates.clear();\n for (const job of this.jobs.values()) this.cancel(job);\n this.internal.clear();\n });\n }\n\n configure(hasChatgptAccount: boolean, models: string[]): void {\n this.hasChatgptAccount = hasChatgptAccount;\n this.models = models;\n }\n\n register(result: TitleSource): void {\n if (\n !this.closed &&\n !this.manualNames.has(result.thread.id) &&\n !result.thread.name &&\n !result.thread.ephemeral\n )\n this.candidates.set(result.thread.id, { ...result, thread: { ...result.thread, turns: [] } });\n else this.candidates.delete(result.thread.id);\n }\n\n async prepareManualName(id: string): Promise<void> {\n this.manualNames.add(id);\n this.candidates.delete(id);\n const job = this.jobs.get(id);\n if (job) this.cancel(job);\n // A timeout does not cancel the upstream write. Retain that failure until a new\n // transport lifetime, rather than let a late generated title overwrite a manual name.\n await this.nameWrites.get(id);\n }\n\n private start(id: string, text: string): void {\n const candidate = this.candidates.get(id);\n // Retry only on a later user-message event, never while another attempt is pending.\n if (!candidate || this.closed || !text.trim() || this.jobs.has(id) || this.nameWrites.has(id))\n return;\n let finish!: Job['finish'];\n const completed = new Promise<Turn | null>((resolve) => {\n finish = resolve;\n });\n const job: Job = { cancelled: false, terminal: false, finish };\n this.jobs.set(id, job);\n this.armTimeout(job);\n void this.generate(id, text, candidate, job, completed)\n .catch(() => {\n /* Keep the upstream preview; naming must never fail the user's task. */\n })\n .finally(() => {\n clearTimeout(job.timer);\n this.jobs.delete(id);\n });\n }\n\n /** Called before ordinary event mapping, including notifications preceding RPC receipts. */\n notification(message: RpcNotification): boolean {\n const event = message as ServerNotification;\n if (event.method === 'thread/started' && event.params.thread.ephemeral) {\n // The notification can arrive before OR after thread/start's response.\n if (!this.internal.has(event.params.thread.id))\n this.internal.set(event.params.thread.id, undefined);\n return true;\n }\n const params = message.params;\n if (!isRecord(params) || typeof params.threadId !== 'string') return false;\n const id = params.threadId;\n if (this.internal.has(id)) {\n const job = this.internal.get(id);\n if (job && event.method === 'item/completed' && event.params.item.type === 'agentMessage') {\n if (Buffer.byteLength(event.params.item.text) > TITLE_RESPONSE_MAX_BYTES) this.cancel(job);\n else job.output = event.params.item.text;\n }\n if (job && (event.method === 'turn/started' || event.method === 'turn/completed')) {\n job.turnId = event.params.turn.id;\n if (event.method === 'turn/completed') {\n job.terminal = true;\n job.finish(event.params.turn);\n }\n }\n if (job && event.method === 'error' && !event.params.willRetry) this.cancel(job);\n if (event.method === 'thread/closed') this.internal.delete(id);\n return true;\n }\n if (event.method === 'thread/name/updated') {\n const source = this.candidates.get(id);\n if (source) source.thread.name = event.params.threadName ?? null;\n if (event.params.threadName) this.candidates.delete(id);\n const job = this.jobs.get(id);\n if (job) this.cancel(job);\n }\n if (event.method === 'thread/closed') this.candidates.delete(id);\n if (event.method === 'item/completed' && event.params.item.type === 'userMessage') {\n const text = event.params.item.content\n .flatMap((input) => {\n if (input.type !== 'text') return [];\n // CLI removes its IDE context wrapper before constructing the title prompt.\n return input.text.split('## My request for Codex:').at(-1)!.trim();\n })\n .join(' ');\n this.start(id, text);\n }\n return false;\n }\n\n isInternal(threadId: unknown): boolean {\n return typeof threadId === 'string' && this.internal.has(threadId);\n }\n\n private cancel(job: Job): void {\n job.cancelled = true;\n job.finish(null);\n }\n\n private armTimeout(job: Job): void {\n clearTimeout(job.timer);\n job.timer = setTimeout(() => this.cancel(job), this.timeoutMs);\n job.timer.unref();\n }\n\n private call<M extends keyof Responses>(\n method: M,\n params: Extract<ClientRequest, { method: M }>['params'],\n ): Promise<Responses[M]> {\n return this.rpc.request<Responses[M]>(method, params);\n }\n\n private async generate(\n id: string,\n text: string,\n source: TitleSource,\n job: Job,\n completed: Promise<Turn | null>,\n ): Promise<void> {\n try {\n const before = await this.call('thread/read', { threadId: id, includeTurns: false });\n if (job.cancelled || before.thread.id !== id) return;\n if (before.thread.name) {\n this.candidates.delete(id);\n return;\n }\n const model = selectTitleModel(\n before.thread.model ?? source.model,\n before.thread.modelProvider,\n this.hasChatgptAccount,\n this.models,\n );\n const profile = source.activePermissionProfile?.id;\n const permissions = profile && !profile.startsWith(':') ? profile : undefined;\n // Config reads may redact values to empty strings. Override only enabled flags,\n // never round-trip the returned server definitions (timeouts/credentials/etc.).\n // The filesystem sandbox does not constrain MCP tools.\n const { config } = await this.call('config/read', {\n cwd: before.thread.cwd,\n includeLayers: false,\n });\n if (job.cancelled) return;\n const overrides: Record<string, JsonValue> = {\n web_search: 'disabled',\n 'cloud.skills.enabled': false,\n 'skills.include_instructions': false,\n 'tools.experimental_request_user_input.enabled': false,\n 'tools.update_plan.enabled': false,\n mcp_servers: Object.fromEntries(\n Object.keys(isRecord(config.mcp_servers) ? config.mcp_servers : {}).map((name) => [\n name,\n { enabled: false },\n ]),\n ) as JsonValue,\n };\n for (const feature of [\n 'shell_tool',\n 'shell_snapshot',\n 'apps',\n 'plugins',\n 'hooks',\n 'multi_agent',\n 'goals',\n 'memories',\n 'browser_use',\n 'browser_use_external',\n 'computer_use',\n 'image_generation',\n 'code_mode',\n 'code_mode_only',\n 'context_management',\n 'current_time_reminder',\n 'deferred_executor',\n 'enable_fanout',\n 'multi_agent_v2',\n 'request_permissions_tool',\n 'standalone_web_search',\n 'token_budget',\n 'tool_suggest',\n 'unified_exec',\n 'view_image',\n ])\n overrides[`features.${feature}`] = false;\n if (!permissions) overrides.default_permissions = ':read-only';\n const params: TemporaryThreadParams = {\n cwd: before.thread.cwd,\n model,\n modelProvider: before.thread.modelProvider,\n ephemeral: true,\n threadSource: 'thread_title',\n ...(permissions ? { permissions } : { sandbox: 'read-only' }),\n runtimeWorkspaceRoots: [],\n environments: [],\n dynamicTools: [],\n selectedCapabilityRoots: [],\n config: overrides,\n };\n const generated = await this.call('thread/start', params);\n job.threadId = generated.thread.id;\n this.internal.set(job.threadId, job);\n if (job.cancelled) return;\n if (\n permissions\n ? generated.activePermissionProfile?.id !== permissions\n : generated.sandbox.type !== 'readOnly'\n )\n return;\n this.armTimeout(job);\n const { turn } = await this.call('turn/start', {\n threadId: job.threadId,\n input: [\n {\n type: 'text',\n text: titlePrompt(text),\n text_elements: [],\n },\n ],\n ...(model === TITLE_MODEL ? { effort: 'low' } : {}),\n outputSchema: titleOutputSchema,\n });\n job.turnId = turn.id;\n if (turn.status !== 'inProgress') {\n job.terminal = true;\n job.finish(turn);\n }\n const result = await completed;\n clearTimeout(job.timer);\n if (job.cancelled || result?.status !== 'completed') return;\n const output =\n result.items.filter((item) => item.type === 'agentMessage').at(-1)?.text ?? job.output;\n const title = output ? parseTitle(output) : undefined;\n if (!title) return;\n // An explicit name always wins, including one set while inference was running.\n const latest = await this.call('thread/read', { threadId: id, includeTurns: false });\n if (job.cancelled || latest.thread.id !== id || latest.thread.name) return;\n const write = this.call('thread/name/set', { threadId: id, name: title });\n this.nameWrites.set(id, write);\n void write.then(\n () => this.nameWrites.delete(id),\n (error: unknown) => {\n if (error instanceof CodexError && !error.uncertain) this.nameWrites.delete(id);\n },\n );\n await write;\n this.candidates.delete(id);\n } finally {\n if (job.threadId && !this.closed) {\n if (job.turnId && !job.terminal)\n await this.call('turn/interrupt', { threadId: job.threadId, turnId: job.turnId }).catch(\n () => {},\n );\n await this.call('thread/unsubscribe', { threadId: job.threadId }).catch(() => {});\n // Retain the ID until thread/closed so late notifications cannot leak into the UI.\n if (this.internal.has(job.threadId)) this.internal.set(job.threadId, undefined);\n }\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ClientRequest } from './generated/ClientRequest.js';\nimport type { ServerNotification } from './generated/ServerNotification.js';\nimport type { ConfigReadResponse } from './generated/v2/ConfigReadResponse.js';\nimport type { ThreadReadResponse } from './generated/v2/ThreadReadResponse.js';\nimport type { ThreadStartResponse } from './generated/v2/ThreadStartResponse.js';\nimport type { TurnStartResponse } from './generated/v2/TurnStartResponse.js';\nimport type { Turn } from './generated/v2/Turn.js';\nimport type { JsonValue } from './generated/serde_json/JsonValue.js';\nimport type { ThreadStartParams } from './generated/v2/ThreadStartParams.js';\nimport {\n parseTitle,\n selectTitleModel,\n titlePrompt,\n titleOutputSchema,\n TITLE_MODEL,\n TITLE_RESPONSE_MAX_BYTES,\n} from './thread-title-policy.js';\nimport { CodexError, isRecord, type RpcNotification, type RpcTransport } from './transport.js';\n\n// These experimental fields are omitted by the stable protocol generator.\n// Their shapes match the verified CLI 0.164.0 app-server protocol.\ntype TitleSource = ThreadStartResponse & {\n activePermissionProfile?: { id: string } | null;\n};\ntype TemporaryThreadParams = ThreadStartParams & {\n permissions?: string;\n runtimeWorkspaceRoots: [];\n environments: [];\n dynamicTools: [];\n selectedCapabilityRoots: [];\n};\ntype Job = {\n cancelled: boolean;\n threadId?: string;\n turnId?: string;\n terminal: boolean;\n output?: string;\n timer?: NodeJS.Timeout;\n finish: (turn: Turn | null) => void;\n};\ntype Responses = {\n 'config/read': ConfigReadResponse;\n 'thread/read': ThreadReadResponse;\n 'thread/start': TitleSource;\n 'turn/start': TurnStartResponse;\n 'thread/name/set': unknown;\n 'thread/unsubscribe': unknown;\n 'turn/interrupt': unknown;\n};\n\n/** Optional naming work, scoped to one transport lifetime and never exposed as a user task. */\nexport class ThreadTitles {\n private readonly candidates = new Map<string, TitleSource>();\n private readonly jobs = new Map<string, Job>();\n private readonly internal = new Map<string, Job | undefined>();\n private readonly manualNames = new Set<string>();\n private readonly nameWrites = new Map<string, Promise<unknown>>();\n private closed = false;\n private hasChatgptAccount = false;\n private models: string[] = [];\n\n constructor(\n private readonly rpc: RpcTransport,\n private readonly timeoutMs = 30_000,\n ) {\n rpc.once('failure', () => {\n this.closed = true;\n this.candidates.clear();\n for (const job of this.jobs.values()) this.cancel(job);\n this.internal.clear();\n });\n }\n\n configure(hasChatgptAccount: boolean, models: string[]): void {\n this.hasChatgptAccount = hasChatgptAccount;\n this.models = models;\n }\n\n register(result: TitleSource): void {\n if (\n !this.closed &&\n !this.manualNames.has(result.thread.id) &&\n !result.thread.name &&\n !result.thread.ephemeral\n )\n this.candidates.set(result.thread.id, { ...result, thread: { ...result.thread, turns: [] } });\n else this.candidates.delete(result.thread.id);\n }\n\n async prepareManualName(id: string): Promise<void> {\n this.manualNames.add(id);\n this.candidates.delete(id);\n const job = this.jobs.get(id);\n if (job) this.cancel(job);\n // A timeout does not cancel the upstream write. Retain that failure until a new\n // transport lifetime, rather than let a late generated title overwrite a manual name.\n await this.nameWrites.get(id);\n }\n\n private start(id: string, text: string): void {\n const candidate = this.candidates.get(id);\n // Retry only on a later user-message event, never while another attempt is pending.\n if (!candidate || this.closed || !text.trim() || this.jobs.has(id) || this.nameWrites.has(id))\n return;\n let finish!: Job['finish'];\n const completed = new Promise<Turn | null>((resolve) => {\n finish = resolve;\n });\n const job: Job = { cancelled: false, terminal: false, finish };\n this.jobs.set(id, job);\n this.armTimeout(job);\n void this.generate(id, text, candidate, job, completed)\n .catch(() => {\n /* Keep the upstream preview; naming must never fail the user's task. */\n })\n .finally(() => {\n clearTimeout(job.timer);\n this.jobs.delete(id);\n });\n }\n\n /** Called before ordinary event mapping, including notifications preceding RPC receipts. */\n notification(message: RpcNotification): boolean {\n const event = message as ServerNotification;\n if (event.method === 'thread/started' && event.params.thread.ephemeral) {\n // The notification can arrive before OR after thread/start's response.\n if (!this.internal.has(event.params.thread.id))\n this.internal.set(event.params.thread.id, undefined);\n return true;\n }\n const params = message.params;\n if (!isRecord(params) || typeof params.threadId !== 'string') return false;\n const id = params.threadId;\n if (this.internal.has(id)) {\n const job = this.internal.get(id);\n if (job && event.method === 'item/completed' && event.params.item.type === 'agentMessage') {\n if (Buffer.byteLength(event.params.item.text) > TITLE_RESPONSE_MAX_BYTES) this.cancel(job);\n else job.output = event.params.item.text;\n }\n if (job && (event.method === 'turn/started' || event.method === 'turn/completed')) {\n job.turnId = event.params.turn.id;\n if (event.method === 'turn/completed') {\n job.terminal = true;\n job.finish(event.params.turn);\n }\n }\n if (job && event.method === 'error' && !event.params.willRetry) this.cancel(job);\n if (event.method === 'thread/closed') this.internal.delete(id);\n return true;\n }\n if (event.method === 'thread/name/updated') {\n const source = this.candidates.get(id);\n if (source) source.thread.name = event.params.threadName ?? null;\n if (event.params.threadName) this.candidates.delete(id);\n const job = this.jobs.get(id);\n if (job) this.cancel(job);\n }\n if (event.method === 'thread/closed') this.candidates.delete(id);\n if (event.method === 'item/completed' && event.params.item.type === 'userMessage') {\n const text = event.params.item.content\n .flatMap((input) => {\n if (input.type !== 'text') return [];\n // CLI removes its IDE context wrapper before constructing the title prompt.\n return input.text.split('## My request for Codex:').at(-1)!.trim();\n })\n .join(' ');\n this.start(id, text);\n }\n return false;\n }\n\n isInternal(threadId: unknown): boolean {\n return typeof threadId === 'string' && this.internal.has(threadId);\n }\n\n private cancel(job: Job): void {\n job.cancelled = true;\n job.finish(null);\n }\n\n private armTimeout(job: Job): void {\n clearTimeout(job.timer);\n job.timer = setTimeout(() => this.cancel(job), this.timeoutMs);\n job.timer.unref();\n }\n\n private call<M extends keyof Responses>(\n method: M,\n params: Extract<ClientRequest, { method: M }>['params'],\n ): Promise<Responses[M]> {\n return this.rpc.request<Responses[M]>(method, params);\n }\n\n private async startTemporary(\n source: { cwd: string; modelProvider: string },\n model: string,\n threadSource: string,\n permissions?: string,\n ) {\n // Config reads may redact values to empty strings. Override only enabled flags,\n // never round-trip the returned server definitions (timeouts/credentials/etc.).\n // The filesystem sandbox does not constrain MCP tools.\n const { config } = await this.call('config/read', {\n cwd: source.cwd,\n includeLayers: false,\n });\n const overrides: Record<string, JsonValue> = {\n web_search: 'disabled',\n 'cloud.skills.enabled': false,\n 'skills.include_instructions': false,\n 'tools.experimental_request_user_input.enabled': false,\n 'tools.update_plan.enabled': false,\n mcp_servers: Object.fromEntries(\n Object.keys(isRecord(config.mcp_servers) ? config.mcp_servers : {}).map((name) => [\n name,\n { enabled: false },\n ]),\n ) as JsonValue,\n };\n for (const feature of [\n 'shell_tool',\n 'shell_snapshot',\n 'apps',\n 'plugins',\n 'hooks',\n 'multi_agent',\n 'goals',\n 'memories',\n 'browser_use',\n 'browser_use_external',\n 'computer_use',\n 'image_generation',\n 'code_mode',\n 'code_mode_only',\n 'context_management',\n 'current_time_reminder',\n 'deferred_executor',\n 'enable_fanout',\n 'multi_agent_v2',\n 'request_permissions_tool',\n 'standalone_web_search',\n 'token_budget',\n 'tool_suggest',\n 'unified_exec',\n 'view_image',\n ])\n overrides[`features.${feature}`] = false;\n if (!permissions) overrides.default_permissions = ':read-only';\n const params: TemporaryThreadParams = {\n cwd: source.cwd,\n model,\n modelProvider: source.modelProvider,\n ephemeral: true,\n threadSource,\n ...(permissions ? { permissions } : { sandbox: 'read-only' }),\n runtimeWorkspaceRoots: [],\n environments: [],\n dynamicTools: [],\n selectedCapabilityRoots: [],\n config: overrides,\n };\n return this.call('thread/start', params);\n }\n\n /** Explicit user-requested recap. Separate inference; no writes to the source thread. */\n async recap(id: string, prompt: string): Promise<string> {\n const key = `recap:${id}`;\n if (this.closed || this.jobs.has(key))\n throw new CodexError('RECAP_BUSY', 'Recap is already running');\n let finish!: Job['finish'];\n const completed = new Promise<Turn | null>((resolve) => {\n finish = resolve;\n });\n const job: Job = { cancelled: false, terminal: false, finish };\n this.jobs.set(key, job);\n this.armTimeout(job);\n try {\n const source = await this.call('thread/read', { threadId: id, includeTurns: false });\n if (job.cancelled || source.thread.id !== id)\n throw new CodexError('RECAP_FAILED', 'Recap was interrupted');\n const generated = await this.startTemporary(\n source.thread,\n source.thread.model ?? '',\n 'recap',\n );\n job.threadId = generated.thread.id;\n this.internal.set(job.threadId, job);\n if (job.cancelled || generated.sandbox.type !== 'readOnly')\n throw new CodexError('RECAP_FAILED', 'Recap isolation could not be confirmed');\n const { turn } = await this.call('turn/start', {\n threadId: job.threadId,\n input: [{ type: 'text', text: prompt, text_elements: [] }],\n outputSchema: {\n type: 'object',\n properties: { summary: { type: 'string' } },\n required: ['summary'],\n additionalProperties: false,\n },\n });\n job.turnId = turn.id;\n if (turn.status !== 'inProgress') {\n job.terminal = true;\n job.finish(turn);\n }\n const result = await completed;\n if (job.cancelled || result?.status !== 'completed')\n throw new CodexError('RECAP_FAILED', 'Recap did not complete');\n const output =\n result.items.filter((item) => item.type === 'agentMessage').at(-1)?.text ?? job.output;\n let value: unknown;\n try {\n value = JSON.parse(output ?? '');\n } catch {\n throw new CodexError('RECAP_FAILED', 'Recap returned an invalid response');\n }\n if (\n !isRecord(value) ||\n typeof value.summary !== 'string' ||\n !value.summary.trim() ||\n Buffer.byteLength(value.summary) > TITLE_RESPONSE_MAX_BYTES\n )\n throw new CodexError('RECAP_FAILED', 'Recap returned an invalid response');\n return value.summary.trim();\n } finally {\n clearTimeout(job.timer);\n this.jobs.delete(key);\n if (job.threadId && !this.closed) {\n if (job.turnId && !job.terminal)\n await this.call('turn/interrupt', { threadId: job.threadId, turnId: job.turnId }).catch(\n () => {},\n );\n await this.call('thread/unsubscribe', { threadId: job.threadId }).catch(() => {});\n this.internal.set(job.threadId, undefined);\n }\n }\n }\n\n private async generate(\n id: string,\n text: string,\n source: TitleSource,\n job: Job,\n completed: Promise<Turn | null>,\n ): Promise<void> {\n try {\n const before = await this.call('thread/read', { threadId: id, includeTurns: false });\n if (job.cancelled || before.thread.id !== id) return;\n if (before.thread.name) {\n this.candidates.delete(id);\n return;\n }\n const model = selectTitleModel(\n before.thread.model ?? source.model,\n before.thread.modelProvider,\n this.hasChatgptAccount,\n this.models,\n );\n const profile = source.activePermissionProfile?.id;\n const permissions = profile && !profile.startsWith(':') ? profile : undefined;\n const generated = await this.startTemporary(\n before.thread,\n model,\n 'thread_title',\n permissions,\n );\n job.threadId = generated.thread.id;\n this.internal.set(job.threadId, job);\n if (job.cancelled) return;\n if (\n permissions\n ? generated.activePermissionProfile?.id !== permissions\n : generated.sandbox.type !== 'readOnly'\n )\n return;\n this.armTimeout(job);\n const { turn } = await this.call('turn/start', {\n threadId: job.threadId,\n input: [\n {\n type: 'text',\n text: titlePrompt(text),\n text_elements: [],\n },\n ],\n ...(model === TITLE_MODEL ? { effort: 'low' } : {}),\n outputSchema: titleOutputSchema,\n });\n job.turnId = turn.id;\n if (turn.status !== 'inProgress') {\n job.terminal = true;\n job.finish(turn);\n }\n const result = await completed;\n clearTimeout(job.timer);\n if (job.cancelled || result?.status !== 'completed') return;\n const output =\n result.items.filter((item) => item.type === 'agentMessage').at(-1)?.text ?? job.output;\n const title = output ? parseTitle(output) : undefined;\n if (!title) return;\n // An explicit name always wins, including one set while inference was running.\n const latest = await this.call('thread/read', { threadId: id, includeTurns: false });\n if (job.cancelled || latest.thread.id !== id || latest.thread.name) return;\n const write = this.call('thread/name/set', { threadId: id, name: title });\n this.nameWrites.set(id, write);\n void write.then(\n () => this.nameWrites.delete(id),\n (error: unknown) => {\n if (error instanceof CodexError && !error.uncertain) this.nameWrites.delete(id);\n },\n );\n await write;\n this.candidates.delete(id);\n } finally {\n if (job.threadId && !this.closed) {\n if (job.turnId && !job.terminal)\n await this.call('turn/interrupt', { threadId: job.threadId, turnId: job.turnId }).catch(\n () => {},\n );\n await this.call('thread/unsubscribe', { threadId: job.threadId }).catch(() => {});\n // Retain the ID until thread/closed so late notifications cannot leak into the UI.\n if (this.internal.has(job.threadId)) this.internal.set(job.threadId, undefined);\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -163,6 +163,14 @@ function createApp({
163
163
  return c.json(op, status(op));
164
164
  });
165
165
  app.get("/api/projects", async (c) => c.json({ data: await service.listProjects() }));
166
+ app.get(
167
+ "/api/projects/:projectId/diff",
168
+ async (c) => c.json(await service.getProjectDiff(id(c.req.param("projectId"))))
169
+ );
170
+ app.get(
171
+ "/api/threads/:threadId/diff",
172
+ async (c) => c.json(await service.getThreadDiff(id(c.req.param("threadId"))))
173
+ );
166
174
  app.get(
167
175
  "/api/projects/:projectId/github-repository",
168
176
  async (c) => c.json(await service.getProjectGithubRepository(id(c.req.param("projectId"))))
@@ -395,6 +403,35 @@ function createApp({
395
403
  );
396
404
  return c.json(op, status(op));
397
405
  });
406
+ app.get(
407
+ "/api/threads/:threadId/goal",
408
+ async (c) => c.json(await service.getGoal(id(c.req.param("threadId"))))
409
+ );
410
+ app.post("/api/threads/:threadId/goal", async (c) => {
411
+ const op = await service.mutateGoal(
412
+ id(c.req.param("threadId")),
413
+ await parse(c, schemas.goalMutationSchema)
414
+ );
415
+ return c.json(op, status(op));
416
+ });
417
+ app.post("/api/threads/:threadId/recap", async (c) => {
418
+ const op = await service.recapThread(
419
+ id(c.req.param("threadId")),
420
+ await parse(c, schemas.recapSchema)
421
+ );
422
+ return c.json(op, status(op));
423
+ });
424
+ app.get(
425
+ "/api/threads/:threadId/denials",
426
+ async (c) => c.json(await service.getGuardianDenials(id(c.req.param("threadId"))))
427
+ );
428
+ app.post("/api/threads/:threadId/approve", async (c) => {
429
+ const op = await service.approveGuardianDenial(
430
+ id(c.req.param("threadId")),
431
+ await parse(c, schemas.approveDenialSchema)
432
+ );
433
+ return c.json(op, status(op));
434
+ });
398
435
  app.post("/api/threads/:threadId/review", async (c) => {
399
436
  const op = await service.startReview(
400
437
  id(c.req.param("threadId")),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/http.ts"],
4
- "sourcesContent": ["import type { BackupController } from '../shared/backups.js';\nimport { backupIdSchema } from '../shared/backups.js';\nimport { backupRequestSchema } from '../backups/manager.js';\nimport { 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 { projectPathPreview, resolveProjectPath } from './project-paths.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 { createReleaseNotesLookup, releaseNotesQuery } from '../updates/release-notes.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 backups?: BackupController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n backups,\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 !c.req.path.startsWith('/api/backups')\n )\n throw service.maintenanceError();\n await next();\n });\n if (backups) {\n app.get('/api/backups', async (c) => c.json(await backups.status()));\n app.post('/api/backups', async (c) =>\n c.json(await backups.start(backupRequestSchema.parse(await c.req.json())), 202),\n );\n app.post('/api/backups/:id/cancel', async (c) =>\n c.json(await backups.cancel(backupIdSchema.parse(c.req.param('id')))),\n );\n app.post('/api/backups/:id/verify', async (c) =>\n c.json(await backups.verify(backupIdSchema.parse(c.req.param('id')))),\n );\n }\n if (updates) {\n const releaseNotes = createReleaseNotesLookup();\n app.get('/api/updates/release-notes', async (c) => {\n const { version, refresh } = releaseNotesQuery.parse(c.req.query());\n return c.json(await releaseNotes(version, refresh === '1'));\n });\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.get('/api/project-path', (c) => {\n const input = z\n .object({\n path: z.string().max(4096).default(''),\n directory: z\n .string()\n .max(255)\n .refine((value) => !/[\\\\/\\0]/.test(value) && value !== '.' && value !== '..')\n .optional(),\n })\n .parse({ path: c.req.query('path'), directory: c.req.query('directory') });\n return c.json(projectPathPreview(input.path.trim(), configuration.workDir, input.directory));\n });\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/github-repository', async (c) =>\n c.json(await service.getProjectGithubRepository(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/github-repository', async (c) =>\n c.json(await service.getThreadGithubRepository(id(c.req.param('threadId')))),\n );\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(\n service.cloneProject(await parse(c, schemas.cloneProjectSchema), (path) =>\n resolveProjectPath(path, configuration.workDir),\n ),\n 202,\n ),\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.post('/api/projects/reorder', async (c) =>\n c.json(service.reorderProjects(await parse(c, schemas.reorderProjectsSchema))),\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 const input = await parse(c, schemas.createProjectSchema);\n return c.json(\n service.addProject({ ...input, path: resolveProjectPath(input.path, configuration.workDir) }),\n );\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/attention', (c) =>\n c.json(service.getThreadAttention(id(c.req.param('threadId')))),\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 // Hash the validated bytes so same-size overwrites with preserved mtimes also invalidate.\n const etag = `\"${createHash('sha256').update(image.bytes).digest('hex')}\"`;\n c.header('Cache-Control', 'private, no-cache');\n c.header('ETag', etag);\n const ifNoneMatch = c.req.header('If-None-Match');\n if (\n ifNoneMatch === '*' ||\n ifNoneMatch?.split(',').some((tag) => tag.trim().replace(/^W\\//, '') === etag)\n )\n return c.body(null, 304);\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/text', 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.getThreadText(id(c.req.param('threadId')), c.req.query('path')));\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/retry', async (c) => {\n const op = await service.retryTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.retryTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/retry/cancel', async (c) => {\n const op = await service.cancelCapacityRetry(\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/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 type { BackupController } from '../shared/backups.js';\nimport { backupIdSchema } from '../shared/backups.js';\nimport { backupRequestSchema } from '../backups/manager.js';\nimport { 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 { projectPathPreview, resolveProjectPath } from './project-paths.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 { createReleaseNotesLookup, releaseNotesQuery } from '../updates/release-notes.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 backups?: BackupController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n backups,\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 !c.req.path.startsWith('/api/backups')\n )\n throw service.maintenanceError();\n await next();\n });\n if (backups) {\n app.get('/api/backups', async (c) => c.json(await backups.status()));\n app.post('/api/backups', async (c) =>\n c.json(await backups.start(backupRequestSchema.parse(await c.req.json())), 202),\n );\n app.post('/api/backups/:id/cancel', async (c) =>\n c.json(await backups.cancel(backupIdSchema.parse(c.req.param('id')))),\n );\n app.post('/api/backups/:id/verify', async (c) =>\n c.json(await backups.verify(backupIdSchema.parse(c.req.param('id')))),\n );\n }\n if (updates) {\n const releaseNotes = createReleaseNotesLookup();\n app.get('/api/updates/release-notes', async (c) => {\n const { version, refresh } = releaseNotesQuery.parse(c.req.query());\n return c.json(await releaseNotes(version, refresh === '1'));\n });\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.get('/api/project-path', (c) => {\n const input = z\n .object({\n path: z.string().max(4096).default(''),\n directory: z\n .string()\n .max(255)\n .refine((value) => !/[\\\\/\\0]/.test(value) && value !== '.' && value !== '..')\n .optional(),\n })\n .parse({ path: c.req.query('path'), directory: c.req.query('directory') });\n return c.json(projectPathPreview(input.path.trim(), configuration.workDir, input.directory));\n });\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/diff', async (c) =>\n c.json(await service.getProjectDiff(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/diff', async (c) =>\n c.json(await service.getThreadDiff(id(c.req.param('threadId')))),\n );\n app.get('/api/projects/:projectId/github-repository', async (c) =>\n c.json(await service.getProjectGithubRepository(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/github-repository', async (c) =>\n c.json(await service.getThreadGithubRepository(id(c.req.param('threadId')))),\n );\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(\n service.cloneProject(await parse(c, schemas.cloneProjectSchema), (path) =>\n resolveProjectPath(path, configuration.workDir),\n ),\n 202,\n ),\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.post('/api/projects/reorder', async (c) =>\n c.json(service.reorderProjects(await parse(c, schemas.reorderProjectsSchema))),\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 const input = await parse(c, schemas.createProjectSchema);\n return c.json(\n service.addProject({ ...input, path: resolveProjectPath(input.path, configuration.workDir) }),\n );\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/attention', (c) =>\n c.json(service.getThreadAttention(id(c.req.param('threadId')))),\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 // Hash the validated bytes so same-size overwrites with preserved mtimes also invalidate.\n const etag = `\"${createHash('sha256').update(image.bytes).digest('hex')}\"`;\n c.header('Cache-Control', 'private, no-cache');\n c.header('ETag', etag);\n const ifNoneMatch = c.req.header('If-None-Match');\n if (\n ifNoneMatch === '*' ||\n ifNoneMatch?.split(',').some((tag) => tag.trim().replace(/^W\\//, '') === etag)\n )\n return c.body(null, 304);\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/text', 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.getThreadText(id(c.req.param('threadId')), c.req.query('path')));\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/retry', async (c) => {\n const op = await service.retryTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.retryTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/retry/cancel', async (c) => {\n const op = await service.cancelCapacityRetry(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/goal', async (c) =>\n c.json(await service.getGoal(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/goal', async (c) => {\n const op = await service.mutateGoal(\n id(c.req.param('threadId')),\n await parse(c, schemas.goalMutationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/recap', async (c) => {\n const op = await service.recapThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.recapSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/denials', async (c) =>\n c.json(await service.getGuardianDenials(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/approve', async (c) => {\n const op = await service.approveGuardianDenial(\n id(c.req.param('threadId')),\n await parse(c, schemas.approveDenialSchema),\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": "AACA,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,wBAA2C;AAEpD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AACpC,YAAY,aAAa;AAGzB,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB,0BAA0B;AACvD,SAAS,2BAA8D;AAEvE,SAAS,sBAAsB;AAC/B,SAAS,SAAS;AAClB,SAAS,uBAA8C;AACvD,SAAS,gBAAgB,2BAA2B;AACpD,SAAS,0BAA0B,yBAAyB;AAC5D,SAAS,wBAAwB;AAS1B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,oBAAoB,MAAM;AAAA,EACzC;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,MAAM,IAAI,KAGb;AACH,MAAI,QAAQ,CAAC,OAAO,MAAM;AACxB,UAAM,UACJ,iBAAiB,WACb,QACA,iBAAiB,YAAY,iBAAiB,cAC5C,IAAI,SAAS,qBAAqB,wBAAwB,GAAG,IAC7D,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AACxE,WAAO,EAAE,KAAK,EAAE,OAAO,QAAQ,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,GAAG,QAAQ,MAAa;AAAA,EACtF,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC;AAClD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,MAAE,IAAI,YAAY,MAAM,aAAa,EAAE,IAAI,KAAK,EAAE,IAAI,SAAS,KAAK,CAAC;AACrE,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAU,CAAC,GAAG,SACpB,UAAU;AAAA,MACR,SAAS,yCAAyC,KAAK,EAAE,IAAI,IAAI,IAC7D,sBACA,MAAM;AAAA,MACV,SAAS,MAAM;AACb,cAAM,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AAAA,MACxE;AAAA,IACF,CAAC,EAAE,GAAG,IAAI;AAAA,EACZ;AACA,MAAI,IAAI,UAAU,OAAO,GAAG,SAAS;AACnC,MAAE,OAAO,iBAAiB,UAAU;AACpC,QACE,QAAQ,gBAAgB,KACxB,CAAC,CAAC,OAAO,QAAQ,SAAS,EAAE,SAAS,EAAE,IAAI,MAAM,KACjD,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc,KACrC,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc;AAErC,YAAM,QAAQ,iBAAiB;AACjC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,SAAS;AACX,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI;AAAA,MAAK;AAAA,MAAgB,OAAO,MAC9B,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AACA,MAAI,SAAS;AACX,UAAM,eAAe,yBAAyB;AAC9C,QAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,YAAM,EAAE,SAAS,QAAQ,IAAI,kBAAkB,MAAM,EAAE,IAAI,MAAM,CAAC;AAClE,aAAO,EAAE,KAAK,MAAM,aAAa,SAAS,YAAY,GAAG,CAAC;AAAA,IAC5D,CAAC;AACD,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI,KAAK,sBAAsB,OAAO,MAAM;AAC1C,YAAM,QAAQ,EACX,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,CAAC,EACtD,OAAO,EACP,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC;AAC3B,aAAO,EAAE,KAAK,MAAM,QAAQ,MAAM,MAAM,OAAO,CAAC;AAAA,IAClD,CAAC;AACD,QAAI;AAAA,MAAK;AAAA,MAAyB,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,eAAe,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1E;AACA,QAAI;AAAA,MAAK;AAAA,MAAoB,OAAO,MAClC,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AAAA,EACF;AACA,QAAM,KAAK,CAAC,UAAkB,QAAQ,SAAS,MAAM,KAAK;AAC1D,QAAM,QAAQ,OACZ,GACA,WACe;AACf,UAAM,QAAiB,MAAM,EAAE,IAAI,KAAK;AACxC,QACE,SACA,OAAO,UAAU,YACjB,uBAAuB,SACvB,OAAO,MAAM,sBAAsB;AAEnC,QAAE,IAAI,eAAe,MAAM,iBAAiB;AAC9C,WAAO,OAAO,MAAM,KAAK;AAAA,EAC3B;AACA,QAAM,SAAS,CAAC,OACd,GAAG,WAAW,iBAAiB,GAAG,WAAW,aAAc,MAAiB;AAC9E,QAAM,gBAAgB,IAAI,YAAY,MAAM;AAC5C,MAAI,IAAI,qBAAqB,CAAC,MAAM;AAClC,UAAM,QAAQ,EACX,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE;AAAA,MACrC,WAAW,EACR,OAAO,EACP,IAAI,GAAG,EACP,OAAO,CAAC,UAAU,CAAC,UAAU,KAAK,KAAK,KAAK,UAAU,OAAO,UAAU,IAAI,EAC3E,SAAS;AAAA,IACd,CAAC,EACA,MAAM,EAAE,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,WAAW,EAAE,IAAI,MAAM,WAAW,EAAE,CAAC;AAC3E,WAAO,EAAE,KAAK,mBAAmB,MAAM,KAAK,KAAK,GAAG,cAAc,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,gBAAgB,OAAO,GAAG,SAAS;AACzC,MAAE,OAAO,iBAAiB,UAAU;AACpC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,SAAS,CAAC,CAAC;AAC1E,MAAI,KAAK,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AACzF,MAAI;AAAA,IAAK;AAAA,IAAsB,OAAO,MACpC,EAAE,KAAK,MAAM,cAAc,cAAc,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,IAAI,sBAAsB,OAAO,MAAM;AACzC,MAAE,OAAO,uBAAuB,8CAA8C;AAC9E,WAAO,EAAE,KAAK,MAAM,cAAc,OAAO,CAAC;AAAA,EAC5C,CAAC;AACD,MAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,UAAM,WAAW,EAAE,IAAI,UAAU;AACjC,QAAI,OAAO,KAAK,SAAS,WAAW,CAAC,SAAS;AAC5C,YAAM,IAAI,SAAS,mBAAmB,gEAAc,GAAG;AACzD,UAAM,WAAW,MAAM,QAAQ,aAAa;AAG5C,UAAM,QAAQ,WAAW,QAAQ,EAC9B;AAAA,MACC,KAAK,UAAU;AAAA,QACb,QAAQ,OAAO;AAAA,QACf,QAAQ,UAAU,EAAE;AAAA,QACpB,OAAO,KAAK;AAAA,QACZ,SAAS,WAAW;AAAA,QACpB,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,UAAU,QAAQ,SAAS,CAAC;AAAA,MAC7E,CAAC;AAAA,IACH,EACC,OAAO,KAAK;AACf,WAAO,EAAE,KAAK,EAAE,MAAM,CAAC;AAAA,EACzB,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,QAAQ,UAAU,CAAC,CAAC;AACzD,MAAI;AAAA,IAAI;AAAA,IAAc,CAAC,MACrB,EAAE;AAAA,MACA,QAAQ,MAAM;AAAA,QACZ,EAAE,IAAI,MAAM,OAAO;AAAA,QACnB,EAAE,OACC,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,OAAO,gBAAgB,EAC3B,QAAQ,CAAC,EACT,MAAM,EAAE,IAAI,MAAM,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,gBAAgB;AAAA,IACjC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,qCAAqC,OAAO,MAAM;AACzD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,MAAM,MAAM,GAAG,QAAQ,0BAA0B;AAAA,IACnD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,IAAI,iBAAiB,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,QAAQ,aAAa,EAAE,CAAC,CAAC;AACpF,MAAI;AAAA,IAAI;AAAA,IAAiC,OAAO,MAC9C,EAAE,KAAK,MAAM,QAAQ,eAAe,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACnE;AACA,MAAI;AAAA,IAAI;AAAA,IAA+B,OAAO,MAC5C,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACjE;AACA,MAAI;AAAA,IAAI;AAAA,IAA8C,OAAO,MAC3D,EAAE,KAAK,MAAM,QAAQ,2BAA2B,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EAC/E;AACA,MAAI;AAAA,IAAI;AAAA,IAA4C,OAAO,MACzD,EAAE,KAAK,MAAM,QAAQ,0BAA0B,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC7E;AACA,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE,KAAK,MAAM,QAAQ,oBAAoB,IAAI,CAAC;AAAA,EAChD;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB;AAAA,MACA,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA2B,OAAO,MACxC,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,2BAA2B,OAAO,MAAM;AAC/C,UAAM,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM,MAAM,GAAG,QAAQ,kBAAkB,CAAC;AACtF,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAuB,OAAO,MACrC,EAAE;AAAA,MACA,QAAQ;AAAA,QAAa,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,QAAG,CAAC,SAChE,mBAAmB,MAAM,cAAc,OAAO;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,cAAc,IAAI,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,KAAK,uCAAuC,OAAO,MAAM;AAC3D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,OAAO,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACxE,CAAC;AACD,MAAI,KAAK,yCAAyC,OAAO,MAAM;AAC7D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,kBAAkB,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACnF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAyB,OAAO,MACvC,EAAE,KAAK,QAAQ,gBAAgB,MAAM,MAAM,GAAG,QAAQ,qBAAqB,CAAC,CAAC;AAAA,EAC/E;AACA,MAAI;AAAA,IAAI;AAAA,IAA6C,OAAO,MAC1D,EAAE,KAAK,MAAM,QAAQ,oBAAoB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACxE;AACA,MAAI,KAAK,2CAA2C,OAAO,MAAM;AAC/D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iBAAiB,OAAO,MAAM;AACrC,UAAM,QAAQ,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AACxD,WAAO,EAAE;AAAA,MACP,QAAQ,WAAW,EAAE,GAAG,OAAO,MAAM,mBAAmB,MAAM,MAAM,cAAc,OAAO,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAmC,OAAO,MACjD,EAAE;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACnE,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgB,OAAO,MAC7B,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,KAAK,EAAE;AAAA,QACjC,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,QAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA0B,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI;AAAA,IAAI;AAAA,IAAkC,OAAO,MAC/C,EAAE,KAAK,MAAM,QAAQ,iBAAiB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,EAC3F;AACA,MAAI;AAAA,IAAI;AAAA,IAAoC,CAAC,MAC3C,EAAE,KAAK,QAAQ,mBAAmB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAChE;AACA,MAAI;AAAA,IAAI;AAAA,IAAmC,OAAO,MAChD,EAAE,KAAK,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACrE;AACA,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,UAAM,WAAW,MAAM,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC;AACvE,MAAE,OAAO,gBAAgB,8BAA8B;AACvD,MAAE,OAAO,uBAAuB,yBAAyB,SAAS,QAAQ,GAAG;AAC7E,MAAE,OAAO,iBAAiB,UAAU;AACpC,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,yBAAyB,SAAS,UAAU,YAAY,eAAe;AAChF,WAAO,EAAE,KAAK,SAAS,QAAQ;AAAA,EACjC,CAAC;AACD,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,MAAE,OAAO,2BAA2B,6BAA6B;AACjE,UAAM,QAAQ,MAAM,QAAQ,eAAe,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAE3F,UAAM,OAAO,IAAI,WAAW,QAAQ,EAAE,OAAO,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;AACvE,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,QAAQ,IAAI;AACrB,UAAM,cAAc,EAAE,IAAI,OAAO,eAAe;AAChD,QACE,gBAAgB,OAChB,aAAa,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,QAAQ,EAAE,MAAM,IAAI;AAE7E,aAAO,EAAE,KAAK,MAAM,GAAG;AACzB,WAAO,EAAE,KAAK,MAAM,OAAO,KAAK;AAAA,MAC9B,gBAAgB,MAAM;AAAA,MACtB,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AACD,MAAI,IAAI,mCAAmC,OAAO,MAAM;AACtD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,+BAA+B,OAAO,MAAM;AACnD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,gBAAgB;AAAA,IACzC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,uCAAuC,OAAO,MAAM;AAC3D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA+B,OAAO,MAC5C,EAAE,KAAK,MAAM,QAAQ,QAAQ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC3D;AACA,MAAI,KAAK,+BAA+B,OAAO,MAAM;AACnD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,WAAW;AAAA,IACpC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAkC,OAAO,MAC/C,EAAE,KAAK,MAAM,QAAQ,mBAAmB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACtE;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,IAC5C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,iBAAiB;AAAA,IAC1C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,WAAW;AAAA,IACpC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,IAC5C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,0CAA0C,OAAO,MAAM;AAC9D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC;AAAA,MAC7B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IACF;AAAA,IACA;AAAA,MAAiB,CAAC,MAChB,eAAe,SAAS,QAAQ,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,MAAM,GAAG;AAAA,IACpF;AAAA,EACF;AACA,MAAI,IAAI,UAAU,MAAM;AACtB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,QAAQ,MAAM;AACpB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,SAAS,MAAM;AACrB,UAAM,IAAI,SAAS,aAAa,6BAA6B,GAAG;AAAA,EAClE,CAAC;AACD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,KAAK,WAAW,UAAU,EAAG,GAAE,OAAO,iBAAiB,UAAU;AAC5E,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,mBAAmB,aAAa;AACzC,MAAE;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC,CAAC;AAC7C,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,OAAO,QAAQ,GAAG,SAAS,WAAW,KAAK,WAAW,KAAK,EAAE,IAAI,IAAI;AAC9E,aAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG;AACpF,WAAO,YAAY,EAAE,MAAM,GAAG,SAAS,cAAc,CAAC,EAAE,GAAG,IAAI;AAAA,EACjE,CAAC;AACD,MAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG,CAAC;AAChG,SAAO;AACT;",
6
6
  "names": []
7
7
  }