create-agentfs 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -0
  3. package/dist/cli.d.ts +51 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +246 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/compile.d.ts +48 -0
  8. package/dist/commands/compile.d.ts.map +1 -0
  9. package/dist/commands/compile.js +228 -0
  10. package/dist/commands/compile.js.map +1 -0
  11. package/dist/commands/cron.d.ts +18 -0
  12. package/dist/commands/cron.d.ts.map +1 -0
  13. package/dist/commands/cron.js +95 -0
  14. package/dist/commands/cron.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +11 -0
  16. package/dist/commands/doctor.d.ts.map +1 -0
  17. package/dist/commands/doctor.js +199 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/memory.d.ts +19 -0
  20. package/dist/commands/memory.d.ts.map +1 -0
  21. package/dist/commands/memory.js +213 -0
  22. package/dist/commands/memory.js.map +1 -0
  23. package/dist/commands/onboard.d.ts +31 -0
  24. package/dist/commands/onboard.d.ts.map +1 -0
  25. package/dist/commands/onboard.js +362 -0
  26. package/dist/commands/onboard.js.map +1 -0
  27. package/dist/commands/secret.d.ts +13 -0
  28. package/dist/commands/secret.d.ts.map +1 -0
  29. package/dist/commands/secret.js +109 -0
  30. package/dist/commands/secret.js.map +1 -0
  31. package/dist/commands/security.d.ts +16 -0
  32. package/dist/commands/security.d.ts.map +1 -0
  33. package/dist/commands/security.js +203 -0
  34. package/dist/commands/security.js.map +1 -0
  35. package/dist/commands/sync.d.ts +14 -0
  36. package/dist/commands/sync.d.ts.map +1 -0
  37. package/dist/commands/sync.js +84 -0
  38. package/dist/commands/sync.js.map +1 -0
  39. package/dist/compilers/agent-map.d.ts +34 -0
  40. package/dist/compilers/agent-map.d.ts.map +1 -0
  41. package/dist/compilers/agent-map.js +66 -0
  42. package/dist/compilers/agent-map.js.map +1 -0
  43. package/dist/compilers/base.d.ts +67 -0
  44. package/dist/compilers/base.d.ts.map +1 -0
  45. package/dist/compilers/base.js +183 -0
  46. package/dist/compilers/base.js.map +1 -0
  47. package/dist/compilers/claude.d.ts +26 -0
  48. package/dist/compilers/claude.d.ts.map +1 -0
  49. package/dist/compilers/claude.js +151 -0
  50. package/dist/compilers/claude.js.map +1 -0
  51. package/dist/compilers/cursor.d.ts +11 -0
  52. package/dist/compilers/cursor.d.ts.map +1 -0
  53. package/dist/compilers/cursor.js +52 -0
  54. package/dist/compilers/cursor.js.map +1 -0
  55. package/dist/compilers/index.d.ts +14 -0
  56. package/dist/compilers/index.d.ts.map +1 -0
  57. package/dist/compilers/index.js +14 -0
  58. package/dist/compilers/index.js.map +1 -0
  59. package/dist/compilers/openclaw.d.ts +12 -0
  60. package/dist/compilers/openclaw.d.ts.map +1 -0
  61. package/dist/compilers/openclaw.js +51 -0
  62. package/dist/compilers/openclaw.js.map +1 -0
  63. package/dist/cron/index.d.ts +10 -0
  64. package/dist/cron/index.d.ts.map +1 -0
  65. package/dist/cron/index.js +9 -0
  66. package/dist/cron/index.js.map +1 -0
  67. package/dist/cron/jobs/consolidate.d.ts +16 -0
  68. package/dist/cron/jobs/consolidate.d.ts.map +1 -0
  69. package/dist/cron/jobs/consolidate.js +61 -0
  70. package/dist/cron/jobs/consolidate.js.map +1 -0
  71. package/dist/cron/jobs/heartbeat.d.ts +11 -0
  72. package/dist/cron/jobs/heartbeat.d.ts.map +1 -0
  73. package/dist/cron/jobs/heartbeat.js +66 -0
  74. package/dist/cron/jobs/heartbeat.js.map +1 -0
  75. package/dist/cron/jobs/inbox-triage.d.ts +11 -0
  76. package/dist/cron/jobs/inbox-triage.d.ts.map +1 -0
  77. package/dist/cron/jobs/inbox-triage.js +85 -0
  78. package/dist/cron/jobs/inbox-triage.js.map +1 -0
  79. package/dist/cron/runner.d.ts +32 -0
  80. package/dist/cron/runner.d.ts.map +1 -0
  81. package/dist/cron/runner.js +69 -0
  82. package/dist/cron/runner.js.map +1 -0
  83. package/dist/cron/types.d.ts +21 -0
  84. package/dist/cron/types.d.ts.map +1 -0
  85. package/dist/cron/types.js +6 -0
  86. package/dist/cron/types.js.map +1 -0
  87. package/dist/generators/filesystem.d.ts +52 -0
  88. package/dist/generators/filesystem.d.ts.map +1 -0
  89. package/dist/generators/filesystem.js +155 -0
  90. package/dist/generators/filesystem.js.map +1 -0
  91. package/dist/generators/ignore.d.ts +38 -0
  92. package/dist/generators/ignore.d.ts.map +1 -0
  93. package/dist/generators/ignore.js +154 -0
  94. package/dist/generators/ignore.js.map +1 -0
  95. package/dist/generators/index.d.ts +14 -0
  96. package/dist/generators/index.d.ts.map +1 -0
  97. package/dist/generators/index.js +14 -0
  98. package/dist/generators/index.js.map +1 -0
  99. package/dist/generators/init.d.ts +37 -0
  100. package/dist/generators/init.d.ts.map +1 -0
  101. package/dist/generators/init.js +169 -0
  102. package/dist/generators/init.js.map +1 -0
  103. package/dist/generators/manifest.d.ts +31 -0
  104. package/dist/generators/manifest.d.ts.map +1 -0
  105. package/dist/generators/manifest.js +123 -0
  106. package/dist/generators/manifest.js.map +1 -0
  107. package/dist/generators/memory.d.ts +36 -0
  108. package/dist/generators/memory.d.ts.map +1 -0
  109. package/dist/generators/memory.js +106 -0
  110. package/dist/generators/memory.js.map +1 -0
  111. package/dist/generators/profiles.d.ts +22 -0
  112. package/dist/generators/profiles.d.ts.map +1 -0
  113. package/dist/generators/profiles.js +92 -0
  114. package/dist/generators/profiles.js.map +1 -0
  115. package/dist/generators/prompts.d.ts +24 -0
  116. package/dist/generators/prompts.d.ts.map +1 -0
  117. package/dist/generators/prompts.js +122 -0
  118. package/dist/generators/prompts.js.map +1 -0
  119. package/dist/generators/scaffold.d.ts +29 -0
  120. package/dist/generators/scaffold.d.ts.map +1 -0
  121. package/dist/generators/scaffold.js +90 -0
  122. package/dist/generators/scaffold.js.map +1 -0
  123. package/dist/index.d.ts +14 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +13 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/memory/confidence.d.ts +69 -0
  128. package/dist/memory/confidence.d.ts.map +1 -0
  129. package/dist/memory/confidence.js +125 -0
  130. package/dist/memory/confidence.js.map +1 -0
  131. package/dist/memory/episodic.d.ts +40 -0
  132. package/dist/memory/episodic.d.ts.map +1 -0
  133. package/dist/memory/episodic.js +139 -0
  134. package/dist/memory/episodic.js.map +1 -0
  135. package/dist/memory/index.d.ts +17 -0
  136. package/dist/memory/index.d.ts.map +1 -0
  137. package/dist/memory/index.js +17 -0
  138. package/dist/memory/index.js.map +1 -0
  139. package/dist/memory/parser.d.ts +73 -0
  140. package/dist/memory/parser.d.ts.map +1 -0
  141. package/dist/memory/parser.js +156 -0
  142. package/dist/memory/parser.js.map +1 -0
  143. package/dist/memory/procedural.d.ts +43 -0
  144. package/dist/memory/procedural.d.ts.map +1 -0
  145. package/dist/memory/procedural.js +126 -0
  146. package/dist/memory/procedural.js.map +1 -0
  147. package/dist/secrets/exfil-guard.d.ts +31 -0
  148. package/dist/secrets/exfil-guard.d.ts.map +1 -0
  149. package/dist/secrets/exfil-guard.js +51 -0
  150. package/dist/secrets/exfil-guard.js.map +1 -0
  151. package/dist/secrets/index.d.ts +8 -0
  152. package/dist/secrets/index.d.ts.map +1 -0
  153. package/dist/secrets/index.js +7 -0
  154. package/dist/secrets/index.js.map +1 -0
  155. package/dist/secrets/vault.d.ts +63 -0
  156. package/dist/secrets/vault.d.ts.map +1 -0
  157. package/dist/secrets/vault.js +163 -0
  158. package/dist/secrets/vault.js.map +1 -0
  159. package/dist/security/claude-compiler.d.ts +28 -0
  160. package/dist/security/claude-compiler.d.ts.map +1 -0
  161. package/dist/security/claude-compiler.js +66 -0
  162. package/dist/security/claude-compiler.js.map +1 -0
  163. package/dist/security/index.d.ts +7 -0
  164. package/dist/security/index.d.ts.map +1 -0
  165. package/dist/security/index.js +7 -0
  166. package/dist/security/index.js.map +1 -0
  167. package/dist/security/parser.d.ts +47 -0
  168. package/dist/security/parser.d.ts.map +1 -0
  169. package/dist/security/parser.js +136 -0
  170. package/dist/security/parser.js.map +1 -0
  171. package/dist/sync/index.d.ts +7 -0
  172. package/dist/sync/index.d.ts.map +1 -0
  173. package/dist/sync/index.js +6 -0
  174. package/dist/sync/index.js.map +1 -0
  175. package/dist/sync/sync.d.ts +46 -0
  176. package/dist/sync/sync.d.ts.map +1 -0
  177. package/dist/sync/sync.js +174 -0
  178. package/dist/sync/sync.js.map +1 -0
  179. package/dist/types/compiler.d.ts +81 -0
  180. package/dist/types/compiler.d.ts.map +1 -0
  181. package/dist/types/compiler.js +10 -0
  182. package/dist/types/compiler.js.map +1 -0
  183. package/dist/types/index.d.ts +15 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +10 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/manifest.d.ts +112 -0
  188. package/dist/types/manifest.d.ts.map +1 -0
  189. package/dist/types/manifest.js +10 -0
  190. package/dist/types/manifest.js.map +1 -0
  191. package/dist/types/memory.d.ts +85 -0
  192. package/dist/types/memory.d.ts.map +1 -0
  193. package/dist/types/memory.js +20 -0
  194. package/dist/types/memory.js.map +1 -0
  195. package/dist/types/security.d.ts +67 -0
  196. package/dist/types/security.d.ts.map +1 -0
  197. package/dist/types/security.js +10 -0
  198. package/dist/types/security.js.map +1 -0
  199. package/dist/types/setup.d.ts +54 -0
  200. package/dist/types/setup.d.ts.map +1 -0
  201. package/dist/types/setup.js +9 -0
  202. package/dist/types/setup.js.map +1 -0
  203. package/dist/utils/fhs-mapping.d.ts +76 -0
  204. package/dist/utils/fhs-mapping.d.ts.map +1 -0
  205. package/dist/utils/fhs-mapping.js +189 -0
  206. package/dist/utils/fhs-mapping.js.map +1 -0
  207. package/package.json +58 -0
  208. package/templates/compilers/agent-map.md.hbs +36 -0
  209. package/templates/compilers/claude.md.hbs +95 -0
  210. package/templates/procedural/code-review.md +54 -0
  211. package/templates/procedural/debugging.md +52 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Confidence scoring engine for PATTERN entries in semantic memory.
