@jmtrin/opencode-kevin 1.2.0 → 1.3.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.
Files changed (141) hide show
  1. package/dist/plugin/index.d.ts +4 -3
  2. package/dist/plugin/index.js +122 -113
  3. package/dist/plugin/native.d.ts +2 -2
  4. package/dist/plugin/native.js +2 -2
  5. package/package.json +56 -68
  6. package/LICENSE +0 -21
  7. package/README.md +0 -605
  8. package/dist/migrations/001_initial.sql +0 -92
  9. package/dist/migrations/002_indexes.sql +0 -14
  10. package/dist/migrations/003_v02_signal.sql +0 -58
  11. package/dist/migrations/004_v03_knowledge.sql +0 -138
  12. package/dist/migrations/005_v04_signal.sql +0 -57
  13. package/dist/migrations/006_v05_glassbox.sql +0 -118
  14. package/dist/migrations/007_v06_pull.sql +0 -145
  15. package/dist/migrations/008_v07_truth.sql +0 -124
  16. package/dist/migrations/009_v08_team.sql +0 -100
  17. package/dist/migrations/010_v09_native.sql +0 -78
  18. package/dist/migrations/011_v10_proven.sql +0 -69
  19. package/dist/migrations/012_v11_drift.sql +0 -24
  20. package/dist/plugin/Archiver.d.ts +0 -42
  21. package/dist/plugin/Archiver.js +0 -83
  22. package/dist/plugin/ArtifactWriter.d.ts +0 -93
  23. package/dist/plugin/ArtifactWriter.js +0 -291
  24. package/dist/plugin/CausalChain.d.ts +0 -22
  25. package/dist/plugin/CausalChain.js +0 -197
  26. package/dist/plugin/ChatBridge.d.ts +0 -41
  27. package/dist/plugin/ChatBridge.js +0 -103
  28. package/dist/plugin/ConflictDetector.d.ts +0 -35
  29. package/dist/plugin/ConflictDetector.js +0 -260
  30. package/dist/plugin/ContextInjector.d.ts +0 -222
  31. package/dist/plugin/ContextInjector.js +0 -533
  32. package/dist/plugin/ConventionMiner.d.ts +0 -35
  33. package/dist/plugin/ConventionMiner.js +0 -242
  34. package/dist/plugin/Curator.d.ts +0 -116
  35. package/dist/plugin/Curator.js +0 -324
  36. package/dist/plugin/DashboardHtml.d.ts +0 -5
  37. package/dist/plugin/DashboardHtml.js +0 -180
  38. package/dist/plugin/Feedback.d.ts +0 -67
  39. package/dist/plugin/Feedback.js +0 -120
  40. package/dist/plugin/HookLiveness.d.ts +0 -88
  41. package/dist/plugin/HookLiveness.js +0 -322
  42. package/dist/plugin/InjectionLedger.d.ts +0 -98
  43. package/dist/plugin/InjectionLedger.js +0 -295
  44. package/dist/plugin/LessonFixer.d.ts +0 -44
  45. package/dist/plugin/LessonFixer.js +0 -45
  46. package/dist/plugin/Materializer.d.ts +0 -83
  47. package/dist/plugin/Materializer.js +0 -181
  48. package/dist/plugin/MemoryService.d.ts +0 -360
  49. package/dist/plugin/MemoryService.js +0 -1242
  50. package/dist/plugin/Migrate.d.ts +0 -17
  51. package/dist/plugin/Migrate.js +0 -271
  52. package/dist/plugin/PatternMiner.d.ts +0 -49
  53. package/dist/plugin/PatternMiner.js +0 -132
  54. package/dist/plugin/QualityGate.d.ts +0 -124
  55. package/dist/plugin/QualityGate.js +0 -119
  56. package/dist/plugin/Reflector.d.ts +0 -91
  57. package/dist/plugin/Reflector.js +0 -307
  58. package/dist/plugin/RepoIdentity.d.ts +0 -124
  59. package/dist/plugin/RepoIdentity.js +0 -300
  60. package/dist/plugin/RepoTruth.d.ts +0 -80
  61. package/dist/plugin/RepoTruth.js +0 -599
  62. package/dist/plugin/Retrospective.d.ts +0 -17
  63. package/dist/plugin/Retrospective.js +0 -216
  64. package/dist/plugin/SharedLayer.d.ts +0 -159
  65. package/dist/plugin/SharedLayer.js +0 -462
  66. package/dist/plugin/Store.d.ts +0 -29
  67. package/dist/plugin/Store.js +0 -50
  68. package/dist/plugin/ToolCallObserver.d.ts +0 -32
  69. package/dist/plugin/ToolCallObserver.js +0 -201
  70. package/dist/plugin/TuiActions.d.ts +0 -43
  71. package/dist/plugin/TuiActions.js +0 -181
  72. package/dist/plugin/TuiSnapshots.d.ts +0 -24
  73. package/dist/plugin/TuiSnapshots.js +0 -158
  74. package/dist/plugin/columns.d.ts +0 -11
  75. package/dist/plugin/columns.js +0 -54
  76. package/dist/plugin/confidence.d.ts +0 -8
  77. package/dist/plugin/confidence.js +0 -34
  78. package/dist/plugin/contract.d.ts +0 -54
  79. package/dist/plugin/contract.js +0 -386
  80. package/dist/plugin/diff.d.ts +0 -8
  81. package/dist/plugin/diff.js +0 -182
  82. package/dist/plugin/escape.d.ts +0 -39
  83. package/dist/plugin/escape.js +0 -60
  84. package/dist/plugin/fingerprint.d.ts +0 -27
  85. package/dist/plugin/fingerprint.js +0 -73
  86. package/dist/plugin/inferability.d.ts +0 -32
  87. package/dist/plugin/inferability.js +0 -88
  88. package/dist/plugin/kevin_approve.d.ts +0 -34
  89. package/dist/plugin/kevin_approve.js +0 -52
  90. package/dist/plugin/kevin_audit.d.ts +0 -229
  91. package/dist/plugin/kevin_audit.js +0 -631
  92. package/dist/plugin/kevin_bench.d.ts +0 -10
  93. package/dist/plugin/kevin_bench.js +0 -82
  94. package/dist/plugin/kevin_conflicts.d.ts +0 -9
  95. package/dist/plugin/kevin_conflicts.js +0 -50
  96. package/dist/plugin/kevin_contract.d.ts +0 -8
  97. package/dist/plugin/kevin_contract.js +0 -59
  98. package/dist/plugin/kevin_doctor.d.ts +0 -62
  99. package/dist/plugin/kevin_doctor.js +0 -196
  100. package/dist/plugin/kevin_facts.d.ts +0 -42
  101. package/dist/plugin/kevin_facts.js +0 -36
  102. package/dist/plugin/kevin_forget.d.ts +0 -33
  103. package/dist/plugin/kevin_forget.js +0 -260
  104. package/dist/plugin/kevin_native.d.ts +0 -29
  105. package/dist/plugin/kevin_native.js +0 -79
  106. package/dist/plugin/kevin_propose.d.ts +0 -23
  107. package/dist/plugin/kevin_propose.js +0 -14
  108. package/dist/plugin/kevin_publish.d.ts +0 -38
  109. package/dist/plugin/kevin_publish.js +0 -18
  110. package/dist/plugin/kevin_why.d.ts +0 -23
  111. package/dist/plugin/kevin_why.js +0 -111
  112. package/dist/plugin/memory-format.d.ts +0 -20
  113. package/dist/plugin/memory-format.js +0 -59
  114. package/dist/plugin/metrics.d.ts +0 -97
  115. package/dist/plugin/metrics.js +0 -288
  116. package/dist/plugin/okf-export.d.ts +0 -3
  117. package/dist/plugin/okf-export.js +0 -134
  118. package/dist/plugin/okf-import.d.ts +0 -76
  119. package/dist/plugin/okf-import.js +0 -271
  120. package/dist/plugin/okf.d.ts +0 -107
  121. package/dist/plugin/okf.js +0 -303
  122. package/dist/plugin/perf.d.ts +0 -35
  123. package/dist/plugin/perf.js +0 -174
  124. package/dist/plugin/query-tokenizer.d.ts +0 -13
  125. package/dist/plugin/query-tokenizer.js +0 -133
  126. package/dist/plugin/redact.d.ts +0 -2
  127. package/dist/plugin/redact.js +0 -18
  128. package/dist/plugin/replay-types.d.ts +0 -69
  129. package/dist/plugin/replay-types.js +0 -156
  130. package/dist/plugin/replay.d.ts +0 -36
  131. package/dist/plugin/replay.js +0 -202
  132. package/dist/plugin/sqlite-adapter.d.ts +0 -12
  133. package/dist/plugin/sqlite-adapter.js +0 -81
  134. package/dist/plugin/time-ms.d.ts +0 -1
  135. package/dist/plugin/time-ms.js +0 -16
  136. package/dist/plugin/tui-types.d.ts +0 -59
  137. package/dist/plugin/tui-types.js +0 -4
  138. package/dist/plugin/tui.d.ts +0 -18
  139. package/dist/plugin/tui.js +0 -198
  140. package/dist/plugin/uuid.d.ts +0 -1
  141. package/dist/plugin/uuid.js +0 -50
