@tekmidian/pai 0.14.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/dist/{auto-route-CLYcToZ5.mjs → auto-route-CdvjEWs5.mjs} +4 -4
  2. package/dist/{auto-route-CLYcToZ5.mjs.map → auto-route-CdvjEWs5.mjs.map} +1 -1
  3. package/dist/{kg-extraction-C8DEUHTS.mjs → checkpoint-block-Bl0HD3U2.mjs} +442 -13
  4. package/dist/checkpoint-block-Bl0HD3U2.mjs.map +1 -0
  5. package/dist/cli/index.mjs +14 -12
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/program.d.mts.map +1 -1
  8. package/dist/cli/program.mjs +31 -16
  9. package/dist/cli/program.mjs.map +1 -1
  10. package/dist/{clusters-BYPw7vfW.mjs → clusters-CKWDwcMX.mjs} +2 -2
  11. package/dist/{clusters-BYPw7vfW.mjs.map → clusters-CKWDwcMX.mjs.map} +1 -1
  12. package/dist/{config-C8m-tPhP.mjs → config-DGOfoGfm.mjs} +1 -1
  13. package/dist/config-DGOfoGfm.mjs.map +1 -0
  14. package/dist/daemon/index.mjs +18 -16
  15. package/dist/daemon/index.mjs.map +1 -1
  16. package/dist/{daemon-COSvHTNu.mjs → daemon-1rKbN-fd.mjs} +31 -30
  17. package/dist/{daemon-COSvHTNu.mjs.map → daemon-1rKbN-fd.mjs.map} +1 -1
  18. package/dist/daemon-mcp/index.mjs +24 -2
  19. package/dist/daemon-mcp/index.mjs.map +1 -1
  20. package/dist/db-BtuN768f.mjs +206 -0
  21. package/dist/db-BtuN768f.mjs.map +1 -0
  22. package/dist/{db-CmYbAVCD.mjs → db-CYmBWcjh.mjs} +1 -1
  23. package/dist/{db-CmYbAVCD.mjs.map → db-CYmBWcjh.mjs.map} +1 -1
  24. package/dist/{detect-KjycLtXM.mjs → detect-Bf2z-oKB.mjs} +1 -1
  25. package/dist/{detect-KjycLtXM.mjs.map → detect-Bf2z-oKB.mjs.map} +1 -1
  26. package/dist/{detector-ZiOhHszd.mjs → detector-rq9JGTmS.mjs} +2 -2
  27. package/dist/{detector-ZiOhHszd.mjs.map → detector-rq9JGTmS.mjs.map} +1 -1
  28. package/dist/{embeddings-BJPOcbik.mjs → embeddings-DGRAPAYb.mjs} +1 -1
  29. package/dist/{embeddings-BJPOcbik.mjs.map → embeddings-DGRAPAYb.mjs.map} +1 -1
  30. package/dist/{factory-Q88X1bAN.mjs → factory-HcQsQqh0.mjs} +8 -5
  31. package/dist/{factory-Q88X1bAN.mjs.map → factory-HcQsQqh0.mjs.map} +1 -1
  32. package/dist/{helpers-IjZkXBhj.mjs → helpers-crDEr6S2.mjs} +1 -1
  33. package/dist/{helpers-IjZkXBhj.mjs.map → helpers-crDEr6S2.mjs.map} +1 -1
  34. package/dist/hooks/capture-all-events.mjs.map +1 -1
  35. package/dist/hooks/capture-session-summary.mjs.map +1 -1
  36. package/dist/hooks/capture-tool-output.mjs.map +1 -1
  37. package/dist/hooks/cleanup-session-files.mjs.map +1 -1
  38. package/dist/hooks/context-compression-hook.mjs +304 -48
  39. package/dist/hooks/context-compression-hook.mjs.map +4 -4
  40. package/dist/hooks/initialize-session.mjs.map +1 -1
  41. package/dist/hooks/inject-observations.mjs.map +1 -1
  42. package/dist/hooks/load-core-context.mjs.map +1 -1
  43. package/dist/hooks/load-project-context.mjs.map +1 -1
  44. package/dist/hooks/observe.mjs.map +1 -1
  45. package/dist/hooks/post-compact-inject.mjs.map +1 -1
  46. package/dist/hooks/security-validator.mjs.map +1 -1
  47. package/dist/hooks/session-commands.mjs.map +1 -1
  48. package/dist/hooks/stop-hook.mjs +299 -43
  49. package/dist/hooks/stop-hook.mjs.map +4 -4
  50. package/dist/hooks/subagent-stop-hook.mjs.map +1 -1
  51. package/dist/hooks/sync-todo-to-md.mjs.map +1 -1
  52. package/dist/hooks/update-tab-on-action.mjs.map +1 -1
  53. package/dist/hooks/update-tab-titles.mjs.map +1 -1
  54. package/dist/hooks/whisper-rules.mjs.map +1 -1
  55. package/dist/index.d.mts +0 -9
  56. package/dist/index.d.mts.map +1 -1
  57. package/dist/index.mjs +10 -9
  58. package/dist/indexer-AEcT8wHf.mjs +1 -0
  59. package/dist/{indexer-backend-Cm5RS7y0.mjs → indexer-backend-BQZXoarl.mjs} +3 -3
  60. package/dist/{indexer-backend-Cm5RS7y0.mjs.map → indexer-backend-BQZXoarl.mjs.map} +1 -1
  61. package/dist/{ipc-client-CoyUHPod.mjs → ipc-client-vO2GV325.mjs} +1 -1
  62. package/dist/{ipc-client-CoyUHPod.mjs.map → ipc-client-vO2GV325.mjs.map} +1 -1
  63. package/dist/{kg-entity-LXblD7LZ.mjs → kg-entity-DbOMPdF9.mjs} +1 -1
  64. package/dist/{kg-entity-LXblD7LZ.mjs.map → kg-entity-DbOMPdF9.mjs.map} +1 -1
  65. package/dist/{latent-ideas-RyC6eyqI.mjs → latent-ideas-C6IFFT0-.mjs} +4 -4
  66. package/dist/{latent-ideas-RyC6eyqI.mjs.map → latent-ideas-C6IFFT0-.mjs.map} +1 -1
  67. package/dist/{main-resolver-uFxNiDy7.mjs → main-resolver-DimnS2qP.mjs} +22 -22
  68. package/dist/{main-resolver-uFxNiDy7.mjs.map → main-resolver-DimnS2qP.mjs.map} +1 -1
  69. package/dist/{migrate-B02wDDgS.mjs → migrate-fLD6rAdO.mjs} +2 -2
  70. package/dist/{migrate-B02wDDgS.mjs.map → migrate-fLD6rAdO.mjs.map} +1 -1
  71. package/dist/{neighborhood-CklGIB8r.mjs → neighborhood-CzRNG2Oy.mjs} +2 -2
  72. package/dist/{neighborhood-CklGIB8r.mjs.map → neighborhood-CzRNG2Oy.mjs.map} +1 -1
  73. package/dist/{note-context-qvZlVXVO.mjs → note-context-CrfMbr4R.mjs} +1 -1
  74. package/dist/{note-context-qvZlVXVO.mjs.map → note-context-CrfMbr4R.mjs.map} +1 -1
  75. package/dist/{pai-marker-HVBwwBW-.mjs → pai-marker-B20KqhA8.mjs} +44 -2
  76. package/dist/pai-marker-B20KqhA8.mjs.map +1 -0
  77. package/dist/{pick-gne3kOJG.mjs → pick-B3zEYjin.mjs} +2316 -483
  78. package/dist/pick-B3zEYjin.mjs.map +1 -0
  79. package/dist/{postgres-B451Hnkm.mjs → postgres-zjKqPl4X.mjs} +2 -2
  80. package/dist/{postgres-B451Hnkm.mjs.map → postgres-zjKqPl4X.mjs.map} +1 -1
  81. package/dist/{query-feedback-fapbqRgh.mjs → query-feedback-BoY8_Dbb.mjs} +1 -1
  82. package/dist/{query-feedback-fapbqRgh.mjs.map → query-feedback-BoY8_Dbb.mjs.map} +1 -1
  83. package/dist/{reranker-C08R99zn.mjs → reranker-CMNZcfVx.mjs} +1 -1
  84. package/dist/{reranker-C08R99zn.mjs.map → reranker-CMNZcfVx.mjs.map} +1 -1
  85. package/dist/{search-HcdKtMla.mjs → search-i2nlQ-JM.mjs} +3 -3
  86. package/dist/{search-HcdKtMla.mjs.map → search-i2nlQ-JM.mjs.map} +1 -1
  87. package/dist/skills/End/SKILL.md +78 -0
  88. package/dist/skills/Pause/SKILL.md +77 -0
  89. package/dist/skills/Tasks/SKILL.md +22 -0
  90. package/dist/{sqlite-DQpY1Esi.mjs → sqlite-ChSCYwiC.mjs} +3 -3
  91. package/dist/{sqlite-DQpY1Esi.mjs.map → sqlite-ChSCYwiC.mjs.map} +1 -1
  92. package/dist/{state-BIlxNRUn.mjs → state-BXIdbxDs.mjs} +1 -1
  93. package/dist/{state-BIlxNRUn.mjs.map → state-BXIdbxDs.mjs.map} +1 -1
  94. package/dist/{stop-words-BwplsQ3z.mjs → stop-words-BaMEGVeY.mjs} +1 -1
  95. package/dist/{stop-words-BwplsQ3z.mjs.map → stop-words-BaMEGVeY.mjs.map} +1 -1
  96. package/dist/{sync-uPR4g438.mjs → sync-CmBKOL3K.mjs} +6 -205
  97. package/dist/sync-CmBKOL3K.mjs.map +1 -0
  98. package/dist/{themes-Cg8oG9Ra.mjs → themes-nvRM8v84.mjs} +3 -3
  99. package/dist/{themes-Cg8oG9Ra.mjs.map → themes-nvRM8v84.mjs.map} +1 -1
  100. package/dist/{tools-Op3C2Nm6.mjs → tools-CznjzfYz.mjs} +26 -26
  101. package/dist/{tools-Op3C2Nm6.mjs.map → tools-CznjzfYz.mjs.map} +1 -1
  102. package/dist/{trace-CLK-NPkb.mjs → trace-B8oz1ok0.mjs} +1 -1
  103. package/dist/{trace-CLK-NPkb.mjs.map → trace-B8oz1ok0.mjs.map} +1 -1
  104. package/dist/{utils-CqqgB0dH.mjs → utils-BAxjW3j8.mjs} +1 -1
  105. package/dist/{utils-CqqgB0dH.mjs.map → utils-BAxjW3j8.mjs.map} +1 -1
  106. package/dist/{vault-indexer-Dn_BccVK.mjs → vault-indexer-DrttVeEk.mjs} +2 -2
  107. package/dist/{vault-indexer-Dn_BccVK.mjs.map → vault-indexer-DrttVeEk.mjs.map} +1 -1
  108. package/dist/{work-queue-worker-BwouhVkb.mjs → work-queue-worker-BPXLkEik.mjs} +47 -30
  109. package/dist/work-queue-worker-BPXLkEik.mjs.map +1 -0
  110. package/dist/{zettelkasten-NwBD1NsT.mjs → zettelkasten-CTlt1dGv.mjs} +4 -4
  111. package/dist/{zettelkasten-NwBD1NsT.mjs.map → zettelkasten-CTlt1dGv.mjs.map} +1 -1
  112. package/docs/commands/README.md +17 -0
  113. package/docs/commands/backup.md +1 -1
  114. package/docs/commands/clear-names.md +1 -1
  115. package/docs/commands/daemon.md +1 -1
  116. package/docs/commands/db.md +1 -1
  117. package/docs/commands/end.md +4 -1
  118. package/docs/commands/help.md +1 -1
  119. package/docs/commands/kg.md +1 -1
  120. package/docs/commands/mcp.md +1 -1
  121. package/docs/commands/memory.md +1 -1
  122. package/docs/commands/notify.md +1 -1
  123. package/docs/commands/observation.md +1 -1
  124. package/docs/commands/obsidian.md +1 -1
  125. package/docs/commands/pause.md +4 -1
  126. package/docs/commands/project.md +1 -1
  127. package/docs/commands/projects.md +1 -1
  128. package/docs/commands/registry.md +18 -1
  129. package/docs/commands/restore.md +1 -1
  130. package/docs/commands/session.md +271 -0
  131. package/docs/commands/sessions.md +1 -1
  132. package/docs/commands/setup.md +1 -1
  133. package/docs/commands/shell-init.md +1 -1
  134. package/docs/commands/skill.md +1 -1
  135. package/docs/commands/task.md +2 -1
  136. package/docs/commands/topic.md +1 -1
  137. package/docs/commands/update.md +1 -1
  138. package/docs/commands/zettel.md +1 -1
  139. package/package.json +1 -1
  140. package/scripts/build-hooks.mjs +32 -3
  141. package/src/hooks/ts/lib/project-utils/todo.test.ts +132 -0
  142. package/src/hooks/ts/lib/project-utils/todo.ts +60 -34
  143. package/dist/config-C8m-tPhP.mjs.map +0 -1
  144. package/dist/kg-extraction-C8DEUHTS.mjs.map +0 -1
  145. package/dist/pai-marker-HVBwwBW-.mjs.map +0 -1
  146. package/dist/pick-gne3kOJG.mjs.map +0 -1
  147. package/dist/sync-uPR4g438.mjs.map +0 -1
  148. package/dist/work-queue-worker-BwouhVkb.mjs.map +0 -1
