trail-code 0.0.0-stage → 0.28.0-semantic.3

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 (593) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +567 -2
  3. package/dist/ai/crux.d.ts +88 -0
  4. package/dist/ai/crux.d.ts.map +1 -0
  5. package/dist/ai/crux.js +219 -0
  6. package/dist/ai/crux.js.map +1 -0
  7. package/dist/ai/failure.d.ts +60 -0
  8. package/dist/ai/failure.d.ts.map +1 -0
  9. package/dist/ai/failure.js +86 -0
  10. package/dist/ai/failure.js.map +1 -0
  11. package/dist/ai/llm/anthropic.d.ts +37 -0
  12. package/dist/ai/llm/anthropic.d.ts.map +1 -0
  13. package/dist/ai/llm/anthropic.js +144 -0
  14. package/dist/ai/llm/anthropic.js.map +1 -0
  15. package/dist/ai/llm/factory.d.ts +28 -0
  16. package/dist/ai/llm/factory.d.ts.map +1 -0
  17. package/dist/ai/llm/factory.js +36 -0
  18. package/dist/ai/llm/factory.js.map +1 -0
  19. package/dist/ai/llm/litellm.d.ts +34 -0
  20. package/dist/ai/llm/litellm.d.ts.map +1 -0
  21. package/dist/ai/llm/litellm.js +45 -0
  22. package/dist/ai/llm/litellm.js.map +1 -0
  23. package/dist/ai/llm/openai.d.ts +145 -0
  24. package/dist/ai/llm/openai.d.ts.map +1 -0
  25. package/dist/ai/llm/openai.js +629 -0
  26. package/dist/ai/llm/openai.js.map +1 -0
  27. package/dist/ai/llm/orcarouter.d.ts +34 -0
  28. package/dist/ai/llm/orcarouter.d.ts.map +1 -0
  29. package/dist/ai/llm/orcarouter.js +45 -0
  30. package/dist/ai/llm/orcarouter.js.map +1 -0
  31. package/dist/ai/llm/recover-tool.d.ts +21 -0
  32. package/dist/ai/llm/recover-tool.d.ts.map +1 -0
  33. package/dist/ai/llm/recover-tool.js +109 -0
  34. package/dist/ai/llm/recover-tool.js.map +1 -0
  35. package/dist/ai/llm/types.d.ts +122 -0
  36. package/dist/ai/llm/types.d.ts.map +1 -0
  37. package/dist/ai/llm/types.js +33 -0
  38. package/dist/ai/llm/types.js.map +1 -0
  39. package/dist/ai/providers.d.ts +59 -0
  40. package/dist/ai/providers.d.ts.map +1 -0
  41. package/dist/ai/providers.js +54 -0
  42. package/dist/ai/providers.js.map +1 -0
  43. package/dist/ai/summarize.d.ts +25 -0
  44. package/dist/ai/summarize.d.ts.map +1 -0
  45. package/dist/ai/summarize.js +34 -0
  46. package/dist/ai/summarize.js.map +1 -0
  47. package/dist/ai/synthesize.d.ts +40 -0
  48. package/dist/ai/synthesize.d.ts.map +1 -0
  49. package/dist/ai/synthesize.js +230 -0
  50. package/dist/ai/synthesize.js.map +1 -0
  51. package/dist/ask/ask.d.ts +199 -0
  52. package/dist/ask/ask.d.ts.map +1 -0
  53. package/dist/ask/ask.js +1291 -0
  54. package/dist/ask/ask.js.map +1 -0
  55. package/dist/ask/file-rank.d.ts +72 -0
  56. package/dist/ask/file-rank.d.ts.map +1 -0
  57. package/dist/ask/file-rank.js +160 -0
  58. package/dist/ask/file-rank.js.map +1 -0
  59. package/dist/ask/file-selection.d.ts +22 -0
  60. package/dist/ask/file-selection.d.ts.map +1 -0
  61. package/dist/ask/file-selection.js +66 -0
  62. package/dist/ask/file-selection.js.map +1 -0
  63. package/dist/ask/fuse.d.ts +195 -0
  64. package/dist/ask/fuse.d.ts.map +1 -0
  65. package/dist/ask/fuse.js +344 -0
  66. package/dist/ask/fuse.js.map +1 -0
  67. package/dist/ask/graphrank.d.ts +61 -0
  68. package/dist/ask/graphrank.d.ts.map +1 -0
  69. package/dist/ask/graphrank.js +130 -0
  70. package/dist/ask/graphrank.js.map +1 -0
  71. package/dist/ask/index-file.d.ts +44 -0
  72. package/dist/ask/index-file.d.ts.map +1 -0
  73. package/dist/ask/index-file.js +128 -0
  74. package/dist/ask/index-file.js.map +1 -0
  75. package/dist/ask/semantic.d.ts +42 -0
  76. package/dist/ask/semantic.d.ts.map +1 -0
  77. package/dist/ask/semantic.js +293 -0
  78. package/dist/ask/semantic.js.map +1 -0
  79. package/dist/bin/graft.d.ts +3 -0
  80. package/dist/bin/graft.d.ts.map +1 -0
  81. package/dist/bin/graft.js +14 -0
  82. package/dist/bin/graft.js.map +1 -0
  83. package/dist/bin/trail.d.ts +3 -0
  84. package/dist/bin/trail.d.ts.map +1 -0
  85. package/dist/bin/trail.js +13 -0
  86. package/dist/bin/trail.js.map +1 -0
  87. package/dist/blast/blast-cli.d.ts +35 -0
  88. package/dist/blast/blast-cli.d.ts.map +1 -0
  89. package/dist/blast/blast-cli.js +155 -0
  90. package/dist/blast/blast-cli.js.map +1 -0
  91. package/dist/blast/blast.d.ts +128 -0
  92. package/dist/blast/blast.d.ts.map +1 -0
  93. package/dist/blast/blast.js +383 -0
  94. package/dist/blast/blast.js.map +1 -0
  95. package/dist/blast/diff.d.ts +53 -0
  96. package/dist/blast/diff.d.ts.map +1 -0
  97. package/dist/blast/diff.js +193 -0
  98. package/dist/blast/diff.js.map +1 -0
  99. package/dist/blast/evidence.d.ts +51 -0
  100. package/dist/blast/evidence.d.ts.map +1 -0
  101. package/dist/blast/evidence.js +162 -0
  102. package/dist/blast/evidence.js.map +1 -0
  103. package/dist/blast/modules.d.ts +33 -0
  104. package/dist/blast/modules.d.ts.map +1 -0
  105. package/dist/blast/modules.js +83 -0
  106. package/dist/blast/modules.js.map +1 -0
  107. package/dist/blast/name.d.ts +74 -0
  108. package/dist/blast/name.d.ts.map +1 -0
  109. package/dist/blast/name.js +269 -0
  110. package/dist/blast/name.js.map +1 -0
  111. package/dist/blast/owners.d.ts +85 -0
  112. package/dist/blast/owners.d.ts.map +1 -0
  113. package/dist/blast/owners.js +272 -0
  114. package/dist/blast/owners.js.map +1 -0
  115. package/dist/blast/render.d.ts +46 -0
  116. package/dist/blast/render.d.ts.map +1 -0
  117. package/dist/blast/render.js +422 -0
  118. package/dist/blast/render.js.map +1 -0
  119. package/dist/blast/viz.d.ts +37 -0
  120. package/dist/blast/viz.d.ts.map +1 -0
  121. package/dist/blast/viz.js +180 -0
  122. package/dist/blast/viz.js.map +1 -0
  123. package/dist/brand.d.ts +111 -0
  124. package/dist/brand.d.ts.map +1 -0
  125. package/dist/brand.js +282 -0
  126. package/dist/brand.js.map +1 -0
  127. package/dist/claude/build-progress.d.ts +30 -0
  128. package/dist/claude/build-progress.d.ts.map +1 -0
  129. package/dist/claude/build-progress.js +81 -0
  130. package/dist/claude/build-progress.js.map +1 -0
  131. package/dist/claude/hermes-skill-template.d.ts +16 -0
  132. package/dist/claude/hermes-skill-template.d.ts.map +1 -0
  133. package/dist/claude/hermes-skill-template.js +154 -0
  134. package/dist/claude/hermes-skill-template.js.map +1 -0
  135. package/dist/claude/init.d.ts +65 -0
  136. package/dist/claude/init.d.ts.map +1 -0
  137. package/dist/claude/init.js +258 -0
  138. package/dist/claude/init.js.map +1 -0
  139. package/dist/claude/paths.d.ts +9 -0
  140. package/dist/claude/paths.d.ts.map +1 -0
  141. package/dist/claude/paths.js +22 -0
  142. package/dist/claude/paths.js.map +1 -0
  143. package/dist/claude/session-metrics.d.ts +73 -0
  144. package/dist/claude/session-metrics.d.ts.map +1 -0
  145. package/dist/claude/session-metrics.js +209 -0
  146. package/dist/claude/session-metrics.js.map +1 -0
  147. package/dist/claude/settings-merge.d.ts +76 -0
  148. package/dist/claude/settings-merge.d.ts.map +1 -0
  149. package/dist/claude/settings-merge.js +283 -0
  150. package/dist/claude/settings-merge.js.map +1 -0
  151. package/dist/claude/skill-template.d.ts +13 -0
  152. package/dist/claude/skill-template.d.ts.map +1 -0
  153. package/dist/claude/skill-template.js +290 -0
  154. package/dist/claude/skill-template.js.map +1 -0
  155. package/dist/claude/state.d.ts +85 -0
  156. package/dist/claude/state.d.ts.map +1 -0
  157. package/dist/claude/state.js +88 -0
  158. package/dist/claude/state.js.map +1 -0
  159. package/dist/claude/stats.d.ts +5 -0
  160. package/dist/claude/stats.d.ts.map +1 -0
  161. package/dist/claude/stats.js +24 -0
  162. package/dist/claude/stats.js.map +1 -0
  163. package/dist/cli-epilogue.d.ts +12 -0
  164. package/dist/cli-epilogue.d.ts.map +1 -0
  165. package/dist/cli-epilogue.js +72 -0
  166. package/dist/cli-epilogue.js.map +1 -0
  167. package/dist/cli-meta.d.ts +82 -0
  168. package/dist/cli-meta.d.ts.map +1 -0
  169. package/dist/cli-meta.js +238 -0
  170. package/dist/cli-meta.js.map +1 -0
  171. package/dist/cli-picker.d.ts +139 -0
  172. package/dist/cli-picker.d.ts.map +1 -0
  173. package/dist/cli-picker.js +439 -0
  174. package/dist/cli-picker.js.map +1 -0
  175. package/dist/cli.d.ts +3 -0
  176. package/dist/cli.d.ts.map +1 -0
  177. package/dist/cli.js +1638 -0
  178. package/dist/cli.js.map +1 -0
  179. package/dist/context/batches.d.ts +29 -0
  180. package/dist/context/batches.d.ts.map +1 -0
  181. package/dist/context/batches.js +130 -0
  182. package/dist/context/batches.js.map +1 -0
  183. package/dist/context/build.d.ts +57 -0
  184. package/dist/context/build.d.ts.map +1 -0
  185. package/dist/context/build.js +396 -0
  186. package/dist/context/build.js.map +1 -0
  187. package/dist/context/check.d.ts +42 -0
  188. package/dist/context/check.d.ts.map +1 -0
  189. package/dist/context/check.js +162 -0
  190. package/dist/context/check.js.map +1 -0
  191. package/dist/context/map-dir.d.ts +13 -0
  192. package/dist/context/map-dir.d.ts.map +1 -0
  193. package/dist/context/map-dir.js +81 -0
  194. package/dist/context/map-dir.js.map +1 -0
  195. package/dist/context/node-file.d.ts +109 -0
  196. package/dist/context/node-file.d.ts.map +1 -0
  197. package/dist/context/node-file.js +390 -0
  198. package/dist/context/node-file.js.map +1 -0
  199. package/dist/context/price.d.ts +49 -0
  200. package/dist/context/price.d.ts.map +1 -0
  201. package/dist/context/price.js +83 -0
  202. package/dist/context/price.js.map +1 -0
  203. package/dist/context/savings.d.ts +67 -0
  204. package/dist/context/savings.d.ts.map +1 -0
  205. package/dist/context/savings.js +125 -0
  206. package/dist/context/savings.js.map +1 -0
  207. package/dist/engine.d.ts +85 -0
  208. package/dist/engine.d.ts.map +1 -0
  209. package/dist/engine.js +122 -0
  210. package/dist/engine.js.map +1 -0
  211. package/dist/graph/bindings.d.ts +64 -0
  212. package/dist/graph/bindings.d.ts.map +1 -0
  213. package/dist/graph/bindings.js +713 -0
  214. package/dist/graph/bindings.js.map +1 -0
  215. package/dist/graph/build-run.d.ts +25 -0
  216. package/dist/graph/build-run.d.ts.map +1 -0
  217. package/dist/graph/build-run.js +121 -0
  218. package/dist/graph/build-run.js.map +1 -0
  219. package/dist/graph/build.d.ts +88 -0
  220. package/dist/graph/build.d.ts.map +1 -0
  221. package/dist/graph/build.js +386 -0
  222. package/dist/graph/build.js.map +1 -0
  223. package/dist/graph/cards.d.ts +46 -0
  224. package/dist/graph/cards.d.ts.map +1 -0
  225. package/dist/graph/cards.js +280 -0
  226. package/dist/graph/cards.js.map +1 -0
  227. package/dist/graph/check.d.ts +25 -0
  228. package/dist/graph/check.d.ts.map +1 -0
  229. package/dist/graph/check.js +192 -0
  230. package/dist/graph/check.js.map +1 -0
  231. package/dist/graph/container.d.ts +63 -0
  232. package/dist/graph/container.d.ts.map +1 -0
  233. package/dist/graph/container.js +191 -0
  234. package/dist/graph/container.js.map +1 -0
  235. package/dist/graph/depth-parser.d.ts +61 -0
  236. package/dist/graph/depth-parser.d.ts.map +1 -0
  237. package/dist/graph/depth-parser.js +153 -0
  238. package/dist/graph/depth-parser.js.map +1 -0
  239. package/dist/graph/enrich.d.ts +62 -0
  240. package/dist/graph/enrich.d.ts.map +1 -0
  241. package/dist/graph/enrich.js +258 -0
  242. package/dist/graph/enrich.js.map +1 -0
  243. package/dist/graph/extract-cache.d.ts +101 -0
  244. package/dist/graph/extract-cache.d.ts.map +1 -0
  245. package/dist/graph/extract-cache.js +199 -0
  246. package/dist/graph/extract-cache.js.map +1 -0
  247. package/dist/graph/extract.d.ts +85 -0
  248. package/dist/graph/extract.d.ts.map +1 -0
  249. package/dist/graph/extract.js +2377 -0
  250. package/dist/graph/extract.js.map +1 -0
  251. package/dist/graph/fingerprint.d.ts +76 -0
  252. package/dist/graph/fingerprint.d.ts.map +1 -0
  253. package/dist/graph/fingerprint.js +160 -0
  254. package/dist/graph/fingerprint.js.map +1 -0
  255. package/dist/graph/generic.d.ts +74 -0
  256. package/dist/graph/generic.d.ts.map +1 -0
  257. package/dist/graph/generic.js +773 -0
  258. package/dist/graph/generic.js.map +1 -0
  259. package/dist/graph/invariants.d.ts +33 -0
  260. package/dist/graph/invariants.d.ts.map +1 -0
  261. package/dist/graph/invariants.js +52 -0
  262. package/dist/graph/invariants.js.map +1 -0
  263. package/dist/graph/load.d.ts +29 -0
  264. package/dist/graph/load.d.ts.map +1 -0
  265. package/dist/graph/load.js +97 -0
  266. package/dist/graph/load.js.map +1 -0
  267. package/dist/graph/lsp/client.d.ts +61 -0
  268. package/dist/graph/lsp/client.d.ts.map +1 -0
  269. package/dist/graph/lsp/client.js +217 -0
  270. package/dist/graph/lsp/client.js.map +1 -0
  271. package/dist/graph/lsp/enrich.d.ts +11 -0
  272. package/dist/graph/lsp/enrich.d.ts.map +1 -0
  273. package/dist/graph/lsp/enrich.js +163 -0
  274. package/dist/graph/lsp/enrich.js.map +1 -0
  275. package/dist/graph/lsp/registry.d.ts +22 -0
  276. package/dist/graph/lsp/registry.d.ts.map +1 -0
  277. package/dist/graph/lsp/registry.js +71 -0
  278. package/dist/graph/lsp/registry.js.map +1 -0
  279. package/dist/graph/map.d.ts +107 -0
  280. package/dist/graph/map.d.ts.map +1 -0
  281. package/dist/graph/map.js +239 -0
  282. package/dist/graph/map.js.map +1 -0
  283. package/dist/graph/markdown.d.ts +22 -0
  284. package/dist/graph/markdown.d.ts.map +1 -0
  285. package/dist/graph/markdown.js +143 -0
  286. package/dist/graph/markdown.js.map +1 -0
  287. package/dist/graph/native.d.ts +46 -0
  288. package/dist/graph/native.d.ts.map +1 -0
  289. package/dist/graph/native.js +169 -0
  290. package/dist/graph/native.js.map +1 -0
  291. package/dist/graph/queries/c.scm +13 -0
  292. package/dist/graph/queries/c_sharp.scm +19 -0
  293. package/dist/graph/queries/clojure.scm +58 -0
  294. package/dist/graph/queries/cpp.scm +23 -0
  295. package/dist/graph/queries/dart.scm +42 -0
  296. package/dist/graph/queries/elixir.scm +54 -0
  297. package/dist/graph/queries/gleam.scm +51 -0
  298. package/dist/graph/queries/java.scm +20 -0
  299. package/dist/graph/queries/kotlin.scm +43 -0
  300. package/dist/graph/queries/lua.scm +36 -0
  301. package/dist/graph/queries/nix.scm +32 -0
  302. package/dist/graph/queries/php.scm +40 -0
  303. package/dist/graph/queries/ruby.scm +65 -0
  304. package/dist/graph/queries/rust.scm +41 -0
  305. package/dist/graph/queries/scala.scm +66 -0
  306. package/dist/graph/queries/solidity.scm +43 -0
  307. package/dist/graph/queries/swift.scm +51 -0
  308. package/dist/graph/refresh.d.ts +106 -0
  309. package/dist/graph/refresh.d.ts.map +1 -0
  310. package/dist/graph/refresh.js +430 -0
  311. package/dist/graph/refresh.js.map +1 -0
  312. package/dist/graph/relations.d.ts +14 -0
  313. package/dist/graph/relations.d.ts.map +1 -0
  314. package/dist/graph/relations.js +8 -0
  315. package/dist/graph/relations.js.map +1 -0
  316. package/dist/graph/resolve.d.ts +17 -0
  317. package/dist/graph/resolve.d.ts.map +1 -0
  318. package/dist/graph/resolve.js +716 -0
  319. package/dist/graph/resolve.js.map +1 -0
  320. package/dist/graph/root.d.ts +11 -0
  321. package/dist/graph/root.d.ts.map +1 -0
  322. package/dist/graph/root.js +40 -0
  323. package/dist/graph/root.js.map +1 -0
  324. package/dist/graph/scopes.d.ts +40 -0
  325. package/dist/graph/scopes.d.ts.map +1 -0
  326. package/dist/graph/scopes.js +383 -0
  327. package/dist/graph/scopes.js.map +1 -0
  328. package/dist/graph/seed.d.ts +38 -0
  329. package/dist/graph/seed.d.ts.map +1 -0
  330. package/dist/graph/seed.js +229 -0
  331. package/dist/graph/seed.js.map +1 -0
  332. package/dist/graph/source-files.d.ts +46 -0
  333. package/dist/graph/source-files.d.ts.map +1 -0
  334. package/dist/graph/source-files.js +118 -0
  335. package/dist/graph/source-files.js.map +1 -0
  336. package/dist/graph/traverse-cli.d.ts +55 -0
  337. package/dist/graph/traverse-cli.d.ts.map +1 -0
  338. package/dist/graph/traverse-cli.js +189 -0
  339. package/dist/graph/traverse-cli.js.map +1 -0
  340. package/dist/graph/traverse.d.ts +112 -0
  341. package/dist/graph/traverse.d.ts.map +1 -0
  342. package/dist/graph/traverse.js +192 -0
  343. package/dist/graph/traverse.js.map +1 -0
  344. package/dist/graph/types.d.ts +78 -0
  345. package/dist/graph/types.d.ts.map +1 -0
  346. package/dist/graph/types.js +14 -0
  347. package/dist/graph/types.js.map +1 -0
  348. package/dist/graph/wasm-runtime.d.ts +19 -0
  349. package/dist/graph/wasm-runtime.d.ts.map +1 -0
  350. package/dist/graph/wasm-runtime.js +38 -0
  351. package/dist/graph/wasm-runtime.js.map +1 -0
  352. package/dist/graph/workspace-cli.d.ts +56 -0
  353. package/dist/graph/workspace-cli.d.ts.map +1 -0
  354. package/dist/graph/workspace-cli.js +111 -0
  355. package/dist/graph/workspace-cli.js.map +1 -0
  356. package/dist/graph/workspace.d.ts +172 -0
  357. package/dist/graph/workspace.d.ts.map +1 -0
  358. package/dist/graph/workspace.js +714 -0
  359. package/dist/graph/workspace.js.map +1 -0
  360. package/dist/graph/write.d.ts +13 -0
  361. package/dist/graph/write.d.ts.map +1 -0
  362. package/dist/graph/write.js +86 -0
  363. package/dist/graph/write.js.map +1 -0
  364. package/dist/hosts/antigravity.d.ts +14 -0
  365. package/dist/hosts/antigravity.d.ts.map +1 -0
  366. package/dist/hosts/antigravity.js +59 -0
  367. package/dist/hosts/antigravity.js.map +1 -0
  368. package/dist/hosts/auto.d.ts +37 -0
  369. package/dist/hosts/auto.d.ts.map +1 -0
  370. package/dist/hosts/auto.js +141 -0
  371. package/dist/hosts/auto.js.map +1 -0
  372. package/dist/hosts/claude-global.d.ts +72 -0
  373. package/dist/hosts/claude-global.d.ts.map +1 -0
  374. package/dist/hosts/claude-global.js +230 -0
  375. package/dist/hosts/claude-global.js.map +1 -0
  376. package/dist/hosts/config-write.d.ts +36 -0
  377. package/dist/hosts/config-write.d.ts.map +1 -0
  378. package/dist/hosts/config-write.js +64 -0
  379. package/dist/hosts/config-write.js.map +1 -0
  380. package/dist/hosts/init.d.ts +28 -0
  381. package/dist/hosts/init.d.ts.map +1 -0
  382. package/dist/hosts/init.js +89 -0
  383. package/dist/hosts/init.js.map +1 -0
  384. package/dist/hosts/instructions.d.ts +14 -0
  385. package/dist/hosts/instructions.d.ts.map +1 -0
  386. package/dist/hosts/instructions.js +95 -0
  387. package/dist/hosts/instructions.js.map +1 -0
  388. package/dist/hosts/mcp-config.d.ts +78 -0
  389. package/dist/hosts/mcp-config.d.ts.map +1 -0
  390. package/dist/hosts/mcp-config.js +251 -0
  391. package/dist/hosts/mcp-config.js.map +1 -0
  392. package/dist/hosts/plan.d.ts +32 -0
  393. package/dist/hosts/plan.d.ts.map +1 -0
  394. package/dist/hosts/plan.js +73 -0
  395. package/dist/hosts/plan.js.map +1 -0
  396. package/dist/hosts/registry.d.ts +41 -0
  397. package/dist/hosts/registry.d.ts.map +1 -0
  398. package/dist/hosts/registry.js +164 -0
  399. package/dist/hosts/registry.js.map +1 -0
  400. package/dist/hosts/retract.d.ts +47 -0
  401. package/dist/hosts/retract.d.ts.map +1 -0
  402. package/dist/hosts/retract.js +520 -0
  403. package/dist/hosts/retract.js.map +1 -0
  404. package/dist/hosts/sections.d.ts +47 -0
  405. package/dist/hosts/sections.d.ts.map +1 -0
  406. package/dist/hosts/sections.js +127 -0
  407. package/dist/hosts/sections.js.map +1 -0
  408. package/dist/index.d.ts +41 -0
  409. package/dist/index.d.ts.map +1 -0
  410. package/dist/index.js +32 -0
  411. package/dist/index.js.map +1 -0
  412. package/dist/ingest/fs.d.ts +79 -0
  413. package/dist/ingest/fs.d.ts.map +1 -0
  414. package/dist/ingest/fs.js +306 -0
  415. package/dist/ingest/fs.js.map +1 -0
  416. package/dist/init-guard.d.ts +16 -0
  417. package/dist/init-guard.d.ts.map +1 -0
  418. package/dist/init-guard.js +27 -0
  419. package/dist/init-guard.js.map +1 -0
  420. package/dist/mcp/instructions.d.ts +5 -0
  421. package/dist/mcp/instructions.d.ts.map +1 -0
  422. package/dist/mcp/instructions.js +64 -0
  423. package/dist/mcp/instructions.js.map +1 -0
  424. package/dist/mcp/kept-listing.d.ts +27 -0
  425. package/dist/mcp/kept-listing.d.ts.map +1 -0
  426. package/dist/mcp/kept-listing.js +63 -0
  427. package/dist/mcp/kept-listing.js.map +1 -0
  428. package/dist/mcp/server.d.ts +4 -0
  429. package/dist/mcp/server.d.ts.map +1 -0
  430. package/dist/mcp/server.js +147 -0
  431. package/dist/mcp/server.js.map +1 -0
  432. package/dist/mcp/tool-names.d.ts +27 -0
  433. package/dist/mcp/tool-names.d.ts.map +1 -0
  434. package/dist/mcp/tool-names.js +47 -0
  435. package/dist/mcp/tool-names.js.map +1 -0
  436. package/dist/mcp/tools.d.ts +22 -0
  437. package/dist/mcp/tools.d.ts.map +1 -0
  438. package/dist/mcp/tools.js +440 -0
  439. package/dist/mcp/tools.js.map +1 -0
  440. package/dist/node-version.d.ts +15 -0
  441. package/dist/node-version.d.ts.map +1 -0
  442. package/dist/node-version.js +23 -0
  443. package/dist/node-version.js.map +1 -0
  444. package/dist/search/grep-cli.d.ts +35 -0
  445. package/dist/search/grep-cli.d.ts.map +1 -0
  446. package/dist/search/grep-cli.js +115 -0
  447. package/dist/search/grep-cli.js.map +1 -0
  448. package/dist/search/grep.d.ts +60 -0
  449. package/dist/search/grep.d.ts.map +1 -0
  450. package/dist/search/grep.js +143 -0
  451. package/dist/search/grep.js.map +1 -0
  452. package/dist/search/ignored-code.d.ts +9 -0
  453. package/dist/search/ignored-code.d.ts.map +1 -0
  454. package/dist/search/ignored-code.js +73 -0
  455. package/dist/search/ignored-code.js.map +1 -0
  456. package/dist/search/user-regexp.d.ts +26 -0
  457. package/dist/search/user-regexp.d.ts.map +1 -0
  458. package/dist/search/user-regexp.js +150 -0
  459. package/dist/search/user-regexp.js.map +1 -0
  460. package/dist/telemetry/contract.d.ts +117 -0
  461. package/dist/telemetry/contract.d.ts.map +1 -0
  462. package/dist/telemetry/contract.js +341 -0
  463. package/dist/telemetry/contract.js.map +1 -0
  464. package/dist/telemetry/flush.d.ts +21 -0
  465. package/dist/telemetry/flush.d.ts.map +1 -0
  466. package/dist/telemetry/flush.js +85 -0
  467. package/dist/telemetry/flush.js.map +1 -0
  468. package/dist/telemetry/gate.d.ts +30 -0
  469. package/dist/telemetry/gate.d.ts.map +1 -0
  470. package/dist/telemetry/gate.js +81 -0
  471. package/dist/telemetry/gate.js.map +1 -0
  472. package/dist/telemetry/identity.d.ts +40 -0
  473. package/dist/telemetry/identity.d.ts.map +1 -0
  474. package/dist/telemetry/identity.js +80 -0
  475. package/dist/telemetry/identity.js.map +1 -0
  476. package/dist/telemetry/index.d.ts +18 -0
  477. package/dist/telemetry/index.d.ts.map +1 -0
  478. package/dist/telemetry/index.js +16 -0
  479. package/dist/telemetry/index.js.map +1 -0
  480. package/dist/telemetry/key.d.ts +21 -0
  481. package/dist/telemetry/key.d.ts.map +1 -0
  482. package/dist/telemetry/key.js +49 -0
  483. package/dist/telemetry/key.js.map +1 -0
  484. package/dist/telemetry/notice.d.ts +19 -0
  485. package/dist/telemetry/notice.d.ts.map +1 -0
  486. package/dist/telemetry/notice.js +93 -0
  487. package/dist/telemetry/notice.js.map +1 -0
  488. package/dist/telemetry/queue.d.ts +35 -0
  489. package/dist/telemetry/queue.d.ts.map +1 -0
  490. package/dist/telemetry/queue.js +162 -0
  491. package/dist/telemetry/queue.js.map +1 -0
  492. package/dist/telemetry/send.d.ts +19 -0
  493. package/dist/telemetry/send.d.ts.map +1 -0
  494. package/dist/telemetry/send.js +84 -0
  495. package/dist/telemetry/send.js.map +1 -0
  496. package/dist/telemetry/sessions.d.ts +25 -0
  497. package/dist/telemetry/sessions.d.ts.map +1 -0
  498. package/dist/telemetry/sessions.js +104 -0
  499. package/dist/telemetry/sessions.js.map +1 -0
  500. package/dist/telemetry/track.d.ts +62 -0
  501. package/dist/telemetry/track.d.ts.map +1 -0
  502. package/dist/telemetry/track.js +143 -0
  503. package/dist/telemetry/track.js.map +1 -0
  504. package/dist/upkeep-run.d.ts +22 -0
  505. package/dist/upkeep-run.d.ts.map +1 -0
  506. package/dist/upkeep-run.js +85 -0
  507. package/dist/upkeep-run.js.map +1 -0
  508. package/dist/upkeep.d.ts +127 -0
  509. package/dist/upkeep.d.ts.map +1 -0
  510. package/dist/upkeep.js +252 -0
  511. package/dist/upkeep.js.map +1 -0
  512. package/dist/util/actions-folder.d.ts +2 -0
  513. package/dist/util/actions-folder.d.ts.map +1 -0
  514. package/dist/util/actions-folder.js +9 -0
  515. package/dist/util/actions-folder.js.map +1 -0
  516. package/dist/util/browser.d.ts +3 -0
  517. package/dist/util/browser.d.ts.map +1 -0
  518. package/dist/util/browser.js +14 -0
  519. package/dist/util/browser.js.map +1 -0
  520. package/dist/util/child-process.d.ts +15 -0
  521. package/dist/util/child-process.d.ts.map +1 -0
  522. package/dist/util/child-process.js +15 -0
  523. package/dist/util/child-process.js.map +1 -0
  524. package/dist/util/front-matter.d.ts +46 -0
  525. package/dist/util/front-matter.d.ts.map +1 -0
  526. package/dist/util/front-matter.js +113 -0
  527. package/dist/util/front-matter.js.map +1 -0
  528. package/dist/util/id.d.ts +7 -0
  529. package/dist/util/id.d.ts.map +1 -0
  530. package/dist/util/id.js +14 -0
  531. package/dist/util/id.js.map +1 -0
  532. package/dist/util/paths.d.ts +29 -0
  533. package/dist/util/paths.d.ts.map +1 -0
  534. package/dist/util/paths.js +71 -0
  535. package/dist/util/paths.js.map +1 -0
  536. package/dist/util/private-file.d.ts +14 -0
  537. package/dist/util/private-file.d.ts.map +1 -0
  538. package/dist/util/private-file.js +82 -0
  539. package/dist/util/private-file.js.map +1 -0
  540. package/dist/util/source.d.ts +4 -0
  541. package/dist/util/source.d.ts.map +1 -0
  542. package/dist/util/source.js +12 -0
  543. package/dist/util/source.js.map +1 -0
  544. package/dist/util/spinner.d.ts +15 -0
  545. package/dist/util/spinner.d.ts.map +1 -0
  546. package/dist/util/spinner.js +52 -0
  547. package/dist/util/spinner.js.map +1 -0
  548. package/dist/util/state.d.ts +120 -0
  549. package/dist/util/state.d.ts.map +1 -0
  550. package/dist/util/state.js +264 -0
  551. package/dist/util/state.js.map +1 -0
  552. package/dist/vendor/grammars/tree-sitter-go.LICENSE +21 -0
  553. package/dist/vendor/grammars/tree-sitter-go.wasm +0 -0
  554. package/dist/vendor/grammars/tree-sitter-java.LICENSE +21 -0
  555. package/dist/vendor/grammars/tree-sitter-java.wasm +0 -0
  556. package/dist/vendor/grammars/tree-sitter-kotlin.LICENSE +9 -0
  557. package/dist/vendor/grammars/tree-sitter-kotlin.wasm +0 -0
  558. package/dist/vendor/grammars/tree-sitter-php.LICENSE +22 -0
  559. package/dist/vendor/grammars/tree-sitter-php.wasm +0 -0
  560. package/dist/vendor/grammars/tree-sitter-python.LICENSE +21 -0
  561. package/dist/vendor/grammars/tree-sitter-python.wasm +0 -0
  562. package/dist/vendor/grammars/tree-sitter-r.LICENSE +9 -0
  563. package/dist/vendor/grammars/tree-sitter-r.wasm +0 -0
  564. package/dist/vendor/grammars/tree-sitter-swift.LICENSE +21 -0
  565. package/dist/vendor/grammars/tree-sitter-swift.wasm +0 -0
  566. package/dist/vendor/grammars/tree-sitter-tsx.wasm +0 -0
  567. package/dist/vendor/grammars/tree-sitter-typescript.LICENSE +21 -0
  568. package/dist/vendor/grammars/tree-sitter-typescript.wasm +0 -0
  569. package/dist/viewer/app.js +2 -0
  570. package/dist/viewer/index.html +49 -0
  571. package/dist/viewer/style.css +154 -0
  572. package/dist/viz/assemble.d.ts +83 -0
  573. package/dist/viz/assemble.d.ts.map +1 -0
  574. package/dist/viz/assemble.js +101 -0
  575. package/dist/viz/assemble.js.map +1 -0
  576. package/dist/viz/export.d.ts +39 -0
  577. package/dist/viz/export.d.ts.map +1 -0
  578. package/dist/viz/export.js +98 -0
  579. package/dist/viz/export.js.map +1 -0
  580. package/dist/viz/serve.d.ts +13 -0
  581. package/dist/viz/serve.d.ts.map +1 -0
  582. package/dist/viz/serve.js +130 -0
  583. package/dist/viz/serve.js.map +1 -0
  584. package/package.json +115 -4
  585. package/scripts/build-grammar-wasm.mjs +112 -0
  586. package/scripts/build-viewer.mjs +44 -0
  587. package/scripts/graph-quality.mjs +117 -0
  588. package/scripts/pack-trail.mjs +53 -0
  589. package/scripts/postinstall.mjs +65 -0
  590. package/scripts/run-tests.mjs +72 -0
  591. package/scripts/stamp-telemetry-key.mjs +56 -0
  592. package/scripts/tally-audit.mjs +140 -0
  593. package/scripts/vendor-grammars.mjs +53 -0
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The telemetry contract: the complete, machine-enforced list of what graft may
3
+ * send. `TELEMETRY.md` is the same list in prose, and the two are kept in
4
+ * lockstep — an event or property that is not in this file cannot be sent, and
5
+ * one that is not in `TELEMETRY.md` must not be added here.
6
+ *
7
+ * Why an allowlist rather than a review rule: every telemetry incident in the
8
+ * tools we studied came from a call site quietly adding a property nobody
9
+ * audited. `track()` (track.ts) drops unknown events and unknown keys instead of
10
+ * trusting its callers, so a future `track('query', { path })` sends `query`
11
+ * with no `path` rather than leaking one. The blast radius of a careless call
12
+ * site is "we lose a metric", never "we received someone's source tree".
13
+ *
14
+ * The other half of that guarantee is the value side: every number crosses as a
15
+ * BUCKET and every string as a member of a fixed union. A raw file count plus a
16
+ * language set starts to fingerprint a specific repo; `"100-500"` does not. A
17
+ * raw error message is a path, a symbol, and sometimes a snippet of code; an
18
+ * enum member is not.
19
+ *
20
+ * This module is pure — no I/O, no config, no clock. It is the file a reviewer
21
+ * (or a suspicious user, since the repo is public) reads to verify the claim.
22
+ */
23
+ /**
24
+ * The contract itself. Common properties (see {@link COMMON_KEYS}) are stamped
25
+ * centrally by `track()` and are deliberately not repeated per event.
26
+ */
27
+ export declare const EVENTS: Record<string, ReadonlySet<string>>;
28
+ /** The labels {@link hookMsBucket} returns. */
29
+ export declare const HOOK_MS_BUCKETS: readonly ["<50ms", "50-100ms", "100-300ms", "300ms-1s", "1-3s", "3s+"];
30
+ /**
31
+ * The values an event's key may take, where the contract fixes them. `track()`
32
+ * drops a value outside the set, key and all, so a call site that passes a
33
+ * skill's name, a prompt or an error line under an allowed key sends nothing
34
+ * for it. Every key of the skills events is listed here.
35
+ */
36
+ export declare const VALUES: Record<string, Record<string, ReadonlySet<string>>>;
37
+ /** Whether `value` may go under `key` of `event`: always, unless {@link VALUES} fixes the key's values. */
38
+ export declare function allowedValue(event: string, key: string, value: string): boolean;
39
+ /** Stamped on every event by `track()`; not listed per event above. */
40
+ export declare const COMMON_KEYS: readonly ["app_version", "os", "arch", "node_major", "ci", "agent_host", "cli_name", "repo_id"];
41
+ /** Which surface issued a query. `hook` is Claude Code's prompt hook, which
42
+ * queries on the user's behalf without them typing a command. */
43
+ export type Surface = 'cli' | 'mcp' | 'hook';
44
+ /** Which editor/agent graft is running under. Derived from the surface and the
45
+ * wiring on disk — never from a hostname, a username, or an env var's value. */
46
+ export type AgentHost = 'claude-code' | 'cursor' | 'copilot' | 'mcp' | 'cli';
47
+ /**
48
+ * The commands worth counting. A command absent here is simply not reported —
49
+ * `track()` drops the event rather than sending a free-form string, which is
50
+ * what keeps a future `graft <something-user-named>` from becoming a data leak.
51
+ */
52
+ export declare const TRACKED_COMMANDS: readonly ["ask", "grep", "callers", "skeleton", "map", "check", "blast", "viz"];
53
+ export type TrackedCommand = (typeof TRACKED_COMMANDS)[number];
54
+ export declare function isTrackedCommand(name: string): name is TrackedCommand;
55
+ /**
56
+ * How a sign-in handoff ended.
57
+ *
58
+ * Five categories and nothing else, because the alternative — the error string
59
+ * the CLI already prints — carries a repo slug and a URL. `timed_out` and
60
+ * `no_tty` are deliberately apart: one is a person who opened the browser and
61
+ * did not finish, the other is a machine that was never able to open one, and
62
+ * treating them alike would read as a product problem where there is only a
63
+ * remote shell. `stopped` is Ctrl-C while waiting: a person changing their
64
+ * mind, not a browser that never came back.
65
+ */
66
+ export declare const BRAIN_SIGNUP_OUTCOMES: readonly ["linked", "timed_out", "no_tty", "bad_callback", "stopped"];
67
+ export type BrainSignupOutcome = (typeof BRAIN_SIGNUP_OUTCOMES)[number];
68
+ /** Where a failing build died. Coarse on purpose: enough to route a bug, not
69
+ * enough to describe anyone's repo. */
70
+ export declare const BUILD_STAGES: readonly ["walk", "extract", "graph", "summarize", "synthesize", "write"];
71
+ export type BuildStage = (typeof BUILD_STAGES)[number];
72
+ /**
73
+ * The failure taxonomy. Anything unrecognised becomes `E_UNKNOWN` — the point of
74
+ * a closed set is that an unclassified error contributes a count and nothing
75
+ * else, so no message text can ride along inside a "code".
76
+ */
77
+ export declare const ERROR_CODES: readonly ["E_UNKNOWN", "E_PARSE", "E_TIMEOUT", "E_LLM", "E_AUTH", "E_RATE_LIMIT", "E_NETWORK", "E_DISK", "E_PERMISSION", "E_OOM", "E_LOCK"];
78
+ export type ErrorCode = (typeof ERROR_CODES)[number];
79
+ /**
80
+ * Map a thrown value to a code without letting its text through. Only fixed
81
+ * substrings are matched, and only a member of {@link ERROR_CODES} is returned —
82
+ * the error's own message is never the return value, not even in part.
83
+ */
84
+ export declare function errorCode(err: unknown): ErrorCode;
85
+ /** Repo scale. Exact counts fingerprint a repo; these five labels answer the
86
+ * only question we have ("toy, service, or monorepo?"). */
87
+ export declare function filesBucket(n: number): string;
88
+ /** Wall-clock for a build. Coarse enough that it says "fast/slow", not "this
89
+ * exact machine on this exact tree". */
90
+ export declare function durationBucket(ms: number): string;
91
+ /** Generic small-count bucket, for the per-session read counters. */
92
+ export declare function countBucket(n: number): string;
93
+ /** One hook's wall-clock. The budgets are 50 ms (PreToolUse) and 300 ms (the
94
+ * rest), so the labels split there. */
95
+ export declare function hookMsBucket(ms: number): (typeof HOOK_MS_BUCKETS)[number];
96
+ /** Estimated tokens saved in one session — the README's central claim, in the
97
+ * only resolution we need to defend it. */
98
+ export declare function savedTokensBucket(n: number): string;
99
+ /**
100
+ * Languages, normalised, filtered to a safe shape, and capped.
101
+ *
102
+ * Sorted so `["go","ts"]` and `["ts","go"]` aggregate as one value, deduped, and
103
+ * cut to eight — a repo with a very long tail of languages is itself a
104
+ * distinguishing fact, and the tail answers no question we have.
105
+ *
106
+ * The character filter is the part that matters. This is the only property in
107
+ * the contract that is not drawn from a closed set defined in this file: the
108
+ * values come from the parser registry, several modules away, via
109
+ * `languageLabelOf() ?? container.name ?? generic.name ?? "unknown"`. That is
110
+ * safe today, but it means the no-free-text guarantee would rest on a promise
111
+ * made elsewhere — and a future generic extractor naming itself after the
112
+ * extension it matched would quietly turn this into a channel for file
113
+ * metadata. Anything outside `[a-z0-9+#._-]`, or longer than 24 characters, is
114
+ * therefore dropped here rather than trusted.
115
+ */
116
+ export declare function langsValue(langs: readonly string[]): string;
117
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/telemetry/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CA0FtD,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,eAAe,wEAAyE,CAAC;AAEtG;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAsBtE,CAAC;AAEF,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAI/E;AAED,uEAAuE;AACvE,eAAO,MAAM,WAAW,iGASd,CAAC;AAMX;kEACkE;AAClE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7C;iFACiF;AACjF,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,iFAEnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,cAAc,CAErE;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,uEAAwE,CAAC;AAC3G,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE;wCACwC;AACxC,eAAO,MAAM,YAAY,2EAA4E,CAAC;AACtG,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,WAAW,6IAGd,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAoBjD;AAMD;4DAC4D;AAC5D,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED;yCACyC;AACzC,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED;wCACwC;AACxC,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAOzE;AAED;4CAC4C;AAC5C,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK3D"}
@@ -0,0 +1,341 @@
1
+ /**
2
+ * The telemetry contract: the complete, machine-enforced list of what graft may
3
+ * send. `TELEMETRY.md` is the same list in prose, and the two are kept in
4
+ * lockstep — an event or property that is not in this file cannot be sent, and
5
+ * one that is not in `TELEMETRY.md` must not be added here.
6
+ *
7
+ * Why an allowlist rather than a review rule: every telemetry incident in the
8
+ * tools we studied came from a call site quietly adding a property nobody
9
+ * audited. `track()` (track.ts) drops unknown events and unknown keys instead of
10
+ * trusting its callers, so a future `track('query', { path })` sends `query`
11
+ * with no `path` rather than leaking one. The blast radius of a careless call
12
+ * site is "we lose a metric", never "we received someone's source tree".
13
+ *
14
+ * The other half of that guarantee is the value side: every number crosses as a
15
+ * BUCKET and every string as a member of a fixed union. A raw file count plus a
16
+ * language set starts to fingerprint a specific repo; `"100-500"` does not. A
17
+ * raw error message is a path, a symbol, and sometimes a snippet of code; an
18
+ * enum member is not.
19
+ *
20
+ * This module is pure — no I/O, no config, no clock. It is the file a reviewer
21
+ * (or a suspicious user, since the repo is public) reads to verify the claim.
22
+ */
23
+ /* -------------------------------------------------------------------------- */
24
+ /* the event → allowed-property-keys map */
25
+ /* -------------------------------------------------------------------------- */
26
+ /**
27
+ * The contract itself. Common properties (see {@link COMMON_KEYS}) are stamped
28
+ * centrally by `track()` and are deliberately not repeated per event.
29
+ */
30
+ export const EVENTS = {
31
+ /** Once per machine per version, from the npm postinstall hook. The real
32
+ * denominator: a machine that installs graft and never runs a command emits
33
+ * this event and no other, so it is the only place the "installed, never
34
+ * used" leak is visible at all. Version-scoped rather than once-ever so an
35
+ * upgrade counts; distinct install ids still give unique machines.
36
+ * `global` separates `npm i -g graft` from a project dependency, which is
37
+ * roughly the difference between a person and a lockfile. */
38
+ install: new Set(['global']),
39
+ /** Once per machine, the first time a command actually runs. Paired with
40
+ * `install`, the gap between the two is the top of the funnel. */
41
+ first_run: new Set(),
42
+ /** `graft init` completed. Tells us which agents people actually wire, and
43
+ * how many decline telemetry at the picker. */
44
+ init_completed: new Set(['agents', 'consent']),
45
+ /** A build finished. The activation event — an install that never reaches one
46
+ * of these is the funnel leak we most want to see. */
47
+ build_completed: new Set(['files_bucket', 'langs', 'mode', 'duration_bucket', 'incremental']),
48
+ /** A build threw. `stage`/`code` are enums; the message never travels. */
49
+ build_failed: new Set(['stage', 'code']),
50
+ /** One query, from any surface. The DAU backbone and the dead-command detector. */
51
+ query: new Set(['command', 'surface', 'hit', 'notes']),
52
+ /** A trail command handing the agent a sign-in link to pass on. Queued the
53
+ * moment the link is printed, so a sign-in somebody walked away from is still
54
+ * counted — the settle below never fires for those. */
55
+ brain_signup_opened: new Set(['mode', 'command', 'wording']),
56
+ /** That handoff reaching an end. `outcome` is a closed set, so the reason a
57
+ * signup failed travels as a category and never as the error's own words. */
58
+ brain_signup_settled: new Set(['outcome', 'mode', 'duration_bucket']),
59
+ /** `trail note` saved a session note (into `~/.trail/`). Whether it carries
60
+ * a cost, and how many files it is about, as a bucket. The title, the text
61
+ * and the paths never travel. The supply side of the notes loop; the
62
+ * `notes` property on `query` is the demand side. */
63
+ note_saved: new Set(['has_cost', 'touches_bucket', 'scope']),
64
+ /** Once a day per repo, from the session-start hook, for a repo trail runs
65
+ * in: whether `.trail/` is committed there, how many learnings it holds,
66
+ * as a bucket, and whether this machine shares it with a workspace. With
67
+ * `repo_id` and the install id this counts devs and repos touched, and
68
+ * repos with Trail committed. Paths and names never travel. */
69
+ repo_seen: new Set(['trail_committed', 'learnings_bucket', 'workspace']),
70
+ /** At session start, when the learnings committed on HEAD went up since the
71
+ * last session in that clone: how many came in and how many there are, as
72
+ * buckets, and whether it's the clone's first look. Committed learnings
73
+ * are trail's activation. Paths and titles never travel. */
74
+ learnings_committed: new Set(['added_bucket', 'total_bucket', 'first_look']),
75
+ /** `trail init` read the repo's past Claude sessions, the review comments
76
+ * on its merged PRs, or Claude Code's memory notes of it (`source`), for
77
+ * learnings: how it went, how many sessions or reviewed PRs there were,
78
+ * findings offered and saved, how many were left out for naming no code
79
+ * (`filtered`), and how many of those offered and saved were the team's,
80
+ * as buckets, how long it took, and the model. The messages, the comments,
81
+ * the notes and the findings never travel. */
82
+ cold_start: new Set(['source', 'outcome', 'sessions_bucket', 'reviews_bucket', 'offered_bucket', 'filtered_bucket', 'picked_bucket', 'team_offered_bucket', 'team_picked_bucket', 'duration_bucket', 'model']),
83
+ /** One closed agent session, summarised. `graft_reads` vs `source_reads` is
84
+ * the single number that says whether an agent prefers graft to grep; the two
85
+ * `*_turns` buckets are the follow-up question — of the turns that used graft,
86
+ * how many told the user what it saved. Both are counts of turns, never text. */
87
+ session_summary: new Set([
88
+ 'graft_reads_bucket', 'source_reads_bucket', 'saved_tokens_bucket',
89
+ 'graft_turns_bucket', 'reported_turns_bucket',
90
+ ]),
91
+ /* Learned skills (spec section 20). Every value is a member of a closed set
92
+ * in {@link VALUES}; a skill's name, its steps, a command, a prompt, a lesson
93
+ * or a path is never one of them, so none of those can travel. */
94
+ /** Trail offered to keep a skill (or a lesson, an update, a promotion): at which moment. */
95
+ skill_offered: new Set(['moment']),
96
+ /** The person's answer to an offer. A withdrawn offer sends nothing. */
97
+ skill_answer: new Set(['answer']),
98
+ /** A skill was saved: what it came from, and whose it is. */
99
+ skill_saved: new Set(['from', 'scope']),
100
+ /** Trail changed a skill it wrote, on the person's yes or their own command (phase 2): how. */
101
+ skill_changed: new Set(['op']),
102
+ /** A skill moved up a scope (phase 3). */
103
+ skill_promoted: new Set(['to']),
104
+ /** A joined team repo was pulled (phase 3): how it went. */
105
+ team_pull: new Set(['outcome']),
106
+ /** A skill the agent was given ran: whether its own check passed. */
107
+ skill_used: new Set(['outcome']),
108
+ /** The weekly value line was said (phase 2): where it went. */
109
+ skill_value: new Set(['channel']),
110
+ /** A skill stopped being offered to the agent as is: why. */
111
+ skill_stale: new Set(['reason']),
112
+ /** A guardrail fired: which built-in one, and what it did. */
113
+ guardrail: new Set(['class', 'outcome']),
114
+ /** A failing command matched a known wall: which one, and whether the person had kept a lesson for it. */
115
+ wall_hit: new Set(['class', 'had_lesson']),
116
+ /** How long one hook took, as a bucket: which hook. */
117
+ hook_ms: new Set(['event', 'bucket']),
118
+ };
119
+ /** The labels {@link hookMsBucket} returns. */
120
+ export const HOOK_MS_BUCKETS = ['<50ms', '50-100ms', '100-300ms', '300ms-1s', '1-3s', '3s+'];
121
+ /**
122
+ * The values an event's key may take, where the contract fixes them. `track()`
123
+ * drops a value outside the set, key and all, so a call site that passes a
124
+ * skill's name, a prompt or an error line under an allowed key sends nothing
125
+ * for it. Every key of the skills events is listed here.
126
+ */
127
+ export const VALUES = {
128
+ skill_offered: { moment: new Set(['asked', 'repeated', 'repaired', 'correction', 'update', 'drift', 'retire', 'promote']) },
129
+ skill_answer: { answer: new Set(['yes', 'no', 'show', 'none', 'off', 'retire']) },
130
+ skill_changed: { op: new Set(['update', 'extend', 'split', 'replace', 'retire', 'adopted', 'restore-version']) },
131
+ skill_value: { channel: new Set(['context', 'notice', 'list']) },
132
+ skill_saved: { from: new Set(['init', 'repeated', 'repaired', 'asked']), scope: new Set(['personal', 'repo', 'team']) },
133
+ skill_promoted: { to: new Set(['repo', 'team']) },
134
+ team_pull: { outcome: new Set(['updated', 'unchanged', 'diverged', 'failed']) },
135
+ skill_used: { outcome: new Set(['checked', 'failed', 'unchecked']) },
136
+ skill_stale: { reason: new Set(['failed', 'corrected', 'missing', 'unused', 'unfollowed']) },
137
+ guardrail: {
138
+ class: new Set(['no-timeout', 'prod-after-beta']),
139
+ outcome: new Set(['hint', 'ask', 'deny', 'sure-fail', 'avoided']),
140
+ },
141
+ wall_hit: {
142
+ class: new Set(['timeout-missing', 'zsh-no-match', 'git-https-auth', 'docker-rootless', 'npm-e401-eotp', 'claude-not-logged-in', 'enospc']),
143
+ had_lesson: new Set(['true', 'false']),
144
+ },
145
+ hook_ms: {
146
+ event: new Set(['session-start', 'prompt', 'pre-bash', 'pre-edit', 'tool-savings', 'post-bash', 'post-bash-fail', 'post-edit', 'post-edit-sync', 'stop']),
147
+ bucket: new Set(HOOK_MS_BUCKETS),
148
+ },
149
+ };
150
+ /** Whether `value` may go under `key` of `event`: always, unless {@link VALUES} fixes the key's values. */
151
+ export function allowedValue(event, key, value) {
152
+ if (!Object.hasOwn(VALUES, event))
153
+ return true;
154
+ const keys = VALUES[event];
155
+ return !Object.hasOwn(keys, key) || keys[key].has(value);
156
+ }
157
+ /** Stamped on every event by `track()`; not listed per event above. */
158
+ export const COMMON_KEYS = [
159
+ 'app_version',
160
+ 'os',
161
+ 'arch',
162
+ 'node_major',
163
+ 'ci',
164
+ 'agent_host',
165
+ 'cli_name',
166
+ 'repo_id',
167
+ ];
168
+ /**
169
+ * The commands worth counting. A command absent here is simply not reported —
170
+ * `track()` drops the event rather than sending a free-form string, which is
171
+ * what keeps a future `graft <something-user-named>` from becoming a data leak.
172
+ */
173
+ export const TRACKED_COMMANDS = [
174
+ 'ask', 'grep', 'callers', 'skeleton', 'map', 'check', 'blast', 'viz',
175
+ ];
176
+ export function isTrackedCommand(name) {
177
+ return TRACKED_COMMANDS.includes(name);
178
+ }
179
+ /**
180
+ * How a sign-in handoff ended.
181
+ *
182
+ * Five categories and nothing else, because the alternative — the error string
183
+ * the CLI already prints — carries a repo slug and a URL. `timed_out` and
184
+ * `no_tty` are deliberately apart: one is a person who opened the browser and
185
+ * did not finish, the other is a machine that was never able to open one, and
186
+ * treating them alike would read as a product problem where there is only a
187
+ * remote shell. `stopped` is Ctrl-C while waiting: a person changing their
188
+ * mind, not a browser that never came back.
189
+ */
190
+ export const BRAIN_SIGNUP_OUTCOMES = ['linked', 'timed_out', 'no_tty', 'bad_callback', 'stopped'];
191
+ /** Where a failing build died. Coarse on purpose: enough to route a bug, not
192
+ * enough to describe anyone's repo. */
193
+ export const BUILD_STAGES = ['walk', 'extract', 'graph', 'summarize', 'synthesize', 'write'];
194
+ /**
195
+ * The failure taxonomy. Anything unrecognised becomes `E_UNKNOWN` — the point of
196
+ * a closed set is that an unclassified error contributes a count and nothing
197
+ * else, so no message text can ride along inside a "code".
198
+ */
199
+ export const ERROR_CODES = [
200
+ 'E_UNKNOWN', 'E_PARSE', 'E_TIMEOUT', 'E_LLM', 'E_AUTH', 'E_RATE_LIMIT',
201
+ 'E_NETWORK', 'E_DISK', 'E_PERMISSION', 'E_OOM', 'E_LOCK',
202
+ ];
203
+ /**
204
+ * Map a thrown value to a code without letting its text through. Only fixed
205
+ * substrings are matched, and only a member of {@link ERROR_CODES} is returned —
206
+ * the error's own message is never the return value, not even in part.
207
+ */
208
+ export function errorCode(err) {
209
+ const code = err?.code;
210
+ if (typeof code === 'string') {
211
+ if (code === 'ENOSPC' || code === 'EDQUOT')
212
+ return 'E_DISK';
213
+ if (code === 'EACCES' || code === 'EPERM')
214
+ return 'E_PERMISSION';
215
+ if (code === 'ENOMEM')
216
+ return 'E_OOM';
217
+ if (code === 'ETIMEDOUT' || code === 'ESOCKETTIMEDOUT')
218
+ return 'E_TIMEOUT';
219
+ if (code === 'ENOTFOUND' || code === 'ECONNREFUSED' || code === 'ECONNRESET')
220
+ return 'E_NETWORK';
221
+ }
222
+ const status = err?.status;
223
+ if (typeof status === 'number') {
224
+ if (status === 401 || status === 403)
225
+ return 'E_AUTH';
226
+ if (status === 429)
227
+ return 'E_RATE_LIMIT';
228
+ if (status >= 500)
229
+ return 'E_LLM';
230
+ }
231
+ const msg = err instanceof Error ? err.message.toLowerCase() : '';
232
+ if (msg.includes('timeout') || msg.includes('timed out'))
233
+ return 'E_TIMEOUT';
234
+ if (msg.includes('parse') || msg.includes('syntax'))
235
+ return 'E_PARSE';
236
+ if (msg.includes('lock'))
237
+ return 'E_LOCK';
238
+ return 'E_UNKNOWN';
239
+ }
240
+ /* -------------------------------------------------------------------------- */
241
+ /* buckets — every number crosses the wire as a label */
242
+ /* -------------------------------------------------------------------------- */
243
+ /** Repo scale. Exact counts fingerprint a repo; these five labels answer the
244
+ * only question we have ("toy, service, or monorepo?"). */
245
+ export function filesBucket(n) {
246
+ if (n <= 0)
247
+ return '0';
248
+ if (n < 50)
249
+ return '1-49';
250
+ if (n < 200)
251
+ return '50-199';
252
+ if (n < 1000)
253
+ return '200-999';
254
+ if (n < 5000)
255
+ return '1000-4999';
256
+ return '5000+';
257
+ }
258
+ /** Wall-clock for a build. Coarse enough that it says "fast/slow", not "this
259
+ * exact machine on this exact tree". */
260
+ export function durationBucket(ms) {
261
+ const s = ms / 1000;
262
+ if (s < 1)
263
+ return '<1s';
264
+ if (s < 5)
265
+ return '1-5s';
266
+ if (s < 30)
267
+ return '5-30s';
268
+ if (s < 120)
269
+ return '30s-2m';
270
+ if (s < 600)
271
+ return '2-10m';
272
+ return '10m+';
273
+ }
274
+ /** Generic small-count bucket, for the per-session read counters. */
275
+ export function countBucket(n) {
276
+ if (n <= 0)
277
+ return '0';
278
+ if (n < 5)
279
+ return '1-4';
280
+ if (n < 20)
281
+ return '5-19';
282
+ if (n < 50)
283
+ return '20-49';
284
+ if (n < 200)
285
+ return '50-199';
286
+ return '200+';
287
+ }
288
+ /** One hook's wall-clock. The budgets are 50 ms (PreToolUse) and 300 ms (the
289
+ * rest), so the labels split there. */
290
+ export function hookMsBucket(ms) {
291
+ if (ms < 50)
292
+ return '<50ms';
293
+ if (ms < 100)
294
+ return '50-100ms';
295
+ if (ms < 300)
296
+ return '100-300ms';
297
+ if (ms < 1000)
298
+ return '300ms-1s';
299
+ if (ms < 3000)
300
+ return '1-3s';
301
+ return '3s+';
302
+ }
303
+ /** Estimated tokens saved in one session — the README's central claim, in the
304
+ * only resolution we need to defend it. */
305
+ export function savedTokensBucket(n) {
306
+ if (n <= 0)
307
+ return '0';
308
+ if (n < 1000)
309
+ return '<1k';
310
+ if (n < 5000)
311
+ return '1-5k';
312
+ if (n < 20000)
313
+ return '5-20k';
314
+ if (n < 100000)
315
+ return '20-100k';
316
+ return '100k+';
317
+ }
318
+ /**
319
+ * Languages, normalised, filtered to a safe shape, and capped.
320
+ *
321
+ * Sorted so `["go","ts"]` and `["ts","go"]` aggregate as one value, deduped, and
322
+ * cut to eight — a repo with a very long tail of languages is itself a
323
+ * distinguishing fact, and the tail answers no question we have.
324
+ *
325
+ * The character filter is the part that matters. This is the only property in
326
+ * the contract that is not drawn from a closed set defined in this file: the
327
+ * values come from the parser registry, several modules away, via
328
+ * `languageLabelOf() ?? container.name ?? generic.name ?? "unknown"`. That is
329
+ * safe today, but it means the no-free-text guarantee would rest on a promise
330
+ * made elsewhere — and a future generic extractor naming itself after the
331
+ * extension it matched would quietly turn this into a channel for file
332
+ * metadata. Anything outside `[a-z0-9+#._-]`, or longer than 24 characters, is
333
+ * therefore dropped here rather than trusted.
334
+ */
335
+ export function langsValue(langs) {
336
+ const clean = langs
337
+ .map((l) => l.toLowerCase().trim())
338
+ .filter((l) => l.length > 0 && l.length <= 24 && /^[a-z0-9+#._-]+$/.test(l));
339
+ return [...new Set(clean)].sort().slice(0, 8).join(',');
340
+ }
341
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/telemetry/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAwC;IACzD;;;;;;kEAM8D;IAC9D,OAAO,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC;IACpC;uEACmE;IACnE,SAAS,EAAE,IAAI,GAAG,EAAU;IAC5B;oDACgD;IAChD,cAAc,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD;2DACuD;IACvD,eAAe,EAAE,IAAI,GAAG,CAAS,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACrG,0EAA0E;IAC1E,YAAY,EAAE,IAAI,GAAG,CAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,mFAAmF;IACnF,KAAK,EAAE,IAAI,GAAG,CAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9D;;4DAEwD;IACxD,mBAAmB,EAAE,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACpE;kFAC8E;IAC9E,oBAAoB,EAAE,IAAI,GAAG,CAAS,CAAC,SAAS,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7E;;;0DAGsD;IACtD,UAAU,EAAE,IAAI,GAAG,CAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACpE;;;;oEAIgE;IAChE,SAAS,EAAE,IAAI,GAAG,CAAS,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAChF;;;iEAG6D;IAC7D,mBAAmB,EAAE,IAAI,GAAG,CAAS,CAAC,cAAc,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACpF;;;;;;mDAM+C;IAC/C,UAAU,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;IACtN;;;sFAGkF;IAClF,eAAe,EAAE,IAAI,GAAG,CAAS;QAC/B,oBAAoB,EAAE,qBAAqB,EAAE,qBAAqB;QAClE,oBAAoB,EAAE,uBAAuB;KAC9C,CAAC;IAEF;;sEAEkE;IAElE,4FAA4F;IAC5F,aAAa,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC;IAC1C,wEAAwE;IACxE,YAAY,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC;IACzC,6DAA6D;IAC7D,WAAW,EAAE,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,+FAA+F;IAC/F,aAAa,EAAE,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,CAAC;IACtC,0CAA0C;IAC1C,cAAc,EAAE,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,CAAC;IACvC,4DAA4D;IAC5D,SAAS,EAAE,IAAI,GAAG,CAAS,CAAC,SAAS,CAAC,CAAC;IACvC,qEAAqE;IACrE,UAAU,EAAE,IAAI,GAAG,CAAS,CAAC,SAAS,CAAC,CAAC;IACxC,+DAA+D;IAC/D,WAAW,EAAE,IAAI,GAAG,CAAS,CAAC,SAAS,CAAC,CAAC;IACzC,6DAA6D;IAC7D,WAAW,EAAE,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC;IACxC,8DAA8D;IAC9D,SAAS,EAAE,IAAI,GAAG,CAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAChD,0GAA0G;IAC1G,QAAQ,EAAE,IAAI,GAAG,CAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAClD,uDAAuD;IACvD,OAAO,EAAE,IAAI,GAAG,CAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;CAC9C,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AAEtG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAwD;IACzE,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE;IAC3H,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE;IACjF,aAAa,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,EAAE;IAChH,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE;IAChE,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE;IACvH,cAAc,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE;IACjD,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,EAAE;IAC/E,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE;IACpE,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,EAAE;IAC5F,SAAS,EAAE;QACT,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QACjD,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;KAClE;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,sBAAsB,EAAE,QAAQ,CAAC,CAAC;QAC3I,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvC;IACD,OAAO,EAAE;QACP,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACzJ,MAAM,EAAE,IAAI,GAAG,CAAC,eAAe,CAAC;KACjC;CACF,CAAC;AAEF,2GAA2G;AAC3G,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,GAAW,EAAE,KAAa;IACpE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAE,CAAC;IAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa;IACb,IAAI;IACJ,MAAM;IACN,YAAY;IACZ,IAAI;IACJ,YAAY;IACZ,UAAU;IACV,SAAS;CACD,CAAC;AAcX;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK;CAC5D,CAAC;AAGX,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAQ,gBAAsC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,CAAU,CAAC;AAG3G;wCACwC;AACxC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,CAAU,CAAC;AAGtG;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc;IACtE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ;CAChD,CAAC;AAGX;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,MAAM,IAAI,GAAI,GAAiC,EAAE,IAAI,CAAC;IACtD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC5D,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,cAAc,CAAC;QACjE,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC;QACtC,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,iBAAiB;YAAE,OAAO,WAAW,CAAC;QAC3E,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,YAAY;YAAE,OAAO,WAAW,CAAC;IACnG,CAAC;IACD,MAAM,MAAM,GAAI,GAAmC,EAAE,MAAM,CAAC;IAC5D,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,QAAQ,CAAC;QACtD,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,cAAc,CAAC;QAC1C,IAAI,MAAM,IAAI,GAAG;YAAE,OAAO,OAAO,CAAC;IACpC,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IAC7E,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IACtE,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1C,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;4DAC4D;AAC5D,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC7B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,SAAS,CAAC;IAC/B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,WAAW,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;yCACyC;AACzC,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IACzB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,OAAO,CAAC;IAC3B,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC7B,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACvB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,OAAO,CAAC;IAC3B,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;wCACwC;AACxC,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,IAAI,EAAE,GAAG,EAAE;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,EAAE,GAAG,GAAG;QAAE,OAAO,UAAU,CAAC;IAChC,IAAI,EAAE,GAAG,GAAG;QAAE,OAAO,WAAW,CAAC;IACjC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,UAAU,CAAC;IACjC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;4CAC4C;AAC5C,MAAM,UAAU,iBAAiB,CAAC,CAAS;IACzC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACvB,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,MAAM,CAAC;IAC5B,IAAI,CAAC,GAAG,KAAK;QAAE,OAAO,OAAO,CAAC;IAC9B,IAAI,CAAC,GAAG,MAAM;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAwB;IACjD,MAAM,KAAK,GAAG,KAAK;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;SAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type SendResult } from './send.js';
2
+ /** Matches `UPDATE_TTL_MS`: a day is the natural period for both. */
3
+ export declare const FLUSH_TTL_MS: number;
4
+ export declare function needsFlush(flushedAt: number | undefined, now?: number): boolean;
5
+ /**
6
+ * Spawn the flush if the queue has something in it and a day has passed. Returns
7
+ * whether a child was started, for tests. Never waits, never throws.
8
+ */
9
+ export declare function maybeFlushInBackground(home?: string, now?: number): boolean;
10
+ /**
11
+ * Whether a failed send is worth keeping the batch for.
12
+ *
13
+ * A 5xx or a transport failure is ours to retry — a week offline should not be
14
+ * a week of lost events. A 4xx is not: a bad key or a malformed batch will fail
15
+ * identically forever, and retrying it would pin the queue at its cap until it
16
+ * starts dropping the events that WOULD have sent.
17
+ */
18
+ export declare function shouldRequeue(res: SendResult): boolean;
19
+ /** The `graft _telemetry-flush` body, running in the detached child. */
20
+ export declare function runFlush(home?: string): Promise<void>;
21
+ //# sourceMappingURL=flush.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flush.d.ts","sourceRoot":"","sources":["../../src/telemetry/flush.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvD,qEAAqE;AACrE,eAAO,MAAM,YAAY,QAAsB,CAAC;AAMhD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,SAAa,GAAG,OAAO,CAEnF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CAgB/E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAGtD;AAED,wEAAwE;AACxE,wBAAsB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3D"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Getting the queue off the machine without any command ever waiting for it.
3
+ *
4
+ * Deliberately the same shape as `maybeRefreshInBackground` in `upkeep.ts`,
5
+ * which has been doing this for the npm registry check since 0.7: check a
6
+ * timestamp, write the timestamp BEFORE spawning so a child that dies cannot
7
+ * make every subsequent command spawn another one, then `spawn` detached and
8
+ * `unref`. The parent returns immediately and never learns the outcome.
9
+ *
10
+ * Once a day, not once a command. Events are cheap to hold and the questions we
11
+ * are asking ("how many repos activated this week") do not get better answers
12
+ * from lower latency.
13
+ */
14
+ import { spawn } from 'node:child_process';
15
+ import { statSync } from 'node:fs';
16
+ import { graftCliPath } from '../claude/paths.js';
17
+ import { drain, queuePath, requeue } from './queue.js';
18
+ import { patchState, readState } from './identity.js';
19
+ import { sendBatch } from './send.js';
20
+ import { telemetryOn } from './gate.js';
21
+ /** Matches `UPDATE_TTL_MS`: a day is the natural period for both. */
22
+ export const FLUSH_TTL_MS = 24 * 60 * 60 * 1000;
23
+ function queueHasEvents(home) {
24
+ try {
25
+ return statSync(queuePath(home)).size > 0;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ export function needsFlush(flushedAt, now = Date.now()) {
32
+ return typeof flushedAt !== 'number' || now - flushedAt >= FLUSH_TTL_MS;
33
+ }
34
+ /**
35
+ * Spawn the flush if the queue has something in it and a day has passed. Returns
36
+ * whether a child was started, for tests. Never waits, never throws.
37
+ */
38
+ export function maybeFlushInBackground(home, now = Date.now()) {
39
+ try {
40
+ if (!telemetryOn(home))
41
+ return false;
42
+ if (!queueHasEvents(home))
43
+ return false;
44
+ if (!needsFlush(readState(home)?.flushedAt, now))
45
+ return false;
46
+ patchState({ flushedAt: now }, home); // before the spawn, so a dying child costs one attempt
47
+ const child = spawn(process.execPath, [graftCliPath(), '_telemetry-flush'], {
48
+ detached: true,
49
+ stdio: 'ignore',
50
+ windowsHide: true,
51
+ });
52
+ child.unref();
53
+ return true;
54
+ }
55
+ catch {
56
+ return false; // no spawn available (sandbox, ENOMEM) — try again tomorrow
57
+ }
58
+ }
59
+ /**
60
+ * Whether a failed send is worth keeping the batch for.
61
+ *
62
+ * A 5xx or a transport failure is ours to retry — a week offline should not be
63
+ * a week of lost events. A 4xx is not: a bad key or a malformed batch will fail
64
+ * identically forever, and retrying it would pin the queue at its cap until it
65
+ * starts dropping the events that WOULD have sent.
66
+ */
67
+ export function shouldRequeue(res) {
68
+ if (res.ok)
69
+ return false;
70
+ return res.status === undefined || res.status >= 500;
71
+ }
72
+ /** The `graft _telemetry-flush` body, running in the detached child. */
73
+ export async function runFlush(home) {
74
+ try {
75
+ if (!telemetryOn(home))
76
+ return;
77
+ const events = drain(home);
78
+ if (events.length === 0)
79
+ return;
80
+ if (shouldRequeue(await sendBatch(events)))
81
+ requeue(events, home);
82
+ }
83
+ catch { /* a failed flush is a non-event by design */ }
84
+ }
85
+ //# sourceMappingURL=flush.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flush.js","sourceRoot":"","sources":["../../src/telemetry/flush.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,CAAC;QAAC,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAA6B,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACxE,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,GAAG,GAAG,SAAS,IAAI,YAAY,CAAC;AAC1E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAa,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACpE,IAAI,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACrC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/D,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,uDAAuD;QAC7F,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,EAAE,kBAAkB,CAAC,EAAE;YAC1E,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,4DAA4D;IAC5E,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAe;IAC3C,IAAI,GAAG,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC;AACvD,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAa;IAC1C,IAAI,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,OAAO;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,IAAI,aAAa,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC,CAAC,6CAA6C,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,30 @@
1
+ export type OffReason = 'no-key' | 'do-not-track' | 'ci' | 'disabled';
2
+ /** The `DO_NOT_TRACK` convention: set and not `0`/empty means "off". */
3
+ export declare function doNotTrack(env?: NodeJS.ProcessEnv): boolean;
4
+ /**
5
+ * Every variable {@link inCi} reads, named once.
6
+ *
7
+ * Exported because a test that needs telemetry actually ON has to clear all of
8
+ * them, and clearing a hand-copied subset is how this list silently drifts: the
9
+ * `cursor-session-end` test cleared `CI` alone, so it passed on a laptop and failed
10
+ * on GitHub Actions — where `GITHUB_ACTIONS` is set — for every run until someone
11
+ * read the log. One list, both callers.
12
+ */
13
+ export declare const CI_ENV_VARS: readonly ["CI", "GITHUB_ACTIONS", "GITLAB_CI", "BUILDKITE", "CIRCLECI", "TEAMCITY_VERSION", "JENKINS_URL", "TF_BUILD", "BUILD_NUMBER"];
14
+ /**
15
+ * CI detection. `CI` covers essentially every provider; the rest are the ones
16
+ * that historically did not set it. Deliberately generous — a false positive
17
+ * costs one uncounted user, a false negative pollutes the dataset.
18
+ *
19
+ * `CI` is the one read with a value test: `CI=false` is a real thing a user sets
20
+ * to mean "not CI", while the provider-specific vars are presence-only — none of
21
+ * them is ever deliberately set to a falsy string.
22
+ */
23
+ export declare function inCi(env?: NodeJS.ProcessEnv): boolean;
24
+ /** Null when telemetry may run, otherwise the first gate that closed. */
25
+ export declare function offReason(home?: string, env?: NodeJS.ProcessEnv): OffReason | null;
26
+ export declare function telemetryOn(home?: string, env?: NodeJS.ProcessEnv): boolean;
27
+ /** One line for `graft telemetry status`, naming the gate that is closed so a
28
+ * user who thinks they disabled it can see which switch actually took. */
29
+ export declare function explainOff(reason: OffReason): string;
30
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/telemetry/gate.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,IAAI,GAAG,UAAU,CAAC;AAEtE,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGxE;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,wIAGd,CAAC;AAEX;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGlE;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,GAAG,IAAI,CAM/F;AAED,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAExF;AAED;2EAC2E;AAC3E,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAOpD"}