circuschief 0.2.0 → 0.3.0

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 (117) hide show
  1. package/package.json +1 -1
  2. package/packages/server/src/api/git.js +15 -0
  3. package/packages/server/src/api/projects-commandButtons.js +96 -0
  4. package/packages/server/src/api/projects-session-helpers.js +51 -33
  5. package/packages/server/src/api/projects.js +102 -111
  6. package/packages/server/src/api/sessions-archive.js +2 -1
  7. package/packages/server/src/api/sessions-lifecycle.js +2 -1
  8. package/packages/server/src/api/sessions-patch.js +2 -0
  9. package/packages/server/src/config.js +6 -0
  10. package/packages/server/src/db/DatabaseManager.js +1 -1
  11. package/packages/server/src/db/ProjectRepository.js +17 -3
  12. package/packages/server/src/db/migrations/index.js +7 -0
  13. package/packages/server/src/db/migrations/miscMigrations.js +78 -1
  14. package/packages/server/src/db/migrations/projectsMigrations.js +4 -0
  15. package/packages/server/src/index.js +7 -1
  16. package/packages/server/src/services/gitService.js +42 -6
  17. package/packages/server/src/services/gitSessionSetup.js +4 -3
  18. package/packages/server/src/services/kanbanTriggers.js +1 -0
  19. package/packages/server/src/services/sessionExecution.js +2 -2
  20. package/packages/server/src/services/templateTriggerService.js +1 -0
  21. package/packages/shared/src/contracts/projects.js +3 -0
  22. package/packages/shared/src/types.js +4 -3
  23. package/packages/web/dist/assets/ActiveSessionsView-BVco8bPU.css +1 -0
  24. package/packages/web/dist/assets/ActiveSessionsView-HgcjR-fv.js +1 -0
  25. package/packages/web/dist/assets/{AgentLogsView-C4FTXUH8.js → AgentLogsView-gnpmy7Ck.js} +1 -1
  26. package/packages/web/dist/assets/{ApiClient-Dbs1H78V.js → ApiClient-CcqJ-GAv.js} +1 -1
  27. package/packages/web/dist/assets/{ArchiveConfirmModal-CQZeuYBz.css → ArchiveConfirmModal-BQ-4gI0R.css} +1 -1
  28. package/packages/web/dist/assets/ArchiveConfirmModal-NDLcfHE9.js +1 -0
  29. package/packages/web/dist/assets/CommandButtonDetailView-UGoO1Rhg.js +1 -0
  30. package/packages/web/dist/assets/EffortLevelSelector-B9STpy07.js +1 -0
  31. package/packages/web/dist/assets/{GeneralSettingsView-BZ4x6T_N.js → GeneralSettingsView-Bvp1zmeb.js} +1 -1
  32. package/packages/web/dist/assets/InputWithButton-cYdrEmTs.css +1 -0
  33. package/packages/web/dist/assets/{PathChooser-CPEkT0uu.js → InputWithButton-kjjnlpHt.js} +1 -1
  34. package/packages/web/dist/assets/InterpolationHelp-Cwyt_Kff.js +1 -0
  35. package/packages/web/dist/assets/MarkdownEditor-CfuhardG.js +2 -0
  36. package/packages/web/dist/assets/{ModelSelector-BTmHxqCs.js → ModelSelector-vRSpXjhL.js} +1 -1
  37. package/packages/web/dist/assets/{NewSessionView-Cdgt6wnk.js → NewSessionView-CJqnlwjP.js} +2 -2
  38. package/packages/web/dist/assets/{NewSessionView-Byoi1XdQ.css → NewSessionView-D_Hi7M9g.css} +1 -1
  39. package/packages/web/dist/assets/ProjectEditView-I36pvIJH.css +1 -0
  40. package/packages/web/dist/assets/ProjectEditView-LZhWNyZD.js +1 -0
  41. package/packages/web/dist/assets/ProjectListView-CumumZN-.css +1 -0
  42. package/packages/web/dist/assets/ProjectListView-DxpzlBb6.js +1 -0
  43. package/packages/web/dist/assets/ProjectNewView-CaLXfFzd.css +1 -0
  44. package/packages/web/dist/assets/ProjectNewView-X1y2iuaX.js +1 -0
  45. package/packages/web/dist/assets/{ProvidersView-C04jD9NZ.js → ProvidersView-DC-v48Oj.js} +1 -1
  46. package/packages/web/dist/assets/{ProvidersView-B_QQF3RM.css → ProvidersView-uD8SKWpA.css} +1 -1
  47. package/packages/web/dist/assets/{QuickResponseSettings-DaEXIp3-.js → QuickResponseSettings-DOZUtaRb.js} +1 -1
  48. package/packages/web/dist/assets/{QuickResponsesPanel-CIdblIbt.js → QuickResponsesPanel-BboDyvfE.js} +1 -1
  49. package/packages/web/dist/assets/{ResizableTextarea-DJekfIXO.js → ResizableTextarea-BIUrLAki.js} +1 -1
  50. package/packages/web/dist/assets/{SessionCard-CAdetaVH.js → SessionCard-D9a5ABHO.js} +1 -1
  51. package/packages/web/dist/assets/{SessionDetailView-mnGRMaLY.css → SessionDetailView-D_p4QqDv.css} +1 -1
  52. package/packages/web/dist/assets/SessionDetailView-DpnAZfLe.js +36 -0
  53. package/packages/web/dist/assets/{SessionFormOptions-Dy57kl-x.js → SessionFormOptions-16tOEDkt.js} +1 -1
  54. package/packages/web/dist/assets/{SessionListView-DUMUXfp4.js → SessionListView-BxayFy5a.js} +1 -1
  55. package/packages/web/dist/assets/{SessionLogStream-DHPxkaaK.js → SessionLogStream-DMUzZOml.js} +6 -6
  56. package/packages/web/dist/assets/SettingsView-IKYDEAFw.js +1 -0
  57. package/packages/web/dist/assets/{SlashCommandWizard-BAC_oF5i.js → SlashCommandWizard-CCEtEF98.js} +1 -1
  58. package/packages/web/dist/assets/{SummarySettingsView-J8BQBEe9.js → SummarySettingsView-Cq_0Bsk4.js} +1 -1
  59. package/packages/web/dist/assets/{TemplateDetailView-2ilWbANb.js → TemplateDetailView-Vj413FOj.js} +1 -1
  60. package/packages/web/dist/assets/{commandButtons-aIO6hqZn.js → commandButtons-BqI7V84_.js} +1 -1
  61. package/packages/web/dist/assets/index-B0PaFn8J.js +1 -0
  62. package/packages/web/dist/assets/index-B0uKzlP3.js +1 -0
  63. package/packages/web/dist/assets/index-BOj2hM4W.js +1 -0
  64. package/packages/web/dist/assets/index-BVH1Fur5.js +1 -0
  65. package/packages/web/dist/assets/index-Bm4uwnFi.js +1 -0
  66. package/packages/web/dist/assets/index-C82-hypB.js +7 -0
  67. package/packages/web/dist/assets/index-C98wGWOV.js +1 -0
  68. package/packages/web/dist/assets/index-CQt0yAHQ.js +1 -0
  69. package/packages/web/dist/assets/index-CTe3Gmxt.js +1 -0
  70. package/packages/web/dist/assets/{index-DMsWg7Ax.js → index-Crwsqc5t.js} +3 -3
  71. package/packages/web/dist/assets/{index-CWTVEGZv.js → index-CzgbuOA8.js} +2 -2
  72. package/packages/web/dist/assets/index-D8oIVxkt.js +1 -0
  73. package/packages/web/dist/assets/index-DIrFNnos.js +1 -0
  74. package/packages/web/dist/assets/index-DVkCrevC.js +3 -0
  75. package/packages/web/dist/assets/index-DXvlnigm.js +1 -0
  76. package/packages/web/dist/assets/{index-DxUd3T5E.js → index-MnvuyUxj.js} +8 -8
  77. package/packages/web/dist/assets/index-mMvVdgsE.js +1 -0
  78. package/packages/web/dist/assets/index-okhXrCbj.js +1 -0
  79. package/packages/web/dist/assets/index-yghSjW4j.js +1 -0
  80. package/packages/web/dist/assets/{projects-DGF_kWVA.js → projects-BpAyb9ba.js} +1 -1
  81. package/packages/web/dist/assets/{providers-Cm7emO-N.js → providers-Di1AKmPp.js} +1 -1
  82. package/packages/web/dist/assets/{sessions-CH7PeypH.js → sessions-GqIMf9RF.js} +1 -1
  83. package/packages/web/dist/assets/{settings-C7sXXJ-n.js → settings-j6pMR_H2.js} +1 -1
  84. package/packages/web/dist/assets/useSummaryHelpers-GVg7sMWF.js +1 -0
  85. package/packages/web/dist/index.html +1 -1
  86. package/packages/web/dist/assets/ActiveSessionsView-Bd8FWObJ.js +0 -1
  87. package/packages/web/dist/assets/ActiveSessionsView-DfYXc6dz.css +0 -1
  88. package/packages/web/dist/assets/ArchiveConfirmModal-MpqhAjWZ.js +0 -1
  89. package/packages/web/dist/assets/CommandButtonDetailView-_tOjEGjk.js +0 -1
  90. package/packages/web/dist/assets/EffortLevelSelector-B4z3zfJ6.js +0 -1
  91. package/packages/web/dist/assets/InterpolationHelp-CIlrD5JA.js +0 -1
  92. package/packages/web/dist/assets/MarkdownEditor-DBvC-1OX.js +0 -2
  93. package/packages/web/dist/assets/PathChooser-BoMGzeg2.css +0 -1
  94. package/packages/web/dist/assets/ProjectEditView-D59hr-v2.js +0 -1
  95. package/packages/web/dist/assets/ProjectEditView-DNwBUNRk.css +0 -1
  96. package/packages/web/dist/assets/ProjectListView-C55H1JHQ.css +0 -1
  97. package/packages/web/dist/assets/ProjectListView-gG4AR1i9.js +0 -1
  98. package/packages/web/dist/assets/ProjectNewView-BPjn1O4f.js +0 -1
  99. package/packages/web/dist/assets/ProjectNewView-CpgE4R-l.css +0 -1
  100. package/packages/web/dist/assets/SessionDetailView-BOdnH-cW.js +0 -36
  101. package/packages/web/dist/assets/SettingsView-BzrkWbH3.js +0 -1
  102. package/packages/web/dist/assets/index-B6W39ctH.js +0 -1
  103. package/packages/web/dist/assets/index-BGmIjKYB.js +0 -1
  104. package/packages/web/dist/assets/index-BwChYYnJ.js +0 -1
  105. package/packages/web/dist/assets/index-CDRRIqmL.js +0 -1
  106. package/packages/web/dist/assets/index-CSA0abwg.js +0 -1
  107. package/packages/web/dist/assets/index-CjJX0Eli.js +0 -1
  108. package/packages/web/dist/assets/index-CpNgrGiE.js +0 -1
  109. package/packages/web/dist/assets/index-DCxYGijD.js +0 -1
  110. package/packages/web/dist/assets/index-DF6g7nEj.js +0 -7
  111. package/packages/web/dist/assets/index-DMl4xPIQ.js +0 -1
  112. package/packages/web/dist/assets/index-DePUHO3n.js +0 -1
  113. package/packages/web/dist/assets/index-DvfYqZgb.js +0 -1
  114. package/packages/web/dist/assets/index-GLkcnEcc.js +0 -3
  115. package/packages/web/dist/assets/index-ZDCxncSd.js +0 -1
  116. package/packages/web/dist/assets/index-f24-2-RT.js +0 -1
  117. package/packages/web/dist/assets/index-uZfsnHcN.js +0 -1
