247-cli 2.23.2 → 2.23.4
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/agent/dist/db/index.d.ts +0 -1
- package/agent/dist/db/index.d.ts.map +1 -1
- package/agent/dist/db/index.js +85 -382
- package/agent/dist/db/index.js.map +1 -1
- package/agent/dist/db/schema.d.ts +3 -49
- package/agent/dist/db/schema.d.ts.map +1 -1
- package/agent/dist/db/schema.js +34 -44
- package/agent/dist/db/schema.js.map +1 -1
- package/agent/dist/db/sessions.d.ts +2 -52
- package/agent/dist/db/sessions.d.ts.map +1 -1
- package/agent/dist/db/sessions.js +8 -194
- package/agent/dist/db/sessions.js.map +1 -1
- package/agent/dist/routes/index.d.ts +0 -1
- package/agent/dist/routes/index.d.ts.map +1 -1
- package/agent/dist/routes/index.js +0 -1
- package/agent/dist/routes/index.js.map +1 -1
- package/agent/dist/routes/sessions.d.ts +1 -0
- package/agent/dist/routes/sessions.d.ts.map +1 -1
- package/agent/dist/routes/sessions.js +16 -375
- package/agent/dist/routes/sessions.js.map +1 -1
- package/agent/dist/server.d.ts.map +1 -1
- package/agent/dist/server.js +22 -17
- package/agent/dist/server.js.map +1 -1
- package/agent/dist/services/index.d.ts +1 -6
- package/agent/dist/services/index.d.ts.map +1 -1
- package/agent/dist/services/index.js +4 -4
- package/agent/dist/services/index.js.map +1 -1
- package/agent/dist/terminal.d.ts +0 -11
- package/agent/dist/terminal.d.ts.map +1 -1
- package/agent/dist/terminal.js +6 -60
- package/agent/dist/terminal.js.map +1 -1
- package/agent/dist/updater.d.ts +1 -2
- package/agent/dist/updater.d.ts.map +1 -1
- package/agent/dist/updater.js +3 -25
- package/agent/dist/updater.js.map +1 -1
- package/agent/dist/websocket-handlers.d.ts +17 -3
- package/agent/dist/websocket-handlers.d.ts.map +1 -1
- package/agent/dist/websocket-handlers.js +81 -127
- package/agent/dist/websocket-handlers.js.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.d.ts +1 -111
- package/agent/node_modules/247-shared/dist/types/index.d.ts.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.js +1 -47
- package/agent/node_modules/247-shared/dist/types/index.js.map +1 -1
- package/agent/node_modules/247-shared/package.json +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +5 -23
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +0 -11
- package/dist/commands/status.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/paths.d.ts +1 -3
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +1 -2
- package/dist/lib/paths.js.map +1 -1
- package/package.json +1 -1
- package/agent/dist/db/history.d.ts +0 -37
- package/agent/dist/db/history.d.ts.map +0 -1
- package/agent/dist/db/history.js +0 -98
- package/agent/dist/db/history.js.map +0 -1
- package/agent/dist/routes/attention.d.ts +0 -10
- package/agent/dist/routes/attention.d.ts.map +0 -1
- package/agent/dist/routes/attention.js +0 -123
- package/agent/dist/routes/attention.js.map +0 -1
- package/agent/dist/services/cleanup.d.ts +0 -45
- package/agent/dist/services/cleanup.d.ts.map +0 -1
- package/agent/dist/services/cleanup.js +0 -130
- package/agent/dist/services/cleanup.js.map +0 -1
- package/agent/dist/services/execution.d.ts +0 -53
- package/agent/dist/services/execution.d.ts.map +0 -1
- package/agent/dist/services/execution.js +0 -75
- package/agent/dist/services/execution.js.map +0 -1
- package/agent/dist/services/worktree.d.ts +0 -41
- package/agent/dist/services/worktree.d.ts.map +0 -1
- package/agent/dist/services/worktree.js +0 -139
- package/agent/dist/services/worktree.js.map +0 -1
- package/agent/dist/setup-hooks.d.ts +0 -10
- package/agent/dist/setup-hooks.d.ts.map +0 -1
- package/agent/dist/setup-hooks.js +0 -157
- package/agent/dist/setup-hooks.js.map +0 -1
- package/agent/dist/status.d.ts +0 -51
- package/agent/dist/status.d.ts.map +0 -1
- package/agent/dist/status.js +0 -142
- package/agent/dist/status.js.map +0 -1
- package/dist/commands/hooks.d.ts +0 -3
- package/dist/commands/hooks.d.ts.map +0 -1
- package/dist/commands/hooks.js +0 -85
- package/dist/commands/hooks.js.map +0 -1
- package/dist/hooks/installer.d.ts +0 -21
- package/dist/hooks/installer.d.ts.map +0 -1
- package/dist/hooks/installer.js +0 -114
- package/dist/hooks/installer.js.map +0 -1
package/agent/dist/db/schema.js
CHANGED
|
@@ -1,61 +1,26 @@
|
|
|
1
1
|
// ============================================================================
|
|
2
|
-
//
|
|
2
|
+
// Database Row Types (Simplified - No Status Tracking)
|
|
3
3
|
// ============================================================================
|
|
4
|
-
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// SQL Schema Definitions (v16 - Status Removed)
|
|
6
|
+
// ============================================================================
|
|
7
|
+
export const SCHEMA_VERSION = 16;
|
|
5
8
|
export const CREATE_TABLES_SQL = `
|
|
6
|
-
-- Sessions: current state of terminal sessions
|
|
9
|
+
-- Sessions: current state of terminal sessions (simplified - no status tracking)
|
|
7
10
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
8
11
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
9
12
|
name TEXT NOT NULL UNIQUE,
|
|
10
13
|
project TEXT NOT NULL,
|
|
11
|
-
status TEXT NOT NULL DEFAULT 'init',
|
|
12
|
-
attention_reason TEXT,
|
|
13
14
|
last_event TEXT,
|
|
14
15
|
last_activity INTEGER NOT NULL,
|
|
15
|
-
last_status_change INTEGER NOT NULL,
|
|
16
|
-
environment_id TEXT,
|
|
17
16
|
archived_at INTEGER,
|
|
18
17
|
created_at INTEGER NOT NULL,
|
|
19
|
-
updated_at INTEGER NOT NULL
|
|
20
|
-
-- StatusLine metrics (v4)
|
|
21
|
-
model TEXT,
|
|
22
|
-
cost_usd REAL,
|
|
23
|
-
context_usage INTEGER,
|
|
24
|
-
lines_added INTEGER,
|
|
25
|
-
lines_removed INTEGER,
|
|
26
|
-
-- Worktree isolation (v6)
|
|
27
|
-
worktree_path TEXT,
|
|
28
|
-
branch_name TEXT,
|
|
29
|
-
-- Spawn/orchestration fields (v9)
|
|
30
|
-
spawn_prompt TEXT,
|
|
31
|
-
parent_session TEXT,
|
|
32
|
-
task_id TEXT,
|
|
33
|
-
exit_code INTEGER,
|
|
34
|
-
exited_at INTEGER,
|
|
35
|
-
-- Output capture (v10)
|
|
36
|
-
output_content TEXT,
|
|
37
|
-
output_captured_at INTEGER
|
|
18
|
+
updated_at INTEGER NOT NULL
|
|
38
19
|
);
|
|
39
20
|
|
|
40
21
|
CREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);
|
|
41
22
|
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);
|
|
42
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
43
23
|
CREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);
|
|
44
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session);
|
|
45
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_task ON sessions(task_id);
|
|
46
|
-
|
|
47
|
-
-- Status history: audit trail of status changes
|
|
48
|
-
CREATE TABLE IF NOT EXISTS status_history (
|
|
49
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
50
|
-
session_name TEXT NOT NULL,
|
|
51
|
-
status TEXT NOT NULL,
|
|
52
|
-
attention_reason TEXT,
|
|
53
|
-
event TEXT,
|
|
54
|
-
timestamp INTEGER NOT NULL
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
CREATE INDEX IF NOT EXISTS idx_history_session ON status_history(session_name);
|
|
58
|
-
CREATE INDEX IF NOT EXISTS idx_history_timestamp ON status_history(timestamp);
|
|
59
24
|
|
|
60
25
|
-- Schema version tracking
|
|
61
26
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
@@ -64,6 +29,33 @@ CREATE TABLE IF NOT EXISTS schema_version (
|
|
|
64
29
|
);
|
|
65
30
|
`;
|
|
66
31
|
// ============================================================================
|
|
32
|
+
// Migration for v16 (Remove status tracking)
|
|
33
|
+
// ============================================================================
|
|
34
|
+
export const MIGRATION_16 = `
|
|
35
|
+
-- Migration v16: Remove status tracking columns
|
|
36
|
+
CREATE TABLE IF NOT EXISTS sessions_new (
|
|
37
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
|
+
name TEXT NOT NULL UNIQUE,
|
|
39
|
+
project TEXT NOT NULL,
|
|
40
|
+
last_event TEXT,
|
|
41
|
+
last_activity INTEGER NOT NULL,
|
|
42
|
+
archived_at INTEGER,
|
|
43
|
+
created_at INTEGER NOT NULL,
|
|
44
|
+
updated_at INTEGER NOT NULL
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
INSERT OR IGNORE INTO sessions_new (id, name, project, last_event, last_activity, archived_at, created_at, updated_at)
|
|
48
|
+
SELECT id, name, project, last_event, last_activity, archived_at, created_at, updated_at
|
|
49
|
+
FROM sessions;
|
|
50
|
+
|
|
51
|
+
DROP TABLE IF EXISTS sessions;
|
|
52
|
+
ALTER TABLE sessions_new RENAME TO sessions;
|
|
53
|
+
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);
|
|
55
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);
|
|
57
|
+
`;
|
|
58
|
+
// ============================================================================
|
|
67
59
|
// Retention Configuration
|
|
68
60
|
// ============================================================================
|
|
69
61
|
export const RETENTION_CONFIG = {
|
|
@@ -71,8 +63,6 @@ export const RETENTION_CONFIG = {
|
|
|
71
63
|
sessionMaxAge: 24 * 60 * 60 * 1000,
|
|
72
64
|
/** Max age for archived sessions before cleanup (30 days) */
|
|
73
65
|
archivedMaxAge: 30 * 24 * 60 * 60 * 1000,
|
|
74
|
-
/** Max age for status history (7 days) */
|
|
75
|
-
historyMaxAge: 7 * 24 * 60 * 60 * 1000,
|
|
76
66
|
/** Cleanup interval (1 hour) */
|
|
77
67
|
cleanupInterval: 60 * 60 * 1000,
|
|
78
68
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,uDAAuD;AACvD,+EAA+E;AA4B/E,+EAA+E;AAC/E,gDAAgD;AAChD,+EAA+E;AAE/E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBhC,CAAC;AAEF,+EAA+E;AAC/E,6CAA6C;AAC7C,+EAA+E;AAE/E,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuB3B,CAAC;AAEF,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,qDAAqD;IACrD,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IAClC,6DAA6D;IAC7D,cAAc,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IACxC,gCAAgC;IAChC,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;CAChC,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { DbSession, UpsertSessionInput } from './schema.js';
|
|
2
|
-
import type { SessionStatus, AttentionReason } from '247-shared';
|
|
3
2
|
/**
|
|
4
3
|
* Get a session by name
|
|
5
4
|
*/
|
|
@@ -18,13 +17,8 @@ export declare function getArchivedSessions(): DbSession[];
|
|
|
18
17
|
export declare function getSessionsByProject(project: string): DbSession[];
|
|
19
18
|
/**
|
|
20
19
|
* Upsert a session (insert or update)
|
|
21
|
-
* Records status history if status changed
|
|
22
20
|
*/
|
|
23
21
|
export declare function upsertSession(name: string, input: UpsertSessionInput): DbSession;
|
|
24
|
-
/**
|
|
25
|
-
* Update session status only
|
|
26
|
-
*/
|
|
27
|
-
export declare function updateSessionStatus(name: string, status: SessionStatus, attentionReason?: AttentionReason | null, lastEvent?: string | null): boolean;
|
|
28
22
|
/**
|
|
29
23
|
* Delete a session
|
|
30
24
|
*/
|
|
@@ -43,53 +37,9 @@ export declare function archiveSession(name: string): DbSession | null;
|
|
|
43
37
|
export declare function cleanupStaleSessions(maxAge: number, archivedMaxAge?: number): number;
|
|
44
38
|
/**
|
|
45
39
|
* Reconcile sessions with active tmux sessions
|
|
46
|
-
* - Sessions in DB but not in tmux:
|
|
47
|
-
* - Sessions in tmux but not in DB:
|
|
40
|
+
* - Sessions in DB but not in tmux: delete if old
|
|
41
|
+
* - Sessions in tmux but not in DB: will be created when they connect
|
|
48
42
|
* - Archived sessions are skipped (they don't have tmux sessions)
|
|
49
43
|
*/
|
|
50
44
|
export declare function reconcileWithTmux(activeTmuxSessions: Set<string>): void;
|
|
51
|
-
/**
|
|
52
|
-
* Get session environment mapping
|
|
53
|
-
*/
|
|
54
|
-
export declare function getSessionEnvironmentId(sessionName: string): string | null;
|
|
55
|
-
/**
|
|
56
|
-
* Set session environment mapping
|
|
57
|
-
*/
|
|
58
|
-
export declare function setSessionEnvironmentId(sessionName: string, environmentId: string): void;
|
|
59
|
-
/**
|
|
60
|
-
* Clear session environment mapping
|
|
61
|
-
*/
|
|
62
|
-
export declare function clearSessionEnvironmentId(sessionName: string): void;
|
|
63
|
-
/**
|
|
64
|
-
* Convert DbSession to HookStatus format (for compatibility with existing code)
|
|
65
|
-
*/
|
|
66
|
-
export declare function toHookStatus(session: DbSession): {
|
|
67
|
-
status: SessionStatus;
|
|
68
|
-
attentionReason?: AttentionReason;
|
|
69
|
-
lastEvent: string;
|
|
70
|
-
lastActivity: number;
|
|
71
|
-
lastStatusChange: number;
|
|
72
|
-
project?: string;
|
|
73
|
-
archivedAt?: number;
|
|
74
|
-
model?: string;
|
|
75
|
-
costUsd?: number;
|
|
76
|
-
contextUsage?: number;
|
|
77
|
-
linesAdded?: number;
|
|
78
|
-
linesRemoved?: number;
|
|
79
|
-
worktreePath?: string;
|
|
80
|
-
branchName?: string;
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Update worktree info for a session
|
|
84
|
-
*/
|
|
85
|
-
export declare function updateSessionWorktree(name: string, worktreePath: string, branchName: string): boolean;
|
|
86
|
-
/**
|
|
87
|
-
* Clear worktree info for a session (after cleanup)
|
|
88
|
-
*/
|
|
89
|
-
export declare function clearSessionWorktree(name: string): boolean;
|
|
90
|
-
/**
|
|
91
|
-
* Get sessions with worktrees that can be cleaned up
|
|
92
|
-
* (archived and last activity older than maxAge)
|
|
93
|
-
*/
|
|
94
|
-
export declare function getCleanableWorktreeSessions(maxAgeMs: number): DbSession[];
|
|
95
45
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMzD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAK5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAKjD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAKjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,SAAS,CA+BhF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAInD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAyB7D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CA4BpF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAyBvE"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getDatabase } from './index.js';
|
|
2
|
-
import { recordStatusChange } from './history.js';
|
|
3
2
|
/**
|
|
4
3
|
* Get a session by name
|
|
5
4
|
*/
|
|
@@ -37,114 +36,35 @@ export function getSessionsByProject(project) {
|
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
38
|
* Upsert a session (insert or update)
|
|
40
|
-
* Records status history if status changed
|
|
41
39
|
*/
|
|
42
40
|
export function upsertSession(name, input) {
|
|
43
41
|
const db = getDatabase();
|
|
44
42
|
const now = Date.now();
|
|
45
|
-
// Check existing session for status change detection
|
|
46
43
|
const existing = getSession(name);
|
|
47
|
-
const statusChanged = !existing || existing.status !== input.status;
|
|
48
44
|
const stmt = db.prepare(`
|
|
49
45
|
INSERT INTO sessions (
|
|
50
|
-
name, project,
|
|
51
|
-
last_activity,
|
|
52
|
-
model, cost_usd, context_usage, lines_added, lines_removed,
|
|
53
|
-
worktree_path, branch_name,
|
|
54
|
-
spawn_prompt, parent_session, task_id, exit_code, exited_at,
|
|
55
|
-
output_content, output_captured_at
|
|
46
|
+
name, project, last_event,
|
|
47
|
+
last_activity, created_at, updated_at
|
|
56
48
|
)
|
|
57
49
|
VALUES (
|
|
58
|
-
@name, @project, @
|
|
59
|
-
@lastActivity, @
|
|
60
|
-
@model, @costUsd, @contextUsage, @linesAdded, @linesRemoved,
|
|
61
|
-
@worktreePath, @branchName,
|
|
62
|
-
@spawnPrompt, @parentSession, @taskId, @exitCode, @exitedAt,
|
|
63
|
-
@outputContent, @outputCapturedAt
|
|
50
|
+
@name, @project, @lastEvent,
|
|
51
|
+
@lastActivity, @createdAt, @updatedAt
|
|
64
52
|
)
|
|
65
53
|
ON CONFLICT(name) DO UPDATE SET
|
|
66
|
-
status = COALESCE(@status, status),
|
|
67
|
-
attention_reason = @attentionReason,
|
|
68
54
|
last_event = COALESCE(@lastEvent, last_event),
|
|
69
55
|
last_activity = COALESCE(@lastActivity, last_activity),
|
|
70
|
-
|
|
71
|
-
environment_id = COALESCE(@environmentId, environment_id),
|
|
72
|
-
updated_at = @updatedAt,
|
|
73
|
-
model = COALESCE(@model, model),
|
|
74
|
-
cost_usd = COALESCE(@costUsd, cost_usd),
|
|
75
|
-
context_usage = COALESCE(@contextUsage, context_usage),
|
|
76
|
-
lines_added = COALESCE(@linesAdded, lines_added),
|
|
77
|
-
lines_removed = COALESCE(@linesRemoved, lines_removed),
|
|
78
|
-
worktree_path = COALESCE(@worktreePath, worktree_path),
|
|
79
|
-
branch_name = COALESCE(@branchName, branch_name),
|
|
80
|
-
spawn_prompt = COALESCE(@spawnPrompt, spawn_prompt),
|
|
81
|
-
parent_session = COALESCE(@parentSession, parent_session),
|
|
82
|
-
task_id = COALESCE(@taskId, task_id),
|
|
83
|
-
exit_code = COALESCE(@exitCode, exit_code),
|
|
84
|
-
exited_at = COALESCE(@exitedAt, exited_at),
|
|
85
|
-
output_content = COALESCE(@outputContent, output_content),
|
|
86
|
-
output_captured_at = COALESCE(@outputCapturedAt, output_captured_at)
|
|
56
|
+
updated_at = @updatedAt
|
|
87
57
|
`);
|
|
88
58
|
stmt.run({
|
|
89
59
|
name,
|
|
90
60
|
project: input.project ?? existing?.project ?? 'unknown',
|
|
91
|
-
status: input.status ?? existing?.status ?? 'init',
|
|
92
|
-
attentionReason: input.attentionReason ?? null,
|
|
93
61
|
lastEvent: input.lastEvent ?? null,
|
|
94
62
|
lastActivity: input.lastActivity ?? now,
|
|
95
|
-
lastStatusChange: statusChanged ? now : (existing?.last_status_change ?? now),
|
|
96
|
-
environmentId: input.environmentId ?? null,
|
|
97
63
|
createdAt: existing?.created_at ?? now,
|
|
98
64
|
updatedAt: now,
|
|
99
|
-
model: input.model ?? null,
|
|
100
|
-
costUsd: input.costUsd ?? null,
|
|
101
|
-
contextUsage: input.contextUsage ?? null,
|
|
102
|
-
linesAdded: input.linesAdded ?? null,
|
|
103
|
-
linesRemoved: input.linesRemoved ?? null,
|
|
104
|
-
worktreePath: input.worktreePath ?? null,
|
|
105
|
-
branchName: input.branchName ?? null,
|
|
106
|
-
spawnPrompt: input.spawn_prompt ?? null,
|
|
107
|
-
parentSession: input.parent_session ?? null,
|
|
108
|
-
taskId: input.task_id ?? null,
|
|
109
|
-
exitCode: input.exit_code ?? null,
|
|
110
|
-
exitedAt: input.exited_at ?? null,
|
|
111
|
-
outputContent: input.output_content ?? null,
|
|
112
|
-
outputCapturedAt: input.output_captured_at ?? null,
|
|
113
65
|
});
|
|
114
|
-
// Record status history if status changed
|
|
115
|
-
if (statusChanged && input.status) {
|
|
116
|
-
recordStatusChange(name, input.status, input.attentionReason ?? null, input.lastEvent ?? null);
|
|
117
|
-
}
|
|
118
66
|
return getSession(name);
|
|
119
67
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Update session status only
|
|
122
|
-
*/
|
|
123
|
-
export function updateSessionStatus(name, status, attentionReason, lastEvent) {
|
|
124
|
-
const db = getDatabase();
|
|
125
|
-
const now = Date.now();
|
|
126
|
-
const existing = getSession(name);
|
|
127
|
-
if (!existing) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
const statusChanged = existing.status !== status;
|
|
131
|
-
const stmt = db.prepare(`
|
|
132
|
-
UPDATE sessions SET
|
|
133
|
-
status = ?,
|
|
134
|
-
attention_reason = ?,
|
|
135
|
-
last_event = COALESCE(?, last_event),
|
|
136
|
-
last_activity = ?,
|
|
137
|
-
last_status_change = ?,
|
|
138
|
-
updated_at = ?
|
|
139
|
-
WHERE name = ?
|
|
140
|
-
`);
|
|
141
|
-
stmt.run(status, attentionReason ?? null, lastEvent, now, statusChanged ? now : existing.last_status_change, now, name);
|
|
142
|
-
// Record status history if status changed
|
|
143
|
-
if (statusChanged) {
|
|
144
|
-
recordStatusChange(name, status, attentionReason ?? null, lastEvent ?? null);
|
|
145
|
-
}
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
68
|
/**
|
|
149
69
|
* Delete a session
|
|
150
70
|
*/
|
|
@@ -207,8 +127,8 @@ export function cleanupStaleSessions(maxAge, archivedMaxAge) {
|
|
|
207
127
|
}
|
|
208
128
|
/**
|
|
209
129
|
* Reconcile sessions with active tmux sessions
|
|
210
|
-
* - Sessions in DB but not in tmux:
|
|
211
|
-
* - Sessions in tmux but not in DB:
|
|
130
|
+
* - Sessions in DB but not in tmux: delete if old
|
|
131
|
+
* - Sessions in tmux but not in DB: will be created when they connect
|
|
212
132
|
* - Archived sessions are skipped (they don't have tmux sessions)
|
|
213
133
|
*/
|
|
214
134
|
export function reconcileWithTmux(activeTmuxSessions) {
|
|
@@ -225,116 +145,10 @@ export function reconcileWithTmux(activeTmuxSessions) {
|
|
|
225
145
|
deleteSession(session.name);
|
|
226
146
|
console.log(`[DB] Deleted stale session: ${session.name}`);
|
|
227
147
|
}
|
|
228
|
-
else if (session.status !== 'idle') {
|
|
229
|
-
// Mark as idle since tmux session is gone
|
|
230
|
-
updateSessionStatus(session.name, 'idle', null, 'session_ended');
|
|
231
|
-
console.log(`[DB] Marked session as idle: ${session.name}`);
|
|
232
|
-
}
|
|
233
148
|
}
|
|
234
149
|
}
|
|
235
150
|
// Handle sessions in tmux but not in DB
|
|
236
|
-
// These will be created when they receive their first
|
|
151
|
+
// These will be created when they receive their first connection
|
|
237
152
|
// We don't create them here because we don't have project info
|
|
238
153
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Get session environment mapping
|
|
241
|
-
*/
|
|
242
|
-
export function getSessionEnvironmentId(sessionName) {
|
|
243
|
-
const db = getDatabase();
|
|
244
|
-
const row = db
|
|
245
|
-
.prepare('SELECT environment_id FROM session_environments WHERE session_name = ?')
|
|
246
|
-
.get(sessionName);
|
|
247
|
-
return row?.environment_id ?? null;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Set session environment mapping
|
|
251
|
-
*/
|
|
252
|
-
export function setSessionEnvironmentId(sessionName, environmentId) {
|
|
253
|
-
const db = getDatabase();
|
|
254
|
-
db.prepare(`
|
|
255
|
-
INSERT OR REPLACE INTO session_environments (session_name, environment_id)
|
|
256
|
-
VALUES (?, ?)
|
|
257
|
-
`).run(sessionName, environmentId);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Clear session environment mapping
|
|
261
|
-
*/
|
|
262
|
-
export function clearSessionEnvironmentId(sessionName) {
|
|
263
|
-
const db = getDatabase();
|
|
264
|
-
db.prepare('DELETE FROM session_environments WHERE session_name = ?').run(sessionName);
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Convert DbSession to HookStatus format (for compatibility with existing code)
|
|
268
|
-
*/
|
|
269
|
-
export function toHookStatus(session) {
|
|
270
|
-
return {
|
|
271
|
-
status: session.status,
|
|
272
|
-
attentionReason: session.attention_reason ?? undefined,
|
|
273
|
-
lastEvent: session.last_event ?? '',
|
|
274
|
-
lastActivity: session.last_activity,
|
|
275
|
-
lastStatusChange: session.last_status_change,
|
|
276
|
-
project: session.project,
|
|
277
|
-
archivedAt: session.archived_at ?? undefined,
|
|
278
|
-
// StatusLine metrics
|
|
279
|
-
model: session.model ?? undefined,
|
|
280
|
-
costUsd: session.cost_usd ?? undefined,
|
|
281
|
-
contextUsage: session.context_usage ?? undefined,
|
|
282
|
-
linesAdded: session.lines_added ?? undefined,
|
|
283
|
-
linesRemoved: session.lines_removed ?? undefined,
|
|
284
|
-
// Worktree isolation
|
|
285
|
-
worktreePath: session.worktree_path ?? undefined,
|
|
286
|
-
branchName: session.branch_name ?? undefined,
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
// ============================================================================
|
|
290
|
-
// Worktree Functions
|
|
291
|
-
// ============================================================================
|
|
292
|
-
/**
|
|
293
|
-
* Update worktree info for a session
|
|
294
|
-
*/
|
|
295
|
-
export function updateSessionWorktree(name, worktreePath, branchName) {
|
|
296
|
-
const db = getDatabase();
|
|
297
|
-
const result = db
|
|
298
|
-
.prepare(`
|
|
299
|
-
UPDATE sessions SET
|
|
300
|
-
worktree_path = ?,
|
|
301
|
-
branch_name = ?,
|
|
302
|
-
updated_at = ?
|
|
303
|
-
WHERE name = ?
|
|
304
|
-
`)
|
|
305
|
-
.run(worktreePath, branchName, Date.now(), name);
|
|
306
|
-
return result.changes > 0;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Clear worktree info for a session (after cleanup)
|
|
310
|
-
*/
|
|
311
|
-
export function clearSessionWorktree(name) {
|
|
312
|
-
const db = getDatabase();
|
|
313
|
-
const result = db
|
|
314
|
-
.prepare(`
|
|
315
|
-
UPDATE sessions SET
|
|
316
|
-
worktree_path = NULL,
|
|
317
|
-
branch_name = NULL,
|
|
318
|
-
updated_at = ?
|
|
319
|
-
WHERE name = ?
|
|
320
|
-
`)
|
|
321
|
-
.run(Date.now(), name);
|
|
322
|
-
return result.changes > 0;
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Get sessions with worktrees that can be cleaned up
|
|
326
|
-
* (archived and last activity older than maxAge)
|
|
327
|
-
*/
|
|
328
|
-
export function getCleanableWorktreeSessions(maxAgeMs) {
|
|
329
|
-
const db = getDatabase();
|
|
330
|
-
const cutoff = Date.now() - maxAgeMs;
|
|
331
|
-
return db
|
|
332
|
-
.prepare(`
|
|
333
|
-
SELECT * FROM sessions
|
|
334
|
-
WHERE worktree_path IS NOT NULL
|
|
335
|
-
AND archived_at IS NOT NULL
|
|
336
|
-
AND last_activity < ?
|
|
337
|
-
`)
|
|
338
|
-
.all(cutoff);
|
|
339
|
-
}
|
|
340
154
|
//# sourceMappingURL=sessions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/db/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,CAAC,IAAI,CAE3D,CAAC;IACd,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,OAAO,EAAE;SACN,OAAO,CAAC,8EAA8E,CAAC;SACvF,GAAG,EAAiB,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,OAAO,EAAE;SACN,OAAO,CAAC,gFAAgF,CAAC;SACzF,GAAG,EAAiB,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,OAAO,EAAE;SACN,OAAO,CAAC,sEAAsE,CAAC;SAC/E,GAAG,CAAC,OAAO,CAAgB,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAyB;IACnE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAElC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;GAavB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC;QACP,IAAI;QACJ,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,IAAI,SAAS;QACxD,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,GAAG;QACvC,SAAS,EAAE,QAAQ,EAAE,UAAU,IAAI,GAAG;QACtC,SAAS,EAAE,GAAG;KACf,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC,IAAI,CAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mBAAmB;IACnB,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,EAAE,CAAC,OAAO,CACR;;;;;GAKD,CACA,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAEtB,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;IAC9C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,cAAuB;IAC1E,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC;IAE5B,qCAAqC;IACrC,MAAM,YAAY,GAAG,EAAE;SACpB,OAAO,CAAC,sEAAsE,CAAC;SAC/E,GAAG,CAAC,MAAM,CAAC,CAAC;IAEf,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,cAAc,GAAG,GAAG,GAAG,cAAc,CAAC;QAC5C,MAAM,cAAc,GAAG,EAAE;aACtB,OAAO,CAAC,wEAAwE,CAAC;aACjF,GAAG,CAAC,cAAc,CAAC,CAAC;QACvB,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,GAAG,eAAe,CAAC;IAE5D,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CACT,mBAAmB,YAAY,CAAC,OAAO,oBAAoB,eAAe,wBAAwB,CACnG,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,kBAA+B;IAC/D,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC,CAAC,kCAAkC;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;IAE/C,OAAO,CAAC,GAAG,CACT,oBAAoB,UAAU,CAAC,MAAM,qBAAqB,kBAAkB,CAAC,IAAI,gBAAgB,CAClG,CAAC;IAEF,kFAAkF;IAClF,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC;YAExC,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC;gBACjB,sBAAsB;gBACtB,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,iEAAiE;IACjE,+DAA+D;AACjE,CAAC"}
|
|
@@ -3,6 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { createProjectRoutes, isProjectAllowed } from './projects.js';
|
|
5
5
|
export { createSessionRoutes } from './sessions.js';
|
|
6
|
-
export { createAttentionRoutes } from './attention.js';
|
|
7
6
|
export { createPairRoutes, verifyToken } from './pair.js';
|
|
8
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -3,6 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { createProjectRoutes, isProjectAllowed } from './projects.js';
|
|
5
5
|
export { createSessionRoutes } from './sessions.js';
|
|
6
|
-
export { createAttentionRoutes } from './attention.js';
|
|
7
6
|
export { createPairRoutes, verifyToken } from './pair.js';
|
|
8
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,wBAAgB,mBAAmB,IAAI,MAAM,CAmR5C"}
|