pi-continuous-learning 0.6.0 → 0.7.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 (77) hide show
  1. package/README.md +78 -0
  2. package/dist/agents-md.d.ts +23 -2
  3. package/dist/agents-md.d.ts.map +1 -1
  4. package/dist/agents-md.js +58 -3
  5. package/dist/agents-md.js.map +1 -1
  6. package/dist/cli/analyze-single-shot.d.ts +8 -2
  7. package/dist/cli/analyze-single-shot.d.ts.map +1 -1
  8. package/dist/cli/analyze-single-shot.js +25 -3
  9. package/dist/cli/analyze-single-shot.js.map +1 -1
  10. package/dist/cli/analyze.js +20 -8
  11. package/dist/cli/analyze.js.map +1 -1
  12. package/dist/command-scaffold.d.ts +25 -0
  13. package/dist/command-scaffold.d.ts.map +1 -0
  14. package/dist/command-scaffold.js +77 -0
  15. package/dist/command-scaffold.js.map +1 -0
  16. package/dist/confidence.d.ts.map +1 -1
  17. package/dist/confidence.js +2 -1
  18. package/dist/confidence.js.map +1 -1
  19. package/dist/config.d.ts +16 -0
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +31 -0
  22. package/dist/config.js.map +1 -1
  23. package/dist/graduation.d.ts +63 -0
  24. package/dist/graduation.d.ts.map +1 -0
  25. package/dist/graduation.js +155 -0
  26. package/dist/graduation.js.map +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +5 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/instinct-cleanup.d.ts +57 -0
  31. package/dist/instinct-cleanup.d.ts.map +1 -0
  32. package/dist/instinct-cleanup.js +150 -0
  33. package/dist/instinct-cleanup.js.map +1 -0
  34. package/dist/instinct-graduate.d.ts +43 -0
  35. package/dist/instinct-graduate.d.ts.map +1 -0
  36. package/dist/instinct-graduate.js +253 -0
  37. package/dist/instinct-graduate.js.map +1 -0
  38. package/dist/instinct-parser.d.ts.map +1 -1
  39. package/dist/instinct-parser.js +12 -0
  40. package/dist/instinct-parser.js.map +1 -1
  41. package/dist/instinct-tools.d.ts.map +1 -1
  42. package/dist/instinct-tools.js +19 -0
  43. package/dist/instinct-tools.js.map +1 -1
  44. package/dist/instinct-validator.d.ts +61 -0
  45. package/dist/instinct-validator.d.ts.map +1 -0
  46. package/dist/instinct-validator.js +235 -0
  47. package/dist/instinct-validator.js.map +1 -0
  48. package/dist/prompts/analyzer-system-single-shot.d.ts.map +1 -1
  49. package/dist/prompts/analyzer-system-single-shot.js +41 -1
  50. package/dist/prompts/analyzer-system-single-shot.js.map +1 -1
  51. package/dist/prompts/analyzer-user-single-shot.d.ts.map +1 -1
  52. package/dist/prompts/analyzer-user-single-shot.js +1 -1
  53. package/dist/prompts/analyzer-user-single-shot.js.map +1 -1
  54. package/dist/skill-scaffold.d.ts +23 -0
  55. package/dist/skill-scaffold.d.ts.map +1 -0
  56. package/dist/skill-scaffold.js +62 -0
  57. package/dist/skill-scaffold.js.map +1 -0
  58. package/dist/types.d.ts +8 -0
  59. package/dist/types.d.ts.map +1 -1
  60. package/package.json +1 -1
  61. package/src/agents-md.ts +73 -3
  62. package/src/cli/analyze-single-shot.ts +33 -3
  63. package/src/cli/analyze.ts +19 -8
  64. package/src/command-scaffold.ts +105 -0
  65. package/src/confidence.ts +2 -1
  66. package/src/config.ts +40 -0
  67. package/src/graduation.ts +243 -0
  68. package/src/index.ts +14 -0
  69. package/src/instinct-cleanup.ts +204 -0
  70. package/src/instinct-graduate.ts +377 -0
  71. package/src/instinct-parser.ts +12 -0
  72. package/src/instinct-tools.ts +26 -0
  73. package/src/instinct-validator.ts +287 -0
  74. package/src/prompts/analyzer-system-single-shot.ts +41 -1
  75. package/src/prompts/analyzer-user-single-shot.ts +6 -0
  76. package/src/skill-scaffold.ts +90 -0
  77. package/src/types.ts +10 -0
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Instinct validation and semantic deduplication.
3
+ * Rejects instincts with empty, undefined, nonsense, or low-quality fields,
4
+ * and detects near-duplicate instincts via Jaccard similarity.
5
+ */
6
+ const MIN_FIELD_LENGTH = 10;
7
+ const INVALID_LITERALS = new Set(["undefined", "null", "none", ""]);
8
+ // ---------------------------------------------------------------------------
9
+ // Known domains (with "other" as escape hatch)
10
+ // ---------------------------------------------------------------------------
11
+ export const KNOWN_DOMAINS = new Set([
12
+ "git",
13
+ "testing",
14
+ "debugging",
15
+ "workflow",
16
+ "typescript",
17
+ "javascript",
18
+ "python",
19
+ "go",
20
+ "css",
21
+ "design",
22
+ "security",
23
+ "performance",
24
+ "documentation",
25
+ "react",
26
+ "node",
27
+ "database",
28
+ "api",
29
+ "devops",
30
+ "architecture",
31
+ "other",
32
+ ]);
33
+ // ---------------------------------------------------------------------------
34
+ // Verb heuristic for action field
35
+ // ---------------------------------------------------------------------------
36
+ /** Common imperative verbs expected at the start of an instinct action. */
37
+ export const KNOWN_VERBS = new Set([
38
+ "add",
39
+ "always",
40
+ "analyze",
41
+ "apply",
42
+ "ask",
43
+ "avoid",
44
+ "build",
45
+ "call",
46
+ "catch",
47
+ "check",
48
+ "clean",
49
+ "confirm",
50
+ "consider",
51
+ "create",
52
+ "define",
53
+ "delete",
54
+ "document",
55
+ "emit",
56
+ "ensure",
57
+ "exclude",
58
+ "export",
59
+ "extract",
60
+ "fetch",
61
+ "find",
62
+ "fix",
63
+ "follow",
64
+ "format",
65
+ "generate",
66
+ "get",
67
+ "handle",
68
+ "import",
69
+ "include",
70
+ "inspect",
71
+ "load",
72
+ "log",
73
+ "look",
74
+ "merge",
75
+ "monitor",
76
+ "move",
77
+ "never",
78
+ "parse",
79
+ "pass",
80
+ "prefer",
81
+ "print",
82
+ "read",
83
+ "record",
84
+ "refactor",
85
+ "reject",
86
+ "rename",
87
+ "require",
88
+ "resolve",
89
+ "return",
90
+ "run",
91
+ "save",
92
+ "scan",
93
+ "search",
94
+ "send",
95
+ "set",
96
+ "show",
97
+ "skip",
98
+ "start",
99
+ "stop",
100
+ "test",
101
+ "track",
102
+ "update",
103
+ "use",
104
+ "validate",
105
+ "verify",
106
+ "watch",
107
+ "wrap",
108
+ "write",
109
+ ]);
110
+ // ---------------------------------------------------------------------------
111
+ // Internal helpers
112
+ // ---------------------------------------------------------------------------
113
+ function isInvalidField(value, fieldName) {
114
+ if (value === undefined || value === null) {
115
+ return `${fieldName} is ${String(value)}`;
116
+ }
117
+ if (typeof value !== "string") {
118
+ return `${fieldName} is not a string (got ${typeof value})`;
119
+ }
120
+ const trimmed = value.trim();
121
+ if (INVALID_LITERALS.has(trimmed.toLowerCase())) {
122
+ return `${fieldName} is the literal string "${trimmed}"`;
123
+ }
124
+ if (trimmed.length < MIN_FIELD_LENGTH) {
125
+ return `${fieldName} is too short (${trimmed.length} chars, minimum ${MIN_FIELD_LENGTH})`;
126
+ }
127
+ return null;
128
+ }
129
+ // ---------------------------------------------------------------------------
130
+ // validateInstinct
131
+ // ---------------------------------------------------------------------------
132
+ /**
133
+ * Validates that an instinct's fields meet quality requirements.
134
+ *
135
+ * Rules:
136
+ * - action and trigger must be non-empty, non-null, non-"undefined", and >= 10 chars
137
+ * - action first word should be a known imperative verb (warning if not)
138
+ * - domain, if provided, must be in KNOWN_DOMAINS (with "other" as escape hatch)
139
+ *
140
+ * Returns { valid: true } or { valid: false, reason: "..." }.
141
+ * Non-fatal issues are reported in the optional `warnings` array.
142
+ */
143
+ export function validateInstinct(fields) {
144
+ const actionError = isInvalidField(fields.action, "action");
145
+ if (actionError) {
146
+ return { valid: false, reason: actionError };
147
+ }
148
+ const triggerError = isInvalidField(fields.trigger, "trigger");
149
+ if (triggerError) {
150
+ return { valid: false, reason: triggerError };
151
+ }
152
+ const warnings = [];
153
+ // Domain validation
154
+ if (fields.domain !== undefined) {
155
+ if (typeof fields.domain !== "string" || !KNOWN_DOMAINS.has(fields.domain.toLowerCase().trim())) {
156
+ return {
157
+ valid: false,
158
+ reason: `domain "${String(fields.domain)}" is not in the known set. Use one of: ${[...KNOWN_DOMAINS].join(", ")}`,
159
+ };
160
+ }
161
+ }
162
+ // Verb heuristic (warning only - does not reject)
163
+ const action = fields.action.trim();
164
+ const firstWord = action.split(/\s+/)[0]?.toLowerCase() ?? "";
165
+ if (firstWord && !KNOWN_VERBS.has(firstWord)) {
166
+ warnings.push(`action should start with an imperative verb (got "${firstWord}"). Consider rewriting as a clear instruction.`);
167
+ }
168
+ return warnings.length > 0 ? { valid: true, warnings } : { valid: true };
169
+ }
170
+ // ---------------------------------------------------------------------------
171
+ // Jaccard similarity deduplication
172
+ // ---------------------------------------------------------------------------
173
+ const STOP_WORDS = new Set([
174
+ "a", "an", "the", "is", "are", "was", "were", "be", "been", "being",
175
+ "have", "has", "had", "do", "does", "did", "will", "would", "should",
176
+ "could", "may", "might", "shall", "can", "of", "in", "on", "at", "to",
177
+ "for", "with", "by", "from", "up", "about", "into", "it", "its", "this",
178
+ "that", "these", "those", "and", "or", "but", "if", "as", "when", "where",
179
+ "how", "what", "which", "who", "not", "no", "so",
180
+ ]);
181
+ /**
182
+ * Tokenizes text into a set of meaningful lowercase words.
183
+ * Splits on non-alphanumeric characters and filters stop words and short tokens.
184
+ */
185
+ export function tokenize(text) {
186
+ return new Set(text
187
+ .toLowerCase()
188
+ .split(/[^a-z0-9]+/)
189
+ .filter((t) => t.length > 2 && !STOP_WORDS.has(t)));
190
+ }
191
+ /**
192
+ * Computes Jaccard similarity between two token sets.
193
+ * Returns 1.0 for two empty sets, 0.0 if one is empty.
194
+ */
195
+ export function jaccardSimilarity(a, b) {
196
+ if (a.size === 0 && b.size === 0)
197
+ return 1.0;
198
+ if (a.size === 0 || b.size === 0)
199
+ return 0.0;
200
+ let intersection = 0;
201
+ for (const token of a) {
202
+ if (b.has(token))
203
+ intersection++;
204
+ }
205
+ const union = a.size + b.size - intersection;
206
+ return intersection / union;
207
+ }
208
+ /**
209
+ * Checks whether a candidate instinct is semantically similar to any existing instinct.
210
+ *
211
+ * Tokenizes trigger+action for both candidate and each existing instinct,
212
+ * computes Jaccard similarity, and returns the closest match above the threshold.
213
+ *
214
+ * @param candidate - The new instinct being considered (trigger + action)
215
+ * @param existing - All current instincts to check against
216
+ * @param skipId - ID to skip (the candidate's own ID on updates)
217
+ * @param threshold - Similarity threshold; default 0.6
218
+ */
219
+ export function findSimilarInstinct(candidate, existing, skipId, threshold = 0.6) {
220
+ const candidateTokens = tokenize(`${candidate.trigger} ${candidate.action}`);
221
+ let bestMatch = null;
222
+ for (const instinct of existing) {
223
+ if (instinct.id === skipId)
224
+ continue;
225
+ const existingTokens = tokenize(`${instinct.trigger} ${instinct.action}`);
226
+ const similarity = jaccardSimilarity(candidateTokens, existingTokens);
227
+ if (similarity >= threshold) {
228
+ if (bestMatch === null || similarity > bestMatch.similarity) {
229
+ bestMatch = { instinct, similarity };
230
+ }
231
+ }
232
+ }
233
+ return bestMatch;
234
+ }
235
+ //# sourceMappingURL=instinct-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instinct-validator.js","sourceRoot":"","sources":["../src/instinct-validator.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-system-single-shot.d.ts","sourceRoot":"","sources":["../../src/prompts/analyzer-system-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAsHpD"}
1
+ {"version":3,"file":"analyzer-system-single-shot.d.ts","sourceRoot":"","sources":["../../src/prompts/analyzer-system-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CA8JpD"}
@@ -119,6 +119,46 @@ When in doubt, prefer project scope.
119
119
  4. New instincts from observation data alone are capped at 0.85 confidence.
120
120
  5. Check existing instincts (provided in the user message) for duplicates before creating. Update instead.
121
121
  6. Write actions as clear instructions starting with a verb.
122
- 7. Be skeptical of outliers - patterns seen only in unusual circumstances should not become instincts.`;
122
+ 7. Be skeptical of outliers - patterns seen only in unusual circumstances should not become instincts.
123
+
124
+ ## Quality Tiers
125
+
126
+ Not all patterns are worth recording as instincts. Use this classification before creating:
127
+
128
+ ### Tier 1 - Project Conventions (RECORD as instinct)
129
+ Patterns specific to this project's tech stack, codebase conventions, or team practices.
130
+ Examples:
131
+ - "Use the Result<T, E> type for error handling in this project"
132
+ - "Place tests next to source files as *.test.ts"
133
+ - "Prefer functional style - avoid class-based patterns in this codebase"
134
+
135
+ ### Tier 2 - Workflow Patterns (RECORD as global instinct)
136
+ Recurring multi-step workflows that apply across many projects.
137
+ Examples:
138
+ - "Run linter and type-checker after every code change"
139
+ - "Write tests before implementation in TDD projects"
140
+
141
+ ### Tier 3 - Generic Agent Behavior (DO NOT RECORD - already known)
142
+ Fundamental behaviors all coding agents should follow. These are not project-specific patterns.
143
+
144
+ **DO NOT create instincts for:**
145
+ - Reading files before editing them ("read before edit")
146
+ - Grepping for context before modifying code
147
+ - Clarifying ambiguous requirements before starting
148
+ - Using conventional commit message formats
149
+ - Checking for errors after tool calls
150
+ - Any behavior that is basic good practice for any coding agent
151
+
152
+ These patterns belong in AGENTS.md from the start, not in learned instincts.
153
+
154
+ ## AGENTS.md Deduplication
155
+
156
+ The user message includes the current AGENTS.md content for this project and globally.
157
+ Before creating any instinct, check: **is this pattern already covered by AGENTS.md?**
158
+
159
+ If yes: do NOT create an instinct. The pattern is already enforced.
160
+ If a pattern appears in AGENTS.md in the same form, skip it entirely.
161
+
162
+ Only create instincts for patterns that are genuinely absent from AGENTS.md.`;
123
163
  }
