cognitive-core 0.0.2 → 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.
Files changed (329) hide show
  1. package/README.md +302 -116
  2. package/SKILL.md +193 -0
  3. package/dist/agents/index.d.ts +3 -0
  4. package/dist/agents/index.d.ts.map +1 -0
  5. package/dist/agents/index.js +5 -0
  6. package/dist/agents/index.js.map +1 -0
  7. package/dist/agents/mock-provider.d.ts +23 -0
  8. package/dist/agents/mock-provider.d.ts.map +1 -0
  9. package/dist/agents/mock-provider.js +71 -0
  10. package/dist/agents/mock-provider.js.map +1 -0
  11. package/dist/agents/types.d.ts +98 -0
  12. package/dist/agents/types.d.ts.map +1 -0
  13. package/dist/agents/types.js +44 -0
  14. package/dist/agents/types.js.map +1 -0
  15. package/dist/atlas.d.ts +196 -0
  16. package/dist/atlas.d.ts.map +1 -0
  17. package/dist/atlas.js +373 -0
  18. package/dist/atlas.js.map +1 -0
  19. package/dist/bin/cognitive-core.d.ts +18 -0
  20. package/dist/bin/cognitive-core.d.ts.map +1 -0
  21. package/dist/bin/cognitive-core.js +419 -0
  22. package/dist/bin/cognitive-core.js.map +1 -0
  23. package/dist/embeddings/bm25.d.ts +104 -0
  24. package/dist/embeddings/bm25.d.ts.map +1 -0
  25. package/dist/embeddings/bm25.js +264 -0
  26. package/dist/embeddings/bm25.js.map +1 -0
  27. package/dist/embeddings/index.d.ts +12 -0
  28. package/dist/embeddings/index.d.ts.map +1 -0
  29. package/dist/embeddings/index.js +16 -0
  30. package/dist/embeddings/index.js.map +1 -0
  31. package/dist/embeddings/manager.d.ts +112 -0
  32. package/dist/embeddings/manager.d.ts.map +1 -0
  33. package/dist/embeddings/manager.js +215 -0
  34. package/dist/embeddings/manager.js.map +1 -0
  35. package/dist/embeddings/provider.d.ts +101 -0
  36. package/dist/embeddings/provider.d.ts.map +1 -0
  37. package/dist/embeddings/provider.js +232 -0
  38. package/dist/embeddings/provider.js.map +1 -0
  39. package/dist/embeddings/vector-store.d.ts +101 -0
  40. package/dist/embeddings/vector-store.d.ts.map +1 -0
  41. package/dist/embeddings/vector-store.js +256 -0
  42. package/dist/embeddings/vector-store.js.map +1 -0
  43. package/dist/factory.d.ts +193 -0
  44. package/dist/factory.d.ts.map +1 -0
  45. package/dist/factory.js +109 -0
  46. package/dist/factory.js.map +1 -0
  47. package/dist/index.d.ts +30 -453
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +84 -509
  50. package/dist/index.js.map +1 -0
  51. package/dist/learning/analyzer.d.ts +110 -0
  52. package/dist/learning/analyzer.d.ts.map +1 -0
  53. package/dist/learning/analyzer.js +213 -0
  54. package/dist/learning/analyzer.js.map +1 -0
  55. package/dist/learning/effectiveness.d.ts +158 -0
  56. package/dist/learning/effectiveness.d.ts.map +1 -0
  57. package/dist/learning/effectiveness.js +251 -0
  58. package/dist/learning/effectiveness.js.map +1 -0
  59. package/dist/learning/index.d.ts +8 -0
  60. package/dist/learning/index.d.ts.map +1 -0
  61. package/dist/learning/index.js +11 -0
  62. package/dist/learning/index.js.map +1 -0
  63. package/dist/learning/llm-extractor.d.ts +88 -0
  64. package/dist/learning/llm-extractor.d.ts.map +1 -0
  65. package/dist/learning/llm-extractor.js +372 -0
  66. package/dist/learning/llm-extractor.js.map +1 -0
  67. package/dist/learning/meta-learner.d.ts +80 -0
  68. package/dist/learning/meta-learner.d.ts.map +1 -0
  69. package/dist/learning/meta-learner.js +355 -0
  70. package/dist/learning/meta-learner.js.map +1 -0
  71. package/dist/learning/pipeline.d.ts +65 -0
  72. package/dist/learning/pipeline.d.ts.map +1 -0
  73. package/dist/learning/pipeline.js +170 -0
  74. package/dist/learning/pipeline.js.map +1 -0
  75. package/dist/learning/playbook-extractor.d.ts +113 -0
  76. package/dist/learning/playbook-extractor.d.ts.map +1 -0
  77. package/dist/learning/playbook-extractor.js +523 -0
  78. package/dist/learning/playbook-extractor.js.map +1 -0
  79. package/dist/learning/usage-inference.d.ts +82 -0
  80. package/dist/learning/usage-inference.d.ts.map +1 -0
  81. package/dist/learning/usage-inference.js +261 -0
  82. package/dist/learning/usage-inference.js.map +1 -0
  83. package/dist/mcp/index.d.ts +6 -0
  84. package/dist/mcp/index.d.ts.map +1 -0
  85. package/dist/mcp/index.js +6 -0
  86. package/dist/mcp/index.js.map +1 -0
  87. package/dist/mcp/playbook-server.d.ts +120 -0
  88. package/dist/mcp/playbook-server.d.ts.map +1 -0
  89. package/dist/mcp/playbook-server.js +427 -0
  90. package/dist/mcp/playbook-server.js.map +1 -0
  91. package/dist/memory/curated-loader.d.ts +62 -0
  92. package/dist/memory/curated-loader.d.ts.map +1 -0
  93. package/dist/memory/curated-loader.js +106 -0
  94. package/dist/memory/curated-loader.js.map +1 -0
  95. package/dist/memory/experience.d.ts +122 -0
  96. package/dist/memory/experience.d.ts.map +1 -0
  97. package/dist/memory/experience.js +392 -0
  98. package/dist/memory/experience.js.map +1 -0
  99. package/dist/memory/index.d.ts +6 -0
  100. package/dist/memory/index.d.ts.map +1 -0
  101. package/dist/memory/index.js +9 -0
  102. package/dist/memory/index.js.map +1 -0
  103. package/dist/memory/meta.d.ts +90 -0
  104. package/dist/memory/meta.d.ts.map +1 -0
  105. package/dist/memory/meta.js +362 -0
  106. package/dist/memory/meta.js.map +1 -0
  107. package/dist/memory/playbook.d.ts +133 -0
  108. package/dist/memory/playbook.d.ts.map +1 -0
  109. package/dist/memory/playbook.js +357 -0
  110. package/dist/memory/playbook.js.map +1 -0
  111. package/dist/memory/system.d.ts +167 -0
  112. package/dist/memory/system.d.ts.map +1 -0
  113. package/dist/memory/system.js +383 -0
  114. package/dist/memory/system.js.map +1 -0
  115. package/dist/runtime/backends/acp.d.ts +67 -0
  116. package/dist/runtime/backends/acp.d.ts.map +1 -0
  117. package/dist/runtime/backends/acp.js +290 -0
  118. package/dist/runtime/backends/acp.js.map +1 -0
  119. package/dist/runtime/backends/index.d.ts +5 -0
  120. package/dist/runtime/backends/index.d.ts.map +1 -0
  121. package/dist/runtime/backends/index.js +6 -0
  122. package/dist/runtime/backends/index.js.map +1 -0
  123. package/dist/runtime/backends/mock.d.ts +67 -0
  124. package/dist/runtime/backends/mock.d.ts.map +1 -0
  125. package/dist/runtime/backends/mock.js +153 -0
  126. package/dist/runtime/backends/mock.js.map +1 -0
  127. package/dist/runtime/backends/subprocess.d.ts +56 -0
  128. package/dist/runtime/backends/subprocess.d.ts.map +1 -0
  129. package/dist/runtime/backends/subprocess.js +260 -0
  130. package/dist/runtime/backends/subprocess.js.map +1 -0
  131. package/dist/runtime/flows/learning.d.ts +73 -0
  132. package/dist/runtime/flows/learning.d.ts.map +1 -0
  133. package/dist/runtime/flows/learning.js +116 -0
  134. package/dist/runtime/flows/learning.js.map +1 -0
  135. package/dist/runtime/flows/validation.d.ts +122 -0
  136. package/dist/runtime/flows/validation.d.ts.map +1 -0
  137. package/dist/runtime/flows/validation.js +223 -0
  138. package/dist/runtime/flows/validation.js.map +1 -0
  139. package/dist/runtime/index.d.ts +6 -0
  140. package/dist/runtime/index.d.ts.map +1 -0
  141. package/dist/runtime/index.js +8 -0
  142. package/dist/runtime/index.js.map +1 -0
  143. package/dist/runtime/manager.d.ts +116 -0
  144. package/dist/runtime/manager.d.ts.map +1 -0
  145. package/dist/runtime/manager.js +416 -0
  146. package/dist/runtime/manager.js.map +1 -0
  147. package/dist/runtime/types.d.ts +138 -0
  148. package/dist/runtime/types.d.ts.map +1 -0
  149. package/dist/runtime/types.js +2 -0
  150. package/dist/runtime/types.js.map +1 -0
  151. package/dist/search/evaluator.d.ts +102 -0
  152. package/dist/search/evaluator.d.ts.map +1 -0
  153. package/dist/search/evaluator.js +352 -0
  154. package/dist/search/evaluator.js.map +1 -0
  155. package/dist/search/index.d.ts +7 -0
  156. package/dist/search/index.d.ts.map +1 -0
  157. package/dist/search/index.js +11 -0
  158. package/dist/search/index.js.map +1 -0
  159. package/dist/search/refinement-loop.d.ts +73 -0
  160. package/dist/search/refinement-loop.d.ts.map +1 -0
  161. package/dist/search/refinement-loop.js +245 -0
  162. package/dist/search/refinement-loop.js.map +1 -0
  163. package/dist/search/refinement-types.d.ts +154 -0
  164. package/dist/search/refinement-types.d.ts.map +1 -0
  165. package/dist/search/refinement-types.js +99 -0
  166. package/dist/search/refinement-types.js.map +1 -0
  167. package/dist/search/router.d.ts +61 -0
  168. package/dist/search/router.d.ts.map +1 -0
  169. package/dist/search/router.js +197 -0
  170. package/dist/search/router.js.map +1 -0
  171. package/dist/search/solver.d.ts +75 -0
  172. package/dist/search/solver.d.ts.map +1 -0
  173. package/dist/search/solver.js +216 -0
  174. package/dist/search/solver.js.map +1 -0
  175. package/dist/search/verification-runner.d.ts +125 -0
  176. package/dist/search/verification-runner.d.ts.map +1 -0
  177. package/dist/search/verification-runner.js +440 -0
  178. package/dist/search/verification-runner.js.map +1 -0
  179. package/dist/surfacing/index.d.ts +2 -0
  180. package/dist/surfacing/index.d.ts.map +1 -0
  181. package/dist/surfacing/index.js +2 -0
  182. package/dist/surfacing/index.js.map +1 -0
  183. package/dist/surfacing/skill-library.d.ts +158 -0
  184. package/dist/surfacing/skill-library.d.ts.map +1 -0
  185. package/dist/surfacing/skill-library.js +429 -0
  186. package/dist/surfacing/skill-library.js.map +1 -0
  187. package/dist/types/config.d.ts +1113 -0
  188. package/dist/types/config.d.ts.map +1 -0
  189. package/dist/types/config.js +274 -0
  190. package/dist/types/config.js.map +1 -0
  191. package/dist/types/index.d.ts +9 -0
  192. package/dist/types/index.d.ts.map +1 -0
  193. package/dist/types/index.js +14 -0
  194. package/dist/types/index.js.map +1 -0
  195. package/dist/types/memory.d.ts +339 -0
  196. package/dist/types/memory.d.ts.map +1 -0
  197. package/dist/types/memory.js +207 -0
  198. package/dist/types/memory.js.map +1 -0
  199. package/dist/types/meta.d.ts +146 -0
  200. package/dist/types/meta.d.ts.map +1 -0
  201. package/dist/types/meta.js +51 -0
  202. package/dist/types/meta.js.map +1 -0
  203. package/dist/types/outcome.d.ts +42 -0
  204. package/dist/types/outcome.d.ts.map +1 -0
  205. package/dist/types/outcome.js +50 -0
  206. package/dist/types/outcome.js.map +1 -0
  207. package/dist/types/playbook.d.ts +119 -0
  208. package/dist/types/playbook.d.ts.map +1 -0
  209. package/dist/types/playbook.js +71 -0
  210. package/dist/types/playbook.js.map +1 -0
  211. package/dist/types/step.d.ts +44 -0
  212. package/dist/types/step.d.ts.map +1 -0
  213. package/dist/types/step.js +32 -0
  214. package/dist/types/step.js.map +1 -0
  215. package/dist/types/task.d.ts +91 -0
  216. package/dist/types/task.d.ts.map +1 -0
  217. package/dist/types/task.js +39 -0
  218. package/dist/types/task.js.map +1 -0
  219. package/dist/types/trajectory.d.ts +221 -0
  220. package/dist/types/trajectory.d.ts.map +1 -0
  221. package/dist/types/trajectory.js +60 -0
  222. package/dist/types/trajectory.js.map +1 -0
  223. package/dist/utils/index.d.ts +4 -0
  224. package/dist/utils/index.d.ts.map +1 -0
  225. package/dist/utils/index.js +4 -0
  226. package/dist/utils/index.js.map +1 -0
  227. package/dist/utils/similarity.d.ts +31 -0
  228. package/dist/utils/similarity.d.ts.map +1 -0
  229. package/dist/utils/similarity.js +107 -0
  230. package/dist/utils/similarity.js.map +1 -0
  231. package/dist/utils/storage.d.ts +106 -0
  232. package/dist/utils/storage.d.ts.map +1 -0
  233. package/dist/utils/storage.js +203 -0
  234. package/dist/utils/storage.js.map +1 -0
  235. package/dist/utils/validation.d.ts +129 -0
  236. package/dist/utils/validation.d.ts.map +1 -0
  237. package/dist/utils/validation.js +171 -0
  238. package/dist/utils/validation.js.map +1 -0
  239. package/package.json +50 -34
  240. package/scripts/migrate-to-playbooks.ts +307 -0
  241. package/src/agents/index.ts +14 -0
  242. package/src/agents/mock-provider.ts +93 -0
  243. package/src/agents/types.ts +137 -0
  244. package/src/atlas.ts +560 -0
  245. package/src/bin/cognitive-core.ts +470 -0
  246. package/src/embeddings/bm25.ts +337 -0
  247. package/src/embeddings/index.ts +39 -0
  248. package/src/embeddings/manager.ts +288 -0
  249. package/src/embeddings/provider.ts +311 -0
  250. package/src/embeddings/vector-store.ts +353 -0
  251. package/src/factory.ts +263 -0
  252. package/src/index.ts +246 -0
  253. package/src/learning/analyzer.ts +335 -0
  254. package/src/learning/effectiveness.ts +428 -0
  255. package/src/learning/index.ts +58 -0
  256. package/src/learning/llm-extractor.ts +542 -0
  257. package/src/learning/meta-learner.ts +516 -0
  258. package/src/learning/pipeline.ts +244 -0
  259. package/src/learning/playbook-extractor.ts +702 -0
  260. package/src/learning/usage-inference.ts +372 -0
  261. package/src/mcp/index.ts +12 -0
  262. package/src/mcp/playbook-server.ts +565 -0
  263. package/src/memory/curated-loader.ts +160 -0
  264. package/src/memory/experience.ts +515 -0
  265. package/src/memory/index.ts +27 -0
  266. package/src/memory/meta.ts +506 -0
  267. package/src/memory/playbook.ts +493 -0
  268. package/src/memory/system.ts +551 -0
  269. package/src/runtime/backends/acp.ts +378 -0
  270. package/src/runtime/backends/index.ts +24 -0
  271. package/src/runtime/backends/mock.ts +218 -0
  272. package/src/runtime/backends/subprocess.ts +356 -0
  273. package/src/runtime/flows/learning.ts +183 -0
  274. package/src/runtime/flows/validation.ts +381 -0
  275. package/src/runtime/index.ts +53 -0
  276. package/src/runtime/manager.ts +541 -0
  277. package/src/runtime/types.ts +157 -0
  278. package/src/search/evaluator.ts +474 -0
  279. package/src/search/index.ts +59 -0
  280. package/src/search/refinement-loop.ts +363 -0
  281. package/src/search/refinement-types.ts +159 -0
  282. package/src/search/router.ts +261 -0
  283. package/src/search/solver.ts +303 -0
  284. package/src/search/verification-runner.ts +570 -0
  285. package/src/surfacing/index.ts +6 -0
  286. package/src/surfacing/skill-library.ts +594 -0
  287. package/src/types/config.ts +333 -0
  288. package/src/types/index.ts +130 -0
  289. package/src/types/memory.ts +270 -0
  290. package/src/types/meta.ts +218 -0
  291. package/src/types/outcome.ts +66 -0
  292. package/src/types/playbook.ts +196 -0
  293. package/src/types/step.ts +40 -0
  294. package/src/types/task.ts +52 -0
  295. package/src/types/trajectory.ts +80 -0
  296. package/src/utils/index.ts +38 -0
  297. package/src/utils/similarity.ts +139 -0
  298. package/src/utils/storage.ts +249 -0
  299. package/src/utils/validation.ts +286 -0
  300. package/tests/embeddings/bm25.test.ts +130 -0
  301. package/tests/embeddings/manager.test.ts +205 -0
  302. package/tests/integration/atlas.test.ts +266 -0
  303. package/tests/integration/e2e.test.ts +929 -0
  304. package/tests/learning/analyzer.test.ts +426 -0
  305. package/tests/learning/effectiveness.test.ts +542 -0
  306. package/tests/learning/pipeline.test.ts +176 -0
  307. package/tests/learning/playbook-extractor-provenance.test.ts +114 -0
  308. package/tests/learning/usage-inference.test.ts +254 -0
  309. package/tests/mcp/playbook-server.test.ts +252 -0
  310. package/tests/memory/experience.test.ts +198 -0
  311. package/tests/memory/playbook.test.ts +338 -0
  312. package/tests/memory/provenance.test.ts +639 -0
  313. package/tests/memory/system.test.ts +325 -0
  314. package/tests/runtime/agent-manager.test.ts +512 -0
  315. package/tests/runtime/mock-backend.test.ts +248 -0
  316. package/tests/search/refinement-loop.test.ts +468 -0
  317. package/tests/search/refinement.test.ts +267 -0
  318. package/tests/search/router.test.ts +427 -0
  319. package/tests/surfacing/skill-library.test.ts +292 -0
  320. package/tests/types/outcome.test.ts +147 -0
  321. package/tests/types/step.test.ts +133 -0
  322. package/tests/types/task.test.ts +158 -0
  323. package/tests/types/trajectory.test.ts +253 -0
  324. package/tests/utils/similarity.test.ts +188 -0
  325. package/tests/utils/validation.test.ts +252 -0
  326. package/tsconfig.json +25 -0
  327. package/vitest.config.ts +22 -0
  328. package/dist/index.d.mts +0 -466
  329. package/dist/index.mjs +0 -478
