atabey-shared 0.0.37 → 0.1.1-beta

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 (80) hide show
  1. package/README.md +2 -2
  2. package/dist/agent-identity.d.ts +34 -0
  3. package/dist/agent-identity.js +77 -0
  4. package/dist/agent-identity.js.map +1 -0
  5. package/dist/api-catalog.d.ts +57 -0
  6. package/dist/api-catalog.js +254 -0
  7. package/dist/api-catalog.js.map +1 -0
  8. package/dist/audit-chain.d.ts +32 -3
  9. package/dist/audit-chain.js +187 -10
  10. package/dist/audit-chain.js.map +1 -1
  11. package/dist/audit.d.ts +8 -0
  12. package/dist/audit.js +44 -7
  13. package/dist/audit.js.map +1 -1
  14. package/dist/constants.d.ts +7 -9
  15. package/dist/constants.js +14 -18
  16. package/dist/constants.js.map +1 -1
  17. package/dist/database.d.ts +1 -0
  18. package/dist/database.js +3 -0
  19. package/dist/database.js.map +1 -1
  20. package/dist/errors.d.ts +1 -1
  21. package/dist/errors.js +1 -1
  22. package/dist/file-lock.d.ts +5 -0
  23. package/dist/file-lock.js +20 -31
  24. package/dist/file-lock.js.map +1 -1
  25. package/dist/index.d.ts +9 -0
  26. package/dist/index.js +9 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/job-queue.d.ts +32 -9
  29. package/dist/job-queue.js +81 -8
  30. package/dist/job-queue.js.map +1 -1
  31. package/dist/logger.d.ts +1 -0
  32. package/dist/logger.js +33 -7
  33. package/dist/logger.js.map +1 -1
  34. package/dist/memory-prune.d.ts +18 -0
  35. package/dist/memory-prune.js +48 -0
  36. package/dist/memory-prune.js.map +1 -0
  37. package/dist/migrations.d.ts +69 -0
  38. package/dist/migrations.js +394 -0
  39. package/dist/migrations.js.map +1 -0
  40. package/dist/otel.d.ts +39 -0
  41. package/dist/otel.js +93 -0
  42. package/dist/otel.js.map +1 -0
  43. package/dist/outbound-http.d.ts +32 -0
  44. package/dist/outbound-http.js +88 -0
  45. package/dist/outbound-http.js.map +1 -0
  46. package/dist/pii.d.ts +1 -0
  47. package/dist/pii.js +82 -26
  48. package/dist/pii.js.map +1 -1
  49. package/dist/policy-gate.js +27 -3
  50. package/dist/policy-gate.js.map +1 -1
  51. package/dist/retention.d.ts +6 -1
  52. package/dist/retention.js +56 -9
  53. package/dist/retention.js.map +1 -1
  54. package/dist/sandbox-fs.d.ts +1 -1
  55. package/dist/sandbox-fs.js +31 -38
  56. package/dist/sandbox-fs.js.map +1 -1
  57. package/dist/sandbox-runtime.d.ts +22 -29
  58. package/dist/sandbox-runtime.js +125 -93
  59. package/dist/sandbox-runtime.js.map +1 -1
  60. package/dist/sandbox.d.ts +1 -1
  61. package/dist/sandbox.js +1 -1
  62. package/dist/secrets.d.ts +99 -0
  63. package/dist/secrets.js +371 -0
  64. package/dist/secrets.js.map +1 -0
  65. package/dist/storage.d.ts +67 -0
  66. package/dist/storage.js +291 -11
  67. package/dist/storage.js.map +1 -1
  68. package/dist/time.js +6 -2
  69. package/dist/time.js.map +1 -1
  70. package/dist/tls.d.ts +87 -0
  71. package/dist/tls.js +154 -0
  72. package/dist/tls.js.map +1 -0
  73. package/dist/tokenizer.d.ts +54 -0
  74. package/dist/tokenizer.js +272 -0
  75. package/dist/tokenizer.js.map +1 -0
  76. package/dist/types.d.ts +1 -1
  77. package/dist/types.js +1 -1
  78. package/dist/worker-pool.js +19 -0
  79. package/dist/worker-pool.js.map +1 -1
  80. package/package.json +19 -7
