@lossless-claude/lcm 0.2.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/.claude-plugin/commands/lcm-compact.md +31 -0
- package/.claude-plugin/commands/lcm-curate.md +31 -0
- package/.claude-plugin/commands/lcm-diagnose.md +29 -0
- package/.claude-plugin/commands/lcm-doctor.md +23 -0
- package/.claude-plugin/commands/lcm-dogfood.md +101 -0
- package/.claude-plugin/commands/lcm-import.md +48 -0
- package/.claude-plugin/commands/lcm-promote.md +29 -0
- package/.claude-plugin/commands/lcm-sensitive.md +55 -0
- package/.claude-plugin/commands/lcm-stats.md +19 -0
- package/.claude-plugin/commands/lcm-status.md +27 -0
- package/.claude-plugin/hooks/README.md +47 -0
- package/.claude-plugin/marketplace.json +20 -0
- package/.claude-plugin/mcp.mjs +12 -0
- package/.claude-plugin/plugin.json +46 -0
- package/.claude-plugin/skills/lcm-context/SKILL.md +107 -0
- package/.claude-plugin/skills/lcm-dogfood/SKILL.md +102 -0
- package/.claude-plugin/skills/lcm-dogfood/references/checks.md +239 -0
- package/.claude-plugin/skills/lcm-dogfood/references/known-issues.md +11 -0
- package/.claude-plugin/skills/lcm-dogfood/scripts/db-integrity.js +40 -0
- package/.claude-plugin/skills/lcm-dogfood/scripts/prompt-search-test.js +35 -0
- package/.claude-plugin/skills/lcm-e2e/SKILL.md +61 -0
- package/.claude-plugin/skills/lcm-e2e/checklist.md +367 -0
- package/.claude-plugin/skills/lossless-claude-upgrade/SKILL.md +47 -0
- package/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/bin/lcm.d.ts +2 -0
- package/dist/bin/lcm.js +461 -0
- package/dist/bin/lcm.js.map +1 -0
- package/dist/installer/dry-run-deps.d.ts +23 -0
- package/dist/installer/dry-run-deps.js +66 -0
- package/dist/installer/dry-run-deps.js.map +1 -0
- package/dist/installer/install.d.ts +39 -0
- package/dist/installer/install.js +236 -0
- package/dist/installer/install.js.map +1 -0
- package/dist/installer/uninstall.d.ts +11 -0
- package/dist/installer/uninstall.js +80 -0
- package/dist/installer/uninstall.js.map +1 -0
- package/dist/src/batch-compact.d.ts +16 -0
- package/dist/src/batch-compact.js +121 -0
- package/dist/src/batch-compact.js.map +1 -0
- package/dist/src/compaction.d.ts +198 -0
- package/dist/src/compaction.js +964 -0
- package/dist/src/compaction.js.map +1 -0
- package/dist/src/connectors/constants.d.ts +5 -0
- package/dist/src/connectors/constants.js +6 -0
- package/dist/src/connectors/constants.js.map +1 -0
- package/dist/src/connectors/installer.d.ts +16 -0
- package/dist/src/connectors/installer.js +200 -0
- package/dist/src/connectors/installer.js.map +1 -0
- package/dist/src/connectors/registry.d.ts +4 -0
- package/dist/src/connectors/registry.js +264 -0
- package/dist/src/connectors/registry.js.map +1 -0
- package/dist/src/connectors/template-service.d.ts +5 -0
- package/dist/src/connectors/template-service.js +54 -0
- package/dist/src/connectors/template-service.js.map +1 -0
- package/dist/src/connectors/templates/base.md +1 -0
- package/dist/src/connectors/templates/mcp-base.md +1 -0
- package/dist/src/connectors/templates/sections/command-reference.md +15 -0
- package/dist/src/connectors/templates/sections/mcp-workflow.md +18 -0
- package/dist/src/connectors/templates/sections/workflow.md +29 -0
- package/dist/src/connectors/templates/skill/SKILL.md +74 -0
- package/dist/src/connectors/types.d.ts +19 -0
- package/dist/src/connectors/types.js +10 -0
- package/dist/src/connectors/types.js.map +1 -0
- package/dist/src/daemon/client.d.ts +9 -0
- package/dist/src/daemon/client.js +28 -0
- package/dist/src/daemon/client.js.map +1 -0
- package/dist/src/daemon/config.d.ts +48 -0
- package/dist/src/daemon/config.js +67 -0
- package/dist/src/daemon/config.js.map +1 -0
- package/dist/src/daemon/lifecycle.d.ts +19 -0
- package/dist/src/daemon/lifecycle.js +102 -0
- package/dist/src/daemon/lifecycle.js.map +1 -0
- package/dist/src/daemon/orientation.d.ts +1 -0
- package/dist/src/daemon/orientation.js +9 -0
- package/dist/src/daemon/orientation.js.map +1 -0
- package/dist/src/daemon/project-queue.d.ts +1 -0
- package/dist/src/daemon/project-queue.js +17 -0
- package/dist/src/daemon/project-queue.js.map +1 -0
- package/dist/src/daemon/project.d.ts +7 -0
- package/dist/src/daemon/project.js +25 -0
- package/dist/src/daemon/project.js.map +1 -0
- package/dist/src/daemon/proxy-manager.d.ts +21 -0
- package/dist/src/daemon/proxy-manager.js +205 -0
- package/dist/src/daemon/proxy-manager.js.map +1 -0
- package/dist/src/daemon/routes/compact.d.ts +13 -0
- package/dist/src/daemon/routes/compact.js +195 -0
- package/dist/src/daemon/routes/compact.js.map +1 -0
- package/dist/src/daemon/routes/describe.d.ts +3 -0
- package/dist/src/daemon/routes/describe.js +39 -0
- package/dist/src/daemon/routes/describe.js.map +1 -0
- package/dist/src/daemon/routes/expand.d.ts +3 -0
- package/dist/src/daemon/routes/expand.js +41 -0
- package/dist/src/daemon/routes/expand.js.map +1 -0
- package/dist/src/daemon/routes/grep.d.ts +3 -0
- package/dist/src/daemon/routes/grep.js +43 -0
- package/dist/src/daemon/routes/grep.js.map +1 -0
- package/dist/src/daemon/routes/ingest.d.ts +3 -0
- package/dist/src/daemon/routes/ingest.js +101 -0
- package/dist/src/daemon/routes/ingest.js.map +1 -0
- package/dist/src/daemon/routes/promote.d.ts +4 -0
- package/dist/src/daemon/routes/promote.js +104 -0
- package/dist/src/daemon/routes/promote.js.map +1 -0
- package/dist/src/daemon/routes/prompt-search.d.ts +3 -0
- package/dist/src/daemon/routes/prompt-search.js +65 -0
- package/dist/src/daemon/routes/prompt-search.js.map +1 -0
- package/dist/src/daemon/routes/recent.d.ts +3 -0
- package/dist/src/daemon/routes/recent.js +37 -0
- package/dist/src/daemon/routes/recent.js.map +1 -0
- package/dist/src/daemon/routes/restore.d.ts +3 -0
- package/dist/src/daemon/routes/restore.js +120 -0
- package/dist/src/daemon/routes/restore.js.map +1 -0
- package/dist/src/daemon/routes/search.d.ts +2 -0
- package/dist/src/daemon/routes/search.js +66 -0
- package/dist/src/daemon/routes/search.js.map +1 -0
- package/dist/src/daemon/routes/status.d.ts +3 -0
- package/dist/src/daemon/routes/status.js +80 -0
- package/dist/src/daemon/routes/status.js.map +1 -0
- package/dist/src/daemon/routes/store.d.ts +2 -0
- package/dist/src/daemon/routes/store.js +46 -0
- package/dist/src/daemon/routes/store.js.map +1 -0
- package/dist/src/daemon/server.d.ts +19 -0
- package/dist/src/daemon/server.js +183 -0
- package/dist/src/daemon/server.js.map +1 -0
- package/dist/src/daemon/summarizer.d.ts +11 -0
- package/dist/src/daemon/summarizer.js +51 -0
- package/dist/src/daemon/summarizer.js.map +1 -0
- package/dist/src/db/config.d.ts +31 -0
- package/dist/src/db/config.js +83 -0
- package/dist/src/db/config.js.map +1 -0
- package/dist/src/db/connection.d.ts +3 -0
- package/dist/src/db/connection.js +62 -0
- package/dist/src/db/connection.js.map +1 -0
- package/dist/src/db/features.d.ts +11 -0
- package/dist/src/db/features.js +36 -0
- package/dist/src/db/features.js.map +1 -0
- package/dist/src/db/migration.d.ts +4 -0
- package/dist/src/db/migration.js +499 -0
- package/dist/src/db/migration.js.map +1 -0
- package/dist/src/db/promoted.d.ts +47 -0
- package/dist/src/db/promoted.js +96 -0
- package/dist/src/db/promoted.js.map +1 -0
- package/dist/src/db/redaction-stats.d.ts +6 -0
- package/dist/src/db/redaction-stats.js +16 -0
- package/dist/src/db/redaction-stats.js.map +1 -0
- package/dist/src/diagnose.d.ts +39 -0
- package/dist/src/diagnose.js +432 -0
- package/dist/src/diagnose.js.map +1 -0
- package/dist/src/doctor/doctor.d.ts +4 -0
- package/dist/src/doctor/doctor.js +378 -0
- package/dist/src/doctor/doctor.js.map +1 -0
- package/dist/src/doctor/types.d.ts +24 -0
- package/dist/src/doctor/types.js +2 -0
- package/dist/src/doctor/types.js.map +1 -0
- package/dist/src/expansion.d.ts +100 -0
- package/dist/src/expansion.js +268 -0
- package/dist/src/expansion.js.map +1 -0
- package/dist/src/hooks/auto-heal.d.ts +12 -0
- package/dist/src/hooks/auto-heal.js +49 -0
- package/dist/src/hooks/auto-heal.js.map +1 -0
- package/dist/src/hooks/compact.d.ts +5 -0
- package/dist/src/hooks/compact.js +22 -0
- package/dist/src/hooks/compact.js.map +1 -0
- package/dist/src/hooks/dispatch.d.ts +7 -0
- package/dist/src/hooks/dispatch.js +36 -0
- package/dist/src/hooks/dispatch.js.map +1 -0
- package/dist/src/hooks/probe-precompact.d.ts +2 -0
- package/dist/src/hooks/probe-precompact.js +17 -0
- package/dist/src/hooks/probe-precompact.js.map +1 -0
- package/dist/src/hooks/probe-sessionstart.d.ts +2 -0
- package/dist/src/hooks/probe-sessionstart.js +18 -0
- package/dist/src/hooks/probe-sessionstart.js.map +1 -0
- package/dist/src/hooks/restore.d.ts +5 -0
- package/dist/src/hooks/restore.js +19 -0
- package/dist/src/hooks/restore.js.map +1 -0
- package/dist/src/hooks/session-end.d.ts +16 -0
- package/dist/src/hooks/session-end.js +73 -0
- package/dist/src/hooks/session-end.js.map +1 -0
- package/dist/src/hooks/user-prompt.d.ts +5 -0
- package/dist/src/hooks/user-prompt.js +31 -0
- package/dist/src/hooks/user-prompt.js.map +1 -0
- package/dist/src/import.d.ts +24 -0
- package/dist/src/import.js +119 -0
- package/dist/src/import.js.map +1 -0
- package/dist/src/large-files.d.ts +28 -0
- package/dist/src/large-files.js +413 -0
- package/dist/src/large-files.js.map +1 -0
- package/dist/src/llm/anthropic.d.ts +9 -0
- package/dist/src/llm/anthropic.js +54 -0
- package/dist/src/llm/anthropic.js.map +1 -0
- package/dist/src/llm/claude-process.d.ts +2 -0
- package/dist/src/llm/claude-process.js +55 -0
- package/dist/src/llm/claude-process.js.map +1 -0
- package/dist/src/llm/codex-process.d.ts +15 -0
- package/dist/src/llm/codex-process.js +142 -0
- package/dist/src/llm/codex-process.js.map +1 -0
- package/dist/src/llm/mock-summarizer.d.ts +9 -0
- package/dist/src/llm/mock-summarizer.js +17 -0
- package/dist/src/llm/mock-summarizer.js.map +1 -0
- package/dist/src/llm/openai.d.ts +10 -0
- package/dist/src/llm/openai.js +52 -0
- package/dist/src/llm/openai.js.map +1 -0
- package/dist/src/llm/types.d.ts +6 -0
- package/dist/src/llm/types.js +2 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/mcp/server.d.ts +9 -0
- package/dist/src/mcp/server.js +128 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/lcm-describe.d.ts +14 -0
- package/dist/src/mcp/tools/lcm-describe.js +12 -0
- package/dist/src/mcp/tools/lcm-describe.js.map +1 -0
- package/dist/src/mcp/tools/lcm-doctor.d.ts +8 -0
- package/dist/src/mcp/tools/lcm-doctor.js +9 -0
- package/dist/src/mcp/tools/lcm-doctor.js.map +1 -0
- package/dist/src/mcp/tools/lcm-expand.d.ts +18 -0
- package/dist/src/mcp/tools/lcm-expand.js +13 -0
- package/dist/src/mcp/tools/lcm-expand.js.map +1 -0
- package/dist/src/mcp/tools/lcm-grep.d.ts +27 -0
- package/dist/src/mcp/tools/lcm-grep.js +15 -0
- package/dist/src/mcp/tools/lcm-grep.js.map +1 -0
- package/dist/src/mcp/tools/lcm-search.d.ts +33 -0
- package/dist/src/mcp/tools/lcm-search.js +15 -0
- package/dist/src/mcp/tools/lcm-search.js.map +1 -0
- package/dist/src/mcp/tools/lcm-stats.d.ts +14 -0
- package/dist/src/mcp/tools/lcm-stats.js +11 -0
- package/dist/src/mcp/tools/lcm-stats.js.map +1 -0
- package/dist/src/mcp/tools/lcm-store.d.ts +26 -0
- package/dist/src/mcp/tools/lcm-store.js +22 -0
- package/dist/src/mcp/tools/lcm-store.js.map +1 -0
- package/dist/src/memory/index.d.ts +22 -0
- package/dist/src/memory/index.js +21 -0
- package/dist/src/memory/index.js.map +1 -0
- package/dist/src/promotion/dedup.d.ts +19 -0
- package/dist/src/promotion/dedup.js +42 -0
- package/dist/src/promotion/dedup.js.map +1 -0
- package/dist/src/promotion/detector.d.ts +15 -0
- package/dist/src/promotion/detector.js +31 -0
- package/dist/src/promotion/detector.js.map +1 -0
- package/dist/src/prompts/condensed-d1.yaml +38 -0
- package/dist/src/prompts/condensed-d2.yaml +32 -0
- package/dist/src/prompts/condensed-d3plus.yaml +32 -0
- package/dist/src/prompts/leaf-aggressive.yaml +34 -0
- package/dist/src/prompts/leaf-normal.yaml +34 -0
- package/dist/src/prompts/loader.d.ts +9 -0
- package/dist/src/prompts/loader.js +37 -0
- package/dist/src/prompts/loader.js.map +1 -0
- package/dist/src/prompts/promoted-merge.yaml +18 -0
- package/dist/src/prompts/system.yaml +5 -0
- package/dist/src/retrieval.d.ts +122 -0
- package/dist/src/retrieval.js +214 -0
- package/dist/src/retrieval.js.map +1 -0
- package/dist/src/scrub.d.ts +46 -0
- package/dist/src/scrub.js +184 -0
- package/dist/src/scrub.js.map +1 -0
- package/dist/src/sensitive.d.ts +4 -0
- package/dist/src/sensitive.js +258 -0
- package/dist/src/sensitive.js.map +1 -0
- package/dist/src/stats.d.ts +34 -0
- package/dist/src/stats.js +260 -0
- package/dist/src/stats.js.map +1 -0
- package/dist/src/store/conversation-store.d.ts +115 -0
- package/dist/src/store/conversation-store.js +447 -0
- package/dist/src/store/conversation-store.js.map +1 -0
- package/dist/src/store/fts5-sanitize.d.ts +23 -0
- package/dist/src/store/fts5-sanitize.js +30 -0
- package/dist/src/store/fts5-sanitize.js.map +1 -0
- package/dist/src/store/full-text-fallback.d.ts +16 -0
- package/dist/src/store/full-text-fallback.js +60 -0
- package/dist/src/store/full-text-fallback.js.map +1 -0
- package/dist/src/store/index.d.ts +4 -0
- package/dist/src/store/index.js +3 -0
- package/dist/src/store/index.js.map +1 -0
- package/dist/src/store/summary-store.d.ts +118 -0
- package/dist/src/store/summary-store.js +570 -0
- package/dist/src/store/summary-store.js.map +1 -0
- package/dist/src/summarize.d.ts +59 -0
- package/dist/src/summarize.js +619 -0
- package/dist/src/summarize.js.map +1 -0
- package/dist/src/transcript.d.ts +7 -0
- package/dist/src/transcript.js +51 -0
- package/dist/src/transcript.js.map +1 -0
- package/dist/src/types.d.ts +116 -0
- package/dist/src/types.js +8 -0
- package/dist/src/types.js.map +1 -0
- package/docs/agent-tools.md +187 -0
- package/docs/architecture.md +224 -0
- package/docs/configuration.md +168 -0
- package/docs/fts5.md +161 -0
- package/docs/hook-protocol.md +41 -0
- package/docs/privacy.md +101 -0
- package/mcp.mjs +17 -0
- package/package.json +79 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Configuration guide
|
|
2
|
+
|
|
3
|
+
## Quick start
|
|
4
|
+
|
|
5
|
+
Clone the repo and link it with Claude Code's plugin installer:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/lossless-claude/lcm.git
|
|
9
|
+
cd lcm
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
claude plugins install --link /path/to/lossless-claude
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`claude plugins install --link` handles plugin registration/enabling and slot selection automatically.
|
|
16
|
+
|
|
17
|
+
Set recommended environment variables:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export LCM_FRESH_TAIL_COUNT=32
|
|
21
|
+
export LCM_INCREMENTAL_MAX_DEPTH=-1
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Restart Claude Code.
|
|
25
|
+
|
|
26
|
+
## Tuning guide
|
|
27
|
+
|
|
28
|
+
### Context threshold
|
|
29
|
+
|
|
30
|
+
`LCM_CONTEXT_THRESHOLD` (default `0.75`) controls when compaction triggers as a fraction of the model's context window.
|
|
31
|
+
|
|
32
|
+
- **Lower values** (e.g., 0.5) trigger compaction earlier, keeping context smaller but doing more LLM calls for summarization.
|
|
33
|
+
- **Higher values** (e.g., 0.85) let conversations grow longer before compacting, reducing summarization cost but risking overflow with large model responses.
|
|
34
|
+
|
|
35
|
+
For most use cases, 0.75 is a good balance.
|
|
36
|
+
|
|
37
|
+
### Fresh tail count
|
|
38
|
+
|
|
39
|
+
`LCM_FRESH_TAIL_COUNT` (default `32`) is the number of most recent messages that are never compacted. These raw messages give the model immediate conversational continuity.
|
|
40
|
+
|
|
41
|
+
- **Smaller values** (e.g., 8–16) save context space for summaries but may lose recent nuance.
|
|
42
|
+
- **Larger values** (e.g., 32–64) give better continuity at the cost of a larger mandatory context floor.
|
|
43
|
+
|
|
44
|
+
For coding conversations with tool calls (which generate many messages per logical turn), 32 is recommended.
|
|
45
|
+
|
|
46
|
+
### Leaf fanout
|
|
47
|
+
|
|
48
|
+
`LCM_LEAF_MIN_FANOUT` (default `8`) is the minimum number of raw messages that must be available outside the fresh tail before a leaf pass runs.
|
|
49
|
+
|
|
50
|
+
- Lower values create summaries more frequently (more, smaller summaries).
|
|
51
|
+
- Higher values create larger, more comprehensive summaries less often.
|
|
52
|
+
|
|
53
|
+
### Condensed fanout
|
|
54
|
+
|
|
55
|
+
`LCM_CONDENSED_MIN_FANOUT` (default `4`) controls how many same-depth summaries accumulate before they're condensed into a higher-level summary.
|
|
56
|
+
|
|
57
|
+
- Lower values create deeper DAGs with more levels of abstraction.
|
|
58
|
+
- Higher values keep the DAG shallower but with more nodes at each level.
|
|
59
|
+
|
|
60
|
+
### Incremental max depth
|
|
61
|
+
|
|
62
|
+
`LCM_INCREMENTAL_MAX_DEPTH` (default `0`) controls whether condensation happens automatically after leaf passes.
|
|
63
|
+
|
|
64
|
+
- **0** — Only leaf summaries are created incrementally. Condensation only happens during manual `/compact` or overflow.
|
|
65
|
+
- **1** — After each leaf pass, attempt to condense d0 summaries into d1.
|
|
66
|
+
- **2+** — Deeper automatic condensation up to the specified depth.
|
|
67
|
+
- **-1** — Unlimited depth. Condensation cascades as deep as needed after each leaf pass. Recommended for long-running sessions.
|
|
68
|
+
|
|
69
|
+
### Summary target tokens
|
|
70
|
+
|
|
71
|
+
`LCM_LEAF_TARGET_TOKENS` (default `1200`) and `LCM_CONDENSED_TARGET_TOKENS` (default `2000`) control the target size of generated summaries.
|
|
72
|
+
|
|
73
|
+
- Larger targets preserve more detail but consume more context space.
|
|
74
|
+
- Smaller targets are more aggressive, losing detail faster.
|
|
75
|
+
|
|
76
|
+
The actual summary size depends on the LLM's output; these values are guidelines passed in the prompt's token target instruction.
|
|
77
|
+
|
|
78
|
+
### Leaf chunk tokens
|
|
79
|
+
|
|
80
|
+
`LCM_LEAF_CHUNK_TOKENS` (default `20000`) caps the amount of source material per leaf compaction pass.
|
|
81
|
+
|
|
82
|
+
- Larger chunks create more comprehensive summaries from more material.
|
|
83
|
+
- Smaller chunks create summaries more frequently from less material.
|
|
84
|
+
- This also affects the condensed minimum input threshold (10% of this value).
|
|
85
|
+
|
|
86
|
+
## Model selection
|
|
87
|
+
|
|
88
|
+
LCM defaults to `LCM_SUMMARY_PROVIDER=auto`.
|
|
89
|
+
|
|
90
|
+
- In Claude sessions, `auto` resolves to `claude-process`
|
|
91
|
+
- In Codex sessions, `auto` resolves to `codex-process`
|
|
92
|
+
- If you explicitly set `LCM_SUMMARY_PROVIDER`, that override applies to both CLIs
|
|
93
|
+
|
|
94
|
+
You can pin a specific summarizer provider and model:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Use a specific provider + model for summarization
|
|
98
|
+
export LCM_SUMMARY_MODEL=anthropic/claude-sonnet-4-20250514
|
|
99
|
+
export LCM_SUMMARY_PROVIDER=anthropic
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Valid provider values are:
|
|
103
|
+
|
|
104
|
+
- `auto`
|
|
105
|
+
- `claude-process`
|
|
106
|
+
- `codex-process`
|
|
107
|
+
- `anthropic`
|
|
108
|
+
- `openai`
|
|
109
|
+
- `disabled`
|
|
110
|
+
|
|
111
|
+
Using a cheaper or faster model for summarization can reduce costs, but quality matters because poor summaries compound as they are condensed into higher-level nodes.
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
## Database management
|
|
115
|
+
|
|
116
|
+
The SQLite database lives at `LCM_DATABASE_PATH` (default `~/.claude/lcm.db`).
|
|
117
|
+
|
|
118
|
+
### Inspecting the database
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
sqlite3 ~/.claude/lcm.db
|
|
122
|
+
|
|
123
|
+
# Count conversations
|
|
124
|
+
SELECT COUNT(*) FROM conversations;
|
|
125
|
+
|
|
126
|
+
# See context items for a conversation
|
|
127
|
+
SELECT * FROM context_items WHERE conversation_id = 1 ORDER BY ordinal;
|
|
128
|
+
|
|
129
|
+
# Check summary depth distribution
|
|
130
|
+
SELECT depth, COUNT(*) FROM summaries GROUP BY depth;
|
|
131
|
+
|
|
132
|
+
# Find large summaries
|
|
133
|
+
SELECT summary_id, depth, token_count FROM summaries ORDER BY token_count DESC LIMIT 10;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Backup
|
|
137
|
+
|
|
138
|
+
The database is a single file. Back it up with:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
cp ~/.claude/lcm.db ~/.claude/lcm.db.backup
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Or use SQLite's online backup:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
sqlite3 ~/.claude/lcm.db ".backup ~/.claude/lcm.db.backup"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Per-agent configuration
|
|
151
|
+
|
|
152
|
+
In multi-agent Claude Code setups, each agent uses the same LCM database but has its own conversations (keyed by session ID). The plugin config applies globally; per-agent overrides use environment variables set in the agent's config.
|
|
153
|
+
|
|
154
|
+
## Disabling LCM
|
|
155
|
+
|
|
156
|
+
To fall back to Claude Code's built-in compaction:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"plugins": {
|
|
161
|
+
"slots": {
|
|
162
|
+
"contextEngine": "legacy"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Or set `LCM_ENABLED=false` to disable the plugin while keeping it registered.
|
package/docs/fts5.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Optional: enable FTS5 for fast full-text search
|
|
2
|
+
|
|
3
|
+
`lossless-claude` works without FTS5 as of the current release. When FTS5 is unavailable in the
|
|
4
|
+
Node runtime that runs the Claude Code gateway, the plugin:
|
|
5
|
+
|
|
6
|
+
- keeps persisting messages and summaries
|
|
7
|
+
- falls back from `"full_text"` search to a slower `LIKE`-based search
|
|
8
|
+
- loses FTS ranking/snippet quality
|
|
9
|
+
|
|
10
|
+
If you want native FTS5 search performance and ranking, the **exact Node runtime that runs the
|
|
11
|
+
gateway** must have SQLite FTS5 compiled in.
|
|
12
|
+
|
|
13
|
+
## Probe the gateway runtime
|
|
14
|
+
|
|
15
|
+
Run this with the same `node` binary your gateway uses:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node --input-type=module - <<'NODE'
|
|
19
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
20
|
+
const db = new DatabaseSync(':memory:');
|
|
21
|
+
const options = db.prepare('pragma compile_options').all().map((row) => row.compile_options);
|
|
22
|
+
|
|
23
|
+
console.log(options.filter((value) => value.includes('FTS')).join('\n') || 'no fts compile options');
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
|
|
27
|
+
console.log("fts5: ok");
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.log("fts5: fail");
|
|
30
|
+
console.log(err instanceof Error ? err.message : String(err));
|
|
31
|
+
}
|
|
32
|
+
NODE
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Expected output:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
ENABLE_FTS5
|
|
39
|
+
fts5: ok
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If you get `fts5: fail`, build or install an FTS5-capable Node and point the gateway at that runtime.
|
|
43
|
+
|
|
44
|
+
## Build an FTS5-capable Node on macOS
|
|
45
|
+
|
|
46
|
+
This workflow was verified with Node `v22.15.0`.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd ~/Projects
|
|
50
|
+
git clone --depth 1 --branch v22.15.0 https://github.com/nodejs/node.git node-fts5
|
|
51
|
+
cd node-fts5
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Edit `deps/sqlite/sqlite.gyp` and add `SQLITE_ENABLE_FTS5` to the `defines` list for the `sqlite`
|
|
55
|
+
target:
|
|
56
|
+
|
|
57
|
+
```diff
|
|
58
|
+
'defines': [
|
|
59
|
+
'SQLITE_DEFAULT_MEMSTATUS=0',
|
|
60
|
+
+ 'SQLITE_ENABLE_FTS5',
|
|
61
|
+
'SQLITE_ENABLE_MATH_FUNCTIONS',
|
|
62
|
+
'SQLITE_ENABLE_SESSION',
|
|
63
|
+
'SQLITE_ENABLE_PREUPDATE_HOOK'
|
|
64
|
+
],
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Important:
|
|
68
|
+
|
|
69
|
+
- patch `deps/sqlite/sqlite.gyp`, not only `node.gyp`
|
|
70
|
+
- `node:sqlite` uses the embedded SQLite built from `deps/sqlite/sqlite.gyp`
|
|
71
|
+
|
|
72
|
+
Build the runtime:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
./configure --prefix="$PWD/out-install"
|
|
76
|
+
make -j8 node
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Expose the binary under a Node-compatible basename that Claude Code recognizes:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
mkdir -p ~/Projects/node-fts5/bin
|
|
83
|
+
ln -sfn ~/Projects/node-fts5/out/Release/node ~/Projects/node-fts5/bin/node-22.15.0
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use a basename like `node-22.15.0`, `node`, or `nodejs`. Names like
|
|
87
|
+
`node-v22.15.0-fts5` may not be recognized correctly by Claude Code's CLI/runtime parsing.
|
|
88
|
+
|
|
89
|
+
Verify the new runtime:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
~/Projects/node-fts5/bin/node-22.15.0 --version
|
|
93
|
+
~/Projects/node-fts5/bin/node-22.15.0 --input-type=module - <<'NODE'
|
|
94
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
95
|
+
const db = new DatabaseSync(':memory:');
|
|
96
|
+
db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
|
|
97
|
+
console.log("fts5: ok");
|
|
98
|
+
NODE
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Point the Claude Code gateway at that runtime on macOS
|
|
102
|
+
|
|
103
|
+
Back up the existing LaunchAgent plist first:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cp ~/Library/LaunchAgents/ai.claude.gateway.plist \
|
|
107
|
+
~/Library/LaunchAgents/ai.claude.gateway.plist.bak-$(date +%Y%m%d-%H%M%S)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Replace the runtime path, then reload the agent:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
/usr/libexec/PlistBuddy -c 'Set :ProgramArguments:0 /Users/youruser/Projects/node-fts5/bin/node-22.15.0' \
|
|
114
|
+
~/Library/LaunchAgents/ai.claude.gateway.plist
|
|
115
|
+
|
|
116
|
+
launchctl bootout gui/$UID ~/Library/LaunchAgents/ai.claude.gateway.plist 2>/dev/null || true
|
|
117
|
+
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.claude.gateway.plist
|
|
118
|
+
launchctl kickstart -k gui/$UID/ai.claude.gateway
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Verify the live runtime:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
launchctl print gui/$UID/ai.claude.gateway | sed -n '1,80p'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
You should see:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
program = /Users/youruser/Projects/node-fts5/bin/node-22.15.0
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Verify `lossless-claude`
|
|
134
|
+
|
|
135
|
+
Check the logs:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
tail -n 60 ~/.claude/logs/gateway.log
|
|
139
|
+
tail -n 60 ~/.claude/logs/gateway.err.log
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
You want:
|
|
143
|
+
|
|
144
|
+
- `[gateway] [lcm] Plugin loaded ...`
|
|
145
|
+
- no new `no such module: fts5`
|
|
146
|
+
|
|
147
|
+
Then force one turn through the gateway and verify the DB fills:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
/Users/youruser/Projects/node-fts5/bin/node-22.15.0 \
|
|
151
|
+
/path/to/claude/dist/index.js \
|
|
152
|
+
agent --session-id fts5-smoke --message 'Reply with exactly: ok' --timeout 60
|
|
153
|
+
|
|
154
|
+
sqlite3 ~/.claude/lcm.db '
|
|
155
|
+
select count(*) as conversations from conversations;
|
|
156
|
+
select count(*) as messages from messages;
|
|
157
|
+
select count(*) as summaries from summaries;
|
|
158
|
+
'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Those counts should increase after a real turn.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Claude Code Hook Protocol — Verified Schemas
|
|
2
|
+
|
|
3
|
+
## PreCompact Hook
|
|
4
|
+
|
|
5
|
+
**Status:** ⚠️ Pending verification via probe-precompact.ts
|
|
6
|
+
|
|
7
|
+
Expected fields (unverified):
|
|
8
|
+
- `session_id` — session identifier
|
|
9
|
+
- `transcript_path` — path to session JSONL transcript (C1: unverified)
|
|
10
|
+
- `cwd` — working directory
|
|
11
|
+
- `hook_event_name` — "PreCompact"
|
|
12
|
+
|
|
13
|
+
### How to verify (C1)
|
|
14
|
+
|
|
15
|
+
1. Add to `~/.claude/settings.json` hooks:
|
|
16
|
+
```json
|
|
17
|
+
"PreCompact": [{ "type": "command", "command": "node /path/to/src/hooks/probe-precompact.ts" }]
|
|
18
|
+
```
|
|
19
|
+
2. Start Claude Code, trigger compaction (use `/compact` command or fill context)
|
|
20
|
+
3. Check `~/.lossless-claude/precompact-probe.json`
|
|
21
|
+
4. Update this file with verified schema
|
|
22
|
+
|
|
23
|
+
## SessionStart Hook
|
|
24
|
+
|
|
25
|
+
**Status:** ⚠️ Pending verification via probe-sessionstart.ts
|
|
26
|
+
|
|
27
|
+
Expected fields:
|
|
28
|
+
- `session_id`
|
|
29
|
+
- `cwd`
|
|
30
|
+
- `hook_event_name` — "SessionStart"
|
|
31
|
+
- `source` — "startup" | "resume" | "compact" (C3: verify "compact" exists)
|
|
32
|
+
|
|
33
|
+
### How to verify (C3)
|
|
34
|
+
|
|
35
|
+
1. Add to `~/.claude/settings.json` hooks:
|
|
36
|
+
```json
|
|
37
|
+
"SessionStart": [{ "type": "command", "command": "node /path/to/src/hooks/probe-sessionstart.ts" }]
|
|
38
|
+
```
|
|
39
|
+
2. Trigger compaction, then observe the next SessionStart event
|
|
40
|
+
3. Check `~/.lossless-claude/sessionstart-probe.jsonl` for `source` values
|
|
41
|
+
4. Update this file with verified schema
|
package/docs/privacy.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Privacy & Data Handling
|
|
2
|
+
|
|
3
|
+
lossless-claude stores your conversation history locally to enable memory across sessions. This document explains exactly what is stored, what leaves your machine, and how to control sensitive data.
|
|
4
|
+
|
|
5
|
+
## What is stored locally
|
|
6
|
+
|
|
7
|
+
All storage is on your machine:
|
|
8
|
+
|
|
9
|
+
- **`~/.lossless-claude/projects/{hash}/db.sqlite`** — Conversation messages, summaries, and promoted long-term memory for each project. The hash is a SHA-256 of the project directory path.
|
|
10
|
+
- **`~/.lossless-claude/projects/{hash}/sensitive-patterns.txt`** — Per-project sensitive patterns (if configured).
|
|
11
|
+
- **`~/.lossless-claude/config.json`** — Global configuration including the optional `security.sensitivePatterns` array.
|
|
12
|
+
- **`~/.lossless-claude/daemon.pid`** — Daemon process ID (transient).
|
|
13
|
+
|
|
14
|
+
No data is sent to any lossless-claude server. There is no telemetry.
|
|
15
|
+
|
|
16
|
+
## What leaves your machine
|
|
17
|
+
|
|
18
|
+
lossless-claude is a local runtime. By default, **nothing leaves your machine**.
|
|
19
|
+
|
|
20
|
+
The exception is the summarizer, which you configure explicitly:
|
|
21
|
+
|
|
22
|
+
| Summarizer (`llm.provider`) | Data sent externally |
|
|
23
|
+
|-----------------------------|----------------------|
|
|
24
|
+
| `disabled` (default) | Nothing |
|
|
25
|
+
| `claude-process` | Messages sent to Anthropic via the `claude` CLI (your Claude subscription) |
|
|
26
|
+
| `codex-process` | Messages sent to OpenAI via the `codex` CLI (your OpenAI subscription) |
|
|
27
|
+
| `anthropic` | Messages sent to Anthropic API (your API key) |
|
|
28
|
+
| `openai` | Messages sent to OpenAI API (your API key) |
|
|
29
|
+
|
|
30
|
+
When using an external summarizer, only the text being summarized is sent — not your full history. The summarizer receives a batch of recent messages to compress into a summary.
|
|
31
|
+
|
|
32
|
+
## Secret redaction
|
|
33
|
+
|
|
34
|
+
lossless-claude scrubs secrets from message content **before writing to SQLite** and **before sending to the summarizer**. Redaction happens at both write points to ensure secrets are never persisted or transmitted.
|
|
35
|
+
|
|
36
|
+
### Built-in patterns
|
|
37
|
+
|
|
38
|
+
These patterns are always active, regardless of configuration:
|
|
39
|
+
|
|
40
|
+
| Pattern | Example match |
|
|
41
|
+
|---------|--------------|
|
|
42
|
+
| OpenAI secret key | `sk-...` |
|
|
43
|
+
| Anthropic API key | `sk-ant-...` |
|
|
44
|
+
| GitHub personal access token | `ghp_...` |
|
|
45
|
+
| AWS access key ID | `AKIA...` |
|
|
46
|
+
| PEM private key | `-----BEGIN ... KEY-----` |
|
|
47
|
+
| Bearer token | `Authorization: Bearer ...` |
|
|
48
|
+
| Password assignment | `password=...`, `PASSWORD: ...` |
|
|
49
|
+
|
|
50
|
+
### Project-specific patterns
|
|
51
|
+
|
|
52
|
+
Add patterns for secrets specific to your project:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Add a pattern (stored in ~/.lossless-claude/projects/{hash}/sensitive-patterns.txt)
|
|
56
|
+
lcm sensitive add "MY_APP_API_KEY_[A-Z0-9]+"
|
|
57
|
+
|
|
58
|
+
# Add a global pattern (applies to all projects, stored in config.json)
|
|
59
|
+
lcm sensitive add --global "CORP_INTERNAL_TOKEN"
|
|
60
|
+
|
|
61
|
+
# Test what gets redacted
|
|
62
|
+
lcm sensitive test "token=MY_APP_API_KEY_ABCDEF123"
|
|
63
|
+
# → token=[REDACTED]
|
|
64
|
+
|
|
65
|
+
# List all active patterns
|
|
66
|
+
lcm sensitive list
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Patterns are JavaScript-compatible regular expressions. Use specific patterns (e.g., `MY_SECRET_[A-Z0-9]+`) rather than broad ones (e.g., `MY_.*`) to avoid over-redaction.
|
|
70
|
+
|
|
71
|
+
## Data retention
|
|
72
|
+
|
|
73
|
+
Messages and summaries persist until you explicitly remove them:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Remove data for the current project
|
|
77
|
+
lcm sensitive purge --yes
|
|
78
|
+
|
|
79
|
+
# Remove all lossless-claude data
|
|
80
|
+
lcm uninstall
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
SQLite database files are stored in `~/.lossless-claude/projects/`. You can delete individual project directories manually to remove their history.
|
|
84
|
+
|
|
85
|
+
## Verifying your setup
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
lcm doctor
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The `Security` section of the doctor output shows:
|
|
92
|
+
- How many built-in patterns are active
|
|
93
|
+
- Whether project-specific patterns are configured
|
|
94
|
+
|
|
95
|
+
## Summary
|
|
96
|
+
|
|
97
|
+
- All data is local — SQLite in `~/.lossless-claude/`.
|
|
98
|
+
- External summarizer (optional) receives only the text to be summarized, after scrubbing.
|
|
99
|
+
- Built-in patterns redact common secret formats automatically.
|
|
100
|
+
- Add project-specific patterns with `lcm sensitive add`.
|
|
101
|
+
- Delete your data with `lcm uninstall` or by removing `~/.lossless-claude/`.
|
package/mcp.mjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// MCP entrypoint for plugin system — delegates to the built lcm MCP server.
|
|
3
|
+
// Uses import.meta.url to resolve paths relative to this file, so it works
|
|
4
|
+
// regardless of how the plugin cache resolves ${CLAUDE_PLUGIN_ROOT}.
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
|
+
import { join, dirname } from "node:path";
|
|
7
|
+
|
|
8
|
+
let __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
// If we're in .claude-plugin/, go up one level to find dist/
|
|
10
|
+
if (__dirname.endsWith(".claude-plugin")) {
|
|
11
|
+
__dirname = join(__dirname, "..");
|
|
12
|
+
}
|
|
13
|
+
const serverModule = join(__dirname, "dist", "src", "mcp", "server.js");
|
|
14
|
+
|
|
15
|
+
// Use file:// URL for cross-platform compatibility (notably Windows)
|
|
16
|
+
const { startMcpServer } = await import(pathToFileURL(serverModule).href);
|
|
17
|
+
await startMcpServer();
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lossless-claude/lcm",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Never lose context again. lossless-claude compresses Claude Code sessions into searchable memory — every message preserved, every insight remembered.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/src/memory/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/src/memory/index.js"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"lcm": "dist/bin/lcm.js"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "Pedro Almeida (https://github.com/ipedro)",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"claude-code",
|
|
17
|
+
"claude-code-plugin",
|
|
18
|
+
"context-management",
|
|
19
|
+
"llm",
|
|
20
|
+
"summarization",
|
|
21
|
+
"conversation-memory",
|
|
22
|
+
"dag"
|
|
23
|
+
],
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/",
|
|
26
|
+
"mcp.mjs",
|
|
27
|
+
".claude-plugin/",
|
|
28
|
+
"docs/",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"postbuild": "mkdir -p dist/src/prompts && cp -r src/prompts/*.yaml dist/src/prompts/ && mkdir -p dist/src/connectors/templates && cp -r src/connectors/templates/. dist/src/connectors/templates/",
|
|
35
|
+
"prepublishOnly": "npm run build",
|
|
36
|
+
"changeset": "changeset",
|
|
37
|
+
"release:verify": "npm test && npm pack --dry-run",
|
|
38
|
+
"test": "vitest run --dir test",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"version-packages": "changeset version"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
44
|
+
"@sinclair/typebox": "0.34.48",
|
|
45
|
+
"js-yaml": "^4.1.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
49
|
+
"@changesets/cli": "^2.30.0",
|
|
50
|
+
"@types/js-yaml": "^4.0.9",
|
|
51
|
+
"@types/node": ">=22",
|
|
52
|
+
"openai": "^6.32.0",
|
|
53
|
+
"typescript": "^5.7.0",
|
|
54
|
+
"vitest": "^3.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
58
|
+
"openai": "^6.32.0"
|
|
59
|
+
},
|
|
60
|
+
"peerDependenciesMeta": {
|
|
61
|
+
"@anthropic-ai/sdk": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"openai": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
},
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "git+https://github.com/lossless-claude/lcm.git"
|
|
74
|
+
},
|
|
75
|
+
"homepage": "https://github.com/lossless-claude/lcm#readme",
|
|
76
|
+
"bugs": {
|
|
77
|
+
"url": "https://github.com/lossless-claude/lcm/issues"
|
|
78
|
+
}
|
|
79
|
+
}
|