@@ -24,12 +24,15 @@ pai pause [target] [options]
24
24
  | Option | Description | Default |
25
25
  |--------|-------------|---------|
26
26
  | `--dry-run` | Preview changes without writing them | |
27
+ | `--body-file <path>` | File holding the checkpoint markdown to persist ('-' reads stdin). Required unless --no-body. | |
28
+ | `--session-id <uuid>` | Claude Code session UUID — recorded as the `claude --resume` handle | |
29
+ | `--no-body` | Deliberately write a metadata-only checkpoint (no content) | |
27
30
  | `--exit` | (pause all only) Also send /exit to each session after pausing | |
28
31
  | `--wait <ms>` | (pause all only) Milliseconds to wait before /exit (default: 5000) | `5000` |
29
32
 
30
33
  ## See also
31
34
 
32
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
35
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
33
36
 
34
37
  Run `pai help <area>` to read any of these in the terminal.
35
38
 
@@ -340,7 +340,7 @@ Use --options to discover available keys and presets.
340
340
 
341
341
  ## See also
342
342
 
343
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
343
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
344
344
 
345
345
  Run `pai help <area>` to read any of these in the terminal.
346
346
 
@@ -359,7 +359,7 @@ pai projects health --fix
359
359
 
360
360
  ## See also
361
361
 
