@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.
- 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/{kg-extraction-C8DEUHTS.mjs → checkpoint-block-Bl0HD3U2.mjs} +442 -13
- package/dist/checkpoint-block-Bl0HD3U2.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-DGOfoGfm.mjs.map +1 -0
- 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-mcp/index.mjs +24 -2
- package/dist/daemon-mcp/index.mjs.map +1 -1
- 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-rq9JGTmS.mjs} +2 -2
- package/dist/{detector-ZiOhHszd.mjs.map → detector-rq9JGTmS.mjs.map} +1 -1
- 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-HcQsQqh0.mjs} +8 -5
- package/dist/{factory-Q88X1bAN.mjs.map → factory-HcQsQqh0.mjs.map} +1 -1
- 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 +304 -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.map +1 -1
- 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 +299 -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/{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-C6IFFT0-.mjs} +4 -4
- package/dist/{latent-ideas-RyC6eyqI.mjs.map → latent-ideas-C6IFFT0-.mjs.map} +1 -1
- 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/{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-gne3kOJG.mjs → pick-B3zEYjin.mjs} +2316 -483
- package/dist/pick-B3zEYjin.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-i2nlQ-JM.mjs} +3 -3
- package/dist/{search-HcdKtMla.mjs.map → search-i2nlQ-JM.mjs.map} +1 -1
- package/dist/skills/End/SKILL.md +78 -0
- package/dist/skills/Pause/SKILL.md +77 -0
- package/dist/skills/Tasks/SKILL.md +22 -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/{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-CmBKOL3K.mjs} +6 -205
- package/dist/sync-CmBKOL3K.mjs.map +1 -0
- package/dist/{themes-Cg8oG9Ra.mjs → themes-nvRM8v84.mjs} +3 -3
- package/dist/{themes-Cg8oG9Ra.mjs.map → themes-nvRM8v84.mjs.map} +1 -1
- 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/{zettelkasten-NwBD1NsT.mjs → zettelkasten-CTlt1dGv.mjs} +4 -4
- package/dist/{zettelkasten-NwBD1NsT.mjs.map → zettelkasten-CTlt1dGv.mjs.map} +1 -1
- package/docs/commands/README.md +17 -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 +4 -1
- 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 +271 -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 +2 -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/scripts/build-hooks.mjs +32 -3
- package/src/hooks/ts/lib/project-utils/todo.test.ts +132 -0
- package/src/hooks/ts/lib/project-utils/todo.ts +60 -34
- package/dist/config-C8m-tPhP.mjs.map +0 -1
- package/dist/kg-extraction-C8DEUHTS.mjs.map +0 -1
- package/dist/pai-marker-HVBwwBW-.mjs.map +0 -1
- package/dist/pick-gne3kOJG.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,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: End
|
|
3
|
+
description: "Finalize a session: checkpoint, mark note completed, commit pending work if asked, then exit safely. USE WHEN user says /end, end session, finish session, OR is done with this conversation entirely."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## End Skill
|
|
7
|
+
|
|
8
|
+
USE WHEN user says /end, end session, finish session, OR is done with this conversation entirely.
|
|
9
|
+
|
|
10
|
+
### The rule that matters
|
|
11
|
+
|
|
12
|
+
**The checkpoint must be written to a FILE before it is printed.** Printing it to the
|
|
13
|
+
terminal does not persist it — if the session ends, it is gone and the user has to copy it
|
|
14
|
+
off the screen by hand. Order is **compose → write file → persist via CLI → print**, and it
|
|
15
|
+
never varies.
|
|
16
|
+
|
|
17
|
+
### Procedure (extends Pause)
|
|
18
|
+
|
|
19
|
+
1. **Compose the checkpoint** — what was accomplished, what was left incomplete, open
|
|
20
|
+
decisions, anything built but not installed, and any follow-up actions. Write it for a
|
|
21
|
+
session that has none of your context.
|
|
22
|
+
|
|
23
|
+
1b. **Write it to a file** with the Write tool:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
/tmp/pai-checkpoint-<session-id>.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use the `sessionId` from the startup system reminders. Body markdown only — no
|
|
30
|
+
`## Continue` or `## Session Complete` heading; PAI adds those.
|
|
31
|
+
|
|
32
|
+
2. **Run `pai end`** via Bash:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pai end --body-file /tmp/pai-checkpoint-<session-id>.md --session-id <session-id>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This does everything `pai pause` does (writes the checkpoint into `## Continue` in
|
|
39
|
+
TODO.md and appends it to the session note) PLUS marks the current session note
|
|
40
|
+
**Status: Completed** with a timestamp.
|
|
41
|
+
|
|
42
|
+
**If this errors, stop and fix it.** It refuses to write a metadata-only checkpoint, so
|
|
43
|
+
an error here is the difference between a real checkpoint and a lost one.
|
|
44
|
+
|
|
45
|
+
2b. **File open items onto the task bus.**
|
|
46
|
+
|
|
47
|
+
`pai end` writes the session note and TODO.md. It does **not** touch Todoist — it is a
|
|
48
|
+
mechanical command, and deciding what counts as an open item needs judgement. So do it
|
|
49
|
+
here, explicitly:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pai task add "<open item>" --into <ProjectName> --owner <project> --body "<reasoning>"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Always use `--into <ProjectName>`** — one sub-project per PAI project, created
|
|
56
|
+
automatically if missing. Doing so is *following the convention, not inventing
|
|
57
|
+
structure*: filing flat into the root out of caution buries findings across projects,
|
|
58
|
+
which is the mess the convention prevents. Omit `--into` only for something genuinely
|
|
59
|
+
cross-cutting.
|
|
60
|
+
|
|
61
|
+
Skip this only if nothing is actually open — say so rather than filing filler. Otherwise
|
|
62
|
+
the open items exist solely in a session note nobody re-reads, which is exactly the loss
|
|
63
|
+
the bus was built to stop.
|
|
64
|
+
|
|
65
|
+
3. **Check for uncommitted changes** with `git status`. If there are any, ask whether to
|
|
66
|
+
commit them. If yes, use clean conventional-commit format — no AI signatures, no
|
|
67
|
+
`--no-verify`.
|
|
68
|
+
|
|
69
|
+
4. **Print the handoff block** — the same content you wrote in step 1b, plus the session ID
|
|
70
|
+
from the `sessionId` field in startup system reminders, and:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
To resume (if needed): claude --resume <uuid>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
5. **Tell the user:**
|
|
77
|
+
"Now type `/exit` to safely close the session. DO NOT press Ctrl+C — that bypasses PAI
|
|
78
|
+
stop-hook and means the stop-hook finalization never runs."
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Pause
|
|
3
|
+
description: "Save a checkpoint and prepare to exit safely, knowing you will come back to the same conversation. USE WHEN user says /pause, pause session, pause this, OR wants to step away knowing they will come back to the same conversation."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Pause Skill
|
|
7
|
+
|
|
8
|
+
USE WHEN user says /pause, pause session, pause this, OR wants to step away knowing they will come back to the same conversation.
|
|
9
|
+
|
|
10
|
+
### The rule that matters
|
|
11
|
+
|
|
12
|
+
**The checkpoint must be written to a FILE before it is printed.** Printing it to the
|
|
13
|
+
terminal does not persist it. If you print first and the session ends, the checkpoint is
|
|
14
|
+
gone and the user has to copy it off the screen by hand — which is the exact failure this
|
|
15
|
+
procedure exists to prevent.
|
|
16
|
+
|
|
17
|
+
Order is: **compose → write file → persist via CLI → print**. Never reorder.
|
|
18
|
+
|
|
19
|
+
### Procedure
|
|
20
|
+
|
|
21
|
+
1. **Compose the checkpoint.** It must be genuinely useful to a session that has none of
|
|
22
|
+
your context. Include:
|
|
23
|
+
|
|
24
|
+
- **Shipped/completed** — what actually landed, with versions or commit refs
|
|
25
|
+
- **Open decisions** — anything blocked on a judgement call, stated as the question
|
|
26
|
+
- **In flight** — built but not installed, written but not tested, etc.
|
|
27
|
+
- **Watch items** — changes whose effects need observing, and why
|
|
28
|
+
- **Cross-session work** — what other sessions are owed, or owe you
|
|
29
|
+
|
|
30
|
+
Be specific. "Continue the refactor" is worthless; "the poller is built and tested but
|
|
31
|
+
`pai task schedule install` has not been run" is a checkpoint.
|
|
32
|
+
|
|
33
|
+
2. **Write it to a file** with the Write tool:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
/tmp/pai-checkpoint-<session-id>.md
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Use the `sessionId` from the startup system reminders for `<session-id>`. Write the
|
|
40
|
+
markdown body only — no `## Continue` heading and no `## Pause Checkpoint` heading.
|
|
41
|
+
PAI adds those.
|
|
42
|
+
|
|
43
|
+
3. **Persist it** via Bash:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pai pause --body-file /tmp/pai-checkpoint-<session-id>.md --session-id <session-id>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This writes the body into `## Continue` in the project TODO.md **and** appends it to
|
|
50
|
+
the current session note, then prints the safe-exit reminder.
|
|
51
|
+
|
|
52
|
+
**If this command errors, do not proceed to step 4.** It refuses to write a
|
|
53
|
+
metadata-only checkpoint, so an error here is the difference between a real checkpoint
|
|
54
|
+
and a lost one. Fix the cause and re-run.
|
|
55
|
+
|
|
56
|
+
4. **Print the checkpoint to the user** — the same content you wrote in step 2, plus:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
To resume: claude --resume <session-id>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
5. **Tell the user:**
|
|
63
|
+
"Now type `/exit` to safely close the session. DO NOT press Ctrl+C — that bypasses PAI
|
|
64
|
+
stop-hook and orphans the session so it cannot be resumed."
|
|
65
|
+
|
|
66
|
+
### Notes
|
|
67
|
+
|
|
68
|
+
- `--session-id` is what makes `claude --resume` recoverable from TODO.md alone. Always
|
|
69
|
+
pass it.
|
|
70
|
+
- The session-stop hook runs `pai session handover` on exit. It will **not** overwrite the
|
|
71
|
+
checkpoint you just wrote — authored checkpoints for the current session are preserved,
|
|
72
|
+
and unattributed content in older blocks is carried forward rather than dropped.
|
|
73
|
+
- `--no-body` exists for deliberate metadata-only checkpoints. Do not reach for it to work
|
|
74
|
+
around a failure in step 2 or 3.
|
|
75
|
+
- Do **not** hand-place state below the generated header lines as a workaround. That was
|
|
76
|
+
necessary when the block got clobbered; it no longer is, and `--body-file` puts the
|
|
77
|
+
content somewhere that survives.
|
|
@@ -64,6 +64,14 @@ pai task add "Short actionable title" \\
|
|
|
64
64
|
--url "hook://..."
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
**Always file into the sub-project for the PAI project you are working in**, using `--into <name>`. It is created if it does not exist:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pai task add "Title" --into Clickr --owner clickr --body "..."
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Creating that sub-project is **following the convention, not inventing structure**. Do not file flat into the root out of caution — a flat pile buries findings across projects, and every session that hesitates makes it worse. Only omit `--into` for something genuinely cross-cutting.
|
|
74
|
+
|
|
67
75
|
Rules:
|
|
68
76
|
- **`--body` is not optional in practice.** Enough that the task is actionable months later, or by the user alone, without re-deriving anything. A bare title is a reminder that something was once known — worthless later.
|
|
69
77
|
- **Omit `--owner` when you genuinely do not know.** It lands in the findings inbox for triage. Guessing is worse than leaving it unrouted.
|
|
@@ -94,6 +102,20 @@ For each `unrouted` item, decide with the user: assign an owner, act now, or del
|
|
|
94
102
|
|
|
95
103
|
A label matching nothing does **not** fall through to the container. The user meant somewhere specific; quietly routing elsewhere is worse than not routing.
|
|
96
104
|
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### At session end
|
|
108
|
+
|
|
109
|
+
`pai end` finalises the session note and TODO.md. It does **not** touch the tracker — it is a mechanical command and deciding what counts as an open item needs judgement.
|
|
110
|
+
|
|
111
|
+
So before ending a session, file anything still open onto the bus yourself:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pai task add "<open item>" --into <ProjectName> --owner <project> --body "<procedure + reasoning>"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Otherwise the open items live only in a session note nobody re-reads, which is the loss the bus exists to prevent. If there is genuinely nothing open, say so rather than filing filler.
|
|
118
|
+
|
|
97
119
|
### Notes
|
|
98
120
|
|
|
99
121
|
- `pai task done <id>` closes a task. Dispatched tasks instruct the receiving session to do this, so work is not dispatched twice.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./embeddings-
|
|
2
|
-
import { a as searchMemorySemantic, r as searchMemory } from "./search-
|
|
1
|
+
import "./embeddings-DGRAPAYb.mjs";
|
|
2
|
+
import { a as searchMemorySemantic, r as searchMemory } from "./search-i2nlQ-JM.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/storage/sqlite.ts
|
|
5
5
|
var SQLiteBackend = class {
|
|
@@ -268,4 +268,4 @@ var SQLiteBackend = class {
|
|
|
268
268
|
|
|
269
269
|
//#endregion
|
|
270
270
|
export { SQLiteBackend };
|
|
271
|
-
//# sourceMappingURL=sqlite-
|
|
271
|
+
//# sourceMappingURL=sqlite-ChSCYwiC.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-DQpY1Esi.mjs","names":[],"sources":["../src/storage/sqlite.ts"],"sourcesContent":["/**\n * SQLiteBackend — wraps the existing better-sqlite3 federation.db\n * behind the StorageBackend interface.\n *\n * This is a thin adapter. The heavy lifting is all in the existing\n * memory/indexer.ts and memory/search.ts code; we just provide a\n * backend-agnostic surface so the daemon and tools can call either\n * SQLite or Postgres transparently.\n */\n\nimport type { Database } from \"better-sqlite3\";\nimport type { StorageBackend, ChunkRow, FileRow, FederationStats } from \"./interface.js\";\nimport type { SearchResult, SearchOptions } from \"../memory/search.js\";\nimport { searchMemory, searchMemorySemantic } from \"../memory/search.js\";\n\nexport class SQLiteBackend implements StorageBackend {\n readonly backendType = \"sqlite\" as const;\n\n private db: Database;\n\n constructor(db: Database) {\n this.db = db;\n }\n\n /**\n * Expose the raw better-sqlite3 Database handle.\n * Used by the daemon to pass to indexAll() which still uses the synchronous API directly.\n */\n getRawDb(): Database {\n return this.db;\n }\n\n /**\n * Alias for getRawDb() — used by the dispatcher for operations that require\n * direct SQLite access (e.g. memory_feedback, touchChunksLastAccessed).\n */\n getSqliteDb(): Database {\n return this.db;\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async close(): Promise<void> {\n try {\n this.db.close();\n } catch {\n // ignore\n }\n }\n\n async getStats(): Promise<FederationStats> {\n const files = (\n this.db.prepare(\"SELECT COUNT(*) AS n FROM memory_files\").get() as { n: number }\n ).n;\n const chunks = (\n this.db.prepare(\"SELECT COUNT(*) AS n FROM memory_chunks\").get() as { n: number }\n ).n;\n return { files, chunks };\n }\n\n // -------------------------------------------------------------------------\n // File tracking\n // -------------------------------------------------------------------------\n\n async getFileHash(projectId: number, path: string): Promise<string | undefined> {\n const row = this.db\n .prepare(\"SELECT hash FROM memory_files WHERE project_id = ? AND path = ?\")\n .get(projectId, path) as { hash: string } | undefined;\n return row?.hash;\n }\n\n async upsertFile(file: FileRow): Promise<void> {\n this.db\n .prepare(\n `INSERT INTO memory_files (project_id, path, source, tier, hash, mtime, size)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(project_id, path) DO UPDATE SET\n source = excluded.source,\n tier = excluded.tier,\n hash = excluded.hash,\n mtime = excluded.mtime,\n size = excluded.size`\n )\n .run(file.projectId, file.path, file.source, file.tier, file.hash, file.mtime, file.size);\n }\n\n // -------------------------------------------------------------------------\n // Chunk management\n // -------------------------------------------------------------------------\n\n async getChunkIds(projectId: number, path: string): Promise<string[]> {\n const rows = this.db\n .prepare(\"SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?\")\n .all(projectId, path) as Array<{ id: string }>;\n return rows.map((r) => r.id);\n }\n\n async deleteChunksForFile(projectId: number, path: string): Promise<void> {\n const ids = await this.getChunkIds(projectId, path);\n const deleteFts = this.db.prepare(\"DELETE FROM memory_fts WHERE id = ?\");\n const deleteChunks = this.db.prepare(\n \"DELETE FROM memory_chunks WHERE project_id = ? AND path = ?\"\n );\n this.db.transaction(() => {\n for (const id of ids) {\n deleteFts.run(id);\n }\n deleteChunks.run(projectId, path);\n })();\n }\n\n async insertChunks(chunks: ChunkRow[]): Promise<void> {\n if (chunks.length === 0) return;\n\n const insertChunk = this.db.prepare(\n `INSERT INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n const insertFts = this.db.prepare(\n `INSERT INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n this.db.transaction(() => {\n for (const c of chunks) {\n insertChunk.run(\n c.id,\n c.projectId,\n c.source,\n c.tier,\n c.path,\n c.startLine,\n c.endLine,\n c.hash,\n c.text,\n c.updatedAt\n );\n insertFts.run(\n c.text,\n c.id,\n c.projectId,\n c.path,\n c.source,\n c.tier,\n c.startLine,\n c.endLine\n );\n }\n })();\n }\n\n async getDistinctChunkPaths(projectId: number): Promise<string[]> {\n const rows = this.db\n .prepare(\"SELECT DISTINCT path FROM memory_chunks WHERE project_id = ?\")\n .all(projectId) as Array<{ path: string }>;\n return rows.map((r) => r.path);\n }\n\n async deletePaths(projectId: number, paths: string[]): Promise<void> {\n if (paths.length === 0) return;\n const deleteFts = this.db.prepare(\"DELETE FROM memory_fts WHERE id = ?\");\n const deleteChunks = this.db.prepare(\n \"DELETE FROM memory_chunks WHERE project_id = ? AND path = ?\"\n );\n const deleteFile = this.db.prepare(\n \"DELETE FROM memory_files WHERE project_id = ? AND path = ?\"\n );\n this.db.transaction(() => {\n for (const path of paths) {\n const ids = this.db\n .prepare(\"SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?\")\n .all(projectId, path) as Array<{ id: string }>;\n for (const { id } of ids) {\n deleteFts.run(id);\n }\n deleteChunks.run(projectId, path);\n deleteFile.run(projectId, path);\n }\n })();\n }\n\n async getUnembeddedChunkIds(projectId?: number): Promise<Array<{ id: string; text: string; project_id: number; path: string }>> {\n const conditions = [\"embedding IS NULL\"];\n const params: (string | number)[] = [];\n\n if (projectId !== undefined) {\n conditions.push(\"project_id = ?\");\n params.push(projectId);\n }\n\n const where = \"WHERE \" + conditions.join(\" AND \");\n // Prioritize real knowledge notes over PAI session/job-search noise.\n // CASE expression assigns lower priority numbers to knowledge paths.\n const rows = this.db\n .prepare(`SELECT id, text, project_id, path FROM memory_chunks ${where}\n ORDER BY CASE\n WHEN path LIKE '🧠 Ideaverse/%' THEN 0\n WHEN path LIKE 'Z - Zettelkasten/%' THEN 0\n WHEN path LIKE '💼 Business/%' THEN 0\n WHEN path LIKE '📆 Meetings/%' THEN 1\n WHEN path LIKE '💡 Insights/%' THEN 1\n WHEN path LIKE '👨💻 People/%' THEN 1\n WHEN path LIKE 'University/%' THEN 1\n WHEN path LIKE 'Copilot/%' THEN 1\n WHEN path LIKE '🗓️ Daily Notes/%' THEN 2\n WHEN path LIKE 'PAI/%' THEN 3\n WHEN path LIKE '09-job-search/%' THEN 4\n WHEN path LIKE 'seriousletter/%' THEN 4\n WHEN path LIKE 'Attachments/%' THEN 5\n ELSE 2\n END, id`)\n .all(...params) as Array<{ id: string; text: string; project_id: number; path: string }>;\n return rows;\n }\n\n async updateEmbedding(chunkId: string, embedding: Buffer): Promise<void> {\n this.db\n .prepare(\"UPDATE memory_chunks SET embedding = ? WHERE id = ?\")\n .run(embedding, chunkId);\n }\n\n // -------------------------------------------------------------------------\n // Search\n // -------------------------------------------------------------------------\n\n async searchKeyword(query: string, opts?: SearchOptions): Promise<SearchResult[]> {\n return searchMemory(this.db, query, opts);\n }\n\n async searchSemantic(queryEmbedding: Float32Array, opts?: SearchOptions): Promise<SearchResult[]> {\n return searchMemorySemantic(this.db, queryEmbedding, opts);\n }\n\n // -------------------------------------------------------------------------\n // Vault operations — not supported on SQLite backend (use Postgres)\n // -------------------------------------------------------------------------\n\n private vaultNotSupported(): never {\n throw new Error(\"Vault operations require the Postgres backend\");\n }\n\n async upsertVaultFile(): Promise<void> { this.vaultNotSupported(); }\n async deleteVaultFile(): Promise<void> { this.vaultNotSupported(); }\n async getVaultFile(): Promise<null> { this.vaultNotSupported(); }\n async getVaultFileByInode(): Promise<null> { this.vaultNotSupported(); }\n async getAllVaultFiles(): Promise<never[]> { this.vaultNotSupported(); }\n async getRecentVaultFiles(): Promise<never[]> { this.vaultNotSupported(); }\n async countVaultFiles(): Promise<number> { this.vaultNotSupported(); }\n async upsertVaultAliases(): Promise<void> { this.vaultNotSupported(); }\n async deleteVaultAliases(): Promise<void> { this.vaultNotSupported(); }\n async replaceLinksForSources(): Promise<void> { this.vaultNotSupported(); }\n async getLinksFromSource(): Promise<never[]> { this.vaultNotSupported(); }\n async getLinksToTarget(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkGraph(): Promise<never[]> { this.vaultNotSupported(); }\n async upsertVaultHealth(): Promise<void> { this.vaultNotSupported(); }\n async getVaultHealth(): Promise<null> { this.vaultNotSupported(); }\n async getOrphans(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinks(): Promise<never[]> { this.vaultNotSupported(); }\n async upsertNameIndex(): Promise<void> { this.vaultNotSupported(); }\n async replaceNameIndex(): Promise<void> { this.vaultNotSupported(); }\n async resolveVaultName(): Promise<never[]> { this.vaultNotSupported(); }\n async searchVaultNameIndex(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilesByPaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilesByPathsAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinksFromPaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getChunksWithEmbeddings(): Promise<never[]> { this.vaultNotSupported(); }\n async getChunksForPath(): Promise<never[]> { this.vaultNotSupported(); }\n async searchChunksByText(): Promise<never[]> { this.vaultNotSupported(); }\n async countVaultFilesWithPrefix(): Promise<number> { this.vaultNotSupported(); }\n async countVaultFilesAfter(): Promise<number> { this.vaultNotSupported(); }\n async countVaultLinksWithPrefix(): Promise<number> { this.vaultNotSupported(); }\n async countVaultLinksAfter(): Promise<number> { this.vaultNotSupported(); }\n async getDeadLinksWithLineNumbers(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinksWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinksAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getOrphansWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getOrphansAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivity(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivityWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivityAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getAllVaultFilePaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilePathsWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilePathsAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdges(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdgesWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdgesAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultAlias(): Promise<null> { this.vaultNotSupported(); }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sqlite-ChSCYwiC.mjs","names":[],"sources":["../src/storage/sqlite.ts"],"sourcesContent":["/**\n * SQLiteBackend — wraps the existing better-sqlite3 federation.db\n * behind the StorageBackend interface.\n *\n * This is a thin adapter. The heavy lifting is all in the existing\n * memory/indexer.ts and memory/search.ts code; we just provide a\n * backend-agnostic surface so the daemon and tools can call either\n * SQLite or Postgres transparently.\n */\n\nimport type { Database } from \"better-sqlite3\";\nimport type { StorageBackend, ChunkRow, FileRow, FederationStats } from \"./interface.js\";\nimport type { SearchResult, SearchOptions } from \"../memory/search.js\";\nimport { searchMemory, searchMemorySemantic } from \"../memory/search.js\";\n\nexport class SQLiteBackend implements StorageBackend {\n readonly backendType = \"sqlite\" as const;\n\n private db: Database;\n\n constructor(db: Database) {\n this.db = db;\n }\n\n /**\n * Expose the raw better-sqlite3 Database handle.\n * Used by the daemon to pass to indexAll() which still uses the synchronous API directly.\n */\n getRawDb(): Database {\n return this.db;\n }\n\n /**\n * Alias for getRawDb() — used by the dispatcher for operations that require\n * direct SQLite access (e.g. memory_feedback, touchChunksLastAccessed).\n */\n getSqliteDb(): Database {\n return this.db;\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async close(): Promise<void> {\n try {\n this.db.close();\n } catch {\n // ignore\n }\n }\n\n async getStats(): Promise<FederationStats> {\n const files = (\n this.db.prepare(\"SELECT COUNT(*) AS n FROM memory_files\").get() as { n: number }\n ).n;\n const chunks = (\n this.db.prepare(\"SELECT COUNT(*) AS n FROM memory_chunks\").get() as { n: number }\n ).n;\n return { files, chunks };\n }\n\n // -------------------------------------------------------------------------\n // File tracking\n // -------------------------------------------------------------------------\n\n async getFileHash(projectId: number, path: string): Promise<string | undefined> {\n const row = this.db\n .prepare(\"SELECT hash FROM memory_files WHERE project_id = ? AND path = ?\")\n .get(projectId, path) as { hash: string } | undefined;\n return row?.hash;\n }\n\n async upsertFile(file: FileRow): Promise<void> {\n this.db\n .prepare(\n `INSERT INTO memory_files (project_id, path, source, tier, hash, mtime, size)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(project_id, path) DO UPDATE SET\n source = excluded.source,\n tier = excluded.tier,\n hash = excluded.hash,\n mtime = excluded.mtime,\n size = excluded.size`\n )\n .run(file.projectId, file.path, file.source, file.tier, file.hash, file.mtime, file.size);\n }\n\n // -------------------------------------------------------------------------\n // Chunk management\n // -------------------------------------------------------------------------\n\n async getChunkIds(projectId: number, path: string): Promise<string[]> {\n const rows = this.db\n .prepare(\"SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?\")\n .all(projectId, path) as Array<{ id: string }>;\n return rows.map((r) => r.id);\n }\n\n async deleteChunksForFile(projectId: number, path: string): Promise<void> {\n const ids = await this.getChunkIds(projectId, path);\n const deleteFts = this.db.prepare(\"DELETE FROM memory_fts WHERE id = ?\");\n const deleteChunks = this.db.prepare(\n \"DELETE FROM memory_chunks WHERE project_id = ? AND path = ?\"\n );\n this.db.transaction(() => {\n for (const id of ids) {\n deleteFts.run(id);\n }\n deleteChunks.run(projectId, path);\n })();\n }\n\n async insertChunks(chunks: ChunkRow[]): Promise<void> {\n if (chunks.length === 0) return;\n\n const insertChunk = this.db.prepare(\n `INSERT INTO memory_chunks (id, project_id, source, tier, path, start_line, end_line, hash, text, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n const insertFts = this.db.prepare(\n `INSERT INTO memory_fts (text, id, project_id, path, source, tier, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n this.db.transaction(() => {\n for (const c of chunks) {\n insertChunk.run(\n c.id,\n c.projectId,\n c.source,\n c.tier,\n c.path,\n c.startLine,\n c.endLine,\n c.hash,\n c.text,\n c.updatedAt\n );\n insertFts.run(\n c.text,\n c.id,\n c.projectId,\n c.path,\n c.source,\n c.tier,\n c.startLine,\n c.endLine\n );\n }\n })();\n }\n\n async getDistinctChunkPaths(projectId: number): Promise<string[]> {\n const rows = this.db\n .prepare(\"SELECT DISTINCT path FROM memory_chunks WHERE project_id = ?\")\n .all(projectId) as Array<{ path: string }>;\n return rows.map((r) => r.path);\n }\n\n async deletePaths(projectId: number, paths: string[]): Promise<void> {\n if (paths.length === 0) return;\n const deleteFts = this.db.prepare(\"DELETE FROM memory_fts WHERE id = ?\");\n const deleteChunks = this.db.prepare(\n \"DELETE FROM memory_chunks WHERE project_id = ? AND path = ?\"\n );\n const deleteFile = this.db.prepare(\n \"DELETE FROM memory_files WHERE project_id = ? AND path = ?\"\n );\n this.db.transaction(() => {\n for (const path of paths) {\n const ids = this.db\n .prepare(\"SELECT id FROM memory_chunks WHERE project_id = ? AND path = ?\")\n .all(projectId, path) as Array<{ id: string }>;\n for (const { id } of ids) {\n deleteFts.run(id);\n }\n deleteChunks.run(projectId, path);\n deleteFile.run(projectId, path);\n }\n })();\n }\n\n async getUnembeddedChunkIds(projectId?: number): Promise<Array<{ id: string; text: string; project_id: number; path: string }>> {\n const conditions = [\"embedding IS NULL\"];\n const params: (string | number)[] = [];\n\n if (projectId !== undefined) {\n conditions.push(\"project_id = ?\");\n params.push(projectId);\n }\n\n const where = \"WHERE \" + conditions.join(\" AND \");\n // Prioritize real knowledge notes over PAI session/job-search noise.\n // CASE expression assigns lower priority numbers to knowledge paths.\n const rows = this.db\n .prepare(`SELECT id, text, project_id, path FROM memory_chunks ${where}\n ORDER BY CASE\n WHEN path LIKE '🧠 Ideaverse/%' THEN 0\n WHEN path LIKE 'Z - Zettelkasten/%' THEN 0\n WHEN path LIKE '💼 Business/%' THEN 0\n WHEN path LIKE '📆 Meetings/%' THEN 1\n WHEN path LIKE '💡 Insights/%' THEN 1\n WHEN path LIKE '👨💻 People/%' THEN 1\n WHEN path LIKE 'University/%' THEN 1\n WHEN path LIKE 'Copilot/%' THEN 1\n WHEN path LIKE '🗓️ Daily Notes/%' THEN 2\n WHEN path LIKE 'PAI/%' THEN 3\n WHEN path LIKE '09-job-search/%' THEN 4\n WHEN path LIKE 'seriousletter/%' THEN 4\n WHEN path LIKE 'Attachments/%' THEN 5\n ELSE 2\n END, id`)\n .all(...params) as Array<{ id: string; text: string; project_id: number; path: string }>;\n return rows;\n }\n\n async updateEmbedding(chunkId: string, embedding: Buffer): Promise<void> {\n this.db\n .prepare(\"UPDATE memory_chunks SET embedding = ? WHERE id = ?\")\n .run(embedding, chunkId);\n }\n\n // -------------------------------------------------------------------------\n // Search\n // -------------------------------------------------------------------------\n\n async searchKeyword(query: string, opts?: SearchOptions): Promise<SearchResult[]> {\n return searchMemory(this.db, query, opts);\n }\n\n async searchSemantic(queryEmbedding: Float32Array, opts?: SearchOptions): Promise<SearchResult[]> {\n return searchMemorySemantic(this.db, queryEmbedding, opts);\n }\n\n // -------------------------------------------------------------------------\n // Vault operations — not supported on SQLite backend (use Postgres)\n // -------------------------------------------------------------------------\n\n private vaultNotSupported(): never {\n throw new Error(\"Vault operations require the Postgres backend\");\n }\n\n async upsertVaultFile(): Promise<void> { this.vaultNotSupported(); }\n async deleteVaultFile(): Promise<void> { this.vaultNotSupported(); }\n async getVaultFile(): Promise<null> { this.vaultNotSupported(); }\n async getVaultFileByInode(): Promise<null> { this.vaultNotSupported(); }\n async getAllVaultFiles(): Promise<never[]> { this.vaultNotSupported(); }\n async getRecentVaultFiles(): Promise<never[]> { this.vaultNotSupported(); }\n async countVaultFiles(): Promise<number> { this.vaultNotSupported(); }\n async upsertVaultAliases(): Promise<void> { this.vaultNotSupported(); }\n async deleteVaultAliases(): Promise<void> { this.vaultNotSupported(); }\n async replaceLinksForSources(): Promise<void> { this.vaultNotSupported(); }\n async getLinksFromSource(): Promise<never[]> { this.vaultNotSupported(); }\n async getLinksToTarget(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkGraph(): Promise<never[]> { this.vaultNotSupported(); }\n async upsertVaultHealth(): Promise<void> { this.vaultNotSupported(); }\n async getVaultHealth(): Promise<null> { this.vaultNotSupported(); }\n async getOrphans(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinks(): Promise<never[]> { this.vaultNotSupported(); }\n async upsertNameIndex(): Promise<void> { this.vaultNotSupported(); }\n async replaceNameIndex(): Promise<void> { this.vaultNotSupported(); }\n async resolveVaultName(): Promise<never[]> { this.vaultNotSupported(); }\n async searchVaultNameIndex(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilesByPaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilesByPathsAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinksFromPaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getChunksWithEmbeddings(): Promise<never[]> { this.vaultNotSupported(); }\n async getChunksForPath(): Promise<never[]> { this.vaultNotSupported(); }\n async searchChunksByText(): Promise<never[]> { this.vaultNotSupported(); }\n async countVaultFilesWithPrefix(): Promise<number> { this.vaultNotSupported(); }\n async countVaultFilesAfter(): Promise<number> { this.vaultNotSupported(); }\n async countVaultLinksWithPrefix(): Promise<number> { this.vaultNotSupported(); }\n async countVaultLinksAfter(): Promise<number> { this.vaultNotSupported(); }\n async getDeadLinksWithLineNumbers(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinksWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getDeadLinksAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getOrphansWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getOrphansAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivity(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivityWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getLowConnectivityAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getAllVaultFilePaths(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilePathsWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultFilePathsAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdges(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdgesWithPrefix(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultLinkEdgesAfter(): Promise<never[]> { this.vaultNotSupported(); }\n async getVaultAlias(): Promise<null> { this.vaultNotSupported(); }\n}\n"],"mappings":"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"}
|
|
@@ -99,4 +99,4 @@ function setLastVaultIndexTime(v) {
|
|
|
99
99
|
|
|
100
100
|
//#endregion
|
|
101
101
|
export { setStorageBackend as C, state_exports as D, startTime as E, storageBackend as O, setStartTime as S, shutdownRequested as T, setLastIndexTime as _, indexSchedulerTimer as a, setRegistryDb as b, lastVaultIndexTime as c, setDaemonConfig as d, setEmbedInProgress as f, setLastEmbedTime as g, setIndexSchedulerTimer as h, indexInProgress as i, vaultIndexInProgress as k, notificationConfig as l, setIndexInProgress as m, embedInProgress as n, lastEmbedTime as o, setEmbedSchedulerTimer as p, embedSchedulerTimer as r, lastIndexTime as s, daemonConfig as t, registryDb as u, setLastVaultIndexTime as v, setVaultIndexInProgress as w, setShutdownRequested as x, setNotificationConfig as y };
|
|
102
|
-
//# sourceMappingURL=state-
|
|
102
|
+
//# sourceMappingURL=state-BXIdbxDs.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-
|
|
1
|
+
{"version":3,"file":"state-BXIdbxDs.mjs","names":[],"sources":["../src/daemon/daemon/state.ts"],"sourcesContent":["/**\n * Shared mutable daemon state — module-level singletons used across all daemon sub-modules.\n */\n\nimport { openRegistry } from \"../../registry/db.js\";\nimport type { StorageBackend } from \"../../storage/interface.js\";\nimport type { NotificationConfig } from \"../../notifications/types.js\";\nimport type { PaiDaemonConfig } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Core singletons (assigned at startup by serve())\n// ---------------------------------------------------------------------------\n\nexport let registryDb: ReturnType<typeof openRegistry>;\nexport let storageBackend: StorageBackend;\nexport let daemonConfig: PaiDaemonConfig;\nexport let startTime = Date.now();\n\n// ---------------------------------------------------------------------------\n// Scheduler state\n// ---------------------------------------------------------------------------\n\n/** True while a project index pass is running. */\nexport let indexInProgress = false;\nexport let lastIndexTime = 0;\nexport let indexSchedulerTimer: ReturnType<typeof setInterval> | null = null;\n\n/** True while an embedding pass is running. */\nexport let embedInProgress = false;\nexport let lastEmbedTime = 0;\nexport let embedSchedulerTimer: ReturnType<typeof setInterval> | null = null;\n\n/** True while a vault index pass is running. */\nexport let vaultIndexInProgress = false;\nexport let lastVaultIndexTime = 0;\n\n// ---------------------------------------------------------------------------\n// Notification state\n// ---------------------------------------------------------------------------\n\n/** Mutable notification config — loaded from disk at startup, patchable at runtime. */\nexport let notificationConfig: NotificationConfig;\n\n// ---------------------------------------------------------------------------\n// Graceful shutdown flag\n// ---------------------------------------------------------------------------\n\n/**\n * Set to true when a SIGTERM/SIGINT is received so that long-running loops\n * (embed, index) can detect the signal and exit their inner loops before the\n * pool/backend is closed.\n */\nexport let shutdownRequested = false;\n\n// ---------------------------------------------------------------------------\n// Setters (TypeScript requires assignment functions for exported `let` vars\n// that need to be mutated across module boundaries)\n// ---------------------------------------------------------------------------\n\nexport function setRegistryDb(db: ReturnType<typeof openRegistry>): void { registryDb = db; }\nexport function setStorageBackend(b: StorageBackend): void { storageBackend = b; }\nexport function setDaemonConfig(c: PaiDaemonConfig): void { daemonConfig = c; }\nexport function setStartTime(t: number): void { startTime = t; }\nexport function setNotificationConfig(c: NotificationConfig): void { notificationConfig = c; }\nexport function setShutdownRequested(v: boolean): void { shutdownRequested = v; }\nexport function setIndexInProgress(v: boolean): void { indexInProgress = v; }\nexport function setLastIndexTime(v: number): void { lastIndexTime = v; }\nexport function setIndexSchedulerTimer(v: ReturnType<typeof setInterval> | null): void { indexSchedulerTimer = v; }\nexport function setEmbedInProgress(v: boolean): void { embedInProgress = v; }\nexport function setLastEmbedTime(v: number): void { lastEmbedTime = v; }\nexport function setEmbedSchedulerTimer(v: ReturnType<typeof setInterval> | null): void { embedSchedulerTimer = v; }\nexport function setVaultIndexInProgress(v: boolean): void { vaultIndexInProgress = v; }\nexport function setLastVaultIndexTime(v: number): void { lastVaultIndexTime = v; }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,IAAW;AACX,IAAW;AACX,IAAW;AACX,IAAW,YAAY,KAAK,KAAK;;AAOjC,IAAW,kBAAkB;AAC7B,IAAW,gBAAgB;AAC3B,IAAW,sBAA6D;;AAGxE,IAAW,kBAAkB;AAC7B,IAAW,gBAAgB;AAC3B,IAAW,sBAA6D;;AAGxE,IAAW,uBAAuB;AAClC,IAAW,qBAAqB;;AAOhC,IAAW;;;;;;AAWX,IAAW,oBAAoB;AAO/B,SAAgB,cAAc,IAA2C;AAAE,cAAa;;AACxF,SAAgB,kBAAkB,GAAyB;AAAE,kBAAiB;;AAC9E,SAAgB,gBAAgB,GAA0B;AAAE,gBAAe;;AAC3E,SAAgB,aAAa,GAAiB;AAAE,aAAY;;AAC5D,SAAgB,sBAAsB,GAA6B;AAAE,sBAAqB;;AAC1F,SAAgB,qBAAqB,GAAkB;AAAE,qBAAoB;;AAC7E,SAAgB,mBAAmB,GAAkB;AAAE,mBAAkB;;AACzE,SAAgB,iBAAiB,GAAiB;AAAE,iBAAgB;;AACpE,SAAgB,uBAAuB,GAAgD;AAAE,uBAAsB;;AAC/G,SAAgB,mBAAmB,GAAkB;AAAE,mBAAkB;;AACzE,SAAgB,iBAAiB,GAAiB;AAAE,iBAAgB;;AACpE,SAAgB,uBAAuB,GAAgD;AAAE,uBAAsB;;AAC/G,SAAgB,wBAAwB,GAAkB;AAAE,wBAAuB;;AACnF,SAAgB,sBAAsB,GAAiB;AAAE,sBAAqB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-words-
|
|
1
|
+
{"version":3,"file":"stop-words-BaMEGVeY.mjs","names":[],"sources":["../src/utils/stop-words.ts"],"sourcesContent":["/**\n * Shared stop-word list used across memory search, slug generation, graph clustering,\n * and zettelkasten modules. This is the union of all per-file sets that previously\n * existed in 7 different files.\n */\n\nexport const STOP_WORDS = new Set([\n // Articles / determiners\n \"a\", \"an\", \"the\",\n // Conjunctions\n \"and\", \"or\", \"but\", \"if\", \"then\", \"else\", \"so\", \"because\", \"as\",\n \"although\", \"however\", \"therefore\", \"thus\", \"hence\", \"meanwhile\",\n \"moreover\", \"furthermore\", \"otherwise\", \"instead\", \"anyway\",\n // Prepositions\n \"at\", \"to\", \"for\", \"of\", \"with\", \"by\", \"from\", \"in\", \"on\", \"out\",\n \"off\", \"over\", \"under\", \"up\", \"into\", \"without\", \"per\", \"via\",\n // Pronouns\n \"i\", \"you\", \"we\", \"they\", \"he\", \"she\", \"it\", \"me\", \"us\", \"him\", \"her\",\n \"my\", \"your\", \"our\", \"their\", \"his\", \"its\", \"who\", \"whom\", \"what\",\n \"which\", \"this\", \"that\", \"these\", \"those\",\n // Common verbs\n \"is\", \"are\", \"was\", \"were\", \"be\", \"been\", \"being\",\n \"have\", \"has\", \"had\", \"do\", \"does\", \"did\",\n \"will\", \"would\", \"could\", \"should\", \"may\", \"might\", \"can\", \"shall\",\n \"want\", \"need\", \"know\", \"think\", \"see\", \"look\", \"make\", \"get\", \"go\",\n \"come\", \"take\", \"use\", \"find\", \"give\", \"tell\", \"say\", \"said\", \"try\",\n \"keep\", \"run\", \"set\", \"put\", \"add\", \"show\", \"check\", \"let\",\n // Negation / common function words\n \"not\", \"no\", \"yes\", \"just\", \"also\", \"very\", \"really\",\n \"about\", \"after\", \"before\",\n \"more\", \"most\", \"some\", \"any\", \"all\", \"each\", \"every\", \"both\", \"few\",\n \"many\", \"much\", \"other\", \"another\", \"such\", \"only\", \"own\", \"same\",\n \"than\", \"too\", \"ok\", \"okay\", \"sure\",\n \"please\", \"thanks\", \"thank\", \"here\", \"there\", \"now\", \"well\", \"like\",\n \"going\", \"done\", \"got\",\n // Tech/URL junk\n \"https\", \"http\", \"www\", \"com\", \"org\", \"net\", \"io\",\n \"null\", \"undefined\", \"true\", \"false\",\n // Contractions (de-apostrophe'd forms that appear after tokenisation)\n \"ll\", \"ve\", \"re\", \"don\", \"thats\", \"heres\", \"theres\",\n \"youre\", \"theyre\", \"didnt\", \"dont\", \"doesnt\", \"havent\", \"hasnt\",\n \"wont\", \"cant\", \"shouldnt\", \"wouldnt\", \"couldnt\", \"isnt\", \"arent\",\n \"wasnt\", \"werent\",\n // Filler adverbs\n \"never\", \"ever\", \"still\", \"already\", \"yet\", \"back\",\n \"away\", \"down\", \"right\", \"left\", \"next\", \"last\", \"first\", \"second\",\n \"third\",\n \"then\", \"again\", \"once\", \"twice\", \"since\", \"while\", \"though\",\n \"actually\", \"basically\", \"literally\", \"simply\", \"exactly\", \"probably\",\n \"possibly\", \"maybe\", \"perhaps\", \"certainly\", \"definitely\", \"absolutely\",\n \"completely\", \"totally\", \"quite\", \"rather\", \"fairly\", \"nearly\",\n \"almost\", \"barely\", \"hardly\", \"quickly\", \"slowly\", \"easily\", \"likely\",\n \"unlikely\",\n // Numbers (spelled out)\n \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\",\n \"eight\", \"nine\", \"ten\",\n // Common nouns (too generic for search/slug)\n \"time\", \"way\", \"thing\", \"something\", \"anything\", \"nothing\",\n \"everything\", \"someone\", \"anyone\", \"everyone\",\n // Zettelkasten / vault-specific noise\n \"new\", \"note\", \"untitled\", \"page\", \"file\", \"doc\", \"code\",\n \"session\", \"notes\", \"moc\", \"template\", \"content\", \"attachment\",\n // Misc abbreviations\n \"etc\", \"ie\", \"eg\", \"vs\",\n // French stop words (for multilingual vaults)\n \"les\", \"des\", \"une\", \"est\", \"que\", \"qui\", \"dans\", \"pour\", \"sur\",\n \"par\", \"pas\", \"son\", \"ses\", \"aux\", \"avec\", \"tout\", \"mais\",\n // German stop words (for multilingual vaults)\n \"und\", \"der\", \"die\", \"das\", \"ein\", \"eine\", \"ist\", \"den\", \"dem\",\n \"von\", \"mit\", \"auf\", \"nicht\", \"sich\", \"auch\", \"noch\", \"wie\",\n]);\n\n/**\n * Alias used by graph modules that need stop-word filtering specifically for\n * vault note titles (same set, just semantically named for clarity).\n */\nexport const TITLE_STOP_WORDS = STOP_WORDS;\n"],"mappings":";;;;;;AAMA,MAAa,aAAa,IAAI,IAAI;CAEhC;CAAK;CAAM;CAEX;CAAO;CAAM;CAAO;CAAM;CAAQ;CAAQ;CAAM;CAAW;CAC3D;CAAY;CAAW;CAAa;CAAQ;CAAS;CACrD;CAAY;CAAe;CAAa;CAAW;CAEnD;CAAM;CAAM;CAAO;CAAM;CAAQ;CAAM;CAAQ;CAAM;CAAM;CAC3D;CAAO;CAAQ;CAAS;CAAM;CAAQ;CAAW;CAAO;CAExD;CAAK;CAAO;CAAM;CAAQ;CAAM;CAAO;CAAM;CAAM;CAAM;CAAO;CAChE;CAAM;CAAQ;CAAO;CAAS;CAAO;CAAO;CAAO;CAAQ;CAC3D;CAAS;CAAQ;CAAQ;CAAS;CAElC;CAAM;CAAO;CAAO;CAAQ;CAAM;CAAQ;CAC1C;CAAQ;CAAO;CAAO;CAAM;CAAQ;CACpC;CAAQ;CAAS;CAAS;CAAU;CAAO;CAAS;CAAO;CAC3D;CAAQ;CAAQ;CAAQ;CAAS;CAAO;CAAQ;CAAQ;CAAO;CAC/D;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAC9D;CAAQ;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAS;CAErD;CAAO;CAAM;CAAO;CAAQ;CAAQ;CAAQ;CAC5C;CAAS;CAAS;CAClB;CAAQ;CAAQ;CAAQ;CAAO;CAAO;CAAQ;CAAS;CAAQ;CAC/D;CAAQ;CAAQ;CAAS;CAAW;CAAQ;CAAQ;CAAO;CAC3D;CAAQ;CAAO;CAAM;CAAQ;CAC7B;CAAU;CAAU;CAAS;CAAQ;CAAS;CAAO;CAAQ;CAC7D;CAAS;CAAQ;CAEjB;CAAS;CAAQ;CAAO;CAAO;CAAO;CAAO;CAC7C;CAAQ;CAAa;CAAQ;CAE7B;CAAM;CAAM;CAAM;CAAO;CAAS;CAAS;CAC3C;CAAS;CAAU;CAAS;CAAQ;CAAU;CAAU;CACxD;CAAQ;CAAQ;CAAY;CAAW;CAAW;CAAQ;CAC1D;CAAS;CAET;CAAS;CAAQ;CAAS;CAAW;CAAO;CAC5C;CAAQ;CAAQ;CAAS;CAAQ;CAAQ;CAAQ;CAAS;CAC1D;CACA;CAAQ;CAAS;CAAQ;CAAS;CAAS;CAAS;CACpD;CAAY;CAAa;CAAa;CAAU;CAAW;CAC3D;CAAY;CAAS;CAAW;CAAa;CAAc;CAC3D;CAAc;CAAW;CAAS;CAAU;CAAU;CACtD;CAAU;CAAU;CAAU;CAAW;CAAU;CAAU;CAC7D;CAEA;CAAO;CAAO;CAAS;CAAQ;CAAQ;CAAO;CAC9C;CAAS;CAAQ;CAEjB;CAAQ;CAAO;CAAS;CAAa;CAAY;CACjD;CAAc;CAAW;CAAU;CAEnC;CAAO;CAAQ;CAAY;CAAQ;CAAQ;CAAO;CAClD;CAAW;CAAS;CAAO;CAAY;CAAW;CAElD;CAAO;CAAM;CAAM;CAEnB;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAQ;CAC1D;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAQ;CAEnD;CAAO;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAO;CAAO;CACzD;CAAO;CAAO;CAAO;CAAS;CAAQ;CAAQ;CAAQ;CACvD,CAAC;;;;;AAMF,MAAa,mBAAmB"}
|
|
@@ -1,206 +1,7 @@
|
|
|
1
|
-
import { a as parseSessionTitleChunk, c as yieldToEventLoop, f as sha256File, i as isPathTooBroadForContentScan, l as chunkMarkdown, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY } from "./helpers-
|
|
2
|
-
import { existsSync,
|
|
3
|
-
import {
|
|
4
|
-
import { basename, dirname, join, relative } from "node:path";
|
|
5
|
-
import BetterSqlite3 from "better-sqlite3";
|
|
1
|
+
import { a as parseSessionTitleChunk, c as yieldToEventLoop, f as sha256File, i as isPathTooBroadForContentScan, l as chunkMarkdown, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY } from "./helpers-crDEr6S2.mjs";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { basename, join, relative } from "node:path";
|
|
6
4
|
|
|
7
|
-
//#region src/registry/schema.ts
|
|
8
|
-
const SCHEMA_VERSION = 4;
|
|
9
|
-
const CREATE_TABLES_SQL = `
|
|
10
|
-
PRAGMA journal_mode = WAL;
|
|
11
|
-
PRAGMA foreign_keys = ON;
|
|
12
|
-
|
|
13
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
14
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15
|
-
slug TEXT NOT NULL UNIQUE,
|
|
16
|
-
display_name TEXT NOT NULL,
|
|
17
|
-
root_path TEXT NOT NULL UNIQUE,
|
|
18
|
-
encoded_dir TEXT NOT NULL UNIQUE,
|
|
19
|
-
type TEXT NOT NULL DEFAULT 'local'
|
|
20
|
-
CHECK(type IN ('local','central','obsidian-linked','external')),
|
|
21
|
-
status TEXT NOT NULL DEFAULT 'active'
|
|
22
|
-
CHECK(status IN ('active','archived','migrating')),
|
|
23
|
-
parent_id INTEGER,
|
|
24
|
-
obsidian_link TEXT,
|
|
25
|
-
claude_notes_dir TEXT,
|
|
26
|
-
session_config TEXT,
|
|
27
|
-
created_at INTEGER NOT NULL,
|
|
28
|
-
updated_at INTEGER NOT NULL,
|
|
29
|
-
archived_at INTEGER,
|
|
30
|
-
FOREIGN KEY (parent_id) REFERENCES projects(id)
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
CREATE TABLE IF NOT EXISTS sessions (
|
|
34
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
-
project_id INTEGER NOT NULL,
|
|
36
|
-
number INTEGER NOT NULL,
|
|
37
|
-
date TEXT NOT NULL,
|
|
38
|
-
slug TEXT NOT NULL,
|
|
39
|
-
title TEXT NOT NULL,
|
|
40
|
-
filename TEXT NOT NULL,
|
|
41
|
-
status TEXT NOT NULL DEFAULT 'open'
|
|
42
|
-
CHECK(status IN ('open','completed','compacted')),
|
|
43
|
-
claude_session_id TEXT,
|
|
44
|
-
token_count INTEGER,
|
|
45
|
-
created_at INTEGER NOT NULL,
|
|
46
|
-
closed_at INTEGER,
|
|
47
|
-
UNIQUE (project_id, number),
|
|
48
|
-
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
CREATE TABLE IF NOT EXISTS tags (
|
|
52
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
53
|
-
name TEXT NOT NULL UNIQUE
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
CREATE TABLE IF NOT EXISTS project_tags (
|
|
57
|
-
project_id INTEGER NOT NULL,
|
|
58
|
-
tag_id INTEGER NOT NULL,
|
|
59
|
-
PRIMARY KEY (project_id, tag_id),
|
|
60
|
-
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
61
|
-
FOREIGN KEY (tag_id) REFERENCES tags(id)
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
CREATE TABLE IF NOT EXISTS session_tags (
|
|
65
|
-
session_id INTEGER NOT NULL,
|
|
66
|
-
tag_id INTEGER NOT NULL,
|
|
67
|
-
PRIMARY KEY (session_id, tag_id),
|
|
68
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
69
|
-
FOREIGN KEY (tag_id) REFERENCES tags(id)
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
CREATE TABLE IF NOT EXISTS aliases (
|
|
73
|
-
alias TEXT PRIMARY KEY,
|
|
74
|
-
project_id INTEGER NOT NULL,
|
|
75
|
-
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
CREATE TABLE IF NOT EXISTS compaction_log (
|
|
79
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
80
|
-
project_id INTEGER NOT NULL,
|
|
81
|
-
session_id INTEGER,
|
|
82
|
-
trigger TEXT NOT NULL
|
|
83
|
-
CHECK(trigger IN ('precompact','manual','end-session')),
|
|
84
|
-
files_written TEXT NOT NULL,
|
|
85
|
-
token_count INTEGER,
|
|
86
|
-
created_at INTEGER NOT NULL,
|
|
87
|
-
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
88
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
CREATE TABLE IF NOT EXISTS links (
|
|
92
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
93
|
-
session_id INTEGER NOT NULL,
|
|
94
|
-
target_project_id INTEGER NOT NULL,
|
|
95
|
-
link_type TEXT NOT NULL DEFAULT 'related'
|
|
96
|
-
CHECK(link_type IN ('related','follow-up','reference')),
|
|
97
|
-
created_at INTEGER NOT NULL,
|
|
98
|
-
UNIQUE (session_id, target_project_id),
|
|
99
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
100
|
-
FOREIGN KEY (target_project_id) REFERENCES projects(id)
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
CREATE TABLE IF NOT EXISTS schema_version (
|
|
104
|
-
version INTEGER PRIMARY KEY,
|
|
105
|
-
applied_at INTEGER NOT NULL
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
-- Indexes
|
|
109
|
-
CREATE INDEX IF NOT EXISTS idx_projects_slug ON projects(slug);
|
|
110
|
-
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
|
|
111
|
-
CREATE INDEX IF NOT EXISTS idx_projects_type ON projects(type);
|
|
112
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id);
|
|
113
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(date);
|
|
114
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
115
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_claude ON sessions(claude_session_id);
|
|
116
|
-
CREATE INDEX IF NOT EXISTS idx_pc_project ON project_tags(project_id);
|
|
117
|
-
`;
|
|
118
|
-
/**
|
|
119
|
-
* Run the full DDL against an open database connection.
|
|
120
|
-
*
|
|
121
|
-
* The function is idempotent — every statement uses IF NOT EXISTS so it is
|
|
122
|
-
* safe to call on an already-initialised database. After creating the tables
|
|
123
|
-
* it inserts the current SCHEMA_VERSION into schema_version if no row exists
|
|
124
|
-
* yet.
|
|
125
|
-
*/
|
|
126
|
-
function initializeSchema(db) {
|
|
127
|
-
db.exec(CREATE_TABLES_SQL);
|
|
128
|
-
if (!db.prepare("SELECT version FROM schema_version WHERE version = ?").get(SCHEMA_VERSION)) db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (?, ?)").run(SCHEMA_VERSION, Date.now());
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Apply incremental schema migrations to an already-initialised database.
|
|
132
|
-
*
|
|
133
|
-
* Each migration is guarded by a version check so it is safe to call on
|
|
134
|
-
* databases at any schema version — already-applied migrations are skipped.
|
|
135
|
-
*/
|
|
136
|
-
function runMigrations(db) {
|
|
137
|
-
const current = db.prepare("SELECT version FROM schema_version ORDER BY version DESC LIMIT 1").get()?.version ?? 0;
|
|
138
|
-
if (current < 2) db.transaction(() => {
|
|
139
|
-
try {
|
|
140
|
-
db.exec("ALTER TABLE projects ADD COLUMN claude_notes_dir TEXT");
|
|
141
|
-
} catch {}
|
|
142
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(2, Date.now());
|
|
143
|
-
})();
|
|
144
|
-
if (current < 3) db.transaction(() => {
|
|
145
|
-
try {
|
|
146
|
-
db.exec(`
|
|
147
|
-
CREATE TABLE IF NOT EXISTS links (
|
|
148
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
149
|
-
session_id INTEGER NOT NULL,
|
|
150
|
-
target_project_id INTEGER NOT NULL,
|
|
151
|
-
link_type TEXT NOT NULL DEFAULT 'related'
|
|
152
|
-
CHECK(link_type IN ('related','follow-up','reference')),
|
|
153
|
-
created_at INTEGER NOT NULL,
|
|
154
|
-
UNIQUE (session_id, target_project_id),
|
|
155
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id),
|
|
156
|
-
FOREIGN KEY (target_project_id) REFERENCES projects(id)
|
|
157
|
-
)
|
|
158
|
-
`);
|
|
159
|
-
} catch {}
|
|
160
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(3, Date.now());
|
|
161
|
-
})();
|
|
162
|
-
if (current < 4) db.transaction(() => {
|
|
163
|
-
try {
|
|
164
|
-
db.exec("ALTER TABLE projects ADD COLUMN session_config TEXT");
|
|
165
|
-
} catch {}
|
|
166
|
-
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, ?)").run(4, Date.now());
|
|
167
|
-
})();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/registry/db.ts
|
|
172
|
-
/**
|
|
173
|
-
* Database connection helper for the PAI registry.
|
|
174
|
-
*
|
|
175
|
-
* Uses better-sqlite3 (synchronous API) to open or create registry.db.
|
|
176
|
-
* On first open it runs the full DDL via initializeSchema().
|
|
177
|
-
*/
|
|
178
|
-
/** Default registry path inside the ~/.pai/ directory. */
|
|
179
|
-
const DEFAULT_REGISTRY_PATH = join(homedir(), ".pai", "registry.db");
|
|
180
|
-
/**
|
|
181
|
-
* Open (or create) the PAI registry database.
|
|
182
|
-
*
|
|
183
|
-
* @param path Absolute path to registry.db. Defaults to ~/.pai/registry.db.
|
|
184
|
-
* @returns An open better-sqlite3 Database instance.
|
|
185
|
-
*
|
|
186
|
-
* Side effects on first call:
|
|
187
|
-
* - Creates the parent directory if it does not exist.
|
|
188
|
-
* - Enables WAL journal mode.
|
|
189
|
-
* - Runs initializeSchema() if schema_version is empty.
|
|
190
|
-
*/
|
|
191
|
-
function openRegistry(path = DEFAULT_REGISTRY_PATH) {
|
|
192
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
193
|
-
const db = new BetterSqlite3(path);
|
|
194
|
-
db.pragma("journal_mode = WAL");
|
|
195
|
-
db.pragma("foreign_keys = ON");
|
|
196
|
-
if (!db.prepare(`SELECT name FROM sqlite_master
|
|
197
|
-
WHERE type = 'table' AND name = 'schema_version'`).get()) initializeSchema(db);
|
|
198
|
-
else if (!db.prepare("SELECT version FROM schema_version LIMIT 1").get()) initializeSchema(db);
|
|
199
|
-
runMigrations(db);
|
|
200
|
-
return db;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
//#endregion
|
|
204
5
|
//#region src/memory/indexer/sync.ts
|
|
205
6
|
/**
|
|
206
7
|
* Synchronous (SQLite) indexer for the PAI federation memory engine.
|
|
@@ -466,7 +267,7 @@ async function indexAll(db, registryDb) {
|
|
|
466
267
|
* @param onProgress Optional callback called after each batch with running totals.
|
|
467
268
|
*/
|
|
468
269
|
async function embedChunks(db, projectId, batchSize = 50, onProgress) {
|
|
469
|
-
const { generateEmbedding, serializeEmbedding } = await import("./embeddings-
|
|
270
|
+
const { generateEmbedding, serializeEmbedding } = await import("./embeddings-DGRAPAYb.mjs").then((n) => n.i);
|
|
470
271
|
const conditions = ["embedding IS NULL"];
|
|
471
272
|
const params = [];
|
|
472
273
|
if (projectId !== void 0) {
|
|
@@ -505,5 +306,5 @@ async function embedChunks(db, projectId, batchSize = 50, onProgress) {
|
|
|
505
306
|
}
|
|
506
307
|
|
|
507
308
|
//#endregion
|
|
508
|
-
export {
|
|
509
|
-
//# sourceMappingURL=sync-
|
|
309
|
+
export { indexProject as i, indexAll as n, indexFile as r, embedChunks as t };
|
|
310
|
+
//# sourceMappingURL=sync-CmBKOL3K.mjs.map
|