@bosun-sh/logbook 1.1.0 → 2.0.1

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 (461) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +249 -318
  3. package/bin/logbook.cjs +18 -0
  4. package/dist/context/attachments.d.ts +55 -0
  5. package/dist/context/attachments.d.ts.map +1 -0
  6. package/dist/context/attachments.js +329 -0
  7. package/dist/context/attachments.js.map +1 -0
  8. package/dist/context/create.d.ts +31 -0
  9. package/dist/context/create.d.ts.map +1 -0
  10. package/dist/context/create.js +101 -0
  11. package/dist/context/create.js.map +1 -0
  12. package/dist/context/delete.d.ts +20 -0
  13. package/dist/context/delete.d.ts.map +1 -0
  14. package/dist/context/delete.js +55 -0
  15. package/dist/context/delete.js.map +1 -0
  16. package/dist/context/get.d.ts +20 -0
  17. package/dist/context/get.d.ts.map +1 -0
  18. package/dist/context/get.js +55 -0
  19. package/dist/context/get.js.map +1 -0
  20. package/dist/context/list.d.ts +30 -0
  21. package/dist/context/list.d.ts.map +1 -0
  22. package/dist/context/list.js +172 -0
  23. package/dist/context/list.js.map +1 -0
  24. package/dist/context/schema.d.ts +156 -0
  25. package/dist/context/schema.d.ts.map +1 -0
  26. package/dist/context/schema.js +34 -0
  27. package/dist/context/schema.js.map +1 -0
  28. package/dist/context/search.d.ts +27 -0
  29. package/dist/context/search.d.ts.map +1 -0
  30. package/dist/context/search.js +266 -0
  31. package/dist/context/search.js.map +1 -0
  32. package/dist/context/topics.d.ts +4 -0
  33. package/dist/context/topics.d.ts.map +1 -0
  34. package/dist/context/topics.js +54 -0
  35. package/dist/context/topics.js.map +1 -0
  36. package/dist/context/update.d.ts +29 -0
  37. package/dist/context/update.d.ts.map +1 -0
  38. package/dist/context/update.js +134 -0
  39. package/dist/context/update.js.map +1 -0
  40. package/dist/epic/cascade-delete.d.ts +30 -0
  41. package/dist/epic/cascade-delete.d.ts.map +1 -0
  42. package/dist/epic/cascade-delete.js +173 -0
  43. package/dist/epic/cascade-delete.js.map +1 -0
  44. package/dist/epic/create.d.ts +24 -0
  45. package/dist/epic/create.d.ts.map +1 -0
  46. package/dist/epic/create.js +54 -0
  47. package/dist/epic/create.js.map +1 -0
  48. package/dist/epic/delete.d.ts +21 -0
  49. package/dist/epic/delete.d.ts.map +1 -0
  50. package/dist/epic/delete.js +42 -0
  51. package/dist/epic/delete.js.map +1 -0
  52. package/dist/epic/get.d.ts +19 -0
  53. package/dist/epic/get.d.ts.map +1 -0
  54. package/dist/epic/get.js +31 -0
  55. package/dist/epic/get.js.map +1 -0
  56. package/dist/epic/list.d.ts +25 -0
  57. package/dist/epic/list.d.ts.map +1 -0
  58. package/dist/epic/list.js +114 -0
  59. package/dist/epic/list.js.map +1 -0
  60. package/dist/epic/rules.d.ts +34 -0
  61. package/dist/epic/rules.d.ts.map +1 -0
  62. package/dist/epic/rules.js +127 -0
  63. package/dist/epic/rules.js.map +1 -0
  64. package/dist/epic/schema.d.ts +85 -0
  65. package/dist/epic/schema.d.ts.map +1 -0
  66. package/dist/epic/schema.js +14 -0
  67. package/dist/epic/schema.js.map +1 -0
  68. package/dist/epic/update.d.ts +25 -0
  69. package/dist/epic/update.d.ts.map +1 -0
  70. package/dist/epic/update.js +69 -0
  71. package/dist/epic/update.js.map +1 -0
  72. package/dist/hook/list.d.ts +71 -0
  73. package/dist/hook/list.d.ts.map +1 -0
  74. package/dist/hook/list.js +364 -0
  75. package/dist/hook/list.js.map +1 -0
  76. package/dist/hook/ports.d.ts +16 -0
  77. package/dist/hook/ports.d.ts.map +1 -0
  78. package/dist/hook/ports.js +3 -0
  79. package/dist/hook/ports.js.map +1 -0
  80. package/dist/hook/run.d.ts +24 -0
  81. package/dist/hook/run.d.ts.map +1 -0
  82. package/dist/hook/run.js +185 -0
  83. package/dist/hook/run.js.map +1 -0
  84. package/dist/index.d.ts +31 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +31 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/plugin/hook-tools.d.ts +8 -0
  89. package/dist/plugin/hook-tools.d.ts.map +1 -0
  90. package/dist/plugin/hook-tools.js +31 -0
  91. package/dist/plugin/hook-tools.js.map +1 -0
  92. package/dist/plugin/linear-pull-tool.d.ts +20 -0
  93. package/dist/plugin/linear-pull-tool.d.ts.map +1 -0
  94. package/dist/plugin/linear-pull-tool.js +19 -0
  95. package/dist/plugin/linear-pull-tool.js.map +1 -0
  96. package/dist/plugin/linear-push-tool.d.ts +20 -0
  97. package/dist/plugin/linear-push-tool.d.ts.map +1 -0
  98. package/dist/plugin/linear-push-tool.js +27 -0
  99. package/dist/plugin/linear-push-tool.js.map +1 -0
  100. package/dist/plugin/linear-setup-tool.d.ts +2 -0
  101. package/dist/plugin/linear-setup-tool.d.ts.map +1 -0
  102. package/dist/plugin/linear-setup-tool.js +22 -0
  103. package/dist/plugin/linear-setup-tool.js.map +1 -0
  104. package/dist/plugin/linear-status-tool.d.ts +10 -0
  105. package/dist/plugin/linear-status-tool.d.ts.map +1 -0
  106. package/dist/plugin/linear-status-tool.js +10 -0
  107. package/dist/plugin/linear-status-tool.js.map +1 -0
  108. package/dist/plugin/list.d.ts +15 -0
  109. package/dist/plugin/list.d.ts.map +1 -0
  110. package/dist/plugin/list.js +87 -0
  111. package/dist/plugin/list.js.map +1 -0
  112. package/dist/plugin/public-schemas.d.ts +42 -0
  113. package/dist/plugin/public-schemas.d.ts.map +1 -0
  114. package/dist/plugin/public-schemas.js +577 -0
  115. package/dist/plugin/public-schemas.js.map +1 -0
  116. package/dist/plugin/registry.d.ts +3 -0
  117. package/dist/plugin/registry.d.ts.map +1 -0
  118. package/dist/plugin/registry.js +3 -0
  119. package/dist/plugin/registry.js.map +1 -0
  120. package/dist/plugin/results.d.ts +8 -0
  121. package/dist/plugin/results.d.ts.map +1 -0
  122. package/dist/plugin/results.js +114 -0
  123. package/dist/plugin/results.js.map +1 -0
  124. package/dist/plugin/sync-conflict-tools.d.ts +2 -0
  125. package/dist/plugin/sync-conflict-tools.d.ts.map +1 -0
  126. package/dist/plugin/sync-conflict-tools.js +5 -0
  127. package/dist/plugin/sync-conflict-tools.js.map +1 -0
  128. package/dist/plugin/tool-registry.d.ts +23 -0
  129. package/dist/plugin/tool-registry.d.ts.map +1 -0
  130. package/dist/plugin/tool-registry.js +251 -0
  131. package/dist/plugin/tool-registry.js.map +1 -0
  132. package/dist/plugin/workspace-init-tool.d.ts +2 -0
  133. package/dist/plugin/workspace-init-tool.d.ts.map +1 -0
  134. package/dist/plugin/workspace-init-tool.js +16 -0
  135. package/dist/plugin/workspace-init-tool.js.map +1 -0
  136. package/dist/plugin/workspace-status-tool.d.ts +2 -0
  137. package/dist/plugin/workspace-status-tool.d.ts.map +1 -0
  138. package/dist/plugin/workspace-status-tool.js +15 -0
  139. package/dist/plugin/workspace-status-tool.js.map +1 -0
  140. package/dist/shared/ids.d.ts +3 -0
  141. package/dist/shared/ids.d.ts.map +1 -0
  142. package/dist/shared/ids.js +15 -0
  143. package/dist/shared/ids.js.map +1 -0
  144. package/dist/shared/pagination.d.ts +19 -0
  145. package/dist/shared/pagination.d.ts.map +1 -0
  146. package/dist/shared/pagination.js +110 -0
  147. package/dist/shared/pagination.js.map +1 -0
  148. package/dist/shared/result.d.ts +20 -0
  149. package/dist/shared/result.d.ts.map +1 -0
  150. package/dist/shared/result.js +6 -0
  151. package/dist/shared/result.js.map +1 -0
  152. package/dist/shared/schema/value-objects.d.ts +363 -0
  153. package/dist/shared/schema/value-objects.d.ts.map +1 -0
  154. package/dist/shared/schema/value-objects.js +112 -0
  155. package/dist/shared/schema/value-objects.js.map +1 -0
  156. package/dist/shared/storage/atomic-write.d.ts +25 -0
  157. package/dist/shared/storage/atomic-write.d.ts.map +1 -0
  158. package/dist/shared/storage/atomic-write.js +71 -0
  159. package/dist/shared/storage/atomic-write.js.map +1 -0
  160. package/dist/shared/storage/jsonl-repository.d.ts +85 -0
  161. package/dist/shared/storage/jsonl-repository.d.ts.map +1 -0
  162. package/dist/shared/storage/jsonl-repository.js +278 -0
  163. package/dist/shared/storage/jsonl-repository.js.map +1 -0
  164. package/dist/shared/storage/transaction.d.ts +3 -0
  165. package/dist/shared/storage/transaction.d.ts.map +1 -0
  166. package/dist/shared/storage/transaction.js +22 -0
  167. package/dist/shared/storage/transaction.js.map +1 -0
  168. package/dist/shared/time.d.ts +3 -0
  169. package/dist/shared/time.d.ts.map +1 -0
  170. package/dist/shared/time.js +3 -0
  171. package/dist/shared/time.js.map +1 -0
  172. package/dist/shared/version.d.ts +2 -0
  173. package/dist/shared/version.d.ts.map +1 -0
  174. package/dist/shared/version.js +2 -0
  175. package/dist/shared/version.js.map +1 -0
  176. package/dist/story/cascade-delete.d.ts +22 -0
  177. package/dist/story/cascade-delete.d.ts.map +1 -0
  178. package/dist/story/cascade-delete.js +117 -0
  179. package/dist/story/cascade-delete.js.map +1 -0
  180. package/dist/story/create.d.ts +30 -0
  181. package/dist/story/create.d.ts.map +1 -0
  182. package/dist/story/create.js +69 -0
  183. package/dist/story/create.js.map +1 -0
  184. package/dist/story/delete.d.ts +21 -0
  185. package/dist/story/delete.d.ts.map +1 -0
  186. package/dist/story/delete.js +42 -0
  187. package/dist/story/delete.js.map +1 -0
  188. package/dist/story/get.d.ts +19 -0
  189. package/dist/story/get.d.ts.map +1 -0
  190. package/dist/story/get.js +31 -0
  191. package/dist/story/get.js.map +1 -0
  192. package/dist/story/hierarchy.d.ts +20 -0
  193. package/dist/story/hierarchy.d.ts.map +1 -0
  194. package/dist/story/hierarchy.js +30 -0
  195. package/dist/story/hierarchy.js.map +1 -0
  196. package/dist/story/list.d.ts +25 -0
  197. package/dist/story/list.d.ts.map +1 -0
  198. package/dist/story/list.js +118 -0
  199. package/dist/story/list.js.map +1 -0
  200. package/dist/story/rules.d.ts +34 -0
  201. package/dist/story/rules.d.ts.map +1 -0
  202. package/dist/story/rules.js +100 -0
  203. package/dist/story/rules.js.map +1 -0
  204. package/dist/story/schema.d.ts +65 -0
  205. package/dist/story/schema.d.ts.map +1 -0
  206. package/dist/story/schema.js +14 -0
  207. package/dist/story/schema.js.map +1 -0
  208. package/dist/story/update.d.ts +23 -0
  209. package/dist/story/update.d.ts.map +1 -0
  210. package/dist/story/update.js +67 -0
  211. package/dist/story/update.js.map +1 -0
  212. package/dist/sync/base-snapshot.d.ts +38 -0
  213. package/dist/sync/base-snapshot.d.ts.map +1 -0
  214. package/dist/sync/base-snapshot.js +86 -0
  215. package/dist/sync/base-snapshot.js.map +1 -0
  216. package/dist/sync/conflict-tools.d.ts +75 -0
  217. package/dist/sync/conflict-tools.d.ts.map +1 -0
  218. package/dist/sync/conflict-tools.js +53 -0
  219. package/dist/sync/conflict-tools.js.map +1 -0
  220. package/dist/sync/conflicts.d.ts +201 -0
  221. package/dist/sync/conflicts.d.ts.map +1 -0
  222. package/dist/sync/conflicts.js +526 -0
  223. package/dist/sync/conflicts.js.map +1 -0
  224. package/dist/sync/deferred-providers.d.ts +2 -0
  225. package/dist/sync/deferred-providers.d.ts.map +1 -0
  226. package/dist/sync/deferred-providers.js +6 -0
  227. package/dist/sync/deferred-providers.js.map +1 -0
  228. package/dist/sync/events.d.ts +401 -0
  229. package/dist/sync/events.d.ts.map +1 -0
  230. package/dist/sync/events.js +357 -0
  231. package/dist/sync/events.js.map +1 -0
  232. package/dist/sync/external-links.d.ts +154 -0
  233. package/dist/sync/external-links.d.ts.map +1 -0
  234. package/dist/sync/external-links.js +306 -0
  235. package/dist/sync/external-links.js.map +1 -0
  236. package/dist/sync/linear/config.d.ts +60 -0
  237. package/dist/sync/linear/config.d.ts.map +1 -0
  238. package/dist/sync/linear/config.js +302 -0
  239. package/dist/sync/linear/config.js.map +1 -0
  240. package/dist/sync/linear/mapping.d.ts +115 -0
  241. package/dist/sync/linear/mapping.d.ts.map +1 -0
  242. package/dist/sync/linear/mapping.js +159 -0
  243. package/dist/sync/linear/mapping.js.map +1 -0
  244. package/dist/sync/linear/pull.d.ts +33 -0
  245. package/dist/sync/linear/pull.d.ts.map +1 -0
  246. package/dist/sync/linear/pull.js +376 -0
  247. package/dist/sync/linear/pull.js.map +1 -0
  248. package/dist/sync/linear/push.d.ts +34 -0
  249. package/dist/sync/linear/push.d.ts.map +1 -0
  250. package/dist/sync/linear/push.js +681 -0
  251. package/dist/sync/linear/push.js.map +1 -0
  252. package/dist/sync/linear/setup.d.ts +33 -0
  253. package/dist/sync/linear/setup.d.ts.map +1 -0
  254. package/dist/sync/linear/setup.js +129 -0
  255. package/dist/sync/linear/setup.js.map +1 -0
  256. package/dist/sync/linear/status.d.ts +35 -0
  257. package/dist/sync/linear/status.d.ts.map +1 -0
  258. package/dist/sync/linear/status.js +138 -0
  259. package/dist/sync/linear/status.js.map +1 -0
  260. package/dist/sync/linear/transport.d.ts +47 -0
  261. package/dist/sync/linear/transport.d.ts.map +1 -0
  262. package/dist/sync/linear/transport.js +249 -0
  263. package/dist/sync/linear/transport.js.map +1 -0
  264. package/dist/sync/provider-port.d.ts +81 -0
  265. package/dist/sync/provider-port.d.ts.map +1 -0
  266. package/dist/sync/provider-port.js +16 -0
  267. package/dist/sync/provider-port.js.map +1 -0
  268. package/dist/sync/provider-registry.d.ts +38 -0
  269. package/dist/sync/provider-registry.d.ts.map +1 -0
  270. package/dist/sync/provider-registry.js +115 -0
  271. package/dist/sync/provider-registry.js.map +1 -0
  272. package/dist/sync/schema.d.ts +147 -0
  273. package/dist/sync/schema.d.ts.map +1 -0
  274. package/dist/sync/schema.js +28 -0
  275. package/dist/sync/schema.js.map +1 -0
  276. package/dist/task/comments.d.ts +9 -0
  277. package/dist/task/comments.d.ts.map +1 -0
  278. package/dist/task/comments.js +79 -0
  279. package/dist/task/comments.js.map +1 -0
  280. package/dist/task/create.d.ts +34 -0
  281. package/dist/task/create.d.ts.map +1 -0
  282. package/dist/task/create.js +126 -0
  283. package/dist/task/create.js.map +1 -0
  284. package/dist/task/current.d.ts +18 -0
  285. package/dist/task/current.d.ts.map +1 -0
  286. package/dist/task/current.js +105 -0
  287. package/dist/task/current.js.map +1 -0
  288. package/dist/task/edit.d.ts +22 -0
  289. package/dist/task/edit.d.ts.map +1 -0
  290. package/dist/task/edit.js +105 -0
  291. package/dist/task/edit.js.map +1 -0
  292. package/dist/task/estimate.d.ts +20 -0
  293. package/dist/task/estimate.d.ts.map +1 -0
  294. package/dist/task/estimate.js +141 -0
  295. package/dist/task/estimate.js.map +1 -0
  296. package/dist/task/get.d.ts +13 -0
  297. package/dist/task/get.d.ts.map +1 -0
  298. package/dist/task/get.js +29 -0
  299. package/dist/task/get.js.map +1 -0
  300. package/dist/task/hierarchy.d.ts +18 -0
  301. package/dist/task/hierarchy.d.ts.map +1 -0
  302. package/dist/task/hierarchy.js +56 -0
  303. package/dist/task/hierarchy.js.map +1 -0
  304. package/dist/task/lifecycle.d.ts +14 -0
  305. package/dist/task/lifecycle.d.ts.map +1 -0
  306. package/dist/task/lifecycle.js +80 -0
  307. package/dist/task/lifecycle.js.map +1 -0
  308. package/dist/task/list.d.ts +24 -0
  309. package/dist/task/list.d.ts.map +1 -0
  310. package/dist/task/list.js +116 -0
  311. package/dist/task/list.js.map +1 -0
  312. package/dist/task/model-assignment.d.ts +33 -0
  313. package/dist/task/model-assignment.d.ts.map +1 -0
  314. package/dist/task/model-assignment.js +145 -0
  315. package/dist/task/model-assignment.js.map +1 -0
  316. package/dist/task/ordering.d.ts +4 -0
  317. package/dist/task/ordering.d.ts.map +1 -0
  318. package/dist/task/ordering.js +14 -0
  319. package/dist/task/ordering.js.map +1 -0
  320. package/dist/task/ports.d.ts +37 -0
  321. package/dist/task/ports.d.ts.map +1 -0
  322. package/dist/task/ports.js +3 -0
  323. package/dist/task/ports.js.map +1 -0
  324. package/dist/task/schema.d.ts +447 -0
  325. package/dist/task/schema.d.ts.map +1 -0
  326. package/dist/task/schema.js +35 -0
  327. package/dist/task/schema.js.map +1 -0
  328. package/dist/task/session-assignment.d.ts +23 -0
  329. package/dist/task/session-assignment.d.ts.map +1 -0
  330. package/dist/task/session-assignment.js +197 -0
  331. package/dist/task/session-assignment.js.map +1 -0
  332. package/dist/task/session-registry.d.ts +8 -0
  333. package/dist/task/session-registry.d.ts.map +1 -0
  334. package/dist/task/session-registry.js +3 -0
  335. package/dist/task/session-registry.js.map +1 -0
  336. package/dist/task/update.d.ts +23 -0
  337. package/dist/task/update.d.ts.map +1 -0
  338. package/dist/task/update.js +92 -0
  339. package/dist/task/update.js.map +1 -0
  340. package/dist/task/v1-compat.d.ts +94 -0
  341. package/dist/task/v1-compat.d.ts.map +1 -0
  342. package/dist/task/v1-compat.js +181 -0
  343. package/dist/task/v1-compat.js.map +1 -0
  344. package/dist/workspace/bin-cli.d.ts +2 -0
  345. package/dist/workspace/bin-cli.d.ts.map +1 -0
  346. package/dist/workspace/bin-cli.js +36 -0
  347. package/dist/workspace/bin-cli.js.map +1 -0
  348. package/dist/workspace/cli-adapter.d.ts +17 -0
  349. package/dist/workspace/cli-adapter.d.ts.map +1 -0
  350. package/dist/workspace/cli-adapter.js +230 -0
  351. package/dist/workspace/cli-adapter.js.map +1 -0
  352. package/dist/workspace/cli-commands.d.ts +11 -0
  353. package/dist/workspace/cli-commands.d.ts.map +1 -0
  354. package/dist/workspace/cli-commands.js +12 -0
  355. package/dist/workspace/cli-commands.js.map +1 -0
  356. package/dist/workspace/duckdb-index.d.ts +56 -0
  357. package/dist/workspace/duckdb-index.d.ts.map +1 -0
  358. package/dist/workspace/duckdb-index.js +178 -0
  359. package/dist/workspace/duckdb-index.js.map +1 -0
  360. package/dist/workspace/hook-templates/need-info-notify/config.json +10 -0
  361. package/dist/workspace/hook-templates/need-info-notify/script.mjs +68 -0
  362. package/dist/workspace/hook-templates/review-spawn/config.json +10 -0
  363. package/dist/workspace/hook-templates/review-spawn/script.mjs +100 -0
  364. package/dist/workspace/init-onboarding.d.ts +9 -0
  365. package/dist/workspace/init-onboarding.d.ts.map +1 -0
  366. package/dist/workspace/init-onboarding.js +335 -0
  367. package/dist/workspace/init-onboarding.js.map +1 -0
  368. package/dist/workspace/init.d.ts +20 -0
  369. package/dist/workspace/init.d.ts.map +1 -0
  370. package/dist/workspace/init.js +288 -0
  371. package/dist/workspace/init.js.map +1 -0
  372. package/dist/workspace/layers.d.ts +127 -0
  373. package/dist/workspace/layers.d.ts.map +1 -0
  374. package/dist/workspace/layers.js +50 -0
  375. package/dist/workspace/layers.js.map +1 -0
  376. package/dist/workspace/mcp-server.d.ts +28 -0
  377. package/dist/workspace/mcp-server.d.ts.map +1 -0
  378. package/dist/workspace/mcp-server.js +191 -0
  379. package/dist/workspace/mcp-server.js.map +1 -0
  380. package/dist/workspace/mcp-stdio.d.ts +2 -0
  381. package/dist/workspace/mcp-stdio.d.ts.map +1 -0
  382. package/dist/workspace/mcp-stdio.js +66 -0
  383. package/dist/workspace/mcp-stdio.js.map +1 -0
  384. package/dist/workspace/mcp-tools.d.ts +24 -0
  385. package/dist/workspace/mcp-tools.d.ts.map +1 -0
  386. package/dist/workspace/mcp-tools.js +43 -0
  387. package/dist/workspace/mcp-tools.js.map +1 -0
  388. package/dist/workspace/migrate-v1.d.ts +12 -0
  389. package/dist/workspace/migrate-v1.d.ts.map +1 -0
  390. package/dist/workspace/migrate-v1.js +301 -0
  391. package/dist/workspace/migrate-v1.js.map +1 -0
  392. package/dist/workspace/ohtools-app.d.ts +3 -0
  393. package/dist/workspace/ohtools-app.d.ts.map +1 -0
  394. package/dist/workspace/ohtools-app.js +10 -0
  395. package/dist/workspace/ohtools-app.js.map +1 -0
  396. package/dist/workspace/repositories.d.ts +25 -0
  397. package/dist/workspace/repositories.d.ts.map +1 -0
  398. package/dist/workspace/repositories.js +76 -0
  399. package/dist/workspace/repositories.js.map +1 -0
  400. package/dist/workspace/runtime.d.ts +123 -0
  401. package/dist/workspace/runtime.d.ts.map +1 -0
  402. package/dist/workspace/runtime.js +4 -0
  403. package/dist/workspace/runtime.js.map +1 -0
  404. package/dist/workspace/session-liveness.d.ts +6 -0
  405. package/dist/workspace/session-liveness.d.ts.map +1 -0
  406. package/dist/workspace/session-liveness.js +3 -0
  407. package/dist/workspace/session-liveness.js.map +1 -0
  408. package/dist/workspace/status.d.ts +46 -0
  409. package/dist/workspace/status.d.ts.map +1 -0
  410. package/dist/workspace/status.js +345 -0
  411. package/dist/workspace/status.js.map +1 -0
  412. package/dist/workspace/storage-layout.d.ts +19 -0
  413. package/dist/workspace/storage-layout.d.ts.map +1 -0
  414. package/dist/workspace/storage-layout.js +55 -0
  415. package/dist/workspace/storage-layout.js.map +1 -0
  416. package/dist/workspace/storage-paths.d.ts +16 -0
  417. package/dist/workspace/storage-paths.d.ts.map +1 -0
  418. package/dist/workspace/storage-paths.js +15 -0
  419. package/dist/workspace/storage-paths.js.map +1 -0
  420. package/dist/workspace/v1-cli-aliases.d.ts +18 -0
  421. package/dist/workspace/v1-cli-aliases.d.ts.map +1 -0
  422. package/dist/workspace/v1-cli-aliases.js +223 -0
  423. package/dist/workspace/v1-cli-aliases.js.map +1 -0
  424. package/dist/workspace/v1-cli-task.d.ts +2 -0
  425. package/dist/workspace/v1-cli-task.d.ts.map +1 -0
  426. package/dist/workspace/v1-cli-task.js +53 -0
  427. package/dist/workspace/v1-cli-task.js.map +1 -0
  428. package/package.json +29 -12
  429. package/quickstart.md +174 -0
  430. package/hooks/need-info-notify/config.yml +0 -3
  431. package/hooks/need-info-notify/script.ts +0 -69
  432. package/hooks/review-spawn/config.yml +0 -3
  433. package/hooks/review-spawn/script.ts +0 -96
  434. package/src/cli/cli.ts +0 -489
  435. package/src/cli/init.ts +0 -230
  436. package/src/domain/fibonacci.ts +0 -39
  437. package/src/domain/kTokens.ts +0 -65
  438. package/src/domain/status-machine.ts +0 -49
  439. package/src/domain/types.ts +0 -66
  440. package/src/hook/hook-executor.ts +0 -70
  441. package/src/hook/ports.ts +0 -16
  442. package/src/infra/hook-config-loader.ts +0 -111
  443. package/src/infra/jsonl-task-repository.ts +0 -157
  444. package/src/infra/layer.ts +0 -34
  445. package/src/infra/logger.ts +0 -40
  446. package/src/infra/pid-session-registry.ts +0 -67
  447. package/src/mcp/error-codes.ts +0 -213
  448. package/src/mcp/server.ts +0 -396
  449. package/src/mcp/session.ts +0 -1
  450. package/src/mcp/tool-create-task.ts +0 -28
  451. package/src/mcp/tool-current-task.ts +0 -19
  452. package/src/mcp/tool-edit-task.ts +0 -40
  453. package/src/mcp/tool-list-tasks.ts +0 -34
  454. package/src/mcp/tool-update-task.ts +0 -55
  455. package/src/task/create-task.ts +0 -67
  456. package/src/task/current-task.ts +0 -111
  457. package/src/task/edit-task.ts +0 -59
  458. package/src/task/list-tasks.ts +0 -35
  459. package/src/task/ports.ts +0 -15
  460. package/src/task/session-registry.ts +0 -9
  461. package/src/task/update-task.ts +0 -160
