@theglitchking/semantic-memory 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +81 -0
  4. package/LICENSES/Apache-2.0.txt +202 -0
  5. package/README.md +19 -2
  6. package/THIRD_PARTY_NOTICES.md +17 -0
  7. package/commands/jev-mode.md +18 -0
  8. package/commands/skill-loop.md +23 -0
  9. package/dist/chunk-2BFG4IBC.js +295 -0
  10. package/dist/chunk-2BFG4IBC.js.map +1 -0
  11. package/dist/chunk-2OMDSTSS.js +118 -0
  12. package/dist/chunk-2OMDSTSS.js.map +1 -0
  13. package/dist/{chunk-TMMTOFHI.js → chunk-34VN47IW.js} +2 -2
  14. package/dist/chunk-3ML5ESXI.js +224 -0
  15. package/dist/chunk-3ML5ESXI.js.map +1 -0
  16. package/dist/{chunk-ZLIHQZ4C.js → chunk-6TIKWOY4.js} +5 -5
  17. package/dist/{chunk-KSH2QO6V.js → chunk-7UAVDOI6.js} +5 -5
  18. package/dist/chunk-ACZKDSMP.js +123 -0
  19. package/dist/chunk-ACZKDSMP.js.map +1 -0
  20. package/dist/{chunk-PGVIBUL3.js → chunk-AIXQFTSB.js} +5 -5
  21. package/dist/chunk-BSXIGPDY.js +137 -0
  22. package/dist/chunk-BSXIGPDY.js.map +1 -0
  23. package/dist/{chunk-HZ7B5KHY.js → chunk-EXAUVIGW.js} +4 -4
  24. package/dist/chunk-GYR7U6KA.js +80 -0
  25. package/dist/chunk-GYR7U6KA.js.map +1 -0
  26. package/dist/chunk-M2PC64DB.js +195 -0
  27. package/dist/chunk-M2PC64DB.js.map +1 -0
  28. package/dist/chunk-MTLYF357.js +130 -0
  29. package/dist/chunk-MTLYF357.js.map +1 -0
  30. package/dist/chunk-N77YCMSX.js +113 -0
  31. package/dist/chunk-N77YCMSX.js.map +1 -0
  32. package/dist/chunk-PJXYCCI2.js +177 -0
  33. package/dist/chunk-PJXYCCI2.js.map +1 -0
  34. package/dist/chunk-PMOZKUEM.js +170 -0
  35. package/dist/chunk-PMOZKUEM.js.map +1 -0
  36. package/dist/chunk-R6GNP7DS.js +87 -0
  37. package/dist/chunk-R6GNP7DS.js.map +1 -0
  38. package/dist/chunk-TKHWVISV.js +71 -0
  39. package/dist/chunk-TKHWVISV.js.map +1 -0
  40. package/dist/chunk-V6PSK4Y4.js +186 -0
  41. package/dist/chunk-V6PSK4Y4.js.map +1 -0
  42. package/dist/{chunk-GYBUBJYM.js → chunk-VBLCUWT4.js} +17 -8
  43. package/dist/chunk-VBLCUWT4.js.map +1 -0
  44. package/dist/chunk-VQCNWRTL.js +121 -0
  45. package/dist/chunk-VQCNWRTL.js.map +1 -0
  46. package/dist/{chunk-HUG7E25D.js → chunk-Y7H76Q7F.js} +1 -1
  47. package/dist/chunk-Y7H76Q7F.js.map +1 -0
  48. package/dist/chunk-ZSWI3Y4Y.js +232 -0
  49. package/dist/chunk-ZSWI3Y4Y.js.map +1 -0
  50. package/dist/cli/index.js +381 -52
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/core/features.d.ts +38 -0
  53. package/dist/core/features.js +28 -0
  54. package/dist/core/index.d.ts +285 -2
  55. package/dist/core/index.js +170 -21
  56. package/dist/core/index.js.map +1 -1
  57. package/dist/core/jev.d.ts +35 -0
  58. package/dist/core/jev.js +20 -0
  59. package/dist/core/skill-curator.d.ts +1 -0
  60. package/dist/core/skill-curator.js +41 -0
  61. package/dist/core/skill-evidence.d.ts +25 -0
  62. package/dist/core/skill-evidence.js +23 -0
  63. package/dist/core/skill-queue.d.ts +46 -0
  64. package/dist/core/skill-queue.js +42 -0
  65. package/dist/core/skill-review.d.ts +3 -0
  66. package/dist/core/skill-review.js +29 -0
  67. package/dist/core/skill-worker.d.ts +21 -0
  68. package/dist/core/skill-worker.js +70 -0
  69. package/dist/core/skill-worker.js.map +1 -0
  70. package/dist/{dossier-EN26WDKC.js → dossier-RXBLQOXC.js} +3 -3
  71. package/dist/failure-eval-IUJO47UC.js +18 -0
  72. package/dist/failure-eval-IUJO47UC.js.map +1 -0
  73. package/dist/{healthcheck-53OVXUQQ.js → healthcheck-S7D6YNTA.js} +7 -7
  74. package/dist/healthcheck-S7D6YNTA.js.map +1 -0
  75. package/dist/{lexicon-XNA5IFIA.js → lexicon-SEJSLBHO.js} +4 -4
  76. package/dist/lexicon-SEJSLBHO.js.map +1 -0
  77. package/dist/{lint-O4RQ47NX.js → lint-3JNLRM5U.js} +6 -6
  78. package/dist/lint-3JNLRM5U.js.map +1 -0
  79. package/dist/mcp/server.js +19 -17
  80. package/dist/mcp/server.js.map +1 -1
  81. package/dist/{profile-SIWAVD7O.js → profile-SNULTJ27.js} +4 -4
  82. package/dist/profile-SNULTJ27.js.map +1 -0
  83. package/dist/{schema-UJNYYRZZ.js → schema-RDYUK6CC.js} +2 -2
  84. package/dist/schema-RDYUK6CC.js.map +1 -0
  85. package/dist/skill-curator-D7HHZaUI.d.ts +71 -0
  86. package/dist/skill-land-EHXZW47F.js +31 -0
  87. package/dist/skill-land-EHXZW47F.js.map +1 -0
  88. package/dist/skill-ledger-AYXVNFX7.js +18 -0
  89. package/dist/skill-ledger-AYXVNFX7.js.map +1 -0
  90. package/dist/skill-merge-HBZBALZX.js +24 -0
  91. package/dist/skill-merge-HBZBALZX.js.map +1 -0
  92. package/dist/skill-review-BNvHipn9.d.ts +182 -0
  93. package/dist/skill-schema-RVB3EHEF.js +30 -0
  94. package/dist/skill-schema-RVB3EHEF.js.map +1 -0
  95. package/hooks/hooks.json +26 -1
  96. package/hooks/jev-bridge.py +109 -0
  97. package/hooks/session-start.js +5 -0
  98. package/hooks/skill-loop.js +65 -0
  99. package/hooks/vault-context.js +104 -6
  100. package/package.json +4 -2
  101. package/dist/chunk-5F5ZIAW2.js +0 -79
  102. package/dist/chunk-5F5ZIAW2.js.map +0 -1
  103. package/dist/chunk-GYBUBJYM.js.map +0 -1
  104. package/dist/chunk-HUG7E25D.js.map +0 -1
  105. package/dist/failure-eval-37JRNTIW.js +0 -10
  106. /package/dist/{chunk-TMMTOFHI.js.map → chunk-34VN47IW.js.map} +0 -0
  107. /package/dist/{chunk-ZLIHQZ4C.js.map → chunk-6TIKWOY4.js.map} +0 -0
  108. /package/dist/{chunk-KSH2QO6V.js.map → chunk-7UAVDOI6.js.map} +0 -0
  109. /package/dist/{chunk-PGVIBUL3.js.map → chunk-AIXQFTSB.js.map} +0 -0
  110. /package/dist/{chunk-HZ7B5KHY.js.map → chunk-EXAUVIGW.js.map} +0 -0
  111. /package/dist/{dossier-EN26WDKC.js.map → core/features.js.map} +0 -0
  112. /package/dist/{failure-eval-37JRNTIW.js.map → core/jev.js.map} +0 -0
  113. /package/dist/{healthcheck-53OVXUQQ.js.map → core/skill-curator.js.map} +0 -0
  114. /package/dist/{lexicon-XNA5IFIA.js.map → core/skill-evidence.js.map} +0 -0
  115. /package/dist/{lint-O4RQ47NX.js.map → core/skill-queue.js.map} +0 -0
  116. /package/dist/{profile-SIWAVD7O.js.map → core/skill-review.js.map} +0 -0
  117. /package/dist/{schema-UJNYYRZZ.js.map → dossier-RXBLQOXC.js.map} +0 -0
