v2: make v2 the main entry point, move v1 to src/v1/

- Move all v1 files (index, router, container-runner, db, ipc, types,
  logger, channels/registry, and all utilities) to src/v1/ as a
  fully self-contained archive with no shared dependencies
- Rename v2 files to remove -v2 suffix (index-v2.ts → index.ts, etc.)
- Update all imports across v2 source, tests, and setup files
- Migrate shared utilities (config, env, container-runtime, mount-security,
  timezone, group-folder) from pino logger to v2 log module
- Migrate setup/ files from logger to log with argument order swap
- Container agent-runner: move v1 entry to v1/, rename v2 to index.ts
- Update setup skill to offer all 13 v2 channels
- Install all Chat SDK adapter packages
- dist/index.js now runs v2; dist/v1/index.js runs v1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-04-09 11:40:36 +03:00
parent 12af451069
commit 9486d56b01
96 changed files with 7904 additions and 3040 deletions

View File

@@ -31,9 +31,9 @@ export class SqliteStateAdapter implements StateAdapter {
async get<T = unknown>(key: string): Promise<T | null> {
this.cleanup();
const row = this.db
.prepare('SELECT value, expires_at FROM chat_sdk_kv WHERE key = ?')
.get(key) as { value: string; expires_at: number | null } | undefined;
const row = this.db.prepare('SELECT value, expires_at FROM chat_sdk_kv WHERE key = ?').get(key) as
| { value: string; expires_at: number | null }
| undefined;
if (!row) return null;
if (row.expires_at && row.expires_at < Date.now()) {
this.db.prepare('DELETE FROM chat_sdk_kv WHERE key = ?').run(key);
@@ -44,16 +44,22 @@ export class SqliteStateAdapter implements StateAdapter {
async set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void> {
const expiresAt = ttlMs ? Date.now() + ttlMs : null;
this.db.prepare('INSERT OR REPLACE INTO chat_sdk_kv (key, value, expires_at) VALUES (?, ?, ?)').run(key, JSON.stringify(value), expiresAt);
this.db
.prepare('INSERT OR REPLACE INTO chat_sdk_kv (key, value, expires_at) VALUES (?, ?, ?)')
.run(key, JSON.stringify(value), expiresAt);
}
async setIfNotExists(key: string, value: unknown, ttlMs?: number): Promise<boolean> {
const existing = this.db.prepare('SELECT expires_at FROM chat_sdk_kv WHERE key = ?').get(key) as { expires_at: number | null } | undefined;
const existing = this.db.prepare('SELECT expires_at FROM chat_sdk_kv WHERE key = ?').get(key) as
| { expires_at: number | null }
| undefined;
if (existing?.expires_at && existing.expires_at < Date.now()) {
this.db.prepare('DELETE FROM chat_sdk_kv WHERE key = ?').run(key);
}
const expiresAt = ttlMs ? Date.now() + ttlMs : null;
const result = this.db.prepare('INSERT OR IGNORE INTO chat_sdk_kv (key, value, expires_at) VALUES (?, ?, ?)').run(key, JSON.stringify(value), expiresAt);
const result = this.db
.prepare('INSERT OR IGNORE INTO chat_sdk_kv (key, value, expires_at) VALUES (?, ?, ?)')
.run(key, JSON.stringify(value), expiresAt);
return result.changes > 0;
}
@@ -83,7 +89,9 @@ export class SqliteStateAdapter implements StateAdapter {
const token = crypto.randomUUID();
const expiresAt = now + ttlMs;
this.db.prepare('DELETE FROM chat_sdk_locks WHERE thread_id = ? AND expires_at < ?').run(threadId, now);
const result = this.db.prepare('INSERT OR IGNORE INTO chat_sdk_locks (thread_id, token, expires_at) VALUES (?, ?, ?)').run(threadId, token, expiresAt);
const result = this.db
.prepare('INSERT OR IGNORE INTO chat_sdk_locks (thread_id, token, expires_at) VALUES (?, ?, ?)')
.run(threadId, token, expiresAt);
if (result.changes === 0) return null;
return { threadId, token, expiresAt };
}
@@ -94,7 +102,9 @@ export class SqliteStateAdapter implements StateAdapter {
async extendLock(lock: Lock, ttlMs: number): Promise<boolean> {
const newExpiry = Date.now() + ttlMs;
const result = this.db.prepare('UPDATE chat_sdk_locks SET expires_at = ? WHERE thread_id = ? AND token = ?').run(newExpiry, lock.threadId, lock.token);
const result = this.db
.prepare('UPDATE chat_sdk_locks SET expires_at = ? WHERE thread_id = ? AND token = ?')
.run(newExpiry, lock.threadId, lock.token);
if (result.changes > 0) {
lock.expiresAt = newExpiry;
return true;
@@ -110,9 +120,13 @@ export class SqliteStateAdapter implements StateAdapter {
async appendToList(key: string, value: unknown, options?: { maxLength?: number; ttlMs?: number }): Promise<void> {
const expiresAt = options?.ttlMs ? Date.now() + options.ttlMs : null;
const maxRow = this.db.prepare('SELECT MAX(idx) as maxIdx FROM chat_sdk_lists WHERE key = ?').get(key) as { maxIdx: number | null } | undefined;
const maxRow = this.db.prepare('SELECT MAX(idx) as maxIdx FROM chat_sdk_lists WHERE key = ?').get(key) as
| { maxIdx: number | null }
| undefined;
const nextIdx = (maxRow?.maxIdx ?? -1) + 1;
this.db.prepare('INSERT INTO chat_sdk_lists (key, idx, value, expires_at) VALUES (?, ?, ?, ?)').run(key, nextIdx, JSON.stringify(value), expiresAt);
this.db
.prepare('INSERT INTO chat_sdk_lists (key, idx, value, expires_at) VALUES (?, ?, ?, ?)')
.run(key, nextIdx, JSON.stringify(value), expiresAt);
if (options?.maxLength) {
const cutoff = nextIdx - options.maxLength;
if (cutoff >= 0) {
@@ -123,7 +137,11 @@ export class SqliteStateAdapter implements StateAdapter {
async getList<T = unknown>(key: string): Promise<T[]> {
const now = Date.now();
const rows = this.db.prepare('SELECT value FROM chat_sdk_lists WHERE key = ? AND (expires_at IS NULL OR expires_at > ?) ORDER BY idx ASC').all(key, now) as { value: string }[];
const rows = this.db
.prepare(
'SELECT value FROM chat_sdk_lists WHERE key = ? AND (expires_at IS NULL OR expires_at > ?) ORDER BY idx ASC',
)
.all(key, now) as { value: string }[];
return rows.map((r) => JSON.parse(r.value) as T);
}
@@ -137,7 +155,9 @@ export class SqliteStateAdapter implements StateAdapter {
async dequeue(threadId: string): Promise<QueueEntry | null> {
const key = `queue:${threadId}`;
const row = this.db.prepare('SELECT idx, value FROM chat_sdk_lists WHERE key = ? ORDER BY idx ASC LIMIT 1').get(key) as { idx: number; value: string } | undefined;
const row = this.db
.prepare('SELECT idx, value FROM chat_sdk_lists WHERE key = ? ORDER BY idx ASC LIMIT 1')
.get(key) as { idx: number; value: string } | undefined;
if (!row) return null;
this.db.prepare('DELETE FROM chat_sdk_lists WHERE key = ? AND idx = ?').run(key, row.idx);
return JSON.parse(row.value) as QueueEntry;
@@ -145,7 +165,9 @@ export class SqliteStateAdapter implements StateAdapter {
async queueDepth(threadId: string): Promise<number> {
const key = `queue:${threadId}`;
const row = this.db.prepare('SELECT COUNT(*) as count FROM chat_sdk_lists WHERE key = ?').get(key) as { count: number };
const row = this.db.prepare('SELECT COUNT(*) as count FROM chat_sdk_lists WHERE key = ?').get(key) as {
count: number;
};
return row.count;
}