package/README.md CHANGED
@@ -1,411 +1,342 @@
1
- # logbook: kanban for ai agents
1
+ # logbook kanban for ai agents
2
2
 
3
- logbook is a kanban board implementation for autonomous agentic development, focusing on autonomous development and context window management.
3
+ logbook is a file-system kanban board for autonomous AI agents. It tracks epics, stories, tasks, and context entries across a structured lifecycle so agents and humans share a single source of truth without context bloat.
4
4
 
5
- → **new here?** see [quickstart.md](quickstart.md) to get running in 2 minutes.
5
+ → **new here?** see [quickstart.md](quickstart.md) to get running in 5 minutes.
6
6
 
7
- ## problem
7
+ ## why logbook
8
8
 
9
- ai agents changed the way software teams worked, and with specification-driven development we encounter a rift: **agents don't manage their tasks as we do**.
9
+ autonomous agents work in parallel, forget context across sessions, and have no shared task state. logbook solves three problems:
10
10
 
11
- ### what's the issue with this?
11
+ - **human visibility** — agents record every task they touch in a file the whole team can read and diff
12
+ - **agent coordination** — `task.current` resolves FIFO per-session, so multiple agents can't claim the same task
13
+ - **context budget** — structured JSONL with a DuckDB optional query layer lets agents find relevant records without loading the whole store
12
14
 