@@ -0,0 +1,35 @@
1
+ type JevCaller = "semantic-memory-hook" | "semantic-memory-judge" | "semantic-memory-skill-loop";
2
+ interface JevQuestion {
3
+ key: string;
4
+ instructions: string;
5
+ }
6
+ interface JevAnswer {
7
+ scores: Record<string, number>;
8
+ tokens?: number;
9
+ error?: string;
10
+ /** The live caller's daily ceiling was reached: nothing was sent. */
11
+ ceiling?: boolean;
12
+ }
13
+ /** jev-loop's bar: act on a yes only at or above it, on a no only at or below 1 - it. */
14
+ declare const JEV_BAR = 0.95;
15
+ declare const BRIDGE: string;
16
+ declare function askJev(input: {
17
+ cwd: string;
18
+ caller: JevCaller;
19
+ state: string;
20
+ questions: JevQuestion[];
21
+ }, opts?: {
22
+ timeoutMs?: number;
23
+ env?: NodeJS.ProcessEnv;
24
+ bridge?: string;
25
+ }): Promise<JevAnswer>;
26
+ /** Tokens each semantic-memory caller spent with Jev today, from jev-loop's usage ledger (numbers only). */
27
+ declare function jevSpendToday(jevDir: string, now?: Date): Record<string, number>;
28
+ /** A Jev probability as a verdict: yes at or above the bar, no at or below 1 − bar, otherwise unsure (null). */
29
+ declare const jevVerdict: (p: number | undefined, bar?: number) => boolean | null;
30
+ /** The failure → document relevance question (judge, gate and the failure hook ask the same thing). */
31
+ declare const relevanceQuestion: (title: string, excerpt: string) => string;
32
+ /** The state Jev sees for a failed tool call: the command and its error, capped. */
33
+ declare const failureState: (command: string, error: string) => string;
34
+
35
+ export { BRIDGE, JEV_BAR, type JevAnswer, type JevCaller, type JevQuestion, askJev, failureState, jevSpendToday, jevVerdict, relevanceQuestion };
@@ -0,0 +1,20 @@
1
+ import {
2
+ BRIDGE,
3
+ JEV_BAR,
4
+ askJev,
5
+ failureState,
6
+ jevSpendToday,
7
+ jevVerdict,
8
+ relevanceQuestion
9
+ } from "../chunk-GYR7U6KA.js";
10
+ import "../chunk-PZ5AY32C.js";
11
+ export {
12
+ BRIDGE,
13
+ JEV_BAR,
14
+ askJev,
15
+ failureState,
16
+ jevSpendToday,
17
+ jevVerdict,
18
+ relevanceQuestion
19
+ };
20
+ //# sourceMappingURL=jev.js.map
@@ -0,0 +1 @@
1
+ export { A as ARCHIVE_DAYS, C as CURATOR_INTERVAL_DAYS, d as CuratorAction, I as IDLE_HOURS, S as STALE_DAYS, c as curate, e as curatorDue, f as curatorState, g as curatorStatePath, l as listArchived, p as plan, a as restore, v as verifySkills } from '../skill-curator-D7HHZaUI.js';
@@ -0,0 +1,41 @@
1
+ import {
2
+ ARCHIVE_DAYS,
3
+ CURATOR_INTERVAL_DAYS,
4
+ IDLE_HOURS,
5
+ STALE_DAYS,
6
+ curate,
7
+ curatorDue,
8
+ curatorState,
9
+ curatorStatePath,
10
+ listArchived,
11
+ plan,
12
+ restore,
13
+ verifySkills
14
+ } from "../chunk-V6PSK4Y4.js";
15
+ import "../chunk-TKHWVISV.js";
16
+ import "../chunk-N77YCMSX.js";
17
+ import "../chunk-MTLYF357.js";
18
+ import "../chunk-PMOZKUEM.js";
19
+ import "../chunk-ZSWI3Y4Y.js";
20
+ import "../chunk-J7LYDRML.js";
21
+ import "../chunk-VQCNWRTL.js";
22
+ import "../chunk-GYR7U6KA.js";
23
+ import "../chunk-M2PC64DB.js";
24
+ import "../chunk-R6GNP7DS.js";
25
+ import "../chunk-H2BES6FU.js";
26
+ import "../chunk-PZ5AY32C.js";
27
+ export {
28
+ ARCHIVE_DAYS,
29
+ CURATOR_INTERVAL_DAYS,
30
+ IDLE_HOURS,
31
+ STALE_DAYS,
32
+ curate,
33
+ curatorDue,
34
+ curatorState,
35
+ curatorStatePath,
36
+ listArchived,
37
+ plan,
38
+ restore,
39
+ verifySkills
40
+ };
41
+ //# sourceMappingURL=skill-curator.js.map
@@ -0,0 +1,25 @@
1
+ type EvidenceKind = "usage" | "failures" | "corrections";
2
+ declare const stateDir: (repoRoot: string) => string;
3
+ declare const evidencePath: (repoRoot: string, kind: EvidenceKind) => string;
4
+ /** The repo a hook's cwd belongs to: the nearest ancestor holding .git, else the cwd itself. */
5
+ declare function repoRoot(cwd: string): string;
6
+ declare function appendEvidence(root: string, kind: EvidenceKind, record: Record<string, unknown>, env?: NodeJS.ProcessEnv): void;
7
+ declare function readEvidence<T = Record<string, any>>(root: string, kind: EvidenceKind): T[];
8
+ declare const failureRecord: (input: {
9
+ session_id?: string;
10
+ tool_use_id?: string;
11
+ tool_name?: string;
12
+ tool_input?: any;
13
+ error?: string;
14
+ }) => {
15
+ session_id: string | null;
16
+ id: string | null;
17
+ tool: string | null;
18
+ command: string;
19
+ error: string;
20
+ };
21
+ declare function detectCorrection(prompt: string): string | null;
22
+ /** `/name …` typed by the user: Claude Code runs the skill without a Skill tool call, so PostToolUse never sees it. */
23
+ declare function slashSkill(prompt: string): string | null;
24
+
25
+ export { type EvidenceKind, appendEvidence, detectCorrection, evidencePath, failureRecord, readEvidence, repoRoot, slashSkill, stateDir };
@@ -0,0 +1,23 @@
1
+ import {
2
+ appendEvidence,
3
+ detectCorrection,
4
+ evidencePath,
5
+ failureRecord,
6
+ readEvidence,
7
+ repoRoot,
8
+ slashSkill,
9
+ stateDir
10
+ } from "../chunk-R6GNP7DS.js";
11
+ import "../chunk-H2BES6FU.js";
12
+ import "../chunk-PZ5AY32C.js";
13
+ export {
14
+ appendEvidence,
15
+ detectCorrection,
16
+ evidencePath,
17
+ failureRecord,
18
+ readEvidence,
19
+ repoRoot,
20
+ slashSkill,
21
+ stateDir
22
+ };
23
+ //# sourceMappingURL=skill-evidence.js.map
@@ -0,0 +1,46 @@
1
+ interface ReviewJob {
2
+ session_id: string;
3
+ repo: string;
4
+ transcript_path: string | null;
5
+ reason: string;
6
+ ts: string;
7
+ evidence: {
8
+ failures: string[];
9
+ corrections: number;
10
+ skills_used: string[];
11
+ tool_calls: number;
12
+ };
13
+ attempts?: number;
14
+ /** a follow-up review of a resumed session: only evidence recorded after this time (the last review's end) */
15
+ since?: string;
16
+ }
17
+ declare const smHome: (env?: NodeJS.ProcessEnv) => string;
18
+ declare const queueDir: (env?: NodeJS.ProcessEnv) => string;
19
+ declare const lockPath: (repo: string) => string;
20
+ declare const logPath: (repo: string) => string;
21
+ declare const dailyRunCap: (env?: NodeJS.ProcessEnv) => number;
22
+ /** Throwaway repos (test runs, benchmarks in mkdtemp dirs) are never reviewed: they would use the daily cap. */
23
+ declare function inTempDir(repo: string, env?: NodeJS.ProcessEnv): boolean;
24
+ /** When this session's last review finished (done or failed record), or null if it was never reviewed. */
25
+ declare function reviewedAt(session_id: string, env?: NodeJS.ProcessEnv): string | null;
26
+ /** The job SessionEnd would write for this session, or null when the session has nothing to learn from. */
27
+ declare function sessionJob(repo: string, input: {
28
+ session_id?: string;
29
+ transcript_path?: string;
30
+ reason?: string;
31
+ }, env?: NodeJS.ProcessEnv): ReviewJob | null;
32
+ declare function enqueue(job: ReviewJob, env?: NodeJS.ProcessEnv): string;
33
+ declare function pendingJobs(repo: string, env?: NodeJS.ProcessEnv): {
34
+ path: string;
35
+ job: ReviewJob;
36
+ }[];
37
+ declare function finishJob(path: string, outcome: "done" | "failed", result: Record<string, unknown>, env?: NodeJS.ProcessEnv): void;
38
+ declare function bumpAttempts(path: string): number;
39
+ declare function runsToday(env?: NodeJS.ProcessEnv, now?: Date): number;
40
+ declare function recordRun(repo: string, session_id: string, env?: NodeJS.ProcessEnv, now?: Date): void;
41
+ declare function lockHolder(repo: string): number | null;
42
+ /** Take the repo's worker lock (reclaiming a dead holder's). Returns a release function, or null if held. */
43
+ declare function takeLock(repo: string): (() => void) | null;
44
+ declare function log(repo: string, line: string): void;
45
+
46
+ export { type ReviewJob, bumpAttempts, dailyRunCap, enqueue, finishJob, inTempDir, lockHolder, lockPath, log, logPath, pendingJobs, queueDir, recordRun, reviewedAt, runsToday, sessionJob, smHome, takeLock };
@@ -0,0 +1,42 @@
1
+ import {
2
+ bumpAttempts,
3
+ dailyRunCap,
4
+ enqueue,
5
+ finishJob,
6
+ inTempDir,
7
+ lockHolder,
8
+ lockPath,
9
+ log,
10
+ logPath,
11
+ pendingJobs,
12
+ queueDir,
13
+ recordRun,
14
+ reviewedAt,
15
+ runsToday,
16
+ sessionJob,
17
+ smHome,
18
+ takeLock
19
+ } from "../chunk-M2PC64DB.js";
20
+ import "../chunk-R6GNP7DS.js";
21
+ import "../chunk-H2BES6FU.js";
22
+ import "../chunk-PZ5AY32C.js";
23
+ export {
24
+ bumpAttempts,
25
+ dailyRunCap,
26
+ enqueue,
27
+ finishJob,
28
+ inTempDir,
29
+ lockHolder,
30
+ lockPath,
31
+ log,
32
+ logPath,
33
+ pendingJobs,
34
+ queueDir,
35
+ recordRun,
36
+ reviewedAt,
37
+ runsToday,
38
+ sessionJob,
39
+ smHome,
40
+ takeLock
41
+ };
42
+ //# sourceMappingURL=skill-queue.js.map
@@ -0,0 +1,3 @@
1
+ export { D as DraftRecord, R as ReviewOptions, q as ReviewerDraft, s as ScopeResolver, h as buildBrief, j as draftsDir, n as listDrafts, t as materializeDraft, u as parseReviewerJson, o as reviewSession, v as transcriptTimeline } from '../skill-review-BNvHipn9.js';
2
+ import './skill-queue.js';
3
+ import './skill-worker.js';
@@ -0,0 +1,29 @@
1
+ import {
2
+ buildBrief,
3
+ draftsDir,
4
+ listDrafts,
5
+ materializeDraft,
6
+ parseReviewerJson,
7
+ reviewSession,
8
+ transcriptTimeline
9
+ } from "../chunk-2BFG4IBC.js";
10
+ import "../chunk-N77YCMSX.js";
11
+ import "../chunk-PMOZKUEM.js";
12
+ import "../chunk-ZSWI3Y4Y.js";
13
+ import "../chunk-J7LYDRML.js";
14
+ import "../chunk-VQCNWRTL.js";
15
+ import "../chunk-GYR7U6KA.js";
16
+ import "../chunk-M2PC64DB.js";
17
+ import "../chunk-R6GNP7DS.js";
18
+ import "../chunk-H2BES6FU.js";
19
+ import "../chunk-PZ5AY32C.js";
20
+ export {
21
+ buildBrief,
22
+ draftsDir,
23
+ listDrafts,
24
+ materializeDraft,
25
+ parseReviewerJson,
26
+ reviewSession,
27
+ transcriptTimeline
28
+ };
29
+ //# sourceMappingURL=skill-review.js.map
@@ -0,0 +1,21 @@
1
+ import { ReviewJob } from './skill-queue.js';
2
+
3
+ interface ReviewOutcome {
4
+ drafts: string[];
5
+ rejected: {
6
+ reason: string;
7
+ }[];
8
+ costUsd: number;
9
+ note?: string;
10
+ }
11
+ declare const MAX_ATTEMPTS = 3;
12
+ declare function drain(repo: string, review: (job: ReviewJob) => Promise<ReviewOutcome>, env?: NodeJS.ProcessEnv): Promise<{
13
+ locked: boolean;
14
+ reviewed: number;
15
+ capped: boolean;
16
+ failed: number;
17
+ }>;
18
+ /** Start `semantic-memory skill-loop worker --repo <repo>` detached, unless a live worker holds the repo's lock. */
19
+ declare function spawnWorker(repo: string, env?: NodeJS.ProcessEnv): boolean;
20
+
21
+ export { MAX_ATTEMPTS, type ReviewOutcome, drain, spawnWorker };
@@ -0,0 +1,70 @@
1
+ import {
2
+ bumpAttempts,
3
+ dailyRunCap,
4
+ finishJob,
5
+ lockHolder,
6
+ log,
7
+ pendingJobs,
8
+ recordRun,
9
+ runsToday,
10
+ takeLock
11
+ } from "../chunk-M2PC64DB.js";
12
+ import "../chunk-R6GNP7DS.js";
13
+ import "../chunk-H2BES6FU.js";
14
+ import "../chunk-PZ5AY32C.js";
15
+
16
+ // src/core/skill-worker.ts
17
+ import { spawn } from "child_process";
18
+ import { fileURLToPath } from "url";
19
+ import { existsSync } from "fs";
20
+ var MAX_ATTEMPTS = 3;
21
+ async function drain(repo, review, env = process.env) {
22
+ const release = takeLock(repo);
23
+ if (!release) return { locked: true, reviewed: 0, capped: false, failed: 0 };
24
+ let reviewed = 0, failed = 0, capped = false;
25
+ try {
26
+ for (let next = pendingJobs(repo, env)[0]; next; next = pendingJobs(repo, env)[0]) {
27
+ if (runsToday(env) >= dailyRunCap(env)) {
28
+ capped = true;
29
+ log(repo, `daily cap reached (${dailyRunCap(env)} reviews; SEMANTIC_MEMORY_SKILL_LOOP_DAILY_RUNS): ${pendingJobs(repo, env).length} job(s) wait for tomorrow`);
30
+ break;
31
+ }
32
+ const attempts = bumpAttempts(next.path);
33
+ if (attempts > MAX_ATTEMPTS) {
34
+ finishJob(next.path, "failed", { reason: `gave up after ${MAX_ATTEMPTS} attempts` }, env);
35
+ failed++;
36
+ continue;
37
+ }
38
+ recordRun(repo, next.job.session_id, env);
39
+ try {
40
+ const outcome = await review(next.job);
41
+ finishJob(next.path, "done", { ...outcome }, env);
42
+ reviewed++;
43
+ log(repo, `reviewed ${next.job.session_id} (${next.job.reason}): ${outcome.drafts.length} draft(s), ${outcome.rejected.length} rejected, $${outcome.costUsd.toFixed(3)}${outcome.note ? ` \u2014 ${outcome.note}` : ""}`);
44
+ } catch (e) {
45
+ log(repo, `review of ${next.job.session_id} failed (attempt ${attempts}): ${e.message}`);
46
+ if (attempts >= MAX_ATTEMPTS) {
47
+ finishJob(next.path, "failed", { reason: e.message }, env);
48
+ failed++;
49
+ } else break;
50
+ }
51
+ }
52
+ } finally {
53
+ release();
54
+ }
55
+ return { locked: false, reviewed, capped, failed };
56
+ }
57
+ function spawnWorker(repo, env = process.env) {
58
+ if (lockHolder(repo) !== null) return false;
59
+ const cli = ["../cli/index.js", "./cli/index.js", "../../dist/cli/index.js"].map((p) => fileURLToPath(new URL(p, import.meta.url))).find((p) => existsSync(p));
60
+ if (!cli) return false;
61
+ const child = spawn(process.execPath, [cli, "skill-loop", "worker", "--repo", repo], { cwd: repo, env, detached: true, stdio: "ignore" });
62
+ child.unref();
63
+ return true;
64
+ }
65
+ export {
66
+ MAX_ATTEMPTS,
67
+ drain,
68
+ spawnWorker
69
+ };
70
+ //# sourceMappingURL=skill-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/skill-worker.ts"],"sourcesContent":["/**\n * The skill loop's worker (v1.7): drains one repo's review queue, oldest job first, one worker per repo\n * (lock), stopping at the global daily cap (SEMANTIC_MEMORY_SKILL_LOOP_DAILY_RUNS, default 10). A job is\n * moved to done/ only after its review returns, so a crash leaves it queued; after 3 attempts it goes to\n * failed/ instead of retrying forever. Started detached by SessionEnd; also `semantic-memory skill-loop worker`.\n */\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport { existsSync } from \"node:fs\";\nimport { bumpAttempts, dailyRunCap, finishJob, lockHolder, log, pendingJobs, recordRun, runsToday, takeLock, type ReviewJob } from \"./skill-queue.js\";\n\nexport interface ReviewOutcome {\n drafts: string[];\n rejected: { reason: string }[];\n costUsd: number;\n note?: string;\n}\n\nexport const MAX_ATTEMPTS = 3;\n\nexport async function drain(\n repo: string,\n review: (job: ReviewJob) => Promise<ReviewOutcome>,\n env = process.env,\n): Promise<{ locked: boolean; reviewed: number; capped: boolean; failed: number }> {\n const release = takeLock(repo);\n if (!release) return { locked: true, reviewed: 0, capped: false, failed: 0 };\n let reviewed = 0, failed = 0, capped = false;\n try {\n // re-read each time: SessionEnds of other sessions may add jobs while this one drains\n for (let next = pendingJobs(repo, env)[0]; next; next = pendingJobs(repo, env)[0]) {\n if (runsToday(env) >= dailyRunCap(env)) {\n capped = true;\n log(repo, `daily cap reached (${dailyRunCap(env)} reviews; SEMANTIC_MEMORY_SKILL_LOOP_DAILY_RUNS): ${pendingJobs(repo, env).length} job(s) wait for tomorrow`);\n break;\n }\n const attempts = bumpAttempts(next.path);\n if (attempts > MAX_ATTEMPTS) {\n finishJob(next.path, \"failed\", { reason: `gave up after ${MAX_ATTEMPTS} attempts` }, env);\n failed++;\n continue;\n }\n recordRun(repo, next.job.session_id, env);\n try {\n const outcome = await review(next.job);\n finishJob(next.path, \"done\", { ...outcome }, env);\n reviewed++;\n log(repo, `reviewed ${next.job.session_id} (${next.job.reason}): ${outcome.drafts.length} draft(s), ${outcome.rejected.length} rejected, $${outcome.costUsd.toFixed(3)}${outcome.note ? ` — ${outcome.note}` : \"\"}`);\n } catch (e) {\n log(repo, `review of ${next.job.session_id} failed (attempt ${attempts}): ${(e as Error).message}`);\n if (attempts >= MAX_ATTEMPTS) {\n finishJob(next.path, \"failed\", { reason: (e as Error).message }, env);\n failed++;\n } else break; // leave it queued for the next worker start\n }\n }\n } finally {\n release();\n }\n return { locked: false, reviewed, capped, failed };\n}\n\n/** Start `semantic-memory skill-loop worker --repo <repo>` detached, unless a live worker holds the repo's lock. */\nexport function spawnWorker(repo: string, env = process.env): boolean {\n if (lockHolder(repo) !== null) return false;\n // from dist/core, a dist/ chunk, or src/core (tests)\n const cli = [\"../cli/index.js\", \"./cli/index.js\", \"../../dist/cli/index.js\"].map((p) => fileURLToPath(new URL(p, import.meta.url))).find((p) => existsSync(p));\n if (!cli) return false;\n const child = spawn(process.execPath, [cli, \"skill-loop\", \"worker\", \"--repo\", repo], { cwd: repo, env, detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAMA,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAUpB,IAAM,eAAe;AAE5B,eAAsB,MACpB,MACA,QACA,MAAM,QAAQ,KACmE;AACjF,QAAM,UAAU,SAAS,IAAI;AAC7B,MAAI,CAAC,QAAS,QAAO,EAAE,QAAQ,MAAM,UAAU,GAAG,QAAQ,OAAO,QAAQ,EAAE;AAC3E,MAAI,WAAW,GAAG,SAAS,GAAG,SAAS;AACvC,MAAI;AAEF,aAAS,OAAO,YAAY,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,OAAO,YAAY,MAAM,GAAG,EAAE,CAAC,GAAG;AACjF,UAAI,UAAU,GAAG,KAAK,YAAY,GAAG,GAAG;AACtC,iBAAS;AACT,YAAI,MAAM,sBAAsB,YAAY,GAAG,CAAC,qDAAqD,YAAY,MAAM,GAAG,EAAE,MAAM,2BAA2B;AAC7J;AAAA,MACF;AACA,YAAM,WAAW,aAAa,KAAK,IAAI;AACvC,UAAI,WAAW,cAAc;AAC3B,kBAAU,KAAK,MAAM,UAAU,EAAE,QAAQ,iBAAiB,YAAY,YAAY,GAAG,GAAG;AACxF;AACA;AAAA,MACF;AACA,gBAAU,MAAM,KAAK,IAAI,YAAY,GAAG;AACxC,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,KAAK,GAAG;AACrC,kBAAU,KAAK,MAAM,QAAQ,EAAE,GAAG,QAAQ,GAAG,GAAG;AAChD;AACA,YAAI,MAAM,YAAY,KAAK,IAAI,UAAU,KAAK,KAAK,IAAI,MAAM,MAAM,QAAQ,OAAO,MAAM,cAAc,QAAQ,SAAS,MAAM,eAAe,QAAQ,QAAQ,QAAQ,CAAC,CAAC,GAAG,QAAQ,OAAO,WAAM,QAAQ,IAAI,KAAK,EAAE,EAAE;AAAA,MACrN,SAAS,GAAG;AACV,YAAI,MAAM,aAAa,KAAK,IAAI,UAAU,oBAAoB,QAAQ,MAAO,EAAY,OAAO,EAAE;AAClG,YAAI,YAAY,cAAc;AAC5B,oBAAU,KAAK,MAAM,UAAU,EAAE,QAAS,EAAY,QAAQ,GAAG,GAAG;AACpE;AAAA,QACF,MAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,UAAE;AACA,YAAQ;AAAA,EACV;AACA,SAAO,EAAE,QAAQ,OAAO,UAAU,QAAQ,OAAO;AACnD;AAGO,SAAS,YAAY,MAAc,MAAM,QAAQ,KAAc;AACpE,MAAI,WAAW,IAAI,MAAM,KAAM,QAAO;AAEtC,QAAM,MAAM,CAAC,mBAAmB,kBAAkB,yBAAyB,EAAE,IAAI,CAAC,MAAM,cAAc,IAAI,IAAI,GAAG,YAAY,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;AAC7J,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,KAAK,cAAc,UAAU,UAAU,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK,UAAU,MAAM,OAAO,SAAS,CAAC;AACxI,QAAM,MAAM;AACZ,SAAO;AACT;","names":[]}
@@ -15,10 +15,10 @@ import {
15
15
  resolveDossierPath,
16
16
  setCurrentState,
17
17
  slugifyEntity
18
- } from "./chunk-HZ7B5KHY.js";
18
+ } from "./chunk-EXAUVIGW.js";
19
19
  import "./chunk-EYVFC745.js";