3
+ *
4
+ * Implements the rules from docs/architecture.md Section 4:
5
+ *
6
+ * New PATTERN → confidence: 0.3 (DEFAULT_CONFIDENCE.initial)
7
+ * Confirmed → confidence += 0.2 (max 1.0)
8
+ * Denied → confidence -= 0.3
9
+ * Inactive 30 days → confidence -= 0.1 (decay)
10
+ * confidence < 0.1 → mark as superseded
11
+ *
12
+ * All functions are pure — they return a new `SemanticEntry` and never
13
+ * mutate the input. Non-PATTERN entries are returned unchanged.
14
+ *
15
+ * @module memory/confidence
16
+ */
17
+ import { DEFAULT_CONFIDENCE } from '../types/index.js';
18
+ // ---------------------------------------------------------------------------
19
+ // Internal helpers
20
+ // ---------------------------------------------------------------------------
21
+ /**
22
+ * Clamp a number to [min, max].
23
+ */
24
+ function clamp(value, min, max) {
25
+ return Math.min(max, Math.max(min, value));
26
+ }
27
+ /**
28
+ * Returns the effective confidence for an entry.
29
+ * For non-PATTERN entries this is always 1.0 (not used in scoring).
30
+ * For PATTERN entries it defaults to DEFAULT_CONFIDENCE.initial when absent.
31
+ */
32
+ function effectiveConfidence(entry) {
33
+ if (entry.type !== 'PATTERN')
34
+ return 1.0;
35
+ return entry.confidence ?? DEFAULT_CONFIDENCE.initial;
36
+ }
37
+ /**
38
+ * Returns a copy of `entry` with the given confidence applied, automatically
39
+ * marking the entry as superseded when the score drops below the threshold.
40
+ */
41
+ function withConfidence(entry, score) {
42
+ const clamped = clamp(score, 0, 1.0);
43
+ if (clamped < DEFAULT_CONFIDENCE.supersededThreshold) {
44
+ // Use today's date in YYYY-MM-DD format for the superseded marker.
45
+ const today = new Date().toISOString().slice(0, 10);
46
+ return {
47
+ ...entry,
48
+ confidence: clamped,
49
+ status: `superseded:${today}`,
50
+ };
51
+ }
52
+ return { ...entry, confidence: clamped, status: 'active' };
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Public API
56
+ // ---------------------------------------------------------------------------
57
+ /**
58
+ * Increases the confidence of a PATTERN entry by `confirmBoost` (default 0.2),
59
+ * capped at 1.0.
60
+ *
61
+ * Non-PATTERN entries are returned unchanged.
62
+ *
63
+ * @param entry - The entry to confirm.
64
+ * @returns A new entry with updated confidence.
65
+ */
66
+ export function confirmPattern(entry) {
67
+ if (entry.type !== 'PATTERN')
68
+ return entry;
69
+ return withConfidence(entry, effectiveConfidence(entry) + DEFAULT_CONFIDENCE.confirmBoost);
70
+ }
71
+ /**
72
+ * Decreases the confidence of a PATTERN entry by `denyPenalty` (default 0.3).
73
+ *
74
+ * If the result drops below `supersededThreshold` (0.1) the entry is
75
+ * automatically marked as superseded.
76
+ *
77
+ * Non-PATTERN entries are returned unchanged.
78
+ *
79
+ * @param entry - The entry to deny.
80
+ * @returns A new entry with updated confidence and status.
81
+ */
82
+ export function denyPattern(entry) {
83
+ if (entry.type !== 'PATTERN')
84
+ return entry;
85
+ return withConfidence(entry, effectiveConfidence(entry) - DEFAULT_CONFIDENCE.denyPenalty);
86
+ }
87
+ /**
88
+ * Applies time-based confidence decay to a PATTERN entry.
89
+ *
90
+ * Each full `decayDays`-period (default 30 days) of inactivity reduces
91
+ * confidence by `decayRate` (default 0.1). Fractional periods are truncated.
92
+ *
93
+ * Examples:
94
+ * - 29 days inactive → 0 decay periods → no change
95
+ * - 30 days inactive → 1 decay period → -0.1
96
+ * - 75 days inactive → 2 decay periods → -0.2
97
+ *
98
+ * Non-PATTERN entries are returned unchanged.
99
+ *
100
+ * @param entry - The entry to decay.
101
+ * @param daysSinceLastSeen - Number of days since the pattern was last confirmed.
102
+ * @returns A new entry with decayed confidence (and possibly superseded status).
103
+ */
104
+ export function decayPattern(entry, daysSinceLastSeen) {
105
+ if (entry.type !== 'PATTERN')
106
+ return entry;
107
+ const periods = Math.floor(daysSinceLastSeen / DEFAULT_CONFIDENCE.decayDays);
108
+ if (periods === 0)
109
+ return entry;
110
+ return withConfidence(entry, effectiveConfidence(entry) - periods * DEFAULT_CONFIDENCE.decayRate);
111
+ }
112
+ /**
113
+ * Returns `true` when an entry has been marked as superseded.
114
+ *
115
+ * An entry is superseded when its `status` string starts with "superseded:".
116
+ * This covers both confidence-driven supersession and manual date-based
117
+ * supersession (e.g. `FACT: [superseded:2026-04-01] …`).
118
+ *
119
+ * @param entry - Any semantic entry.
120
+ * @returns Whether the entry is superseded.
121
+ */
122
+ export function isSuperseded(entry) {
123
+ return entry.status.startsWith('superseded:');
124
+ }
125
+ //# sourceMappingURL=confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/memory/confidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;GAEG;AACH,SAAS,KAAK,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAoB;IAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACzC,OAAO,KAAK,CAAC,UAAU,IAAI,kBAAkB,CAAC,OAAO,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,KAAoB,EAAE,KAAa;IACzD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IAErC,IAAI,OAAO,GAAG,kBAAkB,CAAC,mBAAmB,EAAE,CAAC;QACrD,mEAAmE;QACnE,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO;YACL,GAAG,KAAK;YACR,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,cAAc,KAAK,EAAE;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC7D,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3C,OAAO,cAAc,CACnB,KAAK,EACL,mBAAmB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,YAAY,CAC7D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3C,OAAO,cAAc,CACnB,KAAK,EACL,mBAAmB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,WAAW,CAC5D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAoB,EACpB,iBAAyB;IAEzB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEhC,OAAO,cAAc,CACnB,KAAK,EACL,mBAAmB,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,kBAAkB,CAAC,SAAS,CACpE,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAAoB;IAC/C,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Episodic memory writer — creates/appends to daily event logs.
3
+ *
4
+ * Episodic memory stores timestamped session events in per-day markdown files:
5
+ * `.agentos/memory/episodic/YYYY-MM-DD.md`
6
+ *
7
+ * Each file contains sections for events, decisions, and lessons learned.
8
+ * Appending is idempotent — duplicate event lines are skipped.
9
+ *
10
+ * @module memory/episodic
11
+ */
12
+ import type { EpisodicEntry } from '../types/index.js';
13
+ /**
14
+ * Write or append an episodic entry for a given date.
15
+ *
16
+ * If the file for the date already exists, new events/decisions/lessons are
17
+ * appended only if they are not already present (substring dedup).
18
+ *
19
+ * If the file does not exist, it is created with the full entry.
20
+ *
21
+ * @param vaultRoot - Absolute path to the vault root directory
22
+ * @param entry - The episodic entry to persist
23
+ */
24
+ export declare function writeEpisodicEntry(vaultRoot: string, entry: EpisodicEntry): Promise<void>;
25
+ /**
26
+ * Read an episodic entry for a specific date, returning null if it doesn't exist.
27
+ *
28
+ * @param vaultRoot - Absolute path to the vault root directory
29
+ * @param date - Date string in YYYY-MM-DD format
30
+ * @returns The raw markdown content, or null
31
+ */
32
+ export declare function readEpisodicEntry(vaultRoot: string, date: string): Promise<string | null>;
33
+ /**
34
+ * List all episodic entry dates available in the vault.
35
+ *
36
+ * @param vaultRoot - Absolute path to the vault root directory
37
+ * @returns Sorted array of date strings (YYYY-MM-DD)
38
+ */
39
+ export declare function listEpisodicDates(vaultRoot: string): Promise<string[]>;
40
+ //# sourceMappingURL=episodic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"episodic.d.ts","sourceRoot":"","sources":["../../src/memory/episodic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAYvD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Episodic memory writer — creates/appends to daily event logs.
3
+ *
4
+ * Episodic memory stores timestamped session events in per-day markdown files:
5
+ * `.agentos/memory/episodic/YYYY-MM-DD.md`
6
+ *
7
+ * Each file contains sections for events, decisions, and lessons learned.
8
+ * Appending is idempotent — duplicate event lines are skipped.
9
+ *
10
+ * @module memory/episodic
11
+ */
12
+ import fs from 'node:fs/promises';
13
+ import path from 'node:path';
14
+ // ---------------------------------------------------------------------------
15
+ // Constants
16
+ // ---------------------------------------------------------------------------
17
+ const EPISODIC_DIR = '.agentos/memory/episodic';
18
+ // ---------------------------------------------------------------------------
19
+ // Public API
20
+ // ---------------------------------------------------------------------------
21
+ /**
22
+ * Write or append an episodic entry for a given date.
23
+ *
24
+ * If the file for the date already exists, new events/decisions/lessons are
25
+ * appended only if they are not already present (substring dedup).
26
+ *
27
+ * If the file does not exist, it is created with the full entry.
28
+ *
29
+ * @param vaultRoot - Absolute path to the vault root directory
30
+ * @param entry - The episodic entry to persist
31
+ */
32
+ export async function writeEpisodicEntry(vaultRoot, entry) {
33
+ const dir = path.join(vaultRoot, EPISODIC_DIR);
34
+ await fs.mkdir(dir, { recursive: true });
35
+ const filePath = path.join(dir, `${entry.date}.md`);
36
+ let existing = null;
37
+ try {
38
+ existing = await fs.readFile(filePath, 'utf8');
39
+ }
40
+ catch {
41
+ // File doesn't exist — will create fresh
42
+ }
43
+ if (existing === null) {
44
+ // Create new file
45
+ const content = renderEpisodicEntry(entry);
46
+ await fs.writeFile(filePath, content, 'utf8');
47
+ return;
48
+ }
49
+ // Append new items that don't already exist
50
+ const linesToAppend = [];
51
+ for (const event of entry.events) {
52
+ if (!existing.includes(event)) {
53
+ linesToAppend.push(`- ${event}`);
54
+ }
55
+ }
56
+ for (const decision of entry.decisions) {
57
+ if (!existing.includes(decision)) {
58
+ linesToAppend.push(`- **Decision:** ${decision}`);
59
+ }
60
+ }
61
+ for (const lesson of entry.lessons) {
62
+ if (!existing.includes(lesson)) {
63
+ linesToAppend.push(`- **Lesson:** ${lesson}`);
64
+ }
65
+ }
66
+ if (linesToAppend.length > 0) {
67
+ const separator = existing.endsWith('\n') ? '' : '\n';
68
+ await fs.appendFile(filePath, `${separator}${linesToAppend.join('\n')}\n`, 'utf8');
69
+ }
70
+ }
71
+ /**
72
+ * Read an episodic entry for a specific date, returning null if it doesn't exist.
73
+ *
74
+ * @param vaultRoot - Absolute path to the vault root directory
75
+ * @param date - Date string in YYYY-MM-DD format
76
+ * @returns The raw markdown content, or null
77
+ */
78
+ export async function readEpisodicEntry(vaultRoot, date) {
79
+ const filePath = path.join(vaultRoot, EPISODIC_DIR, `${date}.md`);
80
+ try {
81
+ return await fs.readFile(filePath, 'utf8');
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ /**
88
+ * List all episodic entry dates available in the vault.
89
+ *
90
+ * @param vaultRoot - Absolute path to the vault root directory
91
+ * @returns Sorted array of date strings (YYYY-MM-DD)
92
+ */
93
+ export async function listEpisodicDates(vaultRoot) {
94
+ const dir = path.join(vaultRoot, EPISODIC_DIR);
95
+ try {
96
+ const files = await fs.readdir(dir);
97
+ return files
98
+ .filter((f) => f.endsWith('.md'))
99
+ .map((f) => f.replace(/\.md$/, ''))
100
+ .sort();
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ }
106
+ // ---------------------------------------------------------------------------
107
+ // Internal helpers
108
+ // ---------------------------------------------------------------------------
109
+ /**
110
+ * Render a full episodic entry as markdown.
111
+ */
112
+ function renderEpisodicEntry(entry) {
113
+ const lines = [];
114
+ lines.push(`# ${entry.date}`);
115
+ lines.push('');
116
+ if (entry.events.length > 0) {
117
+ lines.push('## Events');
118
+ for (const event of entry.events) {
119
+ lines.push(`- ${event}`);
120
+ }
121
+ lines.push('');
122
+ }
123
+ if (entry.decisions.length > 0) {
124
+ lines.push('## Decisions');
125
+ for (const decision of entry.decisions) {
126
+ lines.push(`- ${decision}`);
127
+ }
128
+ lines.push('');
129
+ }
130
+ if (entry.lessons.length > 0) {
131
+ lines.push('## Lessons');
132
+ for (const lesson of entry.lessons) {
133
+ lines.push(`- ${lesson}`);
134
+ }
135
+ lines.push('');
136
+ }
137
+ return lines.join('\n');
138
+ }
139
+ //# sourceMappingURL=episodic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"episodic.js","sourceRoot":"","sources":["../../src/memory/episodic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,KAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;IAEpD,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,yCAAyC;IAC3C,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,kBAAkB;QAClB,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,aAAa,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,aAAa,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,aAAa,CAAC,IAAI,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtD,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,IAAY;IAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAClE,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;aAClC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAoB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Memory module — barrel export.
3
+ *
4
+ * Re-exports the semantic memory parser and confidence scoring engine so
5
+ * consumers can import from a single path:
6
+ *
7
+ * ```ts
8
+ * import { parseSemanticMemory, confirmPattern } from './memory/index.js';
9
+ * ```
10
+ *
11
+ * @module memory
12
+ */
13
+ export { parseSemanticMemory, serializeSemanticEntry, appendSemanticEntry, } from './parser.js';
14
+ export { confirmPattern, denyPattern, decayPattern, isSuperseded, } from './confidence.js';
15
+ export { writeEpisodicEntry, readEpisodicEntry, listEpisodicDates, } from './episodic.js';
16
+ export { writeProceduralEntry, readProceduralEntry, listProceduralSkills, slugify, } from './procedural.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,OAAO,GACR,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Memory module — barrel export.
3
+ *
4
+ * Re-exports the semantic memory parser and confidence scoring engine so
5
+ * consumers can import from a single path:
6
+ *
7
+ * ```ts
8
+ * import { parseSemanticMemory, confirmPattern } from './memory/index.js';
9
+ * ```
10
+ *
11
+ * @module memory
12
+ */
13
+ export { parseSemanticMemory, serializeSemanticEntry, appendSemanticEntry, } from './parser.js';
14
+ export { confirmPattern, denyPattern, decayPattern, isSuperseded, } from './confidence.js';
15
+ export { writeEpisodicEntry, readEpisodicEntry, listEpisodicDates, } from './episodic.js';
16
+ export { writeProceduralEntry, readProceduralEntry, listProceduralSkills, slugify, } from './procedural.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,OAAO,GACR,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Semantic memory parser — reads and writes `semantic.md` entry lines.
3
+ *
4
+ * Supported line formats (from docs/architecture.md Section 4):
5
+ *
6
+ * PREF: no emoji in headings
7
+ * FACT: [active] primary stack is Kubernetes + ArgoCD
8
+ * FACT: [superseded:2026-04-01] old stack was AWS
9
+ * PATTERN: [confidence:0.85] more productive in the morning
10
+ * AVOID: don't suggest LangChain
11
+ *
12
+ * Rules:
13
+ * - PREF and AVOID carry no bracketed modifier — status defaults to "active".
14
+ * - FACT carries [active] or [superseded:YYYY-MM-DD].
15
+ * - PATTERN carries [confidence:X.XX] — status always "active" unless confidence
16
+ * drops below the superseded threshold (handled by confidence.ts).
17
+ * - Lines that do not match the recognised format are silently ignored.
18
+ * - Duplicate detection in `appendSemanticEntry` is substring-based on `content`.
19
+ *
20
+ * @module memory/parser
21
+ */
22
+ import type { SemanticEntry } from '../types/index.js';
23
+ /**
24
+ * Parses a `semantic.md` file content string into structured `SemanticEntry`
25
+ * objects.
26
+ *
27
+ * Only lines that match the canonical format are returned; markdown headings,
28
+ * comments, blank lines, and unrecognised lines are discarded.
29
+ *
30
+ * @param content - Raw text content of the file.
31
+ * @returns Array of parsed entries in document order.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const entries = parseSemanticMemory(
36
+ * 'FACT: [active] primary stack is Kubernetes\nAVOID: don\'t use LangChain'
37
+ * );
38
+ * // entries[0] → { type: 'FACT', content: 'primary stack is Kubernetes', status: 'active' }
39
+ * // entries[1] → { type: 'AVOID', content: "don't use LangChain", status: 'active' }
40
+ * ```
41
+ */
42
+ export declare function parseSemanticMemory(content: string): SemanticEntry[];
43
+ /**
44
+ * Converts a `SemanticEntry` back to its single-line string representation.
45
+ *
46
+ * Output examples:
47
+ * ```
48
+ * PREF: no emoji in headings
49
+ * FACT: [active] primary stack is Kubernetes + ArgoCD
50
+ * FACT: [superseded:2026-04-01] old stack was AWS
51
+ * PATTERN: [confidence:0.85] more productive in the morning
52
+ * AVOID: don't suggest LangChain
53
+ * ```
54
+ *
55
+ * @param entry - The entry to serialise.
56
+ * @returns A single line without a trailing newline.
57
+ */
58
+ export declare function serializeSemanticEntry(entry: SemanticEntry): string;
59
+ /**
60
+ * Appends a `SemanticEntry` to a `semantic.md` file at `filePath`.
61
+ *
62
+ * Duplicate detection: if any existing entry's `content` is a substring of
63
+ * (or exactly equals) the new entry's `content`, the append is skipped
64
+ * silently. Comparison is case-sensitive and whitespace-sensitive.
65
+ *
66
+ * The file must already exist. If the file does not end with a newline the
67
+ * appended line is still placed on its own line.
68
+ *
69
+ * @param filePath - Absolute path to the target `semantic.md` file.
70
+ * @param entry - Entry to append.
71
+ */
72
+ export declare function appendSemanticEntry(filePath: string, entry: SemanticEntry): Promise<void>;
73
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/memory/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAkC,MAAM,mBAAmB,CAAC;AAqBvF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CA+CpE;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAiBnE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Semantic memory parser — reads and writes `semantic.md` entry lines.
3
+ *
4
+ * Supported line formats (from docs/architecture.md Section 4):
5
+ *
6
+ * PREF: no emoji in headings
7
+ * FACT: [active] primary stack is Kubernetes + ArgoCD
8
+ * FACT: [superseded:2026-04-01] old stack was AWS
9
+ * PATTERN: [confidence:0.85] more productive in the morning
10
+ * AVOID: don't suggest LangChain
11
+ *
12
+ * Rules:
13
+ * - PREF and AVOID carry no bracketed modifier — status defaults to "active".
14
+ * - FACT carries [active] or [superseded:YYYY-MM-DD].
15
+ * - PATTERN carries [confidence:X.XX] — status always "active" unless confidence
16
+ * drops below the superseded threshold (handled by confidence.ts).
17
+ * - Lines that do not match the recognised format are silently ignored.
18
+ * - Duplicate detection in `appendSemanticEntry` is substring-based on `content`.
19
+ *
20
+ * @module memory/parser
21
+ */
22
+ import fs from 'node:fs/promises';
23
+ // ---------------------------------------------------------------------------
24
+ // Internal regex
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Matches any recognised semantic entry line.
28
+ *
29
+ * Capture groups:
30
+ * 1 — entry type (PREF | FACT | PATTERN | AVOID | DIRECTIVE)
31
+ * 2 — optional bracketed modifier, without the brackets
32
+ * 3 — content text (trimmed)
33
+ */
34
+ const ENTRY_RE = /^(PREF|FACT|PATTERN|AVOID|DIRECTIVE):\s+(?:\[([^\]]+)\]\s+)?(.+)$/;
35
+ // ---------------------------------------------------------------------------
36
+ // parseSemanticMemory
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Parses a `semantic.md` file content string into structured `SemanticEntry`
40
+ * objects.
41
+ *
42
+ * Only lines that match the canonical format are returned; markdown headings,
43
+ * comments, blank lines, and unrecognised lines are discarded.
44
+ *
45
+ * @param content - Raw text content of the file.
46
+ * @returns Array of parsed entries in document order.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const entries = parseSemanticMemory(
51
+ * 'FACT: [active] primary stack is Kubernetes\nAVOID: don\'t use LangChain'
52
+ * );
53
+ * // entries[0] → { type: 'FACT', content: 'primary stack is Kubernetes', status: 'active' }
54
+ * // entries[1] → { type: 'AVOID', content: "don't use LangChain", status: 'active' }
55
+ * ```
56
+ */
57
+ export function parseSemanticMemory(content) {
58
+ const entries = [];
59
+ for (const rawLine of content.split('\n')) {
60
+ const line = rawLine.trim();
61
+ const match = ENTRY_RE.exec(line);
62
+ if (match === null)
63
+ continue;
64
+ const [, rawType, modifier, entryContent] = match;
65
+ const type = rawType;
66
+ const trimmedContent = entryContent.trim();
67
+ // Determine status and confidence from the optional modifier.
68
+ let status = 'active';
69
+ let confidence;
70
+ if (modifier !== undefined) {
71
+ if (modifier === 'active') {
72
+ status = 'active';
73
+ }
74
+ else if (modifier.startsWith('superseded:')) {
75
+ status = modifier;
76
+ }
77
+ else if (modifier.startsWith('confidence:')) {
78
+ const raw = modifier.slice('confidence:'.length);
79
+ const parsed = parseFloat(raw);
80
+ if (!isNaN(parsed)) {
81
+ confidence = parsed;
82
+ }
83
+ // PATTERN entries with confidence tag keep status "active"
84
+ status = 'active';
85
+ }
86
+ }
87
+ const entry = { type, content: trimmedContent, status };
88
+ if (confidence !== undefined) {
89
+ entry.confidence = confidence;
90
+ }
91
+ entries.push(entry);
92
+ }
93
+ return entries;
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // serializeSemanticEntry
97
+ // ---------------------------------------------------------------------------
98
+ /**
99
+ * Converts a `SemanticEntry` back to its single-line string representation.
100
+ *
101
+ * Output examples:
102
+ * ```
103
+ * PREF: no emoji in headings
104
+ * FACT: [active] primary stack is Kubernetes + ArgoCD
105
+ * FACT: [superseded:2026-04-01] old stack was AWS
106
+ * PATTERN: [confidence:0.85] more productive in the morning
107
+ * AVOID: don't suggest LangChain
108
+ * ```
109
+ *
110
+ * @param entry - The entry to serialise.
111
+ * @returns A single line without a trailing newline.
112
+ */
113
+ export function serializeSemanticEntry(entry) {
114
+ const { type, content, status, confidence } = entry;
115
+ // PATTERN entries encode confidence in the modifier slot.
116
+ if (type === 'PATTERN') {
117
+ const score = confidence !== undefined ? confidence : 0.3;
118
+ // Format to two decimal places, matching the canonical format.
119
+ return `PATTERN: [confidence:${score.toFixed(2)}] ${content}`;
120
+ }
121
+ // PREF, AVOID, and DIRECTIVE have no modifier when status is active.
122
+ if (type === 'PREF' || type === 'AVOID' || type === 'DIRECTIVE') {
123
+ return `${type}: ${content}`;
124
+ }
125
+ // FACT always carries an explicit status modifier.
126
+ return `FACT: [${status}] ${content}`;
127
+ }
128
+ // ---------------------------------------------------------------------------
129
+ // appendSemanticEntry
130
+ // ---------------------------------------------------------------------------
131
+ /**
132
+ * Appends a `SemanticEntry` to a `semantic.md` file at `filePath`.
133
+ *
134
+ * Duplicate detection: if any existing entry's `content` is a substring of
135
+ * (or exactly equals) the new entry's `content`, the append is skipped
136
+ * silently. Comparison is case-sensitive and whitespace-sensitive.
137
+ *
138
+ * The file must already exist. If the file does not end with a newline the
139
+ * appended line is still placed on its own line.
140
+ *
141
+ * @param filePath - Absolute path to the target `semantic.md` file.
142
+ * @param entry - Entry to append.
143
+ */
144
+ export async function appendSemanticEntry(filePath, entry) {
145
+ const raw = await fs.readFile(filePath, 'utf8');
146
+ const existing = parseSemanticMemory(raw);
147
+ // Duplicate check: skip if the incoming content already appears.
148
+ const isDuplicate = existing.some((e) => e.content === entry.content && e.type === entry.type);
149
+ if (isDuplicate)
150
+ return;
151
+ const line = serializeSemanticEntry(entry);
152
+ // Ensure the new line starts on a fresh line.
153
+ const separator = raw.endsWith('\n') || raw.length === 0 ? '' : '\n';
154
+ await fs.appendFile(filePath, `${separator}${line}\n`, 'utf8');
155
+ }
156
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/memory/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Procedural memory writer — creates/updates skill files.
3
+ *
4
+ * Procedural memory stores learned workflows as individual markdown files:
5
+ * `.agentos/memory/procedural/{skill-name}.md`
6
+ *
7
+ * Each file documents: description, steps, context, and optional examples.
8
+ * Creates new files or overwrites existing ones (skills are versioned as a
9
+ * whole, not appended line-by-line like episodic memory).
10
+ *
11
+ * @module memory/procedural
12
+ */
13
+ import type { ProceduralEntry } from '../types/index.js';
14
+ /**
15
+ * Write or overwrite a procedural skill file.
16
+ *
17
+ * The skill name is slugified for the filename (lowercase, hyphens).
18
+ * The full content is always rewritten — procedural skills are atomic.
19
+ *
20
+ * @param vaultRoot - Absolute path to the vault root directory
21
+ * @param entry - The procedural entry to persist
22
+ */
23
+ export declare function writeProceduralEntry(vaultRoot: string, entry: ProceduralEntry): Promise<void>;
24
+ /**
25
+ * Read a procedural entry by skill name, returning null if it doesn't exist.
26
+ *
27
+ * @param vaultRoot - Absolute path to the vault root directory
28
+ * @param name - Skill name (will be slugified)
29
+ * @returns The raw markdown content, or null
30
+ */
31
+ export declare function readProceduralEntry(vaultRoot: string, name: string): Promise<string | null>;
32
+ /**
33
+ * List all procedural skill names available in the vault.
34
+ *
35
+ * @param vaultRoot - Absolute path to the vault root directory
36
+ * @returns Sorted array of skill names (derived from filenames)
37
+ */
38
+ export declare function listProceduralSkills(vaultRoot: string): Promise<string[]>;
39
+ /**
40
+ * Slugify a skill name: lowercase, spaces → hyphens, strip non-alnum.
41
+ */
42
+ export declare function slugify(name: string): string;
43
+ //# sourceMappingURL=procedural.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedural.d.ts","sourceRoot":"","sources":["../../src/memory/procedural.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAMD;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C"}