13
- - hard for humans to track autonomous work properly: **"do you know what specific tasks your agent did?"**
14
- - hard for agents to track tasks in-progress and done: **not a centralized way to track tasks so each instance haves to figure this out**
15
- - existing tools add too much overload and are human-centered: **if an agent is going to use it, then it should be tailored for agents**
15
+ v2 adds: *epics stories tasks* hierarchy, reusable *context entries* (knowledge that survives across tasks), and Linear two-way sync as a first-class plugin.
16
16
 
17
- ## solution
18
-
19
- logbook is a file-system based kanban board that uses jsonl files to enter one task per line in a structured and clean approach and gives the agent the right tools to use it:
20
-
21
- ### tools
22
-
23
- - the agent can call `list_tasks(status)` and receive a list of the tasks in that status _(in_progress by default)_
24
- - the agent can call `current_task()` and receive the highest-priority in_progress task for the current session, resolved via this priority chain:
25
-
26
- | priority | condition | action |
27
- |----------|-----------|--------|
28
- | 1 | task already assigned to this session | return highest priority (tie-break: oldest) |
29
- | 2 | unassigned `in_progress` task | claim highest priority, return |
30
- | 3 | `in_progress` task with a dead-session assignee | claim highest priority, return |
31
- | 4 | `todo` task | auto-transition highest priority to `in_progress`, claim, return |
32
- | 5 | nothing available | fail with `no_current_task` |
33
- - the agent can call `update_task(id, new_status, comment)` to transition a task, add a comment, or reply to a `need_info` blocking comment
34
- - the agent can call `create_task(input)` to open a new task in `backlog`, passing `predictedKTokens` so the server derives a Fibonacci estimation automatically
35
- - the agent can call `edit_task(id, updates)` to change mutable fields without altering status
36
-
37
- each one of these tools has the sole purpose of removing overload from the agent context, handling the _"heavy load"_ programmatically on the MCP server or CLI.
38
-
39
- ### cli
40
-
41
- in addition to the MCP server, logbook provides a CLI for direct command-line usage:
17
+ ## quickstart
42
18
 