20
- import "./chunk-H2BES6FU.js";
21
20
  import "./chunk-J7LYDRML.js";
21
+ import "./chunk-H2BES6FU.js";
22
22
  import "./chunk-PZ5AY32C.js";
23
23
  export {
24
24
  DOSSIER_DIR,
@@ -38,4 +38,4 @@ export {
38
38
  setCurrentState,
39
39
  slugifyEntity
40
40
  };
41
- //# sourceMappingURL=dossier-EN26WDKC.js.map
41
+ //# sourceMappingURL=dossier-RXBLQOXC.js.map
@@ -0,0 +1,18 @@
1
+ import {
2
+ calibrateJudge,
3
+ evaluateFailures,
4
+ evaluateGate,
5
+ formatFailureEval,
6
+ formatGate,
7
+ meetsBar
8
+ } from "./chunk-PJXYCCI2.js";
9
+ import "./chunk-PZ5AY32C.js";
10
+ export {
11
+ calibrateJudge,
12
+ evaluateFailures,
13
+ evaluateGate,
14
+ formatFailureEval,
15
+ formatGate,
16
+ meetsBar
17
+ };
18
+ //# sourceMappingURL=failure-eval-IUJO47UC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -2,20 +2,20 @@ import {
2
2
  filterToDrift,
3
3
  formatDriftBanner,
4
4
  runHealthcheck
5
- } from "./chunk-TMMTOFHI.js";
6
- import "./chunk-GYBUBJYM.js";
7
- import "./chunk-HUG7E25D.js";
5
+ } from "./chunk-34VN47IW.js";
6
+ import "./chunk-VBLCUWT4.js";
7
+ import "./chunk-Y7H76Q7F.js";
8
8
  import "./chunk-5ZKNO6ZD.js";
