@nanonets/graft 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/README.md +549 -315
  2. package/dist/app/review-process.d.ts.map +1 -1
  3. package/dist/app/review-process.js +6 -5
  4. package/dist/app/review-process.js.map +1 -1
  5. package/dist/app/sources.js +2 -2
  6. package/dist/app/sources.js.map +1 -1
  7. package/dist/ask/ask.d.ts +12 -6
  8. package/dist/ask/ask.d.ts.map +1 -1
  9. package/dist/ask/ask.js +28 -38
  10. package/dist/ask/ask.js.map +1 -1
  11. package/dist/bin/graft.d.ts +3 -0
  12. package/dist/bin/graft.d.ts.map +1 -0
  13. package/dist/bin/graft.js +8 -0
  14. package/dist/bin/graft.js.map +1 -0
  15. package/dist/bin/trail.d.ts +3 -0
  16. package/dist/bin/trail.d.ts.map +1 -0
  17. package/dist/bin/trail.js +6 -0
  18. package/dist/bin/trail.js.map +1 -0
  19. package/dist/blast/blast-cli.d.ts.map +1 -1
  20. package/dist/blast/blast-cli.js +2 -1
  21. package/dist/blast/blast-cli.js.map +1 -1
  22. package/dist/blast/render.d.ts.map +1 -1
  23. package/dist/blast/render.js +3 -2
  24. package/dist/blast/render.js.map +1 -1
  25. package/dist/brand.d.ts +97 -0
  26. package/dist/brand.d.ts.map +1 -0
  27. package/dist/brand.js +254 -0
  28. package/dist/brand.js.map +1 -0
  29. package/dist/check/local-check.d.ts +104 -0
  30. package/dist/check/local-check.d.ts.map +1 -0
  31. package/dist/check/local-check.js +830 -0
  32. package/dist/check/local-check.js.map +1 -0
  33. package/dist/check/types.d.ts +31 -0
  34. package/dist/check/types.d.ts.map +1 -0
  35. package/dist/check/types.js +2 -0
  36. package/dist/check/types.js.map +1 -0
  37. package/dist/claude/format.d.ts +44 -1
  38. package/dist/claude/format.d.ts.map +1 -1
  39. package/dist/claude/format.js +113 -19
  40. package/dist/claude/format.js.map +1 -1
  41. package/dist/claude/hook-layers.d.ts +8 -0
  42. package/dist/claude/hook-layers.d.ts.map +1 -0
  43. package/dist/claude/hook-layers.js +72 -0
  44. package/dist/claude/hook-layers.js.map +1 -0
  45. package/dist/claude/hooks.d.ts +34 -0
  46. package/dist/claude/hooks.d.ts.map +1 -1
  47. package/dist/claude/hooks.js +220 -12
  48. package/dist/claude/hooks.js.map +1 -1
  49. package/dist/claude/init.d.ts +12 -1
  50. package/dist/claude/init.d.ts.map +1 -1
  51. package/dist/claude/init.js +48 -19
  52. package/dist/claude/init.js.map +1 -1
  53. package/dist/claude/session-metrics.d.ts +1 -1
  54. package/dist/claude/session-metrics.d.ts.map +1 -1
  55. package/dist/claude/session-metrics.js +11 -8
  56. package/dist/claude/session-metrics.js.map +1 -1
  57. package/dist/claude/settings-merge.d.ts +1 -0
  58. package/dist/claude/settings-merge.d.ts.map +1 -1
  59. package/dist/claude/settings-merge.js +21 -18
  60. package/dist/claude/settings-merge.js.map +1 -1
  61. package/dist/claude/shim-template.d.ts +17 -2
  62. package/dist/claude/shim-template.d.ts.map +1 -1
  63. package/dist/claude/shim-template.js +116 -22
  64. package/dist/claude/shim-template.js.map +1 -1
  65. package/dist/claude/skill-template.d.ts +10 -1
  66. package/dist/claude/skill-template.d.ts.map +1 -1
  67. package/dist/claude/skill-template.js +132 -1
  68. package/dist/claude/skill-template.js.map +1 -1
  69. package/dist/claude/state.d.ts +8 -0
  70. package/dist/claude/state.d.ts.map +1 -1
  71. package/dist/claude/state.js.map +1 -1
  72. package/dist/claude/statusline.d.ts.map +1 -1
  73. package/dist/claude/statusline.js +4 -1
  74. package/dist/claude/statusline.js.map +1 -1
  75. package/dist/claude/tally.js +1 -1
  76. package/dist/claude/tally.js.map +1 -1
  77. package/dist/cli-epilogue.d.ts +0 -6
  78. package/dist/cli-epilogue.d.ts.map +1 -1
  79. package/dist/cli-epilogue.js +5 -4
  80. package/dist/cli-epilogue.js.map +1 -1
  81. package/dist/cli-meta.d.ts +8 -0
  82. package/dist/cli-meta.d.ts.map +1 -1
  83. package/dist/cli-meta.js +28 -8
  84. package/dist/cli-meta.js.map +1 -1
  85. package/dist/cli-picker.d.ts.map +1 -1
  86. package/dist/cli-picker.js +11 -7
  87. package/dist/cli-picker.js.map +1 -1
  88. package/dist/cli.d.ts +0 -5
  89. package/dist/cli.d.ts.map +1 -1
  90. package/dist/cli.js +1037 -595
  91. package/dist/cli.js.map +1 -1
  92. package/dist/cloud/diff.d.ts +18 -0
  93. package/dist/cloud/diff.d.ts.map +1 -0
  94. package/dist/cloud/diff.js +58 -0
  95. package/dist/cloud/diff.js.map +1 -0
  96. package/dist/cloud/nudge.d.ts +66 -0
  97. package/dist/cloud/nudge.d.ts.map +1 -0
  98. package/dist/cloud/nudge.js +269 -0
  99. package/dist/cloud/nudge.js.map +1 -0
  100. package/dist/cloud/workspace-sync.d.ts +58 -0
  101. package/dist/cloud/workspace-sync.d.ts.map +1 -0
  102. package/dist/cloud/workspace-sync.js +268 -0
  103. package/dist/cloud/workspace-sync.js.map +1 -0
  104. package/dist/cloud/workspace.d.ts +159 -0
  105. package/dist/cloud/workspace.d.ts.map +1 -0
  106. package/dist/cloud/workspace.js +134 -0
  107. package/dist/cloud/workspace.js.map +1 -0
  108. package/dist/context/check.d.ts +1 -1
  109. package/dist/context/check.d.ts.map +1 -1
  110. package/dist/context/check.js +9 -8
  111. package/dist/context/check.js.map +1 -1
  112. package/dist/context/node-file.js +1 -1
  113. package/dist/context/node-file.js.map +1 -1
  114. package/dist/context/savings.d.ts.map +1 -1
  115. package/dist/context/savings.js +10 -7
  116. package/dist/context/savings.js.map +1 -1
  117. package/dist/engine.d.ts.map +1 -1
  118. package/dist/engine.js +3 -1
  119. package/dist/engine.js.map +1 -1
  120. package/dist/graph/build.d.ts +30 -0
  121. package/dist/graph/build.d.ts.map +1 -1
  122. package/dist/graph/build.js +65 -19
  123. package/dist/graph/build.js.map +1 -1
  124. package/dist/graph/cards.d.ts.map +1 -1
  125. package/dist/graph/cards.js +4 -2
  126. package/dist/graph/cards.js.map +1 -1
  127. package/dist/graph/check.d.ts.map +1 -1
  128. package/dist/graph/check.js +17 -18
  129. package/dist/graph/check.js.map +1 -1
  130. package/dist/graph/container.d.ts.map +1 -1
  131. package/dist/graph/container.js +7 -2
  132. package/dist/graph/container.js.map +1 -1
  133. package/dist/graph/extract-cache.d.ts +4 -0
  134. package/dist/graph/extract-cache.d.ts.map +1 -1
  135. package/dist/graph/extract-cache.js.map +1 -1
  136. package/dist/graph/extract.d.ts +2 -0
  137. package/dist/graph/extract.d.ts.map +1 -1
  138. package/dist/graph/extract.js +5 -32
  139. package/dist/graph/extract.js.map +1 -1
  140. package/dist/graph/generic.d.ts +7 -1
  141. package/dist/graph/generic.d.ts.map +1 -1
  142. package/dist/graph/generic.js +48 -8
  143. package/dist/graph/generic.js.map +1 -1
  144. package/dist/graph/native.d.ts +38 -0
  145. package/dist/graph/native.d.ts.map +1 -0
  146. package/dist/graph/native.js +169 -0
  147. package/dist/graph/native.js.map +1 -0
  148. package/dist/graph/refresh.d.ts.map +1 -1
  149. package/dist/graph/refresh.js +3 -2
  150. package/dist/graph/refresh.js.map +1 -1
  151. package/dist/graph/traverse-cli.d.ts.map +1 -1
  152. package/dist/graph/traverse-cli.js +4 -3
  153. package/dist/graph/traverse-cli.js.map +1 -1
  154. package/dist/graph/workspace-cli.d.ts +2 -0
  155. package/dist/graph/workspace-cli.d.ts.map +1 -1
  156. package/dist/graph/workspace-cli.js +13 -1
  157. package/dist/graph/workspace-cli.js.map +1 -1
  158. package/dist/graph/workspace.d.ts.map +1 -1
  159. package/dist/graph/workspace.js +6 -5
  160. package/dist/graph/workspace.js.map +1 -1
  161. package/dist/hosts/antigravity.d.ts +10 -3
  162. package/dist/hosts/antigravity.d.ts.map +1 -1
  163. package/dist/hosts/antigravity.js +27 -10
  164. package/dist/hosts/antigravity.js.map +1 -1
  165. package/dist/hosts/claude-global.d.ts +27 -4
  166. package/dist/hosts/claude-global.d.ts.map +1 -1
  167. package/dist/hosts/claude-global.js +90 -9
  168. package/dist/hosts/claude-global.js.map +1 -1
  169. package/dist/hosts/codex-hooks.d.ts.map +1 -1
  170. package/dist/hosts/codex-hooks.js +1 -2
  171. package/dist/hosts/codex-hooks.js.map +1 -1
  172. package/dist/hosts/config-write.d.ts.map +1 -1
  173. package/dist/hosts/config-write.js +2 -1
  174. package/dist/hosts/config-write.js.map +1 -1
  175. package/dist/hosts/cursor-hooks.d.ts +5 -2
  176. package/dist/hosts/cursor-hooks.d.ts.map +1 -1
  177. package/dist/hosts/cursor-hooks.js +14 -9
  178. package/dist/hosts/cursor-hooks.js.map +1 -1
  179. package/dist/hosts/init.d.ts +3 -0
  180. package/dist/hosts/init.d.ts.map +1 -1
  181. package/dist/hosts/init.js +32 -10
  182. package/dist/hosts/init.js.map +1 -1
  183. package/dist/hosts/instructions.d.ts +9 -4
  184. package/dist/hosts/instructions.d.ts.map +1 -1
  185. package/dist/hosts/instructions.js +19 -16
  186. package/dist/hosts/instructions.js.map +1 -1
  187. package/dist/hosts/mcp-config.d.ts +19 -4
  188. package/dist/hosts/mcp-config.d.ts.map +1 -1
  189. package/dist/hosts/mcp-config.js +81 -30
  190. package/dist/hosts/mcp-config.js.map +1 -1
  191. package/dist/hosts/plan.d.ts.map +1 -1
  192. package/dist/hosts/plan.js +11 -9
  193. package/dist/hosts/plan.js.map +1 -1
  194. package/dist/hosts/registry.d.ts +25 -2
  195. package/dist/hosts/registry.d.ts.map +1 -1
  196. package/dist/hosts/registry.js +53 -0
  197. package/dist/hosts/registry.js.map +1 -1
  198. package/dist/hosts/retract.d.ts.map +1 -1
  199. package/dist/hosts/retract.js +73 -33
  200. package/dist/hosts/retract.js.map +1 -1
  201. package/dist/hosts/sections.d.ts +17 -1
  202. package/dist/hosts/sections.d.ts.map +1 -1
  203. package/dist/hosts/sections.js +52 -2
  204. package/dist/hosts/sections.js.map +1 -1
  205. package/dist/mcp/instructions.d.ts +1 -25
  206. package/dist/mcp/instructions.d.ts.map +1 -1
  207. package/dist/mcp/instructions.js +6 -4
  208. package/dist/mcp/instructions.js.map +1 -1
  209. package/dist/mcp/server.d.ts.map +1 -1
  210. package/dist/mcp/server.js +7 -3
  211. package/dist/mcp/server.js.map +1 -1
  212. package/dist/mcp/tool-names.d.ts +10 -3
  213. package/dist/mcp/tool-names.d.ts.map +1 -1
  214. package/dist/mcp/tool-names.js +13 -5
  215. package/dist/mcp/tool-names.js.map +1 -1
  216. package/dist/mcp/tools.d.ts.map +1 -1
  217. package/dist/mcp/tools.js +6 -5
  218. package/dist/mcp/tools.js.map +1 -1
  219. package/dist/notes/ask-notes.d.ts +8 -0
  220. package/dist/notes/ask-notes.d.ts.map +1 -0
  221. package/dist/notes/ask-notes.js +18 -0
  222. package/dist/notes/ask-notes.js.map +1 -0
  223. package/dist/notes/branches.d.ts +85 -0
  224. package/dist/notes/branches.d.ts.map +1 -0
  225. package/dist/notes/branches.js +238 -0
  226. package/dist/notes/branches.js.map +1 -0
  227. package/dist/notes/cold-start.d.ts +127 -0
  228. package/dist/notes/cold-start.d.ts.map +1 -0
  229. package/dist/notes/cold-start.js +476 -0
  230. package/dist/notes/cold-start.js.map +1 -0
  231. package/dist/notes/git-facts.d.ts +17 -0
  232. package/dist/notes/git-facts.d.ts.map +1 -0
  233. package/dist/notes/git-facts.js +117 -0
  234. package/dist/notes/git-facts.js.map +1 -0
  235. package/dist/notes/home.d.ts +87 -0
  236. package/dist/notes/home.d.ts.map +1 -0
  237. package/dist/notes/home.js +423 -0
  238. package/dist/notes/home.js.map +1 -0
  239. package/dist/notes/notes.d.ts +178 -0
  240. package/dist/notes/notes.d.ts.map +1 -0
  241. package/dist/notes/notes.js +498 -0
  242. package/dist/notes/notes.js.map +1 -0
  243. package/dist/notes/repo-trail.d.ts +16 -0
  244. package/dist/notes/repo-trail.d.ts.map +1 -0
  245. package/dist/notes/repo-trail.js +74 -0
  246. package/dist/notes/repo-trail.js.map +1 -0
  247. package/dist/notes/session-cost.d.ts +21 -0
  248. package/dist/notes/session-cost.d.ts.map +1 -0
  249. package/dist/notes/session-cost.js +162 -0
  250. package/dist/notes/session-cost.js.map +1 -0
  251. package/dist/search/grep-cli.d.ts.map +1 -1
  252. package/dist/search/grep-cli.js +4 -3
  253. package/dist/search/grep-cli.js.map +1 -1
  254. package/dist/skills/skills.d.ts +118 -0
  255. package/dist/skills/skills.d.ts.map +1 -0
  256. package/dist/skills/skills.js +370 -0
  257. package/dist/skills/skills.js.map +1 -0
  258. package/dist/telemetry/contract.d.ts +2 -14
  259. package/dist/telemetry/contract.d.ts.map +1 -1
  260. package/dist/telemetry/contract.js +39 -24
  261. package/dist/telemetry/contract.js.map +1 -1
  262. package/dist/telemetry/gate.d.ts.map +1 -1
  263. package/dist/telemetry/gate.js +2 -1
  264. package/dist/telemetry/gate.js.map +1 -1
  265. package/dist/telemetry/notice.d.ts +1 -1
  266. package/dist/telemetry/notice.d.ts.map +1 -1
  267. package/dist/telemetry/notice.js +6 -5
  268. package/dist/telemetry/notice.js.map +1 -1
  269. package/dist/telemetry/track.d.ts.map +1 -1
  270. package/dist/telemetry/track.js +5 -0
  271. package/dist/telemetry/track.js.map +1 -1
  272. package/dist/upkeep-run.d.ts +7 -0
  273. package/dist/upkeep-run.d.ts.map +1 -1
  274. package/dist/upkeep-run.js +52 -12
  275. package/dist/upkeep-run.js.map +1 -1
  276. package/dist/upkeep.d.ts +9 -19
  277. package/dist/upkeep.d.ts.map +1 -1
  278. package/dist/upkeep.js +38 -59
  279. package/dist/upkeep.js.map +1 -1
  280. package/dist/util/browser.d.ts +3 -0
  281. package/dist/util/browser.d.ts.map +1 -0
  282. package/dist/util/browser.js +14 -0
  283. package/dist/util/browser.js.map +1 -0
  284. package/dist/util/front-matter.d.ts +19 -0
  285. package/dist/util/front-matter.d.ts.map +1 -0
  286. package/dist/util/front-matter.js +21 -0
  287. package/dist/util/front-matter.js.map +1 -0
  288. package/dist/util/state.d.ts +1 -18
  289. package/dist/util/state.d.ts.map +1 -1
  290. package/dist/util/state.js +4 -2
  291. package/dist/util/state.js.map +1 -1
  292. package/dist/viz/assemble.js +1 -1
  293. package/dist/viz/assemble.js.map +1 -1
  294. package/dist/viz/serve.d.ts.map +1 -1
  295. package/dist/viz/serve.js +4 -3
  296. package/dist/viz/serve.js.map +1 -1
  297. package/package.json +7 -7
  298. package/scripts/pack-trail.mjs +53 -0
  299. package/scripts/postinstall.mjs +17 -2
  300. package/scripts/run-tests.mjs +4 -1
  301. package/dist/brain/attach.d.ts +0 -44
  302. package/dist/brain/attach.d.ts.map +0 -1
  303. package/dist/brain/attach.js +0 -63
  304. package/dist/brain/attach.js.map +0 -1
  305. package/dist/brain/claude-md.d.ts +0 -61
  306. package/dist/brain/claude-md.d.ts.map +0 -1
  307. package/dist/brain/claude-md.js +0 -171
  308. package/dist/brain/claude-md.js.map +0 -1
  309. package/dist/brain/connect.d.ts +0 -59
  310. package/dist/brain/connect.d.ts.map +0 -1
  311. package/dist/brain/connect.js +0 -80
  312. package/dist/brain/connect.js.map +0 -1
  313. package/dist/brain/context-files.d.ts +0 -79
  314. package/dist/brain/context-files.d.ts.map +0 -1
  315. package/dist/brain/context-files.js +0 -245
  316. package/dist/brain/context-files.js.map +0 -1
  317. package/dist/brain/link.d.ts +0 -106
  318. package/dist/brain/link.d.ts.map +0 -1
  319. package/dist/brain/link.js +0 -167
  320. package/dist/brain/link.js.map +0 -1
  321. package/dist/brain/pull.d.ts +0 -17
  322. package/dist/brain/pull.d.ts.map +0 -1
  323. package/dist/brain/pull.js +0 -172
  324. package/dist/brain/pull.js.map +0 -1
  325. package/dist/brain/push.d.ts +0 -155
  326. package/dist/brain/push.d.ts.map +0 -1
  327. package/dist/brain/push.js +0 -304
  328. package/dist/brain/push.js.map +0 -1
  329. package/dist/brain/signup.d.ts +0 -117
  330. package/dist/brain/signup.d.ts.map +0 -1
  331. package/dist/brain/signup.js +0 -276
  332. package/dist/brain/signup.js.map +0 -1
  333. package/dist/brain/upload.d.ts +0 -61
  334. package/dist/brain/upload.d.ts.map +0 -1
  335. package/dist/brain/upload.js +0 -210
  336. package/dist/brain/upload.js.map +0 -1
  337. package/dist/brain/watch.d.ts +0 -209
  338. package/dist/brain/watch.d.ts.map +0 -1
  339. package/dist/brain/watch.js +0 -396
  340. package/dist/brain/watch.js.map +0 -1
  341. package/dist/brain/wire.d.ts +0 -38
  342. package/dist/brain/wire.d.ts.map +0 -1
  343. package/dist/brain/wire.js +0 -133
  344. package/dist/brain/wire.js.map +0 -1
  345. package/dist/legacy-args.d.ts +0 -12
  346. package/dist/legacy-args.d.ts.map +0 -1
  347. package/dist/legacy-args.js +0 -31
  348. package/dist/legacy-args.js.map +0 -1
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Teammates' pushed branches: which files each one changes, and the learnings
3
+ * it carries that the default branch doesn't have yet.
4
+ *
5
+ * This is how two people find out they're on the same thing before review,
6
+ * with no server: once work is pushed, `git fetch` brings it to every clone.
7
+ * Learnings committed on a branch reach everyone the same way, hours or days
8
+ * before the branch merges.
9
+ *
10
+ * Reading branches takes git, and hooks and `ask` must not wait on it, so a
11
+ * detached `_trail-branches` child fetches and writes what it found to a
12
+ * cache, at most every REFRESH_MS. Everything that reads it reads the cache.
13
+ */
14
+ import { execFileSync, spawn } from "node:child_process";
15
+ import { readdirSync, readFileSync, statSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { graftCliPath } from "../claude/paths.js";
18
+ import { cacheDir, readJson, writeJsonAtomic } from "../util/state.js";
19
+ import { LEARNINGS_DIR } from "./repo-trail.js";
20
+ /** How old the cache may get before the next command refreshes it in the
21
+ * background: about what editors that fetch on their own wait between fetches. */
22
+ export const REFRESH_MS = 3 * 60 * 1000;
23
+ /** At the start of a session, a cache older than this is refreshed. */
24
+ export const SESSION_REFRESH_MS = 60 * 1000;
25
+ /** A refresh that started this long ago without finishing is presumed dead. */
26
+ const STALE_RUN_MS = 2 * 60 * 1000;
27
+ /** Branches older than this are finished or abandoned work, not overlap. */
28
+ export const BRANCH_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
29
+ /** Most branches read per refresh, newest first. */
30
+ const MAX_BRANCHES = 30;
31
+ /** Most changed files kept per branch. */
32
+ const MAX_FILES = 200;
33
+ /** A learning file name as `trail note` writes it: no folders, no shell characters. */
34
+ export const SAFE_LEARNING_NAME = /^[A-Za-z0-9._-]+\.md$/;
35
+ /** Most learnings read per branch, and the most bytes per learning. */
36
+ const MAX_LEARNINGS = 20;
37
+ const MAX_LEARNING_BYTES = 64 * 1024;
38
+ function cachePath(repo) {
39
+ return join(cacheDir(repo), "trail-branches.json");
40
+ }
41
+ export function readBranchCache(repo) {
42
+ return readJson(cachePath(repo));
43
+ }
44
+ function git(repo, args, timeout = 15_000) {
45
+ try {
46
+ // Never a credential prompt: this runs detached, where nobody could answer it.
47
+ return execFileSync("git", args, {
48
+ cwd: repo,
49
+ encoding: "utf8",
50
+ stdio: ["ignore", "pipe", "ignore"],
51
+ timeout,
52
+ maxBuffer: 16 * 1024 * 1024,
53
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
54
+ });
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ /** First word of a name, capitalised, the way a learning's author is written. Letters only, at most 40. */
61
+ function firstName(name) {
62
+ const first = (name.trim().split(/\s+/)[0] ?? "").replace(/[^\p{L}\p{N}._-]/gu, "").slice(0, 40);
63
+ return first ? first[0].toUpperCase() + first.slice(1) : "";
64
+ }
65
+ /**
66
+ * A branch name as it may appear in what the agent reads: the characters git
67
+ * branch names are usually made of, at most 80. Branch names and authors come
68
+ * from whoever pushed, so nothing else of theirs reaches an instruction.
69
+ */
70
+ export function safeRef(ref) {
71
+ return ref.replace(/[^A-Za-z0-9._/-]/g, "").slice(0, 80);
72
+ }
73
+ /** The remote branch everything is compared with: what origin/HEAD points at, else a usual name. */
74
+ function defaultRef(repo) {
75
+ const head = git(repo, ["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"])?.trim();
76
+ if (head)
77
+ return head;
78
+ for (const name of ["origin/main", "origin/master", "origin/trunk", "origin/dev"]) {
79
+ if (git(repo, ["rev-parse", "--verify", "--quiet", name]) !== null)
80
+ return name;
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Fetch, then read every recently pushed branch: the files it changes and the
86
+ * learnings it adds. Writes the cache and returns it. `fetch: false` reads
87
+ * the refs already on this machine, for tests and for a repo that's offline.
88
+ */
89
+ export function refreshBranches(repo, opts = {}) {
90
+ const now = opts.now ?? Date.now();
91
+ // TRAIL_NO_FETCH: tests, and anyone who'd rather fetch themselves.
92
+ if (opts.fetch !== false && !process.env.TRAIL_NO_FETCH)
93
+ git(repo, ["fetch", "--quiet", "--prune", "origin"], opts.fetchTimeoutMs ?? 30_000);
94
+ const base = defaultRef(repo);
95
+ const branches = [];
96
+ if (base) {
97
+ const listed = git(repo, ["for-each-ref", "--sort=-committerdate", "--format=%(refname:short)%09%(committerdate:unix)%09%(authorname)", "refs/remotes/origin"]) ?? "";
98
+ for (const line of listed.split("\n")) {
99
+ if (branches.length >= MAX_BRANCHES)
100
+ break;
101
+ const [ref, unix, author] = line.split("\t");
102
+ if (!ref || ref === base || ref === "origin/HEAD" || ref === "origin")
103
+ continue;
104
+ // A name made only of what branch names are usually made of, or the branch is skipped:
105
+ // it reaches what the agent reads, and a cleaned-up copy would name a different branch.
106
+ if (safeRef(ref) !== ref)
107
+ continue;
108
+ const at = Number(unix) * 1000;
109
+ if (!Number.isFinite(at) || now - at > BRANCH_WINDOW_MS)
110
+ continue;
111
+ const changed = (git(repo, ["diff", "--name-only", `${base}...${ref}`]) ?? "").split("\n").map((f) => f.trim()).filter(Boolean);
112
+ if (changed.length === 0)
113
+ continue;
114
+ const learnings = [];
115
+ // Only names trail itself would write: the name reaches a command the agent may run.
116
+ const named = changed.filter((f) => f.startsWith(`${LEARNINGS_DIR}/`) && SAFE_LEARNING_NAME.test(f.slice(LEARNINGS_DIR.length + 1)));
117
+ for (const path of named.slice(0, MAX_LEARNINGS)) {
118
+ const text = git(repo, ["show", `${ref}:${path}`]);
119
+ if (text && text.length <= MAX_LEARNING_BYTES)
120
+ learnings.push({ name: path.slice(LEARNINGS_DIR.length + 1), text });
121
+ }
122
+ branches.push({ ref, author: firstName(author ?? ""), at, files: changed.slice(0, MAX_FILES), learnings });
123
+ }
124
+ }
125
+ const cache = { fetchedAt: Date.now(), stamp: refsStamp(repo), base, branches };
126
+ writeJsonAtomic(cachePath(repo), cache, true);
127
+ return cache;
128
+ }
129
+ /** The checkout's shared git dir: `.git`, or for a linked worktree the main one's. Read, never spawned. */
130
+ function commonGitDir(repo) {
131
+ const dot = join(repo, ".git");
132
+ try {
133
+ if (statSync(dot).isDirectory())
134
+ return dot;
135
+ const line = readFileSync(dot, "utf8").split("\n").find((l) => l.startsWith("gitdir:"));
136
+ const gitDir = line?.slice("gitdir:".length).trim();
137
+ if (!gitDir)
138
+ return null;
139
+ try {
140
+ return join(gitDir, readFileSync(join(gitDir, "commondir"), "utf8").trim());
141
+ }
142
+ catch {
143
+ return gitDir;
144
+ }
145
+ }
146
+ catch {
147
+ return null;
148
+ }
149
+ }
150
+ /**
151
+ * When this clone's idea of the remote last changed: the newest mtime under
152
+ * `refs/remotes/`, `packed-refs` and `FETCH_HEAD`. A push updates the
153
+ * remote-tracking ref it pushed, and a fetch rewrites FETCH_HEAD, so either
154
+ * shows here without running git.
155
+ */
156
+ export function refsStamp(repo) {
157
+ const dir = commonGitDir(repo);
158
+ if (!dir)
159
+ return "";
160
+ let newest = 0;
161
+ const walk = (p, depth) => {
162
+ try {
163
+ const st = statSync(p);
164
+ newest = Math.max(newest, st.mtimeMs);
165
+ if (st.isDirectory() && depth < 6)
166
+ for (const e of readdirSync(p))
167
+ walk(join(p, e), depth + 1);
168
+ }
169
+ catch {
170
+ /* gone, or never there */
171
+ }
172
+ };
173
+ walk(join(dir, "refs", "remotes"), 0);
174
+ for (const f of ["packed-refs", "FETCH_HEAD"])
175
+ walk(join(dir, f), 6);
176
+ return String(Math.round(newest));
177
+ }
178
+ /** Whether the cache is older than `maxAgeMs`, or the clone's remote refs moved since it was written. */
179
+ export function branchesStale(repo, now = Date.now(), maxAgeMs = REFRESH_MS) {
180
+ const cache = readBranchCache(repo);
181
+ return !cache || now - cache.fetchedAt >= maxAgeMs || cache.stamp !== refsStamp(repo);
182
+ }
183
+ /**
184
+ * Refresh in a detached child when the cache is older than `maxAgeMs`, or
185
+ * the clone's remote refs moved since (a push, a fetch), and no refresh is
186
+ * already running. Never waits, never throws. A checkout with no origin gets
187
+ * an empty cache.
188
+ */
189
+ export function maybeRefreshBranches(repo, now = Date.now(), maxAgeMs = REFRESH_MS) {
190
+ try {
191
+ const cache = readBranchCache(repo);
192
+ if (!branchesStale(repo, now, maxAgeMs))
193
+ return false;
194
+ if (cache?.runningSince && now - cache.runningSince < STALE_RUN_MS)
195
+ return false;
196
+ writeJsonAtomic(cachePath(repo), { ...(cache ?? { fetchedAt: 0, base: null, branches: [] }), runningSince: now }, true);
197
+ const child = spawn(process.execPath, [graftCliPath(), "_trail-branches", repo], { detached: true, stdio: "ignore", windowsHide: true });
198
+ child.unref();
199
+ return true;
200
+ }
201
+ catch {
202
+ return false;
203
+ }
204
+ }
205
+ /**
206
+ * Teammates' pushed branches that change any of `files`: work going on in the
207
+ * same place, from someone other than `me`, newest first.
208
+ */
209
+ export function overlapsWith(repo, files, me, cache = readBranchCache(repo)) {
210
+ if (!cache || files.length === 0)
211
+ return [];
212
+ const mine = new Set(files.filter((f) => !f.startsWith(".trail/")));
213
+ const out = [];
214
+ for (const b of cache.branches) {
215
+ if (!b.author || b.author === me)
216
+ continue;
217
+ const shared = b.files.filter((f) => mine.has(f));
218
+ if (shared.length)
219
+ out.push({ ref: b.ref, author: b.author, at: b.at, shared });
220
+ }
221
+ return out.sort((a, b) => b.at - a.at);
222
+ }
223
+ const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
224
+ /** `today 14:20`, `Oct 7`: when a branch was pushed, short. */
225
+ export function pushedWhen(at, now = Date.now()) {
226
+ const d = new Date(at);
227
+ const n = new Date(now);
228
+ if (d.toDateString() === n.toDateString())
229
+ return `today ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
230
+ return `${MONTHS[d.getMonth()]} ${d.getDate()}`;
231
+ }
232
+ /** `● overlap · Kumar's branch kumar/jitter also changes client.go (pushed today 14:20)`. */
233
+ export function formatOverlap(o, now = Date.now()) {
234
+ const branch = o.ref.replace(/^origin\//, "");
235
+ const files = o.shared.length <= 2 ? o.shared.join(" and ") : `${o.shared.slice(0, 2).join(", ")} and ${o.shared.length - 2} more`;
236
+ return `● overlap · ${o.author}'s branch ${branch} also changes ${files} (pushed ${pushedWhen(o.at, now)})`;
237
+ }
238
+ //# sourceMappingURL=branches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branches.js","sourceRoot":"","sources":["../../src/notes/branches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;kFACkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACxC,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC5C,+EAA+E;AAC/E,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzD,oDAAoD;AACpD,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,0CAA0C;AAC1C,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAC1D,uEAAuE;AACvE,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AA2BrC,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAc,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,GAAG,CAAC,IAAY,EAAE,IAAc,EAAE,OAAO,GAAG,MAAM;IACzD,IAAI,CAAC;QACH,+EAA+E;QAC/E,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/B,GAAG,EAAE,IAAI;YACT,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,OAAO;YACP,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE;SAClD,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2GAA2G;AAC3G,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjG,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,oGAAoG;AACpG,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,0BAA0B,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACnG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC;QAClF,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAmE,EAAE;IACjH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,mEAAmE;IACnE,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC;IAC7I,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,cAAc,EAAE,uBAAuB,EAAE,mEAAmE,EAAE,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC;QACtK,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,QAAQ,CAAC,MAAM,IAAI,YAAY;gBAAE,MAAM;YAC3C,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,QAAQ;gBAAE,SAAS;YAChF,uFAAuF;YACvF,wFAAwF;YACxF,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG;gBAAE,SAAS;YACnC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,EAAE,GAAG,gBAAgB;gBAAE,SAAS;YAClE,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAChI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,SAAS,GAA8B,EAAE,CAAC;YAChD,qFAAqF;YACrF,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,aAAa,GAAG,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrI,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC;gBACjD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnD,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,kBAAkB;oBAAE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACtH,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAgB,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC7F,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,2GAA2G;AAC3G,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YAAE,OAAO,GAAG,CAAC;QAC5C,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QACxF,MAAM,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,KAAa,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,KAAK,GAAG,CAAC;gBAAE,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QACjG,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,GAAG,UAAU;IACjF,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,GAAG,UAAU;IACxF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACtD,IAAI,KAAK,EAAE,YAAY,IAAI,GAAG,GAAG,KAAK,CAAC,YAAY,GAAG,YAAY;YAAE,OAAO,KAAK,CAAC;QACjF,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QACxH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACzI,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAUD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAe,EAAE,EAAU,EAAE,QAA4B,eAAe,CAAC,IAAI,CAAC;IACvH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,EAAE;YAAE,SAAS;QAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,MAAM,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAEpG,+DAA+D;AAC/D,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACrD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,YAAY,EAAE;QAAE,OAAO,SAAS,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC9I,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,aAAa,CAAC,CAAU,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACxD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;IACnI,OAAO,eAAe,CAAC,CAAC,MAAM,aAAa,MAAM,iBAAiB,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC;AAC9G,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { type Note } from "./notes.js";
2
+ /** One message the person wrote, with the end of what Claude said just before it. */
3
+ export interface PastPrompt {
4
+ text: string;
5
+ /** The tail of Claude's last reply before this message, so "no, use a worktree" reads on its own. */
6
+ before?: string;
7
+ }
8
+ export interface PastSession {
9
+ id: string;
10
+ /** ISO time of the first message. */
11
+ at: string;
12
+ branch?: string;
13
+ prompts: PastPrompt[];
14
+ }
15
+ export interface Finding {
16
+ title: string;
17
+ /** `team`: about the code or how the team works here. `you`: this person's own habits or machine. */
18
+ for: "team" | "you";
19
+ /** Markdown under `## Decided` and maybe `## Watch out`, secrets scrubbed. */
20
+ body: string;
21
+ /** Sessions the cited quotes were found in, newest first. */
22
+ sessions: string[];
23
+ /** YYYY-MM-DD of the newest of them. */
24
+ last: string;
25
+ quotes: string[];
26
+ }
27
+ export interface FindResult {
28
+ /** Past sessions with at least one message of the person's. */
29
+ sessions: number;
30
+ /** How many of them, newest first, Claude read. */
31
+ read: number;
32
+ findings: Finding[];
33
+ model: string;
34
+ durationMs: number;
35
+ costUsd?: number;
36
+ /** Why nothing came back, when nothing did. */
37
+ reason?: "no_sessions" | "no_claude" | "failed" | "none_found";
38
+ }
39
+ /** Sonnet: on assign's history it merged related corrections into fewer, stronger findings than Haiku. */
40
+ export declare const COLD_START_MODEL = "claude-sonnet-5-5";
41
+ /**
42
+ * The checkout `repo` belongs to and every worktree of it git still lists:
43
+ * sessions run in any of them, or in a folder under one, are this repo's.
44
+ * Worktrees git has forgotten were usually under the main checkout
45
+ * (`.claude/worktrees/…`), so their sessions are still found under it.
46
+ */
47
+ export declare function repoRoots(repo: string): string[];
48
+ /**
49
+ * Transcript files for sessions run inside `roots`. Claude Code names a
50
+ * project's folder after its path with every other character as `-`, so a
51
+ * folder under a root starts with the root's name; but so does a sibling like
52
+ * `assign-old`, so each file's own `cwd` decides.
53
+ */
54
+ export declare function sessionFiles(roots: string[], home?: string): string[];
55
+ /** The person's message with what isn't theirs taken out, or null when nothing of theirs is left. */
56
+ export declare function ownWords(raw: string): string | null;
57
+ /**
58
+ * One transcript's messages from the person, oldest first. Headless runs
59
+ * (`claude -p`, scripts) are skipped whole: their prompts were written once
60
+ * and replayed, so a repeat there isn't the person repeating themselves.
61
+ */
62
+ export declare function readSession(path: string): PastSession | null;
63
+ /** Every past session of the repo with something the person wrote, newest first. */
64
+ export declare function pastSessions(repo: string, home?: string): PastSession[];
65
+ /**
66
+ * The sessions as one text for Claude, newest first, cut at `maxChars`. Each
67
+ * session is headed by a short id that the findings cite back.
68
+ */
69
+ export declare function digest(sessions: PastSession[], maxChars?: number): {
70
+ text: string;
71
+ ids: Map<string, string>;
72
+ };
73
+ interface RawFinding {
74
+ title?: string;
75
+ for?: string;
76
+ body?: string;
77
+ evidence?: {
78
+ session?: string;
79
+ quote?: string;
80
+ }[];
81
+ }
82
+ /** Whether `claude` (Claude Code) is on PATH. */
83
+ export declare function hasClaude(): boolean;
84
+ /**
85
+ * The findings whose quotes are really in the person's messages, in two or
86
+ * more sessions, best first. A quote filed under the wrong session still
87
+ * counts for the session it's in.
88
+ */
89
+ export declare function verify(raw: RawFinding[], sessions: PastSession[], ids: Map<string, string>): Finding[];
90
+ /** Anything that looks like a credential, a key or an email address, replaced. Learnings get committed. */
91
+ export declare function scrub(text: string): string;
92
+ /**
93
+ * What the person kept telling Claude in this repo, checked against their
94
+ * messages. Never throws: no sessions, no Claude Code, or a failed call come
95
+ * back as an empty list with the reason.
96
+ */
97
+ export declare function findLearnings(repo: string, opts?: {
98
+ model?: string;
99
+ timeoutMs?: number;
100
+ home?: string;
101
+ limit?: number;
102
+ sessions?: PastSession[];
103
+ }): Promise<FindResult>;
104
+ export interface PastRead {
105
+ sessions: number;
106
+ started: number;
107
+ result: Promise<FindResult>;
108
+ done: boolean;
109
+ }
110
+ /**
111
+ * Start reading the repo's past Claude sessions, once per repo per machine,
112
+ * for `trail init` to collect at its end; null when there's nothing to read,
113
+ * it was read before, or TRAIL_NO_FETCH is set.
114
+ */
115
+ export declare function beginPastRead(repo: string, env?: NodeJS.ProcessEnv): PastRead | null;
116
+ /**
117
+ * Each finding as a standing learning: the team's in `.trail/learnings/`,
118
+ * the person's own in ~/.trail. The body says where it came from.
119
+ */
120
+ export declare function saveFindings(repo: string, findings: Finding[], author?: string, date?: string): Note[];
121
+ /** Wait for the read, save what it found, and remember the repo was read. */
122
+ export declare function finishPastRead(repo: string, read: PastRead): Promise<{
123
+ result: FindResult;
124
+ saved: Note[];
125
+ }>;
126
+ export {};
127
+ //# sourceMappingURL=cold-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cold-start.d.ts","sourceRoot":"","sources":["../../src/notes/cold-start.ts"],"names":[],"mappings":"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"}