pi-continuous-learning 0.8.0 → 0.9.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 (62) hide show
  1. package/dist/cli/analyze.js +237 -13
  2. package/dist/cli/analyze.js.map +1 -1
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +7 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/consolidation.d.ts +43 -0
  7. package/dist/consolidation.d.ts.map +1 -0
  8. package/dist/consolidation.js +104 -0
  9. package/dist/consolidation.js.map +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +5 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/instinct-cleanup.d.ts +14 -0
  14. package/dist/instinct-cleanup.d.ts.map +1 -1
  15. package/dist/instinct-cleanup.js +59 -3
  16. package/dist/instinct-cleanup.js.map +1 -1
  17. package/dist/instinct-contradiction.d.ts +42 -0
  18. package/dist/instinct-contradiction.d.ts.map +1 -0
  19. package/dist/instinct-contradiction.js +164 -0
  20. package/dist/instinct-contradiction.js.map +1 -0
  21. package/dist/instinct-dream.d.ts +12 -0
  22. package/dist/instinct-dream.d.ts.map +1 -0
  23. package/dist/instinct-dream.js +33 -0
  24. package/dist/instinct-dream.js.map +1 -0
  25. package/dist/prompts/analyzer-system-single-shot.d.ts.map +1 -1
  26. package/dist/prompts/analyzer-system-single-shot.js +16 -0
  27. package/dist/prompts/analyzer-system-single-shot.js.map +1 -1
  28. package/dist/prompts/analyzer-user-single-shot.d.ts.map +1 -1
  29. package/dist/prompts/analyzer-user-single-shot.js +1 -1
  30. package/dist/prompts/analyzer-user-single-shot.js.map +1 -1
  31. package/dist/prompts/consolidate-system.d.ts +6 -0
  32. package/dist/prompts/consolidate-system.d.ts.map +1 -0
  33. package/dist/prompts/consolidate-system.js +102 -0
  34. package/dist/prompts/consolidate-system.js.map +1 -0
  35. package/dist/prompts/consolidate-user.d.ts +19 -0
  36. package/dist/prompts/consolidate-user.d.ts.map +1 -0
  37. package/dist/prompts/consolidate-user.js +45 -0
  38. package/dist/prompts/consolidate-user.js.map +1 -0
  39. package/dist/prompts/dream-prompt.d.ts +7 -0
  40. package/dist/prompts/dream-prompt.d.ts.map +1 -0
  41. package/dist/prompts/dream-prompt.js +64 -0
  42. package/dist/prompts/dream-prompt.js.map +1 -0
  43. package/dist/prompts/evolve-prompt.d.ts.map +1 -1
  44. package/dist/prompts/evolve-prompt.js +6 -5
  45. package/dist/prompts/evolve-prompt.js.map +1 -1
  46. package/dist/types.d.ts +3 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/cli/analyze.ts +268 -13
  50. package/src/config.ts +10 -0
  51. package/src/consolidation.ts +162 -0
  52. package/src/index.ts +15 -0
  53. package/src/instinct-cleanup.ts +62 -3
  54. package/src/instinct-contradiction.ts +202 -0
  55. package/src/instinct-dream.ts +62 -0
  56. package/src/prompts/analyzer-system-single-shot.ts +16 -0
  57. package/src/prompts/analyzer-user-single-shot.ts +2 -0
  58. package/src/prompts/consolidate-system.ts +101 -0
  59. package/src/prompts/consolidate-user.ts +88 -0
  60. package/src/prompts/dream-prompt.ts +88 -0
  61. package/src/prompts/evolve-prompt.ts +6 -5
  62. package/src/types.ts +4 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * User prompt builder for the consolidation (dream) pass.
