wicked-crew 0.7.39 → 0.7.45

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 (380) hide show
  1. package/dist/api/audit.d.ts +3 -0
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +2 -0
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/capture.d.ts +149 -0
  6. package/dist/api/capture.d.ts.map +1 -0
  7. package/dist/api/capture.js +330 -0
  8. package/dist/api/capture.js.map +1 -0
  9. package/dist/api/chat-citations.d.ts +174 -0
  10. package/dist/api/chat-citations.d.ts.map +1 -0
  11. package/dist/api/chat-citations.js +528 -0
  12. package/dist/api/chat-citations.js.map +1 -0
  13. package/dist/api/chat-scope.d.ts +37 -1
  14. package/dist/api/chat-scope.d.ts.map +1 -1
  15. package/dist/api/chat-scope.js +131 -7
  16. package/dist/api/chat-scope.js.map +1 -1
  17. package/dist/api/chat-transcripts.d.ts +20 -1
  18. package/dist/api/chat-transcripts.d.ts.map +1 -1
  19. package/dist/api/chat-transcripts.js +29 -0
  20. package/dist/api/chat-transcripts.js.map +1 -1
  21. package/dist/api/delivery-cache.d.ts +2 -2
  22. package/dist/api/delivery-freeze.d.ts +66 -0
  23. package/dist/api/delivery-freeze.d.ts.map +1 -0
  24. package/dist/api/delivery-freeze.js +104 -0
  25. package/dist/api/delivery-freeze.js.map +1 -0
  26. package/dist/api/delivery-index.d.ts +53 -9
  27. package/dist/api/delivery-index.d.ts.map +1 -1
  28. package/dist/api/delivery-index.js +115 -22
  29. package/dist/api/delivery-index.js.map +1 -1
  30. package/dist/api/demo.d.ts +90 -0
  31. package/dist/api/demo.d.ts.map +1 -0
  32. package/dist/api/demo.js +492 -0
  33. package/dist/api/demo.js.map +1 -0
  34. package/dist/api/diagnostics.d.ts +64 -1
  35. package/dist/api/diagnostics.d.ts.map +1 -1
  36. package/dist/api/diagnostics.js +129 -1
  37. package/dist/api/diagnostics.js.map +1 -1
  38. package/dist/api/eval-sample.d.ts +6 -6
  39. package/dist/api/governance-steering.d.ts +2 -2
  40. package/dist/api/mcp.d.ts +282 -0
  41. package/dist/api/mcp.d.ts.map +1 -0
  42. package/dist/api/mcp.js +521 -0
  43. package/dist/api/mcp.js.map +1 -0
  44. package/dist/api/plan-schema.d.ts +56 -0
  45. package/dist/api/plan-schema.d.ts.map +1 -0
  46. package/dist/api/plan-schema.js +26 -0
  47. package/dist/api/plan-schema.js.map +1 -0
  48. package/dist/api/roster-standing.d.ts +15 -2
  49. package/dist/api/roster-standing.d.ts.map +1 -1
  50. package/dist/api/roster-standing.js +55 -3
  51. package/dist/api/roster-standing.js.map +1 -1
  52. package/dist/api/routes.d.ts +647 -59
  53. package/dist/api/routes.d.ts.map +1 -1
  54. package/dist/api/routes.js +906 -146
  55. package/dist/api/routes.js.map +1 -1
  56. package/dist/api/run-files.d.ts.map +1 -1
  57. package/dist/api/run-files.js +31 -2
  58. package/dist/api/run-files.js.map +1 -1
  59. package/dist/api/run-liveness.d.ts +41 -0
  60. package/dist/api/run-liveness.d.ts.map +1 -0
  61. package/dist/api/run-liveness.js +166 -0
  62. package/dist/api/run-liveness.js.map +1 -0
  63. package/dist/api/run-timing-index.d.ts +10 -0
  64. package/dist/api/run-timing-index.d.ts.map +1 -1
  65. package/dist/api/run-timing-index.js +24 -0
  66. package/dist/api/run-timing-index.js.map +1 -1
  67. package/dist/api/seat-health.d.ts.map +1 -1
  68. package/dist/api/seat-health.js +20 -4
  69. package/dist/api/seat-health.js.map +1 -1
  70. package/dist/api/seat-probe.d.ts +141 -0
  71. package/dist/api/seat-probe.d.ts.map +1 -0
  72. package/dist/api/seat-probe.js +257 -0
  73. package/dist/api/seat-probe.js.map +1 -0
  74. package/dist/api/seat-record.d.ts +40 -0
  75. package/dist/api/seat-record.d.ts.map +1 -0
  76. package/dist/api/seat-record.js +218 -0
  77. package/dist/api/seat-record.js.map +1 -0
  78. package/dist/api/seat-signin.d.ts.map +1 -1
  79. package/dist/api/seat-signin.js +3 -1
  80. package/dist/api/seat-signin.js.map +1 -1
  81. package/dist/api/seat-standing.d.ts +24 -4
  82. package/dist/api/seat-standing.d.ts.map +1 -1
  83. package/dist/api/seat-standing.js +50 -3
  84. package/dist/api/seat-standing.js.map +1 -1
  85. package/dist/api/server.d.ts +34 -48
  86. package/dist/api/server.d.ts.map +1 -1
  87. package/dist/api/server.js +316 -116
  88. package/dist/api/server.js.map +1 -1
  89. package/dist/api/skills.d.ts +3 -1
  90. package/dist/api/skills.d.ts.map +1 -1
  91. package/dist/api/skills.js +7 -2
  92. package/dist/api/skills.js.map +1 -1
  93. package/dist/api/stall-watchdog.d.ts +34 -3
  94. package/dist/api/stall-watchdog.d.ts.map +1 -1
  95. package/dist/api/stall-watchdog.js +107 -8
  96. package/dist/api/stall-watchdog.js.map +1 -1
  97. package/dist/api/steering-landing.d.ts +6 -6
  98. package/dist/api/steering-landing.d.ts.map +1 -1
  99. package/dist/api/steering-landing.js +7 -9
  100. package/dist/api/steering-landing.js.map +1 -1
  101. package/dist/api/testing.d.ts +6 -4
  102. package/dist/api/testing.d.ts.map +1 -1
  103. package/dist/api/testing.js +82 -47
  104. package/dist/api/testing.js.map +1 -1
  105. package/dist/campaign/boot-resume.d.ts +34 -0
  106. package/dist/campaign/boot-resume.d.ts.map +1 -0
  107. package/dist/campaign/boot-resume.js +45 -0
  108. package/dist/campaign/boot-resume.js.map +1 -0
  109. package/dist/campaigns/rollup.d.ts +4 -1
  110. package/dist/campaigns/rollup.d.ts.map +1 -1
  111. package/dist/campaigns/rollup.js +6 -1
  112. package/dist/campaigns/rollup.js.map +1 -1
  113. package/dist/campaigns/routes.d.ts +2 -2
  114. package/dist/cli/bearer.d.ts +27 -1
  115. package/dist/cli/bearer.d.ts.map +1 -1
  116. package/dist/cli/bearer.js +62 -2
  117. package/dist/cli/bearer.js.map +1 -1
  118. package/dist/cli/governance.d.ts +11 -0
  119. package/dist/cli/governance.d.ts.map +1 -1
  120. package/dist/cli/governance.js +8 -2
  121. package/dist/cli/governance.js.map +1 -1
  122. package/dist/cli/index.d.ts.map +1 -1
  123. package/dist/cli/index.js +140 -75
  124. package/dist/cli/index.js.map +1 -1
  125. package/dist/cli/mcp.d.ts +11 -0
  126. package/dist/cli/mcp.d.ts.map +1 -1
  127. package/dist/cli/mcp.js +40 -9
  128. package/dist/cli/mcp.js.map +1 -1
  129. package/dist/cli/service.d.ts +78 -0
  130. package/dist/cli/service.d.ts.map +1 -0
  131. package/dist/cli/service.js +334 -0
  132. package/dist/cli/service.js.map +1 -0
  133. package/dist/core/adapter.d.ts +247 -14
  134. package/dist/core/adapter.d.ts.map +1 -1
  135. package/dist/core/adapter.js +638 -161
  136. package/dist/core/adapter.js.map +1 -1
  137. package/dist/core/bridge-reaper.d.ts +4 -1
  138. package/dist/core/bridge-reaper.d.ts.map +1 -1
  139. package/dist/core/bridge-reaper.js +15 -1
  140. package/dist/core/bridge-reaper.js.map +1 -1
  141. package/dist/core/bus-notice.d.ts +27 -0
  142. package/dist/core/bus-notice.d.ts.map +1 -0
  143. package/dist/core/bus-notice.js +24 -0
  144. package/dist/core/bus-notice.js.map +1 -0
  145. package/dist/core/bus.d.ts +99 -0
  146. package/dist/core/bus.d.ts.map +1 -0
  147. package/dist/core/bus.js +176 -0
  148. package/dist/core/bus.js.map +1 -0
  149. package/dist/core/deliver-exclusions.d.ts +71 -0
  150. package/dist/core/deliver-exclusions.d.ts.map +1 -0
  151. package/dist/core/deliver-exclusions.js +110 -0
  152. package/dist/core/deliver-exclusions.js.map +1 -0
  153. package/dist/core/deliver-text.d.ts +61 -14
  154. package/dist/core/deliver-text.d.ts.map +1 -1
  155. package/dist/core/deliver-text.js +178 -30
  156. package/dist/core/deliver-text.js.map +1 -1
  157. package/dist/core/deliver-triage.d.ts +11 -2
  158. package/dist/core/deliver-triage.d.ts.map +1 -1
  159. package/dist/core/deliver-triage.js +19 -1
  160. package/dist/core/deliver-triage.js.map +1 -1
  161. package/dist/core/deliver.d.ts +161 -3
  162. package/dist/core/deliver.d.ts.map +1 -1
  163. package/dist/core/deliver.js +463 -25
  164. package/dist/core/deliver.js.map +1 -1
  165. package/dist/core/deliverable-floor.d.ts.map +1 -1
  166. package/dist/core/deliverable-floor.js +5 -7
  167. package/dist/core/deliverable-floor.js.map +1 -1
  168. package/dist/core/engine-bus.d.ts +40 -0
  169. package/dist/core/engine-bus.d.ts.map +1 -0
  170. package/dist/core/engine-bus.js +27 -0
  171. package/dist/core/engine-bus.js.map +1 -0
  172. package/dist/core/estate-mcp-client.d.ts +87 -5
  173. package/dist/core/estate-mcp-client.d.ts.map +1 -1
  174. package/dist/core/estate-mcp-client.js +90 -11
  175. package/dist/core/estate-mcp-client.js.map +1 -1
  176. package/dist/core/linked-issues.d.ts +46 -0
  177. package/dist/core/linked-issues.d.ts.map +1 -0
  178. package/dist/core/linked-issues.js +123 -0
  179. package/dist/core/linked-issues.js.map +1 -0
  180. package/dist/core/run-identity.d.ts +100 -0
  181. package/dist/core/run-identity.d.ts.map +1 -0
  182. package/dist/core/run-identity.js +178 -0
  183. package/dist/core/run-identity.js.map +1 -0
  184. package/dist/core/shutdown.d.ts +16 -0
  185. package/dist/core/shutdown.d.ts.map +1 -0
  186. package/dist/core/shutdown.js +39 -0
  187. package/dist/core/shutdown.js.map +1 -0
  188. package/dist/core/types.d.ts +15 -1
  189. package/dist/core/types.d.ts.map +1 -1
  190. package/dist/core/types.js +4 -0
  191. package/dist/core/types.js.map +1 -1
  192. package/dist/interactive/bridge-pool.d.ts +67 -3
  193. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  194. package/dist/interactive/bridge-pool.js +129 -13
  195. package/dist/interactive/bridge-pool.js.map +1 -1
  196. package/dist/interactive/bridge-root.d.ts +9 -0
  197. package/dist/interactive/bridge-root.d.ts.map +1 -1
  198. package/dist/interactive/bridge-root.js +11 -4
  199. package/dist/interactive/bridge-root.js.map +1 -1
  200. package/dist/interactive/chat-events.d.ts +14 -9
  201. package/dist/interactive/chat-events.d.ts.map +1 -1
  202. package/dist/interactive/chat-events.js +55 -57
  203. package/dist/interactive/chat-events.js.map +1 -1
  204. package/dist/interactive/council-outcome.d.ts +1 -0
  205. package/dist/interactive/council-outcome.d.ts.map +1 -1
  206. package/dist/interactive/council-outcome.js +33 -0
  207. package/dist/interactive/council-outcome.js.map +1 -1
  208. package/dist/interactive/draft-events.d.ts +36 -17
  209. package/dist/interactive/draft-events.d.ts.map +1 -1
  210. package/dist/interactive/draft-events.js +121 -92
  211. package/dist/interactive/draft-events.js.map +1 -1
  212. package/dist/interactive/draft-skill.d.ts +59 -0
  213. package/dist/interactive/draft-skill.d.ts.map +1 -1
  214. package/dist/interactive/draft-skill.js +233 -0
  215. package/dist/interactive/draft-skill.js.map +1 -1
  216. package/dist/interactive/edit-events.d.ts +1 -14
  217. package/dist/interactive/edit-events.d.ts.map +1 -1
  218. package/dist/interactive/edit-events.js +37 -70
  219. package/dist/interactive/edit-events.js.map +1 -1
  220. package/dist/interactive/proxy-routes.d.ts +2 -2
  221. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  222. package/dist/interactive/proxy-routes.js +4 -13
  223. package/dist/interactive/proxy-routes.js.map +1 -1
  224. package/dist/interactive/ws-relay.d.ts +9 -10
  225. package/dist/interactive/ws-relay.d.ts.map +1 -1
  226. package/dist/interactive/ws-relay.js +23 -50
  227. package/dist/interactive/ws-relay.js.map +1 -1
  228. package/dist/mcp/broker.d.ts +88 -0
  229. package/dist/mcp/broker.d.ts.map +1 -0
  230. package/dist/mcp/broker.js +307 -0
  231. package/dist/mcp/broker.js.map +1 -0
  232. package/dist/mcp/call-records.d.ts +61 -0
  233. package/dist/mcp/call-records.d.ts.map +1 -0
  234. package/dist/mcp/call-records.js +135 -0
  235. package/dist/mcp/call-records.js.map +1 -0
  236. package/dist/mcp/classify.d.ts +45 -0
  237. package/dist/mcp/classify.d.ts.map +1 -0
  238. package/dist/mcp/classify.js +83 -0
  239. package/dist/mcp/classify.js.map +1 -0
  240. package/dist/mcp/discovery.d.ts +24 -0
  241. package/dist/mcp/discovery.d.ts.map +1 -0
  242. package/dist/mcp/discovery.js +78 -0
  243. package/dist/mcp/discovery.js.map +1 -0
  244. package/dist/mcp/invoke.d.ts +36 -0
  245. package/dist/mcp/invoke.d.ts.map +1 -0
  246. package/dist/mcp/invoke.js +80 -0
  247. package/dist/mcp/invoke.js.map +1 -0
  248. package/dist/mcp/policies.d.ts +110 -0
  249. package/dist/mcp/policies.d.ts.map +1 -0
  250. package/dist/mcp/policies.js +400 -0
  251. package/dist/mcp/policies.js.map +1 -0
  252. package/dist/mcp/probe.d.ts +66 -0
  253. package/dist/mcp/probe.d.ts.map +1 -0
  254. package/dist/mcp/probe.js +116 -0
  255. package/dist/mcp/probe.js.map +1 -0
  256. package/dist/mcp/redact.d.ts +34 -0
  257. package/dist/mcp/redact.d.ts.map +1 -0
  258. package/dist/mcp/redact.js +84 -0
  259. package/dist/mcp/redact.js.map +1 -0
  260. package/dist/mcp/registry-store.d.ts +69 -0
  261. package/dist/mcp/registry-store.d.ts.map +1 -0
  262. package/dist/mcp/registry-store.js +82 -0
  263. package/dist/mcp/registry-store.js.map +1 -0
  264. package/dist/mcp/registry.d.ts +147 -0
  265. package/dist/mcp/registry.d.ts.map +1 -0
  266. package/dist/mcp/registry.js +509 -0
  267. package/dist/mcp/registry.js.map +1 -0
  268. package/dist/mcp/rest.d.ts +111 -0
  269. package/dist/mcp/rest.d.ts.map +1 -0
  270. package/dist/mcp/rest.js +606 -0
  271. package/dist/mcp/rest.js.map +1 -0
  272. package/dist/mcp/secrets.d.ts +66 -0
  273. package/dist/mcp/secrets.d.ts.map +1 -0
  274. package/dist/mcp/secrets.js +180 -0
  275. package/dist/mcp/secrets.js.map +1 -0
  276. package/dist/mcp/tool-list.d.ts +25 -0
  277. package/dist/mcp/tool-list.d.ts.map +1 -0
  278. package/dist/mcp/tool-list.js +62 -0
  279. package/dist/mcp/tool-list.js.map +1 -0
  280. package/dist/mcp/upstream-error.d.ts +12 -0
  281. package/dist/mcp/upstream-error.d.ts.map +1 -0
  282. package/dist/mcp/upstream-error.js +14 -0
  283. package/dist/mcp/upstream-error.js.map +1 -0
  284. package/dist/mcp/usage.d.ts +31 -0
  285. package/dist/mcp/usage.d.ts.map +1 -0
  286. package/dist/mcp/usage.js +159 -0
  287. package/dist/mcp/usage.js.map +1 -0
  288. package/dist/presets/routes.d.ts +53 -0
  289. package/dist/presets/routes.d.ts.map +1 -0
  290. package/dist/presets/routes.js +115 -0
  291. package/dist/presets/routes.js.map +1 -0
  292. package/dist/projects/activity.d.ts +6 -18
  293. package/dist/projects/activity.d.ts.map +1 -1
  294. package/dist/projects/activity.js +17 -60
  295. package/dist/projects/activity.js.map +1 -1
  296. package/dist/projects/events.d.ts +6 -5
  297. package/dist/projects/events.d.ts.map +1 -1
  298. package/dist/projects/events.js +33 -58
  299. package/dist/projects/events.js.map +1 -1
  300. package/dist/projects/graph.d.ts +11 -0
  301. package/dist/projects/graph.d.ts.map +1 -1
  302. package/dist/projects/graph.js +12 -0
  303. package/dist/projects/graph.js.map +1 -1
  304. package/dist/projects/routes.d.ts.map +1 -1
  305. package/dist/projects/routes.js +19 -0
  306. package/dist/projects/routes.js.map +1 -1
  307. package/dist/projects/state-home-preflight.d.ts.map +1 -1
  308. package/dist/projects/state-home-preflight.js +7 -0
  309. package/dist/projects/state-home-preflight.js.map +1 -1
  310. package/dist/projects/state-home-registry.d.ts.map +1 -1
  311. package/dist/projects/state-home-registry.js +9 -1
  312. package/dist/projects/state-home-registry.js.map +1 -1
  313. package/dist/qe/acceptance.d.ts +28 -28
  314. package/dist/qe/acceptance.d.ts.map +1 -1
  315. package/dist/qe/acceptance.js +60 -61
  316. package/dist/qe/acceptance.js.map +1 -1
  317. package/dist/qe/test-sets.d.ts +3 -5
  318. package/dist/qe/test-sets.d.ts.map +1 -1
  319. package/dist/qe/test-sets.js +5 -7
  320. package/dist/qe/test-sets.js.map +1 -1
  321. package/dist/skills/installed.d.ts +51 -0
  322. package/dist/skills/installed.d.ts.map +1 -0
  323. package/dist/skills/installed.js +46 -0
  324. package/dist/skills/installed.js.map +1 -0
  325. package/dist/skills/phase-skill-gaps.d.ts +108 -0
  326. package/dist/skills/phase-skill-gaps.d.ts.map +1 -0
  327. package/dist/skills/phase-skill-gaps.js +199 -0
  328. package/dist/skills/phase-skill-gaps.js.map +1 -0
  329. package/dist/skills/runtime.d.ts +1 -1
  330. package/dist/skills/runtime.d.ts.map +1 -1
  331. package/dist/skills/runtime.js +2 -1
  332. package/dist/skills/runtime.js.map +1 -1
  333. package/dist/standing-orders/evaluator.d.ts +113 -0
  334. package/dist/standing-orders/evaluator.d.ts.map +1 -0
  335. package/dist/standing-orders/evaluator.js +225 -0
  336. package/dist/standing-orders/evaluator.js.map +1 -0
  337. package/dist/standing-orders/history.d.ts +58 -0
  338. package/dist/standing-orders/history.d.ts.map +1 -0
  339. package/dist/standing-orders/history.js +117 -0
  340. package/dist/standing-orders/history.js.map +1 -0
  341. package/dist/standing-orders/parse.d.ts +19 -0
  342. package/dist/standing-orders/parse.d.ts.map +1 -0
  343. package/dist/standing-orders/parse.js +75 -0
  344. package/dist/standing-orders/parse.js.map +1 -0
  345. package/dist/standing-orders/routes.d.ts +180 -0
  346. package/dist/standing-orders/routes.d.ts.map +1 -0
  347. package/dist/standing-orders/routes.js +95 -0
  348. package/dist/standing-orders/routes.js.map +1 -0
  349. package/dist/standing-orders/store.d.ts +154 -0
  350. package/dist/standing-orders/store.d.ts.map +1 -0
  351. package/dist/standing-orders/store.js +189 -0
  352. package/dist/standing-orders/store.js.map +1 -0
  353. package/dist/studio/assets/index-CvV5qITf.css +32 -0
  354. package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
  355. package/dist/studio/index.html +3 -3
  356. package/dist/studio/testid-inventory.json +3307 -897
  357. package/dist/team/key.d.ts +5 -0
  358. package/dist/team/key.d.ts.map +1 -0
  359. package/dist/team/key.js +21 -0
  360. package/dist/team/key.js.map +1 -0
  361. package/dist/team/routes.d.ts +196 -0
  362. package/dist/team/routes.d.ts.map +1 -0
  363. package/dist/team/routes.js +274 -0
  364. package/dist/team/routes.js.map +1 -0
  365. package/dist/team/ws-relay.d.ts +39 -0
  366. package/dist/team/ws-relay.d.ts.map +1 -0
  367. package/dist/team/ws-relay.js +63 -0
  368. package/dist/team/ws-relay.js.map +1 -0
  369. package/endpoint-manifest.json +502 -6
  370. package/package.json +6 -6
  371. package/dist/interactive/demo-events.d.ts +0 -367
  372. package/dist/interactive/demo-events.d.ts.map +0 -1
  373. package/dist/interactive/demo-events.js +0 -1293
  374. package/dist/interactive/demo-events.js.map +0 -1
  375. package/dist/qe/gate-events.d.ts +0 -113
  376. package/dist/qe/gate-events.d.ts.map +0 -1
  377. package/dist/qe/gate-events.js +0 -172
  378. package/dist/qe/gate-events.js.map +0 -1
  379. package/dist/studio/assets/index-BRDAN35i.js +0 -548
  380. package/dist/studio/assets/index-Drfcsy8b.css +0 -32
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Seat credential PROBE (crew#630, crew#645): ask the seat's own CLI whether it can authenticate,
3
+ * under the seat's own configuration home, instead of inferring it from a file.
4
+ *
5
+ * # The defect
6
+ *
7
+ * `seat-signin.ts` reads presence: claude's `<worker home>/claude/.claude.json` with an
8
+ * `oauthAccount` reads signed in. Claude Code keeps the OAuth token itself in the OS keychain, under
9
+ * a service name keyed by a hash of `CLAUDE_CONFIG_DIR` — so a moved or renamed worker home keeps
10
+ * the file and loses the token, and an expired login keeps both. The roster said `signed_in`,
11
+ * launch trusted it, and every ballot / unit on the seat failed "Not logged in" (crew#630) or "OAuth
12
+ * session expired" (crew#645) after the run was already planned.
13
+ *
14
+ * # The probe
15
+ *
16
+ * The CLI's own auth-status command, where one exists, run with the SAME configuration-home variable
17
+ * the engine sets on that seat's workers (`wicked_apps_core::spawn::seat_config_for`):
18
+ *
19
+ * claude — `claude auth status --json` with `CLAUDE_CONFIG_DIR=<root>/claude` → `loggedIn`.
20
+ * It resolves the keychain entry for THAT config dir, so the moved-home case reads false.
21
+ * codex — `codex login status` with `CODEX_HOME=<root>/codex` → exit 0 = signed in.
22
+ *
23
+ * # A status command is not a session (crew#645, reopened)
24
+ *
25
+ * Both status commands read what is STORED; neither asks the provider. An OAuth login whose access
26
+ * token expired and whose refresh is refused ("OAuth session expired and could not be refreshed")
27
+ * still reads `loggedIn: true`. So when the status command says signed in, the probe makes ONE
28
+ * live, authenticated round-trip on the seat's cheapest path ({@link verifyCommand}), which is the
29
+ * only thing that observes a refused refresh:
30
+ *
31
+ * - exit 0 → signed in, `check: 'live'`;
32
+ * - its output says the seat has no credential (the same {@link isAuthRefusal} words ballots are
33
+ * read with) → signed OUT, with the seat's own words as the evidence;
34
+ * - anything else (timeout, quota, network) cannot tell → the status answer stands as
35
+ * `check: 'status'`, and the roster says the login was not verified live.
36
+ *
37
+ * Seats with no status command (pi, copilot, opencode, agy) are not probed: their reading stays the
38
+ * credential-file heuristic plus the seat's own refusal (`seat-health.ts`), and the roster says the
39
+ * login is unverified (`seat-standing.ts`).
40
+ *
41
+ * # Cost
42
+ *
43
+ * The roster route is read on every studio poll, so the probe NEVER runs on the request path:
44
+ * `read()` answers from a cache synchronously and, when the entry is older than its TTL, starts
45
+ * one refresh in the background (deduplicated per seat, one probe process at a time host-wide
46
+ * for this daemon). A signed-in answer is kept for 5 minutes (so a live check costs at most one
47
+ * one-word request per seat per 5 minutes); a signed-out or unknown one for 30 s, so a seat signed
48
+ * in from the System page turns green on the next poll or two. The cache is keyed by (seat, worker
49
+ * home): changing `worker_config_root` discards every answer at once. A launch awaits a missing or
50
+ * stale answer, bounded, before it routes ({@link SeatProbe.ensureFresh}).
51
+ */
52
+ /** A probe process's outcome, as the runner reports it. `error` is set when it never ran to exit
53
+ * (not installed, timed out, killed). */
54
+ export interface ProbeOutput {
55
+ code: number | null;
56
+ stdout: string;
57
+ stderr: string;
58
+ error?: string;
59
+ }
60
+ /** Runs one probe command — injectable so tests never spawn a CLI. */
61
+ export type ProbeRunner = (cmd: string, args: string[], env: NodeJS.ProcessEnv, timeoutMs: number) => Promise<ProbeOutput>;
62
+ /** How far a probe's answer was checked: `live` — an authenticated request answered (or was
63
+ * refused for want of a credential); `status` — only the CLI's status command answered. */
64
+ export type ProbeCheck = 'live' | 'status';
65
+ /** One seat's probe answer. */
66
+ export interface SeatProbeReading {
67
+ /** `true` the seat authenticates, `false` it does not, `null` the probe could not tell. */
68
+ signedIn: boolean | null;
69
+ /** How far the answer was checked (see {@link ProbeCheck}). */
70
+ check: ProbeCheck;
71
+ /** ISO-8601 of the probe. */
72
+ probedAt: string;
73
+ /** A bounded excerpt of what the CLI said (its own words for a `false`). */
74
+ detail: string;
75
+ }
76
+ /** How long an answer is trusted before a background refresh (the stale answer is served meanwhile). */
77
+ export declare const PROBE_TTL_SIGNED_IN_MS: number;
78
+ export declare const PROBE_TTL_OTHER_MS: number;
79
+ /** A status command is local and fast (~1 s); past this it is not answering. */
80
+ export declare const PROBE_TIMEOUT_MS: number;
81
+ /** The live check is one model request (a CLI start plus one short reply). */
82
+ export declare const VERIFY_TIMEOUT_MS: number;
83
+ /** How long a launch waits for missing or stale answers before it routes on what it has. */
84
+ export declare const LAUNCH_PROBE_WAIT_MS: number;
85
+ type Command = {
86
+ cmd: string;
87
+ args: string[];
88
+ env: NodeJS.ProcessEnv;
89
+ };
90
+ /** The probe command for a seat, or `null` when the seat's CLI has no auth-status command. */
91
+ export declare function probeCommand(seatKey: string, workerRoot: string | undefined, env?: NodeJS.ProcessEnv, home?: string): Command | null;
92
+ /** The live check for a seat whose status command said signed in (see the module doc). */
93
+ export declare function verifyCommand(seatKey: string, workerRoot: string | undefined, env?: NodeJS.ProcessEnv, home?: string): Command | null;
94
+ /** Read a probe's outcome: `null` when it did not run to an answer (missing CLI, timeout). */
95
+ export declare function classifyProbe(seatKey: string, out: ProbeOutput): boolean | null;
96
+ /** Read the live check: `true` it answered, `false` it was refused for want of a credential,
97
+ * `null` it could not tell (timeout, quota, network, an unknown failure). */
98
+ export declare function classifyVerify(out: ProbeOutput): boolean | null;
99
+ /** The production runner: `execFile` with a timeout, never a shell, stdin closed (claude `-p`
100
+ * otherwise waits for piped input). Runs in the OS temp dir, so no project context is loaded. */
101
+ export declare const execProbe: ProbeRunner;
102
+ export interface SeatProbeOptions {
103
+ run?: ProbeRunner;
104
+ now?: () => number;
105
+ env?: NodeJS.ProcessEnv;
106
+ home?: string;
107
+ }
108
+ /** The per-daemon probe cache (see the module doc). */
109
+ export declare class SeatProbe {
110
+ private readonly cache;
111
+ private readonly inflight;
112
+ /** One probe process at a time: each refresh chains onto this. */
113
+ private queue;
114
+ private readonly run;
115
+ private readonly now;
116
+ private readonly env;
117
+ private readonly home;
118
+ constructor(opts?: SeatProbeOptions);
119
+ /** Whether this seat has a probe at all. */
120
+ probes(seatKey: string): boolean;
121
+ /**
122
+ * The cached answer for `seatKey` under `workerRoot` (`undefined` before the first probe
123
+ * finishes, or for a seat with no probe). Never waits: a missing or stale answer starts one
124
+ * background refresh.
125
+ */
126
+ read(seatKey: string, workerRoot: string | undefined): SeatProbeReading | undefined;
127
+ /**
128
+ * Before a launch routes: probe every probed seat whose answer is missing or stale and wait for
129
+ * the answers, at most `waitMs` (a probe that is slower keeps running in the background, and the
130
+ * seat reads as it would have without the wait).
131
+ */
132
+ ensureFresh(seatKeys: string[], workerRoot: string | undefined, waitMs?: number): Promise<void>;
133
+ /** Probe now (deduplicated per seat and worker home); resolves to the fresh answer. */
134
+ refresh(seatKey: string, workerRoot: string | undefined): Promise<SeatProbeReading | undefined>;
135
+ /** The status command, then — when it says signed in — the live check. */
136
+ private probeOnce;
137
+ private reading;
138
+ private stale;
139
+ }
140
+ export {};
141
+ //# sourceMappingURL=seat-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-probe.d.ts","sourceRoot":"","sources":["../../src/api/seat-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Seat credential PROBE (crew#630, crew#645): ask the seat's own CLI whether it can authenticate,
3
+ * under the seat's own configuration home, instead of inferring it from a file.
4
+ *
5
+ * # The defect
6
+ *
7
+ * `seat-signin.ts` reads presence: claude's `<worker home>/claude/.claude.json` with an
8
+ * `oauthAccount` reads signed in. Claude Code keeps the OAuth token itself in the OS keychain, under
9
+ * a service name keyed by a hash of `CLAUDE_CONFIG_DIR` — so a moved or renamed worker home keeps
10
+ * the file and loses the token, and an expired login keeps both. The roster said `signed_in`,
11
+ * launch trusted it, and every ballot / unit on the seat failed "Not logged in" (crew#630) or "OAuth
12
+ * session expired" (crew#645) after the run was already planned.
13
+ *
14
+ * # The probe
15
+ *
16
+ * The CLI's own auth-status command, where one exists, run with the SAME configuration-home variable
17
+ * the engine sets on that seat's workers (`wicked_apps_core::spawn::seat_config_for`):
18
+ *
19
+ * claude — `claude auth status --json` with `CLAUDE_CONFIG_DIR=<root>/claude` → `loggedIn`.
20
+ * It resolves the keychain entry for THAT config dir, so the moved-home case reads false.
21
+ * codex — `codex login status` with `CODEX_HOME=<root>/codex` → exit 0 = signed in.
22
+ *
23
+ * # A status command is not a session (crew#645, reopened)
24
+ *
25
+ * Both status commands read what is STORED; neither asks the provider. An OAuth login whose access
26
+ * token expired and whose refresh is refused ("OAuth session expired and could not be refreshed")
27
+ * still reads `loggedIn: true`. So when the status command says signed in, the probe makes ONE
28
+ * live, authenticated round-trip on the seat's cheapest path ({@link verifyCommand}), which is the
29
+ * only thing that observes a refused refresh:
30
+ *
31
+ * - exit 0 → signed in, `check: 'live'`;
32
+ * - its output says the seat has no credential (the same {@link isAuthRefusal} words ballots are
33
+ * read with) → signed OUT, with the seat's own words as the evidence;
34
+ * - anything else (timeout, quota, network) cannot tell → the status answer stands as
35
+ * `check: 'status'`, and the roster says the login was not verified live.
36
+ *
37
+ * Seats with no status command (pi, copilot, opencode, agy) are not probed: their reading stays the
38
+ * credential-file heuristic plus the seat's own refusal (`seat-health.ts`), and the roster says the
39
+ * login is unverified (`seat-standing.ts`).
40
+ *
41
+ * # Cost
42
+ *
43
+ * The roster route is read on every studio poll, so the probe NEVER runs on the request path:
44
+ * `read()` answers from a cache synchronously and, when the entry is older than its TTL, starts
45
+ * one refresh in the background (deduplicated per seat, one probe process at a time host-wide
46
+ * for this daemon). A signed-in answer is kept for 5 minutes (so a live check costs at most one
47
+ * one-word request per seat per 5 minutes); a signed-out or unknown one for 30 s, so a seat signed
48
+ * in from the System page turns green on the next poll or two. The cache is keyed by (seat, worker
49
+ * home): changing `worker_config_root` discards every answer at once. A launch awaits a missing or
50
+ * stale answer, bounded, before it routes ({@link SeatProbe.ensureFresh}).
51
+ */
52
+ import { execFile } from 'node:child_process';
53
+ import { homedir, tmpdir } from 'node:os';
54
+ import { join } from 'node:path';
55
+ import { childEnvWithBootEstateDb } from '../core/governance-store.js';
56
+ import { isAuthRefusal } from './seat-health.js';
57
+ /** How long an answer is trusted before a background refresh (the stale answer is served meanwhile). */
58
+ export const PROBE_TTL_SIGNED_IN_MS = 5 * 60 * 1000;
59
+ export const PROBE_TTL_OTHER_MS = 30 * 1000;
60
+ /** A status command is local and fast (~1 s); past this it is not answering. */
61
+ export const PROBE_TIMEOUT_MS = 15 * 1000;
62
+ /** The live check is one model request (a CLI start plus one short reply). */
63
+ export const VERIFY_TIMEOUT_MS = 60 * 1000;
64
+ /** How long a launch waits for missing or stale answers before it routes on what it has. */
65
+ export const LAUNCH_PROBE_WAIT_MS = 20 * 1000;
66
+ const DETAIL_MAX = 240;
67
+ const VERIFY_PROMPT = 'Reply with the single word OK.';
68
+ function excerpt(s) {
69
+ const flat = s.replace(/\s+/g, ' ').trim();
70
+ return flat.length <= DETAIL_MAX ? flat : `${flat.slice(0, DETAIL_MAX - 1)}…`;
71
+ }
72
+ /** The seat's configuration-home variable, as the engine sets it on the seat's workers. */
73
+ function seatEnv(seatKey, workerRoot, env, home) {
74
+ const name = seatKey === 'claude' ? 'CLAUDE_CONFIG_DIR' : seatKey === 'codex' ? 'CODEX_HOME' : null;
75
+ if (name === null)
76
+ return null;
77
+ // The engine's one hatch: set, every seat runs on the operator's own CLI homes (no override).
78
+ if (env['WICKED_WORKER_INHERIT_OPERATOR_CONFIG'] !== undefined)
79
+ return { ...env };
80
+ const root = workerRoot !== undefined && workerRoot !== '' ? workerRoot : join(home, '.wicked-worker');
81
+ return { ...env, [name]: join(root, seatKey) };
82
+ }
83
+ /** The probe command for a seat, or `null` when the seat's CLI has no auth-status command. */
84
+ export function probeCommand(seatKey, workerRoot, env = process.env, home = homedir()) {
85
+ const e = seatEnv(seatKey, workerRoot, env, home);
86
+ if (e === null)
87
+ return null;
88
+ return seatKey === 'claude'
89
+ ? { cmd: 'claude', args: ['auth', 'status', '--json'], env: e }
90
+ : { cmd: 'codex', args: ['login', 'status'], env: e };
91
+ }
92
+ /** The live check for a seat whose status command said signed in (see the module doc). */
93
+ export function verifyCommand(seatKey, workerRoot, env = process.env, home = homedir()) {
94
+ const e = seatEnv(seatKey, workerRoot, env, home);
95
+ if (e === null)
96
+ return null;
97
+ return seatKey === 'claude'
98
+ ? {
99
+ cmd: 'claude',
100
+ args: ['-p', '--no-session-persistence', '--strict-mcp-config', '--tools', '', '--model', 'haiku', VERIFY_PROMPT],
101
+ env: e,
102
+ }
103
+ : { cmd: 'codex', args: ['exec', '--skip-git-repo-check', '--ephemeral', '--sandbox', 'read-only', VERIFY_PROMPT], env: e };
104
+ }
105
+ /** Read a probe's outcome: `null` when it did not run to an answer (missing CLI, timeout). */
106
+ export function classifyProbe(seatKey, out) {
107
+ if (out.error !== undefined || out.code === null)
108
+ return null;
109
+ if (seatKey === 'claude') {
110
+ try {
111
+ const parsed = JSON.parse(out.stdout);
112
+ if (typeof parsed.loggedIn === 'boolean')
113
+ return parsed.loggedIn;
114
+ }
115
+ catch {
116
+ /* not JSON: fall through to the exit code */
117
+ }
118
+ }
119
+ if (out.code === 0)
120
+ return true;
121
+ return /not logged in|logged out|not authenticated/i.test(`${out.stdout}\n${out.stderr}`) ? false : null;
122
+ }
123
+ /** Read the live check: `true` it answered, `false` it was refused for want of a credential,
124
+ * `null` it could not tell (timeout, quota, network, an unknown failure). */
125
+ export function classifyVerify(out) {
126
+ if (out.error === undefined && out.code === 0)
127
+ return true;
128
+ return isAuthRefusal(`${out.stdout}\n${out.stderr}`) ? false : null;
129
+ }
130
+ /** The production runner: `execFile` with a timeout, never a shell, stdin closed (claude `-p`
131
+ * otherwise waits for piped input). Runs in the OS temp dir, so no project context is loaded. */
132
+ export const execProbe = (cmd, args, env, timeoutMs) => new Promise((resolve) => {
133
+ // The engine-only store variables go back to their BOOT values, as for every crew child (crew#495).
134
+ const child = execFile(cmd, args, { env: childEnvWithBootEstateDb(env), cwd: tmpdir(), timeout: timeoutMs, windowsHide: true, maxBuffer: 256 * 1024 }, (err, stdout, stderr) => {
135
+ // A non-zero exit carries its exit code as a NUMBER `code`; a spawn failure (ENOENT) a
136
+ // string one; a timeout kills the child (`killed`, no code).
137
+ const e = err;
138
+ const out = { stdout: String(stdout ?? ''), stderr: String(stderr ?? '') };
139
+ if (e === null)
140
+ resolve({ code: 0, ...out });
141
+ else if (typeof e.code === 'number' && e.killed !== true)
142
+ resolve({ code: e.code, ...out });
143
+ else
144
+ resolve({ code: null, ...out, error: e.message });
145
+ });
146
+ child.stdin?.on('error', () => undefined);
147
+ child.stdin?.end();
148
+ });
149
+ /** The per-daemon probe cache (see the module doc). */
150
+ export class SeatProbe {
151
+ cache = new Map();
152
+ inflight = new Map();
153
+ /** One probe process at a time: each refresh chains onto this. */
154
+ queue = Promise.resolve();
155
+ run;
156
+ now;
157
+ env;
158
+ home;
159
+ constructor(opts = {}) {
160
+ this.run = opts.run ?? execProbe;
161
+ this.now = opts.now ?? Date.now;
162
+ this.env = opts.env;
163
+ this.home = opts.home;
164
+ }
165
+ /** Whether this seat has a probe at all. */
166
+ probes(seatKey) {
167
+ return probeCommand(seatKey, undefined, this.env ?? process.env, this.home) !== null;
168
+ }
169
+ /**
170
+ * The cached answer for `seatKey` under `workerRoot` (`undefined` before the first probe
171
+ * finishes, or for a seat with no probe). Never waits: a missing or stale answer starts one
172
+ * background refresh.
173
+ */
174
+ read(seatKey, workerRoot) {
175
+ if (!this.probes(seatKey))
176
+ return undefined;
177
+ const hit = this.cache.get(cacheKey(seatKey, workerRoot));
178
+ if (hit === undefined || this.stale(hit))
179
+ void this.refresh(seatKey, workerRoot);
180
+ if (hit === undefined)
181
+ return undefined;
182
+ return { signedIn: hit.signedIn, check: hit.check, probedAt: hit.probedAt, detail: hit.detail };
183
+ }
184
+ /**
185
+ * Before a launch routes: probe every probed seat whose answer is missing or stale and wait for
186
+ * the answers, at most `waitMs` (a probe that is slower keeps running in the background, and the
187
+ * seat reads as it would have without the wait).
188
+ */
189
+ async ensureFresh(seatKeys, workerRoot, waitMs = LAUNCH_PROBE_WAIT_MS) {
190
+ const jobs = seatKeys
191
+ .filter((k) => this.probes(k))
192
+ .filter((k) => {
193
+ const hit = this.cache.get(cacheKey(k, workerRoot));
194
+ return hit === undefined || this.stale(hit);
195
+ })
196
+ .map((k) => this.refresh(k, workerRoot));
197
+ if (jobs.length === 0)
198
+ return;
199
+ let timer;
200
+ const deadline = new Promise((resolve) => {
201
+ timer = setTimeout(resolve, waitMs);
202
+ timer.unref();
203
+ });
204
+ await Promise.race([Promise.all(jobs).then(() => undefined), deadline]);
205
+ clearTimeout(timer);
206
+ }
207
+ /** Probe now (deduplicated per seat and worker home); resolves to the fresh answer. */
208
+ refresh(seatKey, workerRoot) {
209
+ const key = cacheKey(seatKey, workerRoot);
210
+ const running = this.inflight.get(key);
211
+ if (running !== undefined)
212
+ return running;
213
+ const env = this.env ?? process.env;
214
+ const command = probeCommand(seatKey, workerRoot, env, this.home);
215
+ if (command === null)
216
+ return Promise.resolve(undefined);
217
+ const job = this.queue
218
+ .catch(() => undefined)
219
+ .then(() => this.probeOnce(seatKey, command, verifyCommand(seatKey, workerRoot, env, this.home)))
220
+ .then((reading) => {
221
+ this.cache.set(key, { ...reading, atMs: Date.parse(reading.probedAt) });
222
+ return reading;
223
+ })
224
+ .catch(() => undefined)
225
+ .finally(() => this.inflight.delete(key));
226
+ this.queue = job;
227
+ this.inflight.set(key, job);
228
+ return job;
229
+ }
230
+ /** The status command, then — when it says signed in — the live check. */
231
+ async probeOnce(seatKey, status, verify) {
232
+ const out = await this.run(status.cmd, status.args, status.env, PROBE_TIMEOUT_MS);
233
+ const said = classifyProbe(seatKey, out);
234
+ const statusWords = excerpt(out.error ?? `${out.stdout}\n${out.stderr}`);
235
+ if (said !== true || verify === null)
236
+ return this.reading(said, 'status', statusWords);
237
+ const live = await this.run(verify.cmd, verify.args, verify.env, VERIFY_TIMEOUT_MS);
238
+ const verdict = classifyVerify(live);
239
+ const liveWords = excerpt(live.error ?? `${live.stdout}\n${live.stderr}`);
240
+ if (verdict === false)
241
+ return this.reading(false, 'live', liveWords);
242
+ if (verdict === true)
243
+ return this.reading(true, 'live', statusWords);
244
+ return this.reading(true, 'status', `the live check could not tell (${liveWords}); status: ${statusWords}`);
245
+ }
246
+ reading(signedIn, check, detail) {
247
+ return { signedIn, check, probedAt: new Date(this.now()).toISOString(), detail };
248
+ }
249
+ stale(hit) {
250
+ const ttl = hit.signedIn === true ? PROBE_TTL_SIGNED_IN_MS : PROBE_TTL_OTHER_MS;
251
+ return this.now() - hit.atMs >= ttl;
252
+ }
253
+ }
254
+ function cacheKey(seatKey, workerRoot) {
255
+ return `${seatKey}\u0000${workerRoot ?? ''}`;
256
+ }
257
+ //# sourceMappingURL=seat-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-probe.js","sourceRoot":"","sources":["../../src/api/seat-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The seat record: each seat's week, folded from the runs' durable event logs (studio's weekly
3
+ * 1:1 per agent). `GET /roster/record?days=7`.
4
+ *
5
+ * Nothing new is stored. The fold reads what the engine already records per run:
6
+ *
7
+ * - who ran a unit: `unitDistributed.cli`, moved by `unitReassigned.newCli`; a unit no frame
8
+ * names falls back to the unit row's `assigned_cli`;
9
+ * - units run: the distinct units a seat was dispatched on (`unitDispatched`) inside the window;
10
+ * - first pass: the unit's FIRST `gateEvaluated` in the window passed (`combined` and no `denial`);
11
+ * `gated` is how many units had a gate evaluation at all;
12
+ * - rework: a unit dispatched more than once (a retry or a send-back) or given a
13
+ * `unitReworkAmended`, counted against the seat that ran its first dispatch;
14
+ * - stalls: distinct units that went quiet (`workerStalled`, the engine's or the daemon
15
+ * watchdog's), against the seat running the unit then;
16
+ * - benched: runs whose `benched_seats` names the seat, with the reasons;
17
+ * - cost: the sum of `cliUsage.costUsd` where a price was known; `null` when none was.
18
+ *
19
+ * The window is by event time (`ts`, millis). A run that ended before the window opened is not
20
+ * read at all; the reads are capped at {@link SEAT_RECORD_RUN_CAP} runs, newest first, and the
21
+ * answer says when the cap cut.
22
+ */
23
+ import type { RecordedEvent, SeatRecord, SeatRecordResponse, SessionView } from '../core/types.js';
24
+ export declare const SEAT_RECORD_DEFAULT_DAYS = 7;
25
+ export declare const SEAT_RECORD_MAX_DAYS = 30;
26
+ export declare const SEAT_RECORD_RUN_CAP = 200;
27
+ /** Whether a run can have any event inside the window: it ended in it, or has not ended. */
28
+ export declare function runTouchesWindow(view: SessionView, since: number): boolean;
29
+ /** Fold one run's events into the seat map. `since` is the window start, unix millis. */
30
+ export declare function foldRunIntoSeats(seats: Map<string, SeatRecord>, view: SessionView, events: readonly RecordedEvent[], since: number): void;
31
+ /**
32
+ * The whole read: pick the runs that can touch the window (newest first, capped), read each log,
33
+ * fold. `readEvents` answers `null` when the engine has no event-log binding — the caller turns
34
+ * that into a 503 (a missing binding is not an empty week).
35
+ */
36
+ export declare function seatRecord(views: readonly SessionView[], readEvents: (runId: string) => Promise<readonly RecordedEvent[] | null>, opts: {
37
+ days: number;
38
+ now: number;
39
+ }): Promise<SeatRecordResponse | null>;
40
+ //# sourceMappingURL=seat-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-record.d.ts","sourceRoot":"","sources":["../../src/api/seat-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAEV,aAAa,EAEb,UAAU,EACV,kBAAkB,EAClB,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAavC,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAM1E;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,MAAM,GACZ,IAAI,CA6HN;AAOD;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC,EACvE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAwBpC"}