@@ -1,5 +1,6 @@
1
1
  import type { Plugin } from "@opencode-ai/plugin";
2
- import { Store } from "./Store.js";
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;
@@ -18,8 +19,8 @@ export interface KevinPluginOptions {
18
19
  */
19
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"];
20
21
  export declare const ERROR_LESSON_MODE_VALUES: readonly ["all", "triage_only"];
21
- /** Plugin release version — stamped into generated files (K8-021/027). */
22
- export declare const KEVIN_VERSION = "1.2.0";
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;
@@ -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 "./Archiver.js";
7
- import { ArtifactWriter } from "./ArtifactWriter.js";
8
- import { CausalChain } from "./CausalChain.js";
9
- import { handleBridgeCommand } from "./ChatBridge.js";
10
- import { ConflictDetector } from "./ConflictDetector.js";
11
- import { ContextInjector } from "./ContextInjector.js";
12
- import { ConventionMiner } from "./ConventionMiner.js";
13
- import { Curator } from "./Curator.js";
14
- import { writeDashboard } from "./DashboardHtml.js";
15
- import { Feedback } from "./Feedback.js";
16
- import { HookLiveness } from "./HookLiveness.js";
17
- import { InjectionLedger } from "./InjectionLedger.js";
18
- import { Materializer, SKILL_TOPIC } from "./Materializer.js";
19
- import { MemoryService, hasRepoIdColumn, } from "./MemoryService.js";
20
- import { Migrate } from "./Migrate.js";
21
- import { PatternMiner } from "./PatternMiner.js";
22
- import { ERROR_LINE_RE, Reflector, STRONG_ERROR_RE } from "./Reflector.js";
23
- import * as RepoIdentity from "./RepoIdentity.js";
24
- import { RepoTruth } from "./RepoTruth.js";
25
- import { Retrospective } from "./Retrospective.js";
26
- import { SharedLayer } from "./SharedLayer.js";
27
- import { Store } from "./Store.js";
28
- import { ToolCallObserver } from "./ToolCallObserver.js";
29
- import { deleteMailbox, processActions, readMailbox, writeResults, } from "./TuiActions.js";
30
- import { flushSnapshots } from "./TuiSnapshots.js";
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 "./confidence.js";
33
- import { contractDigest, describeContract } from "./contract.js";
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 "./kevin_approve.js";
36
- import { buildAudit } from "./kevin_audit.js";
37
- import { buildKevinBench } from "./kevin_bench.js";
38
- import { executeKevinConflicts } from "./kevin_conflicts.js";
39
- import { buildKevinContract } from "./kevin_contract.js";
40
- import { buildDoctor } from "./kevin_doctor.js";
41
- import { buildKevinFacts } from "./kevin_facts.js";
42
- import { handleForget } from "./kevin_forget.js";
43
- import { handleNative } from "./kevin_native.js";
44
- import { kevinPropose } from "./kevin_propose.js";
45
- import { kevinPublish } from "./kevin_publish.js";
46
- import { kevinWhy } from "./kevin_why.js";
47
- import { Metrics } from "./metrics.js";
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 "./okf-export.js";
50
- import { importOkf } from "./okf-import.js";
51
- import { Perf } from "./perf.js";
52
- import { uuidv7 } from "./uuid.js";
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
@@ -131,11 +132,41 @@ export const KEVIN_CONFIG_KEYS = [
131
132
  // at the surface rather than silently changing every installation's
132
133
  // behaviour on the next reflection.
133
134
  export const ERROR_LESSON_MODE_VALUES = ["all", "triage_only"];
134
- /** Plugin release version — stamped into generated files (K8-021/027). */
135
- export const KEVIN_VERSION = "1.2.0";
135
+ /** Plugin release version — single source is @jmtrin/kevin-core (B-003 drift fix). */
136
+ export { KEVIN_VERSION };
136
137
  function resolveMigrationsDir() {
138
+ // K13-008 (D13-04): migrations now owned by @jmtrin/kevin-core.
139
+ // Explicit option is handled at call site (opts.migrationsDir ?? resolve...),
140
+ // so this helper only resolves the core location.
141
+ // 1. Installed layout: walk-up via require.resolve (reuses host.ts strategy)
142
+ try {
143
+ const pkgJson = createRequire(import.meta.url).resolve("@jmtrin/kevin-core/package.json");
144
+ const cand = join(dirname(pkgJson), "dist", "migrations");
145
+ if (existsSync(cand))
146
+ return cand;
147
+ }
148
+ catch { }
149
+ // 2. Workspace sources: delegate to core's own resolver (handles both
150
+ // src via tsx and dist after build).
151
+ try {
152
+ const dir = exportMigrationsDir();
153
+ if (existsSync(dir))
154
+ return dir;
155
+ }
156
+ catch { }
157
+ // 3. Monorepo fallback probes (dev without build)
137
158
  const here = dirname(fileURLToPath(import.meta.url));
138
- return join(here, "..", "migrations");
159
+ const candidates = [
160
+ join(here, "..", "..", "core", "dist", "migrations"),
161
+ join(here, "..", "..", "core", "migrations"),
162
+ join(here, "..", "migrations"),
163
+ join(here, "..", "..", "migrations"),
164
+ ];
165
+ for (const c of candidates) {
166
+ if (existsSync(c))
167
+ return c;
168
+ }
169
+ return join(here, "..", "..", "core", "migrations");
139
170
  }
140
171
  const REKEY_TABLES = ["memories", "shared_entries", "okf_imports"];
141
172
  export function performRekey(store, toRepoId, opts) {
@@ -337,6 +368,8 @@ export const KevinPlugin = async (input, options) => {
337
368
  // v0.7.0 (K7-009 / plan §5.1, D7-13) — the repository truth scanner reads
338
369
  // the JSON project files. Runs once at init, gated by repo_truth_enabled.
339
370
  const projectRoot = opts.projectRoot ?? process.cwd();
371
+ const materializerRoot = opts.materializerRoot ?? join(homedir(), ".opencode-kevin");
372
+ const kevinEnv = { projectRoot, dataRoot: materializerRoot };
340
373
  const repoTruth = new RepoTruth(store, projectId, projectRoot, metrics);
341
374
  if (memoryService.getSetting("repo_truth_enabled", "0") === "1") {
342
375
  try {
@@ -376,7 +409,7 @@ export const KevinPlugin = async (input, options) => {
376
409
  const archiver = new Archiver(store, memoryService, metrics);
377
410
  const retrospective = new Retrospective(store, memoryService, {
378
411
  dir: opts.retrospectivesDir,
379
- }, metrics);
412
+ }, metrics, kevinEnv);
380
413
  const patternMiner = new PatternMiner(store, memoryService, metrics);
381
414
  const conventionMiner = new ConventionMiner(store, memoryService, projectId, metrics);
382
415
  const conflictDetector = new ConflictDetector(store, projectId, metrics, repoTruth, memoryService);
@@ -408,13 +441,12 @@ export const KevinPlugin = async (input, options) => {
408
441
  metrics.incr("shared_entries_imported", report.imported);
409
442
  return report;
410
443
  }
411
- let curator = new Curator(store, memoryService, projectId, metrics, repoId);
444
+ let curator = new Curator(store, memoryService, projectId, metrics, repoId, kevinEnv);
412
445
  // v0.6.0 (K6-017/018 / plan §5.6-5.7, D6-13) — pull-channel bundles and
413
446
  // the v2 domain probe. `probe()` runs ONCE at init and the result is
414
447
  // held; probing per-event is a hot-path cost for a value that cannot
415
448
  // change within a process (K6-016). The Materializer writes next to its
416
449
  // targets, so the bundle directories are created here at init.
417
- const materializerRoot = opts.materializerRoot ?? join(homedir(), ".opencode-kevin");
418
450
  mkdirSync(join(materializerRoot, "skills"), { recursive: true });
419
451
  mkdirSync(join(materializerRoot, "refs"), { recursive: true });
420
452
  const capabilities = probe(input);
@@ -422,7 +454,7 @@ export const KevinPlugin = async (input, options) => {
422
454
  // When the host exposes permission.ask, the presence is noted; absence is silent no-op.
423
455
  // No new setting — bounded to tui_snapshots_enabled host-support check per spec.
424
456
  void capabilities.permissionAsk;
425
- const materializer = new Materializer(store, { root: materializerRoot });
457
+ const materializer = new Materializer(store, { root: materializerRoot }, kevinEnv);
426
458
  // v0.9.0 (K9-016 / plan §5.4, D9-10) — native registration replaces
427
459
  // file emission. When attachNative returns a registration for a
428
460
  // surface, the corresponding *_emission_enabled path is skipped for
@@ -1002,7 +1034,7 @@ export const KevinPlugin = async (input, options) => {
1002
1034
  version: KEVIN_VERSION,
1003
1035
  writer,
1004
1036
  });
1005
- curator = new Curator(store, memoryService, projectId, metrics, live.repoId);
1037
+ curator = new Curator(store, memoryService, projectId, metrics, live.repoId, kevinEnv);
1006
1038
  // v0.8.0 (BUG-003) — heal the OKF file header.
1007
1039
  // Rekey changes the scope the file is written
1008
1040
  // under; a stale `#repo` first line would make
@@ -1077,7 +1109,7 @@ export const KevinPlugin = async (input, options) => {
1077
1109
  // block; on a pre-008 DB the block is omitted, partial:true.
1078
1110
  // v0.8.0 (K8-007 / plan §5.7) — the penalized-memory rollup
1079
1111
  // scopes on repoId once the 009 column exists.
1080
- const report = buildAudit(store, metrics, capabilities, projectId, sessionIdentity.repoId);
1112
+ const report = buildAudit(store, metrics, capabilities, projectId, sessionIdentity.repoId, undefined, kevinEnv);
1081
1113
  const payload = args.verbose
1082
1114
  ? report
1083
1115
  : { ...report, settings: undefined };
@@ -1096,7 +1128,7 @@ export const KevinPlugin = async (input, options) => {
1096
1128
  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
1129
  args: {},
1098
1130
  async execute() {
1099
- const report = buildDoctor(store, host, memoryService);
1131
+ const report = buildDoctor(store, host, memoryService, {}, kevinEnv);
1100
1132
  return {
1101
1133
  title: "Doctor de Kevin",
1102
1134
  output: JSON.stringify(report),
@@ -1165,7 +1197,7 @@ export const KevinPlugin = async (input, options) => {
1165
1197
  .describe("status | last"),
1166
1198
  },
1167
1199
  async execute(args) {
1168
- const result = buildKevinBench({ store }, args);
1200
+ const result = buildKevinBench({ store }, args, kevinEnv);
1169
1201
  return {
1170
1202
  title: "Benchmark de Kevin",
1171
1203
  output: JSON.stringify(result),
@@ -1843,62 +1875,39 @@ export const KevinPlugin = async (input, options) => {
1843
1875
  // BUG-011 — the session is done: drop the global query
1844
1876
  // so the next session cannot reuse it.
1845
1877
  lastUserQuery = null;
1846
- // v0.4.0 (K4-024) — plan §5.2: settle the session's
1847
- // unmeasured injections (effective/ineffective +
1848
- // recurrence_count charges) at idle. Best-effort: a
1849
- // legacy DB without migration 005 has no ledger table.
1850
- try {
1851
- ledger.settle(sid);
1852
- }
1853
- catch {
1854
- // best-effort: a legacy DB without the ledger
1855
- // table must not break the idle path
1856
- }
1857
- // v0.5.0 (K5-012 / plan §5.4) — retire stale lessons at
1858
- // idle; pre-006 DBs degrade to a no-op.
1859
- try {
1860
- archiver.run();
1861
- }
1862
- catch {
1863
- // best-effort, same pattern as ledger.settle
1864
- }
1865
- fireAndForget(retrospective.generate(sid));
1866
- memoryService.boostPositiveReflectors(sid);
1867
- const recurred = memoryService.penalizeRecurringReflectors(sid);
1868
- injector.setRecurrences(recurred, sid);
1869
- patternMiner.mine(projectId);
1870
- // v0.7.0 (K7-012 / plan §5.4, D7-10) convention mining is
1871
- // session.idle-only, default-off, and isolated from the rest of
1872
- // the idle chain. Mined rules still enter the ordinary Curator
1873
- // approval path; this step never writes to the repository.
1874
- try {
1875
- if (memoryService.getSetting("convention_mining_enabled", "0") ===
1876
- "1") {
1877
- const conventions = conventionMiner.mine();
1878
- conventionMiner.emit(conventions);
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(() => { }));
1878
+ // K13-010 (D13-07) — single ORDER via composeIdlePipeline.
1879
+ // Ledger/archiver/reflectors/pattern are the hand-synced core;
1880
+ // adapter and replay both consume IDLE_STEP_ORDER so re-order is visible in both.
1881
+ await composeIdlePipeline({
1882
+ "ledger.settle": () => { ledger.settle(sid); },
1883
+ "archiver.run": () => { archiver.run(); },
1884
+ retrospective: () => {
1885
+ fireAndForget(retrospective.generate(sid));
1886
+ },
1887
+ "reflectors.boost": () => { memoryService.boostPositiveReflectors(sid); },
1888
+ "reflectors.penalize": () => {
1889
+ const recurred = memoryService.penalizeRecurringReflectors(sid);
1890
+ injector.setRecurrences(recurred, sid);
1891
+ },
1892
+ "patternMiner.mine": () => { patternMiner.mine(projectId); },
1893
+ });
1894
+ // v0.7.0 (K7-012/K7-016) + causalChain — folded into the single ORDER via composeIdlePipeline (K13-010)
1895
+ await composeIdlePipeline({
1896
+ "conventionMiner.mine": () => {
1897
+ if (memoryService.getSetting("convention_mining_enabled", "0") === "1") {
1898
+ const conventions = conventionMiner.mine();
1899
+ conventionMiner.emit(conventions);
1900
+ }
1901
+ },
1902
+ "conflictDetector.detect": () => {
1903
+ if (memoryService.getSetting("conflict_detection_enabled", "0") === "1") {
1904
+ conflictDetector.detect();
1905
+ }
1906
+ },
1907
+ "causalChain.onSessionIdle": () => {
1908
+ fireAndForget(Promise.resolve().then(() => causalChain.onSessionIdle(sid)).catch(() => { }));
1909
+ },
1910
+ });
1902
1911
  // v1.2.0 (K12-007/K12-011 / D12-05) — TUI mailbox: actions→curate ordering.
1903
1912
  // Process mailbox BEFORE curator.propose so a fresh proposal created this idle
1904
1913
  // is NOT visible to a stale token (D12-04). Best-effort, never breaks idle.
@@ -2013,7 +2022,7 @@ export const KevinPlugin = async (input, options) => {
2013
2022
  .prepare("SELECT id, kind, target_path, proposed_text, diff, memory_id, created_at FROM curation_proposals WHERE status = 'pending' ORDER BY created_at")
2014
2023
  .all();
2015
2024
  })();
2016
- const { proposalToken } = await import("./TuiActions.js");
2025
+ const { proposalToken } = await import("@jmtrin/kevin-core");
2017
2026
  proposals = rawPending.map((r) => {
2018
2027
  const row = r;
2019
2028
  const id = String(row.id ?? "");
@@ -2060,7 +2069,7 @@ export const KevinPlugin = async (input, options) => {
2060
2069
  // Health
2061
2070
  let health;
2062
2071
  try {
2063
- const doc = buildDoctor(store, host, memoryService);
2072
+ const doc = buildDoctor(store, host, memoryService, {}, kevinEnv);
2064
2073
  let perfRows = [];
2065
2074
  try {
2066
2075
  const stats = perf.stats?.();
@@ -1,5 +1,5 @@
1
- import { type Materializer } from "./Materializer.js";
2
- import type { Store } from "./Store.js";
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()`. */
@@ -1,5 +1,5 @@
1
- import { SKILL_TOPIC } from "./Materializer.js";
2
- import { uuidv7 } from "./uuid.js";
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`. */
package/package.json CHANGED
@@ -1,70 +1,58 @@
1
1
  {
2
- "name": "@jmtrin/opencode-kevin",
3
- "version": "1.2.0",
4
- "description": "Kevin — Observa y aprende: capa de aprendizaje para OpenCode",
5
- "type": "module",
6
- "main": "dist/plugin/index.js",
7
- "types": "./dist/plugin/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/plugin/index.d.ts",
11
- "import": "./dist/plugin/index.js"
12
- },
13
- "./tui": {
14
- "types": "./dist/plugin/tui.d.ts",
15
- "import": "./dist/plugin/tui.js"
16
- }
17
- },
18
- "files": ["dist/plugin", "dist/migrations"],
19
- "scripts": {
20
- "build": "tsc -p tsconfig.build.json && node scripts/copy-migrations.mjs",
21
- "prepublishOnly": "npm run build",
22
- "test": "vitest run",
23
- "test:unit": "vitest run tests/unit",
24
- "test:integration": "vitest run tests/integration",
25
- "test:e2e": "vitest run tests/e2e",
26
- "typecheck": "tsc --noEmit",
27
- "lint": "biome check .",
28
- "format": "biome format --write .",
29
- "verify": "node --import tsx scripts/verify-install.ts && npm run verify:pack",
30
- "verify:pack": "node --import tsx scripts/verify-pack.ts",
31
- "bench": "node --import tsx scripts/bench.ts",
32
- "gen:corpus": "node --import tsx scripts/gen-corpus.ts",
33
- "bench:check": "node --import tsx scripts/bench-check.ts",
34
- "bench:regress": "tsx scripts/bench-regress.ts",
35
- "replay": "node --import tsx scripts/replay.ts",
36
- "measure:mix": "node --import tsx scripts/measure-mix.ts"
37
- },
38
- "dependencies": {
39
- "@opencode-ai/plugin": "^1.18.16"
40
- },
41
- "optionalDependencies": {
42
- "better-sqlite3": "^12.11.0"
43
- },
44
- "devDependencies": {
45
- "@biomejs/biome": "^1.9.4",
46
- "@types/better-sqlite3": "^7.6.12",
47
- "@types/node": "^22.10.0",
48
- "tsx": "^4.19.0",
49
- "typescript": "^5.7.2",
50
- "vitest": "^2.1.8"
51
- },
52
- "engines": {
53
- "node": ">=22.5.0",
54
- "opencode": "^1.18.0"
55
- },
56
- "repository": {
57
- "type": "git",
58
- "url": "https://github.com/jmtrin/opencode-kevin.git"
59
- },
60
- "homepage": "https://github.com/jmtrin/opencode-kevin#readme",
61
- "bugs": {
62
- "url": "https://github.com/jmtrin/opencode-kevin/issues"
63
- },
64
- "keywords": ["opencode", "plugin", "memory", "learning", "ai"],
65
- "author": "jmtrin",
66
- "publishConfig": {
67
- "access": "public"
68
- },
69
- "license": "MIT"
2
+ "name": "@jmtrin/opencode-kevin",
3
+ "version": "1.3.0",
4
+ "description": "Kevin — Observa y aprende: capa de aprendizaje para OpenCode",
5
+ "type": "module",
6
+ "main": "dist/plugin/index.js",
7
+ "types": "dist/plugin/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/plugin/index.d.ts",
11
+ "import": "./dist/plugin/index.js"
12
+ },
13
+ "./tui": {
14
+ "types": "@jmtrin/opencode-kevin-tui/dist/index.d.ts",
15
+ "import": "@jmtrin/opencode-kevin-tui/dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist/plugin"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "prepublishOnly": "npm run build",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "dependencies": {
27
+ "@opencode-ai/plugin": "^1.18.16",
28
+ "@jmtrin/kevin-core": "1.3.0",
29
+ "@jmtrin/opencode-kevin-tui": "1.3.0"
30
+ },
31
+ "optionalDependencies": {
32
+ "better-sqlite3": "^12.11.0"
33
+ },
34
+ "engines": {
35
+ "node": ">=22.5.0",
36
+ "opencode": "^1.18.0"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/jmtrin/opencode-kevin.git"
41
+ },
42
+ "homepage": "https://github.com/jmtrin/opencode-kevin#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/jmtrin/opencode-kevin/issues"
45
+ },
46
+ "keywords": [
47
+ "opencode",
48
+ "plugin",
49
+ "memory",
50
+ "learning",
51
+ "ai"
52
+ ],
53
+ "author": "jmtrin",
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "license": "MIT"
70
58
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 jmtrin
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.