43
19
  ```bash
44
- # create a task
45
- logbook create-task --project myproject --milestone v1 --title "Fix bug" \
46
- --definition-of-done "Bug fixed and tested" --description "Details..." \
47
- --predicted-k-tokens 3
20
+ npm install -g @bosun-sh/logbook # install the CLI
21
+ logbook init # scaffold .logbook/, configure MCP, optionally set up Linear
22
+ logbook task:create \
23
+ --title "Implement login endpoint" \
24
+ --description "JWT auth, see docs/auth.md" \
25
+ --definition-of-done "Tests pass and endpoint is documented" \
26
+ --project myapp --milestone v1
27
+ logbook task:list --status "*"
28
+ ```
48
29
 
49
- # list tasks
50
- logbook list-tasks --status in_progress
51
- logbook list-tasks --status "*"
30
+ see [quickstart.md](quickstart.md) for the full walkthrough including Linear sync.
52
31
 
53
- # get current task
54
- logbook current-task
32
+ for one-off local use, run commands through your package manager, for example
33
+ `npx @bosun-sh/logbook --help` or `bunx @bosun-sh/logbook --help`.
55
34
 
56
- # update task status
57
- logbook update-task --id <uuid> --new-status in_progress
35
+ ## workspace layout
58
36
 
59
- # edit task
60
- logbook edit-task --id <uuid> --title "New title"
37
+ `logbook init` creates the following structure through `workspace.init`:
61
38
 
