@svenroth-ai/shipwright 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/client/dist/assets/{EmbeddedTerminal-D3wpPNZP.js → EmbeddedTerminal-CqCQUDtp.js} +1 -1
  2. package/client/dist/assets/{abnfDiagram-VRR7QNED-BkLIltB3.js → abnfDiagram-VRR7QNED-DX2objTP.js} +1 -1
  3. package/client/dist/assets/{arc-Sw-Gh0nI.js → arc-DQmjbsFU.js} +1 -1
  4. package/client/dist/assets/{architectureDiagram-ZJ3FMSHR-rdxUi9Ks.js → architectureDiagram-ZJ3FMSHR-DAvCsPCW.js} +1 -1
  5. package/client/dist/assets/{blockDiagram-677ZJIJ3-Ch_9dj8a.js → blockDiagram-677ZJIJ3-DC-dlyYI.js} +1 -1
  6. package/client/dist/assets/{c4Diagram-LMCZKHZV-CkFlO65x.js → c4Diagram-LMCZKHZV-DSlmXfhE.js} +1 -1
  7. package/client/dist/assets/channel-BfmIcrp7.js +1 -0
  8. package/client/dist/assets/{chunk-2Q5K7J3B-CypX83xu.js → chunk-2Q5K7J3B-C111EHL6.js} +1 -1
  9. package/client/dist/assets/{chunk-32BRIVSS-DxVLYGdl.js → chunk-32BRIVSS-DrCYs2XG.js} +1 -1
  10. package/client/dist/assets/{chunk-5VM5RSS4-Cxk1evhx.js → chunk-5VM5RSS4-DIejoaXS.js} +1 -1
  11. package/client/dist/assets/{chunk-EX3LRPZG-n9q5S4yJ.js → chunk-EX3LRPZG-CGWNeH2g.js} +1 -1
  12. package/client/dist/assets/{chunk-JWPE2WC7-jeL4xvir.js → chunk-JWPE2WC7-CCH0SRFY.js} +1 -1
  13. package/client/dist/assets/{chunk-MOJQB5TN-DDSHN0cj.js → chunk-MOJQB5TN-B3OpZGRv.js} +1 -1
  14. package/client/dist/assets/{chunk-RYQCIY6F-C0bo383g.js → chunk-RYQCIY6F-BKhdp_8v.js} +1 -1
  15. package/client/dist/assets/{chunk-V7JOEXUC-C0jDXXAU.js → chunk-V7JOEXUC-B6Bu8x1y.js} +1 -1
  16. package/client/dist/assets/{chunk-VR4S4FIN-h-Rr4Pn2.js → chunk-VR4S4FIN-OgFi2_iB.js} +1 -1
  17. package/client/dist/assets/{chunk-XXDRQBXY-BexSo0-s.js → chunk-XXDRQBXY-xyjuuhxl.js} +1 -1
  18. package/client/dist/assets/classDiagram-OUVF2IWQ-HfUQZ6Uc.js +1 -0
  19. package/client/dist/assets/classDiagram-v2-EOCWNBFH-HfUQZ6Uc.js +1 -0
  20. package/client/dist/assets/{cose-bilkent-JH36ORCC-BQXzaioj.js → cose-bilkent-JH36ORCC-BQIH3SCK.js} +1 -1
  21. package/client/dist/assets/{cynefin-VYW2F7L2-BJIofhfe.js → cynefin-VYW2F7L2-oyLAz8te.js} +1 -1
  22. package/client/dist/assets/{cynefinDiagram-TSTJHNR4-DmPqTM1T.js → cynefinDiagram-TSTJHNR4-DoLCsH0l.js} +1 -1
  23. package/client/dist/assets/{dagre-VKFMJZFB-1xljvw6X.js → dagre-VKFMJZFB-D7djx1_Y.js} +1 -1
  24. package/client/dist/assets/{diagram-FQU43EPY-iyL9muCG.js → diagram-FQU43EPY-DFuYE0Vf.js} +1 -1
  25. package/client/dist/assets/{diagram-G47NLZAW-DREp2Th6.js → diagram-G47NLZAW-CffCZVXk.js} +1 -1
  26. package/client/dist/assets/{diagram-NH7WQ7WH-h0X3Is2S.js → diagram-NH7WQ7WH-BhrHtUlt.js} +1 -1
  27. package/client/dist/assets/{diagram-OA4YK3LP-Bj8YZRFJ.js → diagram-OA4YK3LP-CwQPbOn0.js} +1 -1
  28. package/client/dist/assets/{diagram-WEI45ONY-BZOf805d.js → diagram-WEI45ONY-abtYnYqH.js} +1 -1
  29. package/client/dist/assets/{ebnfDiagram-CCIWWBDH-DO5JnXda.js → ebnfDiagram-CCIWWBDH-DfV7gT4m.js} +1 -1
  30. package/client/dist/assets/{erDiagram-Q63AITRT-DRgcqg1T.js → erDiagram-Q63AITRT-vtbCprgH.js} +1 -1
  31. package/client/dist/assets/{flowDiagram-23GEKE2U-C3J9QmrW.js → flowDiagram-23GEKE2U-CVCgcyDF.js} +1 -1
  32. package/client/dist/assets/{ganttDiagram-NO4QXBWP-BIEl3Tkm.js → ganttDiagram-NO4QXBWP-BclyOgMb.js} +1 -1
  33. package/client/dist/assets/{gitGraphDiagram-IHSO6WYX-BNF0tFWC.js → gitGraphDiagram-IHSO6WYX-BXT4rIKj.js} +1 -1
  34. package/client/dist/assets/index-CKU9dY18.css +1 -0
  35. package/client/dist/assets/{index-BnTOrFHb.js → index-DOMl6atu.js} +232 -214
  36. package/client/dist/assets/{infoDiagram-FWYZ7A6U-DEyFxiyY.js → infoDiagram-FWYZ7A6U-Dr4mN24J.js} +1 -1
  37. package/client/dist/assets/{ishikawaDiagram-FXEZZL3T-B_ehlg3I.js → ishikawaDiagram-FXEZZL3T-BBUFWq5C.js} +1 -1
  38. package/client/dist/assets/{journeyDiagram-5HDEW3XC-Dp00FyJS.js → journeyDiagram-5HDEW3XC-CmclipcQ.js} +1 -1
  39. package/client/dist/assets/{kanban-definition-HUTT4EX6-CTAf16q8.js → kanban-definition-HUTT4EX6-eIzUeZ03.js} +1 -1
  40. package/client/dist/assets/{linear-9vNUgmYd.js → linear-DGiT7uKK.js} +1 -1
  41. package/client/dist/assets/{mermaid.core-A6tjaEVD.js → mermaid.core-BcLNGbxW.js} +4 -4
  42. package/client/dist/assets/{mindmap-definition-LN4V7U3C-DRW3bmCY.js → mindmap-definition-LN4V7U3C-C4ANnNiP.js} +1 -1
  43. package/client/dist/assets/{pegDiagram-2B236MQR-DJFCjHp2.js → pegDiagram-2B236MQR-DnMeh3Yh.js} +1 -1
  44. package/client/dist/assets/{pieDiagram-ENE6RG2P-KRd-sGvC.js → pieDiagram-ENE6RG2P-CKV_rkhF.js} +1 -1
  45. package/client/dist/assets/{quadrantDiagram-ABIIQ3AL-9TLZE3Hu.js → quadrantDiagram-ABIIQ3AL-BuUsGwHh.js} +1 -1
  46. package/client/dist/assets/{railroadDiagram-RFXS5EU6-y4tLtjXg.js → railroadDiagram-RFXS5EU6-BwwdKnFL.js} +1 -1
  47. package/client/dist/assets/{requirementDiagram-TGXJPOKE-B9EOQDQM.js → requirementDiagram-TGXJPOKE-CpQZouJV.js} +1 -1
  48. package/client/dist/assets/{sankeyDiagram-HTMAVEWB-zfwiDzkT.js → sankeyDiagram-HTMAVEWB-4fnDUNVa.js} +1 -1
  49. package/client/dist/assets/{sequenceDiagram-DBY2YBRQ-DW1LWepL.js → sequenceDiagram-DBY2YBRQ-BOcaWlM0.js} +1 -1
  50. package/client/dist/assets/{sizeCapture-X5ZJPWSS-BM81Mik0.js → sizeCapture-X5ZJPWSS-_pv-9R0c.js} +1 -1
  51. package/client/dist/assets/{stateDiagram-2N3HPSRC-D0EMIw1w.js → stateDiagram-2N3HPSRC-CFwCOonY.js} +1 -1
  52. package/client/dist/assets/stateDiagram-v2-6OUMAXLB-srkiu3Ib.js +1 -0
  53. package/client/dist/assets/{swimlanes-5IMT3BWC-CKXNCX6M.js → swimlanes-5IMT3BWC-DFa2tzxu.js} +2 -2
  54. package/client/dist/assets/swimlanesDiagram-G3AALYLV-Dq-0K9Zm.js +8 -0
  55. package/client/dist/assets/{timeline-definition-FHXFAJF6-ByzIfvL5.js → timeline-definition-FHXFAJF6-rhGYElgn.js} +1 -1
  56. package/client/dist/assets/{vennDiagram-L72KCM5P-Xep38xBH.js → vennDiagram-L72KCM5P-BoGjRxyA.js} +1 -1
  57. package/client/dist/assets/{wardleyDiagram-EHGQE667-DKWDpx6g.js → wardleyDiagram-EHGQE667-D-IGv5bH.js} +1 -1
  58. package/client/dist/assets/{xychartDiagram-FW5EYKEG-BGcwZTnu.js → xychartDiagram-FW5EYKEG-D9PFTCfm.js} +1 -1
  59. package/client/dist/index.html +2 -2
  60. package/lib/probes.mjs +10 -4
  61. package/lib/server.mjs +149 -12
  62. package/package.json +1 -1
  63. package/server/dist/core/sdk-sessions-merge.d.ts +19 -0
  64. package/server/dist/core/sdk-sessions-merge.d.ts.map +1 -1
  65. package/server/dist/core/sdk-sessions-merge.js +19 -5
  66. package/server/dist/core/sdk-sessions-merge.js.map +1 -1
  67. package/server/dist/core/sdk-sessions-refresh.d.ts +50 -0
  68. package/server/dist/core/sdk-sessions-refresh.d.ts.map +1 -0
  69. package/server/dist/core/sdk-sessions-refresh.js +69 -0
  70. package/server/dist/core/sdk-sessions-refresh.js.map +1 -0
  71. package/server/dist/core/sdk-sessions-store.d.ts +2 -0
  72. package/server/dist/core/sdk-sessions-store.d.ts.map +1 -1
  73. package/server/dist/core/sdk-sessions-store.js +7 -9
  74. package/server/dist/core/sdk-sessions-store.js.map +1 -1
  75. package/server/dist/core/shipwright-plugin-version-reader.d.ts +15 -0
  76. package/server/dist/core/shipwright-plugin-version-reader.d.ts.map +1 -0
  77. package/server/dist/core/shipwright-plugin-version-reader.js +49 -0
  78. package/server/dist/core/shipwright-plugin-version-reader.js.map +1 -0
  79. package/server/dist/external/inbox/_derive.d.ts +2 -25
  80. package/server/dist/external/inbox/_derive.d.ts.map +1 -1
  81. package/server/dist/external/inbox/_derive.js.map +1 -1
  82. package/server/dist/external/inbox/_lead.d.ts +23 -0
  83. package/server/dist/external/inbox/_lead.d.ts.map +1 -0
  84. package/server/dist/external/inbox/_lead.js +83 -0
  85. package/server/dist/external/inbox/_lead.js.map +1 -0
  86. package/server/dist/external/inbox/_types.d.ts +32 -0
  87. package/server/dist/external/inbox/_types.d.ts.map +1 -0
  88. package/server/dist/external/inbox/_types.js +10 -0
  89. package/server/dist/external/inbox/_types.js.map +1 -0
  90. package/server/dist/external/inbox/routes.d.ts.map +1 -1
  91. package/server/dist/external/inbox/routes.js +29 -1
  92. package/server/dist/external/inbox/routes.js.map +1 -1
  93. package/server/dist/external/launch/claim-holder-gate.d.ts +42 -0
  94. package/server/dist/external/launch/claim-holder-gate.d.ts.map +1 -0
  95. package/server/dist/external/launch/claim-holder-gate.js +87 -0
  96. package/server/dist/external/launch/claim-holder-gate.js.map +1 -0
  97. package/server/dist/external/launch/routes.d.ts.map +1 -1
  98. package/server/dist/external/launch/routes.js +23 -19
  99. package/server/dist/external/launch/routes.js.map +1 -1
  100. package/server/dist/external/org/lead-question-threads.d.ts +46 -0
  101. package/server/dist/external/org/lead-question-threads.d.ts.map +1 -0
  102. package/server/dist/external/org/lead-question-threads.js +132 -0
  103. package/server/dist/external/org/lead-question-threads.js.map +1 -0
  104. package/server/dist/external/org/mount.d.ts +3 -0
  105. package/server/dist/external/org/mount.d.ts.map +1 -1
  106. package/server/dist/external/org/mount.js +2 -1
  107. package/server/dist/external/org/mount.js.map +1 -1
  108. package/server/dist/external/org/usage.d.ts.map +1 -1
  109. package/server/dist/external/org/usage.js +20 -2
  110. package/server/dist/external/org/usage.js.map +1 -1
  111. package/server/dist/external/routes.d.ts.map +1 -1
  112. package/server/dist/external/routes.js +1 -7
  113. package/server/dist/external/routes.js.map +1 -1
  114. package/server/dist/routes/diagnostics.d.ts +12 -0
  115. package/server/dist/routes/diagnostics.d.ts.map +1 -1
  116. package/server/dist/routes/diagnostics.js +4 -1
  117. package/server/dist/routes/diagnostics.js.map +1 -1
  118. package/server/dist/routes/org-threads-composite.d.ts +24 -0
  119. package/server/dist/routes/org-threads-composite.d.ts.map +1 -0
  120. package/server/dist/routes/org-threads-composite.js +51 -0
  121. package/server/dist/routes/org-threads-composite.js.map +1 -0
  122. package/server/dist/routes/org.d.ts +5 -0
  123. package/server/dist/routes/org.d.ts.map +1 -1
  124. package/server/dist/routes/org.js +13 -0
  125. package/server/dist/routes/org.js.map +1 -1
  126. package/server/dist/terminal/pty-manager.d.ts +23 -1
  127. package/server/dist/terminal/pty-manager.d.ts.map +1 -1
  128. package/server/dist/terminal/pty-manager.js +22 -3
  129. package/server/dist/terminal/pty-manager.js.map +1 -1
  130. package/server/dist/terminal/pty-write-chunker.d.ts +109 -0
  131. package/server/dist/terminal/pty-write-chunker.d.ts.map +1 -0
  132. package/server/dist/terminal/pty-write-chunker.js +234 -0
  133. package/server/dist/terminal/pty-write-chunker.js.map +1 -0
  134. package/server/dist/types/org.d.ts +19 -0
  135. package/server/dist/types/org.d.ts.map +1 -1
  136. package/server/package.json +1 -1
  137. package/client/dist/assets/channel-BYPbLjRl.js +0 -1
  138. package/client/dist/assets/classDiagram-OUVF2IWQ-CsFIeTju.js +0 -1
  139. package/client/dist/assets/classDiagram-v2-EOCWNBFH-CsFIeTju.js +0 -1
  140. package/client/dist/assets/index-CYPc6qxw.css +0 -1
  141. package/client/dist/assets/stateDiagram-v2-6OUMAXLB-B3E4_xxT.js +0 -1
  142. package/client/dist/assets/swimlanesDiagram-G3AALYLV-BegQBqnC.js +0 -8
