pi-continuous-learning 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +326 -0
  3. package/dist/active-instincts.d.ts +4 -0
  4. package/dist/active-instincts.d.ts.map +1 -0
  5. package/dist/active-instincts.js +11 -0
  6. package/dist/active-instincts.js.map +1 -0
  7. package/dist/agents-md.d.ts +12 -0
  8. package/dist/agents-md.d.ts.map +1 -0
  9. package/dist/agents-md.js +23 -0
  10. package/dist/agents-md.js.map +1 -0
  11. package/dist/cli/analyze-prompt.d.ts +2 -0
  12. package/dist/cli/analyze-prompt.d.ts.map +1 -0
  13. package/dist/cli/analyze-prompt.js +72 -0
  14. package/dist/cli/analyze-prompt.js.map +1 -0
  15. package/dist/cli/analyze.d.ts +3 -0
  16. package/dist/cli/analyze.d.ts.map +1 -0
  17. package/dist/cli/analyze.js +214 -0
  18. package/dist/cli/analyze.js.map +1 -0
  19. package/dist/confidence.d.ts +25 -0
  20. package/dist/confidence.d.ts.map +1 -0
  21. package/dist/confidence.js +77 -0
  22. package/dist/confidence.js.map +1 -0
  23. package/dist/config.d.ts +19 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +89 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/error-logger.d.ts +34 -0
  28. package/dist/error-logger.d.ts.map +1 -0
  29. package/dist/error-logger.js +102 -0
  30. package/dist/error-logger.js.map +1 -0
  31. package/dist/index.d.ts +10 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +118 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/instinct-decay.d.ts +39 -0
  36. package/dist/instinct-decay.d.ts.map +1 -0
  37. package/dist/instinct-decay.js +93 -0
  38. package/dist/instinct-decay.js.map +1 -0
  39. package/dist/instinct-evolve.d.ts +5 -0
  40. package/dist/instinct-evolve.d.ts.map +1 -0
  41. package/dist/instinct-evolve.js +24 -0
  42. package/dist/instinct-evolve.js.map +1 -0
  43. package/dist/instinct-export.d.ts +40 -0
  44. package/dist/instinct-export.d.ts.map +1 -0
  45. package/dist/instinct-export.js +94 -0
  46. package/dist/instinct-export.js.map +1 -0
  47. package/dist/instinct-import.d.ts +50 -0
  48. package/dist/instinct-import.d.ts.map +1 -0
  49. package/dist/instinct-import.js +168 -0
  50. package/dist/instinct-import.js.map +1 -0
  51. package/dist/instinct-injector.d.ts +39 -0
  52. package/dist/instinct-injector.d.ts.map +1 -0
  53. package/dist/instinct-injector.js +89 -0
  54. package/dist/instinct-injector.js.map +1 -0
  55. package/dist/instinct-loader.d.ts +37 -0
  56. package/dist/instinct-loader.d.ts.map +1 -0
  57. package/dist/instinct-loader.js +96 -0
  58. package/dist/instinct-loader.js.map +1 -0
  59. package/dist/instinct-parser.d.ts +28 -0
  60. package/dist/instinct-parser.d.ts.map +1 -0
  61. package/dist/instinct-parser.js +143 -0
  62. package/dist/instinct-parser.js.map +1 -0
  63. package/dist/instinct-projects.d.ts +32 -0
  64. package/dist/instinct-projects.d.ts.map +1 -0
  65. package/dist/instinct-projects.js +96 -0
  66. package/dist/instinct-projects.js.map +1 -0
  67. package/dist/instinct-promote.d.ts +51 -0
  68. package/dist/instinct-promote.d.ts.map +1 -0
  69. package/dist/instinct-promote.js +169 -0
  70. package/dist/instinct-promote.js.map +1 -0
  71. package/dist/instinct-status.d.ts +39 -0
  72. package/dist/instinct-status.d.ts.map +1 -0
  73. package/dist/instinct-status.js +108 -0
  74. package/dist/instinct-status.js.map +1 -0
  75. package/dist/instinct-store.d.ts +30 -0
  76. package/dist/instinct-store.d.ts.map +1 -0
  77. package/dist/instinct-store.js +118 -0
  78. package/dist/instinct-store.js.map +1 -0
  79. package/dist/instinct-tools.d.ts +161 -0
  80. package/dist/instinct-tools.d.ts.map +1 -0
  81. package/dist/instinct-tools.js +240 -0
  82. package/dist/instinct-tools.js.map +1 -0
  83. package/dist/observations.d.ts +22 -0
  84. package/dist/observations.d.ts.map +1 -0
  85. package/dist/observations.js +62 -0
  86. package/dist/observations.js.map +1 -0
  87. package/dist/observer-guard.d.ts +3 -0
  88. package/dist/observer-guard.d.ts.map +1 -0
  89. package/dist/observer-guard.js +13 -0
  90. package/dist/observer-guard.js.map +1 -0
  91. package/dist/project.d.ts +16 -0
  92. package/dist/project.d.ts.map +1 -0
  93. package/dist/project.js +59 -0
  94. package/dist/project.js.map +1 -0
  95. package/dist/prompt-observer.d.ts +25 -0
  96. package/dist/prompt-observer.d.ts.map +1 -0
  97. package/dist/prompt-observer.js +63 -0
  98. package/dist/prompt-observer.js.map +1 -0
  99. package/dist/prompts/analyzer-user.d.ts +38 -0
  100. package/dist/prompts/analyzer-user.d.ts.map +1 -0
  101. package/dist/prompts/analyzer-user.js +105 -0
  102. package/dist/prompts/analyzer-user.js.map +1 -0
  103. package/dist/prompts/evolve-prompt.d.ts +3 -0
  104. package/dist/prompts/evolve-prompt.d.ts.map +1 -0
  105. package/dist/prompts/evolve-prompt.js +51 -0
  106. package/dist/prompts/evolve-prompt.js.map +1 -0
  107. package/dist/scrubber.d.ts +9 -0
  108. package/dist/scrubber.d.ts.map +1 -0
  109. package/dist/scrubber.js +40 -0
  110. package/dist/scrubber.js.map +1 -0
  111. package/dist/storage.d.ts +22 -0
  112. package/dist/storage.d.ts.map +1 -0
  113. package/dist/storage.js +71 -0
  114. package/dist/storage.js.map +1 -0
  115. package/dist/tool-observer.d.ts +32 -0
  116. package/dist/tool-observer.d.ts.map +1 -0
  117. package/dist/tool-observer.js +77 -0
  118. package/dist/tool-observer.js.map +1 -0
  119. package/dist/types.d.ts +64 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +6 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +66 -0
  124. package/src/active-instincts.ts +13 -0
  125. package/src/agents-md.ts +23 -0
  126. package/src/cli/analyze-prompt.ts +71 -0
  127. package/src/cli/analyze.ts +286 -0
  128. package/src/confidence.ts +103 -0
  129. package/src/config.ts +111 -0
  130. package/src/error-logger.ts +130 -0
  131. package/src/index.ts +144 -0
  132. package/src/instinct-decay.ts +117 -0
  133. package/src/instinct-evolve.ts +44 -0
  134. package/src/instinct-export.ts +138 -0
  135. package/src/instinct-import.ts +260 -0
  136. package/src/instinct-injector.ts +128 -0
  137. package/src/instinct-loader.ts +146 -0
  138. package/src/instinct-parser.ts +171 -0
  139. package/src/instinct-projects.ts +119 -0
  140. package/src/instinct-promote.ts +231 -0
  141. package/src/instinct-status.ts +135 -0
  142. package/src/instinct-store.ts +149 -0
  143. package/src/instinct-tools.ts +340 -0
  144. package/src/observations.ts +82 -0
  145. package/src/observer-guard.ts +14 -0
  146. package/src/project.ts +70 -0
  147. package/src/prompt-observer.ts +92 -0
  148. package/src/prompts/analyzer-user.ts +156 -0
  149. package/src/prompts/evolve-prompt.ts +71 -0
  150. package/src/scrubber.ts +42 -0
  151. package/src/storage.ts +91 -0
  152. package/src/tool-observer.ts +114 -0
  153. package/src/types.ts +90 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * /instinct-import command for pi-continuous-learning.
