skill-tree 0.1.2 → 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/cli/index.js CHANGED
@@ -712,11 +712,76 @@ var LoadoutCompiler = class {
712
712
  // src/serving/project-detector.ts
713
713
  var import_fs = require("fs");
714
714
  var import_path = require("path");
715
- var _ProjectDetector = class _ProjectDetector {
715
+ var ProjectDetector = class _ProjectDetector {
716
716
  constructor() {
717
717
  /** Cache for project context */
718
718
  this.cache = /* @__PURE__ */ new Map();
719
719
  }
720
+ static {
721
+ /** Project type patterns */
722
+ this.PROJECT_TYPES = [
723
+ { manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
724
+ { manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
725
+ { manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
726
+ { manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
727
+ { manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
728
+ { manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
729
+ { manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
730
+ { manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
731
+ ];
732
+ }
733
+ static {
734
+ /** TypeScript detection */
735
+ this.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
736
+ }
737
+ static {
738
+ /** Node.js framework patterns */
739
+ this.NODE_FRAMEWORKS = [
740
+ { name: "react", packageName: "react", tags: ["react", "frontend"] },
741
+ { name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
742
+ { name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
743
+ { name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
744
+ { name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
745
+ { name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
746
+ { name: "express", packageName: "express", tags: ["express", "backend", "api"] },
747
+ { name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
748
+ { name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
749
+ { name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
750
+ { name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
751
+ { name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
752
+ { name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
753
+ { name: "jest", packageName: "jest", tags: ["testing", "jest"] },
754
+ { name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
755
+ { name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
756
+ { name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
757
+ ];
758
+ }
759
+ static {
760
+ /** Python framework patterns (from pyproject.toml or requirements.txt) */
761
+ this.PYTHON_FRAMEWORKS = [
762
+ { name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
763
+ { name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
764
+ { name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
765
+ { name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
766
+ { name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
767
+ { name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
768
+ ];
769
+ }
770
+ static {
771
+ /** Directory patterns */
772
+ this.DIRECTORY_PATTERNS = [
773
+ { pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
774
+ { pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
775
+ { pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
776
+ { pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
777
+ { pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
778
+ { pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
779
+ { pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
780
+ { pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
781
+ { pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
782
+ { pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
783
+ ];
784
+ }
720
785
  /**
721
786
  * Detect project context from a directory
722
787
  */
@@ -878,62 +943,6 @@ var _ProjectDetector = class _ProjectDetector {
878
943
  }
879
944
  }
880
945
  };
881
- /** Project type patterns */
882
- _ProjectDetector.PROJECT_TYPES = [
883
- { manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
884
- { manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
885
- { manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
886
- { manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
887
- { manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
888
- { manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
889
- { manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
890
- { manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
891
- ];
892
- /** TypeScript detection */
893
- _ProjectDetector.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
894
- /** Node.js framework patterns */
895
- _ProjectDetector.NODE_FRAMEWORKS = [
896
- { name: "react", packageName: "react", tags: ["react", "frontend"] },
897
- { name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
898
- { name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
899
- { name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
900
- { name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
901
- { name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
902
- { name: "express", packageName: "express", tags: ["express", "backend", "api"] },
903
- { name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
904
- { name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
905
- { name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
906
- { name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
907
- { name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
908
- { name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
909
- { name: "jest", packageName: "jest", tags: ["testing", "jest"] },
910
- { name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
911
- { name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
912
- { name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
913
- ];
914
- /** Python framework patterns (from pyproject.toml or requirements.txt) */
915
- _ProjectDetector.PYTHON_FRAMEWORKS = [
916
- { name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
917
- { name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
918
- { name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
919
- { name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
920
- { name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
921
- { name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
922
- ];
923
- /** Directory patterns */
924
- _ProjectDetector.DIRECTORY_PATTERNS = [
925
- { pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
926
- { pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
927
- { pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
928
- { pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
929
- { pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
930
- { pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
931
- { pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
932
- { pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
933
- { pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
934
- { pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
935
- ];
936
- var ProjectDetector = _ProjectDetector;
937
946
 
938
947
  // src/serving/view-renderer.ts
939
948
  var DEFAULT_CONFIG2 = {
@@ -6227,10 +6236,7 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
6227
6236
  this.skills = /* @__PURE__ */ new Map();
6228
6237
  // skillId -> version -> skill
6229
6238
  this.lineages = /* @__PURE__ */ new Map();
6230
- this.candidates = /* @__PURE__ */ new Map();
6231
- this.antiPatterns = /* @__PURE__ */ new Map();
6232
6239
  }
6233
- // skillId -> patterns
6234
6240
  async initialize() {
6235
6241
  this.initialized = true;
6236
6242
  }
@@ -6361,78 +6367,6 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
6361
6367
  clear() {
6362
6368
  this.skills.clear();
6363
6369
  this.lineages.clear();
6364
- this.candidates.clear();
6365
- this.antiPatterns.clear();
6366
- }
6367
- // ==========================================================================
6368
- // Learning Candidate Operations
6369
- // ==========================================================================
6370
- async saveCandidate(candidate) {
6371
- this.ensureInitialized();
6372
- this.candidates.set(candidate.id, { ...candidate });
6373
- }
6374
- async getCandidate(id) {
6375
- this.ensureInitialized();
6376
- return this.candidates.get(id) || null;
6377
- }
6378
- async listCandidates(filter) {
6379
- this.ensureInitialized();
6380
- let results = Array.from(this.candidates.values());
6381
- if (filter) {
6382
- if (filter.kind && filter.kind.length > 0) {
6383
- results = results.filter((c) => filter.kind.includes(c.kind));
6384
- }
6385
- if (filter.status && filter.status.length > 0) {
6386
- results = results.filter((c) => filter.status.includes(c.status));
6387
- }
6388
- if (filter.minConfidence !== void 0) {
6389
- results = results.filter((c) => c.confidence >= filter.minConfidence);
6390
- }
6391
- if (filter.createdAfter) {
6392
- results = results.filter((c) => c.createdAt >= filter.createdAfter);
6393
- }
6394
- if (filter.createdBefore) {
6395
- results = results.filter((c) => c.createdAt <= filter.createdBefore);
6396
- }
6397
- }
6398
- return results;
6399
- }
6400
- async updateCandidateStatus(id, status, details) {
6401
- this.ensureInitialized();
6402
- const candidate = this.candidates.get(id);
6403
- if (!candidate) return false;
6404
- candidate.status = status;
6405
- candidate.updatedAt = /* @__PURE__ */ new Date();
6406
- if (details?.promotedToSkillId) {
6407
- candidate.promotedToSkillId = details.promotedToSkillId;
6408
- }
6409
- if (details?.rejectionReason) {
6410
- candidate.rejectionReason = details.rejectionReason;
6411
- }
6412
- return true;
6413
- }
6414
- async deleteCandidate(id) {
6415
- this.ensureInitialized();
6416
- return this.candidates.delete(id);
6417
- }
6418
- // ==========================================================================
6419
- // Anti-Pattern Operations
6420
- // ==========================================================================
6421
- async saveAntiPatterns(skillId, patterns) {
6422
- this.ensureInitialized();
6423
- this.antiPatterns.set(skillId, [...patterns]);
6424
- }
6425
- async getAntiPatterns(skillId) {
6426
- this.ensureInitialized();
6427
- return this.antiPatterns.get(skillId) || [];
6428
- }
6429
- async listAntiPatterns() {
6430
- this.ensureInitialized();
6431
- const results = [];
6432
- for (const [skillId, patterns] of this.antiPatterns) {
6433
- results.push({ skillId, patterns });
6434
- }
6435
- return results;
6436
6370
  }
6437
6371
  // ==========================================================================
6438
6372
  // Fork Tracking
@@ -6983,152 +6917,6 @@ ${body}`;
6983
6917
  return Math.abs(hash).toString(16);
6984
6918
  }
6985
6919
  // ==========================================================================
6986
- // Learning Candidate Operations
6987
- // ==========================================================================
6988
- get candidatesDir() {
6989
- return path4.join(this.skilltreeDir, "candidates");
6990
- }
6991
- get antiPatternsDir() {
6992
- return path4.join(this.skilltreeDir, "anti-patterns");
6993
- }
6994
- async saveCandidate(candidate) {
6995
- this.ensureInitialized();
6996
- await fs4.mkdir(this.candidatesDir, { recursive: true });
6997
- const candidatePath = path4.join(this.candidatesDir, `${candidate.id}.json`);
6998
- await fs4.writeFile(candidatePath, JSON.stringify(candidate, null, 2), "utf-8");
6999
- }
7000
- async getCandidate(id) {
7001
- this.ensureInitialized();
7002
- const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
7003
- try {
7004
- const content = await fs4.readFile(candidatePath, "utf-8");
7005
- const candidate = JSON.parse(content);
7006
- candidate.createdAt = new Date(candidate.createdAt);
7007
- candidate.updatedAt = new Date(candidate.updatedAt);
7008
- candidate.source.extractedAt = new Date(candidate.source.extractedAt);
7009
- return candidate;
7010
- } catch (error) {
7011
- if (error.code === "ENOENT") {
7012
- return null;
7013
- }
7014
- throw error;
7015
- }
7016
- }
7017
- async listCandidates(filter) {
7018
- this.ensureInitialized();
7019
- try {
7020
- const files = await fs4.readdir(this.candidatesDir);
7021
- const candidates = [];
7022
- for (const file of files) {
7023
- if (!file.endsWith(".json")) continue;
7024
- const id = file.replace(".json", "");
7025
- const candidate = await this.getCandidate(id);
7026
- if (candidate) {
7027
- candidates.push(candidate);
7028
- }
7029
- }
7030
- let results = candidates;
7031
- if (filter) {
7032
- if (filter.kind && filter.kind.length > 0) {
7033
- results = results.filter((c) => filter.kind.includes(c.kind));
7034
- }
7035
- if (filter.status && filter.status.length > 0) {
7036
- results = results.filter((c) => filter.status.includes(c.status));
7037
- }
7038
- if (filter.minConfidence !== void 0) {
7039
- results = results.filter((c) => c.confidence >= filter.minConfidence);
7040
- }
7041
- if (filter.createdAfter) {
7042
- results = results.filter((c) => c.createdAt >= filter.createdAfter);
7043
- }
7044
- if (filter.createdBefore) {
7045
- results = results.filter((c) => c.createdAt <= filter.createdBefore);
7046
- }
7047
- }
7048
- return results;
7049
- } catch (error) {
7050
- if (error.code === "ENOENT") {
7051
- return [];
7052
- }
7053
- throw error;
7054
- }
7055
- }
7056
- async updateCandidateStatus(id, status, details) {
7057
- this.ensureInitialized();
7058
- const candidate = await this.getCandidate(id);
7059
- if (!candidate) return false;
7060
- candidate.status = status;
7061
- candidate.updatedAt = /* @__PURE__ */ new Date();
7062
- if (details?.promotedToSkillId) {
7063
- candidate.promotedToSkillId = details.promotedToSkillId;
7064
- }
7065
- if (details?.rejectionReason) {
7066
- candidate.rejectionReason = details.rejectionReason;
7067
- }
7068
- await this.saveCandidate(candidate);
7069
- return true;
7070
- }
7071
- async deleteCandidate(id) {
7072
- this.ensureInitialized();
7073
- const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
7074
- try {
7075
- await fs4.unlink(candidatePath);
7076
- return true;
7077
- } catch (error) {
7078
- if (error.code === "ENOENT") {
7079
- return false;
7080
- }
7081
- throw error;
7082
- }
7083
- }
7084
- // ==========================================================================
7085
- // Anti-Pattern Operations
7086
- // ==========================================================================
7087
- async saveAntiPatterns(skillId, patterns) {
7088
- this.ensureInitialized();
7089
- await fs4.mkdir(this.antiPatternsDir, { recursive: true });
7090
- const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
7091
- await fs4.writeFile(patternPath, JSON.stringify(patterns, null, 2), "utf-8");
7092
- }
7093
- async getAntiPatterns(skillId) {
7094
- this.ensureInitialized();
7095
- const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
7096
- try {
7097
- const content = await fs4.readFile(patternPath, "utf-8");
7098
- const patterns = JSON.parse(content);
7099
- for (const pattern of patterns) {
7100
- pattern.learnedAt = new Date(pattern.learnedAt);
7101
- }
7102
- return patterns;
7103
- } catch (error) {
7104
- if (error.code === "ENOENT") {
7105
- return [];
7106
- }
7107
- throw error;
7108
- }
7109
- }
7110
- async listAntiPatterns() {
7111
- this.ensureInitialized();
7112
- try {
7113
- const files = await fs4.readdir(this.antiPatternsDir);
7114
- const results = [];
7115
- for (const file of files) {
7116
- if (!file.endsWith(".json")) continue;
7117
- const skillId = file.replace(".json", "");
7118
- const patterns = await this.getAntiPatterns(skillId);
7119
- if (patterns.length > 0) {
7120
- results.push({ skillId, patterns });
7121
- }
7122
- }
7123
- return results;
7124
- } catch (error) {
7125
- if (error.code === "ENOENT") {
7126
- return [];
7127
- }
7128
- throw error;
7129
- }
7130
- }
7131
- // ==========================================================================
7132
6920
  // Fork Tracking
7133
6921
  // ==========================================================================
7134
6922
  async recordFork(sourceSkillId, fork) {
@@ -7455,310 +7243,6 @@ ${source}`;
7455
7243
  }
7456
7244
  };
7457
7245
 
7458
- // src/learning/providers/naive.ts
7459
- var NaiveLearningProvider = class {
7460
- constructor(config2) {
7461
- this.name = "naive";
7462
- this.description = "Built-in extraction using heuristics and optional LLM analysis";
7463
- this.capabilities = {
7464
- accumulating: false,
7465
- feedbackEnabled: false,
7466
- persistent: false,
7467
- supportedKinds: ["skill", "strategy", "pattern", "error-fix"]
7468
- };
7469
- this.config = {
7470
- llmProvider: config2?.llmProvider ?? null,
7471
- minConfidence: config2?.minConfidence ?? 0.6,
7472
- runQualityGates: config2?.runQualityGates ?? true,
7473
- creditStrategy: config2?.creditStrategy ?? "simple"
7474
- };
7475
- this.manualExtractor = new ManualExtractor();
7476
- this.automaticExtractor = new AutomaticExtractor({
7477
- llmProvider: this.config.llmProvider || void 0,
7478
- minConfidence: this.config.minConfidence
7479
- });
7480
- }
7481
- /**
7482
- * Set or update the LLM provider
7483
- */
7484
- setLLMProvider(provider) {
7485
- this.config.llmProvider = provider;
7486
- this.automaticExtractor.setLLMProvider(provider);
7487
- }
7488
- /**
7489
- * Analyze a trajectory and extract learning candidates
7490
- */
7491
- async analyze(trajectory, options) {
7492
- const startTime = Date.now();
7493
- const candidates = [];
7494
- const kinds = options?.kinds ?? ["skill"];
7495
- const useAutomatic = this.config.llmProvider != null;
7496
- let results;
7497
- if (useAutomatic) {
7498
- results = await this.automaticExtractor.extract(trajectory, {
7499
- turnRange: options?.turnRange,
7500
- minConfidence: options?.minConfidence ?? this.config.minConfidence,
7501
- skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
7502
- context: options?.context
7503
- });
7504
- } else {
7505
- results = await this.manualExtractor.extract(trajectory, {
7506
- turnRange: options?.turnRange,
7507
- skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
7508
- context: options?.context
7509
- });
7510
- }
7511
- for (const result of results) {
7512
- if (!result.success || !result.skill) continue;
7513
- const kind = this.inferKind(result.skill);
7514
- if (!kinds.includes(kind)) continue;
7515
- const candidate = this.extractionResultToCandidate(result, trajectory);
7516
- candidates.push(candidate);
7517
- }
7518
- return {
7519
- candidates,
7520
- // Naive provider doesn't produce updates, demotions, or anti-patterns
7521
- metadata: {
7522
- trajectoriesAnalyzed: 1,
7523
- durationMs: Date.now() - startTime
7524
- }
7525
- };
7526
- }
7527
- /**
7528
- * Batch analysis - runs individual analysis on each trajectory.
7529
- * A more sophisticated provider could do cross-trajectory pattern detection.
7530
- */
7531
- async analyzeBatch(trajectories, options) {
7532
- const startTime = Date.now();
7533
- const allCandidates = [];
7534
- for (const trajectory of trajectories) {
7535
- const result = await this.analyze(trajectory, options);
7536
- allCandidates.push(...result.candidates);
7537
- }
7538
- const deduplicated = this.deduplicateCandidates(allCandidates);
7539
- return {
7540
- candidates: deduplicated,
7541
- metadata: {
7542
- trajectoriesAnalyzed: trajectories.length,
7543
- durationMs: Date.now() - startTime
7544
- }
7545
- };
7546
- }
7547
- /**
7548
- * Check if a candidate is a duplicate based on name/content similarity
7549
- */
7550
- isDuplicate(candidate, existing) {
7551
- if (existing.some((e) => e.id === candidate.id)) {
7552
- return true;
7553
- }
7554
- const normalizedName = this.normalizeName(candidate.name);
7555
- for (const e of existing) {
7556
- if (this.normalizeName(e.name) === normalizedName) {
7557
- return true;
7558
- }
7559
- }
7560
- return false;
7561
- }
7562
- /**
7563
- * Compute similarity between two candidates (basic implementation)
7564
- */
7565
- computeSimilarity(a, b) {
7566
- if (a.kind !== b.kind) return 0.1;
7567
- const nameA = this.normalizeName(a.name);
7568
- const nameB = this.normalizeName(b.name);
7569
- const nameSimilarity = this.jaccardSimilarity(
7570
- nameA.split("-"),
7571
- nameB.split("-")
7572
- );
7573
- let contentSimilarity = 0;
7574
- if (a.content.kind === "skill" && b.content.kind === "skill") {
7575
- const aWords = this.tokenize(a.content.problem + " " + a.content.solution);
7576
- const bWords = this.tokenize(b.content.problem + " " + b.content.solution);
7577
- contentSimilarity = this.jaccardSimilarity(aWords, bWords);
7578
- }
7579
- return nameSimilarity * 0.3 + contentSimilarity * 0.7;
7580
- }
7581
- // ==========================================================================
7582
- // Private Methods
7583
- // ==========================================================================
7584
- /**
7585
- * Convert an ExtractionResult to a LearningCandidate
7586
- */
7587
- extractionResultToCandidate(result, trajectory) {
7588
- const skill = result.skill;
7589
- const turnRange = result.sourceTrajectory.turnRange;
7590
- return {
7591
- kind: this.inferKind(skill),
7592
- id: skill.id,
7593
- name: skill.name,
7594
- content: this.skillToContent(skill),
7595
- confidence: result.confidence,
7596
- attribution: this.computeAttribution(trajectory, turnRange),
7597
- source: {
7598
- provider: this.name,
7599
- trajectoryId: trajectory.sessionId,
7600
- turnRange,
7601
- extractedAt: /* @__PURE__ */ new Date(),
7602
- metadata: {
7603
- gateResults: result.gateResults,
7604
- extractionMode: this.config.llmProvider ? "automatic" : "manual"
7605
- }
7606
- },
7607
- tags: skill.tags,
7608
- reasoning: result.failureReason
7609
- };
7610
- }
7611
- /**
7612
- * Convert a Skill to LearningContent
7613
- */
7614
- skillToContent(skill) {
7615
- return {
7616
- kind: "skill",
7617
- problem: skill.problem,
7618
- solution: skill.solution,
7619
- verification: skill.verification,
7620
- triggers: skill.triggerConditions.map(
7621
- (t) => ({
7622
- type: t.type,
7623
- value: t.value,
7624
- description: t.description
7625
- })
7626
- ),
7627
- examples: skill.examples.map(
7628
- (e) => ({
7629
- scenario: e.scenario,
7630
- before: e.before,
7631
- after: e.after
7632
- })
7633
- )
7634
- };
7635
- }
7636
- /**
7637
- * Infer the kind of learning from a skill
7638
- */
7639
- inferKind(skill) {
7640
- const hasErrorTriggers = skill.triggerConditions.some(
7641
- (t) => t.type === "error"
7642
- );
7643
- if (hasErrorTriggers && skill.problem.toLowerCase().includes("error")) {
7644
- return "error-fix";
7645
- }
7646
- if (skill.solution.toLowerCase().includes("approach") || skill.solution.toLowerCase().includes("strategy") || skill.solution.toLowerCase().includes("when you see")) {
7647
- return "strategy";
7648
- }
7649
- return "skill";
7650
- }
7651
- /**
7652
- * Compute step attribution using the configured strategy
7653
- */
7654
- computeAttribution(trajectory, turnRange) {
7655
- const [start, end] = turnRange;
7656
- const turns = trajectory.turns.slice(start, end + 1);
7657
- switch (this.config.creditStrategy) {
7658
- case "simple":
7659
- return this.simpleCredit(turns, start);
7660
- case "uniform":
7661
- return this.uniformCredit(turns, start);
7662
- case "llm":
7663
- return this.simpleCredit(turns, start);
7664
- default:
7665
- return this.simpleCredit(turns, start);
7666
- }
7667
- }
7668
- /**
7669
- * Simple credit assignment: exponential decay from end.
7670
- * Last step gets most credit, earlier steps get less.
7671
- */
7672
- simpleCredit(turns, startOffset) {
7673
- const attributions = [];
7674
- const n = turns.length;
7675
- for (let i = 0; i < n; i++) {
7676
- const turn = turns[i];
7677
- if (turn.role === "system") continue;
7678
- const distanceFromEnd = n - 1 - i;
7679
- const score = Math.pow(0.7, distanceFromEnd);
7680
- const hasToolCalls = turn.toolCalls && turn.toolCalls.length > 0;
7681
- const boostedScore = hasToolCalls ? Math.min(1, score * 1.3) : score;
7682
- attributions.push({
7683
- turnIndex: startOffset + i,
7684
- score: Math.round(boostedScore * 100) / 100,
7685
- reasoning: this.getAttributionReasoning(turn, boostedScore)
7686
- });
7687
- }
7688
- return attributions;
7689
- }
7690
- /**
7691
- * Uniform credit assignment: all steps get equal credit.
7692
- */
7693
- uniformCredit(turns, startOffset) {
7694
- const nonSystemTurns = turns.filter((t) => t.role !== "system");
7695
- const score = 1 / nonSystemTurns.length;
7696
- return turns.map((turn, i) => {
7697
- if (turn.role === "system") return null;
7698
- return {
7699
- turnIndex: startOffset + i,
7700
- score: Math.round(score * 100) / 100
7701
- };
7702
- }).filter((a) => a !== null);
7703
- }
7704
- /**
7705
- * Generate reasoning for attribution
7706
- */
7707
- getAttributionReasoning(turn, score) {
7708
- const reasons = [];
7709
- if (score >= 0.8) {
7710
- reasons.push("High impact (near end of solution)");
7711
- } else if (score >= 0.5) {
7712
- reasons.push("Medium impact");
7713
- } else {
7714
- reasons.push("Lower impact (early in trajectory)");
7715
- }
7716
- if (turn.toolCalls && turn.toolCalls.length > 0) {
7717
- const toolNames = turn.toolCalls.map((t) => t.name).join(", ");
7718
- reasons.push(`Used tools: ${toolNames}`);
7719
- }
7720
- if (turn.toolResults?.some((r) => !r.success)) {
7721
- reasons.push("Encountered and handled errors");
7722
- }
7723
- return reasons.join(". ");
7724
- }
7725
- /**
7726
- * Deduplicate candidates by ID
7727
- */
7728
- deduplicateCandidates(candidates) {
7729
- const seen = /* @__PURE__ */ new Map();
7730
- for (const candidate of candidates) {
7731
- const existing = seen.get(candidate.id);
7732
- if (!existing || candidate.confidence > existing.confidence) {
7733
- seen.set(candidate.id, candidate);
7734
- }
7735
- }
7736
- return Array.from(seen.values());
7737
- }
7738
- /**
7739
- * Normalize a name for comparison
7740
- */
7741
- normalizeName(name) {
7742
- return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
7743
- }
7744
- /**
7745
- * Tokenize text into words
7746
- */
7747
- tokenize(text) {
7748
- return text.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
7749
- }
7750
- /**
7751
- * Compute Jaccard similarity between two arrays
7752
- */
7753
- jaccardSimilarity(a, b) {
7754
- const setA = new Set(a);
7755
- const setB = new Set(b);
7756
- const intersection = new Set([...setA].filter((x) => setB.has(x)));
7757
- const union = /* @__PURE__ */ new Set([...setA, ...setB]);
7758
- return union.size === 0 ? 0 : intersection.size / union.size;
7759
- }
7760
- };
7761
-
7762
7246
  // src/hooks/registry.ts
7763
7247
  var import_crypto = require("crypto");
7764
7248
  var PRIORITY_ORDER = {
@@ -8228,10 +7712,6 @@ var SkillBank = class {
8228
7712
  this.eventHandlers = [];
8229
7713
  this.initialized = false;
8230
7714
  this.autoIndexOnInit = false;
8231
- /** Learning providers for meta-learning integration */
8232
- this.learningProviders = /* @__PURE__ */ new Map();
8233
- /** Anti-patterns stored separately as metadata */
8234
- this.antiPatterns = /* @__PURE__ */ new Map();
8235
7715
  /** Validation mode: advisory (non-blocking) or blocking */
8236
7716
  this.validationMode = "advisory";
8237
7717
  /** Whether validation is enabled */
@@ -8269,11 +7749,6 @@ var SkillBank = class {
8269
7749
  similarityThreshold: config2.matching?.similarityThreshold
8270
7750
  });
8271
7751
  this.autoIndexOnInit = config2.matching?.autoIndex ?? false;
8272
- const naiveProvider = new NaiveLearningProvider({
8273
- llmProvider: config2.llmProvider,
8274
- minConfidence: config2.minExtractionConfidence
8275
- });
8276
- this.learningProviders.set(naiveProvider.name, naiveProvider);
8277
7752
  if (config2.namespace) {
8278
7753
  this.namespaceConfig = {
8279
7754
  agentId: config2.namespace.agentId,
@@ -8301,11 +7776,6 @@ var SkillBank = class {
8301
7776
  */
8302
7777
  async initialize() {
8303
7778
  await this.storage.initialize();
8304
- for (const provider of this.learningProviders.values()) {
8305
- if (provider.initialize) {
8306
- await provider.initialize();
8307
- }
8308
- }
8309
7779
  if (this.validator) {
8310
7780
  this.validator.setStorage(this.storage);
8311
7781
  }
@@ -8318,11 +7788,6 @@ var SkillBank = class {
8318
7788
  * Shutdown the skill bank cleanly
8319
7789
  */
8320
7790
  async shutdown() {
8321
- for (const provider of this.learningProviders.values()) {
8322
- if (provider.shutdown) {
8323
- await provider.shutdown();
8324
- }
8325
- }
8326
7791
  }
8327
7792
  /**
8328
7793
  * Ensure initialized before operations
@@ -8480,569 +7945,6 @@ var SkillBank = class {
8480
7945
  */
8481
7946
  setLLMProvider(provider) {
8482
7947
  this.automaticExtractor.setLLMProvider(provider);
8483
- const naiveProvider = this.learningProviders.get("naive");
8484
- if (naiveProvider && "setLLMProvider" in naiveProvider) {
8485
- naiveProvider.setLLMProvider(provider);
8486
- }
8487
- }
8488
- // ==========================================================================
8489
- // Learning Providers (Meta-learning Integration)
8490
- // ==========================================================================
8491
- /**
8492
- * Register a learning provider.
8493
- * Learning providers analyze trajectories and produce learning candidates.
8494
- * Use this to integrate external learning engines like cognitive-core.
8495
- */
8496
- async registerLearningProvider(provider) {
8497
- if (provider.initialize) {
8498
- await provider.initialize();
8499
- }
8500
- this.learningProviders.set(provider.name, provider);
8501
- }
8502
- /**
8503
- * Get a registered learning provider by name
8504
- */
8505
- getLearningProvider(name) {
8506
- return this.learningProviders.get(name);
8507
- }
8508
- /**
8509
- * List all registered learning providers
8510
- */
8511
- listLearningProviders() {
8512
- return Array.from(this.learningProviders.values());
8513
- }
8514
- /**
8515
- * Learn from a trajectory using a learning provider.
8516
- * This is the primary integration point for meta-learning engines.
8517
- *
8518
- * For accumulating providers, this may not return immediate results.
8519
- * Use flushProviders() to force extraction from accumulated trajectories.
8520
- */
8521
- async learnFrom(trajectory, options) {
8522
- this.ensureInitialized();
8523
- const providerName = options?.provider ?? "naive";
8524
- const provider = this.learningProviders.get(providerName);
8525
- if (!provider) {
8526
- throw new Error(
8527
- `Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
8528
- );
8529
- }
8530
- const result = await provider.analyze(trajectory, options);
8531
- return this.processAnalyzeResult(result);
8532
- }
8533
- /**
8534
- * Learn from multiple trajectories.
8535
- * Providers that support batch analysis can find cross-trajectory patterns.
8536
- */
8537
- async learnFromBatch(trajectories, options) {
8538
- this.ensureInitialized();
8539
- const providerName = options?.provider ?? "naive";
8540
- const provider = this.learningProviders.get(providerName);
8541
- if (!provider) {
8542
- throw new Error(`Learning provider not found: ${providerName}`);
8543
- }
8544
- let result;
8545
- if (provider.analyzeBatch) {
8546
- result = await provider.analyzeBatch(trajectories, options);
8547
- } else {
8548
- const candidates = [];
8549
- const updates = [];
8550
- const demotions = [];
8551
- const antiPatterns = [];
8552
- let totalDuration = 0;
8553
- for (const trajectory of trajectories) {
8554
- const r = await provider.analyze(trajectory, options);
8555
- candidates.push(...r.candidates);
8556
- if (r.updates) updates.push(...r.updates);
8557
- if (r.demotions) demotions.push(...r.demotions);
8558
- if (r.antiPatterns) antiPatterns.push(...r.antiPatterns);
8559
- totalDuration += r.metadata.durationMs;
8560
- }
8561
- result = {
8562
- candidates,
8563
- updates: updates.length > 0 ? updates : void 0,
8564
- demotions: demotions.length > 0 ? demotions : void 0,
8565
- antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
8566
- metadata: {
8567
- trajectoriesAnalyzed: trajectories.length,
8568
- durationMs: totalDuration
8569
- }
8570
- };
8571
- }
8572
- return this.processAnalyzeResult(result);
8573
- }
8574
- /**
8575
- * Force extraction from all accumulating providers.
8576
- */
8577
- async flushProviders() {
8578
- this.ensureInitialized();
8579
- const mergedResult = {
8580
- skillsCreated: 0,
8581
- skillsUpdated: 0,
8582
- skillsDemoted: 0,
8583
- antiPatternsAdded: 0,
8584
- createdSkillIds: [],
8585
- updatedSkillIds: []
8586
- };
8587
- for (const provider of this.learningProviders.values()) {
8588
- if (provider.capabilities.accumulating && provider.flush) {
8589
- const result = await provider.flush();
8590
- const processed = await this.processAnalyzeResult(result);
8591
- mergedResult.skillsCreated += processed.skillsCreated;
8592
- mergedResult.skillsUpdated += processed.skillsUpdated;
8593
- mergedResult.skillsDemoted += processed.skillsDemoted;
8594
- mergedResult.antiPatternsAdded += processed.antiPatternsAdded;
8595
- mergedResult.createdSkillIds.push(...processed.createdSkillIds);
8596
- mergedResult.updatedSkillIds.push(...processed.updatedSkillIds);
8597
- }
8598
- }
8599
- return mergedResult;
8600
- }
8601
- /**
8602
- * Record outcome when a skill is applied.
8603
- * Provider updates internal state and returns updates for SkillBank.
8604
- */
8605
- async recordOutcome(feedback, providerName) {
8606
- this.ensureInitialized();
8607
- const skill = await this.storage.getSkill(feedback.candidateId);
8608
- if (skill) {
8609
- skill.metrics.usageCount++;
8610
- if (feedback.success) {
8611
- const totalUses = skill.metrics.usageCount;
8612
- const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
8613
- skill.metrics.successRate = (currentSuccesses + 1) / totalUses;
8614
- } else {
8615
- const totalUses = skill.metrics.usageCount;
8616
- const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
8617
- skill.metrics.successRate = currentSuccesses / totalUses;
8618
- }
8619
- skill.metrics.lastUsed = /* @__PURE__ */ new Date();
8620
- await this.storage.saveSkill(skill);
8621
- }
8622
- const providersToNotify = providerName ? [this.learningProviders.get(providerName)].filter(Boolean) : Array.from(this.learningProviders.values());
8623
- for (const provider of providersToNotify) {
8624
- if (provider.capabilities.feedbackEnabled && provider.recordOutcome) {
8625
- const result = await provider.recordOutcome(feedback);
8626
- if (result.updates) {
8627
- for (const update of result.updates) {
8628
- await this.applyUpdate(update);
8629
- }
8630
- }
8631
- if (result.antiPatterns) {
8632
- for (const ap of result.antiPatterns) {
8633
- await this.addAntiPattern(ap);
8634
- }
8635
- }
8636
- }
8637
- }
8638
- }
8639
- /**
8640
- * Process an AnalyzeResult: store candidates, apply updates, etc.
8641
- */
8642
- async processAnalyzeResult(result) {
8643
- const learnResult = {
8644
- skillsCreated: 0,
8645
- skillsUpdated: 0,
8646
- skillsDemoted: 0,
8647
- antiPatternsAdded: 0,
8648
- providerState: result.providerState,
8649
- createdSkillIds: [],
8650
- updatedSkillIds: []
8651
- };
8652
- for (const candidate of result.candidates) {
8653
- if (candidate.content.kind === "skill") {
8654
- const skill = await this.promoteToSkill(candidate);
8655
- learnResult.skillsCreated++;
8656
- learnResult.createdSkillIds.push(skill.id);
8657
- } else {
8658
- await this.storeCandidateForReview(candidate);
8659
- }
8660
- }
8661
- if (result.updates) {
8662
- for (const update of result.updates) {
8663
- const updated = await this.applyUpdate(update);
8664
- if (updated) {
8665
- learnResult.skillsUpdated++;
8666
- learnResult.updatedSkillIds.push(update.candidateId);
8667
- }
8668
- }
8669
- }
8670
- if (result.demotions) {
8671
- for (const demotion of result.demotions) {
8672
- await this.applyDemotion(demotion);
8673
- learnResult.skillsDemoted++;
8674
- }
8675
- }
8676
- if (result.antiPatterns) {
8677
- for (const ap of result.antiPatterns) {
8678
- await this.addAntiPattern(ap);
8679
- learnResult.antiPatternsAdded++;
8680
- }
8681
- }
8682
- return learnResult;
8683
- }
8684
- /**
8685
- * Store a non-skill candidate for later review
8686
- */
8687
- async storeCandidateForReview(candidate) {
8688
- if (!this.storage.saveCandidate) {
8689
- return;
8690
- }
8691
- const record = {
8692
- id: candidate.id,
8693
- kind: candidate.kind,
8694
- name: candidate.name,
8695
- content: candidate.content,
8696
- confidence: candidate.confidence,
8697
- source: {
8698
- trajectoryId: candidate.source.trajectoryId,
8699
- provider: candidate.source.provider,
8700
- extractedAt: candidate.source.extractedAt,
8701
- turnRange: candidate.source.turnRange
8702
- },
8703
- tags: candidate.tags,
8704
- reasoning: candidate.reasoning,
8705
- createdAt: /* @__PURE__ */ new Date(),
8706
- updatedAt: /* @__PURE__ */ new Date(),
8707
- status: "pending"
8708
- };
8709
- await this.storage.saveCandidate(record);
8710
- }
8711
- /**
8712
- * Apply an update to an existing skill
8713
- */
8714
- async applyUpdate(update) {
8715
- const skill = await this.storage.getSkill(update.candidateId);
8716
- if (!skill) return false;
8717
- let modified = false;
8718
- if (update.addTrigger) {
8719
- const exists = skill.triggerConditions.some(
8720
- (t) => t.type === update.addTrigger.type && t.value === update.addTrigger.value
8721
- );
8722
- if (!exists) {
8723
- skill.triggerConditions.push({
8724
- type: update.addTrigger.type,
8725
- value: update.addTrigger.value,
8726
- description: update.addTrigger.description
8727
- });
8728
- modified = true;
8729
- }
8730
- }
8731
- if (update.refinement) {
8732
- const refinementNote = `[${update.refinement.source}] ${update.refinement.context}: ${update.refinement.addition}`;
8733
- skill.notes = skill.notes ? `${skill.notes}
8734
- ${refinementNote}` : refinementNote;
8735
- modified = true;
8736
- }
8737
- if (update.confidenceAdjustment) {
8738
- skill.metrics.successRate = Math.max(
8739
- 0,
8740
- Math.min(1, skill.metrics.successRate + update.confidenceAdjustment)
8741
- );
8742
- modified = true;
8743
- }
8744
- if (update.incrementSuccess || update.incrementFailure) {
8745
- skill.metrics.usageCount++;
8746
- if (update.incrementSuccess) {
8747
- const total = skill.metrics.usageCount;
8748
- const currentSuccesses = skill.metrics.successRate * (total - 1);
8749
- skill.metrics.successRate = (currentSuccesses + 1) / total;
8750
- }
8751
- modified = true;
8752
- }
8753
- if (modified) {
8754
- skill.updatedAt = /* @__PURE__ */ new Date();
8755
- await this.storage.saveSkill(skill);
8756
- this.emit({ type: "skill:updated", skill, previousVersion: skill.version });
8757
- }
8758
- return modified;
8759
- }
8760
- /**
8761
- * Apply a demotion to an existing skill
8762
- */
8763
- async applyDemotion(demotion) {
8764
- const skill = await this.storage.getSkill(demotion.candidateId);
8765
- if (!skill) return;
8766
- skill.metrics.successRate = demotion.newConfidence;
8767
- if (demotion.deprecate) {
8768
- skill.status = "deprecated";
8769
- this.emit({ type: "skill:deprecated", skillId: skill.id });
8770
- }
8771
- skill.notes = skill.notes ? `${skill.notes}
8772
- [demotion] ${demotion.reason}` : `[demotion] ${demotion.reason}`;
8773
- skill.updatedAt = /* @__PURE__ */ new Date();
8774
- await this.storage.saveSkill(skill);
8775
- }
8776
- // ==========================================================================
8777
- // Anti-Pattern Management
8778
- // ==========================================================================
8779
- /**
8780
- * Get anti-patterns for a skill
8781
- */
8782
- async getAntiPatterns(skillId) {
8783
- return this.antiPatterns.get(skillId) ?? [];
8784
- }
8785
- /**
8786
- * Add an anti-pattern
8787
- */
8788
- async addAntiPattern(antiPattern) {
8789
- const existing = this.antiPatterns.get(antiPattern.candidateId) ?? [];
8790
- existing.push(antiPattern);
8791
- this.antiPatterns.set(antiPattern.candidateId, existing);
8792
- if (this.storage.saveAntiPatterns) {
8793
- const records = existing.map((ap) => ({
8794
- id: ap.id,
8795
- pattern: ap.pattern,
8796
- description: ap.reason,
8797
- context: ap.discoveredFrom,
8798
- severity: "warning",
8799
- learnedAt: ap.createdAt,
8800
- occurrences: 1
8801
- }));
8802
- await this.storage.saveAntiPatterns(antiPattern.candidateId, records);
8803
- }
8804
- }
8805
- /**
8806
- * Remove an anti-pattern by ID
8807
- */
8808
- async removeAntiPattern(antiPatternId) {
8809
- for (const [skillId, patterns] of this.antiPatterns.entries()) {
8810
- const index = patterns.findIndex((p) => p.id === antiPatternId);
8811
- if (index >= 0) {
8812
- patterns.splice(index, 1);
8813
- if (patterns.length === 0) {
8814
- this.antiPatterns.delete(skillId);
8815
- }
8816
- return true;
8817
- }
8818
- }
8819
- return false;
8820
- }
8821
- // ==========================================================================
8822
- // Candidate Lifecycle Management
8823
- // ==========================================================================
8824
- /**
8825
- * List pending learning candidates for review
8826
- */
8827
- async listCandidates(filter) {
8828
- this.ensureInitialized();
8829
- if (!this.storage.listCandidates) {
8830
- return [];
8831
- }
8832
- return this.storage.listCandidates(filter);
8833
- }
8834
- /**
8835
- * Get a specific candidate by ID
8836
- */
8837
- async getCandidate(id) {
8838
- this.ensureInitialized();
8839
- if (!this.storage.getCandidate) {
8840
- return null;
8841
- }
8842
- return this.storage.getCandidate(id);
8843
- }
8844
- /**
8845
- * Promote a candidate to a skill
8846
- * Works for strategy, pattern, and error-fix candidates that were stored for review
8847
- */
8848
- async promoteCandidate(candidateId) {
8849
- this.ensureInitialized();
8850
- if (!this.storage.getCandidate || !this.storage.updateCandidateStatus) {
8851
- throw new Error("Storage does not support candidate operations");
8852
- }
8853
- const record = await this.storage.getCandidate(candidateId);
8854
- if (!record) return null;
8855
- if (record.status !== "pending") {
8856
- throw new Error(`Cannot promote candidate with status: ${record.status}`);
8857
- }
8858
- const candidate = {
8859
- id: record.id,
8860
- kind: record.kind,
8861
- name: record.name,
8862
- content: record.content,
8863
- confidence: record.confidence,
8864
- source: {
8865
- provider: record.source.provider,
8866
- trajectoryId: record.source.trajectoryId,
8867
- extractedAt: record.source.extractedAt,
8868
- turnRange: record.source.turnRange ?? [0, 0]
8869
- },
8870
- tags: record.tags,
8871
- reasoning: record.reasoning
8872
- };
8873
- const skill = await this.promoteToSkill(candidate);
8874
- await this.storage.updateCandidateStatus(candidateId, "promoted", {
8875
- promotedToSkillId: skill.id
8876
- });
8877
- return skill;
8878
- }
8879
- /**
8880
- * Reject a candidate with a reason
8881
- */
8882
- async rejectCandidate(candidateId, reason) {
8883
- this.ensureInitialized();
8884
- if (!this.storage.updateCandidateStatus) {
8885
- throw new Error("Storage does not support candidate operations");
8886
- }
8887
- return this.storage.updateCandidateStatus(candidateId, "rejected", {
8888
- rejectionReason: reason
8889
- });
8890
- }
8891
- /**
8892
- * Delete a candidate
8893
- */
8894
- async deleteCandidate(candidateId) {
8895
- this.ensureInitialized();
8896
- if (!this.storage.deleteCandidate) {
8897
- return false;
8898
- }
8899
- return this.storage.deleteCandidate(candidateId);
8900
- }
8901
- /**
8902
- * Find skills with anti-pattern awareness
8903
- */
8904
- async findSkillsWithAntiPatterns(query, options) {
8905
- this.ensureInitialized();
8906
- const skills = await this.storage.listSkills({ status: ["active"] });
8907
- const matches = await this.semanticMatcher.findMatches(query, skills, {
8908
- threshold: options?.minSimilarity,
8909
- maxResults: options?.maxResults
8910
- });
8911
- const results = [];
8912
- for (const match of matches) {
8913
- const skillAntiPatterns = await this.getAntiPatterns(match.skill.id);
8914
- const warnings = [];
8915
- let relevantAntiPatterns;
8916
- if (options?.context && skillAntiPatterns.length > 0) {
8917
- relevantAntiPatterns = skillAntiPatterns.filter(
8918
- (ap) => options.context.toLowerCase().includes(ap.pattern.toLowerCase())
8919
- );
8920
- if (relevantAntiPatterns.length > 0) {
8921
- warnings.push(
8922
- `This skill has failed in similar contexts: ${relevantAntiPatterns.map((ap) => ap.reason).join("; ")}`
8923
- );
8924
- }
8925
- }
8926
- if (options?.excludeAntiPatternMatches && relevantAntiPatterns && relevantAntiPatterns.length > 0) {
8927
- continue;
8928
- }
8929
- if (match.skill.metrics.successRate < 0.5 && match.skill.metrics.usageCount > 2) {
8930
- warnings.push(`Low success rate: ${Math.round(match.skill.metrics.successRate * 100)}%`);
8931
- }
8932
- results.push({
8933
- ...match,
8934
- relevantAntiPatterns: relevantAntiPatterns && relevantAntiPatterns.length > 0 ? relevantAntiPatterns : void 0,
8935
- warnings: warnings.length > 0 ? warnings : void 0
8936
- });
8937
- }
8938
- return results;
8939
- }
8940
- // ==========================================================================
8941
- // Legacy Learning Methods (backwards compatibility)
8942
- // ==========================================================================
8943
- /**
8944
- * Extract learning candidates from a trajectory using a learning provider.
8945
- * @deprecated Use learnFrom() instead
8946
- */
8947
- async extractLearnings(trajectory, options) {
8948
- this.ensureInitialized();
8949
- const providerName = options?.provider ?? "naive";
8950
- const provider = this.learningProviders.get(providerName);
8951
- if (!provider) {
8952
- throw new Error(
8953
- `Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
8954
- );
8955
- }
8956
- const result = await provider.analyze(trajectory, options);
8957
- return result.candidates;
8958
- }
8959
- /**
8960
- * Extract learning candidates from multiple trajectories.
8961
- * @deprecated Use learnFromBatch() instead
8962
- */
8963
- async extractLearningsBatch(trajectories, options) {
8964
- this.ensureInitialized();
8965
- const providerName = options?.provider ?? "naive";
8966
- const provider = this.learningProviders.get(providerName);
8967
- if (!provider) {
8968
- throw new Error(`Learning provider not found: ${providerName}`);
8969
- }
8970
- if (provider.analyzeBatch) {
8971
- const result = await provider.analyzeBatch(trajectories, options);
8972
- return result.candidates;
8973
- }
8974
- const allCandidates = [];
8975
- for (const trajectory of trajectories) {
8976
- const result = await provider.analyze(trajectory, options);
8977
- allCandidates.push(...result.candidates);
8978
- }
8979
- return allCandidates;
8980
- }
8981
- /**
8982
- * Promote a learning candidate to a versioned skill.
8983
- * This converts the raw learning into a curated, versioned skill.
8984
- */
8985
- async promoteToSkill(candidate, options) {
8986
- this.ensureInitialized();
8987
- if (candidate.content.kind !== "skill") {
8988
- throw new Error(
8989
- `Cannot promote ${candidate.content.kind} to skill directly. Only 'skill' kind is supported.`
8990
- );
8991
- }
8992
- const agentId = this.activationManager.getCurrentAgentId();
8993
- const agentMetadata = this.activationManager.getAgentMetadata();
8994
- const agentName = agentMetadata?.agentName;
8995
- const content = candidate.content;
8996
- const skill = {
8997
- id: candidate.id,
8998
- name: candidate.name,
8999
- version: "1.0.0",
9000
- description: content.problem.substring(0, 150),
9001
- problem: content.problem,
9002
- triggerConditions: (content.triggers ?? []).map((t) => ({
9003
- type: t.type,
9004
- value: t.value,
9005
- description: t.description
9006
- })),
9007
- solution: content.solution,
9008
- verification: content.verification,
9009
- examples: (content.examples ?? []).map((e) => ({
9010
- scenario: e.scenario,
9011
- before: e.before,
9012
- after: e.after
9013
- })),
9014
- author: options?.author ?? agentName ?? candidate.source.provider,
9015
- tags: options?.tags ?? candidate.tags ?? [],
9016
- createdAt: /* @__PURE__ */ new Date(),
9017
- updatedAt: /* @__PURE__ */ new Date(),
9018
- status: options?.status ?? "draft",
9019
- metrics: {
9020
- usageCount: 0,
9021
- successRate: candidate.confidence,
9022
- feedbackScores: []
9023
- },
9024
- source: {
9025
- type: "extracted",
9026
- sessionId: candidate.source.trajectoryId,
9027
- importedAt: candidate.source.extractedAt,
9028
- agentId,
9029
- agentName
9030
- }
9031
- };
9032
- skill.serving = computeServingMetadata(skill);
9033
- await this.storage.saveSkill(skill);
9034
- this.emit({ type: "skill:created", skill });
9035
- if (this.validationEnabled && this.validator) {
9036
- this.runValidationAsync(skill).catch((err) => {
9037
- console.error("Validation error:", err);
9038
- });
9039
- }
9040
- if (this.compositionEnabled && this.composer) {
9041
- this.runCompositionSuggestionsAsync(skill).catch((err) => {
9042
- console.error("Composition suggestion error:", err);
9043
- });
9044
- }
9045
- return skill;
9046
7948
  }
9047
7949
  /**
9048
7950
  * Validate a skill and store the result
@@ -9501,7 +8403,6 @@ ${refinementNote}` : refinementNote;
9501
8403
  const deleted = await this.storage.deleteSkill(id, version);
9502
8404
  if (deleted) {
9503
8405
  this.emit({ type: "skill:deleted", skillId: id });
9504
- this.antiPatterns.delete(id);
9505
8406
  }
9506
8407
  return deleted;
9507
8408
  }
@@ -9975,8 +8876,7 @@ ${refinementNote}` : refinementNote;
9975
8876
  },
9976
8877
  byTag: {},
9977
8878
  avgSuccessRate: 0,
9978
- totalUsage: 0,
9979
- totalAntiPatterns: 0
8879
+ totalUsage: 0
9980
8880
  };
9981
8881
  if (this.namespaceConfig) {
9982
8882
  stats.byScope = { personal: 0, team: 0, global: 0 };
@@ -9994,10 +8894,6 @@ ${refinementNote}` : refinementNote;
9994
8894
  successRateSum += skill.metrics.successRate;
9995
8895
  successRateCount++;
9996
8896
  }
9997
- const ap = this.antiPatterns.get(skill.id);
9998
- if (ap) {
9999
- stats.totalAntiPatterns += ap.length;
10000
- }
10001
8897
  if (stats.byScope && stats.byVisibility) {
10002
8898
  const scope = skill.namespace?.scope || "personal";
10003
8899
  const visibility = skill.namespace?.visibility || "private";
@@ -15283,3 +14179,4 @@ program.addCommand(configCommand);
15283
14179
  program.addCommand(syncCommand2);
15284
14180
  program.addCommand(mcpCommand);
15285
14181
  program.parse();
14182
+ //# sourceMappingURL=index.js.map