@lh8ppl/claude-memory-kit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +77 -0
  2. package/bin/cmk-auto-extract.mjs +62 -0
  3. package/bin/cmk-capture-prompt.mjs +65 -0
  4. package/bin/cmk-capture-turn.mjs +76 -0
  5. package/bin/cmk-compress-lazy.mjs +0 -0
  6. package/bin/cmk-compress-session.mjs +64 -0
  7. package/bin/cmk-daily-distill.mjs +0 -0
  8. package/bin/cmk-inject-context.mjs +69 -0
  9. package/bin/cmk-observe-edit.mjs +57 -0
  10. package/bin/cmk-weekly-curate.mjs +0 -0
  11. package/bin/cmk.mjs +11 -11
  12. package/package.json +10 -2
  13. package/src/audit-log.mjs +1 -0
  14. package/src/claude-md.mjs +212 -212
  15. package/src/doctor.mjs +16 -5
  16. package/src/frontmatter.mjs +73 -73
  17. package/src/install.mjs +49 -1
  18. package/src/merge-facts.mjs +213 -213
  19. package/src/provenance.mjs +217 -217
  20. package/src/reindex.mjs +134 -134
  21. package/src/repair.mjs +26 -96
  22. package/src/settings-hooks.mjs +186 -0
  23. package/src/subcommands.mjs +13 -2
  24. package/template/.gitignore.fragment +12 -12
  25. package/template/CLAUDE.md.template +49 -49
  26. package/template/docs/journey/journey-log.md.template +292 -292
  27. package/template/project/memory/INDEX.md.template +47 -47
  28. package/template/support/cron-jobs/daily-memory-distill.md +15 -15
  29. package/template/support/cron-jobs/nightly-memsearch-index.md +17 -17
  30. package/template/support/cron-jobs/weekly-memory-curator.md +15 -15
  31. package/template/support/milvus-deploy/README.md +57 -57
  32. package/template/support/milvus-deploy/docker-compose.yml +66 -66
  33. package/template/support/scripts/auto-extract-memory.sh +102 -102
  34. package/template/support/scripts/memsearch-index-with-flush.sh +59 -59
  35. package/template/support/scripts/refresh-distill-timestamp.py +35 -35
  36. package/template/support/scripts/register-crons.py +242 -242
  37. package/template/support/scripts/run-daily-distill.sh +67 -67
  38. package/template/support/scripts/run-weekly-curate.sh +58 -58
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # @lh8ppl/claude-memory-kit
2
+
3
+ **`cmk`** — the CLI for [claude-memory-kit](https://github.com/LH8PPL/claude-memory-kit), a per-project, in-repo memory system for [Claude Code](https://docs.claude.com/en/docs/claude-code). It fixes Claude's per-session amnesia so you don't have to re-tell the backstory every time you start a new session.
4
+
5
+ ## What it does
6
+
7
+ - **Frozen snapshot at session start** — MEMORY.md + USER.md + SOUL.md + INDEX.md + today's session log inject once at the first tool call, so Claude sees your context every session without you re-telling it.
8
+ - **Auto-extract on every assistant turn** — a background `claude --print` subagent reads each turn and saves durable facts (decisions, preferences, environment) to memory. No manual writes needed.
9
+ - **`memory-write` skill** — say "remember this", "from now on", "we decided", or "forget X" and the skill dedups, caps, and writes silently.
10
+ - **Per-project, in-repo** — `context/` lives inside your project and travels with `git clone`. Each project keeps its own memory.
11
+ - **9 health checks** — `cmk doctor` validates install, hook wiring, distill freshness, INDEX consistency, cron registration, and stale locks.
12
+
13
+ ## Install — pick ONE route
14
+
15
+ Each route is complete on its own. **Don't run both** — they wire the same hooks.
16
+
17
+ ### Route A — npm (recommended)
18
+
19
+ ```bash
20
+ npm install -g @lh8ppl/claude-memory-kit
21
+ cd ~/my-project
22
+ cmk install # scaffolds context/ AND wires the lifecycle hooks into .claude/settings.json
23
+ cmk doctor # verify, then restart Claude Code
24
+ ```
25
+
26
+ `cmk install` is a complete entry point: it scaffolds `context/` and writes the 5 lifecycle hooks (PATH-resolved, cross-OS) into the project's `.claude/settings.json`. No separate `/plugin` step needed. Use `cmk install --no-hooks` for a scaffold-only install.
27
+
28
+ > Installing the package globally adds the `cmk` CLI **and** the installer. It's the `cmk install` *subcommand* that wires the hooks — not the bare `npm install`.
29
+
30
+ ### Route B — Claude Code plugin marketplace
31
+
32
+ Inside Claude Code:
33
+
34
+ ```text
35
+ /plugin marketplace add LH8PPL/claude-memory-kit
36
+ /plugin install claude-memory-kit
37
+ ```
38
+
39
+ Then say *"bootstrap the memory system"* to scaffold this project's `context/`. The plugin bundles the hooks + the `bootstrap` and `memory-write` skills, so it's complete without the npm CLI (add the CLI later only if you want `cmk search` / `cmk doctor` / cron).
40
+
41
+ ## CLI
42
+
43
+ Most-used commands (full list via `cmk --help`):
44
+
45
+ | Command | Purpose |
46
+ | --- | --- |
47
+ | `cmk install` | Scaffold `context/` + `.gitignore` + CLAUDE.md block + wire hooks (`--no-hooks` for scaffold-only) |
48
+ | `cmk doctor` | Run HC-1..HC-9 health checks, surface repair commands |
49
+ | `cmk repair --hooks` / `--locks` / `--index` / `--all` | Idempotent self-repair |
50
+ | `cmk search "<query>" [--mode keyword\|semantic\|hybrid]` | Search accumulated memory (keyword default) |
51
+ | `cmk roll --scope now\|today\|recent` | Manually trigger a compression pipeline |
52
+ | `cmk register-crons [--dry-run] [--unregister]` | Register daily + weekly jobs with cron / launchd / Task Scheduler |
53
+ | `cmk forget <id>` | Tombstone a fact (preserves audit trail) |
54
+ | `cmk import-anthropic-memory [--dry-run] [--yes]` | Merge bullets from Anthropic's native auto-memory into MEMORY.md |
55
+
56
+ ## Requirements
57
+
58
+ - Node.js ≥ 20
59
+ - Claude Code (for the hook-driven auto-memory loop)
60
+ - Optional: Python 3.12+ for Layer 5b semantic search (deferred to a later release; keyword search ships today)
61
+
62
+ ## Three-tier model
63
+
64
+ | Tier | Location | Scope |
65
+ | --- | --- | --- |
66
+ | **P** (project) | `<repo>/context/` | committed to git, travels with `clone` |
67
+ | **L** (local) | `<repo>/context.local/` | gitignored, per-machine |
68
+ | **U** (user) | `~/.claude-memory-kit/` | cross-project per-user |
69
+
70
+ ## Documentation
71
+
72
+ Full docs, architecture, and design live in the repository:
73
+ **<https://github.com/LH8PPL/claude-memory-kit>**
74
+
75
+ ## License
76
+
77
+ MIT © Lior Hollander
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ // Auto-extract subagent entrypoint — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-auto-extract.mjs (Task 23).
5
+ // NOT declared in package.json `bin` (it's not invoked by Claude Code
6
+ // directly) — it ships in bin/ so the sibling cmk-capture-turn.mjs can
7
+ // spawn it by absolute path. Only the src module paths differ from the
8
+ // plugin copy (../src/ vs ../../packages/cli/src/).
9
+ //
10
+ // Spawned detached by the Stop hook (cmk-capture-turn.mjs):
11
+ // node <thisfile> <turnFile>
12
+ // argv[2] is the turn buffer file path; cwd / CMK_PROJECT_DIR env gives
13
+ // the project root. Never throws to the parent (the spawn is detached);
14
+ // every error path writes an extract.log entry and exits 0.
15
+
16
+ import { dirname, join } from 'node:path';
17
+ import { fileURLToPath, pathToFileURL } from 'node:url';
18
+
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+
22
+ const turnFile = process.argv[2];
23
+ const projectRoot = process.env.CMK_PROJECT_DIR ?? process.cwd();
24
+
25
+ if (!turnFile) {
26
+ process.stderr.write('cmk-auto-extract: missing turnFile argv[2]\n');
27
+ process.exit(0);
28
+ }
29
+
30
+ const autoExtractModulePath = join(__dirname, '..', 'src', 'auto-extract.mjs');
31
+ const compressorModulePath = join(__dirname, '..', 'src', 'compressor.mjs');
32
+
33
+ let runAutoExtract;
34
+ let HaikuViaAnthropicApi;
35
+ try {
36
+ ({ runAutoExtract } = await import(pathToFileURL(autoExtractModulePath).href));
37
+ ({ HaikuViaAnthropicApi } = await import(pathToFileURL(compressorModulePath).href));
38
+ } catch (err) {
39
+ process.stderr.write(
40
+ `cmk-auto-extract: failed to load modules: ${err?.message ?? err}\n`,
41
+ );
42
+ process.exit(0);
43
+ }
44
+
45
+ try {
46
+ const haikuBackend = new HaikuViaAnthropicApi();
47
+ const r = await runAutoExtract({
48
+ turnFile,
49
+ projectRoot,
50
+ haikuBackend,
51
+ sessionId: process.env.CMK_SESSION_ID,
52
+ });
53
+ process.stderr.write(
54
+ `cmk-auto-extract: ${r.action} (observations: ${r.observation_count ?? 0}, ms: ${r.duration_ms ?? 0})\n`,
55
+ );
56
+ } catch (err) {
57
+ process.stderr.write(
58
+ `cmk-auto-extract: unexpected error: ${err?.message ?? err}\n`,
59
+ );
60
+ }
61
+
62
+ process.exit(0);
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ // UserPromptSubmit hook handler — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-capture-prompt.mjs (Task 19).
5
+ // Ships in the @lh8ppl/claude-memory-kit npm package so `cmk install`
6
+ // can wire a PATH-resolved `cmk-capture-prompt` command. Only the src
7
+ // module path differs from the plugin copy (../src/ vs ../../packages/cli/src/).
8
+ //
9
+ // Protocol: payload arrives on stdin as JSON ({prompt, session_id, ...}).
10
+ // Sanitize <private> blocks, preserve <retain> tags, append to the daily
11
+ // transcript, emit {"continue": true}. Always exit 0 — a hook that errors
12
+ // would interrupt the user mid-prompt.
13
+
14
+ import { readFileSync } from 'node:fs';
15
+ import { dirname, join } from 'node:path';
16
+ import { fileURLToPath, pathToFileURL } from 'node:url';
17
+
18
+ function emitContinue() {
19
+ process.stdout.write('{"continue": true}');
20
+ }
21
+
22
+ let rawInput = '';
23
+ try {
24
+ rawInput = readFileSync(0, 'utf8');
25
+ } catch {
26
+ emitContinue();
27
+ process.exit(0);
28
+ }
29
+
30
+ let payload;
31
+ try {
32
+ payload = rawInput.trim() === '' ? {} : JSON.parse(rawInput);
33
+ } catch (err) {
34
+ process.stderr.write(
35
+ `cmk-capture-prompt: failed to parse stdin JSON: ${err?.message ?? err}\n`,
36
+ );
37
+ emitContinue();
38
+ process.exit(0);
39
+ }
40
+
41
+ const __filename = fileURLToPath(import.meta.url);
42
+ const __dirname = dirname(__filename);
43
+ const modulePath = join(__dirname, '..', 'src', 'capture-prompt.mjs');
44
+
45
+ let capturePrompt;
46
+ try {
47
+ ({ capturePrompt } = await import(pathToFileURL(modulePath).href));
48
+ } catch (err) {
49
+ process.stderr.write(
50
+ `cmk-capture-prompt: failed to load module: ${err?.message ?? err}\n`,
51
+ );
52
+ emitContinue();
53
+ process.exit(0);
54
+ }
55
+
56
+ try {
57
+ capturePrompt({ payload, projectRoot: process.cwd() });
58
+ } catch (err) {
59
+ process.stderr.write(
60
+ `cmk-capture-prompt: handler failed: ${err?.message ?? err}\n`,
61
+ );
62
+ }
63
+
64
+ emitContinue();
65
+ process.exit(0);
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ // Stop hook handler — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-capture-turn.mjs (Task 21).
5
+ // Ships in the @lh8ppl/claude-memory-kit npm package so `cmk install`
6
+ // can wire a PATH-resolved `cmk-capture-turn` command. Two differences
7
+ // from the plugin copy:
8
+ // 1. src module path resolves ../src/ (not ../../packages/cli/src/).
9
+ // 2. the detached auto-extract subagent resolves to the sibling
10
+ // cmk-auto-extract.mjs in THIS bin/ dir (it ships alongside).
11
+ //
12
+ // Protocol: payload arrives on stdin as JSON. Honor stop_hook_active,
13
+ // append to transcripts, spawn detached auto-extract, emit
14
+ // {"continue": true}, exit 0 within ~50ms (NFR-1). Always exit 0.
15
+
16
+ import { readFileSync, existsSync } from 'node:fs';
17
+ import { dirname, join } from 'node:path';
18
+ import { fileURLToPath, pathToFileURL } from 'node:url';
19
+
20
+ function emitContinue() {
21
+ process.stdout.write('{"continue": true}');
22
+ }
23
+
24
+ let raw = '';
25
+ try {
26
+ raw = readFileSync(0, 'utf8');
27
+ } catch {
28
+ emitContinue();
29
+ process.exit(0);
30
+ }
31
+
32
+ let payload;
33
+ try {
34
+ payload = raw.trim() === '' ? {} : JSON.parse(raw);
35
+ } catch (err) {
36
+ process.stderr.write(
37
+ `cmk-capture-turn: failed to parse stdin JSON: ${err?.message ?? err}\n`,
38
+ );
39
+ emitContinue();
40
+ process.exit(0);
41
+ }
42
+
43
+ const __filename = fileURLToPath(import.meta.url);
44
+ const __dirname = dirname(__filename);
45
+ const modulePath = join(__dirname, '..', 'src', 'capture-turn.mjs');
46
+
47
+ // Auto-extract path: env override → sibling cmk-auto-extract.mjs (ships
48
+ // in this same bin/ dir). Absent only in a corrupt install; the spawn
49
+ // step is skipped if missing.
50
+ const autoExtractPath =
51
+ process.env.CMK_AUTO_EXTRACT_PATH ??
52
+ (existsSync(join(__dirname, 'cmk-auto-extract.mjs'))
53
+ ? join(__dirname, 'cmk-auto-extract.mjs')
54
+ : null);
55
+
56
+ let captureTurn;
57
+ try {
58
+ ({ captureTurn } = await import(pathToFileURL(modulePath).href));
59
+ } catch (err) {
60
+ process.stderr.write(
61
+ `cmk-capture-turn: failed to load module: ${err?.message ?? err}\n`,
62
+ );
63
+ emitContinue();
64
+ process.exit(0);
65
+ }
66
+
67
+ try {
68
+ captureTurn({ payload, projectRoot: process.cwd(), autoExtractPath });
69
+ } catch (err) {
70
+ process.stderr.write(
71
+ `cmk-capture-turn: handler failed: ${err?.message ?? err}\n`,
72
+ );
73
+ }
74
+
75
+ emitContinue();
76
+ process.exit(0);
File without changes
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ // SessionEnd hook handler — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-compress-session.mjs (Task 22).
5
+ // Ships in the @lh8ppl/claude-memory-kit npm package so `cmk install`
6
+ // can wire a PATH-resolved `cmk-compress-session` command. Only the src
7
+ // module paths differ from the plugin copy (../src/ vs ../../packages/cli/src/).
8
+ //
9
+ // Protocol: drain stdin, resolve project root from CMK_PROJECT_DIR env
10
+ // or cwd, run compressSession() with a real HaikuViaAnthropicApi, emit
11
+ // {"continue": true}. Always exit 0 — a crashed SessionEnd hook would
12
+ // block the user from closing their terminal.
13
+
14
+ import { readFileSync } from 'node:fs';
15
+ import { dirname, join } from 'node:path';
16
+ import { fileURLToPath, pathToFileURL } from 'node:url';
17
+
18
+ function emitContinue() {
19
+ process.stdout.write('{"continue": true}');
20
+ }
21
+
22
+ let rawInput = '';
23
+ try {
24
+ rawInput = readFileSync(0, 'utf8');
25
+ } catch {
26
+ // stdin not connected — fine; SessionEnd still proceeds.
27
+ }
28
+ void rawInput;
29
+
30
+ const __filename = fileURLToPath(import.meta.url);
31
+ const __dirname = dirname(__filename);
32
+
33
+ const compressSessionModulePath = join(__dirname, '..', 'src', 'compress-session.mjs');
34
+ const compressorModulePath = join(__dirname, '..', 'src', 'compressor.mjs');
35
+
36
+ let compressSession;
37
+ let HaikuViaAnthropicApi;
38
+ try {
39
+ ({ compressSession } = await import(pathToFileURL(compressSessionModulePath).href));
40
+ ({ HaikuViaAnthropicApi } = await import(pathToFileURL(compressorModulePath).href));
41
+ } catch (err) {
42
+ process.stderr.write(
43
+ `cmk-compress-session: failed to load modules: ${err?.message ?? err}\n`,
44
+ );
45
+ emitContinue();
46
+ process.exit(0);
47
+ }
48
+
49
+ const projectRoot = process.env.CMK_PROJECT_DIR ?? process.cwd();
50
+
51
+ try {
52
+ const backend = new HaikuViaAnthropicApi();
53
+ const r = await compressSession({ projectRoot, backend });
54
+ process.stderr.write(
55
+ `cmk-compress-session: ${r.action}${r.reason ? ` (${r.reason})` : ''}${r.bytesIn ? ` (in: ${r.bytesIn}b, out: ${r.bytesOut}b)` : ''} ms: ${r.duration_ms ?? 0}\n`,
56
+ );
57
+ } catch (err) {
58
+ process.stderr.write(
59
+ `cmk-compress-session: unexpected error: ${err?.message ?? err}\n`,
60
+ );
61
+ }
62
+
63
+ emitContinue();
64
+ process.exit(0);
File without changes
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ // SessionStart hook handler — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-inject-context.mjs (Task 18).
5
+ // This copy lives in the published @lh8ppl/claude-memory-kit npm package
6
+ // (declared in package.json `bin`), so `cmk install` can wire a
7
+ // PATH-resolved `cmk-inject-context` hook command into settings.json
8
+ // WITHOUT the plugin's `${CLAUDE_PLUGIN_ROOT}` / bash dependency. The
9
+ // only difference from the plugin copy is the src module path: here it
10
+ // resolves ../src/ (bin/ → src/), not ../../packages/cli/src/.
11
+ //
12
+ // Protocol: payload arrives on stdin as JSON (drained, not consumed).
13
+ // Emit the Anthropic SessionStart hookOutput JSON on stdout. Exit 0
14
+ // unconditionally — a throwing SessionStart hook would interrupt
15
+ // session start, worse than an empty additionalContext.
16
+
17
+ import { readFileSync } from 'node:fs';
18
+ import { dirname, join } from 'node:path';
19
+ import { fileURLToPath, pathToFileURL } from 'node:url';
20
+
21
+ // Drain stdin so callers blocking on EPIPE don't hang.
22
+ try {
23
+ readFileSync(0, 'utf8');
24
+ } catch {
25
+ // stdin not connected; fine.
26
+ }
27
+
28
+ const __filename = fileURLToPath(import.meta.url);
29
+ const __dirname = dirname(__filename);
30
+ const modulePath = join(__dirname, '..', 'src', 'inject-context.mjs');
31
+
32
+ let injectContext;
33
+ try {
34
+ ({ injectContext } = await import(pathToFileURL(modulePath).href));
35
+ } catch (err) {
36
+ process.stderr.write(
37
+ `cmk-inject-context: failed to load module at ${modulePath}: ${
38
+ err?.message ?? String(err)
39
+ }\n`,
40
+ );
41
+ process.stdout.write(
42
+ JSON.stringify({
43
+ hookSpecificOutput: {
44
+ hookEventName: 'SessionStart',
45
+ additionalContext: '',
46
+ },
47
+ }),
48
+ );
49
+ process.exit(0);
50
+ }
51
+
52
+ try {
53
+ const r = injectContext({ cwd: process.cwd() });
54
+ process.stdout.write(JSON.stringify(r.hookOutput));
55
+ process.exit(0);
56
+ } catch (err) {
57
+ process.stderr.write(
58
+ `cmk-inject-context: handler failed: ${err?.message ?? String(err)}\n`,
59
+ );
60
+ process.stdout.write(
61
+ JSON.stringify({
62
+ hookSpecificOutput: {
63
+ hookEventName: 'SessionStart',
64
+ additionalContext: '',
65
+ },
66
+ }),
67
+ );
68
+ process.exit(0);
69
+ }
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ // PostToolUse hook handler — npm-route bin (Task 49, T-037).
3
+ //
4
+ // De-plugin-ified twin of plugin/bin/cmk-observe-edit.mjs (Task 20).
5
+ // Ships in the @lh8ppl/claude-memory-kit npm package so `cmk install`
6
+ // can wire a PATH-resolved `cmk-observe-edit` command (registered
7
+ // async: true in the hooks block). Only the src module path differs
8
+ // from the plugin copy (../src/ vs ../../packages/cli/src/).
9
+ //
10
+ // All errors are swallowed + logged to stderr — a hook child crashing
11
+ // must never surface in the user's session. The append is
12
+ // fire-and-forget by design.
13
+
14
+ import { readFileSync } from 'node:fs';
15
+ import { dirname, join } from 'node:path';
16
+ import { fileURLToPath, pathToFileURL } from 'node:url';
17
+
18
+ let raw = '';
19
+ try {
20
+ raw = readFileSync(0, 'utf8');
21
+ } catch {
22
+ process.exit(0);
23
+ }
24
+
25
+ let payload;
26
+ try {
27
+ payload = raw.trim() === '' ? {} : JSON.parse(raw);
28
+ } catch (err) {
29
+ process.stderr.write(
30
+ `cmk-observe-edit: failed to parse stdin JSON: ${err?.message ?? err}\n`,
31
+ );
32
+ process.exit(0);
33
+ }
34
+
35
+ const __filename = fileURLToPath(import.meta.url);
36
+ const __dirname = dirname(__filename);
37
+ const modulePath = join(__dirname, '..', 'src', 'observe-edit.mjs');
38
+
39
+ let observeEdit;
40
+ try {
41
+ ({ observeEdit } = await import(pathToFileURL(modulePath).href));
42
+ } catch (err) {
43
+ process.stderr.write(
44
+ `cmk-observe-edit: failed to load module: ${err?.message ?? err}\n`,
45
+ );
46
+ process.exit(0);
47
+ }
48
+
49
+ try {
50
+ observeEdit({ payload, projectRoot: process.cwd() });
51
+ } catch (err) {
52
+ process.stderr.write(
53
+ `cmk-observe-edit: handler failed: ${err?.message ?? err}\n`,
54
+ );
55
+ }
56
+
57
+ process.exit(0);
File without changes
package/bin/cmk.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- // cmk — claude-memory-kit CLI entry point.
3
- // Thin shim: defers all argv parsing + dispatch to src/index.mjs.
4
- // Kept thin so the bin file rarely needs to change once installed.
5
-
6
- import { run } from '../src/index.mjs';
7
-
8
- run(process.argv).catch((err) => {
9
- console.error('cmk: unexpected error');
10
- console.error(err && err.stack ? err.stack : err);
11
- process.exit(1);
12
- });
2
+ // cmk — claude-memory-kit CLI entry point.
3
+ // Thin shim: defers all argv parsing + dispatch to src/index.mjs.
4
+ // Kept thin so the bin file rarely needs to change once installed.
5
+
6
+ import { run } from '../src/index.mjs';
7
+
8
+ run(process.argv).catch((err) => {
9
+ console.error('cmk: unexpected error');
10
+ console.error(err && err.stack ? err.stack : err);
11
+ process.exit(1);
12
+ });
package/package.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
2
  "name": "@lh8ppl/claude-memory-kit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "cmk — the CLI for claude-memory-kit. Per-project, in-repo memory system for Claude Code.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "cmk": "./bin/cmk.mjs",
8
8
  "cmk-daily-distill": "./bin/cmk-daily-distill.mjs",
9
9
  "cmk-weekly-curate": "./bin/cmk-weekly-curate.mjs",
10
- "cmk-compress-lazy": "./bin/cmk-compress-lazy.mjs"
10
+ "cmk-compress-lazy": "./bin/cmk-compress-lazy.mjs",
11
+ "cmk-inject-context": "./bin/cmk-inject-context.mjs",
12
+ "cmk-capture-prompt": "./bin/cmk-capture-prompt.mjs",
13
+ "cmk-observe-edit": "./bin/cmk-observe-edit.mjs",
14
+ "cmk-capture-turn": "./bin/cmk-capture-turn.mjs",
15
+ "cmk-compress-session": "./bin/cmk-compress-session.mjs"
11
16
  },
