cognitive-core 0.2.0 → 0.2.2

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 (397) hide show
  1. package/.claude/settings.json +111 -2
  2. package/.sessionlog/settings.json +4 -0
  3. package/dist/atlas.d.ts +10 -0
  4. package/dist/atlas.d.ts.map +1 -1
  5. package/dist/atlas.js +65 -0
  6. package/dist/atlas.js.map +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +5 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/learning/index.d.ts +1 -1
  12. package/dist/learning/index.d.ts.map +1 -1
  13. package/dist/learning/index.js.map +1 -1
  14. package/dist/learning/pipeline.d.ts +4 -31
  15. package/dist/learning/pipeline.d.ts.map +1 -1
  16. package/dist/learning/pipeline.js +12 -64
  17. package/dist/learning/pipeline.js.map +1 -1
  18. package/dist/learning/unified-pipeline.d.ts +30 -0
  19. package/dist/learning/unified-pipeline.d.ts.map +1 -1
  20. package/dist/learning/unified-pipeline.js +207 -0
  21. package/dist/learning/unified-pipeline.js.map +1 -1
  22. package/dist/memory/candidate-retrieval.d.ts.map +1 -1
  23. package/dist/memory/candidate-retrieval.js +3 -1
  24. package/dist/memory/candidate-retrieval.js.map +1 -1
  25. package/dist/memory/curated-loader.d.ts +21 -4
  26. package/dist/memory/curated-loader.d.ts.map +1 -1
  27. package/dist/memory/curated-loader.js +53 -16
  28. package/dist/memory/curated-loader.js.map +1 -1
  29. package/dist/memory/index.d.ts +2 -1
  30. package/dist/memory/index.d.ts.map +1 -1
  31. package/dist/memory/index.js +3 -1
  32. package/dist/memory/index.js.map +1 -1
  33. package/dist/memory/playbook.d.ts +6 -0
  34. package/dist/memory/playbook.d.ts.map +1 -1
  35. package/dist/memory/playbook.js +15 -0
  36. package/dist/memory/playbook.js.map +1 -1
  37. package/dist/memory/source-resolver.d.ts +120 -0
  38. package/dist/memory/source-resolver.d.ts.map +1 -0
  39. package/dist/memory/source-resolver.js +300 -0
  40. package/dist/memory/source-resolver.js.map +1 -0
  41. package/dist/types/config.d.ts +141 -0
  42. package/dist/types/config.d.ts.map +1 -1
  43. package/dist/types/config.js +40 -0
  44. package/dist/types/config.js.map +1 -1
  45. package/dist/types/index.d.ts +1 -1
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js +1 -1
  48. package/dist/types/index.js.map +1 -1
  49. package/dist/utils/error-classifier.js +8 -8
  50. package/dist/utils/error-classifier.js.map +1 -1
  51. package/dist/workspace/efficacy-toolkit.d.ts +164 -0
  52. package/dist/workspace/efficacy-toolkit.d.ts.map +1 -0
  53. package/dist/workspace/efficacy-toolkit.js +281 -0
  54. package/dist/workspace/efficacy-toolkit.js.map +1 -0
  55. package/dist/workspace/index.d.ts +2 -1
  56. package/dist/workspace/index.d.ts.map +1 -1
  57. package/dist/workspace/index.js +3 -1
  58. package/dist/workspace/index.js.map +1 -1
  59. package/dist/workspace/templates/index.d.ts +3 -0
  60. package/dist/workspace/templates/index.d.ts.map +1 -1
  61. package/dist/workspace/templates/index.js +6 -0
  62. package/dist/workspace/templates/index.js.map +1 -1
  63. package/dist/workspace/templates/playbook-decay-detection.d.ts +46 -0
  64. package/dist/workspace/templates/playbook-decay-detection.d.ts.map +1 -0
  65. package/dist/workspace/templates/playbook-decay-detection.js +197 -0
  66. package/dist/workspace/templates/playbook-decay-detection.js.map +1 -0
  67. package/dist/workspace/templates/playbook-efficacy-audit.d.ts +46 -0
  68. package/dist/workspace/templates/playbook-efficacy-audit.d.ts.map +1 -0
  69. package/dist/workspace/templates/playbook-efficacy-audit.js +160 -0
  70. package/dist/workspace/templates/playbook-efficacy-audit.js.map +1 -0
  71. package/dist/workspace/templates/playbook-lifecycle-review.d.ts +51 -0
  72. package/dist/workspace/templates/playbook-lifecycle-review.d.ts.map +1 -0
  73. package/dist/workspace/templates/playbook-lifecycle-review.js +187 -0
  74. package/dist/workspace/templates/playbook-lifecycle-review.js.map +1 -0
  75. package/dist/workspace/types.d.ts +12 -54
  76. package/dist/workspace/types.d.ts.map +1 -1
  77. package/dist/workspace/types.js.map +1 -1
  78. package/package.json +8 -2
  79. package/playbooks/compound-engineering/adversarial-review.json +51 -0
  80. package/playbooks/compound-engineering/agent-native-architecture.json +59 -0
  81. package/playbooks/compound-engineering/agent-native-review.json +54 -0
  82. package/playbooks/compound-engineering/api-contract-review.json +52 -0
  83. package/playbooks/compound-engineering/brainstorm-requirements.json +55 -0
  84. package/playbooks/compound-engineering/bug-reproduction.json +62 -0
  85. package/playbooks/compound-engineering/confidence-calibration.json +49 -0
  86. package/playbooks/compound-engineering/correctness-review.json +49 -0
  87. package/playbooks/compound-engineering/data-migration-safety.json +59 -0
  88. package/playbooks/compound-engineering/deployment-verification.json +63 -0
  89. package/playbooks/compound-engineering/error-recovery-patterns.json +53 -0
  90. package/playbooks/compound-engineering/implementation-planning.json +64 -0
  91. package/playbooks/compound-engineering/issue-pattern-analysis.json +53 -0
  92. package/playbooks/compound-engineering/knowledge-compounding.json +63 -0
  93. package/playbooks/compound-engineering/learnings-research.json +54 -0
  94. package/playbooks/compound-engineering/maintainability-review.json +49 -0
  95. package/playbooks/compound-engineering/performance-review.json +54 -0
  96. package/playbooks/compound-engineering/plan-adversarial-review.json +56 -0
  97. package/playbooks/compound-engineering/plan-feasibility-review.json +56 -0
  98. package/playbooks/compound-engineering/project-standards-review.json +52 -0
  99. package/playbooks/compound-engineering/reliability-review.json +53 -0
  100. package/playbooks/compound-engineering/review-orchestration.json +64 -0
  101. package/playbooks/compound-engineering/security-review.json +54 -0
  102. package/playbooks/compound-engineering/systematic-execution.json +64 -0
  103. package/playbooks/compound-engineering/testing-review.json +50 -0
  104. package/src/atlas.ts +96 -0
  105. package/src/index.ts +27 -0
  106. package/src/learning/index.ts +1 -0
  107. package/src/learning/unified-pipeline.ts +271 -1
  108. package/src/memory/candidate-retrieval.ts +2 -1
  109. package/src/memory/curated-loader.ts +69 -16
  110. package/src/memory/index.ts +16 -0
  111. package/src/memory/playbook.ts +19 -0
  112. package/src/memory/source-resolver.ts +422 -0
  113. package/src/types/config.ts +46 -0
  114. package/src/types/index.ts +4 -0
  115. package/src/utils/error-classifier.ts +8 -8
  116. package/src/workspace/efficacy-toolkit.ts +496 -0
  117. package/src/workspace/index.ts +29 -0
  118. package/src/workspace/templates/index.ts +24 -0
  119. package/src/workspace/templates/playbook-decay-detection.ts +272 -0
  120. package/src/workspace/templates/playbook-efficacy-audit.ts +246 -0
  121. package/src/workspace/templates/playbook-lifecycle-review.ts +274 -0
  122. package/src/workspace/types.ts +22 -78
  123. package/tests/fixtures/behavioral-trajectories.ts +210 -0
  124. package/tests/integration/curated-sources-e2e.test.ts +502 -0
  125. package/tests/integration/pipeline-data-correctness.test.ts +794 -0
  126. package/tests/learning/meta-learner.test.ts +418 -0
  127. package/tests/learning/pipeline-memory-updates.test.ts +721 -0
  128. package/tests/learning/unified-pipeline-efficacy.test.ts +232 -0
  129. package/tests/memory/candidate-retrieval.test.ts +167 -0
  130. package/tests/memory/compound-engineering-seed.test.ts +338 -0
  131. package/tests/memory/curated-loader-extended.test.ts +225 -0
  132. package/tests/memory/meta.test.ts +399 -0
  133. package/tests/memory/playbook-quality-validation.test.ts +430 -0
  134. package/tests/memory/source-resolver.test.ts +700 -0
  135. package/tests/search/evaluator.test.ts +257 -0
  136. package/tests/search/verification-runner.test.ts +357 -0
  137. package/tests/utils/error-classifier.test.ts +149 -0
  138. package/tests/utils/trajectory-helpers.test.ts +163 -0
  139. package/tests/workspace/efficacy-toolkit.test.ts +404 -0
  140. package/tests/workspace/templates/playbook-efficacy.test.ts +377 -0
  141. package/.claude/settings.local.json +0 -11
  142. package/dist/learning/llm-extractor.d.ts +0 -88
  143. package/dist/learning/llm-extractor.d.ts.map +0 -1
  144. package/dist/learning/llm-extractor.js +0 -372
  145. package/dist/learning/llm-extractor.js.map +0 -1
  146. package/dist/learning/loop-coordinator.d.ts +0 -61
  147. package/dist/learning/loop-coordinator.d.ts.map +0 -1
  148. package/dist/learning/loop-coordinator.js +0 -96
  149. package/dist/learning/loop-coordinator.js.map +0 -1
  150. package/references/agent-workspace/CLAUDE.md +0 -74
  151. package/references/agent-workspace/README.md +0 -587
  152. package/references/agent-workspace/media/banner.png +0 -0
  153. package/references/agent-workspace/package-lock.json +0 -2061
  154. package/references/agent-workspace/package.json +0 -54
  155. package/references/agent-workspace/src/handle.ts +0 -122
  156. package/references/agent-workspace/src/index.ts +0 -32
  157. package/references/agent-workspace/src/manager.ts +0 -102
  158. package/references/agent-workspace/src/readers/json.ts +0 -71
  159. package/references/agent-workspace/src/readers/markdown.ts +0 -37
  160. package/references/agent-workspace/src/readers/raw.ts +0 -27
  161. package/references/agent-workspace/src/types.ts +0 -68
  162. package/references/agent-workspace/src/validation.ts +0 -93
  163. package/references/agent-workspace/src/writers/json.ts +0 -17
  164. package/references/agent-workspace/src/writers/markdown.ts +0 -27
  165. package/references/agent-workspace/src/writers/raw.ts +0 -22
  166. package/references/agent-workspace/tests/errors.test.ts +0 -652
  167. package/references/agent-workspace/tests/handle.test.ts +0 -144
  168. package/references/agent-workspace/tests/manager.test.ts +0 -124
  169. package/references/agent-workspace/tests/readers.test.ts +0 -205
  170. package/references/agent-workspace/tests/validation.test.ts +0 -196
  171. package/references/agent-workspace/tests/writers.test.ts +0 -108
  172. package/references/agent-workspace/tsconfig.json +0 -20
  173. package/references/agent-workspace/tsup.config.ts +0 -9
  174. package/references/minimem/.claude/settings.json +0 -7
  175. package/references/minimem/.sudocode/issues.jsonl +0 -18
  176. package/references/minimem/.sudocode/specs.jsonl +0 -1
  177. package/references/minimem/CLAUDE.md +0 -310
  178. package/references/minimem/README.md +0 -556
  179. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +0 -10
  180. package/references/minimem/claude-plugin/.mcp.json +0 -7
  181. package/references/minimem/claude-plugin/README.md +0 -158
  182. package/references/minimem/claude-plugin/commands/recall.md +0 -47
  183. package/references/minimem/claude-plugin/commands/remember.md +0 -41
  184. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +0 -272
  185. package/references/minimem/claude-plugin/hooks/hooks.json +0 -27
  186. package/references/minimem/claude-plugin/hooks/session-end.sh +0 -86
  187. package/references/minimem/claude-plugin/hooks/session-start.sh +0 -85
  188. package/references/minimem/claude-plugin/skills/memory/SKILL.md +0 -108
  189. package/references/minimem/package-lock.json +0 -5373
  190. package/references/minimem/package.json +0 -60
  191. package/references/minimem/scripts/postbuild.js +0 -35
  192. package/references/minimem/src/__tests__/edge-cases.test.ts +0 -371
  193. package/references/minimem/src/__tests__/errors.test.ts +0 -265
  194. package/references/minimem/src/__tests__/helpers.ts +0 -199
  195. package/references/minimem/src/__tests__/internal.test.ts +0 -407
  196. package/references/minimem/src/__tests__/knowledge.test.ts +0 -287
  197. package/references/minimem/src/__tests__/minimem.integration.test.ts +0 -1127
  198. package/references/minimem/src/__tests__/session.test.ts +0 -190
  199. package/references/minimem/src/cli/__tests__/commands.test.ts +0 -759
  200. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +0 -141
  201. package/references/minimem/src/cli/commands/append.ts +0 -76
  202. package/references/minimem/src/cli/commands/config.ts +0 -262
  203. package/references/minimem/src/cli/commands/conflicts.ts +0 -413
  204. package/references/minimem/src/cli/commands/daemon.ts +0 -169
  205. package/references/minimem/src/cli/commands/index.ts +0 -12
  206. package/references/minimem/src/cli/commands/init.ts +0 -88
  207. package/references/minimem/src/cli/commands/mcp.ts +0 -177
  208. package/references/minimem/src/cli/commands/push-pull.ts +0 -213
  209. package/references/minimem/src/cli/commands/search.ts +0 -158
  210. package/references/minimem/src/cli/commands/status.ts +0 -84
  211. package/references/minimem/src/cli/commands/sync-init.ts +0 -290
  212. package/references/minimem/src/cli/commands/sync.ts +0 -70
  213. package/references/minimem/src/cli/commands/upsert.ts +0 -197
  214. package/references/minimem/src/cli/config.ts +0 -584
  215. package/references/minimem/src/cli/index.ts +0 -264
  216. package/references/minimem/src/cli/shared.ts +0 -161
  217. package/references/minimem/src/cli/sync/__tests__/central.test.ts +0 -152
  218. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +0 -209
  219. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +0 -118
  220. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +0 -207
  221. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +0 -476
  222. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +0 -363
  223. package/references/minimem/src/cli/sync/__tests__/state.test.ts +0 -255
  224. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +0 -193
  225. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +0 -178
  226. package/references/minimem/src/cli/sync/central.ts +0 -292
  227. package/references/minimem/src/cli/sync/conflicts.ts +0 -204
  228. package/references/minimem/src/cli/sync/daemon.ts +0 -407
  229. package/references/minimem/src/cli/sync/detection.ts +0 -138
  230. package/references/minimem/src/cli/sync/index.ts +0 -107
  231. package/references/minimem/src/cli/sync/operations.ts +0 -373
  232. package/references/minimem/src/cli/sync/registry.ts +0 -279
  233. package/references/minimem/src/cli/sync/state.ts +0 -355
  234. package/references/minimem/src/cli/sync/validation.ts +0 -206
  235. package/references/minimem/src/cli/sync/watcher.ts +0 -234
  236. package/references/minimem/src/cli/version.ts +0 -34
  237. package/references/minimem/src/core/index.ts +0 -9
  238. package/references/minimem/src/core/indexer.ts +0 -628
  239. package/references/minimem/src/core/searcher.ts +0 -221
  240. package/references/minimem/src/db/schema.ts +0 -183
  241. package/references/minimem/src/db/sqlite-vec.ts +0 -24
  242. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +0 -431
  243. package/references/minimem/src/embeddings/batch-gemini.ts +0 -392
  244. package/references/minimem/src/embeddings/batch-openai.ts +0 -409
  245. package/references/minimem/src/embeddings/embeddings.ts +0 -434
  246. package/references/minimem/src/index.ts +0 -109
  247. package/references/minimem/src/internal.ts +0 -299
  248. package/references/minimem/src/minimem.ts +0 -1276
  249. package/references/minimem/src/search/__tests__/hybrid.test.ts +0 -247
  250. package/references/minimem/src/search/graph.ts +0 -234
  251. package/references/minimem/src/search/hybrid.ts +0 -151
  252. package/references/minimem/src/search/search.ts +0 -256
  253. package/references/minimem/src/server/__tests__/mcp.test.ts +0 -341
  254. package/references/minimem/src/server/__tests__/tools.test.ts +0 -364
  255. package/references/minimem/src/server/mcp.ts +0 -326
  256. package/references/minimem/src/server/tools.ts +0 -720
  257. package/references/minimem/src/session.ts +0 -460
  258. package/references/minimem/tsconfig.json +0 -19
  259. package/references/minimem/tsup.config.ts +0 -26
  260. package/references/minimem/vitest.config.ts +0 -24
  261. package/references/sessionlog/.husky/pre-commit +0 -1
  262. package/references/sessionlog/.lintstagedrc.json +0 -4
  263. package/references/sessionlog/.prettierignore +0 -4
  264. package/references/sessionlog/.prettierrc.json +0 -11
  265. package/references/sessionlog/LICENSE +0 -21
  266. package/references/sessionlog/README.md +0 -453
  267. package/references/sessionlog/eslint.config.js +0 -58
  268. package/references/sessionlog/package-lock.json +0 -3672
  269. package/references/sessionlog/package.json +0 -65
  270. package/references/sessionlog/src/__tests__/agent-hooks.test.ts +0 -570
  271. package/references/sessionlog/src/__tests__/agent-registry.test.ts +0 -127
  272. package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +0 -225
  273. package/references/sessionlog/src/__tests__/claude-generator.test.ts +0 -46
  274. package/references/sessionlog/src/__tests__/commit-msg.test.ts +0 -86
  275. package/references/sessionlog/src/__tests__/cursor-agent.test.ts +0 -224
  276. package/references/sessionlog/src/__tests__/e2e-live.test.ts +0 -890
  277. package/references/sessionlog/src/__tests__/event-log.test.ts +0 -183
  278. package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +0 -105
  279. package/references/sessionlog/src/__tests__/gemini-agent.test.ts +0 -375
  280. package/references/sessionlog/src/__tests__/git-hooks.test.ts +0 -78
  281. package/references/sessionlog/src/__tests__/hook-managers.test.ts +0 -121
  282. package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +0 -759
  283. package/references/sessionlog/src/__tests__/opencode-agent.test.ts +0 -338
  284. package/references/sessionlog/src/__tests__/redaction.test.ts +0 -136
  285. package/references/sessionlog/src/__tests__/session-repo.test.ts +0 -353
  286. package/references/sessionlog/src/__tests__/session-store.test.ts +0 -166
  287. package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +0 -466
  288. package/references/sessionlog/src/__tests__/skill-live.test.ts +0 -461
  289. package/references/sessionlog/src/__tests__/summarize.test.ts +0 -348
  290. package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +0 -610
  291. package/references/sessionlog/src/__tests__/task-plan-live.test.ts +0 -632
  292. package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +0 -121
  293. package/references/sessionlog/src/__tests__/types.test.ts +0 -166
  294. package/references/sessionlog/src/__tests__/utils.test.ts +0 -333
  295. package/references/sessionlog/src/__tests__/validation.test.ts +0 -103
  296. package/references/sessionlog/src/__tests__/worktree.test.ts +0 -57
  297. package/references/sessionlog/src/agent/agents/claude-code.ts +0 -1089
  298. package/references/sessionlog/src/agent/agents/cursor.ts +0 -361
  299. package/references/sessionlog/src/agent/agents/gemini-cli.ts +0 -632
  300. package/references/sessionlog/src/agent/agents/opencode.ts +0 -540
  301. package/references/sessionlog/src/agent/registry.ts +0 -143
  302. package/references/sessionlog/src/agent/session-types.ts +0 -113
  303. package/references/sessionlog/src/agent/types.ts +0 -220
  304. package/references/sessionlog/src/cli.ts +0 -597
  305. package/references/sessionlog/src/commands/clean.ts +0 -133
  306. package/references/sessionlog/src/commands/disable.ts +0 -84
  307. package/references/sessionlog/src/commands/doctor.ts +0 -145
  308. package/references/sessionlog/src/commands/enable.ts +0 -202
  309. package/references/sessionlog/src/commands/explain.ts +0 -261
  310. package/references/sessionlog/src/commands/reset.ts +0 -105
  311. package/references/sessionlog/src/commands/resume.ts +0 -180
  312. package/references/sessionlog/src/commands/rewind.ts +0 -195
  313. package/references/sessionlog/src/commands/setup-ccweb.ts +0 -275
  314. package/references/sessionlog/src/commands/status.ts +0 -172
  315. package/references/sessionlog/src/config.ts +0 -165
  316. package/references/sessionlog/src/events/event-log.ts +0 -126
  317. package/references/sessionlog/src/git-operations.ts +0 -558
  318. package/references/sessionlog/src/hooks/git-hooks.ts +0 -165
  319. package/references/sessionlog/src/hooks/lifecycle.ts +0 -391
  320. package/references/sessionlog/src/index.ts +0 -650
  321. package/references/sessionlog/src/security/redaction.ts +0 -283
  322. package/references/sessionlog/src/session/state-machine.ts +0 -452
  323. package/references/sessionlog/src/store/checkpoint-store.ts +0 -509
  324. package/references/sessionlog/src/store/native-store.ts +0 -173
  325. package/references/sessionlog/src/store/provider-types.ts +0 -99
  326. package/references/sessionlog/src/store/session-store.ts +0 -266
  327. package/references/sessionlog/src/strategy/attribution.ts +0 -296
  328. package/references/sessionlog/src/strategy/common.ts +0 -207
  329. package/references/sessionlog/src/strategy/content-overlap.ts +0 -228
  330. package/references/sessionlog/src/strategy/manual-commit.ts +0 -988
  331. package/references/sessionlog/src/strategy/types.ts +0 -279
  332. package/references/sessionlog/src/summarize/claude-generator.ts +0 -115
  333. package/references/sessionlog/src/summarize/summarize.ts +0 -432
  334. package/references/sessionlog/src/types.ts +0 -508
  335. package/references/sessionlog/src/utils/chunk-files.ts +0 -49
  336. package/references/sessionlog/src/utils/commit-message.ts +0 -65
  337. package/references/sessionlog/src/utils/detect-agent.ts +0 -36
  338. package/references/sessionlog/src/utils/hook-managers.ts +0 -125
  339. package/references/sessionlog/src/utils/ide-tags.ts +0 -32
  340. package/references/sessionlog/src/utils/paths.ts +0 -79
  341. package/references/sessionlog/src/utils/preview-rewind.ts +0 -80
  342. package/references/sessionlog/src/utils/rewind-conflict.ts +0 -121
  343. package/references/sessionlog/src/utils/shadow-branch.ts +0 -109
  344. package/references/sessionlog/src/utils/string-utils.ts +0 -46
  345. package/references/sessionlog/src/utils/todo-extract.ts +0 -188
  346. package/references/sessionlog/src/utils/trailers.ts +0 -187
  347. package/references/sessionlog/src/utils/transcript-parse.ts +0 -177
  348. package/references/sessionlog/src/utils/transcript-timestamp.ts +0 -59
  349. package/references/sessionlog/src/utils/tree-ops.ts +0 -219
  350. package/references/sessionlog/src/utils/tty.ts +0 -72
  351. package/references/sessionlog/src/utils/validation.ts +0 -65
  352. package/references/sessionlog/src/utils/worktree.ts +0 -58
  353. package/references/sessionlog/src/wire-types.ts +0 -59
  354. package/references/sessionlog/templates/setup-env.sh +0 -153
  355. package/references/sessionlog/tsconfig.json +0 -18
  356. package/references/sessionlog/vitest.config.ts +0 -12
  357. package/references/skill-tree/.claude/settings.json +0 -6
  358. package/references/skill-tree/.sudocode/issues.jsonl +0 -19
  359. package/references/skill-tree/.sudocode/specs.jsonl +0 -3
  360. package/references/skill-tree/CLAUDE.md +0 -126
  361. package/references/skill-tree/README.md +0 -372
  362. package/references/skill-tree/docs/GAPS_v1.md +0 -221
  363. package/references/skill-tree/docs/INTEGRATION_PLAN.md +0 -467
  364. package/references/skill-tree/docs/TODOS.md +0 -91
  365. package/references/skill-tree/docs/anthropic_skill_guide.md +0 -1364
  366. package/references/skill-tree/docs/design/federated-skill-trees.md +0 -524
  367. package/references/skill-tree/docs/design/multi-agent-sync.md +0 -759
  368. package/references/skill-tree/docs/scraper/BRAINSTORM.md +0 -583
  369. package/references/skill-tree/docs/scraper/POC_PLAN.md +0 -420
  370. package/references/skill-tree/docs/scraper/README.md +0 -170
  371. package/references/skill-tree/examples/basic-usage.ts +0 -164
  372. package/references/skill-tree/package-lock.json +0 -1852
  373. package/references/skill-tree/package.json +0 -66
  374. package/references/skill-tree/scraper/README.md +0 -123
  375. package/references/skill-tree/scraper/docs/DESIGN.md +0 -683
  376. package/references/skill-tree/scraper/docs/PLAN.md +0 -336
  377. package/references/skill-tree/scraper/drizzle.config.ts +0 -10
  378. package/references/skill-tree/scraper/package-lock.json +0 -6329
  379. package/references/skill-tree/scraper/package.json +0 -68
  380. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +0 -7
  381. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +0 -7
  382. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +0 -27
  383. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +0 -21
  384. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +0 -54
  385. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +0 -24
  386. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +0 -93
  387. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +0 -22
  388. package/references/skill-tree/scraper/tsup.config.ts +0 -14
  389. package/references/skill-tree/scraper/vitest.config.ts +0 -17
  390. package/references/skill-tree/scripts/convert-to-vitest.ts +0 -166
  391. package/references/skill-tree/skills/skill-writer/SKILL.md +0 -339
  392. package/references/skill-tree/skills/skill-writer/references/examples.md +0 -326
  393. package/references/skill-tree/skills/skill-writer/references/patterns.md +0 -210
  394. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +0 -123
  395. package/references/skill-tree/test/run-all.ts +0 -106
  396. package/references/skill-tree/test/utils.ts +0 -128
  397. package/references/skill-tree/vitest.config.ts +0 -16