@@ -0,0 +1,32 @@
1
+ export type AggregatedEntry = {
2
+ kind: "ask_tool";
3
+ taskId: string;
4
+ sessionUuid: string;
5
+ taskTitle: string;
6
+ toolUseId: string;
7
+ toolName: string;
8
+ input: unknown;
9
+ bestEffort: true;
10
+ } | {
11
+ kind: "text_question";
12
+ taskId: string;
13
+ sessionUuid: string;
14
+ taskTitle: string;
15
+ questionId: string;
16
+ questionText: string;
17
+ bestEffort: true;
18
+ } | {
19
+ kind: "terminal_prompt";
20
+ taskId: string;
21
+ sessionUuid: string;
22
+ taskTitle: string;
23
+ promptText: string;
24
+ bestEffort: true;
25
+ } | {
26
+ kind: "lead_question";
27
+ taskId: string;
28
+ sessionUuid: string;
29
+ taskTitle: string;
30
+ questionText: string;
31
+ };
32
+ //# sourceMappingURL=_types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_types.d.ts","sourceRoot":"","sources":["../../../src/external/inbox/_types.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;CAClB,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,IAAI,CAAC;CAClB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;CAClB,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /*
2
+ * external/inbox/_types.ts — the aggregator's output shape, shared by
3
+ * `_derive.ts` (JSONL/terminal-derived kinds) and `_lead.ts` (the written
4
+ * `lead_question` kind). Split out to keep `_derive.ts` under the 300-LOC
5
+ * guideline. Discriminated union precedence: ask_tool > terminal_prompt >
6
+ * text_question; `lead_question` is independent of that precedence — it
7
+ * reflects a different waiting state on the same task, not a JSONL read.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_types.js","sourceRoot":"","sources":["../../../src/external/inbox/_types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/external/inbox/routes.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAKpE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE;QACV,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7B,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;KAClD,CAAC;CACH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA0C7D"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/external/inbox/routes.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAUpE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE;QACV,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7B,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;KAClD,CAAC;CACH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAoE7D"}
@@ -7,10 +7,13 @@
7
7
  * `detectAwaitingUserQuestion`.
