skill-tree 0.1.1 → 0.1.3

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/dist/index.js CHANGED
@@ -42,7 +42,6 @@ __export(index_exports, {
42
42
  BaseStorageAdapter: () => BaseStorageAdapter,
43
43
  BatchProcessor: () => BatchProcessor,
44
44
  ClaudeCodeAdapter: () => ClaudeCodeAdapter,
45
- CognitiveCoreProvider: () => CognitiveCoreProvider,
46
45
  ConflictStore: () => ConflictStore,
47
46
  DEFAULT_ACTIVATION_CONFIG: () => DEFAULT_ACTIVATION_CONFIG,
48
47
  DEFAULT_AGENTS_CONFIG: () => DEFAULT_AGENTS_CONFIG,
@@ -61,7 +60,6 @@ __export(index_exports, {
61
60
  MemoryMetricsStorage: () => MemoryMetricsStorage,
62
61
  MemoryStorageAdapter: () => MemoryStorageAdapter,
63
62
  MetricsTracker: () => MetricsTracker,
64
- NaiveLearningProvider: () => NaiveLearningProvider,
65
63
  OpenAIAdapter: () => OpenAIAdapter,
66
64
  OpenAIEmbedding: () => OpenAIEmbedding,
67
65
  ProjectDetector: () => ProjectDetector,
@@ -94,7 +92,6 @@ __export(index_exports, {
94
92
  createAgentsParser: () => createAgentsParser,
95
93
  createAgentsSync: () => createAgentsSync,
96
94
  createBackupHook: () => createBackupHook,
97
- createCognitiveCoreProvider: () => createCognitiveCoreProvider,
98
95
  createConflictStore: () => createConflictStore,
99
96
  createDefaultSyncConfig: () => createDefaultSyncConfig,
100
97
  createExtractionEnrichmentHook: () => createExtractionEnrichmentHook,
@@ -105,7 +102,6 @@ __export(index_exports, {
105
102
  createMcpServer: () => createMcpServer,
106
103
  createMetricsHook: () => createMetricsHook,
107
104
  createMetricsTracker: () => createMetricsTracker,
108
- createNaiveProvider: () => createNaiveProvider,
109
105
  createQualityBypassHook: () => createQualityBypassHook,
110
106
  createQualityLoggingHook: () => createQualityLoggingHook,
111
107
  createSaveValidationHook: () => createSaveValidationHook,
@@ -115,6 +111,7 @@ __export(index_exports, {
115
111
  createToolHandlers: () => createToolHandlers,
116
112
  debuggingProfile: () => debuggingProfile,
117
113
  devopsProfile: () => devopsProfile,
114
+ discoverSkills: () => discoverSkills,
118
115
  documentationProfile: () => documentationProfile,
119
116
  euclideanDistance: () => euclideanDistance,
120
117
  executeToolCall: () => executeToolCall,
@@ -125,6 +122,7 @@ __export(index_exports, {
125
122
  getLatestVersion: () => getLatestVersion,
126
123
  getToolDefinition: () => getToolDefinition,
127
124
  getToolNames: () => getToolNames,
125
+ hasSkilltreeDir: () => hasSkilltreeDir,
128
126
  hookRegistry: () => hookRegistry,
129
127
  implementationProfile: () => implementationProfile,
130
128
  importFromAgentsMd: () => importFromAgentsMd,
@@ -845,11 +843,76 @@ var LoadoutCompiler = class {
845
843
  // src/serving/project-detector.ts
846
844
  var import_fs = require("fs");
847
845
  var import_path = require("path");
848
- var _ProjectDetector = class _ProjectDetector {
846
+ var ProjectDetector = class _ProjectDetector {
849
847
  constructor() {
850
848
  /** Cache for project context */
851
849
  this.cache = /* @__PURE__ */ new Map();
852
850
  }
851
+ static {
852
+ /** Project type patterns */
853
+ this.PROJECT_TYPES = [
854
+ { manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
855
+ { manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
856
+ { manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
857
+ { manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
858
+ { manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
859
+ { manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
860
+ { manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
861
+ { manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
862
+ ];
863
+ }
864
+ static {
865
+ /** TypeScript detection */
866
+ this.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
867
+ }
868
+ static {
869
+ /** Node.js framework patterns */
870
+ this.NODE_FRAMEWORKS = [
871
+ { name: "react", packageName: "react", tags: ["react", "frontend"] },
872
+ { name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
873
+ { name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
874
+ { name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
875
+ { name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
876
+ { name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
877
+ { name: "express", packageName: "express", tags: ["express", "backend", "api"] },
878
+ { name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
879
+ { name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
880
+ { name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
881
+ { name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
882
+ { name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
883
+ { name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
884
+ { name: "jest", packageName: "jest", tags: ["testing", "jest"] },
885
+ { name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
886
+ { name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
887
+ { name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
888
+ ];
889
+ }
890
+ static {
891
+ /** Python framework patterns (from pyproject.toml or requirements.txt) */
892
+ this.PYTHON_FRAMEWORKS = [
893
+ { name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
894
+ { name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
895
+ { name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
896
+ { name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
897
+ { name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
898
+ { name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
899
+ ];
900
+ }
901
+ static {
902
+ /** Directory patterns */
903
+ this.DIRECTORY_PATTERNS = [
904
+ { pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
905
+ { pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
906
+ { pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
907
+ { pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
908
+ { pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
909
+ { pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
910
+ { pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
911
+ { pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
912
+ { pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
913
+ { pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
914
+ ];
915
+ }
853
916
  /**
854
917
  * Detect project context from a directory
855
918
  */
@@ -1011,62 +1074,6 @@ var _ProjectDetector = class _ProjectDetector {
1011
1074
  }
1012
1075
  }
1013
1076
  };
1014
- /** Project type patterns */
1015
- _ProjectDetector.PROJECT_TYPES = [
1016
- { manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
1017
- { manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
1018
- { manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
1019
- { manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
1020
- { manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
1021
- { manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
1022
- { manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
1023
- { manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
1024
- ];
1025
- /** TypeScript detection */
1026
- _ProjectDetector.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
1027
- /** Node.js framework patterns */
1028
- _ProjectDetector.NODE_FRAMEWORKS = [
1029
- { name: "react", packageName: "react", tags: ["react", "frontend"] },
1030
- { name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
1031
- { name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
1032
- { name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
1033
- { name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
1034
- { name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
1035
- { name: "express", packageName: "express", tags: ["express", "backend", "api"] },
1036
- { name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
1037
- { name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
1038
- { name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
1039
- { name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
1040
- { name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
1041
- { name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
1042
- { name: "jest", packageName: "jest", tags: ["testing", "jest"] },
1043
- { name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
1044
- { name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
1045
- { name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
1046
- ];
1047
- /** Python framework patterns (from pyproject.toml or requirements.txt) */
1048
- _ProjectDetector.PYTHON_FRAMEWORKS = [
1049
- { name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
1050
- { name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
1051
- { name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
1052
- { name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
1053
- { name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
1054
- { name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
1055
- ];
1056
- /** Directory patterns */
1057
- _ProjectDetector.DIRECTORY_PATTERNS = [
1058
- { pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
1059
- { pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
1060
- { pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
1061
- { pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
1062
- { pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
1063
- { pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
1064
- { pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
1065
- { pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
1066
- { pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
1067
- { pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
1068
- ];
1069
- var ProjectDetector = _ProjectDetector;
1070
1077
 
1071
1078
  // src/serving/view-renderer.ts
1072
1079
  var DEFAULT_CONFIG2 = {
@@ -6521,10 +6528,7 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
6521
6528
  this.skills = /* @__PURE__ */ new Map();
6522
6529
  // skillId -> version -> skill
6523
6530
  this.lineages = /* @__PURE__ */ new Map();
6524
- this.candidates = /* @__PURE__ */ new Map();
6525
- this.antiPatterns = /* @__PURE__ */ new Map();
6526
6531
  }
6527
- // skillId -> patterns
6528
6532
  async initialize() {
6529
6533
  this.initialized = true;
6530
6534
  }
@@ -6655,78 +6659,6 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
6655
6659
  clear() {
6656
6660
  this.skills.clear();
6657
6661
  this.lineages.clear();
6658
- this.candidates.clear();
6659
- this.antiPatterns.clear();
6660
- }
6661
- // ==========================================================================
6662
- // Learning Candidate Operations
6663
- // ==========================================================================
6664
- async saveCandidate(candidate) {
6665
- this.ensureInitialized();
6666
- this.candidates.set(candidate.id, { ...candidate });
6667
- }
6668
- async getCandidate(id) {
6669
- this.ensureInitialized();
6670
- return this.candidates.get(id) || null;
6671
- }
6672
- async listCandidates(filter) {
6673
- this.ensureInitialized();
6674
- let results = Array.from(this.candidates.values());
6675
- if (filter) {
6676
- if (filter.kind && filter.kind.length > 0) {
6677
- results = results.filter((c) => filter.kind.includes(c.kind));
6678
- }
6679
- if (filter.status && filter.status.length > 0) {
6680
- results = results.filter((c) => filter.status.includes(c.status));
6681
- }
6682
- if (filter.minConfidence !== void 0) {
6683
- results = results.filter((c) => c.confidence >= filter.minConfidence);
6684
- }
6685
- if (filter.createdAfter) {
6686
- results = results.filter((c) => c.createdAt >= filter.createdAfter);
6687
- }
6688
- if (filter.createdBefore) {
6689
- results = results.filter((c) => c.createdAt <= filter.createdBefore);
6690
- }
6691
- }
6692
- return results;
6693
- }
6694
- async updateCandidateStatus(id, status, details) {
6695
- this.ensureInitialized();
6696
- const candidate = this.candidates.get(id);
6697
- if (!candidate) return false;
6698
- candidate.status = status;
6699
- candidate.updatedAt = /* @__PURE__ */ new Date();
6700
- if (details?.promotedToSkillId) {
6701
- candidate.promotedToSkillId = details.promotedToSkillId;
6702
- }
6703
- if (details?.rejectionReason) {
6704
- candidate.rejectionReason = details.rejectionReason;
6705
- }
6706
- return true;
6707
- }
6708
- async deleteCandidate(id) {
6709
- this.ensureInitialized();
6710
- return this.candidates.delete(id);
6711
- }
6712
- // ==========================================================================
6713
- // Anti-Pattern Operations
6714
- // ==========================================================================
6715
- async saveAntiPatterns(skillId, patterns) {
6716
- this.ensureInitialized();
6717
- this.antiPatterns.set(skillId, [...patterns]);
6718
- }
6719
- async getAntiPatterns(skillId) {
6720
- this.ensureInitialized();
6721
- return this.antiPatterns.get(skillId) || [];
6722
- }
6723
- async listAntiPatterns() {
6724
- this.ensureInitialized();
6725
- const results = [];
6726
- for (const [skillId, patterns] of this.antiPatterns) {
6727
- results.push({ skillId, patterns });
6728
- }
6729
- return results;
6730
6662
  }
6731
6663
  // ==========================================================================
6732
6664
  // Fork Tracking
@@ -7277,152 +7209,6 @@ ${body}`;
7277
7209
  return Math.abs(hash).toString(16);
7278
7210
  }
7279
7211
  // ==========================================================================
7280
- // Learning Candidate Operations
7281
- // ==========================================================================
7282
- get candidatesDir() {
7283
- return path4.join(this.skilltreeDir, "candidates");
7284
- }
7285
- get antiPatternsDir() {
7286
- return path4.join(this.skilltreeDir, "anti-patterns");
7287
- }
7288
- async saveCandidate(candidate) {
7289
- this.ensureInitialized();
7290
- await fs4.mkdir(this.candidatesDir, { recursive: true });
7291
- const candidatePath = path4.join(this.candidatesDir, `${candidate.id}.json`);
7292
- await fs4.writeFile(candidatePath, JSON.stringify(candidate, null, 2), "utf-8");
7293
- }
7294
- async getCandidate(id) {
7295
- this.ensureInitialized();
7296
- const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
7297
- try {
7298
- const content = await fs4.readFile(candidatePath, "utf-8");
7299
- const candidate = JSON.parse(content);
7300
- candidate.createdAt = new Date(candidate.createdAt);
7301
- candidate.updatedAt = new Date(candidate.updatedAt);
7302
- candidate.source.extractedAt = new Date(candidate.source.extractedAt);
7303
- return candidate;
7304
- } catch (error) {
7305
- if (error.code === "ENOENT") {
7306
- return null;
7307
- }
7308
- throw error;
7309
- }
7310
- }
7311
- async listCandidates(filter) {
7312
- this.ensureInitialized();
7313
- try {
7314
- const files = await fs4.readdir(this.candidatesDir);
7315
- const candidates = [];
7316
- for (const file of files) {
7317
- if (!file.endsWith(".json")) continue;
7318
- const id = file.replace(".json", "");
7319
- const candidate = await this.getCandidate(id);
7320
- if (candidate) {
7321
- candidates.push(candidate);
7322
- }
7323
- }
7324
- let results = candidates;
7325
- if (filter) {
7326
- if (filter.kind && filter.kind.length > 0) {
7327
- results = results.filter((c) => filter.kind.includes(c.kind));
7328
- }
7329
- if (filter.status && filter.status.length > 0) {
7330
- results = results.filter((c) => filter.status.includes(c.status));
7331
- }
7332
- if (filter.minConfidence !== void 0) {
7333
- results = results.filter((c) => c.confidence >= filter.minConfidence);
7334
- }
7335
- if (filter.createdAfter) {
7336
- results = results.filter((c) => c.createdAt >= filter.createdAfter);
7337
- }
7338
- if (filter.createdBefore) {
7339
- results = results.filter((c) => c.createdAt <= filter.createdBefore);
7340
- }
7341
- }
7342
- return results;
7343
- } catch (error) {
7344
- if (error.code === "ENOENT") {
7345
- return [];
7346
- }
7347
- throw error;
7348
- }
7349
- }
7350
- async updateCandidateStatus(id, status, details) {
7351
- this.ensureInitialized();
7352
- const candidate = await this.getCandidate(id);
7353
- if (!candidate) return false;
7354
- candidate.status = status;
7355
- candidate.updatedAt = /* @__PURE__ */ new Date();
7356
- if (details?.promotedToSkillId) {
7357
- candidate.promotedToSkillId = details.promotedToSkillId;
7358
- }
7359
- if (details?.rejectionReason) {
7360
- candidate.rejectionReason = details.rejectionReason;
7361
- }
7362
- await this.saveCandidate(candidate);
7363
- return true;
7364
- }
7365
- async deleteCandidate(id) {
7366
- this.ensureInitialized();
7367
- const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
7368
- try {
7369
- await fs4.unlink(candidatePath);
7370
- return true;
7371
- } catch (error) {
7372
- if (error.code === "ENOENT") {
7373
- return false;
7374
- }
7375
- throw error;
7376
- }
7377
- }
7378
- // ==========================================================================
7379
- // Anti-Pattern Operations
7380
- // ==========================================================================
7381
- async saveAntiPatterns(skillId, patterns) {
7382
- this.ensureInitialized();
7383
- await fs4.mkdir(this.antiPatternsDir, { recursive: true });
7384
- const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
7385
- await fs4.writeFile(patternPath, JSON.stringify(patterns, null, 2), "utf-8");
7386
- }
7387
- async getAntiPatterns(skillId) {
7388
- this.ensureInitialized();
7389
- const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
7390
- try {
7391
- const content = await fs4.readFile(patternPath, "utf-8");
7392
- const patterns = JSON.parse(content);
7393
- for (const pattern of patterns) {
7394
- pattern.learnedAt = new Date(pattern.learnedAt);
7395
- }
7396
- return patterns;
7397
- } catch (error) {
7398
- if (error.code === "ENOENT") {
7399
- return [];
7400
- }
7401
- throw error;
7402
- }
7403
- }
7404
- async listAntiPatterns() {
7405
- this.ensureInitialized();
7406
- try {
7407
- const files = await fs4.readdir(this.antiPatternsDir);
7408
- const results = [];
7409
- for (const file of files) {
7410
- if (!file.endsWith(".json")) continue;
7411
- const skillId = file.replace(".json", "");
7412
- const patterns = await this.getAntiPatterns(skillId);
7413
- if (patterns.length > 0) {
7414
- results.push({ skillId, patterns });
7415
- }
7416
- }
7417
- return results;
7418
- } catch (error) {
7419
- if (error.code === "ENOENT") {
7420
- return [];
7421
- }
7422
- throw error;
7423
- }
7424
- }
7425
- // ==========================================================================
7426
7212
  // Fork Tracking
7427
7213
  // ==========================================================================
7428
7214
  async recordFork(sourceSkillId, fork) {
@@ -8225,8 +8011,6 @@ async function migrateStorage(source, target, options = {}) {
8225
8011
  const opts = {
8226
8012
  skills: options.skills ?? true,
8227
8013
  lineage: options.lineage ?? true,
8228
- candidates: options.candidates ?? true,
8229
- antiPatterns: options.antiPatterns ?? true,
8230
8014
  onProgress: options.onProgress ?? (() => {
8231
8015
  }),
8232
8016
  overwrite: options.overwrite ?? false
@@ -8238,9 +8022,7 @@ async function migrateStorage(source, target, options = {}) {
8238
8022
  errors: 0,
8239
8023
  details: {
8240
8024
  skills: { migrated: 0, skipped: 0, errors: 0 },
8241
- lineages: { migrated: 0, skipped: 0, errors: 0 },
8242
- candidates: { migrated: 0, skipped: 0, errors: 0 },
8243
- antiPatterns: { migrated: 0, skipped: 0, errors: 0 }
8025
+ lineages: { migrated: 0, skipped: 0, errors: 0 }
8244
8026
  }
8245
8027
  };
8246
8028
  if (opts.skills) {
@@ -8249,12 +8031,6 @@ async function migrateStorage(source, target, options = {}) {
8249
8031
  if (opts.lineage) {
8250
8032
  await migrateLineages(source, target, opts, result);
8251
8033
  }
8252
- if (opts.candidates) {
8253
- await migrateCandidates(source, target, opts, result);
8254
- }
8255
- if (opts.antiPatterns) {
8256
- await migrateAntiPatterns(source, target, opts, result);
8257
- }
8258
8034
  return result;
8259
8035
  }
8260
8036
  async function migrateSkills(source, target, opts, result) {
@@ -8320,65 +8096,6 @@ async function migrateLineages(source, target, opts, result) {
8320
8096
  }
8321
8097
  }
8322
8098
  }
8323
- async function migrateCandidates(source, target, opts, result) {
8324
- if (!source.listCandidates || !target.saveCandidate) {
8325
- return;
8326
- }
8327
- const candidates = await source.listCandidates();
8328
- for (const candidate of candidates) {
8329
- result.totalProcessed++;
8330
- try {
8331
- if (!opts.overwrite && target.getCandidate) {
8332
- const existing = await target.getCandidate(candidate.id);
8333
- if (existing) {
8334
- result.skipped++;
8335
- result.details.candidates.skipped++;
8336
- opts.onProgress({ type: "candidate", id: candidate.id, status: "skipped" });
8337
- continue;
8338
- }
8339
- }
8340
- await target.saveCandidate(candidate);
8341
- result.migrated++;
8342
- result.details.candidates.migrated++;
8343
- opts.onProgress({ type: "candidate", id: candidate.id, status: "migrated" });
8344
- } catch (error) {
8345
- result.errors++;
8346
- result.details.candidates.errors++;
8347
- opts.onProgress({
8348
- type: "candidate",
8349
- id: candidate.id,
8350
- status: "error",
8351
- error: error instanceof Error ? error.message : String(error)
8352
- });
8353
- }
8354
- }
8355
- }
8356
- async function migrateAntiPatterns(source, target, opts, result) {
8357
- if (!source.getAntiPatterns || !target.saveAntiPatterns) {
8358
- return;
8359
- }
8360
- const skills = await source.listSkills();
8361
- for (const skill of skills) {
8362
- try {
8363
- const patterns = await source.getAntiPatterns(skill.id);
8364
- if (!patterns || patterns.length === 0) continue;
8365
- result.totalProcessed++;
8366
- await target.saveAntiPatterns(skill.id, patterns);
8367
- result.migrated++;
8368
- result.details.antiPatterns.migrated++;
8369
- opts.onProgress({ type: "anti-pattern", id: skill.id, status: "migrated" });
8370
- } catch (error) {
8371
- result.errors++;
8372
- result.details.antiPatterns.errors++;
8373
- opts.onProgress({
8374
- type: "anti-pattern",
8375
- id: skill.id,
8376
- status: "error",
8377
- error: error instanceof Error ? error.message : String(error)
8378
- });
8379
- }
8380
- }
8381
- }
8382
8099
 
8383
8100
  // src/versioning/lineage.ts
8384
8101
  var LineageTracker = class {
@@ -9151,387 +8868,80 @@ function createSkillMerger(storage, config) {
9151
8868
  return new SkillMerger(storage, config);
9152
8869
  }
9153
8870
 
9154
- // src/learning/providers/naive.ts
9155
- var NaiveLearningProvider = class {
9156
- constructor(config) {
9157
- this.name = "naive";
9158
- this.description = "Built-in extraction using heuristics and optional LLM analysis";
9159
- this.capabilities = {
9160
- accumulating: false,
9161
- feedbackEnabled: false,
9162
- persistent: false,
9163
- supportedKinds: ["skill", "strategy", "pattern", "error-fix"]
9164
- };
9165
- this.config = {
9166
- llmProvider: config?.llmProvider ?? null,
9167
- minConfidence: config?.minConfidence ?? 0.6,
9168
- runQualityGates: config?.runQualityGates ?? true,
9169
- creditStrategy: config?.creditStrategy ?? "simple"
9170
- };
9171
- this.manualExtractor = new ManualExtractor();
9172
- this.automaticExtractor = new AutomaticExtractor({
9173
- llmProvider: this.config.llmProvider || void 0,
9174
- minConfidence: this.config.minConfidence
9175
- });
8871
+ // src/hooks/registry.ts
8872
+ var import_crypto = require("crypto");
8873
+ var PRIORITY_ORDER = {
8874
+ high: 0,
8875
+ normal: 1,
8876
+ low: 2
8877
+ };
8878
+ var HookRegistry = class {
8879
+ constructor() {
8880
+ this.hooks = /* @__PURE__ */ new Map();
8881
+ this.eventIndex = /* @__PURE__ */ new Map();
9176
8882
  }
9177
8883
  /**
9178
- * Set or update the LLM provider
8884
+ * Register a new hook
9179
8885
  */
9180
- setLLMProvider(provider) {
9181
- this.config.llmProvider = provider;
9182
- this.automaticExtractor.setLLMProvider(provider);
8886
+ register(options) {
8887
+ const id = (0, import_crypto.randomUUID)();
8888
+ const events = Array.isArray(options.events) ? options.events : [options.events];
8889
+ const hook = {
8890
+ id,
8891
+ name: options.name,
8892
+ events,
8893
+ handler: options.handler,
8894
+ priority: options.priority || "normal",
8895
+ enabled: options.enabled !== false,
8896
+ filter: options.filter
8897
+ };
8898
+ this.hooks.set(id, hook);
8899
+ for (const event of events) {
8900
+ if (!this.eventIndex.has(event)) {
8901
+ this.eventIndex.set(event, /* @__PURE__ */ new Set());
8902
+ }
8903
+ this.eventIndex.get(event).add(id);
8904
+ }
8905
+ return id;
9183
8906
  }
9184
8907
  /**
9185
- * Analyze a trajectory and extract learning candidates
8908
+ * Unregister a hook
9186
8909
  */
9187
- async analyze(trajectory, options) {
9188
- const startTime = Date.now();
9189
- const candidates = [];
9190
- const kinds = options?.kinds ?? ["skill"];
9191
- const useAutomatic = this.config.llmProvider != null;
9192
- let results;
9193
- if (useAutomatic) {
9194
- results = await this.automaticExtractor.extract(trajectory, {
9195
- turnRange: options?.turnRange,
9196
- minConfidence: options?.minConfidence ?? this.config.minConfidence,
9197
- skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
9198
- context: options?.context
9199
- });
9200
- } else {
9201
- results = await this.manualExtractor.extract(trajectory, {
9202
- turnRange: options?.turnRange,
9203
- skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
9204
- context: options?.context
9205
- });
9206
- }
9207
- for (const result of results) {
9208
- if (!result.success || !result.skill) continue;
9209
- const kind = this.inferKind(result.skill);
9210
- if (!kinds.includes(kind)) continue;
9211
- const candidate = this.extractionResultToCandidate(result, trajectory);
9212
- candidates.push(candidate);
8910
+ unregister(hookId) {
8911
+ const hook = this.hooks.get(hookId);
8912
+ if (!hook) return false;
8913
+ for (const event of hook.events) {
8914
+ this.eventIndex.get(event)?.delete(hookId);
9213
8915
  }
9214
- return {
9215
- candidates,
9216
- // Naive provider doesn't produce updates, demotions, or anti-patterns
9217
- metadata: {
9218
- trajectoriesAnalyzed: 1,
9219
- durationMs: Date.now() - startTime
9220
- }
9221
- };
8916
+ this.hooks.delete(hookId);
8917
+ return true;
9222
8918
  }
9223
8919
  /**
9224
- * Batch analysis - runs individual analysis on each trajectory.
9225
- * A more sophisticated provider could do cross-trajectory pattern detection.
8920
+ * Enable a hook
9226
8921
  */
9227
- async analyzeBatch(trajectories, options) {
9228
- const startTime = Date.now();
9229
- const allCandidates = [];
9230
- for (const trajectory of trajectories) {
9231
- const result = await this.analyze(trajectory, options);
9232
- allCandidates.push(...result.candidates);
9233
- }
9234
- const deduplicated = this.deduplicateCandidates(allCandidates);
9235
- return {
9236
- candidates: deduplicated,
9237
- metadata: {
9238
- trajectoriesAnalyzed: trajectories.length,
9239
- durationMs: Date.now() - startTime
9240
- }
9241
- };
8922
+ enable(hookId) {
8923
+ const hook = this.hooks.get(hookId);
8924
+ if (!hook) return false;
8925
+ hook.enabled = true;
8926
+ return true;
9242
8927
  }
9243
8928
  /**
9244
- * Check if a candidate is a duplicate based on name/content similarity
8929
+ * Disable a hook
9245
8930
  */
9246
- isDuplicate(candidate, existing) {
9247
- if (existing.some((e) => e.id === candidate.id)) {
9248
- return true;
9249
- }
9250
- const normalizedName = this.normalizeName(candidate.name);
9251
- for (const e of existing) {
9252
- if (this.normalizeName(e.name) === normalizedName) {
9253
- return true;
9254
- }
9255
- }
9256
- return false;
8931
+ disable(hookId) {
8932
+ const hook = this.hooks.get(hookId);
8933
+ if (!hook) return false;
8934
+ hook.enabled = false;
8935
+ return true;
9257
8936
  }
9258
8937
  /**
9259
- * Compute similarity between two candidates (basic implementation)
8938
+ * Get a hook by ID
9260
8939
  */
9261
- computeSimilarity(a, b) {
9262
- if (a.kind !== b.kind) return 0.1;
9263
- const nameA = this.normalizeName(a.name);
9264
- const nameB = this.normalizeName(b.name);
9265
- const nameSimilarity = this.jaccardSimilarity(
9266
- nameA.split("-"),
9267
- nameB.split("-")
9268
- );
9269
- let contentSimilarity = 0;
9270
- if (a.content.kind === "skill" && b.content.kind === "skill") {
9271
- const aWords = this.tokenize(a.content.problem + " " + a.content.solution);
9272
- const bWords = this.tokenize(b.content.problem + " " + b.content.solution);
9273
- contentSimilarity = this.jaccardSimilarity(aWords, bWords);
9274
- }
9275
- return nameSimilarity * 0.3 + contentSimilarity * 0.7;
8940
+ get(hookId) {
8941
+ return this.hooks.get(hookId);
9276
8942
  }
9277
- // ==========================================================================
9278
- // Private Methods
9279
- // ==========================================================================
9280
8943
  /**
9281
- * Convert an ExtractionResult to a LearningCandidate
9282
- */
9283
- extractionResultToCandidate(result, trajectory) {
9284
- const skill = result.skill;
9285
- const turnRange = result.sourceTrajectory.turnRange;
9286
- return {
9287
- kind: this.inferKind(skill),
9288
- id: skill.id,
9289
- name: skill.name,
9290
- content: this.skillToContent(skill),
9291
- confidence: result.confidence,
9292
- attribution: this.computeAttribution(trajectory, turnRange),
9293
- source: {
9294
- provider: this.name,
9295
- trajectoryId: trajectory.sessionId,
9296
- turnRange,
9297
- extractedAt: /* @__PURE__ */ new Date(),
9298
- metadata: {
9299
- gateResults: result.gateResults,
9300
- extractionMode: this.config.llmProvider ? "automatic" : "manual"
9301
- }
9302
- },
9303
- tags: skill.tags,
9304
- reasoning: result.failureReason
9305
- };
9306
- }
9307
- /**
9308
- * Convert a Skill to LearningContent
9309
- */
9310
- skillToContent(skill) {
9311
- return {
9312
- kind: "skill",
9313
- problem: skill.problem,
9314
- solution: skill.solution,
9315
- verification: skill.verification,
9316
- triggers: skill.triggerConditions.map(
9317
- (t) => ({
9318
- type: t.type,
9319
- value: t.value,
9320
- description: t.description
9321
- })
9322
- ),
9323
- examples: skill.examples.map(
9324
- (e) => ({
9325
- scenario: e.scenario,
9326
- before: e.before,
9327
- after: e.after
9328
- })
9329
- )
9330
- };
9331
- }
9332
- /**
9333
- * Infer the kind of learning from a skill
9334
- */
9335
- inferKind(skill) {
9336
- const hasErrorTriggers = skill.triggerConditions.some(
9337
- (t) => t.type === "error"
9338
- );
9339
- if (hasErrorTriggers && skill.problem.toLowerCase().includes("error")) {
9340
- return "error-fix";
9341
- }
9342
- if (skill.solution.toLowerCase().includes("approach") || skill.solution.toLowerCase().includes("strategy") || skill.solution.toLowerCase().includes("when you see")) {
9343
- return "strategy";
9344
- }
9345
- return "skill";
9346
- }
9347
- /**
9348
- * Compute step attribution using the configured strategy
9349
- */
9350
- computeAttribution(trajectory, turnRange) {
9351
- const [start, end] = turnRange;
9352
- const turns = trajectory.turns.slice(start, end + 1);
9353
- switch (this.config.creditStrategy) {
9354
- case "simple":
9355
- return this.simpleCredit(turns, start);
9356
- case "uniform":
9357
- return this.uniformCredit(turns, start);
9358
- case "llm":
9359
- return this.simpleCredit(turns, start);
9360
- default:
9361
- return this.simpleCredit(turns, start);
9362
- }
9363
- }
9364
- /**
9365
- * Simple credit assignment: exponential decay from end.
9366
- * Last step gets most credit, earlier steps get less.
9367
- */
9368
- simpleCredit(turns, startOffset) {
9369
- const attributions = [];
9370
- const n = turns.length;
9371
- for (let i = 0; i < n; i++) {
9372
- const turn = turns[i];
9373
- if (turn.role === "system") continue;
9374
- const distanceFromEnd = n - 1 - i;
9375
- const score = Math.pow(0.7, distanceFromEnd);
9376
- const hasToolCalls = turn.toolCalls && turn.toolCalls.length > 0;
9377
- const boostedScore = hasToolCalls ? Math.min(1, score * 1.3) : score;
9378
- attributions.push({
9379
- turnIndex: startOffset + i,
9380
- score: Math.round(boostedScore * 100) / 100,
9381
- reasoning: this.getAttributionReasoning(turn, boostedScore)
9382
- });
9383
- }
9384
- return attributions;
9385
- }
9386
- /**
9387
- * Uniform credit assignment: all steps get equal credit.
9388
- */
9389
- uniformCredit(turns, startOffset) {
9390
- const nonSystemTurns = turns.filter((t) => t.role !== "system");
9391
- const score = 1 / nonSystemTurns.length;
9392
- return turns.map((turn, i) => {
9393
- if (turn.role === "system") return null;
9394
- return {
9395
- turnIndex: startOffset + i,
9396
- score: Math.round(score * 100) / 100
9397
- };
9398
- }).filter((a) => a !== null);
9399
- }
9400
- /**
9401
- * Generate reasoning for attribution
9402
- */
9403
- getAttributionReasoning(turn, score) {
9404
- const reasons = [];
9405
- if (score >= 0.8) {
9406
- reasons.push("High impact (near end of solution)");
9407
- } else if (score >= 0.5) {
9408
- reasons.push("Medium impact");
9409
- } else {
9410
- reasons.push("Lower impact (early in trajectory)");
9411
- }
9412
- if (turn.toolCalls && turn.toolCalls.length > 0) {
9413
- const toolNames = turn.toolCalls.map((t) => t.name).join(", ");
9414
- reasons.push(`Used tools: ${toolNames}`);
9415
- }
9416
- if (turn.toolResults?.some((r) => !r.success)) {
9417
- reasons.push("Encountered and handled errors");
9418
- }
9419
- return reasons.join(". ");
9420
- }
9421
- /**
9422
- * Deduplicate candidates by ID
9423
- */
9424
- deduplicateCandidates(candidates) {
9425
- const seen = /* @__PURE__ */ new Map();
9426
- for (const candidate of candidates) {
9427
- const existing = seen.get(candidate.id);
9428
- if (!existing || candidate.confidence > existing.confidence) {
9429
- seen.set(candidate.id, candidate);
9430
- }
9431
- }
9432
- return Array.from(seen.values());
9433
- }
9434
- /**
9435
- * Normalize a name for comparison
9436
- */
9437
- normalizeName(name) {
9438
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
9439
- }
9440
- /**
9441
- * Tokenize text into words
9442
- */
9443
- tokenize(text) {
9444
- return text.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
9445
- }
9446
- /**
9447
- * Compute Jaccard similarity between two arrays
9448
- */
9449
- jaccardSimilarity(a, b) {
9450
- const setA = new Set(a);
9451
- const setB = new Set(b);
9452
- const intersection = new Set([...setA].filter((x) => setB.has(x)));
9453
- const union = /* @__PURE__ */ new Set([...setA, ...setB]);
9454
- return union.size === 0 ? 0 : intersection.size / union.size;
9455
- }
9456
- };
9457
- function createNaiveProvider(config) {
9458
- return new NaiveLearningProvider(config);
9459
- }
9460
-
9461
- // src/hooks/registry.ts
9462
- var import_crypto = require("crypto");
9463
- var PRIORITY_ORDER = {
9464
- high: 0,
9465
- normal: 1,
9466
- low: 2
9467
- };
9468
- var HookRegistry = class {
9469
- constructor() {
9470
- this.hooks = /* @__PURE__ */ new Map();
9471
- this.eventIndex = /* @__PURE__ */ new Map();
9472
- }
9473
- /**
9474
- * Register a new hook
9475
- */
9476
- register(options) {
9477
- const id = (0, import_crypto.randomUUID)();
9478
- const events = Array.isArray(options.events) ? options.events : [options.events];
9479
- const hook = {
9480
- id,
9481
- name: options.name,
9482
- events,
9483
- handler: options.handler,
9484
- priority: options.priority || "normal",
9485
- enabled: options.enabled !== false,
9486
- filter: options.filter
9487
- };
9488
- this.hooks.set(id, hook);
9489
- for (const event of events) {
9490
- if (!this.eventIndex.has(event)) {
9491
- this.eventIndex.set(event, /* @__PURE__ */ new Set());
9492
- }
9493
- this.eventIndex.get(event).add(id);
9494
- }
9495
- return id;
9496
- }
9497
- /**
9498
- * Unregister a hook
9499
- */
9500
- unregister(hookId) {
9501
- const hook = this.hooks.get(hookId);
9502
- if (!hook) return false;
9503
- for (const event of hook.events) {
9504
- this.eventIndex.get(event)?.delete(hookId);
9505
- }
9506
- this.hooks.delete(hookId);
9507
- return true;
9508
- }
9509
- /**
9510
- * Enable a hook
9511
- */
9512
- enable(hookId) {
9513
- const hook = this.hooks.get(hookId);
9514
- if (!hook) return false;
9515
- hook.enabled = true;
9516
- return true;
9517
- }
9518
- /**
9519
- * Disable a hook
9520
- */
9521
- disable(hookId) {
9522
- const hook = this.hooks.get(hookId);
9523
- if (!hook) return false;
9524
- hook.enabled = false;
9525
- return true;
9526
- }
9527
- /**
9528
- * Get a hook by ID
9529
- */
9530
- get(hookId) {
9531
- return this.hooks.get(hookId);
9532
- }
9533
- /**
9534
- * List all registered hooks
8944
+ * List all registered hooks
9535
8945
  */
9536
8946
  list() {
9537
8947
  return Array.from(this.hooks.values());
@@ -9930,10 +9340,6 @@ var SkillBank = class {
9930
9340
  this.eventHandlers = [];
9931
9341
  this.initialized = false;
9932
9342
  this.autoIndexOnInit = false;
9933
- /** Learning providers for meta-learning integration */
9934
- this.learningProviders = /* @__PURE__ */ new Map();
9935
- /** Anti-patterns stored separately as metadata */
9936
- this.antiPatterns = /* @__PURE__ */ new Map();
9937
9343
  /** Validation mode: advisory (non-blocking) or blocking */
9938
9344
  this.validationMode = "advisory";
9939
9345
  /** Whether validation is enabled */
@@ -9971,11 +9377,6 @@ var SkillBank = class {
9971
9377
  similarityThreshold: config.matching?.similarityThreshold
9972
9378
  });
9973
9379
  this.autoIndexOnInit = config.matching?.autoIndex ?? false;
9974
- const naiveProvider = new NaiveLearningProvider({
9975
- llmProvider: config.llmProvider,
9976
- minConfidence: config.minExtractionConfidence
9977
- });
9978
- this.learningProviders.set(naiveProvider.name, naiveProvider);
9979
9380
  if (config.namespace) {
9980
9381
  this.namespaceConfig = {
9981
9382
  agentId: config.namespace.agentId,
@@ -10003,11 +9404,6 @@ var SkillBank = class {
10003
9404
  */
10004
9405
  async initialize() {
10005
9406
  await this.storage.initialize();
10006
- for (const provider of this.learningProviders.values()) {
10007
- if (provider.initialize) {
10008
- await provider.initialize();
10009
- }
10010
- }
10011
9407
  if (this.validator) {
10012
9408
  this.validator.setStorage(this.storage);
10013
9409
  }
@@ -10020,11 +9416,6 @@ var SkillBank = class {
10020
9416
  * Shutdown the skill bank cleanly
10021
9417
  */
10022
9418
  async shutdown() {
10023
- for (const provider of this.learningProviders.values()) {
10024
- if (provider.shutdown) {
10025
- await provider.shutdown();
10026
- }
10027
- }
10028
9419
  }
10029
9420
  /**
10030
9421
  * Ensure initialized before operations
@@ -10121,630 +9512,67 @@ var SkillBank = class {
10121
9512
  /**
10122
9513
  * Extract skills automatically from a trajectory
10123
9514
  */
10124
- async extractAutomatic(trajectory, options) {
10125
- this.ensureInitialized();
10126
- this.emit({ type: "extraction:started", sessionId: trajectory.sessionId });
10127
- const results = await this.automaticExtractor.extract(trajectory, options);
10128
- for (const result of results) {
10129
- if (result.success && result.skill) {
10130
- const duplicate = await this.findSemanticDuplicate(result.skill);
10131
- if (duplicate) {
10132
- result.success = false;
10133
- result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;
10134
- } else {
10135
- await this.storage.saveSkill(result.skill);
10136
- this.emit({ type: "skill:created", skill: result.skill });
10137
- }
10138
- }
10139
- this.emit({ type: "extraction:completed", result });
10140
- }
10141
- return results;
10142
- }
10143
- /**
10144
- * Unified extraction entry point.
10145
- *
10146
- * Supports both manual (targeted) and automatic (LLM-driven) extraction
10147
- * from a Trajectory. Use this instead of calling extractManual/extractAutomatic
10148
- * directly.
10149
- *
10150
- * @example
10151
- * ```typescript
10152
- * // Manual extraction with defaults
10153
- * const results = await bank.extract(trajectory);
10154
- *
10155
- * // Automatic extraction
10156
- * const results = await bank.extract(trajectory, { mode: 'automatic' });
10157
- *
10158
- * // Manual with specific turn range
10159
- * const results = await bank.extract(trajectory, {
10160
- * mode: 'manual',
10161
- * turnRange: [0, 5],
10162
- * suggestedName: 'fix-auth-error',
10163
- * });
10164
- * ```
10165
- */
10166
- async extract(trajectory, options) {
10167
- if (options?.mode === "automatic") {
10168
- return this.extractAutomatic(trajectory, options);
10169
- }
10170
- const result = await this.extractManual(trajectory, options);
10171
- return [result];
10172
- }
10173
- /**
10174
- * Extract from raw session content (convenience method)
10175
- */
10176
- async extractFromSession(content, options) {
10177
- const trajectory = await this.parseSession(content, options?.adapterName);
10178
- return this.extract(trajectory, options);
10179
- }
10180
- /**
10181
- * Set LLM provider for automatic extraction
10182
- */
10183
- setLLMProvider(provider) {
10184
- this.automaticExtractor.setLLMProvider(provider);
10185
- const naiveProvider = this.learningProviders.get("naive");
10186
- if (naiveProvider && "setLLMProvider" in naiveProvider) {
10187
- naiveProvider.setLLMProvider(provider);
10188
- }
10189
- }
10190
- // ==========================================================================
10191
- // Learning Providers (Meta-learning Integration)
10192
- // ==========================================================================
10193
- /**
10194
- * Register a learning provider.
10195
- * Learning providers analyze trajectories and produce learning candidates.
10196
- * Use this to integrate external learning engines like cognitive-core.
10197
- */
10198
- async registerLearningProvider(provider) {
10199
- if (provider.initialize) {
10200
- await provider.initialize();
10201
- }
10202
- this.learningProviders.set(provider.name, provider);
10203
- }
10204
- /**
10205
- * Get a registered learning provider by name
10206
- */
10207
- getLearningProvider(name) {
10208
- return this.learningProviders.get(name);
10209
- }
10210
- /**
10211
- * List all registered learning providers
10212
- */
10213
- listLearningProviders() {
10214
- return Array.from(this.learningProviders.values());
10215
- }
10216
- /**
10217
- * Learn from a trajectory using a learning provider.
10218
- * This is the primary integration point for meta-learning engines.
10219
- *
10220
- * For accumulating providers, this may not return immediate results.
10221
- * Use flushProviders() to force extraction from accumulated trajectories.
10222
- */
10223
- async learnFrom(trajectory, options) {
10224
- this.ensureInitialized();
10225
- const providerName = options?.provider ?? "naive";
10226
- const provider = this.learningProviders.get(providerName);
10227
- if (!provider) {
10228
- throw new Error(
10229
- `Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
10230
- );
10231
- }
10232
- const result = await provider.analyze(trajectory, options);
10233
- return this.processAnalyzeResult(result);
10234
- }
10235
- /**
10236
- * Learn from multiple trajectories.
10237
- * Providers that support batch analysis can find cross-trajectory patterns.
10238
- */
10239
- async learnFromBatch(trajectories, options) {
10240
- this.ensureInitialized();
10241
- const providerName = options?.provider ?? "naive";
10242
- const provider = this.learningProviders.get(providerName);
10243
- if (!provider) {
10244
- throw new Error(`Learning provider not found: ${providerName}`);
10245
- }
10246
- let result;
10247
- if (provider.analyzeBatch) {
10248
- result = await provider.analyzeBatch(trajectories, options);
10249
- } else {
10250
- const candidates = [];
10251
- const updates = [];
10252
- const demotions = [];
10253
- const antiPatterns = [];
10254
- let totalDuration = 0;
10255
- for (const trajectory of trajectories) {
10256
- const r = await provider.analyze(trajectory, options);
10257
- candidates.push(...r.candidates);
10258
- if (r.updates) updates.push(...r.updates);
10259
- if (r.demotions) demotions.push(...r.demotions);
10260
- if (r.antiPatterns) antiPatterns.push(...r.antiPatterns);
10261
- totalDuration += r.metadata.durationMs;
10262
- }
10263
- result = {
10264
- candidates,
10265
- updates: updates.length > 0 ? updates : void 0,
10266
- demotions: demotions.length > 0 ? demotions : void 0,
10267
- antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
10268
- metadata: {
10269
- trajectoriesAnalyzed: trajectories.length,
10270
- durationMs: totalDuration
10271
- }
10272
- };
10273
- }
10274
- return this.processAnalyzeResult(result);
10275
- }
10276
- /**
10277
- * Force extraction from all accumulating providers.
10278
- */
10279
- async flushProviders() {
10280
- this.ensureInitialized();
10281
- const mergedResult = {
10282
- skillsCreated: 0,
10283
- skillsUpdated: 0,
10284
- skillsDemoted: 0,
10285
- antiPatternsAdded: 0,
10286
- createdSkillIds: [],
10287
- updatedSkillIds: []
10288
- };
10289
- for (const provider of this.learningProviders.values()) {
10290
- if (provider.capabilities.accumulating && provider.flush) {
10291
- const result = await provider.flush();
10292
- const processed = await this.processAnalyzeResult(result);
10293
- mergedResult.skillsCreated += processed.skillsCreated;
10294
- mergedResult.skillsUpdated += processed.skillsUpdated;
10295
- mergedResult.skillsDemoted += processed.skillsDemoted;
10296
- mergedResult.antiPatternsAdded += processed.antiPatternsAdded;
10297
- mergedResult.createdSkillIds.push(...processed.createdSkillIds);
10298
- mergedResult.updatedSkillIds.push(...processed.updatedSkillIds);
10299
- }
10300
- }
10301
- return mergedResult;
10302
- }
10303
- /**
10304
- * Record outcome when a skill is applied.
10305
- * Provider updates internal state and returns updates for SkillBank.
10306
- */
10307
- async recordOutcome(feedback, providerName) {
10308
- this.ensureInitialized();
10309
- const skill = await this.storage.getSkill(feedback.candidateId);
10310
- if (skill) {
10311
- skill.metrics.usageCount++;
10312
- if (feedback.success) {
10313
- const totalUses = skill.metrics.usageCount;
10314
- const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
10315
- skill.metrics.successRate = (currentSuccesses + 1) / totalUses;
10316
- } else {
10317
- const totalUses = skill.metrics.usageCount;
10318
- const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
10319
- skill.metrics.successRate = currentSuccesses / totalUses;
10320
- }
10321
- skill.metrics.lastUsed = /* @__PURE__ */ new Date();
10322
- await this.storage.saveSkill(skill);
10323
- }
10324
- const providersToNotify = providerName ? [this.learningProviders.get(providerName)].filter(Boolean) : Array.from(this.learningProviders.values());
10325
- for (const provider of providersToNotify) {
10326
- if (provider.capabilities.feedbackEnabled && provider.recordOutcome) {
10327
- const result = await provider.recordOutcome(feedback);
10328
- if (result.updates) {
10329
- for (const update of result.updates) {
10330
- await this.applyUpdate(update);
10331
- }
10332
- }
10333
- if (result.antiPatterns) {
10334
- for (const ap of result.antiPatterns) {
10335
- await this.addAntiPattern(ap);
10336
- }
10337
- }
10338
- }
10339
- }
10340
- }
10341
- /**
10342
- * Process an AnalyzeResult: store candidates, apply updates, etc.
10343
- */
10344
- async processAnalyzeResult(result) {
10345
- const learnResult = {
10346
- skillsCreated: 0,
10347
- skillsUpdated: 0,
10348
- skillsDemoted: 0,
10349
- antiPatternsAdded: 0,
10350
- providerState: result.providerState,
10351
- createdSkillIds: [],
10352
- updatedSkillIds: []
10353
- };
10354
- for (const candidate of result.candidates) {
10355
- if (candidate.content.kind === "skill") {
10356
- const skill = await this.promoteToSkill(candidate);
10357
- learnResult.skillsCreated++;
10358
- learnResult.createdSkillIds.push(skill.id);
10359
- } else {
10360
- await this.storeCandidateForReview(candidate);
10361
- }
10362
- }
10363
- if (result.updates) {
10364
- for (const update of result.updates) {
10365
- const updated = await this.applyUpdate(update);
10366
- if (updated) {
10367
- learnResult.skillsUpdated++;
10368
- learnResult.updatedSkillIds.push(update.candidateId);
10369
- }
10370
- }
10371
- }
10372
- if (result.demotions) {
10373
- for (const demotion of result.demotions) {
10374
- await this.applyDemotion(demotion);
10375
- learnResult.skillsDemoted++;
10376
- }
10377
- }
10378
- if (result.antiPatterns) {
10379
- for (const ap of result.antiPatterns) {
10380
- await this.addAntiPattern(ap);
10381
- learnResult.antiPatternsAdded++;
10382
- }
10383
- }
10384
- return learnResult;
10385
- }
10386
- /**
10387
- * Store a non-skill candidate for later review
10388
- */
10389
- async storeCandidateForReview(candidate) {
10390
- if (!this.storage.saveCandidate) {
10391
- return;
10392
- }
10393
- const record = {
10394
- id: candidate.id,
10395
- kind: candidate.kind,
10396
- name: candidate.name,
10397
- content: candidate.content,
10398
- confidence: candidate.confidence,
10399
- source: {
10400
- trajectoryId: candidate.source.trajectoryId,
10401
- provider: candidate.source.provider,
10402
- extractedAt: candidate.source.extractedAt,
10403
- turnRange: candidate.source.turnRange
10404
- },
10405
- tags: candidate.tags,
10406
- reasoning: candidate.reasoning,
10407
- createdAt: /* @__PURE__ */ new Date(),
10408
- updatedAt: /* @__PURE__ */ new Date(),
10409
- status: "pending"
10410
- };
10411
- await this.storage.saveCandidate(record);
10412
- }
10413
- /**
10414
- * Apply an update to an existing skill
10415
- */
10416
- async applyUpdate(update) {
10417
- const skill = await this.storage.getSkill(update.candidateId);
10418
- if (!skill) return false;
10419
- let modified = false;
10420
- if (update.addTrigger) {
10421
- const exists = skill.triggerConditions.some(
10422
- (t) => t.type === update.addTrigger.type && t.value === update.addTrigger.value
10423
- );
10424
- if (!exists) {
10425
- skill.triggerConditions.push({
10426
- type: update.addTrigger.type,
10427
- value: update.addTrigger.value,
10428
- description: update.addTrigger.description
10429
- });
10430
- modified = true;
10431
- }
10432
- }
10433
- if (update.refinement) {
10434
- const refinementNote = `[${update.refinement.source}] ${update.refinement.context}: ${update.refinement.addition}`;
10435
- skill.notes = skill.notes ? `${skill.notes}
10436
- ${refinementNote}` : refinementNote;
10437
- modified = true;
10438
- }
10439
- if (update.confidenceAdjustment) {
10440
- skill.metrics.successRate = Math.max(
10441
- 0,
10442
- Math.min(1, skill.metrics.successRate + update.confidenceAdjustment)
10443
- );
10444
- modified = true;
10445
- }
10446
- if (update.incrementSuccess || update.incrementFailure) {
10447
- skill.metrics.usageCount++;
10448
- if (update.incrementSuccess) {
10449
- const total = skill.metrics.usageCount;
10450
- const currentSuccesses = skill.metrics.successRate * (total - 1);
10451
- skill.metrics.successRate = (currentSuccesses + 1) / total;
10452
- }
10453
- modified = true;
10454
- }
10455
- if (modified) {
10456
- skill.updatedAt = /* @__PURE__ */ new Date();
10457
- await this.storage.saveSkill(skill);
10458
- this.emit({ type: "skill:updated", skill, previousVersion: skill.version });
10459
- }
10460
- return modified;
10461
- }
10462
- /**
10463
- * Apply a demotion to an existing skill
10464
- */
10465
- async applyDemotion(demotion) {
10466
- const skill = await this.storage.getSkill(demotion.candidateId);
10467
- if (!skill) return;
10468
- skill.metrics.successRate = demotion.newConfidence;
10469
- if (demotion.deprecate) {
10470
- skill.status = "deprecated";
10471
- this.emit({ type: "skill:deprecated", skillId: skill.id });
10472
- }
10473
- skill.notes = skill.notes ? `${skill.notes}
10474
- [demotion] ${demotion.reason}` : `[demotion] ${demotion.reason}`;
10475
- skill.updatedAt = /* @__PURE__ */ new Date();
10476
- await this.storage.saveSkill(skill);
10477
- }
10478
- // ==========================================================================
10479
- // Anti-Pattern Management
10480
- // ==========================================================================
10481
- /**
10482
- * Get anti-patterns for a skill
10483
- */
10484
- async getAntiPatterns(skillId) {
10485
- return this.antiPatterns.get(skillId) ?? [];
10486
- }
10487
- /**
10488
- * Add an anti-pattern
10489
- */
10490
- async addAntiPattern(antiPattern) {
10491
- const existing = this.antiPatterns.get(antiPattern.candidateId) ?? [];
10492
- existing.push(antiPattern);
10493
- this.antiPatterns.set(antiPattern.candidateId, existing);
10494
- if (this.storage.saveAntiPatterns) {
10495
- const records = existing.map((ap) => ({
10496
- id: ap.id,
10497
- pattern: ap.pattern,
10498
- description: ap.reason,
10499
- context: ap.discoveredFrom,
10500
- severity: "warning",
10501
- learnedAt: ap.createdAt,
10502
- occurrences: 1
10503
- }));
10504
- await this.storage.saveAntiPatterns(antiPattern.candidateId, records);
10505
- }
10506
- }
10507
- /**
10508
- * Remove an anti-pattern by ID
10509
- */
10510
- async removeAntiPattern(antiPatternId) {
10511
- for (const [skillId, patterns] of this.antiPatterns.entries()) {
10512
- const index = patterns.findIndex((p) => p.id === antiPatternId);
10513
- if (index >= 0) {
10514
- patterns.splice(index, 1);
10515
- if (patterns.length === 0) {
10516
- this.antiPatterns.delete(skillId);
10517
- }
10518
- return true;
10519
- }
10520
- }
10521
- return false;
10522
- }
10523
- // ==========================================================================
10524
- // Candidate Lifecycle Management
10525
- // ==========================================================================
10526
- /**
10527
- * List pending learning candidates for review
10528
- */
10529
- async listCandidates(filter) {
10530
- this.ensureInitialized();
10531
- if (!this.storage.listCandidates) {
10532
- return [];
10533
- }
10534
- return this.storage.listCandidates(filter);
10535
- }
10536
- /**
10537
- * Get a specific candidate by ID
10538
- */
10539
- async getCandidate(id) {
10540
- this.ensureInitialized();
10541
- if (!this.storage.getCandidate) {
10542
- return null;
10543
- }
10544
- return this.storage.getCandidate(id);
10545
- }
10546
- /**
10547
- * Promote a candidate to a skill
10548
- * Works for strategy, pattern, and error-fix candidates that were stored for review
10549
- */
10550
- async promoteCandidate(candidateId) {
10551
- this.ensureInitialized();
10552
- if (!this.storage.getCandidate || !this.storage.updateCandidateStatus) {
10553
- throw new Error("Storage does not support candidate operations");
10554
- }
10555
- const record = await this.storage.getCandidate(candidateId);
10556
- if (!record) return null;
10557
- if (record.status !== "pending") {
10558
- throw new Error(`Cannot promote candidate with status: ${record.status}`);
10559
- }
10560
- const candidate = {
10561
- id: record.id,
10562
- kind: record.kind,
10563
- name: record.name,
10564
- content: record.content,
10565
- confidence: record.confidence,
10566
- source: {
10567
- provider: record.source.provider,
10568
- trajectoryId: record.source.trajectoryId,
10569
- extractedAt: record.source.extractedAt,
10570
- turnRange: record.source.turnRange ?? [0, 0]
10571
- },
10572
- tags: record.tags,
10573
- reasoning: record.reasoning
10574
- };
10575
- const skill = await this.promoteToSkill(candidate);
10576
- await this.storage.updateCandidateStatus(candidateId, "promoted", {
10577
- promotedToSkillId: skill.id
10578
- });
10579
- return skill;
10580
- }
10581
- /**
10582
- * Reject a candidate with a reason
10583
- */
10584
- async rejectCandidate(candidateId, reason) {
10585
- this.ensureInitialized();
10586
- if (!this.storage.updateCandidateStatus) {
10587
- throw new Error("Storage does not support candidate operations");
10588
- }
10589
- return this.storage.updateCandidateStatus(candidateId, "rejected", {
10590
- rejectionReason: reason
10591
- });
10592
- }
10593
- /**
10594
- * Delete a candidate
10595
- */
10596
- async deleteCandidate(candidateId) {
10597
- this.ensureInitialized();
10598
- if (!this.storage.deleteCandidate) {
10599
- return false;
10600
- }
10601
- return this.storage.deleteCandidate(candidateId);
10602
- }
10603
- /**
10604
- * Find skills with anti-pattern awareness
10605
- */
10606
- async findSkillsWithAntiPatterns(query, options) {
9515
+ async extractAutomatic(trajectory, options) {
10607
9516
  this.ensureInitialized();
10608
- const skills = await this.storage.listSkills({ status: ["active"] });
10609
- const matches = await this.semanticMatcher.findMatches(query, skills, {
10610
- threshold: options?.minSimilarity,
10611
- maxResults: options?.maxResults
10612
- });
10613
- const results = [];
10614
- for (const match of matches) {
10615
- const skillAntiPatterns = await this.getAntiPatterns(match.skill.id);
10616
- const warnings = [];
10617
- let relevantAntiPatterns;
10618
- if (options?.context && skillAntiPatterns.length > 0) {
10619
- relevantAntiPatterns = skillAntiPatterns.filter(
10620
- (ap) => options.context.toLowerCase().includes(ap.pattern.toLowerCase())
10621
- );
10622
- if (relevantAntiPatterns.length > 0) {
10623
- warnings.push(
10624
- `This skill has failed in similar contexts: ${relevantAntiPatterns.map((ap) => ap.reason).join("; ")}`
10625
- );
9517
+ this.emit({ type: "extraction:started", sessionId: trajectory.sessionId });
9518
+ const results = await this.automaticExtractor.extract(trajectory, options);
9519
+ for (const result of results) {
9520
+ if (result.success && result.skill) {
9521
+ const duplicate = await this.findSemanticDuplicate(result.skill);
9522
+ if (duplicate) {
9523
+ result.success = false;
9524
+ result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;
9525
+ } else {
9526
+ await this.storage.saveSkill(result.skill);
9527
+ this.emit({ type: "skill:created", skill: result.skill });
10626
9528
  }
10627
9529
  }
10628
- if (options?.excludeAntiPatternMatches && relevantAntiPatterns && relevantAntiPatterns.length > 0) {
10629
- continue;
10630
- }
10631
- if (match.skill.metrics.successRate < 0.5 && match.skill.metrics.usageCount > 2) {
10632
- warnings.push(`Low success rate: ${Math.round(match.skill.metrics.successRate * 100)}%`);
10633
- }
10634
- results.push({
10635
- ...match,
10636
- relevantAntiPatterns: relevantAntiPatterns && relevantAntiPatterns.length > 0 ? relevantAntiPatterns : void 0,
10637
- warnings: warnings.length > 0 ? warnings : void 0
10638
- });
9530
+ this.emit({ type: "extraction:completed", result });
10639
9531
  }
10640
9532
  return results;
10641
9533
  }
10642
- // ==========================================================================
10643
- // Legacy Learning Methods (backwards compatibility)
10644
- // ==========================================================================
10645
9534
  /**
10646
- * Extract learning candidates from a trajectory using a learning provider.
10647
- * @deprecated Use learnFrom() instead
9535
+ * Unified extraction entry point.
9536
+ *
9537
+ * Supports both manual (targeted) and automatic (LLM-driven) extraction
9538
+ * from a Trajectory. Use this instead of calling extractManual/extractAutomatic
9539
+ * directly.
9540
+ *
9541
+ * @example
9542
+ * ```typescript
9543
+ * // Manual extraction with defaults
9544
+ * const results = await bank.extract(trajectory);
9545
+ *
9546
+ * // Automatic extraction
9547
+ * const results = await bank.extract(trajectory, { mode: 'automatic' });
9548
+ *
9549
+ * // Manual with specific turn range
9550
+ * const results = await bank.extract(trajectory, {
9551
+ * mode: 'manual',
9552
+ * turnRange: [0, 5],
9553
+ * suggestedName: 'fix-auth-error',
9554
+ * });
9555
+ * ```
10648
9556
  */
10649
- async extractLearnings(trajectory, options) {
10650
- this.ensureInitialized();
10651
- const providerName = options?.provider ?? "naive";
10652
- const provider = this.learningProviders.get(providerName);
10653
- if (!provider) {
10654
- throw new Error(
10655
- `Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
10656
- );
9557
+ async extract(trajectory, options) {
9558
+ if (options?.mode === "automatic") {
9559
+ return this.extractAutomatic(trajectory, options);
10657
9560
  }
10658
- const result = await provider.analyze(trajectory, options);
10659
- return result.candidates;
9561
+ const result = await this.extractManual(trajectory, options);
9562
+ return [result];
10660
9563
  }
10661
9564
  /**
10662
- * Extract learning candidates from multiple trajectories.
10663
- * @deprecated Use learnFromBatch() instead
9565
+ * Extract from raw session content (convenience method)
10664
9566
  */
10665
- async extractLearningsBatch(trajectories, options) {
10666
- this.ensureInitialized();
10667
- const providerName = options?.provider ?? "naive";
10668
- const provider = this.learningProviders.get(providerName);
10669
- if (!provider) {
10670
- throw new Error(`Learning provider not found: ${providerName}`);
10671
- }
10672
- if (provider.analyzeBatch) {
10673
- const result = await provider.analyzeBatch(trajectories, options);
10674
- return result.candidates;
10675
- }
10676
- const allCandidates = [];
10677
- for (const trajectory of trajectories) {
10678
- const result = await provider.analyze(trajectory, options);
10679
- allCandidates.push(...result.candidates);
10680
- }
10681
- return allCandidates;
9567
+ async extractFromSession(content, options) {
9568
+ const trajectory = await this.parseSession(content, options?.adapterName);
9569
+ return this.extract(trajectory, options);
10682
9570
  }
10683
9571
  /**
10684
- * Promote a learning candidate to a versioned skill.
10685
- * This converts the raw learning into a curated, versioned skill.
9572
+ * Set LLM provider for automatic extraction
10686
9573
  */
10687
- async promoteToSkill(candidate, options) {
10688
- this.ensureInitialized();
10689
- if (candidate.content.kind !== "skill") {
10690
- throw new Error(
10691
- `Cannot promote ${candidate.content.kind} to skill directly. Only 'skill' kind is supported.`
10692
- );
10693
- }
10694
- const agentId = this.activationManager.getCurrentAgentId();
10695
- const agentMetadata = this.activationManager.getAgentMetadata();
10696
- const agentName = agentMetadata?.agentName;
10697
- const content = candidate.content;
10698
- const skill = {
10699
- id: candidate.id,
10700
- name: candidate.name,
10701
- version: "1.0.0",
10702
- description: content.problem.substring(0, 150),
10703
- problem: content.problem,
10704
- triggerConditions: (content.triggers ?? []).map((t) => ({
10705
- type: t.type,
10706
- value: t.value,
10707
- description: t.description
10708
- })),
10709
- solution: content.solution,
10710
- verification: content.verification,
10711
- examples: (content.examples ?? []).map((e) => ({
10712
- scenario: e.scenario,
10713
- before: e.before,
10714
- after: e.after
10715
- })),
10716
- author: options?.author ?? agentName ?? candidate.source.provider,
10717
- tags: options?.tags ?? candidate.tags ?? [],
10718
- createdAt: /* @__PURE__ */ new Date(),
10719
- updatedAt: /* @__PURE__ */ new Date(),
10720
- status: options?.status ?? "draft",
10721
- metrics: {
10722
- usageCount: 0,
10723
- successRate: candidate.confidence,
10724
- feedbackScores: []
10725
- },
10726
- source: {
10727
- type: "extracted",
10728
- sessionId: candidate.source.trajectoryId,
10729
- importedAt: candidate.source.extractedAt,
10730
- agentId,
10731
- agentName
10732
- }
10733
- };
10734
- skill.serving = computeServingMetadata(skill);
10735
- await this.storage.saveSkill(skill);
10736
- this.emit({ type: "skill:created", skill });
10737
- if (this.validationEnabled && this.validator) {
10738
- this.runValidationAsync(skill).catch((err) => {
10739
- console.error("Validation error:", err);
10740
- });
10741
- }
10742
- if (this.compositionEnabled && this.composer) {
10743
- this.runCompositionSuggestionsAsync(skill).catch((err) => {
10744
- console.error("Composition suggestion error:", err);
10745
- });
10746
- }
10747
- return skill;
9574
+ setLLMProvider(provider) {
9575
+ this.automaticExtractor.setLLMProvider(provider);
10748
9576
  }
10749
9577
  /**
10750
9578
  * Validate a skill and store the result
@@ -11203,7 +10031,6 @@ ${refinementNote}` : refinementNote;
11203
10031
  const deleted = await this.storage.deleteSkill(id, version);
11204
10032
  if (deleted) {
11205
10033
  this.emit({ type: "skill:deleted", skillId: id });
11206
- this.antiPatterns.delete(id);
11207
10034
  }
11208
10035
  return deleted;
11209
10036
  }
@@ -11677,8 +10504,7 @@ ${refinementNote}` : refinementNote;
11677
10504
  },
11678
10505
  byTag: {},
11679
10506
  avgSuccessRate: 0,
11680
- totalUsage: 0,
11681
- totalAntiPatterns: 0
10507
+ totalUsage: 0
11682
10508
  };
11683
10509
  if (this.namespaceConfig) {
11684
10510
  stats.byScope = { personal: 0, team: 0, global: 0 };
@@ -11696,10 +10522,6 @@ ${refinementNote}` : refinementNote;
11696
10522
  successRateSum += skill.metrics.successRate;
11697
10523
  successRateCount++;
11698
10524
  }
11699
- const ap = this.antiPatterns.get(skill.id);
11700
- if (ap) {
11701
- stats.totalAntiPatterns += ap.length;
11702
- }
11703
10525
  if (stats.byScope && stats.byVisibility) {
11704
10526
  const scope = skill.namespace?.scope || "personal";
11705
10527
  const visibility = skill.namespace?.visibility || "private";
@@ -13909,486 +12731,6 @@ function conditionalHook(filter, handler) {
13909
12731
  };
13910
12732
  }
13911
12733
 
13912
- // src/learning/providers/cognitive-core.ts
13913
- var CognitiveCoreProvider = class {
13914
- constructor(options) {
13915
- this.name = "cognitive-core";
13916
- this.description = "Advanced learning using cognitive-core with batch extraction and feedback";
13917
- this.capabilities = {
13918
- accumulating: true,
13919
- feedbackEnabled: true,
13920
- persistent: true,
13921
- minTrajectories: 5,
13922
- supportedKinds: ["skill", "strategy", "pattern", "error-fix"]
13923
- };
13924
- this.initialized = false;
13925
- // ID mapping: playbook.id <-> candidate.id
13926
- // For cognitive-core, we use playbook.id as the candidate.id directly
13927
- this.playbookIdCache = /* @__PURE__ */ new Map();
13928
- this.factory = options.factory;
13929
- this.config = {
13930
- storagePath: options.storagePath ?? "./.cognitive-core",
13931
- minTrajectories: options.minTrajectories ?? 5,
13932
- deduplicationThreshold: options.deduplicationThreshold ?? 0.85,
13933
- creditStrategy: options.creditStrategy ?? "simple",
13934
- convertToReAct: options.convertToReAct ?? true
13935
- };
13936
- this.memory = this.factory.createMemorySystem(this.config.storagePath);
13937
- this.pipeline = this.factory.createLearningPipeline(this.memory, {
13938
- creditStrategy: this.config.creditStrategy,
13939
- minTrajectories: this.config.minTrajectories,
13940
- deduplicationThreshold: this.config.deduplicationThreshold
13941
- });
13942
- }
13943
- /**
13944
- * Initialize the provider (load persisted state)
13945
- */
13946
- async initialize() {
13947
- if (this.initialized) return;
13948
- await this.memory.init();
13949
- this.initialized = true;
13950
- }
13951
- /**
13952
- * Shutdown cleanly (persist state, release resources)
13953
- */
13954
- async shutdown() {
13955
- await this.memory.close();
13956
- this.initialized = false;
13957
- }
13958
- /**
13959
- * Analyze a trajectory and accumulate for batch learning.
13960
- * Returns empty candidates until flush() or batch threshold.
13961
- */
13962
- async analyze(trajectory, options) {
13963
- await this.initialize();
13964
- const startTime = Date.now();
13965
- const ccTrajectory = this.convertTrajectory(trajectory, options);
13966
- await this.pipeline.processTrajectory(ccTrajectory);
13967
- let candidates = [];
13968
- let updates = [];
13969
- let demotions = [];
13970
- let antiPatterns = [];
13971
- if (options?.forceImmediate || this.pipeline.shouldRunBatch()) {
13972
- const batchResult = await this.runBatchExtraction(options);
13973
- candidates = batchResult.candidates;
13974
- updates = batchResult.updates ?? [];
13975
- demotions = batchResult.demotions ?? [];
13976
- antiPatterns = batchResult.antiPatterns ?? [];
13977
- }
13978
- return {
13979
- candidates,
13980
- updates: updates.length > 0 ? updates : void 0,
13981
- demotions: demotions.length > 0 ? demotions : void 0,
13982
- antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
13983
- providerState: {
13984
- pendingCount: this.pipeline.getAccumulatedCount(),
13985
- readyForFlush: this.pipeline.shouldRunBatch()
13986
- },
13987
- metadata: {
13988
- trajectoriesAnalyzed: 1,
13989
- durationMs: Date.now() - startTime
13990
- }
13991
- };
13992
- }
13993
- /**
13994
- * Analyze multiple trajectories together.
13995
- * Enables better cross-trajectory pattern detection.
13996
- */
13997
- async analyzeBatch(trajectories, options) {
13998
- await this.initialize();
13999
- const startTime = Date.now();
14000
- for (const trajectory of trajectories) {
14001
- const ccTrajectory = this.convertTrajectory(trajectory, options);
14002
- await this.pipeline.processTrajectory(ccTrajectory);
14003
- }
14004
- const batchResult = await this.runBatchExtraction(options);
14005
- return {
14006
- candidates: batchResult.candidates,
14007
- updates: batchResult.updates,
14008
- demotions: batchResult.demotions,
14009
- antiPatterns: batchResult.antiPatterns,
14010
- providerState: {
14011
- pendingCount: this.pipeline.getAccumulatedCount(),
14012
- readyForFlush: this.pipeline.shouldRunBatch()
14013
- },
14014
- metadata: {
14015
- trajectoriesAnalyzed: trajectories.length,
14016
- durationMs: Date.now() - startTime
14017
- }
14018
- };
14019
- }
14020
- /**
14021
- * Force extraction from accumulated trajectories.
14022
- */
14023
- async flush(options) {
14024
- await this.initialize();
14025
- const startTime = Date.now();
14026
- const pendingCount = this.pipeline.getAccumulatedCount();
14027
- const batchResult = await this.runBatchExtraction(options);
14028
- return {
14029
- ...batchResult,
14030
- metadata: {
14031
- trajectoriesAnalyzed: pendingCount,
14032
- durationMs: Date.now() - startTime
14033
- }
14034
- };
14035
- }
14036
- /**
14037
- * Record outcome when a candidate/playbook is applied.
14038
- * Updates playbook confidence and may generate refinements.
14039
- */
14040
- async recordOutcome(feedback) {
14041
- await this.initialize();
14042
- const playbookId = feedback.candidateId;
14043
- const playbook = await this.memory.playbooks.get(playbookId);
14044
- if (!playbook) {
14045
- return { recorded: false };
14046
- }
14047
- await this.memory.recordPlaybookUsage(
14048
- playbookId,
14049
- feedback.trajectoryId,
14050
- feedback.success,
14051
- feedback.context,
14052
- feedback.failureMode
14053
- );
14054
- const updates = [];
14055
- const antiPatterns = [];
14056
- if (feedback.success) {
14057
- updates.push({
14058
- candidateId: playbookId,
14059
- incrementSuccess: true,
14060
- confidenceAdjustment: 0.05
14061
- // Slight boost on success
14062
- });
14063
- } else {
14064
- updates.push({
14065
- candidateId: playbookId,
14066
- incrementFailure: true,
14067
- confidenceAdjustment: -0.1
14068
- // Decrease confidence on failure
14069
- });
14070
- if (feedback.context || feedback.failureMode) {
14071
- antiPatterns.push({
14072
- id: `anti-${playbookId}-${Date.now()}`,
14073
- candidateId: playbookId,
14074
- pattern: feedback.context ?? "Unknown context",
14075
- reason: feedback.failureMode ?? "Unknown failure mode",
14076
- discoveredFrom: feedback.trajectoryId,
14077
- createdAt: /* @__PURE__ */ new Date()
14078
- });
14079
- }
14080
- }
14081
- return {
14082
- recorded: true,
14083
- updates: updates.length > 0 ? updates : void 0,
14084
- antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0
14085
- };
14086
- }
14087
- /**
14088
- * Check if a candidate is a duplicate based on playbook similarity
14089
- */
14090
- isDuplicate(candidate, existing) {
14091
- if (existing.some((e) => e.id === candidate.id)) {
14092
- return true;
14093
- }
14094
- for (const e of existing) {
14095
- const similarity = this.computeSimilarity(candidate, e);
14096
- if (similarity > this.config.deduplicationThreshold) {
14097
- return true;
14098
- }
14099
- }
14100
- return false;
14101
- }
14102
- /**
14103
- * Compute similarity between two candidates
14104
- */
14105
- computeSimilarity(a, b) {
14106
- if (a.kind !== b.kind) return 0.1;
14107
- const nameA = this.tokenize(a.name);
14108
- const nameB = this.tokenize(b.name);
14109
- const nameSimilarity = this.jaccardSimilarity(nameA, nameB);
14110
- let contentSimilarity = 0;
14111
- if (a.content.kind === "skill" && b.content.kind === "skill") {
14112
- const aWords = this.tokenize(a.content.problem + " " + a.content.solution);
14113
- const bWords = this.tokenize(b.content.problem + " " + b.content.solution);
14114
- contentSimilarity = this.jaccardSimilarity(aWords, bWords);
14115
- }
14116
- return nameSimilarity * 0.3 + contentSimilarity * 0.7;
14117
- }
14118
- // ==========================================================================
14119
- // Private Methods
14120
- // ==========================================================================
14121
- /**
14122
- * Run batch extraction and convert results to LearningCandidates
14123
- */
14124
- async runBatchExtraction(options) {
14125
- await this.pipeline.runBatchLearning();
14126
- const allPlaybooks = await this.memory.playbooks.getAll();
14127
- const candidates = [];
14128
- const updates = [];
14129
- const demotions = [];
14130
- const antiPatterns = [];
14131
- const minConfidence = options?.minConfidence ?? 0;
14132
- const requestedKinds = options?.kinds;
14133
- for (const playbook of allPlaybooks) {
14134
- if (!this.playbookIdCache.has(playbook.id)) {
14135
- const candidate = this.playbookToCandidate(playbook);
14136
- if (candidate.confidence < minConfidence) {
14137
- continue;
14138
- }
14139
- if (requestedKinds && !requestedKinds.includes(candidate.kind)) {
14140
- continue;
14141
- }
14142
- candidates.push(candidate);
14143
- this.playbookIdCache.set(playbook.id, true);
14144
- }
14145
- const successRate = playbook.evolution.successCount + playbook.evolution.failureCount > 0 ? playbook.evolution.successCount / (playbook.evolution.successCount + playbook.evolution.failureCount) : 1;
14146
- if (successRate < 0.3 && playbook.evolution.successCount + playbook.evolution.failureCount >= 3) {
14147
- demotions.push({
14148
- candidateId: playbook.id,
14149
- reason: `Low success rate: ${Math.round(successRate * 100)}%`,
14150
- newConfidence: successRate,
14151
- deprecate: successRate < 0.1
14152
- });
14153
- }
14154
- for (const antiPattern of playbook.applicability.antiPatterns) {
14155
- antiPatterns.push({
14156
- id: `anti-${playbook.id}-${antiPattern.slice(0, 10)}`,
14157
- candidateId: playbook.id,
14158
- pattern: antiPattern,
14159
- reason: "Learned from playbook applicability",
14160
- discoveredFrom: playbook.evolution.createdFrom[0] ?? "unknown",
14161
- createdAt: playbook.createdAt
14162
- });
14163
- }
14164
- }
14165
- return {
14166
- candidates,
14167
- updates: updates.length > 0 ? updates : void 0,
14168
- demotions: demotions.length > 0 ? demotions : void 0,
14169
- antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
14170
- providerState: {
14171
- pendingCount: this.pipeline.getAccumulatedCount(),
14172
- readyForFlush: this.pipeline.shouldRunBatch()
14173
- }
14174
- };
14175
- }
14176
- /**
14177
- * Convert a skill-tree Trajectory to cognitive-core Trajectory format
14178
- */
14179
- convertTrajectory(trajectory, options) {
14180
- const firstUserTurn = trajectory.turns.find((t) => t.role === "user");
14181
- let taskDescription = firstUserTurn?.content ?? "Unknown task";
14182
- if (options?.context) {
14183
- taskDescription = `${taskDescription}
14184
-
14185
- Context: ${options.context}`;
14186
- }
14187
- const task = this.factory.createTask({
14188
- id: trajectory.sessionId,
14189
- domain: trajectory.metadata.projectName ?? "general",
14190
- description: taskDescription,
14191
- context: trajectory.metadata.custom ?? {}
14192
- });
14193
- const [startTurn, endTurn] = options?.turnRange ?? [0, trajectory.turns.length - 1];
14194
- const turnsToProcess = trajectory.turns.slice(startTurn, endTurn + 1);
14195
- const steps = [];
14196
- if (this.config.convertToReAct) {
14197
- for (let i = 0; i < turnsToProcess.length; i++) {
14198
- const turn = turnsToProcess[i];
14199
- if (turn.role === "assistant") {
14200
- const step = this.turnToStep(turn, turnsToProcess, i);
14201
- if (step) {
14202
- steps.push(step);
14203
- }
14204
- }
14205
- }
14206
- }
14207
- const outcome = {
14208
- success: trajectory.outcome?.success ?? false,
14209
- partialScore: trajectory.outcome?.success ? 1 : 0,
14210
- solution: trajectory.outcome?.summary ?? "",
14211
- errorInfo: trajectory.outcome?.errors?.join("; ")
14212
- };
14213
- return this.factory.createTrajectory({
14214
- id: trajectory.sessionId,
14215
- task,
14216
- steps,
14217
- outcome,
14218
- agentId: trajectory.metadata.agentType ?? "skill-tree",
14219
- metadata: trajectory.metadata.custom ?? {}
14220
- });
14221
- }
14222
- /**
14223
- * Convert an assistant turn to a cognitive-core Step
14224
- */
14225
- turnToStep(turn, allTurns, turnIndex) {
14226
- let observation = "";
14227
- const nextTurn = allTurns[turnIndex + 1];
14228
- if (nextTurn?.role === "tool" && nextTurn.toolResults?.length) {
14229
- observation = nextTurn.toolResults.map((r) => r.output).join("\n");
14230
- } else if (nextTurn?.role === "user") {
14231
- observation = nextTurn.content.slice(0, 500);
14232
- }
14233
- let action = "";
14234
- if (turn.toolCalls?.length) {
14235
- action = turn.toolCalls.map((tc) => `${tc.name}(${JSON.stringify(tc.input).slice(0, 200)})`).join("; ");
14236
- } else {
14237
- action = turn.content.slice(0, 300);
14238
- }
14239
- const thought = turn.toolCalls?.length ? turn.content.slice(0, 500) : void 0;
14240
- return this.factory.createStep({
14241
- thought,
14242
- action,
14243
- observation
14244
- });
14245
- }
14246
- /**
14247
- * Convert a cognitive-core Playbook to a LearningCandidate
14248
- */
14249
- playbookToCandidate(playbook) {
14250
- const kind = this.inferKind(playbook);
14251
- const content = this.createContentForKind(kind, playbook);
14252
- const attribution = playbook.evolution.createdFrom.map(
14253
- (trajectoryId, i) => ({
14254
- turnIndex: i,
14255
- score: 1 / Math.max(1, playbook.evolution.createdFrom.length),
14256
- reasoning: `Derived from trajectory ${trajectoryId}`
14257
- })
14258
- );
14259
- return {
14260
- kind,
14261
- id: playbook.id,
14262
- name: playbook.name,
14263
- content,
14264
- confidence: playbook.confidence,
14265
- attribution,
14266
- source: {
14267
- provider: this.name,
14268
- trajectoryId: playbook.evolution.createdFrom[0] ?? "unknown",
14269
- turnRange: [0, 0],
14270
- // Playbooks don't track specific turn ranges
14271
- extractedAt: playbook.createdAt,
14272
- metadata: {
14273
- version: playbook.evolution.version,
14274
- successCount: playbook.evolution.successCount,
14275
- failureCount: playbook.evolution.failureCount,
14276
- complexity: playbook.complexity
14277
- }
14278
- },
14279
- embedding: playbook.embedding,
14280
- // Pass through embedding if present
14281
- tags: playbook.applicability.domains,
14282
- reasoning: playbook.guidance.strategy
14283
- };
14284
- }
14285
- /**
14286
- * Create appropriate content type for the inferred kind
14287
- */
14288
- createContentForKind(kind, playbook) {
14289
- switch (kind) {
14290
- case "strategy":
14291
- return {
14292
- kind: "strategy",
14293
- situation: playbook.applicability.situations.join(". "),
14294
- suggestion: playbook.guidance.strategy,
14295
- parameters: playbook.guidance.codeExample ? { example: playbook.guidance.codeExample } : void 0
14296
- };
14297
- case "pattern":
14298
- return {
14299
- kind: "pattern",
14300
- pattern: playbook.applicability.triggers[0] ?? playbook.name,
14301
- description: playbook.guidance.strategy,
14302
- examples: playbook.applicability.situations
14303
- };
14304
- case "error-fix":
14305
- return {
14306
- kind: "error-fix",
14307
- errorPattern: playbook.applicability.triggers.join(" | "),
14308
- fix: playbook.guidance.strategy + (playbook.guidance.steps?.length ? "\n\nSteps:\n" + playbook.guidance.steps.map((s, i) => `${i + 1}. ${s}`).join("\n") : ""),
14309
- frequency: playbook.evolution.successCount + playbook.evolution.failureCount,
14310
- errorExamples: playbook.applicability.triggers
14311
- };
14312
- case "skill":
14313
- default:
14314
- return {
14315
- kind: "skill",
14316
- problem: playbook.applicability.situations.join(". "),
14317
- solution: playbook.guidance.strategy + (playbook.guidance.steps?.length ? "\n\nSteps:\n" + playbook.guidance.steps.map((s, i) => `${i + 1}. ${s}`).join("\n") : ""),
14318
- verification: playbook.verification.successIndicators.join(". "),
14319
- triggers: this.extractTriggers(playbook),
14320
- examples: []
14321
- // Playbooks don't have direct examples
14322
- };
14323
- }
14324
- }
14325
- /**
14326
- * Infer the kind of learning from a playbook
14327
- */
14328
- inferKind(playbook) {
14329
- const hasErrorTriggers = playbook.applicability.triggers.some(
14330
- (t) => t.toLowerCase().includes("error") || /^[A-Z]{2,}\d+/.test(t)
14331
- );
14332
- if (hasErrorTriggers) {
14333
- return "error-fix";
14334
- }
14335
- const strategy = playbook.guidance.strategy.toLowerCase();
14336
- if (strategy.includes("approach") || strategy.includes("strategy") || strategy.includes("when you see")) {
14337
- return "strategy";
14338
- }
14339
- if (playbook.applicability.situations.some((s) => s.includes("pattern"))) {
14340
- return "pattern";
14341
- }
14342
- return "skill";
14343
- }
14344
- /**
14345
- * Extract triggers from playbook applicability
14346
- */
14347
- extractTriggers(playbook) {
14348
- const triggers = [];
14349
- for (const situation of playbook.applicability.situations) {
14350
- triggers.push({
14351
- type: "context",
14352
- value: situation,
14353
- description: "Situation trigger"
14354
- });
14355
- }
14356
- for (const trigger of playbook.applicability.triggers) {
14357
- let type = "keyword";
14358
- if (trigger.toLowerCase().includes("error") || /^[A-Z]{2,}\d+/.test(trigger)) {
14359
- type = "error";
14360
- } else if (trigger.startsWith("/") || trigger.includes("*")) {
14361
- type = "pattern";
14362
- }
14363
- triggers.push({
14364
- type,
14365
- value: trigger,
14366
- description: "Explicit trigger"
14367
- });
14368
- }
14369
- return triggers;
14370
- }
14371
- /**
14372
- * Tokenize text into words
14373
- */
14374
- tokenize(text) {
14375
- return text.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
14376
- }
14377
- /**
14378
- * Compute Jaccard similarity between two arrays
14379
- */
14380
- jaccardSimilarity(a, b) {
14381
- const setA = new Set(a);
14382
- const setB = new Set(b);
14383
- const intersection = new Set([...setA].filter((x) => setB.has(x)));
14384
- const union = /* @__PURE__ */ new Set([...setA, ...setB]);
14385
- return union.size === 0 ? 0 : intersection.size / union.size;
14386
- }
14387
- };
14388
- function createCognitiveCoreProvider(options) {
14389
- return new CognitiveCoreProvider(options);
14390
- }
14391
-
14392
12734
  // src/sync/git-sync-adapter.ts
14393
12735
  var fs8 = __toESM(require("fs"));
14394
12736
  var path8 = __toESM(require("path"));
@@ -15918,7 +14260,6 @@ var VERSION = "0.1.0";
15918
14260
  BaseStorageAdapter,
15919
14261
  BatchProcessor,
15920
14262
  ClaudeCodeAdapter,
15921
- CognitiveCoreProvider,
15922
14263
  ConflictStore,
15923
14264
  DEFAULT_ACTIVATION_CONFIG,
15924
14265
  DEFAULT_AGENTS_CONFIG,
@@ -15937,7 +14278,6 @@ var VERSION = "0.1.0";
15937
14278
  MemoryMetricsStorage,
15938
14279
  MemoryStorageAdapter,
15939
14280
  MetricsTracker,
15940
- NaiveLearningProvider,
15941
14281
  OpenAIAdapter,
15942
14282
  OpenAIEmbedding,
15943
14283
  ProjectDetector,
@@ -15970,7 +14310,6 @@ var VERSION = "0.1.0";
15970
14310
  createAgentsParser,
15971
14311
  createAgentsSync,
15972
14312
  createBackupHook,
15973
- createCognitiveCoreProvider,
15974
14313
  createConflictStore,
15975
14314
  createDefaultSyncConfig,
15976
14315
  createExtractionEnrichmentHook,
@@ -15981,7 +14320,6 @@ var VERSION = "0.1.0";
15981
14320
  createMcpServer,
15982
14321
  createMetricsHook,
15983
14322
  createMetricsTracker,
15984
- createNaiveProvider,
15985
14323
  createQualityBypassHook,
15986
14324
  createQualityLoggingHook,
15987
14325
  createSaveValidationHook,
@@ -15991,6 +14329,7 @@ var VERSION = "0.1.0";
15991
14329
  createToolHandlers,
15992
14330
  debuggingProfile,
15993
14331
  devopsProfile,
14332
+ discoverSkills,
15994
14333
  documentationProfile,
15995
14334
  euclideanDistance,
15996
14335
  executeToolCall,
@@ -16001,6 +14340,7 @@ var VERSION = "0.1.0";
16001
14340
  getLatestVersion,
16002
14341
  getToolDefinition,
16003
14342
  getToolNames,
14343
+ hasSkilltreeDir,
16004
14344
  hookRegistry,
16005
14345
  implementationProfile,
16006
14346
  importFromAgentsMd,
@@ -16030,3 +14370,4 @@ var VERSION = "0.1.0";
16030
14370
  testingProfile,
16031
14371
  writeAgentsMd
16032
14372
  });
14373
+ //# sourceMappingURL=index.js.map