9
9
  import "./chunk-7M34JDTH.js";
10
- import "./chunk-KSH2QO6V.js";
11
- import "./chunk-HZ7B5KHY.js";
10
+ import "./chunk-7UAVDOI6.js";
11
+ import "./chunk-EXAUVIGW.js";
12
12
  import "./chunk-EYVFC745.js";
13
- import "./chunk-H2BES6FU.js";
14
13
  import "./chunk-J7LYDRML.js";
14
+ import "./chunk-H2BES6FU.js";
15
15
  import "./chunk-PZ5AY32C.js";
16
16
  export {
17
17
  filterToDrift,
18
18
  formatDriftBanner,
19
19
  runHealthcheck
20
20
  };
21
- //# sourceMappingURL=healthcheck-53OVXUQQ.js.map
21
+ //# sourceMappingURL=healthcheck-S7D6YNTA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -8,11 +8,11 @@ import {
8
8
  normalizePhrase,
9
9
  removeAlias,
10
10
  slugify
11
- } from "./chunk-KSH2QO6V.js";
12
- import "./chunk-HZ7B5KHY.js";
11
+ } from "./chunk-7UAVDOI6.js";
12
+ import "./chunk-EXAUVIGW.js";
13
13
  import "./chunk-EYVFC745.js";
14
- import "./chunk-H2BES6FU.js";
15
14
  import "./chunk-J7LYDRML.js";