8
8
  * - `terminal_prompt` — a waiting picker visible in the LIVE headless
9
9
  * mirror but not (yet) journaled to the JSONL.
10
+ * - `lead_question` — a leadwright follow-up WRITTEN onto the task's
11
+ * `description` (FR-04.19), not derived from a JSONL/terminal read
12
+ * — see `./_lead.ts`.
10
13
  *
11
14
  * Precedence: ask_tool > terminal_prompt > text_question. terminal_prompt
12
15
  * is a post-pass over the JSONL-derived set so the mtime-keyed cache
13
- * stays byte-identical.
16
+ * stays byte-identical. `lead_question` is independent of that precedence.
14
17
  *
15
18
  * Phase A4 hot-path: per-session derive cache + negative-result cache
16
19
  * — see `./_cache.ts`. JSONL cold-path + terminal_prompt post-pass live
@@ -19,6 +22,7 @@
19
22
  import { Hono } from "hono";
20
23
  import { inboxDeriveCache } from "./_cache.js";
21
24
  import { deriveInboxFromJsonl, appendTerminalPrompts } from "./_derive.js";
25
+ import { appendLeadQuestions, extractLeadQuestionBody, LEAD_QUESTION_DISMISS_PREFIX, } from "./_lead.js";
22
26
  export function createInboxRouter(deps) {
23
27
  const app = new Hono();
24
28
  const { store, watcher, ptyManager } = deps;
@@ -28,6 +32,7 @@ export function createInboxRouter(deps) {
28
32
  watcher,
29
33
  });
