@runweave/server-linux-x64 0.1.14 → 0.1.17

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 (98) hide show
  1. package/manifest.json +189 -177
  2. package/native.tar.gz +0 -0
  3. package/package.json +1 -1
  4. package/payload/app-server/build-info.json +4 -4
  5. package/payload/app-server/configuration-compatibility.json +1 -1
  6. package/payload/app-server/index.cjs +1011 -637
  7. package/payload/app-server/index.cjs.map +1 -1
  8. package/payload/backend/activity-sqlite-worker.cjs +3 -1
  9. package/payload/backend/build-info.json +4 -4
  10. package/payload/backend/dev-resources/control.cjs +6 -2
  11. package/payload/backend/index.cjs +3307 -2163
  12. package/payload/backend/scheduled-tasks-sqlite-worker.cjs +14 -1
  13. package/payload/frontend/dist/assets/{_baseUniq-BqvkeJO_.js → _baseUniq-Rpr7ObZY.js} +1 -1
  14. package/payload/frontend/dist/assets/{access-DdS0UJde.js → access-BvxRY1pA.js} +1 -1
  15. package/payload/frontend/dist/assets/{advanced-BbcDBPNv.js → advanced-CZfrALGq.js} +1 -1
  16. package/payload/frontend/dist/assets/{appearance-BvmkpQdR.js → appearance-D0AwwNw_.js} +1 -1
  17. package/payload/frontend/dist/assets/{arc-C0XOrQvn.js → arc-BxzXVQYF.js} +1 -1
  18. package/payload/frontend/dist/assets/{architectureDiagram-Q4EWVU46-BPP9wqzx.js → architectureDiagram-Q4EWVU46-DTYJSSVX.js} +1 -1
  19. package/payload/frontend/dist/assets/{blockDiagram-DXYQGD6D-C-tmnyfm.js → blockDiagram-DXYQGD6D-DaIImc6U.js} +1 -1
  20. package/payload/frontend/dist/assets/{c4Diagram-AHTNJAMY-C6uI9h_3.js → c4Diagram-AHTNJAMY-DRS-zy_e.js} +1 -1
  21. package/payload/frontend/dist/assets/channel-hL0i3Xgx.js +1 -0
  22. package/payload/frontend/dist/assets/{chunk-4BX2VUAB-CCI-uz3D.js → chunk-4BX2VUAB-BxZHfjDE.js} +1 -1
  23. package/payload/frontend/dist/assets/{chunk-4TB4RGXK-CqUM0_7D.js → chunk-4TB4RGXK-BbTiOq_d.js} +1 -1
  24. package/payload/frontend/dist/assets/{chunk-55IACEB6-DDxrCLKB.js → chunk-55IACEB6-DSGNAzPL.js} +1 -1
  25. package/payload/frontend/dist/assets/{chunk-EDXVE4YY-LwYMVaGh.js → chunk-EDXVE4YY-C3VoLWVy.js} +1 -1
  26. package/payload/frontend/dist/assets/{chunk-FMBD7UC4-CQR_-5z5.js → chunk-FMBD7UC4-jgIQKRAn.js} +1 -1
  27. package/payload/frontend/dist/assets/{chunk-OYMX7WX6-DQ0IiFt5.js → chunk-OYMX7WX6-CR1nxjr3.js} +1 -1
  28. package/payload/frontend/dist/assets/{chunk-QZHKN3VN-BPX4TBXp.js → chunk-QZHKN3VN-BsZQAe-R.js} +1 -1
  29. package/payload/frontend/dist/assets/{chunk-YZCP3GAM-DqZhVlNy.js → chunk-YZCP3GAM-C7hytF3a.js} +1 -1
  30. package/payload/frontend/dist/assets/classDiagram-6PBFFD2Q-Nr4qU3jt.js +1 -0
  31. package/payload/frontend/dist/assets/classDiagram-v2-HSJHXN6E-Nr4qU3jt.js +1 -0
  32. package/payload/frontend/dist/assets/clone-ePxKteP6.js +1 -0
  33. package/payload/frontend/dist/assets/{connection-ToakGqMm.js → connection-Brx3p6gD.js} +1 -1
  34. package/payload/frontend/dist/assets/{connections-DD38aD2_.js → connections-DV6_2T4t.js} +1 -1
  35. package/payload/frontend/dist/assets/{cose-bilkent-S5V4N54A-Bi6kn4wb.js → cose-bilkent-S5V4N54A-CrqquZt2.js} +1 -1
  36. package/payload/frontend/dist/assets/{dagre-KV5264BT-D7PPmb_h.js → dagre-KV5264BT-BOAEPW4D.js} +1 -1
  37. package/payload/frontend/dist/assets/{desktop-D80mAqEi.js → desktop-1i0ByIN_.js} +1 -1
  38. package/payload/frontend/dist/assets/{diagram-5BDNPKRD-2Fg0LDFB.js → diagram-5BDNPKRD-NVdwMJnF.js} +1 -1
  39. package/payload/frontend/dist/assets/{diagram-G4DWMVQ6-DDht1hGL.js → diagram-G4DWMVQ6-RKmkTTau.js} +1 -1
  40. package/payload/frontend/dist/assets/{diagram-MMDJMWI5-_slCo5qd.js → diagram-MMDJMWI5-B0Or1DIY.js} +1 -1
  41. package/payload/frontend/dist/assets/{diagram-TYMM5635-BibhtXBj.js → diagram-TYMM5635-CoJGPUQX.js} +1 -1
  42. package/payload/frontend/dist/assets/{erDiagram-SMLLAGMA-Tb9JdHm7.js → erDiagram-SMLLAGMA-DHK_lg3E.js} +1 -1
  43. package/payload/frontend/dist/assets/{flowDiagram-DWJPFMVM-DmV0VUHI.js → flowDiagram-DWJPFMVM-CzirUF-x.js} +1 -1
  44. package/payload/frontend/dist/assets/{ganttDiagram-T4ZO3ILL-boTSPZL8.js → ganttDiagram-T4ZO3ILL-DGY2KYoN.js} +1 -1
  45. package/payload/frontend/dist/assets/{gitGraphDiagram-UUTBAWPF-3Akku_ak.js → gitGraphDiagram-UUTBAWPF-BI5lNHKC.js} +1 -1
  46. package/payload/frontend/dist/assets/{graph-GAq0lcsb.js → graph-CxjgBe1N.js} +1 -1
  47. package/payload/frontend/dist/assets/{image-PejzD76r.js → image-LArOi_ON.js} +1 -1
  48. package/payload/frontend/dist/assets/{index-BBNE8InR.js → index-CLYrzd8Y.js} +5 -5
  49. package/payload/frontend/dist/assets/{infoDiagram-42DDH7IO-TrixGt-D.js → infoDiagram-42DDH7IO-DTRl6YSd.js} +1 -1
  50. package/payload/frontend/dist/assets/{ishikawaDiagram-UXIWVN3A-BYKU82ro.js → ishikawaDiagram-UXIWVN3A-DCnBRtVx.js} +1 -1
  51. package/payload/frontend/dist/assets/{journeyDiagram-VCZTEJTY-BL_50q1o.js → journeyDiagram-VCZTEJTY-ChVgjvDs.js} +1 -1
  52. package/payload/frontend/dist/assets/{kanban-definition-6JOO6SKY-Clxk3CDg.js → kanban-definition-6JOO6SKY-skToH2-J.js} +1 -1
  53. package/payload/frontend/dist/assets/{layout-BbxLzgiJ.js → layout-B4V_ctSo.js} +1 -1
  54. package/payload/frontend/dist/assets/{linear-DWemxXgm.js → linear-DYom329p.js} +1 -1
  55. package/payload/frontend/dist/assets/{main-BHwOPARZ.js → main-C_6tTN_b.js} +5 -5
  56. package/payload/frontend/dist/assets/{min-DIL93Hib.js → min-EMXbJh1s.js} +1 -1
  57. package/payload/frontend/dist/assets/{mindmap-definition-QFDTVHPH-DlfLczjR.js → mindmap-definition-QFDTVHPH-DLHGcrEw.js} +1 -1
  58. package/payload/frontend/dist/assets/{monitoring-B6pQ-P1J.js → monitoring-Bvfy9Q9G.js} +1 -1
  59. package/payload/frontend/dist/assets/{notifications-B9lXATqv.js → notifications-CdkYtTCy.js} +1 -1
  60. package/payload/frontend/dist/assets/{pieDiagram-DEJITSTG-BaU_H2x3.js → pieDiagram-DEJITSTG-LrDfLpSu.js} +1 -1
  61. package/payload/frontend/dist/assets/{quadrantDiagram-34T5L4WZ-D3nVMaXv.js → quadrantDiagram-34T5L4WZ-uV9sfVKm.js} +1 -1
  62. package/payload/frontend/dist/assets/{record-content-Dn6GE_dv.js → record-content-B3qVdcq-.js} +1 -1
  63. package/payload/frontend/dist/assets/{requirementDiagram-MS252O5E-C7J-xGnU.js → requirementDiagram-MS252O5E-Cf_SmlxS.js} +1 -1
  64. package/payload/frontend/dist/assets/{sankeyDiagram-XADWPNL6-BAkualMS.js → sankeyDiagram-XADWPNL6-DSLCPq2l.js} +1 -1
  65. package/payload/frontend/dist/assets/{sequenceDiagram-FGHM5R23-BYWAdS9C.js → sequenceDiagram-FGHM5R23-CAAjivQf.js} +1 -1
  66. package/payload/frontend/dist/assets/{stateDiagram-FHFEXIEX-C3qD8m-7.js → stateDiagram-FHFEXIEX-DNMUe2-F.js} +1 -1
  67. package/payload/frontend/dist/assets/stateDiagram-v2-QKLJ7IA2-Ca5k1Q3K.js +1 -0
  68. package/payload/frontend/dist/assets/{status-MDvjSQ51.js → status-BPA1tGcF.js} +1 -1
  69. package/payload/frontend/dist/assets/suiji-ZMTJOgTp.js +1 -0
  70. package/payload/frontend/dist/assets/{svg-C0XZL3qU.js → svg-BbHfpNxC.js} +1 -1
  71. package/payload/frontend/dist/assets/{tabs-Y-BEbPyW.js → tabs-DkuqaUwz.js} +1 -1
  72. package/payload/frontend/dist/assets/{timeline-definition-GMOUNBTQ-JER6Qyhn.js → timeline-definition-GMOUNBTQ-DNJNPFK4.js} +1 -1
  73. package/payload/frontend/dist/assets/{vennDiagram-DHZGUBPP-kRp3Wh4r.js → vennDiagram-DHZGUBPP-BycjIB3y.js} +1 -1
  74. package/payload/frontend/dist/assets/{wardley-RL74JXVD-Dnh_rEyA.js → wardley-RL74JXVD-Bq01rln7.js} +1 -1
  75. package/payload/frontend/dist/assets/{wardleyDiagram-NUSXRM2D-DxiIy5IP.js → wardleyDiagram-NUSXRM2D-D4_m8ewM.js} +1 -1
  76. package/payload/frontend/dist/assets/{xychartDiagram-5P7HB3ND-DcckHE39.js → xychartDiagram-5P7HB3ND-CovxGnwH.js} +1 -1
  77. package/payload/frontend/dist/build-info.json +4 -4
  78. package/payload/frontend/dist/companion.html +1 -1
  79. package/payload/frontend/dist/index.html +2 -2
  80. package/payload/packages/agent-bridge/src/install-pi.mjs +1 -0
  81. package/payload/plugins/pi/dist/bridge/runweave-hook-bridge.cjs +21 -4
  82. package/payload/plugins/pi/dist/bridge/runweave-hook-claude.cjs +68 -0
  83. package/payload/plugins/pi/dist/bridge/runweave-hook-completion.cjs +16 -4
  84. package/payload/plugins/pi/dist/bridge/runweave-hook-payload.cjs +1 -0
  85. package/payload/plugins/toolkit/.codex-plugin/plugin.json +1 -1
  86. package/payload/plugins/toolkit/hooks/runweave-hook-bridge.cjs +21 -4
  87. package/payload/plugins/toolkit/hooks/runweave-hook-claude.cjs +68 -0
  88. package/payload/plugins/toolkit/hooks/runweave-hook-completion.cjs +16 -4
  89. package/payload/plugins/toolkit/hooks/runweave-hook-payload.cjs +1 -0
  90. package/payload/plugins/toolkit-release.json +1 -1
  91. package/payload/pty-host/index.cjs +3 -1
  92. package/payload/server/index.cjs +5 -1
  93. package/payload/frontend/dist/assets/channel-DaIQFY7W.js +0 -1
  94. package/payload/frontend/dist/assets/classDiagram-6PBFFD2Q-TM6ckD19.js +0 -1
  95. package/payload/frontend/dist/assets/classDiagram-v2-HSJHXN6E-TM6ckD19.js +0 -1
  96. package/payload/frontend/dist/assets/clone-BoG338Z7.js +0 -1
  97. package/payload/frontend/dist/assets/stateDiagram-v2-QKLJ7IA2-C18IEkog.js +0 -1
  98. package/payload/frontend/dist/assets/suiji-B6w3AzG7.js +0 -1
