@jmtrin/opencode-kevin 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -22
- package/dist/plugin/index.d.ts +5 -4
- package/dist/plugin/index.js +127 -113
- package/dist/plugin/native.d.ts +2 -2
- package/dist/plugin/native.js +2 -2
- package/package.json +56 -68
- package/dist/migrations/001_initial.sql +0 -92
- package/dist/migrations/002_indexes.sql +0 -14
- package/dist/migrations/003_v02_signal.sql +0 -58
- package/dist/migrations/004_v03_knowledge.sql +0 -138
- package/dist/migrations/005_v04_signal.sql +0 -57
- package/dist/migrations/006_v05_glassbox.sql +0 -118
- package/dist/migrations/007_v06_pull.sql +0 -145
- package/dist/migrations/008_v07_truth.sql +0 -124
- package/dist/migrations/009_v08_team.sql +0 -100
- package/dist/migrations/010_v09_native.sql +0 -78
- package/dist/migrations/011_v10_proven.sql +0 -69
- package/dist/migrations/012_v11_drift.sql +0 -24
- package/dist/plugin/Archiver.d.ts +0 -42
- package/dist/plugin/Archiver.js +0 -83
- package/dist/plugin/ArtifactWriter.d.ts +0 -93
- package/dist/plugin/ArtifactWriter.js +0 -291
- package/dist/plugin/CausalChain.d.ts +0 -22
- package/dist/plugin/CausalChain.js +0 -197
- package/dist/plugin/ChatBridge.d.ts +0 -41
- package/dist/plugin/ChatBridge.js +0 -103
- package/dist/plugin/ConflictDetector.d.ts +0 -35
- package/dist/plugin/ConflictDetector.js +0 -260
- package/dist/plugin/ContextInjector.d.ts +0 -222
- package/dist/plugin/ContextInjector.js +0 -533
- package/dist/plugin/ConventionMiner.d.ts +0 -35
- package/dist/plugin/ConventionMiner.js +0 -242
- package/dist/plugin/Curator.d.ts +0 -116
- package/dist/plugin/Curator.js +0 -324
- package/dist/plugin/DashboardHtml.d.ts +0 -5
- package/dist/plugin/DashboardHtml.js +0 -180
- package/dist/plugin/Feedback.d.ts +0 -67
- package/dist/plugin/Feedback.js +0 -120
- package/dist/plugin/HookLiveness.d.ts +0 -88
- package/dist/plugin/HookLiveness.js +0 -322
- package/dist/plugin/InjectionLedger.d.ts +0 -98
- package/dist/plugin/InjectionLedger.js +0 -295
- package/dist/plugin/LessonFixer.d.ts +0 -44
- package/dist/plugin/LessonFixer.js +0 -45
- package/dist/plugin/Materializer.d.ts +0 -83
- package/dist/plugin/Materializer.js +0 -181
- package/dist/plugin/MemoryService.d.ts +0 -360
- package/dist/plugin/MemoryService.js +0 -1242
- package/dist/plugin/Migrate.d.ts +0 -17
- package/dist/plugin/Migrate.js +0 -271
- package/dist/plugin/PatternMiner.d.ts +0 -49
- package/dist/plugin/PatternMiner.js +0 -132
- package/dist/plugin/QualityGate.d.ts +0 -124
- package/dist/plugin/QualityGate.js +0 -119
- package/dist/plugin/Reflector.d.ts +0 -91
- package/dist/plugin/Reflector.js +0 -307
- package/dist/plugin/RepoIdentity.d.ts +0 -124
- package/dist/plugin/RepoIdentity.js +0 -300
- package/dist/plugin/RepoTruth.d.ts +0 -80
- package/dist/plugin/RepoTruth.js +0 -599
- package/dist/plugin/Retrospective.d.ts +0 -17
- package/dist/plugin/Retrospective.js +0 -216
- package/dist/plugin/SharedLayer.d.ts +0 -159
- package/dist/plugin/SharedLayer.js +0 -462
- package/dist/plugin/Store.d.ts +0 -29
- package/dist/plugin/Store.js +0 -50
- package/dist/plugin/ToolCallObserver.d.ts +0 -32
- package/dist/plugin/ToolCallObserver.js +0 -201
- package/dist/plugin/TuiActions.d.ts +0 -43
- package/dist/plugin/TuiActions.js +0 -181
- package/dist/plugin/TuiSnapshots.d.ts +0 -24
- package/dist/plugin/TuiSnapshots.js +0 -158
- package/dist/plugin/columns.d.ts +0 -11
- package/dist/plugin/columns.js +0 -54
- package/dist/plugin/confidence.d.ts +0 -8
- package/dist/plugin/confidence.js +0 -34
- package/dist/plugin/contract.d.ts +0 -54
- package/dist/plugin/contract.js +0 -386
- package/dist/plugin/diff.d.ts +0 -8
- package/dist/plugin/diff.js +0 -182
- package/dist/plugin/escape.d.ts +0 -39
- package/dist/plugin/escape.js +0 -60
- package/dist/plugin/fingerprint.d.ts +0 -27
- package/dist/plugin/fingerprint.js +0 -73
- package/dist/plugin/inferability.d.ts +0 -32
- package/dist/plugin/inferability.js +0 -88
- package/dist/plugin/kevin_approve.d.ts +0 -34
- package/dist/plugin/kevin_approve.js +0 -52
- package/dist/plugin/kevin_audit.d.ts +0 -229
- package/dist/plugin/kevin_audit.js +0 -631
- package/dist/plugin/kevin_bench.d.ts +0 -10
- package/dist/plugin/kevin_bench.js +0 -82
- package/dist/plugin/kevin_conflicts.d.ts +0 -9
- package/dist/plugin/kevin_conflicts.js +0 -50
- package/dist/plugin/kevin_contract.d.ts +0 -8
- package/dist/plugin/kevin_contract.js +0 -59
- package/dist/plugin/kevin_doctor.d.ts +0 -62
- package/dist/plugin/kevin_doctor.js +0 -196
- package/dist/plugin/kevin_facts.d.ts +0 -42
- package/dist/plugin/kevin_facts.js +0 -36
- package/dist/plugin/kevin_forget.d.ts +0 -33
- package/dist/plugin/kevin_forget.js +0 -260
- package/dist/plugin/kevin_native.d.ts +0 -29
- package/dist/plugin/kevin_native.js +0 -79
- package/dist/plugin/kevin_propose.d.ts +0 -23
- package/dist/plugin/kevin_propose.js +0 -14
- package/dist/plugin/kevin_publish.d.ts +0 -38
- package/dist/plugin/kevin_publish.js +0 -18
- package/dist/plugin/kevin_why.d.ts +0 -23
- package/dist/plugin/kevin_why.js +0 -111
- package/dist/plugin/memory-format.d.ts +0 -20
- package/dist/plugin/memory-format.js +0 -59
- package/dist/plugin/metrics.d.ts +0 -97
- package/dist/plugin/metrics.js +0 -288
- package/dist/plugin/okf-export.d.ts +0 -3
- package/dist/plugin/okf-export.js +0 -134
- package/dist/plugin/okf-import.d.ts +0 -76
- package/dist/plugin/okf-import.js +0 -271
- package/dist/plugin/okf.d.ts +0 -107
- package/dist/plugin/okf.js +0 -303
- package/dist/plugin/perf.d.ts +0 -35
- package/dist/plugin/perf.js +0 -174
- package/dist/plugin/query-tokenizer.d.ts +0 -13
- package/dist/plugin/query-tokenizer.js +0 -133
- package/dist/plugin/redact.d.ts +0 -2
- package/dist/plugin/redact.js +0 -18
- package/dist/plugin/replay-types.d.ts +0 -69
- package/dist/plugin/replay-types.js +0 -156
- package/dist/plugin/replay.d.ts +0 -36
- package/dist/plugin/replay.js +0 -202
- package/dist/plugin/sqlite-adapter.d.ts +0 -12
- package/dist/plugin/sqlite-adapter.js +0 -81
- package/dist/plugin/time-ms.d.ts +0 -1
- package/dist/plugin/time-ms.js +0 -16
- package/dist/plugin/tui-types.d.ts +0 -59
- package/dist/plugin/tui-types.js +0 -4
- package/dist/plugin/tui.d.ts +0 -18
- package/dist/plugin/tui.js +0 -198
- package/dist/plugin/uuid.d.ts +0 -1
- package/dist/plugin/uuid.js +0 -50
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ injects exactly what matters back into the model's context, curates the best
|
|
|
26
26
|
of it into files you control, and shares it across a team through one
|
|
27
27
|
git-friendly file — deterministically, locally, with zero network calls.
|
|
28
28
|
|
|
29
|
-