15
+ import "./chunk-H2BES6FU.js";
16
16
  import "./chunk-PZ5AY32C.js";
17
17
  export {
18
18
  addAlias,
@@ -25,4 +25,4 @@ export {
25
25
  removeAlias,
26
26
  slugify
27
27
  };
28
- //# sourceMappingURL=lexicon-XNA5IFIA.js.map
28
+ //# sourceMappingURL=lexicon-SEJSLBHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  formatLintReport,
3
3
  lintVault
4
- } from "./chunk-GYBUBJYM.js";
5
- import "./chunk-HUG7E25D.js";
4
+ } from "./chunk-VBLCUWT4.js";
5
+ import "./chunk-Y7H76Q7F.js";
6
6
  import "./chunk-5ZKNO6ZD.js";
7
7
  import "./chunk-7M34JDTH.js";
8
- import "./chunk-KSH2QO6V.js";
9
- import "./chunk-HZ7B5KHY.js";
8
+ import "./chunk-7UAVDOI6.js";
9
+ import "./chunk-EXAUVIGW.js";
10
10
  import "./chunk-EYVFC745.js";
11
- import "./chunk-H2BES6FU.js";
12
11
  import "./chunk-J7LYDRML.js";
12
+ import "./chunk-H2BES6FU.js";
13
13
  import "./chunk-PZ5AY32C.js";