@@ -1,4 +1,4 @@
1
- /* runweave:build-info */var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"20261109T213633989Z-9301bc5f","sourceRevision":"9301bc5fbeb157ec84245bf38efb0073647b86fe","sourceDirty":false,"builtAt":"2026-11-09T21:36:33.989Z","contentSha256":"ee24c2adfe7a38b0f7698d68d8493b560042b699baba92c63e79961518d9a9af"};
1
+ /* runweave:build-info */var __RUNWEAVE_BUILD_INFO__={"version":"0.1.0","buildId":"20261111T123023230Z-f1639624","sourceRevision":"f163962417a1f3dc6a3dd4047035441250b1d093","sourceDirty":false,"builtAt":"2026-11-11T12:30:23.230Z","contentSha256":"3e73b1239b0c133d54445efe06027741d084894b8260f2554670cd3fb4d89010"};
2
2
  const __IMPORT_META_URL__ = require('url').pathToFileURL(__filename).href;
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -109,17 +109,17 @@ var require_visit = __commonJS({
109
109
  visit.BREAK = BREAK;
110
110
  visit.SKIP = SKIP;
111
111
  visit.REMOVE = REMOVE;
112
- function visit_(key, node, visitor, path21) {
113
- const ctrl = callVisitor(key, node, visitor, path21);
112
+ function visit_(key, node, visitor, path24) {
113
+ const ctrl = callVisitor(key, node, visitor, path24);
114
114
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
115
- replaceNode(key, path21, ctrl);
116
- return visit_(key, ctrl, visitor, path21);
115
+ replaceNode(key, path24, ctrl);
116
+ return visit_(key, ctrl, visitor, path24);
117
117
  }
118
118
  if (typeof ctrl !== "symbol") {
119
119
  if (identity.isCollection(node)) {
120
- path21 = Object.freeze(path21.concat(node));
120
+ path24 = Object.freeze(path24.concat(node));
121
121
  for (let i = 0; i < node.items.length; ++i) {
122
- const ci = visit_(i, node.items[i], visitor, path21);
122
+ const ci = visit_(i, node.items[i], visitor, path24);
123
123
  if (typeof ci === "number")
124
124
  i = ci - 1;
125
125
  else if (ci === BREAK)
@@ -130,13 +130,13 @@ var require_visit = __commonJS({
130
130
  }
131
131
  }
132
132
  } else if (identity.isPair(node)) {
133
- path21 = Object.freeze(path21.concat(node));
134
- const ck = visit_("key", node.key, visitor, path21);
133
+ path24 = Object.freeze(path24.concat(node));
134
+ const ck = visit_("key", node.key, visitor, path24);
135
135
  if (ck === BREAK)
136
136
  return BREAK;
137
137
  else if (ck === REMOVE)
138
138
  node.key = null;
139
- const cv = visit_("value", node.value, visitor, path21);
139
+ const cv = visit_("value", node.value, visitor, path24);
140
140
  if (cv === BREAK)
141
141
  return BREAK;
142
142
  else if (cv === REMOVE)
@@ -157,17 +157,17 @@ var require_visit = __commonJS({
157
157
  visitAsync.BREAK = BREAK;
158
158
  visitAsync.SKIP = SKIP;
159
159
  visitAsync.REMOVE = REMOVE;
160
- async function visitAsync_(key, node, visitor, path21) {
161
- const ctrl = await callVisitor(key, node, visitor, path21);
160
+ async function visitAsync_(key, node, visitor, path24) {
161
+ const ctrl = await callVisitor(key, node, visitor, path24);
162
162
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
163
- replaceNode(key, path21, ctrl);
164
- return visitAsync_(key, ctrl, visitor, path21);
163
+ replaceNode(key, path24, ctrl);
164
+ return visitAsync_(key, ctrl, visitor, path24);
165
165
  }
166
166
  if (typeof ctrl !== "symbol") {
167
167
  if (identity.isCollection(node)) {
168
- path21 = Object.freeze(path21.concat(node));
168
+ path24 = Object.freeze(path24.concat(node));
169
169
  for (let i = 0; i < node.items.length; ++i) {
170
- const ci = await visitAsync_(i, node.items[i], visitor, path21);
170
+ const ci = await visitAsync_(i, node.items[i], visitor, path24);
171
171
  if (typeof ci === "number")
172
172
  i = ci - 1;
173
173
  else if (ci === BREAK)
@@ -178,13 +178,13 @@ var require_visit = __commonJS({
178
178
  }
179
179
  }
180
180
  } else if (identity.isPair(node)) {
181
- path21 = Object.freeze(path21.concat(node));
182
- const ck = await visitAsync_("key", node.key, visitor, path21);
181
+ path24 = Object.freeze(path24.concat(node));
182
+ const ck = await visitAsync_("key", node.key, visitor, path24);
183
183
  if (ck === BREAK)
184
184
  return BREAK;
185
185
  else if (ck === REMOVE)
186
186
  node.key = null;
187
- const cv = await visitAsync_("value", node.value, visitor, path21);
187
+ const cv = await visitAsync_("value", node.value, visitor, path24);
188
188
  if (cv === BREAK)
189
189
  return BREAK;
190
190
  else if (cv === REMOVE)
@@ -211,23 +211,23 @@ var require_visit = __commonJS({
211
211
  }
212
212
  return visitor;
213
213
  }
214
- function callVisitor(key, node, visitor, path21) {
214
+ function callVisitor(key, node, visitor, path24) {
215
215
  if (typeof visitor === "function")
216
- return visitor(key, node, path21);
216
+ return visitor(key, node, path24);
217
217
  if (identity.isMap(node))
218
- return visitor.Map?.(key, node, path21);
218
+ return visitor.Map?.(key, node, path24);
219
219
  if (identity.isSeq(node))
220
- return visitor.Seq?.(key, node, path21);
220
+ return visitor.Seq?.(key, node, path24);
221
221
  if (identity.isPair(node))
222
- return visitor.Pair?.(key, node, path21);
222
+ return visitor.Pair?.(key, node, path24);
223
223
  if (identity.isScalar(node))
224
- return visitor.Scalar?.(key, node, path21);
224
+ return visitor.Scalar?.(key, node, path24);
225
225
  if (identity.isAlias(node))
226
- return visitor.Alias?.(key, node, path21);
226
+ return visitor.Alias?.(key, node, path24);
227
227
  return void 0;
228
228
  }
229
- function replaceNode(key, path21, node) {
230
- const parent = path21[path21.length - 1];
229
+ function replaceNode(key, path24, node) {
230
+ const parent = path24[path24.length - 1];
231
231
  if (identity.isCollection(parent)) {
232
232
  parent.items[key] = node;
233
233
  } else if (identity.isPair(parent)) {
@@ -835,10 +835,10 @@ var require_Collection = __commonJS({
835
835
  var createNode = require_createNode();
836
836
  var identity = require_identity();
837
837
  var Node = require_Node();
838
- function collectionFromPath(schema, path21, value) {
838
+ function collectionFromPath(schema, path24, value) {
839
839
  let v = value;
840
- for (let i = path21.length - 1; i >= 0; --i) {
841
- const k = path21[i];
840
+ for (let i = path24.length - 1; i >= 0; --i) {
841
+ const k = path24[i];
842
842
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
843
843
  const a = [];
844
844
  a[k] = v;
@@ -857,7 +857,7 @@ var require_Collection = __commonJS({
857
857
  sourceObjects: /* @__PURE__ */ new Map()
858
858
  });
859
859
  }
860
- var isEmptyPath = (path21) => path21 == null || typeof path21 === "object" && !!path21[Symbol.iterator]().next().done;
860
+ var isEmptyPath = (path24) => path24 == null || typeof path24 === "object" && !!path24[Symbol.iterator]().next().done;
861
861
  var Collection = class extends Node.NodeBase {
862
862
  constructor(type, schema) {
863
863
  super(type);
@@ -887,11 +887,11 @@ var require_Collection = __commonJS({
887
887
  * be a Pair instance or a `{ key, value }` object, which may not have a key
888
888
  * that already exists in the map.
889
889
  */
890
- addIn(path21, value) {
891
- if (isEmptyPath(path21))
890
+ addIn(path24, value) {
891
+ if (isEmptyPath(path24))
892
892
  this.add(value);
893
893
  else {
894
- const [key, ...rest] = path21;
894
+ const [key, ...rest] = path24;
895
895
  const node = this.get(key, true);
896
896
  if (identity.isCollection(node))
897
897
  node.addIn(rest, value);
@@ -905,8 +905,8 @@ var require_Collection = __commonJS({
905
905
  * Removes a value from the collection.
906
906
  * @returns `true` if the item was found and removed.
907
907
  */
908
- deleteIn(path21) {
909
- const [key, ...rest] = path21;
908
+ deleteIn(path24) {
909
+ const [key, ...rest] = path24;
910
910
  if (rest.length === 0)
911
911
  return this.delete(key);
912
912
  const node = this.get(key, true);
@@ -920,8 +920,8 @@ var require_Collection = __commonJS({
920
920
  * scalar values from their surrounding node; to disable set `keepScalar` to
921
921
  * `true` (collections are always returned intact).
922
922
  */
923
- getIn(path21, keepScalar) {
924
- const [key, ...rest] = path21;
923
+ getIn(path24, keepScalar) {
924
+ const [key, ...rest] = path24;
925
925
  const node = this.get(key, true);
926
926
  if (rest.length === 0)
927
927
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -939,8 +939,8 @@ var require_Collection = __commonJS({
939
939
  /**
940
940
  * Checks if the collection includes a value with the key `key`.
941
941
  */
942
- hasIn(path21) {
943
- const [key, ...rest] = path21;
942
+ hasIn(path24) {
943
+ const [key, ...rest] = path24;
944
944
  if (rest.length === 0)
945
945
  return this.has(key);
946
946
  const node = this.get(key, true);
@@ -950,8 +950,8 @@ var require_Collection = __commonJS({
950
950
  * Sets a value in this collection. For `!!set`, `value` needs to be a
951
951
  * boolean to add/remove the item from the set.
952
952
  */
953
- setIn(path21, value) {
954
- const [key, ...rest] = path21;
953
+ setIn(path24, value) {
954
+ const [key, ...rest] = path24;
955
955
  if (rest.length === 0) {
956
956
  this.set(key, value);
957
957
  } else {
@@ -3455,9 +3455,9 @@ var require_Document = __commonJS({
3455
3455
  this.contents.add(value);
3456
3456
  }
3457
3457
  /** Adds a value to the document. */
3458
- addIn(path21, value) {
3458
+ addIn(path24, value) {
3459
3459
  if (assertCollection(this.contents))
3460
- this.contents.addIn(path21, value);
3460
+ this.contents.addIn(path24, value);
3461
3461
  }
3462
3462
  /**
3463
3463
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3532,14 +3532,14 @@ var require_Document = __commonJS({
3532
3532
  * Removes a value from the document.
3533
3533
  * @returns `true` if the item was found and removed.
3534
3534
  */
3535
- deleteIn(path21) {
3536
- if (Collection.isEmptyPath(path21)) {
3535
+ deleteIn(path24) {
3536
+ if (Collection.isEmptyPath(path24)) {
3537
3537
  if (this.contents == null)
3538
3538
  return false;
3539
3539
  this.contents = null;
3540
3540
  return true;
3541
3541
  }
3542
- return assertCollection(this.contents) ? this.contents.deleteIn(path21) : false;
3542
+ return assertCollection(this.contents) ? this.contents.deleteIn(path24) : false;
3543
3543
  }
3544
3544
  /**
3545
3545
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3554,10 +3554,10 @@ var require_Document = __commonJS({
3554
3554
  * scalar values from their surrounding node; to disable set `keepScalar` to
3555
3555
  * `true` (collections are always returned intact).
3556
3556
  */
3557
- getIn(path21, keepScalar) {
3558
- if (Collection.isEmptyPath(path21))
3557
+ getIn(path24, keepScalar) {
3558
+ if (Collection.isEmptyPath(path24))
3559
3559
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3560
- return identity.isCollection(this.contents) ? this.contents.getIn(path21, keepScalar) : void 0;
3560
+ return identity.isCollection(this.contents) ? this.contents.getIn(path24, keepScalar) : void 0;
3561
3561
  }
3562
3562
  /**
3563
3563
  * Checks if the document includes a value with the key `key`.
@@ -3568,10 +3568,10 @@ var require_Document = __commonJS({
3568
3568
  /**
3569
3569
  * Checks if the document includes a value at `path`.
3570
3570
  */
3571
- hasIn(path21) {
3572
- if (Collection.isEmptyPath(path21))
3571
+ hasIn(path24) {
3572
+ if (Collection.isEmptyPath(path24))
3573
3573
  return this.contents !== void 0;
3574
- return identity.isCollection(this.contents) ? this.contents.hasIn(path21) : false;
3574
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path24) : false;
3575
3575
  }
3576
3576
  /**
3577
3577
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3588,13 +3588,13 @@ var require_Document = __commonJS({
3588
3588
  * Sets a value in this document. For `!!set`, `value` needs to be a
3589
3589
  * boolean to add/remove the item from the set.
3590
3590
  */
3591
- setIn(path21, value) {
3592
- if (Collection.isEmptyPath(path21)) {
3591
+ setIn(path24, value) {
3592
+ if (Collection.isEmptyPath(path24)) {
3593
3593
  this.contents = value;
3594
3594
  } else if (this.contents == null) {
3595
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path21), value);
3595
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path24), value);
3596
3596
  } else if (assertCollection(this.contents)) {
3597
- this.contents.setIn(path21, value);
3597
+ this.contents.setIn(path24, value);
3598
3598
  }
3599
3599
  }
3600
3600
  /**
@@ -5546,9 +5546,9 @@ var require_cst_visit = __commonJS({
5546
5546
  visit.BREAK = BREAK;
5547
5547
  visit.SKIP = SKIP;
5548
5548
  visit.REMOVE = REMOVE;
5549
- visit.itemAtPath = (cst, path21) => {
5549
+ visit.itemAtPath = (cst, path24) => {
5550
5550
  let item = cst;
5551
- for (const [field, index] of path21) {
5551
+ for (const [field, index] of path24) {
5552
5552
  const tok = item?.[field];
5553
5553
  if (tok && "items" in tok) {
5554
5554
  item = tok.items[index];
@@ -5557,23 +5557,23 @@ var require_cst_visit = __commonJS({
5557
5557
  }
5558
5558
  return item;
5559
5559
  };
5560
- visit.parentCollection = (cst, path21) => {
5561
- const parent = visit.itemAtPath(cst, path21.slice(0, -1));
5562
- const field = path21[path21.length - 1][0];
5560
+ visit.parentCollection = (cst, path24) => {
5561
+ const parent = visit.itemAtPath(cst, path24.slice(0, -1));
5562
+ const field = path24[path24.length - 1][0];
5563
5563
  const coll = parent?.[field];
5564
5564
  if (coll && "items" in coll)
5565
5565
  return coll;
5566
5566
  throw new Error("Parent collection not found");
5567
5567
  };
5568
- function _visit(path21, item, visitor) {
5569
- let ctrl = visitor(item, path21);
5568
+ function _visit(path24, item, visitor) {
5569
+ let ctrl = visitor(item, path24);
5570
5570
  if (typeof ctrl === "symbol")
5571
5571
  return ctrl;
5572
5572
  for (const field of ["key", "value"]) {
5573
5573
  const token = item[field];
5574
5574
  if (token && "items" in token) {
5575
5575
  for (let i = 0; i < token.items.length; ++i) {
5576
- const ci = _visit(Object.freeze(path21.concat([[field, i]])), token.items[i], visitor);
5576
+ const ci = _visit(Object.freeze(path24.concat([[field, i]])), token.items[i], visitor);
5577
5577
  if (typeof ci === "number")
5578
5578
  i = ci - 1;
5579
5579
  else if (ci === BREAK)
@@ -5584,10 +5584,10 @@ var require_cst_visit = __commonJS({
5584
5584
  }
5585
5585
  }
5586
5586
  if (typeof ctrl === "function" && field === "key")
5587
- ctrl = ctrl(item, path21);
5587
+ ctrl = ctrl(item, path24);
5588
5588
  }
5589
5589
  }
5590
- return typeof ctrl === "function" ? ctrl(item, path21) : ctrl;
5590
+ return typeof ctrl === "function" ? ctrl(item, path24) : ctrl;
5591
5591
  }
5592
5592
  exports2.visit = visit;
5593
5593
  }
@@ -21369,11 +21369,11 @@ var require_mime_types = __commonJS({
21369
21369
  }
21370
21370
  return exts[0];
21371
21371
  }
21372
- function lookup(path21) {
21373
- if (!path21 || typeof path21 !== "string") {
21372
+ function lookup(path24) {
21373
+ if (!path24 || typeof path24 !== "string") {
21374
21374
  return false;
21375
21375
  }
21376
- var extension2 = extname("x." + path21).toLowerCase().substr(1);
21376
+ var extension2 = extname("x." + path24).toLowerCase().substr(1);
21377
21377
  if (!extension2) {
21378
21378
  return false;
21379
21379
  }
@@ -24888,7 +24888,7 @@ var require_path_to_regexp = __commonJS({
24888
24888
  "node_modules/.pnpm/path-to-regexp@0.1.12/node_modules/path-to-regexp/index.js"(exports2, module2) {
24889
24889
  module2.exports = pathToRegexp;
24890
24890
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
24891
- function pathToRegexp(path21, keys, options) {
24891
+ function pathToRegexp(path24, keys, options) {
24892
24892
  options = options || {};
24893
24893
  keys = keys || [];
24894
24894
  var strict = options.strict;
@@ -24902,8 +24902,8 @@ var require_path_to_regexp = __commonJS({
24902
24902
  var pos = 0;
24903
24903
  var backtrack = "";
24904
24904
  var m;
24905
- if (path21 instanceof RegExp) {
24906
- while (m = MATCHING_GROUP_REGEXP.exec(path21.source)) {
24905
+ if (path24 instanceof RegExp) {
24906
+ while (m = MATCHING_GROUP_REGEXP.exec(path24.source)) {
24907
24907
  if (m[0][0] === "\\") continue;
24908
24908
  keys.push({
24909
24909
  name: m[1] || name++,
@@ -24911,18 +24911,18 @@ var require_path_to_regexp = __commonJS({
24911
24911
  offset: m.index
24912
24912
  });
24913
24913
  }
24914
- return path21;
24914
+ return path24;
24915
24915
  }
24916
- if (Array.isArray(path21)) {
24917
- path21 = path21.map(function(value) {
24916
+ if (Array.isArray(path24)) {
24917
+ path24 = path24.map(function(value) {
24918
24918
  return pathToRegexp(value, keys, options).source;
24919
24919
  });
24920
- return new RegExp(path21.join("|"), flags);
24920
+ return new RegExp(path24.join("|"), flags);
24921
24921
  }
24922
- if (typeof path21 !== "string") {
24922
+ if (typeof path24 !== "string") {
24923
24923
  throw new TypeError("path must be a string, array of strings, or regular expression");
24924
24924
  }
24925
- path21 = path21.replace(
24925
+ path24 = path24.replace(
24926
24926
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
24927
24927
  function(match, slash, format, key, capture, star, optional, offset) {
24928
24928
  if (match[0] === "\\") {
@@ -24939,7 +24939,7 @@ var require_path_to_regexp = __commonJS({
24939
24939
  if (slash || format) {
24940
24940
  backtrack = "";
24941
24941
  } else {
24942
- backtrack += path21.slice(pos, offset);
24942
+ backtrack += path24.slice(pos, offset);
24943
24943
  }
24944
24944
  pos = offset + match.length;
24945
24945
  if (match === "*") {
@@ -24967,7 +24967,7 @@ var require_path_to_regexp = __commonJS({
24967
24967
  return result;
24968
24968
  }
24969
24969
  );
24970
- while (m = MATCHING_GROUP_REGEXP.exec(path21)) {
24970
+ while (m = MATCHING_GROUP_REGEXP.exec(path24)) {
24971
24971
  if (m[0][0] === "\\") continue;
24972
24972
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
24973
24973
  keys.splice(keysOffset + i, 0, {
@@ -24979,13 +24979,13 @@ var require_path_to_regexp = __commonJS({
24979
24979
  }
24980
24980
  i++;
24981
24981
  }
24982
- path21 += strict ? "" : path21[path21.length - 1] === "/" ? "?" : "/?";
24982
+ path24 += strict ? "" : path24[path24.length - 1] === "/" ? "?" : "/?";
24983
24983
  if (end) {
24984
- path21 += "$";
24985
- } else if (path21[path21.length - 1] !== "/") {
24986
- path21 += lookahead ? "(?=/|$)" : "(?:/|$)";
24984
+ path24 += "$";
24985
+ } else if (path24[path24.length - 1] !== "/") {
24986
+ path24 += lookahead ? "(?=/|$)" : "(?:/|$)";
24987
24987
  }
24988
- return new RegExp("^" + path21, flags);
24988
+ return new RegExp("^" + path24, flags);
24989
24989
  }
24990
24990
  }
24991
24991
  });
@@ -24998,19 +24998,19 @@ var require_layer = __commonJS({
24998
24998
  var debug = require_src()("express:router:layer");
24999
24999
  var hasOwnProperty = Object.prototype.hasOwnProperty;
25000
25000
  module2.exports = Layer;
25001
- function Layer(path21, options, fn) {
25001
+ function Layer(path24, options, fn) {
25002
25002
  if (!(this instanceof Layer)) {
25003
- return new Layer(path21, options, fn);
25003
+ return new Layer(path24, options, fn);
25004
25004
  }
25005
- debug("new %o", path21);
25005
+ debug("new %o", path24);
25006
25006
  var opts = options || {};
25007
25007
  this.handle = fn;
25008
25008
  this.name = fn.name || "<anonymous>";
25009
25009
  this.params = void 0;
25010
25010
  this.path = void 0;
25011
- this.regexp = pathRegexp(path21, this.keys = [], opts);
25012
- this.regexp.fast_star = path21 === "*";
25013
- this.regexp.fast_slash = path21 === "/" && opts.end === false;
25011
+ this.regexp = pathRegexp(path24, this.keys = [], opts);
25012
+ this.regexp.fast_star = path24 === "*";
25013
+ this.regexp.fast_slash = path24 === "/" && opts.end === false;
25014
25014
  }
25015
25015
  Layer.prototype.handle_error = function handle_error(error, req, res, next) {
25016
25016
  var fn = this.handle;
@@ -25034,20 +25034,20 @@ var require_layer = __commonJS({
25034
25034
  next(err);
25035
25035
  }
25036
25036
  };
25037
- Layer.prototype.match = function match(path21) {
25037
+ Layer.prototype.match = function match(path24) {
25038
25038
  var match2;
25039
- if (path21 != null) {
25039
+ if (path24 != null) {
25040
25040
  if (this.regexp.fast_slash) {
25041
25041
  this.params = {};
25042
25042
  this.path = "";
25043
25043
  return true;
25044
25044
  }
25045
25045
  if (this.regexp.fast_star) {
25046
- this.params = { "0": decode_param(path21) };
25047
- this.path = path21;
25046
+ this.params = { "0": decode_param(path24) };
25047
+ this.path = path24;
25048
25048
  return true;
25049
25049
  }
25050
- match2 = this.regexp.exec(path21);
25050
+ match2 = this.regexp.exec(path24);
25051
25051
  }
25052
25052
  if (!match2) {
25053
25053
  this.params = void 0;
@@ -25140,10 +25140,10 @@ var require_route = __commonJS({
25140
25140
  var slice = Array.prototype.slice;
25141
25141
  var toString = Object.prototype.toString;
25142
25142
  module2.exports = Route;
25143
- function Route(path21) {
25144
- this.path = path21;
25143
+ function Route(path24) {
25144
+ this.path = path24;
25145
25145
  this.stack = [];
25146
- debug("new %o", path21);
25146
+ debug("new %o", path24);
25147
25147
  this.methods = {};
25148
25148
  }
25149
25149
  Route.prototype._handles_method = function _handles_method(method) {
@@ -25355,8 +25355,8 @@ var require_router = __commonJS({
25355
25355
  if (++sync > 100) {
25356
25356
  return setImmediate(next, err);
25357
25357
  }
25358
- var path21 = getPathname(req);
25359
- if (path21 == null) {
25358
+ var path24 = getPathname(req);
25359
+ if (path24 == null) {
25360
25360
  return done(layerError);
25361
25361
  }
25362
25362
  var layer;
@@ -25364,7 +25364,7 @@ var require_router = __commonJS({
25364
25364
  var route;
25365
25365
  while (match !== true && idx < stack.length) {
25366
25366
  layer = stack[idx++];
25367
- match = matchLayer(layer, path21);
25367
+ match = matchLayer(layer, path24);
25368
25368
  route = layer.route;
25369
25369
  if (typeof match !== "boolean") {
25370
25370
  layerError = layerError || match;
@@ -25402,18 +25402,18 @@ var require_router = __commonJS({
25402
25402
  } else if (route) {
25403
25403
  layer.handle_request(req, res, next);
25404
25404
  } else {
25405
- trim_prefix(layer, layerError, layerPath, path21);
25405
+ trim_prefix(layer, layerError, layerPath, path24);
25406
25406
  }
25407
25407
  sync = 0;
25408
25408
  });
25409
25409
  }
25410
- function trim_prefix(layer, layerError, layerPath, path21) {
25410
+ function trim_prefix(layer, layerError, layerPath, path24) {
25411
25411
  if (layerPath.length !== 0) {
25412
- if (layerPath !== path21.slice(0, layerPath.length)) {
25412
+ if (layerPath !== path24.slice(0, layerPath.length)) {
25413
25413
  next(layerError);
25414
25414
  return;
25415
25415
  }
25416
- var c = path21[layerPath.length];
25416
+ var c = path24[layerPath.length];
25417
25417
  if (c && c !== "/" && c !== ".") return next(layerError);
25418
25418
  debug("trim prefix (%s) from url %s", layerPath, req.url);
25419
25419
  removed = layerPath;
@@ -25491,7 +25491,7 @@ var require_router = __commonJS({
25491
25491
  };
25492
25492
  proto.use = function use(fn) {
25493
25493
  var offset = 0;
25494
- var path21 = "/";
25494
+ var path24 = "/";
25495
25495
  if (typeof fn !== "function") {
25496
25496
  var arg = fn;
25497
25497
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -25499,7 +25499,7 @@ var require_router = __commonJS({
25499
25499
  }
25500
25500
  if (typeof arg !== "function") {
25501
25501
  offset = 1;
25502
- path21 = fn;
25502
+ path24 = fn;
25503
25503
  }
25504
25504
  }
25505
25505
  var callbacks = flatten(slice.call(arguments, offset));
@@ -25511,8 +25511,8 @@ var require_router = __commonJS({
25511
25511
  if (typeof fn !== "function") {
25512
25512
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
25513
25513
  }
25514
- debug("use %o %s", path21, fn.name || "<anonymous>");
25515
- var layer = new Layer(path21, {
25514
+ debug("use %o %s", path24, fn.name || "<anonymous>");
25515
+ var layer = new Layer(path24, {
25516
25516
  sensitive: this.caseSensitive,
25517
25517
  strict: false,
25518
25518
  end: false
@@ -25522,9 +25522,9 @@ var require_router = __commonJS({
25522
25522
  }
25523
25523
  return this;
25524
25524
  };
25525
- proto.route = function route(path21) {
25526
- var route2 = new Route(path21);
25527
- var layer = new Layer(path21, {
25525
+ proto.route = function route(path24) {
25526
+ var route2 = new Route(path24);
25527
+ var layer = new Layer(path24, {
25528
25528
  sensitive: this.caseSensitive,
25529
25529
  strict: this.strict,
25530
25530
  end: true
@@ -25534,8 +25534,8 @@ var require_router = __commonJS({
25534
25534
  return route2;
25535
25535
  };
25536
25536
  methods.concat("all").forEach(function(method) {
25537
- proto[method] = function(path21) {
25538
- var route = this.route(path21);
25537
+ proto[method] = function(path24) {
25538
+ var route = this.route(path24);
25539
25539
  route[method].apply(route, slice.call(arguments, 1));
25540
25540
  return this;
25541
25541
  };
@@ -25571,9 +25571,9 @@ var require_router = __commonJS({
25571
25571
  }
25572
25572
  return toString.call(obj).replace(objectRegExp, "$1");
25573
25573
  }
25574
- function matchLayer(layer, path21) {
25574
+ function matchLayer(layer, path24) {
25575
25575
  try {
25576
- return layer.match(path21);
25576
+ return layer.match(path24);
25577
25577
  } catch (err) {
25578
25578
  return err;
25579
25579
  }
@@ -25691,13 +25691,13 @@ var require_view = __commonJS({
25691
25691
  "node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports2, module2) {
25692
25692
  "use strict";
25693
25693
  var debug = require_src()("express:view");
25694
- var path21 = require("path");
25694
+ var path24 = require("path");
25695
25695
  var fs = require("fs");
25696
- var dirname = path21.dirname;
25697
- var basename = path21.basename;
25698
- var extname = path21.extname;
25699
- var join = path21.join;
25700
- var resolve = path21.resolve;
25696
+ var dirname = path24.dirname;
25697
+ var basename = path24.basename;
25698
+ var extname = path24.extname;
25699
+ var join = path24.join;
25700
+ var resolve = path24.resolve;
25701
25701
  module2.exports = View;
25702
25702
  function View(name, options) {
25703
25703
  var opts = options || {};
@@ -25726,17 +25726,17 @@ var require_view = __commonJS({
25726
25726
  this.path = this.lookup(fileName);
25727
25727
  }
25728
25728
  View.prototype.lookup = function lookup(name) {
25729
- var path22;
25729
+ var path25;
25730
25730
  var roots = [].concat(this.root);
25731
25731
  debug('lookup "%s"', name);
25732
- for (var i = 0; i < roots.length && !path22; i++) {
25732
+ for (var i = 0; i < roots.length && !path25; i++) {
25733
25733
  var root = roots[i];
25734
25734
  var loc = resolve(root, name);
25735
25735
  var dir = dirname(loc);
25736
25736
  var file = basename(loc);
25737
- path22 = this.resolve(dir, file);
25737
+ path25 = this.resolve(dir, file);
25738
25738
  }
25739
- return path22;
25739
+ return path25;
25740
25740
  };
25741
25741
  View.prototype.render = function render(options, callback) {
25742
25742
  debug('render "%s"', this.path);
@@ -25744,21 +25744,21 @@ var require_view = __commonJS({
25744
25744
  };
25745
25745
  View.prototype.resolve = function resolve2(dir, file) {
25746
25746
  var ext = this.ext;
25747
- var path22 = join(dir, file);
25748
- var stat3 = tryStat(path22);
25747
+ var path25 = join(dir, file);
25748
+ var stat3 = tryStat(path25);
25749
25749
  if (stat3 && stat3.isFile()) {
25750
- return path22;
25750
+ return path25;
25751
25751
  }
25752
- path22 = join(dir, basename(file, ext), "index" + ext);
25753
- stat3 = tryStat(path22);
25752
+ path25 = join(dir, basename(file, ext), "index" + ext);
25753
+ stat3 = tryStat(path25);
25754
25754
  if (stat3 && stat3.isFile()) {
25755
- return path22;
25755
+ return path25;
25756
25756
  }
25757
25757
  };
25758
- function tryStat(path22) {
25759
- debug('stat "%s"', path22);
25758
+ function tryStat(path25) {
25759
+ debug('stat "%s"', path25);
25760
25760
  try {
25761
- return fs.statSync(path22);
25761
+ return fs.statSync(path25);
25762
25762
  } catch (e) {
25763
25763
  return void 0;
25764
25764
  }
@@ -26112,7 +26112,7 @@ var require_types = __commonJS({
26112
26112
  // node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js
26113
26113
  var require_mime = __commonJS({
26114
26114
  "node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports2, module2) {
26115
- var path21 = require("path");
26115
+ var path24 = require("path");
26116
26116
  var fs = require("fs");
26117
26117
  function Mime() {
26118
26118
  this.types = /* @__PURE__ */ Object.create(null);
@@ -26142,8 +26142,8 @@ var require_mime = __commonJS({
26142
26142
  this.define(map);
26143
26143
  this._loading = null;
26144
26144
  };
26145
- Mime.prototype.lookup = function(path22, fallback) {
26146
- var ext = path22.replace(/^.*[\.\/\\]/, "").toLowerCase();
26145
+ Mime.prototype.lookup = function(path25, fallback) {
26146
+ var ext = path25.replace(/^.*[\.\/\\]/, "").toLowerCase();
26147
26147
  return this.types[ext] || fallback || this.default_type;
26148
26148
  };
26149
26149
  Mime.prototype.extension = function(mimeType) {
@@ -26377,28 +26377,28 @@ var require_send = __commonJS({
26377
26377
  var ms = require_ms2();
26378
26378
  var onFinished = require_on_finished();
26379
26379
  var parseRange = require_range_parser();
26380
- var path21 = require("path");
26380
+ var path24 = require("path");
26381
26381
  var statuses = require_statuses();
26382
26382
  var Stream = require("stream");
26383
26383
  var util2 = require("util");
26384
- var extname = path21.extname;
26385
- var join = path21.join;
26386
- var normalize = path21.normalize;
26387
- var resolve = path21.resolve;
26388
- var sep = path21.sep;
26384
+ var extname = path24.extname;
26385
+ var join = path24.join;
26386
+ var normalize = path24.normalize;
26387
+ var resolve = path24.resolve;
26388
+ var sep = path24.sep;
26389
26389
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
26390
26390
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
26391
26391
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
26392
26392
  module2.exports = send2;
26393
26393
  module2.exports.mime = mime;
26394
- function send2(req, path22, options) {
26395
- return new SendStream(req, path22, options);
26394
+ function send2(req, path25, options) {
26395
+ return new SendStream(req, path25, options);
26396
26396
  }
26397
- function SendStream(req, path22, options) {
26397
+ function SendStream(req, path25, options) {
26398
26398
  Stream.call(this);
26399
26399
  var opts = options || {};
26400
26400
  this.options = opts;
26401
- this.path = path22;
26401
+ this.path = path25;
26402
26402
  this.req = req;
26403
26403
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
26404
26404
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -26444,8 +26444,8 @@ var require_send = __commonJS({
26444
26444
  this._index = index2;
26445
26445
  return this;
26446
26446
  }, "send.index: pass index as option");
26447
- SendStream.prototype.root = function root(path22) {
26448
- this._root = resolve(String(path22));
26447
+ SendStream.prototype.root = function root(path25) {
26448
+ this._root = resolve(String(path25));
26449
26449
  debug("root %s", this._root);
26450
26450
  return this;
26451
26451
  };
@@ -26558,10 +26558,10 @@ var require_send = __commonJS({
26558
26558
  var lastModified = this.res.getHeader("Last-Modified");
26559
26559
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
26560
26560
  };
26561
- SendStream.prototype.redirect = function redirect(path22) {
26561
+ SendStream.prototype.redirect = function redirect(path25) {
26562
26562
  var res = this.res;
26563
26563
  if (hasListeners(this, "directory")) {
26564
- this.emit("directory", res, path22);
26564
+ this.emit("directory", res, path25);
26565
26565
  return;
26566
26566
  }
26567
26567
  if (this.hasTrailingSlash()) {
@@ -26581,42 +26581,42 @@ var require_send = __commonJS({
26581
26581
  SendStream.prototype.pipe = function pipe(res) {
26582
26582
  var root = this._root;
26583
26583
  this.res = res;
26584
- var path22 = decode(this.path);
26585
- if (path22 === -1) {
26584
+ var path25 = decode(this.path);
26585
+ if (path25 === -1) {
26586
26586
  this.error(400);
26587
26587
  return res;
26588
26588
  }
26589
- if (~path22.indexOf("\0")) {
26589
+ if (~path25.indexOf("\0")) {
26590
26590
  this.error(400);
26591
26591
  return res;
26592
26592
  }
26593
26593
  var parts;
26594
26594
  if (root !== null) {
26595
- if (path22) {
26596
- path22 = normalize("." + sep + path22);
26595
+ if (path25) {
26596
+ path25 = normalize("." + sep + path25);
26597
26597
  }
26598
- if (UP_PATH_REGEXP.test(path22)) {
26599
- debug('malicious path "%s"', path22);
26598
+ if (UP_PATH_REGEXP.test(path25)) {
26599
+ debug('malicious path "%s"', path25);
26600
26600
  this.error(403);
26601
26601
  return res;
26602
26602
  }
26603
- parts = path22.split(sep);
26604
- path22 = normalize(join(root, path22));
26603
+ parts = path25.split(sep);
26604
+ path25 = normalize(join(root, path25));
26605
26605
  } else {
26606
- if (UP_PATH_REGEXP.test(path22)) {
26607
- debug('malicious path "%s"', path22);
26606
+ if (UP_PATH_REGEXP.test(path25)) {
26607
+ debug('malicious path "%s"', path25);
26608
26608
  this.error(403);
26609
26609
  return res;
26610
26610
  }
26611
- parts = normalize(path22).split(sep);
26612
- path22 = resolve(path22);
26611
+ parts = normalize(path25).split(sep);
26612
+ path25 = resolve(path25);
26613
26613
  }
26614
26614
  if (containsDotFile(parts)) {
26615
26615
  var access = this._dotfiles;
26616
26616
  if (access === void 0) {
26617
26617
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
26618
26618
  }
26619
- debug('%s dotfile "%s"', access, path22);
26619
+ debug('%s dotfile "%s"', access, path25);
26620
26620
  switch (access) {
26621
26621
  case "allow":
26622
26622
  break;
@@ -26630,13 +26630,13 @@ var require_send = __commonJS({
26630
26630
  }
26631
26631
  }
26632
26632
  if (this._index.length && this.hasTrailingSlash()) {
26633
- this.sendIndex(path22);
26633
+ this.sendIndex(path25);
26634
26634
  return res;
26635
26635
  }
26636
- this.sendFile(path22);
26636
+ this.sendFile(path25);
26637
26637
  return res;
26638
26638
  };
26639
- SendStream.prototype.send = function send3(path22, stat3) {
26639
+ SendStream.prototype.send = function send3(path25, stat3) {
26640
26640
  var len = stat3.size;
26641
26641
  var options = this.options;
26642
26642
  var opts = {};
@@ -26648,9 +26648,9 @@ var require_send = __commonJS({
26648
26648
  this.headersAlreadySent();
26649
26649
  return;
26650
26650
  }
26651
- debug('pipe "%s"', path22);
26652
- this.setHeader(path22, stat3);
26653
- this.type(path22);
26651
+ debug('pipe "%s"', path25);
26652
+ this.setHeader(path25, stat3);
26653
+ this.type(path25);
26654
26654
  if (this.isConditionalGET()) {
26655
26655
  if (this.isPreconditionFailure()) {
26656
26656
  this.error(412);
@@ -26699,26 +26699,26 @@ var require_send = __commonJS({
26699
26699
  res.end();
26700
26700
  return;
26701
26701
  }
26702
- this.stream(path22, opts);
26702
+ this.stream(path25, opts);
26703
26703
  };
26704
- SendStream.prototype.sendFile = function sendFile(path22) {
26704
+ SendStream.prototype.sendFile = function sendFile(path25) {
26705
26705
  var i = 0;
26706
26706
  var self = this;
26707
- debug('stat "%s"', path22);
26708
- fs.stat(path22, function onstat(err, stat3) {
26709
- if (err && err.code === "ENOENT" && !extname(path22) && path22[path22.length - 1] !== sep) {
26707
+ debug('stat "%s"', path25);
26708
+ fs.stat(path25, function onstat(err, stat3) {
26709
+ if (err && err.code === "ENOENT" && !extname(path25) && path25[path25.length - 1] !== sep) {
26710
26710
  return next(err);
26711
26711
  }
26712
26712
  if (err) return self.onStatError(err);
26713
- if (stat3.isDirectory()) return self.redirect(path22);
26714
- self.emit("file", path22, stat3);
26715
- self.send(path22, stat3);
26713
+ if (stat3.isDirectory()) return self.redirect(path25);
26714
+ self.emit("file", path25, stat3);
26715
+ self.send(path25, stat3);
26716
26716
  });
26717
26717
  function next(err) {
26718
26718
  if (self._extensions.length <= i) {
26719
26719
  return err ? self.onStatError(err) : self.error(404);
26720
26720
  }
26721
- var p = path22 + "." + self._extensions[i++];
26721
+ var p = path25 + "." + self._extensions[i++];
26722
26722
  debug('stat "%s"', p);
26723
26723
  fs.stat(p, function(err2, stat3) {
26724
26724
  if (err2) return next(err2);
@@ -26728,7 +26728,7 @@ var require_send = __commonJS({
26728
26728
  });
26729
26729
  }
26730
26730
  };
26731
- SendStream.prototype.sendIndex = function sendIndex(path22) {
26731
+ SendStream.prototype.sendIndex = function sendIndex(path25) {
26732
26732
  var i = -1;
26733
26733
  var self = this;
26734
26734
  function next(err) {
@@ -26736,7 +26736,7 @@ var require_send = __commonJS({
26736
26736
  if (err) return self.onStatError(err);
26737
26737
  return self.error(404);
26738
26738
  }
26739
- var p = join(path22, self._index[i]);
26739
+ var p = join(path25, self._index[i]);
26740
26740
  debug('stat "%s"', p);
26741
26741
  fs.stat(p, function(err2, stat3) {
26742
26742
  if (err2) return next(err2);
@@ -26747,10 +26747,10 @@ var require_send = __commonJS({
26747
26747
  }
26748
26748
  next();
26749
26749
  };
26750
- SendStream.prototype.stream = function stream(path22, options) {
26750
+ SendStream.prototype.stream = function stream(path25, options) {
26751
26751
  var self = this;
26752
26752
  var res = this.res;
26753
- var stream2 = fs.createReadStream(path22, options);
26753
+ var stream2 = fs.createReadStream(path25, options);
26754
26754
  this.emit("stream", stream2);
26755
26755
  stream2.pipe(res);
26756
26756
  function cleanup() {
@@ -26765,10 +26765,10 @@ var require_send = __commonJS({
26765
26765
  self.emit("end");
26766
26766
  });
26767
26767
  };
26768
- SendStream.prototype.type = function type(path22) {
26768
+ SendStream.prototype.type = function type(path25) {
26769
26769
  var res = this.res;
26770
26770
  if (res.getHeader("Content-Type")) return;
26771
- var type2 = mime.lookup(path22);
26771
+ var type2 = mime.lookup(path25);
26772
26772
  if (!type2) {
26773
26773
  debug("no content-type");
26774
26774
  return;
@@ -26777,9 +26777,9 @@ var require_send = __commonJS({
26777
26777
  debug("content-type %s", type2);
26778
26778
  res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
26779
26779
  };
26780
- SendStream.prototype.setHeader = function setHeader(path22, stat3) {
26780
+ SendStream.prototype.setHeader = function setHeader(path25, stat3) {
26781
26781
  var res = this.res;
26782
- this.emit("headers", res, path22, stat3);
26782
+ this.emit("headers", res, path25, stat3);
26783
26783
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
26784
26784
  debug("accept ranges");
26785
26785
  res.setHeader("Accept-Ranges", "bytes");
@@ -26838,9 +26838,9 @@ var require_send = __commonJS({
26838
26838
  }
26839
26839
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
26840
26840
  }
26841
- function decode(path22) {
26841
+ function decode(path25) {
26842
26842
  try {
26843
- return decodeURIComponent(path22);
26843
+ return decodeURIComponent(path25);
26844
26844
  } catch (err) {
26845
26845
  return -1;
26846
26846
  }
@@ -27749,10 +27749,10 @@ var require_utils2 = __commonJS({
27749
27749
  var querystring = require("querystring");
27750
27750
  exports2.etag = createETagGenerator({ weak: false });
27751
27751
  exports2.wetag = createETagGenerator({ weak: true });
27752
- exports2.isAbsolute = function(path21) {
27753
- if ("/" === path21[0]) return true;
27754
- if (":" === path21[1] && ("\\" === path21[2] || "/" === path21[2])) return true;
27755
- if ("\\\\" === path21.substring(0, 2)) return true;
27752
+ exports2.isAbsolute = function(path24) {
27753
+ if ("/" === path24[0]) return true;
27754
+ if (":" === path24[1] && ("\\" === path24[2] || "/" === path24[2])) return true;
27755
+ if ("\\\\" === path24.substring(0, 2)) return true;
27756
27756
  };
27757
27757
  exports2.flatten = deprecate.function(
27758
27758
  flatten,
@@ -27963,7 +27963,7 @@ var require_application = __commonJS({
27963
27963
  };
27964
27964
  app.use = function use(fn) {
27965
27965
  var offset = 0;
27966
- var path21 = "/";
27966
+ var path24 = "/";
27967
27967
  if (typeof fn !== "function") {
27968
27968
  var arg = fn;
27969
27969
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -27971,7 +27971,7 @@ var require_application = __commonJS({
27971
27971
  }
27972
27972
  if (typeof arg !== "function") {
27973
27973
  offset = 1;
27974
- path21 = fn;
27974
+ path24 = fn;
27975
27975
  }
27976
27976
  }
27977
27977
  var fns = flatten(slice.call(arguments, offset));
@@ -27982,12 +27982,12 @@ var require_application = __commonJS({
27982
27982
  var router = this._router;
27983
27983
  fns.forEach(function(fn2) {
27984
27984
  if (!fn2 || !fn2.handle || !fn2.set) {
27985
- return router.use(path21, fn2);
27985
+ return router.use(path24, fn2);
27986
27986
  }
27987
- debug(".use app under %s", path21);
27988
- fn2.mountpath = path21;
27987
+ debug(".use app under %s", path24);
27988
+ fn2.mountpath = path24;
27989
27989
  fn2.parent = this;
27990
- router.use(path21, function mounted_app(req, res, next) {
27990
+ router.use(path24, function mounted_app(req, res, next) {
27991
27991
  var orig = req.app;
27992
27992
  fn2.handle(req, res, function(err) {
27993
27993
  setPrototypeOf(req, orig.request);
@@ -27999,9 +27999,9 @@ var require_application = __commonJS({
27999
27999
  }, this);
28000
28000
  return this;
28001
28001
  };
28002
- app.route = function route(path21) {
28002
+ app.route = function route(path24) {
28003
28003
  this.lazyrouter();
28004
- return this._router.route(path21);
28004
+ return this._router.route(path24);
28005
28005
  };
28006
28006
  app.engine = function engine(ext, fn) {
28007
28007
  if (typeof fn !== "function") {
@@ -28052,7 +28052,7 @@ var require_application = __commonJS({
28052
28052
  }
28053
28053
  return this;
28054
28054
  };
28055
- app.path = function path21() {
28055
+ app.path = function path24() {
28056
28056
  return this.parent ? this.parent.path() + this.mountpath : "";
28057
28057
  };
28058
28058
  app.enabled = function enabled(setting2) {
@@ -28068,19 +28068,19 @@ var require_application = __commonJS({
28068
28068
  return this.set(setting2, false);
28069
28069
  };
28070
28070
  methods.forEach(function(method) {
28071
- app[method] = function(path21) {
28071
+ app[method] = function(path24) {
28072
28072
  if (method === "get" && arguments.length === 1) {
28073
- return this.set(path21);
28073
+ return this.set(path24);
28074
28074
  }
28075
28075
  this.lazyrouter();
28076
- var route = this._router.route(path21);
28076
+ var route = this._router.route(path24);
28077
28077
  route[method].apply(route, slice.call(arguments, 1));
28078
28078
  return this;
28079
28079
  };
28080
28080
  });
28081
- app.all = function all(path21) {
28081
+ app.all = function all(path24) {
28082
28082
  this.lazyrouter();
28083
- var route = this._router.route(path21);
28083
+ var route = this._router.route(path24);
28084
28084
  var args = slice.call(arguments, 1);
28085
28085
  for (var i = 0; i < methods.length; i++) {
28086
28086
  route[methods[i]].apply(route, args);
@@ -28839,7 +28839,7 @@ var require_request = __commonJS({
28839
28839
  var subdomains2 = !isIP(hostname) ? hostname.split(".").reverse() : [hostname];
28840
28840
  return subdomains2.slice(offset);
28841
28841
  });
28842
- defineGetter(req, "path", function path21() {
28842
+ defineGetter(req, "path", function path24() {
28843
28843
  return parse(this).pathname;
28844
28844
  });
28845
28845
  defineGetter(req, "hostname", function hostname() {
@@ -29161,7 +29161,7 @@ var require_response = __commonJS({
29161
29161
  var http2 = require("http");
29162
29162
  var isAbsolute = require_utils2().isAbsolute;
29163
29163
  var onFinished = require_on_finished();
29164
- var path21 = require("path");
29164
+ var path24 = require("path");
29165
29165
  var statuses = require_statuses();
29166
29166
  var merge = require_utils_merge();
29167
29167
  var sign = require_cookie_signature().sign;
@@ -29170,9 +29170,9 @@ var require_response = __commonJS({
29170
29170
  var setCharset = require_utils2().setCharset;
29171
29171
  var cookie = require_cookie();
29172
29172
  var send2 = require_send();
29173
- var extname = path21.extname;
29173
+ var extname = path24.extname;
29174
29174
  var mime = send2.mime;
29175
- var resolve = path21.resolve;
29175
+ var resolve = path24.resolve;
29176
29176
  var vary = require_vary();
29177
29177
  var res = Object.create(http2.ServerResponse.prototype);
29178
29178
  module2.exports = res;
@@ -29349,26 +29349,26 @@ var require_response = __commonJS({
29349
29349
  this.type("txt");
29350
29350
  return this.send(body);
29351
29351
  };
29352
- res.sendFile = function sendFile(path22, options, callback) {
29352
+ res.sendFile = function sendFile(path25, options, callback) {
29353
29353
  var done = callback;
29354
29354
  var req = this.req;
29355
29355
  var res2 = this;
29356
29356
  var next = req.next;
29357
29357
  var opts = options || {};
29358
- if (!path22) {
29358
+ if (!path25) {
29359
29359
  throw new TypeError("path argument is required to res.sendFile");
29360
29360
  }
29361
- if (typeof path22 !== "string") {
29361
+ if (typeof path25 !== "string") {
29362
29362
  throw new TypeError("path must be a string to res.sendFile");
29363
29363
  }
29364
29364
  if (typeof options === "function") {
29365
29365
  done = options;
29366
29366
  opts = {};
29367
29367
  }
29368
- if (!opts.root && !isAbsolute(path22)) {
29368
+ if (!opts.root && !isAbsolute(path25)) {
29369
29369
  throw new TypeError("path must be absolute or specify root to res.sendFile");
29370
29370
  }
29371
- var pathname = encodeURI(path22);
29371
+ var pathname = encodeURI(path25);
29372
29372
  var file = send2(req, pathname, opts);
29373
29373
  sendfile(res2, file, opts, function(err) {
29374
29374
  if (done) return done(err);
@@ -29378,7 +29378,7 @@ var require_response = __commonJS({
29378
29378
  }
29379
29379
  });
29380
29380
  };
29381
- res.sendfile = function(path22, options, callback) {
29381
+ res.sendfile = function(path25, options, callback) {
29382
29382
  var done = callback;
29383
29383
  var req = this.req;
29384
29384
  var res2 = this;
@@ -29388,7 +29388,7 @@ var require_response = __commonJS({
29388
29388
  done = options;
29389
29389
  opts = {};
29390
29390
  }
29391
- var file = send2(req, path22, opts);
29391
+ var file = send2(req, path25, opts);
29392
29392
  sendfile(res2, file, opts, function(err) {
29393
29393
  if (done) return done(err);
29394
29394
  if (err && err.code === "EISDIR") return next();
@@ -29401,7 +29401,7 @@ var require_response = __commonJS({
29401
29401
  res.sendfile,
29402
29402
  "res.sendfile: Use res.sendFile instead"
29403
29403
  );
29404
- res.download = function download(path22, filename, options, callback) {
29404
+ res.download = function download(path25, filename, options, callback) {
29405
29405
  var done = callback;
29406
29406
  var name = filename;
29407
29407
  var opts = options || null;
@@ -29418,7 +29418,7 @@ var require_response = __commonJS({
29418
29418
  opts = filename;
29419
29419
  }
29420
29420
  var headers = {
29421
- "Content-Disposition": contentDisposition(name || path22)
29421
+ "Content-Disposition": contentDisposition(name || path25)
29422
29422
  };
29423
29423
  if (opts && opts.headers) {
29424
29424
  var keys = Object.keys(opts.headers);
@@ -29431,7 +29431,7 @@ var require_response = __commonJS({
29431
29431
  }
29432
29432
  opts = Object.create(opts);
29433
29433
  opts.headers = headers;
29434
- var fullPath = !opts.root ? resolve(path22) : path22;
29434
+ var fullPath = !opts.root ? resolve(path25) : path25;
29435
29435
  return this.sendFile(fullPath, opts, done);
29436
29436
  };
29437
29437
  res.contentType = res.type = function contentType(type) {
@@ -29732,11 +29732,11 @@ var require_serve_static = __commonJS({
29732
29732
  }
29733
29733
  var forwardError = !fallthrough;
29734
29734
  var originalUrl = parseUrl.original(req);
29735
- var path21 = parseUrl(req).pathname;
29736
- if (path21 === "/" && originalUrl.pathname.substr(-1) !== "/") {
29737
- path21 = "";
29735
+ var path24 = parseUrl(req).pathname;
29736
+ if (path24 === "/" && originalUrl.pathname.substr(-1) !== "/") {
29737
+ path24 = "";
29738
29738
  }
29739
- var stream = send2(req, path21, opts);
29739
+ var stream = send2(req, path24, opts);
29740
29740
  stream.on("directory", onDirectory);
29741
29741
  if (setHeaders) {
29742
29742
  stream.on("headers", setHeaders);
@@ -33014,7 +33014,7 @@ var require_stream = __commonJS({
33014
33014
  };
33015
33015
  duplex._final = function(callback) {
33016
33016
  if (ws.readyState === ws.CONNECTING) {
33017
- ws.once("open", function open8() {
33017
+ ws.once("open", function open9() {
33018
33018
  duplex._final(callback);
33019
33019
  });
33020
33020
  return;
@@ -33035,7 +33035,7 @@ var require_stream = __commonJS({
33035
33035
  };
33036
33036
  duplex._write = function(chunk, encoding, callback) {
33037
33037
  if (ws.readyState === ws.CONNECTING) {
33038
- ws.once("open", function open8() {
33038
+ ws.once("open", function open9() {
33039
33039
  duplex._write(chunk, encoding, callback);
33040
33040
  });
33041
33041
  return;
@@ -33554,14 +33554,15 @@ var ConversationReadError = class extends Error {
33554
33554
  this.code = code;
33555
33555
  }
33556
33556
  };
33557
- async function scanConversationSource(file, consume, signal) {
33557
+ async function scanConversationSource(file, consume, signal, validateSource) {
33558
33558
  if (!import_node_path.default.isAbsolute(file) || import_node_path.default.extname(file) !== ".jsonl") return null;
33559
33559
  let handle;
33560
33560
  try {
33561
33561
  if (await (0, import_promises.realpath)(file) !== file) return null;
33562
- handle = await (0, import_promises.open)(file, import_node_fs2.constants.O_RDONLY | import_node_fs2.constants.O_NOFOLLOW);
33562
+ handle = await (0, import_promises.open)(file, import_node_fs2.constants.O_RDONLY | import_node_fs2.constants.O_NOFOLLOW | (validateSource ? import_node_fs2.constants.O_NONBLOCK : 0));
33563
33563
  const stat3 = await handle.stat();
33564
33564
  if (!stat3.isFile()) return null;
33565
+ await validateSource?.(stat3);
33565
33566
  const windowBytes = 64 * 1024 * 1024;
33566
33567
  const truncated = stat3.size > windowBytes;
33567
33568
  let partial = truncated;
@@ -33617,6 +33618,7 @@ async function scanConversationSource(file, consume, signal) {
33617
33618
  }
33618
33619
  }
33619
33620
  signal?.throwIfAborted();
33621
+ await validateSource?.(await handle.stat());
33620
33622
  return { partial, truncated };
33621
33623
  } catch (error) {
33622
33624
  if (["ENOENT", "ELOOP", "ENOTDIR"].includes(String(error.code))) return null;
@@ -33656,7 +33658,7 @@ var AnalysisEvidenceReader = class {
33656
33658
  throw new ConversationReadError(503, "SOURCE_IDENTITY_UNAVAILABLE", "\u6765\u6E90\u8EAB\u4EFD\u6682\u4E0D\u53EF\u8BFB");
33657
33659
  }
33658
33660
  if (metadata.type !== "session_meta" || metadata.payload?.id !== threadID) throw new ConversationReadError(409, "SOURCE_CHANGED", "\u6765\u6E90\u8EAB\u4EFD\u53D8\u5316");
33659
- let offset = 0, skip = false, missing = false;
33661
+ let offset = 0, skip = false, missing2 = false;
33660
33662
  let calls = {};
33661
33663
  let derived = metadata.payload?.source === "screen-analysis" || metadata.payload?.source === "daily-record";
33662
33664
  if (cursor) {
@@ -33665,7 +33667,7 @@ var AnalysisEvidenceReader = class {
33665
33667
  if (c.identity !== identity || !Number.isSafeInteger(c.offset) || c.offset < 0 || c.offset > info.size) throw new Error();
33666
33668
  offset = c.offset;
33667
33669
  skip = c.skip === true;
33668
- missing = c.missing === true;
33670
+ missing2 = c.missing === true;
33669
33671
  derived ||= c.derived === true;
33670
33672
  if (c.calls && Object.keys(c.calls).length <= 3 && Object.entries(c.calls).every(([id, name]) => id.length <= 128 && typeof name === "string" && ["exec_command", "shell_command", "functions.exec_command", "functions.shell_command"].includes(name))) calls = c.calls;
33671
33673
  } catch {
@@ -33753,7 +33755,7 @@ var AnalysisEvidenceReader = class {
33753
33755
  bytes += cost;
33754
33756
  consumed = end;
33755
33757
  }
33756
- return { events, nextCursor: Buffer.from(JSON.stringify({ identity, offset: offset + consumed, skip, derived, calls, missing: missing || truncated })).toString("base64url"), coverage: missing || truncated || offset + consumed < info.size ? "partial" : "complete", bytes, sourceVersion: identity };
33758
+ return { events, nextCursor: Buffer.from(JSON.stringify({ identity, offset: offset + consumed, skip, derived, calls, missing: missing2 || truncated })).toString("base64url"), coverage: missing2 || truncated || offset + consumed < info.size ? "partial" : "complete", bytes, sourceVersion: identity };
33757
33759
  } finally {
33758
33760
  await handle.close();
33759
33761
  }
@@ -33761,7 +33763,7 @@ var AnalysisEvidenceReader = class {
33761
33763
  };
33762
33764
 
33763
33765
  // app-server/src/index.ts
33764
- var import_node_path20 = __toESM(require("node:path"), 1);
33766
+ var import_node_path23 = __toESM(require("node:path"), 1);
33765
33767
 
33766
33768
  // app-server/src/agents/supervision-reader.ts
33767
33769
  var import_node_fs3 = require("node:fs");
@@ -33836,9 +33838,9 @@ var SemanticJsonStream = class {
33836
33838
  ] : [];
33837
33839
  }
33838
33840
  selected(parts) {
33839
- const path21 = parts.join(".");
33841
+ const path24 = parts.join(".");
33840
33842
  return /^(type|timestamp|payload\.(type|id|role|phase|channel|turn_id|turnId|content)|payload\.content\.\d+\.(type|text)|payload\.error\.(message|codex_error_info))$/.test(
33841
- path21
33843
+ path24
33842
33844
  );
33843
33845
  }
33844
33846
  put(parts, value) {
@@ -34403,12 +34405,13 @@ var SupervisionConversationReader = class {
34403
34405
 
34404
34406
  // app-server/src/agents/conversation-reader.ts
34405
34407
  var ConversationReader = class {
34406
- constructor(codex, pi, trae, supervision, analysis) {
34408
+ constructor(codex, pi, trae, supervision, analysis, claude) {
34407
34409
  this.codex = codex;
34408
34410
  this.pi = pi;
34409
34411
  this.trae = trae;
34410
34412
  this.supervision = supervision;
34411
34413
  this.analysis = analysis;
34414
+ this.claude = claude;
34412
34415
  }
34413
34416
  async readAnalysis(thread, cursor) {
34414
34417
  if (thread.agent !== "codex" || !this.analysis) return { events: [], nextCursor: cursor ?? "", coverage: "unavailable", bytes: 0 };
@@ -34419,11 +34422,12 @@ var ConversationReader = class {
34419
34422
  if (!this.supervision) throw new ConversationReadError(503, "SUPERVISION_READER_UNAVAILABLE", "\u76D1\u63A7\u8BFB\u53D6\u670D\u52A1\u5C1A\u672A\u521D\u59CB\u5316");
34420
34423
  return this.supervision.read(thread.threadId, requiredIds);
34421
34424
  }
34422
- // Codex and Trae verify controlled sources; Pi needs its registered file context.
34425
+ // Claude, Codex and Trae verify controlled sources; Pi needs its registered file context.
34423
34426
  async read(thread, signal) {
34424
34427
  const isTrae = ["trae", "traecli", "traex"].includes(thread.agent);
34425
- const supported = thread.agent === "codex" || thread.agent === "pi" || isTrae;
34426
- const content = thread.agent === "codex" ? await this.codex.read(thread.threadId, signal) : thread.agent === "pi" ? await this.pi.readConversation(thread, signal) : isTrae ? await this.trae.read(thread.threadId, signal) : null;
34428
+ const supported = thread.agent === "codex" || thread.agent === "pi" || thread.agent === "claude" || isTrae;
34429
+ if (thread.agent === "claude" && !this.claude) throw new ConversationReadError(503, "CLAUDE_READER_UNAVAILABLE", "Claude \u4F1A\u8BDD\u8BFB\u53D6\u670D\u52A1\u5C1A\u672A\u521D\u59CB\u5316");
34430
+ const content = thread.agent === "codex" ? await this.codex.read(thread.threadId, signal) : thread.agent === "pi" ? await this.pi.readConversation(thread, signal) : thread.agent === "claude" ? await this.claude.read(thread, signal) : isTrae ? await this.trae.read(thread.threadId, signal) : null;
34427
34431
  const response = {
34428
34432
  threadId: thread.threadId,
34429
34433
  provider: thread.agent,
@@ -34538,260 +34542,180 @@ var CodexConversationReader = class {
34538
34542
  }
34539
34543
  };
34540
34544
 
34541
- // packages/config-node/src/context.ts
34542
- var import_node_async_hooks = require("node:async_hooks");
34543
- var import_node_fs5 = require("node:fs");
34544
- var import_node_os = __toESM(require("node:os"), 1);
34545
+ // app-server/src/claude/conversation-reader.ts
34545
34546
  var import_node_path3 = __toESM(require("node:path"), 1);
34546
34547
 
34547
- // packages/config-node/src/errors.ts
34548
- var ConfigurationError = class extends Error {
34549
- constructor(code, fields = [], location) {
34550
- super(`${code}${fields.length ? `: ${fields.join(", ")}` : ""}${location ? ` (line ${location.line}, column ${location.column})` : ""}`);
34551
- this.code = code;
34552
- this.fields = fields;
34553
- this.location = location;
34554
- this.name = "ConfigurationError";
34555
- }
34556
- };
34557
-
34558
- // packages/config-node/src/private-file.ts
34559
- var import_node_fs4 = require("node:fs");
34560
-
34561
- // packages/config-node/src/windows-permissions.ts
34562
- var import_node_child_process = require("node:child_process");
34563
- function assertWindowsPrivatePath(file) {
34564
- if (process.platform !== "win32") return;
34565
- const script = `
34566
- $ErrorActionPreference = 'Stop'
34567
- # Use .NET directly: a parent pwsh may export a PSModulePath incompatible with Windows PowerShell.
34568
- $acl = if ([IO.Directory]::Exists($env:RUNWEAVE_PRIVATE_PATH)) {
34569
- [IO.Directory]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH)
34570
- } else { [IO.File]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH) }
34571
- $sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
34572
- $allowed = @($sid.Value, 'S-1-5-18', 'S-1-5-32-544')
34573
- if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) { throw 'owner' }
34574
- foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
34575
- if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) { throw 'access' }
34576
- }
34577
- `;
34578
- try {
34579
- (0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
34580
- env: { ...process.env, RUNWEAVE_PRIVATE_PATH: file },
34581
- stdio: "ignore",
34582
- timeout: 1e4,
34583
- windowsHide: true
34584
- });
34585
- } catch {
34586
- throw new ConfigurationError("CONFIG_WINDOWS_ACL_NOT_PRIVATE", [file]);
34548
+ // packages/shared/src/app-server/thread-preview.ts
34549
+ function formatThreadPreviewText(value) {
34550
+ if (!value) return null;
34551
+ const text = value.replace(/<oai-mem-citation>[\s\S]*?<\/oai-mem-citation>/g, "").replace(/```[^\n]*\n?/g, "").replace(/!?\[([^\]]*)\]\([^\n]*?\)/g, "$1").replace(/<[^>\n]+>/g, "").replace(/^\s{0,3}(?:#{1,6}\s+|>\s*|[-*+]\s+|\d+[.)]\s+)/gm, "").replace(/(`+)([\s\S]*?)\1/g, "$2").replace(/(\*\*|__|~~)([^\n]+?)\1/g, "$2").replace(/\*([^*\n]+)\*/g, "$1").replace(/(^|\s)_([^_\n]+)_(?=\s|[.,!?,。!?]|$)/g, "$1$2").replace(/\s+/g, " ").trim();
34552
+ if (!text) return null;
34553
+ const characters = [];
34554
+ for (const part of new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(text)) {
34555
+ if (characters.length === 120) return `${characters.join("")}\u2026`;
34556
+ characters.push(part.segment);
34587
34557
  }
34558
+ return text;
34588
34559
  }
34589
34560
 
34590
- // packages/config-node/src/private-file.ts
34591
- function assertPrivateDirectory(directory) {
34592
- const stat3 = (0, import_node_fs4.lstatSync)(directory);
34593
- if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && stat3.mode & 63 || typeof process.getuid === "function" && stat3.uid !== process.getuid()) throw new ConfigurationError("CONFIG_ROOT_PERMISSIONS_INVALID");
34594
- assertWindowsPrivatePath(directory);
34595
- }
34596
- function assertPrivateDescriptor(fd, maxBytes = 1024 * 1024, file) {
34597
- const stat3 = (0, import_node_fs4.fstatSync)(fd);
34598
- if (!stat3.isFile() || stat3.nlink !== 1) throw new ConfigurationError("CONFIG_FILE_NOT_PRIVATE_REGULAR");
34599
- if (typeof process.getuid === "function" && stat3.uid !== process.getuid()) throw new ConfigurationError("CONFIG_FILE_OWNER_MISMATCH");
34600
- if (process.platform !== "win32" && stat3.mode & 63) throw new ConfigurationError("CONFIG_FILE_PERMISSIONS_INVALID");
34601
- if (process.platform === "win32") {
34602
- if (!file) throw new ConfigurationError("CONFIG_PRIVATE_PATH_REQUIRED");
34603
- assertWindowsPrivatePath(file);
34561
+ // app-server/src/claude/conversation-reader.ts
34562
+ var ClaudeConversationReader = class {
34563
+ constructor(sessions) {
34564
+ this.sessions = sessions;
34604
34565
  }
34605
- if (stat3.size > maxBytes) throw new ConfigurationError("CONFIG_FILE_TOO_LARGE");
34606
- }
34607
- function readPrivateFile(file, maxBytes = 1024 * 1024) {
34608
- const fd = (0, import_node_fs4.openSync)(file, import_node_fs4.constants.O_RDONLY | import_node_fs4.constants.O_NOFOLLOW);
34609
- try {
34610
- assertPrivateDescriptor(fd, maxBytes, file);
34611
- const source = (0, import_node_fs4.readFileSync)(fd, "utf8");
34612
- if (Buffer.byteLength(source) > maxBytes) throw new ConfigurationError("CONFIG_FILE_TOO_LARGE");
34613
- return source;
34614
- } finally {
34615
- (0, import_node_fs4.closeSync)(fd);
34566
+ isSourceUnchanged(threadId, signature) {
34567
+ return this.sessions.isUnchanged(threadId, signature);
34616
34568
  }
34617
- }
34618
-
34619
- // packages/config-node/src/context.ts
34620
- var invocationArgumentsKey = Symbol.for("runweave.configuration.invocationArguments");
34621
- var invocationGlobals = globalThis;
34622
- var invocationArguments = invocationGlobals[invocationArgumentsKey] ??= new import_node_async_hooks.AsyncLocalStorage();
34623
- function configurationOption(name, args = invocationArguments.getStore() ?? process.argv.slice(2)) {
34624
- const values = [];
34625
- for (let i = 0; i < args.length; i++) {
34626
- const item = args[i];
34627
- if (item.startsWith(`--${name}=`)) values.push(item.slice(name.length + 3));
34628
- else if (item === `--${name}`) {
34629
- const value = args[++i];
34630
- if (!value || value.startsWith("--")) throw new ConfigurationError("CONFIG_ARGUMENT_REQUIRED", [name]);
34631
- values.push(value);
34632
- }
34633
- }
34634
- if (values.some((value) => !value || value !== values[0])) throw new ConfigurationError("CONFIG_ARGUMENT_CONFLICT", [name]);
34635
- return values[0];
34636
- }
34637
- function canonicalPath(value) {
34638
- const absolute = import_node_path3.default.resolve(value);
34639
- if ((0, import_node_fs5.existsSync)(absolute)) return (0, import_node_fs5.realpathSync)(absolute);
34640
- const parent = import_node_path3.default.dirname(absolute);
34641
- return parent === absolute ? absolute : import_node_path3.default.join(canonicalPath(parent), import_node_path3.default.basename(absolute));
34642
- }
34643
- function resolveConfigurationContext(options = {}) {
34644
- const args = options.args ?? invocationArguments.getStore() ?? process.argv.slice(2);
34645
- const id = configurationOption("instance", args);
34646
- const requestedRoot = configurationOption("config-dir", args);
34647
- if (options.requireExplicit && !id) throw new ConfigurationError("CONFIG_INSTANCE_REQUIRED");
34648
- if (id && !/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(id)) throw new ConfigurationError("CONFIG_INSTANCE_INVALID");
34649
- const devMarker = process.env.RUNWEAVE_DEV_SESSION_ID?.trim();
34650
- if (devMarker && (!id || id === "stable" || id !== devMarker)) throw new ConfigurationError("CONFIG_INSTANCE_CONFLICT");
34651
- const instanceId = id ?? "stable";
34652
- const kind = instanceId === "stable" ? "stable" : "dev";
34653
- const globalRoot = import_node_path3.default.join(options.home ?? import_node_os.default.userInfo().homedir, ".runweave");
34654
- let stableRoot = globalRoot;
34655
- const registry = import_node_path3.default.join(globalRoot, "runtime", "stable-root.json");
34656
- if (kind === "stable" && (0, import_node_fs5.existsSync)(registry)) {
34657
- try {
34658
- assertPrivateDirectory(globalRoot);
34659
- assertPrivateDirectory(import_node_path3.default.dirname(registry));
34660
- const stored = JSON.parse(readPrivateFile(registry));
34661
- if (!stored || typeof stored !== "object" || !("root" in stored) || typeof stored.root !== "string" || !import_node_path3.default.isAbsolute(stored.root)) throw new Error();
34662
- stableRoot = stored.root;
34663
- if (requestedRoot && canonicalPath(requestedRoot) !== canonicalPath(stableRoot)) throw new ConfigurationError("CONFIG_STABLE_ROOT_CONFLICT");
34664
- } catch (error) {
34665
- if (error instanceof ConfigurationError) throw error;
34666
- throw new ConfigurationError("CONFIG_ROOT_REGISTRY_INVALID");
34569
+ async read(thread, signal) {
34570
+ if (thread.agent !== "claude") return null;
34571
+ const nodes = /* @__PURE__ */ new Map();
34572
+ let leaf = null;
34573
+ let valid = false;
34574
+ let partial = false;
34575
+ const result = await this.sessions.scan(thread.threadId, (record2) => {
34576
+ const sessionId = readString(record2.sessionId);
34577
+ if (sessionId && sessionId !== thread.threadId) {
34578
+ throw new ConversationReadError(409, "CLAUDE_SESSION_MISMATCH", "Claude \u4F1A\u8BDD\u8EAB\u4EFD\u4E0D\u5339\u914D");
34579
+ }
34580
+ if (record2.isSidechain === true || record2.agentId || record2.type === "progress") return;
34581
+ if (record2.type === "last-prompt" && sessionId) {
34582
+ const selected = readString(record2.leafUuid);
34583
+ if (selected && selected.length <= 200) leaf = selected;
34584
+ return;
34585
+ }
34586
+ if (!["user", "assistant", "system", "attachment"].includes(String(record2.type))) return;
34587
+ const id = readString(record2.uuid);
34588
+ if (record2.type === "system" && !id) return;
34589
+ if (!sessionId || !id || id.length > 200 || record2.parentUuid !== null && typeof record2.parentUuid !== "string") {
34590
+ partial = true;
34591
+ return;
34592
+ }
34593
+ const cwd = readString(record2.cwd);
34594
+ if (thread.cwd && (!cwd || !import_node_path3.default.isAbsolute(cwd) || import_node_path3.default.resolve(cwd) !== import_node_path3.default.resolve(thread.cwd))) {
34595
+ throw new ConversationReadError(409, "CLAUDE_SESSION_MISMATCH", "Claude \u4F1A\u8BDD\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u5339\u914D");
34596
+ }
34597
+ valid = true;
34598
+ const compactBoundary = record2.type === "system" && record2.subtype === "compact_boundary";
34599
+ const parent = compactBoundary ? readString(record2.logicalParentUuid) ?? readString(record2.parentUuid) : readString(record2.parentUuid);
34600
+ const node = {
34601
+ id,
34602
+ parent,
34603
+ type: String(record2.type),
34604
+ compactBoundary,
34605
+ compactSummary: record2.isCompactSummary === true,
34606
+ ...compactBoundary ? { preserved: readPreservedSegment(record2) } : {}
34607
+ };
34608
+ const message = asRecord(record2.message);
34609
+ if ((record2.type === "user" || record2.type === "assistant") && message?.role === record2.type && record2.isMeta !== true && record2.isCompactSummary !== true && record2.isVisibleInTranscriptOnly !== true && record2.repeatsCompactSummary !== true && !(record2.type === "user" && (record2.toolUseResult != null || Array.isArray(message.content) && message.content.some((part) => asRecord(part)?.type === "tool_result")))) {
34610
+ const text = visibleText(message.content);
34611
+ if (!(record2.type === "user" && isNativeCommandEnvelope(text))) {
34612
+ node.userInput = record2.type === "user";
34613
+ if (text.trim()) node.message = {
34614
+ id,
34615
+ role: record2.type,
34616
+ text,
34617
+ ...typeof record2.timestamp === "string" ? { createdAt: record2.timestamp } : {}
34618
+ };
34619
+ }
34620
+ }
34621
+ const previous = nodes.get(id);
34622
+ if (previous && (previous.parent !== parent || previous.type !== node.type || previous.compactSummary !== node.compactSummary || previous.compactBoundary !== node.compactBoundary || JSON.stringify(previous.preserved) !== JSON.stringify(node.preserved))) {
34623
+ throw new ConversationReadError(422, "CLAUDE_TRANSCRIPT_INVALID", "Claude \u4F1A\u8BDD\u8BB0\u5F55\u5B58\u5728\u51B2\u7A81");
34624
+ }
34625
+ nodes.set(id, node);
34626
+ if (!previous && (record2.type !== "system" || record2.subtype === "compact_boundary")) leaf = id;
34627
+ }, signal);
34628
+ if (!result) return null;
34629
+ if (!valid) {
34630
+ if (result.partial || partial) throw new ConversationReadError(422, "CLAUDE_TRANSCRIPT_INVALID", "Claude \u4F1A\u8BDD\u8BB0\u5F55\u635F\u574F");
34631
+ return null;
34667
34632
  }
34668
- }
34669
- const defaultRoot = kind === "stable" ? stableRoot : import_node_path3.default.join(globalRoot, "dev-sessions", instanceId);
34670
- if (requestedRoot && !import_node_path3.default.isAbsolute(requestedRoot)) throw new ConfigurationError("CONFIG_ROOT_MUST_BE_ABSOLUTE");
34671
- const configRoot = canonicalPath(requestedRoot ?? defaultRoot);
34672
- if (kind === "dev" && (configRoot !== canonicalPath(defaultRoot) || configRoot !== import_node_path3.default.join(canonicalPath(globalRoot), "dev-sessions", instanceId))) throw new ConfigurationError("CONFIG_INSTANCE_ROOT_MISMATCH");
34673
- return { kind, instanceId, configRoot };
34674
- }
34675
- function assertOwnedPath(context, value) {
34676
- if (context.kind === "stable") return;
34677
- const root = canonicalPath(context.configRoot);
34678
- const target = canonicalPath(value);
34679
- const relative = import_node_path3.default.relative(root, target);
34680
- if (!relative || relative === ".." || relative.startsWith(`..${import_node_path3.default.sep}`) || import_node_path3.default.isAbsolute(relative)) {
34681
- throw new ConfigurationError("CONFIG_PATH_OUTSIDE_INSTANCE");
34682
- }
34683
- }
34684
-
34685
- // packages/config-node/src/platform.ts
34686
- var import_node_fs6 = require("node:fs");
34687
- function syncDirectory(directory) {
34688
- if (process.platform === "win32") return;
34689
- const fd = (0, import_node_fs6.openSync)(directory, "r");
34690
- try {
34691
- (0, import_node_fs6.fsyncSync)(fd);
34692
- } finally {
34693
- (0, import_node_fs6.closeSync)(fd);
34694
- }
34695
- }
34696
-
34697
- // packages/config-node/src/owner.ts
34698
- var import_node_fs7 = require("node:fs");
34699
- var import_node_path4 = __toESM(require("node:path"), 1);
34700
- var import_node_os2 = __toESM(require("node:os"), 1);
34701
- var import_node_crypto3 = require("node:crypto");
34702
- var import_fs_native_extensions = require("fs-native-extensions");
34703
- function ownerDirectory(context) {
34704
- const directory = context.kind === "stable" ? import_node_path4.default.join(import_node_os2.default.userInfo().homedir, ".runweave", "runtime") : import_node_path4.default.join(context.configRoot, "runtime");
34705
- (0, import_node_fs7.mkdirSync)(directory, { recursive: true, mode: 448 });
34706
- assertPrivateDirectory(import_node_path4.default.dirname(directory));
34707
- assertPrivateDirectory(directory);
34708
- return directory;
34709
- }
34710
- function registerStableConfigurationRoot(context) {
34711
- if (context.kind !== "stable") return;
34712
- const directory = ownerDirectory(context);
34713
- const registry = import_node_path4.default.join(directory, "stable-root.json");
34714
- const registryFd = (0, import_node_fs7.openSync)(import_node_path4.default.join(directory, "stable-root.lock"), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
34715
- try {
34716
- assertPrivateDescriptor(registryFd, void 0, import_node_path4.default.join(directory, "stable-root.lock"));
34717
- if (!(0, import_fs_native_extensions.tryLock)(registryFd)) throw new ConfigurationError("CONFIG_ROOT_REGISTRATION_BUSY");
34718
- if ((0, import_node_fs7.existsSync)(registry)) {
34719
- let stored;
34720
- try {
34721
- stored = JSON.parse(readPrivateFile(registry));
34722
- } catch {
34723
- throw new ConfigurationError("CONFIG_ROOT_REGISTRY_INVALID");
34633
+ const branch = [];
34634
+ const seen = /* @__PURE__ */ new Set();
34635
+ let cursor = leaf;
34636
+ while (cursor) {
34637
+ if (seen.has(cursor)) throw new ConversationReadError(422, "CLAUDE_TRANSCRIPT_INVALID", "Claude \u4F1A\u8BDD\u5206\u652F\u5B58\u5728\u5FAA\u73AF");
34638
+ seen.add(cursor);
34639
+ const node = nodes.get(cursor);
34640
+ if (!node) {
34641
+ partial = true;
34642
+ break;
34724
34643
  }
34725
- if (!stored || typeof stored !== "object" || !("root" in stored) || stored.root !== canonicalPath(context.configRoot)) throw new ConfigurationError("CONFIG_STABLE_ROOT_CONFLICT");
34726
- } else {
34727
- const temporary = `${registry}.${(0, import_node_crypto3.randomUUID)()}.tmp`;
34728
- const file = (0, import_node_fs7.openSync)(temporary, "wx", 384);
34729
- try {
34730
- (0, import_node_fs7.writeFileSync)(file, JSON.stringify({ root: canonicalPath(context.configRoot) }));
34731
- (0, import_node_fs7.fsyncSync)(file);
34732
- } finally {
34733
- (0, import_node_fs7.closeSync)(file);
34644
+ branch.push(node);
34645
+ cursor = node.parent;
34646
+ if (node.compactBoundary && (!cursor || !nodes.has(cursor))) {
34647
+ cursor = retainedParent(node, nodes) ?? cursor;
34648
+ if (!cursor) partial = true;
34734
34649
  }
34735
- (0, import_node_fs7.renameSync)(temporary, registry);
34736
- syncDirectory(directory);
34737
34650
  }
34738
- } finally {
34739
- (0, import_node_fs7.closeSync)(registryFd);
34651
+ const turns = [];
34652
+ let current;
34653
+ for (const node of branch.reverse()) {
34654
+ if (node.userInput || node.message && !current) {
34655
+ current = { id: node.id, messages: [] };
34656
+ turns.push(current);
34657
+ }
34658
+ if (node.message) current?.messages.push(node.message);
34659
+ }
34660
+ return { ...result, partial: result.partial || partial, turns };
34740
34661
  }
34741
- }
34742
- function withUpgradeGate(context, shared, run) {
34743
- const directory = ownerDirectory(context);
34744
- const fd = (0, import_node_fs7.openSync)(import_node_path4.default.join(directory, "configuration-upgrade.lock"), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
34745
- try {
34746
- assertPrivateDescriptor(fd, void 0, import_node_path4.default.join(directory, "configuration-upgrade.lock"));
34747
- if (!(0, import_fs_native_extensions.tryLock)(fd, 0, 0, { shared })) throw new ConfigurationError("CONFIG_UPGRADE_BUSY");
34748
- return run();
34749
- } finally {
34750
- (0, import_node_fs7.closeSync)(fd);
34662
+ async summary(thread) {
34663
+ const result = await this.read(thread);
34664
+ if (!result) return null;
34665
+ return {
34666
+ provider: "claude",
34667
+ id: thread.threadId,
34668
+ status: "unknown",
34669
+ preview: formatThreadPreviewText(result.turns.at(-1)?.messages.at(-1)?.text),
34670
+ // The shared summary turns require lifecycle status, which transcript text cannot prove.
34671
+ turns: [],
34672
+ lifecycle: [],
34673
+ lastLifecycleCursor: null,
34674
+ sourcePath: null
34675
+ };
34751
34676
  }
34677
+ };
34678
+ function readPreservedSegment(record2) {
34679
+ const metadata = asRecord(record2.compactMetadata);
34680
+ const segment = asRecord(metadata?.preservedSegment);
34681
+ const head = readString(segment?.headUuid), tail = readString(segment?.tailUuid), anchor = readString(segment?.anchorUuid);
34682
+ const messages = asRecord(metadata?.preservedMessages);
34683
+ if (!head || !tail || !anchor || [head, tail, anchor].some((id) => id.length > 200) || messages && readString(messages.anchorUuid) !== anchor) return null;
34684
+ return { head, tail, anchor };
34752
34685
  }
34753
- function withConfigurationUpgradeOwnership(context, run, ignoredRoles = []) {
34754
- return withUpgradeGate(context, false, () => {
34755
- const directory = ownerDirectory(context);
34756
- const held = [];
34757
- try {
34758
- for (const file of (0, import_node_fs7.readdirSync)(directory).filter((name) => name.endsWith(".owner.lock"))) {
34759
- if (ignoredRoles.includes(file.replace(/\.owner\.lock$/, ""))) continue;
34760
- const fd = (0, import_node_fs7.openSync)(import_node_path4.default.join(directory, file), import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW);
34761
- held.push(fd);
34762
- assertPrivateDescriptor(fd, void 0, import_node_path4.default.join(directory, file));
34763
- if (!(0, import_fs_native_extensions.tryLock)(fd)) throw new ConfigurationError("CONFIG_UPGRADE_CONSUMER_RUNNING", [file.replace(/\.owner\.lock$/, "")]);
34764
- }
34765
- return run();
34766
- } finally {
34767
- for (const fd of held) (0, import_node_fs7.closeSync)(fd);
34768
- }
34769
- });
34686
+ function retainedParent(boundary, nodes) {
34687
+ const segment = boundary.preserved;
34688
+ if (!segment) return null;
34689
+ const summary = nodes.get(segment.anchor);
34690
+ if (!summary?.compactSummary || summary.parent !== boundary.id) return null;
34691
+ const seen = /* @__PURE__ */ new Set();
34692
+ for (let cursor = segment.tail; cursor && cursor !== boundary.id && !seen.has(cursor); ) {
34693
+ seen.add(cursor);
34694
+ const node = nodes.get(cursor);
34695
+ if (!node) return null;
34696
+ if (cursor === segment.head) return segment.tail;
34697
+ cursor = node.parent;
34698
+ }
34699
+ return null;
34770
34700
  }
34771
- function acquireConfigurationOwner(context, role) {
34772
- return withUpgradeGate(context, true, () => acquireOwner(context, role));
34701
+ function isNativeCommandEnvelope(text) {
34702
+ const value = text.trim();
34703
+ if (/^<local-command-(stdout|stderr|caveat)>[\s\S]*<\/local-command-\1>$/.test(value)) return true;
34704
+ const prefix = /^<command-name>[^<>\r\n]+<\/command-name>\s*<command-message>/.exec(value);
34705
+ const suffix = "</command-args>";
34706
+ if (!prefix || !value.endsWith(suffix)) return false;
34707
+ return /<\/command-message>\s*<command-args>/.test(value.slice(prefix[0].length, -suffix.length));
34773
34708
  }
34774
- function acquireOwner(context, role) {
34775
- const directory = ownerDirectory(context);
34776
- const fd = (0, import_node_fs7.openSync)(import_node_path4.default.join(directory, `${role}.owner.lock`), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
34777
- let closed = false;
34778
- const release = () => {
34779
- if (!closed) {
34780
- closed = true;
34781
- (0, import_node_fs7.closeSync)(fd);
34782
- }
34783
- };
34784
- try {
34785
- assertPrivateDescriptor(fd, void 0, import_node_path4.default.join(directory, `${role}.owner.lock`));
34786
- if (!(0, import_fs_native_extensions.tryLock)(fd)) throw new ConfigurationError("CONFIG_INSTANCE_ALREADY_RUNNING", [role]);
34787
- registerStableConfigurationRoot(context);
34788
- return { release };
34789
- } catch (error) {
34790
- release();
34791
- throw error;
34792
- }
34709
+ function visibleText(content) {
34710
+ if (typeof content === "string") return content;
34711
+ if (!Array.isArray(content)) return "";
34712
+ return content.map(asRecord).filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
34793
34713
  }
34794
34714
 
34715
+ // packages/config-node/src/claude.ts
34716
+ var import_node_os3 = __toESM(require("node:os"), 1);
34717
+ var import_node_path9 = __toESM(require("node:path"), 1);
34718
+
34795
34719
  // packages/shared/src/configuration/fields.ts
34796
34720
  var CONFIGURATION_FIELDS = [
34797
34721
  { "path": "screenRecording.analysis.enabled", "type": "boolean", "domain": "screenRecording.analysis", "sensitive": false, "remote": false, "apply": "reload", "description": "\u542F\u7528\u672C\u673A\u5C4F\u5E55\u4E8B\u9879\u5206\u6790\uFF0C\u9ED8\u8BA4\u5173\u95ED", "environmentKeys": [], "owner": "backend/screen-recording-analysis", "scope": "instance", "storage": "settings.yaml", "default": { "value": false }, "migrationSources": ["new-field:no-legacy-source"] },
@@ -34850,6 +34774,8 @@ var CONFIGURATION_FIELDS = [
34850
34774
  { "path": "services.feishu.legacyWebhook.transport", "type": "string", "domain": "services.feishu", "sensitive": false, "remote": true, "apply": "restart", "description": "\u65E7\u901A\u77E5 hook \u53D1\u9001\u65B9\u5F0F", "environmentKeys": ["FEISHU_NOTIFY_TRANSPORT"], "owner": "cli/feishu", "scope": "instance", "storage": "settings.yaml", "default": { "value": null }, "migrationSources": ["FEISHU_NOTIFY_TRANSPORT"] },
34851
34775
  { "path": "agents.codex.binary", "type": "string", "domain": "agents.codex", "sensitive": false, "remote": false, "apply": "restart", "description": "Codex \u53EF\u6267\u884C\u6587\u4EF6", "environmentKeys": ["CODEX_BIN", "RUNWEAVE_CODEX_BIN"], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u672A\u6307\u5B9A\u65F6\u901A\u8FC7 PATH / \u5E73\u53F0\u5B89\u88C5\u4F4D\u7F6E\u67E5\u627E codex\uFF1B\u663E\u5F0F\u914D\u7F6E\u6307\u5411\u540C\u4E00\u53EF\u6267\u884C\u7A0B\u5E8F\u3002" }, "migrationSources": ["CODEX_BIN", "RUNWEAVE_CODEX_BIN"] },
34852
34776
  { "path": "agents.traex.binary", "type": "string", "domain": "agents.traex", "sensitive": false, "remote": false, "apply": "restart", "description": "Trae \u53EF\u6267\u884C\u6587\u4EF6\uFF1B\u591A\u4E2A\u5165\u53E3\u7EDF\u4E00", "environmentKeys": ["TRAEX_BIN", "RUNWEAVE_TRAE_BIN"], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u672A\u6307\u5B9A\u65F6\u901A\u8FC7 PATH / \u5E73\u53F0\u5B89\u88C5\u4F4D\u7F6E\u67E5\u627E traex\uFF1B\u663E\u5F0F\u914D\u7F6E\u6307\u5411\u540C\u4E00\u53EF\u6267\u884C\u7A0B\u5E8F\u3002" }, "migrationSources": ["TRAEX_BIN", "RUNWEAVE_TRAE_BIN"] },
34777
+ { "path": "agents.claude.binary", "type": "string", "domain": "agents.claude", "sensitive": false, "remote": false, "apply": "restart", "description": "Claude Code \u53EF\u6267\u884C\u6587\u4EF6\uFF1B\u4EC5\u9650\u7A0B\u5E8F\u540D\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4E0D\u63A5\u53D7\u547D\u4EE4\u53C2\u6570", "environmentKeys": [], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u4F7F\u7528\u5F53\u524D Backend \u7684 PATH \u67E5\u627E claude\uFF1B\u4E0D\u6539\u53D8\u73B0\u6709\u9ED8\u8BA4 provider\u3002" }, "migrationSources": ["new-field:no-legacy-source"] },
34778
+ { "path": "agents.claude.configDirectory", "type": "string", "domain": "agents.claude", "sensitive": false, "remote": false, "apply": "restart", "description": "Claude \u539F\u751F\u914D\u7F6E\u76EE\u5F55\u7684\u5916\u90E8\u5F15\u7528\uFF1B\u4F1A\u8BDD\u6839\u4E3A\u5176 projects \u5B50\u76EE\u5F55\uFF0C\u4E0D\u590D\u5236\u51ED\u636E", "environmentKeys": ["CLAUDE_CONFIG_DIR"], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u663E\u5F0F\u5B9E\u4F8B\u76EE\u5F55\u4F18\u5148\uFF0C\u5426\u5219\u5F15\u7528\u5916\u90E8 CLAUDE_CONFIG_DIR \u6216\u64CD\u4F5C\u7CFB\u7EDF\u7528\u6237\u76EE\u5F55\u4E0B .claude\uFF1B\u5FC5\u987B\u4E3A\u7EDD\u5BF9\u8DEF\u5F84\u3002" }, "migrationSources": ["CLAUDE_CONFIG_DIR"] },
34853
34779
  { "path": "agents.companion.binary", "type": "string", "domain": "agents.companion", "sensitive": false, "remote": false, "apply": "restart", "description": "\u4F34\u968F\u7A97\u53E3 Agent \u53EF\u6267\u884C\u6587\u4EF6", "environmentKeys": ["RUNWEAVE_COMPANION_AGENT_EXECUTABLE"], "owner": "electron/companion", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u4F7F\u7528\u5DF2\u5B89\u88C5 Codex App \u81EA\u5E26\u6267\u884C\u5165\u53E3\uFF1B\u663E\u5F0F\u503C\u5FC5\u987B\u53EF\u6267\u884C\u3002" }, "migrationSources": ["RUNWEAVE_COMPANION_AGENT_EXECUTABLE"] },
34854
34780
  { "path": "agents.codex.sessionsDirectory", "type": "string", "domain": "agents.codex", "sensitive": false, "remote": false, "apply": "restart", "description": "\u5916\u90E8 Codex \u4F1A\u8BDD\u76EE\u5F55\u5F15\u7528", "environmentKeys": ["RUNWEAVE_CODEX_SESSIONS_DIR"], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u5916\u90E8\u5DE5\u5177\u62E5\u6709\u7684 CODEX_HOME/sessions \u6216\u64CD\u4F5C\u7CFB\u7EDF\u7528\u6237\u76EE\u5F55\u4E0B .codex/sessions\uFF0C\u4EC5\u5F15\u7528\u3002" }, "migrationSources": ["RUNWEAVE_CODEX_SESSIONS_DIR"] },
34855
34781
  { "path": "agents.traex.sessionsDirectory", "type": "string", "domain": "agents.traex", "sensitive": false, "remote": false, "apply": "restart", "description": "\u5916\u90E8 Trae \u4F1A\u8BDD\u76EE\u5F55\u5F15\u7528", "environmentKeys": ["RUNWEAVE_TRAE_SESSIONS_DIR"], "owner": "backend+app-server", "scope": "instance", "storage": "settings.yaml", "default": { "rule": "\u64CD\u4F5C\u7CFB\u7EDF\u7528\u6237\u76EE\u5F55\u4E0B .trae/cli/sessions\uFF0C\u4EC5\u5F15\u7528\u3002" }, "migrationSources": ["RUNWEAVE_TRAE_SESSIONS_DIR"] },
@@ -34977,7 +34903,7 @@ var CONFIGURATION_COMPATIBILITY = {
34977
34903
  };
34978
34904
  var APP_SERVER_CONFIGURATION_COMPATIBILITY = {
34979
34905
  ...CONFIGURATION_COMPATIBILITY,
34980
- domainVersions: Object.fromEntries(["appServer", "agents.codex", "agents.traex"].map((domain) => [domain, [CONFIGURATION_DOMAIN_VERSIONS[domain]]]))
34906
+ domainVersions: Object.fromEntries(["appServer", "agents.codex", "agents.traex", "agents.claude"].map((domain) => [domain, [CONFIGURATION_DOMAIN_VERSIONS[domain]]]))
34981
34907
  };
34982
34908
  function supportsConfiguration(target, value) {
34983
34909
  if (!target || typeof target !== "object") return false;
@@ -35053,6 +34979,262 @@ function configurationPathSegment(key) {
35053
34979
  return key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
35054
34980
  }
35055
34981
 
34982
+ // packages/config-node/src/platform.ts
34983
+ var import_node_fs4 = require("node:fs");
34984
+ function syncDirectory(directory) {
34985
+ if (process.platform === "win32") return;
34986
+ const fd = (0, import_node_fs4.openSync)(directory, "r");
34987
+ try {
34988
+ (0, import_node_fs4.fsyncSync)(fd);
34989
+ } finally {
34990
+ (0, import_node_fs4.closeSync)(fd);
34991
+ }
34992
+ }
34993
+
34994
+ // packages/config-node/src/owner.ts
34995
+ var import_node_fs7 = require("node:fs");
34996
+ var import_node_path5 = __toESM(require("node:path"), 1);
34997
+ var import_node_os2 = __toESM(require("node:os"), 1);
34998
+ var import_node_crypto3 = require("node:crypto");
34999
+ var import_fs_native_extensions = require("fs-native-extensions");
35000
+
35001
+ // packages/config-node/src/errors.ts
35002
+ var ConfigurationError = class extends Error {
35003
+ constructor(code, fields = [], location) {
35004
+ super(`${code}${fields.length ? `: ${fields.join(", ")}` : ""}${location ? ` (line ${location.line}, column ${location.column})` : ""}`);
35005
+ this.code = code;
35006
+ this.fields = fields;
35007
+ this.location = location;
35008
+ this.name = "ConfigurationError";
35009
+ }
35010
+ };
35011
+
35012
+ // packages/config-node/src/context.ts
35013
+ var import_node_async_hooks = require("node:async_hooks");
35014
+ var import_node_fs6 = require("node:fs");
35015
+ var import_node_os = __toESM(require("node:os"), 1);
35016
+ var import_node_path4 = __toESM(require("node:path"), 1);
35017
+
35018
+ // packages/config-node/src/private-file.ts
35019
+ var import_node_fs5 = require("node:fs");
35020
+
35021
+ // packages/config-node/src/windows-permissions.ts
35022
+ var import_node_child_process = require("node:child_process");
35023
+ function assertWindowsPrivatePath(file) {
35024
+ if (process.platform !== "win32") return;
35025
+ const script = `
35026
+ $ErrorActionPreference = 'Stop'
35027
+ # Use .NET directly: a parent pwsh may export a PSModulePath incompatible with Windows PowerShell.
35028
+ $acl = if ([IO.Directory]::Exists($env:RUNWEAVE_PRIVATE_PATH)) {
35029
+ [IO.Directory]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH)
35030
+ } else { [IO.File]::GetAccessControl($env:RUNWEAVE_PRIVATE_PATH) }
35031
+ $sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
35032
+ $allowed = @($sid.Value, 'S-1-5-18', 'S-1-5-32-544')
35033
+ if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -notin $allowed) { throw 'owner' }
35034
+ foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
35035
+ if ($rule.AccessControlType -eq 'Allow' -and $rule.IdentityReference.Value -notin $allowed) { throw 'access' }
35036
+ }
35037
+ `;
35038
+ try {
35039
+ (0, import_node_child_process.execFileSync)("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], {
35040
+ env: { ...process.env, RUNWEAVE_PRIVATE_PATH: file },
35041
+ stdio: "ignore",
35042
+ timeout: 1e4,
35043
+ windowsHide: true
35044
+ });
35045
+ } catch {
35046
+ throw new ConfigurationError("CONFIG_WINDOWS_ACL_NOT_PRIVATE", [file]);
35047
+ }
35048
+ }
35049
+
35050
+ // packages/config-node/src/private-file.ts
35051
+ function assertPrivateDirectory(directory) {
35052
+ const stat3 = (0, import_node_fs5.lstatSync)(directory);
35053
+ if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && stat3.mode & 63 || typeof process.getuid === "function" && stat3.uid !== process.getuid()) throw new ConfigurationError("CONFIG_ROOT_PERMISSIONS_INVALID");
35054
+ assertWindowsPrivatePath(directory);
35055
+ }
35056
+ function assertPrivateDescriptor(fd, maxBytes = 1024 * 1024, file) {
35057
+ const stat3 = (0, import_node_fs5.fstatSync)(fd);
35058
+ if (!stat3.isFile() || stat3.nlink !== 1) throw new ConfigurationError("CONFIG_FILE_NOT_PRIVATE_REGULAR");
35059
+ if (typeof process.getuid === "function" && stat3.uid !== process.getuid()) throw new ConfigurationError("CONFIG_FILE_OWNER_MISMATCH");
35060
+ if (process.platform !== "win32" && stat3.mode & 63) throw new ConfigurationError("CONFIG_FILE_PERMISSIONS_INVALID");
35061
+ if (process.platform === "win32") {
35062
+ if (!file) throw new ConfigurationError("CONFIG_PRIVATE_PATH_REQUIRED");
35063
+ assertWindowsPrivatePath(file);
35064
+ }
35065
+ if (stat3.size > maxBytes) throw new ConfigurationError("CONFIG_FILE_TOO_LARGE");
35066
+ }
35067
+ function readPrivateFile(file, maxBytes = 1024 * 1024) {
35068
+ const fd = (0, import_node_fs5.openSync)(file, import_node_fs5.constants.O_RDONLY | import_node_fs5.constants.O_NOFOLLOW);
35069
+ try {
35070
+ assertPrivateDescriptor(fd, maxBytes, file);
35071
+ const source = (0, import_node_fs5.readFileSync)(fd, "utf8");
35072
+ if (Buffer.byteLength(source) > maxBytes) throw new ConfigurationError("CONFIG_FILE_TOO_LARGE");
35073
+ return source;
35074
+ } finally {
35075
+ (0, import_node_fs5.closeSync)(fd);
35076
+ }
35077
+ }
35078
+
35079
+ // packages/config-node/src/context.ts
35080
+ var invocationArgumentsKey = Symbol.for("runweave.configuration.invocationArguments");
35081
+ var invocationGlobals = globalThis;
35082
+ var invocationArguments = invocationGlobals[invocationArgumentsKey] ??= new import_node_async_hooks.AsyncLocalStorage();
35083
+ function configurationOption(name, args = invocationArguments.getStore() ?? process.argv.slice(2)) {
35084
+ const values = [];
35085
+ for (let i = 0; i < args.length; i++) {
35086
+ const item = args[i];
35087
+ if (item.startsWith(`--${name}=`)) values.push(item.slice(name.length + 3));
35088
+ else if (item === `--${name}`) {
35089
+ const value = args[++i];
35090
+ if (!value || value.startsWith("--")) throw new ConfigurationError("CONFIG_ARGUMENT_REQUIRED", [name]);
35091
+ values.push(value);
35092
+ }
35093
+ }
35094
+ if (values.some((value) => !value || value !== values[0])) throw new ConfigurationError("CONFIG_ARGUMENT_CONFLICT", [name]);
35095
+ return values[0];
35096
+ }
35097
+ function canonicalPath(value) {
35098
+ const absolute = import_node_path4.default.resolve(value);
35099
+ if ((0, import_node_fs6.existsSync)(absolute)) return (0, import_node_fs6.realpathSync)(absolute);
35100
+ const parent = import_node_path4.default.dirname(absolute);
35101
+ return parent === absolute ? absolute : import_node_path4.default.join(canonicalPath(parent), import_node_path4.default.basename(absolute));
35102
+ }
35103
+ function resolveConfigurationContext(options = {}) {
35104
+ const args = options.args ?? invocationArguments.getStore() ?? process.argv.slice(2);
35105
+ const id = configurationOption("instance", args);
35106
+ const requestedRoot = configurationOption("config-dir", args);
35107
+ if (options.requireExplicit && !id) throw new ConfigurationError("CONFIG_INSTANCE_REQUIRED");
35108
+ if (id && !/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(id)) throw new ConfigurationError("CONFIG_INSTANCE_INVALID");
35109
+ const devMarker = process.env.RUNWEAVE_DEV_SESSION_ID?.trim();
35110
+ if (devMarker && (!id || id === "stable" || id !== devMarker)) throw new ConfigurationError("CONFIG_INSTANCE_CONFLICT");
35111
+ const instanceId = id ?? "stable";
35112
+ const kind = instanceId === "stable" ? "stable" : "dev";
35113
+ const globalRoot = import_node_path4.default.join(options.home ?? import_node_os.default.userInfo().homedir, ".runweave");
35114
+ let stableRoot = globalRoot;
35115
+ const registry = import_node_path4.default.join(globalRoot, "runtime", "stable-root.json");
35116
+ if (kind === "stable" && (0, import_node_fs6.existsSync)(registry)) {
35117
+ try {
35118
+ assertPrivateDirectory(globalRoot);
35119
+ assertPrivateDirectory(import_node_path4.default.dirname(registry));
35120
+ const stored = JSON.parse(readPrivateFile(registry));
35121
+ if (!stored || typeof stored !== "object" || !("root" in stored) || typeof stored.root !== "string" || !import_node_path4.default.isAbsolute(stored.root)) throw new Error();
35122
+ stableRoot = stored.root;
35123
+ if (requestedRoot && canonicalPath(requestedRoot) !== canonicalPath(stableRoot)) throw new ConfigurationError("CONFIG_STABLE_ROOT_CONFLICT");
35124
+ } catch (error) {
35125
+ if (error instanceof ConfigurationError) throw error;
35126
+ throw new ConfigurationError("CONFIG_ROOT_REGISTRY_INVALID");
35127
+ }
35128
+ }
35129
+ const defaultRoot = kind === "stable" ? stableRoot : import_node_path4.default.join(globalRoot, "dev-sessions", instanceId);
35130
+ if (requestedRoot && !import_node_path4.default.isAbsolute(requestedRoot)) throw new ConfigurationError("CONFIG_ROOT_MUST_BE_ABSOLUTE");
35131
+ const configRoot = canonicalPath(requestedRoot ?? defaultRoot);
35132
+ if (kind === "dev" && (configRoot !== canonicalPath(defaultRoot) || configRoot !== import_node_path4.default.join(canonicalPath(globalRoot), "dev-sessions", instanceId))) throw new ConfigurationError("CONFIG_INSTANCE_ROOT_MISMATCH");
35133
+ return { kind, instanceId, configRoot };
35134
+ }
35135
+ function assertOwnedPath(context, value) {
35136
+ if (context.kind === "stable") return;
35137
+ const root = canonicalPath(context.configRoot);
35138
+ const target = canonicalPath(value);
35139
+ const relative = import_node_path4.default.relative(root, target);
35140
+ if (!relative || relative === ".." || relative.startsWith(`..${import_node_path4.default.sep}`) || import_node_path4.default.isAbsolute(relative)) {
35141
+ throw new ConfigurationError("CONFIG_PATH_OUTSIDE_INSTANCE");
35142
+ }
35143
+ }
35144
+
35145
+ // packages/config-node/src/owner.ts
35146
+ function ownerDirectory(context) {
35147
+ const directory = context.kind === "stable" ? import_node_path5.default.join(import_node_os2.default.userInfo().homedir, ".runweave", "runtime") : import_node_path5.default.join(context.configRoot, "runtime");
35148
+ (0, import_node_fs7.mkdirSync)(directory, { recursive: true, mode: 448 });
35149
+ assertPrivateDirectory(import_node_path5.default.dirname(directory));
35150
+ assertPrivateDirectory(directory);
35151
+ return directory;
35152
+ }
35153
+ function registerStableConfigurationRoot(context) {
35154
+ if (context.kind !== "stable") return;
35155
+ const directory = ownerDirectory(context);
35156
+ const registry = import_node_path5.default.join(directory, "stable-root.json");
35157
+ const registryFd = (0, import_node_fs7.openSync)(import_node_path5.default.join(directory, "stable-root.lock"), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
35158
+ try {
35159
+ assertPrivateDescriptor(registryFd, void 0, import_node_path5.default.join(directory, "stable-root.lock"));
35160
+ if (!(0, import_fs_native_extensions.tryLock)(registryFd)) throw new ConfigurationError("CONFIG_ROOT_REGISTRATION_BUSY");
35161
+ if ((0, import_node_fs7.existsSync)(registry)) {
35162
+ let stored;
35163
+ try {
35164
+ stored = JSON.parse(readPrivateFile(registry));
35165
+ } catch {
35166
+ throw new ConfigurationError("CONFIG_ROOT_REGISTRY_INVALID");
35167
+ }
35168
+ if (!stored || typeof stored !== "object" || !("root" in stored) || stored.root !== canonicalPath(context.configRoot)) throw new ConfigurationError("CONFIG_STABLE_ROOT_CONFLICT");
35169
+ } else {
35170
+ const temporary = `${registry}.${(0, import_node_crypto3.randomUUID)()}.tmp`;
35171
+ const file = (0, import_node_fs7.openSync)(temporary, "wx", 384);
35172
+ try {
35173
+ (0, import_node_fs7.writeFileSync)(file, JSON.stringify({ root: canonicalPath(context.configRoot) }));
35174
+ (0, import_node_fs7.fsyncSync)(file);
35175
+ } finally {
35176
+ (0, import_node_fs7.closeSync)(file);
35177
+ }
35178
+ (0, import_node_fs7.renameSync)(temporary, registry);
35179
+ syncDirectory(directory);
35180
+ }
35181
+ } finally {
35182
+ (0, import_node_fs7.closeSync)(registryFd);
35183
+ }
35184
+ }
35185
+ function withUpgradeGate(context, shared, run) {
35186
+ const directory = ownerDirectory(context);
35187
+ const fd = (0, import_node_fs7.openSync)(import_node_path5.default.join(directory, "configuration-upgrade.lock"), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
35188
+ try {
35189
+ assertPrivateDescriptor(fd, void 0, import_node_path5.default.join(directory, "configuration-upgrade.lock"));
35190
+ if (!(0, import_fs_native_extensions.tryLock)(fd, 0, 0, { shared })) throw new ConfigurationError("CONFIG_UPGRADE_BUSY");
35191
+ return run();
35192
+ } finally {
35193
+ (0, import_node_fs7.closeSync)(fd);
35194
+ }
35195
+ }
35196
+ function withConfigurationUpgradeOwnership(context, run, ignoredRoles = []) {
35197
+ return withUpgradeGate(context, false, () => {
35198
+ const directory = ownerDirectory(context);
35199
+ const held = [];
35200
+ try {
35201
+ for (const file of (0, import_node_fs7.readdirSync)(directory).filter((name) => name.endsWith(".owner.lock"))) {
35202
+ if (ignoredRoles.includes(file.replace(/\.owner\.lock$/, ""))) continue;
35203
+ const fd = (0, import_node_fs7.openSync)(import_node_path5.default.join(directory, file), import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW);
35204
+ held.push(fd);
35205
+ assertPrivateDescriptor(fd, void 0, import_node_path5.default.join(directory, file));
35206
+ if (!(0, import_fs_native_extensions.tryLock)(fd)) throw new ConfigurationError("CONFIG_UPGRADE_CONSUMER_RUNNING", [file.replace(/\.owner\.lock$/, "")]);
35207
+ }
35208
+ return run();
35209
+ } finally {
35210
+ for (const fd of held) (0, import_node_fs7.closeSync)(fd);
35211
+ }
35212
+ });
35213
+ }
35214
+ function acquireConfigurationOwner(context, role) {
35215
+ return withUpgradeGate(context, true, () => acquireOwner(context, role));
35216
+ }
35217
+ function acquireOwner(context, role) {
35218
+ const directory = ownerDirectory(context);
35219
+ const fd = (0, import_node_fs7.openSync)(import_node_path5.default.join(directory, `${role}.owner.lock`), import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_RDWR | import_node_fs7.constants.O_NOFOLLOW, 384);
35220
+ let closed = false;
35221
+ const release = () => {
35222
+ if (!closed) {
35223
+ closed = true;
35224
+ (0, import_node_fs7.closeSync)(fd);
35225
+ }
35226
+ };
35227
+ try {
35228
+ assertPrivateDescriptor(fd, void 0, import_node_path5.default.join(directory, `${role}.owner.lock`));
35229
+ if (!(0, import_fs_native_extensions.tryLock)(fd)) throw new ConfigurationError("CONFIG_INSTANCE_ALREADY_RUNNING", [role]);
35230
+ registerStableConfigurationRoot(context);
35231
+ return { release };
35232
+ } catch (error) {
35233
+ release();
35234
+ throw error;
35235
+ }
35236
+ }
35237
+
35056
35238
  // packages/config-node/src/version-migrations.ts
35057
35239
  var CONFIGURATION_VERSION_MIGRATIONS = [];
35058
35240
  function migrateConfigurationDocument(document2) {
@@ -35108,13 +35290,13 @@ function migrateConfigurationDocument(document2) {
35108
35290
 
35109
35291
  // packages/config-node/src/store.ts
35110
35292
  var import_node_fs8 = require("node:fs");
35111
- var import_node_path6 = __toESM(require("node:path"), 1);
35293
+ var import_node_path7 = __toESM(require("node:path"), 1);
35112
35294
  var import_node_crypto4 = require("node:crypto");
35113
35295
  var import_yaml = __toESM(require_dist(), 1);
35114
35296
  var import_fs_native_extensions2 = require("fs-native-extensions");
35115
35297
 
35116
35298
  // packages/config-node/src/validation.ts
35117
- var import_node_path5 = __toESM(require("node:path"), 1);
35299
+ var import_node_path6 = __toESM(require("node:path"), 1);
35118
35300
  var patterns = CONFIGURATION_FIELDS.map((field) => ({ field, segments: field.path.replace(/\[\]/g, ".#").split(".") }));
35119
35301
  function segmentMatches(pattern, value) {
35120
35302
  return pattern === value || /^<[^>]+>$/.test(pattern) && value.length > 0 || pattern === "#" && /^\d+$/.test(value);
@@ -35178,8 +35360,10 @@ function validateDomains(value, context) {
35178
35360
  continue;
35179
35361
  }
35180
35362
  if (["backend.taskSupervision.model", "terminal.defaultShell.command"].includes(key) && typeof entry === "string" && !entry.trim()) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35181
- if (key === "terminal.defaultShell.command" && typeof entry === "string" && /[\\/]/.test(entry) && !import_node_path5.default.isAbsolute(entry.trim())) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35363
+ if (key === "terminal.defaultShell.command" && typeof entry === "string" && /[\\/]/.test(entry) && !import_node_path6.default.isAbsolute(entry.trim())) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35182
35364
  if (key.startsWith("terminal.defaultShell.") && (typeof entry === "string" ? entry.includes("\0") : Array.isArray(entry) && entry.some((item) => typeof item === "string" && item.includes("\0")))) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35365
+ if (key === "agents.claude.binary" && typeof entry === "string" && (!entry.trim() || entry !== entry.trim() || [...entry].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127) || !import_node_path6.default.isAbsolute(entry) && !/^[A-Za-z0-9_][A-Za-z0-9_.+-]*$/.test(entry))) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35366
+ if (key === "agents.claude.configDirectory" && typeof entry === "string" && (!import_node_path6.default.isAbsolute(entry) || [...entry].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127))) issue(key, "CONFIG_FIELD_VALUE_INVALID");
35183
35367
  if (CONFIGURATION_ENUMS[key] && !CONFIGURATION_ENUMS[key].includes(String(entry))) issue(key, "CONFIG_FIELD_ENUM_INVALID");
35184
35368
  if (configurationServiceOrigin(key) && typeof entry === "string") {
35185
35369
  try {
@@ -35203,7 +35387,7 @@ function validateDomains(value, context) {
35203
35387
  const mutablePath = configurationOwnedPath(key);
35204
35388
  if (typeof entry === "string" && mutablePath) {
35205
35389
  try {
35206
- if (!import_node_path5.default.isAbsolute(entry)) throw new Error();
35390
+ if (!import_node_path6.default.isAbsolute(entry)) throw new Error();
35207
35391
  assertOwnedPath(context, entry);
35208
35392
  } catch {
35209
35393
  issue(key, "CONFIG_PATH_OUTSIDE_INSTANCE");
@@ -35213,8 +35397,8 @@ function validateDomains(value, context) {
35213
35397
  for (const [domain, keys] of Object.entries(CONFIGURATION_CREDENTIAL_GROUPS)) {
35214
35398
  const fields = keys.map((key) => readConfigurationPath(value, `${domain}.${key}`));
35215
35399
  if (fields.some((entry) => entry !== null && entry !== void 0)) {
35216
- const missing = fields.findIndex((entry) => typeof entry !== "string" || !entry.trim());
35217
- if (missing >= 0) issue(`${domain}.${keys[missing]}`, "CONFIG_CREDENTIAL_GROUP_INCOMPLETE");
35400
+ const missing2 = fields.findIndex((entry) => typeof entry !== "string" || !entry.trim());
35401
+ if (missing2 >= 0) issue(`${domain}.${keys[missing2]}`, "CONFIG_CREDENTIAL_GROUP_INCOMPLETE");
35218
35402
  }
35219
35403
  }
35220
35404
  const feishuRole = readConfigurationPath(value, "services.feishu.role") ?? "standalone";
@@ -35313,7 +35497,7 @@ function assertPrivateFile(file, fd) {
35313
35497
  var ConfigurationStore = class {
35314
35498
  constructor(context) {
35315
35499
  this.context = context;
35316
- this.file = import_node_path6.default.join(context.configRoot, "settings.yaml");
35500
+ this.file = import_node_path7.default.join(context.configRoot, "settings.yaml");
35317
35501
  }
35318
35502
  file;
35319
35503
  read() {
@@ -35333,9 +35517,9 @@ var ConfigurationStore = class {
35333
35517
  const dirStat = (0, import_node_fs8.lstatSync)(this.context.configRoot);
35334
35518
  if (!dirStat.isDirectory() || dirStat.isSymbolicLink() || typeof process.getuid === "function" && dirStat.uid !== process.getuid()) throw new ConfigurationError("CONFIG_ROOT_OWNER_MISMATCH");
35335
35519
  assertPrivateDirectory(this.context.configRoot);
35336
- const fd = (0, import_node_fs8.openSync)(import_node_path6.default.join(this.context.configRoot, "settings.lock"), import_node_fs8.constants.O_CREAT | import_node_fs8.constants.O_RDWR | import_node_fs8.constants.O_NOFOLLOW, 384);
35520
+ const fd = (0, import_node_fs8.openSync)(import_node_path7.default.join(this.context.configRoot, "settings.lock"), import_node_fs8.constants.O_CREAT | import_node_fs8.constants.O_RDWR | import_node_fs8.constants.O_NOFOLLOW, 384);
35337
35521
  try {
35338
- assertPrivateFile(import_node_path6.default.join(this.context.configRoot, "settings.lock"), fd);
35522
+ assertPrivateFile(import_node_path7.default.join(this.context.configRoot, "settings.lock"), fd);
35339
35523
  if (!(0, import_fs_native_extensions2.tryLock)(fd)) throw new ConfigurationError("CONFIG_WRITE_BUSY");
35340
35524
  return run();
35341
35525
  } finally {
@@ -35348,10 +35532,10 @@ var ConfigurationStore = class {
35348
35532
  registerStableConfigurationRoot(this.context);
35349
35533
  const temporary = `${this.file}.${(0, import_node_crypto4.randomUUID)()}.tmp`;
35350
35534
  if (previous !== void 0) {
35351
- const backupRoot = import_node_path6.default.join(this.context.configRoot, "config-backups");
35535
+ const backupRoot = import_node_path7.default.join(this.context.configRoot, "config-backups");
35352
35536
  (0, import_node_fs8.mkdirSync)(backupRoot, { recursive: true, mode: 448 });
35353
35537
  assertPrivateDirectory(backupRoot);
35354
- const backup = import_node_path6.default.join(backupRoot, backupId ?? `${Date.now()}-${(0, import_node_crypto4.randomUUID)()}.yaml`);
35538
+ const backup = import_node_path7.default.join(backupRoot, backupId ?? `${Date.now()}-${(0, import_node_crypto4.randomUUID)()}.yaml`);
35355
35539
  const fd2 = (0, import_node_fs8.openSync)(backup, "wx", 384);
35356
35540
  try {
35357
35541
  (0, import_node_fs8.writeFileSync)(fd2, previous);
@@ -35416,7 +35600,7 @@ var ConfigurationStore = class {
35416
35600
  });
35417
35601
  }
35418
35602
  backups() {
35419
- const root = import_node_path6.default.join(this.context.configRoot, "config-backups");
35603
+ const root = import_node_path7.default.join(this.context.configRoot, "config-backups");
35420
35604
  if (!(0, import_node_fs8.existsSync)(root)) return [];
35421
35605
  assertPrivateDirectory(root);
35422
35606
  return (0, import_node_fs8.readdirSync)(root).filter((id) => /^\d+-[a-f0-9-]+\.yaml$/.test(id)).sort().reverse().map((id) => {
@@ -35430,9 +35614,9 @@ var ConfigurationStore = class {
35430
35614
  }
35431
35615
  readBackup(id) {
35432
35616
  if (!/^\d+-[a-f0-9-]+\.yaml$/.test(id)) throw new ConfigurationError("CONFIG_BACKUP_ID_INVALID");
35433
- const root = import_node_path6.default.join(this.context.configRoot, "config-backups");
35617
+ const root = import_node_path7.default.join(this.context.configRoot, "config-backups");
35434
35618
  assertPrivateDirectory(root);
35435
- const backup = parseConfigurationYaml(readPrivateFile(import_node_path6.default.join(root, id)), this.context);
35619
+ const backup = parseConfigurationYaml(readPrivateFile(import_node_path7.default.join(root, id)), this.context);
35436
35620
  if (Object.keys(backup.issues).length || !supportsConfiguration(CONFIGURATION_COMPATIBILITY, backup.value)) throw new ConfigurationError("CONFIG_BACKUP_INCOMPATIBLE");
35437
35621
  return backup;
35438
35622
  }
@@ -35495,7 +35679,7 @@ var ConfigurationStore = class {
35495
35679
  return this.prepareUpgrade().preview;
35496
35680
  }
35497
35681
  recordUpgrade(value) {
35498
- const file = import_node_path6.default.join(this.context.configRoot, "config-upgrade.json");
35682
+ const file = import_node_path7.default.join(this.context.configRoot, "config-upgrade.json");
35499
35683
  const temporary = `${file}.${(0, import_node_crypto4.randomUUID)()}.tmp`;
35500
35684
  const fd = (0, import_node_fs8.openSync)(temporary, "wx", 384);
35501
35685
  try {
@@ -35516,7 +35700,7 @@ var ConfigurationStore = class {
35516
35700
  const { source, document: document2, preview } = this.prepareUpgrade();
35517
35701
  if (preview.expectedRevision !== expected.revision || preview.expectedDigest !== expected.digest) throw new ConfigurationError("CONFIG_REVISION_CONFLICT");
35518
35702
  if (!preview.changed) {
35519
- const receiptFile = import_node_path6.default.join(this.context.configRoot, "config-upgrade.json");
35703
+ const receiptFile = import_node_path7.default.join(this.context.configRoot, "config-upgrade.json");
35520
35704
  if ((0, import_node_fs8.existsSync)(receiptFile)) {
35521
35705
  const receipt = JSON.parse(readPrivateFile(receiptFile));
35522
35706
  if (isConfigurationObject(receipt) && receipt.phase === "prepared" && receipt.plannedDigest === expected.digest)
@@ -35550,12 +35734,12 @@ var ConfigurationStore = class {
35550
35734
  }
35551
35735
  previous(keys) {
35552
35736
  const current = this.read();
35553
- const root = import_node_path6.default.join(this.context.configRoot, "config-backups");
35737
+ const root = import_node_path7.default.join(this.context.configRoot, "config-backups");
35554
35738
  if (!(0, import_node_fs8.existsSync)(root)) throw new ConfigurationError("CONFIG_BACKUP_UNAVAILABLE");
35555
35739
  assertPrivateDirectory(root);
35556
35740
  const candidates = (0, import_node_fs8.readdirSync)(root).filter((file) => /^\d+-[a-f0-9-]+\.yaml$/.test(file)).sort().reverse();
35557
35741
  for (const candidate of candidates) {
35558
- const file = import_node_path6.default.join(root, candidate);
35742
+ const file = import_node_path7.default.join(root, candidate);
35559
35743
  const previous = parseConfigurationYaml(readPrivateFile(file), this.context);
35560
35744
  if (keys.some((key) => previous.issues[domainForPath(key)]?.length)) continue;
35561
35745
  const changes = Object.fromEntries(keys.map((key) => [key, readConfigurationPath(previous.value, key) ?? null]));
@@ -35583,7 +35767,7 @@ var ConfigurationStore = class {
35583
35767
  };
35584
35768
 
35585
35769
  // packages/config-node/src/runtime.ts
35586
- var import_node_path7 = __toESM(require("node:path"), 1);
35770
+ var import_node_path8 = __toESM(require("node:path"), 1);
35587
35771
 
35588
35772
  // packages/config-node/src/resolution.ts
35589
35773
  function resolveConfigurationValue(snapshot, key) {
@@ -35772,15 +35956,136 @@ function settingText(key) {
35772
35956
  function configurationPath(key, relativeDefault) {
35773
35957
  const runtime = configuration();
35774
35958
  runtime.requireDomain(domainForPath(key));
35775
- const value = settingText(key) ?? import_node_path7.default.join(runtime.context.configRoot, "data", relativeDefault);
35776
- if (!import_node_path7.default.isAbsolute(value)) throw new ConfigurationError("CONFIG_PATH_MUST_BE_ABSOLUTE", [key]);
35959
+ const value = settingText(key) ?? import_node_path8.default.join(runtime.context.configRoot, "data", relativeDefault);
35960
+ if (!import_node_path8.default.isAbsolute(value)) throw new ConfigurationError("CONFIG_PATH_MUST_BE_ABSOLUTE", [key]);
35777
35961
  assertOwnedPath(runtime.context, value);
35778
35962
  return value;
35779
35963
  }
35780
35964
 
35781
- // packages/config-node/src/runtime-status.ts
35965
+ // packages/config-node/src/claude.ts
35966
+ function resolveClaudeConfiguration(env = process.env) {
35967
+ configuration().requireDomain("agents.claude");
35968
+ const binary = settingText("agents.claude.binary") ?? "claude";
35969
+ const configDirectory = settingText("agents.claude.configDirectory") ?? (env.CLAUDE_CONFIG_DIR || void 0) ?? import_node_path9.default.join(import_node_os3.default.userInfo().homedir, ".claude");
35970
+ if (!import_node_path9.default.isAbsolute(configDirectory) || [...configDirectory].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) {
35971
+ throw new ConfigurationError("CONFIG_FIELD_VALUE_INVALID", ["agents.claude.configDirectory"]);
35972
+ }
35973
+ return { binary, configDirectory, projectsDirectory: import_node_path9.default.join(configDirectory, "projects") };
35974
+ }
35975
+
35976
+ // app-server/src/claude/session-reader.ts
35977
+ var import_promises4 = require("node:fs/promises");
35978
+ var import_node_path10 = __toESM(require("node:path"), 1);
35782
35979
  var import_node_fs9 = require("node:fs");
35783
- var import_node_path8 = __toESM(require("node:path"), 1);
35980
+ var SESSION_ID = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i;
35981
+ var ClaudeSessionReader = class {
35982
+ projectsRoot;
35983
+ constructor(projectsRoot) {
35984
+ this.projectsRoot = import_node_path10.default.resolve(projectsRoot ?? resolveClaudeConfiguration().projectsDirectory);
35985
+ }
35986
+ async scan(threadId, consume, signal) {
35987
+ const source = await this.locate(threadId, signal);
35988
+ if (!source) return null;
35989
+ const signature = sourceSignature(source);
35990
+ const result = await scanConversationSource(source.file, consume, signal, async (stat3) => {
35991
+ await this.validateSource(source, stat3);
35992
+ });
35993
+ return result ? { ...result, file: source.file, signature } : null;
35994
+ }
35995
+ /** Revalidate the unique source before reusing only an existing short-text projection. */
35996
+ async isUnchanged(threadId, signature) {
35997
+ const source = await this.locate(threadId);
35998
+ if (!source || sourceSignature(source) !== signature) return false;
35999
+ const handle = await (0, import_promises4.open)(source.file, import_node_fs9.constants.O_RDONLY | import_node_fs9.constants.O_NOFOLLOW | import_node_fs9.constants.O_NONBLOCK);
36000
+ try {
36001
+ const stat3 = await handle.stat();
36002
+ await this.validateSource(source, stat3);
36003
+ const current = await handle.stat();
36004
+ await this.validateSource(source, current);
36005
+ return sourceSignature({ ...source, stat: stat3 }) === signature && sourceSignature({ ...source, stat: current }) === signature;
36006
+ } finally {
36007
+ await handle.close();
36008
+ }
36009
+ }
36010
+ async validateSource(source, stat3) {
36011
+ const [root, project, current] = await Promise.all([
36012
+ (0, import_promises4.lstat)(this.projectsRoot),
36013
+ (0, import_promises4.lstat)(import_node_path10.default.dirname(source.file)),
36014
+ (0, import_promises4.lstat)(source.file)
36015
+ ]);
36016
+ if (!sameFile(root, source.root) || !sameFile(project, source.project) || !sameSourceVersion(current, source.stat) || !sameSourceVersion(stat3, source.stat) || await (0, import_promises4.realpath)(source.file) !== source.file) {
36017
+ throw unsafeSource();
36018
+ }
36019
+ }
36020
+ async locate(threadId, signal) {
36021
+ if (!SESSION_ID.test(threadId)) return null;
36022
+ try {
36023
+ if (await (0, import_promises4.realpath)(this.projectsRoot) !== this.projectsRoot) throw unsafeSource();
36024
+ const root = await (0, import_promises4.lstat)(this.projectsRoot);
36025
+ if (!root.isDirectory() || root.isSymbolicLink()) throw unsafeSource();
36026
+ let found = null;
36027
+ const directories = (await (0, import_promises4.readdir)(this.projectsRoot, { withFileTypes: true })).filter((directory) => directory.isDirectory() && !directory.isSymbolicLink());
36028
+ for (let index = 0; index < directories.length; index += 8) {
36029
+ signal?.throwIfAborted();
36030
+ const candidates = await Promise.allSettled(directories.slice(index, index + 8).map(async (directory) => {
36031
+ const projectPath = import_node_path10.default.join(this.projectsRoot, directory.name);
36032
+ const file = import_node_path10.default.join(projectPath, `${threadId}.jsonl`);
36033
+ try {
36034
+ return { file, projectPath, stat: await (0, import_promises4.lstat)(file) };
36035
+ } catch (error) {
36036
+ if (missing(error)) return null;
36037
+ throw error;
36038
+ }
36039
+ }));
36040
+ for (const candidate of candidates) {
36041
+ signal?.throwIfAborted();
36042
+ if (candidate.status === "rejected") throw candidate.reason;
36043
+ if (!candidate.value) continue;
36044
+ const { file, projectPath, stat: stat3 } = candidate.value;
36045
+ const project = await (0, import_promises4.lstat)(projectPath);
36046
+ if (!project.isDirectory() || project.isSymbolicLink() || !stat3.isFile() || stat3.isSymbolicLink() || stat3.nlink !== 1 || await (0, import_promises4.realpath)(file) !== file) throw unsafeSource();
36047
+ if (found) throw new ConversationReadError(409, "CLAUDE_SESSION_AMBIGUOUS", "Claude \u4F1A\u8BDD\u6765\u6E90\u4E0D\u552F\u4E00");
36048
+ found = { file, stat: stat3, project, root };
36049
+ }
36050
+ }
36051
+ return found;
36052
+ } catch (error) {
36053
+ if (missing(error)) return null;
36054
+ throw error;
36055
+ }
36056
+ }
36057
+ };
36058
+ function sourceSignature(source) {
36059
+ const { file, stat: stat3, project, root } = source;
36060
+ return JSON.stringify([
36061
+ file,
36062
+ root.dev,
36063
+ root.ino,
36064
+ project.dev,
36065
+ project.ino,
36066
+ stat3.dev,
36067
+ stat3.ino,
36068
+ stat3.size,
36069
+ stat3.mtimeMs,
36070
+ stat3.ctimeMs
36071
+ ]);
36072
+ }
36073
+ function sameFile(left, right) {
36074
+ return left.dev === right.dev && left.ino === right.ino && !left.isSymbolicLink();
36075
+ }
36076
+ function sameSourceVersion(current, expected) {
36077
+ return sameFile(current, expected) && current.isFile() && current.nlink === 1 && current.size === expected.size && current.mtimeMs === expected.mtimeMs && current.ctimeMs === expected.ctimeMs;
36078
+ }
36079
+ function missing(error) {
36080
+ return ["ENOENT", "ENOTDIR"].includes(String(error.code));
36081
+ }
36082
+ function unsafeSource() {
36083
+ return new ConversationReadError(409, "CLAUDE_SOURCE_CHANGED", "Claude \u4F1A\u8BDD\u6765\u6E90\u5DF2\u53D8\u5316\u6216\u4E0D\u5B89\u5168");
36084
+ }
36085
+
36086
+ // packages/config-node/src/runtime-status.ts
36087
+ var import_node_fs10 = require("node:fs");
36088
+ var import_node_path11 = __toESM(require("node:path"), 1);
35784
36089
 
35785
36090
  // packages/shared/src/monitoring/runtime-version.ts
35786
36091
  function runtimeBuildInfo(fallback = { version: "development" }) {
@@ -35823,38 +36128,38 @@ function runtimeInstallationFacts(running, installed) {
35823
36128
 
35824
36129
  // packages/config-node/src/runtime-status.ts
35825
36130
  function readInstalledRuntimeBuild(entry) {
35826
- if (!entry || !import_node_path8.default.isAbsolute(entry)) return null;
36131
+ if (!entry || !import_node_path11.default.isAbsolute(entry)) return null;
35827
36132
  let fd;
35828
36133
  try {
35829
- const marker = `${import_node_path8.default.sep}releases${import_node_path8.default.sep}`;
36134
+ const marker = `${import_node_path11.default.sep}releases${import_node_path11.default.sep}`;
35830
36135
  const index = entry.lastIndexOf(marker);
35831
36136
  if (index >= 0) {
35832
36137
  const root = entry.slice(0, index);
35833
- const relative = entry.slice(index + marker.length).split(import_node_path8.default.sep).slice(1);
35834
- const pointer = import_node_path8.default.join(root, "current.json");
35835
- if ((0, import_node_fs9.existsSync)(pointer)) {
35836
- const selected = JSON.parse((0, import_node_fs9.readFileSync)(pointer, "utf8"));
36138
+ const relative = entry.slice(index + marker.length).split(import_node_path11.default.sep).slice(1);
36139
+ const pointer = import_node_path11.default.join(root, "current.json");
36140
+ if ((0, import_node_fs10.existsSync)(pointer)) {
36141
+ const selected = JSON.parse((0, import_node_fs10.readFileSync)(pointer, "utf8"));
35837
36142
  if (!/^[a-zA-Z0-9._-]+$/.test(selected.releaseId) || [".", ".."].includes(selected.releaseId)) return null;
35838
- entry = import_node_path8.default.join(root, "releases", selected.releaseId, ...relative);
36143
+ entry = import_node_path11.default.join(root, "releases", selected.releaseId, ...relative);
35839
36144
  }
35840
36145
  }
35841
- fd = (0, import_node_fs9.openSync)(entry, "r");
36146
+ fd = (0, import_node_fs10.openSync)(entry, "r");
35842
36147
  const buffer = Buffer.alloc(8192);
35843
- const length = (0, import_node_fs9.readSync)(fd, buffer, 0, buffer.length, 0);
36148
+ const length = (0, import_node_fs10.readSync)(fd, buffer, 0, buffer.length, 0);
35844
36149
  const match = buffer.subarray(0, length).toString("utf8").split("\n", 1)[0]?.match(/var __RUNWEAVE_BUILD_INFO__=(\{.*\});/);
35845
- const metadata = import_node_path8.default.join(import_node_path8.default.dirname(entry), "release.json");
35846
- const value = match ? JSON.parse(match[1]) : JSON.parse((0, import_node_fs9.readFileSync)((0, import_node_fs9.existsSync)(metadata) ? metadata : import_node_path8.default.join(import_node_path8.default.dirname(entry), "build-info.json"), "utf8"));
36150
+ const metadata = import_node_path11.default.join(import_node_path11.default.dirname(entry), "release.json");
36151
+ const value = match ? JSON.parse(match[1]) : JSON.parse((0, import_node_fs10.readFileSync)((0, import_node_fs10.existsSync)(metadata) ? metadata : import_node_path11.default.join(import_node_path11.default.dirname(entry), "build-info.json"), "utf8"));
35847
36152
  return typeof value.version === "string" && typeof value.buildId === "string" ? value : null;
35848
36153
  } catch {
35849
36154
  return null;
35850
36155
  } finally {
35851
- if (fd !== void 0) (0, import_node_fs9.closeSync)(fd);
36156
+ if (fd !== void 0) (0, import_node_fs10.closeSync)(fd);
35852
36157
  }
35853
36158
  }
35854
36159
 
35855
36160
  // app-server/src/pi/session-reader.ts
35856
- var import_promises4 = require("node:fs/promises");
35857
- var import_node_path9 = __toESM(require("node:path"), 1);
36161
+ var import_promises5 = require("node:fs/promises");
36162
+ var import_node_path12 = __toESM(require("node:path"), 1);
35858
36163
 
35859
36164
  // packages/shared/src/terminal/pi-agent.ts
35860
36165
  function isPiAgentContext(value) {
@@ -35943,11 +36248,11 @@ var PiSessionReader = class {
35943
36248
  async read(thread) {
35944
36249
  if (thread.agent !== "pi" || !thread.pi?.sessionFile) return null;
35945
36250
  const file = thread.pi.sessionFile;
35946
- if (!import_node_path9.default.isAbsolute(file) || import_node_path9.default.extname(file) !== ".jsonl") return null;
36251
+ if (!import_node_path12.default.isAbsolute(file) || import_node_path12.default.extname(file) !== ".jsonl") return null;
35947
36252
  let handle;
35948
36253
  try {
35949
- if (await (0, import_promises4.realpath)(file) !== file) return null;
35950
- handle = await (0, import_promises4.open)(file, "r");
36254
+ if (await (0, import_promises5.realpath)(file) !== file) return null;
36255
+ handle = await (0, import_promises5.open)(file, "r");
35951
36256
  const stat3 = await handle.stat();
35952
36257
  if (!stat3.isFile() || stat3.size > 64 * 1024 * 1024) return null;
35953
36258
  const content = await handle.readFile("utf8");
@@ -36100,26 +36405,13 @@ function contentText(value) {
36100
36405
  }
36101
36406
 
36102
36407
  // app-server/src/agents/thread-previews.ts
36103
- var import_promises6 = require("node:fs/promises");
36104
- var import_node_path11 = __toESM(require("node:path"), 1);
36105
-
36106
- // packages/shared/src/app-server/thread-preview.ts
36107
- function formatThreadPreviewText(value) {
36108
- if (!value) return null;
36109
- const text = value.replace(/<oai-mem-citation>[\s\S]*?<\/oai-mem-citation>/g, "").replace(/```[^\n]*\n?/g, "").replace(/!?\[([^\]]*)\]\([^\n]*?\)/g, "$1").replace(/<[^>\n]+>/g, "").replace(/^\s{0,3}(?:#{1,6}\s+|>\s*|[-*+]\s+|\d+[.)]\s+)/gm, "").replace(/(`+)([\s\S]*?)\1/g, "$2").replace(/(\*\*|__|~~)([^\n]+?)\1/g, "$2").replace(/\*([^*\n]+)\*/g, "$1").replace(/(^|\s)_([^_\n]+)_(?=\s|[.,!?,。!?]|$)/g, "$1$2").replace(/\s+/g, " ").trim();
36110
- if (!text) return null;
36111
- const characters = [];
36112
- for (const part of new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(text)) {
36113
- if (characters.length === 120) return `${characters.join("")}\u2026`;
36114
- characters.push(part.segment);
36115
- }
36116
- return text;
36117
- }
36408
+ var import_promises7 = require("node:fs/promises");
36409
+ var import_node_path14 = __toESM(require("node:path"), 1);
36118
36410
 
36119
36411
  // app-server/src/trae/lifecycle-reader.ts
36120
- var import_promises5 = require("node:fs/promises");
36121
- var import_node_os3 = __toESM(require("node:os"), 1);
36122
- var import_node_path10 = __toESM(require("node:path"), 1);
36412
+ var import_promises6 = require("node:fs/promises");
36413
+ var import_node_os4 = __toESM(require("node:os"), 1);
36414
+ var import_node_path13 = __toESM(require("node:path"), 1);
36123
36415
  var TRAE_AGENTS = /* @__PURE__ */ new Set(["trae", "traecli", "traex"]);
36124
36416
  var KNOWN_CONTENT_EVENT_TYPES = /* @__PURE__ */ new Set([
36125
36417
  "agent_reasoning_raw_content",
@@ -36134,8 +36426,8 @@ var TraeThreadLifecycleReader = class {
36134
36426
  sessionsRoot;
36135
36427
  threadPaths = /* @__PURE__ */ new Map();
36136
36428
  constructor(sessionsRoot) {
36137
- this.sessionsRoot = import_node_path10.default.resolve(
36138
- sessionsRoot ?? settingText("agents.traex.sessionsDirectory") ?? import_node_path10.default.join(import_node_os3.default.homedir(), ".trae", "cli", "sessions")
36429
+ this.sessionsRoot = import_node_path13.default.resolve(
36430
+ sessionsRoot ?? settingText("agents.traex.sessionsDirectory") ?? import_node_path13.default.join(import_node_os4.default.homedir(), ".trae", "cli", "sessions")
36139
36431
  );
36140
36432
  }
36141
36433
  supports(provider) {
@@ -36180,7 +36472,7 @@ var TraeThreadLifecycleReader = class {
36180
36472
  return null;
36181
36473
  }
36182
36474
  async readThreadFile(filePath, expectedThreadId, provider) {
36183
- const records = parseJsonl(await (0, import_promises5.readFile)(filePath, "utf8"));
36475
+ const records = parseJsonl(await (0, import_promises6.readFile)(filePath, "utf8"));
36184
36476
  const sessionId = readSessionIdFromRecords(records);
36185
36477
  if (sessionId !== expectedThreadId) {
36186
36478
  this.threadPaths.delete(expectedThreadId);
@@ -36262,7 +36554,7 @@ var TraeThreadLifecycleReader = class {
36262
36554
  }
36263
36555
  };
36264
36556
  function readThreadIdFromFilename(filePath) {
36265
- return import_node_path10.default.basename(filePath).match(/([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})\.jsonl$/i)?.[1] ?? null;
36557
+ return import_node_path13.default.basename(filePath).match(/([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})\.jsonl$/i)?.[1] ?? null;
36266
36558
  }
36267
36559
  function isLifecycleEventType(type) {
36268
36560
  return type === "task_started" || type === "task_complete" || type === "turn_aborted" || !KNOWN_CONTENT_EVENT_TYPES.has(type);
@@ -36272,12 +36564,12 @@ async function listJsonlFiles(root) {
36272
36564
  const visit = async (directory) => {
36273
36565
  let entries;
36274
36566
  try {
36275
- entries = await (0, import_promises5.readdir)(directory, { withFileTypes: true });
36567
+ entries = await (0, import_promises6.readdir)(directory, { withFileTypes: true });
36276
36568
  } catch {
36277
36569
  return;
36278
36570
  }
36279
36571
  for (const entry of entries) {
36280
- const entryPath = import_node_path10.default.join(directory, entry.name);
36572
+ const entryPath = import_node_path13.default.join(directory, entry.name);
36281
36573
  if (entry.isDirectory()) {
36282
36574
  await visit(entryPath);
36283
36575
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -36290,7 +36582,7 @@ async function listJsonlFiles(root) {
36290
36582
  }
36291
36583
  async function readSessionId(filePath) {
36292
36584
  try {
36293
- return readSessionIdFromRecords(parseJsonl(await (0, import_promises5.readFile)(filePath, "utf8")));
36585
+ return readSessionIdFromRecords(parseJsonl(await (0, import_promises6.readFile)(filePath, "utf8")));
36294
36586
  } catch {
36295
36587
  return null;
36296
36588
  }
@@ -36341,9 +36633,10 @@ var MAX_LINE_BYTES = 4 * 1024 * 1024;
36341
36633
  var MAX_THREADS = 256;
36342
36634
  var MAX_PI_NODES = 2e3;
36343
36635
  var ThreadPreviewReader = class {
36344
- constructor(codex, trae = new TraeThreadLifecycleReader()) {
36636
+ constructor(codex, trae = new TraeThreadLifecycleReader(), claude) {
36345
36637
  this.codex = codex;
36346
36638
  this.trae = trae;
36639
+ this.claude = claude;
36347
36640
  }
36348
36641
  entries = /* @__PURE__ */ new Map();
36349
36642
  queued = /* @__PURE__ */ new Set();
@@ -36352,7 +36645,7 @@ var ThreadPreviewReader = class {
36352
36645
  read(threads) {
36353
36646
  return threads.map((thread) => {
36354
36647
  let entry = this.entries.get(thread.threadId);
36355
- if (entry?.thread.agent !== thread.agent || entry && entry.thread.pi?.sessionFile !== thread.pi?.sessionFile) {
36648
+ if (entry?.thread.agent !== thread.agent || entry && thread.agent === "claude" && entry.thread.cwd !== thread.cwd || entry && entry.thread.pi?.sessionFile !== thread.pi?.sessionFile) {
36356
36649
  if (entry) this.queued.delete(entry);
36357
36650
  entry = void 0;
36358
36651
  }
@@ -36434,17 +36727,33 @@ var ThreadPreviewReader = class {
36434
36727
  async refresh(entry) {
36435
36728
  const thread = entry.thread;
36436
36729
  entry.checkedAt = Date.now();
36730
+ if (thread.agent === "claude") {
36731
+ if (entry.ready && entry.valid && entry.claudeSignature && await this.claude?.isSourceUnchanged(thread.threadId, entry.claudeSignature)) return;
36732
+ const result = await this.claude?.read(thread);
36733
+ if (entry.thread.cwd !== thread.cwd) return;
36734
+ entry.claudeSignature = result?.signature;
36735
+ entry.file = result?.file ?? null;
36736
+ entry.ready = entry.valid = Boolean(result);
36737
+ entry.availability = !this.claude ? "read_failed" : result ? "available" : "source_missing";
36738
+ const turn = result?.turns.at(-1);
36739
+ entry.value = {
36740
+ turnId: turn?.id ?? null,
36741
+ userText: formatThreadPreviewText(turn?.messages.find((message) => message.role === "user")?.text),
36742
+ agentText: formatThreadPreviewText(turn?.messages.filter((message) => message.role === "assistant").at(-1)?.text)
36743
+ };
36744
+ return;
36745
+ }
36437
36746
  if (thread.agent !== "codex" && thread.agent !== "pi" && !this.trae.supports(thread.agent)) {
36438
36747
  entry.availability = "provider_unsupported";
36439
36748
  return;
36440
36749
  }
36441
36750
  const file = thread.agent === "pi" ? thread.pi?.sessionFile : entry.file ?? await (thread.agent === "codex" ? this.codex : this.trae).findThreadPath(thread.threadId);
36442
- if (!file || !import_node_path11.default.isAbsolute(file) || import_node_path11.default.extname(file) !== ".jsonl" || await (0, import_promises6.realpath)(file) !== file) {
36751
+ if (!file || !import_node_path14.default.isAbsolute(file) || import_node_path14.default.extname(file) !== ".jsonl" || await (0, import_promises7.realpath)(file) !== file) {
36443
36752
  entry.ready = false;
36444
36753
  entry.availability = "source_missing";
36445
36754
  return;
36446
36755
  }
36447
- const handle = await (0, import_promises6.open)(file, "r");
36756
+ const handle = await (0, import_promises7.open)(file, "r");
36448
36757
  try {
36449
36758
  const stat3 = await handle.stat();
36450
36759
  if (!stat3.isFile()) {
@@ -36597,7 +36906,7 @@ function messageText(content) {
36597
36906
  // app-server/src/index.ts
36598
36907
  var import_node_http = __toESM(require("node:http"), 1);
36599
36908
  var import_node_crypto7 = require("node:crypto");
36600
- var import_promises13 = require("node:fs/promises");
36909
+ var import_promises14 = require("node:fs/promises");
36601
36910
 
36602
36911
  // app-server/package.json
36603
36912
  var package_default = {
@@ -36644,7 +36953,7 @@ var package_default = {
36644
36953
  };
36645
36954
 
36646
36955
  // app-server/src/config.ts
36647
- var import_node_path12 = __toESM(require("node:path"), 1);
36956
+ var import_node_path15 = __toESM(require("node:path"), 1);
36648
36957
  function resolveAppServerConfig(env = process.env) {
36649
36958
  configuration().requireDomain("appServer");
36650
36959
  const stateDir = configurationPath("appServer.stateDirectory", "app-server");
@@ -36652,10 +36961,10 @@ function resolveAppServerConfig(env = process.env) {
36652
36961
  host: "127.0.0.1",
36653
36962
  requestedPort: parsePort(configurationOption("port")),
36654
36963
  stateDir,
36655
- lockPath: import_node_path12.default.join(stateDir, "app-server.lock.json"),
36656
- tokenPath: import_node_path12.default.join(stateDir, "app-server-token"),
36657
- eventLogPath: import_node_path12.default.join(stateDir, "app-server-events.jsonl"),
36658
- threadStatePath: import_node_path12.default.join(stateDir, "app-server-thread-state.json"),
36964
+ lockPath: import_node_path15.default.join(stateDir, "app-server.lock.json"),
36965
+ tokenPath: import_node_path15.default.join(stateDir, "app-server-token"),
36966
+ eventLogPath: import_node_path15.default.join(stateDir, "app-server-events.jsonl"),
36967
+ threadStatePath: import_node_path15.default.join(stateDir, "app-server-thread-state.json"),
36659
36968
  cloudSyncDir: configurationPath("appServer.cloudSyncDirectory", "app-server/cloud-sync"),
36660
36969
  version: runtimeBuildInfo({ version: `${package_default.version}-dev` }).version,
36661
36970
  source: parseSource(env.RUNWEAVE_APP_SERVER_SOURCE),
@@ -36686,22 +36995,22 @@ function parsePort(raw) {
36686
36995
 
36687
36996
  // app-server/src/auth.ts
36688
36997
  var import_node_crypto5 = __toESM(require("node:crypto"), 1);
36689
- var import_promises7 = require("node:fs/promises");
36690
- var import_node_path13 = __toESM(require("node:path"), 1);
36998
+ var import_promises8 = require("node:fs/promises");
36999
+ var import_node_path16 = __toESM(require("node:path"), 1);
36691
37000
  async function loadOrCreateToken(tokenPath) {
36692
37001
  try {
36693
- const token2 = (await (0, import_promises7.readFile)(tokenPath, "utf8")).trim();
37002
+ const token2 = (await (0, import_promises8.readFile)(tokenPath, "utf8")).trim();
36694
37003
  if (token2) {
36695
- await (0, import_promises7.chmod)(tokenPath, 384).catch(() => void 0);
37004
+ await (0, import_promises8.chmod)(tokenPath, 384).catch(() => void 0);
36696
37005
  return token2;
36697
37006
  }
36698
37007
  } catch {
36699
37008
  }
36700
37009
  const token = import_node_crypto5.default.randomBytes(32).toString("base64url");
36701
- await (0, import_promises7.mkdir)(import_node_path13.default.dirname(tokenPath), { recursive: true });
36702
- await (0, import_promises7.writeFile)(tokenPath, `${token}
37010
+ await (0, import_promises8.mkdir)(import_node_path16.default.dirname(tokenPath), { recursive: true });
37011
+ await (0, import_promises8.writeFile)(tokenPath, `${token}
36703
37012
  `, { encoding: "utf8", mode: 384 });
36704
- await (0, import_promises7.chmod)(tokenPath, 384).catch(() => void 0);
37013
+ await (0, import_promises8.chmod)(tokenPath, 384).catch(() => void 0);
36705
37014
  return token;
36706
37015
  }
36707
37016
  function rejectNonLoopbackOrigin(req, res, next) {
@@ -36748,8 +37057,8 @@ function isLoopbackOrigin(origin) {
36748
37057
  }
36749
37058
 
36750
37059
  // app-server/src/cloud-sync-sim.ts
36751
- var import_promises8 = require("node:fs/promises");
36752
- var import_node_path14 = __toESM(require("node:path"), 1);
37060
+ var import_promises9 = require("node:fs/promises");
37061
+ var import_node_path17 = __toESM(require("node:path"), 1);
36753
37062
  var AppServerCloudSyncSim = class {
36754
37063
  constructor(options) {
36755
37064
  this.options = options;
@@ -36778,7 +37087,7 @@ var AppServerCloudSyncSim = class {
36778
37087
  (event) => Number(event.id) > Number(this.latestSyncedEventId ?? 0)
36779
37088
  );
36780
37089
  if (eventsToSync.length > 0) {
36781
- await (0, import_promises8.appendFile)(
37090
+ await (0, import_promises9.appendFile)(
36782
37091
  this.eventsMirrorPath,
36783
37092
  eventsToSync.map((event) => JSON.stringify(event)).join("\n") + "\n",
36784
37093
  "utf8"
@@ -36818,7 +37127,7 @@ var AppServerCloudSyncSim = class {
36818
37127
  if (changes.length === 0) {
36819
37128
  return;
36820
37129
  }
36821
- await (0, import_promises8.appendFile)(
37130
+ await (0, import_promises9.appendFile)(
36822
37131
  filePath,
36823
37132
  changes.map((change) => JSON.stringify(change)).join("\n") + "\n",
36824
37133
  "utf8"
@@ -36826,12 +37135,12 @@ var AppServerCloudSyncSim = class {
36826
37135
  }
36827
37136
  async ensureDirectories() {
36828
37137
  await Promise.all([
36829
- (0, import_promises8.mkdir)(import_node_path14.default.join(this.options.syncDir, "events"), { recursive: true }),
36830
- (0, import_promises8.mkdir)(import_node_path14.default.join(this.options.syncDir, "projections"), {
37138
+ (0, import_promises9.mkdir)(import_node_path17.default.join(this.options.syncDir, "events"), { recursive: true }),
37139
+ (0, import_promises9.mkdir)(import_node_path17.default.join(this.options.syncDir, "projections"), {
36831
37140
  recursive: true
36832
37141
  }),
36833
- (0, import_promises8.mkdir)(import_node_path14.default.join(this.options.syncDir, "cursors"), { recursive: true }),
36834
- (0, import_promises8.mkdir)(import_node_path14.default.join(this.options.syncDir, "manifests"), { recursive: true })
37142
+ (0, import_promises9.mkdir)(import_node_path17.default.join(this.options.syncDir, "cursors"), { recursive: true }),
37143
+ (0, import_promises9.mkdir)(import_node_path17.default.join(this.options.syncDir, "manifests"), { recursive: true })
36835
37144
  ]);
36836
37145
  }
36837
37146
  async writeManifest() {
@@ -36847,36 +37156,36 @@ var AppServerCloudSyncSim = class {
36847
37156
  });
36848
37157
  }
36849
37158
  get eventsMirrorPath() {
36850
- return import_node_path14.default.join(this.options.syncDir, "events", "app-server-events.jsonl");
37159
+ return import_node_path17.default.join(this.options.syncDir, "events", "app-server-events.jsonl");
36851
37160
  }
36852
37161
  get threadProjectionPath() {
36853
- return import_node_path14.default.join(this.options.syncDir, "projections", "threads.jsonl");
37162
+ return import_node_path17.default.join(this.options.syncDir, "projections", "threads.jsonl");
36854
37163
  }
36855
37164
  get latestThreadsPath() {
36856
- return import_node_path14.default.join(
37165
+ return import_node_path17.default.join(
36857
37166
  this.options.syncDir,
36858
37167
  "projections",
36859
37168
  "latest-threads.json"
36860
37169
  );
36861
37170
  }
36862
37171
  get cursorPath() {
36863
- return import_node_path14.default.join(this.options.syncDir, "cursors", "upload-cursor.json");
37172
+ return import_node_path17.default.join(this.options.syncDir, "cursors", "upload-cursor.json");
36864
37173
  }
36865
37174
  get manifestPath() {
36866
- return import_node_path14.default.join(this.options.syncDir, "manifests", "sync-manifest.json");
37175
+ return import_node_path17.default.join(this.options.syncDir, "manifests", "sync-manifest.json");
36867
37176
  }
36868
37177
  };
36869
37178
  async function readJsonFile(filePath, predicate) {
36870
37179
  try {
36871
- const value = JSON.parse(await (0, import_promises8.readFile)(filePath, "utf8"));
37180
+ const value = JSON.parse(await (0, import_promises9.readFile)(filePath, "utf8"));
36872
37181
  return predicate(value) ? value : null;
36873
37182
  } catch {
36874
37183
  return null;
36875
37184
  }
36876
37185
  }
36877
37186
  async function writeJsonFile(filePath, value) {
36878
- await (0, import_promises8.mkdir)(import_node_path14.default.dirname(filePath), { recursive: true });
36879
- await (0, import_promises8.writeFile)(filePath, `${JSON.stringify(value, null, 2)}
37187
+ await (0, import_promises9.mkdir)(import_node_path17.default.dirname(filePath), { recursive: true });
37188
+ await (0, import_promises9.writeFile)(filePath, `${JSON.stringify(value, null, 2)}
36880
37189
  `, "utf8");
36881
37190
  }
36882
37191
  function isUploadCursor(value) {
@@ -36977,9 +37286,9 @@ var CodexQuotaService = class {
36977
37286
 
36978
37287
  // app-server/src/codex/client.ts
36979
37288
  var import_node_child_process2 = require("node:child_process");
36980
- var import_node_fs10 = require("node:fs");
36981
- var import_node_os4 = __toESM(require("node:os"), 1);
36982
- var import_node_path15 = __toESM(require("node:path"), 1);
37289
+ var import_node_fs11 = require("node:fs");
37290
+ var import_node_os5 = __toESM(require("node:os"), 1);
37291
+ var import_node_path18 = __toESM(require("node:path"), 1);
36983
37292
 
36984
37293
  // app-server/src/codex/thread-detail.ts
36985
37294
  var CODEX_THREAD_DETAIL_STATUS_TYPES = /* @__PURE__ */ new Set([
@@ -37342,32 +37651,32 @@ function buildCodexAppServerArgs() {
37342
37651
  return [...CODEX_SKIP_UPDATE_ON_STARTUP_ARGS, ...CODEX_APP_SERVER_ARGS];
37343
37652
  }
37344
37653
  function buildCodexProcessEnv(env, launchPlan) {
37345
- const launchDir = import_node_path15.default.dirname(launchPlan.command);
37654
+ const launchDir = import_node_path18.default.dirname(launchPlan.command);
37346
37655
  const currentPath = env.PATH ?? "";
37347
- const pathEntries = [launchDir, ...currentPath.split(import_node_path15.default.delimiter)].map((entry) => entry.trim()).filter(Boolean);
37656
+ const pathEntries = [launchDir, ...currentPath.split(import_node_path18.default.delimiter)].map((entry) => entry.trim()).filter(Boolean);
37348
37657
  return {
37349
37658
  ...env,
37350
- PATH: Array.from(new Set(pathEntries)).join(import_node_path15.default.delimiter)
37659
+ PATH: Array.from(new Set(pathEntries)).join(import_node_path18.default.delimiter)
37351
37660
  };
37352
37661
  }
37353
37662
  function resolveCodexBinaryCandidates(env) {
37354
- const homeDir = import_node_os4.default.homedir();
37355
- const pathCandidates = (env.PATH ?? "").split(import_node_path15.default.delimiter).map((entry) => entry.trim()).filter(Boolean).map((entry) => import_node_path15.default.join(entry, "codex"));
37663
+ const homeDir = import_node_os5.default.homedir();
37664
+ const pathCandidates = (env.PATH ?? "").split(import_node_path18.default.delimiter).map((entry) => entry.trim()).filter(Boolean).map((entry) => import_node_path18.default.join(entry, "codex"));
37356
37665
  return Array.from(
37357
37666
  /* @__PURE__ */ new Set([
37358
37667
  ...pathCandidates,
37359
- import_node_path15.default.join(homeDir, ".volta", "bin", "codex"),
37360
- import_node_path15.default.join(homeDir, ".local", "bin", "codex"),
37361
- import_node_path15.default.join(homeDir, ".npm-global", "bin", "codex"),
37668
+ import_node_path18.default.join(homeDir, ".volta", "bin", "codex"),
37669
+ import_node_path18.default.join(homeDir, ".local", "bin", "codex"),
37670
+ import_node_path18.default.join(homeDir, ".npm-global", "bin", "codex"),
37362
37671
  ...resolveNvmCodexCandidates(
37363
- import_node_path15.default.join(homeDir, ".nvm", "versions", "node")
37672
+ import_node_path18.default.join(homeDir, ".nvm", "versions", "node")
37364
37673
  )
37365
37674
  ])
37366
37675
  );
37367
37676
  }
37368
37677
  function resolveNvmCodexCandidates(nodeVersionsDir) {
37369
37678
  try {
37370
- return (0, import_node_fs10.readdirSync)(nodeVersionsDir).map((entry) => import_node_path15.default.join(nodeVersionsDir, entry, "bin", "codex")).sort((left, right) => readMtimeMs(right) - readMtimeMs(left));
37679
+ return (0, import_node_fs11.readdirSync)(nodeVersionsDir).map((entry) => import_node_path18.default.join(nodeVersionsDir, entry, "bin", "codex")).sort((left, right) => readMtimeMs(right) - readMtimeMs(left));
37371
37680
  } catch {
37372
37681
  return [];
37373
37682
  }
@@ -37387,9 +37696,9 @@ function isCodexThreadNotFoundError(error) {
37387
37696
  }
37388
37697
 
37389
37698
  // app-server/src/codex/lifecycle-reader.ts
37390
- var import_promises9 = require("node:fs/promises");
37391
- var import_node_os5 = __toESM(require("node:os"), 1);
37392
- var import_node_path16 = __toESM(require("node:path"), 1);
37699
+ var import_promises10 = require("node:fs/promises");
37700
+ var import_node_os6 = __toESM(require("node:os"), 1);
37701
+ var import_node_path19 = __toESM(require("node:path"), 1);
37393
37702
  var ROLLOUT_TAIL_BYTES = 1024 * 1024;
37394
37703
  var ROLLOUT_LOOKBACK_BYTES = 64 * ROLLOUT_TAIL_BYTES;
37395
37704
  var TERMINAL_LIFECYCLE_TYPES = /* @__PURE__ */ new Set([
@@ -37405,9 +37714,9 @@ var CodexRolloutLifecycleReader = class {
37405
37714
  indexedAt = 0;
37406
37715
  constructor(sessionsRoot) {
37407
37716
  const configuredRoot = sessionsRoot ?? settingText("agents.codex.sessionsDirectory");
37408
- this.sessionsRoots = configuredRoot ? [import_node_path16.default.resolve(configuredRoot)] : [
37409
- import_node_path16.default.join(import_node_os5.default.homedir(), ".codex", "sessions"),
37410
- import_node_path16.default.join(import_node_os5.default.homedir(), ".codex", "archived_sessions")
37717
+ this.sessionsRoots = configuredRoot ? [import_node_path19.default.resolve(configuredRoot)] : [
37718
+ import_node_path19.default.join(import_node_os6.default.homedir(), ".codex", "sessions"),
37719
+ import_node_path19.default.join(import_node_os6.default.homedir(), ".codex", "archived_sessions")
37411
37720
  ];
37412
37721
  }
37413
37722
  async readLatestLifecycle(threadId) {
@@ -37441,7 +37750,7 @@ var CodexRolloutLifecycleReader = class {
37441
37750
  this.indexPromise = (async () => {
37442
37751
  for (const root of this.sessionsRoots) {
37443
37752
  for (const candidate of await listJsonlFiles2(root)) {
37444
- const id = readThreadIdFromFilename2(candidate) ?? import_node_path16.default.basename(candidate, ".jsonl");
37753
+ const id = readThreadIdFromFilename2(candidate) ?? import_node_path19.default.basename(candidate, ".jsonl");
37445
37754
  if (!this.threadPaths.has(id)) this.threadPaths.set(id, candidate);
37446
37755
  }
37447
37756
  }
@@ -37455,7 +37764,7 @@ var CodexRolloutLifecycleReader = class {
37455
37764
  }
37456
37765
  };
37457
37766
  async function readFileLifecycle(filePath, previous) {
37458
- const handle = await (0, import_promises9.open)(filePath, "r");
37767
+ const handle = await (0, import_promises10.open)(filePath, "r");
37459
37768
  try {
37460
37769
  const { size, dev, ino, mtimeMs, ctimeMs } = await handle.stat();
37461
37770
  const signature = `${filePath}:${dev}:${ino}:${size}:${mtimeMs}:${ctimeMs}`;
@@ -37476,7 +37785,7 @@ async function readFileLifecycle(filePath, previous) {
37476
37785
  suffix = boundary >= 0 && boundary < ROLLOUT_TAIL_BYTES ? Buffer.from(value.subarray(0, boundary + 1)) : Buffer.alloc(0);
37477
37786
  end = start;
37478
37787
  }
37479
- const current = await (0, import_promises9.stat)(filePath);
37788
+ const current = await (0, import_promises10.stat)(filePath);
37480
37789
  if (current.dev !== dev || current.ino !== ino || current.size !== size || current.mtimeMs !== mtimeMs || current.ctimeMs !== ctimeMs)
37481
37790
  return { signature, lifecycle: null };
37482
37791
  return { signature, lifecycle };
@@ -37519,19 +37828,19 @@ function parseLatestLifecycle(value) {
37519
37828
  return latest;
37520
37829
  }
37521
37830
  function readThreadIdFromFilename2(filePath) {
37522
- return import_node_path16.default.basename(filePath).match(/([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})\.jsonl$/i)?.[1] ?? null;
37831
+ return import_node_path19.default.basename(filePath).match(/([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})\.jsonl$/i)?.[1] ?? null;
37523
37832
  }
37524
37833
  async function listJsonlFiles2(root) {
37525
37834
  const files = [];
37526
37835
  const visit = async (directory) => {
37527
37836
  let entries;
37528
37837
  try {
37529
- entries = await (0, import_promises9.readdir)(directory, { withFileTypes: true });
37838
+ entries = await (0, import_promises10.readdir)(directory, { withFileTypes: true });
37530
37839
  } catch {
37531
37840
  return;
37532
37841
  }
37533
37842
  for (const entry of entries) {
37534
- const entryPath = import_node_path16.default.join(directory, entry.name);
37843
+ const entryPath = import_node_path19.default.join(directory, entry.name);
37535
37844
  if (entry.isDirectory()) {
37536
37845
  await visit(entryPath);
37537
37846
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -37997,8 +38306,8 @@ var AppServerEventCenter = class {
37997
38306
 
37998
38307
  // app-server/src/events/store.ts
37999
38308
  var import_node_crypto6 = require("node:crypto");
38000
- var import_promises10 = require("node:fs/promises");
38001
- var import_node_path17 = __toESM(require("node:path"), 1);
38309
+ var import_promises11 = require("node:fs/promises");
38310
+ var import_node_path20 = __toESM(require("node:path"), 1);
38002
38311
  var DEFAULT_EVENT_RETENTION_DAYS = 7;
38003
38312
  var DEFAULT_RETENTION_PRUNE_INTERVAL_MS = 60 * 60 * 1e3;
38004
38313
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -38018,17 +38327,17 @@ var AppServerEventStore = class {
38018
38327
  retentionMs;
38019
38328
  pruneIntervalMs;
38020
38329
  async initialize() {
38021
- await (0, import_promises10.mkdir)(import_node_path17.default.dirname(this.eventLogPath), { recursive: true });
38330
+ await (0, import_promises11.mkdir)(import_node_path20.default.dirname(this.eventLogPath), { recursive: true });
38022
38331
  let content = "";
38023
38332
  try {
38024
- content = await (0, import_promises10.readFile)(this.eventLogPath, "utf8");
38333
+ content = await (0, import_promises11.readFile)(this.eventLogPath, "utf8");
38025
38334
  } catch (error) {
38026
38335
  if (!isNodeError(error) || error.code !== "ENOENT") {
38027
38336
  throw error;
38028
38337
  }
38029
38338
  this.events = [];
38030
38339
  this.nextId = 1;
38031
- await (0, import_promises10.writeFile)(this.eventLogPath, "", { flag: "a" });
38340
+ await (0, import_promises11.writeFile)(this.eventLogPath, "", { flag: "a" });
38032
38341
  this.lastPrunedAtMs = Date.now();
38033
38342
  return;
38034
38343
  }
@@ -38071,7 +38380,7 @@ var AppServerEventStore = class {
38071
38380
  payload: input.payload,
38072
38381
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
38073
38382
  };
38074
- await (0, import_promises10.writeFile)(this.eventLogPath, `${JSON.stringify(event)}
38383
+ await (0, import_promises11.writeFile)(this.eventLogPath, `${JSON.stringify(event)}
38075
38384
  `, {
38076
38385
  encoding: "utf8",
38077
38386
  flag: "a"
@@ -38116,7 +38425,7 @@ var AppServerEventStore = class {
38116
38425
  async rewriteEventLog(events) {
38117
38426
  const temporaryPath = `${this.eventLogPath}.${(0, import_node_crypto6.randomUUID)()}.tmp`;
38118
38427
  try {
38119
- const file = await (0, import_promises10.open)(temporaryPath, "wx", 384);
38428
+ const file = await (0, import_promises11.open)(temporaryPath, "wx", 384);
38120
38429
  try {
38121
38430
  await file.writeFile(
38122
38431
  events.map((event) => JSON.stringify(event)).join("\n") + (events.length > 0 ? "\n" : ""),
@@ -38126,15 +38435,15 @@ var AppServerEventStore = class {
38126
38435
  } finally {
38127
38436
  await file.close();
38128
38437
  }
38129
- await (0, import_promises10.rename)(temporaryPath, this.eventLogPath);
38130
- const directory = await (0, import_promises10.open)(import_node_path17.default.dirname(this.eventLogPath), "r");
38438
+ await (0, import_promises11.rename)(temporaryPath, this.eventLogPath);
38439
+ const directory = await (0, import_promises11.open)(import_node_path20.default.dirname(this.eventLogPath), "r");
38131
38440
  try {
38132
38441
  await directory.sync();
38133
38442
  } finally {
38134
38443
  await directory.close();
38135
38444
  }
38136
38445
  } finally {
38137
- await (0, import_promises10.unlink)(temporaryPath).catch(() => void 0);
38446
+ await (0, import_promises11.unlink)(temporaryPath).catch(() => void 0);
38138
38447
  }
38139
38448
  }
38140
38449
  };
@@ -38168,6 +38477,18 @@ function isNodeError(error) {
38168
38477
  // app-server/src/agents/thread-readers.ts
38169
38478
  function createThreadReaders(options) {
38170
38479
  const readers = [
38480
+ {
38481
+ supports: (thread) => thread.agent === "claude",
38482
+ summary: async (thread) => await options.claudeConversationReader?.summary(thread) ?? null,
38483
+ detail: async (thread) => {
38484
+ const detail = await options.claudeConversationReader?.summary(thread);
38485
+ return {
38486
+ thread,
38487
+ availability: !options.claudeConversationReader ? "provider_unavailable" : detail ? "available" : "thread_not_found",
38488
+ ...detail ? { detail } : {}
38489
+ };
38490
+ }
38491
+ },
38171
38492
  {
38172
38493
  supports: (thread) => thread.agent === "pi",
38173
38494
  summary: async (thread) => (await options.piSessionReader.read(thread))?.summary ?? null,
@@ -38685,8 +39006,8 @@ function getErrorMap() {
38685
39006
 
38686
39007
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
38687
39008
  var makeIssue = (params) => {
38688
- const { data, path: path21, errorMaps, issueData } = params;
38689
- const fullPath = [...path21, ...issueData.path || []];
39009
+ const { data, path: path24, errorMaps, issueData } = params;
39010
+ const fullPath = [...path24, ...issueData.path || []];
38690
39011
  const fullIssue = {
38691
39012
  ...issueData,
38692
39013
  path: fullPath
@@ -38802,11 +39123,11 @@ var errorUtil;
38802
39123
 
38803
39124
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
38804
39125
  var ParseInputLazyPath = class {
38805
- constructor(parent, value, path21, key) {
39126
+ constructor(parent, value, path24, key) {
38806
39127
  this._cachedPath = [];
38807
39128
  this.parent = parent;
38808
39129
  this.data = value;
38809
- this._path = path21;
39130
+ this._path = path24;
38810
39131
  this._key = key;
38811
39132
  }
38812
39133
  get path() {
@@ -42249,8 +42570,8 @@ var coerce = {
42249
42570
  var NEVER = INVALID;
42250
42571
 
42251
42572
  // app-server/src/singleton.ts
42252
- var import_promises11 = require("node:fs/promises");
42253
- var import_node_path18 = __toESM(require("node:path"), 1);
42573
+ var import_promises12 = require("node:fs/promises");
42574
+ var import_node_path21 = __toESM(require("node:path"), 1);
42254
42575
  var APP_SERVER_SERVICE_NAME = "runweave-app-server";
42255
42576
  var APP_SERVER_PROTOCOL_VERSION = 1;
42256
42577
  async function preflightSingleton(lockPath) {
@@ -42261,14 +42582,14 @@ async function preflightSingleton(lockPath) {
42261
42582
  if (isPidAlive(lock.pid) && await healthCheck(lock)) {
42262
42583
  return { status: "owned", lock };
42263
42584
  }
42264
- await (0, import_promises11.rm)(lockPath, { force: true });
42585
+ await (0, import_promises12.rm)(lockPath, { force: true });
42265
42586
  return { status: "available" };
42266
42587
  }
42267
42588
  async function acquireSingletonLock(lockPath, lock) {
42268
- await (0, import_promises11.mkdir)(import_node_path18.default.dirname(lockPath), { recursive: true });
42589
+ await (0, import_promises12.mkdir)(import_node_path21.default.dirname(lockPath), { recursive: true });
42269
42590
  for (let attempt = 0; attempt < 2; attempt += 1) {
42270
42591
  try {
42271
- await (0, import_promises11.writeFile)(lockPath, `${JSON.stringify(lock, null, 2)}
42592
+ await (0, import_promises12.writeFile)(lockPath, `${JSON.stringify(lock, null, 2)}
42272
42593
  `, {
42273
42594
  encoding: "utf8",
42274
42595
  flag: "wx"
@@ -42284,13 +42605,13 @@ async function acquireSingletonLock(lockPath, lock) {
42284
42605
  if (existing2 && isPidAlive(existing2.pid) && await healthCheck(existing2)) {
42285
42606
  return { status: "owned", lock: existing2 };
42286
42607
  }
42287
- await (0, import_promises11.rm)(lockPath, { force: true });
42608
+ await (0, import_promises12.rm)(lockPath, { force: true });
42288
42609
  }
42289
42610
  const existing = await readAppServerLock(lockPath);
42290
42611
  if (existing && isPidAlive(existing.pid) && await healthCheck(existing)) {
42291
42612
  return { status: "owned", lock: existing };
42292
42613
  }
42293
- await (0, import_promises11.writeFile)(lockPath, `${JSON.stringify(lock, null, 2)}
42614
+ await (0, import_promises12.writeFile)(lockPath, `${JSON.stringify(lock, null, 2)}
42294
42615
  `, {
42295
42616
  encoding: "utf8",
42296
42617
  flag: "wx"
@@ -42302,14 +42623,14 @@ async function releaseLock(lockPath) {
42302
42623
  if (!current || current.pid !== process.pid) {
42303
42624
  return;
42304
42625
  }
42305
- await (0, import_promises11.rm)(lockPath, { force: true });
42626
+ await (0, import_promises12.rm)(lockPath, { force: true });
42306
42627
  }
42307
42628
  async function readLock(lockPath) {
42308
42629
  return readAppServerLock(lockPath);
42309
42630
  }
42310
42631
  async function readAppServerLock(lockPath) {
42311
42632
  try {
42312
- const parsed = JSON.parse(await (0, import_promises11.readFile)(lockPath, "utf8"));
42633
+ const parsed = JSON.parse(await (0, import_promises12.readFile)(lockPath, "utf8"));
42313
42634
  return isLock(parsed) ? parsed : null;
42314
42635
  } catch {
42315
42636
  return null;
@@ -42536,6 +42857,10 @@ function createHttpApp(options) {
42536
42857
  const response = { thread, detail };
42537
42858
  res.json(response);
42538
42859
  } catch (error) {
42860
+ if (error instanceof ConversationReadError) {
42861
+ res.status(error.status).json({ code: error.code, message: error.message });
42862
+ return;
42863
+ }
42539
42864
  next(error);
42540
42865
  }
42541
42866
  });
@@ -42627,6 +42952,10 @@ function createHttpApp(options) {
42627
42952
  const response = await threadReader(thread).detail(thread);
42628
42953
  res.json(response);
42629
42954
  } catch (error) {
42955
+ if (error instanceof ConversationReadError) {
42956
+ res.status(error.status).json({ code: error.code, message: error.message });
42957
+ return;
42958
+ }
42630
42959
  next(error);
42631
42960
  }
42632
42961
  });
@@ -42700,9 +43029,29 @@ function isRunStatus(value) {
42700
43029
  return value === "starting" || value === "running" || value === "idle" || value === "completed" || value === "failed" || value === "unknown";
42701
43030
  }
42702
43031
 
43032
+ // packages/shared/src/terminal/claude-agent.ts
43033
+ function isClaudeAgentContext(value) {
43034
+ if (!value || typeof value !== "object") return false;
43035
+ const v = value;
43036
+ const text = (x) => typeof x === "string" && x.length > 0 && x.length <= 256;
43037
+ return v.version === 1 && text(v.sessionId) && text(v.instanceId) && text(v.eventId) && text(v.event) && typeof v.startedAt === "number" && Number.isFinite(v.startedAt) && v.startedAt > 0 && typeof v.observedAt === "number" && Number.isFinite(v.observedAt) && v.observedAt >= v.startedAt && (v.sessionSource === void 0 || text(v.sessionSource)) && (v.notificationType === void 0 || text(v.notificationType));
43038
+ }
43039
+ function isNewerClaudeContext(next, previous) {
43040
+ if (!previous) return true;
43041
+ if (next.instanceId !== previous.instanceId) return next.startedAt > previous.startedAt;
43042
+ if (next.observedAt <= previous.observedAt) return false;
43043
+ return next.sessionId === previous.sessionId || next.event === "sessionstart";
43044
+ }
43045
+ function claudeHookStatus(context) {
43046
+ if (context.event === "sessionstart") return context.sessionSource === "compact" ? null : "idle";
43047
+ if (["userpromptsubmit", "pretooluse", "posttooluse", "posttoolusefailure"].includes(context.event)) return "running";
43048
+ if (context.event === "notification" && context.notificationType === "idle_prompt") return "idle";
43049
+ return null;
43050
+ }
43051
+
42703
43052
  // app-server/src/state/store.ts
42704
- var import_promises12 = require("node:fs/promises");
42705
- var import_node_path19 = __toESM(require("node:path"), 1);
43053
+ var import_promises13 = require("node:fs/promises");
43054
+ var import_node_path22 = __toESM(require("node:path"), 1);
42706
43055
  var AppServerStateStore = class {
42707
43056
  constructor(threadStatePath) {
42708
43057
  this.threadStatePath = threadStatePath;
@@ -42710,7 +43059,7 @@ var AppServerStateStore = class {
42710
43059
  threads = /* @__PURE__ */ new Map();
42711
43060
  threadTmuxPaneIds = /* @__PURE__ */ new Map();
42712
43061
  async initialize() {
42713
- await (0, import_promises12.mkdir)(import_node_path19.default.dirname(this.threadStatePath), { recursive: true });
43062
+ await (0, import_promises13.mkdir)(import_node_path22.default.dirname(this.threadStatePath), { recursive: true });
42714
43063
  this.threads.clear();
42715
43064
  this.threadTmuxPaneIds.clear();
42716
43065
  for (const persistedThread of await readStateArray(
@@ -42755,6 +43104,7 @@ var AppServerStateStore = class {
42755
43104
  const previousTmuxPaneId = this.threadTmuxPaneIds.get(update.threadId) ?? null;
42756
43105
  const startsNewTurn = update.agent === "codex" && (update.lastHookEvent === "UserPromptSubmit" || update.lastHookEvent === "SessionStart");
42757
43106
  const current = {
43107
+ ...update.claude ?? previous?.claude ? { claude: update.claude ?? previous?.claude } : {},
42758
43108
  ...update.pi ?? previous?.pi ? { pi: update.pi ?? previous?.pi } : {},
42759
43109
  threadId: update.threadId,
42760
43110
  agent: update.agent,
@@ -42817,15 +43167,15 @@ function filterStateRefs(items, options) {
42817
43167
  }
42818
43168
  async function readStateArray(filePath, predicate) {
42819
43169
  try {
42820
- const parsed = JSON.parse(await (0, import_promises12.readFile)(filePath, "utf8"));
43170
+ const parsed = JSON.parse(await (0, import_promises13.readFile)(filePath, "utf8"));
42821
43171
  return Array.isArray(parsed) ? parsed.filter(predicate) : [];
42822
43172
  } catch {
42823
43173
  return [];
42824
43174
  }
42825
43175
  }
42826
43176
  async function writeJsonFile2(filePath, value) {
42827
- await (0, import_promises12.mkdir)(import_node_path19.default.dirname(filePath), { recursive: true });
42828
- await (0, import_promises12.writeFile)(filePath, `${JSON.stringify(value, null, 2)}
43177
+ await (0, import_promises13.mkdir)(import_node_path22.default.dirname(filePath), { recursive: true });
43178
+ await (0, import_promises13.writeFile)(filePath, `${JSON.stringify(value, null, 2)}
42829
43179
  `, "utf8");
42830
43180
  }
42831
43181
  function isThreadRef(value) {
@@ -42877,6 +43227,20 @@ var AppServerStateProjector = class {
42877
43227
  if (!projection) {
42878
43228
  return { threadChange: null };
42879
43229
  }
43230
+ const previous = this.stateStore.getThread(projection.threadId);
43231
+ if (previous && previous.agent !== projection.agent && (previous.agent === "claude" || projection.agent === "claude")) {
43232
+ return { threadChange: null };
43233
+ }
43234
+ if (projection.agent === "claude") {
43235
+ const native = projection.claude;
43236
+ if (native) {
43237
+ const status = claudeHookStatus(native);
43238
+ if (native.sessionId !== projection.threadId || !isNewerClaudeContext(native, previous?.claude) || (!previous?.claude || previous.claude.instanceId !== native.instanceId) && native.event !== "sessionstart" && status !== "running") return { threadChange: null };
43239
+ projection.status = status ?? previous?.status ?? "unknown";
43240
+ } else if (previous?.claude) {
43241
+ return { threadChange: null };
43242
+ }
43243
+ }
42880
43244
  if (projection.agent === "pi" && (!projection.pi || projection.pi.sessionId !== projection.threadId || !isNewerPiContext(projection.pi, this.stateStore.getThread(projection.threadId)?.pi))) return { threadChange: null };
42881
43245
  const threadChange = this.stateStore.upsertThread(projection);
42882
43246
  return { threadChange };
@@ -42885,7 +43249,7 @@ var AppServerStateProjector = class {
42885
43249
  function buildProjection(event) {
42886
43250
  const payload = readPayloadRecord(event.payload);
42887
43251
  const agent = readAgent(payload);
42888
- const status = event.kind === "agent.hook" ? readHookStatus(payload) : event.kind === "agent.completion" ? readCompletionStatus(payload) : readLifecycleStatus(payload);
43252
+ const status = agent === "claude" ? "unknown" : event.kind === "agent.hook" ? readHookStatus(payload) : event.kind === "agent.completion" ? readCompletionStatus(payload) : readLifecycleStatus(payload);
42889
43253
  if (!status) {
42890
43254
  return null;
42891
43255
  }
@@ -42899,6 +43263,7 @@ function buildProjection(event) {
42899
43263
  const completionReason = event.kind === "agent.completion" ? readCompletionReason(payload) : void 0;
42900
43264
  return {
42901
43265
  agent,
43266
+ ...event.kind === "agent.hook" && isClaudeAgentContext(payload.claude) ? { claude: payload.claude } : {},
42902
43267
  ...isPiAgentContext(payload.pi) ? { pi: payload.pi } : {},
42903
43268
  status,
42904
43269
  threadId,
@@ -42980,6 +43345,7 @@ function readCompletionReason(payload) {
42980
43345
  return reason === "hook_stop" || reason === "notify" || reason === "ai_process_exit" || reason === "manual" ? reason : null;
42981
43346
  }
42982
43347
  function readAgent(payload) {
43348
+ if (readString4(payload, "source") === "claude" || readString4(payload, "agent") === "claude") return "claude";
42983
43349
  const commandAgent = readAgentFromCommand(readString4(payload, "commandName"));
42984
43350
  if (commandAgent) {
42985
43351
  return commandAgent;
@@ -43248,7 +43614,7 @@ async function startAppServer(prepareRuntime) {
43248
43614
  const owner = acquireConfigurationOwner(configuration().context, "app-server");
43249
43615
  process.once("exit", () => owner.release());
43250
43616
  const serviceInstanceId = config.serviceInstanceId ?? `app-server:${(0, import_node_crypto7.randomUUID)()}`;
43251
- await (0, import_promises13.mkdir)(config.stateDir, { recursive: true });
43617
+ await (0, import_promises14.mkdir)(config.stateDir, { recursive: true });
43252
43618
  const preflight = await preflightSingleton(config.lockPath);
43253
43619
  if (preflight.status === "owned") {
43254
43620
  logInfo2("Runweave app-server already running", {
@@ -43294,8 +43660,15 @@ async function startAppServer(prepareRuntime) {
43294
43660
  const piSessionReader = new PiSessionReader();
43295
43661
  const codexAppServerClient = new CodexAppServerClient();
43296
43662
  const codexRolloutLifecycleReader = new CodexRolloutLifecycleReader();
43297
- const threadPreviews = new ThreadPreviewReader(codexRolloutLifecycleReader, traeLifecycleReader);
43298
- const conversations = new ConversationReader(new CodexConversationReader(codexRolloutLifecycleReader), piSessionReader, new TraeConversationReader(traeLifecycleReader), new SupervisionConversationReader(codexRolloutLifecycleReader, import_node_path20.default.join(config.stateDir, "supervision-cache")), new AnalysisEvidenceReader(codexRolloutLifecycleReader));
43663
+ let claudeConversationReader;
43664
+ try {
43665
+ claudeConversationReader = new ClaudeConversationReader(new ClaudeSessionReader());
43666
+ } catch (error) {
43667
+ if (!(error instanceof ConfigurationError) || error.code !== "CONFIG_FIELD_VALUE_INVALID") throw error;
43668
+ logInfo2("Claude conversation reader unavailable", { reason: "configuration_invalid" });
43669
+ }
43670
+ const threadPreviews = new ThreadPreviewReader(codexRolloutLifecycleReader, traeLifecycleReader, claudeConversationReader);
43671
+ const conversations = new ConversationReader(new CodexConversationReader(codexRolloutLifecycleReader), piSessionReader, new TraeConversationReader(traeLifecycleReader), new SupervisionConversationReader(codexRolloutLifecycleReader, import_node_path23.default.join(config.stateDir, "supervision-cache")), new AnalysisEvidenceReader(codexRolloutLifecycleReader), claudeConversationReader);
43299
43672
  const agentThreadStatusReconciler = new AgentThreadStatusReconciler({
43300
43673
  eventCenter,
43301
43674
  sourceInstanceId,
@@ -43323,6 +43696,7 @@ async function startAppServer(prepareRuntime) {
43323
43696
  codexQuota: new CodexQuotaService(codexAppServerClient),
43324
43697
  threadPreviews,
43325
43698
  conversations,
43699
+ claudeConversationReader,
43326
43700
  getRuntimeStatusReport: () => createAppServerRuntimeStatusReport({
43327
43701
  eventCenter,
43328
43702
  reconciler: agentThreadStatusReconciler,