62
- # initialize project
63
- logbook init
64
- logbook init --force # ensures both AGENTS.md and CLAUDE.md exist
65
39
  ```
66
-
67
- all commands output JSON to stdout for easy parsing:
68
-
69
- ```json
70
- {"ok": true, "task": {...}}
71
- {"ok": false, "error": {"code": -32001, "message": "Task not found", ...}}
40
+ .logbook/
41
+ ├── config.json # workspace config (Linear credentials, hook overrides)
42
+ ├── workspace.json # workspace metadata
43
+ ├── hooks/
44
+ │ ├── review-spawn/ # spawns a reviewer agent on pending_review
45
+ │ │ ├── config.json
46
+ │ │ └── script.mjs
47
+ │ └── need-info-notify/ # notifies user when a task needs info
48
+ │ ├── config.json
49
+ │ └── script.mjs
50
+ └── storage/
51
+ ├── epics.jsonl
52
+ ├── stories.jsonl
53
+ ├── tasks.jsonl
54
+ ├── context-entries.jsonl
55
+ ├── external-links.jsonl
56
+ ├── sync-events.jsonl
57
+ └── sync-conflicts.jsonl
72
58
  ```
73
59
 
74
- see `logbook --help` for full documentation.
75
-
76
- ## walkthrough
60
+ add `.logbook/storage/` to `.gitignore` to keep runtime data out of version control:
77
61
 
78
- a complete agent session from start to done:
79
-
80
- **1. agent starts — get current task**
81
-
82
- ```
83
- current_task()
84
- → { id: "abc-123", title: "implement login endpoint", status: "in_progress", ... }
62
+ ```gitignore
63
+ .logbook/storage/
85
64
  ```
86
65
 
87
- **2. agent needs clarification — blocks on a question**
66
+ ## mcp tools by plugin
88
67
 
89
- ```
90
- update_task("abc-123", "need_info", {
91
- title: "which auth provider?",
92
- content: "should i use jwt or session-based auth? the spec doesn't say.",
93
- kind: "need_info"
94
- })
95
- → hook fires: user is notified with the comment
96
- ```
68
+ connect `logbook mcp` as an MCP server and call any of the 38 tools below.
97
69
 
98
- **3. user replies — task unblocked**
70
+ ### task plugin
99
71
 
100
- ```
101
- update_task("abc-123", "in_progress", {
102
- id: "<comment-id>",
103
- reply: "use jwt, see the auth spec in docs/auth.md",
104
- title: "jwt confirmed",
105
- content: "jwt confirmed",
106
- kind: "need_info"
107
- })
108
- task returns to in_progress
109
- ```
72
+ | Tool ID | Purpose |
73
+ |---------|---------|
74
+ | `task.create` | Create a task in backlog |
75
+ | `task.get` | Load one task by id |
76
+ | `task.list` | List tasks (default status: `in_progress`) |
77
+ | `task.current` | Claim and return the highest-priority in-progress task for this session |
78
+ | `task.update` | Transition task status, add comments, reply to need_info |
79
+ | `task.edit` | Edit mutable fields without status change |
80
+ | `task.assign.session` | Assign a session to a task |
81
+ | `task.assign.model` | Assign a model to a task |
82
+ | `task.assign.phase-model` | Set a per-phase model override |
83
+ | `task.estimate` | Compute or re-compute a Fibonacci estimation |
110
84
 
111
- **4. agent finishes submits for review**
85
+ `task.current` priority chain: session-owned in_progress unassigned in_progress → orphaned in_progress (dead session) → highest-priority todo (auto-transitions) → `no_current_task` error.
112
86
 
113
- ```
114
- update_task("abc-123", "pending_review", {
115
- title: "implementation complete",
116
- content: "jwt login endpoint implemented, tests passing",
117
- kind: "regular"
118
- })
119
- → review-spawn hook fires: review task created, reviewer agent spawned
120
- ```
87
+ ### epic plugin
121
88
 
122
- **5. reviewer approves task closed**
89
+ | Tool ID | Purpose |
90
+ |---------|---------|
91
+ | `epic.create` | Create an epic |
92
+ | `epic.get` | Load one epic |
93
+ | `epic.list` | List epics |
94
+ | `epic.update` | Update an epic |
95
+ | `epic.delete` | Tombstone an epic |
123
96
 