3
+ * Embeds all instincts and optional AGENTS.md context.
4
+ */
5
+ import type { Instinct, InstalledSkill } from "../types.js";
6
+ export interface ConsolidatePromptOptions {
7
+ agentsMdProject?: string | null;
8
+ agentsMdGlobal?: string | null;
9
+ installedSkills?: InstalledSkill[];
10
+ projectName?: string;
11
+ projectId?: string;
12
+ }
13
+ /**
14
+ * Builds the user prompt for a consolidation pass.
15
+ * Unlike the observation analyzer, this prompt contains only instincts
16
+ * and guidelines - no observations.
17
+ */
18
+ export declare function buildConsolidateUserPrompt(instincts: readonly Instinct[], options?: ConsolidatePromptOptions): string;
19
+ //# sourceMappingURL=consolidate-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate-user.d.ts","sourceRoot":"","sources":["../../src/prompts/consolidate-user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,GAAE,wBAA6B,GACrC,MAAM,CA+DR"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * User prompt builder for the consolidation (dream) pass.
3
+ * Embeds all instincts and optional AGENTS.md context.
4
+ */
5
+ import { formatInstinctsCompact } from "../cli/analyze-single-shot.js";
6
+ /**
7
+ * Builds the user prompt for a consolidation pass.
8
+ * Unlike the observation analyzer, this prompt contains only instincts
9
+ * and guidelines - no observations.
10
+ */
11
+ export function buildConsolidateUserPrompt(instincts, options = {}) {
12
+ const { agentsMdProject = null, agentsMdGlobal = null, installedSkills = [], projectName, projectId, } = options;
13
+ const instinctBlock = instincts.length > 0
14
+ ? formatInstinctsCompact([...instincts])
15
+ : "(no instincts)";
16
+ const parts = [];
17
+ if (projectId || projectName) {
18
+ parts.push("## Project Context", "");
19
+ if (projectId)
20
+ parts.push(`project_id: ${projectId}`);
21
+ if (projectName)
22
+ parts.push(`project_name: ${projectName}`);
23
+ parts.push("");
24
+ }
25
+ parts.push("## Full Instinct Corpus", "", instinctBlock, "", `Total instincts: ${instincts.length}`, "");
26
+ if (agentsMdProject != null || agentsMdGlobal != null) {
27
+ parts.push("## Existing Guidelines (AGENTS.md)", "");
28
+ if (agentsMdProject != null) {
29
+ parts.push("### Project AGENTS.md", "", agentsMdProject, "");
30
+ }
31
+ if (agentsMdGlobal != null) {
32
+ parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
33
+ }
34
+ }
35
+ if (installedSkills.length > 0) {
36
+ parts.push("## Installed Skills", "");
37
+ for (const skill of installedSkills) {
38
+ parts.push(`- **${skill.name}**: ${skill.description}`);
39
+ }
40
+ parts.push("");
41
+ }
42
+ parts.push("## Instructions", "", "1. Review ALL instincts above as a complete corpus.", "2. Identify merge candidates, contradictions, stale entries, and promotion candidates.", "3. Check for instincts duplicated by AGENTS.md guidelines.", "4. Return a JSON change-set with your proposed modifications.", "5. Prefer conservative changes - only act when the improvement is clear.", "", "Return ONLY the JSON object. No prose, no markdown fences.");
43
+ return parts.join("\n");
44
+ }
45
+ //# sourceMappingURL=consolidate-user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate-user.js","sourceRoot":"","sources":["../../src/prompts/consolidate-user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAUvE;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,SAA8B,EAC9B,UAAoC,EAAE;IAEtC,MAAM,EACJ,eAAe,GAAG,IAAI,EACtB,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,EAAE,EACpB,WAAW,EACX,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GACjB,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;QACxC,CAAC,CAAC,gBAAgB,CAAC;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;QACtD,IAAI,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,yBAAyB,EACzB,EAAE,EACF,aAAa,EACb,EAAE,EACF,oBAAoB,SAAS,CAAC,MAAM,EAAE,EACtC,EAAE,CACH,CAAC;IAEF,IAAI,eAAe,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;QACrD,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,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACtC,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,iBAAiB,EACjB,EAAE,EACF,qDAAqD,EACrD,wFAAwF,EACxF,4DAA4D,EAC5D,+DAA+D,EAC/D,0EAA0E,EAC1E,EAAE,EACF,4DAA4D,CAC7D,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Prompt builder for the interactive /instinct-dream command.
3
+ * Similar to evolve-prompt but focused on holistic consolidation tasks.
4
+ */
5
+ import type { Instinct, InstalledSkill } from "../types.js";
6
+ export declare function buildDreamPrompt(instincts: Instinct[], agentsMdProject?: string | null, agentsMdGlobal?: string | null, installedSkills?: InstalledSkill[]): string;
7
+ //# sourceMappingURL=dream-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/dream-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA8B5D,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,CA+CR"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Prompt builder for the interactive /instinct-dream command.
3
+ * Similar to evolve-prompt but focused on holistic consolidation tasks.
4
+ */
5
+ function summarizeInstinct(i) {
6
+ return {
7
+ id: i.id,
8
+ title: i.title,
9
+ trigger: i.trigger,
10
+ action: i.action,
11
+ confidence: i.confidence,
12
+ domain: i.domain,
13
+ scope: i.scope,
14
+ confirmed_count: i.confirmed_count,
15
+ contradicted_count: i.contradicted_count,
16
+ inactive_count: i.inactive_count,
17
+ };
18
+ }
19
+ export function buildDreamPrompt(instincts, agentsMdProject, agentsMdGlobal, installedSkills) {
20
+ const parts = [
21
+ "Perform a holistic consolidation review of my learned instincts.",
22
+ "You have access to instinct tools (instinct_merge, instinct_delete, instinct_write) to act on your findings.",
23
+ "",
24
+ "## Full Instinct Corpus",
25
+ "",
26
+ "```json",
27
+ JSON.stringify(instincts.map(summarizeInstinct), null, 2),
28
+ "```",
29
+ "",
30
+ `Total: ${instincts.length} instincts`,
31
+ "",
32
+ "## Consolidation Tasks",
33
+ "",
34
+ "Review the entire corpus and identify:",
35
+ "",
36
+ "1. **Merge candidates**: Instincts with semantically similar triggers or actions (even if worded differently). Merge into a single, stronger instinct using instinct_merge.",
37
+ "2. **Contradictions**: Instincts with similar triggers but opposing actions. Resolve by keeping the stronger one or merging into a nuanced context-dependent instinct.",
38
+ "3. **Stale instincts**: Entries with zero confirmations, high inactive_count, or references to outdated patterns. Delete them.",
39
+ "4. **AGENTS.md duplicates**: Instincts already covered by the guidelines below. Delete them.",
40
+ "5. **Promotion candidates**: Project-scoped instincts with confidence >= 0.7 and confirmed_count >= 3 that apply universally. Promote to global scope.",
41
+ "6. **Skill shadows**: Instincts whose purpose is already served by an installed skill. Delete them.",
42
+ "7. **Quality cleanup**: Instincts with confidence < 0.2, vague triggers, or flagged_for_removal. Clean up or delete.",
43
+ "",
44
+ "Present your findings conversationally. For each suggestion, explain your reasoning and ask if I'd like you to take action using the instinct tools.",
45
+ "If the corpus looks healthy, say so briefly.",
46
+ ];
47
+ if (agentsMdProject || agentsMdGlobal) {
48
+ parts.push("", "## Current Guidelines (AGENTS.md)", "");
49
+ if (agentsMdProject) {
50
+ parts.push("### Project AGENTS.md", "", agentsMdProject, "");
51
+ }
52
+ if (agentsMdGlobal) {
53
+ parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
54
+ }
55
+ }
56
+ if (installedSkills && installedSkills.length > 0) {
57
+ parts.push("", "## Installed Skills", "");
58
+ for (const skill of installedSkills) {
59
+ parts.push(`- **${skill.name}**: ${skill.description}`);
60
+ }
61
+ }
62
+ return parts.join("\n");
63
+ }
64
+ //# sourceMappingURL=dream-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-prompt.js","sourceRoot":"","sources":["../../src/prompts/dream-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,eAAe,EAAE,CAAC,CAAC,eAAe;QAClC,kBAAkB,EAAE,CAAC,CAAC,kBAAkB;QACxC,cAAc,EAAE,CAAC,CAAC,cAAc;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,kEAAkE;QAClE,8GAA8G;QAC9G,EAAE;QACF,yBAAyB;QACzB,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,UAAU,SAAS,CAAC,MAAM,YAAY;QACtC,EAAE;QACF,wBAAwB;QACxB,EAAE;QACF,wCAAwC;QACxC,EAAE;QACF,6KAA6K;QAC7K,wKAAwK;QACxK,gIAAgI;QAChI,8FAA8F;QAC9F,wJAAwJ;QACxJ,qGAAqG;QACrG,sHAAsH;QACtH,EAAE;QACF,sJAAsJ;QACtJ,8CAA8C;KAC/C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,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;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"evolve-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwB5D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,CAyCR"}
1
+ {"version":3,"file":"evolve-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwB5D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,CA0CR"}
@@ -22,11 +22,12 @@ export function buildEvolvePrompt(instincts, agentsMdProject, agentsMdGlobal, in
22
22
  "",
23
23
  "## Analysis Tasks",
24
24
  "",
25
- "1. **Merge candidates**: Find instincts with semantically similar triggers or actions (even if worded differently). Offer to merge them using the instinct_merge tool.",
26
- "2. **Duplicates of AGENTS.md**: Flag instincts already covered by the guidelines below. Offer to delete them.",
27
- "3. **Promotion candidates**: Project-scoped instincts with confidence >= 0.7 that could become global.",
28
- "4. **Skill shadows**: Instincts whose purpose is already served by an installed skill (listed below). Offer to delete them.",
29
- "5. **Low-confidence cleanup**: Instincts with confidence < 0.3 or flagged_for_removal that should be deleted.",
25
+ "1. **Contradictions**: Find instincts with similar triggers but opposing actions (e.g., 'prefer X' vs 'avoid X', 'always do Y' vs 'never do Y'). Offer to delete the weaker one, or merge both into a nuanced context-dependent instinct.",
26
+ "2. **Merge candidates**: Find instincts with semantically similar triggers or actions (even if worded differently). Offer to merge them using the instinct_merge tool.",
27
+ "3. **Duplicates of AGENTS.md**: Flag instincts already covered by the guidelines below. Offer to delete them.",
28
+ "4. **Promotion candidates**: Project-scoped instincts with confidence >= 0.7 that could become global.",
29
+ "5. **Skill shadows**: Instincts whose purpose is already served by an installed skill (listed below). Offer to delete them.",
30
+ "6. **Low-confidence cleanup**: Instincts with confidence < 0.3 or flagged_for_removal that should be deleted.",
30
31
  "",
31
32
  "Present your findings conversationally. For each suggestion, explain your reasoning and ask if I'd like you to take action using the instinct tools.",
32
33
  "If there are no issues, say so briefly.",
@@ -1 +1 @@
1
- {"version":3,"file":"evolve-prompt.js","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAYA,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,qFAAqF;QACrF,8GAA8G;QAC9G,EAAE;QACF,cAAc;QACd,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,wKAAwK;QACxK,+GAA+G;QAC/G,wGAAwG;QACxG,6HAA6H;QAC7H,+GAA+G;QAC/G,EAAE;QACF,sJAAsJ;QACtJ,yCAAyC;KAC1C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,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;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"evolve-prompt.js","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAYA,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,qFAAqF;QACrF,8GAA8G;QAC9G,EAAE;QACF,cAAc;QACd,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,2OAA2O;QAC3O,wKAAwK;QACxK,+GAA+G;QAC/G,wGAAwG;QACxG,6HAA6H;QAC7H,+GAA+G;QAC/G,EAAE;QACF,sJAAsJ;QACtJ,yCAAyC;KAC1C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,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;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/dist/types.d.ts CHANGED
@@ -80,5 +80,8 @@ export interface Config {
80
80
  max_new_instincts_per_run: number;
81
81
  flagged_cleanup_days: number;
82
82
  instinct_ttl_days: number;
83
+ dreaming_enabled: boolean;
84
+ consolidation_interval_days: number;
85
+ consolidation_min_sessions: number;
83
86
  }
84
87
  //# 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;IAC9B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAMjE,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;IAElB,+BAA+B,EAAE,MAAM,CAAC;IACxC,0BAA0B,EAAE,MAAM,CAAC;IACnC,yBAAyB,EAAE,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC3B"}
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.8.0",
3
+ "version": "0.9.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",
@@ -21,6 +21,14 @@ import {
21
21
  getProjectInstinctsDir,
22
22
  getGlobalInstinctsDir,
23
23
  } from "../storage.js";
24
+ import {
25
+ checkConsolidationGate,
26
+ countDistinctSessions,
27
+ loadConsolidationMeta,
28
+ saveConsolidationMeta,
29
+ } from "../consolidation.js";
30
+ import { buildConsolidateSystemPrompt } from "../prompts/consolidate-system.js";
31
+ import { buildConsolidateUserPrompt } from "../prompts/consolidate-user.js";
24
32
  import { countObservations } from "../observations.js";
25
33
  import { runDecayPass } from "../instinct-decay.js";
26
34
  import { runCleanupPass } from "../instinct-cleanup.js";
@@ -447,10 +455,218 @@ async function analyzeProject(
447
455
  return { ran: true, stats };
448
456
  }
449
457
 
458
+ // ---------------------------------------------------------------------------
459
+ // Consolidation mode
460
+ // ---------------------------------------------------------------------------
461
+
462
+ async function consolidateProject(
463
+ project: ProjectEntry,
464
+ config: ReturnType<typeof loadConfig>,
465
+ baseDir: string,
466
+ logger: AnalyzeLogger,
467
+ force: boolean
468
+ ): Promise<AnalyzeResult> {
469
+ const obsPath = getObservationsPath(project.id, baseDir);
470
+ const sessionCount = countDistinctSessions(obsPath);
471
+ const meta = loadConsolidationMeta(project.id, baseDir);
472
+
473
+ if (!force) {
474
+ const gate = checkConsolidationGate({
475
+ meta,
476
+ currentSessionCount: sessionCount,
477
+ intervalDays: config.consolidation_interval_days ?? DEFAULT_CONFIG.consolidation_interval_days,
478
+ minSessions: config.consolidation_min_sessions ?? DEFAULT_CONFIG.consolidation_min_sessions,
479
+ });
480
+
481
+ if (!gate.eligible) {
482
+ return { ran: false, skippedReason: `consolidation gate: ${gate.reason}` };
483
+ }
484
+ }
485
+
486
+ const startTime = Date.now();
487
+ logger.info(`Consolidating ${project.name}`, {
488
+ event: "consolidation_start",
489
+ project_id: project.id,
490
+ project_name: project.name,
491
+ session_count: sessionCount,
492
+ });
493
+
494
+ // Run cleanup and decay before consolidation
495
+ runCleanupPass(project.id, config, baseDir);
496
+ runDecayPass(project.id, baseDir);
497
+
498
+ // Load all instincts
499
+ const projectInstincts = loadProjectInstincts(project.id, baseDir);
500
+ const globalInstincts = loadGlobalInstincts(baseDir);
501
+ const allInstincts = [...projectInstincts, ...globalInstincts];
502
+
503
+ if (allInstincts.length === 0) {
504
+ return { ran: false, skippedReason: "no instincts to consolidate" };
505
+ }
506
+
507
+ // Load AGENTS.md for deduplication
508
+ const agentsMdProject = readAgentsMd(join(project.root, "AGENTS.md"));
509
+ const agentsMdGlobal = readAgentsMd(join(homedir(), ".pi", "agent", "AGENTS.md"));
510
+
511
+ let installedSkills: InstalledSkill[] = [];
512
+ try {
513
+ const { loadSkills } = await import("@mariozechner/pi-coding-agent");
514
+ const result = loadSkills({ cwd: project.root });
515
+ installedSkills = result.skills.map((s: { name: string; description: string }) => ({
516
+ name: s.name,
517
+ description: s.description,
518
+ }));
519
+ } catch {
520
+ // Best effort
521
+ }
522
+
523
+ const systemPrompt = buildConsolidateSystemPrompt();
524
+ const userPrompt = buildConsolidateUserPrompt(allInstincts, {
525
+ agentsMdProject,
526
+ agentsMdGlobal,
527
+ installedSkills,
528
+ projectName: project.name,
529
+ projectId: project.id,
530
+ });
531
+
532
+ const authStorage = AuthStorage.create();
533
+ const modelId = (config.model || DEFAULT_CONFIG.model) as Parameters<typeof getModel>[1];
534
+ const model = getModel("anthropic", modelId);
535
+ const apiKey = await authStorage.getApiKey("anthropic");
536
+
537
+ if (!apiKey) {
538
+ throw new Error("No Anthropic API key configured. Set via auth.json or ANTHROPIC_API_KEY.");
539
+ }
540
+
541
+ const context = {
542
+ systemPrompt,
543
+ messages: [
544
+ { role: "user" as const, content: userPrompt, timestamp: Date.now() },
545
+ ],
546
+ };
547
+
548
+ const timeoutMs = (config.timeout_seconds ?? DEFAULT_CONFIG.timeout_seconds) * 1000;
549
+ const abortController = new AbortController();
550
+ const timeoutHandle = setTimeout(() => abortController.abort(), timeoutMs);
551
+
552
+ const instinctCounts = { created: 0, updated: 0, deleted: 0 };
553
+ const createdSummaries: InstinctChangeSummary[] = [];
554
+ const updatedSummaries: InstinctChangeSummary[] = [];
555
+ const deletedSummaries: InstinctChangeSummary[] = [];
556
+ const projectInstinctsDir = getProjectInstinctsDir(project.id, "personal", baseDir);
557
+ const globalInstinctsDir = getGlobalInstinctsDir("personal", baseDir);
558
+
559
+ let singleShotMessage;
560
+ try {
561
+ const result = await runSingleShot(context, model, apiKey, abortController.signal);
562
+ singleShotMessage = result.message;
563
+
564
+ // Consolidation allows more creates than normal analysis (merges produce new instincts)
565
+ const maxNewInstincts = (config.max_new_instincts_per_run ?? DEFAULT_CONFIG.max_new_instincts_per_run) * 2;
566
+ let createsRemaining = maxNewInstincts;
567
+
568
+ for (const change of result.changes) {
569
+ if (change.action === "delete") {
570
+ const id = change.id;
571
+ if (!id) continue;
572
+ const dir = change.scope === "global" ? globalInstinctsDir : projectInstinctsDir;
573
+ const filePath = join(dir, `${id}.md`);
574
+ if (existsSync(filePath)) {
575
+ unlinkSync(filePath);
576
+ instinctCounts.deleted++;
577
+ deletedSummaries.push({ id, title: id, scope: change.scope ?? "project" });
578
+ }
579
+ } else if (change.action === "create") {
580
+ if (createsRemaining <= 0) continue;
581
+ const existing = allInstincts.find((i) => i.id === change.instinct?.id) ?? null;
582
+ const instinct = buildInstinctFromChange(change, existing, project.id, allInstincts);
583
+ if (!instinct) continue;
584
+
585
+ const dir = instinct.scope === "global" ? globalInstinctsDir : projectInstinctsDir;
586
+ saveInstinct(instinct, dir);
587
+ instinctCounts.created++;
588
+ createsRemaining--;
589
+ createdSummaries.push({
590
+ id: instinct.id,
591
+ title: instinct.title,
592
+ scope: instinct.scope,
593
+ trigger: instinct.trigger,
594
+ action: instinct.action,
595
+ });
596
+ } else {
597
+ const existing = allInstincts.find((i) => i.id === change.instinct?.id) ?? null;
598
+ const instinct = buildInstinctFromChange(change, existing, project.id, allInstincts);
599
+ if (!instinct) continue;
600
+
601
+ const dir = instinct.scope === "global" ? globalInstinctsDir : projectInstinctsDir;
602
+ saveInstinct(instinct, dir);
603
+ instinctCounts.updated++;
604
+ const delta = existing ? instinct.confidence - existing.confidence : undefined;
605
+ updatedSummaries.push({
606
+ id: instinct.id,
607
+ title: instinct.title,
608
+ scope: instinct.scope,
609
+ ...(delta !== undefined ? { confidence_delta: delta } : {}),
610
+ });
611
+ }
612
+ }
613
+ } finally {
614
+ clearTimeout(timeoutHandle);
615
+ }
616
+
617
+ const usage = singleShotMessage!.usage;
618
+ const durationMs = Date.now() - startTime;
619
+
620
+ const stats: ProjectRunStats = {
621
+ project_id: project.id,
622
+ project_name: project.name,
623
+ duration_ms: durationMs,
624
+ observations_processed: 0,
625
+ observations_total: 0,
626
+ instincts_created: instinctCounts.created,
627
+ instincts_updated: instinctCounts.updated,
628
+ instincts_deleted: instinctCounts.deleted,
629
+ tokens_input: usage.input,
630
+ tokens_output: usage.output,
631
+ tokens_cache_read: usage.cacheRead,
632
+ tokens_cache_write: usage.cacheWrite,
633
+ tokens_total: usage.totalTokens,
634
+ cost_usd: usage.cost.total,
635
+ model: modelId,
636
+ };
637
+
638
+ logger.projectComplete(stats);
639
+
640
+ // Write analysis event for extension notification
641
+ const analysisEvent: AnalysisEvent = {
642
+ timestamp: new Date().toISOString(),
643
+ project_id: project.id,
644
+ project_name: project.name,
645
+ created: createdSummaries,
646
+ updated: updatedSummaries,
647
+ deleted: deletedSummaries,
648
+ };
649
+ appendAnalysisEvent(analysisEvent, baseDir);
650
+
651
+ // Update consolidation meta
652
+ saveConsolidationMeta(
653
+ project.id,
654
+ {
655
+ last_consolidation_at: new Date().toISOString(),
656
+ last_consolidation_session_count: sessionCount,
657
+ },
658
+ baseDir
659
+ );
660
+
661
+ return { ran: true, stats };
662
+ }
663
+
450
664
  // ---------------------------------------------------------------------------
451
665
  // Main
452
666
  // ---------------------------------------------------------------------------
453
667
 
668
+ const isConsolidateOnly = process.argv.includes("--consolidate");
669
+
454
670
  async function main(): Promise<void> {
455
671
  const baseDir = getBaseDir();
456
672
  const config = loadConfig();
@@ -481,21 +697,60 @@ async function main(): Promise<void> {
481
697
  let errored = 0;
482
698
  const allProjectStats: ProjectRunStats[] = [];
483
699
 
484
- for (const project of projects) {
485
- try {
486
- const result = await analyzeProject(project, config, baseDir, logger);
487
- if (result.ran && result.stats) {
488
- processed++;
489
- allProjectStats.push(result.stats);
490
- } else {
491
- skipped++;
492
- if (result.skippedReason) {
493
- logger.projectSkipped(project.id, project.name, result.skippedReason);
700
+ if (isConsolidateOnly) {
701
+ // --consolidate: manual trigger, consolidation only, skip gates
702
+ for (const project of projects) {
703
+ try {
704
+ const result = await consolidateProject(project, config, baseDir, logger, true);
705
+ if (result.ran && result.stats) {
706
+ processed++;
707
+ allProjectStats.push(result.stats);
708
+ } else {
709
+ skipped++;
710
+ if (result.skippedReason) {
711
+ logger.projectSkipped(project.id, project.name, result.skippedReason);
712
+ }
713
+ }
714
+ } catch (err) {
715
+ errored++;
716
+ logger.projectError(project.id, project.name, err);
717
+ }
718
+ }
719
+ } else {
720
+ // Normal mode: analyze observations, then opportunistic consolidation
721
+ for (const project of projects) {
722
+ try {
723
+ const result = await analyzeProject(project, config, baseDir, logger);
724
+ if (result.ran && result.stats) {
725
+ processed++;
726
+ allProjectStats.push(result.stats);
727
+ } else {
728
+ skipped++;
729
+ if (result.skippedReason) {
730
+ logger.projectSkipped(project.id, project.name, result.skippedReason);
731
+ }
732
+ }
733
+ } catch (err) {
734
+ errored++;
735
+ logger.projectError(project.id, project.name, err);
736
+ }
737
+ }
738
+
739
+ // Opportunistic consolidation: run if enabled and gates pass
740
+ if (config.dreaming_enabled) {
741
+ for (const project of projects) {
742
+ try {
743
+ const result = await consolidateProject(project, config, baseDir, logger, false);
744
+ if (result.ran && result.stats) {
745
+ processed++;
746
+ allProjectStats.push(result.stats);
747
+ } else if (result.skippedReason) {
748
+ logger.projectSkipped(project.id, project.name, result.skippedReason);
749
+ }
750
+ } catch (err) {
751
+ logger.projectError(project.id, project.name, err);
494
752
  }
495
753
  }
496
- } catch (err) {
497
- errored++;
498
- logger.projectError(project.id, project.name, err);
499
754
  }
500
755
  }
501
756
 
package/src/config.ts CHANGED
@@ -9,6 +9,10 @@ import * as path from "node:path";
9
9
  import { Type, type Static } from "@sinclair/typebox";
10
10
  import { Value } from "@sinclair/typebox/value";
11
11
  import type { Config } from "./types.js";
12
+ import {
13
+ DEFAULT_CONSOLIDATION_INTERVAL_DAYS,
14
+ DEFAULT_CONSOLIDATION_MIN_SESSIONS,
15
+ } from "./consolidation.js";
12
16
 
13
17
  // ---------------------------------------------------------------------------
14
18
  // Constants
@@ -83,6 +87,9 @@ export const DEFAULT_CONFIG: Config = {
83
87
  max_new_instincts_per_run: 3,
84
88
  flagged_cleanup_days: 7,
85
89
  instinct_ttl_days: 28,
90
+ dreaming_enabled: true,
91
+ consolidation_interval_days: DEFAULT_CONSOLIDATION_INTERVAL_DAYS,
92
+ consolidation_min_sessions: DEFAULT_CONSOLIDATION_MIN_SESSIONS,
86
93
  };
87
94
 
88
95
  // ---------------------------------------------------------------------------
@@ -108,6 +115,9 @@ const PartialConfigSchema = Type.Partial(
108
115
  max_new_instincts_per_run: Type.Number(),
109
116
  flagged_cleanup_days: Type.Number(),
110
117
  instinct_ttl_days: Type.Number(),
118
+ dreaming_enabled: Type.Boolean(),
119
+ consolidation_interval_days: Type.Number(),
120
+ consolidation_min_sessions: Type.Number(),
111
121
  })
112
122
  );
113
123