14
14
  export {
15
15
  formatLintReport,
16
16
  lintVault
17
17
  };
18
- //# sourceMappingURL=lint-O4RQ47NX.js.map
18
+ //# sourceMappingURL=lint-3JNLRM5U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  initSpeakerProfile,
4
4
  readSpeakerProfile,
5
5
  updateProfileSection
6
- } from "../chunk-ZLIHQZ4C.js";
6
+ } from "../chunk-6TIKWOY4.js";
7
7
  import {
8
8
  FrontmatterManager,
9
9
  NoteCrud,
@@ -17,23 +17,19 @@ import {
17
17
  regenDirectoryIndex,
18
18
  regenIndexesForPaths,
19
19
  regenerateAgentsContract
20
- } from "../chunk-PGVIBUL3.js";
20
+ } from "../chunk-AIXQFTSB.js";
21
21
  import {
22
22
  Embedder,
23
23
  GraphBuilder,
24
24
  TextSearch,
25
25
  VectorIndex
26
26
  } from "../chunk-SHSOCFJH.js";
27
- import {
28
- logEvent,
29
- logQuery
30
- } from "../chunk-XKGK643R.js";
31
27
  import {
32
28
  lintVault
33
- } from "../chunk-GYBUBJYM.js";
29
+ } from "../chunk-VBLCUWT4.js";
34
30
  import {
35
31
  installDefaultSchema
36
- } from "../chunk-HUG7E25D.js";
32
+ } from "../chunk-Y7H76Q7F.js";
37
33
  import {
38
34
  computeDecay,
39
35
  loadDecayConfig,
@@ -51,7 +47,7 @@ import {
51
47
  expandQuery,
52
48
  loadLexiconCache,
53
49
  removeAlias
54
- } from "../chunk-KSH2QO6V.js";
50
+ } from "../chunk-7UAVDOI6.js";
55
51
  import {
56
52
  appendIncident,
57
53
  compileDossiers,
@@ -60,21 +56,25 @@ import {
60
56
  listDossiers,
61
57
  resolveDossierPath,
62
58
  setCurrentState
63
- } from "../chunk-HZ7B5KHY.js";
59
+ } from "../chunk-EXAUVIGW.js";
64
60
  import {
65
61
  SessionManager,
66
62
  deriveProjectRoot,
67
63
  deriveSessionDir
68
64
  } from "../chunk-EYVFC745.js";
