@abdasis/agentdeck 2.44.2

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 (196) hide show
  1. package/README.md +122 -0
  2. package/agent/dist/config.d.ts +31 -0
  3. package/agent/dist/config.d.ts.map +1 -0
  4. package/agent/dist/config.js +81 -0
  5. package/agent/dist/config.js.map +1 -0
  6. package/agent/dist/db/commands.d.ts +25 -0
  7. package/agent/dist/db/commands.d.ts.map +1 -0
  8. package/agent/dist/db/commands.js +93 -0
  9. package/agent/dist/db/commands.js.map +1 -0
  10. package/agent/dist/db/index.d.ts +30 -0
  11. package/agent/dist/db/index.d.ts.map +1 -0
  12. package/agent/dist/db/index.js +368 -0
  13. package/agent/dist/db/index.js.map +1 -0
  14. package/agent/dist/db/schema.d.ts +74 -0
  15. package/agent/dist/db/schema.d.ts.map +1 -0
  16. package/agent/dist/db/schema.js +100 -0
  17. package/agent/dist/db/schema.js.map +1 -0
  18. package/agent/dist/db/sessions.d.ts +46 -0
  19. package/agent/dist/db/sessions.d.ts.map +1 -0
  20. package/agent/dist/db/sessions.js +198 -0
  21. package/agent/dist/db/sessions.js.map +1 -0
  22. package/agent/dist/index.d.ts +2 -0
  23. package/agent/dist/index.d.ts.map +1 -0
  24. package/agent/dist/index.js +19 -0
  25. package/agent/dist/index.js.map +1 -0
  26. package/agent/dist/lib/command-session.d.ts +20 -0
  27. package/agent/dist/lib/command-session.d.ts.map +1 -0
  28. package/agent/dist/lib/command-session.js +64 -0
  29. package/agent/dist/lib/command-session.js.map +1 -0
  30. package/agent/dist/lib/git.d.ts +8 -0
  31. package/agent/dist/lib/git.d.ts.map +1 -0
  32. package/agent/dist/lib/git.js +194 -0
  33. package/agent/dist/lib/git.js.map +1 -0
  34. package/agent/dist/lib/init-script.d.ts +33 -0
  35. package/agent/dist/lib/init-script.d.ts.map +1 -0
  36. package/agent/dist/lib/init-script.js +523 -0
  37. package/agent/dist/lib/init-script.js.map +1 -0
  38. package/agent/dist/lib/transcript.d.ts +16 -0
  39. package/agent/dist/lib/transcript.d.ts.map +1 -0
  40. package/agent/dist/lib/transcript.js +64 -0
  41. package/agent/dist/lib/transcript.js.map +1 -0
  42. package/agent/dist/logger.d.ts +12 -0
  43. package/agent/dist/logger.d.ts.map +1 -0
  44. package/agent/dist/logger.js +39 -0
  45. package/agent/dist/logger.js.map +1 -0
  46. package/agent/dist/middleware/auth.d.ts +15 -0
  47. package/agent/dist/middleware/auth.d.ts.map +1 -0
  48. package/agent/dist/middleware/auth.js +55 -0
  49. package/agent/dist/middleware/auth.js.map +1 -0
  50. package/agent/dist/routes/commands.d.ts +8 -0
  51. package/agent/dist/routes/commands.d.ts.map +1 -0
  52. package/agent/dist/routes/commands.js +229 -0
  53. package/agent/dist/routes/commands.js.map +1 -0
  54. package/agent/dist/routes/files.d.ts +7 -0
  55. package/agent/dist/routes/files.d.ts.map +1 -0
  56. package/agent/dist/routes/files.js +206 -0
  57. package/agent/dist/routes/files.js.map +1 -0
  58. package/agent/dist/routes/hooks.d.ts +7 -0
  59. package/agent/dist/routes/hooks.d.ts.map +1 -0
  60. package/agent/dist/routes/hooks.js +147 -0
  61. package/agent/dist/routes/hooks.js.map +1 -0
  62. package/agent/dist/routes/index.d.ts +10 -0
  63. package/agent/dist/routes/index.d.ts.map +1 -0
  64. package/agent/dist/routes/index.js +10 -0
  65. package/agent/dist/routes/index.js.map +1 -0
  66. package/agent/dist/routes/pair.d.ts +26 -0
  67. package/agent/dist/routes/pair.d.ts.map +1 -0
  68. package/agent/dist/routes/pair.js +384 -0
  69. package/agent/dist/routes/pair.js.map +1 -0
  70. package/agent/dist/routes/projects.d.ts +6 -0
  71. package/agent/dist/routes/projects.d.ts.map +1 -0
  72. package/agent/dist/routes/projects.js +121 -0
  73. package/agent/dist/routes/projects.js.map +1 -0
  74. package/agent/dist/routes/sessions-git.d.ts +7 -0
  75. package/agent/dist/routes/sessions-git.d.ts.map +1 -0
  76. package/agent/dist/routes/sessions-git.js +31 -0
  77. package/agent/dist/routes/sessions-git.js.map +1 -0
  78. package/agent/dist/routes/sessions-tmux.d.ts +7 -0
  79. package/agent/dist/routes/sessions-tmux.d.ts.map +1 -0
  80. package/agent/dist/routes/sessions-tmux.js +94 -0
  81. package/agent/dist/routes/sessions-tmux.js.map +1 -0
  82. package/agent/dist/routes/sessions.d.ts +7 -0
  83. package/agent/dist/routes/sessions.d.ts.map +1 -0
  84. package/agent/dist/routes/sessions.js +172 -0
  85. package/agent/dist/routes/sessions.js.map +1 -0
  86. package/agent/dist/server.d.ts +6 -0
  87. package/agent/dist/server.d.ts.map +1 -0
  88. package/agent/dist/server.js +95 -0
  89. package/agent/dist/server.js.map +1 -0
  90. package/agent/dist/terminal.d.ts +19 -0
  91. package/agent/dist/terminal.d.ts.map +1 -0
  92. package/agent/dist/terminal.js +175 -0
  93. package/agent/dist/terminal.js.map +1 -0
  94. package/agent/dist/updater.d.ts +18 -0
  95. package/agent/dist/updater.d.ts.map +1 -0
  96. package/agent/dist/updater.js +122 -0
  97. package/agent/dist/updater.js.map +1 -0
  98. package/agent/dist/version.d.ts +20 -0
  99. package/agent/dist/version.d.ts.map +1 -0
  100. package/agent/dist/version.js +66 -0
  101. package/agent/dist/version.js.map +1 -0
  102. package/agent/dist/websocket-handlers.d.ts +38 -0
  103. package/agent/dist/websocket-handlers.d.ts.map +1 -0
  104. package/agent/dist/websocket-handlers.js +389 -0
  105. package/agent/dist/websocket-handlers.js.map +1 -0
  106. package/agent/node_modules/@agentdeck/shared/dist/index.d.ts +2 -0
  107. package/agent/node_modules/@agentdeck/shared/dist/index.d.ts.map +1 -0
  108. package/agent/node_modules/@agentdeck/shared/dist/index.js +2 -0
  109. package/agent/node_modules/@agentdeck/shared/dist/index.js.map +1 -0
  110. package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts +235 -0
  111. package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts.map +1 -0
  112. package/agent/node_modules/@agentdeck/shared/dist/types/index.js +5 -0
  113. package/agent/node_modules/@agentdeck/shared/dist/types/index.js.map +1 -0
  114. package/agent/node_modules/@agentdeck/shared/package.json +29 -0
  115. package/dist/commands/doctor.d.ts +3 -0
  116. package/dist/commands/doctor.d.ts.map +1 -0
  117. package/dist/commands/doctor.js +304 -0
  118. package/dist/commands/doctor.js.map +1 -0
  119. package/dist/commands/hooks.d.ts +3 -0
  120. package/dist/commands/hooks.d.ts.map +1 -0
  121. package/dist/commands/hooks.js +187 -0
  122. package/dist/commands/hooks.js.map +1 -0
  123. package/dist/commands/init.d.ts +3 -0
  124. package/dist/commands/init.d.ts.map +1 -0
  125. package/dist/commands/init.js +109 -0
  126. package/dist/commands/init.js.map +1 -0
  127. package/dist/commands/logs.d.ts +3 -0
  128. package/dist/commands/logs.d.ts.map +1 -0
  129. package/dist/commands/logs.js +38 -0
  130. package/dist/commands/logs.js.map +1 -0
  131. package/dist/commands/profile.d.ts +3 -0
  132. package/dist/commands/profile.d.ts.map +1 -0
  133. package/dist/commands/profile.js +156 -0
  134. package/dist/commands/profile.js.map +1 -0
  135. package/dist/commands/service.d.ts +3 -0
  136. package/dist/commands/service.d.ts.map +1 -0
  137. package/dist/commands/service.js +235 -0
  138. package/dist/commands/service.js.map +1 -0
  139. package/dist/commands/start.d.ts +3 -0
  140. package/dist/commands/start.d.ts.map +1 -0
  141. package/dist/commands/start.js +122 -0
  142. package/dist/commands/start.js.map +1 -0
  143. package/dist/commands/status.d.ts +3 -0
  144. package/dist/commands/status.d.ts.map +1 -0
  145. package/dist/commands/status.js +48 -0
  146. package/dist/commands/status.js.map +1 -0
  147. package/dist/commands/stop.d.ts +3 -0
  148. package/dist/commands/stop.d.ts.map +1 -0
  149. package/dist/commands/stop.js +23 -0
  150. package/dist/commands/stop.js.map +1 -0
  151. package/dist/commands/update.d.ts +3 -0
  152. package/dist/commands/update.d.ts.map +1 -0
  153. package/dist/commands/update.js +129 -0
  154. package/dist/commands/update.js.map +1 -0
  155. package/dist/commands/version.d.ts +3 -0
  156. package/dist/commands/version.d.ts.map +1 -0
  157. package/dist/commands/version.js +39 -0
  158. package/dist/commands/version.js.map +1 -0
  159. package/dist/index.d.ts +5 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +45 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/lib/config.d.ts +68 -0
  164. package/dist/lib/config.d.ts.map +1 -0
  165. package/dist/lib/config.js +156 -0
  166. package/dist/lib/config.js.map +1 -0
  167. package/dist/lib/hooks.d.ts +67 -0
  168. package/dist/lib/hooks.d.ts.map +1 -0
  169. package/dist/lib/hooks.js +353 -0
  170. package/dist/lib/hooks.js.map +1 -0
  171. package/dist/lib/paths.d.ts +36 -0
  172. package/dist/lib/paths.d.ts.map +1 -0
  173. package/dist/lib/paths.js +77 -0
  174. package/dist/lib/paths.js.map +1 -0
  175. package/dist/lib/prerequisites.d.ts +60 -0
  176. package/dist/lib/prerequisites.d.ts.map +1 -0
  177. package/dist/lib/prerequisites.js +266 -0
  178. package/dist/lib/prerequisites.js.map +1 -0
  179. package/dist/lib/process.d.ts +40 -0
  180. package/dist/lib/process.d.ts.map +1 -0
  181. package/dist/lib/process.js +192 -0
  182. package/dist/lib/process.js.map +1 -0
  183. package/dist/service/index.d.ts +44 -0
  184. package/dist/service/index.d.ts.map +1 -0
  185. package/dist/service/index.js +18 -0
  186. package/dist/service/index.js.map +1 -0
  187. package/dist/service/launchd.d.ts +18 -0
  188. package/dist/service/launchd.d.ts.map +1 -0
  189. package/dist/service/launchd.js +208 -0
  190. package/dist/service/launchd.js.map +1 -0
  191. package/dist/service/systemd.d.ts +18 -0
  192. package/dist/service/systemd.d.ts.map +1 -0
  193. package/dist/service/systemd.js +196 -0
  194. package/dist/service/systemd.js.map +1 -0
  195. package/hooks/notify-agentdeck.sh +53 -0
  196. package/package.json +83 -0
