atabey-shared 0.1.3 → 0.1.5
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.
- package/LICENSE +0 -0
- package/README.md +4 -1
- package/dist/modules/index.d.ts +2 -0
- package/dist/modules/index.js +2 -0
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/lifecycle/index.d.ts +1 -0
- package/dist/modules/lifecycle/index.js +2 -0
- package/dist/modules/lifecycle/index.js.map +1 -0
- package/dist/modules/lifecycle/task-lifecycle.d.ts +63 -0
- package/dist/modules/lifecycle/task-lifecycle.js +135 -0
- package/dist/modules/lifecycle/task-lifecycle.js.map +1 -0
- package/dist/modules/primitives/fs.js +1 -3
- package/dist/modules/primitives/fs.js.map +1 -1
- package/dist/modules/primitives/outbound-http.d.ts +2 -0
- package/dist/modules/primitives/outbound-http.js +5 -1
- package/dist/modules/primitives/outbound-http.js.map +1 -1
- package/dist/modules/security/secrets.d.ts +1 -0
- package/dist/modules/security/secrets.js +55 -27
- package/dist/modules/security/secrets.js.map +1 -1
- package/dist/modules/storage/agents.d.ts +15 -0
- package/dist/modules/storage/agents.js +59 -0
- package/dist/modules/storage/agents.js.map +1 -0
- package/dist/modules/storage/api-catalog.d.ts +24 -0
- package/dist/modules/storage/api-catalog.js +96 -0
- package/dist/modules/storage/api-catalog.js.map +1 -0
- package/dist/modules/storage/approvals.d.ts +63 -0
- package/dist/modules/storage/approvals.js +80 -0
- package/dist/modules/storage/approvals.js.map +1 -0
- package/dist/modules/storage/base.d.ts +13 -0
- package/dist/modules/storage/base.js +186 -0
- package/dist/modules/storage/base.js.map +1 -0
- package/dist/modules/storage/code-graph.d.ts +37 -0
- package/dist/modules/storage/code-graph.js +109 -0
- package/dist/modules/storage/code-graph.js.map +1 -0
- package/dist/modules/storage/cooldowns.d.ts +25 -0
- package/dist/modules/storage/cooldowns.js +81 -0
- package/dist/modules/storage/cooldowns.js.map +1 -0
- package/dist/modules/storage/costs.d.ts +27 -0
- package/dist/modules/storage/costs.js +30 -0
- package/dist/modules/storage/costs.js.map +1 -0
- package/dist/modules/storage/discipline.d.ts +38 -0
- package/dist/modules/storage/discipline.js +108 -0
- package/dist/modules/storage/discipline.js.map +1 -0
- package/dist/modules/storage/framework-dir.d.ts +9 -0
- package/dist/modules/storage/framework-dir.js +54 -0
- package/dist/modules/storage/framework-dir.js.map +1 -0
- package/dist/modules/storage/integrity.d.ts +29 -0
- package/dist/modules/storage/integrity.js +41 -0
- package/dist/modules/storage/integrity.js.map +1 -0
- package/dist/modules/storage/knowledge.d.ts +20 -0
- package/dist/modules/storage/knowledge.js +40 -0
- package/dist/modules/storage/knowledge.js.map +1 -0
- package/dist/modules/storage/logs.d.ts +26 -0
- package/dist/modules/storage/logs.js +97 -0
- package/dist/modules/storage/logs.js.map +1 -0
- package/dist/modules/storage/messages.d.ts +18 -0
- package/dist/modules/storage/messages.js +60 -0
- package/dist/modules/storage/messages.js.map +1 -0
- package/dist/modules/storage/metadata.d.ts +11 -0
- package/dist/modules/storage/metadata.js +20 -0
- package/dist/modules/storage/metadata.js.map +1 -0
- package/dist/modules/storage/migrations.js +19 -5
- package/dist/modules/storage/migrations.js.map +1 -1
- package/dist/modules/storage/storage.d.ts +11 -334
- package/dist/modules/storage/storage.js +11 -996
- package/dist/modules/storage/storage.js.map +1 -1
- package/dist/modules/storage/tasks.d.ts +13 -0
- package/dist/modules/storage/tasks.js +54 -0
- package/dist/modules/storage/tasks.js.map +1 -0
- package/dist/modules/storage/types.d.ts +91 -0
- package/dist/modules/storage/types.js +6 -0
- package/dist/modules/storage/types.js.map +1 -0
- package/dist/modules/storage/users.d.ts +21 -0
- package/dist/modules/storage/users.js +46 -0
- package/dist/modules/storage/users.js.map +1 -0
- package/package.json +5 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API endpoint registry (contract drift detection source).
|
|
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 { StorageIntegrity } from "./integrity.js";
|
|
8
|
+
export class StorageApiCatalog extends StorageIntegrity {
|
|
9
|
+
static saveApiEndpoint(endpoint) {
|
|
10
|
+
this.getDB().prepare(`
|
|
11
|
+
INSERT INTO api_endpoints (method, path, tag, summary, auth_required, request_schema, response_schema, source, updated_at)
|
|
12
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
13
|
+
ON CONFLICT(method, path) DO UPDATE SET
|
|
14
|
+
tag = excluded.tag,
|
|
15
|
+
summary = excluded.summary,
|
|
16
|
+
auth_required = excluded.auth_required,
|
|
17
|
+
request_schema = excluded.request_schema,
|
|
18
|
+
response_schema = excluded.response_schema,
|
|
19
|
+
source = excluded.source,
|
|
20
|
+
updated_at = excluded.updated_at
|
|
21
|
+
`).run(endpoint.method.toUpperCase(), endpoint.path, endpoint.tag ?? null, endpoint.summary ?? null, endpoint.authRequired ? 1 : 0, endpoint.requestSchema ?? null, endpoint.responseSchema ?? null, endpoint.source ?? null, endpoint.updatedAt || new Date().toISOString());
|
|
22
|
+
}
|
|
23
|
+
static getApiEndpoints(filter = {}) {
|
|
24
|
+
const conditions = [];
|
|
25
|
+
const params = [];
|
|
26
|
+
if (filter.tag) {
|
|
27
|
+
conditions.push("tag = ?");
|
|
28
|
+
params.push(filter.tag);
|
|
29
|
+
}
|
|
30
|
+
if (filter.method) {
|
|
31
|
+
conditions.push("method = ?");
|
|
32
|
+
params.push(filter.method.toUpperCase());
|
|
33
|
+
}
|
|
34
|
+
if (filter.search) {
|
|
35
|
+
conditions.push("(LOWER(path) LIKE ? OR LOWER(request_schema) LIKE ? OR LOWER(response_schema) LIKE ? OR LOWER(summary) LIKE ?)");
|
|
36
|
+
const like = `%${filter.search.toLowerCase()}%`;
|
|
37
|
+
params.push(like, like, like, like);
|
|
38
|
+
}
|
|
39
|
+
const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
40
|
+
const rows = this.getDB().prepare(`SELECT method, path, tag, summary, auth_required, request_schema, response_schema, source, updated_at
|
|
41
|
+
FROM api_endpoints ${where} ORDER BY path ASC, method ASC`).all(...params);
|
|
42
|
+
return rows.map((r) => this.rowToApiEndpoint(r));
|
|
43
|
+
}
|
|
44
|
+
static findApiEndpoint(pathQuery, method) {
|
|
45
|
+
const conditions = ["path = ?"];
|
|
46
|
+
const params = [pathQuery];
|
|
47
|
+
if (method) {
|
|
48
|
+
conditions.push("method = ?");
|
|
49
|
+
params.push(method.toUpperCase());
|
|
50
|
+
}
|
|
51
|
+
let rows = this.getDB().prepare(`SELECT method, path, tag, summary, auth_required, request_schema, response_schema, source, updated_at
|
|
52
|
+
FROM api_endpoints WHERE ${conditions.join(" AND ")}`).all(...params);
|
|
53
|
+
if (rows.length === 0) {
|
|
54
|
+
// Fallback: substring match when exact path not found.
|
|
55
|
+
rows = this.getDB().prepare(`SELECT method, path, tag, summary, auth_required, request_schema, response_schema, source, updated_at
|
|
56
|
+
FROM api_endpoints WHERE path LIKE ?${method ? " AND method = ?" : ""}`).all(`%${pathQuery}%`, ...(method ? [method.toUpperCase()] : []));
|
|
57
|
+
}
|
|
58
|
+
return rows.map((r) => this.rowToApiEndpoint(r));
|
|
59
|
+
}
|
|
60
|
+
static deleteApiEndpoint(method, path) {
|
|
61
|
+
return this.getDB().prepare("DELETE FROM api_endpoints WHERE method = ? AND path = ?")
|
|
62
|
+
.run(method.toUpperCase(), path).changes > 0;
|
|
63
|
+
}
|
|
64
|
+
/** Replace the whole catalog with a fresh scan; returns upserted/deleted counts. */
|
|
65
|
+
static replaceApiCatalog(endpoints) {
|
|
66
|
+
const db = this.getDB();
|
|
67
|
+
const tx = db.transaction(() => {
|
|
68
|
+
const keys = new Set(endpoints.map((e) => `${e.method.toUpperCase()} ${e.path}`));
|
|
69
|
+
const existing = db.prepare("SELECT method, path FROM api_endpoints").all();
|
|
70
|
+
let deleted = 0;
|
|
71
|
+
for (const row of existing) {
|
|
72
|
+
if (!keys.has(`${row.method} ${row.path}`)) {
|
|
73
|
+
deleted += db.prepare("DELETE FROM api_endpoints WHERE method = ? AND path = ?").run(row.method, row.path).changes;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for (const e of endpoints)
|
|
77
|
+
this.saveApiEndpoint(e);
|
|
78
|
+
return { upserted: endpoints.length, deleted };
|
|
79
|
+
});
|
|
80
|
+
return tx();
|
|
81
|
+
}
|
|
82
|
+
static rowToApiEndpoint(r) {
|
|
83
|
+
return {
|
|
84
|
+
method: String(r.method),
|
|
85
|
+
path: String(r.path),
|
|
86
|
+
tag: r.tag ?? undefined,
|
|
87
|
+
summary: r.summary ?? undefined,
|
|
88
|
+
authRequired: Number(r.auth_required) === 1,
|
|
89
|
+
requestSchema: r.request_schema ?? undefined,
|
|
90
|
+
responseSchema: r.response_schema ?? undefined,
|
|
91
|
+
source: r.source ?? undefined,
|
|
92
|
+
updatedAt: String(r.updated_at),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=api-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-catalog.js","sourceRoot":"","sources":["../../../src/modules/storage/api-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-in-the-Loop approval requests and decisions.
|
|
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 { StorageCooldowns } from "./cooldowns.js";
|
|
8
|
+
export declare class StorageApprovals extends StorageCooldowns {
|
|
9
|
+
static saveApproval(app: {
|
|
10
|
+
traceId: string;
|
|
11
|
+
toolName: string;
|
|
12
|
+
agent: string;
|
|
13
|
+
riskScore: number;
|
|
14
|
+
riskLevel: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
args: Record<string, unknown>;
|
|
17
|
+
createdAt: number;
|
|
18
|
+
expiresAt: number;
|
|
19
|
+
status?: "PENDING" | "APPROVED" | "REJECTED" | "EXPIRED";
|
|
20
|
+
passcode?: string;
|
|
21
|
+
}): void;
|
|
22
|
+
static saveApprovalRequest(request: {
|
|
23
|
+
traceId: string;
|
|
24
|
+
toolName: string;
|
|
25
|
+
agent: string;
|
|
26
|
+
riskScore: number;
|
|
27
|
+
riskLevel: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
args: Record<string, unknown>;
|
|
30
|
+
createdAt: number;
|
|
31
|
+
expiresAt: number;
|
|
32
|
+
status?: "PENDING" | "APPROVED" | "REJECTED" | "EXPIRED";
|
|
33
|
+
passcode?: string;
|
|
34
|
+
}): void;
|
|
35
|
+
static getApproval(traceId: string): {
|
|
36
|
+
traceId: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
agent: string;
|
|
39
|
+
riskScore: number;
|
|
40
|
+
riskLevel: string;
|
|
41
|
+
reason: string;
|
|
42
|
+
args: Record<string, unknown>;
|
|
43
|
+
createdAt: number;
|
|
44
|
+
expiresAt: number;
|
|
45
|
+
status: "PENDING" | "APPROVED" | "REJECTED" | "EXPIRED";
|
|
46
|
+
passcode?: string;
|
|
47
|
+
} | null;
|
|
48
|
+
static getPendingApprovals(): Array<{
|
|
49
|
+
traceId: string;
|
|
50
|
+
toolName: string;
|
|
51
|
+
agent: string;
|
|
52
|
+
riskScore: number;
|
|
53
|
+
riskLevel: string;
|
|
54
|
+
reason: string;
|
|
55
|
+
args: Record<string, unknown>;
|
|
56
|
+
createdAt: number;
|
|
57
|
+
expiresAt: number;
|
|
58
|
+
status: "PENDING" | "APPROVED" | "REJECTED" | "EXPIRED";
|
|
59
|
+
passcode?: string;
|
|
60
|
+
}>;
|
|
61
|
+
static updateApprovalStatus(traceId: string, status: string): void;
|
|
62
|
+
static clearAllApprovals(): void;
|
|
63
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-in-the-Loop approval requests and decisions.
|
|
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 { StorageCooldowns } from "./cooldowns.js";
|
|
9
|
+
export class StorageApprovals extends StorageCooldowns {
|
|
10
|
+
static saveApproval(app) {
|
|
11
|
+
this.saveApprovalRequest(app);
|
|
12
|
+
}
|
|
13
|
+
static saveApprovalRequest(request) {
|
|
14
|
+
const db = this.getDB();
|
|
15
|
+
db.prepare(`
|
|
16
|
+
INSERT OR REPLACE INTO approvals (
|
|
17
|
+
trace_id, tool_name, agent, risk_score, risk_level, reason, args,
|
|
18
|
+
created_at, expires_at, status, passcode
|
|
19
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
20
|
+
`).run(request.traceId, request.toolName, request.agent, request.riskScore, request.riskLevel, request.reason, JSON.stringify(request.args), request.createdAt, request.expiresAt, request.status || "PENDING", request.passcode || null);
|
|
21
|
+
}
|
|
22
|
+
static getApproval(traceId) {
|
|
23
|
+
try {
|
|
24
|
+
const row = this.getDB().prepare("SELECT * FROM approvals WHERE trace_id = ?").get(traceId);
|
|
25
|
+
if (!row)
|
|
26
|
+
return null;
|
|
27
|
+
return {
|
|
28
|
+
traceId: row.trace_id,
|
|
29
|
+
toolName: row.tool_name,
|
|
30
|
+
agent: row.agent,
|
|
31
|
+
riskScore: row.risk_score,
|
|
32
|
+
riskLevel: row.risk_level,
|
|
33
|
+
reason: row.reason,
|
|
34
|
+
args: JSON.parse(row.args || "{}"),
|
|
35
|
+
createdAt: row.created_at,
|
|
36
|
+
expiresAt: row.expires_at,
|
|
37
|
+
status: row.status,
|
|
38
|
+
passcode: row.passcode || undefined
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
logger.debug(`Failed to get approval: ${err.message}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
static getPendingApprovals() {
|
|
47
|
+
try {
|
|
48
|
+
const rows = this.getDB().prepare("SELECT * FROM approvals WHERE status = 'PENDING'").all();
|
|
49
|
+
return rows.map(row => ({
|
|
50
|
+
traceId: row.trace_id,
|
|
51
|
+
toolName: row.tool_name,
|
|
52
|
+
agent: row.agent,
|
|
53
|
+
riskScore: row.risk_score,
|
|
54
|
+
riskLevel: row.risk_level,
|
|
55
|
+
reason: row.reason,
|
|
56
|
+
args: JSON.parse(row.args || "{}"),
|
|
57
|
+
createdAt: row.created_at,
|
|
58
|
+
expiresAt: row.expires_at,
|
|
59
|
+
status: row.status,
|
|
60
|
+
passcode: row.passcode || undefined
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
logger.debug(`Failed to get pending approvals: ${err.message}`);
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
static updateApprovalStatus(traceId, status) {
|
|
69
|
+
this.getDB().prepare("UPDATE approvals SET status = ? WHERE trace_id = ?").run(status, traceId);
|
|
70
|
+
}
|
|
71
|
+
static clearAllApprovals() {
|
|
72
|
+
try {
|
|
73
|
+
this.getDB().prepare("DELETE FROM approvals").run();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
logger.debug(`Failed to clear approvals: ${err.message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../src/modules/storage/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
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 Database from "better-sqlite3";
|
|
8
|
+
export declare class StorageBase {
|
|
9
|
+
private static db;
|
|
10
|
+
static getDB(): Database.Database;
|
|
11
|
+
private static initializeSchema;
|
|
12
|
+
static reset(): void;
|
|
13
|
+
}
|
|
@@ -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
|
+
}
|