124
- ```
125
- # reviewer agent calls:
126
- current_task() → gets the review task
127
- update_task("<review-task-id>", "done")
128
- → original task abc-123 → done automatically
129
- ```
97
+ ### story plugin
130
98
 
131
- ### how the agent knows logbook exists
99
+ | Tool ID | Purpose |
100
+ |---------|---------|
101
+ | `story.create` | Create a story within an epic |
102
+ | `story.get` | Load one story |
103
+ | `story.list` | List stories |
104
+ | `story.update` | Update a story |
105
+ | `story.delete` | Tombstone a story |
132
106
 
133
- add the logbook MCP server to your AI client config (see [configuration](#configuration)), then include these instructions in your agent's system prompt or `CLAUDE.md`:
107
+ ### context plugin
134
108
 
135
- ```
136
- You are connected to the logbook MCP server. Call current_task() immediately at session start.
137
- ```
109
+ | Tool ID | Purpose |
110
+ |---------|---------|
111
+ | `context.create` | Create a reusable context entry |
112
+ | `context.get` | Load one context entry |
113
+ | `context.list` | List context entries |
114
+ | `context.update` | Update a context entry |
115
+ | `context.delete` | Tombstone a context entry |
116
+ | `context.attach` | Attach a context entry to an epic, story, or task |
117
+ | `context.detach` | Remove an attachment |
118
+ | `context.search` | Full-text search over context entries |
138
119
 
139
- the full system prompt is injected automatically when the MCP server connects.
120
+ ### sync plugin (Linear)
140
121
 
141
- ## architecture
122
+ | Tool ID | Purpose |
123
+ |---------|---------|
124
+ | `sync.linear.pull` | Pull issues from Linear into logbook (since-cursor pagination) |
125
+ | `sync.linear.push` | Push logbook tasks to Linear |
126
+ | `sync.linear.setup` | Configure Linear sync from a team URL or explicit ids |
127
+ | `sync.linear.status` | Check Linear configuration and connectivity |
128
+ | `sync.conflicts.list` | List unresolved sync conflicts |
129
+ | `sync.conflicts.resolve` | Resolve a conflict (`use_local`, `use_remote`, or `manual`) |
142
130
 
143
- - **runtime**: Bun / TypeScript
144
- - **effect system**: Effect.ts — all async operations and errors are modeled as `Effect<A, E, R>`
145
- - **architecture**: hexagonal (ports & adapters), organized by vertical slices per domain concept (task, hook)
146
- - **validation**: Zod at every system boundary (MCP input, filesystem reads)
147
- - **persistence**: JSONL — one task per line, append-only writes, full file scan for reads
131
+ ### workspace plugin
148
132
 
149
- JSONL was chosen for simplicity and agent-friendliness: a single line = a single task makes partial reads and diffs readable without tooling.
133
+ | Tool ID | Purpose |
134
+ |---------|---------|
135
+ | `workspace.init` | Initialize or re-scaffold the `.logbook/` workspace |
136
+ | `workspace.status` | Report workspace health and provider status |
150
137
 
151
- ### hooks
138
+ ### hook plugin
152
139
 
153
- besides the tools that the agent call manually, each action performed in the kanban can have automatic _hooks_ executed right before or after.
154
- the default hooks include:
140
+ | Tool ID | Purpose |
141
+ |---------|---------|
142
+ | `hook.list` | List registered hooks |
143
+ | `hook.run` | Run a hook manually |
155
144
 
156
- - after moving a task to `need_info`, the user receives a notification with the comment left to be able to answer the question.
157
- - after moving a task to `pending_review`, a reviewer sub-agent spawns and a review task is automatically generated for it.
158
- - when a second task is moved to `in_progress`, a built-in hook fires and requires a comment justifying the overlap before proceeding.
145
+ ### plugin plugin
159
146
 
160
- but hooks can also be defined by the user as scripts in any language as long as it's installed in the system, under the "hooks/" directory, following this structure:
147
+ | Tool ID | Purpose |
148
+ |---------|---------|
149
+ | `plugin.list` | List all registered plugins and their tool IDs |
161
150
 
162
- ```
163
- hooks/
164
- └── example_hook/
165
- ├── config.yml
166
- └── script.ts
167
- ```
151
+ ## cli
168
152
 
169
- a minimal `config.yml` looks like:
153
+ every tool is available as `logbook <tool-id-with-colons>`:
170
154
 
171
- ```yaml
172
- # config.yml
173
- event: task.status_changed # lifecycle event that triggers the hook
174
- condition: "new_status == 'need_info'" # optional; JS-like expression
175
- timeout_ms: 5000 # optional; default 5000
155
+ ```bash
156
+ # preferred onboarding
157
+ logbook init
158
+ logbook init --mcp-client claude --no-linear
159
+ logbook init --mcp-client codex --no-linear
160
+
161
+ # workspace
162
+ logbook workspace:init
163
+ logbook workspace:status
164
+
165
+ # tasks
166
+ logbook task:create --title "x" --description "y" --definition-of-done "z" --project p --milestone m
167
+ logbook task:list --status "*"
168
+ logbook task:list --status in_progress
169
+ logbook task:current
170
+ logbook task:update --id <uuid> --new-status pending_review
171
+ logbook task:edit --id <uuid> --title "New title"
172
+
173
+ # epics and stories
174
+ logbook epic:create --title "Auth" --description "Login and session management" --outcome "Users can log in"
175
+ logbook story:create --epic-id <uuid> --title "JWT login" --description "..." --user-value "Users can authenticate"
176
+
177
+ # context
178
+ logbook context:create --title "Auth spec" --body "Use JWT RS256. See docs/auth.md."
179
+ logbook context:attach --context-entry-id <uuid> --task-id <uuid>
180
+
181
+ # Linear sync
182
+ logbook sync:linear:setup --team-url https://linear.app/<workspace>/team/<team>
183
+ logbook sync:linear:pull
184
+ logbook sync:linear:push --dry-run
185
+ logbook sync:linear:status
186
+
187
+ # v1 aliases (still work, emit a compatibility warning)
188
+ logbook create-task --title "..." --definition-of-done "..." --predicted-k-tokens 3
189
+ logbook list-tasks --status in_progress
176
190
  ```
177
191
 
178
- you can base your config.yml in the default hooks-which have complete configuration files.
179
-
180
- > note: as mentioned, you can change .ts for any language, but the .yml / .yaml is required for configuration.
192
+ all commands write a single-line JSON envelope to stdout:
181
193
 
182
- #### review flow
194
+ ```json
195
+ {"ok":true,"data":{"task":{...}}}
196
+ {"ok":false,"error":{"code":"not_found","message":"task abc was not found"}}
197
+ ```
183
198
 
184
- when a task is moved to `pending_review`, the built-in `review-spawn` hook automatically creates a review task and spawns a reviewer sub-agent. the reviewer classifies every finding before acting:
199
+ ## linear integration
185
200
 
186
- ```mermaid
187
- flowchart TD
188
- PR[task: pending_review]
189
- PR -->|review-spawn hook| SPAWN[review task created\nreviewer agent spawned]
190
- SPAWN --> CL{classify findings}
201
+ ### setup
191
202
 
192
- CL -->|nice-to-have findings| TD["[tech debt] tasks created\nin backlog silently"]
203
+ The preferred setup path is `logbook init`, which prompts for Linear sync setup.
204
+ To configure Linear separately:
193
205
 
194
- CL -->|must-fix found| MF[originalin_progress\nneed_info: must fix before re-submitting]
195
- CL -->|consider only| CO[original in_progress\nneed_info: implementer decides\nfix now or backlog]
196
- CL -->|clean| DONE[original → done]
206
+ 1. create a Linear API key at **Linear Settings API Personal API keys**
207
+ 2. add it to `.env` or export it in your shell:
208
+ ```bash
209
+ echo "LINEAR_API_KEY=lin_api_..." >> .env
210
+ ```
211
+ 3. configure Logbook from your Linear team URL:
212
+ ```bash
213
+ logbook sync:linear:setup --team-url https://linear.app/bosun/team/BOSUN
214
+ ```
197
215
 
198
- MF --> RD[review task done]
199
- CO --> RD
200
- DONE --> RD
216
+ The setup command resolves the workspace and team ids and writes the public config to `.logbook/config.json`.
217
+ It never writes the API key there. To let setup write `.env` for you, pass the token once:
201
218
 
202
- TD -.->|accompanies any outcome| RD
219
+ ```bash
220
+ logbook sync:linear:setup \
221
+ --team-url https://linear.app/bosun/team/BOSUN \
222
+ --api-token lin_api_... \
223
+ --write-env
203
224
  ```
204
225
 
205
- | finding severity | original task | review task | side effect |
206
- |-----------------|---------------|-------------|-------------|
207
- | **must-fix** | `→ in_progress` + `need_info` | `→ done` | — |
208
- | **consider** | `→ in_progress` + `need_info` | `→ done` | implementer replies: fix now or backlog |
209
- | **nice-to-have** | unchanged | — | `[tech debt]` backlog task created |
210
- | **clean** | `→ done` | `→ done` | — |
211
-
212
- nice-to-have findings are always handled silently — they never block progress or ping the implementer.
213
-
214
- #### why hooks?
226
+ Manual setup is also supported:
215
227
 
216
- hooks don't need to store information from one execution to the other, so the main principle here is: **"execute and forget"**, this way we can focus on the kanban and actual tasks.
217
-
218
- ## contracts
228
+ ```bash
229
+ logbook sync:linear:setup \
230
+ --workspace-id <workspace-id> \
231
+ --team-id <team-id>
232
+ ```
219
233
 
220
- the core types the server operates on:
234
+ This produces a `linear` block like:
221
235
 
222
- ```ts
223
- type Agent = {
224
- id: string, // session_id assigned by the server on connection
225
- title: string,
226
- description: string
227
- }
236
+ ```json
237
+ {
238
+ "linear": {
239
+ "apiTokenEnv": "LINEAR_API_KEY",
240
+ "workspaceId": "your-workspace-id",
241
+ "defaultTeamId": "your-team-id"
242
+ }
243
+ }
244
+ ```
228
245
 
229
- type Status = 'backlog' | 'todo' | 'need_info' | 'blocked' | 'in_progress' | 'pending_review' | 'done'
246
+ ### pull / push
230
247
 
231
- type Comment = {
232
- id: string,
233
- timestamp: Date,
234
- title: string,
235
- content: string,
236
- reply: string, // user's reply, populated when responding to a need_info comment
237
- kind: 'need_info' | 'regular' // drives the reply cycle — only need_info comments accept replies
238
- }
248
+ when Logbook runs through MCP, task-facing tools automatically pull before the call and push successful task writes back to Linear. the explicit commands below are still available for manual refreshes, dry runs, and targeted syncs.
239
249
 
240
- type Task = {
241
- project: string,
242
- milestone: string,
243
- id: string,
244
- title: string,
245
- definition_of_done: string,
246
- description: string,
247
- estimation: number, // fibonacci number derived from predictedKTokens at creation time
248
- comments: Comment[],
249
- assignee: Agent,
250
- status: Status,
251
- in_progress_since?: Date // set when task enters in_progress; used as tie-breaker in current_task
252
- priority: number // integer ≥ 0; higher = more urgent; defaults to 0
253
- }
250
+ ```bash
251
+ # pull issues from Linear since the last cursor
252
+ logbook sync:linear:pull
254
253
 
255
- // status defaults to 'in_progress'; results ordered by priority DESC
256
- // project and milestone are optional; all provided filters compose (AND semantics)
257
- type ListTasks = (options: { status: Status | '*', project?: string, milestone?: string }) => Task[]
258
-
259
- // returns the highest-priority task for the current session using a priority chain:
260
- // 1. own in_progress → 2. unassigned in_progress → 3. orphaned in_progress
261
- // (dead-session assignee) → 4. highest-priority todo (auto-transitioned) → 5. no_current_task error.
262
- // within each step, tasks are ordered by priority DESC, tie-broken by in_progress_since ASC.
263
- // if a second task is moved to in_progress, a built-in hook fires and
264
- // requires a comment justifying the overlap.
265
- type GetCurrentTask = () => Task
266
-
267
- // transitions a task to a new status; sessionId is injected server-side.
268
- // to reply to a need_info comment, pass a comment with the existing comment's id and a reply string.
269
- type UpdateTask = (id: string, new_status: Status, comment: CommentInput | null, sessionId: string) => void
270
-
271
- type CommentInput = {
272
- id?: string, // existing comment id — only when replying to a need_info comment
273
- title: string,
274
- content: string,
275
- reply?: string, // reply text — only meaningful when id refers to a need_info comment
276
- kind: 'need_info' | 'regular'
277
- }
254
+ # pull with options
255
+ logbook sync:linear:pull --dry-run --team-id <id>
278
256
 
279
- // creates a new task in backlog assigned to the calling session.
280
- // predictedKTokens is mapped to a Fibonacci estimation by the server.
281
- type CreateTask = (input: CreateTaskInput, sessionId: string) => Task
282
-
283
- type CreateTaskInput = {
284
- project: string,
285
- milestone: string,
286
- title: string,
287
- definition_of_done: string,
288
- description: string,
289
- predictedKTokens: number, // positive number; server maps this to a Fibonacci estimation (max 20)
290
- priority?: number // integer ≥ 0; defaults to 0
291
- }
257
+ # push logbook tasks to Linear
258
+ logbook sync:linear:push
292
259
 
293
- // edits mutable fields without changing status
294
- type EditTask = (id: string, updates: EditTaskInput) => Task
260
+ # push only specific tasks
261
+ logbook sync:linear:push --task-ids '["task_abc","task_xyz"]' --dry-run
295
262
 
296
- type EditTaskInput = {
297
- title?: string,
298
- description?: string,
299
- definition_of_done?: string,
300
- predictedKTokens?: number, // re-derives estimation if provided
301
- priority?: number // integer ≥ 0; re-assigns priority if provided
302
- }
263
+ # check status (connectivity + cursor position)
264
+ logbook sync:linear:status --check-provider
303
265
  ```
304
266
 
305
- each MCP session is treated as a distinct agent instance. the server assigns a `session_id` on connection and uses it to scope `GetCurrentTask` — no explicit agent ID needs to be passed by the caller.
267
+ ### conflicts
306
268
 
307
- ## install
269
+ when the same record is modified in both logbook and Linear, a conflict entry is written to `sync-conflicts.jsonl`:
308
270
 
309
271
  ```bash
310
- npm install -g @bosun-sh/logbook
272
+ logbook sync:conflicts:list
273
+ logbook sync:conflicts:resolve --id <conflict-uuid> --resolution use_local
274
+ # resolutions: use_local | use_remote | manual
311
275
  ```
312
276
 
313
- requires **bun 1.0.0** as the runtime ([install bun](https://bun.sh)).
277
+ conflict states: `open` `resolved` or `ignored`.
314
278
 
315
- verify the installation:
279
+ ### external links
316
280
 
317
- ```bash
318
- logbook --version
319
- # or
320
- logbook-mcp --version
321
- ```
281
+ bidirectional `linear:<id>` mappings are stored in `external-links.jsonl` and updated automatically by pull/push.
322
282
 
323
- for a full onboarding walkthrough see [quickstart.md](quickstart.md).
283
+ ## hooks
324
284
 
325
- ## configuration
285
+ hooks execute shell commands on task lifecycle events. configuration lives in `.logbook/hooks/<id>/config.json`:
326
286
 
327
- ### quick setup
287
+ ```json
288
+ {
289
+ "id": "need-info-notify",
290
+ "event": "task.status_changed",
291
+ "condition": { "status": "need_info" },
292
+ "command": ["node", ".logbook/hooks/need-info-notify/script.mjs"],
293
+ "timeoutMs": 5000
294
+ }
295
+ ```
328
296
 
329
- run `logbook init` in your project directory to scaffold:
330
- - `tasks.jsonl` — the task store
331
- - `hooks/` — directory for custom hooks
332
- - `AGENTS.md` and `CLAUDE.md` — documentation for AI agents
297
+ two hooks are materialized by `workspace.init`:
333
298
 
334
- by default:
335
- - if neither AGENTS.md nor CLAUDE.md exists creates AGENTS.md and symlinks CLAUDE.md to it
336
- - if only AGENTS.md exists → appends logbook docs to AGENTS.md
337
- - if only CLAUDE.md exists → appends logbook docs to CLAUDE.md
299
+ - **`need-info-notify`** — prints the blocking comment when a task moves to `need_info`
300
+ - **`review-spawn`** creates a review task and spawns a reviewer agent when a task moves to `pending_review`
338
301
 
339
- use `logbook init --force` to ensure both files exist (appends to existing, creates/symlinks missing).
302
+ hooks are stateless — execute and forget. the `command` field is an argv array; no shell expansion is performed.
340
303
 
341
- ### environment variables
304
+ ## environment variables
342
305
 
343
306
  | Variable | Default | Description |
344
307
  |----------|---------|-------------|
345
- | `LOGBOOK_TASKS_FILE` | `./tasks.jsonl` | path to the JSONL task store |
346
- | `LOGBOOK_HOOKS_DIR` | `./hooks` | directory scanned for custom hook definitions |
347
- | `LOGBOOK_LOG_LEVEL` | `warn` | structured logger level: `debug`, `info`, `warn`, or `error` |
308
+ | `LOGBOOK_WORKSPACE_ROOT` | `process.cwd()` | workspace root used by the compiled binaries |
309
+ | `LOGBOOK_LOG_LEVEL` | `warn` | log level: `debug`, `info`, `warn`, `error` |
310
+ | `LINEAR_API_KEY` | | Linear API token (or the env var named in `linear.apiTokenEnv`) |
348
311
 
349
- ### gitignore
312
+ ## optional duckdb index
350
313
 
351
- `tasks.jsonl`, `sessions.json`, and `.logbook-session` are runtime files generated by logbookthey should not be committed to version control:
314
+ logbook uses `@duckdb/node-api` to run ad-hoc SQL over the canonical JSONL files. the index is in-memory no separate index file is written or maintained:
352
315
 
353
- ```gitignore
354
- tasks.jsonl
355
- sessions.json
356
- .logbook-session
316
+ ```sql
317
+ -- example: find all in_progress tasks for a specific project
318
+ SELECT id, title, status FROM read_json_auto('.logbook/storage/tasks.jsonl', format='newline_delimited')
319
+ WHERE status = 'in_progress' AND project = 'myapp'
357
320
  ```
358
321
 
359
- > note: the logbook repo itself intentionally commits these files for dogfoodingthat is the exception, not the rule.
360
-
361
- ### client setup
362
-
363
- **Claude Code** — add to `.claude/settings.json`:
364
-
365
- ```json
366
- {
367
- "mcpServers": {
368
- "logbook": {
369
- "command": "logbook-mcp"
370
- }
371
- }
372
- }
373
- ```
374
-
375
- **OpenCode** — add to `opencode.json`:
376
-
377
- ```json
378
- {
379
- "mcp": {
380
- "logbook": {
381
- "type": "local",
382
- "command": ["logbook-mcp"],
383
- "enabled": true
384
- }
385
- }
386
- }
387
- ```
388
-
389
- ## security
390
-
391
- ### hook conditions are trusted code
322
+ the DuckDB path is opt-in via `workspace.status` and is non-canonicalthe JSONL files remain the source of truth.
392
323
 
393
- hook `config.yml` files support an optional `condition` field (e.g. `"new_status == 'pending_review'"`). these conditions are compiled and evaluated as live JavaScript at runtime — equivalent in trust level to a shell script.
324
+ ## migrating from v1
394
325
 
395
- **what this means for you:**
326
+ if your project has a `tasks.jsonl` at the repository root, `workspace.init` detects it and migrates all records to `.logbook/storage/tasks.jsonl` automatically:
396
327
 
397
- - **only add hooks from sources you trust.** a malicious `config.yml` condition can execute arbitrary code in the process that runs the MCP server.
398
- - **do not expose `LOGBOOK_HOOKS_DIR` to external write access.** if an untrusted process can write files under the hooks directory, it can inject conditions that execute as the MCP server's user.
399
- - the built-in hooks shipped with logbook are safe — they use simple equality checks (`new_status == 'need_info'`).
400
- - if a condition throws or is malformed, the hook is skipped silently and execution continues — it fails safe.
328
+ - field names renamed from `snake_case` to `camelCase`
329
+ - `kind: "task"` injected on every record
330
+ - v1 comment shape converted to v2 shape
401
331
 
402
- the security model here is the same as running a `Makefile` or a `.husky/` script: filesystem-level trust. as long as you control what goes into your hooks directory, you are safe.
332
+ v1 CLI commands (`create-task`, `list-tasks`, `current-task`, `update-task`, `edit-task`, `init`) remain registered and emit a `compatibility_mapping_applied` warning. remove the deprecated commands from your scripts when ready.
403
333
 
404
- ## stability
334
+ see `CHANGELOG.md` for the full v2.0.0 breaking-change list.
405
335
 
406
- logbook follows semantic versioning. here is what is stable at v1.0.0:
336
+ ## stack
407
337
 
408
- - **mcp api**: tool names and required parameters will not change within a major version. optional parameters may be added.
409
- - **jsonl format**: the serialized `Task` type in `tasks.jsonl` is stable. new optional fields may be added; existing fields will not be removed or renamed within a major version.
410
- - **hook config schema**: the `event`, `condition`, and `timeout_ms` keys in `config.yml` are stable. new optional keys may be added.
411
- - **breaking changes**: any breaking change will be preceded by a deprecation notice in the prior minor release and documented in `CHANGELOG.md`.
338
+ - **runtime**: Node.js / TypeScript
339
+ - **effect system**: Effect.ts all async operations and errors modeled as `Effect<A, E, R>`
340
+ - **architecture**: ohtools plugin registry, hexagonal adapters (CLI + MCP), vertical slices per entity
341
+ - **persistence**: JSONL append-only, one record per line, full-scan reads; DuckDB for optional ad-hoc queries
342
+ - **validation**: Zod at every public boundary (MCP input, CLI flags, filesystem reads)