@@ -28,7 +28,8 @@ function seedBuiltInProvider(db) {
28
28
  const defaultModels = [
29
29
  { id: 'anthropic-haiku', modelId: 'claude-haiku-4-5-20251001', displayName: 'Haiku 4.5', description: 'Fast & lightweight', tier: 'haiku' },
30
30
  { id: 'anthropic-sonnet', modelId: 'claude-sonnet-4-6', displayName: 'Sonnet 4.6', description: 'Balanced', tier: 'sonnet' },
31
- { id: 'anthropic-opus', modelId: 'claude-opus-4-6', displayName: 'Opus 4.6', description: 'Most capable (default)', tier: 'opus' },
31
+ { id: 'anthropic-opus', modelId: 'claude-opus-4-6', displayName: 'Opus 4.6', description: 'Previous generation', tier: 'opus' },
32
+ { id: 'anthropic-opus-4-7', modelId: 'claude-opus-4-7', displayName: 'Opus 4.7', description: 'Most capable (default)', tier: 'opus' },
32
33
  ];
33
34
 
34
35
  const insertModel = db.prepare(
@@ -61,6 +62,55 @@ function updateBuiltInModels(db) {
61
62
  ).run('claude-opus-4-6', 'Opus 4.6', providerId, 'anthropic-opus');
62
63
  }
63
64
 
65
+ /**
66
+ * Prompt strings for the default global session templates.
67
+ * Exported so tests can assert verbatim equality.
68
+ */
69
+ export const DEFAULT_SESSION_TEMPLATE_PROMPTS = {
70
+ REVIEW: `Review the plan on the canvas. If there's more than one plan then review the most recently updated plan. if there are no plans on the canvas then look for the most recently updated plan on the root session canvas.
71
+
72
+ Make sure there are tests explicitly called out for all changes. Make sure that all context necessary to hand off the task is included in the plan.
73
+
74
+ Are there any gaps in the plan? Is test coverage spelled out explicitly? Does the code match the assumptions in the plan?
75
+
76
+ Update the plan according to your review recommendations.`,
77
+ IMPLEMENT: `Implement the plan on the canvas. If there's more than one plan on the canvas then use the most recently updated plan. If you don't see a plan on the canvas then look at the parent session's canvas.`,
78
+ PR: `Ensure all relevant changes are committed and pushed. Then determine the session's goals. You can typically find details about the goals of the session by looking at the most recently modified markdown documents on the root session's canvas - these are typically plans that were implemented during the session. You can also look at the root session's summary, but don't trigger a new summary to be created if the summary is missing.
79
+
80
+ Create a draft pr and ensure all changes are committed and pushed.`,
81
+ };
82
+
83
+ /**
84
+ * Seed default global session templates when no global template exists.
85
+ * Idempotent: if any global session template already exists, does nothing.
86
+ */
87
+ function seedDefaultSessionTemplates(db) {
88
+ const count = db.prepare(
89
+ 'SELECT COUNT(*) AS cnt FROM session_templates WHERE project_id IS NULL'
90
+ ).get().cnt;
91
+ if (count > 0) return;
92
+
93
+ const defaults = [
94
+ { name: 'Review the plan', prompt: DEFAULT_SESSION_TEMPLATE_PROMPTS.REVIEW },
95
+ { name: 'Implement the plan on the canvas', prompt: DEFAULT_SESSION_TEMPLATE_PROMPTS.IMPLEMENT },
96
+ { name: 'Create/update PR', prompt: DEFAULT_SESSION_TEMPLATE_PROMPTS.PR },
97
+ ];
98
+
99
+ const stmt = db.prepare(`
100
+ INSERT INTO session_templates (
101
+ id, project_id, name, prompt,
102
+ next_template_id, thinking_enabled,
103
+ git_branch, git_mode, model, mode, effort_level, target_lane_id,
104
+ created_at, updated_at
105
+ ) VALUES (?, NULL, ?, ?, NULL, 1, NULL, NULL, NULL, 'yolo', NULL, NULL, ?, ?)
106
+ `);
107
+
108
+ const now = Date.now();
109
+ for (const item of defaults) {
110
+ stmt.run(randomUUID(), item.name, item.prompt, now, now);
111
+ }
112
+ }
113
+
64
114
  /**
65
115
  * Seed default global quick responses when the table is empty.
66
116
  */
@@ -239,4 +289,31 @@ export const miscMigrations = [
239
289
  name: 'quick_responses-seed-defaults',
240
290
  up(db) { seedDefaultQuickResponses(db); },
241
291
  },
292
+
293
+ // --- Seed default global session templates ---
294
+ {
295
+ name: 'session_templates-seed-defaults',
296
+ up(db) { seedDefaultSessionTemplates(db); },
297
+ },
298
+
299
+ // --- Add Opus 4.7 as a new built-in model (keep Opus 4.6 for existing sessions) ---
300
+ {
301
+ name: 'providers-update-built-in-opus-4-7',
302
+ up(db) {
303
+ const providerId = 'anthropic-default';
304
+
305
+ // Mark existing Opus 4.6 row as previous generation
306
+ db.prepare(
307
+ `UPDATE provider_models
308
+ SET description = ?
309
+ WHERE provider_id = ? AND id = ?`
310
+ ).run('Previous generation', providerId, 'anthropic-opus');
311
+
312
+ // Insert new Opus 4.7 row (OR IGNORE in case seed already created it)
313
+ db.prepare(
314
+ `INSERT OR IGNORE INTO provider_models (id, provider_id, model_id, display_name, description, tier, created_at)
315
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
316
+ ).run('anthropic-opus-4-7', providerId, 'claude-opus-4-7', 'Opus 4.7', 'Most capable (default)', 'opus', Date.now());
317
+ },
318
+ },
242
319
  ];
@@ -43,6 +43,10 @@ export const projectsMigrations = [
43
43
  name: 'projects-add-repo_url',
44
44
  up(db) { addColumnIfMissing(db, 'projects', 'repo_url', 'TEXT'); },
45
45
  },
46
+ {
47
+ name: 'projects-add-worktree_path',
48
+ up(db) { addColumnIfMissing(db, 'projects', 'worktree_path', 'TEXT'); },
49
+ },
46
50
  {
47
51
  name: 'projects-drop-summary-columns',
48
52
  up(db) { migrateProjectsDropSummaryColumns(db); },
@@ -1,5 +1,7 @@
1
1
  import { createServer } from 'http';
2
2
  import { execSync } from 'child_process';
3
+ import { mkdirSync } from 'fs';
4
+ import { dirname } from 'path';
3
5
  import { createApp } from './app.js';
4
6
  import { initDatabase } from './database.js';
5
7
  import { initWebSocket, webSocketManager } from './websocket.js';
@@ -11,6 +13,7 @@ import { schedulerService } from './services/schedulerService.js';
11
13
  import * as sessionManager from './services/sessionManager.js';
12
14
  import { clearScheduledTimers } from './services/summaryService.js';
13
15
  import { commandRunner } from './services/commandRunner.js';
16
+ import { getDefaultDbPath } from './config.js';
14
17
 
15
18
  /**
16
19
  * Validate Node.js environment at startup.
@@ -32,7 +35,7 @@ function validateNodeEnvironment() {
32
35
  const { port, disableAnalytics } = parseCliOptions();
33
36
  process.env.PORT = String(port);
34
37
  const production = process.env.NODE_ENV === 'production';
35
- const dbPath = process.env.DB_PATH || 'circuschief.db';
38
+ const dbPath = process.env.DB_PATH || getDefaultDbPath();
36
39
 
37
40
  // Catch uncaught exceptions
38
41
  process.on('uncaughtException', (err) => {
@@ -45,6 +48,9 @@ process.on('unhandledRejection', (reason, promise) => {
45
48
  // Validate Node.js environment
46
49
  validateNodeEnvironment();
47
50
 
51
+ // Ensure the database directory exists
52
+ mkdirSync(dirname(dbPath), { recursive: true });
53
+
48
54
  // Initialize database
49
55
  initDatabase(dbPath);
50
56
  console.log(`Database initialized: ${dbPath}`);
@@ -1,5 +1,7 @@
1
1
  import { exec } from 'child_process';
2
2
  import { promisify } from 'util';
3
+ import path from 'path';
4
+ import { realpath } from 'fs/promises';
3
5
 
4
6
  const execAsync = promisify(exec);
5
7
 
@@ -239,12 +241,12 @@ export async function getCurrentBranch(directory) {
239
241
  * Create a new worktree
240
242
  * @param {string} directory
241
243
  * @param {string} branch
242
- * @param {string} path
244
+ * @param {string} worktreePath
243
245
  * @param {Object} options
244
246
  * @param {boolean} options.skipFetch - Skip fetching from origin (default: false)
245
247
  * @returns {Promise<{path: string, branch: string}>}
246
248
  */
247
- export async function createWorktree(directory, branch, path, options = {}) {
249
+ export async function createWorktree(directory, branch, worktreePath, options = {}) {
248
250
  const { skipFetch = false } = options;
249
251
 
250
252
  // Fetch latest from origin to ensure we have up-to-date default branch
@@ -256,8 +258,8 @@ export async function createWorktree(directory, branch, path, options = {}) {
256
258
  const defaultBranch = await getOriginDefaultBranch(directory);
257
259
  // Base new branch on origin's default branch to avoid including unrelated commits from HEAD
258
260
  // Use --no-track to prevent the new branch from tracking the start-point (main/master)
259
- await git(directory, `worktree add --no-track "${path}" -b "${branch}" ${defaultBranch}`);
260
- return { path, branch };
261
+ await git(directory, `worktree add --no-track "${worktreePath}" -b "${branch}" ${defaultBranch}`);
262
+ return { path: worktreePath, branch };
261
263
  }
262
264
 
263
265
  /**
@@ -266,9 +268,9 @@ export async function createWorktree(directory, branch, path, options = {}) {
266
268
  * @param {string} path
267
269
  * @param {boolean} force - Force removal even if worktree has uncommitted changes
268
270
  */
269
- export async function removeWorktree(directory, path, force = false) {
271
+ export async function removeWorktree(directory, worktreePath, force = false) {
270
272
  const forceFlag = force ? '--force' : '';
271
- await git(directory, `worktree remove ${forceFlag} "${path}"`);
273
+ await git(directory, `worktree remove ${forceFlag} "${worktreePath}"`);
272
274
  }
273
275
 
274
276
  /**
@@ -518,3 +520,37 @@ export async function pinAuthorInWorktree(worktreePath, projectDir, { env } = {}
518
520
 
519
521
  return true;
520
522
  }
523
+
524
+ /**
525
+ * Detect the worktree path for a directory by inspecting existing worktrees.
526
+ * If external worktrees exist, uses the parent directory of the first one.
527
+ * Otherwise, falls back to {directory}/.worktrees.
528
+ * @param {string} directory - The git repository directory
529
+ * @returns {Promise<{worktreePath: string, source: 'detected' | 'default'}>}
530
+ */
531
+ export async function detectWorktreePath(directory) {
532
+ const isRepo = await isGitRepo(directory);
533
+ if (!isRepo) {
534
+ return { worktreePath: path.join(directory, '.worktrees'), source: 'default' };
535
+ }
536
+
537
+ // Resolve symlinks for consistent path comparison (e.g., /var -> /private/var on macOS)
538
+ let resolvedDir;
539
+ try {
540
+ resolvedDir = await realpath(directory);
541
+ } catch {
542
+ resolvedDir = path.resolve(directory);
543
+ }
544
+
545
+ const worktrees = await getWorktrees(directory);
546
+ // Filter out the main worktree (its path === directory or resolves to it)
547
+ const externalWorktrees = worktrees.filter(wt => path.resolve(wt.path) !== resolvedDir);
548
+
549
+ if (externalWorktrees.length > 0) {
550
+ // Use the parent directory of the first external worktree
551
+ const parentDir = path.dirname(path.resolve(externalWorktrees[0].path));
552
+ return { worktreePath: parentDir, source: 'detected' };
553
+ }
554
+
555
+ return { worktreePath: path.join(resolvedDir, '.worktrees'), source: 'default' };
556
+ }
@@ -8,9 +8,10 @@ import * as gitService from './gitService.js';
8
8
  * @param {string|null} options.gitMode - 'branch', 'worktree', or null
9
9
  * @param {string|null} options.gitBranch - Branch name
10
10
  * @param {string} options.sessionId - Session ID
11
+ * @param {string|null} [options.worktreeBasePath] - Custom base path for worktrees (overrides default .worktrees)
11
12
  * @returns {Promise<{workingDirectory: string, gitWorktree: string|null}>}
12
13
  */
13
- export async function setupGitForSession({ projectDir, gitMode, gitBranch, sessionId }) {
14
+ export async function setupGitForSession({ projectDir, gitMode, gitBranch, sessionId, worktreeBasePath }) {
14
15
  // No git operations if gitMode is not specified
15
16
  if (!gitMode || !gitBranch) {
16
17
  return {
@@ -29,8 +30,8 @@ export async function setupGitForSession({ projectDir, gitMode, gitBranch, sessi
29
30
  }
30
31
 
31
32
  if (gitMode === 'worktree') {
32
- // Create a worktree in .worktrees/{sessionId}
33
- const worktreePath = join(projectDir, '.worktrees', sessionId);
33
+ // Create a worktree in the configured base path or .worktrees/{sessionId}
34
+ const worktreePath = join(worktreeBasePath || join(projectDir, '.worktrees'), sessionId);
34
35
  await gitService.createWorktreeForBranch(projectDir, gitBranch, worktreePath);
35
36
  // Pin the human developer's git identity so they are the commit Author
36
37
  await gitService.pinAuthorInWorktree(worktreePath, projectDir);
@@ -54,6 +54,7 @@ export async function determineWorkingDirectory(parentSession, project, gitOptio
54
54
  gitMode: gitOptions.gitMode || null,
55
55
  gitBranch: gitOptions.gitBranch || null,
56
56
  sessionId: gitOptions.sessionId,
57
+ worktreeBasePath: project.worktreePath || null,
57
58
  });
58
59
  return { workingDirectory: gitSetup.workingDirectory, gitWorktree: gitSetup.gitWorktree };
59
60
  }
@@ -21,6 +21,8 @@ import {
21
21
  import { shouldRescheduleOnError, _checkProactiveReschedule } from './sessionErrors.js';
22
22
  import { schedulerService } from './schedulerService.js';
23
23
  import { buildConversationContextForModelSwitch } from './conversationContext.js';
24
+ import { broadcastToSession } from '../websocket.js';
25
+ import { WS_MESSAGE_TYPES } from '../../../shared/src/index.js';
24
26
 
25
27
  /**
26
28
  * Create the agent for a session, using gateway + logging + VCR.
@@ -243,8 +245,6 @@ async function setupConversationAndMessage(sessionId, content, fileAttachments)
243
245
  const activeConversation = conversations.ensureActiveConversation(sessionId);
244
246
  activeConversationIds.set(sessionId, activeConversation.id);
245
247
 
246
- const { broadcastToSession } = await import('../websocket.js');
247
- const { WS_MESSAGE_TYPES } = await import('@circuschief/shared');
248
248
  const message = messages.create(sessionId, 'user', content, { toolUse: null, conversationId: activeConversation.id });
249
249
  broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_MESSAGE, {
250
250
  message,
@@ -98,6 +98,7 @@ async function resolveWorkingDirectory(parentSession, project, settings, newSess
98
98
  gitMode: settings.gitMode,
99
99
  gitBranch: settings.gitBranch,
100
100
  sessionId: newSessionId,
101
+ worktreeBasePath: project.worktreePath || null,
101
102
  });
102
103
  return { workingDirectory: gitSetup.workingDirectory, gitWorktree: gitSetup.gitWorktree };
103
104
  }
@@ -9,6 +9,7 @@ export const CreateProjectRequest = z.object({
9
9
  prPollInterval: z.number().int().min(10000).optional(), // Min 10 seconds
10
10
  repoUrl: z.string().url().nullable().optional(),
11
11
  kanbanEnabled: z.boolean().optional(), // Default true
12
+ worktreePath: z.string().nullable().optional(),
12
13
  });
13
14
 
14
15
  export const UpdateProjectRequest = z.object({
@@ -20,6 +21,7 @@ export const UpdateProjectRequest = z.object({
20
21
  prPollInterval: z.number().int().min(10000).optional(), // Min 10 seconds
21
22
  repoUrl: z.string().url().nullable().optional(),
22
23
  kanbanEnabled: z.boolean().optional(),
24
+ worktreePath: z.string().nullable().optional(),
23
25
  });
24
26
 
25
27
  export const ProjectResponse = z.object({
@@ -32,6 +34,7 @@ export const ProjectResponse = z.object({
32
34
  prPollInterval: z.number().int(),
33
35
  repoUrl: z.string().url().nullable().optional(),
34
36
  kanbanEnabled: z.boolean(),
37
+ worktreePath: z.string().nullable(),
35
38
  createdAt: z.number(),
36
39
  updatedAt: z.number(),
37
40
  });
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  /**
10
- * @typedef {'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-haiku-4-5-20251001'} ClaudeModel
10
+ * @typedef {'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7' | 'claude-haiku-4-5-20251001'} ClaudeModel
11
11
  */
12
12
 
13
13
  /**
@@ -117,9 +117,10 @@ export const TOOL_TEMPLATE_PAYLOAD_TYPES = ['command', 'prompt'];
117
117
  export const CLAUDE_MODELS = [
118
118
  { id: 'claude-haiku-4-5-20251001', name: 'Haiku 4.5', description: 'Fast & lightweight' },
119
119
  { id: 'claude-sonnet-4-6', name: 'Sonnet 4.6', description: 'Balanced' },
120
- { id: 'claude-opus-4-6', name: 'Opus 4.6', description: 'Most capable (default)' },
120
+ { id: 'claude-opus-4-6', name: 'Opus 4.6', description: 'Previous generation' },
121
+ { id: 'claude-opus-4-7', name: 'Opus 4.7', description: 'Most capable (default)' },
121
122
  ];
122
- export const DEFAULT_MODEL = 'claude-opus-4-6';
123
+ export const DEFAULT_MODEL = 'claude-opus-4-7';
123
124
 
124
125
  /**
125
126
  * @typedef {Object} KanbanBoard
@@ -0,0 +1 @@
1
+ .page-header[data-v-9a53578e]{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:2rem}.page-header h1[data-v-9a53578e]{margin:0}.page-description[data-v-9a53578e]{margin:.25rem 0 0;font-size:.875rem;color:var(--color-text-soft)}.skeleton-list[data-v-9a53578e]{display:flex;flex-direction:column;gap:1rem}.error-message[data-v-9a53578e]{color:var(--color-error);padding:1rem;background-color:#f851491a;border-radius:var(--border-radius)}.empty-state[data-v-9a53578e]{text-align:center;padding:3rem;color:var(--color-text-soft)}.empty-state p[data-v-9a53578e]{margin-bottom:1rem}.session-list[data-v-9a53578e]{display:flex;flex-direction:column;gap:1rem}.status-filters[data-v-9a53578e]{display:flex;align-items:center;gap:.5rem;margin-bottom:1rem}.filter-label[data-v-9a53578e]{font-size:.875rem;color:var(--color-text-soft)}.filter-btn[data-v-9a53578e]{background:none;border:1px solid var(--color-border);padding:.375rem .75rem;font-size:.8rem;color:var(--color-text-soft);cursor:pointer;border-radius:var(--border-radius);transition:all .15s;text-transform:capitalize}.filter-btn[data-v-9a53578e]:hover{border-color:var(--color-primary);color:var(--color-text)}.star-icon[data-v-9a53578e]{position:relative;display:inline-block}.filter-btn.star-filter-all[data-v-9a53578e]{background:transparent;border-color:var(--color-border);color:var(--color-text-soft)}.filter-btn.star-filter-all[data-v-9a53578e]:hover{border-color:var(--color-primary);color:var(--color-text)}.filter-btn.star-filter-active[data-v-9a53578e],.filter-btn.active[data-v-9a53578e]{background:var(--color-primary);border-color:var(--color-primary);color:#fff}.filter-btn.star-filter-unstarred[data-v-9a53578e]{background:transparent;border-color:#f97316;color:#f97316}.star-crossed[data-v-9a53578e]:after{content:"";position:absolute;top:50%;left:-10%;right:-10%;height:2px;background:currentColor;transform:translateY(-50%) rotate(-45deg);pointer-events:none}
@@ -0,0 +1 @@
1
+ import{u as K}from"./sessions-GqIMf9RF.js";import{u as Q}from"./commandButtons-BqI7V84_.js";import{z as j,W as c,_ as X,o as Z,A as ee,l as te,a,c as l,b as f,F as A,r as C,E as O,u as S,t as b,d as se,w as re,f as ne,x as D,g as oe,n as ie,y as R,G as ae}from"./index-MnvuyUxj.js";import{a as x}from"./ApiClient-CcqJ-GAv.js";import{S as le}from"./SessionCard-D9a5ABHO.js";import"./settings-j6pMR_H2.js";import"./SessionLogStream-DMUzZOml.js";function ce(){const{on:E,off:s}=j(),d=h=>p=>{const i=F=>{F.session&&p(F.session,F.projectId)};return E(h,i),()=>s(h,i)},I=d(c.SESSION_CREATED),w=d(c.SESSION_UPDATED);return{onSessionCreated:I,onSessionUpdated:w,onSessionDeleted:h=>{const p=i=>{i.sessionId&&h(i.sessionId,i.projectId)};return E(c.SESSION_DELETED,p),()=>s(c.SESSION_DELETED,p)},onSessionSummaryUpdated:h=>{const p=i=>{i.sessionId&&i.summary&&h(i.sessionId,i.summary,i.projectId)};return E(c.SESSION_SUMMARY_UPDATED,p),()=>s(c.SESSION_SUMMARY_UPDATED,p)}}}const de=["data-state"],ue={class:"filters-container"},fe={class:"status-filters"},Se=["onClick"],pe=["title"],me={key:0,class:"star-icon"},he={key:1,class:"star-icon star-crossed"},_e={key:2,class:"star-icon"},ye={key:0,class:"skeleton-list"},ve={key:1,class:"error-message"},Fe={key:2,class:"empty-state","data-testid":"active-sessions-empty"},Ee={key:3,class:"empty-state","data-testid":"active-sessions-empty"},Ie={key:4,class:"session-list"},we={__name:"ActiveSessionsView",setup(E){const s=K(),d=Q(),I=["waiting","stopped","error"],w=["running","starting"],v=ie(new Set),g=e=>{s.statusFilter===e?s.setStatusFilter(null):s.setStatusFilter(e)},h=()=>{s.starredFilter===null?s.setStarredFilter("starred"):s.starredFilter==="starred"?s.setStarredFilter("unstarred"):s.setStarredFilter(null)},p=D(()=>s.starredFilter==="starred"?"Showing starred sessions only. Click to filter unstarred.":s.starredFilter==="unstarred"?"Showing unstarred sessions only. Click to show all.":"Showing all sessions. Click to filter by starred."),i=D(()=>{let e=s.activeSessions;return s.statusFilter&&(e=e.filter(t=>{const r=t.status;return!!(s.statusFilter==="idle"&&I.includes(r)||s.statusFilter==="running"&&w.includes(r))})),s.starredFilter==="starred"?e=e.filter(t=>t.starred):s.starredFilter==="unstarred"&&(e=e.filter(t=>!t.starred)),e}),F=D(()=>s.loading?"loading":s.error?"error":s.activeSessions.length===0?"empty-all":i.value.length===0?"empty-filtered":"results"),_=R({}),u=R({}),m=R({});let N=null;const y=[],{onSessionCreated:P,onSessionUpdated:B,onSessionDeleted:L,onSessionSummaryUpdated:V}=ce();async function M(){const e=new Set(s.activeSessions.map(t=>t.projectId).filter(t=>t&&!v.value.has(t)));for(const t of e)try{await d.fetchButtons(t),await d.fetchLatestRunsForProject(t),v.value.add(t)}catch(r){console.error(`Failed to fetch buttons for project ${t}:`,r)}}function U(e,t,r){d.runs[e]||(d.runs[e]={runId:e,buttonId:t,sessionId:r,status:"running",output:"",exitCode:null,startedAt:Date.now(),outputTruncated:!1})}function H(e){["running","waiting","starting"].includes(e.status)&&(s.activeSessions.some(r=>r.id===e.id)||(s.activeSessions.unshift(e),e.projectId&&!v.value.has(e.projectId)&&(d.fetchButtons(e.projectId),v.value.add(e.projectId))))}function G(e){const t=["running","waiting","starting"].includes(e.status),r=s.activeSessions.findIndex(n=>n.id===e.id);t?r>=0?s.activeSessions[r]=e:s.activeSessions.unshift(e):r>=0&&(s.activeSessions.splice(r,1),delete _[e.id],delete u[e.id],delete m[e.id])}function W(e){const t=s.activeSessions.findIndex(r=>r.id===e);t>=0&&s.activeSessions.splice(t,1),delete _[e],delete u[e],delete m[e]}function Y(e,t){_[e]=t,u[e]=!1,m[e]=!1}function $(e,t,r){const n=o=>{U(o.runId,o.buttonId,o.sessionId),d.appendOutput(o.runId,o.output)};e(c.COMMAND_RUN_OUTPUT,n),r.push(()=>t(c.COMMAND_RUN_OUTPUT,n));const k=o=>{U(o.runId,o.buttonId,o.sessionId),d.completeRun(o.runId,o.exitCode,o.output)};e(c.COMMAND_RUN_COMPLETE,k),r.push(()=>t(c.COMMAND_RUN_COMPLETE,k));const T=o=>{U(o.runId,o.buttonId,o.sessionId),d.errorRun(o.runId,o.error)};e(c.COMMAND_RUN_ERROR,T),r.push(()=>t(c.COMMAND_RUN_ERROR,T))}Z(async()=>{s.restoreStatusFilter(),s.restoreStarredFilter(),await s.fetchActiveSessions(),await M(),y.push(P(H)),y.push(B(G)),y.push(L(W)),y.push(V(Y));const{on:e,off:t}=j();$(e,t,y),N=setInterval(()=>{s.fetchActiveSessions(!1)},3e4)}),ee(()=>{y.forEach(e=>e()),N&&clearInterval(N)}),te(()=>s.activeSessions,()=>{z(),M()},{immediate:!0});async function z(){const t=s.activeSessions.filter(r=>!_[r.id]&&!u[r.id]).map(r=>r.id);if(t.length!==0){for(const r of t)u[r]=!0,m[r]=!1;try{const r=await x.getSessionSummariesBatch(t);for(const n of t)r[n]&&(_[n]=r[n]),u[n]=!1}catch(r){console.warn("Failed to fetch summaries batch:",r.message);for(const n of t)m[n]=!0,u[n]=!1}}}async function q(e){var t;u[e]=!0,m[e]=!1;try{const r=await x.getSessionSummary(e);r&&(_[e]=r)}catch(r){((t=r.response)==null?void 0:t.status)!==404&&(console.warn(`Failed to fetch summary for session ${e}:`,r.message),m[e]=!0)}finally{u[e]=!1}}async function J(e){m[e]=!1,await q(e)}return(e,t)=>{const r=oe("router-link");return a(),l("div",{class:"container","data-testid":"active-sessions-view","data-state":F.value},[t[3]||(t[3]=f("div",{class:"page-header"},[f("div",null,[f("p",{class:"page-description"}," All active sessions across your projects ")])],-1)),f("div",ue,[f("div",fe,[(a(),l(A,null,C(["running","idle"],n=>f("button",{key:n,class:O(["filter-btn",{active:S(s).statusFilter===n}]),onClick:k=>g(n)},b(n),11,Se)),64)),f("button",{class:O(["filter-btn star-btn",{"star-filter-active":S(s).starredFilter==="starred","star-filter-unstarred":S(s).starredFilter==="unstarred","star-filter-all":S(s).starredFilter===null}]),title:p.value,onClick:h},[S(s).starredFilter==="starred"?(a(),l("span",me,"⭐")):S(s).starredFilter==="unstarred"?(a(),l("span",he,"⭐")):(a(),l("span",_e,"☆"))],10,pe)])]),S(s).loading?(a(),l("div",ye,[(a(),l(A,null,C(3,n=>f("div",{key:n,class:"skeleton card",style:{height:"120px"}})),64))])):S(s).error?(a(),l("div",ve,b(S(s).error),1)):S(s).activeSessions.length===0?(a(),l("div",Fe,[t[1]||(t[1]=f("p",null,"No active sessions. All sessions are completed or there are no sessions yet.",-1)),se(r,{to:"/",class:"btn btn-primary"},{default:re(()=>[...t[0]||(t[0]=[ne(" View Projects ",-1)])]),_:1})])):i.value.length===0?(a(),l("div",Ee,[...t[2]||(t[2]=[f("p",null,"No sessions match the current filter.",-1)])])):(a(),l("div",Ie,[(a(!0),l(A,null,C(i.value,n=>(a(),ae(le,{key:n.id,session:n,"show-project":!0,"show-summary":!0,summary:_[n.id],"summary-loading":u[n.id],"summary-error":m[n.id],onRetrySummary:J},null,8,["session","summary","summary-loading","summary-error"]))),128))]))],8,de)}}},ge=X(we,[["__scopeId","data-v-9a53578e"]]);export{ge as default};
@@ -1,2 +1,2 @@
1
- import{L as q,_ as O,a as r,c as i,b as t,F as k,r as $,t as f,k as _,E as A,x as p,f as W,e as F,G as z,w as G,o as H,A as J,d as w,u as m,l as B}from"./index-DxUd3T5E.js";import{a as L}from"./ApiClient-Dbs1H78V.js";const U=q("agentLogs",{state:()=>({logs:[],pagination:{total:0,limit:25,offset:0,hasMore:!1},filters:{agentType:null,callType:null,status:null,model:null,startDate:null,endDate:null,sessionId:null},filterOptions:{agentTypes:[],callTypes:[],statuses:[],models:[]},perPage:25,currentPage:1,sortBy:"started_at",sortOrder:"DESC",loading:!1,error:null}),getters:{totalPages:s=>Math.ceil(s.pagination.total/s.perPage)||0,activeFilters:s=>{const e={};for(const[y,h]of Object.entries(s.filters))h!=null&&(e[y]=h);return e}},actions:{async fetchLogs(){this.loading=!0,this.error=null;try{const s=(this.currentPage-1)*this.perPage,e=await L.getAgentCallLogs({limit:this.perPage,offset:s,...this.activeFilters,sortBy:this.sortBy,sortOrder:this.sortOrder});this.logs=e.logs,this.pagination=e.pagination}catch(s){this.error=s.message}finally{this.loading=!1}},async fetchFilterOptions(){try{const s=await L.getAgentCallFilterOptions();this.filterOptions=s}catch(s){console.error("Failed to fetch filter options:",s)}},setFilter(s,e){this.filters[s]=e||null,this.currentPage=1,this.fetchLogs()},clearFilters(){Object.keys(this.filters).forEach(s=>this.filters[s]=null),this.currentPage=1,this.fetchLogs()},setPage(s){this.currentPage=s,this.fetchLogs()},setPerPage(s){this.perPage=s,this.currentPage=1,this.fetchLogs()},setSort(s,e){this.sortBy=s,this.sortOrder=e,this.currentPage=1,this.fetchLogs()},async clearAllLogs(){this.loading=!0,this.error=null;try{await L.deleteAllAgentCallLogs(),this.logs=[],this.pagination={total:0,limit:this.perPage,offset:0,hasMore:!1},this.currentPage=1,await this.fetchFilterOptions()}catch(s){this.error=s.message}finally{this.loading=!1}}}}),Z={class:"filter-bar"},Q={class:"filter-row"},X={class:"filter-group"},Y=["value"],K={class:"filter-group"},tt=["value"],et={class:"filter-group"},st=["value"],lt=["value"],at={class:"filter-group"},nt=["value"],ot=["value"],rt={class:"filter-group"},it=["value"],ut=["value"],dt={class:"filter-group"},ct=["value"],ft=["value"],gt={__name:"AgentLogFilters",props:{filters:{type:Object,required:!0},filterOptions:{type:Object,required:!0},hasActiveFilters:{type:Boolean,default:!1},confirming:{type:Boolean,default:!1}},emits:["filter-change","date-change","clear-filters","clear-all"],setup(s){const e=s;function y(v){return new Date(v).toISOString().slice(0,10)}const h=p(()=>e.filters.startDate?y(e.filters.startDate):""),b=p(()=>e.filters.endDate?y(e.filters.endDate):"");return(v,a)=>(r(),i("div",Z,[t("div",Q,[t("div",X,[a[8]||(a[8]=t("label",{class:"filter-label"},"From",-1)),t("input",{type:"date",class:"filter-input",value:h.value,onChange:a[0]||(a[0]=n=>v.$emit("date-change","startDate",n))},null,40,Y)]),t("div",K,[a[9]||(a[9]=t("label",{class:"filter-label"},"To",-1)),t("input",{type:"date",class:"filter-input",value:b.value,onChange:a[1]||(a[1]=n=>v.$emit("date-change","endDate",n))},null,40,tt)]),t("div",et,[a[11]||(a[11]=t("label",{class:"filter-label"},"Agent Type",-1)),t("select",{class:"filter-select",value:s.filters.agentType||"",onChange:a[2]||(a[2]=n=>v.$emit("filter-change","agentType",n.target.value))},[a[10]||(a[10]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.agentTypes,n=>(r(),i("option",{key:n,value:n},f(n),9,lt))),128))],40,st)]),t("div",at,[a[13]||(a[13]=t("label",{class:"filter-label"},"Call Type",-1)),t("select",{class:"filter-select",value:s.filters.callType||"",onChange:a[3]||(a[3]=n=>v.$emit("filter-change","callType",n.target.value))},[a[12]||(a[12]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.callTypes,n=>(r(),i("option",{key:n,value:n},f(n),9,ot))),128))],40,nt)]),t("div",rt,[a[15]||(a[15]=t("label",{class:"filter-label"},"Status",-1)),t("select",{class:"filter-select",value:s.filters.status||"",onChange:a[4]||(a[4]=n=>v.$emit("filter-change","status",n.target.value))},[a[14]||(a[14]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.statuses,n=>(r(),i("option",{key:n,value:n},f(n),9,ut))),128))],40,it)]),t("div",dt,[a[17]||(a[17]=t("label",{class:"filter-label"},"Model",-1)),t("select",{class:"filter-select",value:s.filters.model||"",onChange:a[5]||(a[5]=n=>v.$emit("filter-change","model",n.target.value))},[a[16]||(a[16]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.models,n=>(r(),i("option",{key:n,value:n},f(n),9,ft))),128))],40,ct)]),s.hasActiveFilters?(r(),i("button",{key:0,class:"btn-clear",onClick:a[6]||(a[6]=n=>v.$emit("clear-filters"))}," Clear Filters ")):_("",!0),t("button",{class:A(["btn-clear-all",{confirming:s.confirming}]),onClick:a[7]||(a[7]=n=>v.$emit("clear-all"))},f(s.confirming?"Confirm Clear All?":"Clear All Logs"),3)])]))}},vt=O(gt,[["__scopeId","data-v-780329d3"]]),pt={class:"table-wrapper"},ht={key:0,class:"loading-overlay"},yt={class:"log-table"},bt=["onClick"],mt={key:0,class:"sort-indicator"},kt={key:0},$t=["colspan"],Ct={class:"td"},_t={class:"status-text"},Tt={class:"td font-mono text-sm"},At={class:"td font-mono text-sm"},Pt={class:"td model-cell"},Lt={class:"td"},Ot={key:1},St={class:"td"},Dt={key:1},Ft=["title"],wt={class:"td text-right"},Bt=["title"],Mt={__name:"AgentLogTable",props:{logs:{type:Array,required:!0},loading:{type:Boolean,default:!1},sortBy:{type:String,default:"started_at"},sortOrder:{type:String,default:"DESC"}},emits:["sort"],setup(s){const e=[{key:"status",label:"Status",sortable:!0},{key:"agent_type",label:"Agent Type",sortable:!0},{key:"call_type",label:"Call Type",sortable:!0},{key:"model",label:"Model",sortable:!0},{key:"session",label:"Session",sortable:!1},{key:"effort",label:"Effort",sortable:!1},{key:"total_tokens",label:"Tokens",sortable:!0},{key:"duration_ms",label:"Duration",sortable:!0},{key:"started_at",label:"Started",sortable:!0}];function y(l){switch(l){case"completed":return"dot-completed";case"error":return"dot-error";case"streaming":case"pending":return"dot-pending";default:return"dot-default"}}function h(l){const d=[];return l.inputTokens&&d.push(`Input: ${b(l.inputTokens)}`),l.outputTokens&&d.push(`Output: ${b(l.outputTokens)}`),l.thinkingTokens&&d.push(`Thinking: ${b(l.thinkingTokens)}`),l.cacheReadTokens&&d.push(`Cache Read: ${b(l.cacheReadTokens)}`),l.cacheWriteTokens&&d.push(`Cache Write: ${b(l.cacheWriteTokens)}`),d.join(`
1
+ import{L as q,_ as O,a as r,c as i,b as t,F as k,r as $,t as f,i as _,E as A,x as p,g as W,f as F,G as z,w as G,o as H,A as J,d as w,u as m,n as B}from"./index-MnvuyUxj.js";import{a as L}from"./ApiClient-CcqJ-GAv.js";const U=q("agentLogs",{state:()=>({logs:[],pagination:{total:0,limit:25,offset:0,hasMore:!1},filters:{agentType:null,callType:null,status:null,model:null,startDate:null,endDate:null,sessionId:null},filterOptions:{agentTypes:[],callTypes:[],statuses:[],models:[]},perPage:25,currentPage:1,sortBy:"started_at",sortOrder:"DESC",loading:!1,error:null}),getters:{totalPages:s=>Math.ceil(s.pagination.total/s.perPage)||0,activeFilters:s=>{const e={};for(const[y,h]of Object.entries(s.filters))h!=null&&(e[y]=h);return e}},actions:{async fetchLogs(){this.loading=!0,this.error=null;try{const s=(this.currentPage-1)*this.perPage,e=await L.getAgentCallLogs({limit:this.perPage,offset:s,...this.activeFilters,sortBy:this.sortBy,sortOrder:this.sortOrder});this.logs=e.logs,this.pagination=e.pagination}catch(s){this.error=s.message}finally{this.loading=!1}},async fetchFilterOptions(){try{const s=await L.getAgentCallFilterOptions();this.filterOptions=s}catch(s){console.error("Failed to fetch filter options:",s)}},setFilter(s,e){this.filters[s]=e||null,this.currentPage=1,this.fetchLogs()},clearFilters(){Object.keys(this.filters).forEach(s=>this.filters[s]=null),this.currentPage=1,this.fetchLogs()},setPage(s){this.currentPage=s,this.fetchLogs()},setPerPage(s){this.perPage=s,this.currentPage=1,this.fetchLogs()},setSort(s,e){this.sortBy=s,this.sortOrder=e,this.currentPage=1,this.fetchLogs()},async clearAllLogs(){this.loading=!0,this.error=null;try{await L.deleteAllAgentCallLogs(),this.logs=[],this.pagination={total:0,limit:this.perPage,offset:0,hasMore:!1},this.currentPage=1,await this.fetchFilterOptions()}catch(s){this.error=s.message}finally{this.loading=!1}}}}),Z={class:"filter-bar"},Q={class:"filter-row"},X={class:"filter-group"},Y=["value"],K={class:"filter-group"},tt=["value"],et={class:"filter-group"},st=["value"],lt=["value"],at={class:"filter-group"},nt=["value"],ot=["value"],rt={class:"filter-group"},it=["value"],ut=["value"],dt={class:"filter-group"},ct=["value"],ft=["value"],gt={__name:"AgentLogFilters",props:{filters:{type:Object,required:!0},filterOptions:{type:Object,required:!0},hasActiveFilters:{type:Boolean,default:!1},confirming:{type:Boolean,default:!1}},emits:["filter-change","date-change","clear-filters","clear-all"],setup(s){const e=s;function y(v){return new Date(v).toISOString().slice(0,10)}const h=p(()=>e.filters.startDate?y(e.filters.startDate):""),b=p(()=>e.filters.endDate?y(e.filters.endDate):"");return(v,a)=>(r(),i("div",Z,[t("div",Q,[t("div",X,[a[8]||(a[8]=t("label",{class:"filter-label"},"From",-1)),t("input",{type:"date",class:"filter-input",value:h.value,onChange:a[0]||(a[0]=n=>v.$emit("date-change","startDate",n))},null,40,Y)]),t("div",K,[a[9]||(a[9]=t("label",{class:"filter-label"},"To",-1)),t("input",{type:"date",class:"filter-input",value:b.value,onChange:a[1]||(a[1]=n=>v.$emit("date-change","endDate",n))},null,40,tt)]),t("div",et,[a[11]||(a[11]=t("label",{class:"filter-label"},"Agent Type",-1)),t("select",{class:"filter-select",value:s.filters.agentType||"",onChange:a[2]||(a[2]=n=>v.$emit("filter-change","agentType",n.target.value))},[a[10]||(a[10]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.agentTypes,n=>(r(),i("option",{key:n,value:n},f(n),9,lt))),128))],40,st)]),t("div",at,[a[13]||(a[13]=t("label",{class:"filter-label"},"Call Type",-1)),t("select",{class:"filter-select",value:s.filters.callType||"",onChange:a[3]||(a[3]=n=>v.$emit("filter-change","callType",n.target.value))},[a[12]||(a[12]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.callTypes,n=>(r(),i("option",{key:n,value:n},f(n),9,ot))),128))],40,nt)]),t("div",rt,[a[15]||(a[15]=t("label",{class:"filter-label"},"Status",-1)),t("select",{class:"filter-select",value:s.filters.status||"",onChange:a[4]||(a[4]=n=>v.$emit("filter-change","status",n.target.value))},[a[14]||(a[14]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.statuses,n=>(r(),i("option",{key:n,value:n},f(n),9,ut))),128))],40,it)]),t("div",dt,[a[17]||(a[17]=t("label",{class:"filter-label"},"Model",-1)),t("select",{class:"filter-select",value:s.filters.model||"",onChange:a[5]||(a[5]=n=>v.$emit("filter-change","model",n.target.value))},[a[16]||(a[16]=t("option",{value:""}," All ",-1)),(r(!0),i(k,null,$(s.filterOptions.models,n=>(r(),i("option",{key:n,value:n},f(n),9,ft))),128))],40,ct)]),s.hasActiveFilters?(r(),i("button",{key:0,class:"btn-clear",onClick:a[6]||(a[6]=n=>v.$emit("clear-filters"))}," Clear Filters ")):_("",!0),t("button",{class:A(["btn-clear-all",{confirming:s.confirming}]),onClick:a[7]||(a[7]=n=>v.$emit("clear-all"))},f(s.confirming?"Confirm Clear All?":"Clear All Logs"),3)])]))}},vt=O(gt,[["__scopeId","data-v-780329d3"]]),pt={class:"table-wrapper"},ht={key:0,class:"loading-overlay"},yt={class:"log-table"},bt=["onClick"],mt={key:0,class:"sort-indicator"},kt={key:0},$t=["colspan"],Ct={class:"td"},_t={class:"status-text"},Tt={class:"td font-mono text-sm"},At={class:"td font-mono text-sm"},Pt={class:"td model-cell"},Lt={class:"td"},Ot={key:1},St={class:"td"},Dt={key:1},Ft=["title"],wt={class:"td text-right"},Bt=["title"],Mt={__name:"AgentLogTable",props:{logs:{type:Array,required:!0},loading:{type:Boolean,default:!1},sortBy:{type:String,default:"started_at"},sortOrder:{type:String,default:"DESC"}},emits:["sort"],setup(s){const e=[{key:"status",label:"Status",sortable:!0},{key:"agent_type",label:"Agent Type",sortable:!0},{key:"call_type",label:"Call Type",sortable:!0},{key:"model",label:"Model",sortable:!0},{key:"session",label:"Session",sortable:!1},{key:"effort",label:"Effort",sortable:!1},{key:"total_tokens",label:"Tokens",sortable:!0},{key:"duration_ms",label:"Duration",sortable:!0},{key:"started_at",label:"Started",sortable:!0}];function y(l){switch(l){case"completed":return"dot-completed";case"error":return"dot-error";case"streaming":case"pending":return"dot-pending";default:return"dot-default"}}function h(l){const d=[];return l.inputTokens&&d.push(`Input: ${b(l.inputTokens)}`),l.outputTokens&&d.push(`Output: ${b(l.outputTokens)}`),l.thinkingTokens&&d.push(`Thinking: ${b(l.thinkingTokens)}`),l.cacheReadTokens&&d.push(`Cache Read: ${b(l.cacheReadTokens)}`),l.cacheWriteTokens&&d.push(`Cache Write: ${b(l.cacheWriteTokens)}`),d.join(`
2
2
  `)||"No token data"}function b(l){return l==null||l===0?"0":l.toLocaleString()}function v(l){if(l==null)return"—";if(l<1e3)return`${l}ms`;if(l<6e4)return`${(l/1e3).toFixed(1)}s`;const d=Math.floor(l/6e4),C=Math.floor(l%6e4/1e3);return`${d}m ${C}s`}function a(l){const d=Date.now()-l;return d<6e4?"just now":d<36e5?`${Math.floor(d/6e4)}m ago`:d<864e5?`${Math.floor(d/36e5)}h ago`:`${Math.floor(d/864e5)}d ago`}function n(l){try{if(l.metadata)return(typeof l.metadata=="string"?JSON.parse(l.metadata):l.metadata).effortLevel||null}catch{}return null}function P(l){return{auto:"Auto",low:"Low",medium:"Med",high:"High",max:"Max"}[l]||l}return(l,d)=>{const C=W("router-link");return r(),i("div",pt,[s.loading?(r(),i("div",ht,[...d[0]||(d[0]=[t("div",{class:"spinner"},null,-1)])])):_("",!0),t("table",yt,[t("thead",null,[t("tr",null,[(r(),i(k,null,$(e,o=>t("th",{key:o.key,class:A(["th",o.sortable?"sortable":""]),onClick:S=>o.sortable?l.$emit("sort",o.key):null},[F(f(o.label)+" ",1),o.sortable&&s.sortBy===o.key?(r(),i("span",mt,f(s.sortOrder==="ASC"?"↑":"↓"),1)):_("",!0)],10,bt)),64))])]),t("tbody",null,[!s.loading&&s.logs.length===0?(r(),i("tr",kt,[t("td",{colspan:e.length,class:"empty-cell"}," No agent call logs found. ",8,$t)])):_("",!0),(r(!0),i(k,null,$(s.logs,o=>(r(),i("tr",{key:o.id,class:"log-row"},[t("td",Ct,[t("span",{class:A(["status-dot",y(o.status)])},null,2),t("span",_t,f(o.status),1)]),t("td",Tt,f(o.agentType||"—"),1),t("td",At,f(o.callType||"—"),1),t("td",Pt,f(o.model||"—"),1),t("td",Lt,[o.sessionId?(r(),z(C,{key:0,to:`/sessions/${o.sessionId}`,class:"session-link"},{default:G(()=>[F(f(o.sessionName||o.sessionId),1)]),_:2},1032,["to"])):(r(),i("span",Ot,"—"))]),t("td",St,[n(o)?(r(),i("span",{key:0,class:A(["effort-badge",`effort-${n(o)}`])},f(P(n(o))),3)):(r(),i("span",Dt,"—"))]),t("td",{class:"td text-right",title:h(o)},f(b(o.totalTokens)),9,Ft),t("td",wt,f(v(o.durationMs)),1),t("td",{class:"td text-right",title:o.startedAt?new Date(o.startedAt).toLocaleString():""},f(o.startedAt?a(o.startedAt):"—"),9,Bt)]))),128))])])])}}},It=O(Mt,[["__scopeId","data-v-20d5856a"]]),Et={class:"agent-logs"},Nt={key:0,class:"error-banner"},Vt={key:1,class:"pagination-bar"},xt={class:"per-page-control"},jt=["value"],Rt=["value"],qt={class:"page-info"},Wt={class:"page-buttons"},zt=["disabled"],Gt=["disabled"],Ht={key:0,class:"page-ellipsis"},Jt=["onClick"],Ut=["disabled"],Zt=["disabled"],Qt={__name:"AgentLogsView",setup(s){const e=U(),y=B(!1),h=B(null),b=p(()=>e.logs),v=p(()=>e.pagination),a=p(()=>e.filters),n=p(()=>e.filterOptions),P=p(()=>e.perPage),l=p(()=>e.currentPage),d=p(()=>e.totalPages),C=p(()=>e.sortBy),o=p(()=>e.sortOrder),S=p(()=>e.loading),D=p(()=>e.error),M=p(()=>Object.values(e.filters).some(g=>g!=null)),I=p(()=>v.value.total===0?0:v.value.offset+1),E=p(()=>Math.min(v.value.offset+P.value,v.value.total)),N=p(()=>{const g=d.value,c=l.value;if(g<=7)return Array.from({length:g},(T,R)=>R+1);const u=[];return c<=4?u.push(1,2,3,4,5,"...",g):c>=g-3?u.push(1,"...",g-4,g-3,g-2,g-1,g):u.push(1,"...",c-1,c,c+1,"...",g),u});function V(g){C.value===g?e.setSort(g,o.value==="ASC"?"DESC":"ASC"):e.setSort(g,"DESC")}function x(g,c){const u=c.target.value;if(!u){e.setFilter(g,null);return}const T=new Date(`${u}T00:00:00Z`).getTime();e.filters[g]=T,e.currentPage=1,e.fetchLogs()}function j(){y.value?(h.value&&(clearTimeout(h.value),h.value=null),y.value=!1,e.clearAllLogs()):(y.value=!0,h.value=setTimeout(()=>{y.value=!1,h.value=null},3e3))}return H(()=>{e.fetchLogs(),e.fetchFilterOptions()}),J(()=>{h.value&&clearTimeout(h.value)}),(g,c)=>(r(),i("div",Et,[w(vt,{filters:a.value,"filter-options":n.value,"has-active-filters":M.value,confirming:y.value,onFilterChange:c[0]||(c[0]=(u,T)=>m(e).setFilter(u,T)),onDateChange:x,onClearFilters:c[1]||(c[1]=u=>m(e).clearFilters()),onClearAll:j},null,8,["filters","filter-options","has-active-filters","confirming"]),D.value?(r(),i("div",Nt,[t("span",null,f(D.value),1),t("button",{class:"btn-retry",onClick:c[2]||(c[2]=u=>m(e).fetchLogs())}," Retry ")])):_("",!0),w(It,{logs:b.value,loading:S.value,"sort-by":C.value,"sort-order":o.value,onSort:V},null,8,["logs","loading","sort-by","sort-order"]),v.value.total>0?(r(),i("div",Vt,[t("div",xt,[c[8]||(c[8]=t("label",{class:"filter-label"},"Per page",-1)),t("select",{class:"filter-select per-page-select",value:P.value,onChange:c[3]||(c[3]=u=>m(e).setPerPage(parseInt(u.target.value)))},[(r(),i(k,null,$([10,25,50,100],u=>t("option",{key:u,value:u},f(u),9,Rt)),64))],40,jt)]),t("div",qt," Showing "+f(I.value)+"–"+f(E.value)+" of "+f(v.value.total)+" logs ",1),t("div",Wt,[t("button",{class:"page-btn",disabled:l.value===1,onClick:c[4]||(c[4]=u=>m(e).setPage(1))}," « ",8,zt),t("button",{class:"page-btn",disabled:l.value===1,onClick:c[5]||(c[5]=u=>m(e).setPage(l.value-1))}," ‹ ",8,Gt),(r(!0),i(k,null,$(N.value,u=>(r(),i(k,{key:u},[u==="..."?(r(),i("span",Ht,"…")):(r(),i("button",{key:1,class:A(["page-btn",{"page-btn-active":u===l.value}]),onClick:T=>m(e).setPage(u)},f(u),11,Jt))],64))),128)),t("button",{class:"page-btn",disabled:l.value===d.value,onClick:c[6]||(c[6]=u=>m(e).setPage(l.value+1))}," › ",8,Ut),t("button",{class:"page-btn",disabled:l.value===d.value,onClick:c[7]||(c[7]=u=>m(e).setPage(d.value))}," » ",8,Zt)])])):_("",!0)]))}},Kt=O(Qt,[["__scopeId","data-v-e1df2011"]]);export{Kt as default};
