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 @@
1
+ {"version":3,"file":"observer-guard.d.ts","sourceRoot":"","sources":["../src/observer-guard.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAGhE"}
@@ -0,0 +1,13 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ const LEARNING_BASE_DIR = join(homedir(), ".pi", "continuous-learning");
4
+ const LEARNING_BASE_DIR_PREFIX = LEARNING_BASE_DIR + "/";
5
+ export function shouldSkipPath(filePath) {
6
+ return filePath === LEARNING_BASE_DIR || filePath.startsWith(LEARNING_BASE_DIR_PREFIX);
7
+ }
8
+ export function shouldSkipObservation(filePath) {
9
+ if (filePath !== undefined && shouldSkipPath(filePath))
10
+ return true;
11
+ return false;
12
+ }
13
+ //# sourceMappingURL=observer-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer-guard.js","sourceRoot":"","sources":["../src/observer-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;AACxE,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,GAAG,CAAC;AAEzD,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,QAAQ,KAAK,iBAAiB,IAAI,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAiB;IACrD,IAAI,QAAQ,KAAK,SAAS,IAAI,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Project detection via git remote URL hashing.
3
+ * Scopes observations and instincts to the correct project.
4
+ */
5
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
6
+ import type { ProjectEntry } from "./types.js";
7
+ /**
8
+ * Detect the current project by inspecting git remote URL.
9
+ *
10
+ * Resolution order:
11
+ * 1. git remote get-url origin -> hash of remote URL
12
+ * 2. git rev-parse --show-toplevel -> hash of repo root path
13
+ * 3. fallback to project ID "global"
14
+ */
15
+ export declare function detectProject(pi: ExtensionAPI, cwd: string): Promise<ProjectEntry>;
16
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAyCvB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Project detection via git remote URL hashing.
3
+ * Scopes observations and instincts to the correct project.
4
+ */
5
+ import { createHash } from "node:crypto";
6
+ import { basename } from "node:path";
7
+ const GLOBAL_PROJECT_ID = "global";
8
+ const HASH_LENGTH = 12;
9
+ function hashString(input) {
10
+ return createHash("sha256").update(input).digest("hex").substring(0, HASH_LENGTH);
11
+ }
12
+ /**
13
+ * Detect the current project by inspecting git remote URL.
14
+ *
15
+ * Resolution order:
16
+ * 1. git remote get-url origin -> hash of remote URL
17
+ * 2. git rev-parse --show-toplevel -> hash of repo root path
18
+ * 3. fallback to project ID "global"
19
+ */
20
+ export async function detectProject(pi, cwd) {
21
+ const now = new Date().toISOString();
22
+ const name = basename(cwd);
23
+ // 1. Try remote URL
24
+ const remoteResult = await pi.exec("git", ["remote", "get-url", "origin"], { cwd });
25
+ if (remoteResult.code === 0) {
26
+ const remote = remoteResult.stdout.trim();
27
+ return {
28
+ id: hashString(remote),
29
+ name,
30
+ root: cwd,
31
+ remote,
32
+ created_at: now,
33
+ last_seen: now,
34
+ };
35
+ }
36
+ // 2. Fallback: repo root path (no remote)
37
+ const rootResult = await pi.exec("git", ["rev-parse", "--show-toplevel"], { cwd });
38
+ if (rootResult.code === 0) {
39
+ const root = rootResult.stdout.trim();
40
+ return {
41
+ id: hashString(root),
42
+ name,
43
+ root,
44
+ remote: "",
45
+ created_at: now,
46
+ last_seen: now,
47
+ };
48
+ }
49
+ // 3. Fallback: not in a git repo
50
+ return {
51
+ id: GLOBAL_PROJECT_ID,
52
+ name,
53
+ root: cwd,
54
+ remote: "",
55
+ created_at: now,
56
+ last_seen: now,
57
+ };
58
+ }
59
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIrC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AACnC,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAgB,EAChB,GAAW;IAEX,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE3B,oBAAoB;IACpB,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACpF,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,OAAO;YACL,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC;YACtB,IAAI;YACJ,IAAI,EAAE,GAAG;YACT,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;SACf,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACnF,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC;YACpB,IAAI;YACJ,IAAI;YACJ,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;SACf,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,OAAO;QACL,EAAE,EAAE,iBAAiB;QACrB,IAAI;QACJ,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,EAAE;QACV,UAAU,EAAE,GAAG;QACf,SAAS,EAAE,GAAG;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * User prompt and agent end observation handlers for pi-continuous-learning.
3
+ * Captures before_agent_start (user_prompt) and agent_end events as JSONL observations.
4
+ */
5
+ import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
6
+ export interface BeforeAgentStartEvent {
7
+ type: "before_agent_start";
8
+ prompt: string;
9
+ systemPrompt: string;
10
+ }
11
+ export interface AgentEndEvent {
12
+ type: "agent_end";
13
+ }
14
+ import type { ProjectEntry } from "./types.js";
15
+ /**
16
+ * Handles before_agent_start events.
17
+ * Records an observation with event: user_prompt and scrubbed prompt text.
18
+ */
19
+ export declare function handleBeforeAgentStart(event: BeforeAgentStartEvent, ctx: ExtensionContext, project: ProjectEntry, baseDir?: string): void;
20
+ /**
21
+ * Handles agent_end events.
22
+ * Records an observation with event: agent_end.
23
+ */
24
+ export declare function handleAgentEnd(_event: AgentEndEvent, ctx: ExtensionContext, project: ProjectEntry, baseDir?: string): void;
25
+ //# sourceMappingURL=prompt-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-observer.d.ts","sourceRoot":"","sources":["../src/prompt-observer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAOD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,YAAY,CAAC;AAW5D;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAoBN;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAiBN"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * User prompt and agent end observation handlers for pi-continuous-learning.
3
+ * Captures before_agent_start (user_prompt) and agent_end events as JSONL observations.
4
+ */
5
+ import { getCurrentActiveInstincts } from "./active-instincts.js";
6
+ import { appendObservation } from "./observations.js";
7
+ import { shouldSkipObservation } from "./observer-guard.js";
8
+ import { scrubSecrets } from "./scrubber.js";
9
+ import { logError } from "./error-logger.js";
10
+ function getSessionId(ctx) {
11
+ return ctx.sessionManager.getSessionId();
12
+ }
13
+ function buildActiveInstincts() {
14
+ const ids = getCurrentActiveInstincts();
15
+ return ids.length > 0 ? { active_instincts: ids } : {};
16
+ }
17
+ /**
18
+ * Handles before_agent_start events.
19
+ * Records an observation with event: user_prompt and scrubbed prompt text.
20
+ */
21
+ export function handleBeforeAgentStart(event, ctx, project, baseDir) {
22
+ try {
23
+ if (shouldSkipObservation())
24
+ return;
25
+ const input = scrubSecrets(event.prompt);
26
+ const observation = {
27
+ timestamp: new Date().toISOString(),
28
+ event: "user_prompt",
29
+ session: getSessionId(ctx),
30
+ project_id: project.id,
31
+ project_name: project.name,
32
+ input,
33
+ ...buildActiveInstincts(),
34
+ };
35
+ appendObservation(observation, project.id, baseDir);
36
+ }
37
+ catch (err) {
38
+ logError(project.id, "prompt-observer:handleBeforeAgentStart", err, baseDir);
39
+ }
40
+ }
41
+ /**
42
+ * Handles agent_end events.
43
+ * Records an observation with event: agent_end.
44
+ */
45
+ export function handleAgentEnd(_event, ctx, project, baseDir) {
46
+ try {
47
+ if (shouldSkipObservation())
48
+ return;
49
+ const observation = {
50
+ timestamp: new Date().toISOString(),
51
+ event: "agent_end",
52
+ session: getSessionId(ctx),
53
+ project_id: project.id,
54
+ project_name: project.name,
55
+ ...buildActiveInstincts(),
56
+ };
57
+ appendObservation(observation, project.id, baseDir);
58
+ }
59
+ catch (err) {
60
+ logError(project.id, "prompt-observer:handleAgentEnd", err, baseDir);
61
+ }
62
+ }
63
+ //# sourceMappingURL=prompt-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-observer.js","sourceRoot":"","sources":["../src/prompt-observer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,SAAS,YAAY,CAAC,GAAqB;IACzC,OAAO,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,GAAG,GAAG,yBAAyB,EAAE,CAAC;IACxC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAA4B,EAC5B,GAAqB,EACrB,OAAqB,EACrB,OAAgB;IAEhB,IAAI,CAAC;QACH,IAAI,qBAAqB,EAAE;YAAE,OAAO;QAEpC,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEzC,MAAM,WAAW,GAAgB;YAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC;YAC1B,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,YAAY,EAAE,OAAO,CAAC,IAAI;YAC1B,KAAK;YACL,GAAG,oBAAoB,EAAE;SAC1B,CAAC;QAEF,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,wCAAwC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAqB,EACrB,GAAqB,EACrB,OAAqB,EACrB,OAAgB;IAEhB,IAAI,CAAC;QACH,IAAI,qBAAqB,EAAE;YAAE,OAAO;QAEpC,MAAM,WAAW,GAAgB;YAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC;YAC1B,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,YAAY,EAAE,OAAO,CAAC,IAAI;YAC1B,GAAG,oBAAoB,EAAE;SAC1B,CAAC;QAEF,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,gCAAgC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Analyzer user prompt construction.
3
+ * Returns the user prompt string used by the Haiku background analyzer
4
+ * to locate observations and instinct files for the current project.
5
+ */
6
+ import type { InstalledSkill, ProjectEntry } from "../types.js";
7
+ /**
8
+ * Reads the last `maxEntries` lines from a JSONL observations file.
9
+ * Returns an empty array if the file does not exist.
10
+ *
11
+ * @param observationsPath - Absolute path to observations.jsonl
12
+ * @param maxEntries - Maximum number of lines to return (default 500)
13
+ */
14
+ export declare function tailObservations(observationsPath: string, maxEntries?: number): string[];
15
+ export interface TailSinceResult {
16
+ lines: string[];
17
+ totalLineCount: number;
18
+ }
19
+ export declare function tailObservationsSince(observationsPath: string, sinceLineCount: number, maxEntries?: number): TailSinceResult;
20
+ export interface AnalyzerUserPromptOptions {
21
+ agentsMdProject?: string | null;
22
+ agentsMdGlobal?: string | null;
23
+ installedSkills?: InstalledSkill[];
24
+ observationLines?: string[];
25
+ }
26
+ /**
27
+ * Builds the user prompt for the background Haiku analyzer.
28
+ * Includes observation and instinct file paths plus project context.
29
+ * Optionally includes AGENTS.md content and installed skills for deduplication.
30
+ * Template construction only - no subprocess I/O.
31
+ *
32
+ * @param observationsPath - Absolute path to the project's observations.jsonl
33
+ * @param instinctsDir - Absolute path to the project's instincts directory
34
+ * @param project - ProjectEntry with id and name
35
+ * @param options - Optional AGENTS.md content and installed skills
36
+ */
37
+ export declare function buildAnalyzerUserPrompt(observationsPath: string, instinctsDir: string, project: ProjectEntry, options?: AnalyzerUserPromptOptions): string;
38
+ //# sourceMappingURL=analyzer-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer-user.d.ts","sourceRoot":"","sources":["../../src/prompts/analyzer-user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,UAAU,SAAmB,GAC5B,MAAM,EAAE,CAUV;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,UAAU,SAAmB,GAC5B,eAAe,CAoBjB;AAED,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAmER"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Analyzer user prompt construction.
3
+ * Returns the user prompt string used by the Haiku background analyzer
4
+ * to locate observations and instinct files for the current project.
5
+ */
6
+ import { existsSync, readFileSync } from "node:fs";
7
+ /** Maximum number of observation lines to include in analysis. */
8
+ const MAX_TAIL_ENTRIES = 500;
9
+ /**
10
+ * Reads the last `maxEntries` lines from a JSONL observations file.
11
+ * Returns an empty array if the file does not exist.
12
+ *
13
+ * @param observationsPath - Absolute path to observations.jsonl
14
+ * @param maxEntries - Maximum number of lines to return (default 500)
15
+ */
16
+ export function tailObservations(observationsPath, maxEntries = MAX_TAIL_ENTRIES) {
17
+ if (!existsSync(observationsPath)) {
18
+ return [];
19
+ }
20
+ const content = readFileSync(observationsPath, "utf-8");
21
+ const lines = content
22
+ .split("\n")
23
+ .map((l) => l.trim())
24
+ .filter((l) => l.length > 0);
25
+ return lines.slice(-maxEntries);
26
+ }
27
+ export function tailObservationsSince(observationsPath, sinceLineCount, maxEntries = MAX_TAIL_ENTRIES) {
28
+ if (!existsSync(observationsPath)) {
29
+ return { lines: [], totalLineCount: 0 };
30
+ }
31
+ const content = readFileSync(observationsPath, "utf-8");
32
+ const allLines = content
33
+ .split("\n")
34
+ .map((l) => l.trim())
35
+ .filter((l) => l.length > 0);
36
+ const totalLineCount = allLines.length;
37
+ // If file was archived/reset (fewer lines than cursor), treat as fresh
38
+ const effectiveSince = totalLineCount < sinceLineCount ? 0 : sinceLineCount;
39
+ const newLines = allLines.slice(effectiveSince);
40
+ return {
41
+ lines: newLines.slice(-maxEntries),
42
+ totalLineCount,
43
+ };
44
+ }
45
+ /**
46
+ * Builds the user prompt for the background Haiku analyzer.
47
+ * Includes observation and instinct file paths plus project context.
48
+ * Optionally includes AGENTS.md content and installed skills for deduplication.
49
+ * Template construction only - no subprocess I/O.
50
+ *
51
+ * @param observationsPath - Absolute path to the project's observations.jsonl
52
+ * @param instinctsDir - Absolute path to the project's instincts directory
53
+ * @param project - ProjectEntry with id and name
54
+ * @param options - Optional AGENTS.md content and installed skills
55
+ */
56
+ export function buildAnalyzerUserPrompt(observationsPath, instinctsDir, project, options = {}) {
57
+ const { agentsMdProject = null, agentsMdGlobal = null, installedSkills = [], observationLines } = options;
58
+ const tailedLines = observationLines ?? tailObservations(observationsPath);
59
+ const observationBlock = tailedLines.length > 0
60
+ ? tailedLines.join("\n")
61
+ : "(no observations recorded yet)";
62
+ const entriesLabel = observationLines
63
+ ? `new observations since last analysis (up to ${MAX_TAIL_ENTRIES})`
64
+ : `most recent entries (up to ${MAX_TAIL_ENTRIES})`;
65
+ const parts = [
66
+ "## Analysis Task",
67
+ "",
68
+ "Analyze the following session observations and update the instinct files accordingly.",
69
+ "",
70
+ "## Project Context",
71
+ "",
72
+ `project_id: ${project.id}`,
73
+ `project_name: ${project.name}`,
74
+ "",
75
+ "## File Paths",
76
+ "",
77
+ `Observations file: ${observationsPath}`,
78
+ `Instincts directory: ${instinctsDir}`,
79
+ "",
80
+ `The following observations are ${entriesLabel}:`,
81
+ "",
82
+ "```",
83
+ observationBlock,
84
+ "```",
85
+ ];
86
+ if (agentsMdProject != null || agentsMdGlobal != null) {
87
+ parts.push("", "## Existing Guidelines", "");
88
+ if (agentsMdProject != null) {
89
+ parts.push("### Project AGENTS.md", "", agentsMdProject, "");
90
+ }
91
+ if (agentsMdGlobal != null) {
92
+ parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
93
+ }
94
+ }
95
+ if (installedSkills.length > 0) {
96
+ parts.push("", "## Installed Skills", "");
97
+ for (const skill of installedSkills) {
98
+ parts.push(`- **${skill.name}**: ${skill.description}`);
99
+ }
100
+ parts.push("");
101
+ }
102
+ parts.push("", "## Instructions", "", "1. Read existing instinct files from the instincts directory.", "2. Analyze the observations above for patterns following the system prompt rules.", "3. Create new instinct files or update existing ones in the instincts directory.", "4. Apply feedback analysis using the active_instincts field in each observation.", "5. Do not delete any instinct files - only create or update.", "", "Note: Passive confidence decay has already been applied to existing instincts before this analysis.");
103
+ return parts.join("\n");
104
+ }
105
+ //# sourceMappingURL=analyzer-user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer-user.js","sourceRoot":"","sources":["../../src/prompts/analyzer-user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGnD,kEAAkE;AAClE,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,gBAAwB,EACxB,UAAU,GAAG,gBAAgB;IAE7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO;SAClB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAOD,MAAM,UAAU,qBAAqB,CACnC,gBAAwB,EACxB,cAAsB,EACtB,UAAU,GAAG,gBAAgB;IAE7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;IAC1C,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,OAAO;SACrB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE/B,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEvC,uEAAuE;IACvE,MAAM,cAAc,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC5E,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAEhD,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC;QAClC,cAAc;KACf,CAAC;AACJ,CAAC;AASD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,gBAAwB,EACxB,YAAoB,EACpB,OAAqB,EACrB,UAAqC,EAAE;IAEvC,MAAM,EAAE,eAAe,GAAG,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,eAAe,GAAG,EAAE,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAE1G,MAAM,WAAW,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAC3E,MAAM,gBAAgB,GACpB,WAAW,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,CAAC,CAAC,gCAAgC,CAAC;IAEvC,MAAM,YAAY,GAAG,gBAAgB;QACnC,CAAC,CAAC,+CAA+C,gBAAgB,GAAG;QACpE,CAAC,CAAC,8BAA8B,gBAAgB,GAAG,CAAC;IAEtD,MAAM,KAAK,GAAa;QACtB,kBAAkB;QAClB,EAAE;QACF,uFAAuF;QACvF,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,eAAe,OAAO,CAAC,EAAE,EAAE;QAC3B,iBAAiB,OAAO,CAAC,IAAI,EAAE;QAC/B,EAAE;QACF,eAAe;QACf,EAAE;QACF,sBAAsB,gBAAgB,EAAE;QACxC,wBAAwB,YAAY,EAAE;QACtC,EAAE;QACF,kCAAkC,YAAY,GAAG;QACjD,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,+DAA+D,EAC/D,mFAAmF,EACnF,kFAAkF,EAClF,kFAAkF,EAClF,8DAA8D,EAC9D,EAAE,EACF,qGAAqG,CACtG,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Instinct, InstalledSkill } from "../types.js";
2
+ export declare function buildEvolvePrompt(instincts: Instinct[], agentsMdProject?: string | null, agentsMdGlobal?: string | null, installedSkills?: InstalledSkill[]): string;
3
+ //# sourceMappingURL=evolve-prompt.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,51 @@
1
+ function summarizeInstinct(i) {
2
+ return {
3
+ id: i.id,
4
+ title: i.title,
5
+ trigger: i.trigger,
6
+ action: i.action,
7
+ confidence: i.confidence,
8
+ domain: i.domain,
9
+ scope: i.scope,
10
+ };
11
+ }
12
+ export function buildEvolvePrompt(instincts, agentsMdProject, agentsMdGlobal, installedSkills) {
13
+ const parts = [
14
+ "Analyze the following learned instincts and identify opportunities for improvement.",
15
+ "You have access to instinct tools (instinct_merge, instinct_delete, instinct_write) to act on your findings.",
16
+ "",
17
+ "## Instincts",
18
+ "",
19
+ "```json",
20
+ JSON.stringify(instincts.map(summarizeInstinct), null, 2),
21
+ "```",
22
+ "",
23
+ "## Analysis Tasks",
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.",
30
+ "",
31
+ "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
+ "If there are no issues, say so briefly.",
33
+ ];
34
+ if (agentsMdProject || agentsMdGlobal) {
35
+ parts.push("", "## Current Guidelines (AGENTS.md)", "");
36
+ if (agentsMdProject) {
37
+ parts.push("### Project AGENTS.md", "", agentsMdProject, "");
38
+ }
39
+ if (agentsMdGlobal) {
40
+ parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
41
+ }
42
+ }
43
+ if (installedSkills && installedSkills.length > 0) {
44
+ parts.push("", "## Installed Skills", "");
45
+ for (const skill of installedSkills) {
46
+ parts.push(`- **${skill.name}**: ${skill.description}`);
47
+ }
48
+ }
49
+ return parts.join("\n");
50
+ }
51
+ //# sourceMappingURL=evolve-prompt.js.map
@@ -0,0 +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"}
@@ -0,0 +1,9 @@
1
+ /** Secret scrubbing - replaces sensitive values with [REDACTED] before writing to disk */
2
+ export declare const REDACTED = "[REDACTED]";
3
+ /**
4
+ * Scrub secrets from arbitrary text.
5
+ * Replaces all matched secret patterns with [REDACTED].
6
+ * Non-secret text is returned unchanged.
7
+ */
8
+ export declare function scrubSecrets(text: string): string;
9
+ //# sourceMappingURL=scrubber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrubber.d.ts","sourceRoot":"","sources":["../src/scrubber.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,eAAO,MAAM,QAAQ,eAAe,CAAC;AA2BrC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjD"}
@@ -0,0 +1,40 @@
1
+ /** Secret scrubbing - replaces sensitive values with [REDACTED] before writing to disk */
2
+ export const REDACTED = "[REDACTED]";
3
+ /**
4
+ * Ordered list of regex patterns that match common secret formats.
5
+ * Full matches are replaced with REDACTED.
6
+ */
7
+ const SECRET_PATTERNS = [
8
+ // Authorization header value (bearer, basic, token schemes)
9
+ /authorization\s*:\s*(?:bearer|basic|token)\s+\S+/gi,
10
+ // Standalone bearer token (match full token value, any non-whitespace chars)
11
+ /bearer\s+\S+/gi,
12
+ // HTTP header shorthand: x-api-key: <value>, x-auth-token: <value>
13
+ /x-(?:api-key|auth-token)\s*:\s*\S+/gi,
14
+ // API key assignments: api_key=, apiKey:, api-key =, access_key=, secret_key=
15
+ /(?:api[_-]?key|apikey|access[_-]?key|secret[_-]?key)\s*[:=]\s*\S+/gi,
16
+ // Token assignments: token=, auth_token:, access_token=, refresh_token=
17
+ /(?:auth[_-]?token|access[_-]?token|refresh[_-]?token)\s*[:=]\s*\S+/gi,
18
+ // Password assignments: password=, passwd:, pwd =
19
+ /(?:password|passwd|pwd)\s*[:=]\s*\S+/gi,
20
+ // Secret / credential / private_key assignments
21
+ /(?:secret|credential|private[_-]?key)\s*[:=]\s*\S+/gi,
22
+ // AWS Access Key IDs (AKIA...)
23
+ /AKIA[0-9A-Z]{16}/g,
24
+ // OpenAI / Anthropic SDK keys: sk-..., sk-ant-...
25
+ /sk-(?:ant-api03-)?[a-zA-Z0-9]{32,}/g,
26
+ ];
27
+ /**
28
+ * Scrub secrets from arbitrary text.
29
+ * Replaces all matched secret patterns with [REDACTED].
30
+ * Non-secret text is returned unchanged.
31
+ */
32
+ export function scrubSecrets(text) {
33
+ let result = text;
34
+ for (const pattern of SECRET_PATTERNS) {
35
+ pattern.lastIndex = 0;
36
+ result = result.replace(pattern, REDACTED);
37
+ }
38
+ return result;
39
+ }
40
+ //# sourceMappingURL=scrubber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrubber.js","sourceRoot":"","sources":["../src/scrubber.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC;AAErC;;;GAGG;AACH,MAAM,eAAe,GAAsB;IACzC,4DAA4D;IAC5D,oDAAoD;IACpD,6EAA6E;IAC7E,gBAAgB;IAChB,mEAAmE;IACnE,sCAAsC;IACtC,8EAA8E;IAC9E,qEAAqE;IACrE,wEAAwE;IACxE,sEAAsE;IACtE,kDAAkD;IAClD,wCAAwC;IACxC,gDAAgD;IAChD,sDAAsD;IACtD,+BAA+B;IAC/B,mBAAmB;IACnB,kDAAkD;IAClD,qCAAqC;CACtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Storage layout creation for pi-continuous-learning.
3
+ * Creates the directory structure under ~/.pi/continuous-learning/
4
+ * on first use, and maintains the projects.json registry.
5
+ */
6
+ import type { ProjectEntry } from "./types.js";
7
+ export declare function getBaseDir(): string;
8
+ export declare function getProjectDir(projectId: string, baseDir?: string): string;
9
+ export declare function getObservationsPath(projectId: string, baseDir?: string): string;
10
+ export declare function getArchiveDir(projectId: string, baseDir?: string): string;
11
+ export declare function getProjectInstinctsDir(projectId: string, source: "personal" | "inherited", baseDir?: string): string;
12
+ export declare function getGlobalInstinctsDir(source: "personal" | "inherited", baseDir?: string): string;
13
+ export declare function getProjectsRegistryPath(baseDir?: string): string;
14
+ /**
15
+ * Ensures the full storage directory layout exists.
16
+ * Idempotent - safe to call multiple times.
17
+ *
18
+ * @param project - Project entry with metadata
19
+ * @param baseDir - Base directory (defaults to ~/.pi/continuous-learning/)
20
+ */
21
+ export declare function ensureStorageLayout(project: ProjectEntry, baseDir?: string): void;
22
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,SAAe,GAAG,MAAM,CAE/E;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,SAAe,GAAG,MAAM,CAErF;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,SAAe,GAAG,MAAM,CAE/E;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,GAAG,WAAW,EAChC,OAAO,SAAe,GACrB,MAAM,CAER;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,GAAG,WAAW,EAChC,OAAO,SAAe,GACrB,MAAM,CAER;AAED,wBAAgB,uBAAuB,CAAC,OAAO,SAAe,GAAG,MAAM,CAEtE;AAiBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,SAAe,GAAG,IAAI,CAsBvF"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Storage layout creation for pi-continuous-learning.
3
+ * Creates the directory structure under ~/.pi/continuous-learning/
4
+ * on first use, and maintains the projects.json registry.
5
+ */
6
+ import { homedir } from "node:os";
7
+ import { join } from "node:path";
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
+ export function getBaseDir() {
10
+ return join(homedir(), ".pi", "continuous-learning");
11
+ }
12
+ export function getProjectDir(projectId, baseDir = getBaseDir()) {
13
+ return join(baseDir, "projects", projectId);
14
+ }
15
+ export function getObservationsPath(projectId, baseDir = getBaseDir()) {
16
+ return join(getProjectDir(projectId, baseDir), "observations.jsonl");
17
+ }
18
+ export function getArchiveDir(projectId, baseDir = getBaseDir()) {
19
+ return join(getProjectDir(projectId, baseDir), "observations.archive");
20
+ }
21
+ export function getProjectInstinctsDir(projectId, source, baseDir = getBaseDir()) {
22
+ return join(getProjectDir(projectId, baseDir), "instincts", source);
23
+ }
24
+ export function getGlobalInstinctsDir(source, baseDir = getBaseDir()) {
25
+ return join(baseDir, "instincts", source);
26
+ }
27
+ export function getProjectsRegistryPath(baseDir = getBaseDir()) {
28
+ return join(baseDir, "projects.json");
29
+ }
30
+ function ensureDir(dir) {
31
+ mkdirSync(dir, { recursive: true });
32
+ }
33
+ function readProjectsRegistry(registryPath) {
34
+ if (!existsSync(registryPath)) {
35
+ return {};
36
+ }
37
+ try {
38
+ return JSON.parse(readFileSync(registryPath, "utf-8"));
39
+ }
40
+ catch {
41
+ return {};
42
+ }
43
+ }
44
+ /**
45
+ * Ensures the full storage directory layout exists.
46
+ * Idempotent - safe to call multiple times.
47
+ *
48
+ * @param project - Project entry with metadata
49
+ * @param baseDir - Base directory (defaults to ~/.pi/continuous-learning/)
50
+ */
51
+ export function ensureStorageLayout(project, baseDir = getBaseDir()) {
52
+ // Global instinct directories
53
+ ensureDir(join(baseDir, "instincts", "personal"));
54
+ ensureDir(join(baseDir, "instincts", "inherited"));
55
+ // Project-scoped directories
56
+ const projectDir = getProjectDir(project.id, baseDir);
57
+ ensureDir(join(projectDir, "instincts", "personal"));
58
+ ensureDir(join(projectDir, "instincts", "inherited"));
59
+ ensureDir(join(projectDir, "observations.archive"));
60
+ // Write project.json only if it does not yet exist
61
+ const projectJsonPath = join(projectDir, "project.json");
62
+ if (!existsSync(projectJsonPath)) {
63
+ writeFileSync(projectJsonPath, JSON.stringify(project, null, 2), "utf-8");
64
+ }
65
+ // Update projects.json registry (always updates the entry)
66
+ const registryPath = getProjectsRegistryPath(baseDir);
67
+ const registry = readProjectsRegistry(registryPath);
68
+ const updated = { ...registry, [project.id]: project };
69
+ writeFileSync(registryPath, JSON.stringify(updated, null, 2), "utf-8");
70
+ }
71
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Tool call observation handlers for pi-continuous-learning.
3
+ * Captures tool_execution_start and tool_execution_end events as JSONL observations.
4
+ */
5
+ import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
6
+ export interface ToolExecutionStartEvent {
7
+ type: "tool_execution_start";
8
+ toolCallId: string;
9
+ toolName: string;
10
+ args: unknown;
11
+ }
12
+ export interface ToolExecutionEndEvent {
13
+ type: "tool_execution_end";
14
+ toolCallId: string;
15
+ toolName: string;
16
+ result: unknown;
17
+ isError: boolean;
18
+ }
19
+ import type { ProjectEntry } from "./types.js";
20
+ export declare const MAX_TOOL_INPUT_LENGTH = 5000;
21
+ export declare const MAX_TOOL_OUTPUT_LENGTH = 5000;
22
+ /**
23
+ * Handles tool_execution_start events.
24
+ * Records an observation with event: tool_start, tool name, and scrubbed/truncated input.
25
+ */
26
+ export declare function handleToolStart(event: ToolExecutionStartEvent, ctx: ExtensionContext, project: ProjectEntry, baseDir?: string): void;
27
+ /**
28
+ * Handles tool_execution_end events.
29
+ * Records an observation with event: tool_complete, tool name, scrubbed/truncated output, and is_error.
30
+ */
31
+ export declare function handleToolEnd(event: ToolExecutionEndEvent, ctx: ExtensionContext, project: ProjectEntry, baseDir?: string): void;
32
+ //# sourceMappingURL=tool-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-observer.d.ts","sourceRoot":"","sources":["../src/tool-observer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAOD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAgB3C;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,uBAAuB,EAC9B,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAsBN;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAwBN"}