30
34
  appendTerminalPrompts(entries, { store, ptyManager });
35
+ appendLeadQuestions(entries, { store });
31
36
  if (storeDirty)
32
37
  await store.persist();
33
38
  return c.json({ items: entries });
@@ -52,6 +57,29 @@ export function createInboxRouter(deps) {
52
57
  await store.persist();
53
58
  return c.json({ ok: true, taskId: task.taskId });
54
59
  }
60
+ // lead_question dismiss — the id is `lq-<taskId>`, not a JSONL toolUseId
61
+ // (a written kind has no toolUseId at all). Reuses `dismissedToolUseIds`
62
+ // as a generic dismissed-id set rather than adding a parallel field.
63
+ if (toolUseId.startsWith(LEAD_QUESTION_DISMISS_PREFIX)) {
64
+ const taskId = toolUseId.slice(LEAD_QUESTION_DISMISS_PREFIX.length);
65
+ const task = store.get(taskId);
66
+ if (task &&
67
+ extractLeadQuestionBody(task.description) !== null &&
68
+ !task.inbox.dismissedToolUseIds.includes(toolUseId)) {
69
+ store.patch(task.taskId, {
70
+ inbox: {
71
+ pendingToolUseIds: task.inbox.pendingToolUseIds,
72
+ dismissedToolUseIds: [
73
+ ...task.inbox.dismissedToolUseIds,
74
+ toolUseId,
75
+ ],
76
+ lastProcessedByteOffset: task.inbox.lastProcessedByteOffset,
77
+ },
78
+ });
79
+ await store.persist();
80
+ return c.json({ ok: true, taskId: task.taskId });
81
+ }
82
+ }
55
83
  return c.json({ ok: false, error: "toolUseId not found in any pending set" }, 404);
56
84
  });
57
85
  return app;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/external/inbox/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAW3E,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAE5C,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACzC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,oBAAoB,CAAC;YACzD,KAAK;YACL,OAAO;SACR,CAAC,CAAC;QACH,qBAAqB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACtD,IAAI,UAAU;YAAE,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7D,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,SAAS;YAChE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC1D,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACzB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;gBACvB,KAAK,EAAE;oBACL,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CACpD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CACzB;oBACD,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;oBAC1C,uBAAuB,EAAE,IAAI,CAAC,KAAK,CAAC,uBAAuB;iBAC5D;aACF,CAAC,CAAC;YACH,gEAAgE;YAChE,gEAAgE;YAChE,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,EAC9D,GAAG,CACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/external/inbox/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AAWpB,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAE5C,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACzC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,oBAAoB,CAAC;YACzD,KAAK;YACL,OAAO;SACR,CAAC,CAAC;QACH,qBAAqB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACtD,mBAAmB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACxC,IAAI,UAAU;YAAE,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7D,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,SAAS;YAChE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC1D,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACzB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;gBACvB,KAAK,EAAE;oBACL,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CACpD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CACzB;oBACD,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;oBAC1C,uBAAuB,EAAE,IAAI,CAAC,KAAK,CAAC,uBAAuB;iBAC5D;aACF,CAAC,CAAC;YACH,gEAAgE;YAChE,gEAAgE;YAChE,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,IAAI,SAAS,CAAC,UAAU,CAAC,4BAA4B,CAAC,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/B,IACE,IAAI;gBACJ,uBAAuB,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI;gBAClD,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,EACnD,CAAC;gBACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;oBACvB,KAAK,EAAE;wBACL,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB;wBAC/C,mBAAmB,EAAE;4BACnB,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB;4BACjC,SAAS;yBACV;wBACD,uBAAuB,EAAE,IAAI,CAAC,KAAK,CAAC,uBAAuB;qBAC5D;iBACF,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,EAC9D,GAAG,CACJ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { ExternalTask } from "../../core/sdk-sessions-store.js";