12
17
  "files": [
13
18
  "bin/",
@@ -40,6 +45,9 @@
40
45
  "url": "https://github.com/LH8PPL/claude-memory-kit.git",
41
46
  "directory": "packages/cli"
42
47
  },
48
+ "bugs": {
49
+ "url": "https://github.com/LH8PPL/claude-memory-kit/issues"
50
+ },
43
51
  "keywords": [
44
52
  "claude",
45
53
  "claude-code",
package/src/audit-log.mjs CHANGED
@@ -44,6 +44,7 @@ export const REASON_CODES = Object.freeze({
44
44
  IMPORT_SKIPPED_DUPLICATE: 'import-skipped-duplicate', // import-anthropic-memory: candidate canonicalize-matched existing fact, skipped (Task 38)
45
45
  REPAIR_HOOKS_APPLIED: 'repair-hooks-applied', // cmk repair --hooks: settings.json updated with canonical kit hooks (Task 39)
46
46
  REPAIR_HOOKS_NOOP: 'repair-hooks-noop', // cmk repair --hooks: settings.json already canonical, no-op (Task 39)
47
+ INSTALL_HOOKS_WIRED: 'install-hooks-wired', // cmk install: settings.json wired with npm-route hooks (Task 49). NOTE: no NOOP counterpart — install audits only on change, to keep re-runs byte-idempotent (the audit.log is append-only).
47
48
  REPAIR_LOCK_REMOVED: 'repair-lock-removed', // cmk repair --locks: stale lock unlinked (Task 39)
48
49
  });
49
50