package/dist/sandbox.js CHANGED
@@ -149,7 +149,7 @@ export function sandboxSpawn(command, args, options = {}) {
149
149
  return spawn(command, args, opts);
150
150
  }
151
151
  /**
152
- * Human-readable status for dashboard / CLI diagnostics.
152
+ * Human-readable status for CLI diagnostics.
153
153
  */
154
154
  export function getSandboxStatus() {
155
155
  return {
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Secret Management & Leak Guard (Phase 1.5)
3
+ *
4
+ * Provides:
5
+ * 1. Encrypted local secret vault (.atabey/secrets.vault.json) using AES-256-GCM
6
+ * with per-secret random salt (HKDF-SHA256) and 96-bit IV.
7
+ * 2. Subprocess environment scrubber (strips sensitive keys before spawning child processes).
8
+ * 3. Secret leak scanner (detects API keys, cloud credentials, private keys, and vault values).
9
+ */
10
+ export interface VaultEntry {
11
+ /** Base64-encoded 16-byte HKDF salt */
12
+ salt: string;
13
+ /** Base64-encoded 12-byte GCM initialization vector */
14
+ iv: string;
15
+ /** Base64-encoded 16-byte GCM authentication tag */
16
+ tag: string;
17
+ /** Base64-encoded ciphertext */
18
+ ciphertext: string;
19
+ /** ISO-8601 creation timestamp */
20
+ createdAt: string;
21
+ /** ISO-8601 last update timestamp */
22
+ updatedAt: string;
23
+ /** Optional non-sensitive description */
24
+ description?: string;
25
+ }
26
+ export interface VaultFile {
27
+ version: 1;
28
+ entries: Record<string, VaultEntry>;
29
+ }
30
+ export interface SecretMetadata {
31
+ name: string;
32
+ createdAt: string;
33
+ updatedAt: string;
34
+ description?: string;
35
+ }
36
+ export interface SecretFinding {
37
+ ruleId: string;
38
+ description: string;
39
+ matchPreview: string;
40
+ index: number;
41
+ }
42
+ export declare class SecretManager {
43
+ private static resolveVaultDir;
44
+ private static resolveMasterKey;
45
+ private static vaultFilePath;
46
+ private static readVault;
47
+ private static writeVault;
48
+ /**
49
+ * Encrypt and store a secret in the local AES-256-GCM vault.
50
+ */
51
+ static setSecret(name: string, value: string, options?: {
52
+ description?: string;
53
+ vaultDir?: string;
54
+ }): void;
55
+ /**
56
+ * Retrieve and decrypt a secret by name.
57
+ * Checks process.env[name] fallback only when allowEnvFallback is true.
58
+ */
59
+ static getSecret(name: string, options?: {
60
+ vaultDir?: string;
61
+ allowEnvFallback?: boolean;
62
+ }): string | null;
63
+ /**
64
+ * Delete a secret from the vault.
65
+ */
66
+ static deleteSecret(name: string, options?: {
67
+ vaultDir?: string;
68
+ }): boolean;
69
+ /**
70
+ * List stored secret metadata without exposing plaintext values.
71
+ */
72
+ static listSecrets(options?: {
73
+ vaultDir?: string;
74
+ }): SecretMetadata[];
75
+ /**
76
+ * Re-encrypt all vault entries under a new 32-byte master key.
77
+ *
78
+ * Safe ordering: decrypt everything first, build the new vault in memory,
79
+ * then atomically swap. The previous key is kept as `master.key.bak` for
80
+ * the duration of the swap and restored on failure, so a mid-rotation error
81
+ * cannot make the vault permanently undecryptable.
82
+ */
83
+ static rotateMasterKey(newKeyMaterial: string | Buffer, options?: {
84
+ vaultDir?: string;
85
+ }): number;
86
+ }
87
+ /**
88
+ * Scrub sensitive credentials from an environment object before passing to a child process.
89
+ */
90
+ export declare function scrubEnvForSubprocess(env?: NodeJS.ProcessEnv, extraAllowedKeys?: string[]): NodeJS.ProcessEnv;
91
+ /**
92
+ * Scan arbitrary text (command output, file content, tool arguments) for leaked secrets.
93
+ */
94
+ export declare function scanForSecrets(text: string): SecretFinding[];
95
+ /**
96
+ * Redact leaked secrets from text before it is returned to an AI/LLM.
97
+ * Complements PII masking with cloud-credential/private-key patterns.
98
+ */
99
+ export declare function redactSecrets(text: string): string;
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Secret Management & Leak Guard (Phase 1.5)
3
+ *
4
+ * Provides:
5
+ * 1. Encrypted local secret vault (.atabey/secrets.vault.json) using AES-256-GCM
6
+ * with per-secret random salt (HKDF-SHA256) and 96-bit IV.
7
+ * 2. Subprocess environment scrubber (strips sensitive keys before spawning child processes).
8
+ * 3. Secret leak scanner (detects API keys, cloud credentials, private keys, and vault values).
9
+ */
10
+ import crypto from "crypto";
11
+ import fs from "fs";
12
+ import path from "path";
13
+ import { resolveFrameworkDir } from "./storage.js";
14
+ /** Env var names or patterns that must never leak into untrusted subprocesses. */
15
+ const SENSITIVE_ENV_PATTERNS = [
16
+ /_KEY$/i,
17
+ /_KEYS$/i,
18
+ /_SECRET/i,
19
+ /_TOKEN$/i,
20
+ /_PASSWORD$/i,
21
+ /_PASSWD$/i,
22
+ /(^|_)PWD$/i,
23
+ /^PGPASSWORD$/i,
24
+ /_CREDENTIAL/i,
25
+ /_PRIVATE/i,
26
+ /_PASSPHRASE$/i,
27
+ /ACCESS_KEY/i,
28
+ /_APIKEY$/i,
29
+ /_DSN$/i,
30
+ /(^|_)AUTH$/i,
31
+ /_SALT$/i,
32
+ /(^|_)SECRETKEY/i,
33
+ /^ATABEY_AUDIT_HMAC_KEY$/i,
34
+ /^ATABEY_MASTER_KEY$/i,
35
+ /^MCP_AUTH_TOKEN$/i,
36
+ /^MCP_AUTH_USERS$/i,
37
+ /^DATABASE_URL$/i,
38
+ /^REDIS_URL$/i,
39
+ /^OPENAI_API_KEY$/i,
40
+ /^ANTHROPIC_API_KEY$/i,
41
+ /^GEMINI_API_KEY$/i,
42
+ /^GOOGLE_API_KEY$/i,
43
+ /^AWS_SECRET_ACCESS_KEY$/i,
44
+ /^AWS_SESSION_TOKEN$/i,
45
+ /^GITHUB_TOKEN$/i,
46
+ /^GH_TOKEN$/i,
47
+ /^GITLAB_TOKEN$/i,
48
+ /^NPM_TOKEN$/i,
49
+ /^SLACK_BOT_TOKEN$/i,
50
+ /^STRIPE_SECRET_KEY$/i,
51
+ ];
52
+ const SECRET_LEAK_PATTERNS = [
53
+ {
54
+ id: "aws-access-key",
55
+ description: "AWS Access Key ID",
56
+ regex: /\b(?:AKIA|ASIA|ABIA|ACCA)[0-9A-Z]{16}\b/g,
57
+ },
58
+ {
59
+ id: "github-pat",
60
+ description: "GitHub Personal Access Token",
61
+ regex: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,255}\b|\bgithub_pat_[A-Za-z0-9_]{80,255}\b/g,
62
+ },
63
+ {
64
+ id: "openai-anthropic-key",
65
+ description: "OpenAI / Anthropic API Key",
66
+ regex: /\bsk-(?:proj-|ant-api\d{2}-|live-|test-)?[A-Za-z0-9_-]{20,200}\b/g,
67
+ },
68
+ {
69
+ id: "google-api-key",
70
+ description: "Google Cloud / Gemini API Key",
71
+ regex: /\bAIza[0-9A-Za-z_-]{35}\b/g,
72
+ },
73
+ {
74
+ id: "slack-token",
75
+ description: "Slack API Token",
76
+ regex: /\bxox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*\b/g,
77
+ },
78
+ {
79
+ id: "private-key-pem",
80
+ description: "PEM Private Key Block",
81
+ regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH |ENCRYPTED )?PRIVATE KEY-----/g,
82
+ },
83
+ {
84
+ id: "stripe-secret",
85
+ description: "Stripe Live/Test Secret Key",
86
+ regex: /\b(?:sk|rk)_(?:live|test)_[0-9a-zA-Z]{24,99}\b/g,
87
+ },
88
+ ];
89
+ function deriveSubkey(masterKey, salt) {
90
+ return Buffer.from(crypto.hkdfSync("sha256", masterKey, salt, Buffer.from("atabey-vault-v1", "utf8"), 32));
91
+ }
92
+ function redactPreview(match) {
93
+ if (match.length <= 8)
94
+ return "***";
95
+ return `${match.slice(0, 4)}...${match.slice(-3)}`;
96
+ }
97
+ export class SecretManager {
98
+ static resolveVaultDir(customDir) {
99
+ if (customDir)
100
+ return customDir;
101
+ const envDir = process.env.ATABEY_TEST_DIR || process.env.ATABEY_FRAMEWORK_DIR;
102
+ if (envDir && envDir.trim())
103
+ return envDir.trim();
104
+ return resolveFrameworkDir();
105
+ }
106
+ static resolveMasterKey(vaultDir) {
107
+ const envKey = process.env.ATABEY_MASTER_KEY?.trim();
108
+ if (envKey) {
109
+ return crypto.createHash("sha256").update(envKey, "utf8").digest();
110
+ }
111
+ const keyPath = path.join(vaultDir, "master.key");
112
+ if (fs.existsSync(keyPath)) {
113
+ const raw = fs.readFileSync(keyPath);
114
+ if (raw.length === 32)
115
+ return raw;
116
+ return crypto.createHash("sha256").update(raw).digest();
117
+ }
118
+ fs.mkdirSync(vaultDir, { recursive: true });
119
+ const generated = crypto.randomBytes(32);
120
+ fs.writeFileSync(keyPath, generated, { mode: 0o600 });
121
+ return generated;
122
+ }
123
+ static vaultFilePath(vaultDir) {
124
+ return path.join(vaultDir, "secrets.vault.json");
125
+ }
126
+ static readVault(vaultDir) {
127
+ const filePath = this.vaultFilePath(vaultDir);
128
+ if (!fs.existsSync(filePath)) {
129
+ return { version: 1, entries: {} };
130
+ }
131
+ const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
132
+ if (!raw || raw.version !== 1 || typeof raw.entries !== "object" || raw.entries === null) {
133
+ throw new Error("Invalid or unsupported secrets.vault.json format.");
134
+ }
135
+ return raw;
136
+ }
137
+ static writeVault(vaultDir, vault) {
138
+ fs.mkdirSync(vaultDir, { recursive: true });
139
+ const filePath = this.vaultFilePath(vaultDir);
140
+ const tmpPath = `${filePath}.tmp.${process.pid}`;
141
+ fs.writeFileSync(tmpPath, JSON.stringify(vault, null, 2), { mode: 0o600 });
142
+ fs.renameSync(tmpPath, filePath);
143
+ }
144
+ /**
145
+ * Encrypt and store a secret in the local AES-256-GCM vault.
146
+ */
147
+ static setSecret(name, value, options = {}) {
148
+ const keyName = name.trim();
149
+ if (!keyName || !/^[A-Za-z_][A-Za-z0-9_.-]{0,127}$/.test(keyName)) {
150
+ throw new Error(`Invalid secret name "${name}". Use alphanumeric, '_', '.', or '-' characters.`);
151
+ }
152
+ const vaultDir = this.resolveVaultDir(options.vaultDir);
153
+ const masterKey = this.resolveMasterKey(vaultDir);
154
+ const salt = crypto.randomBytes(16);
155
+ const iv = crypto.randomBytes(12);
156
+ const subkey = deriveSubkey(masterKey, salt);
157
+ const cipher = crypto.createCipheriv("aes-256-gcm", subkey, iv);
158
+ cipher.setAAD(Buffer.from(keyName, "utf8"));
159
+ const encrypted = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
160
+ const tag = cipher.getAuthTag();
161
+ const vault = this.readVault(vaultDir);
162
+ const now = new Date().toISOString();
163
+ const existing = vault.entries[keyName];
164
+ vault.entries[keyName] = {
165
+ salt: salt.toString("base64"),
166
+ iv: iv.toString("base64"),
167
+ tag: tag.toString("base64"),
168
+ ciphertext: encrypted.toString("base64"),
169
+ createdAt: existing?.createdAt ?? now,
170
+ updatedAt: now,
171
+ description: options.description ?? existing?.description,
172
+ };
173
+ this.writeVault(vaultDir, vault);
174
+ }
175
+ /**
176
+ * Retrieve and decrypt a secret by name.
177
+ * Checks process.env[name] fallback only when allowEnvFallback is true.
178
+ */
179
+ static getSecret(name, options = {}) {
180
+ const keyName = name.trim();
181
+ const vaultDir = this.resolveVaultDir(options.vaultDir);
182
+ const vault = this.readVault(vaultDir);
183
+ const entry = vault.entries[keyName];
184
+ if (!entry) {
185
+ if (options.allowEnvFallback && process.env[keyName] !== undefined) {
186
+ return process.env[keyName] ?? null;
187
+ }
188
+ return null;
189
+ }
190
+ const masterKey = this.resolveMasterKey(vaultDir);
191
+ const salt = Buffer.from(entry.salt, "base64");
192
+ const iv = Buffer.from(entry.iv, "base64");
193
+ const tag = Buffer.from(entry.tag, "base64");
194
+ const ciphertext = Buffer.from(entry.ciphertext, "base64");
195
+ const subkey = deriveSubkey(masterKey, salt);
196
+ const decipher = crypto.createDecipheriv("aes-256-gcm", subkey, iv);
197
+ decipher.setAAD(Buffer.from(keyName, "utf8"));
198
+ decipher.setAuthTag(tag);
199
+ const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
200
+ return decrypted.toString("utf8");
201
+ }
202
+ /**
203
+ * Delete a secret from the vault.
204
+ */
205
+ static deleteSecret(name, options = {}) {
206
+ const keyName = name.trim();
207
+ const vaultDir = this.resolveVaultDir(options.vaultDir);
208
+ const vault = this.readVault(vaultDir);
209
+ if (!(keyName in vault.entries))
210
+ return false;
211
+ delete vault.entries[keyName];
212
+ this.writeVault(vaultDir, vault);
213
+ return true;
214
+ }
215
+ /**
216
+ * List stored secret metadata without exposing plaintext values.
217
+ */
218
+ static listSecrets(options = {}) {
219
+ const vaultDir = this.resolveVaultDir(options.vaultDir);
220
+ const vault = this.readVault(vaultDir);
221
+ return Object.entries(vault.entries).map(([name, entry]) => ({
222
+ name,
223
+ createdAt: entry.createdAt,
224
+ updatedAt: entry.updatedAt,
225
+ description: entry.description,
226
+ }));
227
+ }
228
+ /**
229
+ * Re-encrypt all vault entries under a new 32-byte master key.
230
+ *
231
+ * Safe ordering: decrypt everything first, build the new vault in memory,
232
+ * then atomically swap. The previous key is kept as `master.key.bak` for
233
+ * the duration of the swap and restored on failure, so a mid-rotation error
234
+ * cannot make the vault permanently undecryptable.
235
+ */
236
+ static rotateMasterKey(newKeyMaterial, options = {}) {
237
+ const vaultDir = this.resolveVaultDir(options.vaultDir);
238
+ if (process.env.ATABEY_MASTER_KEY?.trim()) {
239
+ throw new Error("[VAULT] ATABEY_MASTER_KEY is authoritative; file-based rotation is disabled while it is set. " +
240
+ "Rotate by changing ATABEY_MASTER_KEY and re-running `atabey secrets set` for each secret.");
241
+ }
242
+ const vault = this.readVault(vaultDir);
243
+ const names = Object.keys(vault.entries);
244
+ if (names.length === 0)
245
+ return 0;
246
+ // 1. Decrypt everything with the CURRENT key (no writes yet).
247
+ const decrypted = names.map((name) => {
248
+ const value = this.getSecret(name, { vaultDir });
249
+ if (value === null) {
250
+ throw new Error(`Failed to decrypt secret "${name}" during key rotation.`);
251
+ }
252
+ return {
253
+ name,
254
+ value,
255
+ description: vault.entries[name].description,
256
+ createdAt: vault.entries[name].createdAt,
257
+ };
258
+ });
259
+ const newMasterKey = typeof newKeyMaterial === "string"
260
+ ? crypto.createHash("sha256").update(newKeyMaterial, "utf8").digest()
261
+ : newKeyMaterial.length === 32
262
+ ? Buffer.from(newKeyMaterial)
263
+ : crypto.createHash("sha256").update(newKeyMaterial).digest();
264
+ // 2. Build the new vault in memory, encrypted with the new key.
265
+ const newEntries = {};
266
+ const now = new Date().toISOString();
267
+ for (const item of decrypted) {
268
+ const salt = crypto.randomBytes(16);
269
+ const iv = crypto.randomBytes(12);
270
+ const subkey = deriveSubkey(newMasterKey, salt);
271
+ const cipher = crypto.createCipheriv("aes-256-gcm", subkey, iv);
272
+ cipher.setAAD(Buffer.from(item.name, "utf8"));
273
+ const encrypted = Buffer.concat([cipher.update(item.value, "utf8"), cipher.final()]);
274
+ newEntries[item.name] = {
275
+ salt: salt.toString("base64"),
276
+ iv: iv.toString("base64"),
277
+ tag: cipher.getAuthTag().toString("base64"),
278
+ ciphertext: encrypted.toString("base64"),
279
+ createdAt: item.createdAt,
280
+ updatedAt: now,
281
+ description: item.description,
282
+ };
283
+ }
284
+ // 3. Atomically swap key + vault with rollback protection.
285
+ fs.mkdirSync(vaultDir, { recursive: true });
286
+ const keyPath = path.join(vaultDir, "master.key");
287
+ const backupPath = `${keyPath}.bak`;
288
+ const hadKey = fs.existsSync(keyPath);
289
+ const oldKey = hadKey ? fs.readFileSync(keyPath) : null;
290
+ try {
291
+ if (oldKey)
292
+ fs.writeFileSync(backupPath, oldKey, { mode: 0o600 });
293
+ fs.writeFileSync(keyPath, newMasterKey, { mode: 0o600 });
294
+ this.writeVault(vaultDir, { version: 1, entries: newEntries });
295
+ if (fs.existsSync(backupPath))
296
+ fs.unlinkSync(backupPath);
297
+ }
298
+ catch (err) {
299
+ // Restore the previous key so the (unchanged) old vault stays readable.
300
+ try {
301
+ if (oldKey)
302
+ fs.writeFileSync(keyPath, oldKey, { mode: 0o600 });
303
+ else if (fs.existsSync(keyPath))
304
+ fs.unlinkSync(keyPath);
305
+ if (fs.existsSync(backupPath))
306
+ fs.unlinkSync(backupPath);
307
+ }
308
+ catch {
309
+ /* best-effort rollback */
310
+ }
311
+ throw err;
312
+ }
313
+ return decrypted.length;
314
+ }
315
+ }
316
+ /**
317
+ * Scrub sensitive credentials from an environment object before passing to a child process.
318
+ */
319
+ export function scrubEnvForSubprocess(env = process.env, extraAllowedKeys = []) {
320
+ const allowed = new Set(extraAllowedKeys.map((k) => k.toUpperCase()));
321
+ const clean = {};
322
+ for (const [key, value] of Object.entries(env)) {
323
+ if (value === undefined)
324
+ continue;
325
+ if (allowed.has(key.toUpperCase())) {
326
+ clean[key] = value;
327
+ continue;
328
+ }
329
+ const isSensitive = SENSITIVE_ENV_PATTERNS.some((re) => re.test(key));
330
+ if (!isSensitive) {
331
+ clean[key] = value;
332
+ }
333
+ }
334
+ return clean;
335
+ }
336
+ /**
337
+ * Scan arbitrary text (command output, file content, tool arguments) for leaked secrets.
338
+ */
339
+ export function scanForSecrets(text) {
340
+ if (!text)
341
+ return [];
342
+ const findings = [];
343
+ for (const pattern of SECRET_LEAK_PATTERNS) {
344
+ pattern.regex.lastIndex = 0;
345
+ let match;
346
+ while ((match = pattern.regex.exec(text)) !== null) {
347
+ findings.push({
348
+ ruleId: pattern.id,
349
+ description: pattern.description,
350
+ matchPreview: redactPreview(match[0]),
351
+ index: match.index,
352
+ });
353
+ }
354
+ }
355
+ return findings;
356
+ }
357
+ /**
358
+ * Redact leaked secrets from text before it is returned to an AI/LLM.
359
+ * Complements PII masking with cloud-credential/private-key patterns.
360
+ */
361
+ export function redactSecrets(text) {
362
+ if (!text)
363
+ return text;
364
+ let out = text;
365
+ for (const pattern of SECRET_LEAK_PATTERNS) {
366
+ const flags = pattern.regex.flags.includes("g") ? pattern.regex.flags : `${pattern.regex.flags}g`;
367
+ out = out.replace(new RegExp(pattern.regex.source, flags), `[REDACTED:${pattern.id}]`);
368
+ }
369
+ return out;
370
+ }
371
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"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"}
package/dist/storage.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import Database from "better-sqlite3";
2
+ import type { ApiEndpoint } from "./api-catalog.js";
3
+ import { type BackupResult, type IntegrityCheckResult } from "./migrations.js";
2
4
  import { AgentID, LogID, MessageID, TaskID, TraceID } from "./types.js";