@@ -0,0 +1,493 @@
1
+ /**
2
+ * Playbook Library - Unified store for adaptive guidance
3
+ * Replaces StrategyBank + SkillStore with a single, evolvable abstraction
4
+ */
5
+
6
+ import type {
7
+ Playbook,
8
+ PlaybookOrigin,
9
+ FailureRecord,
10
+ Refinement,
11
+ } from '../types/index.js';
12
+ import { createPlaybook, bumpPlaybookVersion } from '../types/index.js';
13
+ import { JsonStore } from '../utils/storage.js';
14
+ import { textSimilarity } from '../utils/similarity.js';
15
+
16
+ /**
17
+ * Match result for playbook retrieval
18
+ */
19
+ export interface PlaybookMatch {
20
+ playbook: Playbook;
21
+ score: number;
22
+ matchType: 'situation' | 'trigger' | 'domain';
23
+ }
24
+
25
+ /**
26
+ * Options for finding matching playbooks
27
+ */
28
+ export interface FindMatchingOptions {
29
+ k?: number;
30
+ domains?: string[];
31
+ minConfidence?: number;
32
+ excludeAntiPatterns?: boolean;
33
+ minScore?: number;
34
+ }
35
+
36
+ /**
37
+ * Playbook Library - Store and retrieve adaptive guidance
38
+ */
39
+ export class PlaybookLibrary {
40
+ private store: JsonStore<Playbook>;
41
+ private initialized = false;
42
+
43
+ constructor(baseDir: string) {
44
+ this.store = new JsonStore<Playbook>(baseDir, 'playbooks', {
45
+ autoSaveInterval: 60000,
46
+ pretty: true,
47
+ });
48
+ }
49
+
50
+ async init(): Promise<void> {
51
+ if (this.initialized) return;
52
+ await this.store.init();
53
+ this.initialized = true;
54
+ }
55
+
56
+ // === RETRIEVAL ===
57
+
58
+ /**
59
+ * Find playbooks matching a context
60
+ * Uses weighted scoring across situations, triggers, and anti-patterns
61
+ */
62
+ async findMatching(
63
+ context: string,
64
+ options?: FindMatchingOptions
65
+ ): Promise<PlaybookMatch[]> {
66
+ await this.init();
67
+
68
+ const k = options?.k ?? 5;
69
+ let playbooks = this.store.values();
70
+
71
+ // Filter by domains if specified
72
+ if (options?.domains && options.domains.length > 0) {
73
+ playbooks = playbooks.filter((p) =>
74
+ p.applicability.domains.some((d) => options.domains!.includes(d))
75
+ );
76
+ }
77
+
78
+ // Filter by minimum confidence
79
+ if (options?.minConfidence !== undefined) {
80
+ playbooks = playbooks.filter((p) => p.confidence >= options.minConfidence!);
81
+ }
82
+
83
+ // Score playbooks
84
+ const scored: PlaybookMatch[] = [];
85
+
86
+ for (const playbook of playbooks) {
87
+ // Check anti-patterns first (if enabled)
88
+ if (options?.excludeAntiPatterns !== false) {
89
+ const antiPatternMatch = playbook.applicability.antiPatterns.some(
90
+ (ap) => textSimilarity(context, ap) > 0.7
91
+ );
92
+ if (antiPatternMatch) continue;
93
+ }
94
+
95
+ // Score against situations
96
+ const situationScores = playbook.applicability.situations.map((s) =>
97
+ textSimilarity(context, s)
98
+ );
99
+ const maxSituationScore =
100
+ situationScores.length > 0 ? Math.max(...situationScores) : 0;
101
+
102
+ // Score against triggers (weighted higher for exact matches)
103
+ const triggerScores = playbook.applicability.triggers.map((t) =>
104
+ textSimilarity(context, t)
105
+ );
106
+ const maxTriggerScore =
107
+ triggerScores.length > 0 ? Math.max(...triggerScores) * 1.2 : 0;
108
+
109
+ // Combine scores
110
+ const score = Math.max(maxSituationScore, maxTriggerScore);
111
+ const matchType: 'situation' | 'trigger' =
112
+ maxTriggerScore > maxSituationScore ? 'trigger' : 'situation';
113
+
114
+ if (score > 0) {
115
+ scored.push({ playbook, score, matchType });
116
+ }
117
+ }
118
+
119
+ // Sort by score and return top k
120
+ scored.sort((a, b) => b.score - a.score);
121
+ const results = scored.slice(0, k);
122
+
123
+ // Apply minimum score filter
124
+ if (options?.minScore !== undefined) {
125
+ return results.filter((r) => r.score >= options.minScore!);
126
+ }
127
+
128
+ return results;
129
+ }
130
+
131
+ /**
132
+ * Find by specific trigger (for error messages, etc.)
133
+ */
134
+ async findByTrigger(trigger: string, threshold = 0.5): Promise<Playbook[]> {
135
+ await this.init();
136
+
137
+ return this.store.values().filter((playbook) =>
138
+ playbook.applicability.triggers.some(
139
+ (t) =>
140
+ t.toLowerCase().includes(trigger.toLowerCase()) ||
141
+ textSimilarity(trigger, t) >= threshold
142
+ )
143
+ );
144
+ }
145
+
146
+ /**
147
+ * Get playbooks with refinements for a specific context
148
+ */
149
+ async findWithRefinements(context: string): Promise<Playbook[]> {
150
+ await this.init();
151
+
152
+ return this.store.values().filter((playbook) =>
153
+ playbook.evolution.refinements.some(
154
+ (r) => textSimilarity(context, r.context) > 0.6
155
+ )
156
+ );
157
+ }
158
+
159
+ // === EVOLUTION ===
160
+
161
+ /**
162
+ * Record successful application
163
+ */
164
+ async recordSuccess(id: string, _trajectoryId: string): Promise<void> {
165
+ await this.init();
166
+ const playbook = this.store.get(id);
167
+ if (!playbook) return;
168
+
169
+ playbook.evolution.successCount++;
170
+ playbook.evolution.lastUsed = new Date();
171
+
172
+ // Increase confidence (exponential moving average)
173
+ const alpha = 0.1;
174
+ playbook.confidence = playbook.confidence * (1 - alpha) + 1 * alpha;
175
+ playbook.confidence = Math.min(playbook.confidence, 0.99); // Cap at 0.99
176
+
177
+ playbook.updatedAt = new Date();
178
+ this.store.set(id, playbook);
179
+ await this.store.save(id);
180
+ }
181
+
182
+ /**
183
+ * Record failure and capture context
184
+ */
185
+ async recordFailure(
186
+ id: string,
187
+ trajectoryId: string,
188
+ failureContext: string,
189
+ failureMode: string
190
+ ): Promise<void> {
191
+ await this.init();
192
+ const playbook = this.store.get(id);
193
+ if (!playbook) return;
194
+
195
+ playbook.evolution.failureCount++;
196
+ playbook.evolution.lastUsed = new Date();
197
+
198
+ // Add failure record
199
+ const failure: FailureRecord = {
200
+ trajectoryId,
201
+ context: failureContext,
202
+ failureMode,
203
+ timestamp: new Date(),
204
+ };
205
+ playbook.evolution.failures.push(failure);
206
+
207
+ // Keep only last 10 failures
208
+ if (playbook.evolution.failures.length > 10) {
209
+ playbook.evolution.failures = playbook.evolution.failures.slice(-10);
210
+ }
211
+
212
+ // Decrease confidence
213
+ const alpha = 0.15; // Failures have slightly more impact
214
+ playbook.confidence = playbook.confidence * (1 - alpha) + 0 * alpha;
215
+ playbook.confidence = Math.max(playbook.confidence, 0.1); // Floor at 0.1
216
+
217
+ playbook.updatedAt = new Date();
218
+ this.store.set(id, playbook);
219
+ await this.store.save(id);
220
+ }
221
+
222
+ /**
223
+ * Add a context-specific refinement
224
+ */
225
+ async addRefinement(
226
+ id: string,
227
+ context: string,
228
+ addition: string,
229
+ source: 'failure' | 'success' | 'manual'
230
+ ): Promise<void> {
231
+ await this.init();
232
+ const playbook = this.store.get(id);
233
+ if (!playbook) return;
234
+
235
+ // Check if similar refinement exists
236
+ const exists = playbook.evolution.refinements.some(
237
+ (r) => textSimilarity(r.context, context) > 0.85
238
+ );
239
+ if (exists) return;
240
+
241
+ const refinement: Refinement = {
242
+ context,
243
+ addition,
244
+ source,
245
+ addedAt: new Date(),
246
+ };
247
+
248
+ playbook.evolution.refinements.push(refinement);
249
+
250
+ // Bump patch version
251
+ playbook.evolution.version = bumpPlaybookVersion(playbook, 'patch');
252
+ playbook.updatedAt = new Date();
253
+
254
+ this.store.set(id, playbook);
255
+ await this.store.save(id);
256
+ }
257
+
258
+ /**
259
+ * Evolve playbook based on accumulated failures
260
+ * Should be called after several failures to update guidance
261
+ */
262
+ async evolve(
263
+ id: string,
264
+ newGuidance?: Partial<Playbook['guidance']>,
265
+ newAntiPatterns?: string[]
266
+ ): Promise<Playbook | undefined> {
267
+ await this.init();
268
+ const playbook = this.store.get(id);
269
+ if (!playbook) return undefined;
270
+
271
+ // Update guidance if provided
272
+ if (newGuidance) {
273
+ playbook.guidance = { ...playbook.guidance, ...newGuidance };
274
+ }
275
+
276
+ // Add new anti-patterns
277
+ if (newAntiPatterns) {
278
+ const unique = newAntiPatterns.filter(
279
+ (ap) => !playbook.applicability.antiPatterns.includes(ap)
280
+ );
281
+ playbook.applicability.antiPatterns.push(...unique);
282
+ }
283
+
284
+ // Bump minor version for evolution
285
+ playbook.evolution.version = bumpPlaybookVersion(playbook, 'minor');
286
+ playbook.updatedAt = new Date();
287
+
288
+ this.store.set(id, playbook);
289
+ await this.store.save(id);
290
+
291
+ return playbook;
292
+ }
293
+
294
+ // === LIFECYCLE ===
295
+
296
+ /**
297
+ * Add a new playbook
298
+ */
299
+ async add(playbook: Playbook): Promise<void> {
300
+ await this.init();
301
+ this.store.set(playbook.id, playbook);
302
+ await this.store.save(playbook.id);
303
+ }
304
+
305
+ /**
306
+ * Create and add a new playbook
307
+ */
308
+ async create(
309
+ input: Parameters<typeof createPlaybook>[0]
310
+ ): Promise<Playbook> {
311
+ const playbook = createPlaybook(input);
312
+ await this.add(playbook);
313
+ return playbook;
314
+ }
315
+
316
+ /**
317
+ * Get a playbook by ID
318
+ */
319
+ async get(id: string): Promise<Playbook | undefined> {
320
+ await this.init();
321
+ return this.store.get(id);
322
+ }
323
+
324
+ /**
325
+ * Get playbook by name
326
+ */
327
+ async getByName(name: string): Promise<Playbook | undefined> {
328
+ await this.init();
329
+ return this.store.values().find((p) => p.name === name);
330
+ }
331
+
332
+ /**
333
+ * Check if a similar playbook exists
334
+ */
335
+ async exists(
336
+ description: string,
337
+ threshold = 0.85
338
+ ): Promise<Playbook | undefined> {
339
+ await this.init();
340
+
341
+ // Check by exact name match
342
+ const byName = this.store.values().find(
343
+ (p) => p.name === description.toLowerCase().replace(/\s+/g, '-')
344
+ );
345
+ if (byName) return byName;
346
+
347
+ // Check by situation similarity
348
+ for (const playbook of this.store.values()) {
349
+ for (const situation of playbook.applicability.situations) {
350
+ if (textSimilarity(description, situation) >= threshold) {
351
+ return playbook;
352
+ }
353
+ }
354
+ }
355
+
356
+ return undefined;
357
+ }
358
+
359
+ /**
360
+ * Get playbooks by domain
361
+ */
362
+ async getByDomain(domain: string): Promise<Playbook[]> {
363
+ await this.init();
364
+ return this.store.values().filter((p) =>
365
+ p.applicability.domains.includes(domain)
366
+ );
367
+ }
368
+
369
+ /**
370
+ * Get most effective playbooks (by success rate)
371
+ */
372
+ async getMostEffective(k = 10): Promise<Playbook[]> {
373
+ await this.init();
374
+ return this.store
375
+ .values()
376
+ .filter((p) => p.evolution.successCount + p.evolution.failureCount >= 3)
377
+ .sort((a, b) => {
378
+ const rateA =
379
+ a.evolution.successCount /
380
+ (a.evolution.successCount + a.evolution.failureCount);
381
+ const rateB =
382
+ b.evolution.successCount /
383
+ (b.evolution.successCount + b.evolution.failureCount);
384
+ return rateB - rateA;
385
+ })
386
+ .slice(0, k);
387
+ }
388
+
389
+ /**
390
+ * Get playbooks by confidence threshold
391
+ */
392
+ async getHighConfidence(minConfidence = 0.8): Promise<Playbook[]> {
393
+ await this.init();
394
+ return this.store.values().filter((p) => p.confidence >= minConfidence);
395
+ }
396
+
397
+ /**
398
+ * Get all playbooks
399
+ */
400
+ async getAll(): Promise<Playbook[]> {
401
+ await this.init();
402
+ return this.store.values();
403
+ }
404
+
405
+ /**
406
+ * Delete a playbook
407
+ */
408
+ async delete(id: string): Promise<boolean> {
409
+ await this.init();
410
+ const existed = this.store.has(id);
411
+ if (existed) {
412
+ this.store.delete(id);
413
+ }
414
+ return existed;
415
+ }
416
+
417
+ /**
418
+ * Get count
419
+ */
420
+ async count(): Promise<number> {
421
+ await this.init();
422
+ return this.store.size();
423
+ }
424
+
425
+ /**
426
+ * Get all unique domains
427
+ */
428
+ async getDomains(): Promise<string[]> {
429
+ await this.init();
430
+ const domains = new Set<string>();
431
+ for (const playbook of this.store.values()) {
432
+ for (const domain of playbook.applicability.domains) {
433
+ domains.add(domain);
434
+ }
435
+ }
436
+ return Array.from(domains);
437
+ }
438
+
439
+ // === PROVENANCE ===
440
+
441
+ /**
442
+ * Get playbooks by origin type
443
+ */
444
+ async getByOrigin(origin: PlaybookOrigin): Promise<Playbook[]> {
445
+ await this.init();
446
+ return this.store.values().filter((p) => p.provenance?.origin === origin);
447
+ }
448
+
449
+ /**
450
+ * Delete all playbooks with a specific origin
451
+ * Returns the number of playbooks deleted
452
+ */
453
+ async deleteByOrigin(origin: PlaybookOrigin): Promise<number> {
454
+ await this.init();
455
+ const toDelete = this.store.values().filter((p) => p.provenance?.origin === origin);
456
+ for (const playbook of toDelete) {
457
+ this.store.delete(playbook.id);
458
+ }
459
+ return toDelete.length;
460
+ }
461
+
462
+ /**
463
+ * Get provenance summary across all playbooks
464
+ */
465
+ async getProvenanceSummary(): Promise<Record<PlaybookOrigin, number>> {
466
+ await this.init();
467
+ const summary: Record<string, number> = {
468
+ extracted: 0,
469
+ curated: 0,
470
+ imported: 0,
471
+ manual: 0,
472
+ };
473
+ for (const playbook of this.store.values()) {
474
+ const origin = playbook.provenance?.origin ?? 'extracted';
475
+ summary[origin] = (summary[origin] ?? 0) + 1;
476
+ }
477
+ return summary as Record<PlaybookOrigin, number>;
478
+ }
479
+
480
+ /**
481
+ * Close the store
482
+ */
483
+ async close(): Promise<void> {
484
+ await this.store.close();
485
+ }
486
+ }
487
+
488
+ /**
489
+ * Create a playbook library
490
+ */
491
+ export function createPlaybookLibrary(baseDir: string): PlaybookLibrary {
492
+ return new PlaybookLibrary(baseDir);
493
+ }