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,126 @@
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 fs from 'node:fs/promises';
14
+ import path from 'node:path';
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ const PROCEDURAL_DIR = '.agentos/memory/procedural';
19
+ // ---------------------------------------------------------------------------
20
+ // Public API
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Write or overwrite a procedural skill file.
24
+ *
25
+ * The skill name is slugified for the filename (lowercase, hyphens).
26
+ * The full content is always rewritten — procedural skills are atomic.
27
+ *
28
+ * @param vaultRoot - Absolute path to the vault root directory
29
+ * @param entry - The procedural entry to persist
30
+ */
31
+ export async function writeProceduralEntry(vaultRoot, entry) {
32
+ const dir = path.join(vaultRoot, PROCEDURAL_DIR);
33
+ await fs.mkdir(dir, { recursive: true });
34
+ const slug = slugify(entry.name);
35
+ const filePath = path.join(dir, `${slug}.md`);
36
+ const content = renderProceduralEntry(entry);
37
+ await fs.writeFile(filePath, content, 'utf8');
38
+ }
39
+ /**
40
+ * Read a procedural entry by skill name, returning null if it doesn't exist.
41
+ *
42
+ * @param vaultRoot - Absolute path to the vault root directory
43
+ * @param name - Skill name (will be slugified)
44
+ * @returns The raw markdown content, or null
45
+ */
46
+ export async function readProceduralEntry(vaultRoot, name) {
47
+ const slug = slugify(name);
48
+ const filePath = path.join(vaultRoot, PROCEDURAL_DIR, `${slug}.md`);
49
+ try {
50
+ return await fs.readFile(filePath, 'utf8');
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ /**
57
+ * List all procedural skill names available in the vault.
58
+ *
59
+ * @param vaultRoot - Absolute path to the vault root directory
60
+ * @returns Sorted array of skill names (derived from filenames)
61
+ */
62
+ export async function listProceduralSkills(vaultRoot) {
63
+ const dir = path.join(vaultRoot, PROCEDURAL_DIR);
64
+ try {
65
+ const files = await fs.readdir(dir);
66
+ return files
67
+ .filter((f) => f.endsWith('.md'))
68
+ .map((f) => f.replace(/\.md$/, ''))
69
+ .sort();
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Internal helpers
77
+ // ---------------------------------------------------------------------------
78
+ /**
79
+ * Slugify a skill name: lowercase, spaces → hyphens, strip non-alnum.
80
+ */
81
+ export function slugify(name) {
82
+ return name
83
+ .toLowerCase()
84
+ .trim()
85
+ .replace(/\s+/g, '-')
86
+ .replace(/[^a-z0-9-]/g, '');
87
+ }
88
+ /**
89
+ * Render a full procedural entry as markdown.
90
+ */
91
+ function renderProceduralEntry(entry) {
92
+ const lines = [];
93
+ // YAML frontmatter with triggers and metadata (SKILL.md pattern)
94
+ lines.push('---');
95
+ lines.push(`name: ${entry.name}`);
96
+ lines.push(`description: ${entry.description}`);
97
+ if (entry.triggers && entry.triggers.length > 0) {
98
+ lines.push(`triggers: [${entry.triggers.join(', ')}]`);
99
+ }
100
+ if (entry.useCount !== undefined) {
101
+ lines.push(`use_count: ${entry.useCount}`);
102
+ }
103
+ if (entry.lastUsed) {
104
+ lines.push(`last_used: ${entry.lastUsed}`);
105
+ }
106
+ lines.push('---');
107
+ lines.push('');
108
+ lines.push(`# ${entry.name}`);
109
+ lines.push('');
110
+ lines.push(entry.description);
111
+ lines.push('');
112
+ if (entry.context) {
113
+ lines.push('## Context');
114
+ lines.push(entry.context);
115
+ lines.push('');
116
+ }
117
+ if (entry.steps.length > 0) {
118
+ lines.push('## Steps');
119
+ for (let i = 0; i < entry.steps.length; i++) {
120
+ lines.push(`${i + 1}. ${entry.steps[i]}`);
121
+ }
122
+ lines.push('');
123
+ }
124
+ return lines.join('\n');
125
+ }
126
+ //# sourceMappingURL=procedural.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedural.js","sourceRoot":"","sources":["../../src/memory/procedural.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Exfiltration guard — Story 8.4.
3
+ *
4
+ * Scans output text for patterns that may indicate secret leakage.
5
+ * Logs violations to `.agentos/security/audit/violations.log`.
6
+ *
7
+ * @module secrets/exfil-guard
8
+ */
9
+ import type { SecurityPolicy } from '../types/index.js';
10
+ /** Result of an exfiltration scan. */
11
+ export interface ExfilResult {
12
+ clean: boolean;
13
+ matches: string[];
14
+ }
15
+ /**
16
+ * Scan text for exfiltration patterns defined in security policy.
17
+ *
18
+ * @param text - Text to scan (agent output, file content, etc.)
19
+ * @param policy - Security policy with deny_exfil_patterns
20
+ * @returns ExfilResult with matches
21
+ */
22
+ export declare function scanForExfiltration(text: string, policy: SecurityPolicy): ExfilResult;
23
+ /**
24
+ * Log an exfiltration violation to the audit log.
25
+ *
26
+ * @param vaultRoot - Vault root path
27
+ * @param source - Where the violation was detected
28
+ * @param matches - Matched patterns
29
+ */
30
+ export declare function logViolation(vaultRoot: string, source: string, matches: string[]): Promise<void>;
31
+ //# sourceMappingURL=exfil-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exfil-guard.d.ts","sourceRoot":"","sources":["../../src/secrets/exfil-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAKxD,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,GACrB,WAAW,CAgBb;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Exfiltration guard — Story 8.4.
3
+ *
4
+ * Scans output text for patterns that may indicate secret leakage.
5
+ * Logs violations to `.agentos/security/audit/violations.log`.
6
+ *
7
+ * @module secrets/exfil-guard
8
+ */
9
+ import fs from 'node:fs/promises';
10
+ import path from 'node:path';
11
+ const AUDIT_DIR = '.agentos/security/audit';
12
+ const VIOLATIONS_LOG = 'violations.log';
13
+ /**
14
+ * Scan text for exfiltration patterns defined in security policy.
15
+ *
16
+ * @param text - Text to scan (agent output, file content, etc.)
17
+ * @param policy - Security policy with deny_exfil_patterns
18
+ * @returns ExfilResult with matches
19
+ */
20
+ export function scanForExfiltration(text, policy) {
21
+ const matches = [];
22
+ for (const pattern of policy.network.deny_exfil_patterns) {
23
+ try {
24
+ const regex = new RegExp(pattern.regex, 'gi');
25
+ const found = text.match(regex);
26
+ if (found) {
27
+ matches.push(...found);
28
+ }
29
+ }
30
+ catch {
31
+ // Invalid regex — skip silently
32
+ }
33
+ }
34
+ return { clean: matches.length === 0, matches };
35
+ }
36
+ /**
37
+ * Log an exfiltration violation to the audit log.
38
+ *
39
+ * @param vaultRoot - Vault root path
40
+ * @param source - Where the violation was detected
41
+ * @param matches - Matched patterns
42
+ */
43
+ export async function logViolation(vaultRoot, source, matches) {
44
+ const dir = path.join(vaultRoot, AUDIT_DIR);
45
+ await fs.mkdir(dir, { recursive: true });
46
+ const logPath = path.join(dir, VIOLATIONS_LOG);
47
+ const timestamp = new Date().toISOString();
48
+ const lines = matches.map((m) => `[${timestamp}] EXFIL_DETECTED source=${source} match="${m}"\n`);
49
+ await fs.appendFile(logPath, lines.join(''), 'utf8');
50
+ }
51
+ //# sourceMappingURL=exfil-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exfil-guard.js","sourceRoot":"","sources":["../../src/secrets/exfil-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,SAAS,GAAG,yBAAyB,CAAC;AAC5C,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAQxC;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,MAAsB;IAEtB,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,MAAc,EACd,OAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CACvB,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,SAAS,2BAA2B,MAAM,WAAW,CAAC,KAAK,CACvE,CAAC;IAEF,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Secrets module — barrel export.
3
+ * @module secrets
4
+ */
5
+ export { addSecret, removeSecret, listSecrets, rotateSecret, decryptSecrets, resolveSecretRefs, } from './vault.js';
6
+ export { scanForExfiltration, logViolation, } from './exfil-guard.js';
7
+ export type { ExfilResult } from './exfil-guard.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Secrets module — barrel export.
3
+ * @module secrets
4
+ */
5
+ export { addSecret, removeSecret, listSecrets, rotateSecret, decryptSecrets, resolveSecretRefs, } from './vault.js';
6
+ export { scanForExfiltration, logViolation, } from './exfil-guard.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Secrets vault — encrypted secret storage with reference-only access.
3
+ *
4
+ * Story 8.1: Manages secrets in `.agentos/secrets/vault.yaml` (encrypted)
5
+ * and `.agentos/secrets/refs.yaml` (reference names only).
6
+ *
7
+ * In a full implementation, this would use SOPS/age for real encryption.
8
+ * For MVP, we use a simple base64 encoding with a marker to simulate
9
+ * the encrypted-at-rest pattern. The API surface is identical to what
10
+ * a SOPS integration would provide.
11
+ *
12
+ * @module secrets/vault
13
+ */
14
+ /**
15
+ * Add a secret to the vault.
16
+ *
17
+ * @param vaultRoot - Vault root path
18
+ * @param name - Secret name (e.g. 'github-token')
19
+ * @param value - Secret value to encrypt
20
+ */
21
+ export declare function addSecret(vaultRoot: string, name: string, value: string): Promise<void>;
22
+ /**
23
+ * Remove a secret from the vault.
24
+ *
25
+ * @param vaultRoot - Vault root path
26
+ * @param name - Secret name to remove
27
+ * @returns true if removed, false if not found
28
+ */
29
+ export declare function removeSecret(vaultRoot: string, name: string): Promise<boolean>;
30
+ /**
31
+ * List all secret names (never values).
32
+ *
33
+ * @param vaultRoot - Vault root path
34
+ * @returns Sorted array of secret names
35
+ */
36
+ export declare function listSecrets(vaultRoot: string): Promise<string[]>;
37
+ /**
38
+ * Rotate a secret (re-encrypt with new value).
39
+ *
40
+ * @param vaultRoot - Vault root path
41
+ * @param name - Secret name to rotate
42
+ * @param newValue - New secret value
43
+ * @returns true if rotated, false if not found
44
+ */
45
+ export declare function rotateSecret(vaultRoot: string, name: string, newValue: string): Promise<boolean>;
46
+ /**
47
+ * Decrypt all secrets to a key-value map (for exec proxy).
48
+ * WARNING: Returns plaintext — only use in-memory for child process env.
49
+ *
50
+ * @param vaultRoot - Vault root path
51
+ * @returns Map of name → plaintext value
52
+ */
53
+ export declare function decryptSecrets(vaultRoot: string): Promise<Record<string, string>>;
54
+ /**
55
+ * Resolve secret references in a string.
56
+ * Replaces `${{secret:name}}` with actual values.
57
+ *
58
+ * @param template - String with secret references
59
+ * @param vaultRoot - Vault root path
60
+ * @returns Resolved string
61
+ */
62
+ export declare function resolveSecretRefs(template: string, vaultRoot: string): Promise<string>;
63
+ //# sourceMappingURL=vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/secrets/vault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiFH;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGtE;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASjC;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Secrets vault — encrypted secret storage with reference-only access.
3
+ *
4
+ * Story 8.1: Manages secrets in `.agentos/secrets/vault.yaml` (encrypted)
5
+ * and `.agentos/secrets/refs.yaml` (reference names only).
6
+ *
7
+ * In a full implementation, this would use SOPS/age for real encryption.
8
+ * For MVP, we use a simple base64 encoding with a marker to simulate
9
+ * the encrypted-at-rest pattern. The API surface is identical to what
10
+ * a SOPS integration would provide.
11
+ *
12
+ * @module secrets/vault
13
+ */
14
+ import fs from 'node:fs/promises';
15
+ import path from 'node:path';
16
+ import yaml from 'js-yaml';
17
+ const SECRETS_DIR = '.agentos/secrets';
18
+ const VAULT_FILE = 'vault.yaml';
19
+ const REFS_FILE = 'refs.yaml';
20
+ /** Header marker for "encrypted" values. */
21
+ const ENC_PREFIX = 'ENC[agentfs:';
22
+ const ENC_SUFFIX = ']';
23
+ function encode(value) {
24
+ return `${ENC_PREFIX}${Buffer.from(value).toString('base64')}${ENC_SUFFIX}`;
25
+ }
26
+ function decode(encoded) {
27
+ const inner = encoded.slice(ENC_PREFIX.length, -ENC_SUFFIX.length);
28
+ return Buffer.from(inner, 'base64').toString('utf8');
29
+ }
30
+ function isEncoded(value) {
31
+ return value.startsWith(ENC_PREFIX) && value.endsWith(ENC_SUFFIX);
32
+ }
33
+ async function ensureDir(vaultRoot) {
34
+ const dir = path.join(vaultRoot, SECRETS_DIR);
35
+ await fs.mkdir(dir, { recursive: true });
36
+ return dir;
37
+ }
38
+ async function readVault(vaultRoot) {
39
+ const filePath = path.join(vaultRoot, SECRETS_DIR, VAULT_FILE);
40
+ try {
41
+ const content = await fs.readFile(filePath, 'utf8');
42
+ return yaml.load(content) ?? { version: '1.0', secrets: {} };
43
+ }
44
+ catch {
45
+ return { version: '1.0', secrets: {} };
46
+ }
47
+ }
48
+ async function writeVault(vaultRoot, data) {
49
+ const dir = await ensureDir(vaultRoot);
50
+ await fs.writeFile(path.join(dir, VAULT_FILE), yaml.dump(data), 'utf8');
51
+ }
52
+ async function readRefs(vaultRoot) {
53
+ const filePath = path.join(vaultRoot, SECRETS_DIR, REFS_FILE);
54
+ try {
55
+ const content = await fs.readFile(filePath, 'utf8');
56
+ return yaml.load(content) ?? { version: '1.0', refs: [] };
57
+ }
58
+ catch {
59
+ return { version: '1.0', refs: [] };
60
+ }
61
+ }
62
+ async function writeRefs(vaultRoot, data) {
63
+ const dir = await ensureDir(vaultRoot);
64
+ await fs.writeFile(path.join(dir, REFS_FILE), yaml.dump(data), 'utf8');
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Public API
68
+ // ---------------------------------------------------------------------------
69
+ /**
70
+ * Add a secret to the vault.
71
+ *
72
+ * @param vaultRoot - Vault root path
73
+ * @param name - Secret name (e.g. 'github-token')
74
+ * @param value - Secret value to encrypt
75
+ */
76
+ export async function addSecret(vaultRoot, name, value) {
77
+ const vault = await readVault(vaultRoot);
78
+ vault.secrets[name] = encode(value);
79
+ await writeVault(vaultRoot, vault);
80
+ const refs = await readRefs(vaultRoot);
81
+ if (!refs.refs.includes(name)) {
82
+ refs.refs.push(name);
83
+ refs.refs.sort();
84
+ await writeRefs(vaultRoot, refs);
85
+ }
86
+ }
87
+ /**
88
+ * Remove a secret from the vault.
89
+ *
90
+ * @param vaultRoot - Vault root path
91
+ * @param name - Secret name to remove
92
+ * @returns true if removed, false if not found
93
+ */
94
+ export async function removeSecret(vaultRoot, name) {
95
+ const vault = await readVault(vaultRoot);
96
+ if (!(name in vault.secrets))
97
+ return false;
98
+ delete vault.secrets[name];
99
+ await writeVault(vaultRoot, vault);
100
+ const refs = await readRefs(vaultRoot);
101
+ refs.refs = refs.refs.filter((r) => r !== name);
102
+ await writeRefs(vaultRoot, refs);
103
+ return true;
104
+ }
105
+ /**
106
+ * List all secret names (never values).
107
+ *
108
+ * @param vaultRoot - Vault root path
109
+ * @returns Sorted array of secret names
110
+ */
111
+ export async function listSecrets(vaultRoot) {
112
+ const refs = await readRefs(vaultRoot);
113
+ return refs.refs;
114
+ }
115
+ /**
116
+ * Rotate a secret (re-encrypt with new value).
117
+ *
118
+ * @param vaultRoot - Vault root path
119
+ * @param name - Secret name to rotate
120
+ * @param newValue - New secret value
121
+ * @returns true if rotated, false if not found
122
+ */
123
+ export async function rotateSecret(vaultRoot, name, newValue) {
124
+ const vault = await readVault(vaultRoot);
125
+ if (!(name in vault.secrets))
126
+ return false;
127
+ vault.secrets[name] = encode(newValue);
128
+ await writeVault(vaultRoot, vault);
129
+ return true;
130
+ }
131
+ /**
132
+ * Decrypt all secrets to a key-value map (for exec proxy).
133
+ * WARNING: Returns plaintext — only use in-memory for child process env.
134
+ *
135
+ * @param vaultRoot - Vault root path
136
+ * @returns Map of name → plaintext value
137
+ */
138
+ export async function decryptSecrets(vaultRoot) {
139
+ const vault = await readVault(vaultRoot);
140
+ const result = {};
141
+ for (const [name, encrypted] of Object.entries(vault.secrets)) {
142
+ if (isEncoded(encrypted)) {
143
+ result[name.toUpperCase().replace(/-/g, '_')] = decode(encrypted);
144
+ }
145
+ }
146
+ return result;
147
+ }
148
+ /**
149
+ * Resolve secret references in a string.
150
+ * Replaces `${{secret:name}}` with actual values.
151
+ *
152
+ * @param template - String with secret references
153
+ * @param vaultRoot - Vault root path
154
+ * @returns Resolved string
155
+ */
156
+ export async function resolveSecretRefs(template, vaultRoot) {
157
+ const secrets = await decryptSecrets(vaultRoot);
158
+ return template.replace(/\$\{\{secret:([^}]+)\}\}/g, (_match, name) => {
159
+ const envKey = name.toUpperCase().replace(/-/g, '_');
160
+ return secrets[envKey] ?? ('${{secret:' + name + '}}');
161
+ });
162
+ }
163
+ //# sourceMappingURL=vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/secrets/vault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Claude AppArmor compiler — Story 7.2.
3
+ *
4
+ * Compiles SecurityPolicy into `.claude/settings.json` permissions format.
5
+ * Preserves existing user settings when the file already exists.
6
+ *
7
+ * @module security/claude-compiler
8
+ */
9
+ import type { SecurityPolicy } from '../types/index.js';
10
+ /** Shape of .claude/settings.json that we manage. */
11
+ interface ClaudeSettings {
12
+ permissions?: {
13
+ deny?: string[];
14
+ ask?: string[];
15
+ };
16
+ [key: string]: unknown;
17
+ }
18
+ /**
19
+ * Compile SecurityPolicy into .claude/settings.json permissions.
20
+ *
21
+ * @param vaultRoot - Absolute path to vault root
22
+ * @param policy - Parsed security policy
23
+ * @param dryRun - If true, returns the settings without writing
24
+ * @returns The compiled ClaudeSettings object
25
+ */
26
+ export declare function compileClaudeSecurity(vaultRoot: string, policy: SecurityPolicy, dryRun?: boolean): Promise<ClaudeSettings>;
27
+ export {};
28
+ //# sourceMappingURL=claude-compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-compiler.d.ts","sourceRoot":"","sources":["../../src/security/claude-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,qDAAqD;AACrD,UAAU,cAAc;IACtB,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,MAAM,UAAQ,GACb,OAAO,CAAC,cAAc,CAAC,CAwDzB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Claude AppArmor compiler — Story 7.2.
3
+ *
4
+ * Compiles SecurityPolicy into `.claude/settings.json` permissions format.
5
+ * Preserves existing user settings when the file already exists.
6
+ *
7
+ * @module security/claude-compiler
8
+ */
9
+ import fs from 'node:fs/promises';
10
+ import path from 'node:path';
11
+ /**
12
+ * Compile SecurityPolicy into .claude/settings.json permissions.
13
+ *
14
+ * @param vaultRoot - Absolute path to vault root
15
+ * @param policy - Parsed security policy
16
+ * @param dryRun - If true, returns the settings without writing
17
+ * @returns The compiled ClaudeSettings object
18
+ */
19
+ export async function compileClaudeSecurity(vaultRoot, policy, dryRun = false) {
20
+ const settingsPath = path.join(vaultRoot, '.claude', 'settings.json');
21
+ // Read existing settings to preserve user customizations
22
+ let existing = {};
23
+ try {
24
+ const raw = await fs.readFile(settingsPath, 'utf8');
25
+ existing = JSON.parse(raw);
26
+ }
27
+ catch {
28
+ // No existing settings — start fresh
29
+ }
30
+ // Build deny rules from policy
31
+ const denyRules = [];
32
+ // File read denials → "Read" deny
33
+ for (const pattern of policy.file_access.deny_read) {
34
+ denyRules.push(`Read(${pattern})`);
35
+ }
36
+ // File write denials → "Write" deny
37
+ for (const pattern of policy.file_access.deny_write) {
38
+ denyRules.push(`Write(${pattern})`);
39
+ }
40
+ // Blocked commands
41
+ for (const cmd of policy.commands.blocked) {
42
+ denyRules.push(`Execute(${cmd})`);
43
+ }
44
+ // Build ask rules from policy
45
+ const askRules = [];
46
+ for (const pattern of policy.file_access.ask_write) {
47
+ askRules.push(`Write(${pattern})`);
48
+ }
49
+ for (const cmd of policy.commands.ask_before) {
50
+ askRules.push(`Execute(${cmd})`);
51
+ }
52
+ // Merge with existing settings
53
+ const result = {
54
+ ...existing,
55
+ permissions: {
56
+ deny: denyRules,
57
+ ask: askRules,
58
+ },
59
+ };
60
+ if (!dryRun) {
61
+ await fs.mkdir(path.dirname(settingsPath), { recursive: true });
62
+ await fs.writeFile(settingsPath, JSON.stringify(result, null, 2) + '\n', 'utf8');
63
+ }
64
+ return result;
65
+ }
66
+ //# sourceMappingURL=claude-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-compiler.js","sourceRoot":"","sources":["../../src/security/claude-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAY7B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAiB,EACjB,MAAsB,EACtB,MAAM,GAAG,KAAK;IAEd,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IAEtE,yDAAyD;IACzD,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACpD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;IAED,+BAA+B;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,kCAAkC;IAClC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QACnD,SAAS,CAAC,IAAI,CAAC,QAAQ,OAAO,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,oCAAoC;IACpC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QACpD,SAAS,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,mBAAmB;IACnB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC1C,SAAS,CAAC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,+BAA+B;IAC/B,MAAM,MAAM,GAAmB;QAC7B,GAAG,QAAQ;QACX,WAAW,EAAE;YACX,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,QAAQ;SACd;KACF,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Security module — barrel export.
3
+ * @module security
4
+ */
5
+ export { readSecurityPolicy, writeSecurityPolicy, scanForInjections, checkCommand, DEFAULT_POLICY, } from './parser.js';
6
+ export { compileClaudeSecurity } from './claude-compiler.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Security module — barrel export.
3
+ * @module security
4
+ */
5
+ export { readSecurityPolicy, writeSecurityPolicy, scanForInjections, checkCommand, DEFAULT_POLICY, } from './parser.js';
6
+ export { compileClaudeSecurity } from './claude-compiler.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}