69
- import {
70
- redactedNote
71
- } from "../chunk-H2BES6FU.js";
72
65
  import {
73
66
  Indexer
74
67
  } from "../chunk-CJUY55GG.js";
75
68
  import {
76
69
  matter_default
77
70
  } from "../chunk-J7LYDRML.js";
71
+ import {
72
+ logEvent,
73
+ logQuery
74
+ } from "../chunk-XKGK643R.js";
75
+ import {
76
+ redactedNote
77
+ } from "../chunk-H2BES6FU.js";
78
78
  import {
79
79
  __export
80
80
  } from "../chunk-PZ5AY32C.js";
@@ -5200,7 +5200,8 @@ var RULE_KEY_FOR_CHECK = {
5200
5200
  decay_candidates: "decay_candidates",
5201
5201
  alias_conflicts: "alias_conflicts",
5202
5202
  decoys: "decoys",
5203
- secrets: "secrets"
5203
+ secrets: "secrets",
5204
+ skills: "skills"
5204
5205
  };
5205
5206
  function registerLintTools(server, ctx) {
5206
5207
  server.tool(
@@ -5241,10 +5242,10 @@ function registerLintTools(server, ctx) {
5241
5242
  );
5242
5243
  server.tool(
5243
5244
  "lint_vault",
5244
- "Run lint rules across the vault. Default returns the full LintReport with all findings grouped by rule. Pass `checks` to filter to specific rules (schema, provenance, stale, broken_links, code_symbols, decay_candidates) \u2014 when filtered, byRule contains only the requested rules. Two checks are opt-in only (never in the default report): `code_symbols` flags inline-code file-path references that no longer exist under the project root (no-op outside a code repo); `decay_candidates` cross-references the selection log against current decay to surface frequently-retrieved-but-decayed notes (no-op with no selection log). `decoys` flags notes retrieved 3+ times but never cited - surfaced for review, never auto-down-ranked (v1.5 Q5). `secrets` flags notes containing an API key, token, password or private key (path, line, kind \u2014 never the value; nothing is rewritten): rotate the secret, then remove it.",
5245
+ "Run lint rules across the vault. Default returns the full LintReport with all findings grouped by rule. Pass `checks` to filter to specific rules (schema, provenance, stale, broken_links, code_symbols, decay_candidates) \u2014 when filtered, byRule contains only the requested rules. Two checks are opt-in only (never in the default report): `code_symbols` flags inline-code file-path references that no longer exist under the project root (no-op outside a code repo); `decay_candidates` cross-references the selection log against current decay to surface frequently-retrieved-but-decayed notes (no-op with no selection log). `decoys` flags notes retrieved 3+ times but never cited - surfaced for review, never auto-down-ranked (v1.5 Q5). `secrets` flags notes containing an API key, token, password or private key (path, line, kind \u2014 never the value; nothing is rewritten): rotate the secret, then remove it. `skills` lints the skill loop's learned skills this repo loads (format, description, evidence, sections, cites, applies_to paths, secrets, name clashes with skills it did not write).",
5245
5246
  {
5246
5247
  pathGlob: external_exports.string().optional(),
5247
- checks: external_exports.array(external_exports.enum(["schema", "provenance", "stale", "broken_links", "code_symbols", "decay_candidates", "alias_conflicts", "decoys", "secrets"])).optional().describe("Filter to specific lint rules. Omit for full report (excludes the opt-in code_symbols / decay_candidates / alias_conflicts / decoys / secrets).")
5248
+ checks: external_exports.array(external_exports.enum(["schema", "provenance", "stale", "broken_links", "code_symbols", "decay_candidates", "alias_conflicts", "decoys", "secrets", "skills"])).optional().describe("Filter to specific lint rules. Omit for full report (excludes the opt-in code_symbols / decay_candidates / alias_conflicts / decoys / secrets / skills).")
5248
5249
  },
5249
5250
  async ({ pathGlob, checks }) => {
5250
5251
  const report = await lintVault(ctx.notesPath, {
@@ -5253,7 +5254,8 @@ function registerLintTools(server, ctx) {
5253
5254
  checkDecayCandidates: !!checks?.includes("decay_candidates"),
5254
5255
  checkAliasConflicts: !!checks?.includes("alias_conflicts"),
5255
5256
  checkDecoys: !!checks?.includes("decoys"),
5256
- checkSecrets: !!checks?.includes("secrets")
5257
+ checkSecrets: !!checks?.includes("secrets"),
5258
+ checkSkills: !!checks?.includes("skills")
5257
5259
  });
5258
5260
  if (!checks || checks.length === 0) {
5259
5261
  return ctx.textResponse(JSON.stringify(report, null, 2));