atabey-shared 0.1.4 → 0.1.6

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 (179) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +4 -1
  3. package/dist/modules/index.d.ts +2 -0
  4. package/dist/modules/index.js +2 -0
  5. package/dist/modules/index.js.map +1 -1
  6. package/dist/modules/lifecycle/index.d.ts +1 -0
  7. package/dist/modules/lifecycle/index.js +2 -0
  8. package/dist/modules/lifecycle/index.js.map +1 -0
  9. package/dist/modules/lifecycle/task-lifecycle.d.ts +63 -0
  10. package/dist/modules/lifecycle/task-lifecycle.js +135 -0
  11. package/dist/modules/lifecycle/task-lifecycle.js.map +1 -0
  12. package/dist/modules/primitives/constants.d.ts +6 -10
  13. package/dist/modules/primitives/constants.js +3 -9
  14. package/dist/modules/primitives/constants.js.map +1 -1
  15. package/dist/modules/primitives/fs.js +1 -3
  16. package/dist/modules/primitives/fs.js.map +1 -1
  17. package/dist/modules/primitives/outbound-http.d.ts +2 -0
  18. package/dist/modules/primitives/outbound-http.js +5 -1
  19. package/dist/modules/primitives/outbound-http.js.map +1 -1
  20. package/dist/modules/sandbox/sandbox-runtime.js +1 -2
  21. package/dist/modules/sandbox/sandbox-runtime.js.map +1 -1
  22. package/dist/modules/security/policy-gate.js +27 -0
  23. package/dist/modules/security/policy-gate.js.map +1 -1
  24. package/dist/modules/security/secrets.d.ts +1 -0
  25. package/dist/modules/security/secrets.js +55 -27
  26. package/dist/modules/security/secrets.js.map +1 -1
  27. package/dist/modules/storage/agents.d.ts +15 -0
  28. package/dist/modules/storage/agents.js +59 -0
  29. package/dist/modules/storage/agents.js.map +1 -0
  30. package/dist/modules/storage/api-catalog.d.ts +24 -0
  31. package/dist/modules/storage/api-catalog.js +96 -0
  32. package/dist/modules/storage/api-catalog.js.map +1 -0
  33. package/dist/modules/storage/approvals.d.ts +63 -0
  34. package/dist/modules/storage/approvals.js +80 -0
  35. package/dist/modules/storage/approvals.js.map +1 -0
  36. package/dist/modules/storage/base.d.ts +13 -0
  37. package/dist/modules/storage/base.js +186 -0
  38. package/dist/modules/storage/base.js.map +1 -0
  39. package/dist/modules/storage/code-graph.d.ts +37 -0
  40. package/dist/modules/storage/code-graph.js +109 -0
  41. package/dist/modules/storage/code-graph.js.map +1 -0
  42. package/dist/modules/storage/cooldowns.d.ts +25 -0
  43. package/dist/modules/storage/cooldowns.js +81 -0
  44. package/dist/modules/storage/cooldowns.js.map +1 -0
  45. package/dist/modules/storage/costs.d.ts +27 -0
  46. package/dist/modules/storage/costs.js +30 -0
  47. package/dist/modules/storage/costs.js.map +1 -0
  48. package/dist/modules/storage/discipline.d.ts +38 -0
  49. package/dist/modules/storage/discipline.js +108 -0
  50. package/dist/modules/storage/discipline.js.map +1 -0
  51. package/dist/modules/storage/framework-dir.d.ts +9 -0
  52. package/dist/modules/storage/framework-dir.js +54 -0
  53. package/dist/modules/storage/framework-dir.js.map +1 -0
  54. package/dist/modules/storage/integrity.d.ts +29 -0
  55. package/dist/modules/storage/integrity.js +41 -0
  56. package/dist/modules/storage/integrity.js.map +1 -0
  57. package/dist/modules/storage/knowledge.d.ts +20 -0
  58. package/dist/modules/storage/knowledge.js +40 -0
  59. package/dist/modules/storage/knowledge.js.map +1 -0
  60. package/dist/modules/storage/logs.d.ts +26 -0
  61. package/dist/modules/storage/logs.js +97 -0
  62. package/dist/modules/storage/logs.js.map +1 -0
  63. package/dist/modules/storage/messages.d.ts +18 -0
  64. package/dist/modules/storage/messages.js +60 -0
  65. package/dist/modules/storage/messages.js.map +1 -0
  66. package/dist/modules/storage/metadata.d.ts +11 -0
  67. package/dist/modules/storage/metadata.js +20 -0
  68. package/dist/modules/storage/metadata.js.map +1 -0
  69. package/dist/modules/storage/migrations.js +19 -5
  70. package/dist/modules/storage/migrations.js.map +1 -1
  71. package/dist/modules/storage/storage.d.ts +11 -334
  72. package/dist/modules/storage/storage.js +11 -996
  73. package/dist/modules/storage/storage.js.map +1 -1
  74. package/dist/modules/storage/tasks.d.ts +13 -0
  75. package/dist/modules/storage/tasks.js +54 -0
  76. package/dist/modules/storage/tasks.js.map +1 -0
  77. package/dist/modules/storage/types.d.ts +91 -0
  78. package/dist/modules/storage/types.js +6 -0
  79. package/dist/modules/storage/types.js.map +1 -0
  80. package/dist/modules/storage/users.d.ts +21 -0
  81. package/dist/modules/storage/users.js +46 -0
  82. package/dist/modules/storage/users.js.map +1 -0
  83. package/package.json +5 -3
  84. package/dist/agent-identity.d.ts +0 -1
  85. package/dist/agent-identity.js +0 -2
  86. package/dist/agent-identity.js.map +0 -1
  87. package/dist/api-catalog.d.ts +0 -1
  88. package/dist/api-catalog.js +0 -2
  89. package/dist/api-catalog.js.map +0 -1
  90. package/dist/audit-chain.d.ts +0 -1
  91. package/dist/audit-chain.js +0 -2
  92. package/dist/audit-chain.js.map +0 -1
  93. package/dist/audit.d.ts +0 -1
  94. package/dist/audit.js +0 -2
  95. package/dist/audit.js.map +0 -1
  96. package/dist/constants.d.ts +0 -1
  97. package/dist/constants.js +0 -2
  98. package/dist/constants.js.map +0 -1
  99. package/dist/database.d.ts +0 -1
  100. package/dist/database.js +0 -2
  101. package/dist/database.js.map +0 -1
  102. package/dist/errors.d.ts +0 -1
  103. package/dist/errors.js +0 -2
  104. package/dist/errors.js.map +0 -1
  105. package/dist/file-lock.d.ts +0 -1
  106. package/dist/file-lock.js +0 -2
  107. package/dist/file-lock.js.map +0 -1
  108. package/dist/fs.d.ts +0 -1
  109. package/dist/fs.js +0 -2
  110. package/dist/fs.js.map +0 -1
  111. package/dist/job-queue.d.ts +0 -1
  112. package/dist/job-queue.js +0 -2
  113. package/dist/job-queue.js.map +0 -1
  114. package/dist/lock.d.ts +0 -1
  115. package/dist/lock.js +0 -2
  116. package/dist/lock.js.map +0 -1
  117. package/dist/logger.d.ts +0 -1
  118. package/dist/logger.js +0 -2
  119. package/dist/logger.js.map +0 -1
  120. package/dist/memory-prune.d.ts +0 -1
  121. package/dist/memory-prune.js +0 -2
  122. package/dist/memory-prune.js.map +0 -1
  123. package/dist/migrations.d.ts +0 -1
  124. package/dist/migrations.js +0 -2
  125. package/dist/migrations.js.map +0 -1
  126. package/dist/otel.d.ts +0 -1
  127. package/dist/otel.js +0 -2
  128. package/dist/otel.js.map +0 -1
  129. package/dist/outbound-http.d.ts +0 -1
  130. package/dist/outbound-http.js +0 -2
  131. package/dist/outbound-http.js.map +0 -1
  132. package/dist/pii.d.ts +0 -1
  133. package/dist/pii.js +0 -2
  134. package/dist/pii.js.map +0 -1
  135. package/dist/policy-gate.d.ts +0 -1
  136. package/dist/policy-gate.js +0 -2
  137. package/dist/policy-gate.js.map +0 -1
  138. package/dist/resilience.d.ts +0 -1
  139. package/dist/resilience.js +0 -2
  140. package/dist/resilience.js.map +0 -1
  141. package/dist/retention.d.ts +0 -1
  142. package/dist/retention.js +0 -2
  143. package/dist/retention.js.map +0 -1
  144. package/dist/sandbox-fs.d.ts +0 -1
  145. package/dist/sandbox-fs.js +0 -2
  146. package/dist/sandbox-fs.js.map +0 -1
  147. package/dist/sandbox-runtime.d.ts +0 -1
  148. package/dist/sandbox-runtime.js +0 -2
  149. package/dist/sandbox-runtime.js.map +0 -1
  150. package/dist/sandbox.d.ts +0 -1
  151. package/dist/sandbox.js +0 -2
  152. package/dist/sandbox.js.map +0 -1
  153. package/dist/secrets.d.ts +0 -1
  154. package/dist/secrets.js +0 -2
  155. package/dist/secrets.js.map +0 -1
  156. package/dist/storage.d.ts +0 -1
  157. package/dist/storage.js +0 -2
  158. package/dist/storage.js.map +0 -1
  159. package/dist/string.d.ts +0 -1
  160. package/dist/string.js +0 -2
  161. package/dist/string.js.map +0 -1
  162. package/dist/time.d.ts +0 -1
  163. package/dist/time.js +0 -2
  164. package/dist/time.js.map +0 -1
  165. package/dist/tls.d.ts +0 -1
  166. package/dist/tls.js +0 -2
  167. package/dist/tls.js.map +0 -1
  168. package/dist/tokenizer.d.ts +0 -1
  169. package/dist/tokenizer.js +0 -2
  170. package/dist/tokenizer.js.map +0 -1
  171. package/dist/types.d.ts +0 -1
  172. package/dist/types.js +0 -2
  173. package/dist/types.js.map +0 -1
  174. package/dist/worker-pool.d.ts +0 -1
  175. package/dist/worker-pool.js +0 -2
  176. package/dist/worker-pool.js.map +0 -1
  177. package/dist/worker-thread.d.ts +0 -1
  178. package/dist/worker-thread.js +0 -2
  179. package/dist/worker-thread.js.map +0 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * SQLite connection bootstrap, schema creation, migrations and reset.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import fs from "fs";