2
+ /**
3
+ * How long a claim stays launch-eligible after `claimedAt`. §10.9 left the
4
+ * VALUE unfixed ("a named limit"), justified only against one criterion: a
5
+ * holder who restarts LATE must still succeed, never be locked out (AC
6
+ * FR-04.22) — the fix for a stale token is re-claiming, not an indefinite
7
+ * grant. 24h is generous enough to survive a sleeping laptop, a slow beat,
8
+ * or an overnight gap between claim and restart, while still bounding how
9
+ * long an abandoned claim stays replayable.
10
+ */
11
+ export declare const CLAIM_LAUNCH_WINDOW_MS: number;
12
+ /**
13
+ * Doubt-review finding (iterate-2026-09-03-claim-holder-launch): `withinWindow`
14
+ * originally only bounded the claim's age from ABOVE, so a well-formed but
15
+ * FUTURE-dated `claimedAt` (clock skew between the webui host and the daemon
16
+ * host, or a daemon bug) made `Date.now() - claimedAtMs` negative — always
17
+ * `<= CLAIM_LAUNCH_WINDOW_MS`, reading as "very fresh" instead of being
18
+ * rejected. `sdk-sessions-validate.ts` does no date-sanity check on
19
+ * `claimedAt`, so this module is the only place that can catch it. A small
20
+ * tolerance (rather than rejecting any future timestamp outright) survives
21
+ * ordinary clock drift between two processes' wall clocks without reopening
22
+ * the gap: anything beyond it is refused as not-within-window, same as an
23
+ * expired claim.
24
+ */
25
+ export declare const CLAIM_CLOCK_SKEW_TOLERANCE_MS: number;
26
+ export type ClaimGateResult = {
27
+ allowed: true;
28
+ } | {
29
+ allowed: false;
30
+ error: Record<string, unknown>;
31
+ };
32
+ /**
33
+ * Decide whether a launch request may proceed against a (possibly) claimed
34
+ * task. Returns `{ allowed: true }` when there is no active claim, or when
35
+ * `bodyClaimToken` matches the task's current `claimToken` AND the claim is
36
+ * within the launch window. Otherwise refuses with the `task_claimed`
37
+ * envelope — `claimExpired: true` distinguishes "right token, too old" from
38
+ * a foreign/absent token (trap: an expired claim must read differently from
39
+ * someone else's).
40
+ */
41
+ export declare function checkClaimHolderGate(task: ExternalTask, bodyClaimToken: string | undefined): ClaimGateResult;
42
+ //# sourceMappingURL=claim-holder-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim-holder-gate.d.ts","sourceRoot":"","sources":["../../../src/external/launch/claim-holder-gate.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAAgB,CAAC;AAE3D,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,eAAe,CAqCjB"}
@@ -0,0 +1,87 @@
1
+ /*
2
+ * external/launch/claim-holder-gate.ts — FR-04.22 / V5 (leadwright
3
+ * spec/lead-model-spec.md §5.2 + §10.9, PO decision 2026-08-16).
4
+ *
5
+ * The launch route refuses everyone while `claimToken` is set — EXCEPT the
6
+ * claim holder, who must be able to (re)launch (AC FR-04.22). `task` passed
7
+ * in here MUST already be the freshly-disk-read row (see
8
+ * SdkSessionsStore.refreshRowFromDisk in ../../core/sdk-sessions-store.ts) —
9
+ * this module makes no disk access itself and trusts the caller's freshness.
10
+ *
11
+ * §10.9 decided variant (a) plus a time window: the exception accepts the
12
+ * caller presenting the CURRENT claimToken, and additionally requires
13
+ * `claimedAt` to be no older than CLAIM_LAUNCH_WINDOW_MS. Explicitly
14
+ * rejected: making the token single-use (valid only while `launchedAt` is
15
+ * unset) — that breaks AC FR-04.22's "a restart by the holder succeeds".
16
+ *
17
+ * Named residual risk (§8, §10.9): both sides run as the same local user
18
+ * with sdk-sessions.json readable, so this defends against a MISTAKE (a
19
+ * stale browser tab racing a daemon claim), not a local attacker — a
20
+ * process on the same machine under the same user can read the token
21
+ * directly. The window only shrinks that exposure; it does not close it.
22
+ */
23
+ /**
24
+ * How long a claim stays launch-eligible after `claimedAt`. §10.9 left the
25
+ * VALUE unfixed ("a named limit"), justified only against one criterion: a
26
+ * holder who restarts LATE must still succeed, never be locked out (AC
27
+ * FR-04.22) — the fix for a stale token is re-claiming, not an indefinite
28
+ * grant. 24h is generous enough to survive a sleeping laptop, a slow beat,
29
+ * or an overnight gap between claim and restart, while still bounding how
30
+ * long an abandoned claim stays replayable.
31
+ */
32
+ export const CLAIM_LAUNCH_WINDOW_MS = 24 * 60 * 60 * 1000;
33
+ /**
34
+ * Doubt-review finding (iterate-2026-09-03-claim-holder-launch): `withinWindow`
35
+ * originally only bounded the claim's age from ABOVE, so a well-formed but
36
+ * FUTURE-dated `claimedAt` (clock skew between the webui host and the daemon
37
+ * host, or a daemon bug) made `Date.now() - claimedAtMs` negative — always
38
+ * `<= CLAIM_LAUNCH_WINDOW_MS`, reading as "very fresh" instead of being
39
+ * rejected. `sdk-sessions-validate.ts` does no date-sanity check on
40
+ * `claimedAt`, so this module is the only place that can catch it. A small
41
+ * tolerance (rather than rejecting any future timestamp outright) survives
42
+ * ordinary clock drift between two processes' wall clocks without reopening
43
+ * the gap: anything beyond it is refused as not-within-window, same as an
44
+ * expired claim.
45
+ */
46
+ export const CLAIM_CLOCK_SKEW_TOLERANCE_MS = 5 * 60 * 1000;
47
+ /**
48
+ * Decide whether a launch request may proceed against a (possibly) claimed
49
+ * task. Returns `{ allowed: true }` when there is no active claim, or when
50
+ * `bodyClaimToken` matches the task's current `claimToken` AND the claim is
51
+ * within the launch window. Otherwise refuses with the `task_claimed`
52
+ * envelope — `claimExpired: true` distinguishes "right token, too old" from
53
+ * a foreign/absent token (trap: an expired claim must read differently from
54
+ * someone else's).
55
+ */
56
+ export function checkClaimHolderGate(task, bodyClaimToken) {
57
+ if (typeof task.claimToken !== "string" || task.claimToken.length === 0) {
58
+ return { allowed: true };
59
+ }
60
+ const tokenMatches = bodyClaimToken !== undefined && bodyClaimToken === task.claimToken;
61
+ const claimedAtMs = task.claimedAt ? Date.parse(task.claimedAt) : NaN;
62
+ const age = Date.now() - claimedAtMs;
63
+ const withinWindow = Number.isFinite(claimedAtMs) &&
64
+ age >= -CLAIM_CLOCK_SKEW_TOLERANCE_MS &&
65
+ age <= CLAIM_LAUNCH_WINDOW_MS;
66
+ if (tokenMatches && withinWindow) {
67
+ return { allowed: true };
68
+ }
69
+ console.warn(JSON.stringify({
70
+ level: "warn",
71
+ message: "task_claimed: launch refused while claimToken is set",
72
+ taskId: task.taskId,
73
+ claimedBy: task.claimedBy,
74
+ claimedAt: task.claimedAt,
75
+ claimPid: task.claimPid,
76
+ reason: tokenMatches ? "claim_expired" : "foreign_claim",
77
+ }));
78
+ const error = {
79
+ error: "task_claimed",
80
+ claimedBy: task.claimedBy,
81
+ claimedAt: task.claimedAt,
82
+ };
83
+ if (tokenMatches)
84
+ error.claimExpired = true;
85
+ return { allowed: false, error };
86
+ }
87
+ //# sourceMappingURL=claim-holder-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim-holder-gate.js","sourceRoot":"","sources":["../../../src/external/launch/claim-holder-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAM3D;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAkB,EAClB,cAAkC;IAElC,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,YAAY,GAChB,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,CAAC,UAAU,CAAC;IACrE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;IACrC,MAAM,YAAY,GAChB,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC5B,GAAG,IAAI,CAAC,6BAA6B;QACrC,GAAG,IAAI,sBAAsB,CAAC;IAEhC,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,IAAI,CACV,IAAI,CAAC,SAAS,CAAC;QACb,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,sDAAsD;QAC/D,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe;KACzD,CAAC,CACH,CAAC;IAEF,MAAM,KAAK,GAA4B;QACrC,KAAK,EAAE,cAAc;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAC;IACF,IAAI,YAAY;QAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/external/launch/routes.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAEjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAatE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,wBAAwB,GAAG,SAAS,CAAC;IACtE,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvE;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAyN/D"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/external/launch/routes.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAEjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AActE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,wBAAwB,GAAG,SAAS,CAAC;IACtE,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvE;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAwN/D"}
@@ -20,6 +20,7 @@
20
20
  import { Hono } from "hono";
