opencode-clm 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # Changelog
2
+
3
+ From 0.1.1 on, release notes are generated by git-cliff from Conventional Commits and
4
+ published on [GitHub Releases](https://github.com/bcmyguest/opencode-clm/releases).
5
+
6
+ ## 0.1.0 (unreleased)
7
+
8
+ First release: Context Language Model mode for OpenCode 1.18, ported from pi-clm 1.0.0.
9
+
10
+ - Context mirror `LIVE_CONTEXT.md` per session, rewritten before each request; the model
11
+ edits it with bash, and the plugin applies the edit on the next request.
12
+ - Edit gate (`fit`, `shrink`, `none`; default `fit`), with a verdict appended to each tool
13
+ call that writes the mirror and a `[CLM]` note on the next request.
14
+ - Projection checkpoints in `state.json` that survive OpenCode's prune; the plugin drops
15
+ the revision when the stored history no longer matches, except after a compaction,
16
+ where it rebases onto the summary and keeps pins and continuity annotations.
17
+ - Budget tiers (default 32,000 tokens, reserve 2,048, reminders at 25/50/75% and at
18
+ budget − reserve) with a calibrated chars/4 estimate that counts the system prompt and
19
+ tool schemas; with `guard: "off"` budget notices omit the guard sentence.
20
+ - Optional per-result observation cap; overflow guard that withholds the oldest new tool
21
+ results to files above budget − reserve.
22
+ - Continuity tools `clm_annotate` (pin, continuity, archive) and `clm_recall`.
23
+ - Commands `/clm [status | path | on | off | reset]` and `/clm-compact [instructions]`.
24
+ - Skill `clm-context`; optional steering document, with pi-clm's house brief bundled.
25
+ - Settings through plugin options or `CLM_*` environment variables.
26
+ - Hooks fail open; user-defined `clm` and `clm-compact` commands are kept and left alone.
package/LICENSE ADDED
@@ -0,0 +1,35 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 B Guest
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ -------------------------------------------------------------------------------
24
+
25
+ Portions of this software are derived from pi-clm 1.0.0
26
+ (https://github.com/lolipopshock/pi-clm, commit b84a9d7), distributed under the
27
+ MIT License. The NOTICE file lists the files concerned. pi-clm's notice:
28
+
29
+ Copyright 2026 Emanuel Casco
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/NOTICE ADDED
@@ -0,0 +1,41 @@
1
+ opencode-clm
2
+ Copyright (c) 2026 B Guest. MIT License (see LICENSE).
3
+
4
+ This product includes software derived from pi-clm 1.0.0
5
+ (https://github.com/lolipopshock/pi-clm, commit b84a9d7), MIT License,
6
+ Copyright 2026 Emanuel Casco. pi-clm's license notice is reproduced in LICENSE.
7
+
8
+ Derived from pi-clm (code and model-facing text, adapted for OpenCode):
9
+ index.ts pi-clm index.ts, src/index.ts (hooks, commands, tools)
10
+ src/budget.ts src/budget.ts (status line and budget notices)
11
+ src/clm.ts src/index.ts (context and turn_end handling)
12
+ src/compact.ts src/compact.ts (compaction prompt, near verbatim)
13
+ src/context-document.ts src/context-document.ts (rejection and receipt text)
14
+ src/continuity.ts src/continuity.ts, annotate/recall tools in src/index.ts
15
+ src/mirror-guard.ts src/mirror-guard.ts
16
+ src/mirror-store.ts src/mirror-store.ts
17
+ src/observation.ts src/observation.ts
18
+ src/overflow.ts src/overflow.ts
19
+ src/projection.ts src/projection.ts
20
+ src/settings.ts src/settings.ts
21
+ src/state.ts src/state.ts
22
+ src/steering.ts src/steering.ts
23
+ src/types.ts src/types.ts
24
+ steering/house-brief.md steering/house-brief.md (byte-identical copy)
25
+ skills/clm-context/SKILL.md src/skills/live-context/SKILL.md
26
+
27
+ Written for this package (structure follows pi-clm, text does not):
28
+ src/presentation.ts (system-prompt protocol section and /clm status text),
29
+ src/policy.ts (edit gate and its refusal note), src/opencode.ts.
30
+
31
+ Context Language Models
32
+ Paper: arXiv 2609.37725. Research code:
33
+ https://github.com/facebookresearch/context-language-models, licensed CC BY-NC 4.0.
34
+ opencode-clm is not licensed under CC BY-NC and is not endorsed by its authors. A
35
+ normalized 5-gram comparison of every model-facing string here against that
36
+ repository found no shared span longer than 6 tokens (generic phrases and URLs).
37
+ Two design choices follow its harness: the fit/shrink edit gate and the default
38
+ 25/50/75% reminder steps. pi-clm's skill guidance on edit cost (batch edits, mind the
39
+ tail below an edit, write detailed summaries), carried into
40
+ skills/clm-context/SKILL.md, covers the same points as the harness prompt in
41
+ different words.
package/README.md ADDED
@@ -0,0 +1,294 @@
1
+ # opencode-clm
2
+
3
+ An [OpenCode](https://opencode.ai) plugin that runs a model as a Context Language Model
4
+ (CLM): the model edits a text mirror of its own conversation, and the edited mirror
5
+ becomes its input on the next request. OpenCode's stored session stays unchanged.
6
+
7
+ It ports [pi-clm](https://github.com/lolipopshock/pi-clm) 1.0.0, the Pi extension that
8
+ accompanies the CLM paper ([arXiv 2609.37725](https://arxiv.org/abs/2609.37725)).
9
+ [PORTING.md](PORTING.md) maps each pi-clm file to its counterpart here.
10
+
11
+ ## Install
12
+
13
+ Tested with OpenCode 1.18.34.
14
+
15
+ From npm, once published, in `opencode.json`:
16
+
17
+ ```json
18
+ { "plugin": ["opencode-clm"] }
19
+ ```
20
+
21
+ From a local clone:
22
+
23
+ ```json
24
+ { "plugin": ["file:///path/to/opencode-clm/index.ts"] }
25
+ ```
26
+
27
+ ## Configuration
28
+
29
+ Pass options as the second element of a plugin tuple:
30
+
31
+ ```json
32
+ { "plugin": [["opencode-clm", { "budget": "64k", "gate": "shrink" }]] }
33
+ ```
34
+
35
+ Each option falls back to its environment variable, then to the default. The plugin reads
36
+ them once at load; an invalid value fails the plugin load with an error that names the
37
+ option.
38
+
39
+ | option | env | default | values |
40
+ |---|---|---|---|
41
+ | `enabled` | `CLM_ENABLED` | `true` | `false` registers no hooks |
42
+ | `budget` | `CLM_BUDGET` | `32000` | tokens (`32000`, `32k`, `1.5m`, `32_000`), or `window` for the model's context window. The model window minus its output limit caps the value |
43
+ | `reserve` | `CLM_RESERVE` | `2048` | tokens held back below the budget for generation |
44
+ | `remindAt` | `CLM_REMIND_AT` | `0.25,0.5,0.75` | fractions (`0.25,0.5`) or percentages (`25/50%`) strictly between 0 and 1; `off` disables all reminders, the budget − reserve reminder included |
45
+ | `gate` | `CLM_EDIT_GATE` | `fit` | `fit`, `shrink` or `none` |
46
+ | `guard` | `CLM_OVERFLOW` | `withhold` | `withhold` or `off` |
47
+ | `observationCap` | `CLM_OBSERVATION_CAP` | off | `characters[:head fraction]`, e.g. `10000:0.5`; at least 200; head fraction defaults to 0.8; `off` or `0` disables |
48
+ | `mirrorDir` | `CLM_MIRROR_DIR` | `<project>/.opencode/clm` | parent of the per-session directories; relative paths resolve against the project |
49
+ | `steering` | `CLM_STEERING` | none | path to a steering document, or `house` for the bundled `steering/house-brief.md`; `none` or `off` disables |
50
+ | `compactPrompt` | `CLM_COMPACT_PROMPT` | built-in | path to a `/clm-compact` template; `default`, `none` or `off` mean the built-in prompt |
51
+ | `estimateFactor` | `CLM_ESTIMATE_FACTOR` | `1` | 1 to 4; multiplies the chars/4 token estimate (1.5–2 for dense content) |
52
+ | `reasoning` | `CLM_REASONING` | `true` | render assistant reasoning in the mirror |
53
+ | `dumpRequests` | `CLM_DUMP_REQUESTS` | `false` | write each transformed request to `<session dir>/requests/nN.json` |
54
+ | `skill` | — | `true` | register the `clm-context` skill; `false` matches pi-clm's CLM mode, which offers no skill |
55
+ | `commands` | — | `true` | register `/clm` and `/clm-compact` |
56
+
57
+ Booleans accept `true/false`, `1/0`, `on/off` and `yes/no`.
58
+
59
+ A steering document carries context-management strategy (when to compact, what to keep);
60
+ the plugin itself states only the editing protocol. The plugin reads the document once at
61
+ load and appends it to the system prompt; `/clm` shows its name and SHA-256 prefix.
62
+
63
+ A `compactPrompt` template may use `{{mirror}}`, `{{current}}`, `{{budget}}` and
64
+ `{{instructions}}`. The plugin rereads it on every use.
65
+
66
+ ## Commands
67
+
68
+ - `/clm [status | path | on | off | reset]`: `status` (the default) prints the session's
69
+ mirror path, revision, accepted and rejected edits, gate, guard, budget reading and
70
+ active revision, and shows a toast. `path` prints the mirror path. `on` and `off` switch
71
+ CLM for the session. `reset` drops the accepted revision, so the next request carries
72
+ the stored history. The command costs one model turn: OpenCode cannot cancel a command,
73
+ so the model receives the text and repeats it.
74
+ - `/clm-compact [instructions]`: asks the model to compact its context now by editing the
75
+ mirror. Text after the command is appended to the prompt.
76
+
77
+ If your config already defines `clm` or `clm-compact`, the plugin keeps your command,
78
+ logs a warning and leaves it alone. A failing command prints `[CLM] /<name> failed:
79
+ <reason>` and shows an error toast.
80
+
81
+ ## Tools
82
+
83
+ - `clm_annotate`: `action` is `create`, `resolve` or `list`. `create` takes a mirror block
84
+ id (`source`), `title`, `reason`, `futureAction` and `retention`:
85
+ - `pin` keeps the exact source text in every request (up to 8,000 tokens);
86
+ - `continuity` keeps the title, reason, next action and recall id in every request;
87
+ - `archive` keeps nothing in the request; the source is available through recall.
88
+ - `clm_recall`: returns an annotation's saved source; `maxTokens` 128–8,000, default 2,000.
89
+
90
+ ## Skill
91
+
92
+ `skills/clm-context/SKILL.md`, adapted from pi-clm's `live-context` skill, tells the model
93
+ when and how to edit the mirror: batched surgical edits, keeping conversational units
94
+ together, durable summaries, and Python scripts that list headers and replace or remove
95
+ blocks by id. The plugin adds the `skills` directory to OpenCode's `skills.paths`.
96
+
97
+ ## How it works
98
+
99
+ **Mirror.** Before each model request, the plugin writes every message after the first
100
+ user message to `LIVE_CONTEXT.md` in the session directory. Line 1 is a `[[LIVE_CONTEXT
101
+ ...]]` header with the revision and document id; each message follows as a block headed
102
+ `[[CTX_TURN document=<id> index=<n> role=<role> id=<block id> protected=<bool>]]`. The
103
+ system prompt and the first user message stay outside the mirror and are always sent. A
104
+ system-prompt section, `## Editable context`, teaches the model the format.
105
+
106
+ **Editing.** The model edits the mirror with the bash tool (python3, `sed -i`). The edit
107
+ and write tools keep a copy that goes stale when the plugin regenerates the file, so the
108
+ protocol tells the model to avoid them on the mirror. Deleting a block drops the message.
109
+ New text under a tool result replaces its output and keeps the call. New text under an
110
+ assistant header replaces the reply and turns its tool results into notes. A header copied
111
+ with `id=new-NAME` inserts a note. Replacing the whole file with text that has no block
112
+ headers replaces everything after the first user message with one notes block. When a
113
+ bash, edit, write or apply_patch call writes the mirror, the plugin appends a verdict to
114
+ its output (accepted, or the reason for refusal); a heuristic detects bash writes. A
115
+ `[CLM]` note on the next request reports what was applied.
116
+
117
+ **Commit.** OpenCode has no end-of-turn hook, so the plugin reads the mirror at the start
118
+ of the next request. If the file differs from the last render, the plugin parses it and
119
+ applies it. It refuses a file whose line 1 no longer parses or names another document, a
120
+ file with duplicate or unknown block ids, and a file the edit gate rejects; the context
121
+ then stays as it was.
122
+
123
+ **Edit gate.** Every gate accepts an edit that keeps the context the same size or smaller.
124
+ For growth: `fit` accepts it while the editable context stays within budget − reserve
125
+ minus the system prompt, tool schemas, pinned text and continuity notes, and accepts everything while the budget is
126
+ unknown; `shrink` rejects it; `none` applies no size check.
127
+
128
+ **Projection checkpoints.** An accepted edit becomes a revision. The checkpoint stores the
129
+ number of flattened raw messages it replaces, their OpenCode message ids, and a SHA-256
130
+ digest of them, with tool-result content excluded so OpenCode's prune does not invalidate
131
+ it. A pruned tool output inside an accepted revision goes out with the revision's text.
132
+ Each later request sends the projected messages plus the raw messages added since.
133
+ When the stored prefix no longer matches (a revert, for example), the plugin drops the
134
+ revision, sends the raw history, and tells the model. Compaction is the exception (see
135
+ Compaction).
136
+
137
+ **Budget tiers.** Token estimates are chars/4 × `estimateFactor` × a calibration factor
138
+ learned from the provider's reported input sizes (never below 1). The estimate covers the
139
+ system prompt, tool schemas, pinned task, editable context, continuity text and notices.
140
+ Until a size is known, the `[CLM BUDGET]` note names what the estimate leaves out. Reminders fire once per tier, as `[CLM BUDGET]` notes, at each
141
+ `remindAt` fraction and at budget − reserve. Requests are never blocked.
142
+
143
+ **Observation cap.** When set, each tool result in the sent context keeps at most
144
+ `characters` characters (the head fraction from the start, the rest from the end) plus a
145
+ marker stating how much was cut. The stored output stays complete.
146
+
147
+ **Overflow guard.** When the estimated request exceeds budget − reserve, the guard
148
+ replaces new tool results, oldest first, with a note naming the tool, call id, size and a
149
+ file in `withheld/` that holds the full output (or, if saving fails, a pointer to the
150
+ session history), until the estimate fits. User and
151
+ assistant messages stay untouched, and no tool runs again. `guard: "off"` disables it.
152
+
153
+ **Continuity.** Annotations (see Tools) let the model shorten or delete a block while a
154
+ pin, a continuity note or a recall copy keeps what later work needs. The plugin sends
155
+ active annotations as a user-role note after the conversation, and warns the model when they exceed
156
+ 8,000 tokens.
157
+
158
+ **Compaction.** CLM replaces compaction: the model shrinks its own context by editing the
159
+ mirror. Set `"compaction": { "auto": false }` in `opencode.json` while CLM is on, and keep
160
+ auto-compaction only as a fallback for a session that outgrows the window anyway.
161
+
162
+ When OpenCode compacts:
163
+ 1. The plugin applies the accepted revision to the history OpenCode summarizes, so the
164
+ summary reflects the edited context. It makes no commit or render.
165
+ 2. It appends an instruction to the compaction prompt: copy every pin and continuity
166
+ annotation, listed after it, into the summary verbatim.
167
+ 3. When a revision is active and OpenCode reports the finished compaction (the `session.compacted` event or the
168
+ `experimental.compaction.autocontinue` hook), the next request rebases: the summary
169
+ becomes the new baseline, the revision number moves on, and the model gets no
170
+ dropped-revision note. Pins and continuity annotations carry over unchanged, and
171
+ `events.jsonl` records a `compacted` event.
172
+
173
+ OpenCode's title, summary and compaction agents get no protocol text.
174
+
175
+ ## State
176
+
177
+ Each session has a directory `<mirrorDir>/clm-<session id>/` (mode 0700; files 0600):
178
+
179
+ | file | content |
180
+ |---|---|
181
+ | `LIVE_CONTEXT.md` | the mirror |
182
+ | `state.json` | enabled flag, revision, active checkpoint |
183
+ | `annotations.jsonl` | continuity annotations |
184
+ | `events.jsonl` | one line per request, edit, reset, notice and error |
185
+ | `revisions/rN.md` | the mirror text of each accepted revision |
186
+ | `withheld/` | tool outputs held back by the overflow guard |
187
+ | `requests/nN.json` | transformed requests, with `dumpRequests` only |
188
+
189
+ The plugin deletes session directories untouched for 7 days when it opens another
190
+ session. The default `mirrorDir` lies inside the project; add `.opencode/clm/` to
191
+ `.gitignore`.
192
+
193
+ ## Limitations
194
+
195
+ - Status, budget and edit outcomes appear as text, toasts and `events.jsonl`. pi-clm's
196
+ TUI viewer, timeline and diff are not ported: OpenCode server plugins cannot draw panels.
197
+ - No per-session settings panel; `/clm on|off|reset` are the only per-session switches.
198
+ - Model limits and the system-prompt size reach the plugin one request late. On the
199
+ first request of a process the model window does not yet cap the budget and the
200
+ estimate omits the system prompt; with `budget: "window"` that request has no budget
201
+ reading. `/clm-compact` before the first request reports about 0 tokens.
202
+ - Built-in tool descriptions are measured, but not their parameter schemas, so
203
+ calibration attributes that size to undercounting.
204
+ - A checkpoint ignores changes to stored tool output inside the prefix it covers. An
205
+ output rewritten by another plugin or an SDK client goes out with the new text, while
206
+ the mirror and estimate keep the revision's.
207
+ - Hooks fail open: if the transform throws, the request goes out with the raw history and
208
+ an error toast.
209
+ - The calibration factor lives in memory and restarts at 1 with each process.
210
+ - A subagent (task) session gets its own mirror and state.
211
+ - Not ported from pi-clm: branch-aware restore, the `max_tokens` clamp lift, cancelling
212
+ Pi's own compaction, and the `oneToolPerTurn` and `sizeTrailer` switches.
213
+
214
+ ## Testing
215
+
216
+ No model has run through this package. Its tests are unit tests, a load smoke test and a
217
+ mock-server end-to-end test (see Development).
218
+
219
+ The integration suite (`test/e2e`, 10 tests) drives the real OpenCode binary
220
+ (1.18.34, pinned in CI) against a scripted OpenAI-compatible mock, with temporary HOME
221
+ and XDG directories. It covers: plugin load and command registration (`debug config`,
222
+ `/clm path`, `/clm-compact`); the mirror written and re-rendered each turn; an accepted
223
+ edit whose text reaches the next request; a `shrink` gate refusal and the note the model
224
+ sees; budget nudges at 50% and at budget − reserve; auto-compaction (the summary carries
225
+ the edited text and the summarizer gets the pin instruction; the next request rebases onto
226
+ the summary with no drop note, and a pin survives); receipts
227
+ from `tool.execute.after`; the observation cap; and a second `opencode run --session`
228
+ resuming the revision and mirror. Not covered: the overflow guard, the continuity tools
229
+ and a manual `/compact`.
230
+
231
+ The server-side suffix-cache work is experimental and unreleased.
232
+
233
+ ## Development
234
+
235
+ - `bun test`: unit tests.
236
+ - `bun run typecheck`: `tsc --noEmit`.
237
+ - `scripts/smoke.sh`: offline, no model. Checks the `npm pack` file list, that OpenCode
238
+ loads the plugin from `file://` and registers `/clm`, `/clm-compact` and the skills
239
+ path with no plugin error in its logs, and how `@opencode-ai/plugin` resolves from the
240
+ repo, a bare tarball and an offline `npm install`.
241
+ - `bun run test:e2e`: the integration suite above (about 30-55 s). Needs the `opencode`
242
+ binary (`OPENCODE_BIN` overrides it; `OPENCODE_CLM_E2E_KEEP=1` keeps the temp tree) and
243
+ npm registry access, because OpenCode installs `@opencode-ai/plugin` into its temporary
244
+ config directory.
245
+ - CI (`.github/workflows/ci.yml`) runs on pull requests and pushes to `main`: frozen
246
+ install, typecheck, `bun test`, `npm pack --dry-run`, `scripts/smoke.sh --strict` and the
247
+ integration suite against `opencode-ai@1.18.34`.
248
+ - Commit messages follow [Conventional Commits](https://www.conventionalcommits.org)
249
+ (`feat:`, `fix:`, `docs:`, `ci:`, `test:`, `refactor:`, `chore:`; `!` for breaking
250
+ changes). `pre-commit install` adds a commit-msg hook that checks them.
251
+
252
+ ## Releasing
253
+
254
+ Releases come from Conventional Commits through [git-cliff](https://git-cliff.org)
255
+ (`cliff.toml`). `feat` bumps minor; `fix` and any commit except `chore` and `style` bump
256
+ patch; a breaking change bumps minor below 1.0.0. v0.1.0 is a single commit,
257
+ `feat: initial release`.
258
+
259
+ 1. Actions → "Prepare release" → Run workflow on `main` (tick `dry_run` to preview).
260
+ It computes the version (`git-cliff --bumped-version`), bumps `package.json` if needed,
261
+ commits `chore(release): vX.Y.Z`, tags, pushes and dispatches "Release".
262
+ 2. "Release" checks the tag against `package.json`, runs CI on the tag, publishes to npm
263
+ through trusted publishing (OIDC, provenance, no token), then creates the GitHub
264
+ Release with git-cliff notes.
265
+
266
+ Preview locally: `git-cliff --bumped-version` and `git-cliff --unreleased --strip header`.
267
+ Notes for 0.1.1 and later live in GitHub Releases; CHANGELOG.md holds 0.1.0.
268
+
269
+ ## Credits
270
+
271
+ - [pi-clm](https://github.com/lolipopshock/pi-clm) 1.0.0 (MIT, Copyright 2026 Emanuel
272
+ Casco): the design and most of the code derive from it. Model-facing text taken from
273
+ pi-clm, adapted: the compaction prompt (`src/compact.ts`), the `clm-context` skill, the
274
+ budget notices, the mirror rejection and receipt messages, and the overflow and
275
+ observation notes. `steering/house-brief.md` is byte-identical to pi-clm's. Written for
276
+ this package: the system-prompt protocol section (`src/presentation.ts`), the edit-gate
277
+ refusal note, and the plugin's own receipts, commands and tool descriptions.
278
+ [NOTICE](NOTICE) lists the files; [LICENSE](LICENSE) carries pi-clm's notice.
279
+ - Context Language Models, [arXiv 2609.37725](https://arxiv.org/abs/2609.37725), and
280
+ [facebookresearch/context-language-models](https://github.com/facebookresearch/context-language-models)
281
+ (CC BY-NC 4.0). This package copies no text from that repository (normalized 5-gram
282
+ check: no shared span over 6 tokens). The `fit` / `shrink` edit gate and the default
283
+ 25/50/75% reminder steps follow its harness design, and the edit-cost advice in the
284
+ skill, inherited from pi-clm, covers the same points as the harness prompt in different
285
+ words. This package is not licensed under CC BY-NC and is not endorsed by its authors.
286
+
287
+ ## AI assistance
288
+
289
+ Claude Code (Claude Opus) wrote the code and documentation in this repository. The
290
+ maintainer has not hand-reviewed them.
291
+
292
+ ## License
293
+
294
+ MIT. See [LICENSE](LICENSE), which includes the pi-clm notice, and [NOTICE](NOTICE).