8
+ import path from "path";
9
+ import Database from "better-sqlite3";
10
+ import { databaseHolder } from "./database.js";
11
+ import { logger } from "../observability/logger.js";
12
+ import { runPendingMigrations, verifyDatabaseIntegrity } from "./migrations.js";
13
+ import { resolveFrameworkDir } from "./framework-dir.js";
14
+ export class StorageBase {
15
+ static db = null;
16
+ static getDB() {
17
+ if (!this.db) {
18
+ const frameworkDir = resolveFrameworkDir();
19
+ if (!fs.existsSync(frameworkDir)) {
20
+ fs.mkdirSync(frameworkDir, { recursive: true });
21
+ }
22
+ const dbPath = path.join(frameworkDir, "atabey.db");
23
+ this.db = new Database(dbPath, { timeout: 5000 });
24
+ this.db.pragma("journal_mode = WAL");
25
+ databaseHolder.setDB(this.db);
26
+ this.initializeSchema();
27
+ }
28
+ return this.db;
29
+ }
30
+ static initializeSchema() {
31
+ const db = this.db;
32
+ db.exec(`
33
+ CREATE TABLE IF NOT EXISTS agents (
34
+ name TEXT PRIMARY KEY,
35
+ state TEXT DEFAULT 'READY',
36
+ task TEXT DEFAULT 'Idle',
37
+ description TEXT DEFAULT '',
38
+ skills TEXT DEFAULT '[]',
39
+ last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
40
+ )
41
+ `);
42
+ db.exec(`
43
+ CREATE TABLE IF NOT EXISTS messages (
44
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
45
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
46
+ sender TEXT,
47
+ receiver TEXT,
48
+ category TEXT,
49
+ content TEXT,
50
+ trace_id TEXT,
51
+ parent_id TEXT,
52
+ status TEXT DEFAULT 'PENDING',
53
+ priority TEXT DEFAULT 'NORMAL',
54
+ requires_approval BOOLEAN DEFAULT 0
55
+ )
56
+ `);
57
+ db.exec(`
58
+ CREATE TABLE IF NOT EXISTS tasks (
59
+ id TEXT PRIMARY KEY,
60
+ trace_id TEXT,
61
+ description TEXT,
62
+ agent TEXT,
63
+ status TEXT DEFAULT 'PENDING',
64
+ priority TEXT DEFAULT 'NORMAL',
65
+ dependencies TEXT,
66
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
67
+ )
68
+ `);
69
+ db.exec(`
70
+ CREATE TABLE IF NOT EXISTS logs (
71
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
72
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
73
+ agent TEXT,
74
+ action TEXT,
75
+ trace_id TEXT,
76
+ status TEXT,
77
+ summary TEXT,
78
+ findings TEXT,
79
+ prev_hash TEXT,
80
+ hash TEXT
81
+ )
82
+ `);
83
+ try {
84
+ const tableInfo = db.prepare("PRAGMA table_info(logs)").all();
85
+ const columnNames = tableInfo.map(c => c.name);
86
+ if (!columnNames.includes("prev_hash"))
87
+ db.exec("ALTER TABLE logs ADD COLUMN prev_hash TEXT");
88
+ if (!columnNames.includes("hash"))
89
+ db.exec("ALTER TABLE logs ADD COLUMN hash TEXT");
90
+ }
91
+ catch (err) {
92
+ logger.error(`Failed to migrate logs table schema: ${err.message}`);
93
+ }
94
+ db.exec(`
95
+ CREATE TABLE IF NOT EXISTS metadata (
96
+ key TEXT PRIMARY KEY,
97
+ value TEXT
98
+ )
99
+ `);
100
+ db.exec(`
101
+ CREATE TABLE IF NOT EXISTS costs (
102
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
103
+ provider TEXT,
104
+ model TEXT,
105
+ input_tokens INTEGER,
106
+ output_tokens INTEGER,
107
+ cost REAL,
108
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
109
+ trace_id TEXT
110
+ )
111
+ `);
112
+ db.exec(`
113
+ CREATE TABLE IF NOT EXISTS knowledge (
114
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
115
+ filename TEXT UNIQUE,
116
+ content TEXT,
117
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
118
+ )
119
+ `);
120
+ db.exec(`
121
+ CREATE TABLE IF NOT EXISTS users (
122
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
123
+ name TEXT UNIQUE,
124
+ token TEXT UNIQUE,
125
+ role TEXT DEFAULT 'user',
126
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
127
+ )
128
+ `);
129
+ db.exec(`
130
+ CREATE TABLE IF NOT EXISTS loop_cooldowns (
131
+ agent TEXT PRIMARY KEY,
132
+ cooldown_until INTEGER NOT NULL,
133
+ detail TEXT,
134
+ cooldown_count INTEGER DEFAULT 1,
135
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
136
+ )
137
+ `);
138
+ db.exec(`
139
+ CREATE TABLE IF NOT EXISTS approvals (
140
+ trace_id TEXT PRIMARY KEY,
141
+ tool_name TEXT NOT NULL,
142
+ agent TEXT NOT NULL,
143
+ risk_score INTEGER NOT NULL,
144
+ risk_level TEXT NOT NULL,
145
+ reason TEXT NOT NULL,
146
+ args TEXT NOT NULL,
147
+ created_at INTEGER NOT NULL,
148
+ expires_at INTEGER NOT NULL,
149
+ status TEXT DEFAULT 'PENDING',
150
+ passcode TEXT
151
+ )
152
+ `);
153
+ db.exec(`
154
+ CREATE TABLE IF NOT EXISTS discipline (
155
+ agent TEXT PRIMARY KEY,
156
+ total_calls INTEGER DEFAULT 0,
157
+ violations INTEGER DEFAULT 0,
158
+ last_violation TEXT,
159
+ cooldown_until INTEGER DEFAULT 0,
160
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
161
+ )
162
+ `);
163
+ try {
164
+ runPendingMigrations(db);
165
+ const integrity = verifyDatabaseIntegrity(db, "quick");
166
+ if (!integrity.ok) {
167
+ logger.error(`[DB] SQLite startup integrity check failed: ${integrity.messages.join("; ")}`);
168
+ }
169
+ }
170
+ catch (err) {
171
+ const msg = err.message;
172
+ if (/Checksum mismatch/i.test(msg)) {
173
+ // Schema drift or tampering — fail closed instead of running on an unknown schema.
174
+ throw err;
175
+ }
176
+ logger.error(`[DB] Schema migration / integrity check warning: ${msg}`);
177
+ }
178
+ }
179
+ static reset() {
180
+ if (this.db) {
181
+ this.db.close();
182
+ this.db = null;
183
+ }
184
+ }
185
+ }
186
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/modules/storage/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Incremental code graph (files, symbols, imports) for RAG context.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { StorageDiscipline } from "./discipline.js";
8
+ export declare class StorageCodeGraph extends StorageDiscipline {
9
+ static getCodeFileHash(filePath: string): string | null;
10
+ static upsertCodeFile(filePath: string, hash: string): void;
11
+ static replaceCodeSymbols(filePath: string, symbols: Array<{
12
+ name: string;
13
+ kind: string;
14
+ startLine: number;
15
+ endLine: number;
16
+ signature: string;
17
+ exported: boolean;
18
+ }>): void;
19
+ static replaceCodeImports(filePath: string, specifiers: string[]): void;
20
+ static deleteCodeFile(filePath: string): void;
21
+ static getAllCodeFilePaths(): string[];
22
+ static searchCodeSymbols(query: string, limit?: number): Array<{
23
+ file: string;
24
+ name: string;
25
+ kind: string;
26
+ startLine: number;
27
+ endLine: number;
28
+ signature: string;
29
+ exported: boolean;
30
+ }>;
31
+ static getCodeGraphStats(): {
32
+ files: number;
33
+ symbols: number;
34
+ imports: number;
35
+ };
36
+ static clearCodeGraph(): void;
37
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Incremental code graph (files, symbols, imports) for RAG context.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { logger } from "../observability/logger.js";
8
+ import { StorageDiscipline } from "./discipline.js";
9
+ export class StorageCodeGraph extends StorageDiscipline {
10
+ static getCodeFileHash(filePath) {
11
+ try {
12
+ const row = this.getDB().prepare("SELECT hash FROM code_files WHERE path = ?").get(filePath);
13
+ return row?.hash ?? null;
14
+ }
15
+ catch (err) {
16
+ logger.debug(`Failed to get code file hash: ${err.message}`);
17
+ return null;
18
+ }
19
+ }
20
+ static upsertCodeFile(filePath, hash) {
21
+ this.getDB().prepare(`
22
+ INSERT INTO code_files (path, hash, updated_at) VALUES (?, ?, datetime('now'))
23
+ ON CONFLICT(path) DO UPDATE SET hash = excluded.hash, updated_at = datetime('now')
24
+ `).run(filePath, hash);
25
+ }
26
+ static replaceCodeSymbols(filePath, symbols) {
27
+ const db = this.getDB();
28
+ const tx = db.transaction(() => {
29
+ db.prepare("DELETE FROM code_symbols WHERE file = ?").run(filePath);
30
+ const ins = db.prepare("INSERT INTO code_symbols (file, name, kind, start_line, end_line, signature, exported) VALUES (?, ?, ?, ?, ?, ?, ?)");
31
+ for (const s of symbols) {
32
+ ins.run(filePath, s.name, s.kind, s.startLine, s.endLine, s.signature, s.exported ? 1 : 0);
33
+ }
34
+ });
35
+ tx();
36
+ }
37
+ static replaceCodeImports(filePath, specifiers) {
38
+ const db = this.getDB();
39
+ const tx = db.transaction(() => {
40
+ db.prepare("DELETE FROM code_imports WHERE file = ?").run(filePath);
41
+ const ins = db.prepare("INSERT INTO code_imports (file, specifier) VALUES (?, ?)");
42
+ for (const s of specifiers)
43
+ ins.run(filePath, s);
44
+ });
45
+ tx();
46
+ }
47
+ static deleteCodeFile(filePath) {
48
+ const db = this.getDB();
49
+ const tx = db.transaction(() => {
50
+ db.prepare("DELETE FROM code_symbols WHERE file = ?").run(filePath);
51
+ db.prepare("DELETE FROM code_imports WHERE file = ?").run(filePath);
52
+ db.prepare("DELETE FROM code_files WHERE path = ?").run(filePath);
53
+ });
54
+ tx();
55
+ }
56
+ static getAllCodeFilePaths() {
57
+ try {
58
+ return this.getDB().prepare("SELECT path FROM code_files").all().map((r) => r.path);
59
+ }
60
+ catch (err) {
61
+ logger.debug(`Failed to list code files: ${err.message}`);
62
+ return [];
63
+ }
64
+ }
65
+ static searchCodeSymbols(query, limit = 20) {
66
+ try {
67
+ const rows = this.getDB()
68
+ .prepare("SELECT file, name, kind, start_line, end_line, signature, exported FROM code_symbols " +
69
+ "WHERE name LIKE ? ORDER BY (name = ?) DESC, length(name) ASC LIMIT ?")
70
+ .all(`%${query}%`, query, limit);
71
+ return rows.map((r) => ({
72
+ file: r.file,
73
+ name: r.name,
74
+ kind: r.kind,
75
+ startLine: r.start_line,
76
+ endLine: r.end_line,
77
+ signature: r.signature,
78
+ exported: r.exported === 1,
79
+ }));
80
+ }
81
+ catch (err) {
82
+ logger.debug(`Failed to search code symbols: ${err.message}`);
83
+ return [];
84
+ }
85
+ }
86
+ static getCodeGraphStats() {
87
+ try {
88
+ const db = this.getDB();
89
+ const files = db.prepare("SELECT COUNT(*) AS c FROM code_files").get().c;
90
+ const symbols = db.prepare("SELECT COUNT(*) AS c FROM code_symbols").get().c;
91
+ const imports = db.prepare("SELECT COUNT(*) AS c FROM code_imports").get().c;
92
+ return { files, symbols, imports };
93
+ }
94
+ catch (err) {
95
+ logger.debug(`Failed to read code graph stats: ${err.message}`);
96
+ return { files: 0, symbols: 0, imports: 0 };
97
+ }
98
+ }
99
+ static clearCodeGraph() {
100
+ const db = this.getDB();
101
+ const tx = db.transaction(() => {
102
+ db.prepare("DELETE FROM code_symbols").run();
103
+ db.prepare("DELETE FROM code_imports").run();
104
+ db.prepare("DELETE FROM code_files").run();
105
+ });
106
+ tx();
107
+ }
108
+ }
109
+ //# sourceMappingURL=code-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-graph.js","sourceRoot":"","sources":["../../../src/modules/storage/code-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Loop-detector cooldown state (restart-durable).
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { StorageMetadata } from "./metadata.js";
8
+ export declare class StorageCooldowns extends StorageMetadata {
9
+ static saveLoopCooldown(agent: string, cooldownUntil: number, detail: string | null, cooldownCount?: number): void;
10
+ static getLoopCooldown(agent: string): {
11
+ agent: string;
12
+ cooldownUntil: number;
13
+ detail: string | null;
14
+ cooldownCount: number;
15
+ } | null;
16
+ static clearLoopCooldown(agent: string): boolean;
17
+ static clearAllLoopCooldowns(): void;
18
+ static listActiveLoopCooldowns(): Array<{
19
+ agent: string;
20
+ cooldownUntil: number;
21
+ detail: string | null;
22
+ cooldownCount: number;
23
+ }>;
24
+ static purgeExpiredLoopCooldowns(): number;
25
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Loop-detector cooldown state (restart-durable).
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { logger } from "../observability/logger.js";
8
+ import { StorageMetadata } from "./metadata.js";
9
+ export class StorageCooldowns extends StorageMetadata {
10
+ static saveLoopCooldown(agent, cooldownUntil, detail, cooldownCount = 1) {
11
+ const cleanAgent = agent.replace("@", "");
12
+ this.getDB().prepare(`
13
+ INSERT INTO loop_cooldowns (agent, cooldown_until, detail, cooldown_count, updated_at)
14
+ VALUES (?, ?, ?, ?, datetime('now'))
15
+ ON CONFLICT(agent) DO UPDATE SET
16
+ cooldown_until = excluded.cooldown_until,
17
+ detail = excluded.detail,
18
+ cooldown_count = excluded.cooldown_count,
19
+ updated_at = datetime('now')
20
+ `).run(cleanAgent, cooldownUntil, detail, cooldownCount);
21
+ }
22
+ static getLoopCooldown(agent) {
23
+ const cleanAgent = agent.replace("@", "");
24
+ try {
25
+ const row = this.getDB().prepare("SELECT * FROM loop_cooldowns WHERE agent = ?").get(cleanAgent);
26
+ if (!row)
27
+ return null;
28
+ return {
29
+ agent: row.agent,
30
+ cooldownUntil: row.cooldown_until,
31
+ detail: row.detail,
32
+ cooldownCount: row.cooldown_count
33
+ };
34
+ }
35
+ catch (err) {
36
+ logger.debug(`Failed to get loop cooldown: ${err.message}`);
37
+ return null;
38
+ }
39
+ }
40
+ static clearLoopCooldown(agent) {
41
+ const cleanAgent = agent.replace("@", "");
42
+ const info = this.getDB().prepare("DELETE FROM loop_cooldowns WHERE agent = ?").run(cleanAgent);
43
+ return info.changes > 0;
44
+ }
45
+ static clearAllLoopCooldowns() {
46
+ try {
47
+ this.getDB().prepare("DELETE FROM loop_cooldowns").run();
48
+ }
49
+ catch (err) {
50
+ logger.debug(`Failed to clear all loop cooldowns: ${err.message}`);
51
+ }
52
+ }
53
+ static listActiveLoopCooldowns() {
54
+ const now = Date.now();
55
+ try {
56
+ const rows = this.getDB().prepare("SELECT * FROM loop_cooldowns WHERE cooldown_until > ?").all(now);
57
+ return rows.map(r => ({
58
+ agent: r.agent,
59
+ cooldownUntil: r.cooldown_until,
60
+ detail: r.detail,
61
+ cooldownCount: r.cooldown_count
62
+ }));
63
+ }
64
+ catch (err) {
65
+ logger.debug(`Failed to list active loop cooldowns: ${err.message}`);
66
+ return [];
67
+ }
68
+ }
69
+ static purgeExpiredLoopCooldowns() {
70
+ const now = Date.now();
71
+ try {
72
+ const info = this.getDB().prepare("DELETE FROM loop_cooldowns WHERE cooldown_until <= ?").run(now);
73
+ return info.changes;
74
+ }
75
+ catch (err) {
76
+ logger.debug(`Failed to purge expired loop cooldowns: ${err.message}`);
77
+ return 0;
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=cooldowns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cooldowns.js","sourceRoot":"","sources":["../../../src/modules/storage/cooldowns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Token cost accounting rows per provider/model.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { StorageLogs } from "./logs.js";
8
+ export declare class StorageCosts extends StorageLogs {
9
+ static saveCost(cost: {
10
+ provider: string;
11
+ model: string;
12
+ inputTokens: number;
13
+ outputTokens: number;
14
+ cost: number;
15
+ timestamp: string;
16
+ traceId?: string;
17
+ }): void;
18
+ static getAllCosts(): Array<{
19
+ provider: string;
20
+ model: string;
21
+ inputTokens: number;
22
+ outputTokens: number;
23
+ cost: number;
24
+ timestamp: string;
25
+ traceId?: string;
26
+ }>;
27
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Token cost accounting rows per provider/model.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { StorageLogs } from "./logs.js";
8
+ export class StorageCosts extends StorageLogs {
9
+ static saveCost(cost) {
10
+ const db = this.getDB();
11
+ db.prepare(`
12
+ INSERT INTO costs (provider, model, input_tokens, output_tokens, cost, timestamp, trace_id)
13
+ VALUES (?, ?, ?, ?, ?, ?, ?)
14
+ `).run(cost.provider, cost.model, cost.inputTokens, cost.outputTokens, cost.cost, cost.timestamp, cost.traceId || null);
15
+ }
16
+ static getAllCosts() {
17
+ const db = this.getDB();
18
+ const rows = db.prepare("SELECT * FROM costs ORDER BY timestamp ASC").all();
19
+ return rows.map(r => ({
20
+ provider: r.provider,
21
+ model: r.model,
22
+ inputTokens: r.input_tokens,
23
+ outputTokens: r.output_tokens,
24
+ cost: r.cost,
25
+ timestamp: r.timestamp,
26
+ traceId: r.trace_id || undefined
27
+ }));
28
+ }
29
+ }
30
+ //# sourceMappingURL=costs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costs.js","sourceRoot":"","sources":["../../../src/modules/storage/costs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,OAAO,YAAa,SAAQ,WAAW;IAClC,MAAM,CAAC,QAAQ,CAAC,IAQtB;QACG,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,EAAE,CAAC,OAAO,CAAC;;;SAGV,CAAC,CAAC,GAAG,CACF,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,OAAO,IAAI,IAAI,CACvB,CAAC;IACN,CAAC;IAEM,MAAM,CAAC,WAAW;QASrB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC,GAAG,EAAiB,CAAC;QAC3F,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,WAAW,EAAE,CAAC,CAAC,YAAY;YAC3B,YAAY,EAAE,CAAC,CAAC,aAAa;YAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;SACnC,CAAC,CAAC,CAAC;IACR,CAAC;CACJ"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * AI discipline engine stats and call history.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { StorageApprovals } from "./approvals.js";
8
+ export declare class StorageDiscipline extends StorageApprovals {
9
+ static saveDiscipline(agent: string, stats: {
10
+ totalCalls: number;
11
+ violations: number;
12
+ lastViolation: string | null;
13
+ cooldownUntil: number;
14
+ }): void;
15
+ static getDiscipline(agent: string): {
16
+ agent: string;
17
+ totalCalls: number;
18
+ violations: number;
19
+ lastViolation: string | null;
20
+ cooldownUntil: number;
21
+ } | null;
22
+ static getAllDiscipline(): Array<{
23
+ agent: string;
24
+ totalCalls: number;
25
+ violations: number;
26
+ lastViolation: string | null;
27
+ cooldownUntil: number;
28
+ }>;
29
+ static clearAllDiscipline(): void;
30
+ static recordDisciplineCall(agent: string, tool: string, timestamp: number, argsSize: number): void;
31
+ static getRecentDisciplineCalls(agent: string, sinceTs: number): Array<{
32
+ tool: string;
33
+ timestamp: number;
34
+ argsSize: number;
35
+ }>;
36
+ static pruneDisciplineCalls(beforeTs: number): void;
37
+ static clearDisciplineCalls(agent?: string): void;
38
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * AI discipline engine stats and call history.
3
+ *
4
+ * Split from the original AtabeyStorage god-class (2026-10-20 audit, S7).
5
+ * Part of the storage inheritance chain; AtabeyStorage (storage.ts) is the facade.
6
+ */
7
+ import { logger } from "../observability/logger.js";
8
+ import { StorageApprovals } from "./approvals.js";
9
+ export class StorageDiscipline extends StorageApprovals {
10
+ static saveDiscipline(agent, stats) {
11
+ const cleanAgent = agent.replace("@", "");
12
+ this.getDB().prepare(`
13
+ INSERT INTO discipline (agent, total_calls, violations, last_violation, cooldown_until, updated_at)
14
+ VALUES (?, ?, ?, ?, ?, datetime('now'))
15
+ ON CONFLICT(agent) DO UPDATE SET
16
+ total_calls = excluded.total_calls,
17
+ violations = excluded.violations,
18
+ last_violation = excluded.last_violation,
19
+ cooldown_until = excluded.cooldown_until,
20
+ updated_at = datetime('now')
21
+ `).run(cleanAgent, stats.totalCalls, stats.violations, stats.lastViolation, stats.cooldownUntil);
22
+ }
23
+ static getDiscipline(agent) {
24
+ const cleanAgent = agent.replace("@", "");
25
+ try {
26
+ const row = this.getDB().prepare("SELECT * FROM discipline WHERE agent = ?").get(cleanAgent);
27
+ if (!row)
28
+ return null;
29
+ return {
30
+ agent: row.agent,
31
+ totalCalls: row.total_calls,
32
+ violations: row.violations,
33
+ lastViolation: row.last_violation,
34
+ cooldownUntil: row.cooldown_until
35
+ };
36
+ }
37
+ catch (err) {
38
+ logger.debug(`Failed to get discipline: ${err.message}`);
39
+ return null;
40
+ }
41
+ }
42
+ static getAllDiscipline() {
43
+ try {
44
+ const rows = this.getDB().prepare("SELECT * FROM discipline").all();
45
+ return rows.map(row => ({
46
+ agent: row.agent,
47
+ totalCalls: row.total_calls,
48
+ violations: row.violations,
49
+ lastViolation: row.last_violation,
50
+ cooldownUntil: row.cooldown_until
51
+ }));
52
+ }
53
+ catch (err) {
54
+ logger.debug(`Failed to get all discipline: ${err.message}`);
55
+ return [];
56
+ }
57
+ }
58
+ static clearAllDiscipline() {
59
+ try {
60
+ this.getDB().prepare("DELETE FROM discipline").run();
61
+ }
62
+ catch (err) {
63
+ logger.debug(`Failed to clear discipline: ${err.message}`);
64
+ }
65
+ }
66
+ static recordDisciplineCall(agent, tool, timestamp, argsSize) {
67
+ const cleanAgent = agent.replace("@", "");
68
+ try {
69
+ this.getDB().prepare("INSERT INTO discipline_calls (agent, tool, ts, args_size) VALUES (?, ?, ?, ?)").run(cleanAgent, tool, timestamp, argsSize);
70
+ }
71
+ catch (err) {
72
+ logger.debug(`Failed to record discipline call: ${err.message}`);
73
+ }
74
+ }
75
+ static getRecentDisciplineCalls(agent, sinceTs) {
76
+ const cleanAgent = agent.replace("@", "");
77
+ try {
78
+ const rows = this.getDB().prepare("SELECT tool, ts, args_size FROM discipline_calls WHERE agent = ? AND ts > ? ORDER BY ts ASC").all(cleanAgent, sinceTs);
79
+ return rows.map(r => ({ tool: r.tool, timestamp: r.ts, argsSize: r.args_size }));
80
+ }
81
+ catch (err) {
82
+ logger.debug(`Failed to get recent discipline calls: ${err.message}`);
83
+ return [];
84
+ }
85
+ }
86
+ static pruneDisciplineCalls(beforeTs) {
87
+ try {
88
+ this.getDB().prepare("DELETE FROM discipline_calls WHERE ts < ?").run(beforeTs);
89
+ }
90
+ catch (err) {
91
+ logger.debug(`Failed to prune discipline calls: ${err.message}`);
92
+ }
93
+ }
94
+ static clearDisciplineCalls(agent) {
95
+ try {
96
+ if (agent) {
97
+ this.getDB().prepare("DELETE FROM discipline_calls WHERE agent = ?").run(agent.replace("@", ""));
98
+ }
99
+ else {
100
+ this.getDB().prepare("DELETE FROM discipline_calls").run();
101
+ }
102
+ }
103
+ catch (err) {
104
+ logger.debug(`Failed to clear discipline calls: ${err.message}`);
105
+ }
106
+ }
107
+ }
108
+ //# sourceMappingURL=discipline.js.map