21
21
  import { withLiveSession } from "../_shared/helpers.js";
22
22
  import { parseLaunchBody, applyPhaseTaskBranch, applyCampaignBranch, applyCampaignStepBranch, applyMasterRunBranch, applyActionSubstitutionBranch, applyLegacyFallbackBranch, } from "./_helpers.js";
23
+ import { checkClaimHolderGate } from "./claim-holder-gate.js";
23
24
  export function createLaunchRouter(deps) {
24
25
  const app = new Hono();
25
26
  const { store, ptyManager, getProjectById, runConfigReader, jsonlExistsOnDisk } = deps;
@@ -28,7 +29,7 @@ export function createLaunchRouter(deps) {
28
29
  const body = rawBody && typeof rawBody === "object" && !Array.isArray(rawBody)
29
30
  ? rawBody
30
31
  : {};
31
- const task = store.get(c.req.param("id"));
32
+ let task = store.get(c.req.param("id"));
32
33
  if (!task)
33
34
  return c.json({ error: "Task not found" }, 404);
34
35
  // Section 03 (iterate 3) — O20 idempotency guard. Reject re-launch on
@@ -39,24 +40,27 @@ export function createLaunchRouter(deps) {
39
40
  return c.json({ error: "launch_invalid_state", state: task.state }, 409);
40
41
  }
41
42
  // iterate-2026-05-14 lead-foundation-task-schema (leadwright Phase 1).
42
- // While a task is claimed the user-level launch route MUST step aside
43
- // so user + daemon don't fight over the same session (stale SQLite
44
- // lock, interleaved JSONL, double-running shells). External review
45
- // HIGH-2: only `claimToken` triggers the 409.
46
- if (typeof task.claimToken === "string" && task.claimToken.length > 0) {
47
- console.warn(JSON.stringify({
48
- level: "warn",
49
- message: "task_claimed: launch refused while claimToken is set",
50
- taskId: task.taskId,
51
- claimedBy: task.claimedBy,
52
- claimedAt: task.claimedAt,
53
- claimPid: task.claimPid,
54
- }));
55
- return c.json({
56
- error: "task_claimed",
57
- claimedBy: task.claimedBy,
58
- claimedAt: task.claimedAt,
59
- }, 409);
43
+ // While a task is claimed the launch route MUST step aside for anyone
44
+ // but the claim HOLDER (FR-04.22/V5, iterate-2026-09-03-claim-holder-launch)
45
+ // — so a stranger and the daemon don't fight over the same session
46
+ // (stale SQLite lock, interleaved JSONL, double-running shells), while
47
+ // the holder itself can still (re)launch. External review HIGH-2: only
48
+ // `claimToken` triggers the 409.
49
+ //
50
+ // The in-memory row can be STALE — `load()` runs once at server boot
51
+ // (index.ts), so a foreign claim written to disk by the leadwright
52
+ // daemon only reaches this process's memory via its OWN persist(). A
53
+ // webui that has persisted nothing since the claim was written would
54
+ // otherwise see no claim at all (the normal case for an idle daemon
55
+ // with no browser open). Refresh this one row from disk first — never
56
+ // re-run `load()` (a guarded no-op after the first call).
57
+ const freshTask = await store.refreshRowFromDisk(task.taskId);
58
+ if (freshTask)
59
+ task = freshTask;
60
+ const bodyClaimToken = typeof body.claimToken === "string" ? body.claimToken : undefined;
61
+ const claimGate = checkClaimHolderGate(task, bodyClaimToken);
62
+ if (!claimGate.allowed) {
63
+ return c.json(claimGate.error, 409);
60
64
  }
61
65
  // Parse + apply once-set-always-used (v0.4.1 fallback contract).
62
66
  const parseResult = parseLaunchBody(body, task);
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/external/launch/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/external/launch/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ export interface LeadQuestionRoundMirror {
2
+ round: number;
3
+ questionType: string;
4
+ question: string;
5
+ askedAt: string;
6
+ answer?: {
7
+ text: string;
8
+ answeredAt: string;
9
+ };
10
+ }
11
+ export interface LeadQuestionThreadMirror {
12
+ taskId: string;
13
+ dedupKey: string;
14
+ rounds: LeadQuestionRoundMirror[];
15
+ }
16
+ interface LeadQuestionThreadsFileMirror {
17
+ version: number;
18
+ threads: Record<string, LeadQuestionThreadMirror>;
19
+ }
20
+ /**
21
+ * Structural-only parse. `null` on anything that isn't a well-formed,
22
+ * KNOWN-version threads file — every such case reads as "no threads" to
23
+ * every caller (see file header).
24
+ */
25
+ export declare function parseLeadQuestionThreadsFile(raw: string): LeadQuestionThreadsFileMirror | null;
26
+ export interface LeadQuestionThreadsRouteDeps {
27
+ leadsRoot: string;
28
+ /** Injectable for tests; production wires the real lstatSync. */
29
+ lstatSync?: (p: string) => {
30
+ isSymbolicLink(): boolean;
31
+ };
32
+ }
33
+ export type LeadQuestionThreadsReadResult = {
34
+ ok: true;
35
+ threads: Record<string, LeadQuestionThreadMirror>;
36
+ } | {
37
+ ok: false;
38
+ };
39
+ /**
40
+ * Pure core. Always succeeds with a (possibly empty) threads map — a
41
+ * missing/symlinked/unreadable/invalid/unknown-version file degrades to
42
+ * `{ ok: false }`, which callers treat identically to "no threads yet".
43
+ */
44
+ export declare function readLeadQuestionThreadsCore(deps: LeadQuestionThreadsRouteDeps, leadId: string): LeadQuestionThreadsReadResult;
45
+ export {};
46
+ //# sourceMappingURL=lead-question-threads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lead-question-threads.d.ts","sourceRoot":"","sources":["../../../src/external/org/lead-question-threads.ts"],"names":[],"mappings":"AA+BA,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AAED,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACnD;AAkCD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,6BAA6B,GAAG,IAAI,CA4B9F;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK;QAAE,cAAc,IAAI,OAAO,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,MAAM,6BAA6B,GACrC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;CAAE,GAC/D;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAElB;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,4BAA4B,EAClC,MAAM,EAAE,MAAM,GACb,6BAA6B,CAiC/B"}
@@ -0,0 +1,132 @@
1
+ /*
2
+ * external/org/lead-question-threads.ts — reads leadwright's
3
+ * `<leadsRoot>/<lead-id>/lead-question-threads.json` (FR-04.42, pinned by
4
+ * leadwright#35's `lib/lead-question-thread.ts`). This module is the
5
+ * webui-side half of that contract: leadwright owns the write path and the
6
+ * exposure shape (`exposeLeadQuestionThread`) that this mirrors; this repo
7
+ * only ever reads.
8
+ *
9
+ * Shapes below are a VERBATIM, INDEPENDENT mirror of leadwright's
10
+ * `LeadQuestionRound` / `LeadQuestionThread` / `LeadQuestionThreadsFile`
11
+ * (CLAUDE.md rule 7 — no cross-package import), not a re-implementation of
12
+ * its write-time invariants.
13
+ *
14
+ * Unlike every sibling reader in this directory (`usage.ts`, `last-run.ts`,
15
+ * `org-chart.ts`), a missing file, an unreadable file, invalid JSON, an
16
+ * unknown `version`, or a malformed shape all collapse to the SAME "no
17
+ * threads" result — never a distinct error status. A lead with no follow-up
18
+ * history is the overwhelming steady state (most leads have never asked a
19
+ * question), and the Org page must keep rendering cleanly either way (AC-d):
20
+ * there is no page-level error surface for this data the way there is for
21
+ * `org-chart.json` (`org_chart_invalid`, 502).
22
+ */
23
+ import { readFileSync, lstatSync } from "node:fs";
24
+ import path from "node:path";
25
+ import { realPathGuard } from "../../core/path-guard.js";
26
+ import { LEAD_ID_RE } from "./_helpers.js";
27
+ const LEAD_QUESTION_THREADS_VERSION = 1;
28
+ function isValidAnswer(v) {
29
+ if (typeof v !== "object" || v === null)
30
+ return false;
31
+ const a = v;
32
+ return typeof a.text === "string" && typeof a.answeredAt === "string";
33
+ }
34
+ function isValidRound(v) {
35
+ if (typeof v !== "object" || v === null)
36
+ return false;
37
+ const r = v;
38
+ if (typeof r.round !== "number" ||
39
+ typeof r.questionType !== "string" ||
40
+ typeof r.question !== "string" ||
41
+ typeof r.askedAt !== "string") {
42
+ return false;
43
+ }
44
+ if (r.answer !== undefined && !isValidAnswer(r.answer))
45
+ return false;
46
+ return true;
47
+ }
48
+ function isValidThread(v) {
49
+ if (typeof v !== "object" || v === null)
50
+ return false;
51
+ const t = v;
52
+ return (typeof t.taskId === "string" &&
53
+ typeof t.dedupKey === "string" &&
54
+ Array.isArray(t.rounds) &&
55
+ t.rounds.every(isValidRound));
56
+ }
57
+ /**
58
+ * Structural-only parse. `null` on anything that isn't a well-formed,
59
+ * KNOWN-version threads file — every such case reads as "no threads" to
60
+ * every caller (see file header).
61
+ */
62
+ export function parseLeadQuestionThreadsFile(raw) {
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(raw);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ if (typeof parsed !== "object" || parsed === null)
71
+ return null;
72
+ const obj = parsed;
73
+ if (obj.version !== LEAD_QUESTION_THREADS_VERSION) {
74
+ // Not a crash, not a page-level error (AC-d) — but a schema bump on
75
+ // leadwright's side would otherwise blank every Org-page thread with no
76
+ // operator-visible signal anywhere, so this one branch gets a breadcrumb.
77
+ console.warn(`lead-question-threads.json: unknown version ${JSON.stringify(obj.version)}, expected ${LEAD_QUESTION_THREADS_VERSION} — treating as no threads`);
78
+ return null;
79
+ }
80
+ if (typeof obj.threads !== "object" || obj.threads === null || Array.isArray(obj.threads)) {
81
+ return null;
82
+ }
83
+ const threadsIn = obj.threads;
84
+ const threads = {};
85
+ for (const [taskId, thread] of Object.entries(threadsIn)) {
86
+ if (!isValidThread(thread))
87
+ return null;
88
+ threads[taskId] = thread;
89
+ }
90
+ return { version: obj.version, threads };
91
+ }
92
+ /**
93
+ * Pure core. Always succeeds with a (possibly empty) threads map — a
94
+ * missing/symlinked/unreadable/invalid/unknown-version file degrades to
95
+ * `{ ok: false }`, which callers treat identically to "no threads yet".
96
+ */
97
+ export function readLeadQuestionThreadsCore(deps, leadId) {
98
+ const { leadsRoot } = deps;
99
+ // Defense in depth, mirroring usage.ts/last-run.ts: callers pass a
100
+ // chart-derived leadId (org-chart.json's parser validates each lead's
101
+ // FIELDS but not that its object KEY is kebab-case), so this reader
102
+ // re-validates its own leadId regardless of caller rather than trusting
103
+ // the containment check below to be the only guard.
104
+ if (!LEAD_ID_RE.test(leadId))
105
+ return { ok: false };
106
+ const lstat = deps.lstatSync ?? ((p) => lstatSync(p));
107
+ const absolute = path.join(leadsRoot, leadId, "lead-question-threads.json");
108
+ let lst;
109
+ try {
110
+ lst = lstat(absolute);
111
+ }
112
+ catch {
113
+ return { ok: false };
114
+ }
115
+ if (lst.isSymbolicLink())
116
+ return { ok: false };
117
+ const containment = realPathGuard(leadsRoot, absolute);
118
+ if (!containment.ok)
119
+ return { ok: false };
120
+ let raw;
121
+ try {
122
+ raw = readFileSync(absolute, "utf8");
123
+ }
124
+ catch {
125
+ return { ok: false };
126
+ }
127
+ const file = parseLeadQuestionThreadsFile(raw);
128
+ if (!file)
129
+ return { ok: false };
130
+ return { ok: true, threads: file.threads };
131
+ }
132
+ //# sourceMappingURL=lead-question-threads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lead-question-threads.js","sourceRoot":"","sources":["../../../src/external/org/lead-question-threads.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,14 @@
1
1
  import type { Hono } from "hono";
2
2
  import { type OrgRouterDeps } from "./routes.js";
3
+ import { type OrgApiRouterDeps } from "../../routes/org.js";
3
4
  export interface MountOrgRoutersDeps {
4
5
  honoHost?: string;
5
6
  leadsRoot?: string;
6
7
  leadsRouteSecret?: string;
7
8
  orgLstatSync?: OrgRouterDeps["lstatSync"];
8
9
  orgWithDecisionsLock?: OrgRouterDeps["withDecisionsLock"];
10
+ /** FR-04.42 — task-title lookup for `GET /api/org/threads`. */
11
+ store?: OrgApiRouterDeps["store"];
9
12
  }
10
13
  /** FR-04.38 — mounted only when `honoHost` + `leadsRoot` are both provided. */
11
14
  export declare function mountOrgRouters(app: Hono, deps: MountOrgRoutersDeps): void;
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/external/org/mount.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGlE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;CAC3D;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAuB1E"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/external/org/mount.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1D,+DAA+D;IAC/D,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAwB1E"}
@@ -14,7 +14,7 @@ import { createOrgRouter } from "./routes.js";
14
14
  import { createOrgApiRouter } from "../../routes/org.js";
15
15
  /** FR-04.38 — mounted only when `honoHost` + `leadsRoot` are both provided. */
16
16
  export function mountOrgRouters(app, deps) {
17
- const { honoHost, leadsRoot, leadsRouteSecret, orgLstatSync, orgWithDecisionsLock } = deps;
17
+ const { honoHost, leadsRoot, leadsRouteSecret, orgLstatSync, orgWithDecisionsLock, store } = deps;
18
18
  if (!honoHost || !leadsRoot)
19
19
  return;
20
20
  app.route("/", createOrgRouter({
@@ -29,6 +29,7 @@ export function mountOrgRouters(app, deps) {
29
29
  leadsRoot,
30
30
  lstatSync: orgLstatSync,
31
31
  withDecisionsLock: orgWithDecisionsLock,
32
+ store,
32
33
  }));
33
34
  }
34
35
  //# sourceMappingURL=mount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../../src/external/org/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,eAAe,EAAsB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAUzD,+EAA+E;AAC/E,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,IAAyB;IAClE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IAC3F,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;QAAE,OAAO;IAEpC,GAAG,CAAC,KAAK,CACP,GAAG,EACH,eAAe,CAAC;QACd,QAAQ;QACR,SAAS;QACT,gBAAgB;QAChB,SAAS,EAAE,YAAY;QACvB,iBAAiB,EAAE,oBAAoB;KACxC,CAAC,CACH,CAAC;IACF,GAAG,CAAC,KAAK,CACP,GAAG,EACH,kBAAkB,CAAC;QACjB,QAAQ;QACR,SAAS;QACT,SAAS,EAAE,YAAY;QACvB,iBAAiB,EAAE,oBAAoB;KACxC,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../../src/external/org/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,eAAe,EAAsB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAyB,MAAM,qBAAqB,CAAC;AAYhF,+EAA+E;AAC/E,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,IAAyB;IAClE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAClG,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;QAAE,OAAO;IAEpC,GAAG,CAAC,KAAK,CACP,GAAG,EACH,eAAe,CAAC;QACd,QAAQ;QACR,SAAS;QACT,gBAAgB;QAChB,SAAS,EAAE,YAAY;QACvB,iBAAiB,EAAE,oBAAoB;KACxC,CAAC,CACH,CAAC;IACF,GAAG,CAAC,KAAK,CACP,GAAG,EACH,kBAAkB,CAAC;QACjB,QAAQ;QACR,SAAS;QACT,SAAS,EAAE,YAAY;QACvB,iBAAiB,EAAE,oBAAoB;QACvC,KAAK;KACN,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/external/org/usage.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAIjC,OAAO,EAAc,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,+BAA+B,EAAE,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAsBxD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB;kFAC8E;IAC9E,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,cAAc,IAAI,OAAO,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEjG,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAwE/E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAKxE"}
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/external/org/usage.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAIjC,OAAO,EAAc,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,+BAA+B,EAAE,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA0CxD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB;kFAC8E;IAC9E,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,cAAc,IAAI,OAAO,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEjG,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CA4E/E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAKxE"}