362
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
362
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
363
363
 
364
364
  Run `pai help <area>` to read any of these in the terminal.
365
365
 
@@ -18,6 +18,7 @@ pai registry <subcommand> [options]
18
18
  | [`pai registry migrate`](#pai-registry-migrate) | Import data from ~/.claude/session-registry.json |
19
19
  | [`pai registry stats`](#pai-registry-stats) | Show summary statistics for the registry |
20
20
  | [`pai registry rebuild`](#pai-registry-rebuild) | Erase all registry data and rebuild from the filesystem (destructive) |
21
+ | [`pai registry dedupe`](#pai-registry-dedupe) | Merge registry rows that describe the same project. |
21
22
  | [`pai registry lookup`](#pai-registry-lookup) | Find the project slug for a filesystem path (for use in scripts) |
22
23
 
23
24
  ### pai registry scan
@@ -49,6 +50,22 @@ Show summary statistics for the registry
49
50
  Erase all registry data and rebuild from the filesystem (destructive)
50
51
 
51
52
 
53
+ ### pai registry dedupe
54
+
55
+ Merge registry rows that describe the same project.
56
+
57
+ Two spellings of one directory (e.g. via a symlinked path prefix) register
58
+ as separate projects and split session history between them. Rows are grouped
59
+ by resolved path, so a merge only happens when the paths are provably identical.
60
+ Dry-run by default; --execute backs up the registry first and merges in one transaction.
61
+
62
+ **Options**
63
+
64
+ | Option | Description | Default |
65
+ |--------|-------------|---------|
66
+ | `--execute` | Actually perform the merge (default is dry-run) | |
67
+
68
+
52
69
  ### pai registry lookup
53
70
 
54
71
  Find the project slug for a filesystem path (for use in scripts)
@@ -62,7 +79,7 @@ Find the project slug for a filesystem path (for use in scripts)
62
79
 
63
80
  ## See also
64
81
 
65
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
82
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
66
83
 
67
84
  Run `pai help <area>` to read any of these in the terminal.
68
85
 
@@ -25,7 +25,7 @@ pai restore [backup-path] [options]
25
25
 
26
26
  ## See also
27
27
 
28
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
28
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
29
29
 
30
30
  Run `pai help <area>` to read any of these in the terminal.
31
31
 
@@ -0,0 +1,271 @@
1
+ <!-- GENERATED by scripts/build-docs.mjs from the live Commander tree (src/cli/program.ts). Do not edit by hand. -->
2
+
3
+ # pai session
4
+
5
+ > Session management: list, info, checkpoint, handover, cleanup, slug, tag, route.
6
+
7
+ Short forms: `pai pause`, `pai end`, `pai resume <name>`.
8
+
9
+ ## Synopsis
10
+
11
+ ```
12
+ pai session <subcommand> [options]
13
+ ```
14
+
15
+ ## Subcommands
16
+
17
+ | Command | Description |
18
+ |---------|-------------|
19
+ | [`pai session list`](#pai-session-list) | Resumable sessions catalog — named sessions with resume status. |
20
+ | [`pai session info <project-slug> <number>`](#pai-session-info-project-slug-number) | Show full details for a specific session |
21
+ | [`pai session rename <project-slug> <number> <new-slug>`](#pai-session-rename-project-slug-number-new-slug) | Rename a session note — updates file on disk, H1 title, and registry |
22
+ | [`pai session slug <project-slug> <number>`](#pai-session-slug-project-slug-number) | Generate a descriptive slug from the session JSONL transcript |
23
+ | [`pai session tag <project-slug> <number> [tags...]`](#pai-session-tag-project-slug-number-tags) | Set or show tags on a session. Tags can be space-separated or comma-separated. |
24
+ | [`pai session route <project-slug> <number> <target-project>`](#pai-session-route-project-slug-number-target-project) | Create a cross-reference link from a session to a target project |
25
+ | [`pai session handover [project-slug] [session-id]`](#pai-session-handover-project-slug-session-id) | Write a ## Continue section to the project's TODO.md. |
26
+ | [`pai session checkpoint <message>`](#pai-session-checkpoint-message) | Append a timestamped checkpoint to the active session note. |
27
+ | [`pai session active`](#pai-session-active) | Show currently active Claude Code sessions. |
28
+ | [`pai session recent`](#pai-session-recent) | [Deprecated] Use `pai session list` or `pai sessions` instead. |
29
+ | [`pai session goto <name-or-id>`](#pai-session-goto-name-or-id) | Go to a session: resume if a resumable snapshot exists, start fresh otherwise. |
30
+ | [`pai session pause`](#pai-session-pause) | Write a ## Continue checkpoint to the project's TODO.md. |
31
+ | [`pai session auto-route`](#pai-session-auto-route) | Auto-detect which project this session belongs to. |
32
+ | [`pai session cleanup [project-slug]`](#pai-session-cleanup-project-slug) | Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber |
33
+
34
+ ### pai session list
35
+
36
+ Resumable sessions catalog — named sessions with resume status.
37
+
38
+ Short form: pai sessions
39
+ Default shows all sessions you've named or that are resumable.
40
+ Use --all to also show unnamed orphan sessions.
41
+
42
+ **Options**
43
+
44
+ | Option | Description | Default |
45
+ |--------|-------------|---------|
46
+ | `-n <count>` | Maximum sessions to show (default: 20) | `20` |
47
+ | `--all` | Include unnamed orphan sessions (not in clc registry) | |
48
+ | `--json` | Output raw JSON instead of formatted table | |
49
+
50
+
51
+ ### pai session info <project-slug> <number>
52
+
53
+ Show full details for a specific session
54
+
55
+ **Arguments**
56
+
57
+ | Argument | Kind |
58
+ |----------|------|
59
+ | `<project-slug>` | required |
60
+ | `<number>` | required |
61
+
62
+
63
+ ### pai session rename <project-slug> <number> <new-slug>
64
+
65
+ Rename a session note — updates file on disk, H1 title, and registry
66
+
67
+ **Arguments**
68
+
69
+ | Argument | Kind |
70
+ |----------|------|
71
+ | `<project-slug>` | required |
72
+ | `<number>` | required |
73
+ | `<new-slug>` | required |
74
+
75
+
76
+ ### pai session slug <project-slug> <number>
77
+
78
+ Generate a descriptive slug from the session JSONL transcript
79
+
80
+ **Arguments**
81
+
82
+ | Argument | Kind |
83
+ |----------|------|
84
+ | `<project-slug>` | required |
85
+ | `<number>` | required |
86
+
87
+ **Options**
88
+
89
+ | Option | Description | Default |
90
+ |--------|-------------|---------|
91
+ | `--apply` | Rename the session note using the generated slug | |
92
+
93
+
94
+ ### pai session tag <project-slug> <number> [tags...]
95
+
96
+ Set or show tags on a session. Tags can be space-separated or comma-separated.
97
+
98
+ **Arguments**
99
+
100
+ | Argument | Kind |
101
+ |----------|------|
102
+ | `<project-slug>` | required |
103
+ | `<number>` | required |
104
+ | `[tags...]` | variadic |
105
+
106
+
107
+ ### pai session route <project-slug> <number> <target-project>
108
+
109
+ Create a cross-reference link from a session to a target project
110
+
111
+ **Arguments**
112
+
113
+ | Argument | Kind |
114
+ |----------|------|
115
+ | `<project-slug>` | required |
116
+ | `<number>` | required |
117
+ | `<target-project>` | required |
118
+
119
+ **Options**
120
+
121
+ | Option | Description | Default |
122
+ |--------|-------------|---------|
123
+ | `--type <type>` | Link type: related \| follow-up \| reference | `related` |
124
+
125
+
126
+ ### pai session handover [project-slug] [session-id]
127
+
128
+ Write a ## Continue section to the project's TODO.md.
129
+
130
+ Called automatically from session-stop and pre-compact hooks.
131
+ Records the last session identifier, timestamp, and working directory
132
+ so the next session can resume from the correct context.
133
+
134
+ **Arguments**
135
+
136
+ | Argument | Kind |
137
+ |----------|------|
138
+ | `[project-slug]` | optional |
139
+ | `[session-id]` | optional |
140
+
141
+
142
+ ### pai session checkpoint <message>
143
+
144
+ Append a timestamped checkpoint to the active session note.
145
+
146
+ Designed for hooks (PostToolUse, UserPromptSubmit) — fast and silent.
147
+ Rate-limited: skips silently if last checkpoint was < --min-gap seconds ago.
148
+
149
+ **Arguments**
150
+
151
+ | Argument | Kind |
152
+ |----------|------|
153
+ | `<message>` | required |
154
+
155
+ **Options**
156
+
157
+ | Option | Description | Default |
158
+ |--------|-------------|---------|
159
+ | `--min-gap <seconds>` | Minimum seconds between checkpoints (default: 300 = 5 minutes) | `300` |
160
+
161
+
162
+ ### pai session active
163
+
164
+ Show currently active Claude Code sessions.
165
+
166
+ Detects live sessions by checking which JSONL transcript files
167
+ were recently modified in ~/.claude/projects/.
168
+
169
+ **Options**
170
+
171
+ | Option | Description | Default |
172
+ |--------|-------------|---------|
173
+ | `--minutes <n>` | Consider sessions active if modified within N minutes (default: 60) | `60` |
174
+ | `--json` | Output raw JSON instead of formatted display | |
175
+
176
+
177
+ ### pai session recent
178
+
179
+ [Deprecated] Use `pai session list` or `pai sessions` instead.
180
+
181
+ **Options**
182
+
183
+ | Option | Description | Default |
184
+ |--------|-------------|---------|
185
+ | `-n <count>` | Maximum sessions to show (default: 20) | `20` |
186
+ | `--all` | Include unnamed orphan sessions (not in clc registry) | |
187
+ | `--json` | Output raw JSON instead of formatted table | |
188
+
189
+
190
+ ### pai session goto <name-or-id>
191
+
192
+ Go to a session: resume if a resumable snapshot exists, start fresh otherwise.
193
+
194
+ Recommended short form: pai resume <name>
195
+ Resolves by clc/registry name (case-insensitive) or UUID prefix.
196
+ Sends '/Name <name>\ngo' as the initial prompt so the PAI ## Continue hook fires.
197
+
198
+ **Arguments**
199
+
200
+ | Argument | Kind |
201
+ |----------|------|
202
+ | `<name-or-id>` | required |
203
+
204
+ **Options**
205
+
206
+ | Option | Description | Default |
207
+ |--------|-------------|---------|
208
+ | `--skip-name` | Do not prepend /Name to set the session name in chrome | |
209
+ | `--skip-go` | Do not append \ngo to trigger PAI auto-resume (## Continue) | |
210
+ | `--dry-run` | Print the exact argv and cwd, then exit without launching | |
211
+
212
+
213
+ ### pai session pause
214
+
215
+ Write a ## Continue checkpoint to the project's TODO.md.
216
+
217
+ Recommended short form: pai pause
218
+ Ctrl+C bypasses the stop-hook, orphaning the session (cannot --resume).
219
+ Use /exit inside Claude Code to preserve full session resumability.
220
+
221
+ **Options**
222
+
223
+ | Option | Description | Default |
224
+ |--------|-------------|---------|
225
+ | `--dry-run` | Preview the ## Continue block without writing it | |
226
+ | `--body-file <path>` | File holding the checkpoint markdown to persist ('-' reads stdin). Required unless --no-body. | |
227
+ | `--session-id <uuid>` | Claude Code session UUID — recorded as the `claude --resume` handle | |
228
+ | `--no-body` | Deliberately write a metadata-only checkpoint (no content) | |
229
+
230
+
231
+ ### pai session auto-route
232
+
233
+ Auto-detect which project this session belongs to.
234
+
235
+ Tries: (1) path match in registry, (2) Notes/PAI.md marker walk, (3) topic detection.
236
+ Designed for use in CLAUDE.md session-start hooks.
237
+
238
+ **Options**
239
+
240
+ | Option | Description | Default |
241
+ |--------|-------------|---------|
242
+ | `--cwd <path>` | Working directory to detect from (default: process.cwd()) | |
243
+ | `--context <text>` | Conversation context for topic-based fallback routing | |
244
+ | `--json` | Output raw JSON instead of formatted display | |
245
+
246
+
247
+ ### pai session cleanup [project-slug]
248
+
249
+ Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber
250
+
251
+ **Arguments**
252
+
253
+ | Argument | Kind |
254
+ |----------|------|
255
+ | `[project-slug]` | optional |
256
+
257
+ **Options**
258
+
259
+ | Option | Description | Default |
260
+ |--------|-------------|---------|
261
+ | `--execute` | Actually perform the cleanup (default is dry-run) | |
262
+ | `--no-renumber` | Skip renumbering sessions after deletions | |
263
+ | `--no-reindex` | Skip triggering memory re-index after moves | |
264
+
265
+
266
+ ## See also
267
+
268
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
269
+
270
+ Run `pai help <area>` to read any of these in the terminal.
271
+
@@ -19,7 +19,7 @@ pai sessions [options]
19
19
 
20
20
  ## See also
21
21
 
22
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
22
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
23
23
 
24
24
  Run `pai help <area>` to read any of these in the terminal.
25
25
 
@@ -14,7 +14,7 @@ pai setup
14
14
 
15
15
  ## See also
16
16
 
17
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
17
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
18
18
 
19
19
  Run `pai help <area>` to read any of these in the terminal.
20
20
 
@@ -12,7 +12,7 @@ pai shell-init
12
12
 
13
13
  ## See also
14
14
 
15
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
15
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
16
16
 
17
17
  Run `pai help <area>` to read any of these in the terminal.
18
18
 
@@ -48,7 +48,7 @@ See `Notes/swarm/skills-self-educating.md` for the full self-educating loop
48
48
 
49
49
  ## See also
50
50
 
51
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
51
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
52
52
 
53
53
  Run `pai help <area>` to read any of these in the terminal.
54
54
 
@@ -58,6 +58,7 @@ File a task onto the bus
58
58
  | `--due <date>` | Due date (ISO or natural language) | |
59
59
  | `--priority <p>` | p1 (highest) … p4 (default) | |
60
60
  | `--url <url>` | Reference — prefer a hook:// URL over a file path | |
61
+ | `--into <sub-project>` | File into this sub-project under the bus root, creating it if absent | |
61
62
 
62
63
 
63
64
  ### pai task dispatch
@@ -141,7 +142,7 @@ Mark a task complete on the tracker
141
142
 
142
143
  ## See also
143
144
 
144
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
145
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai topic`](topic.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
145
146
 
146
147
  Run `pai help <area>` to read any of these in the terminal.
147
148
 
@@ -40,7 +40,7 @@ Exit code 1 if a shift is detected (useful for hooks).
40
40
 
41
41
  ## See also
42
42
 
43
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
43
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai update`](update.md) · [`pai zettel`](zettel.md)
44
44
 
45
45
  Run `pai help <area>` to read any of these in the terminal.
46
46
 
@@ -12,7 +12,7 @@ pai update
12
12
 
13
13
  ## See also
14
14
 
15
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai zettel`](zettel.md)
15
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai zettel`](zettel.md)
16
16
 
17
17
  Run `pai help <area>` to read any of these in the terminal.
18
18
 
@@ -145,7 +145,7 @@ pai zettel health
145
145
 
146
146
  ## See also
147
147
 
148
- [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md)
148
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai session`](session.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai task`](task.md) · [`pai topic`](topic.md) · [`pai update`](update.md)
149
149
 
150
150
  Run `pai help <area>` to read any of these in the terminal.
151
151
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekmidian/pai",
3
- "version": "0.14.2",
3
+ "version": "0.16.0",
4
4
  "description": "PAI Knowledge OS — Personal AI Infrastructure with federated memory and project management",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -24,6 +24,8 @@ import {
24
24
  copyFileSync,
25
25
  readFileSync,
26
26
  writeFileSync,
27
+ renameSync,
28
+ rmSync,
27
29
  } from "fs";
28
30
  import { join, resolve, basename } from "path";
29
31
  import { homedir, platform } from "os";
@@ -51,8 +53,24 @@ const entryPoints = collectEntryPoints(HOOKS_SRC);
51
53
 
52
54
  console.log(`Building ${entryPoints.length} hooks with esbuild...`);
53
55
 
56
+ // Build into a staging directory, then rename each artefact into place.
57
+ //
58
+ // ~/.claude/Hooks/*.mjs are symlinks to these files, and every LIVE Claude Code
59
+ // session executes them on each tool call. esbuild truncates-then-writes, so
60
+ // building straight to the output path leaves a window in which the file does
61
+ // not exist — any hook firing during a build in another session dies with
62
+ // "No such file or directory". That is not hypothetical: a rebuild here breaks
63
+ // hooks in every other session that happens to fire during it.
64
+ //
65
+ // rename(2) within one filesystem is atomic, so a concurrent session sees
66
+ // either the previous build or the new one, never a partial or absent file.
67
+ const STAGING = join(HOOKS_OUT, ".staging");
68
+ rmSync(STAGING, { recursive: true, force: true });
69
+ mkdirSync(STAGING, { recursive: true });
70
+
54
71
  for (const entry of entryPoints) {
55
- const outfile = join(HOOKS_OUT, basename(entry).replace(/\.ts$/, ".mjs"));
72
+ const name = basename(entry).replace(/\.ts$/, ".mjs");
73
+ const staged = join(STAGING, name);
56
74
 
57
75
  buildSync({
58
76
  entryPoints: [entry],
@@ -60,13 +78,24 @@ for (const entry of entryPoints) {
60
78
  platform: "node",
61
79
  target: "node20",
62
80
  format: "esm",
63
- outfile,
81
+ outfile: staged,
64
82
  sourcemap: true,
65
83
  });
66
84
 
67
- chmodSync(outfile, 0o755);
85
+ chmodSync(staged, 0o755);
86
+
87
+ // The sourceMappingURL comment is a bare filename, so the map must land in
88
+ // the same directory as the module. Move it first: a stale map for a moment
89
+ // is harmless, a missing module is not.
90
+ const stagedMap = `${staged}.map`;
91
+ if (existsSync(stagedMap)) {
92
+ renameSync(stagedMap, join(HOOKS_OUT, `${name}.map`));
93
+ }
94
+ renameSync(staged, join(HOOKS_OUT, name));
68
95
  }
69
96
 
97
+ rmSync(STAGING, { recursive: true, force: true });
98
+
70
99
  console.log(`✔ ${entryPoints.length} hooks built to ${HOOKS_OUT}/`);
71
100
 
72
101
  // ---------------------------------------------------------------------------