@@ -0,0 +1,368 @@
1
+ import Database from 'better-sqlite3';
2
+ import { existsSync, mkdirSync } from 'fs';
3
+ import { dirname, join, resolve } from 'path';
4
+ import { CREATE_TABLES_SQL, SCHEMA_VERSION, RETENTION_CONFIG, MIGRATION_16 } from './schema.js';
5
+ // Database file location: ~/.agentdeck/data/agent.db
6
+ const DATA_DIR = resolve(process.env.HOME || '~', '.agentdeck', 'data');
7
+ const DB_PATH = join(DATA_DIR, 'agent.db');
8
+ // Singleton database instance
9
+ let db = null;
10
+ /**
11
+ * Get or create the database instance
12
+ */
13
+ export function getDatabase() {
14
+ if (!db) {
15
+ throw new Error('Database not initialized. Call initDatabase() first.');
16
+ }
17
+ return db;
18
+ }
19
+ /**
20
+ * Initialize the database
21
+ * - Creates data directory if missing
22
+ * - Opens/creates database file
23
+ * - Runs migrations
24
+ * - Sets WAL mode for better performance
25
+ */
26
+ export function initDatabase(dbPath) {
27
+ const path = dbPath ?? DB_PATH;
28
+ // Create data directory if it doesn't exist
29
+ const dataDir = dirname(path);
30
+ if (!existsSync(dataDir)) {
31
+ console.log(`[DB] Creating data directory: ${dataDir}`);
32
+ mkdirSync(dataDir, { recursive: true });
33
+ }
34
+ // Open database (creates if doesn't exist)
35
+ console.log(`[DB] Opening database: ${path}`);
36
+ db = new Database(path);
37
+ // Enable WAL mode for better concurrent performance
38
+ db.pragma('journal_mode = WAL');
39
+ // Run migrations
40
+ runMigrations(db);
41
+ // Heal DB yang setengah-migrasi (versi sudah tercatat tapi tabel/kolom hilang).
42
+ ensureTokenTrackingColumns(db);
43
+ ensureProjectCommandsSchema(db);
44
+ return db;
45
+ }
46
+ /**
47
+ * Create an in-memory database for testing
48
+ */
49
+ export function initTestDatabase() {
50
+ db = new Database(':memory:');
51
+ runMigrations(db);
52
+ return db;
53
+ }
54
+ /**
55
+ * Close the database connection
56
+ */
57
+ export function closeDatabase() {
58
+ if (db) {
59
+ console.log('[DB] Closing database connection');
60
+ db.close();
61
+ db = null;
62
+ }
63
+ }
64
+ /**
65
+ * Run database migrations
66
+ */
67
+ function runMigrations(database) {
68
+ const currentVersion = getCurrentSchemaVersion(database);
69
+ if (currentVersion < SCHEMA_VERSION) {
70
+ console.log(`[DB] Running migrations from v${currentVersion} to v${SCHEMA_VERSION}`);
71
+ // For fresh databases, just run the simplified schema
72
+ if (currentVersion === 0) {
73
+ database.exec(CREATE_TABLES_SQL);
74
+ }
75
+ else {
76
+ // For existing databases, run migrations in order
77
+ if (currentVersion < 15) {
78
+ migrateToV15(database);
79
+ }
80
+ if (currentVersion < 16) {
81
+ migrateToV16(database);
82
+ }
83
+ if (currentVersion < 17) {
84
+ migrateToV17(database);
85
+ }
86
+ if (currentVersion < 18) {
87
+ migrateToV18(database);
88
+ }
89
+ if (currentVersion < 19) {
90
+ migrateToV19(database);
91
+ }
92
+ }
93
+ // Record the new version
94
+ database
95
+ .prepare(`
96
+ INSERT OR REPLACE INTO schema_version (version, applied_at)
97
+ VALUES (?, ?)
98
+ `)
99
+ .run(SCHEMA_VERSION, Date.now());
100
+ console.log(`[DB] Migrations complete. Now at v${SCHEMA_VERSION}`);
101
+ }
102
+ else {
103
+ console.log(`[DB] Database schema is up to date (v${currentVersion})`);
104
+ }
105
+ }
106
+ /**
107
+ * Migration to v15: Simplification - remove unused columns and tables
108
+ * SQLite doesn't support dropping columns easily, so we recreate the sessions table
109
+ */
110
+ function migrateToV15(database) {
111
+ console.log('[DB] v15 migration: Simplifying schema');
112
+ // Drop status_history table if it exists
113
+ const historyTableExists = database
114
+ .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='status_history'`)
115
+ .get();
116
+ if (historyTableExists) {
117
+ console.log('[DB] v15 migration: Dropping status_history table');
118
+ database.exec('DROP TABLE IF EXISTS status_history');
119
+ }
120
+ // Check if sessions table has the old columns we want to remove
121
+ const columns = database.pragma('table_info(sessions)');
122
+ const columnNames = new Set(columns.map((c) => c.name));
123
+ // If we have old columns like model, cost_usd, worktree_path, etc., recreate the table
124
+ const hasOldColumns = columnNames.has('model') ||
125
+ columnNames.has('cost_usd') ||
126
+ columnNames.has('worktree_path') ||
127
+ columnNames.has('spawn_prompt');
128
+ if (hasOldColumns) {
129
+ console.log('[DB] v15 migration: Recreating sessions table with simplified schema');
130
+ // Create new simplified sessions table
131
+ database.exec(`
132
+ CREATE TABLE IF NOT EXISTS sessions_new (
133
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
134
+ name TEXT NOT NULL UNIQUE,
135
+ project TEXT NOT NULL,
136
+ status TEXT NOT NULL DEFAULT 'init',
137
+ attention_reason TEXT,
138
+ last_event TEXT,
139
+ last_activity INTEGER NOT NULL,
140
+ last_status_change INTEGER NOT NULL,
141
+ archived_at INTEGER,
142
+ created_at INTEGER NOT NULL,
143
+ updated_at INTEGER NOT NULL
144
+ );
145
+ `);
146
+ // Copy data from old table to new table (only the columns we're keeping)
147
+ database.exec(`
148
+ INSERT INTO sessions_new (name, project, status, attention_reason, last_event,
149
+ last_activity, last_status_change, archived_at, created_at, updated_at)
150
+ SELECT name, project, status, attention_reason, last_event,
151
+ last_activity, last_status_change, archived_at, created_at, updated_at
152
+ FROM sessions;
153
+ `);
154
+ // Drop old table and rename new one
155
+ database.exec('DROP TABLE sessions');
156
+ database.exec('ALTER TABLE sessions_new RENAME TO sessions');
157
+ // Recreate indexes
158
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name)');
159
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project)');
160
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status)');
161
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity)');
162
+ console.log('[DB] v15 migration: Sessions table simplified');
163
+ }
164
+ // Ensure schema_version table exists
165
+ database.exec(`
166
+ CREATE TABLE IF NOT EXISTS schema_version (
167
+ version INTEGER PRIMARY KEY,
168
+ applied_at INTEGER NOT NULL
169
+ );
170
+ `);
171
+ console.log('[DB] v15 migration: Simplification complete');
172
+ }
173
+ /**
174
+ * Migration to v16: Remove status tracking
175
+ * Remove status, attention_reason, and last_status_change columns
176
+ */
177
+ function migrateToV16(database) {
178
+ console.log('[DB] v16 migration: Removing status tracking');
179
+ // Check if sessions table has the status columns we want to remove
180
+ const columns = database.pragma('table_info(sessions)');
181
+ const columnNames = new Set(columns.map((c) => c.name));
182
+ const hasStatusColumns = columnNames.has('status') ||
183
+ columnNames.has('attention_reason') ||
184
+ columnNames.has('last_status_change');
185
+ if (hasStatusColumns) {
186
+ console.log('[DB] v16 migration: Recreating sessions table without status columns');
187
+ database.exec(MIGRATION_16);
188
+ console.log('[DB] v16 migration: Sessions table updated');
189
+ }
190
+ console.log('[DB] v16 migration: Status tracking removed');
191
+ }
192
+ /**
193
+ * Migration to v17: Add status tracking via hooks
194
+ * Adds status, status_source, attention_reason, and last_status_change columns
195
+ */
196
+ function migrateToV17(database) {
197
+ console.log('[DB] v17 migration: Adding status tracking via hooks');
198
+ // Helper to get current columns
199
+ const getColumnNames = () => {
200
+ const columns = database.pragma('table_info(sessions)');
201
+ return new Set(columns.map((c) => c.name));
202
+ };
203
+ const requiredColumns = ['status', 'status_source', 'attention_reason', 'last_status_change'];
204
+ let columnNames = getColumnNames();
205
+ // Add each missing column
206
+ for (const col of requiredColumns) {
207
+ if (!columnNames.has(col)) {
208
+ console.log(`[DB] v17 migration: Adding column ${col}`);
209
+ try {
210
+ database.exec(`ALTER TABLE sessions ADD COLUMN ${col} ${col === 'last_status_change' ? 'INTEGER' : 'TEXT'}`);
211
+ }
212
+ catch {
213
+ // Column might already exist from a failed partial migration
214
+ console.log(`[DB] v17 migration: Column ${col} might already exist, continuing...`);
215
+ }
216
+ }
217
+ }
218
+ // Verify all columns were added
219
+ columnNames = getColumnNames();
220
+ const missingColumns = requiredColumns.filter((col) => !columnNames.has(col));
221
+ if (missingColumns.length > 0) {
222
+ throw new Error(`[DB] v17 migration failed: Missing columns: ${missingColumns.join(', ')}`);
223
+ }
224
+ // Create index if it doesn't exist
225
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status)');
226
+ console.log('[DB] v17 migration: Complete');
227
+ }
228
+ /**
229
+ * Migration to v18: Add token tracking columns
230
+ * Menambah kolom token usage + model + cost_usd hasil parse transcript.
231
+ */
232
+ function migrateToV18(database) {
233
+ console.log('[DB] v18 migration: Adding token tracking columns');
234
+ const getColumnNames = () => {
235
+ const columns = database.pragma('table_info(sessions)');
236
+ return new Set(columns.map((c) => c.name));
237
+ };
238
+ const requiredColumns = [
239
+ ['tokens_input', 'INTEGER DEFAULT 0'],
240
+ ['tokens_output', 'INTEGER DEFAULT 0'],
241
+ ['tokens_cache_read', 'INTEGER DEFAULT 0'],
242
+ ['tokens_cache_creation', 'INTEGER DEFAULT 0'],
243
+ ['model', 'TEXT'],
244
+ ['cost_usd', 'REAL'],
245
+ ];
246
+ const columnNames = getColumnNames();
247
+ for (const [col, def] of requiredColumns) {
248
+ if (!columnNames.has(col)) {
249
+ console.log(`[DB] v18 migration: Adding column ${col}`);
250
+ try {
251
+ database.exec(`ALTER TABLE sessions ADD COLUMN ${col} ${def}`);
252
+ }
253
+ catch {
254
+ console.log(`[DB] v18 migration: Column ${col} might already exist, continuing...`);
255
+ }
256
+ }
257
+ }
258
+ console.log('[DB] v18 migration: Complete');
259
+ }
260
+ /**
261
+ * Migration to v19: Project commands feature.
262
+ * Tambah tabel project_commands + kolom sessions.command_id.
263
+ */
264
+ function migrateToV19(database) {
265
+ console.log('[DB] v19 migration: Adding project_commands table + sessions.command_id');
266
+ ensureProjectCommandsSchema(database);
267
+ console.log('[DB] v19 migration: Complete');
268
+ }
269
+ /**
270
+ * Pastikan kolom tracking token (v18) ada di sessions. Idempotent, dipanggil
271
+ * tiap boot lewat initDatabase untuk sembuhkan DB setengah-migrasi: kasus
272
+ * schema_version sudah 18/19 tapi kolom tokens_input/model/cost_usd belum ke-add,
273
+ * yang bikin upsertSession throw "no such column" dan session baru ga ke-persist.
274
+ */
275
+ function ensureTokenTrackingColumns(database) {
276
+ const requiredColumns = [
277
+ ['tokens_input', 'INTEGER DEFAULT 0'],
278
+ ['tokens_output', 'INTEGER DEFAULT 0'],
279
+ ['tokens_cache_read', 'INTEGER DEFAULT 0'],
280
+ ['tokens_cache_creation', 'INTEGER DEFAULT 0'],
281
+ ['model', 'TEXT'],
282
+ ['cost_usd', 'REAL'],
283
+ ];
284
+ const columns = database.pragma('table_info(sessions)');
285
+ const columnNames = new Set(columns.map((c) => c.name));
286
+ for (const [col, def] of requiredColumns) {
287
+ if (!columnNames.has(col)) {
288
+ try {
289
+ database.exec(`ALTER TABLE sessions ADD COLUMN ${col} ${def}`);
290
+ console.log(`[DB] Self-heal: added missing column sessions.${col}`);
291
+ }
292
+ catch {
293
+ // Kolom mungkin sudah ada dari proses lain yang berjalan paralel.
294
+ }
295
+ }
296
+ }
297
+ }
298
+ /**
299
+ * Pastikan tabel project_commands + kolom sessions.command_id ada. Idempotent,
300
+ * dipanggil tiap boot (lewat initDatabase) supaya DB yang setengah-migrasi
301
+ * (schema_version sudah 19 tapi tabel belum ke-create) otomatis sembuh.
302
+ */
303
+ function ensureProjectCommandsSchema(database) {
304
+ database.exec(`
305
+ CREATE TABLE IF NOT EXISTS project_commands (
306
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
307
+ project TEXT NOT NULL,
308
+ name TEXT NOT NULL,
309
+ command TEXT NOT NULL,
310
+ cwd TEXT,
311
+ position INTEGER NOT NULL DEFAULT 0,
312
+ created_at INTEGER NOT NULL,
313
+ updated_at INTEGER NOT NULL,
314
+ UNIQUE (project, name)
315
+ );
316
+ CREATE INDEX IF NOT EXISTS idx_project_commands_project ON project_commands(project);
317
+ `);
318
+ const columns = database.pragma('table_info(sessions)');
319
+ const columnNames = new Set(columns.map((c) => c.name));
320
+ if (!columnNames.has('command_id')) {
321
+ try {
322
+ database.exec('ALTER TABLE sessions ADD COLUMN command_id INTEGER');
323
+ }
324
+ catch {
325
+ // Kolom mungkin sudah ada dari migrasi parsial sebelumnya.
326
+ }
327
+ database.exec('CREATE INDEX IF NOT EXISTS idx_sessions_command_id ON sessions(command_id)');
328
+ }
329
+ }
330
+ /**
331
+ * Get current schema version
332
+ */
333
+ function getCurrentSchemaVersion(database) {
334
+ try {
335
+ // Check if schema_version table exists
336
+ const tableExists = database
337
+ .prepare(`
338
+ SELECT name FROM sqlite_master
339
+ WHERE type='table' AND name='schema_version'
340
+ `)
341
+ .get();
342
+ if (!tableExists) {
343
+ return 0;
344
+ }
345
+ const row = database
346
+ .prepare(`
347
+ SELECT version FROM schema_version ORDER BY version DESC LIMIT 1
348
+ `)
349
+ .get();
350
+ return row?.version ?? 0;
351
+ }
352
+ catch {
353
+ return 0;
354
+ }
355
+ }
356
+ /**
357
+ * Get database statistics for debugging
358
+ */
359
+ export function getDatabaseStats() {
360
+ const database = getDatabase();
361
+ const sessions = database.prepare('SELECT COUNT(*) as count FROM sessions').get();
362
+ return {
363
+ sessions: sessions.count,
364
+ };
365
+ }
366
+ // Export retention config for use in cleanup
367
+ export { RETENTION_CONFIG };
368
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ export type DbSessionStatus = 'init' | 'working' | 'needs_attention' | 'idle';
2
+ export type DbAttentionReason = string;
3
+ export type DbStatusSource = 'hook' | 'tmux';
4
+ export interface DbSession {
5
+ id: number;
6
+ name: string;
7
+ project: string;
8
+ last_event: string | null;
9
+ last_activity: number;
10
+ archived_at: number | null;
11
+ created_at: number;
12
+ updated_at: number;
13
+ status: DbSessionStatus | null;
14
+ status_source: DbStatusSource | null;
15
+ attention_reason: DbAttentionReason | null;
16
+ last_status_change: number | null;
17
+ tokens_input: number | null;
18
+ tokens_output: number | null;
19
+ tokens_cache_read: number | null;
20
+ tokens_cache_creation: number | null;
21
+ model: string | null;
22
+ cost_usd: number | null;
23
+ command_id: number | null;
24
+ }
25
+ export interface DbProjectCommand {
26
+ id: number;
27
+ project: string;
28
+ name: string;
29
+ command: string;
30
+ cwd: string | null;
31
+ position: number;
32
+ created_at: number;
33
+ updated_at: number;
34
+ }
35
+ export interface CommandRunState {
36
+ sessionName: string | null;
37
+ status: string | null;
38
+ lastActivity: number | null;
39
+ }
40
+ export interface DbProjectCommandWithRunState extends DbProjectCommand {
41
+ runState: CommandRunState;
42
+ }
43
+ export interface DbSchemaVersion {
44
+ version: number;
45
+ applied_at: number;
46
+ }
47
+ export interface UpsertSessionInput {
48
+ project?: string;
49
+ lastEvent?: string | null;
50
+ lastActivity?: number;
51
+ status?: DbSessionStatus | null;
52
+ statusSource?: DbStatusSource | null;
53
+ attentionReason?: DbAttentionReason | null;
54
+ usage?: {
55
+ inputTokens: number;
56
+ outputTokens: number;
57
+ cacheReadTokens: number;
58
+ cacheCreationTokens: number;
59
+ };
60
+ model?: string;
61
+ costUsd?: number;
62
+ }
63
+ export declare const SCHEMA_VERSION = 19;
64
+ export declare const CREATE_TABLES_SQL = "\n-- Sessions: current state of terminal sessions with status tracking\nCREATE TABLE IF NOT EXISTS sessions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n project TEXT NOT NULL,\n last_event TEXT,\n last_activity INTEGER NOT NULL,\n archived_at INTEGER,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n -- Status tracking (v17)\n status TEXT,\n status_source TEXT,\n attention_reason TEXT,\n last_status_change INTEGER,\n -- Token tracking (v18)\n tokens_input INTEGER DEFAULT 0,\n tokens_output INTEGER DEFAULT 0,\n tokens_cache_read INTEGER DEFAULT 0,\n tokens_cache_creation INTEGER DEFAULT 0,\n model TEXT,\n cost_usd REAL,\n -- Project command link (v19)\n command_id INTEGER\n);\n\nCREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);\nCREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);\nCREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);\nCREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\nCREATE INDEX IF NOT EXISTS idx_sessions_command_id ON sessions(command_id);\n\n-- Project commands: saved per-project long-running commands (v19)\nCREATE TABLE IF NOT EXISTS project_commands (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project TEXT NOT NULL,\n name TEXT NOT NULL,\n command TEXT NOT NULL,\n cwd TEXT,\n position INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n UNIQUE (project, name)\n);\n\nCREATE INDEX IF NOT EXISTS idx_project_commands_project ON project_commands(project);\n\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at INTEGER NOT NULL\n);\n";
65
+ export declare const MIGRATION_16 = "\n-- Migration v16: Remove status tracking columns\nCREATE TABLE IF NOT EXISTS sessions_new (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n project TEXT NOT NULL,\n last_event TEXT,\n last_activity INTEGER NOT NULL,\n archived_at INTEGER,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nINSERT OR IGNORE INTO sessions_new (id, name, project, last_event, last_activity, archived_at, created_at, updated_at)\nSELECT id, name, project, last_event, last_activity, archived_at, created_at, updated_at\nFROM sessions;\n\nDROP TABLE IF EXISTS sessions;\nALTER TABLE sessions_new RENAME TO sessions;\n\nCREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);\nCREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);\nCREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);\n";
66
+ export declare const RETENTION_CONFIG: {
67
+ /** Max age for sessions before cleanup (24 hours) */
68
+ sessionMaxAge: number;
69
+ /** Max age for archived sessions before cleanup (30 days) */
70
+ archivedMaxAge: number;
71
+ /** Cleanup interval (1 hour) */
72
+ cleanupInterval: number;
73
+ };
74
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,iBAAiB,GAAG,MAAM,CAAC;AAE9E,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACvC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,gBAAgB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC3C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA6B,SAAQ,gBAAgB;IACpE,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAE3C,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,eAAO,MAAM,iBAAiB,osDAqD7B,CAAC;AAMF,eAAO,MAAM,YAAY,w2BAuBxB,CAAC;AAMF,eAAO,MAAM,gBAAgB;IAC3B,qDAAqD;;IAErD,6DAA6D;;IAE7D,gCAAgC;;CAEjC,CAAC"}
@@ -0,0 +1,100 @@
1
+ // ============================================================================
2
+ // Database Row Types
3
+ // ============================================================================
4
+ // ============================================================================
5
+ // SQL Schema Definitions (v18 - Token Tracking via Transcript)
6
+ // ============================================================================
7
+ export const SCHEMA_VERSION = 19;
8
+ export const CREATE_TABLES_SQL = `
9
+ -- Sessions: current state of terminal sessions with status tracking
10
+ CREATE TABLE IF NOT EXISTS sessions (
11
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
12
+ name TEXT NOT NULL UNIQUE,
13
+ project TEXT NOT NULL,
14
+ last_event TEXT,
15
+ last_activity INTEGER NOT NULL,
16
+ archived_at INTEGER,
17
+ created_at INTEGER NOT NULL,
18
+ updated_at INTEGER NOT NULL,
19
+ -- Status tracking (v17)
20
+ status TEXT,
21
+ status_source TEXT,
22
+ attention_reason TEXT,
23
+ last_status_change INTEGER,
24
+ -- Token tracking (v18)
25
+ tokens_input INTEGER DEFAULT 0,
26
+ tokens_output INTEGER DEFAULT 0,
27
+ tokens_cache_read INTEGER DEFAULT 0,
28
+ tokens_cache_creation INTEGER DEFAULT 0,
29
+ model TEXT,
30
+ cost_usd REAL,
31
+ -- Project command link (v19)
32
+ command_id INTEGER
33
+ );
34
+
35
+ CREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);
36
+ CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);
37
+ CREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);
38
+ CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
39
+ CREATE INDEX IF NOT EXISTS idx_sessions_command_id ON sessions(command_id);
40
+
41
+ -- Project commands: saved per-project long-running commands (v19)
42
+ CREATE TABLE IF NOT EXISTS project_commands (
43
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
44
+ project TEXT NOT NULL,
45
+ name TEXT NOT NULL,
46
+ command TEXT NOT NULL,
47
+ cwd TEXT,
48
+ position INTEGER NOT NULL DEFAULT 0,
49
+ created_at INTEGER NOT NULL,
50
+ updated_at INTEGER NOT NULL,
51
+ UNIQUE (project, name)
52
+ );
53
+
54
+ CREATE INDEX IF NOT EXISTS idx_project_commands_project ON project_commands(project);
55
+
56
+ -- Schema version tracking
57
+ CREATE TABLE IF NOT EXISTS schema_version (
58
+ version INTEGER PRIMARY KEY,
59
+ applied_at INTEGER NOT NULL
60
+ );
61
+ `;
62
+ // ============================================================================
63
+ // Migration for v16 (Remove status tracking)
64
+ // ============================================================================
65
+ export const MIGRATION_16 = `
66
+ -- Migration v16: Remove status tracking columns
67
+ CREATE TABLE IF NOT EXISTS sessions_new (
68
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
69
+ name TEXT NOT NULL UNIQUE,
70
+ project TEXT NOT NULL,
71
+ last_event TEXT,
72
+ last_activity INTEGER NOT NULL,
73
+ archived_at INTEGER,
74
+ created_at INTEGER NOT NULL,
75
+ updated_at INTEGER NOT NULL
76
+ );
77
+
78
+ INSERT OR IGNORE INTO sessions_new (id, name, project, last_event, last_activity, archived_at, created_at, updated_at)
79
+ SELECT id, name, project, last_event, last_activity, archived_at, created_at, updated_at
80
+ FROM sessions;
81
+
82
+ DROP TABLE IF EXISTS sessions;
83
+ ALTER TABLE sessions_new RENAME TO sessions;
84
+
85
+ CREATE INDEX IF NOT EXISTS idx_sessions_name ON sessions(name);
86
+ CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project);
87
+ CREATE INDEX IF NOT EXISTS idx_sessions_last_activity ON sessions(last_activity);
88
+ `;
89
+ // ============================================================================
90
+ // Retention Configuration
91
+ // ============================================================================
92
+ export const RETENTION_CONFIG = {
93
+ /** Max age for sessions before cleanup (24 hours) */
94
+ sessionMaxAge: 24 * 60 * 60 * 1000,
95
+ /** Max age for archived sessions before cleanup (30 days) */
96
+ archivedMaxAge: 30 * 24 * 60 * 60 * 1000,
97
+ /** Cleanup interval (1 hour) */
98
+ cleanupInterval: 60 * 60 * 1000,
99
+ };
100
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAqF/E,+EAA+E;AAC/E,+DAA+D;AAC/D,+EAA+E;AAE/E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDhC,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"}
@@ -0,0 +1,46 @@
1
+ import type { DbSession, UpsertSessionInput } from './schema.js';
2
+ import type { WSSessionInfo } from '@agentdeck/shared';
3
+ /**
4
+ * Map baris DB sessions ke WSSessionInfo (kontrak WS/HTTP). Satu sumber
5
+ * kebenaran agar token fields konsisten lintas broadcast & route.
6
+ */
7
+ export declare function dbSessionToInfo(name: string, project: string, createdAt: number, dbSession: DbSession | null, overrides?: Partial<WSSessionInfo>): WSSessionInfo;
8
+ /**
9
+ * Get a session by name
10
+ */
11
+ export declare function getSession(name: string): DbSession | null;
12
+ /**
13
+ * Get all active (non-archived) sessions
14
+ */
15
+ export declare function getAllSessions(): DbSession[];
16
+ /**
17
+ * Get all archived sessions
18
+ */
19
+ export declare function getArchivedSessions(): DbSession[];
20
+ /**
21
+ * Upsert a session (insert or update)
22
+ */
23
+ export declare function upsertSession(name: string, input: UpsertSessionInput): DbSession;
24
+ /**
25
+ * Delete a session
26
+ */
27
+ export declare function deleteSession(name: string): boolean;
28
+ /**
29
+ * Archive a session (mark as done and keep in history)
30
+ * Returns the archived session or null if not found
31
+ */
32
+ export declare function archiveSession(name: string): DbSession | null;
33
+ /**
34
+ * Reconcile sessions with active tmux sessions
35
+ * - Sessions in DB but not in tmux: delete if old
36
+ * - Sessions in tmux but not in DB: will be created when they connect
37
+ * - Archived sessions are skipped (they don't have tmux sessions)
38
+ */
39
+ export declare function reconcileWithTmux(activeTmuxSessions: Set<string>): void;
40
+ /**
41
+ * Insert session row untuk command yang di-spawn di luar flow WS terminal.
42
+ * Dipakai oleh routes/commands.ts start. Tidak memakai upsertSession agar
43
+ * insert minimal dan benar (upsertSession punya mismatch jumlah kolom/value).
44
+ */
45
+ export declare function insertCommandSession(name: string, project: string, commandId: number): DbSession;
46
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
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;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GACjC,aAAa,CAkCf;AAED;;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,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,SAAS,CA6DhF;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,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAyBvE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,SAAS,CAUX"}