124
164
  //# sourceMappingURL=analyzer-system-single-shot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-system-single-shot.js","sourceRoot":"","sources":["../../src/prompts/analyzer-system-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGAoH8F,CAAC;AACxG,CAAC"}
1
+ {"version":3,"file":"analyzer-system-single-shot.js","sourceRoot":"","sources":["../../src/prompts/analyzer-system-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EA4JoE,CAAC;AAC9E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-user-single-shot.d.ts","sourceRoot":"","sources":["../../src/prompts/analyzer-user-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1E,MAAM,WAAW,uBAAuB;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,YAAY,EACrB,iBAAiB,EAAE,QAAQ,EAAE,EAC7B,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,CA2DR"}
1
+ {"version":3,"file":"analyzer-user-single-shot.d.ts","sourceRoot":"","sources":["../../src/prompts/analyzer-user-single-shot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1E,MAAM,WAAW,uBAAuB;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,YAAY,EACrB,iBAAiB,EAAE,QAAQ,EAAE,EAC7B,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAiER"}
@@ -47,7 +47,7 @@ export function buildSingleShotUserPrompt(project, existingInstincts, observatio
47
47
  }
48
48
  parts.push("");
49
49
  }
50
- parts.push("", "## Instructions", "", "1. Review the existing instincts above.", "2. Analyze the new observations for patterns per the system prompt rules.", "3. Return a JSON change-set: create new instincts, update existing ones, or delete obsolete ones.", "4. Apply feedback analysis using the active_instincts field in each observation.", "5. Passive confidence decay has already been applied before this analysis.", "", "Return ONLY the JSON object. No prose, no markdown fences.");
50
+ parts.push("", "## Instructions", "", "1. Review the existing instincts above.", "2. Analyze the new observations for patterns per the system prompt rules.", "3. Return a JSON change-set: create new instincts, update existing ones, or delete obsolete ones.", "4. Apply feedback analysis using the active_instincts field in each observation.", "5. Passive confidence decay has already been applied before this analysis.", "6. Before creating any instinct, check the Existing Guidelines section above.", " If the pattern is already covered by AGENTS.md, do NOT create an instinct for it.", "7. Apply the Quality Tier rules from the system prompt:", " - Generic agent behaviors (read-before-edit, clarify-before-implement) -> skip entirely", " - Project-specific patterns -> project-scoped instinct", " - Universal workflow patterns -> global-scoped instinct", "", "Return ONLY the JSON object. No prose, no markdown fences.");
51
51
  return parts.join("\n");
52
52
  }
53
53
  //# sourceMappingURL=analyzer-user-single-shot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-user-single-shot.js","sourceRoot":"","sources":["../../src/prompts/analyzer-user-single-shot.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAQzE;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAqB,EACrB,iBAA6B,EAC7B,gBAA0B,EAC1B,UAAmC,EAAE;IAErC,MAAM,EAAE,eAAe,GAAG,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,eAAe,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAExF,MAAM,gBAAgB,GACpB,gBAAgB,CAAC,MAAM,GAAG,CAAC;QACzB,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,gCAAgC,CAAC;IAEvC,MAAM,aAAa,GAAG,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAElE,MAAM,KAAK,GAAa;QACtB,oBAAoB;QACpB,EAAE;QACF,eAAe,OAAO,CAAC,EAAE,EAAE;QAC3B,iBAAiB,OAAO,CAAC,IAAI,EAAE;QAC/B,EAAE;QACF,uBAAuB;QACvB,EAAE;QACF,aAAa;QACb,EAAE;QACF,oCAAoC;QACpC,EAAE;QACF,KAAK;QACL,gBAAgB;QAChB,KAAK;KACN,CAAC;IAEF,IAAI,eAAe,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iBAAiB,EACjB,EAAE,EACF,yCAAyC,EACzC,2EAA2E,EAC3E,mGAAmG,EACnG,kFAAkF,EAClF,4EAA4E,EAC5E,EAAE,EACF,4DAA4D,CAC7D,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"analyzer-user-single-shot.js","sourceRoot":"","sources":["../../src/prompts/analyzer-user-single-shot.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAQzE;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAqB,EACrB,iBAA6B,EAC7B,gBAA0B,EAC1B,UAAmC,EAAE;IAErC,MAAM,EAAE,eAAe,GAAG,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,eAAe,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAExF,MAAM,gBAAgB,GACpB,gBAAgB,CAAC,MAAM,GAAG,CAAC;QACzB,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,gCAAgC,CAAC;IAEvC,MAAM,aAAa,GAAG,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAElE,MAAM,KAAK,GAAa;QACtB,oBAAoB;QACpB,EAAE;QACF,eAAe,OAAO,CAAC,EAAE,EAAE;QAC3B,iBAAiB,OAAO,CAAC,IAAI,EAAE;QAC/B,EAAE;QACF,uBAAuB;QACvB,EAAE;QACF,aAAa;QACb,EAAE;QACF,oCAAoC;QACpC,EAAE;QACF,KAAK;QACL,gBAAgB;QAChB,KAAK;KACN,CAAC;IAEF,IAAI,eAAe,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iBAAiB,EACjB,EAAE,EACF,yCAAyC,EACzC,2EAA2E,EAC3E,mGAAmG,EACnG,kFAAkF,EAClF,4EAA4E,EAC5E,+EAA+E,EAC/E,sFAAsF,EACtF,yDAAyD,EACzD,4FAA4F,EAC5F,2DAA2D,EAC3D,4DAA4D,EAC5D,EAAE,EACF,4DAA4D,CAC7D,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Skill scaffolding from instinct clusters.
3
+ *
4
+ * When 3+ related instincts in the same domain form a cohesive topic,
5
+ * generates a SKILL.md file that can be installed as a Pi skill.
6
+ */
7
+ import type { DomainCluster } from "./graduation.js";
8
+ export interface SkillScaffold {
9
+ name: string;
10
+ description: string;
11
+ domain: string;
12
+ content: string;
13
+ sourceInstinctIds: string[];
14
+ }
15
+ /**
16
+ * Generates a SKILL.md scaffold from a domain cluster of instincts.
17
+ */
18
+ export declare function generateSkillScaffold(cluster: DomainCluster): SkillScaffold;
19
+ /**
20
+ * Generates skill scaffolds for all qualifying clusters.
21
+ */
22
+ export declare function generateAllSkillScaffolds(clusters: DomainCluster[]): SkillScaffold[];
23
+ //# sourceMappingURL=skill-scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-scaffold.d.ts","sourceRoot":"","sources":["../src/skill-scaffold.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMrD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAyBD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAgC3E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,EAAE,GACxB,aAAa,EAAE,CAEjB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Skill scaffolding from instinct clusters.
3
+ *
4
+ * When 3+ related instincts in the same domain form a cohesive topic,
5
+ * generates a SKILL.md file that can be installed as a Pi skill.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Helpers
9
+ // ---------------------------------------------------------------------------
10
+ function toSkillName(domain) {
11
+ return domain.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
12
+ }
13
+ function formatInstinctAsSection(instinct, index) {
14
+ return [
15
+ `### ${index + 1}. ${instinct.title}`,
16
+ "",
17
+ `**When:** ${instinct.trigger}`,
18
+ "",
19
+ instinct.action,
20
+ "",
21
+ ].join("\n");
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // Public API
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Generates a SKILL.md scaffold from a domain cluster of instincts.
28
+ */
29
+ export function generateSkillScaffold(cluster) {
30
+ const name = toSkillName(cluster.domain);
31
+ const sortedInstincts = [...cluster.instincts].sort((a, b) => b.confidence - a.confidence);
32
+ const description = `Learned ${cluster.domain} patterns from coding sessions. ` +
33
+ `Covers ${sortedInstincts.length} practices distilled from instinct observations.`;
34
+ const sections = sortedInstincts.map((inst, i) => formatInstinctAsSection(inst, i));
35
+ const content = [
36
+ `# ${cluster.domain} Skill`,
37
+ "",
38
+ `> Auto-generated from ${sortedInstincts.length} graduated instincts in the "${cluster.domain}" domain.`,
39
+ "",
40
+ `## Description`,
41
+ "",
42
+ description,
43
+ "",
44
+ `## Practices`,
45
+ "",
46
+ ...sections,
47
+ ].join("\n");
48
+ return {
49
+ name,
50
+ description,
51
+ domain: cluster.domain,
52
+ content,
53
+ sourceInstinctIds: sortedInstincts.map((i) => i.id),
54
+ };
55
+ }
56
+ /**
57
+ * Generates skill scaffolds for all qualifying clusters.
58
+ */
59
+ export function generateAllSkillScaffolds(clusters) {
60
+ return clusters.map(generateSkillScaffold);
61
+ }
62
+ //# sourceMappingURL=skill-scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-scaffold.js","sourceRoot":"","sources":["../src/skill-scaffold.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,uBAAuB,CAAC,QAAkB,EAAE,KAAa;IAChE,OAAO;QACL,OAAO,KAAK,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE;QACrC,EAAE;QACF,aAAa,QAAQ,CAAC,OAAO,EAAE;QAC/B,EAAE;QACF,QAAQ,CAAC,MAAM;QACf,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAsB;IAC1D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,eAAe,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CACjD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CACtC,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,OAAO,CAAC,MAAM,kCAAkC;QAC7E,UAAU,eAAe,CAAC,MAAM,kDAAkD,CAAC;IAErF,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEpF,MAAM,OAAO,GAAG;QACd,KAAK,OAAO,CAAC,MAAM,QAAQ;QAC3B,EAAE;QACF,yBAAyB,eAAe,CAAC,MAAM,gCAAgC,OAAO,CAAC,MAAM,WAAW;QACxG,EAAE;QACF,gBAAgB;QAChB,EAAE;QACF,WAAW;QACX,EAAE;QACF,cAAc;QACd,EAAE;QACF,GAAG,QAAQ;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACL,IAAI;QACJ,WAAW;QACX,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;QACP,iBAAiB,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAyB;IAEzB,OAAO,QAAQ,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAC7C,CAAC"}
package/dist/types.d.ts CHANGED
@@ -46,7 +46,10 @@ export interface Instinct {
46
46
  inactive_count: number;
47
47
  evidence?: string[];
48
48
  flagged_for_removal?: boolean;
49
+ graduated_to?: GraduationTarget;
50
+ graduated_at?: string;
49
51
  }
52
+ export type GraduationTarget = "agents-md" | "skill" | "command";
50
53
  export interface ProjectEntry {
51
54
  id: string;
52
55
  name: string;
@@ -71,5 +74,10 @@ export interface Config {
71
74
  active_hours_end: number;
72
75
  max_idle_seconds: number;
73
76
  log_path?: string;
77
+ max_total_instincts_per_project: number;
78
+ max_total_instincts_global: number;
79
+ max_new_instincts_per_run: number;
80
+ flagged_cleanup_days: number;
81
+ instinct_ttl_days: number;
74
82
  }
75
83
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,eAAe,GACf,aAAa,GACb,WAAW,GACX,YAAY,GACZ,UAAU,GACV,WAAW,GACX,iBAAiB,GACjB,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAMD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,2BAA2B,EAAE,MAAM,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-continuous-learning",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A Pi extension that observes coding sessions and distills patterns into reusable instincts.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/agents-md.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  /**
2
- * Utility for reading AGENTS.md files.
3
- * Provides a safe wrapper around filesystem access that returns null on any failure.
2
+ * Utility for reading and writing AGENTS.md files.
3
+ * Provides safe wrappers around filesystem access.
4
4
  */
5
5
 
6
- import { existsSync, readFileSync } from "node:fs";
6
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
7
+ import { dirname } from "node:path";
8
+ import type { Instinct } from "./types.js";
7
9
 
8
10
  /**
9
11
  * Reads an AGENTS.md file and returns its content.
@@ -21,3 +23,71 @@ export function readAgentsMd(filePath: string): string | null {
21
23
  return null;
22
24
  }
23
25
  }
26
+
27
+ /**
28
+ * Formats an instinct as an AGENTS.md section entry.
29
+ * Produces a markdown block with the instinct title as heading and
30
+ * trigger/action as content.
31
+ */
32
+ export function formatInstinctAsAgentsMdEntry(instinct: Instinct): string {
33
+ const lines = [
34
+ `### ${instinct.title}`,
35
+ "",
36
+ `**When:** ${instinct.trigger}`,
37
+ "",
38
+ instinct.action,
39
+ "",
40
+ ];
41
+ return lines.join("\n");
42
+ }
43
+
44
+ /**
45
+ * Generates a complete AGENTS.md diff showing proposed additions.
46
+ * Returns the full new content that would result from appending the entries.
47
+ */
48
+ export function generateAgentsMdDiff(
49
+ currentContent: string | null,
50
+ instincts: Instinct[]
51
+ ): string {
52
+ const entries = instincts.map(formatInstinctAsAgentsMdEntry);
53
+ const graduatedSection = [
54
+ "",
55
+ "## Graduated Instincts",
56
+ "",
57
+ ...entries,
58
+ ].join("\n");
59
+
60
+ if (currentContent === null || currentContent.trim().length === 0) {
61
+ return `# Project Guidelines\n${graduatedSection}\n`;
62
+ }
63
+
64
+ // If the section already exists, append to it; otherwise add a new section
65
+ if (currentContent.includes("## Graduated Instincts")) {
66
+ return `${currentContent.trimEnd()}\n\n${entries.join("\n")}\n`;
67
+ }
68
+
69
+ return `${currentContent.trimEnd()}\n${graduatedSection}\n`;
70
+ }
71
+
72
+ /**
73
+ * Appends graduated instinct entries to an AGENTS.md file.
74
+ * Creates the file and parent directories if they don't exist.
75
+ *
76
+ * @param filePath - Absolute path to AGENTS.md
77
+ * @param instincts - Instincts to append as entries
78
+ * @returns The new file content that was written
79
+ */
80
+ export function appendToAgentsMd(
81
+ filePath: string,
82
+ instincts: Instinct[]
83
+ ): string {
84
+ if (instincts.length === 0) return readAgentsMd(filePath) ?? "";
85
+
86
+ const currentContent = readAgentsMd(filePath);
87
+ const newContent = generateAgentsMdDiff(currentContent, instincts);
88
+
89
+ mkdirSync(dirname(filePath), { recursive: true });
90
+ writeFileSync(filePath, newContent, "utf-8");
91
+
92
+ return newContent;
93
+ }
@@ -9,6 +9,7 @@ import type { AssistantMessage, Context } from "@mariozechner/pi-ai";
9
9
  import { complete } from "@mariozechner/pi-ai";
10
10
  import type { Instinct } from "../types.js";
11
11
  import { serializeInstinct } from "../instinct-parser.js";
12
+ import { validateInstinct, findSimilarInstinct } from "../instinct-validator.js";
12
13
 
13
14
  export interface InstinctChangePayload {
14
15
  id: string;
@@ -73,20 +74,49 @@ export function parseChanges(raw: string): InstinctChange[] {
73
74
 
74
75
  /**
75
76
  * Builds a full Instinct from a create/update change.
76
- * Returns null for delete changes or changes with missing instinct data.
77
+ * Returns null for delete changes, changes with missing instinct data,
78
+ * invalid fields, or semantically duplicate actions.
79
+ *
80
+ * @param change - The change to apply
81
+ * @param existing - The existing instinct with this ID, if any
82
+ * @param projectId - Project ID for scoping
83
+ * @param allInstincts - All current instincts, used for dedup check on creates
77
84
  */
78
85
  export function buildInstinctFromChange(
79
86
  change: InstinctChange,
80
87
  existing: Instinct | null,
81
- projectId: string
88
+ projectId: string,
89
+ allInstincts: Instinct[] = []
82
90
  ): Instinct | null {
83
91
  if (change.action === "delete" || !change.instinct) {
84
92
  return null;
85
93
  }
86
94
 
87
- const now = new Date().toISOString();
88
95
  const payload = change.instinct;
89
96
 
97
+ const validation = validateInstinct({
98
+ action: payload.action,
99
+ trigger: payload.trigger,
100
+ domain: payload.domain,
101
+ });
102
+ if (!validation.valid) {
103
+ return null;
104
+ }
105
+
106
+ // On create, reject if semantically similar to an existing instinct (skip self on update)
107
+ if (change.action === "create") {
108
+ const similar = findSimilarInstinct(
109
+ { trigger: payload.trigger, action: payload.action },
110
+ allInstincts,
111
+ payload.id
112
+ );
113
+ if (similar) {
114
+ return null;
115
+ }
116
+ }
117
+
118
+ const now = new Date().toISOString();
119
+
90
120
  return {
91
121
  id: payload.id,
92
122
  title: payload.title,