clitrigger 0.1.5 → 0.1.7
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/README.md +146 -97
- package/README_KR.md +268 -0
- package/dist/client/assets/index-BiXO2oR3.js +541 -0
- package/dist/client/assets/index-tGOot928.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/data/cli-models-registry.json +34 -0
- package/dist/server/db/queries.d.ts +95 -48
- package/dist/server/db/queries.d.ts.map +1 -1
- package/dist/server/db/queries.js +328 -129
- package/dist/server/db/queries.js.map +1 -1
- package/dist/server/db/schema.d.ts.map +1 -1
- package/dist/server/db/schema.js +67 -35
- package/dist/server/db/schema.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +43 -20
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/git.d.ts +3 -0
- package/dist/server/lib/git.d.ts.map +1 -0
- package/dist/server/lib/git.js +7 -0
- package/dist/server/lib/git.js.map +1 -0
- package/dist/server/routes/{pipelines.d.ts → analytics.d.ts} +1 -1
- package/dist/server/routes/analytics.d.ts.map +1 -0
- package/dist/server/routes/analytics.js +102 -0
- package/dist/server/routes/analytics.js.map +1 -0
- package/dist/server/routes/cli-status.d.ts +3 -0
- package/dist/server/routes/cli-status.d.ts.map +1 -0
- package/dist/server/routes/cli-status.js +28 -0
- package/dist/server/routes/cli-status.js.map +1 -0
- package/dist/server/routes/discussions.js +5 -5
- package/dist/server/routes/discussions.js.map +1 -1
- package/dist/server/routes/execution.d.ts.map +1 -1
- package/dist/server/routes/execution.js +9 -5
- package/dist/server/routes/execution.js.map +1 -1
- package/dist/server/routes/images.d.ts +21 -0
- package/dist/server/routes/images.d.ts.map +1 -1
- package/dist/server/routes/images.js +163 -1
- package/dist/server/routes/images.js.map +1 -1
- package/dist/server/routes/logs.js +3 -3
- package/dist/server/routes/logs.js.map +1 -1
- package/dist/server/routes/models.d.ts.map +1 -1
- package/dist/server/routes/models.js +2 -0
- package/dist/server/routes/models.js.map +1 -1
- package/dist/server/routes/planner.d.ts +3 -0
- package/dist/server/routes/planner.d.ts.map +1 -0
- package/dist/server/routes/planner.js +344 -0
- package/dist/server/routes/planner.js.map +1 -0
- package/dist/server/routes/projects.d.ts.map +1 -1
- package/dist/server/routes/projects.js +159 -1
- package/dist/server/routes/projects.js.map +1 -1
- package/dist/server/routes/schedules.d.ts.map +1 -1
- package/dist/server/routes/schedules.js +39 -0
- package/dist/server/routes/schedules.js.map +1 -1
- package/dist/server/routes/sessions.d.ts +3 -0
- package/dist/server/routes/sessions.d.ts.map +1 -0
- package/dist/server/routes/sessions.js +200 -0
- package/dist/server/routes/sessions.js.map +1 -0
- package/dist/server/routes/todos.d.ts.map +1 -1
- package/dist/server/routes/todos.js +16 -4
- package/dist/server/routes/todos.js.map +1 -1
- package/dist/server/services/claude-manager.d.ts.map +1 -1
- package/dist/server/services/claude-manager.js +63 -28
- package/dist/server/services/claude-manager.js.map +1 -1
- package/dist/server/services/cli-adapters.d.ts +60 -0
- package/dist/server/services/cli-adapters.d.ts.map +1 -1
- package/dist/server/services/cli-adapters.js +123 -5
- package/dist/server/services/cli-adapters.js.map +1 -1
- package/dist/server/services/cli-status.d.ts +8 -0
- package/dist/server/services/cli-status.d.ts.map +1 -0
- package/dist/server/services/cli-status.js +57 -0
- package/dist/server/services/cli-status.js.map +1 -0
- package/dist/server/services/discussion-orchestrator.d.ts.map +1 -1
- package/dist/server/services/discussion-orchestrator.js +33 -6
- package/dist/server/services/discussion-orchestrator.js.map +1 -1
- package/dist/server/services/log-streamer.d.ts +12 -0
- package/dist/server/services/log-streamer.d.ts.map +1 -1
- package/dist/server/services/log-streamer.js +116 -31
- package/dist/server/services/log-streamer.js.map +1 -1
- package/dist/server/services/model-sync.d.ts +22 -0
- package/dist/server/services/model-sync.d.ts.map +1 -0
- package/dist/server/services/model-sync.js +181 -0
- package/dist/server/services/model-sync.js.map +1 -0
- package/dist/server/services/orchestrator.d.ts +18 -0
- package/dist/server/services/orchestrator.d.ts.map +1 -1
- package/dist/server/services/orchestrator.js +81 -11
- package/dist/server/services/orchestrator.js.map +1 -1
- package/dist/server/services/pty-output-filter.d.ts.map +1 -1
- package/dist/server/services/pty-output-filter.js +91 -8
- package/dist/server/services/pty-output-filter.js.map +1 -1
- package/dist/server/services/session-manager.d.ts +22 -0
- package/dist/server/services/session-manager.d.ts.map +1 -0
- package/dist/server/services/session-manager.js +249 -0
- package/dist/server/services/session-manager.js.map +1 -0
- package/dist/server/services/worktree-manager.d.ts +11 -1
- package/dist/server/services/worktree-manager.d.ts.map +1 -1
- package/dist/server/services/worktree-manager.js +128 -32
- package/dist/server/services/worktree-manager.js.map +1 -1
- package/dist/server/websocket/events.d.ts +13 -22
- package/dist/server/websocket/events.d.ts.map +1 -1
- package/dist/server/websocket/index.d.ts.map +1 -1
- package/dist/server/websocket/index.js +17 -2
- package/dist/server/websocket/index.js.map +1 -1
- package/package.json +3 -3
- package/README_EN.md +0 -219
- package/dist/client/assets/index-B4peRpUi.js +0 -134
- package/dist/client/assets/index-Bjyoy6lB.css +0 -1
- package/dist/server/routes/pipelines.d.ts.map +0 -1
- package/dist/server/routes/pipelines.js +0 -315
- package/dist/server/routes/pipelines.js.map +0 -1
- package/dist/server/services/pipeline-orchestrator.d.ts +0 -43
- package/dist/server/services/pipeline-orchestrator.d.ts.map +0 -1
- package/dist/server/services/pipeline-orchestrator.js +0 -503
- package/dist/server/services/pipeline-orchestrator.js.map +0 -1
|
@@ -164,12 +164,13 @@ export function deleteProject(id) {
|
|
|
164
164
|
const result = db.prepare('DELETE FROM projects WHERE id = ?').run(id);
|
|
165
165
|
return result.changes > 0;
|
|
166
166
|
}
|
|
167
|
-
export function createTodo(projectId, title, description, priority = 0, cliTool, cliModel, scheduleId, dependsOn, maxTurns) {
|
|
167
|
+
export function createTodo(projectId, title, description, priority = 0, cliTool, cliModel, scheduleId, dependsOn, maxTurns, useWorktree) {
|
|
168
168
|
const db = getDatabase();
|
|
169
169
|
const id = uuidv4();
|
|
170
170
|
const now = new Date().toISOString();
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
const normalizedUseWorktree = useWorktree === 0 || useWorktree === 1 ? useWorktree : null;
|
|
172
|
+
db.prepare(`INSERT INTO todos (id, project_id, title, description, priority, cli_tool, cli_model, schedule_id, depends_on, max_turns, use_worktree, created_at, updated_at)
|
|
173
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, projectId, title, description ?? null, priority, cliTool ?? null, cliModel ?? null, scheduleId ?? null, dependsOn ?? null, maxTurns ?? null, normalizedUseWorktree, now, now);
|
|
173
174
|
return getTodoById(id);
|
|
174
175
|
}
|
|
175
176
|
export function getTodosByProjectId(projectId) {
|
|
@@ -256,6 +257,19 @@ export function updateTodo(id, updates) {
|
|
|
256
257
|
fields.push('round_count = ?');
|
|
257
258
|
values.push(updates.round_count);
|
|
258
259
|
}
|
|
260
|
+
if (updates.total_cost_usd !== undefined) {
|
|
261
|
+
fields.push('total_cost_usd = ?');
|
|
262
|
+
values.push(updates.total_cost_usd);
|
|
263
|
+
}
|
|
264
|
+
if (updates.total_tokens !== undefined) {
|
|
265
|
+
fields.push('total_tokens = ?');
|
|
266
|
+
values.push(updates.total_tokens);
|
|
267
|
+
}
|
|
268
|
+
if (updates.use_worktree !== undefined) {
|
|
269
|
+
const v = updates.use_worktree === 0 || updates.use_worktree === 1 ? updates.use_worktree : null;
|
|
270
|
+
fields.push('use_worktree = ?');
|
|
271
|
+
values.push(v);
|
|
272
|
+
}
|
|
259
273
|
if (fields.length === 0)
|
|
260
274
|
return getTodoById(id);
|
|
261
275
|
fields.push('updated_at = ?');
|
|
@@ -295,125 +309,6 @@ export function deleteTaskLogsByTodoId(todoId) {
|
|
|
295
309
|
const result = db.prepare('DELETE FROM task_logs WHERE todo_id = ?').run(todoId);
|
|
296
310
|
return result.changes;
|
|
297
311
|
}
|
|
298
|
-
export function createPipeline(projectId, title, description) {
|
|
299
|
-
const db = getDatabase();
|
|
300
|
-
const id = uuidv4();
|
|
301
|
-
const now = new Date().toISOString();
|
|
302
|
-
db.prepare(`INSERT INTO pipelines (id, project_id, title, description, created_at, updated_at)
|
|
303
|
-
VALUES (?, ?, ?, ?, ?, ?)`).run(id, projectId, title, description, now, now);
|
|
304
|
-
return getPipelineById(id);
|
|
305
|
-
}
|
|
306
|
-
export function getPipelinesByProjectId(projectId) {
|
|
307
|
-
const db = getDatabase();
|
|
308
|
-
return db.prepare('SELECT * FROM pipelines WHERE project_id = ? ORDER BY created_at DESC').all(projectId);
|
|
309
|
-
}
|
|
310
|
-
export function getPipelineById(id) {
|
|
311
|
-
const db = getDatabase();
|
|
312
|
-
return db.prepare('SELECT * FROM pipelines WHERE id = ?').get(id);
|
|
313
|
-
}
|
|
314
|
-
export function updatePipeline(id, updates) {
|
|
315
|
-
const db = getDatabase();
|
|
316
|
-
const fields = [];
|
|
317
|
-
const values = [];
|
|
318
|
-
if (updates.title !== undefined) {
|
|
319
|
-
fields.push('title = ?');
|
|
320
|
-
values.push(updates.title);
|
|
321
|
-
}
|
|
322
|
-
if (updates.description !== undefined) {
|
|
323
|
-
fields.push('description = ?');
|
|
324
|
-
values.push(updates.description);
|
|
325
|
-
}
|
|
326
|
-
if (updates.current_phase !== undefined) {
|
|
327
|
-
fields.push('current_phase = ?');
|
|
328
|
-
values.push(updates.current_phase);
|
|
329
|
-
}
|
|
330
|
-
if (updates.branch_name !== undefined) {
|
|
331
|
-
fields.push('branch_name = ?');
|
|
332
|
-
values.push(updates.branch_name);
|
|
333
|
-
}
|
|
334
|
-
if (updates.worktree_path !== undefined) {
|
|
335
|
-
fields.push('worktree_path = ?');
|
|
336
|
-
values.push(updates.worktree_path);
|
|
337
|
-
}
|
|
338
|
-
if (updates.process_pid !== undefined) {
|
|
339
|
-
fields.push('process_pid = ?');
|
|
340
|
-
values.push(updates.process_pid);
|
|
341
|
-
}
|
|
342
|
-
if (fields.length === 0)
|
|
343
|
-
return getPipelineById(id);
|
|
344
|
-
fields.push('updated_at = ?');
|
|
345
|
-
values.push(new Date().toISOString());
|
|
346
|
-
values.push(id);
|
|
347
|
-
db.prepare(`UPDATE pipelines SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
348
|
-
return getPipelineById(id);
|
|
349
|
-
}
|
|
350
|
-
export function updatePipelineStatus(id, status) {
|
|
351
|
-
const db = getDatabase();
|
|
352
|
-
db.prepare('UPDATE pipelines SET status = ?, updated_at = ? WHERE id = ?').run(status, new Date().toISOString(), id);
|
|
353
|
-
return getPipelineById(id);
|
|
354
|
-
}
|
|
355
|
-
export function getPipelinesByStatus(status) {
|
|
356
|
-
const db = getDatabase();
|
|
357
|
-
return db.prepare('SELECT * FROM pipelines WHERE status = ? ORDER BY created_at DESC').all(status);
|
|
358
|
-
}
|
|
359
|
-
export function deletePipeline(id) {
|
|
360
|
-
const db = getDatabase();
|
|
361
|
-
const result = db.prepare('DELETE FROM pipelines WHERE id = ?').run(id);
|
|
362
|
-
return result.changes > 0;
|
|
363
|
-
}
|
|
364
|
-
export function createPipelinePhase(pipelineId, phaseType, phaseOrder) {
|
|
365
|
-
const db = getDatabase();
|
|
366
|
-
const id = uuidv4();
|
|
367
|
-
const now = new Date().toISOString();
|
|
368
|
-
db.prepare(`INSERT INTO pipeline_phases (id, pipeline_id, phase_type, phase_order, created_at)
|
|
369
|
-
VALUES (?, ?, ?, ?, ?)`).run(id, pipelineId, phaseType, phaseOrder, now);
|
|
370
|
-
return db.prepare('SELECT * FROM pipeline_phases WHERE id = ?').get(id);
|
|
371
|
-
}
|
|
372
|
-
export function getPipelinePhases(pipelineId) {
|
|
373
|
-
const db = getDatabase();
|
|
374
|
-
return db.prepare('SELECT * FROM pipeline_phases WHERE pipeline_id = ? ORDER BY phase_order ASC').all(pipelineId);
|
|
375
|
-
}
|
|
376
|
-
export function updatePipelinePhase(id, updates) {
|
|
377
|
-
const db = getDatabase();
|
|
378
|
-
const fields = [];
|
|
379
|
-
const values = [];
|
|
380
|
-
if (updates.status !== undefined) {
|
|
381
|
-
fields.push('status = ?');
|
|
382
|
-
values.push(updates.status);
|
|
383
|
-
}
|
|
384
|
-
if (updates.output !== undefined) {
|
|
385
|
-
fields.push('output = ?');
|
|
386
|
-
values.push(updates.output);
|
|
387
|
-
}
|
|
388
|
-
if (updates.started_at !== undefined) {
|
|
389
|
-
fields.push('started_at = ?');
|
|
390
|
-
values.push(updates.started_at);
|
|
391
|
-
}
|
|
392
|
-
if (updates.completed_at !== undefined) {
|
|
393
|
-
fields.push('completed_at = ?');
|
|
394
|
-
values.push(updates.completed_at);
|
|
395
|
-
}
|
|
396
|
-
if (fields.length === 0)
|
|
397
|
-
return undefined;
|
|
398
|
-
values.push(id);
|
|
399
|
-
db.prepare(`UPDATE pipeline_phases SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
400
|
-
return db.prepare('SELECT * FROM pipeline_phases WHERE id = ?').get(id);
|
|
401
|
-
}
|
|
402
|
-
export function createPipelineLog(pipelineId, phaseType, logType, message) {
|
|
403
|
-
const db = getDatabase();
|
|
404
|
-
const id = uuidv4();
|
|
405
|
-
const now = new Date().toISOString();
|
|
406
|
-
db.prepare(`INSERT INTO pipeline_logs (id, pipeline_id, phase_type, log_type, message, created_at)
|
|
407
|
-
VALUES (?, ?, ?, ?, ?, ?)`).run(id, pipelineId, phaseType, logType, message, now);
|
|
408
|
-
return db.prepare('SELECT * FROM pipeline_logs WHERE id = ?').get(id);
|
|
409
|
-
}
|
|
410
|
-
export function getPipelineLogs(pipelineId, phaseType) {
|
|
411
|
-
const db = getDatabase();
|
|
412
|
-
if (phaseType) {
|
|
413
|
-
return db.prepare('SELECT * FROM pipeline_logs WHERE pipeline_id = ? AND phase_type = ? ORDER BY created_at ASC').all(pipelineId, phaseType);
|
|
414
|
-
}
|
|
415
|
-
return db.prepare('SELECT * FROM pipeline_logs WHERE pipeline_id = ? ORDER BY created_at ASC').all(pipelineId);
|
|
416
|
-
}
|
|
417
312
|
export function createSchedule(projectId, title, description, cronExpression, cliTool, cliModel, skipIfRunning = 1, scheduleType = 'recurring', runAt) {
|
|
418
313
|
const db = getDatabase();
|
|
419
314
|
const id = uuidv4();
|
|
@@ -556,7 +451,7 @@ export function addModel(cliTool, modelValue, modelLabel) {
|
|
|
556
451
|
const id = uuidv4();
|
|
557
452
|
const maxOrder = db.prepare('SELECT MAX(sort_order) as max_order FROM cli_models WHERE cli_tool = ?').get(cliTool);
|
|
558
453
|
const sortOrder = (maxOrder.max_order ?? -1) + 1;
|
|
559
|
-
db.prepare(`INSERT INTO cli_models (id, cli_tool, model_value, model_label, sort_order, is_default) VALUES (?, ?, ?, ?, ?, 0)`).run(id, cliTool, modelValue, modelLabel, sortOrder);
|
|
454
|
+
db.prepare(`INSERT INTO cli_models (id, cli_tool, model_value, model_label, sort_order, is_default, source) VALUES (?, ?, ?, ?, ?, 0, 'user')`).run(id, cliTool, modelValue, modelLabel, sortOrder);
|
|
560
455
|
return db.prepare('SELECT * FROM cli_models WHERE id = ?').get(id);
|
|
561
456
|
}
|
|
562
457
|
export function removeModel(id) {
|
|
@@ -569,9 +464,57 @@ export function removeModel(id) {
|
|
|
569
464
|
}
|
|
570
465
|
export function isModelSupported(cliTool, modelValue) {
|
|
571
466
|
const db = getDatabase();
|
|
572
|
-
const row = db.prepare('SELECT 1 FROM cli_models WHERE cli_tool = ? AND model_value = ?').get(cliTool, modelValue);
|
|
467
|
+
const row = db.prepare('SELECT 1 FROM cli_models WHERE cli_tool = ? AND model_value = ? AND deprecated = 0').get(cliTool, modelValue);
|
|
573
468
|
return !!row;
|
|
574
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Upsert a discovered model. Updates label/source/last_verified_at and clears
|
|
472
|
+
* the deprecated flag on conflict. Does not overwrite user-added (source='user')
|
|
473
|
+
* entries except to refresh their verified timestamp.
|
|
474
|
+
*/
|
|
475
|
+
export function upsertDiscoveredModel(cliTool, modelValue, modelLabel, source, now) {
|
|
476
|
+
const db = getDatabase();
|
|
477
|
+
const existing = db.prepare('SELECT * FROM cli_models WHERE cli_tool = ? AND model_value = ?').get(cliTool, modelValue);
|
|
478
|
+
if (existing) {
|
|
479
|
+
if (existing.source === 'user') {
|
|
480
|
+
db.prepare(`UPDATE cli_models SET deprecated = 0, last_verified_at = ? WHERE id = ?`).run(now, existing.id);
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
db.prepare(`UPDATE cli_models SET model_label = ?, source = ?, deprecated = 0, last_verified_at = ? WHERE id = ?`).run(modelLabel, source, now, existing.id);
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const id = uuidv4();
|
|
488
|
+
const maxOrder = db.prepare('SELECT MAX(sort_order) as max_order FROM cli_models WHERE cli_tool = ?').get(cliTool);
|
|
489
|
+
const sortOrder = (maxOrder.max_order ?? -1) + 1;
|
|
490
|
+
db.prepare(`INSERT INTO cli_models (id, cli_tool, model_value, model_label, sort_order, is_default, deprecated, last_verified_at, source)
|
|
491
|
+
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`).run(id, cliTool, modelValue, modelLabel, sortOrder, now, source);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Mark any non-user, non-default cli_models entries for the given tool as
|
|
495
|
+
* deprecated if their model_value is NOT in the discovered list.
|
|
496
|
+
*/
|
|
497
|
+
export function markDeprecatedExcept(cliTool, discoveredValues) {
|
|
498
|
+
const db = getDatabase();
|
|
499
|
+
if (discoveredValues.length === 0) {
|
|
500
|
+
db.prepare(`UPDATE cli_models SET deprecated = 1
|
|
501
|
+
WHERE cli_tool = ? AND is_default = 0 AND source IN ('seed','probe','registry')`).run(cliTool);
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const placeholders = discoveredValues.map(() => '?').join(',');
|
|
505
|
+
db.prepare(`UPDATE cli_models SET deprecated = 1
|
|
506
|
+
WHERE cli_tool = ? AND is_default = 0 AND source IN ('seed','probe','registry')
|
|
507
|
+
AND model_value NOT IN (${placeholders})`).run(cliTool, ...discoveredValues);
|
|
508
|
+
}
|
|
509
|
+
export function getCliVersion(cliTool) {
|
|
510
|
+
const db = getDatabase();
|
|
511
|
+
return db.prepare('SELECT * FROM cli_versions WHERE cli_tool = ?').get(cliTool);
|
|
512
|
+
}
|
|
513
|
+
export function setCliVersion(cliTool, version, syncedAt) {
|
|
514
|
+
const db = getDatabase();
|
|
515
|
+
db.prepare(`INSERT INTO cli_versions (cli_tool, last_version, last_synced_at) VALUES (?, ?, ?)
|
|
516
|
+
ON CONFLICT(cli_tool) DO UPDATE SET last_version = excluded.last_version, last_synced_at = excluded.last_synced_at`).run(cliTool, version, syncedAt);
|
|
517
|
+
}
|
|
575
518
|
// ── CLI Fallback ──
|
|
576
519
|
export function getNextFallbackCli(projectId, currentCliTool) {
|
|
577
520
|
const project = getProjectById(projectId);
|
|
@@ -625,14 +568,14 @@ export function deletePluginConfigs(projectId, pluginId) {
|
|
|
625
568
|
const db = getDatabase();
|
|
626
569
|
db.prepare('DELETE FROM plugin_configs WHERE project_id = ? AND plugin_id = ?').run(projectId, pluginId);
|
|
627
570
|
}
|
|
628
|
-
export function createDiscussionAgent(projectId, name, role, systemPrompt, cliTool, cliModel, avatarColor) {
|
|
571
|
+
export function createDiscussionAgent(projectId, name, role, systemPrompt, cliTool, cliModel, avatarColor, canImplement = false) {
|
|
629
572
|
const db = getDatabase();
|
|
630
573
|
const id = uuidv4();
|
|
631
574
|
const now = new Date().toISOString();
|
|
632
575
|
const maxOrder = db.prepare('SELECT MAX(sort_order) as max_order FROM discussion_agents WHERE project_id = ?').get(projectId);
|
|
633
576
|
const sortOrder = (maxOrder.max_order ?? -1) + 1;
|
|
634
|
-
db.prepare(`INSERT INTO discussion_agents (id, project_id, name, role, system_prompt, cli_tool, cli_model, avatar_color, sort_order, created_at, updated_at)
|
|
635
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, projectId, name, role, systemPrompt, cliTool ?? null, cliModel ?? null, avatarColor ?? null, sortOrder, now, now);
|
|
577
|
+
db.prepare(`INSERT INTO discussion_agents (id, project_id, name, role, system_prompt, cli_tool, cli_model, avatar_color, sort_order, can_implement, created_at, updated_at)
|
|
578
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, projectId, name, role, systemPrompt, cliTool ?? null, cliModel ?? null, avatarColor ?? null, sortOrder, canImplement ? 1 : 0, now, now);
|
|
636
579
|
return getDiscussionAgentById(id);
|
|
637
580
|
}
|
|
638
581
|
export function getDiscussionAgentsByProjectId(projectId) {
|
|
@@ -675,6 +618,10 @@ export function updateDiscussionAgent(id, updates) {
|
|
|
675
618
|
fields.push('sort_order = ?');
|
|
676
619
|
values.push(updates.sort_order);
|
|
677
620
|
}
|
|
621
|
+
if (updates.can_implement !== undefined) {
|
|
622
|
+
fields.push('can_implement = ?');
|
|
623
|
+
values.push(updates.can_implement ? 1 : 0);
|
|
624
|
+
}
|
|
678
625
|
if (fields.length === 0)
|
|
679
626
|
return getDiscussionAgentById(id);
|
|
680
627
|
fields.push('updated_at = ?');
|
|
@@ -836,13 +783,265 @@ export function deleteDiscussionLogs(discussionId) {
|
|
|
836
783
|
const result = db.prepare('DELETE FROM discussion_logs WHERE discussion_id = ?').run(discussionId);
|
|
837
784
|
return result.changes;
|
|
838
785
|
}
|
|
786
|
+
export function createSession(projectId, title, description, cliTool, cliModel, useWorktree) {
|
|
787
|
+
const db = getDatabase();
|
|
788
|
+
const id = uuidv4();
|
|
789
|
+
const now = new Date().toISOString();
|
|
790
|
+
db.prepare(`INSERT INTO sessions (id, project_id, title, description, cli_tool, cli_model, use_worktree, created_at, updated_at)
|
|
791
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, projectId, title, description ?? null, cliTool ?? null, cliModel ?? null, useWorktree ? 1 : 0, now, now);
|
|
792
|
+
return getSessionById(id);
|
|
793
|
+
}
|
|
794
|
+
export function getSessionsByProjectId(projectId) {
|
|
795
|
+
const db = getDatabase();
|
|
796
|
+
return db.prepare('SELECT * FROM sessions WHERE project_id = ? ORDER BY created_at DESC').all(projectId);
|
|
797
|
+
}
|
|
798
|
+
export function getSessionById(id) {
|
|
799
|
+
const db = getDatabase();
|
|
800
|
+
return db.prepare('SELECT * FROM sessions WHERE id = ?').get(id);
|
|
801
|
+
}
|
|
802
|
+
export function updateSession(id, updates) {
|
|
803
|
+
const db = getDatabase();
|
|
804
|
+
const fields = [];
|
|
805
|
+
const values = [];
|
|
806
|
+
if (updates.title !== undefined) {
|
|
807
|
+
fields.push('title = ?');
|
|
808
|
+
values.push(updates.title);
|
|
809
|
+
}
|
|
810
|
+
if (updates.description !== undefined) {
|
|
811
|
+
fields.push('description = ?');
|
|
812
|
+
values.push(updates.description);
|
|
813
|
+
}
|
|
814
|
+
if (updates.cli_tool !== undefined) {
|
|
815
|
+
fields.push('cli_tool = ?');
|
|
816
|
+
values.push(updates.cli_tool);
|
|
817
|
+
}
|
|
818
|
+
if (updates.cli_model !== undefined) {
|
|
819
|
+
fields.push('cli_model = ?');
|
|
820
|
+
values.push(updates.cli_model);
|
|
821
|
+
}
|
|
822
|
+
if (updates.process_pid !== undefined) {
|
|
823
|
+
fields.push('process_pid = ?');
|
|
824
|
+
values.push(updates.process_pid);
|
|
825
|
+
}
|
|
826
|
+
if (updates.branch_name !== undefined) {
|
|
827
|
+
fields.push('branch_name = ?');
|
|
828
|
+
values.push(updates.branch_name);
|
|
829
|
+
}
|
|
830
|
+
if (updates.worktree_path !== undefined) {
|
|
831
|
+
fields.push('worktree_path = ?');
|
|
832
|
+
values.push(updates.worktree_path);
|
|
833
|
+
}
|
|
834
|
+
if (updates.use_worktree !== undefined) {
|
|
835
|
+
fields.push('use_worktree = ?');
|
|
836
|
+
values.push(updates.use_worktree);
|
|
837
|
+
}
|
|
838
|
+
if (updates.token_usage !== undefined) {
|
|
839
|
+
fields.push('token_usage = ?');
|
|
840
|
+
values.push(updates.token_usage);
|
|
841
|
+
}
|
|
842
|
+
if (updates.total_cost_usd !== undefined) {
|
|
843
|
+
fields.push('total_cost_usd = ?');
|
|
844
|
+
values.push(updates.total_cost_usd);
|
|
845
|
+
}
|
|
846
|
+
if (updates.total_tokens !== undefined) {
|
|
847
|
+
fields.push('total_tokens = ?');
|
|
848
|
+
values.push(updates.total_tokens);
|
|
849
|
+
}
|
|
850
|
+
if (fields.length === 0)
|
|
851
|
+
return getSessionById(id);
|
|
852
|
+
fields.push('updated_at = ?');
|
|
853
|
+
values.push(new Date().toISOString());
|
|
854
|
+
values.push(id);
|
|
855
|
+
db.prepare(`UPDATE sessions SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
856
|
+
return getSessionById(id);
|
|
857
|
+
}
|
|
858
|
+
export function updateSessionStatus(id, status) {
|
|
859
|
+
const db = getDatabase();
|
|
860
|
+
db.prepare('UPDATE sessions SET status = ?, updated_at = ? WHERE id = ?').run(status, new Date().toISOString(), id);
|
|
861
|
+
return getSessionById(id);
|
|
862
|
+
}
|
|
863
|
+
export function getSessionsByStatus(status) {
|
|
864
|
+
const db = getDatabase();
|
|
865
|
+
return db.prepare('SELECT * FROM sessions WHERE status = ? ORDER BY created_at DESC').all(status);
|
|
866
|
+
}
|
|
867
|
+
export function deleteSession(id) {
|
|
868
|
+
const db = getDatabase();
|
|
869
|
+
const result = db.prepare('DELETE FROM sessions WHERE id = ?').run(id);
|
|
870
|
+
return result.changes > 0;
|
|
871
|
+
}
|
|
872
|
+
export function createSessionLog(sessionId, logType, message) {
|
|
873
|
+
const db = getDatabase();
|
|
874
|
+
const id = uuidv4();
|
|
875
|
+
const now = new Date().toISOString();
|
|
876
|
+
db.prepare(`INSERT INTO session_logs (id, session_id, log_type, message, created_at)
|
|
877
|
+
VALUES (?, ?, ?, ?, ?)`).run(id, sessionId, logType, message, now);
|
|
878
|
+
return db.prepare('SELECT * FROM session_logs WHERE id = ?').get(id);
|
|
879
|
+
}
|
|
880
|
+
export function getSessionLogsBySessionId(sessionId) {
|
|
881
|
+
const db = getDatabase();
|
|
882
|
+
return db.prepare('SELECT * FROM session_logs WHERE session_id = ? ORDER BY created_at ASC').all(sessionId);
|
|
883
|
+
}
|
|
884
|
+
export function deleteSessionLogsBySessionId(sessionId) {
|
|
885
|
+
const db = getDatabase();
|
|
886
|
+
const result = db.prepare('DELETE FROM session_logs WHERE session_id = ?').run(sessionId);
|
|
887
|
+
return result.changes;
|
|
888
|
+
}
|
|
889
|
+
// ── Planner Items ──
|
|
890
|
+
const PLANNER_TAG_COLORS = ['gray', 'brown', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink', 'red'];
|
|
891
|
+
export function createPlannerItem(projectId, title, description, tags, dueDate, priority = 0) {
|
|
892
|
+
const db = getDatabase();
|
|
893
|
+
const id = uuidv4();
|
|
894
|
+
const now = new Date().toISOString();
|
|
895
|
+
db.prepare(`INSERT INTO planner_items (id, project_id, title, description, tags, due_date, priority, created_at, updated_at)
|
|
896
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, projectId, title, description ?? null, tags ?? null, dueDate ?? null, priority, now, now);
|
|
897
|
+
return getPlannerItemById(id);
|
|
898
|
+
}
|
|
899
|
+
export function getPlannerItemsByProjectId(projectId) {
|
|
900
|
+
const db = getDatabase();
|
|
901
|
+
return db.prepare('SELECT * FROM planner_items WHERE project_id = ? ORDER BY priority DESC, created_at ASC').all(projectId);
|
|
902
|
+
}
|
|
903
|
+
export function getPlannerItemById(id) {
|
|
904
|
+
const db = getDatabase();
|
|
905
|
+
return db.prepare('SELECT * FROM planner_items WHERE id = ?').get(id);
|
|
906
|
+
}
|
|
907
|
+
export function updatePlannerItem(id, updates) {
|
|
908
|
+
const db = getDatabase();
|
|
909
|
+
const fields = [];
|
|
910
|
+
const values = [];
|
|
911
|
+
if (updates.title !== undefined) {
|
|
912
|
+
fields.push('title = ?');
|
|
913
|
+
values.push(updates.title);
|
|
914
|
+
}
|
|
915
|
+
if (updates.description !== undefined) {
|
|
916
|
+
fields.push('description = ?');
|
|
917
|
+
values.push(updates.description);
|
|
918
|
+
}
|
|
919
|
+
if (updates.tags !== undefined) {
|
|
920
|
+
fields.push('tags = ?');
|
|
921
|
+
values.push(updates.tags);
|
|
922
|
+
}
|
|
923
|
+
if (updates.due_date !== undefined) {
|
|
924
|
+
fields.push('due_date = ?');
|
|
925
|
+
values.push(updates.due_date);
|
|
926
|
+
}
|
|
927
|
+
if (updates.status !== undefined) {
|
|
928
|
+
fields.push('status = ?');
|
|
929
|
+
values.push(updates.status);
|
|
930
|
+
}
|
|
931
|
+
if (updates.priority !== undefined) {
|
|
932
|
+
fields.push('priority = ?');
|
|
933
|
+
values.push(updates.priority);
|
|
934
|
+
}
|
|
935
|
+
if (updates.images !== undefined) {
|
|
936
|
+
fields.push('images = ?');
|
|
937
|
+
values.push(updates.images);
|
|
938
|
+
}
|
|
939
|
+
if (updates.converted_type !== undefined) {
|
|
940
|
+
fields.push('converted_type = ?');
|
|
941
|
+
values.push(updates.converted_type);
|
|
942
|
+
}
|
|
943
|
+
if (updates.converted_id !== undefined) {
|
|
944
|
+
fields.push('converted_id = ?');
|
|
945
|
+
values.push(updates.converted_id);
|
|
946
|
+
}
|
|
947
|
+
if (fields.length === 0)
|
|
948
|
+
return getPlannerItemById(id);
|
|
949
|
+
fields.push('updated_at = ?');
|
|
950
|
+
values.push(new Date().toISOString());
|
|
951
|
+
values.push(id);
|
|
952
|
+
db.prepare(`UPDATE planner_items SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
953
|
+
return getPlannerItemById(id);
|
|
954
|
+
}
|
|
955
|
+
export function deletePlannerItem(id) {
|
|
956
|
+
const db = getDatabase();
|
|
957
|
+
const result = db.prepare('DELETE FROM planner_items WHERE id = ?').run(id);
|
|
958
|
+
return result.changes > 0;
|
|
959
|
+
}
|
|
960
|
+
// Returns tag objects with colors. Merges planner_tags table with tags found in items.
|
|
961
|
+
export function getPlannerTagsByProjectId(projectId) {
|
|
962
|
+
const db = getDatabase();
|
|
963
|
+
// Get saved tag metadata
|
|
964
|
+
const savedTags = db.prepare('SELECT * FROM planner_tags WHERE project_id = ? ORDER BY name').all(projectId);
|
|
965
|
+
const savedMap = new Map(savedTags.map(t => [t.name, t]));
|
|
966
|
+
// Collect all tags used in items
|
|
967
|
+
let colorIndex = savedTags.length;
|
|
968
|
+
const items = getPlannerItemsByProjectId(projectId);
|
|
969
|
+
for (const item of items) {
|
|
970
|
+
if (item.tags) {
|
|
971
|
+
try {
|
|
972
|
+
const parsed = JSON.parse(item.tags);
|
|
973
|
+
if (Array.isArray(parsed)) {
|
|
974
|
+
for (const name of parsed) {
|
|
975
|
+
if (!savedMap.has(name)) {
|
|
976
|
+
const color = PLANNER_TAG_COLORS[colorIndex % PLANNER_TAG_COLORS.length];
|
|
977
|
+
colorIndex++;
|
|
978
|
+
const tag = upsertPlannerTag(projectId, name, color);
|
|
979
|
+
savedMap.set(name, tag);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
catch { /* ignore */ }
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
return Array.from(savedMap.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
988
|
+
}
|
|
989
|
+
export function upsertPlannerTag(projectId, name, color) {
|
|
990
|
+
const db = getDatabase();
|
|
991
|
+
const existing = db.prepare('SELECT * FROM planner_tags WHERE project_id = ? AND name = ?').get(projectId, name);
|
|
992
|
+
if (existing) {
|
|
993
|
+
db.prepare('UPDATE planner_tags SET color = ? WHERE id = ?').run(color, existing.id);
|
|
994
|
+
return { ...existing, color };
|
|
995
|
+
}
|
|
996
|
+
const id = uuidv4();
|
|
997
|
+
db.prepare('INSERT INTO planner_tags (id, project_id, name, color) VALUES (?, ?, ?, ?)').run(id, projectId, name, color);
|
|
998
|
+
return { id, project_id: projectId, name, color };
|
|
999
|
+
}
|
|
1000
|
+
export function renamePlannerTag(projectId, oldName, newName) {
|
|
1001
|
+
const db = getDatabase();
|
|
1002
|
+
// Update tag table
|
|
1003
|
+
db.prepare('UPDATE planner_tags SET name = ? WHERE project_id = ? AND name = ?').run(newName, projectId, oldName);
|
|
1004
|
+
// Update all items' JSON arrays
|
|
1005
|
+
const items = getPlannerItemsByProjectId(projectId);
|
|
1006
|
+
for (const item of items) {
|
|
1007
|
+
if (!item.tags)
|
|
1008
|
+
continue;
|
|
1009
|
+
try {
|
|
1010
|
+
const parsed = JSON.parse(item.tags);
|
|
1011
|
+
const idx = parsed.indexOf(oldName);
|
|
1012
|
+
if (idx !== -1) {
|
|
1013
|
+
parsed[idx] = newName;
|
|
1014
|
+
db.prepare('UPDATE planner_items SET tags = ? WHERE id = ?').run(JSON.stringify(parsed), item.id);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
catch { /* ignore */ }
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
export function deletePlannerTag(projectId, name) {
|
|
1021
|
+
const db = getDatabase();
|
|
1022
|
+
// Remove from tag table
|
|
1023
|
+
db.prepare('DELETE FROM planner_tags WHERE project_id = ? AND name = ?').run(projectId, name);
|
|
1024
|
+
// Remove from all items' JSON arrays
|
|
1025
|
+
const items = getPlannerItemsByProjectId(projectId);
|
|
1026
|
+
for (const item of items) {
|
|
1027
|
+
if (!item.tags)
|
|
1028
|
+
continue;
|
|
1029
|
+
try {
|
|
1030
|
+
const parsed = JSON.parse(item.tags);
|
|
1031
|
+
const filtered = parsed.filter(t => t !== name);
|
|
1032
|
+
const newTags = filtered.length > 0 ? JSON.stringify(filtered) : null;
|
|
1033
|
+
db.prepare('UPDATE planner_items SET tags = ? WHERE id = ?').run(newTags, item.id);
|
|
1034
|
+
}
|
|
1035
|
+
catch { /* ignore */ }
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
839
1038
|
// ── Cleanup ──
|
|
840
1039
|
export function cleanOldLogs(daysToKeep) {
|
|
841
1040
|
const db = getDatabase();
|
|
842
1041
|
const cutoff = new Date(Date.now() - daysToKeep * 24 * 60 * 60 * 1000).toISOString();
|
|
843
1042
|
const taskResult = db.prepare('DELETE FROM task_logs WHERE created_at < ?').run(cutoff);
|
|
844
|
-
const pipelineResult = db.prepare('DELETE FROM pipeline_logs WHERE created_at < ?').run(cutoff);
|
|
845
1043
|
const discussionResult = db.prepare('DELETE FROM discussion_logs WHERE created_at < ?').run(cutoff);
|
|
846
|
-
|
|
1044
|
+
const sessionResult = db.prepare('DELETE FROM session_logs WHERE created_at < ?').run(cutoff);
|
|
1045
|
+
return taskResult.changes + discussionResult.changes + sessionResult.changes;
|
|
847
1046
|
}
|
|
848
1047
|
//# sourceMappingURL=queries.js.map
|