@@ -1,890 +0,0 @@
1
- /**
2
- * Comprehensive E2E Live Tests for Sessionlog
3
- *
4
- * Tests the full sessionlog lifecycle with real Claude Code sessions:
5
- * session creation, file tracking, commit handling, status reporting,
6
- * doctor/clean, token usage, and checkpoint verification via CLI binary.
7
- *
8
- * Note on checkpoints: In single-turn `-p` mode, Claude creates files and
9
- * commits within one turn. The checkpoint trailer requires a shadow branch
10
- * (created during saveStep/TurnEnd), which doesn't exist yet when
11
- * prepare-commit-msg fires within the same turn. Checkpoint verification
12
- * is therefore tested deterministically via CLI binary piping (Suite 7).
13
- *
14
- * Gated behind LIVE_AGENT=1 environment variable:
15
- * LIVE_AGENT=1 npx vitest run src/__tests__/e2e-live.test.ts
16
- *
17
- * Prerequisites:
18
- * - `claude` CLI installed and authenticated (Claude Max or API key)
19
- * - `npm run build` has been run (dist/ exists)
20
- * - `npm link` has been run (sessionlog available in PATH)
21
- */
22
-
23
- import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
24
- import * as fs from 'node:fs';
25
- import * as path from 'node:path';
26
- import * as os from 'node:os';
27
- import { execFileSync, execSync } from 'node:child_process';
28
-
29
- const LIVE = process.env.LIVE_AGENT === '1';
30
- const HOOK_WAIT_MS = 2000;
31
-
32
- // ============================================================================
33
- // Helpers
34
- // ============================================================================
35
-
36
- function initRepo(dir: string): void {
37
- execFileSync('git', ['init'], { cwd: dir, stdio: 'pipe' });
38
- execFileSync('git', ['config', 'user.email', 'test@test.com'], { cwd: dir, stdio: 'pipe' });
39
- execFileSync('git', ['config', 'user.name', 'Test'], { cwd: dir, stdio: 'pipe' });
40
- fs.writeFileSync(path.join(dir, 'README.md'), '# Test Project\n\nA simple test project.');
41
- execFileSync('git', ['add', '.'], { cwd: dir, stdio: 'pipe' });
42
- execFileSync('git', ['commit', '-m', 'initial commit'], { cwd: dir, stdio: 'pipe' });
43
- }
44
-
45
- function enableSessionlog(dir: string): void {
46
- execFileSync('sessionlog', ['enable', '--force', '--agent', 'claude-code'], {
47
- cwd: dir,
48
- stdio: 'pipe',
49
- });
50
- }
51
-
52
- /**
53
- * Read all session state files from .git/sessionlog-sessions/.
54
- */
55
- function readSessionStates(dir: string): Record<string, unknown>[] {
56
- const sessionsDir = path.join(dir, '.git', 'sessionlog-sessions');
57
- if (!fs.existsSync(sessionsDir)) return [];
58
-
59
- return fs
60
- .readdirSync(sessionsDir)
61
- .filter((f) => f.endsWith('.json'))
62
- .map((f) => {
63
- try {
64
- return JSON.parse(fs.readFileSync(path.join(sessionsDir, f), 'utf-8'));
65
- } catch {
66
- return null;
67
- }
68
- })
69
- .filter(Boolean) as Record<string, unknown>[];
70
- }
71
-
72
- /**
73
- * Run claude in print mode with the given prompt.
74
- */
75
- function runClaude(
76
- dir: string,
77
- prompt: string,
78
- opts?: {
79
- allowedTools?: string[];
80
- systemPrompt?: string;
81
- timeoutMs?: number;
82
- model?: string;
83
- },
84
- ): string {
85
- const args = ['-p', '--dangerously-skip-permissions'];
86
-
87
- if (opts?.model) {
88
- args.push('--model', opts.model);
89
- } else {
90
- args.push('--model', 'sonnet');
91
- }
92
-
93
- if (opts?.allowedTools?.length) {
94
- args.push('--allowedTools', opts.allowedTools.join(','));
95
- }
96
-
97
- if (opts?.systemPrompt) {
98
- args.push('--system-prompt', opts.systemPrompt);
99
- }
100
-
101
- args.push('--', prompt);
102
-
103
- const cmd = ['claude', ...args].map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
104
-
105
- const result = execSync(cmd, {
106
- cwd: dir,
107
- timeout: opts?.timeoutMs ?? 120_000,
108
- encoding: 'utf-8',
109
- env: {
110
- ...process.env,
111
- CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
112
- },
113
- });
114
-
115
- return result;
116
- }
117
-
118
- /**
119
- * Run a sessionlog CLI command and return stdout.
120
- */
121
- function runSessionlog(dir: string, args: string[], timeoutMs = 30_000): string {
122
- return execSync(`sessionlog ${args.join(' ')}`, {
123
- cwd: dir,
124
- timeout: timeoutMs,
125
- encoding: 'utf-8',
126
- env: { ...process.env },
127
- });
128
- }
129
-
130
- /**
131
- * Parse sessionlog status --json output.
132
- */
133
- function getStatus(dir: string): Record<string, unknown> {
134
- const output = runSessionlog(dir, ['status', '--json']);
135
- return JSON.parse(output);
136
- }
137
-
138
- /**
139
- * Get the last commit message (full body with trailers).
140
- */
141
- function getLastCommitMessage(dir: string): string {
142
- return execFileSync('git', ['log', '-1', '--format=%B'], {
143
- cwd: dir,
144
- encoding: 'utf-8',
145
- });
146
- }
147
-
148
- /**
149
- * Count commits on current branch.
150
- */
151
- function getCommitCount(dir: string): number {
152
- const output = execFileSync('git', ['rev-list', '--count', 'HEAD'], {
153
- cwd: dir,
154
- encoding: 'utf-8',
155
- });
156
- return parseInt(output.trim(), 10);
157
- }
158
-
159
- /**
160
- * List git branches matching a pattern.
161
- */
162
- function listGitBranches(dir: string, pattern?: string): string[] {
163
- const args = ['branch', '--list'];
164
- if (pattern) args.push(pattern);
165
- const output = execFileSync('git', args, { cwd: dir, encoding: 'utf-8' });
166
- return output
167
- .trim()
168
- .split('\n')
169
- .map((b) => b.replace('* ', '').trim())
170
- .filter(Boolean);
171
- }
172
-
173
- /**
174
- * Get HEAD commit SHA.
175
- */
176
- function getHead(dir: string): string {
177
- return execFileSync('git', ['rev-parse', 'HEAD'], {
178
- cwd: dir,
179
- encoding: 'utf-8',
180
- }).trim();
181
- }
182
-
183
- // ============================================================================
184
- // Tests
185
- // ============================================================================
186
-
187
- describe.skipIf(!LIVE)('Live E2E — Core Sessionlog', () => {
188
- let tmpDir: string;
189
-
190
- beforeAll(() => {
191
- // Verify prerequisites
192
- try {
193
- execFileSync('which', ['sessionlog'], { stdio: 'pipe' });
194
- } catch {
195
- throw new Error('sessionlog not found in PATH. Run: npm run build && npm link');
196
- }
197
- try {
198
- execFileSync('which', ['claude'], { stdio: 'pipe' });
199
- } catch {
200
- throw new Error('claude CLI not found in PATH');
201
- }
202
- });
203
-
204
- beforeEach(() => {
205
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sessionlog-live-e2e-'));
206
- initRepo(tmpDir);
207
- enableSessionlog(tmpDir);
208
- });
209
-
210
- afterEach(() => {
211
- fs.rmSync(tmpDir, { recursive: true, force: true });
212
- });
213
-
214
- // ==========================================================================
215
- // Suite 1: Session Lifecycle
216
- // ==========================================================================
217
-
218
- describe('Session Lifecycle', () => {
219
- it('should create session state when Claude edits a file', async () => {
220
- const output = runClaude(
221
- tmpDir,
222
- 'Create a file called src/hello.ts with this exact content: export function hello() { return "Hello"; }',
223
- {
224
- allowedTools: ['Write'],
225
- systemPrompt: 'Create only the requested file. Do not run any other commands.',
226
- timeoutMs: 120_000,
227
- },
228
- );
229
-
230
- console.log('Claude output:', output.slice(0, 500));
231
-
232
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
233
-
234
- // Verify file was created
235
- const srcDir = path.join(tmpDir, 'src');
236
- const fileCreated =
237
- fs.existsSync(path.join(srcDir, 'hello.ts')) ||
238
- fs.existsSync(path.join(tmpDir, 'hello.ts'));
239
- console.log('File created:', fileCreated);
240
-
241
- // Verify session state
242
- const sessions = readSessionStates(tmpDir);
243
- console.log('Sessions found:', sessions.length);
244
-
245
- expect(sessions.length).toBeGreaterThan(0);
246
-
247
- const session = sessions[0];
248
- expect(session.agentType).toBe('Claude Code');
249
- expect(session.startedAt).toBeDefined();
250
- expect(typeof session.startedAt).toBe('string');
251
- expect(session.baseCommit).toBeDefined();
252
- expect(typeof session.baseCommit).toBe('string');
253
- expect((session.baseCommit as string).length).toBe(40);
254
- }, 180_000);
255
-
256
- it('should track files and commit when Claude creates and commits', async () => {
257
- const initialHead = getHead(tmpDir);
258
-
259
- const output = runClaude(
260
- tmpDir,
261
- [
262
- 'Do these two steps exactly:',
263
- '1. Create a file at src/greet.ts with content: export const greet = (n: string) => "Hi " + n;',
264
- '2. Then run these exact shell commands: git add src/greet.ts && git commit -m "feat: add greet function"',
265
- ].join('\n'),
266
- {
267
- allowedTools: ['Write', 'Bash'],
268
- systemPrompt:
269
- 'Create the file and commit it using the exact commands specified. Do not do anything else.',
270
- timeoutMs: 120_000,
271
- },
272
- );
273
-
274
- console.log('Claude output:', output.slice(0, 500));
275
-
276
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
277
-
278
- // Verify file exists
279
- const fileExists = fs.existsSync(path.join(tmpDir, 'src', 'greet.ts'));
280
- console.log('File exists:', fileExists);
281
- expect(fileExists).toBe(true);
282
-
283
- // Verify a new commit was made
284
- const commitCount = getCommitCount(tmpDir);
285
- console.log('Commit count:', commitCount);
286
- expect(commitCount).toBeGreaterThan(1);
287
-
288
- // Verify HEAD changed
289
- const newHead = getHead(tmpDir);
290
- console.log('HEAD changed:', initialHead !== newHead);
291
- expect(newHead).not.toBe(initialHead);
292
-
293
- // Check commit message for checkpoint trailer (informational only).
294
- // In single-turn -p mode, the shadow branch doesn't exist yet when
295
- // prepare-commit-msg fires, so the trailer won't be injected.
296
- // Checkpoint creation is tested deterministically in Suite 7 via CLI piping.
297
- const commitMsg = getLastCommitMessage(tmpDir);
298
- console.log('Commit message:', commitMsg.trim());
299
- const hasCheckpointTrailer = /Sessionlog-Checkpoint:\s*[0-9a-f]{12}/.test(commitMsg);
300
- console.log('Has checkpoint trailer:', hasCheckpointTrailer);
301
-
302
- // Check for sessionlog branches (informational)
303
- const checkpointBranches = listGitBranches(tmpDir, 'sessionlog/*');
304
- console.log('Sessionlog branches:', checkpointBranches);
305
-
306
- // Session state should exist with tracked files
307
- const sessions = readSessionStates(tmpDir);
308
- expect(sessions.length).toBeGreaterThan(0);
309
-
310
- const session = sessions[0];
311
- console.log(
312
- 'Session state:',
313
- JSON.stringify(
314
- {
315
- phase: session.phase,
316
- baseCommit: (session.baseCommit as string)?.slice(0, 8),
317
- stepCount: session.stepCount,
318
- filesTouched: session.filesTouched,
319
- },
320
- null,
321
- 2,
322
- ),
323
- );
324
-
325
- // Session should track the file Claude touched
326
- const filesTouched = session.filesTouched as string[];
327
- expect(filesTouched.length).toBeGreaterThan(0);
328
- }, 180_000);
329
-
330
- it('should mark session as ended after -p mode completes', async () => {
331
- runClaude(tmpDir, 'Create a file called END_TEST.md with content: # End Test', {
332
- allowedTools: ['Write'],
333
- timeoutMs: 120_000,
334
- });
335
-
336
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
337
-
338
- const sessions = readSessionStates(tmpDir);
339
- expect(sessions.length).toBeGreaterThan(0);
340
-
341
- const session = sessions[0];
342
- console.log('Session phase:', session.phase, 'endedAt:', session.endedAt);
343
-
344
- // In -p mode, session_end hook fires, so phase should be 'ended'
345
- // or at minimum endedAt should be set
346
- const isEnded = session.phase === 'ended' || session.endedAt !== undefined;
347
- expect(isEnded).toBe(true);
348
- }, 180_000);
349
- });
350
-
351
- // ==========================================================================
352
- // Suite 2: Commit & Explain
353
- // ==========================================================================
354
-
355
- describe('Commit & Explain', () => {
356
- it('should show commit info via explain command after Claude commits', async () => {
357
- runClaude(
358
- tmpDir,
359
- [
360
- 'Do these two steps exactly:',
361
- '1. Create a file at lib/utils.ts with content: export const noop = () => {};',
362
- '2. Then run: git add lib/utils.ts && git commit -m "feat: add noop utility"',
363
- ].join('\n'),
364
- {
365
- allowedTools: ['Write', 'Bash'],
366
- systemPrompt: 'Create the file and commit it. Do exactly as instructed.',
367
- timeoutMs: 120_000,
368
- },
369
- );
370
-
371
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
372
-
373
- const commitCount = getCommitCount(tmpDir);
374
- console.log('Commit count:', commitCount);
375
-
376
- if (commitCount <= 1) {
377
- console.warn('Claude did not commit — skipping explain test');
378
- return;
379
- }
380
-
381
- // Run explain command — should always show commit info
382
- const output = runSessionlog(tmpDir, ['explain', 'HEAD']);
383
- console.log('Explain output:', output);
384
-
385
- expect(output).toContain('Commit:');
386
- expect(output).toContain('Message:');
387
-
388
- // Checkpoint details are only present if shadow branch existed during commit.
389
- // In single-turn -p mode this won't happen. Tested deterministically in Suite 7.
390
- const hasCheckpoint = output.includes('Checkpoint:');
391
- console.log('Has checkpoint in explain (expected false in single-turn):', hasCheckpoint);
392
- }, 180_000);
393
-
394
- it('should run rewind --list without errors after a session', async () => {
395
- runClaude(tmpDir, 'Create a file called REWIND_TEST.md with content: # Rewind Test', {
396
- allowedTools: ['Write'],
397
- timeoutMs: 120_000,
398
- });
399
-
400
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
401
-
402
- // rewind --list should return valid JSON even with no checkpoints
403
- const output = runSessionlog(tmpDir, ['rewind', '--list']);
404
- console.log('Rewind list output:', output.slice(0, 300));
405
-
406
- const points = JSON.parse(output);
407
- expect(Array.isArray(points)).toBe(true);
408
- console.log('Rewind points:', points.length);
409
- }, 180_000);
410
- });
411
-
412
- // ==========================================================================
413
- // Suite 3: Status Command
414
- // ==========================================================================
415
-
416
- describe('Status Command', () => {
417
- it('should report enabled state and sessions after Claude session', async () => {
418
- runClaude(tmpDir, 'Create a file called HELLO.md with content: # Hello', {
419
- allowedTools: ['Write'],
420
- systemPrompt: 'Only create the file.',
421
- timeoutMs: 120_000,
422
- });
423
-
424
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
425
-
426
- const status = getStatus(tmpDir);
427
- console.log('Status:', JSON.stringify(status, null, 2));
428
-
429
- expect(status.enabled).toBe(true);
430
- expect(status.strategy).toBe('manual-commit');
431
- expect(status.gitHooksInstalled).toBe(true);
432
- expect(status.agents).toBeDefined();
433
- expect(status.agents as string[]).toContain('claude-code');
434
-
435
- const sessions = status.sessions as Record<string, unknown>[];
436
- expect(sessions.length).toBeGreaterThan(0);
437
-
438
- const session = sessions[0];
439
- expect(session.agentType).toBe('Claude Code');
440
- expect(session.startedAt).toBeDefined();
441
- expect(['idle', 'active', 'ended']).toContain(session.phase);
442
- }, 180_000);
443
-
444
- it('should report zero sessions before any Claude invocation', () => {
445
- const status = getStatus(tmpDir);
446
- console.log('Status (no sessions):', JSON.stringify(status, null, 2));
447
-
448
- expect(status.enabled).toBe(true);
449
- expect(status.strategy).toBe('manual-commit');
450
- expect(status.gitHooksInstalled).toBe(true);
451
-
452
- const sessions = status.sessions as Record<string, unknown>[];
453
- expect(sessions).toHaveLength(0);
454
- });
455
- });
456
-
457
- // ==========================================================================
458
- // Suite 4: Doctor & Clean (no live Claude needed)
459
- // ==========================================================================
460
-
461
- describe('Doctor & Clean', () => {
462
- it('should diagnose stuck sessions', () => {
463
- // Create a synthetic stuck session
464
- const sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
465
- fs.mkdirSync(sessionsDir, { recursive: true });
466
-
467
- const head = getHead(tmpDir);
468
- const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
469
-
470
- const stuckState = {
471
- sessionID: 'stuck-session-001',
472
- baseCommit: head,
473
- startedAt: twoHoursAgo,
474
- lastInteractionTime: twoHoursAgo,
475
- phase: 'active',
476
- turnCheckpointIDs: [],
477
- stepCount: 0,
478
- checkpointTranscriptStart: 0,
479
- untrackedFilesAtStart: [],
480
- filesTouched: [],
481
- agentType: 'Claude Code',
482
- };
483
-
484
- fs.writeFileSync(
485
- path.join(sessionsDir, 'stuck-session-001.json'),
486
- JSON.stringify(stuckState, null, 2),
487
- );
488
-
489
- const output = runSessionlog(tmpDir, ['doctor']);
490
- console.log('Doctor output:', output);
491
-
492
- expect(output).toContain('stuck');
493
- });
494
-
495
- it('should fix stuck sessions with --force', () => {
496
- const sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
497
- fs.mkdirSync(sessionsDir, { recursive: true });
498
-
499
- const head = getHead(tmpDir);
500
- const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
501
-
502
- const stuckState = {
503
- sessionID: 'stuck-session-fix',
504
- baseCommit: head,
505
- startedAt: twoHoursAgo,
506
- lastInteractionTime: twoHoursAgo,
507
- phase: 'active',
508
- turnCheckpointIDs: [],
509
- stepCount: 0,
510
- checkpointTranscriptStart: 0,
511
- untrackedFilesAtStart: [],
512
- filesTouched: [],
513
- agentType: 'Claude Code',
514
- };
515
-
516
- fs.writeFileSync(
517
- path.join(sessionsDir, 'stuck-session-fix.json'),
518
- JSON.stringify(stuckState, null, 2),
519
- );
520
-
521
- const output = runSessionlog(tmpDir, ['doctor', '--force']);
522
- console.log('Doctor --force output:', output);
523
-
524
- expect(output).toContain('Discarded:');
525
-
526
- // Session file should be deleted
527
- const sessionFile = path.join(sessionsDir, 'stuck-session-fix.json');
528
- expect(fs.existsSync(sessionFile)).toBe(false);
529
- });
530
-
531
- it('should report nothing to clean in a healthy repo', () => {
532
- const output = runSessionlog(tmpDir, ['clean']);
533
- console.log('Clean output:', output);
534
-
535
- expect(output).toContain('Nothing to clean');
536
- });
537
-
538
- it('should detect orphaned shadow branches', () => {
539
- // Create an orphaned shadow branch
540
- execFileSync('git', ['branch', 'sessionlog/0000000'], { cwd: tmpDir, stdio: 'pipe' });
541
-
542
- const branches = listGitBranches(tmpDir, 'sessionlog/*');
543
- console.log('Branches before clean:', branches);
544
- expect(branches).toContain('sessionlog/0000000');
545
-
546
- const output = runSessionlog(tmpDir, ['clean']);
547
- console.log('Clean output:', output);
548
-
549
- // Should detect the orphaned branch
550
- expect(output).toContain('sessionlog/0000000');
551
- });
552
- });
553
-
554
- // ==========================================================================
555
- // Suite 5: Token Usage
556
- // ==========================================================================
557
-
558
- describe('Token Usage', () => {
559
- it('should populate token usage after a Claude session', async () => {
560
- runClaude(tmpDir, 'What is 2 plus 2? Answer with just the number.', {
561
- timeoutMs: 60_000,
562
- });
563
-
564
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
565
-
566
- const sessions = readSessionStates(tmpDir);
567
- console.log('Sessions found:', sessions.length);
568
- expect(sessions.length).toBeGreaterThan(0);
569
-
570
- const session = sessions[0];
571
- console.log('Token usage:', JSON.stringify(session.tokenUsage, null, 2));
572
-
573
- // Token usage depends on transcript parsing which may not fire in -p mode.
574
- // Use soft assertions.
575
- if (session.tokenUsage) {
576
- const usage = session.tokenUsage as Record<string, number>;
577
- expect.soft(usage.inputTokens, 'Expected inputTokens > 0').toBeGreaterThan(0);
578
- expect.soft(usage.outputTokens, 'Expected outputTokens > 0').toBeGreaterThan(0);
579
- } else {
580
- console.warn('tokenUsage not populated — this is timing-dependent and may be expected');
581
- }
582
- }, 180_000);
583
- });
584
-
585
- // ==========================================================================
586
- // Suite 6: Multiple Sessions
587
- // ==========================================================================
588
-
589
- describe('Multiple Sessions', () => {
590
- it('should create separate session states for sequential invocations', async () => {
591
- // First invocation: create a file
592
- runClaude(tmpDir, 'Create a file called app/main.ts with content: console.log("hello");', {
593
- allowedTools: ['Write'],
594
- timeoutMs: 120_000,
595
- });
596
-
597
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
598
-
599
- const sessionsAfterFirst = readSessionStates(tmpDir);
600
- console.log('Sessions after first invocation:', sessionsAfterFirst.length);
601
-
602
- // Second invocation: modify the file
603
- runClaude(tmpDir, 'Read the file app/main.ts and add a second line: console.log("world");', {
604
- allowedTools: ['Edit', 'Read', 'Write'],
605
- timeoutMs: 120_000,
606
- });
607
-
608
- await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
609
-
610
- const sessionsAfterSecond = readSessionStates(tmpDir);
611
- console.log('Sessions after second invocation:', sessionsAfterSecond.length);
612
-
613
- // Each -p invocation creates a new session, so we should have >= 2
614
- expect(sessionsAfterSecond.length).toBeGreaterThanOrEqual(2);
615
-
616
- // Verify sessions have different IDs
617
- const sessionIDs = sessionsAfterSecond.map((s) => s.sessionID);
618
- const uniqueIDs = new Set(sessionIDs);
619
- expect(uniqueIDs.size).toBeGreaterThanOrEqual(2);
620
-
621
- // Status should list all sessions
622
- const status = getStatus(tmpDir);
623
- const statusSessions = status.sessions as Record<string, unknown>[];
624
- console.log('Status sessions count:', statusSessions.length);
625
- expect(statusSessions.length).toBeGreaterThanOrEqual(2);
626
- }, 300_000);
627
- });
628
-
629
- // ==========================================================================
630
- // Suite 7: Checkpoint Lifecycle via CLI Binary (deterministic, no timing issues)
631
- // ==========================================================================
632
-
633
- describe('Checkpoint Lifecycle — CLI Binary', () => {
634
- /**
635
- * These tests pipe hook events directly to the sessionlog CLI binary,
636
- * bypassing the need for a real Claude session. This allows deterministic
637
- * testing of the checkpoint creation, rewind, and explain flows.
638
- */
639
-
640
- let sessionsDir: string;
641
-
642
- beforeEach(() => {
643
- sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
644
- fs.mkdirSync(sessionsDir, { recursive: true });
645
-
646
- // Pre-create an active session state
647
- const head = getHead(tmpDir);
648
- const sessionState = {
649
- sessionID: 'cli-e2e-session',
650
- baseCommit: head,
651
- startedAt: new Date().toISOString(),
652
- phase: 'active',
653
- turnCheckpointIDs: [],
654
- stepCount: 0,
655
- checkpointTranscriptStart: 0,
656
- untrackedFilesAtStart: [],
657
- filesTouched: [],
658
- agentType: 'Claude Code',
659
- };
660
- fs.writeFileSync(
661
- path.join(sessionsDir, 'cli-e2e-session.json'),
662
- JSON.stringify(sessionState, null, 2),
663
- );
664
- });
665
-
666
- it('should dispatch session_start through the CLI and create session state', () => {
667
- const payload = JSON.stringify({
668
- session_id: 'cli-e2e-session',
669
- transcript_path: '/path/to/transcript.jsonl',
670
- });
671
-
672
- execSync(`echo ${JSON.stringify(payload)} | sessionlog hooks claude-code session-start`, {
673
- cwd: tmpDir,
674
- timeout: 10_000,
675
- stdio: 'pipe',
676
- });
677
-
678
- const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
679
- const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
680
- expect(state.sessionID).toBe('cli-e2e-session');
681
- expect(state.agentType).toBe('Claude Code');
682
- });
683
-
684
- it('should dispatch session_end and mark session as ended', () => {
685
- const payload = JSON.stringify({
686
- session_id: 'cli-e2e-session',
687
- transcript_path: '/path/to/transcript.jsonl',
688
- });
689
-
690
- execSync(`echo ${JSON.stringify(payload)} | sessionlog hooks claude-code session-end`, {
691
- cwd: tmpDir,
692
- timeout: 10_000,
693
- stdio: 'pipe',
694
- });
695
-
696
- const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
697
- const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
698
- expect(state.phase).toBe('ended');
699
- expect(state.endedAt).toBeDefined();
700
- });
701
-
702
- it('should handle full hook lifecycle: start → prompt → tool use → stop → end', () => {
703
- // 1. Session start
704
- execSync(
705
- `echo ${JSON.stringify(
706
- JSON.stringify({
707
- session_id: 'cli-e2e-session',
708
- transcript_path: '/path/to/transcript.jsonl',
709
- }),
710
- )} | sessionlog hooks claude-code session-start`,
711
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
712
- );
713
-
714
- // 2. User prompt submit (turn start)
715
- execSync(
716
- `echo ${JSON.stringify(
717
- JSON.stringify({
718
- session_id: 'cli-e2e-session',
719
- transcript_path: '/path/to/transcript.jsonl',
720
- }),
721
- )} | sessionlog hooks claude-code user-prompt-submit`,
722
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
723
- );
724
-
725
- // 3. Post tool use (Write tool)
726
- execSync(
727
- `echo ${JSON.stringify(
728
- JSON.stringify({
729
- session_id: 'cli-e2e-session',
730
- transcript_path: '/path/to/transcript.jsonl',
731
- tool_use_id: 'toolu_01',
732
- tool_name: 'Write',
733
- tool_input: { file_path: '/tmp/test/src/app.ts', content: 'console.log("hi")' },
734
- }),
735
- )} | sessionlog hooks claude-code post-tool-Write`,
736
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
737
- );
738
-
739
- // 4. Stop
740
- execSync(
741
- `echo ${JSON.stringify(
742
- JSON.stringify({
743
- session_id: 'cli-e2e-session',
744
- transcript_path: '/path/to/transcript.jsonl',
745
- }),
746
- )} | sessionlog hooks claude-code stop`,
747
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
748
- );
749
-
750
- // 5. Session end
751
- execSync(
752
- `echo ${JSON.stringify(
753
- JSON.stringify({
754
- session_id: 'cli-e2e-session',
755
- transcript_path: '/path/to/transcript.jsonl',
756
- }),
757
- )} | sessionlog hooks claude-code session-end`,
758
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
759
- );
760
-
761
- // Verify final state
762
- const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
763
- const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
764
-
765
- expect(state.phase).toBe('ended');
766
- expect(state.endedAt).toBeDefined();
767
- });
768
-
769
- it('should track tasks and plan mode through full CLI lifecycle', () => {
770
- // 1. Enter plan mode
771
- execSync(
772
- `echo ${JSON.stringify(
773
- JSON.stringify({
774
- session_id: 'cli-e2e-session',
775
- transcript_path: '/path/to/transcript.jsonl',
776
- }),
777
- )} | sessionlog hooks claude-code post-plan-enter`,
778
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
779
- );
780
-
781
- // 2. Exit plan mode with plan file
782
- const planDir = path.join(tmpDir, '.claude', 'plans');
783
- fs.mkdirSync(planDir, { recursive: true });
784
- const planPath = path.join(planDir, 'e2e-plan.md');
785
- fs.writeFileSync(planPath, '# E2E Plan\n\n1. Create files\n2. Run tests');
786
-
787
- execSync(
788
- `echo ${JSON.stringify(
789
- JSON.stringify({
790
- session_id: 'cli-e2e-session',
791
- transcript_path: '/path/to/transcript.jsonl',
792
- tool_input: {},
793
- tool_response: { planFilePath: planPath },
794
- }),
795
- )} | sessionlog hooks claude-code post-plan-exit`,
796
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
797
- );
798
-
799
- // 3. Create task
800
- execSync(
801
- `echo ${JSON.stringify(
802
- JSON.stringify({
803
- session_id: 'cli-e2e-session',
804
- transcript_path: '/path/to/transcript.jsonl',
805
- tool_use_id: 'toolu_01',
806
- tool_input: {
807
- subject: 'Set up project',
808
- description: 'Initialize project structure and dependencies',
809
- },
810
- tool_response: { taskId: '1' },
811
- }),
812
- )} | sessionlog hooks claude-code post-task-create`,
813
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
814
- );
815
-
816
- // 4. Create second task
817
- execSync(
818
- `echo ${JSON.stringify(
819
- JSON.stringify({
820
- session_id: 'cli-e2e-session',
821
- transcript_path: '/path/to/transcript.jsonl',
822
- tool_use_id: 'toolu_02',
823
- tool_input: {
824
- subject: 'Write tests',
825
- description: 'Add unit and integration tests',
826
- },
827
- tool_response: { taskId: '2' },
828
- }),
829
- )} | sessionlog hooks claude-code post-task-create`,
830
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
831
- );
832
-
833
- // 5. Update first task to completed
834
- execSync(
835
- `echo ${JSON.stringify(
836
- JSON.stringify({
837
- session_id: 'cli-e2e-session',
838
- transcript_path: '/path/to/transcript.jsonl',
839
- tool_use_id: 'toolu_03',
840
- tool_input: { taskId: '1', status: 'completed' },
841
- }),
842
- )} | sessionlog hooks claude-code post-task-update`,
843
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
844
- );
845
-
846
- // Verify final state
847
- const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
848
- const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
849
-
850
- // Plan mode tracking
851
- expect(state.inPlanMode).toBe(false);
852
- expect(state.planModeEntries).toBe(1);
853
- expect(state.planEntries).toHaveLength(1);
854
- expect(state.planEntries[0].content).toBe('# E2E Plan\n\n1. Create files\n2. Run tests');
855
- expect(state.planEntries[0].exitedAt).toBeDefined();
856
-
857
- // Task tracking
858
- expect(Object.keys(state.tasks)).toHaveLength(2);
859
- expect(state.tasks['1'].subject).toBe('Set up project');
860
- expect(state.tasks['1'].description).toBe('Initialize project structure and dependencies');
861
- expect(state.tasks['1'].status).toBe('completed');
862
- expect(state.tasks['2'].subject).toBe('Write tests');
863
- expect(state.tasks['2'].description).toBe('Add unit and integration tests');
864
- expect(state.tasks['2'].status).toBe('pending');
865
- });
866
-
867
- it('should verify status command reflects CLI-dispatched session state', () => {
868
- // Dispatch some events
869
- execSync(
870
- `echo ${JSON.stringify(
871
- JSON.stringify({
872
- session_id: 'cli-e2e-session',
873
- transcript_path: '/path/to/transcript.jsonl',
874
- }),
875
- )} | sessionlog hooks claude-code session-start`,
876
- { cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
877
- );
878
-
879
- // Check status reflects the session
880
- const status = getStatus(tmpDir);
881
- const sessions = status.sessions as Record<string, unknown>[];
882
-
883
- expect(sessions.length).toBeGreaterThanOrEqual(1);
884
-
885
- const session = sessions.find((s) => s.sessionID === 'cli-e2e-session');
886
- expect(session).toBeDefined();
887
- expect(session!.agentType).toBe('Claude Code');
888
- });
889
- });
890
- });