@@ -1 +1 @@
1
- var b=n=>{throw TypeError(n)};var g=(n,e,s)=>e.has(n)||b("Cannot "+s);var h=(n,e,s)=>(g(n,e,"read from private field"),s?s.call(n):e.get(n)),y=(n,e,s)=>e.has(n)?b("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,s),C=(n,e,s,t)=>(g(n,e,"write to private field"),t?t.call(n,s):e.set(n,s),s),l=(n,e,s)=>(g(n,e,"access private method"),s);function j(n){Object.assign(n.prototype,{async getProjects(){return this._get("/projects")},async getProject(e){return this._get(`/projects/${e}`)},async createProject(e){return this._post("/projects",e)},async updateProject(e,s){return this._put(`/projects/${e}`,s)},async deleteProject(e){return this._delete(`/projects/${e}`)}})}function S(n,e,s){for(const t of s)e[t]!==void 0&&e[t]!==null&&n.append(t,e[t])}function k(n,e,s){for(const t of s)e[t]!==void 0&&e[t]!==null&&n.append(t,String(e[t]))}function P(n,e){const s=new FormData;s.append("prompt",n.prompt),S(s,n,["name","mode","model","effortLevel","gitBranch","gitMode","templateId","parentSessionId"]),k(s,n,["thinkingEnabled","startImmediately","autoRescheduleEnabled","rescheduleOnTokenLimit","rescheduleOnServiceError"]),S(s,n,["scheduledAt","rescheduleDelayMinutes","maxRescheduleCount","maxTotalTokens","rescheduleAtTokenCount"]);for(const t of e)s.append("files",t);return s}function T(n){Object.assign(n.prototype,{async getActiveSessions(){return this._get("/sessions")},async getScheduledSessions(e=null){return this._get(this._buildQueryPath("/sessions/scheduled",{projectId:e||void 0}))},async getProjectSessions(e,s=null,t=null,{limit:r=null,offset:a=0}={}){const o={};return s!==null&&(o.archived=s),t==="starred"?o.starred=!0:t==="unstarred"&&(o.starred=!1),r!==null&&(o.limit=r,o.offset=a),this._get(this._buildQueryPath(`/projects/${e}/sessions`,o))},async createSession(e,s){const{files:t,...r}=s;if(t&&t.length>0){const a=P(r,t);return this._uploadFormData(`/projects/${e}/sessions`,a)}return this._post(`/projects/${e}/sessions`,r)},async getSession(e){return this._get(`/sessions/${e}`)},async getSessionMessages(e){return this._get(`/sessions/${e}/messages`)},async getSessionWorkLogs(e){return this._get(`/sessions/${e}/work-logs`)},async sendMessage(e,s,t=[],r=null){if(console.log(`[MODEL AUDIT - ApiClient] sendMessage called with model: "${r}"`),t&&t.length>0){const a=new FormData;a.append("content",s),r&&a.append("model",r);for(const o of t)a.append("files",o);return this._uploadFormData(`/sessions/${e}/message`,a)}return this._post(`/sessions/${e}/message`,{content:s,model:r})},async stopSession(e){return this._post(`/sessions/${e}/stop`)},async getSessionChanges(e,s="local",t=null){const r={};return s==="branch"&&(r.compareMode="branch",t&&(r.branch=t)),this._get(this._buildQueryPath(`/sessions/${e}/changes`,r))},async getSessionDefaultBranch(e){return this._get(`/sessions/${e}/default-branch`)},async getSessionFilesCount(e){return this._get(`/sessions/${e}/files-count`)},async getSessionFile(e,s){return this._get(`/sessions/${e}/file?path=${encodeURIComponent(s)}`)},async restartSession(e){return this._post(`/sessions/${e}/restart`)},async startSession(e,s,t){const r={};return s!==void 0&&(r.prompt=s),t!==void 0&&(r.model=t),this._post(`/sessions/${e}/start`,Object.keys(r).length>0?r:void 0)},async updateSessionInitialPrompt(e,s){return this._put(`/sessions/${e}/initial-prompt`,{prompt:s})},async updateSession(e,s){return this._patch(`/sessions/${e}`,s)},async updateSessionPendingPrompt(e,s){return this._patch(`/sessions/${e}/pending-prompt`,{pendingPrompt:s})},async deleteSession(e){return this._delete(`/sessions/${e}`)},async archiveSession(e,{cleanup:s=!1}={}){return this._post(`/sessions/${e}/archive`,{cleanup:s})},async unarchiveSession(e){return this._post(`/sessions/${e}/unarchive`)},async toggleSessionStar(e){return this._post(`/sessions/${e}/star`)},async duplicateSession(e,s={}){return this._post(`/sessions/${e}/duplicate`,s)},async scheduleSession(e,s){return this._post(`/sessions/${e}/schedule`,s)}})}function w(n){Object.assign(n.prototype,{async getCanvasItems(e){return this._get(`/sessions/${e}/canvas`)},async getCanvasFileContent(e,s){return this._get(`/sessions/${e}/canvas/file/${encodeURIComponent(s)}/content`)},async getAllCanvasItems(e){return this._get(`/sessions/${e}/canvas/all`)},async uploadCanvasItem(e,s){const t=new FormData;return t.append("file",s),this._uploadFormData(`/sessions/${e}/canvas`,t)},async createCanvasItem(e,s){return this._post(`/sessions/${e}/canvas`,s)},async updateCanvasItem(e,s,t){return this._put(`/sessions/${e}/canvas/${s}`,t)},async deleteCanvasItem(e,s){return this._delete(`/sessions/${e}/canvas/${s}`)},async getCanvasTrash(e){return this._get(`/sessions/${e}/canvas-trash`)},async recoverCanvasItem(e,s){return this._post(`/sessions/${e}/canvas/${s}/recover`)},async recoverCanvasFile(e,s){return this._post(`/sessions/${e}/canvas-trash/recover-file/${encodeURIComponent(s)}`)},async permanentlyDeleteCanvasItem(e,s){return this._delete(`/sessions/${e}/canvas/${s}/permanent`)},async bulkDeleteCanvasItems(e,s){return this._post(`/sessions/${e}/canvas/bulk-delete`,{itemIds:s})},async bulkRecoverCanvasItems(e,s){return this._post(`/sessions/${e}/canvas/bulk-recover`,{itemIds:s})},async bulkPermanentlyDeleteCanvasItems(e,s){return this._delete(`/sessions/${e}/canvas/bulk-delete-permanent`,{itemIds:s})}})}function R(n){Object.assign(n.prototype,{async getProviders(){return this._get("/providers")},async getProvider(e){return this._get(`/providers/${e}`)},async createProvider(e){return this._post("/providers",e)},async updateProvider(e,s){return this._patch(`/providers/${e}`,s)},async deleteProvider(e){return this._delete(`/providers/${e}`)},async testProviderConnection(e){return this._post("/providers/test",e)},async testExistingProvider(e){return this._post(`/providers/${e}/test`)},async getProviderModels(e){return this._get(`/providers/${e}/models`)},async addProviderModel(e,s){return this._post(`/providers/${e}/models`,s)},async updateProviderModel(e,s,t){return this._patch(`/providers/${e}/models/${s}`,t)},async removeProviderModel(e,s){return this._delete(`/providers/${e}/models/${s}`)}})}function A(n){Object.assign(n.prototype,{async getCommandButtons(e){return this._get(`/projects/${e}/command-buttons`)},async createCommandButton(e,s){return this._post(`/projects/${e}/command-buttons`,s)},async getCommandButton(e,s){return this._get(`/projects/${e}/command-buttons/${s}`)},async updateCommandButton(e,s,t){return this._patch(`/projects/${e}/command-buttons/${s}`,t)},async deleteCommandButton(e,s){return this._delete(`/projects/${e}/command-buttons/${s}`)},async runCommandButton(e,s){return this._post(`/sessions/${e}/command-buttons/${s}/run`)},async getActiveRuns(e){return this._get(`/sessions/${e}/command-buttons/runs`)},async getCommandRun(e,s){return this._get(`/sessions/${e}/command-buttons/runs/${s}`)},async getLatestRunsForProject(e){return this._get(`/projects/${e}/command-buttons/latest-runs`)},async killCommandRun(e,s){return this._post(`/sessions/${e}/command-buttons/runs/${s}/kill`)},async deleteCommandRun(e,s){return this._delete(`/sessions/${e}/command-buttons/runs/${s}`)},async deleteAllRunsForButton(e,s){return this._delete(`/sessions/${e}/command-buttons/${s}/runs/all`)}})}function I(n){Object.assign(n.prototype,{async getTokenCostWeights(){return this._get("/settings/token-weights")},async updateTokenCostWeights(e){return this._put("/settings/token-weights",e)},async resetTokenCostWeights(){return this._delete("/settings/token-weights")},async getSummarySettings(){return this._get("/settings/summary")},async updateSummarySettings(e){return this._put("/settings/summary",e)},async resetSummarySettings(){return this._delete("/settings/summary")},async getGeneralSettings(){return this._get("/settings/general")},async updateGeneralSettings(e){return this._put("/settings/general",e)},async resetGeneralSettings(){return this._delete("/settings/general")}})}function O(n){Object.assign(n.prototype,{async getConversations(e){return this._get(`/sessions/${e}/conversations`)},async createConversation(e,s=null){return this._post(`/sessions/${e}/conversations`,{name:s})},async getConversation(e,s){return this._get(`/sessions/${e}/conversations/${s}`)},async updateConversation(e,s,t){return this._patch(`/sessions/${e}/conversations/${s}`,t)},async deleteConversation(e,s){return this._delete(`/sessions/${e}/conversations/${s}`)},async branchConversation(e,s,t){return this._post(`/sessions/${e}/conversations/${s}/branch`,t)},async getConversationMessages(e,s){return this._get(`/sessions/${e}/messages?conversation_id=${s}`)}})}function D(n){Object.assign(n.prototype,{async getGlobalTemplates(){return this._get("/templates")},async createGlobalTemplate(e){return this._post("/templates",e)},async getTemplate(e){return this._get(`/templates/${e}`)},async updateTemplate(e,s){return this._patch(`/templates/${e}`,s)},async deleteTemplate(e){return this._delete(`/templates/${e}`)},async getProjectTemplates(e){return this._get(`/projects/${e}/templates`)},async createProjectTemplate(e,s){return this._post(`/projects/${e}/templates`,s)}})}function F(n){Object.assign(n.prototype,{async getQuickResponses(e){return this._get(`/projects/${e}/quick-responses`)},async getGlobalQuickResponses(){return this._get("/quick-responses/global")},async createQuickResponse(e,s){return this._post(`/projects/${e}/quick-responses`,s)},async updateQuickResponse(e,s){return this._patch(`/quick-responses/${e}`,s)},async deleteQuickResponse(e){return this._delete(`/quick-responses/${e}`)},async reorderQuickResponses(e,s){return this._post(`/projects/${e}/quick-responses/reorder`,s)},async reorderGlobalQuickResponses(e){return this._post("/quick-responses/global/reorder",e)}})}function Q(n){Object.assign(n.prototype,{async getGitStatus(e){return this._get(`/git/projects/${e}/status`)},async getWorktrees(e){return this._get(`/git/projects/${e}/worktrees`)},async getSessionTodos(e,s=null){return this._get(this._buildQueryPath(`/sessions/${e}/todos`,{conversation_id:s||void 0}))},async getSessionSummary(e,s=!1){const t=s?this._buildQueryPath(`/sessions/${e}/summary`,{generate:"true"}):`/sessions/${e}/summary`;try{return await this._get(t)}catch(r){if(r.message.includes("404")||r.message.includes("not found"))return null;throw r}},async getSessionSummariesBatch(e){return!e||e.length===0?{}:this._post("/sessions/summaries/batch",{ids:e})},async generateSessionSummary(e){return this._post(`/sessions/${e}/summary`)},async getWorkflowLatestResponse(e){try{return await this._get(`/sessions/${e}/workflow-latest-response`)}catch(s){if(s.message.includes("404"))return null;throw s}},async getSessionNotes(e){return this._get(`/sessions/${e}/notes`)},async createNote(e,s){return this._post(`/sessions/${e}/notes`,{content:s})},async updateNote(e,s,t){return this._put(`/sessions/${e}/notes/${s}`,{content:t})},async deleteNote(e,s){return this._delete(`/sessions/${e}/notes/${s}`)},async browseDirectory(e=""){return this._get(this._buildQueryPath("/filesystem/browse",{path:e||void 0}))},async getSlashCommands(e){return this._get(`/commands?directory=${encodeURIComponent(e)}`)},async getSlashCommand(e,s){return this._get(`/commands/${encodeURIComponent(s)}?directory=${encodeURIComponent(e)}`)},async executeSlashCommand(e,s,t={}){return this._post(`/commands/${encodeURIComponent(s)}/execute`,{sessionId:e,args:t})},async getAgentCallLogs({limit:e,offset:s,agentType:t,callType:r,status:a,startDate:o,endDate:m,sessionId:_,model:$,sortBy:f,sortOrder:v}={}){const i={};return e!=null&&(i.limit=e),s!=null&&(i.offset=s),t&&(i.agentType=t),r&&(i.callType=r),a&&(i.status=a),o&&(i.startDate=o),m&&(i.endDate=m),_&&(i.sessionId=_),$&&(i.model=$),f&&(i.sortBy=f),v&&(i.sortOrder=v),this._get(this._buildQueryPath("/agent-calls",i))},async getAgentCallFilterOptions(){return this._get("/agent-calls/filter-options")},async deleteAllAgentCallLogs(){return this._delete("/agent-calls")},async getProjectSessionDefaults(e){return this._get(`/projects/${e}/session-defaults`)},async updateProjectSessionDefaults(e,s){return this._post(`/projects/${e}/session-defaults`,s)},async resetProjectSessionDefaults(e){return this._delete(`/projects/${e}/session-defaults`)}})}function B(n){Object.assign(n.prototype,{async getKanbanBoard(e){return this._get(`/projects/${e}/kanban`)},async deleteKanbanBoard(e){return this._delete(`/projects/${e}/kanban`)},async createKanbanLane(e,s){return this._post(`/projects/${e}/kanban/lanes`,s)},async updateKanbanLane(e,s,t){return this._patch(`/projects/${e}/kanban/lanes/${s}`,t)},async deleteKanbanLane(e,s){return this._delete(`/projects/${e}/kanban/lanes/${s}`)},async reorderKanbanLanes(e,s){return this._put(`/projects/${e}/kanban/lanes/reorder`,s)},async createKanbanCard(e,s){return this._post(`/projects/${e}/kanban/cards`,s)},async moveKanbanCard(e,s,t){return this._patch(`/projects/${e}/kanban/cards/${s}/move`,t)},async deleteKanbanCard(e,s){return this._delete(`/projects/${e}/kanban/cards/${s}`)},async reorderKanbanCards(e,s,t){return this._put(`/projects/${e}/kanban/lanes/${s}/cards/reorder`,t)}})}var p,u,d;class c{constructor(e="/api"){y(this,u);y(this,p);C(this,p,e)}get baseUrl(){return h(this,p)}async _uploadFormData(e,s){const t=await fetch(`${h(this,p)}${e}`,{method:"POST",body:s});if(!t.ok){const r=await t.json().catch(()=>({}));throw new Error(r.error||`HTTP ${t.status}`)}return t.json()}_buildQueryPath(e,s){const t=new URLSearchParams;for(const[a,o]of Object.entries(s))o!=null&&t.append(a,o);const r=t.toString();return r?`${e}?${r}`:e}_get(e){return l(this,u,d).call(this,"GET",e)}_post(e,s){return l(this,u,d).call(this,"POST",e,s)}_put(e,s){return l(this,u,d).call(this,"PUT",e,s)}_patch(e,s){return l(this,u,d).call(this,"PATCH",e,s)}_delete(e,s){return l(this,u,d).call(this,"DELETE",e,s)}}p=new WeakMap,u=new WeakSet,d=async function(e,s,t=null){const r={method:e,headers:{"Content-Type":"application/json"}};t&&e!=="GET"&&(r.body=JSON.stringify(t));const a=await fetch(`${h(this,p)}${s}`,r);if(!a.ok){const o=await a.json().catch(()=>({}));throw new Error(o.error||`HTTP ${a.status}`)}return a.status===204?null:a.json()};j(c);T(c);w(c);R(c);A(c);I(c);O(c);D(c);F(c);Q(c);B(c);const M=new c;export{M as a};
1
+ var b=n=>{throw TypeError(n)};var g=(n,e,s)=>e.has(n)||b("Cannot "+s);var h=(n,e,s)=>(g(n,e,"read from private field"),s?s.call(n):e.get(n)),y=(n,e,s)=>e.has(n)?b("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,s),C=(n,e,s,t)=>(g(n,e,"write to private field"),t?t.call(n,s):e.set(n,s),s),l=(n,e,s)=>(g(n,e,"access private method"),s);function j(n){Object.assign(n.prototype,{async getProjects(){return this._get("/projects")},async getProject(e){return this._get(`/projects/${e}`)},async createProject(e){return this._post("/projects",e)},async updateProject(e,s){return this._put(`/projects/${e}`,s)},async deleteProject(e){return this._delete(`/projects/${e}`)}})}function S(n,e,s){for(const t of s)e[t]!==void 0&&e[t]!==null&&n.append(t,e[t])}function k(n,e,s){for(const t of s)e[t]!==void 0&&e[t]!==null&&n.append(t,String(e[t]))}function P(n,e){const s=new FormData;s.append("prompt",n.prompt),S(s,n,["name","mode","model","effortLevel","gitBranch","gitMode","templateId","parentSessionId"]),k(s,n,["thinkingEnabled","startImmediately","autoRescheduleEnabled","rescheduleOnTokenLimit","rescheduleOnServiceError"]),S(s,n,["scheduledAt","rescheduleDelayMinutes","maxRescheduleCount","maxTotalTokens","rescheduleAtTokenCount"]);for(const t of e)s.append("files",t);return s}function T(n){Object.assign(n.prototype,{async getActiveSessions(){return this._get("/sessions")},async getScheduledSessions(e=null){return this._get(this._buildQueryPath("/sessions/scheduled",{projectId:e||void 0}))},async getProjectSessions(e,s=null,t=null,{limit:r=null,offset:a=0}={}){const o={};return s!==null&&(o.archived=s),t==="starred"?o.starred=!0:t==="unstarred"&&(o.starred=!1),r!==null&&(o.limit=r,o.offset=a),this._get(this._buildQueryPath(`/projects/${e}/sessions`,o))},async createSession(e,s){const{files:t,...r}=s;if(t&&t.length>0){const a=P(r,t);return this._uploadFormData(`/projects/${e}/sessions`,a)}return this._post(`/projects/${e}/sessions`,r)},async getSession(e){return this._get(`/sessions/${e}`)},async getSessionMessages(e){return this._get(`/sessions/${e}/messages`)},async getSessionWorkLogs(e){return this._get(`/sessions/${e}/work-logs`)},async sendMessage(e,s,t=[],r=null){if(console.log(`[MODEL AUDIT - ApiClient] sendMessage called with model: "${r}"`),t&&t.length>0){const a=new FormData;a.append("content",s),r&&a.append("model",r);for(const o of t)a.append("files",o);return this._uploadFormData(`/sessions/${e}/message`,a)}return this._post(`/sessions/${e}/message`,{content:s,model:r})},async stopSession(e){return this._post(`/sessions/${e}/stop`)},async getSessionChanges(e,s="local",t=null){const r={};return s==="branch"&&(r.compareMode="branch",t&&(r.branch=t)),this._get(this._buildQueryPath(`/sessions/${e}/changes`,r))},async getSessionDefaultBranch(e){return this._get(`/sessions/${e}/default-branch`)},async getSessionFilesCount(e){return this._get(`/sessions/${e}/files-count`)},async getSessionFile(e,s){return this._get(`/sessions/${e}/file?path=${encodeURIComponent(s)}`)},async restartSession(e){return this._post(`/sessions/${e}/restart`)},async startSession(e,s,t){const r={};return s!==void 0&&(r.prompt=s),t!==void 0&&(r.model=t),this._post(`/sessions/${e}/start`,Object.keys(r).length>0?r:void 0)},async updateSessionInitialPrompt(e,s){return this._put(`/sessions/${e}/initial-prompt`,{prompt:s})},async updateSession(e,s){return this._patch(`/sessions/${e}`,s)},async updateSessionPendingPrompt(e,s){return this._patch(`/sessions/${e}/pending-prompt`,{pendingPrompt:s})},async deleteSession(e){return this._delete(`/sessions/${e}`)},async archiveSession(e,{cleanup:s=!1}={}){return this._post(`/sessions/${e}/archive`,{cleanup:s})},async unarchiveSession(e){return this._post(`/sessions/${e}/unarchive`)},async toggleSessionStar(e){return this._post(`/sessions/${e}/star`)},async duplicateSession(e,s={}){return this._post(`/sessions/${e}/duplicate`,s)},async scheduleSession(e,s){return this._post(`/sessions/${e}/schedule`,s)}})}function w(n){Object.assign(n.prototype,{async getCanvasItems(e){return this._get(`/sessions/${e}/canvas`)},async getCanvasFileContent(e,s){return this._get(`/sessions/${e}/canvas/file/${encodeURIComponent(s)}/content`)},async getAllCanvasItems(e){return this._get(`/sessions/${e}/canvas/all`)},async uploadCanvasItem(e,s){const t=new FormData;return t.append("file",s),this._uploadFormData(`/sessions/${e}/canvas`,t)},async createCanvasItem(e,s){return this._post(`/sessions/${e}/canvas`,s)},async updateCanvasItem(e,s,t){return this._put(`/sessions/${e}/canvas/${s}`,t)},async deleteCanvasItem(e,s){return this._delete(`/sessions/${e}/canvas/${s}`)},async getCanvasTrash(e){return this._get(`/sessions/${e}/canvas-trash`)},async recoverCanvasItem(e,s){return this._post(`/sessions/${e}/canvas/${s}/recover`)},async recoverCanvasFile(e,s){return this._post(`/sessions/${e}/canvas-trash/recover-file/${encodeURIComponent(s)}`)},async permanentlyDeleteCanvasItem(e,s){return this._delete(`/sessions/${e}/canvas/${s}/permanent`)},async bulkDeleteCanvasItems(e,s){return this._post(`/sessions/${e}/canvas/bulk-delete`,{itemIds:s})},async bulkRecoverCanvasItems(e,s){return this._post(`/sessions/${e}/canvas/bulk-recover`,{itemIds:s})},async bulkPermanentlyDeleteCanvasItems(e,s){return this._delete(`/sessions/${e}/canvas/bulk-delete-permanent`,{itemIds:s})}})}function R(n){Object.assign(n.prototype,{async getProviders(){return this._get("/providers")},async getProvider(e){return this._get(`/providers/${e}`)},async createProvider(e){return this._post("/providers",e)},async updateProvider(e,s){return this._patch(`/providers/${e}`,s)},async deleteProvider(e){return this._delete(`/providers/${e}`)},async testProviderConnection(e){return this._post("/providers/test",e)},async testExistingProvider(e){return this._post(`/providers/${e}/test`)},async getProviderModels(e){return this._get(`/providers/${e}/models`)},async addProviderModel(e,s){return this._post(`/providers/${e}/models`,s)},async updateProviderModel(e,s,t){return this._patch(`/providers/${e}/models/${s}`,t)},async removeProviderModel(e,s){return this._delete(`/providers/${e}/models/${s}`)}})}function A(n){Object.assign(n.prototype,{async getCommandButtons(e){return this._get(`/projects/${e}/command-buttons`)},async createCommandButton(e,s){return this._post(`/projects/${e}/command-buttons`,s)},async getCommandButton(e,s){return this._get(`/projects/${e}/command-buttons/${s}`)},async updateCommandButton(e,s,t){return this._patch(`/projects/${e}/command-buttons/${s}`,t)},async deleteCommandButton(e,s){return this._delete(`/projects/${e}/command-buttons/${s}`)},async runCommandButton(e,s){return this._post(`/sessions/${e}/command-buttons/${s}/run`)},async getActiveRuns(e){return this._get(`/sessions/${e}/command-buttons/runs`)},async getCommandRun(e,s){return this._get(`/sessions/${e}/command-buttons/runs/${s}`)},async getLatestRunsForProject(e){return this._get(`/projects/${e}/command-buttons/latest-runs`)},async killCommandRun(e,s){return this._post(`/sessions/${e}/command-buttons/runs/${s}/kill`)},async deleteCommandRun(e,s){return this._delete(`/sessions/${e}/command-buttons/runs/${s}`)},async deleteAllRunsForButton(e,s){return this._delete(`/sessions/${e}/command-buttons/${s}/runs/all`)}})}function I(n){Object.assign(n.prototype,{async getTokenCostWeights(){return this._get("/settings/token-weights")},async updateTokenCostWeights(e){return this._put("/settings/token-weights",e)},async resetTokenCostWeights(){return this._delete("/settings/token-weights")},async getSummarySettings(){return this._get("/settings/summary")},async updateSummarySettings(e){return this._put("/settings/summary",e)},async resetSummarySettings(){return this._delete("/settings/summary")},async getGeneralSettings(){return this._get("/settings/general")},async updateGeneralSettings(e){return this._put("/settings/general",e)},async resetGeneralSettings(){return this._delete("/settings/general")}})}function O(n){Object.assign(n.prototype,{async getConversations(e){return this._get(`/sessions/${e}/conversations`)},async createConversation(e,s=null){return this._post(`/sessions/${e}/conversations`,{name:s})},async getConversation(e,s){return this._get(`/sessions/${e}/conversations/${s}`)},async updateConversation(e,s,t){return this._patch(`/sessions/${e}/conversations/${s}`,t)},async deleteConversation(e,s){return this._delete(`/sessions/${e}/conversations/${s}`)},async branchConversation(e,s,t){return this._post(`/sessions/${e}/conversations/${s}/branch`,t)},async getConversationMessages(e,s){return this._get(`/sessions/${e}/messages?conversation_id=${s}`)}})}function D(n){Object.assign(n.prototype,{async getGlobalTemplates(){return this._get("/templates")},async createGlobalTemplate(e){return this._post("/templates",e)},async getTemplate(e){return this._get(`/templates/${e}`)},async updateTemplate(e,s){return this._patch(`/templates/${e}`,s)},async deleteTemplate(e){return this._delete(`/templates/${e}`)},async getProjectTemplates(e){return this._get(`/projects/${e}/templates`)},async createProjectTemplate(e,s){return this._post(`/projects/${e}/templates`,s)}})}function F(n){Object.assign(n.prototype,{async getQuickResponses(e){return this._get(`/projects/${e}/quick-responses`)},async getGlobalQuickResponses(){return this._get("/quick-responses/global")},async createQuickResponse(e,s){return this._post(`/projects/${e}/quick-responses`,s)},async updateQuickResponse(e,s){return this._patch(`/quick-responses/${e}`,s)},async deleteQuickResponse(e){return this._delete(`/quick-responses/${e}`)},async reorderQuickResponses(e,s){return this._post(`/projects/${e}/quick-responses/reorder`,s)},async reorderGlobalQuickResponses(e){return this._post("/quick-responses/global/reorder",e)}})}function Q(n){Object.assign(n.prototype,{async getGitStatus(e){return this._get(`/git/projects/${e}/status`)},async getWorktrees(e){return this._get(`/git/projects/${e}/worktrees`)},async detectWorktreePath(e){return this._get(this._buildQueryPath("/git/detect-worktree-path",{directory:e}))},async getSessionTodos(e,s=null){return this._get(this._buildQueryPath(`/sessions/${e}/todos`,{conversation_id:s||void 0}))},async getSessionSummary(e,s=!1){const t=s?this._buildQueryPath(`/sessions/${e}/summary`,{generate:"true"}):`/sessions/${e}/summary`;try{return await this._get(t)}catch(r){if(r.message.includes("404")||r.message.includes("not found"))return null;throw r}},async getSessionSummariesBatch(e){return!e||e.length===0?{}:this._post("/sessions/summaries/batch",{ids:e})},async generateSessionSummary(e){return this._post(`/sessions/${e}/summary`)},async getWorkflowLatestResponse(e){try{return await this._get(`/sessions/${e}/workflow-latest-response`)}catch(s){if(s.message.includes("404"))return null;throw s}},async getSessionNotes(e){return this._get(`/sessions/${e}/notes`)},async createNote(e,s){return this._post(`/sessions/${e}/notes`,{content:s})},async updateNote(e,s,t){return this._put(`/sessions/${e}/notes/${s}`,{content:t})},async deleteNote(e,s){return this._delete(`/sessions/${e}/notes/${s}`)},async browseDirectory(e=""){return this._get(this._buildQueryPath("/filesystem/browse",{path:e||void 0}))},async getSlashCommands(e){return this._get(`/commands?directory=${encodeURIComponent(e)}`)},async getSlashCommand(e,s){return this._get(`/commands/${encodeURIComponent(s)}?directory=${encodeURIComponent(e)}`)},async executeSlashCommand(e,s,t={}){return this._post(`/commands/${encodeURIComponent(s)}/execute`,{sessionId:e,args:t})},async getAgentCallLogs({limit:e,offset:s,agentType:t,callType:r,status:a,startDate:o,endDate:m,sessionId:_,model:$,sortBy:f,sortOrder:v}={}){const i={};return e!=null&&(i.limit=e),s!=null&&(i.offset=s),t&&(i.agentType=t),r&&(i.callType=r),a&&(i.status=a),o&&(i.startDate=o),m&&(i.endDate=m),_&&(i.sessionId=_),$&&(i.model=$),f&&(i.sortBy=f),v&&(i.sortOrder=v),this._get(this._buildQueryPath("/agent-calls",i))},async getAgentCallFilterOptions(){return this._get("/agent-calls/filter-options")},async deleteAllAgentCallLogs(){return this._delete("/agent-calls")},async getProjectSessionDefaults(e){return this._get(`/projects/${e}/session-defaults`)},async updateProjectSessionDefaults(e,s){return this._post(`/projects/${e}/session-defaults`,s)},async resetProjectSessionDefaults(e){return this._delete(`/projects/${e}/session-defaults`)}})}function B(n){Object.assign(n.prototype,{async getKanbanBoard(e){return this._get(`/projects/${e}/kanban`)},async deleteKanbanBoard(e){return this._delete(`/projects/${e}/kanban`)},async createKanbanLane(e,s){return this._post(`/projects/${e}/kanban/lanes`,s)},async updateKanbanLane(e,s,t){return this._patch(`/projects/${e}/kanban/lanes/${s}`,t)},async deleteKanbanLane(e,s){return this._delete(`/projects/${e}/kanban/lanes/${s}`)},async reorderKanbanLanes(e,s){return this._put(`/projects/${e}/kanban/lanes/reorder`,s)},async createKanbanCard(e,s){return this._post(`/projects/${e}/kanban/cards`,s)},async moveKanbanCard(e,s,t){return this._patch(`/projects/${e}/kanban/cards/${s}/move`,t)},async deleteKanbanCard(e,s){return this._delete(`/projects/${e}/kanban/cards/${s}`)},async reorderKanbanCards(e,s,t){return this._put(`/projects/${e}/kanban/lanes/${s}/cards/reorder`,t)}})}var p,u,d;class c{constructor(e="/api"){y(this,u);y(this,p);C(this,p,e)}get baseUrl(){return h(this,p)}async _uploadFormData(e,s){const t=await fetch(`${h(this,p)}${e}`,{method:"POST",body:s});if(!t.ok){const r=await t.json().catch(()=>({}));throw new Error(r.error||`HTTP ${t.status}`)}return t.json()}_buildQueryPath(e,s){const t=new URLSearchParams;for(const[a,o]of Object.entries(s))o!=null&&t.append(a,o);const r=t.toString();return r?`${e}?${r}`:e}_get(e){return l(this,u,d).call(this,"GET",e)}_post(e,s){return l(this,u,d).call(this,"POST",e,s)}_put(e,s){return l(this,u,d).call(this,"PUT",e,s)}_patch(e,s){return l(this,u,d).call(this,"PATCH",e,s)}_delete(e,s){return l(this,u,d).call(this,"DELETE",e,s)}}p=new WeakMap,u=new WeakSet,d=async function(e,s,t=null){const r={method:e,headers:{"Content-Type":"application/json"}};t&&e!=="GET"&&(r.body=JSON.stringify(t));const a=await fetch(`${h(this,p)}${s}`,r);if(!a.ok){const o=await a.json().catch(()=>({}));throw new Error(o.error||`HTTP ${a.status}`)}return a.status===204?null:a.json()};j(c);T(c);w(c);R(c);A(c);I(c);O(c);D(c);F(c);Q(c);B(c);const M=new c;export{M as a};
@@ -1 +1 @@
1
- .template-selector[data-v-d206f8db]{padding:1rem;background:var(--color-bg-soft);border-radius:.5rem;margin-bottom:1rem}.selector-label[data-v-d206f8db]{display:block;font-weight:500;font-size:.875rem;margin-bottom:.5rem;color:var(--color-text)}.selector-wrapper[data-v-d206f8db]{display:flex;gap:.5rem;align-items:center}.selector-wrapper .form-input[data-v-d206f8db]{flex:1}.btn-clear[data-v-d206f8db]{background:none;border:1px solid var(--color-border);border-radius:4px;padding:.5rem .75rem;cursor:pointer;color:var(--color-text-soft);font-size:.875rem;transition:all .15s}.btn-clear[data-v-d206f8db]:hover:not(:disabled){background:var(--color-bg-hover);color:var(--color-error);border-color:var(--color-error)}.btn-clear[data-v-d206f8db]:disabled{opacity:.5;cursor:not-allowed}.template-preview[data-v-d206f8db]{margin-top:.75rem;padding:.75rem;background:var(--color-background);border-radius:.375rem;border:1px solid var(--color-border)}.template-prompt-preview[data-v-d206f8db]{margin:0;font-size:.8rem;color:var(--color-text-soft);line-height:1.4;font-style:italic}.chain-indicator[data-v-d206f8db]{display:inline-block;margin-top:.5rem;font-size:.75rem;padding:.2rem .5rem;background:var(--color-warning, #f0ad4e);color:#333;border-radius:4px}.selector-help[data-v-d206f8db]{margin:.5rem 0 0;font-size:.75rem;color:var(--color-text-soft)}.saving-indicator[data-v-d206f8db]{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.75rem;color:var(--color-text-soft)}@media (max-width: 480px){.template-selector[data-v-d206f8db]{padding:.75rem}.selector-wrapper[data-v-d206f8db]{flex-direction:column;align-items:stretch}.btn-clear[data-v-d206f8db]{align-self:flex-end}}.modal-backdrop[data-v-e1ffc2da]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-e1ffc2da]{display:flex;flex-direction:column;background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:500px;max-height:90vh;overflow:hidden;border:1px solid var(--color-border)}.modal-header[data-v-e1ffc2da]{flex-shrink:0;display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-e1ffc2da]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-e1ffc2da]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-e1ffc2da]:hover{color:var(--color-text)}.modal-body[data-v-e1ffc2da]{flex:1;overflow-y:auto;min-height:0;padding:1.5rem}.form-section[data-v-e1ffc2da]{margin-bottom:1.5rem;padding-bottom:1.5rem;border-bottom:1px solid var(--color-border)}.form-section[data-v-e1ffc2da]:last-of-type{border-bottom:none}.section-title[data-v-e1ffc2da]{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--color-text)}.error-message[data-v-e1ffc2da]{padding:.75rem;margin-bottom:1rem;background:#ef44441a;border:1px solid rgba(239,68,68,.3);border-radius:.25rem;color:#fca5a5;font-size:.9rem}.modal-footer[data-v-e1ffc2da]{flex-shrink:0;display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.form-group[data-v-e1ffc2da]{margin-bottom:1rem}.form-label[data-v-e1ffc2da]{display:block;margin-bottom:.5rem;font-weight:500;color:var(--color-text)}.form-input[data-v-e1ffc2da]{width:100%;padding:.5rem;border:1px solid var(--color-border);border-radius:.25rem;background:var(--color-background);color:var(--color-text);font-size:.95rem}.form-input[data-v-e1ffc2da]:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px #22c5ff1a}.form-help[data-v-e1ffc2da]{margin-top:.25rem;font-size:.875rem;color:var(--color-text-soft)}.toggle-switch[data-v-e1ffc2da]{display:flex;align-items:center;cursor:pointer;gap:.75rem}.toggle-switch input[data-v-e1ffc2da]{display:none}.toggle-slider[data-v-e1ffc2da]{position:relative;display:inline-block;width:2.5rem;height:1.25rem;background-color:var(--color-border);border-radius:1rem;transition:background-color .2s;flex-shrink:0}.toggle-slider[data-v-e1ffc2da]:after{content:"";position:absolute;width:1rem;height:1rem;border-radius:50%;background-color:#fff;top:.125rem;left:.125rem;transition:transform .2s}.toggle-switch input:checked+.toggle-slider[data-v-e1ffc2da]{background-color:var(--color-primary)}.toggle-switch input:checked+.toggle-slider[data-v-e1ffc2da]:after{transform:translate(1.25rem)}.toggle-label[data-v-e1ffc2da]{color:var(--color-text);font-weight:500}.reschedule-settings[data-v-e1ffc2da]{padding:1rem;margin-top:1rem;border-left:2px solid var(--color-primary);background:var(--color-background, rgba(255, 255, 255, .02));border-radius:0 .25rem .25rem 0}.settings-label[data-v-e1ffc2da]{margin-bottom:.75rem;font-weight:500;font-size:.95rem;color:var(--color-text)}.checkbox-option[data-v-e1ffc2da]{display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem;cursor:pointer;color:var(--color-text)}.checkbox-option input[data-v-e1ffc2da]{width:1rem;height:1rem;cursor:pointer}.btn[data-v-e1ffc2da]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-e1ffc2da]{background:var(--color-primary);color:#fff}.btn-primary[data-v-e1ffc2da]:hover:not(:disabled){opacity:.9}.btn-primary[data-v-e1ffc2da]:disabled{opacity:.5;cursor:not-allowed}.btn-secondary[data-v-e1ffc2da]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-e1ffc2da]:hover{background:var(--color-background-secondary)}.modal-backdrop[data-v-bddc7788]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-bddc7788]{background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:500px;max-height:90vh;overflow:hidden;display:flex;flex-direction:column;border:1px solid var(--color-border)}.modal-header[data-v-bddc7788]{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-bddc7788]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-bddc7788]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-bddc7788]:hover{color:var(--color-text)}.modal-body[data-v-bddc7788]{padding:1.5rem;flex:1;overflow-y:auto}.modal-footer[data-v-bddc7788]{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.moving-info[data-v-bddc7788]{margin-bottom:1.5rem;padding:.75rem;background:var(--color-bg-soft, rgba(255, 255, 255, .05));border-radius:.25rem}.moving-label[data-v-bddc7788]{display:block;font-size:.75rem;color:var(--color-text-soft);margin-bottom:.25rem}.moving-session-name[data-v-bddc7788]{display:block;font-size:.875rem;font-weight:500;color:var(--color-text)}.empty-state[data-v-bddc7788]{display:flex;align-items:center;justify-content:center;padding:2rem;color:var(--color-text-soft)}.lanes-list[data-v-bddc7788]{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.lane-row[data-v-bddc7788]{border:1px solid var(--color-border);border-radius:.25rem;transition:background-color .15s,border-color .15s}.lane-row[data-v-bddc7788]:not(.lane-row-disabled):hover{background:var(--color-bg-soft);border-color:var(--color-primary)}.lane-row-current[data-v-bddc7788]{opacity:.6}.lane-label[data-v-bddc7788]{display:flex;align-items:center;padding:.75rem;cursor:pointer;gap:.75rem;width:100%}.lane-label input[type=radio][data-v-bddc7788]{flex-shrink:0;width:1rem;height:1rem;cursor:pointer}.lane-label input[type=radio][data-v-bddc7788]:disabled{cursor:not-allowed}.lane-info[data-v-bddc7788]{display:flex;align-items:center;gap:.5rem;flex:1}.lane-name[data-v-bddc7788]{font-size:.875rem;font-weight:500;color:var(--color-text)}.lane-current-badge[data-v-bddc7788]{font-size:.75rem;color:var(--color-text-soft);font-style:italic}.lane-automation-icon[data-v-bddc7788]{color:#f59e0b;flex-shrink:0;display:flex;align-items:center}.automation-option[data-v-bddc7788]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--color-border)}.checkbox-label[data-v-bddc7788]{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:var(--color-text)}.checkbox-label input[type=checkbox][data-v-bddc7788]{width:1rem;height:1rem;cursor:pointer}.btn[data-v-bddc7788]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-bddc7788]{background:var(--color-primary);color:#fff}.btn-primary[data-v-bddc7788]:hover:not(:disabled){opacity:.9}.btn-primary[data-v-bddc7788]:disabled{opacity:.5;cursor:not-allowed}.btn-secondary[data-v-bddc7788]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-bddc7788]:hover{background:var(--color-background-secondary)}.btn-danger[data-v-bddc7788]{background:#ef4444;color:#fff}.btn-danger[data-v-bddc7788]:hover:not(:disabled){background:#dc2626}.btn-danger[data-v-bddc7788]:disabled{opacity:.5;cursor:not-allowed}.modal-backdrop[data-v-58eef4e8]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-58eef4e8]{background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:450px;overflow:hidden;display:flex;flex-direction:column;border:1px solid var(--color-border)}.modal-header[data-v-58eef4e8]{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-58eef4e8]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-58eef4e8]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-58eef4e8]:hover{color:var(--color-text)}.modal-body[data-v-58eef4e8]{padding:1.5rem}.confirm-message[data-v-58eef4e8]{margin:0;font-size:.9rem;color:var(--color-text);line-height:1.5}.cleanup-option[data-v-58eef4e8]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--color-border)}.checkbox-label[data-v-58eef4e8]{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:var(--color-text)}.checkbox-label input[type=checkbox][data-v-58eef4e8]{width:1rem;height:1rem;cursor:pointer}.modal-footer[data-v-58eef4e8]{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.btn[data-v-58eef4e8]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-58eef4e8]{background:var(--color-primary);color:#fff}.btn-primary[data-v-58eef4e8]:hover{opacity:.9}.btn-secondary[data-v-58eef4e8]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-58eef4e8]:hover{background:var(--color-background-secondary)}.btn[data-v-58eef4e8]:disabled{opacity:.5;cursor:not-allowed}.close-btn[data-v-58eef4e8]:disabled{opacity:.5;cursor:not-allowed}
1
+ .template-selector[data-v-77a4f989]{padding:1rem;background:var(--color-bg-soft);border-radius:.5rem;margin-bottom:1rem}.selector-label[data-v-77a4f989]{display:block;font-weight:500;font-size:.875rem;margin-bottom:.5rem;color:var(--color-text)}.selector-wrapper[data-v-77a4f989]{display:flex;gap:.5rem;align-items:center}.selector-wrapper .form-input[data-v-77a4f989]{flex:1}.btn-clear[data-v-77a4f989]{background:none;border:1px solid var(--color-border);border-radius:4px;padding:.5rem .75rem;cursor:pointer;color:var(--color-text-soft);font-size:.875rem;transition:all .15s}.btn-clear[data-v-77a4f989]:hover:not(:disabled){background:var(--color-bg-hover);color:var(--color-error);border-color:var(--color-error)}.btn-clear[data-v-77a4f989]:disabled{opacity:.5;cursor:not-allowed}.template-preview[data-v-77a4f989]{margin-top:.75rem;padding:.75rem;background:var(--color-background);border-radius:.375rem;border:1px solid var(--color-border)}.template-prompt-preview[data-v-77a4f989]{margin:0;font-size:.8rem;color:var(--color-text-soft);line-height:1.4;font-style:italic}.chain-indicator[data-v-77a4f989]{display:inline-block;margin-top:.5rem;font-size:.75rem;padding:.2rem .5rem;background:var(--color-warning, #f0ad4e);color:#333;border-radius:4px}.selector-help[data-v-77a4f989]{margin:.5rem 0 0;font-size:.75rem;color:var(--color-text-soft)}.saving-indicator[data-v-77a4f989]{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.75rem;color:var(--color-text-soft)}@media (max-width: 480px){.template-selector[data-v-77a4f989]{padding:.75rem}.selector-wrapper[data-v-77a4f989]{flex-direction:column;align-items:stretch}.btn-clear[data-v-77a4f989]{align-self:flex-end}}.modal-backdrop[data-v-e1ffc2da]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-e1ffc2da]{display:flex;flex-direction:column;background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:500px;max-height:90vh;overflow:hidden;border:1px solid var(--color-border)}.modal-header[data-v-e1ffc2da]{flex-shrink:0;display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-e1ffc2da]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-e1ffc2da]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-e1ffc2da]:hover{color:var(--color-text)}.modal-body[data-v-e1ffc2da]{flex:1;overflow-y:auto;min-height:0;padding:1.5rem}.form-section[data-v-e1ffc2da]{margin-bottom:1.5rem;padding-bottom:1.5rem;border-bottom:1px solid var(--color-border)}.form-section[data-v-e1ffc2da]:last-of-type{border-bottom:none}.section-title[data-v-e1ffc2da]{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--color-text)}.error-message[data-v-e1ffc2da]{padding:.75rem;margin-bottom:1rem;background:#ef44441a;border:1px solid rgba(239,68,68,.3);border-radius:.25rem;color:#fca5a5;font-size:.9rem}.modal-footer[data-v-e1ffc2da]{flex-shrink:0;display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.form-group[data-v-e1ffc2da]{margin-bottom:1rem}.form-label[data-v-e1ffc2da]{display:block;margin-bottom:.5rem;font-weight:500;color:var(--color-text)}.form-input[data-v-e1ffc2da]{width:100%;padding:.5rem;border:1px solid var(--color-border);border-radius:.25rem;background:var(--color-background);color:var(--color-text);font-size:.95rem}.form-input[data-v-e1ffc2da]:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px #22c5ff1a}.form-help[data-v-e1ffc2da]{margin-top:.25rem;font-size:.875rem;color:var(--color-text-soft)}.toggle-switch[data-v-e1ffc2da]{display:flex;align-items:center;cursor:pointer;gap:.75rem}.toggle-switch input[data-v-e1ffc2da]{display:none}.toggle-slider[data-v-e1ffc2da]{position:relative;display:inline-block;width:2.5rem;height:1.25rem;background-color:var(--color-border);border-radius:1rem;transition:background-color .2s;flex-shrink:0}.toggle-slider[data-v-e1ffc2da]:after{content:"";position:absolute;width:1rem;height:1rem;border-radius:50%;background-color:#fff;top:.125rem;left:.125rem;transition:transform .2s}.toggle-switch input:checked+.toggle-slider[data-v-e1ffc2da]{background-color:var(--color-primary)}.toggle-switch input:checked+.toggle-slider[data-v-e1ffc2da]:after{transform:translate(1.25rem)}.toggle-label[data-v-e1ffc2da]{color:var(--color-text);font-weight:500}.reschedule-settings[data-v-e1ffc2da]{padding:1rem;margin-top:1rem;border-left:2px solid var(--color-primary);background:var(--color-background, rgba(255, 255, 255, .02));border-radius:0 .25rem .25rem 0}.settings-label[data-v-e1ffc2da]{margin-bottom:.75rem;font-weight:500;font-size:.95rem;color:var(--color-text)}.checkbox-option[data-v-e1ffc2da]{display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem;cursor:pointer;color:var(--color-text)}.checkbox-option input[data-v-e1ffc2da]{width:1rem;height:1rem;cursor:pointer}.btn[data-v-e1ffc2da]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-e1ffc2da]{background:var(--color-primary);color:#fff}.btn-primary[data-v-e1ffc2da]:hover:not(:disabled){opacity:.9}.btn-primary[data-v-e1ffc2da]:disabled{opacity:.5;cursor:not-allowed}.btn-secondary[data-v-e1ffc2da]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-e1ffc2da]:hover{background:var(--color-background-secondary)}.modal-backdrop[data-v-bddc7788]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-bddc7788]{background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:500px;max-height:90vh;overflow:hidden;display:flex;flex-direction:column;border:1px solid var(--color-border)}.modal-header[data-v-bddc7788]{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-bddc7788]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-bddc7788]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-bddc7788]:hover{color:var(--color-text)}.modal-body[data-v-bddc7788]{padding:1.5rem;flex:1;overflow-y:auto}.modal-footer[data-v-bddc7788]{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.moving-info[data-v-bddc7788]{margin-bottom:1.5rem;padding:.75rem;background:var(--color-bg-soft, rgba(255, 255, 255, .05));border-radius:.25rem}.moving-label[data-v-bddc7788]{display:block;font-size:.75rem;color:var(--color-text-soft);margin-bottom:.25rem}.moving-session-name[data-v-bddc7788]{display:block;font-size:.875rem;font-weight:500;color:var(--color-text)}.empty-state[data-v-bddc7788]{display:flex;align-items:center;justify-content:center;padding:2rem;color:var(--color-text-soft)}.lanes-list[data-v-bddc7788]{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}.lane-row[data-v-bddc7788]{border:1px solid var(--color-border);border-radius:.25rem;transition:background-color .15s,border-color .15s}.lane-row[data-v-bddc7788]:not(.lane-row-disabled):hover{background:var(--color-bg-soft);border-color:var(--color-primary)}.lane-row-current[data-v-bddc7788]{opacity:.6}.lane-label[data-v-bddc7788]{display:flex;align-items:center;padding:.75rem;cursor:pointer;gap:.75rem;width:100%}.lane-label input[type=radio][data-v-bddc7788]{flex-shrink:0;width:1rem;height:1rem;cursor:pointer}.lane-label input[type=radio][data-v-bddc7788]:disabled{cursor:not-allowed}.lane-info[data-v-bddc7788]{display:flex;align-items:center;gap:.5rem;flex:1}.lane-name[data-v-bddc7788]{font-size:.875rem;font-weight:500;color:var(--color-text)}.lane-current-badge[data-v-bddc7788]{font-size:.75rem;color:var(--color-text-soft);font-style:italic}.lane-automation-icon[data-v-bddc7788]{color:#f59e0b;flex-shrink:0;display:flex;align-items:center}.automation-option[data-v-bddc7788]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--color-border)}.checkbox-label[data-v-bddc7788]{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:var(--color-text)}.checkbox-label input[type=checkbox][data-v-bddc7788]{width:1rem;height:1rem;cursor:pointer}.btn[data-v-bddc7788]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-bddc7788]{background:var(--color-primary);color:#fff}.btn-primary[data-v-bddc7788]:hover:not(:disabled){opacity:.9}.btn-primary[data-v-bddc7788]:disabled{opacity:.5;cursor:not-allowed}.btn-secondary[data-v-bddc7788]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-bddc7788]:hover{background:var(--color-background-secondary)}.btn-danger[data-v-bddc7788]{background:#ef4444;color:#fff}.btn-danger[data-v-bddc7788]:hover:not(:disabled){background:#dc2626}.btn-danger[data-v-bddc7788]:disabled{opacity:.5;cursor:not-allowed}.modal-backdrop[data-v-140e797f]{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content[data-v-140e797f]{background:var(--color-background-secondary, #1f2937);border-radius:.5rem;width:100%;max-width:450px;overflow:hidden;display:flex;flex-direction:column;border:1px solid var(--color-border)}.modal-header[data-v-140e797f]{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--color-border)}.modal-title[data-v-140e797f]{margin:0;font-size:1.25rem;font-weight:600;color:var(--color-text)}.close-btn[data-v-140e797f]{background:none;border:none;font-size:1.5rem;color:var(--color-text-soft);cursor:pointer;padding:0;line-height:1}.close-btn[data-v-140e797f]:hover{color:var(--color-text)}.modal-body[data-v-140e797f]{padding:1.5rem}.confirm-message[data-v-140e797f]{margin:0;font-size:.9rem;color:var(--color-text);line-height:1.5}.cleanup-option[data-v-140e797f]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--color-border)}.checkbox-label[data-v-140e797f]{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:var(--color-text)}.checkbox-label input[type=checkbox][data-v-140e797f]{width:1rem;height:1rem;cursor:pointer}.modal-footer[data-v-140e797f]{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--color-border)}.btn[data-v-140e797f]{padding:.5rem 1rem;border-radius:.25rem;font-weight:500;cursor:pointer;border:none;font-size:.9rem;transition:opacity .2s,background-color .2s}.btn-primary[data-v-140e797f]{background:var(--color-primary);color:#fff}.btn-primary[data-v-140e797f]:hover{opacity:.9}.btn-secondary[data-v-140e797f]{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-text)}.btn-secondary[data-v-140e797f]:hover{background:var(--color-background-secondary)}.btn[data-v-140e797f]:disabled{opacity:.5;cursor:not-allowed}.close-btn[data-v-140e797f]:disabled{opacity:.5;cursor:not-allowed}
@@ -0,0 +1 @@
1
+ import{_ as L,n as I,l as O,o as N,a,c as d,b as t,m as T,p as q,F as j,r as D,t as C,i as f,f as B,x,$ as K,k as P,G as z,d as U,q as w,v as A,j as F,V as G,y as W,A as H,E as Y,H as J}from"./index-MnvuyUxj.js";import{u as Q,b as X}from"./EffortLevelSelector-B9STpy07.js";import{M as Z}from"./ModelSelector-vRSpXjhL.js";import{M as ee}from"./SlashCommandWizard-CCEtEF98.js";import{u as te}from"./SessionLogStream-DMUzZOml.js";const se={class:"template-selector"},le={class:"selector-wrapper"},ne=["disabled"],oe={key:0,label:"Project Templates"},ae=["value"],de={key:1,label:"Global Templates"},ie=["value"],ue=["disabled"],re={key:0,class:"template-preview"},ce={class:"template-prompt-preview"},me={key:0,class:"chain-indicator"},pe={key:1,class:"selector-help"},ve={key:2,class:"saving-indicator"},be={__name:"TemplateSelector",props:{sessionId:{type:String,required:!1,default:null},projectId:{type:String,required:!0},currentTemplateId:{type:String,default:null},disabled:{type:Boolean,default:!1}},emits:["update:templateId"],setup(o,{emit:M}){const n=o,k=M,p=Q(),v=I(n.currentTemplateId),u=I(!1),h=x(()=>p.loading),s=x(()=>p.projectTemplates),g=x(()=>p.globalTemplates),c=x(()=>v.value?p.getTemplateById(v.value):null),$=x(()=>{var S;if(!((S=c.value)!=null&&S.nextTemplateId))return null;const e=[];let i=c.value.nextTemplateId;const m=new Set;for(;i&&!m.has(i);){m.add(i);const l=p.getTemplateById(i);if(l)e.push(l.name),i=l.nextTemplateId;else{e.push("Unknown");break}if(e.length>=3){e.push("...");break}}return e.length>0?`Chains to: ${e.join(" → ")}`:null}),R=K(n,"currentTemplateId");O(R,e=>{v.value=e},{flush:"sync"}),N(()=>{n.projectId&&p.projectTemplates.length===0&&p.globalTemplates.length===0&&p.fetchProjectTemplates(n.projectId)});function _(e,i=100){return e?e.length<=i?e:`${e.substring(0,i)}...`:""}function E(e){var S;const i=((S=e==null?void 0:e.target)==null?void 0:S.value)||v.value,m=i===""?null:i;u.value=!0,k("update:templateId",m),setTimeout(()=>{u.value=!1},1e3)}function r(){v.value=null,E()}return(e,i)=>(a(),d("div",se,[i[3]||(i[3]=t("label",{class:"selector-label"},"Next Template",-1)),t("div",le,[T(t("select",{"onUpdate:modelValue":i[0]||(i[0]=m=>v.value=m),class:"form-input",disabled:o.disabled||h.value,onChange:E},[i[1]||(i[1]=t("option",{value:null}," Select a template to run... ",-1)),s.value.length?(a(),d("optgroup",oe,[(a(!0),d(j,null,D(s.value,m=>(a(),d("option",{key:m.id,value:m.id},C(m.name),9,ae))),128))])):f("",!0),g.value.length?(a(),d("optgroup",de,[(a(!0),d(j,null,D(g.value,m=>(a(),d("option",{key:m.id,value:m.id},C(m.name),9,ie))),128))])):f("",!0)],40,ne),[[q,v.value]]),v.value?(a(),d("button",{key:0,class:"btn-clear",title:"Clear selection",disabled:o.disabled||u.value,onClick:r}," ✕ ",8,ue)):f("",!0)]),c.value?(a(),d("div",re,[t("p",ce,C(_(c.value.prompt)),1),$.value?(a(),d("span",me,C($.value),1)):f("",!0)])):(a(),d("p",pe," When the agent finishes responding, a new session will automatically start using this template. ")),u.value?(a(),d("div",ve,[...i[2]||(i[2]=[t("span",{class:"loading-spinner"},null,-1),B(" Saving... ",-1)])])):f("",!0)]))}},he=L(be,[["__scopeId","data-v-77a4f989"]]),fe={class:"modal-content"},ge={class:"modal-header"},ke={class:"modal-title"},ye={class:"modal-body"},Te={key:0,class:"error-message"},Ce={class:"form-section"},Se={class:"form-group"},$e={class:"form-group"},xe={class:"form-group"},Ie={class:"toggle-switch"},Me={key:1,class:"form-group"},Ee=["min"],we={key:2,class:"form-section"},Re={class:"form-group"},_e={class:"toggle-switch"},Oe={key:3,class:"reschedule-settings"},Ae={class:"form-group"},Le={class:"checkbox-option"},Ve={class:"checkbox-option"},Ue={class:"form-group"},je={class:"form-group"},De={class:"form-group"},Be={class:"form-group"},Ne={key:0,class:"form-group"},Fe={class:"checkbox-option"},qe={class:"form-help"},Pe={class:"modal-footer"},ze=["disabled"],Ge={__name:"SchedulingEditModal",props:{isOpen:{type:Boolean,default:!1},session:{type:Object,default:null}},emits:["close","saved"],setup(o,{emit:M}){const n=o,k=M,p=X(),v=P(),u=I(!1),h=I(null),s=W({scheduledAtLocal:"",model:null,mode:"standard",thinkingEnabled:!1,nextTemplateId:null,autoRescheduleEnabled:!1,rescheduleDelayMinutes:15,rescheduleOnTokenLimit:!0,rescheduleOnServiceError:!0,maxRescheduleCount:null,maxTotalTokens:null,rescheduleAtTokenCount:null,resetRescheduleCount:!1}),g=x(()=>{const r=new Date;return r.setMinutes(r.getMinutes()+1),r.toISOString().slice(0,16)}),c=x(()=>{var r;return((r=n.session)==null?void 0:r.status)==="scheduled"?"Edit Scheduling Settings":"Auto-Reschedule Settings"});function $(){k("close")}function R(r){s.nextTemplateId=r}function _(r){if(!r)return"";const e=new Date(r),i=e.getFullYear(),m=String(e.getMonth()+1).padStart(2,"0"),S=String(e.getDate()).padStart(2,"0"),l=String(e.getHours()).padStart(2,"0"),b=String(e.getMinutes()).padStart(2,"0");return`${i}-${m}-${S}T${l}:${b}`}async function E(){var r;u.value=!0,h.value=null;try{const e={model:s.model,mode:s.mode,thinkingEnabled:s.thinkingEnabled,nextTemplateId:s.nextTemplateId,autoRescheduleEnabled:s.autoRescheduleEnabled,rescheduleDelayMinutes:s.rescheduleDelayMinutes,rescheduleOnTokenLimit:s.rescheduleOnTokenLimit,rescheduleOnServiceError:s.rescheduleOnServiceError,maxRescheduleCount:s.maxRescheduleCount||null,maxTotalTokens:s.maxTotalTokens||null,rescheduleAtTokenCount:s.rescheduleAtTokenCount||null};((r=n.session)==null?void 0:r.status)==="scheduled"&&s.scheduledAtLocal&&(e.scheduledAt=new Date(s.scheduledAtLocal).getTime()),s.resetRescheduleCount&&(e.rescheduleCount=0),await p.updateSessionFields(n.session.id,e),v.success("Settings saved"),k("saved"),$()}catch(e){h.value=e.message||"Failed to save settings",v.error(`Failed to save settings: ${h.value}`)}finally{u.value=!1}}return O(()=>n.isOpen,r=>{r&&n.session&&(h.value=null,s.scheduledAtLocal=_(n.session.scheduledAt),s.model=n.session.model||null,s.mode=n.session.mode||"standard",s.thinkingEnabled=n.session.thinkingEnabled||!1,s.nextTemplateId=n.session.nextTemplateId||null,s.autoRescheduleEnabled=n.session.autoRescheduleEnabled||!1,s.rescheduleDelayMinutes=n.session.rescheduleDelayMinutes||15,s.rescheduleOnTokenLimit=n.session.rescheduleOnTokenLimit??!0,s.rescheduleOnServiceError=n.session.rescheduleOnServiceError??!0,s.maxRescheduleCount=n.session.maxRescheduleCount,s.maxTotalTokens=n.session.maxTotalTokens,s.rescheduleAtTokenCount=n.session.rescheduleAtTokenCount,s.resetRescheduleCount=!1)}),(r,e)=>{var i,m,S;return a(),z(G,{to:"body"},[o.isOpen?(a(),d("div",{key:0,class:"modal-backdrop",onClick:F($,["self"])},[t("div",fe,[t("div",ge,[t("h2",ke,C(c.value),1),t("button",{class:"close-btn","aria-label":"Close",onClick:$}," × ")]),t("div",ye,[h.value?(a(),d("div",Te,C(h.value),1)):f("",!0),t("div",Ce,[e[16]||(e[16]=t("h3",{class:"section-title"}," Session Settings ",-1)),t("div",Se,[e[12]||(e[12]=t("label",{class:"form-label"},"Model",-1)),U(Z,{modelValue:s.model,"onUpdate:modelValue":e[0]||(e[0]=l=>s.model=l)},null,8,["modelValue"])]),t("div",$e,[e[13]||(e[13]=t("label",{class:"form-label"},"Mode",-1)),U(ee,{modelValue:s.mode,"onUpdate:modelValue":e[1]||(e[1]=l=>s.mode=l)},null,8,["modelValue"])]),t("div",xe,[t("label",Ie,[T(t("input",{"onUpdate:modelValue":e[2]||(e[2]=l=>s.thinkingEnabled=l),type:"checkbox"},null,512),[[w,s.thinkingEnabled]]),e[14]||(e[14]=t("span",{class:"toggle-slider"},null,-1)),e[15]||(e[15]=t("span",{class:"toggle-label"},"Extended Thinking",-1))])])]),((i=o.session)==null?void 0:i.status)==="scheduled"?(a(),d("div",Me,[e[17]||(e[17]=t("label",{for:"scheduled-at",class:"form-label"},"Scheduled Time",-1)),T(t("input",{id:"scheduled-at","onUpdate:modelValue":e[3]||(e[3]=l=>s.scheduledAtLocal=l),type:"datetime-local",min:g.value,class:"form-input"},null,8,Ee),[[A,s.scheduledAtLocal]])])):f("",!0),((m=o.session)==null?void 0:m.status)==="scheduled"?(a(),d("div",we,[e[18]||(e[18]=t("h3",{class:"section-title"}," Template Chain ",-1)),U(he,{"session-id":o.session.id,"project-id":o.session.projectId,"current-template-id":s.nextTemplateId,disabled:u.value,"onUpdate:templateId":R},null,8,["session-id","project-id","current-template-id","disabled"])])):f("",!0),t("div",Re,[t("label",_e,[T(t("input",{"onUpdate:modelValue":e[4]||(e[4]=l=>s.autoRescheduleEnabled=l),type:"checkbox"},null,512),[[w,s.autoRescheduleEnabled]]),e[19]||(e[19]=t("span",{class:"toggle-slider"},null,-1)),e[20]||(e[20]=t("span",{class:"toggle-label"},"Auto-reschedule on errors",-1))])]),s.autoRescheduleEnabled?(a(),d("div",Oe,[t("div",Ae,[e[23]||(e[23]=t("p",{class:"settings-label"}," Reschedule Triggers ",-1)),t("label",Le,[T(t("input",{"onUpdate:modelValue":e[5]||(e[5]=l=>s.rescheduleOnTokenLimit=l),type:"checkbox"},null,512),[[w,s.rescheduleOnTokenLimit]]),e[21]||(e[21]=t("span",null,"Token limit errors",-1))]),t("label",Ve,[T(t("input",{"onUpdate:modelValue":e[6]||(e[6]=l=>s.rescheduleOnServiceError=l),type:"checkbox"},null,512),[[w,s.rescheduleOnServiceError]]),e[22]||(e[22]=t("span",null,"Service unavailability",-1))])]),t("div",Ue,[e[25]||(e[25]=t("label",{class:"form-label"},"Reschedule Delay",-1)),T(t("select",{"onUpdate:modelValue":e[7]||(e[7]=l=>s.rescheduleDelayMinutes=l),class:"form-input"},[...e[24]||(e[24]=[t("option",{value:5}," 5 minutes ",-1),t("option",{value:15}," 15 minutes ",-1),t("option",{value:30}," 30 minutes ",-1),t("option",{value:60}," 1 hour ",-1),t("option",{value:120}," 2 hours ",-1)])],512),[[q,s.rescheduleDelayMinutes,void 0,{number:!0}]])]),t("div",je,[e[26]||(e[26]=t("label",{class:"form-label"},"Max Reschedule Count",-1)),T(t("input",{"onUpdate:modelValue":e[8]||(e[8]=l=>s.maxRescheduleCount=l),type:"number",min:"1",max:"100",class:"form-input",placeholder:"Unlimited"},null,512),[[A,s.maxRescheduleCount,void 0,{number:!0}]])]),t("div",De,[e[27]||(e[27]=t("label",{class:"form-label"},"Max Total Tokens",-1)),T(t("input",{"onUpdate:modelValue":e[9]||(e[9]=l=>s.maxTotalTokens=l),type:"number",min:"1000",step:"1000",class:"form-input",placeholder:"Unlimited"},null,512),[[A,s.maxTotalTokens,void 0,{number:!0}]])]),t("div",Be,[e[28]||(e[28]=t("label",{class:"form-label"},"Reschedule At Token Count",-1)),T(t("input",{"onUpdate:modelValue":e[10]||(e[10]=l=>s.rescheduleAtTokenCount=l),type:"number",min:"10000",step:"10000",class:"form-input",placeholder:"None"},null,512),[[A,s.rescheduleAtTokenCount,void 0,{number:!0}]])]),((S=o.session)==null?void 0:S.rescheduleCount)>0?(a(),d("div",Ne,[t("label",Fe,[T(t("input",{"onUpdate:modelValue":e[11]||(e[11]=l=>s.resetRescheduleCount=l),type:"checkbox"},null,512),[[w,s.resetRescheduleCount]]),e[29]||(e[29]=t("span",null,"Reset reschedule count to 0",-1))]),t("p",qe," Current count: "+C(o.session.rescheduleCount),1)])):f("",!0)])):f("",!0)]),t("div",Pe,[t("button",{class:"btn btn-secondary",onClick:$}," Cancel "),t("button",{class:"btn btn-primary",disabled:u.value,onClick:E},C(u.value?"Updating...":"Update"),9,ze)])])])):f("",!0)])}}},Mt=L(Ge,[["__scopeId","data-v-e1ffc2da"]]),He={class:"modal-content",role:"dialog","aria-labelledby":"modal-title"},Ke={class:"modal-body"},We={class:"moving-info"},Ye={class:"moving-session-name"},Je={key:0,class:"empty-state"},Qe={key:1,class:"lanes-list"},Xe={class:"lane-label"},Ze=["name","value","disabled","aria-disabled","aria-label"],et={class:"lane-info"},tt={class:"lane-name"},st={key:0,class:"lane-current-badge"},lt={key:1,class:"lane-automation-icon",title:"Automation enabled"},nt={key:2,class:"automation-option"},ot={class:"checkbox-label"},at={class:"modal-footer"},dt=["disabled"],it=["disabled","aria-label"],ut=["disabled"],rt={__name:"MoveCardModal",props:{isOpen:Boolean,projectId:{type:String,required:!0},cardId:{type:String,required:!0},currentLaneId:{type:String,required:!0},sessionName:{type:String,default:""}},emits:["update:isOpen","close","moved"],setup(o,{emit:M}){const n=o,k=M,p=te(),v=P(),u=I(null),h=I(!0),s=I(!1),g=I(!1),c=x(()=>{var l;return((l=p.board)==null?void 0:l.lanes)||[]}),$=x(()=>n.sessionName?n.sessionName:n.cardId||"Unnamed session"),R=x(()=>u.value&&c.value.find(l=>l.id===u.value)||null),_=x(()=>R.value?r(R.value):!1),E=x(()=>u.value&&u.value!==n.currentLaneId);function r(l){return l?!!(l.onEnterTemplateId||l.onEnterPrompt):!1}function e(){k("update:isOpen",!1),k("close"),u.value=null,h.value=!0}async function i(){if(!(!E.value||!n.cardId)){s.value=!0;try{await p.moveCard(n.projectId,n.cardId,u.value,{runOnEnterTemplate:h.value}),v.success("Card moved successfully"),k("moved"),e()}catch(l){console.error("Failed to move card:",l),v.error(l.message||"Failed to move card")}finally{s.value=!1}}}async function m(){if(confirm("Remove this session from the board?")){g.value=!0;try{await p.removeCard(n.projectId,n.cardId),v.success("Session removed from board"),k("close")}catch(l){console.error("Failed to remove card:",l),v.error(l.message||"Failed to remove session")}finally{g.value=!1}}}O(u,(l,b)=>{if(l!==b){const y=c.value.find(V=>V.id===l);h.value=r(y)}}),O(()=>n.isOpen,l=>{l&&(u.value=null,h.value=!0)});function S(l){l.key==="Escape"&&n.isOpen&&e()}return N(()=>{document.addEventListener("keydown",S)}),H(()=>{document.removeEventListener("keydown",S)}),(l,b)=>o.isOpen?(a(),d("div",{key:0,class:"modal-backdrop",onClick:F(e,["self"])},[t("div",He,[t("div",{class:"modal-header"},[b[2]||(b[2]=t("h2",{id:"modal-title",class:"modal-title"}," Move to Lane ",-1)),t("button",{class:"close-btn","aria-label":"Close modal",onClick:e}," × ")]),t("div",Ke,[t("div",We,[b[3]||(b[3]=t("span",{class:"moving-label"},"Moving:",-1)),t("span",Ye,C($.value),1)]),c.value.length===0?(a(),d("div",Je,[...b[4]||(b[4]=[t("p",null,"No lanes available",-1)])])):(a(),d("div",Qe,[(a(!0),d(j,null,D(c.value,y=>(a(),d("div",{key:y.id,class:Y(["lane-row",{"lane-row-current":y.id===o.currentLaneId,"lane-row-disabled":y.id===o.currentLaneId}])},[t("label",Xe,[T(t("input",{"onUpdate:modelValue":b[0]||(b[0]=V=>u.value=V),type:"radio",name:`lane-${o.cardId}`,value:y.id,disabled:y.id===o.currentLaneId,"aria-disabled":y.id===o.currentLaneId,"aria-label":`Move to ${y.name}`},null,8,Ze),[[J,u.value]]),t("span",et,[t("span",tt,C(y.name),1),y.id===o.currentLaneId?(a(),d("span",st,"(current)")):f("",!0),r(y)?(a(),d("span",lt,[...b[5]||(b[5]=[t("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor"},[t("path",{d:"M13 10V3L4 14h7v7l9-11h-7z"})],-1)])])):f("",!0)])])],2))),128))])),_.value?(a(),d("div",nt,[t("label",ot,[T(t("input",{"onUpdate:modelValue":b[1]||(b[1]=y=>h.value=y),type:"checkbox","aria-label":"Run automation on entry"},null,512),[[w,h.value]]),b[6]||(b[6]=t("span",null,"Run automation on entry",-1))])])):f("",!0)]),t("div",at,[t("button",{class:"btn btn-secondary",disabled:g.value,onClick:e}," Cancel ",8,dt),t("button",{class:"btn btn-danger",disabled:g.value,"aria-label":`Remove ${$.value} from board`,onClick:m},C(g.value?"Removing...":"Remove from Board"),9,it),t("button",{class:"btn btn-primary",disabled:!E.value||s.value||g.value,"aria-label":"Move card to selected lane",onClick:i},C(s.value?"Moving...":"Move"),9,ut)])])])):f("",!0)}},Et=L(rt,[["__scopeId","data-v-bddc7788"]]),ct={class:"modal-content",role:"dialog","aria-labelledby":"archive-modal-title"},mt={class:"modal-header"},pt=["disabled"],vt={class:"modal-body"},bt={class:"confirm-message"},ht={key:0,class:"cleanup-option"},ft={class:"checkbox-label"},gt={class:"modal-footer"},kt=["disabled"],yt=["disabled"],Tt={__name:"ArchiveConfirmModal",props:{isOpen:{type:Boolean,default:!1},sessionName:{type:String,default:"this session"},hasCleanupScript:{type:Boolean,default:!1},loading:{type:Boolean,default:!1}},emits:["confirm","cancel"],setup(o,{emit:M}){const n=o,k=M,p=I(!0);O(()=>n.isOpen,g=>{g&&(p.value=!0)});function v(){k("confirm",p.value)}function u(){n.loading||k("cancel")}function h(){n.loading||k("cancel")}function s(g){g.key==="Escape"&&n.isOpen&&!n.loading&&k("cancel")}return N(()=>{document.addEventListener("keydown",s)}),H(()=>{document.removeEventListener("keydown",s)}),(g,c)=>(a(),z(G,{to:"body"},[o.isOpen?(a(),d("div",{key:0,class:"modal-backdrop",onClick:F(h,["self"])},[t("div",ct,[t("div",mt,[c[1]||(c[1]=t("h2",{id:"archive-modal-title",class:"modal-title"}," Archive Session ",-1)),t("button",{class:"close-btn","aria-label":"Close modal",disabled:o.loading,onClick:u}," × ",8,pt)]),t("div",vt,[t("p",bt,[c[2]||(c[2]=B(" Are you sure you want to archive ",-1)),t("strong",null,C(o.sessionName),1),c[3]||(c[3]=B("? ",-1))]),o.hasCleanupScript?(a(),d("div",ht,[t("label",ft,[T(t("input",{"onUpdate:modelValue":c[0]||(c[0]=$=>p.value=$),type:"checkbox","aria-label":"Run git worktree cleanup"},null,512),[[w,p.value]]),c[4]||(c[4]=t("span",null,"Run git worktree cleanup",-1))])])):f("",!0)]),t("div",gt,[t("button",{class:"btn btn-secondary",disabled:o.loading,onClick:u}," Cancel ",8,kt),t("button",{class:"btn btn-primary",disabled:o.loading,onClick:v},C(o.loading?"Archiving...":"Archive"),9,yt)])])])):f("",!0)]))}},wt=L(Tt,[["__scopeId","data-v-140e797f"]]);export{wt as A,Et as M,Mt as S,he as T};