|
|
30
30
|

|
|
31
31
|

|
|
32
32
|

|
|
@@ -48,10 +48,14 @@ git-friendly file — deterministically, locally, with zero network calls.
|
|
|
48
48
|
- [Why Kevin](#-why-kevin)
|
|
49
49
|
- [The Kevin loop](#-the-kevin-loop)
|
|
50
50
|
- [Quick start](#-quick-start)
|
|
51
|
-
- [What's new in 1.
|
|
51
|
+
- [What's new in 1.4.0 — Bridge](#-whats-new-in-140--bridge)
|
|
52
|
+
- [What's new in 1.3.0 — Bedrock](#-whats-new-in-130--bedrock)
|
|
53
|
+
- [What's new in 1.2.0 — Surface](#-whats-new-in-120--surface)
|
|
54
|
+
- [What's new in 1.1.0 — Drift](#-whats-new-in-110--drift)
|
|
52
55
|
- [What's new in 1.0.0](#-whats-new-in-100)
|
|
53
56
|
- [How it works](#-how-it-works)
|
|
54
|
-
- [The 26 tools](#-the-26-tools)
|
|
57
|
+
- [The 26 tools (plugin) + 11 MCP tools](#-the-26-tools-plugin--11-mcp-tools)
|
|
58
|
+
- [MCP Bridge — cross-harness memory](#-mcp-bridge--cross-harness-memory)
|
|
55
59
|
- [The benchmark: proven, not promised](#-the-benchmark-proven-not-promised)
|
|
56
60
|
- [Curation: from session noise to AGENTS.md](#-curation-from-session-noise-to-agentsmd)
|
|
57
61
|
- [Team sharing: one file, zero servers](#-team-sharing-one-file-zero-servers)
|
|
@@ -141,7 +145,7 @@ npm install @jmtrin/opencode-kevin
|
|
|
141
145
|
|
|
142
146
|
### 2. Restart OpenCode
|
|
143
147
|
|
|
144
|
-
On first boot Kevin migrates its database to schema version `
|
|
148
|
+
On first boot Kevin migrates its database to schema version `013` and starts
|
|
145
149
|
observing. Nothing else is required.
|
|
146
150
|
|
|
147
151
|
### 3. Talk to it
|
|
@@ -176,6 +180,35 @@ kevin_doctor → health report: hooks, deps, perf, verdict
|
|
|
176
180
|
|
|
177
181
|
---
|
|
178
182
|
|
|
183
|
+
## 🆕 What's new in 1.4.0 — "Bridge"
|
|
184
|
+
|
|
185
|
+
> 1.4.0 opens Kevin to every MCP harness — same local DB, same ranked recall, no network.
|
|
186
|
+
|
|
187
|
+
- 🌉 **MCP Bridge** — new package `@jmtrin/kevin-mcp` (stdio MCP server, SDK 1.30.0): 7 read tools (`query/get/recall/why/status/trace/feedback` with provenance `{repo_id, identity_source, channel:"mcp"}` + token ceiling `ceil(chars/4)` + `pull_mcp` ledger), 3 gated write tools (`save/approve/share` behind `mcp_write_enabled` / `mcp_approve_enabled` double-gate + `mcp_writes_refused/accepted`), `ping` liveness — single binary `npx @jmtrin/kevin-mcp [--repo <id>]`, stderr `ready` line, SIGINT/SIGTERM flush.
|
|
188
|
+
- 🔐 **Identity & repo scope** — `RepoIdentity` (declared → remote → path hex-16), `mcp_repo_override` setting, `--repo` CLI, scope guard `repo_mismatch` on every tool (read + write), resolves once at init (heals OKF header on rekey).
|
|
189
|
+
- 🗄️ **Migration 013** — `channel TEXT DEFAULT 'plugin' CHECK(plugin|mcp)`, `injected_at_ms` probe, 5 metrics `mcp_requests_total/reads_served/writes_accepted/writes_refused/errors_total`, `schema_version 013`; `busy_timeout=5000` on Store for plugin↔MCP WAL concurrency; pre-013 DBs omit `mcp` block in `kevin_audit` (partial:true).
|
|
190
|
+
- 📊 **Contracts & audit** — `C-04/C-05` since `1.4.0` (3 MCP config keys, 5 MCP metrics), `C-07` schema `013`, golden `v1.json` 35/61, `METRIC_KEY_LABELS`, `kevin_audit` gains `mcp{requests,reads,writes_accepted/refused,errors,channel_split{plugin,mcp}}`.
|
|
191
|
+
- ⏱️ **Perf** — `mcp.read` p95 25/max 100, `mcp.write` p95 50/max 250, flush every 100 requests or SIGINT to `perf_samples`; concurrency stress 500×500 interleaved ops, zero `SQLITE_BUSY`.
|
|
192
|
+
- 📚 **Harnesses & demo** — recipes for Claude Code / Codex / Cursor / Windsurf / Gemini CLI / Opencode (`docs/harnesses/*.md`, valid JSON blocks), 10-min cross-harness demo `docs/demo-cross-harness.md`, release ordering `core→tui→plugin→mcp` in `docs/DISTRIBUTION.md`.
|
|
193
|
+
|
|
194
|
+
**Upgrade:** `npm i @jmtrin/kevin-core@1.4.0 @jmtrin/opencode-kevin@1.4.0 @jmtrin/opencode-kevin-tui@1.4.0 @jmtrin/kevin-mcp@1.4.0` — DB auto-migrates to 013; writes remain gated off until `mcp_write_enabled='1'`.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 🆕 What's new in 1.3.0 — "Bedrock"
|
|
199
|
+
|
|
200
|
+
> 1.3.0 declares the border the code already had. No visible behavior change — everything after this changes *because* of it.
|
|
201
|
+
|
|
202
|
+
- 🏗️ **Monorepo with a hostless core** — root becomes a private `npm workspaces` manager; `packages/core` (`@jmtrin/kevin-core` **zero deps**), `packages/plugin` (`@jmtrin/opencode-kevin` — name frozen by C-06, now depends on core `1.3.0` exact), `packages/tui` (`@jmtrin/opencode-kevin-tui`, isolated). 60+ domain modules `plugin/*.ts` → `packages/core/src/*.ts` via `git mv`, migrations `migrations/` → `packages/core/migrations/` (12 SQL, built to `dist/migrations`).
|
|
203
|
+
- 🔌 **One new type + one new export** (`KevinEnv` + `exportMigrationsDir`): every `process.cwd()`/`homedir()` touchpoint now takes an injected `KevinEnv {projectRoot,dataRoot}` via `resolveEnv()` (defaults `cwd` / `~/.opencode-kevin` only in `env.ts`). Core scans as `0` `process.cwd/homedir/node:os` outside the allowlist (K13-007), verified by `packages/core/tests/core_purity_scan.test.ts`.
|
|
204
|
+
- 🔄 **Replay lives in core** — `replay.ts` + `idle-pipeline.ts` (`IDLE_STEP_ORDER` single source, `composeIdlePipeline`) moved to core; adapter and replay both mount the same pipeline (D13-07). Parity harness `packages/plugin/tests/parity.test.ts` mounts adapter vs core wirings over every `tests/replay/fixtures/*.json` and asserts byte-identical outputs (swapped-step probe proves sensitivity).
|
|
205
|
+
- 📦 **Packaging proof** — both tarballs verified + offline consumer smoke (`npm install <core.tgz> <tui.tgz> <plugin.tgz>` → `Store` + `Migrate` + `exportMigrationsDir` → `schema_version 012`). Core zero-deps and `types`-first exports; plugin pins core exact `1.3.0`, `exports["./tui"]` redirects to the tui package — external specifiers unchanged.
|
|
206
|
+
- 📜 **Contract unchanged** — `describeContract({scanRoots})` now accepts explicit roots (monorepo vs packed), golden values byte-equal (D13-05, 26/32/56 unchanged, no new setting/tool/metric/migration).
|
|
207
|
+
|
|
208
|
+
**Upgrade:** no action required — drop-in reorganization, behavior diff empty (K13-016), DB untouched.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
179
212
|
## 🆕 What's new in 1.1.0 — "Drift"
|
|
180
213
|
|
|
181
214
|
> 1.1.0 protects what 1.0.0 proved: a published number without a regression gate is marketing.
|
|
@@ -276,7 +309,7 @@ Kevin is an intentionally deterministic pipeline — no LLM in the core loop:
|
|
|
276
309
|
|
|
277
310
|
---
|
|
278
311
|
|
|
279
|
-
## 🧰 The 26 tools
|
|
312
|
+
## 🧰 The 26 tools (plugin) + 11 MCP tools
|
|
280
313
|
|
|
281
314
|
<details open>
|
|
282
315
|
<summary><b>🧠 Core memory</b></summary>
|
|
@@ -336,6 +369,22 @@ Kevin is an intentionally deterministic pipeline — no LLM in the core loop:
|
|
|
336
369
|
|
|
337
370
|
---
|
|
338
371
|
|
|
372
|
+
## 🌉 MCP Bridge — cross-harness memory
|
|
373
|
+
|
|
374
|
+
Kevin's SQLite file becomes accessible outside OpenCode via the MCP bridge — same ranking, same gates, same file you already trust.
|
|
375
|
+
|
|
376
|
+
| Surface | Install | Transport | Reads | Writes |
|
|
377
|
+
|---|---|---|---|---|
|
|
378
|
+
| **MCP** `@jmtrin/kevin-mcp` | `npx -y @jmtrin/kevin-mcp` ( `--repo <id>` optional) | stdio (SDK 1.30.0), no HTTP/SSE | 7 tools always on (query/get/recall/why/status/trace/feedback + ping) | 3 tools gated (`save` needs `mcp_write_enabled='1'`, `approve/share` need + `mcp_approve_enabled='1'`) |
|
|
379
|
+
|
|
380
|
+
- **One DB, two processes** — plugin and MCP server share `.opencode-kevin/kevin.db` via WAL + `busy_timeout=5000`; every read/write is repo-scoped (`repo_mismatch` on drift).
|
|
381
|
+
- **Provenance** — every MCP response carries `{repo_id, identity_source, channel:"mcp"}` (plus confidence/evidence when applicable).
|
|
382
|
+
- **Harnesses** — `docs/harnesses/{claude-code,codex,cursor,windsurf,gemini-cli,opencode}.md` with exact JSON/TOML snippets, verification, troubleshooting, uninstall; demo `docs/demo-cross-harness.md` (opencode → Claude Code recall).
|
|
383
|
+
|
|
384
|
+
See `packages/mcp/README.md` for full MCP reference.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
339
388
|
## 📊 The benchmark: proven, not promised
|
|
340
389
|
|
|
341
390
|
Kevin ships a committed synthetic corpus and a four-arm harness measuring
|
|
@@ -458,7 +507,7 @@ removals and silent changes fail loudly; additions must carry `since`.
|
|
|
458
507
|
|
|
459
508
|
## ⏱️ Hooks & latency budgets
|
|
460
509
|
|
|
461
|
-
Six host hooks plus Kevin's own `dispose` checkpoint —
|
|
510
|
+
Six host hooks plus Kevin's own `dispose` checkpoint plus two MCP bridges — ten measured scopes,
|
|
462
511
|
each with a declared p95/max budget enforced by `npm run bench:check`:
|
|
463
512
|
|
|
464
513
|
| Scope | p95 budget | max |
|
|
@@ -471,6 +520,8 @@ each with a declared p95/max budget enforced by `npm run bench:check`:
|
|
|
471
520
|
| `event` | 5 ms | 25 ms |
|
|
472
521
|
| `session.idle` | 150 ms | 600 ms |
|
|
473
522
|
| `dispose` | 50 ms | 250 ms |
|
|
523
|
+
| `mcp.read` | 25 ms | 100 ms |
|
|
524
|
+
| `mcp.write` | 50 ms | 250 ms |
|
|
474
525
|
|
|
475
526
|
Measured on the reference laptop: retrieval p50 ≈ 0.2 ms, p95 < 1 ms — orders
|
|
476
527
|
of magnitude under budget. Samples persist to `perf_samples` at idle; a breach
|
|
@@ -518,6 +569,9 @@ client). All values are TEXT — flags compare with `=== "1"`, never truthiness.
|
|
|
518
569
|
| `perf_flush_on_idle` | `'1'` | Persist samples at idle |
|
|
519
570
|
| `contract_report_enabled` | `'1'` | Contract block in `kevin_audit` |
|
|
520
571
|
| `tui_snapshots_enabled` | `'1'` | Snapshot + dashboard flush at idle (opencode-kevin/tui) |
|
|
572
|
+
| `mcp_write_enabled` | `'0'` | Gate for MCP `save` (refused counter `mcp_writes_refused`) |
|
|
573
|
+
| `mcp_approve_enabled` | `'0'` | Double-gate for MCP `approve`/`share` (needs + `mcp_write_enabled`) |
|
|
574
|
+
| `mcp_repo_override` | `''` | Override `RepoIdentity` for MCP (hex-16 or empty) |
|
|
521
575
|
|
|
522
576
|
---
|
|
523
577
|
|
|
@@ -530,8 +584,7 @@ client). All values are TEXT — flags compare with `=== "1"`, never truthiness.
|
|
|
530
584
|
| Node 22.5+ | `node:sqlite` behind `--experimental-sqlite` | 🔶 Works, unsupported — exercised in CI, not promised |
|
|
531
585
|
| Bun ≥ 1.1 | `bun:sqlite` | ✅ **Supported** — smoke-tested in `npm run verify` |
|
|
532
586
|
|
|
533
|
-
Zero
|
|
534
|
-
test run.
|
|
587
|
+
Zero network calls — asserted by source scan (forbidden: http/https/net/dgram/fetch/SSE/HttpTransport/child_process/spawn) on every test run; MCP uses stdio only, no spawn, logs on stderr only.
|
|
535
588
|
|
|
536
589
|
---
|
|
537
590
|
|
|
@@ -571,26 +624,35 @@ instrumentation. That is what Kevin adds around it.
|
|
|
571
624
|
## 🛠️ Development
|
|
572
625
|
|
|
573
626
|
```bash
|
|
574
|
-
npm install
|
|
575
|
-
npm run
|
|
576
|
-
npm run
|
|
577
|
-
npm
|
|
578
|
-
npm
|
|
579
|
-
npm
|
|
580
|
-
npm run
|
|
627
|
+
npm install # hoists workspaces (root private, 4 packages)
|
|
628
|
+
npm run build # core → tui → plugin → mcp (tsc + copy-migrations)
|
|
629
|
+
npm run typecheck # -w core -w tui -w plugin -w mcp + root (strict)
|
|
630
|
+
npm run lint # biome
|
|
631
|
+
npm test # vitest — root suite (190 files)
|
|
632
|
+
npm test -w @jmtrin/kevin-core # core only — also passes with @opencode-ai/plugin absent (K13-013)
|
|
633
|
+
npm run verify # install checks + Bun smoke + verify:pack (×2 + consumer)
|
|
634
|
+
npm run verify:pack # dual-tarball + offline consumer smoke (K13-014)
|
|
635
|
+
npm run gen:corpus # regenerate the seeded corpus (byte-identical)
|
|
636
|
+
npm run replay # replay recorded sessions deterministically (now via core)
|
|
581
637
|
```
|
|
582
638
|
|
|
583
|
-
Project layout:
|
|
639
|
+
Project layout (Bedrock monorepo):
|
|
584
640
|
|
|
585
641
|
```
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
bench
|
|
591
|
-
|
|
642
|
+
packages/core/ @jmtrin/kevin-core — ~60 modules (zero deps), src/*.ts, migrations/ 001→013, dist/migrations
|
|
643
|
+
packages/plugin/ @jmtrin/opencode-kevin — 4 modules (index, host, native, capabilities), adapter thin, depends on core+tui 1.4.0 exact
|
|
644
|
+
packages/tui/ @jmtrin/opencode-kevin-tui — isolated TUI panel (target-exclusive, own package.json/exports)
|
|
645
|
+
packages/mcp/ @jmtrin/kevin-mcp — MCP bridge (stdio, 11 tools, pure helper, identity+provenance)
|
|
646
|
+
scripts/ bench · gen-corpus · verify-pack (dual) · verify-install · …
|
|
647
|
+
tests/ unit · integration · e2e · replay fixtures (at root, run via workspaces)
|
|
648
|
+
bench/ committed corpus + committed results
|
|
649
|
+
docs/ CONTRACT.md · per-release plans/tasks · roadmap v2
|
|
592
650
|
```
|
|
593
651
|
|
|
652
|
+
> **C-10 preview** — the future public surface is the explicit re-export list at `packages/core/src/index.ts` (keep it minimal and deliberate).
|
|
653
|
+
|
|
654
|
+
C-06 frozen: `plugin` package name `@jmtrin/opencode-kevin` and `exports["./tui"]` specifier unchanged; consumers see no break.
|
|
655
|
+
|
|
594
656
|
---
|
|
595
657
|
|
|
596
658
|
## 📄 License
|
package/dist/plugin/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
|
-
import { Store } from "
|
|
2
|
+
import { Store } from "@jmtrin/kevin-core";
|
|
3
|
+
import { KEVIN_VERSION } from "@jmtrin/kevin-core";
|
|
3
4
|
export interface KevinPluginOptions {
|
|
4
5
|
dbPath?: string;
|
|
5
6
|
migrationsDir?: string;
|
|
@@ -16,10 +17,10 @@ export interface KevinPluginOptions {
|
|
|
16
17
|
* v0.4.0 (K4-021) — settings surfaced by `kevin_config` (plan §8.8).
|
|
17
18
|
* Unknown keys are rejected on `set` unless `strict: false`.
|
|
18
19
|
*/
|
|
19
|
-
export declare const KEVIN_CONFIG_KEYS: readonly ["quality_gate_enabled", "lesson_snippet_injection", "patternminer_enabled", "cross_project_enabled", "llm_reflection_enabled", "tool_calls_dedup_enabled", "deterministic_retrieval", "pre_prompt_budget_tokens", "archive_after_days", "curation_enabled", "agents_md_path", "skill_emission_enabled", "reference_emission_enabled", "injection_confidence_floor", "repo_truth_enabled", "convention_mining_enabled", "conflict_detection_enabled", "error_lesson_mode", "shared_layer_enabled", "okf_path", "share_requires_approval", "author_identity_mode", "shared_confidence_floor", "hook_liveness_enabled", "native_registration_enabled", "host_probe_history_enabled", "dead_hook_report_threshold", "perf_enabled", "perf_ring_capacity", "perf_flush_on_idle", "contract_report_enabled", "tui_snapshots_enabled"];
|
|
20
|
+
export declare const KEVIN_CONFIG_KEYS: readonly ["quality_gate_enabled", "lesson_snippet_injection", "patternminer_enabled", "cross_project_enabled", "llm_reflection_enabled", "tool_calls_dedup_enabled", "deterministic_retrieval", "pre_prompt_budget_tokens", "archive_after_days", "curation_enabled", "agents_md_path", "skill_emission_enabled", "reference_emission_enabled", "injection_confidence_floor", "repo_truth_enabled", "convention_mining_enabled", "conflict_detection_enabled", "error_lesson_mode", "shared_layer_enabled", "okf_path", "share_requires_approval", "author_identity_mode", "shared_confidence_floor", "hook_liveness_enabled", "native_registration_enabled", "host_probe_history_enabled", "dead_hook_report_threshold", "perf_enabled", "perf_ring_capacity", "perf_flush_on_idle", "contract_report_enabled", "tui_snapshots_enabled", "mcp_write_enabled", "mcp_approve_enabled", "mcp_repo_override"];
|
|
20
21
|
export declare const ERROR_LESSON_MODE_VALUES: readonly ["all", "triage_only"];
|
|
21
|
-
/** Plugin release version —
|
|
22
|
-
export
|
|
22
|
+
/** Plugin release version — single source is @jmtrin/kevin-core (B-003 drift fix). */
|
|
23
|
+
export { KEVIN_VERSION };
|
|
23
24
|
export interface RekeyCounts {
|
|
24
25
|
memories: number;
|
|
25
26
|
shared_entries: number;
|
package/dist/plugin/index.js
CHANGED
|
@@ -1,55 +1,56 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { dirname, join } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { tool } from "@opencode-ai/plugin";
|
|
6
|
-
import { Archiver } from "
|
|
7
|
-
import { ArtifactWriter } from "
|
|
8
|
-
import { CausalChain } from "
|
|
9
|
-
import { handleBridgeCommand } from "
|
|
10
|
-
import { ConflictDetector } from "
|
|
11
|
-
import { ContextInjector } from "
|
|
12
|
-
import { ConventionMiner } from "
|
|
13
|
-
import { Curator } from "
|
|
14
|
-
import { writeDashboard } from "
|
|
15
|
-
import { Feedback } from "
|
|
16
|
-
import { HookLiveness } from "
|
|
17
|
-
import { InjectionLedger } from "
|
|
18
|
-
import { Materializer, SKILL_TOPIC } from "
|
|
19
|
-
import { MemoryService, hasRepoIdColumn, } from "
|
|
20
|
-
import { Migrate } from "
|
|
21
|
-
import { PatternMiner } from "
|
|
22
|
-
import { ERROR_LINE_RE, Reflector, STRONG_ERROR_RE } from "
|
|
23
|
-
import * as RepoIdentity from "
|
|
24
|
-
import { RepoTruth } from "
|
|
25
|
-
import { Retrospective } from "
|
|
26
|
-
import { SharedLayer } from "
|
|
27
|
-
import { Store } from "
|
|
28
|
-
import { ToolCallObserver } from "
|
|
29
|
-
import { deleteMailbox, processActions, readMailbox, writeResults, } from "
|
|
30
|
-
import { flushSnapshots } from "
|
|
7
|
+
import { Archiver } from "@jmtrin/kevin-core";
|
|
8
|
+
import { ArtifactWriter } from "@jmtrin/kevin-core";
|
|
9
|
+
import { CausalChain } from "@jmtrin/kevin-core";
|
|
10
|
+
import { handleBridgeCommand } from "@jmtrin/kevin-core";
|
|
11
|
+
import { ConflictDetector } from "@jmtrin/kevin-core";
|
|
12
|
+
import { ContextInjector } from "@jmtrin/kevin-core";
|
|
13
|
+
import { ConventionMiner } from "@jmtrin/kevin-core";
|
|
14
|
+
import { Curator } from "@jmtrin/kevin-core";
|
|
15
|
+
import { writeDashboard } from "@jmtrin/kevin-core";
|
|
16
|
+
import { Feedback } from "@jmtrin/kevin-core";
|
|
17
|
+
import { HookLiveness } from "@jmtrin/kevin-core";
|
|
18
|
+
import { InjectionLedger } from "@jmtrin/kevin-core";
|
|
19
|
+
import { Materializer, SKILL_TOPIC } from "@jmtrin/kevin-core";
|
|
20
|
+
import { MemoryService, hasRepoIdColumn, } from "@jmtrin/kevin-core";
|
|
21
|
+
import { Migrate } from "@jmtrin/kevin-core";
|
|
22
|
+
import { PatternMiner } from "@jmtrin/kevin-core";
|
|
23
|
+
import { ERROR_LINE_RE, Reflector, STRONG_ERROR_RE } from "@jmtrin/kevin-core";
|
|
24
|
+
import * as RepoIdentity from "@jmtrin/kevin-core";
|
|
25
|
+
import { RepoTruth } from "@jmtrin/kevin-core";
|
|
26
|
+
import { Retrospective } from "@jmtrin/kevin-core";
|
|
27
|
+
import { SharedLayer } from "@jmtrin/kevin-core";
|
|
28
|
+
import { Store } from "@jmtrin/kevin-core";
|
|
29
|
+
import { ToolCallObserver } from "@jmtrin/kevin-core";
|
|
30
|
+
import { deleteMailbox, processActions, readMailbox, writeResults, } from "@jmtrin/kevin-core";
|
|
31
|
+
import { flushSnapshots } from "@jmtrin/kevin-core";
|
|
31
32
|
import { probe } from "./capabilities.js";
|
|
32
|
-
import { computeConfidence } from "
|
|
33
|
-
import { contractDigest, describeContract } from "
|
|
33
|
+
import { computeConfidence, exportMigrationsDir, composeIdlePipeline, KEVIN_VERSION } from "@jmtrin/kevin-core";
|
|
34
|
+
import { contractDigest, describeContract } from "@jmtrin/kevin-core";
|
|
34
35
|
import { probeHost, summarize } from "./host.js";
|
|
35
|
-
import { kevinApprove } from "
|
|
36
|
-
import { buildAudit } from "
|
|
37
|
-
import { buildKevinBench } from "
|
|
38
|
-
import { executeKevinConflicts } from "
|
|
39
|
-
import { buildKevinContract } from "
|
|
40
|
-
import { buildDoctor } from "
|
|
41
|
-
import { buildKevinFacts } from "
|
|
42
|
-
import { handleForget } from "
|
|
43
|
-
import { handleNative } from "
|
|
44
|
-
import { kevinPropose } from "
|
|
45
|
-
import { kevinPublish } from "
|
|
46
|
-
import { kevinWhy } from "
|
|
47
|
-
import { Metrics } from "
|
|
36
|
+
import { kevinApprove } from "@jmtrin/kevin-core";
|
|
37
|
+
import { buildAudit } from "@jmtrin/kevin-core";
|
|
38
|
+
import { buildKevinBench } from "@jmtrin/kevin-core";
|
|
39
|
+
import { executeKevinConflicts } from "@jmtrin/kevin-core";
|
|
40
|
+
import { buildKevinContract } from "@jmtrin/kevin-core";
|
|
41
|
+
import { buildDoctor } from "@jmtrin/kevin-core";
|
|
42
|
+
import { buildKevinFacts } from "@jmtrin/kevin-core";
|
|
43
|
+
import { handleForget } from "@jmtrin/kevin-core";
|
|
44
|
+
import { handleNative } from "@jmtrin/kevin-core";
|
|
45
|
+
import { kevinPropose } from "@jmtrin/kevin-core";
|
|
46
|
+
import { kevinPublish } from "@jmtrin/kevin-core";
|
|
47
|
+
import { kevinWhy } from "@jmtrin/kevin-core";
|
|
48
|
+
import { Metrics } from "@jmtrin/kevin-core";
|
|
48
49
|
import { attachNative } from "./native.js";
|
|
49
|
-
import { exportMarkdown, exportOkf } from "
|
|
50
|
-
import { importOkf } from "
|
|
51
|
-
import { Perf } from "
|
|
52
|
-
import { uuidv7 } from "
|
|
50
|
+
import { exportMarkdown, exportOkf } from "@jmtrin/kevin-core";
|
|
51
|
+
import { importOkf } from "@jmtrin/kevin-core";
|
|
52
|
+
import { Perf } from "@jmtrin/kevin-core";
|
|
53
|
+
import { uuidv7 } from "@jmtrin/kevin-core";
|
|
53
54
|
// v0.6.0 (K6-019) — process-global set of reference topics already
|
|
54
55
|
// registered with the host this process. Keeps re-registration idempotent
|
|
55
56
|
// across sessions within one process: a topic registered once is never
|
|
@@ -122,6 +123,11 @@ export const KEVIN_CONFIG_KEYS = [
|
|
|
122
123
|
// return { error: "unknown_key" } while `kevin_config list` still
|
|
123
124
|
// shows it.
|
|
124
125
|
"tui_snapshots_enabled",
|
|
126
|
+
// v1.4.0 (K14-006 / plan §4) — the three MCP bridge settings seeded by migration 013
|
|
127
|
+
// Omitting makes `kevin_config set` return { error: "unknown_key" } while list shows them.
|
|
128
|
+
"mcp_write_enabled",
|
|
129
|
+
"mcp_approve_enabled",
|
|
130
|
+
"mcp_repo_override",
|
|
125
131
|
];
|
|
126
132
|
// v1.1.0 (K11-007 / D11-08) — no new settings in 1.1.0; thresholds are constants (D11-03)
|
|
127
133
|
// v0.7.0 (K7-003 / plan §5.6, D7-12) — the explicit VALUE domain for
|
|
@@ -131,11 +137,41 @@ export const KEVIN_CONFIG_KEYS = [
|
|
|
131
137
|
// at the surface rather than silently changing every installation's
|
|
132
138
|
// behaviour on the next reflection.
|
|
133
139
|
export const ERROR_LESSON_MODE_VALUES = ["all", "triage_only"];
|
|
134
|
-
/** Plugin release version —
|
|
135
|
-
export
|
|
140
|
+
/** Plugin release version — single source is @jmtrin/kevin-core (B-003 drift fix). */
|
|
141
|
+
export { KEVIN_VERSION };
|
|
136
142
|
function resolveMigrationsDir() {
|
|
143
|
+
// K13-008 (D13-04): migrations now owned by @jmtrin/kevin-core.
|
|
144
|
+
// Explicit option is handled at call site (opts.migrationsDir ?? resolve...),
|
|
145
|
+
// so this helper only resolves the core location.
|
|
146
|
+
// 1. Installed layout: walk-up via require.resolve (reuses host.ts strategy)
|
|
147
|
+
try {
|
|
148
|
+
const pkgJson = createRequire(import.meta.url).resolve("@jmtrin/kevin-core/package.json");
|
|
149
|
+
const cand = join(dirname(pkgJson), "dist", "migrations");
|
|
150
|
+
if (existsSync(cand))
|
|
151
|
+
return cand;
|
|
152
|
+
}
|
|
153
|
+
catch { }
|
|
154
|
+
// 2. Workspace sources: delegate to core's own resolver (handles both
|
|
155
|
+
// src via tsx and dist after build).
|
|
156
|
+
try {
|
|
157
|
+
const dir = exportMigrationsDir();
|
|
158
|
+
if (existsSync(dir))
|
|
159
|
+
return dir;
|
|
160
|
+
}
|
|
161
|
+
catch { }
|
|
162
|
+
// 3. Monorepo fallback probes (dev without build)
|
|
137
163
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
138
|
-
|
|
164
|
+
const candidates = [
|
|
165
|
+
join(here, "..", "..", "core", "dist", "migrations"),
|
|
166
|
+
join(here, "..", "..", "core", "migrations"),
|
|
167
|
+
join(here, "..", "migrations"),
|
|
168
|
+
join(here, "..", "..", "migrations"),
|
|
169
|
+
];
|
|
170
|
+
for (const c of candidates) {
|
|
171
|
+
if (existsSync(c))
|
|
172
|
+
return c;
|
|
173
|
+
}
|
|
174
|
+
return join(here, "..", "..", "core", "migrations");
|
|
139
175
|
}
|
|
140
176
|
const REKEY_TABLES = ["memories", "shared_entries", "okf_imports"];
|
|
141
177
|
export function performRekey(store, toRepoId, opts) {
|
|
@@ -337,6 +373,8 @@ export const KevinPlugin = async (input, options) => {
|
|
|
337
373
|
// v0.7.0 (K7-009 / plan §5.1, D7-13) — the repository truth scanner reads
|
|
338
374
|
// the JSON project files. Runs once at init, gated by repo_truth_enabled.
|
|
339
375
|
const projectRoot = opts.projectRoot ?? process.cwd();
|
|
376
|
+
const materializerRoot = opts.materializerRoot ?? join(homedir(), ".opencode-kevin");
|
|
377
|
+
const kevinEnv = { projectRoot, dataRoot: materializerRoot };
|
|
340
378
|
const repoTruth = new RepoTruth(store, projectId, projectRoot, metrics);
|
|
341
379
|
if (memoryService.getSetting("repo_truth_enabled", "0") === "1") {
|
|
342
380
|
try {
|
|
@@ -376,7 +414,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
376
414
|
const archiver = new Archiver(store, memoryService, metrics);
|
|
377
415
|
const retrospective = new Retrospective(store, memoryService, {
|
|
378
416
|
dir: opts.retrospectivesDir,
|
|
379
|
-
}, metrics);
|
|
417
|
+
}, metrics, kevinEnv);
|
|
380
418
|
const patternMiner = new PatternMiner(store, memoryService, metrics);
|
|
381
419
|
const conventionMiner = new ConventionMiner(store, memoryService, projectId, metrics);
|
|
382
420
|
const conflictDetector = new ConflictDetector(store, projectId, metrics, repoTruth, memoryService);
|
|
@@ -408,13 +446,12 @@ export const KevinPlugin = async (input, options) => {
|
|
|
408
446
|
metrics.incr("shared_entries_imported", report.imported);
|
|
409
447
|
return report;
|
|
410
448
|
}
|
|
411
|
-
let curator = new Curator(store, memoryService, projectId, metrics, repoId);
|
|
449
|
+
let curator = new Curator(store, memoryService, projectId, metrics, repoId, kevinEnv);
|
|
412
450
|
// v0.6.0 (K6-017/018 / plan §5.6-5.7, D6-13) — pull-channel bundles and
|
|
413
451
|
// the v2 domain probe. `probe()` runs ONCE at init and the result is
|
|
414
452
|
// held; probing per-event is a hot-path cost for a value that cannot
|
|
415
453
|
// change within a process (K6-016). The Materializer writes next to its
|
|
416
454
|
// targets, so the bundle directories are created here at init.
|
|
417
|
-
const materializerRoot = opts.materializerRoot ?? join(homedir(), ".opencode-kevin");
|
|
418
455
|
mkdirSync(join(materializerRoot, "skills"), { recursive: true });
|
|
419
456
|
mkdirSync(join(materializerRoot, "refs"), { recursive: true });
|
|
420
457
|
const capabilities = probe(input);
|
|
@@ -422,7 +459,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
422
459
|
// When the host exposes permission.ask, the presence is noted; absence is silent no-op.
|
|
423
460
|
// No new setting — bounded to tui_snapshots_enabled host-support check per spec.
|
|
424
461
|
void capabilities.permissionAsk;
|
|
425
|
-
const materializer = new Materializer(store, { root: materializerRoot });
|
|
462
|
+
const materializer = new Materializer(store, { root: materializerRoot }, kevinEnv);
|
|
426
463
|
// v0.9.0 (K9-016 / plan §5.4, D9-10) — native registration replaces
|
|
427
464
|
// file emission. When attachNative returns a registration for a
|
|
428
465
|
// surface, the corresponding *_emission_enabled path is skipped for
|
|
@@ -1002,7 +1039,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
1002
1039
|
version: KEVIN_VERSION,
|
|
1003
1040
|
writer,
|
|
1004
1041
|
});
|
|
1005
|
-
curator = new Curator(store, memoryService, projectId, metrics, live.repoId);
|
|
1042
|
+
curator = new Curator(store, memoryService, projectId, metrics, live.repoId, kevinEnv);
|
|
1006
1043
|
// v0.8.0 (BUG-003) — heal the OKF file header.
|
|
1007
1044
|
// Rekey changes the scope the file is written
|
|
1008
1045
|
// under; a stale `#repo` first line would make
|
|
@@ -1077,7 +1114,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
1077
1114
|
// block; on a pre-008 DB the block is omitted, partial:true.
|
|
1078
1115
|
// v0.8.0 (K8-007 / plan §5.7) — the penalized-memory rollup
|
|
1079
1116
|
// scopes on repoId once the 009 column exists.
|
|
1080
|
-
const report = buildAudit(store, metrics, capabilities, projectId, sessionIdentity.repoId);
|
|
1117
|
+
const report = buildAudit(store, metrics, capabilities, projectId, sessionIdentity.repoId, undefined, kevinEnv);
|
|
1081
1118
|
const payload = args.verbose
|
|
1082
1119
|
? report
|
|
1083
1120
|
: { ...report, settings: undefined };
|
|
@@ -1096,7 +1133,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
1096
1133
|
description: "Doctor de Kevin (v0.9.0): salud del host, hooks, dependencias y registros nativos. Solo lectura, sin LLM ni writes, invocable en cualquier momento. Devuelve host (version, flavour, shell, v2), hooks ordenados dead primero, dependencies (zod_copies), native (enabled, registered/verified por surface), verdict (healthy|degraded|unknown) y reason. Output pensado para pegar en un issue: sin filesystem paths ni session ids.",
|
|
1097
1134
|
args: {},
|
|
1098
1135
|
async execute() {
|
|
1099
|
-
const report = buildDoctor(store, host, memoryService);
|
|
1136
|
+
const report = buildDoctor(store, host, memoryService, {}, kevinEnv);
|
|
1100
1137
|
return {
|
|
1101
1138
|
title: "Doctor de Kevin",
|
|
1102
1139
|
output: JSON.stringify(report),
|
|
@@ -1165,7 +1202,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
1165
1202
|
.describe("status | last"),
|
|
1166
1203
|
},
|
|
1167
1204
|
async execute(args) {
|
|
1168
|
-
const result = buildKevinBench({ store }, args);
|
|
1205
|
+
const result = buildKevinBench({ store }, args, kevinEnv);
|
|
1169
1206
|
return {
|
|
1170
1207
|
title: "Benchmark de Kevin",
|
|
1171
1208
|
output: JSON.stringify(result),
|
|
@@ -1843,62 +1880,39 @@ export const KevinPlugin = async (input, options) => {
|
|
|
1843
1880
|
// BUG-011 — the session is done: drop the global query
|
|
1844
1881
|
// so the next session cannot reuse it.
|
|
1845
1882
|
lastUserQuery = null;
|
|
1846
|
-
//
|
|
1847
|
-
//
|
|
1848
|
-
//
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
catch {
|
|
1882
|
-
// A throwing miner must not reject or truncate the idle chain.
|
|
1883
|
-
}
|
|
1884
|
-
// v0.7.0 (K7-016 / plan §5.5, D7-06) — conflict detection is
|
|
1885
|
-
// surfacing-only on idle. It may create/open conflict rows, but
|
|
1886
|
-
// no idle path can acknowledge or resolve one.
|
|
1887
|
-
try {
|
|
1888
|
-
if (memoryService.getSetting("conflict_detection_enabled", "0") ===
|
|
1889
|
-
"1") {
|
|
1890
|
-
conflictDetector.detect();
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
catch {
|
|
1894
|
-
// Conflict surfacing is best-effort and must not reject idle.
|
|
1895
|
-
}
|
|
1896
|
-
fireAndForget(Promise.resolve()
|
|
1897
|
-
.then(() => causalChain.onSessionIdle(sid))
|
|
1898
|
-
// non-blocking — promote is a best-effort pass
|
|
1899
|
-
// (legacy DBs pre-005 lack the recurrence_count
|
|
1900
|
-
// column)
|
|
1901
|
-
.catch(() => { }));
|
|
1883
|
+
// K13-010 (D13-07) — single ORDER via composeIdlePipeline.
|
|
1884
|
+
// Ledger/archiver/reflectors/pattern are the hand-synced core;
|
|
1885
|
+
// adapter and replay both consume IDLE_STEP_ORDER so re-order is visible in both.
|
|
1886
|
+
await composeIdlePipeline({
|
|
1887
|
+
"ledger.settle": () => { ledger.settle(sid); },
|
|
1888
|
+
"archiver.run": () => { archiver.run(); },
|
|
1889
|
+
retrospective: () => {
|
|
1890
|
+
fireAndForget(retrospective.generate(sid));
|
|
1891
|
+
},
|
|
1892
|
+
"reflectors.boost": () => { memoryService.boostPositiveReflectors(sid); },
|
|
1893
|
+
"reflectors.penalize": () => {
|
|
1894
|
+
const recurred = memoryService.penalizeRecurringReflectors(sid);
|
|
1895
|
+
injector.setRecurrences(recurred, sid);
|
|
1896
|
+
},
|
|
1897
|
+
"patternMiner.mine": () => { patternMiner.mine(projectId); },
|
|
1898
|
+
});
|
|
1899
|
+
// v0.7.0 (K7-012/K7-016) + causalChain — folded into the single ORDER via composeIdlePipeline (K13-010)
|
|
1900
|
+
await composeIdlePipeline({
|
|
1901
|
+
"conventionMiner.mine": () => {
|
|
1902
|
+
if (memoryService.getSetting("convention_mining_enabled", "0") === "1") {
|
|
1903
|
+
const conventions = conventionMiner.mine();
|
|
1904
|
+
conventionMiner.emit(conventions);
|
|
1905
|
+
}
|
|
1906
|
+
},
|
|
1907
|
+
"conflictDetector.detect": () => {
|
|
1908
|
+
if (memoryService.getSetting("conflict_detection_enabled", "0") === "1") {
|
|
1909
|
+
conflictDetector.detect();
|
|
1910
|
+
}
|
|
1911
|
+
},
|
|
1912
|
+
"causalChain.onSessionIdle": () => {
|
|
1913
|
+
fireAndForget(Promise.resolve().then(() => causalChain.onSessionIdle(sid)).catch(() => { }));
|
|
1914
|
+
},
|
|
1915
|
+
});
|
|
1902
1916
|
// v1.2.0 (K12-007/K12-011 / D12-05) — TUI mailbox: actions→curate ordering.
|
|
1903
1917
|
// Process mailbox BEFORE curator.propose so a fresh proposal created this idle
|
|
1904
1918
|
// is NOT visible to a stale token (D12-04). Best-effort, never breaks idle.
|
|
@@ -2013,7 +2027,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
2013
2027
|
.prepare("SELECT id, kind, target_path, proposed_text, diff, memory_id, created_at FROM curation_proposals WHERE status = 'pending' ORDER BY created_at")
|
|
2014
2028
|
.all();
|
|
2015
2029
|
})();
|
|
2016
|
-
const { proposalToken } = await import("
|
|
2030
|
+
const { proposalToken } = await import("@jmtrin/kevin-core");
|
|
2017
2031
|
proposals = rawPending.map((r) => {
|
|
2018
2032
|
const row = r;
|
|
2019
2033
|
const id = String(row.id ?? "");
|
|
@@ -2060,7 +2074,7 @@ export const KevinPlugin = async (input, options) => {
|
|
|
2060
2074
|
// Health
|
|
2061
2075
|
let health;
|
|
2062
2076
|
try {
|
|
2063
|
-
const doc = buildDoctor(store, host, memoryService);
|
|
2077
|
+
const doc = buildDoctor(store, host, memoryService, {}, kevinEnv);
|
|
2064
2078
|
let perfRows = [];
|
|
2065
2079
|
try {
|
|
2066
2080
|
const stats = perf.stats?.();
|
package/dist/plugin/native.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Materializer } from "
|
|
2
|
-
import type { Store } from "
|
|
1
|
+
import { type Materializer } from "@jmtrin/kevin-core";
|
|
2
|
+
import type { Store } from "@jmtrin/kevin-core";
|
|
3
3
|
import type { HostSurface } from "./host.js";
|
|
4
4
|
/** The surface `attachNative()` returned. `verified` is filled by the
|
|
5
5
|
* read-back checks (K9-014/015) once the host ran `setup()`. */
|
package/dist/plugin/native.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SKILL_TOPIC } from "
|
|
2
|
-
import { uuidv7 } from "
|
|
1
|
+
import { SKILL_TOPIC } from "@jmtrin/kevin-core";
|
|
2
|
+
import { uuidv7 } from "@jmtrin/kevin-core";
|
|
3
3
|
/** The only place in the repository allowed to name the v2 subpath. */
|
|
4
4
|
export const V2_SPECIFIER = "@opencode-ai/plugin/v2/promise";
|
|
5
5
|
/** The skill body Kevin registers through `skill.transform`. */
|