@tekmidian/pai 0.15.0 → 0.17.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.
- package/README.md +11 -3
- package/dist/{auto-route-CLYcToZ5.mjs → auto-route-CdvjEWs5.mjs} +4 -4
- package/dist/{auto-route-CLYcToZ5.mjs.map → auto-route-CdvjEWs5.mjs.map} +1 -1
- package/dist/auto-route-DkIRampF.mjs +86 -0
- package/dist/auto-route-DkIRampF.mjs.map +1 -0
- package/dist/{kg-extraction-C8DEUHTS.mjs → checkpoint-block-Bl0HD3U2.mjs} +442 -13
- package/dist/checkpoint-block-Bl0HD3U2.mjs.map +1 -0
- package/dist/checkpoint-block-C05sK_HK.mjs +1056 -0
- package/dist/checkpoint-block-C05sK_HK.mjs.map +1 -0
- package/dist/checkpoint-block-CUCG10Uh.mjs +1022 -0
- package/dist/checkpoint-block-CUCG10Uh.mjs.map +1 -0
- package/dist/checkpoint-block-D5IyLLTr.mjs +1062 -0
- package/dist/checkpoint-block-D5IyLLTr.mjs.map +1 -0
- package/dist/cli/index.mjs +14 -12
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.d.mts.map +1 -1
- package/dist/cli/program.mjs +31 -16
- package/dist/cli/program.mjs.map +1 -1
- package/dist/{clusters-BYPw7vfW.mjs → clusters-CKWDwcMX.mjs} +2 -2
- package/dist/{clusters-BYPw7vfW.mjs.map → clusters-CKWDwcMX.mjs.map} +1 -1
- package/dist/{config-C8m-tPhP.mjs → config-DGOfoGfm.mjs} +1 -1
- package/dist/{config-C8m-tPhP.mjs.map → config-DGOfoGfm.mjs.map} +1 -1
- package/dist/daemon/index.mjs +18 -16
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{daemon-COSvHTNu.mjs → daemon-1rKbN-fd.mjs} +31 -30
- package/dist/{daemon-COSvHTNu.mjs.map → daemon-1rKbN-fd.mjs.map} +1 -1
- package/dist/daemon-9AL6Pwh-.mjs +1581 -0
- package/dist/daemon-9AL6Pwh-.mjs.map +1 -0
- package/dist/daemon-Bbk-_rV6.mjs +1581 -0
- package/dist/daemon-Bbk-_rV6.mjs.map +1 -0
- package/dist/daemon-BvcaMk4g.mjs +1581 -0
- package/dist/daemon-BvcaMk4g.mjs.map +1 -0
- package/dist/daemon-CTDEfwcq.mjs +1576 -0
- package/dist/daemon-CTDEfwcq.mjs.map +1 -0
- package/dist/daemon-ClbfaF60.mjs +1576 -0
- package/dist/daemon-ClbfaF60.mjs.map +1 -0
- package/dist/daemon-DDQNDgYF.mjs +1576 -0
- package/dist/daemon-DDQNDgYF.mjs.map +1 -0
- package/dist/daemon-DU8yDWlQ.mjs +1576 -0
- package/dist/daemon-DU8yDWlQ.mjs.map +1 -0
- package/dist/daemon-NJr4iSW3.mjs +1576 -0
- package/dist/daemon-NJr4iSW3.mjs.map +1 -0
- package/dist/daemon-mcp/index.mjs +2 -2
- package/dist/db-BtuN768f.mjs +206 -0
- package/dist/db-BtuN768f.mjs.map +1 -0
- package/dist/{db-CmYbAVCD.mjs → db-CYmBWcjh.mjs} +1 -1
- package/dist/{db-CmYbAVCD.mjs.map → db-CYmBWcjh.mjs.map} +1 -1
- package/dist/{detect-KjycLtXM.mjs → detect-Bf2z-oKB.mjs} +1 -1
- package/dist/{detect-KjycLtXM.mjs.map → detect-Bf2z-oKB.mjs.map} +1 -1
- package/dist/{detector-ZiOhHszd.mjs → detector-Bwzm3E_x.mjs} +2 -2
- package/dist/{detector-ZiOhHszd.mjs.map → detector-Bwzm3E_x.mjs.map} +1 -1
- package/dist/detector-rq9JGTmS.mjs +74 -0
- package/dist/detector-rq9JGTmS.mjs.map +1 -0
- package/dist/embeddings-Bn86ssxR.mjs +119 -0
- package/dist/embeddings-Bn86ssxR.mjs.map +1 -0
- package/dist/{embeddings-BJPOcbik.mjs → embeddings-DGRAPAYb.mjs} +1 -1
- package/dist/{embeddings-BJPOcbik.mjs.map → embeddings-DGRAPAYb.mjs.map} +1 -1
- package/dist/{factory-Q88X1bAN.mjs → factory-0-57Ac-7.mjs} +8 -5
- package/dist/{factory-Q88X1bAN.mjs.map → factory-0-57Ac-7.mjs.map} +1 -1
- package/dist/factory-HcQsQqh0.mjs +72 -0
- package/dist/factory-HcQsQqh0.mjs.map +1 -0
- package/dist/factory-PDXQdkLO.mjs +72 -0
- package/dist/factory-PDXQdkLO.mjs.map +1 -0
- package/dist/{helpers-IjZkXBhj.mjs → helpers-crDEr6S2.mjs} +1 -1
- package/dist/{helpers-IjZkXBhj.mjs.map → helpers-crDEr6S2.mjs.map} +1 -1
- package/dist/hooks/capture-all-events.mjs.map +1 -1
- package/dist/hooks/capture-session-summary.mjs.map +1 -1
- package/dist/hooks/capture-tool-output.mjs.map +1 -1
- package/dist/hooks/cleanup-session-files.mjs.map +1 -1
- package/dist/hooks/context-compression-hook.mjs +336 -48
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/initialize-session.mjs.map +1 -1
- package/dist/hooks/inject-observations.mjs.map +1 -1
- package/dist/hooks/load-core-context.mjs.map +1 -1
- package/dist/hooks/load-project-context.mjs +188 -6
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/observe.mjs.map +1 -1
- package/dist/hooks/post-compact-inject.mjs.map +1 -1
- package/dist/hooks/security-validator.mjs.map +1 -1
- package/dist/hooks/session-commands.mjs.map +1 -1
- package/dist/hooks/stop-hook.mjs +331 -43
- package/dist/hooks/stop-hook.mjs.map +4 -4
- package/dist/hooks/subagent-stop-hook.mjs.map +1 -1
- package/dist/hooks/sync-todo-to-md.mjs.map +1 -1
- package/dist/hooks/update-tab-on-action.mjs.map +1 -1
- package/dist/hooks/update-tab-titles.mjs.map +1 -1
- package/dist/hooks/whisper-rules.mjs.map +1 -1
- package/dist/index.d.mts +0 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +10 -9
- package/dist/indexer-AEcT8wHf.mjs +1 -0
- package/dist/{indexer-backend-Cm5RS7y0.mjs → indexer-backend-BQZXoarl.mjs} +3 -3
- package/dist/{indexer-backend-Cm5RS7y0.mjs.map → indexer-backend-BQZXoarl.mjs.map} +1 -1
- package/dist/indexer-backend-BmaS2VcD.mjs +299 -0
- package/dist/indexer-backend-BmaS2VcD.mjs.map +1 -0
- package/dist/indexer-backend-COrJ5rjS.mjs +299 -0
- package/dist/indexer-backend-COrJ5rjS.mjs.map +1 -0
- package/dist/indexer-backend-NwD7TBGh.mjs +301 -0
- package/dist/indexer-backend-NwD7TBGh.mjs.map +1 -0
- package/dist/{ipc-client-CoyUHPod.mjs → ipc-client-vO2GV325.mjs} +1 -1
- package/dist/{ipc-client-CoyUHPod.mjs.map → ipc-client-vO2GV325.mjs.map} +1 -1
- package/dist/{kg-entity-LXblD7LZ.mjs → kg-entity-DbOMPdF9.mjs} +1 -1
- package/dist/{kg-entity-LXblD7LZ.mjs.map → kg-entity-DbOMPdF9.mjs.map} +1 -1
- package/dist/{latent-ideas-RyC6eyqI.mjs → latent-ideas-BwM3WdBp.mjs} +4 -4
- package/dist/{latent-ideas-RyC6eyqI.mjs.map → latent-ideas-BwM3WdBp.mjs.map} +1 -1
- package/dist/latent-ideas-C6IFFT0-.mjs +191 -0
- package/dist/latent-ideas-C6IFFT0-.mjs.map +1 -0
- package/dist/{main-resolver-uFxNiDy7.mjs → main-resolver-DimnS2qP.mjs} +22 -22
- package/dist/{main-resolver-uFxNiDy7.mjs.map → main-resolver-DimnS2qP.mjs.map} +1 -1
- package/dist/{migrate-B02wDDgS.mjs → migrate-fLD6rAdO.mjs} +2 -2
- package/dist/{migrate-B02wDDgS.mjs.map → migrate-fLD6rAdO.mjs.map} +1 -1
- package/dist/{neighborhood-CklGIB8r.mjs → neighborhood-CzRNG2Oy.mjs} +2 -2
- package/dist/{neighborhood-CklGIB8r.mjs.map → neighborhood-CzRNG2Oy.mjs.map} +1 -1
- package/dist/neighborhood-DZY0wkpE.mjs +135 -0
- package/dist/neighborhood-DZY0wkpE.mjs.map +1 -0
- package/dist/{note-context-qvZlVXVO.mjs → note-context-CrfMbr4R.mjs} +1 -1
- package/dist/{note-context-qvZlVXVO.mjs.map → note-context-CrfMbr4R.mjs.map} +1 -1
- package/dist/{pai-marker-HVBwwBW-.mjs → pai-marker-B20KqhA8.mjs} +44 -2
- package/dist/pai-marker-B20KqhA8.mjs.map +1 -0
- package/dist/pick-B0q5cy79.mjs +11785 -0
- package/dist/pick-B0q5cy79.mjs.map +1 -0
- package/dist/{pick-r95zvydr.mjs → pick-B3zEYjin.mjs} +2288 -497
- package/dist/pick-B3zEYjin.mjs.map +1 -0
- package/dist/pick-BHE9_iA0.mjs +11947 -0
- package/dist/pick-BHE9_iA0.mjs.map +1 -0
- package/dist/pick-BaTjoNqM.mjs +11544 -0
- package/dist/pick-BaTjoNqM.mjs.map +1 -0
- package/dist/pick-C6JbZfN4.mjs +11893 -0
- package/dist/pick-C6JbZfN4.mjs.map +1 -0
- package/dist/pick-CK-bJyjp.mjs +11883 -0
- package/dist/pick-CK-bJyjp.mjs.map +1 -0
- package/dist/pick-CLBkGHyI.mjs +11826 -0
- package/dist/pick-CLBkGHyI.mjs.map +1 -0
- package/dist/pick-CTOif21h.mjs +11544 -0
- package/dist/pick-CTOif21h.mjs.map +1 -0
- package/dist/pick-Ck2cdQgD.mjs +11893 -0
- package/dist/pick-Ck2cdQgD.mjs.map +1 -0
- package/dist/pick-Cr4nJzHA.mjs +11914 -0
- package/dist/pick-Cr4nJzHA.mjs.map +1 -0
- package/dist/pick-D4dFfKAu.mjs +11893 -0
- package/dist/pick-D4dFfKAu.mjs.map +1 -0
- package/dist/pick-D7-lYiGX.mjs +11543 -0
- package/dist/pick-D7-lYiGX.mjs.map +1 -0
- package/dist/pick-DMjCY0np.mjs +11875 -0
- package/dist/pick-DMjCY0np.mjs.map +1 -0
- package/dist/pick-DbX4OrCP.mjs +11543 -0
- package/dist/pick-DbX4OrCP.mjs.map +1 -0
- package/dist/pick-iCiPjlnC.mjs +11893 -0
- package/dist/pick-iCiPjlnC.mjs.map +1 -0
- package/dist/pick-sF9GnQUS.mjs +11893 -0
- package/dist/pick-sF9GnQUS.mjs.map +1 -0
- package/dist/pick-yHKUrnfG.mjs +11793 -0
- package/dist/pick-yHKUrnfG.mjs.map +1 -0
- package/dist/postgres-BJxiqtqg.mjs +891 -0
- package/dist/postgres-BJxiqtqg.mjs.map +1 -0
- package/dist/{postgres-B451Hnkm.mjs → postgres-zjKqPl4X.mjs} +2 -2
- package/dist/{postgres-B451Hnkm.mjs.map → postgres-zjKqPl4X.mjs.map} +1 -1
- package/dist/{query-feedback-fapbqRgh.mjs → query-feedback-BoY8_Dbb.mjs} +1 -1
- package/dist/{query-feedback-fapbqRgh.mjs.map → query-feedback-BoY8_Dbb.mjs.map} +1 -1
- package/dist/{reranker-C08R99zn.mjs → reranker-CMNZcfVx.mjs} +1 -1
- package/dist/{reranker-C08R99zn.mjs.map → reranker-CMNZcfVx.mjs.map} +1 -1
- package/dist/{search-HcdKtMla.mjs → search-CpTv1I24.mjs} +3 -3
- package/dist/{search-HcdKtMla.mjs.map → search-CpTv1I24.mjs.map} +1 -1
- package/dist/search-i2nlQ-JM.mjs +298 -0
- package/dist/search-i2nlQ-JM.mjs.map +1 -0
- package/dist/skills/End/SKILL.md +78 -0
- package/dist/skills/Pause/SKILL.md +84 -0
- package/dist/sqlite-CZ0LFili.mjs +271 -0
- package/dist/sqlite-CZ0LFili.mjs.map +1 -0
- package/dist/{sqlite-DQpY1Esi.mjs → sqlite-ChSCYwiC.mjs} +3 -3
- package/dist/{sqlite-DQpY1Esi.mjs.map → sqlite-ChSCYwiC.mjs.map} +1 -1
- package/dist/sqlite-Nw8ZW5Rj.mjs +271 -0
- package/dist/sqlite-Nw8ZW5Rj.mjs.map +1 -0
- package/dist/{state-BIlxNRUn.mjs → state-BXIdbxDs.mjs} +1 -1
- package/dist/{state-BIlxNRUn.mjs.map → state-BXIdbxDs.mjs.map} +1 -1
- package/dist/{stop-words-BwplsQ3z.mjs → stop-words-BaMEGVeY.mjs} +1 -1
- package/dist/{stop-words-BwplsQ3z.mjs.map → stop-words-BaMEGVeY.mjs.map} +1 -1
- package/dist/{sync-uPR4g438.mjs → sync--BoxBBok.mjs} +6 -205
- package/dist/sync--BoxBBok.mjs.map +1 -0
- package/dist/sync-CmBKOL3K.mjs +310 -0
- package/dist/sync-CmBKOL3K.mjs.map +1 -0
- package/dist/{themes-Cg8oG9Ra.mjs → themes-BBOlGXAg.mjs} +3 -3
- package/dist/{themes-Cg8oG9Ra.mjs.map → themes-BBOlGXAg.mjs.map} +1 -1
- package/dist/themes-nvRM8v84.mjs +148 -0
- package/dist/themes-nvRM8v84.mjs.map +1 -0
- package/dist/tools-B6BmaAvz.mjs +1939 -0
- package/dist/tools-B6BmaAvz.mjs.map +1 -0
- package/dist/tools-CAIY8TAb.mjs +1939 -0
- package/dist/tools-CAIY8TAb.mjs.map +1 -0
- package/dist/{tools-Op3C2Nm6.mjs → tools-CznjzfYz.mjs} +26 -26
- package/dist/{tools-Op3C2Nm6.mjs.map → tools-CznjzfYz.mjs.map} +1 -1
- package/dist/{trace-CLK-NPkb.mjs → trace-B8oz1ok0.mjs} +1 -1
- package/dist/{trace-CLK-NPkb.mjs.map → trace-B8oz1ok0.mjs.map} +1 -1
- package/dist/{utils-CqqgB0dH.mjs → utils-BAxjW3j8.mjs} +1 -1
- package/dist/{utils-CqqgB0dH.mjs.map → utils-BAxjW3j8.mjs.map} +1 -1
- package/dist/{vault-indexer-Dn_BccVK.mjs → vault-indexer-DrttVeEk.mjs} +2 -2
- package/dist/{vault-indexer-Dn_BccVK.mjs.map → vault-indexer-DrttVeEk.mjs.map} +1 -1
- package/dist/{work-queue-worker-BwouhVkb.mjs → work-queue-worker-BPXLkEik.mjs} +47 -30
- package/dist/work-queue-worker-BPXLkEik.mjs.map +1 -0
- package/dist/work-queue-worker-BoHIH70K.mjs +1856 -0
- package/dist/work-queue-worker-BoHIH70K.mjs.map +1 -0
- package/dist/work-queue-worker-CZGcQoLw.mjs +1856 -0
- package/dist/work-queue-worker-CZGcQoLw.mjs.map +1 -0
- package/dist/work-queue-worker-D05Ze9e9.mjs +1856 -0
- package/dist/work-queue-worker-D05Ze9e9.mjs.map +1 -0
- package/dist/work-queue-worker-DdXFINfH.mjs +1856 -0
- package/dist/work-queue-worker-DdXFINfH.mjs.map +1 -0
- package/dist/{zettelkasten-NwBD1NsT.mjs → zettelkasten-CTlt1dGv.mjs} +4 -4
- package/dist/{zettelkasten-NwBD1NsT.mjs.map → zettelkasten-CTlt1dGv.mjs.map} +1 -1
- package/dist/zettelkasten-D0N_A_OE.mjs +1063 -0
- package/dist/zettelkasten-D0N_A_OE.mjs.map +1 -0
- package/docs/commands/README.md +18 -0
- package/docs/commands/backup.md +1 -1
- package/docs/commands/clear-names.md +1 -1
- package/docs/commands/daemon.md +1 -1
- package/docs/commands/db.md +1 -1
- package/docs/commands/end.md +4 -1
- package/docs/commands/help.md +1 -1
- package/docs/commands/kg.md +1 -1
- package/docs/commands/mcp.md +1 -1
- package/docs/commands/memory.md +1 -1
- package/docs/commands/notify.md +1 -1
- package/docs/commands/observation.md +1 -1
- package/docs/commands/obsidian.md +1 -1
- package/docs/commands/pause.md +5 -2
- package/docs/commands/project.md +1 -1
- package/docs/commands/projects.md +1 -1
- package/docs/commands/registry.md +18 -1
- package/docs/commands/restore.md +1 -1
- package/docs/commands/session.md +295 -0
- package/docs/commands/sessions.md +1 -1
- package/docs/commands/setup.md +1 -1
- package/docs/commands/shell-init.md +1 -1
- package/docs/commands/skill.md +1 -1
- package/docs/commands/task.md +1 -1
- package/docs/commands/topic.md +1 -1
- package/docs/commands/update.md +1 -1
- package/docs/commands/zettel.md +1 -1
- package/package.json +1 -1
- package/plugins/context-preservation/hooks/hooks.json +12 -1
- package/scripts/build-hooks.mjs +33 -3
- package/src/hooks/session-autosave.sh +69 -0
- package/src/hooks/session-stop.sh +32 -1
- package/src/hooks/ts/lib/project-utils/todo.test.ts +132 -0
- package/src/hooks/ts/lib/project-utils/todo.ts +60 -34
- package/src/hooks/ts/session-start/load-project-context.ts +44 -0
- package/dist/kg-extraction-C8DEUHTS.mjs.map +0 -1
- package/dist/pai-marker-HVBwwBW-.mjs.map +0 -1
- package/dist/pick-r95zvydr.mjs.map +0 -1
- package/dist/sync-uPR4g438.mjs.map +0 -1
- package/dist/work-queue-worker-BwouhVkb.mjs.map +0 -1
|
@@ -0,0 +1,295 @@
|
|
|
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] [number-or-latest]`](#pai-session-handover-project-slug-number-or-latest) | 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 autosave`](#pai-session-autosave) | Refresh the ## Continue checkpoint from the transcript and working tree. |
|
|
28
|
+
| [`pai session active`](#pai-session-active) | Show currently active Claude Code sessions. |
|
|
29
|
+
| [`pai session recent`](#pai-session-recent) | [Deprecated] Use `pai session list` or `pai sessions` instead. |
|
|
30
|
+
| [`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. |
|
|
31
|
+
| [`pai session pause`](#pai-session-pause) | Write a ## Continue checkpoint to the project's TODO.md. |
|
|
32
|
+
| [`pai session auto-route`](#pai-session-auto-route) | Auto-detect which project this session belongs to. |
|
|
33
|
+
| [`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 |
|
|
34
|
+
|
|
35
|
+
### pai session list
|
|
36
|
+
|
|
37
|
+
Resumable sessions catalog — named sessions with resume status.
|
|
38
|
+
|
|
39
|
+
Short form: pai sessions
|
|
40
|
+
Default shows all sessions you've named or that are resumable.
|
|
41
|
+
Use --all to also show unnamed orphan sessions.
|
|
42
|
+
|
|
43
|
+
**Options**
|
|
44
|
+
|
|
45
|
+
| Option | Description | Default |
|
|
46
|
+
|--------|-------------|---------|
|
|
47
|
+
| `-n <count>` | Maximum sessions to show (default: 20) | `20` |
|
|
48
|
+
| `--all` | Include unnamed orphan sessions (not in clc registry) | |
|
|
49
|
+
| `--json` | Output raw JSON instead of formatted table | |
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### pai session info <project-slug> <number>
|
|
53
|
+
|
|
54
|
+
Show full details for a specific session
|
|
55
|
+
|
|
56
|
+
**Arguments**
|
|
57
|
+
|
|
58
|
+
| Argument | Kind |
|
|
59
|
+
|----------|------|
|
|
60
|
+
| `<project-slug>` | required |
|
|
61
|
+
| `<number>` | required |
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### pai session rename <project-slug> <number> <new-slug>
|
|
65
|
+
|
|
66
|
+
Rename a session note — updates file on disk, H1 title, and registry
|
|
67
|
+
|
|
68
|
+
**Arguments**
|
|
69
|
+
|
|
70
|
+
| Argument | Kind |
|
|
71
|
+
|----------|------|
|
|
72
|
+
| `<project-slug>` | required |
|
|
73
|
+
| `<number>` | required |
|
|
74
|
+
| `<new-slug>` | required |
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
### pai session slug <project-slug> <number>
|
|
78
|
+
|
|
79
|
+
Generate a descriptive slug from the session JSONL transcript
|
|
80
|
+
|
|
81
|
+
**Arguments**
|
|
82
|
+
|
|
83
|
+
| Argument | Kind |
|
|
84
|
+
|----------|------|
|
|
85
|
+
| `<project-slug>` | required |
|
|
86
|
+
| `<number>` | required |
|
|
87
|
+
|
|
88
|
+
**Options**
|
|
89
|
+
|
|
90
|
+
| Option | Description | Default |
|
|
91
|
+
|--------|-------------|---------|
|
|
92
|
+
| `--apply` | Rename the session note using the generated slug | |
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### pai session tag <project-slug> <number> [tags...]
|
|
96
|
+
|
|
97
|
+
Set or show tags on a session. Tags can be space-separated or comma-separated.
|
|
98
|
+
|
|
99
|
+
**Arguments**
|
|
100
|
+
|
|
101
|
+
| Argument | Kind |
|
|
102
|
+
|----------|------|
|
|
103
|
+
| `<project-slug>` | required |
|
|
104
|
+
| `<number>` | required |
|
|
105
|
+
| `[tags...]` | variadic |
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### pai session route <project-slug> <number> <target-project>
|
|
109
|
+
|
|
110
|
+
Create a cross-reference link from a session to a target project
|
|
111
|
+
|
|
112
|
+
**Arguments**
|
|
113
|
+
|
|
114
|
+
| Argument | Kind |
|
|
115
|
+
|----------|------|
|
|
116
|
+
| `<project-slug>` | required |
|
|
117
|
+
| `<number>` | required |
|
|
118
|
+
| `<target-project>` | required |
|
|
119
|
+
|
|
120
|
+
**Options**
|
|
121
|
+
|
|
122
|
+
| Option | Description | Default |
|
|
123
|
+
|--------|-------------|---------|
|
|
124
|
+
| `--type <type>` | Link type: related \| follow-up \| reference | `related` |
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
### pai session handover [project-slug] [number-or-latest]
|
|
128
|
+
|
|
129
|
+
Write a ## Continue section to the project's TODO.md.
|
|
130
|
+
|
|
131
|
+
Called automatically from session-stop and pre-compact hooks.
|
|
132
|
+
Records the last session identifier, timestamp, and working directory
|
|
133
|
+
so the next session can resume from the correct context.
|
|
134
|
+
|
|
135
|
+
**Arguments**
|
|
136
|
+
|
|
137
|
+
| Argument | Kind |
|
|
138
|
+
|----------|------|
|
|
139
|
+
| `[project-slug]` | optional |
|
|
140
|
+
| `[number-or-latest]` | optional |
|
|
141
|
+
|
|
142
|
+
**Options**
|
|
143
|
+
|
|
144
|
+
| Option | Description | Default |
|
|
145
|
+
|--------|-------------|---------|
|
|
146
|
+
| `--session-id <uuid>` | Claude session UUID. Used to decide whether an existing authored checkpoint belongs to this session and must be preserved. Without it the comparison falls back to the session note filename, which the stop hook itself renames — so pass it whenever it is known. | |
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
### pai session checkpoint <message>
|
|
150
|
+
|
|
151
|
+
Append a timestamped checkpoint to the active session note.
|
|
152
|
+
|
|
153
|
+
Designed for hooks (PostToolUse, UserPromptSubmit) — fast and silent.
|
|
154
|
+
Rate-limited: skips silently if last checkpoint was < --min-gap seconds ago.
|
|
155
|
+
|
|
156
|
+
**Arguments**
|
|
157
|
+
|
|
158
|
+
| Argument | Kind |
|
|
159
|
+
|----------|------|
|
|
160
|
+
| `<message>` | required |
|
|
161
|
+
|
|
162
|
+
**Options**
|
|
163
|
+
|
|
164
|
+
| Option | Description | Default |
|
|
165
|
+
|--------|-------------|---------|
|
|
166
|
+
| `--min-gap <seconds>` | Minimum seconds between checkpoints (default: 300 = 5 minutes) | `300` |
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### pai session autosave
|
|
170
|
+
|
|
171
|
+
Refresh the ## Continue checkpoint from the transcript and working tree.
|
|
172
|
+
|
|
173
|
+
Runs unattended from live hooks so an interrupted session still leaves
|
|
174
|
+
a usable handover. Writes in auto mode, so a model-authored checkpoint
|
|
175
|
+
for the same session is preserved untouched. Silent; always exits 0.
|
|
176
|
+
|
|
177
|
+
**Options**
|
|
178
|
+
|
|
179
|
+
| Option | Description | Default |
|
|
180
|
+
|--------|-------------|---------|
|
|
181
|
+
| `--session-id <uuid>` | Claude session UUID — the key that decides whether an existing authored checkpoint belongs to this session and must be left alone. | |
|
|
182
|
+
| `--min-gap <seconds>` | Minimum seconds between autosaves, shared across all triggers (default: 240) | `240` |
|
|
183
|
+
| `--dry-run` | Print the block that would be written and exit | |
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
### pai session active
|
|
187
|
+
|
|
188
|
+
Show currently active Claude Code sessions.
|
|
189
|
+
|
|
190
|
+
Detects live sessions by checking which JSONL transcript files
|
|
191
|
+
were recently modified in ~/.claude/projects/.
|
|
192
|
+
|
|
193
|
+
**Options**
|
|
194
|
+
|
|
195
|
+
| Option | Description | Default |
|
|
196
|
+
|--------|-------------|---------|
|
|
197
|
+
| `--minutes <n>` | Consider sessions active if modified within N minutes (default: 60) | `60` |
|
|
198
|
+
| `--json` | Output raw JSON instead of formatted display | |
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
### pai session recent
|
|
202
|
+
|
|
203
|
+
[Deprecated] Use `pai session list` or `pai sessions` instead.
|
|
204
|
+
|
|
205
|
+
**Options**
|
|
206
|
+
|
|
207
|
+
| Option | Description | Default |
|
|
208
|
+
|--------|-------------|---------|
|
|
209
|
+
| `-n <count>` | Maximum sessions to show (default: 20) | `20` |
|
|
210
|
+
| `--all` | Include unnamed orphan sessions (not in clc registry) | |
|
|
211
|
+
| `--json` | Output raw JSON instead of formatted table | |
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### pai session goto <name-or-id>
|
|
215
|
+
|
|
216
|
+
Go to a session: resume if a resumable snapshot exists, start fresh otherwise.
|
|
217
|
+
|
|
218
|
+
Recommended short form: pai resume <name>
|
|
219
|
+
Resolves by clc/registry name (case-insensitive) or UUID prefix.
|
|
220
|
+
Sends '/Name <name>\ngo' as the initial prompt so the PAI ## Continue hook fires.
|
|
221
|
+
|
|
222
|
+
**Arguments**
|
|
223
|
+
|
|
224
|
+
| Argument | Kind |
|
|
225
|
+
|----------|------|
|
|
226
|
+
| `<name-or-id>` | required |
|
|
227
|
+
|
|
228
|
+
**Options**
|
|
229
|
+
|
|
230
|
+
| Option | Description | Default |
|
|
231
|
+
|--------|-------------|---------|
|
|
232
|
+
| `--skip-name` | Do not prepend /Name to set the session name in chrome | |
|
|
233
|
+
| `--skip-go` | Do not append \ngo to trigger PAI auto-resume (## Continue) | |
|
|
234
|
+
| `--dry-run` | Print the exact argv and cwd, then exit without launching | |
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
### pai session pause
|
|
238
|
+
|
|
239
|
+
Write a ## Continue checkpoint to the project's TODO.md.
|
|
240
|
+
|
|
241
|
+
Recommended short form: pai pause
|
|
242
|
+
Ctrl+C bypasses the stop-hook, orphaning the session (cannot --resume).
|
|
243
|
+
Use /exit inside Claude Code to preserve full session resumability.
|
|
244
|
+
|
|
245
|
+
**Options**
|
|
246
|
+
|
|
247
|
+
| Option | Description | Default |
|
|
248
|
+
|--------|-------------|---------|
|
|
249
|
+
| `--dry-run` | Preview the ## Continue block without writing it | |
|
|
250
|
+
| `--body-file <path>` | File holding the checkpoint markdown to persist ('-' reads stdin). Required unless --no-body. | |
|
|
251
|
+
| `--session-id <uuid>` | Claude Code session UUID — recorded as the `claude --resume` handle | |
|
|
252
|
+
| `--no-body` | Deliberately write a metadata-only checkpoint (no content) | |
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
### pai session auto-route
|
|
256
|
+
|
|
257
|
+
Auto-detect which project this session belongs to.
|
|
258
|
+
|
|
259
|
+
Tries: (1) path match in registry, (2) Notes/PAI.md marker walk, (3) topic detection.
|
|
260
|
+
Designed for use in CLAUDE.md session-start hooks.
|
|
261
|
+
|
|
262
|
+
**Options**
|
|
263
|
+
|
|
264
|
+
| Option | Description | Default |
|
|
265
|
+
|--------|-------------|---------|
|
|
266
|
+
| `--cwd <path>` | Working directory to detect from (default: process.cwd()) | |
|
|
267
|
+
| `--context <text>` | Conversation context for topic-based fallback routing | |
|
|
268
|
+
| `--json` | Output raw JSON instead of formatted display | |
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
### pai session cleanup [project-slug]
|
|
272
|
+
|
|
273
|
+
Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber
|
|
274
|
+
|
|
275
|
+
**Arguments**
|
|
276
|
+
|
|
277
|
+
| Argument | Kind |
|
|
278
|
+
|----------|------|
|
|
279
|
+
| `[project-slug]` | optional |
|
|
280
|
+
|
|
281
|
+
**Options**
|
|
282
|
+
|
|
283
|
+
| Option | Description | Default |
|
|
284
|
+
|--------|-------------|---------|
|
|
285
|
+
| `--execute` | Actually perform the cleanup (default is dry-run) | |
|
|
286
|
+
| `--no-renumber` | Skip renumbering sessions after deletions | |
|
|
287
|
+
| `--no-reindex` | Skip triggering memory re-index after moves | |
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
## See also
|
|
291
|
+
|
|
292
|
+
[`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)
|
|
293
|
+
|
|
294
|
+
Run `pai help <area>` to read any of these in the terminal.
|
|
295
|
+
|
|
@@ -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
|
|
package/docs/commands/setup.md
CHANGED
|
@@ -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
|
|
package/docs/commands/skill.md
CHANGED
|
@@ -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
|
|
package/docs/commands/task.md
CHANGED
|
@@ -142,7 +142,7 @@ Mark a task complete on the tracker
|
|
|
142
142
|
|
|
143
143
|
## See also
|
|
144
144
|
|
|
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 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)
|
|
146
146
|
|
|
147
147
|
Run `pai help <area>` to read any of these in the terminal.
|
|
148
148
|
|
package/docs/commands/topic.md
CHANGED
|
@@ -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
|
|
package/docs/commands/update.md
CHANGED
|
@@ -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
|
|
package/docs/commands/zettel.md
CHANGED
|
@@ -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,7 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"module": "context-preservation",
|
|
3
|
-
"description": "Context
|
|
3
|
+
"description": "Context preservation across compaction cycles, restarts, and interrupted sessions",
|
|
4
4
|
"hooks": [
|
|
5
|
+
{
|
|
6
|
+
"event": "UserPromptSubmit",
|
|
7
|
+
"command": "${PAI_DIR}/Hooks/pai-session-autosave.sh",
|
|
8
|
+
"description": "Refresh the rolling ## Continue checkpoint from the transcript and working tree (rate-limited). Never overwrites a model-authored checkpoint for the same session."
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"event": "PostToolUse",
|
|
12
|
+
"matcher": "*",
|
|
13
|
+
"command": "${PAI_DIR}/Hooks/pai-session-autosave.sh",
|
|
14
|
+
"description": "Same rolling checkpoint, so a long working turn interrupted by Ctrl+C still leaves recoverable state"
|
|
15
|
+
},
|
|
5
16
|
{
|
|
6
17
|
"event": "PreCompact",
|
|
7
18
|
"command": "${PAI_DIR}/Hooks/context-compression-hook.mjs",
|
package/scripts/build-hooks.mjs
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
// ---------------------------------------------------------------------------
|
|
@@ -141,6 +170,7 @@ if (doSync) {
|
|
|
141
170
|
const shellHooks = [
|
|
142
171
|
["src/hooks/pre-compact.sh", "pai-pre-compact.sh"],
|
|
143
172
|
["src/hooks/session-stop.sh", "pai-session-stop.sh"],
|
|
173
|
+
["src/hooks/session-autosave.sh", "pai-session-autosave.sh"],
|
|
144
174
|
];
|
|
145
175
|
for (const [src, destName] of shellHooks) {
|
|
146
176
|
if (existsSync(src)) {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PAI Knowledge OS — rolling session autosave
|
|
3
|
+
#
|
|
4
|
+
# Fires from live hooks (UserPromptSubmit, PostToolUse) so that a session which
|
|
5
|
+
# never gets a model-authored checkpoint still leaves a usable ## Continue
|
|
6
|
+
# behind. Ctrl+C kills the process without running any stop hook, and /exit does
|
|
7
|
+
# not invoke the model — so an exit-time-only guarantee is no guarantee at all.
|
|
8
|
+
# The state has to be written while the session is still running.
|
|
9
|
+
#
|
|
10
|
+
# Writes in "auto" mode, so a model-authored checkpoint for the same session is
|
|
11
|
+
# preserved untouched. This is the floor, never a replacement for the ceiling.
|
|
12
|
+
#
|
|
13
|
+
# NEVER exits non-zero, NEVER prints — this must not interrupt Claude Code.
|
|
14
|
+
|
|
15
|
+
PAI_OS="pai"
|
|
16
|
+
command -v "$PAI_OS" &>/dev/null || exit 0
|
|
17
|
+
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
# Shell-side rate limit
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
# PostToolUse fires after every single tool call. The CLI rate-limits too, but
|
|
22
|
+
# reaching it costs a Node start-up each time — hundreds of milliseconds, paid
|
|
23
|
+
# on every tool call in the session. Checking a sentinel's mtime here costs a
|
|
24
|
+
# stat, so the expensive path is only taken when it will actually do work.
|
|
25
|
+
|
|
26
|
+
MIN_GAP_SECONDS="${PAI_AUTOSAVE_MIN_GAP:-240}"
|
|
27
|
+
|
|
28
|
+
SENTINEL_KEY=$(printf '%s' "$PWD" | tr -c 'a-zA-Z0-9' '-' | tail -c 80)
|
|
29
|
+
SENTINEL="${TMPDIR:-/tmp}/pai-autosave-hook-${SENTINEL_KEY}"
|
|
30
|
+
|
|
31
|
+
if [ -f "$SENTINEL" ]; then
|
|
32
|
+
NOW=$(date +%s)
|
|
33
|
+
# stat is not portable: BSD/macOS uses -f %m, GNU/Linux uses -c %Y.
|
|
34
|
+
LAST=$(stat -f %m "$SENTINEL" 2>/dev/null || stat -c %Y "$SENTINEL" 2>/dev/null || echo 0)
|
|
35
|
+
if [ $((NOW - LAST)) -lt "$MIN_GAP_SECONDS" ]; then
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Session UUID from the hook payload
|
|
42
|
+
# ---------------------------------------------------------------------------
|
|
43
|
+
# The UUID decides whether an existing authored checkpoint belongs to this
|
|
44
|
+
# session and must be left alone. Without it the comparison falls back to the
|
|
45
|
+
# session note filename, which other stop-hook steps rename underneath us.
|
|
46
|
+
|
|
47
|
+
CLAUDE_SESSION_UUID=""
|
|
48
|
+
if [ ! -t 0 ]; then
|
|
49
|
+
HOOK_INPUT=$(timeout 2 cat 2>/dev/null || true)
|
|
50
|
+
if [ -n "$HOOK_INPUT" ]; then
|
|
51
|
+
if command -v jq &>/dev/null; then
|
|
52
|
+
CLAUDE_SESSION_UUID=$(printf '%s' "$HOOK_INPUT" | jq -r '.session_id // empty' 2>/dev/null || true)
|
|
53
|
+
else
|
|
54
|
+
CLAUDE_SESSION_UUID=$(printf '%s' "$HOOK_INPUT" | python3 -c \
|
|
55
|
+
"import sys,json; print(json.load(sys.stdin).get('session_id',''))" 2>/dev/null || true)
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
touch "$SENTINEL" 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
if [ -n "$CLAUDE_SESSION_UUID" ]; then
|
|
63
|
+
"$PAI_OS" session autosave --session-id "$CLAUDE_SESSION_UUID" \
|
|
64
|
+
--min-gap "$MIN_GAP_SECONDS" &>/dev/null || true
|
|
65
|
+
else
|
|
66
|
+
"$PAI_OS" session autosave --min-gap "$MIN_GAP_SECONDS" &>/dev/null || true
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
exit 0
|
|
@@ -12,6 +12,32 @@ PAI_OS="pai"
|
|
|
12
12
|
command -v "$PAI_OS" &>/dev/null || exit 0
|
|
13
13
|
command -v sqlite3 &>/dev/null || exit 0
|
|
14
14
|
|
|
15
|
+
# ---------------------------------------------------------------------------
|
|
16
|
+
# Read the Claude session UUID from the hook payload
|
|
17
|
+
# ---------------------------------------------------------------------------
|
|
18
|
+
# Claude Code delivers the Stop event as JSON on stdin, carrying `session_id`.
|
|
19
|
+
# That UUID is the only stable handle on this session: the steps below rename
|
|
20
|
+
# (`session slug --apply`) and renumber (`session cleanup --execute`) the
|
|
21
|
+
# session note, so anything derived from its filename has already changed by
|
|
22
|
+
# the time the handover runs. Passing the UUID through is what lets the
|
|
23
|
+
# handover recognise a checkpoint `pai pause` wrote minutes earlier instead of
|
|
24
|
+
# mistaking it for a stale one and overwriting it.
|
|
25
|
+
#
|
|
26
|
+
# Read non-blocking: when no payload is piped in, carry on without it.
|
|
27
|
+
|
|
28
|
+
CLAUDE_SESSION_UUID=""
|
|
29
|
+
if [ ! -t 0 ]; then
|
|
30
|
+
HOOK_INPUT=$(timeout 2 cat 2>/dev/null || true)
|
|
31
|
+
if [ -n "$HOOK_INPUT" ]; then
|
|
32
|
+
if command -v jq &>/dev/null; then
|
|
33
|
+
CLAUDE_SESSION_UUID=$(printf '%s' "$HOOK_INPUT" | jq -r '.session_id // empty' 2>/dev/null || true)
|
|
34
|
+
else
|
|
35
|
+
CLAUDE_SESSION_UUID=$(printf '%s' "$HOOK_INPUT" | python3 -c \
|
|
36
|
+
"import sys,json; print(json.load(sys.stdin).get('session_id',''))" 2>/dev/null || true)
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
|
|
15
41
|
REGISTRY_DB="$HOME/.pai/registry.db"
|
|
16
42
|
[ -f "$REGISTRY_DB" ] || exit 0
|
|
17
43
|
|
|
@@ -88,7 +114,12 @@ fi
|
|
|
88
114
|
# a handover section. If the command doesn't exist yet, fail gracefully.
|
|
89
115
|
#
|
|
90
116
|
|
|
91
|
-
|
|
117
|
+
if [ -n "$CLAUDE_SESSION_UUID" ]; then
|
|
118
|
+
"$PAI_OS" session handover "$PROJECT_SLUG" latest \
|
|
119
|
+
--session-id "$CLAUDE_SESSION_UUID" 2>/dev/null || true
|
|
120
|
+
else
|
|
121
|
+
"$PAI_OS" session handover "$PROJECT_SLUG" latest 2>/dev/null || true
|
|
122
|
+
fi
|
|
92
123
|
|
|
93
124
|
# Set tab color to completed state when session ends
|
|
94
125
|
TAB_COLOR="${PAI_DIR:-$HOME/.claude}/tab-color-command.sh"
|