3
5
  export interface AgentRow {
4
6
  name: AgentID;
@@ -264,10 +266,75 @@ export declare class AtabeyStorage {
264
266
  cooldownUntil: number;
265
267
  }>;
266
268
  static clearAllDiscipline(): void;
269
+ static recordDisciplineCall(agent: string, tool: string, timestamp: number, argsSize: number): void;
270
+ static getRecentDisciplineCalls(agent: string, sinceTs: number): Array<{
271
+ tool: string;
272
+ timestamp: number;
273
+ argsSize: number;
274
+ }>;
275
+ static pruneDisciplineCalls(beforeTs: number): void;
276
+ static clearDisciplineCalls(agent?: string): void;
277
+ static getCodeFileHash(filePath: string): string | null;
278
+ static upsertCodeFile(filePath: string, hash: string): void;
279
+ static replaceCodeSymbols(filePath: string, symbols: Array<{
280
+ name: string;
281
+ kind: string;
282
+ startLine: number;
283
+ endLine: number;
284
+ signature: string;
285
+ exported: boolean;
286
+ }>): void;
287
+ static replaceCodeImports(filePath: string, specifiers: string[]): void;
288
+ static deleteCodeFile(filePath: string): void;
289
+ static getAllCodeFilePaths(): string[];
290
+ static searchCodeSymbols(query: string, limit?: number): Array<{
291
+ file: string;
292
+ name: string;
293
+ kind: string;
294
+ startLine: number;
295
+ endLine: number;
296
+ signature: string;
297
+ exported: boolean;
298
+ }>;
299
+ static getCodeGraphStats(): {
300
+ files: number;
301
+ symbols: number;
302
+ imports: number;
303
+ };
304
+ static clearCodeGraph(): void;
267
305
  static checkIntegrity(): {
268
306
  ok: boolean;
269
307
  message: string;
270
308
  };
309
+ static verifyDatabaseIntegrity(mode?: "quick" | "full"): IntegrityCheckResult;
310
+ static getMigrationStatus(): {
311
+ currentVersion: number;
312
+ applied: import("./migrations.js").AppliedMigration[];
313
+ pending: Array<{
314
+ version: number;
315
+ name: string;
316
+ }>;
317
+ };
318
+ static backup(destinationPath?: string): BackupResult;
319
+ static restore(backupPath: string, targetDbPath?: string): {
320
+ restoredPath: string;
321
+ sha256: string;
322
+ schemaVersion: number;
323
+ };
324
+ static saveApiEndpoint(endpoint: ApiEndpoint): void;
325
+ static getApiEndpoints(filter?: {
326
+ tag?: string;
327
+ method?: string;
328
+ search?: string;
329
+ }): ApiEndpoint[];
330
+ static findApiEndpoint(pathQuery: string, method?: string): ApiEndpoint[];
331
+ static deleteApiEndpoint(method: string, path: string): boolean;
332
+ /** Replace the whole catalog with a fresh scan; returns upserted/deleted counts. */
333
+ static replaceApiCatalog(endpoints: ApiEndpoint[]): {
334
+ upserted: number;
335
+ deleted: number;
336
+ };
337
+ private static rowToApiEndpoint;
271
338
  static reset(): void;
272
339
  }
273
340
  /** Canonical alias */