3
+ * Imports instincts from a JSON file into the inherited instincts directory.
4
+ * Destination is determined by each instinct's scope field:
5
+ * - scope "project" -> projects/<id>/instincts/inherited/
6
+ * - scope "global" -> instincts/inherited/
7
+ */
8
+ import { readFileSync, mkdirSync, existsSync } from "node:fs";
9
+ import { resolve } from "node:path";
10
+ import { saveInstinct, listInstincts } from "./instinct-store.js";
11
+ import { getProjectInstinctsDir, getGlobalInstinctsDir, getBaseDir, } from "./storage.js";
12
+ // ---------------------------------------------------------------------------
13
+ // Constants
14
+ // ---------------------------------------------------------------------------
15
+ export const COMMAND_NAME = "instinct-import";
16
+ const KEBAB_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
17
+ const REQUIRED_FIELDS = [
18
+ "id",
19
+ "title",
20
+ "trigger",
21
+ "action",
22
+ "confidence",
23
+ "domain",
24
+ "source",
25
+ "scope",
26
+ "created_at",
27
+ "updated_at",
28
+ "observation_count",
29
+ "confirmed_count",
30
+ "contradicted_count",
31
+ "inactive_count",
32
+ ];
33
+ /**
34
+ * Validates a raw JSON object as an Instinct.
35
+ * Returns an error string if invalid, null if valid.
36
+ */
37
+ export function validateImportObject(obj, index) {
38
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
39
+ return { index, reason: "not an object" };
40
+ }
41
+ const record = obj;
42
+ for (const field of REQUIRED_FIELDS) {
43
+ if (record[field] === undefined || record[field] === null) {
44
+ return { index, reason: `missing required field "${field}"` };
45
+ }
46
+ }
47
+ const id = String(record["id"]);
48
+ if (!KEBAB_RE.test(id)) {
49
+ return { index, reason: `invalid id "${id}" - must be kebab-case` };
50
+ }
51
+ return null;
52
+ }
53
+ /**
54
+ * Reads and parses the import JSON file.
55
+ * Returns valid instincts and validation errors separately.
56
+ */
57
+ export function loadImportFile(filePath) {
58
+ const content = readFileSync(filePath, "utf-8");
59
+ const parsed = JSON.parse(content);
60
+ if (!Array.isArray(parsed)) {
61
+ throw new Error("Import file must contain a JSON array of instinct objects.");
62
+ }
63
+ const valid = [];
64
+ const invalid = [];
65
+ for (let i = 0; i < parsed.length; i++) {
66
+ const err = validateImportObject(parsed[i], i);
67
+ if (err) {
68
+ invalid.push(err);
69
+ }
70
+ else {
71
+ valid.push(parsed[i]);
72
+ }
73
+ }
74
+ return { valid, invalid };
75
+ }
76
+ /**
77
+ * Partitions instincts into those to import and those skipped as duplicates.
78
+ * Checks existing inherited instincts in both project and global directories.
79
+ */
80
+ export function partitionByDuplicates(instincts, projectId, baseDir) {
81
+ const existingIds = new Set();
82
+ const globalDir = getGlobalInstinctsDir("inherited", baseDir);
83
+ for (const inst of listInstincts(globalDir)) {
84
+ existingIds.add(inst.id);
85
+ }
86
+ if (projectId != null) {
87
+ const projectDir = getProjectInstinctsDir(projectId, "inherited", baseDir);
88
+ for (const inst of listInstincts(projectDir)) {
89
+ existingIds.add(inst.id);
90
+ }
91
+ }
92
+ const toImport = [];
93
+ const duplicates = [];
94
+ for (const inst of instincts) {
95
+ if (existingIds.has(inst.id)) {
96
+ duplicates.push(inst.id);
97
+ }
98
+ else {
99
+ toImport.push(inst);
100
+ }
101
+ }
102
+ return { toImport, duplicates };
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Target directory resolution
106
+ // ---------------------------------------------------------------------------
107
+ /**
108
+ * Returns the inherited instincts directory for the given instinct.
109
+ * Project-scoped instincts go into the project's inherited dir.
110
+ * Global instincts go into the global inherited dir.
111
+ */
112
+ export function getTargetDir(instinct, projectId, baseDir) {
113
+ if (instinct.scope === "project" && projectId != null) {
114
+ return getProjectInstinctsDir(projectId, "inherited", baseDir);
115
+ }
116
+ return getGlobalInstinctsDir("inherited", baseDir);
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // handleInstinctImport
120
+ // ---------------------------------------------------------------------------
121
+ /**
122
+ * Command handler for /instinct-import.
123
+ * Reads the JSON file at the given path, validates each instinct,
124
+ * skips duplicates, and saves valid instincts to inherited/ directories.
125
+ */
126
+ export async function handleInstinctImport(args, ctx, projectId, baseDir) {
127
+ const effectiveBase = baseDir ?? getBaseDir();
128
+ const filePath = resolve(ctx.cwd, args.trim());
129
+ if (!existsSync(filePath)) {
130
+ ctx.ui.notify(`Import failed: file not found: ${filePath}`, "error");
131
+ return;
132
+ }
133
+ let loadResult;
134
+ try {
135
+ loadResult = loadImportFile(filePath);
136
+ }
137
+ catch (err) {
138
+ const msg = err instanceof Error ? err.message : String(err);
139
+ ctx.ui.notify(`Import failed: ${msg}`, "error");
140
+ return;
141
+ }
142
+ const { valid, invalid } = loadResult;
143
+ const { toImport, duplicates } = partitionByDuplicates(valid, projectId, effectiveBase);
144
+ // Ensure target dirs exist before writing
145
+ const globalInheritedDir = getGlobalInstinctsDir("inherited", effectiveBase);
146
+ mkdirSync(globalInheritedDir, { recursive: true });
147
+ if (projectId != null) {
148
+ const projectInheritedDir = getProjectInstinctsDir(projectId, "inherited", effectiveBase);
149
+ mkdirSync(projectInheritedDir, { recursive: true });
150
+ }
151
+ // Save each instinct to the correct inherited directory
152
+ for (const instinct of toImport) {
153
+ const targetDir = getTargetDir(instinct, projectId, effectiveBase);
154
+ saveInstinct(instinct, targetDir);
155
+ }
156
+ // Build summary message
157
+ const lines = [
158
+ `Imported ${toImport.length} instinct${toImport.length !== 1 ? "s" : ""} from ${filePath}`,
159
+ ];
160
+ if (duplicates.length > 0) {
161
+ lines.push(`Skipped ${duplicates.length} duplicate${duplicates.length !== 1 ? "s" : ""}: ${duplicates.join(", ")}`);
162
+ }
163
+ if (invalid.length > 0) {
164
+ lines.push(`Skipped ${invalid.length} invalid entr${invalid.length !== 1 ? "ies" : "y"}: ${invalid.map((e) => `[${e.index}] ${e.reason}`).join("; ")}`);
165
+ }
166
+ ctx.ui.notify(lines.join("\n"), "info");
167
+ }
168
+ //# sourceMappingURL=instinct-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-import.js","sourceRoot":"","sources":["../src/instinct-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * System prompt injection for pi-continuous-learning.
3
+ * Loads filtered instincts and appends them to the system prompt on each
4
+ * before_agent_start event so the agent benefits from learned behaviors.
5
+ * Also bridges injected instinct IDs to shared active-instincts state (US-023).
6
+ */
7
+ import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
8
+ import type { BeforeAgentStartEvent, AgentEndEvent } from "./prompt-observer.js";
9
+ import type { Config, Instinct } from "./types.js";
10
+ /** Subset of BeforeAgentStartEventResult used by this module. */
11
+ export interface InjectionResult {
12
+ /** Replacement system prompt to use for this turn. */
13
+ systemPrompt?: string;
14
+ }
15
+ export declare const INSTINCTS_HEADER = "## Learned Behaviors (Instincts)";
16
+ /**
17
+ * Builds the injection block string from a list of instincts.
18
+ * Returns null when the list is empty (no block needed).
19
+ */
20
+ export declare function buildInjectionBlock(instincts: Instinct[], maxChars?: number): string | null;
21
+ /**
22
+ * Returns a modified system prompt string with injected instincts,
23
+ * or null when no qualifying instincts were found.
24
+ * Pure function - no I/O.
25
+ */
26
+ export declare function injectInstincts(systemPrompt: string, instincts: Instinct[]): string | null;
27
+ /**
28
+ * Handles before_agent_start events.
29
+ * Loads qualifying instincts, appends them to the system prompt, and stores
30
+ * their IDs in shared active-instincts state for observation tagging (US-023).
31
+ * Returns undefined when no instincts qualify (no-op).
32
+ */
33
+ export declare function handleBeforeAgentStartInjection(event: BeforeAgentStartEvent, _ctx: ExtensionContext, config: Config, projectId?: string | null, baseDir?: string): InjectionResult | void;
34
+ /**
35
+ * Handles agent_end events.
36
+ * Clears active instincts state so the next prompt starts clean (US-023).
37
+ */
38
+ export declare function handleAgentEndClearInstincts(_event: AgentEndEvent, _ctx: ExtensionContext): void;
39
+ //# sourceMappingURL=instinct-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-injector.d.ts","sourceRoot":"","sources":["../src/instinct-injector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEnD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAWD,eAAO,MAAM,gBAAgB,qCAAqC,CAAC;AAMnE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4B3F;AAMD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,QAAQ,EAAE,GACpB,MAAM,GAAG,IAAI,CAIf;AAMD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,OAAO,CAAC,EAAE,MAAM,GACf,eAAe,GAAG,IAAI,CAYxB;AAMD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GACrB,IAAI,CAEN"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * System prompt injection for pi-continuous-learning.
3
+ * Loads filtered instincts and appends them to the system prompt on each
4
+ * before_agent_start event so the agent benefits from learned behaviors.
5
+ * Also bridges injected instinct IDs to shared active-instincts state (US-023).
6
+ */
7
+ import { loadAndFilterFromConfig, inferDomains } from "./instinct-loader.js";
8
+ import { setCurrentActiveInstincts, clearActiveInstincts, } from "./active-instincts.js";
9
+ // ---------------------------------------------------------------------------
10
+ // Constants
11
+ // ---------------------------------------------------------------------------
12
+ export const INSTINCTS_HEADER = "## Learned Behaviors (Instincts)";
13
+ // ---------------------------------------------------------------------------
14
+ // buildInjectionBlock
15
+ // ---------------------------------------------------------------------------
16
+ /**
17
+ * Builds the injection block string from a list of instincts.
18
+ * Returns null when the list is empty (no block needed).
19
+ */
20
+ export function buildInjectionBlock(instincts, maxChars) {
21
+ if (instincts.length === 0)
22
+ return null;
23
+ const headerLen = `\n\n${INSTINCTS_HEADER}\n`.length;
24
+ const allBullets = [];
25
+ let charCount = headerLen;
26
+ let omitted = 0;
27
+ for (const i of instincts) {
28
+ const bullet = `- [${i.confidence.toFixed(2)}] ${i.trigger}: ${i.action}`;
29
+ const bulletLen = bullet.length + 1; // +1 for newline
30
+ if (maxChars && charCount + bulletLen > maxChars) {
31
+ omitted = instincts.length - allBullets.length;
32
+ break;
33
+ }
34
+ allBullets.push(bullet);
35
+ charCount += bulletLen;
36
+ }
37
+ if (allBullets.length === 0)
38
+ return null;
39
+ let result = `\n\n${INSTINCTS_HEADER}\n${allBullets.join("\n")}`;
40
+ if (omitted > 0) {
41
+ result += `\n(${omitted} lower-confidence instinct${omitted > 1 ? "s" : ""} omitted)`;
42
+ }
43
+ return result;
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // injectInstincts (pure, for testing)
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Returns a modified system prompt string with injected instincts,
50
+ * or null when no qualifying instincts were found.
51
+ * Pure function - no I/O.
52
+ */
53
+ export function injectInstincts(systemPrompt, instincts) {
54
+ const block = buildInjectionBlock(instincts);
55
+ if (block === null)
56
+ return null;
57
+ return systemPrompt + block;
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // handleBeforeAgentStartInjection
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Handles before_agent_start events.
64
+ * Loads qualifying instincts, appends them to the system prompt, and stores
65
+ * their IDs in shared active-instincts state for observation tagging (US-023).
66
+ * Returns undefined when no instincts qualify (no-op).
67
+ */
68
+ export function handleBeforeAgentStartInjection(event, _ctx, config, projectId, baseDir) {
69
+ const relevantDomains = inferDomains(event.prompt);
70
+ const instincts = loadAndFilterFromConfig(config, projectId, baseDir, relevantDomains);
71
+ const block = buildInjectionBlock(instincts, config.max_injection_chars);
72
+ if (block === null) {
73
+ setCurrentActiveInstincts([]);
74
+ return undefined;
75
+ }
76
+ setCurrentActiveInstincts(instincts.map((i) => i.id));
77
+ return { systemPrompt: event.systemPrompt + block };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // handleAgentEndClearInstincts
81
+ // ---------------------------------------------------------------------------
82
+ /**
83
+ * Handles agent_end events.
84
+ * Clears active instincts state so the next prompt starts clean (US-023).
85
+ */
86
+ export function handleAgentEndClearInstincts(_event, _ctx) {
87
+ clearActiveInstincts();
88
+ }
89
+ //# sourceMappingURL=instinct-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-injector.js","sourceRoot":"","sources":["../src/instinct-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Instinct loading and filtering for the injector.
3
+ * Loads project and global instincts, filters by confidence threshold,
4
+ * sorts by confidence descending, and caps to max_instincts.
5
+ */
6
+ import type { Instinct, Config } from "./types.js";
7
+ export declare function inferDomains(userPrompt: string): Set<string>;
8
+ export interface LoadInstinctsOptions {
9
+ /** Project ID, or undefined/null when running outside a project. */
10
+ projectId?: string | null;
11
+ /** Minimum confidence threshold (default: DEFAULT_CONFIG.min_confidence). */
12
+ minConfidence?: number;
13
+ /** Maximum number of instincts to return (default: DEFAULT_CONFIG.max_instincts). */
14
+ maxInstincts?: number;
15
+ /** Optional base directory for storage (used in tests). */
16
+ baseDir?: string;
17
+ /** Domains relevant to the current context — matched instincts sort first. */
18
+ relevantDomains?: Set<string>;
19
+ }
20
+ /**
21
+ * Filters, sorts, and caps a flat list of instincts.
22
+ * Pure function - no I/O.
23
+ */
24
+ export declare function filterInstincts(instincts: Instinct[], minConfidence: number, maxInstincts: number, relevantDomains?: Set<string>): Instinct[];
25
+ /**
26
+ * Loads instincts from disk, filters by confidence threshold, sorts by
27
+ * confidence descending, and caps to max_instincts.
28
+ *
29
+ * When projectId is provided (and non-null), loads both project-scoped
30
+ * instincts and global instincts. Otherwise loads only global instincts.
31
+ */
32
+ export declare function loadAndFilterInstincts(options?: LoadInstinctsOptions): Instinct[];
33
+ /**
34
+ * Convenience wrapper - uses thresholds from a Config object.
35
+ */
36
+ export declare function loadAndFilterFromConfig(config: Config, projectId?: string | null, baseDir?: string, relevantDomains?: Set<string>): Instinct[];
37
+ //# sourceMappingURL=instinct-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-loader.d.ts","sourceRoot":"","sources":["../src/instinct-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAuBnD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAS5D;AAMD,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,QAAQ,EAAE,EACrB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC5B,QAAQ,EAAE,CAiBZ;AAMD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,oBAAyB,GACjC,QAAQ,EAAE,CAoBZ;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC5B,QAAQ,EAAE,CASZ"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Instinct loading and filtering for the injector.
3
+ * Loads project and global instincts, filters by confidence threshold,
4
+ * sorts by confidence descending, and caps to max_instincts.
5
+ */
6
+ import { loadProjectInstincts, loadGlobalInstincts } from "./instinct-store.js";
7
+ import { DEFAULT_CONFIG } from "./config.js";
8
+ // ---------------------------------------------------------------------------
9
+ // Domain inference
10
+ // ---------------------------------------------------------------------------
11
+ const UNIVERSAL_DOMAINS = new Set(["workflow", "git"]);
12
+ const DOMAIN_KEYWORDS = {
13
+ typescript: ["typescript", ".ts", "type ", "interface ", "generic"],
14
+ css: ["css", "style", "tailwind", "classname", "scss", "sass"],
15
+ testing: ["test", "spec", "vitest", "jest", "coverage", "assert"],
16
+ git: ["git", "commit", "branch", "merge", "rebase", "stash"],
17
+ debugging: ["debug", "error", "stack trace", "exception", "breakpoint"],
18
+ performance: ["performance", "slow", "memory", "profil", "latency", "cache"],
19
+ security: ["security", "auth", "token", "secret", "csrf", "xss", "injection"],
20
+ documentation: ["documentation", "readme", "jsdoc", "docstring"],
21
+ design: ["component", "ui ", "layout", "responsive", "accessibility"],
22
+ workflow: ["workflow", "ci", "pipeline", "deploy", "automat"],
23
+ };
24
+ export function inferDomains(userPrompt) {
25
+ const lower = userPrompt.toLowerCase();
26
+ const matched = new Set();
27
+ for (const [domain, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
28
+ if (keywords.some((kw) => lower.includes(kw))) {
29
+ matched.add(domain);
30
+ }
31
+ }
32
+ return matched;
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // filterInstincts
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Filters, sorts, and caps a flat list of instincts.
39
+ * Pure function - no I/O.
40
+ */
41
+ export function filterInstincts(instincts, minConfidence, maxInstincts, relevantDomains) {
42
+ const eligible = instincts.filter((i) => !i.flagged_for_removal && i.confidence >= minConfidence);
43
+ const sorted = [...eligible].sort((a, b) => {
44
+ // When relevantDomains are provided, prioritize domain-matched instincts
45
+ if (relevantDomains && relevantDomains.size > 0) {
46
+ const aRelevant = relevantDomains.has(a.domain) || UNIVERSAL_DOMAINS.has(a.domain);
47
+ const bRelevant = relevantDomains.has(b.domain) || UNIVERSAL_DOMAINS.has(b.domain);
48
+ if (aRelevant && !bRelevant)
49
+ return -1;
50
+ if (!aRelevant && bRelevant)
51
+ return 1;
52
+ }
53
+ return b.confidence - a.confidence;
54
+ });
55
+ return sorted.slice(0, maxInstincts);
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // loadAndFilterInstincts
59
+ // ---------------------------------------------------------------------------
60
+ /**
61
+ * Loads instincts from disk, filters by confidence threshold, sorts by
62
+ * confidence descending, and caps to max_instincts.
63
+ *
64
+ * When projectId is provided (and non-null), loads both project-scoped
65
+ * instincts and global instincts. Otherwise loads only global instincts.
66
+ */
67
+ export function loadAndFilterInstincts(options = {}) {
68
+ const { projectId, minConfidence = DEFAULT_CONFIG.min_confidence, maxInstincts = DEFAULT_CONFIG.max_instincts, baseDir, relevantDomains, } = options;
69
+ const projectInstincts = projectId != null
70
+ ? loadProjectInstincts(projectId, baseDir)
71
+ : [];
72
+ const globalInstincts = loadGlobalInstincts(baseDir);
73
+ // Combine: project instincts first, then global (project-scoped are more specific)
74
+ const all = [...projectInstincts, ...globalInstincts];
75
+ return filterInstincts(all, minConfidence, maxInstincts, relevantDomains);
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // loadAndFilterFromConfig
79
+ // ---------------------------------------------------------------------------
80
+ /**
81
+ * Convenience wrapper - uses thresholds from a Config object.
82
+ */
83
+ export function loadAndFilterFromConfig(config, projectId, baseDir, relevantDomains) {
84
+ const opts = {
85
+ minConfidence: config.min_confidence,
86
+ maxInstincts: config.max_instincts,
87
+ };
88
+ if (projectId !== undefined)
89
+ opts.projectId = projectId;
90
+ if (baseDir !== undefined)
91
+ opts.baseDir = baseDir;
92
+ if (relevantDomains !== undefined)
93
+ opts.relevantDomains = relevantDomains;
94
+ return loadAndFilterInstincts(opts);
95
+ }
96
+ //# sourceMappingURL=instinct-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-loader.js","sourceRoot":"","sources":["../src/instinct-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Instinct file parsing and serialization.
3
+ * Instinct files use YAML frontmatter + a markdown body for the action text.
4
+ *
5
+ * Format:
6
+ * ---
7
+ * id: some-kebab-id
8
+ * title: Human readable title
9
+ * trigger: when condition is met
10
+ * confidence: 0.7
11
+ * ...other metadata...
12
+ * ---
13
+ *
14
+ * Action text describing what to do.
15
+ */
16
+ import type { Instinct } from "./types.js";
17
+ /**
18
+ * Parse an instinct markdown file (YAML frontmatter + body) into an Instinct.
19
+ * Throws if required fields are missing or the ID is not kebab-case.
20
+ * Clamps confidence to 0.1–0.9 rather than throwing.
21
+ */
22
+ export declare function parseInstinct(content: string): Instinct;
23
+ /**
24
+ * Serialize an Instinct into a YAML-frontmatter markdown string.
25
+ * Confidence is clamped to 0.1–0.9 before writing.
26
+ */
27
+ export declare function serializeInstinct(instinct: Instinct): string;
28
+ //# sourceMappingURL=instinct-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-parser.d.ts","sourceRoot":"","sources":["../src/instinct-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyD3C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAmDvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAkC5D"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Instinct file parsing and serialization.
3
+ * Instinct files use YAML frontmatter + a markdown body for the action text.
4
+ *
5
+ * Format:
6
+ * ---
7
+ * id: some-kebab-id
8
+ * title: Human readable title
9
+ * trigger: when condition is met
10
+ * confidence: 0.7
11
+ * ...other metadata...
12
+ * ---
13
+ *
14
+ * Action text describing what to do.
15
+ */
16
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
17
+ // Constants
18
+ const KEBAB_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
19
+ const MIN_CONFIDENCE = 0.1;
20
+ const MAX_CONFIDENCE = 0.9;
21
+ const REQUIRED_FIELDS = [
22
+ "id",
23
+ "title",
24
+ "trigger",
25
+ "confidence",
26
+ "domain",
27
+ "source",
28
+ "scope",
29
+ "created_at",
30
+ "updated_at",
31
+ "observation_count",
32
+ "confirmed_count",
33
+ "contradicted_count",
34
+ "inactive_count",
35
+ ];
36
+ // ---------------------------------------------------------------------------
37
+ // Helpers
38
+ // ---------------------------------------------------------------------------
39
+ function clampConfidence(value) {
40
+ return Math.min(MAX_CONFIDENCE, Math.max(MIN_CONFIDENCE, value));
41
+ }
42
+ function assertKebabCase(id) {
43
+ if (!KEBAB_RE.test(id)) {
44
+ throw new Error(`Invalid instinct ID "${id}": must be kebab-case (lowercase letters, numbers, hyphens only).`);
45
+ }
46
+ }
47
+ function splitFrontmatter(content) {
48
+ // Expect content starting with ---\n<yaml>\n---
49
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
50
+ if (!match) {
51
+ throw new Error("Invalid instinct file: content must begin with YAML frontmatter delimiters (---).");
52
+ }
53
+ return { frontmatterStr: match[1] ?? "", body: (match[2] ?? "").trim() };
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Public API
57
+ // ---------------------------------------------------------------------------
58
+ /**
59
+ * Parse an instinct markdown file (YAML frontmatter + body) into an Instinct.
60
+ * Throws if required fields are missing or the ID is not kebab-case.
61
+ * Clamps confidence to 0.1–0.9 rather than throwing.
62
+ */
63
+ export function parseInstinct(content) {
64
+ const { frontmatterStr, body } = splitFrontmatter(content);
65
+ const fm = parseYaml(frontmatterStr);
66
+ if (!fm || typeof fm !== "object") {
67
+ throw new Error("Invalid instinct file: frontmatter is not a valid YAML object.");
68
+ }
69
+ for (const field of REQUIRED_FIELDS) {
70
+ if (fm[field] === null || fm[field] === undefined) {
71
+ throw new Error(`Invalid instinct file: missing required field "${field}".`);
72
+ }
73
+ }
74
+ const id = String(fm["id"]);
75
+ assertKebabCase(id);
76
+ const confidence = clampConfidence(Number(fm["confidence"]));
77
+ const instinct = {
78
+ id,
79
+ title: String(fm["title"]),
80
+ trigger: String(fm["trigger"]),
81
+ action: body,
82
+ confidence,
83
+ domain: String(fm["domain"]),
84
+ source: fm["source"],
85
+ scope: fm["scope"],
86
+ created_at: String(fm["created_at"]),
87
+ updated_at: String(fm["updated_at"]),
88
+ observation_count: Number(fm["observation_count"]),
89
+ confirmed_count: Number(fm["confirmed_count"]),
90
+ contradicted_count: Number(fm["contradicted_count"]),
91
+ inactive_count: Number(fm["inactive_count"]),
92
+ };
93
+ if (fm["project_id"] !== undefined && fm["project_id"] !== null) {
94
+ instinct.project_id = String(fm["project_id"]);
95
+ }
96
+ if (fm["project_name"] !== undefined && fm["project_name"] !== null) {
97
+ instinct.project_name = String(fm["project_name"]);
98
+ }
99
+ if (Array.isArray(fm["evidence"])) {
100
+ instinct.evidence = fm["evidence"].map(String);
101
+ }
102
+ if (fm["flagged_for_removal"] !== undefined && fm["flagged_for_removal"] !== null) {
103
+ instinct.flagged_for_removal = Boolean(fm["flagged_for_removal"]);
104
+ }
105
+ return instinct;
106
+ }
107
+ /**
108
+ * Serialize an Instinct into a YAML-frontmatter markdown string.
109
+ * Confidence is clamped to 0.1–0.9 before writing.
110
+ */
111
+ export function serializeInstinct(instinct) {
112
+ const confidence = clampConfidence(instinct.confidence);
113
+ const frontmatter = {
114
+ id: instinct.id,
115
+ title: instinct.title,
116
+ trigger: instinct.trigger,
117
+ confidence,
118
+ domain: instinct.domain,
119
+ source: instinct.source,
120
+ scope: instinct.scope,
121
+ created_at: instinct.created_at,
122
+ updated_at: instinct.updated_at,
123
+ observation_count: instinct.observation_count,
124
+ confirmed_count: instinct.confirmed_count,
125
+ contradicted_count: instinct.contradicted_count,
126
+ inactive_count: instinct.inactive_count,
127
+ };
128
+ if (instinct.project_id !== undefined) {
129
+ frontmatter["project_id"] = instinct.project_id;
130
+ }
131
+ if (instinct.project_name !== undefined) {
132
+ frontmatter["project_name"] = instinct.project_name;
133
+ }
134
+ if (instinct.evidence !== undefined) {
135
+ frontmatter["evidence"] = instinct.evidence;
136
+ }
137
+ if (instinct.flagged_for_removal !== undefined) {
138
+ frontmatter["flagged_for_removal"] = instinct.flagged_for_removal;
139
+ }
140
+ const yamlStr = stringifyYaml(frontmatter);
141
+ return `---\n${yamlStr}---\n\n${instinct.action}\n`;
142
+ }
143
+ //# sourceMappingURL=instinct-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-parser.js","sourceRoot":"","sources":["../src/instinct-parser.ts"],"names":[],"mappings":"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"}