commandmate 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -1
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +12 -12
- package/.next/app-path-routes-manifest.json +1 -1
- package/.next/build-manifest.json +2 -2
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/1.pack +0 -0
- package/.next/cache/webpack/client-production/2.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/route.js +2 -2
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +3 -3
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +7 -7
- package/.next/server/chunks/5488.js +4 -4
- package/.next/server/chunks/8693.js +1 -0
- package/.next/server/chunks/9238.js +14 -14
- package/.next/server/chunks/9367.js +2 -2
- package/.next/server/functions-config-manifest.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/5970-2e18108d0cabd8af.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-4a3c0861367e0391.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-dc0dde49ed95076f.js +1 -0
- package/.next/static/css/7c6675f6f65b4990.css +3 -0
- package/.next/trace +5 -5
- package/dist/server/src/lib/auto-yes-manager.js +114 -25
- package/dist/server/src/lib/claude-session.js +60 -21
- package/dist/server/src/lib/prompt-key.js +30 -0
- package/package.json +12 -1
- package/.next/server/chunks/667.js +0 -1
- package/.next/static/chunks/5970-dc8fb1c8c0217636.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-ce9ac3658f2b7d91.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-1b8e4c49fbaf3f99.js +0 -1
- package/.next/static/css/a69d9c70fce558b4.css +0 -3
- /package/.next/static/{NGcx1ej6oVBba0MO0bwCg → ZTtC8-q8xrYUSilnXmMHl}/_buildManifest.js +0 -0
- /package/.next/static/{NGcx1ej6oVBba0MO0bwCg → ZTtC8-q8xrYUSilnXmMHl}/_ssgManifest.js +0 -0
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* auto-yes responses when browser tabs are in background.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.THINKING_CHECK_LINE_COUNT = exports.MAX_CONCURRENT_POLLERS = exports.MAX_CONSECUTIVE_ERRORS = exports.MAX_BACKOFF_MS = exports.POLLING_INTERVAL_MS = void 0;
|
|
12
|
+
exports.THINKING_CHECK_LINE_COUNT = exports.MAX_CONCURRENT_POLLERS = exports.MAX_CONSECUTIVE_ERRORS = exports.MAX_BACKOFF_MS = exports.COOLDOWN_INTERVAL_MS = exports.POLLING_INTERVAL_MS = void 0;
|
|
13
13
|
exports.isValidWorktreeId = isValidWorktreeId;
|
|
14
14
|
exports.calculateBackoffInterval = calculateBackoffInterval;
|
|
15
15
|
exports.isAutoYesExpired = isAutoYesExpired;
|
|
@@ -29,11 +29,14 @@ const prompt_answer_sender_1 = require("./prompt-answer-sender");
|
|
|
29
29
|
const manager_1 = require("./cli-tools/manager");
|
|
30
30
|
const cli_patterns_1 = require("./cli-patterns");
|
|
31
31
|
const auto_yes_config_1 = require("../config/auto-yes-config");
|
|
32
|
+
const prompt_key_1 = require("./prompt-key");
|
|
32
33
|
// =============================================================================
|
|
33
34
|
// Constants (Issue #138)
|
|
34
35
|
// =============================================================================
|
|
35
36
|
/** Polling interval in milliseconds */
|
|
36
37
|
exports.POLLING_INTERVAL_MS = 2000;
|
|
38
|
+
/** Cooldown interval after successful response (milliseconds) (Issue #306) */
|
|
39
|
+
exports.COOLDOWN_INTERVAL_MS = 5000;
|
|
37
40
|
/** Maximum backoff interval in milliseconds (60 seconds) */
|
|
38
41
|
exports.MAX_BACKOFF_MS = 60000;
|
|
39
42
|
/** Number of consecutive errors before applying backoff */
|
|
@@ -52,6 +55,16 @@ exports.MAX_CONCURRENT_POLLERS = 50;
|
|
|
52
55
|
exports.THINKING_CHECK_LINE_COUNT = 50;
|
|
53
56
|
/** Worktree ID validation pattern (security: prevent command injection) */
|
|
54
57
|
const WORKTREE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
58
|
+
/**
|
|
59
|
+
* Extract error message from unknown error type.
|
|
60
|
+
* Provides consistent error message extraction across the module (DRY).
|
|
61
|
+
*
|
|
62
|
+
* @param error - Unknown error object
|
|
63
|
+
* @returns Error message string, or 'Unknown error' for non-Error values
|
|
64
|
+
*/
|
|
65
|
+
function getErrorMessage(error) {
|
|
66
|
+
return error instanceof Error ? error.message : 'Unknown error';
|
|
67
|
+
}
|
|
55
68
|
/** In-memory storage for auto-yes states (globalThis for hot reload persistence) */
|
|
56
69
|
const autoYesStates = globalThis.__autoYesStates ??
|
|
57
70
|
(globalThis.__autoYesStates = new Map());
|
|
@@ -62,8 +75,11 @@ const autoYesPollerStates = globalThis.__autoYesPollerStates ??
|
|
|
62
75
|
// Utility Functions
|
|
63
76
|
// =============================================================================
|
|
64
77
|
/**
|
|
65
|
-
* Validate worktree ID format (security measure)
|
|
78
|
+
* Validate worktree ID format (security measure).
|
|
66
79
|
* Only allows alphanumeric characters, hyphens, and underscores.
|
|
80
|
+
*
|
|
81
|
+
* @param worktreeId - Worktree ID to validate
|
|
82
|
+
* @returns true if the ID matches the allowed pattern
|
|
67
83
|
*/
|
|
68
84
|
function isValidWorktreeId(worktreeId) {
|
|
69
85
|
if (!worktreeId || worktreeId.length === 0)
|
|
@@ -71,7 +87,12 @@ function isValidWorktreeId(worktreeId) {
|
|
|
71
87
|
return WORKTREE_ID_PATTERN.test(worktreeId);
|
|
72
88
|
}
|
|
73
89
|
/**
|
|
74
|
-
* Calculate backoff interval based on consecutive errors
|
|
90
|
+
* Calculate backoff interval based on consecutive errors.
|
|
91
|
+
* Returns the normal polling interval when errors are below the threshold,
|
|
92
|
+
* and applies exponential backoff (capped at MAX_BACKOFF_MS) above it.
|
|
93
|
+
*
|
|
94
|
+
* @param consecutiveErrors - Number of consecutive errors encountered
|
|
95
|
+
* @returns Polling interval in milliseconds
|
|
75
96
|
*/
|
|
76
97
|
function calculateBackoffInterval(consecutiveErrors) {
|
|
77
98
|
if (consecutiveErrors < exports.MAX_CONSECUTIVE_ERRORS) {
|
|
@@ -89,14 +110,21 @@ function calculateBackoffInterval(consecutiveErrors) {
|
|
|
89
110
|
// Auto-Yes State Management (Existing)
|
|
90
111
|
// =============================================================================
|
|
91
112
|
/**
|
|
92
|
-
* Check if an auto-yes state has expired
|
|
113
|
+
* Check if an auto-yes state has expired.
|
|
114
|
+
* Compares current time against the expiresAt timestamp.
|
|
115
|
+
*
|
|
116
|
+
* @param state - Auto-yes state to check
|
|
117
|
+
* @returns true if the current time is past the expiration time
|
|
93
118
|
*/
|
|
94
119
|
function isAutoYesExpired(state) {
|
|
95
120
|
return Date.now() > state.expiresAt;
|
|
96
121
|
}
|
|
97
122
|
/**
|
|
98
|
-
* Get the auto-yes state for a worktree
|
|
99
|
-
* Returns null if no state exists
|
|
123
|
+
* Get the auto-yes state for a worktree.
|
|
124
|
+
* Returns null if no state exists. If expired, auto-disables and returns the disabled state.
|
|
125
|
+
*
|
|
126
|
+
* @param worktreeId - Worktree identifier
|
|
127
|
+
* @returns Current auto-yes state, or null if no state exists
|
|
100
128
|
*/
|
|
101
129
|
function getAutoYesState(worktreeId) {
|
|
102
130
|
const state = autoYesStates.get(worktreeId);
|
|
@@ -142,7 +170,8 @@ function setAutoYesEnabled(worktreeId, enabled, duration) {
|
|
|
142
170
|
}
|
|
143
171
|
}
|
|
144
172
|
/**
|
|
145
|
-
* Clear all auto-yes states
|
|
173
|
+
* Clear all auto-yes states.
|
|
174
|
+
* @internal Exported for testing purposes only.
|
|
146
175
|
*/
|
|
147
176
|
function clearAllAutoYesStates() {
|
|
148
177
|
autoYesStates.clear();
|
|
@@ -151,28 +180,38 @@ function clearAllAutoYesStates() {
|
|
|
151
180
|
// Server-side Polling (Issue #138)
|
|
152
181
|
// =============================================================================
|
|
153
182
|
/**
|
|
154
|
-
* Get the number of active pollers
|
|
183
|
+
* Get the number of active pollers.
|
|
184
|
+
*
|
|
185
|
+
* @returns Count of currently active polling instances
|
|
155
186
|
*/
|
|
156
187
|
function getActivePollerCount() {
|
|
157
188
|
return autoYesPollerStates.size;
|
|
158
189
|
}
|
|
159
190
|
/**
|
|
160
|
-
* Clear all poller states
|
|
191
|
+
* Clear all poller states.
|
|
192
|
+
* Stops all active pollers before clearing state.
|
|
193
|
+
* @internal Exported for testing purposes only.
|
|
161
194
|
*/
|
|
162
195
|
function clearAllPollerStates() {
|
|
163
196
|
stopAllAutoYesPolling();
|
|
164
197
|
autoYesPollerStates.clear();
|
|
165
198
|
}
|
|
166
199
|
/**
|
|
167
|
-
* Get the last server response timestamp for a worktree
|
|
168
|
-
* Used by clients to prevent duplicate responses
|
|
200
|
+
* Get the last server response timestamp for a worktree.
|
|
201
|
+
* Used by clients to prevent duplicate responses.
|
|
202
|
+
*
|
|
203
|
+
* @param worktreeId - Worktree identifier
|
|
204
|
+
* @returns Timestamp (Date.now()) of the last server response, or null if none
|
|
169
205
|
*/
|
|
170
206
|
function getLastServerResponseTimestamp(worktreeId) {
|
|
171
207
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
172
208
|
return pollerState?.lastServerResponseTimestamp ?? null;
|
|
173
209
|
}
|
|
174
210
|
/**
|
|
175
|
-
* Update the last server response timestamp
|
|
211
|
+
* Update the last server response timestamp.
|
|
212
|
+
*
|
|
213
|
+
* @param worktreeId - Worktree identifier
|
|
214
|
+
* @param timestamp - Timestamp value (Date.now())
|
|
176
215
|
*/
|
|
177
216
|
function updateLastServerResponseTimestamp(worktreeId, timestamp) {
|
|
178
217
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
@@ -181,7 +220,9 @@ function updateLastServerResponseTimestamp(worktreeId, timestamp) {
|
|
|
181
220
|
}
|
|
182
221
|
}
|
|
183
222
|
/**
|
|
184
|
-
* Reset error count for a poller
|
|
223
|
+
* Reset error count for a poller and restore the default polling interval.
|
|
224
|
+
*
|
|
225
|
+
* @param worktreeId - Worktree identifier
|
|
185
226
|
*/
|
|
186
227
|
function resetErrorCount(worktreeId) {
|
|
187
228
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
@@ -191,7 +232,9 @@ function resetErrorCount(worktreeId) {
|
|
|
191
232
|
}
|
|
192
233
|
}
|
|
193
234
|
/**
|
|
194
|
-
* Increment error count and apply backoff if
|
|
235
|
+
* Increment error count and apply backoff if the threshold is exceeded.
|
|
236
|
+
*
|
|
237
|
+
* @param worktreeId - Worktree identifier
|
|
195
238
|
*/
|
|
196
239
|
function incrementErrorCount(worktreeId) {
|
|
197
240
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
@@ -201,7 +244,26 @@ function incrementErrorCount(worktreeId) {
|
|
|
201
244
|
}
|
|
202
245
|
}
|
|
203
246
|
/**
|
|
204
|
-
*
|
|
247
|
+
* Check if the given prompt has already been answered.
|
|
248
|
+
* Extracted from pollAutoYes() to reduce responsibility concentration (F005/SRP).
|
|
249
|
+
*
|
|
250
|
+
* @param pollerState - Current poller state containing the last answered prompt key
|
|
251
|
+
* @param promptKey - Composite key of the current prompt (generated by generatePromptKey)
|
|
252
|
+
* @returns true if the prompt key matches the last answered prompt key
|
|
253
|
+
*/
|
|
254
|
+
function isDuplicatePrompt(pollerState, promptKey) {
|
|
255
|
+
return pollerState.lastAnsweredPromptKey === promptKey;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Internal polling function that recursively schedules itself via setTimeout.
|
|
259
|
+
* Captures tmux output, detects prompts, and sends auto-responses when appropriate.
|
|
260
|
+
*
|
|
261
|
+
* Includes duplicate prevention (Issue #306): skips prompts that have already
|
|
262
|
+
* been answered (tracked via lastAnsweredPromptKey) and applies a cooldown
|
|
263
|
+
* interval (COOLDOWN_INTERVAL_MS) after successful responses.
|
|
264
|
+
*
|
|
265
|
+
* @param worktreeId - Worktree identifier
|
|
266
|
+
* @param cliToolId - CLI tool type being polled
|
|
205
267
|
*/
|
|
206
268
|
async function pollAutoYes(worktreeId, cliToolId) {
|
|
207
269
|
// Check if poller was stopped
|
|
@@ -224,7 +286,7 @@ async function pollAutoYes(worktreeId, cliToolId) {
|
|
|
224
286
|
// while Claude is actively processing (thinking/planning).
|
|
225
287
|
//
|
|
226
288
|
// Issue #191: Apply windowing to detectThinking() to prevent stale thinking
|
|
227
|
-
// summary lines (e.g., "· Simmering
|
|
289
|
+
// summary lines (e.g., "· Simmering...") from blocking prompt detection.
|
|
228
290
|
// Window size matches detectPrompt()'s multiple_choice scan range (50 lines).
|
|
229
291
|
//
|
|
230
292
|
// Safety: Claude CLI does not emit prompts during thinking, so narrowing
|
|
@@ -246,7 +308,14 @@ async function pollAutoYes(worktreeId, cliToolId) {
|
|
|
246
308
|
const promptOptions = (0, cli_patterns_1.buildDetectPromptOptions)(cliToolId);
|
|
247
309
|
const promptDetection = (0, prompt_detector_1.detectPrompt)(cleanOutput, promptOptions);
|
|
248
310
|
if (!promptDetection.isPrompt || !promptDetection.promptData) {
|
|
249
|
-
// No prompt detected
|
|
311
|
+
// No prompt detected - reset lastAnsweredPromptKey (Issue #306)
|
|
312
|
+
pollerState.lastAnsweredPromptKey = null;
|
|
313
|
+
scheduleNextPoll(worktreeId, cliToolId);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
// Issue #306: Check for duplicate prompt before responding
|
|
317
|
+
const promptKey = (0, prompt_key_1.generatePromptKey)(promptDetection.promptData);
|
|
318
|
+
if (isDuplicatePrompt(pollerState, promptKey)) {
|
|
250
319
|
scheduleNextPoll(worktreeId, cliToolId);
|
|
251
320
|
return;
|
|
252
321
|
}
|
|
@@ -274,32 +343,47 @@ async function pollAutoYes(worktreeId, cliToolId) {
|
|
|
274
343
|
updateLastServerResponseTimestamp(worktreeId, Date.now());
|
|
275
344
|
// 7. Reset error count on success
|
|
276
345
|
resetErrorCount(worktreeId);
|
|
346
|
+
// Issue #306: Record answered prompt key and apply cooldown
|
|
347
|
+
pollerState.lastAnsweredPromptKey = promptKey;
|
|
277
348
|
// Log success (without sensitive content)
|
|
278
349
|
console.info(`[Auto-Yes Poller] Sent response for worktree: ${worktreeId}`);
|
|
350
|
+
// Issue #306: Apply cooldown interval after successful response (early return)
|
|
351
|
+
scheduleNextPoll(worktreeId, cliToolId, exports.COOLDOWN_INTERVAL_MS);
|
|
352
|
+
return;
|
|
279
353
|
}
|
|
280
354
|
catch (error) {
|
|
281
355
|
// Increment error count on failure
|
|
282
356
|
incrementErrorCount(worktreeId);
|
|
283
357
|
// Log error (without sensitive details)
|
|
284
|
-
|
|
285
|
-
console.warn(`[Auto-Yes Poller] Error for worktree ${worktreeId}: ${errorMessage}`);
|
|
358
|
+
console.warn(`[Auto-Yes Poller] Error for worktree ${worktreeId}: ${getErrorMessage(error)}`);
|
|
286
359
|
}
|
|
287
|
-
// Schedule next poll
|
|
360
|
+
// Schedule next poll (catch block fallthrough or other paths)
|
|
288
361
|
scheduleNextPoll(worktreeId, cliToolId);
|
|
289
362
|
}
|
|
290
363
|
/**
|
|
291
364
|
* Schedule the next polling iteration
|
|
365
|
+
* @param overrideInterval - Optional interval in milliseconds (S2-F009: type definition).
|
|
366
|
+
* When provided (e.g., COOLDOWN_INTERVAL_MS), overrides pollerState.currentInterval.
|
|
367
|
+
* Type: number | undefined (optional parameter).
|
|
292
368
|
*/
|
|
293
|
-
function scheduleNextPoll(worktreeId, cliToolId) {
|
|
369
|
+
function scheduleNextPoll(worktreeId, cliToolId, overrideInterval) {
|
|
294
370
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
295
371
|
if (!pollerState)
|
|
296
372
|
return;
|
|
373
|
+
// S4-F003: Floor guard - polling interval must not be below POLLING_INTERVAL_MS
|
|
374
|
+
const interval = Math.max(overrideInterval ?? pollerState.currentInterval, exports.POLLING_INTERVAL_MS);
|
|
297
375
|
pollerState.timerId = setTimeout(() => {
|
|
298
376
|
pollAutoYes(worktreeId, cliToolId);
|
|
299
|
-
},
|
|
377
|
+
}, interval);
|
|
300
378
|
}
|
|
301
379
|
/**
|
|
302
|
-
* Start server-side auto-yes polling for a worktree
|
|
380
|
+
* Start server-side auto-yes polling for a worktree.
|
|
381
|
+
* Validates the worktree ID, checks auto-yes state, enforces concurrent poller limits,
|
|
382
|
+
* and begins the polling loop.
|
|
383
|
+
*
|
|
384
|
+
* @param worktreeId - Worktree identifier (must match WORKTREE_ID_PATTERN)
|
|
385
|
+
* @param cliToolId - CLI tool type to poll for
|
|
386
|
+
* @returns Result indicating whether the poller was started, with reason if not
|
|
303
387
|
*/
|
|
304
388
|
function startAutoYesPolling(worktreeId, cliToolId) {
|
|
305
389
|
// Validate worktree ID (security)
|
|
@@ -328,6 +412,7 @@ function startAutoYesPolling(worktreeId, cliToolId) {
|
|
|
328
412
|
consecutiveErrors: 0,
|
|
329
413
|
currentInterval: exports.POLLING_INTERVAL_MS,
|
|
330
414
|
lastServerResponseTimestamp: null,
|
|
415
|
+
lastAnsweredPromptKey: null, // S2-F003: initialized to null
|
|
331
416
|
};
|
|
332
417
|
autoYesPollerStates.set(worktreeId, pollerState);
|
|
333
418
|
// Start polling immediately
|
|
@@ -338,7 +423,10 @@ function startAutoYesPolling(worktreeId, cliToolId) {
|
|
|
338
423
|
return { started: true };
|
|
339
424
|
}
|
|
340
425
|
/**
|
|
341
|
-
* Stop server-side auto-yes polling for a worktree
|
|
426
|
+
* Stop server-side auto-yes polling for a worktree.
|
|
427
|
+
* Clears the timer and removes the poller state.
|
|
428
|
+
*
|
|
429
|
+
* @param worktreeId - Worktree identifier
|
|
342
430
|
*/
|
|
343
431
|
function stopAutoYesPolling(worktreeId) {
|
|
344
432
|
const pollerState = autoYesPollerStates.get(worktreeId);
|
|
@@ -353,7 +441,8 @@ function stopAutoYesPolling(worktreeId) {
|
|
|
353
441
|
console.info(`[Auto-Yes Poller] Stopped for worktree: ${worktreeId}`);
|
|
354
442
|
}
|
|
355
443
|
/**
|
|
356
|
-
* Stop all server-side auto-yes polling (graceful shutdown)
|
|
444
|
+
* Stop all server-side auto-yes polling (graceful shutdown).
|
|
445
|
+
* Clears all timers and removes all poller states.
|
|
357
446
|
*/
|
|
358
447
|
function stopAllAutoYesPolling() {
|
|
359
448
|
for (const [worktreeId, pollerState] of autoYesPollerStates.entries()) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.CLAUDE_PROMPT_POLL_INTERVAL = exports.CLAUDE_SEND_PROMPT_WAIT_TIMEOUT = exports.CLAUDE_PROMPT_WAIT_TIMEOUT = exports.CLAUDE_POST_PROMPT_DELAY = exports.CLAUDE_INIT_POLL_INTERVAL = exports.CLAUDE_INIT_TIMEOUT = void 0;
|
|
8
8
|
exports.clearCachedClaudePath = clearCachedClaudePath;
|
|
9
|
+
exports.isSessionHealthy = isSessionHealthy;
|
|
9
10
|
exports.getSessionName = getSessionName;
|
|
10
11
|
exports.isClaudeInstalled = isClaudeInstalled;
|
|
11
12
|
exports.isClaudeRunning = isClaudeRunning;
|
|
@@ -124,6 +125,17 @@ exports.CLAUDE_SEND_PROMPT_WAIT_TIMEOUT = 10000;
|
|
|
124
125
|
* 200ms provides quick response while minimizing CPU usage.
|
|
125
126
|
*/
|
|
126
127
|
exports.CLAUDE_PROMPT_POLL_INTERVAL = 200;
|
|
128
|
+
/**
|
|
129
|
+
* Maximum expected length of a shell prompt line (characters)
|
|
130
|
+
*
|
|
131
|
+
* Shell prompts are typically under 40 characters (e.g., "user@host:~/project$" ~30 chars).
|
|
132
|
+
* Lines at or above this threshold are not considered shell prompts, preventing
|
|
133
|
+
* false positives from Claude CLI output that happens to end with $, %, or #.
|
|
134
|
+
*
|
|
135
|
+
* Used by isSessionHealthy() to distinguish shell prompts from CLI output.
|
|
136
|
+
* 40 is an empirical threshold with safety margin.
|
|
137
|
+
*/
|
|
138
|
+
const MAX_SHELL_PROMPT_LENGTH = 40;
|
|
127
139
|
/**
|
|
128
140
|
* Cached Claude CLI path
|
|
129
141
|
*/
|
|
@@ -229,45 +241,69 @@ async function getCleanPaneOutput(sessionName, lines = 50) {
|
|
|
229
241
|
const output = await (0, tmux_1.capturePane)(sessionName, { startLine: -lines });
|
|
230
242
|
return (0, cli_patterns_1.stripAnsi)(output);
|
|
231
243
|
}
|
|
232
|
-
// ----- Health Check Functions (Bug 2) -----
|
|
233
244
|
/**
|
|
234
245
|
* Verify that Claude CLI is actually running inside a tmux session
|
|
235
246
|
* Detects broken sessions where tmux exists but Claude failed to start
|
|
236
247
|
*
|
|
248
|
+
* @internal Exported for testing purposes only.
|
|
249
|
+
* Follows clearCachedClaudePath() precedent (L148-156).
|
|
250
|
+
*
|
|
237
251
|
* @param sessionName - tmux session name
|
|
238
|
-
* @returns
|
|
252
|
+
* @returns HealthCheckResult with healthy status and optional reason
|
|
239
253
|
*/
|
|
240
254
|
async function isSessionHealthy(sessionName) {
|
|
241
255
|
try {
|
|
242
256
|
// SF-001: Use shared helper instead of inline capturePane + stripAnsi
|
|
243
257
|
const cleanOutput = await getCleanPaneOutput(sessionName);
|
|
244
|
-
// MF-001: Check error patterns from cli-patterns.ts (SRP - pattern management centralized)
|
|
245
|
-
for (const pattern of cli_patterns_1.CLAUDE_SESSION_ERROR_PATTERNS) {
|
|
246
|
-
if (cleanOutput.includes(pattern)) {
|
|
247
|
-
return false;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
for (const regex of cli_patterns_1.CLAUDE_SESSION_ERROR_REGEX_PATTERNS) {
|
|
251
|
-
if (regex.test(cleanOutput)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
258
|
// MF-002: Check shell prompt endings from extensible array (OCP)
|
|
256
259
|
const trimmed = cleanOutput.trim();
|
|
260
|
+
// S2-F010: Empty output judgment (HealthCheckResult format)
|
|
257
261
|
// C-S2-001: Empty output means tmux session exists but Claude CLI has no output.
|
|
258
262
|
// This is treated as unhealthy because a properly running Claude CLI always
|
|
259
263
|
// produces output (prompt, spinner, or response). An empty pane indicates
|
|
260
264
|
// the CLI process has exited or failed to start.
|
|
261
265
|
if (trimmed === '') {
|
|
262
|
-
return false;
|
|
266
|
+
return { healthy: false, reason: 'empty output' };
|
|
263
267
|
}
|
|
264
|
-
|
|
265
|
-
|
|
268
|
+
// S2-F010: Error pattern detection (HealthCheckResult format)
|
|
269
|
+
// MF-001: Check error patterns from cli-patterns.ts (SRP - pattern management centralized)
|
|
270
|
+
for (const pattern of cli_patterns_1.CLAUDE_SESSION_ERROR_PATTERNS) {
|
|
271
|
+
if (trimmed.includes(pattern)) {
|
|
272
|
+
return { healthy: false, reason: `error pattern: ${pattern}` };
|
|
273
|
+
}
|
|
266
274
|
}
|
|
267
|
-
|
|
275
|
+
for (const regex of cli_patterns_1.CLAUDE_SESSION_ERROR_REGEX_PATTERNS) {
|
|
276
|
+
if (regex.test(trimmed)) {
|
|
277
|
+
return { healthy: false, reason: `error pattern: ${regex.source}` };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// S2-F002: Extract last line after empty line filtering
|
|
281
|
+
const lines = trimmed.split('\n').filter(line => line.trim() !== '');
|
|
282
|
+
const lastLine = lines[lines.length - 1]?.trim() ?? '';
|
|
283
|
+
// F006: Line length check BEFORE SHELL_PROMPT_ENDINGS check (early return)
|
|
284
|
+
if (lastLine.length >= MAX_SHELL_PROMPT_LENGTH) {
|
|
285
|
+
// Long lines are not shell prompts -> treat as healthy (early return)
|
|
286
|
+
return { healthy: true };
|
|
287
|
+
}
|
|
288
|
+
// F003: Individual pattern exclusions for SHELL_PROMPT_ENDINGS
|
|
289
|
+
// NOTE(F003): If new false positive patterns are found in the future,
|
|
290
|
+
// consider refactoring to a structure that associates exclusionPattern
|
|
291
|
+
// with each SHELL_PROMPT_ENDINGS entry. Currently only % needs exclusion (YAGNI).
|
|
292
|
+
if (SHELL_PROMPT_ENDINGS.some(ending => {
|
|
293
|
+
if (!lastLine.endsWith(ending))
|
|
294
|
+
return false;
|
|
295
|
+
// Exclude N% pattern (e.g., "Context left until auto-compact: 7%")
|
|
296
|
+
if (ending === '%' && /\d+%$/.test(lastLine))
|
|
297
|
+
return false;
|
|
298
|
+
return true;
|
|
299
|
+
})) {
|
|
300
|
+
return { healthy: false, reason: `shell prompt ending detected: ${lastLine}` };
|
|
301
|
+
}
|
|
302
|
+
return { healthy: true };
|
|
268
303
|
}
|
|
269
304
|
catch {
|
|
270
|
-
|
|
305
|
+
// S3-F001: Catch block also returns HealthCheckResult format
|
|
306
|
+
return { healthy: false, reason: 'capture error' };
|
|
271
307
|
}
|
|
272
308
|
}
|
|
273
309
|
/**
|
|
@@ -279,8 +315,9 @@ async function isSessionHealthy(sessionName) {
|
|
|
279
315
|
* @returns true if session is healthy and can be reused, false if it was killed
|
|
280
316
|
*/
|
|
281
317
|
async function ensureHealthySession(sessionName) {
|
|
282
|
-
const
|
|
283
|
-
if (!healthy) {
|
|
318
|
+
const result = await isSessionHealthy(sessionName);
|
|
319
|
+
if (!result.healthy) {
|
|
320
|
+
console.warn(`[health-check] Session ${sessionName} unhealthy: ${result.reason}`);
|
|
284
321
|
await (0, tmux_1.killSession)(sessionName);
|
|
285
322
|
return false;
|
|
286
323
|
}
|
|
@@ -376,7 +413,9 @@ async function isClaudeRunning(worktreeId) {
|
|
|
376
413
|
return false;
|
|
377
414
|
}
|
|
378
415
|
// MF-S3-001: Verify session health to avoid reporting broken sessions as running
|
|
379
|
-
return
|
|
416
|
+
// S2-F001: await + extract .healthy to maintain boolean return type
|
|
417
|
+
const result = await isSessionHealthy(sessionName);
|
|
418
|
+
return result.healthy;
|
|
380
419
|
}
|
|
381
420
|
/**
|
|
382
421
|
* Get Claude session state
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generatePromptKey = generatePromptKey;
|
|
4
|
+
/**
|
|
5
|
+
* Generate a composite key for prompt deduplication.
|
|
6
|
+
*
|
|
7
|
+
* Used by both client-side (useAutoYes.ts) and server-side (auto-yes-manager.ts)
|
|
8
|
+
* to ensure consistent prompt identification across the duplicate prevention system.
|
|
9
|
+
*
|
|
10
|
+
* The key format is `{type}:{question}`, which uniquely identifies a prompt
|
|
11
|
+
* by combining its type and question text.
|
|
12
|
+
*
|
|
13
|
+
* @param promptData - Prompt data containing type and question fields
|
|
14
|
+
* @returns Composite key string in the format "type:question"
|
|
15
|
+
*
|
|
16
|
+
* @internal Used for in-memory comparison only. Do NOT use for logging,
|
|
17
|
+
* persistence, or external output. If the return value is ever used in
|
|
18
|
+
* log output, DB storage, or HTML rendering, apply appropriate sanitization
|
|
19
|
+
* (CR/LF escaping, prepared statements, HTML escaping respectively).
|
|
20
|
+
* See SEC: S4-F001.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const key = generatePromptKey({ type: 'yes_no', question: 'Continue?' });
|
|
25
|
+
* // Returns 'yes_no:Continue?'
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function generatePromptKey(promptData) {
|
|
29
|
+
return `${promptData.type}:${promptData.question}`;
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commandmate",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "Git worktree management with Claude CLI and tmux sessions",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"codex-cli",
|
|
8
|
+
"terminal",
|
|
9
|
+
"session-manager",
|
|
10
|
+
"tmux",
|
|
11
|
+
"git-worktree",
|
|
12
|
+
"ai-coding",
|
|
13
|
+
"cli",
|
|
14
|
+
"developer-tools"
|
|
15
|
+
],
|
|
5
16
|
"repository": {
|
|
6
17
|
"type": "git",
|
|
7
18
|
"url": "https://github.com/Kewton/CommandMate.git"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=667,exports.ids=[667],exports.modules={87946:(e,t,r)=>{r.d(t,{Ad:()=>l,l1:()=>o});let n=[36e5,108e5,288e5],l=36e5;function o(e){return"number"==typeof e&&n.includes(e)}},60667:(e,t,r)=>{r.d(t,{bq:()=>m,gf:()=>w,m$:()=>p,bY:()=>g,w:()=>v,Qz:()=>A});var n=r(89194),l=r(63661),o=r(49528),s=r(43839),i=r(19377),a=r(87946);let u=/^[a-zA-Z0-9_-]+$/,c=globalThis.__autoYesStates??(globalThis.__autoYesStates=new Map),f=globalThis.__autoYesPollerStates??(globalThis.__autoYesPollerStates=new Map);function p(e){return!!e&&0!==e.length&&u.test(e)}function d(e){return Date.now()>e.expiresAt}function m(e){let t=c.get(e);if(!t)return null;if(d(t)){let r={...t,enabled:!1};return c.set(e,r),r}return t}function g(e,t,r){if(t){let t=Date.now(),n={enabled:!0,enabledAt:t,expiresAt:t+(r??a.Ad)};return c.set(e,n),n}{let t=c.get(e),r={enabled:!1,enabledAt:t?.enabledAt??0,expiresAt:t?.expiresAt??0};return c.set(e,r),r}}function w(e){let t=f.get(e);return t?.lastServerResponseTimestamp??null}async function b(e,t){if(!f.get(e))return;let r=m(e);if(!r?.enabled||d(r)){A(e);return}try{let r=await (0,n.NA)(e,t,5e3),a=(0,i.vp)(r),u=a.split("\n").slice(-50).join("\n");if((0,i.Wg)(t,u)){h(e,t);return}let c=(0,i.Sg)(t),p=(0,l.F)(a,c);if(!p.isPrompt||!p.promptData){h(e,t);return}let d=function(e){if("yes_no"===e.type)return"y";if("multiple_choice"===e.type){let t=e.options.find(e=>e.isDefault)??e.options[0];return!t||t.requiresTextInput?null:t.number.toString()}return null}(p.promptData);if(null===d){h(e,t);return}let m=s.g.getInstance().getTool(t).getSessionName(e);await (0,o.z)({sessionName:m,answer:d,cliToolId:t,promptData:p.promptData}),function(e,t){let r=f.get(e);r&&(r.lastServerResponseTimestamp=t)}(e,Date.now()),function(e){let t=f.get(e);t&&(t.consecutiveErrors=0,t.currentInterval=2e3)}(e),console.info(`[Auto-Yes Poller] Sent response for worktree: ${e}`)}catch(r){!function(e){let t=f.get(e);if(t){var r;t.consecutiveErrors++,t.currentInterval=(r=t.consecutiveErrors)<5?2e3:Math.min(2e3*Math.pow(2,r-5+1),6e4)}}(e);let t=r instanceof Error?r.message:"Unknown error";console.warn(`[Auto-Yes Poller] Error for worktree ${e}: ${t}`)}h(e,t)}function h(e,t){let r=f.get(e);r&&(r.timerId=setTimeout(()=>{b(e,t)},r.currentInterval))}function v(e,t){if(!p(e))return{started:!1,reason:"invalid worktree ID"};let r=m(e);if(!r?.enabled)return{started:!1,reason:"auto-yes not enabled"};let n=f.has(e);if(!n&&f.size>=50)return{started:!1,reason:"max concurrent pollers reached"};n&&A(e);let l={timerId:null,cliToolId:t,consecutiveErrors:0,currentInterval:2e3,lastServerResponseTimestamp:null};return f.set(e,l),l.timerId=setTimeout(()=>{b(e,t)},2e3),console.info(`[Auto-Yes Poller] Started for worktree: ${e}, cliTool: ${t}`),{started:!0}}function A(e){let t=f.get(e);t&&(t.timerId&&clearTimeout(t.timerId),f.delete(e),console.info(`[Auto-Yes Poller] Stopped for worktree: ${e}`))}},49528:(e,t,r)=>{r.d(t,{z:()=>s});var n=r(10927);let l=/^\[[ x]\] /;function o(e){if(0===e)return[];let t=e>0?"Down":"Up";return Array.from({length:Math.abs(e)},()=>t)}async function s(e){let{sessionName:t,answer:r,cliToolId:s,promptData:i,fallbackPromptType:a,fallbackDefaultOptionNumber:u}=e;if("claude"===s&&(i?.type==="multiple_choice"||"multiple_choice"===a)&&/^\d+$/.test(r)){let e;let s=parseInt(r,10),a=null;if(i?.type==="multiple_choice"){let t=(a=i.options).find(e=>e.isDefault);e=t?.number??1}else e=u??1;let c=s-e;if(null!==a&&a.some(e=>l.test(e.label))&&null!==a){let e=a.filter(e=>l.test(e.label)).length,r=[...o(c),"Space"];r.push(...o(e-s+1)),r.push("Enter"),await (0,n.hL)(t,r)}else{let e=[...o(c),"Enter"];await (0,n.hL)(t,e)}}else await (0,n.Is)(t,r,!1),await new Promise(e=>setTimeout(e,100)),await (0,n.Is)(t,"",!0)}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5970],{20318:function(e,t,n){n.d(t,{Ix:function(){return u},pm:function(){return x}});var r=n(57437),a=n(2265),s=n(41671),l=n(99388),o=n(33245),i=n(32489);function c(e){let{type:t,iconColor:n}=e,a="h-5 w-5 ".concat(n);switch(t){case"success":return(0,r.jsx)(s.Z,{className:a,"data-testid":"toast-icon-success"});case"error":return(0,r.jsx)(l.Z,{className:a,"data-testid":"toast-icon-error"});default:return(0,r.jsx)(o.Z,{className:a,"data-testid":"toast-icon-info"})}}function d(e){let{id:t,message:n,type:s,onClose:l,duration:o=3e3}=e,d=(0,a.useRef)(null),u=function(e){switch(e){case"success":return{bgColor:"bg-green-50",borderColor:"border-green-200",textColor:"text-green-800",iconColor:"text-green-500"};case"error":return{bgColor:"bg-red-50",borderColor:"border-red-200",textColor:"text-red-800",iconColor:"text-red-500"};default:return{bgColor:"bg-blue-50",borderColor:"border-blue-200",textColor:"text-blue-800",iconColor:"text-blue-500"}}}(s);(0,a.useEffect)(()=>(o>0&&(d.current=setTimeout(()=>{l(t)},o)),()=>{d.current&&clearTimeout(d.current)}),[t,o,l]);let x=(0,a.useCallback)(()=>{d.current&&clearTimeout(d.current),l(t)},[t,l]);return(0,r.jsxs)("div",{"data-testid":"toast-".concat(t),role:"alert",className:"\n ".concat(u.bgColor,"\n ").concat(u.borderColor,"\n ").concat(u.textColor,"\n border rounded-lg shadow-lg p-4 min-w-[300px] max-w-[400px]\n flex items-start gap-3\n animate-slide-in\n "),children:[(0,r.jsx)(c,{type:s,iconColor:u.iconColor}),(0,r.jsx)("p",{className:"flex-1 text-sm font-medium",children:n}),(0,r.jsx)("button",{"data-testid":"toast-close-button",onClick:x,"aria-label":"Close notification",className:"\n ".concat(u.textColor,"\n hover:opacity-70\n focus:outline-none focus:ring-2 focus:ring-offset-2\n transition-opacity\n "),children:(0,r.jsx)(i.Z,{className:"h-4 w-4"})})]})}function u(e){let{toasts:t,onClose:n}=e;return(0,r.jsx)("div",{"data-testid":"toast-container","aria-live":"polite",className:"fixed bottom-4 right-4 z-50 flex flex-col gap-2",children:t.map(e=>(0,r.jsx)(d,{id:e.id,message:e.message,type:e.type,onClose:n,duration:e.duration},e.id))})}function x(){let[e,t]=(0,a.useState)([]),n=(0,a.useRef)(0);return{toasts:e,showToast:(0,a.useCallback)(function(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info",a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3e3,s="toast-".concat(++n.current,"-").concat(Date.now()),l={id:s,message:e,type:r,duration:a};return t(e=>[...e,l]),s},[]),removeToast:(0,a.useCallback)(e=>{t(t=>t.filter(t=>t.id!==e))},[]),clearToasts:(0,a.useCallback)(()=>{t([])},[])}}},21221:function(e,t,n){n.d(t,{Vw:function(){return S}});var r=n(57437),a=n(2265);n(27648);var s=n(43241),l=n(58819),o=n(99376),i=n(34021),c=n(8672);function d(e){let{status:t,label:n}=e,a=c.F4[t],s="".concat(n,": ").concat(a.label);return"spinner"===a.type?(0,r.jsx)("span",{className:"w-2 h-2 rounded-full flex-shrink-0 border-2 border-t-transparent animate-spin ".concat(a.className),title:s,"aria-label":s}):(0,r.jsx)("span",{className:"w-2 h-2 rounded-full flex-shrink-0 ".concat(a.className),title:s,"aria-label":s})}let u=(0,a.memo)(function(e){let{branch:t,isSelected:n,onClick:a}=e;return(0,r.jsxs)("button",{"data-testid":"branch-list-item",onClick:a,"aria-current":n?"true":void 0,className:"\n w-full px-4 py-3 flex flex-col gap-1\n hover:bg-gray-800 transition-colors\n focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500\n ".concat(n?"bg-gray-700 border-l-2 border-blue-500":"border-l-2 border-transparent","\n "),children:[(0,r.jsxs)("div",{className:"flex items-center gap-3 w-full",children:[t.cliStatus&&(0,r.jsxs)("div",{className:"flex items-center gap-1 flex-shrink-0","aria-label":"CLI tool status",children:[(0,r.jsx)(d,{status:t.cliStatus.claude,label:"Claude"}),(0,r.jsx)(d,{status:t.cliStatus.codex,label:"Codex"})]}),(0,r.jsxs)("div",{className:"flex-1 min-w-0 text-left",children:[(0,r.jsx)("p",{className:"text-sm font-medium text-white truncate",children:t.name}),(0,r.jsx)("p",{className:"text-xs text-gray-400 truncate",children:t.repositoryName})]}),t.hasUnread&&(0,r.jsx)("span",{"data-testid":"unread-indicator",className:"w-2 h-2 rounded-full bg-blue-500 flex-shrink-0","aria-label":"Has unread messages"})]}),t.description&&(0,r.jsx)("div",{"data-testid":"branch-description",className:"pl-6 pr-2 mt-1 text-left",children:(0,r.jsx)("p",{className:"text-xs text-gray-400 line-clamp-2",children:t.description})})]})}),x=[{key:"updatedAt",label:"Updated"},{key:"repositoryName",label:"Repository"},{key:"branchName",label:"Branch"},{key:"status",label:"Status"}],m=(0,a.memo)(function(){var e;let{sortKey:t,sortDirection:n,setSortKey:l,setSortDirection:o}=(0,s.Sz)(),[i,c]=(0,a.useState)(!1),d=(0,a.useRef)(null);(0,a.useEffect)(()=>{function e(e){d.current&&!d.current.contains(e.target)&&c(!1)}if(i)return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[i]),(0,a.useEffect)(()=>{function e(e){"Escape"===e.key&&c(!1)}if(i)return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[i]);let u=(0,a.useCallback)(()=>{c(e=>!e)},[]),m=(0,a.useCallback)(e=>{e===t?o("asc"===n?"desc":"asc"):(l(e),o("updatedAt"===e?"desc":"asc")),c(!1)},[t,n,l,o]),p=(0,a.useCallback)(()=>{o("asc"===n?"desc":"asc")},[n,o]),b=(null===(e=x.find(e=>e.key===t))||void 0===e?void 0:e.label)||"Sort";return(0,r.jsxs)("div",{ref:d,className:"relative","data-testid":"sort-selector",children:[(0,r.jsxs)("div",{className:"flex items-center gap-1",children:[(0,r.jsxs)("button",{type:"button",onClick:u,"aria-expanded":i,"aria-haspopup":"listbox","aria-label":"Sort by ".concat(b),className:" flex items-center gap-1 px-2 py-1 rounded text-xs text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors ",children:[(0,r.jsx)(h,{className:"w-3 h-3"}),(0,r.jsx)("span",{className:"hidden sm:inline",children:b})]}),(0,r.jsx)("button",{type:"button",onClick:p,"aria-label":"asc"===n?"Sort ascending":"Sort descending",className:" p-1 rounded text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors ",children:"asc"===n?(0,r.jsx)(f,{className:"w-3 h-3"}):(0,r.jsx)(g,{className:"w-3 h-3"})})]}),i&&(0,r.jsx)("div",{role:"listbox","aria-label":"Sort options",className:" absolute right-0 top-full mt-1 z-50 min-w-[140px] py-1 rounded-md shadow-lg bg-gray-800 border border-gray-600 ",children:x.map(e=>(0,r.jsxs)("button",{type:"button",role:"option","aria-selected":t===e.key,onClick:()=>m(e.key),className:"\n w-full px-3 py-2 text-left text-sm\n flex items-center justify-between\n hover:bg-gray-700 transition-colors\n ".concat(t===e.key?"text-blue-400":"text-gray-300","\n "),children:[(0,r.jsx)("span",{children:e.label}),t===e.key&&(0,r.jsx)("span",{className:"text-xs",children:"asc"===n?"ASC":"DESC"})]},e.key))})]})});function h(e){let{className:t}=e;return(0,r.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"})})}function f(e){let{className:t}=e;return(0,r.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"})})}function g(e){let{className:t}=e;return(0,r.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})}var p=n(69234);let b=["en","ja"],y={en:"English",ja:"日本語"};function v(){let{currentLocale:e,switchLocale:t}={currentLocale:(0,p.bU)(),switchLocale:e=>{b.includes(e)&&(!function(e){let t="https:"===window.location.protocol;document.cookie="".concat("locale","=").concat(e,";path=/;max-age=").concat(31536e3,";SameSite=Lax").concat(t?";Secure":"")}(e),localStorage.setItem("locale",e),window.location.reload())}};return(0,r.jsx)("select",{value:e,onChange:e=>t(e.target.value),"aria-label":"Language",className:" w-full px-3 py-2 rounded-md bg-gray-800 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm ",children:b.map(e=>(0,r.jsx)("option",{value:e,children:y[e]},e))})}var w=n(47712);let j={waiting:0,ready:1,running:2,generating:3,idle:4},N=(0,a.memo)(function(){let e=(0,o.useRouter)(),{worktrees:t,selectedWorktreeId:n,selectWorktree:l}=(0,i.Mu)(),{closeMobileDrawer:c,sortKey:d,sortDirection:x}=(0,s.Sz)(),[h,f]=(0,a.useState)(""),g=(0,a.useMemo)(()=>{let e=t.map(w.I_),n=e;if(h.trim()){let t=h.toLowerCase();n=e.filter(e=>e.name.toLowerCase().includes(t)||e.repositoryName.toLowerCase().includes(t))}return function(e,t,n){let r=[...e];return r.sort((e,r)=>{let a=0;switch(t){case"updatedAt":{let t=e=>e?e instanceof Date?e.getTime():new Date(e).getTime():0,n=t(e.lastActivity);a=t(r.lastActivity)-n;break}case"repositoryName":{let t=e.repositoryName.toLowerCase(),n=r.repositoryName.toLowerCase();a=t.localeCompare(n);break}case"branchName":{let t=e.name.toLowerCase(),n=r.name.toLowerCase();a=t.localeCompare(n);break}case"status":a=j[e.status]-j[r.status]}return("updatedAt"===t?"desc"===n:"asc"===n)?a:-a}),r}(n,d,x)},[t,h,d,x]),p=t=>{l(t),e.push("/worktrees/".concat(t)),c()};return(0,r.jsxs)("nav",{"data-testid":"sidebar","aria-label":"Branch navigation",className:"h-full flex flex-col bg-gray-900 text-white",role:"navigation",children:[(0,r.jsx)("div",{"data-testid":"sidebar-header",className:"flex-shrink-0 px-4 py-4 border-b border-gray-700",children:(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsx)("h2",{className:"text-lg font-semibold text-white",children:"Branches"}),(0,r.jsx)(m,{})]})}),(0,r.jsx)("div",{className:"flex-shrink-0 px-4 py-3 border-b border-gray-700",children:(0,r.jsx)("input",{type:"text",placeholder:"Search branches...",value:h,onChange:e=>f(e.target.value),className:" w-full px-3 py-2 rounded-md bg-gray-800 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent "})}),(0,r.jsx)("div",{"data-testid":"branch-list",className:"flex-1 overflow-y-auto",children:0===g.length?(0,r.jsx)("div",{className:"px-4 py-8 text-center text-gray-400",children:h?"No branches found":"No branches available"}):g.map(e=>(0,r.jsx)(u,{branch:e,isSelected:e.id===n,onClick:()=>p(e.id)},e.id))}),(0,r.jsx)("div",{className:"flex-shrink-0 px-4 py-3 border-t border-gray-700",children:(0,r.jsx)(v,{})})]})});var k=n(3468);let C="transform transition-transform duration-300 ease-out",S=(0,a.memo)(function(e){let{children:t}=e,{isOpen:n,isMobileDrawerOpen:a,closeMobileDrawer:o}=(0,s.Sz)();return(0,l.d)()?(0,r.jsxs)("div",{"data-testid":"app-shell",className:"h-screen flex flex-col",children:[a&&(0,r.jsx)("div",{"data-testid":"drawer-overlay",className:"fixed inset-0 bg-black/50 z-40",onClick:o,"aria-hidden":"true"}),(0,r.jsx)("aside",{"data-testid":"sidebar-container",className:"\n fixed left-0 top-0 h-full w-72 z-50\n ".concat(C,"\n ").concat(a?"translate-x-0":"-translate-x-full","\n "),role:"complementary",children:(0,r.jsx)(N,{})}),(0,r.jsx)("main",{className:"flex-1 min-h-0 overflow-hidden",role:"main",children:t})]}):(0,r.jsxs)("div",{"data-testid":"app-shell",className:"h-screen flex",children:[(0,r.jsx)("aside",{"data-testid":"sidebar-container",className:"\n fixed left-0 top-0 h-full w-72\n ".concat(C,"\n ").concat(n?"translate-x-0":"-translate-x-full","\n "),style:{zIndex:k.k.SIDEBAR},role:"complementary","aria-hidden":!n,children:(0,r.jsx)(N,{})}),(0,r.jsx)("main",{className:"\n flex-1 min-w-0 h-full overflow-hidden\n transition-[padding] duration-300 ease-out\n ".concat(n?"md:pl-72":"md:pl-0","\n "),role:"main",children:t})]})})},98702:function(e,t,n){n.d(t,{u:function(){return l}});var r=n(57437),a=n(2265),s=n(54887);function l(e){let{isOpen:t,onClose:n,title:l,children:o,size:i="lg",showCloseButton:c=!0,disableClose:d=!1}=e,u=(0,a.useRef)(null);return((0,a.useEffect)(()=>{if(d)return;let e=e=>{"Escape"===e.key&&t&&n()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[t,n,d]),(0,a.useEffect)(()=>(t?document.body.style.overflow="hidden":document.body.style.overflow="unset",()=>{document.body.style.overflow="unset"}),[t]),t)?(0,s.createPortal)((0,r.jsxs)("div",{className:"fixed inset-0 z-[9999] overflow-y-auto",children:[(0,r.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 transition-opacity",onClick:d?void 0:n}),(0,r.jsx)("div",{className:"relative flex min-h-full items-center justify-center p-2 sm:p-4",children:(0,r.jsxs)("div",{ref:u,className:"relative w-full ".concat({sm:"max-w-[calc(100vw-2rem)] sm:max-w-md",md:"max-w-[calc(100vw-2rem)] sm:max-w-2xl",lg:"max-w-[calc(100vw-2rem)] sm:max-w-4xl",xl:"max-w-[calc(100vw-2rem)] sm:max-w-6xl",full:"max-w-[calc(100vw-2rem)] sm:max-w-[95vw]"}[i]," max-h-[calc(100vh-1rem)] sm:max-h-[calc(100vh-2rem)] flex flex-col bg-white rounded-lg shadow-xl transform transition-all"),children:[(l||c)&&(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 flex-shrink-0",children:[(0,r.jsx)("h3",{className:"text-base sm:text-lg font-semibold text-gray-900 truncate pr-2",children:l}),c&&(0,r.jsx)("button",{onClick:n,className:"text-gray-400 hover:text-gray-600 transition-colors flex-shrink-0",children:(0,r.jsx)("svg",{className:"w-5 h-5 sm:w-6 sm:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),(0,r.jsx)("div",{className:"px-4 sm:px-6 py-3 sm:py-4 overflow-y-auto flex-1 min-h-0",children:o})]})})]}),document.body):null}},10789:function(e,t,n){n.d(t,{Ct:function(){return c},zx:function(){return a},Zb:function(){return s},aY:function(){return i},Ol:function(){return l},ll:function(){return o},u_:function(){return d.u}});var r=n(57437);function a(e){let{variant:t="primary",size:n="md",fullWidth:a=!1,loading:s=!1,disabled:l,className:o="",children:i,...c}=e,d=["btn",{primary:"btn-primary",secondary:"btn-secondary",danger:"btn-danger",ghost:"bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-500"}[t],{sm:"btn-sm",md:"",lg:"btn-lg"}[n],a?"w-full":"",l||s?"opacity-50 cursor-not-allowed":"",o].filter(Boolean).join(" ");return(0,r.jsxs)("button",{className:d,disabled:l||s,...c,children:[s&&(0,r.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[(0,r.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,r.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),i]})}function s(e){let{hover:t=!1,padding:n="md",className:a="",children:s,...l}=e,o=["card",t?"card-hover":"",{none:"",sm:"p-3",md:"p-4",lg:"p-6"}[n],a].filter(Boolean).join(" ");return(0,r.jsx)("div",{className:o,...l,children:s})}function l(e){let{className:t="",children:n,...a}=e;return(0,r.jsx)("div",{className:"mb-3 ".concat(t),...a,children:n})}function o(e){let{className:t="",children:n,...a}=e;return(0,r.jsx)("h3",{className:"text-lg font-semibold text-gray-900 ".concat(t),...a,children:n})}function i(e){let{className:t="",children:n,...a}=e;return(0,r.jsx)("div",{className:t,...a,children:n})}function c(e){let{variant:t="gray",dot:n=!1,className:a="",children:s,...l}=e,o=["badge",{success:"badge-success",warning:"badge-warning",error:"badge-error",info:"badge-info",gray:"badge-gray"}[t],a].filter(Boolean).join(" ");return(0,r.jsxs)("span",{className:o,...l,children:[n&&(0,r.jsx)("span",{className:"mr-1.5 inline-block h-2 w-2 rounded-full ".concat({success:"bg-green-600",warning:"bg-yellow-600",error:"bg-red-600",info:"bg-blue-600",gray:"bg-gray-600"}[t]),"aria-hidden":"true"}),s]})}n(2265);var d=n(98702)},43616:function(e,t,n){n.d(t,{n:function(){return d}});var r=n(57437),a=n(2265),s=n(10789),l=n(20318),o=n(3227),i=n(32636),c=n(93448);function d(e){let{worktreeId:t}=e,[n,d]=(0,a.useState)([]),[u,x]=(0,a.useState)(null),[m,h]=(0,a.useState)(null),[f,g]=(0,a.useState)(!0),[p,b]=(0,a.useState)(null),[y,v]=(0,a.useState)(""),[w,j]=(0,a.useState)(0),[N,k]=(0,a.useState)("all"),[C,S]=(0,a.useState)(!1),{toasts:E,showToast:L,removeToast:z}=(0,l.pm)();(0,a.useEffect)(()=>{(async()=>{try{g(!0),b(null);let e=await o.Iv.getLogs(t);d(e)}catch(e){b((0,o.zG)(e))}finally{g(!1)}})()},[t]);let M=(0,a.useMemo)(()=>"all"===N?n:n.filter(e=>e.toLowerCase().includes(N)),[n,N]),T=async e=>{try{g(!0),b(null);let n=await o.Iv.getLogFile(t,e);h(n.content),x(e),v(""),j(0)}catch(e){b((0,o.zG)(e))}finally{g(!1)}},I=(0,a.useCallback)(async()=>{if(u)try{S(!0);let e=await o.Iv.getLogFile(t,u,{sanitize:!0});await (0,i.v)(e.content),L("Log copied to clipboard (sanitized)","success")}catch(e){L("Failed to export log: ".concat((0,o.zG)(e)),"error")}finally{S(!1)}},[t,u,L]),A=(0,a.useMemo)(()=>{let e;if(!y||!m)return[];let t=RegExp((0,c.hr)(y),"gi"),n=[];for(;null!==(e=t.exec(m));)n.push({index:e.index,length:e[0].length});return n},[y,m]);(0,a.useEffect)(()=>{j(0)},[y]);let B=()=>{A.length>0&&j(e=>(e+1)%A.length)},D=()=>{A.length>0&&j(e=>(e-1+A.length)%A.length)},R=(0,a.useMemo)(()=>{if(!m||!y||0===A.length)return m;let e="",t=0;return A.forEach((n,r)=>{e+=(0,c.Xv)(m.substring(t,n.index));let a=m.substring(n.index,n.index+n.length),s=r===w;e+='<mark class="'.concat(s?"bg-yellow-400 text-black":"bg-yellow-200 text-black",'" data-match-index="').concat(r,'">').concat((0,c.Xv)(a),"</mark>"),t=n.index+n.length}),e+=(0,c.Xv)(m.substring(t))},[m,y,A,w]);return(0,a.useEffect)(()=>{A.length>0&&w>=0&&setTimeout(()=>{let e=document.querySelector('mark[data-match-index="'.concat(w,'"]'));e&&e.scrollIntoView({behavior:"smooth",block:"center"})},100)},[w,A.length]),(0,r.jsxs)("div",{className:"space-y-4",children:[(0,r.jsxs)(s.Zb,{padding:"md",children:[(0,r.jsx)(s.Ol,{children:(0,r.jsxs)("div",{className:"space-y-3",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsx)(s.ll,{children:"Log Files"}),(0,r.jsx)(s.Ct,{variant:"gray",children:M.length})]}),(0,r.jsxs)("div",{className:"flex gap-2 flex-wrap",children:[(0,r.jsxs)(s.zx,{variant:"all"===N?"primary":"ghost",size:"sm",onClick:()=>k("all"),children:["All (",n.length,")"]}),(0,r.jsxs)(s.zx,{variant:"claude"===N?"primary":"ghost",size:"sm",onClick:()=>k("claude"),children:["Claude (",n.filter(e=>e.toLowerCase().includes("claude")).length,")"]}),(0,r.jsxs)(s.zx,{variant:"codex"===N?"primary":"ghost",size:"sm",onClick:()=>k("codex"),children:["Codex (",n.filter(e=>e.toLowerCase().includes("codex")).length,")"]}),(0,r.jsxs)(s.zx,{variant:"gemini"===N?"primary":"ghost",size:"sm",onClick:()=>k("gemini"),children:["Gemini (",n.filter(e=>e.toLowerCase().includes("gemini")).length,")"]})]})]})}),(0,r.jsxs)(s.aY,{children:[f&&0===n.length&&(0,r.jsx)("div",{className:"text-center py-4",children:(0,r.jsx)("div",{className:"inline-block animate-spin rounded-full h-6 w-6 border-4 border-gray-300 border-t-blue-600"})}),p&&(0,r.jsx)("div",{className:"p-3 bg-red-50 border border-red-200 rounded text-sm text-red-800",children:p}),!f&&0===M.length&&!p&&(0,r.jsx)("p",{className:"text-sm text-gray-600 text-center py-4",children:"all"===N?"No log files found":"No ".concat(N," log files found")}),M.length>0&&(0,r.jsx)("div",{className:"space-y-2",children:M.map(e=>(0,r.jsx)("button",{onClick:()=>T(e),className:"w-full text-left px-3 py-2 rounded text-sm font-mono transition-colors ".concat(u===e?"bg-blue-50 text-blue-700 border border-blue-200":"hover:bg-gray-50 border border-transparent"),children:e},e))})]})]}),u&&(0,r.jsxs)(s.Zb,{padding:"md",children:[(0,r.jsx)(s.Ol,{children:(0,r.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsx)(s.ll,{className:"font-mono text-base",children:u}),(0,r.jsxs)("div",{className:"flex gap-2",children:[(0,r.jsx)(s.zx,{variant:"ghost",size:"sm",onClick:I,disabled:!u||C,title:"Copy sanitized log to clipboard",children:C?"Exporting...":"Export"}),(0,r.jsx)(s.zx,{variant:"ghost",size:"sm",onClick:()=>{x(null),h(null),v(""),j(0)},children:"Close"})]})]}),(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsxs)("div",{className:"relative flex-1",children:[(0,r.jsx)("input",{type:"text",value:y,onChange:e=>v(e.target.value),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),e.shiftKey?D():B())},placeholder:"Search in log file...",className:"input w-full pr-20"}),A.length>0&&(0,r.jsxs)("div",{className:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-gray-500",children:[w+1," / ",A.length]})]}),A.length>0&&(0,r.jsxs)("div",{className:"flex gap-1",children:[(0,r.jsx)(s.zx,{variant:"ghost",size:"sm",onClick:D,disabled:0===A.length,title:"Previous match (Shift+Enter)",children:"↑"}),(0,r.jsx)(s.zx,{variant:"ghost",size:"sm",onClick:B,disabled:0===A.length,title:"Next match (Enter)",children:"↓"})]})]})]})}),(0,r.jsxs)(s.aY,{children:[f&&(0,r.jsx)("div",{className:"text-center py-8",children:(0,r.jsx)("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-4 border-gray-300 border-t-blue-600"})}),!f&&m&&(0,r.jsx)("div",{className:"bg-gray-900 text-gray-100 rounded p-4 overflow-x-auto max-h-[500px] scrollbar-thin",children:y&&A.length>0?(0,r.jsx)("pre",{className:"text-xs font-mono whitespace-pre-wrap",dangerouslySetInnerHTML:{__html:R||""}}):(0,r.jsx)("pre",{className:"text-xs font-mono whitespace-pre-wrap",children:m})}),!f&&y&&0===A.length&&m&&(0,r.jsxs)("div",{className:"text-center py-4 text-sm text-gray-500",children:['No matches found for "',y,'"']})]})]}),(0,r.jsx)(l.Ix,{toasts:E,onClose:z})]})}},6940:function(e,t,n){n.d(t,{R:function(){return x}});var r=n(57437),a=n(2265),s=n(3227);function l(e,t){if(!t.trim())return e;let n=t.toLowerCase();return e.map(e=>({...e,commands:e.commands.filter(e=>{let t=e.name.toLowerCase().includes(n),r=e.description.toLowerCase().includes(n);return t||r})})).filter(e=>e.commands.length>0)}function o(e){let{groups:t,onSelect:n,highlightedIndex:a=-1,className:s=""}=e,l=0;return 0===t.length?(0,r.jsx)("div",{className:"text-sm text-gray-500 p-4 text-center ".concat(s),children:"No commands available"}):(0,r.jsx)("div",{className:"overflow-y-auto ".concat(s),children:t.map(e=>(0,r.jsxs)("div",{className:"mb-2",children:[(0,r.jsx)("div",{className:"px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider bg-gray-50",children:e.label}),(0,r.jsx)("div",{children:e.commands.map(e=>{let t=l;l++;let s=t===a;return(0,r.jsxs)("button",{type:"button","data-command-item":!0,"data-highlighted":s,onClick:()=>n(e),className:"w-full px-3 py-2 text-left flex items-start gap-2 hover:bg-blue-50 transition-colors ".concat(s?"bg-blue-100":""),children:[(0,r.jsxs)("span",{className:"text-blue-600 font-mono text-sm flex-shrink-0",children:["/",e.name]}),(0,r.jsx)("span",{className:"text-gray-600 text-sm truncate",children:e.description})]},e.name)})})]},e.category))})}function i(e){let{isOpen:t,groups:n,onSelect:s,onClose:i,isMobile:c=!1,position:d,onFreeInput:u}=e,[x,m]=(0,a.useState)(""),[h,f]=(0,a.useState)(0),g=(0,a.useRef)(null),p=(0,a.useMemo)(()=>l(n,x),[n,x]),b=(0,a.useMemo)(()=>p.flatMap(e=>e.commands),[p]);(0,a.useEffect)(()=>{t&&(m(""),f(0),setTimeout(()=>{var e;null===(e=g.current)||void 0===e||e.focus()},50))},[t]);let y=(0,a.useCallback)(e=>{s(e),i()},[s,i]),v=(0,a.useCallback)(e=>{if(t)switch(e.key){case"Escape":e.preventDefault(),i();break;case"ArrowDown":e.preventDefault(),f(e=>Math.min(e+1,b.length-1));break;case"ArrowUp":e.preventDefault(),f(e=>Math.max(e-1,0));break;case"Enter":e.preventDefault(),b[h]&&y(b[h])}},[t,b,h,i,y]);return((0,a.useEffect)(()=>{if(t)return document.addEventListener("keydown",v),()=>{document.removeEventListener("keydown",v)}},[t,v]),t)?c?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"fixed inset-0 bg-black/50 z-40",onClick:i,"aria-hidden":"true"}),(0,r.jsxs)("div",{"data-testid":"slash-command-bottom-sheet",className:"fixed bottom-0 left-0 right-0 bg-white rounded-t-xl z-50 max-h-[70vh] flex flex-col shadow-xl",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-gray-200",children:[(0,r.jsx)("h2",{className:"text-lg font-semibold",children:"Commands"}),(0,r.jsx)("button",{type:"button",onClick:i,"aria-label":"Close",className:"p-2 rounded-full hover:bg-gray-100",children:(0,r.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),(0,r.jsx)("div",{className:"px-4 py-2 border-b border-gray-100",children:(0,r.jsx)("input",{ref:g,type:"text",value:x,onChange:e=>m(e.target.value),placeholder:"Search commands...",className:"w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"})}),u&&(0,r.jsxs)("button",{type:"button","data-testid":"free-input-button",onClick:()=>u(x),className:"w-full px-4 py-3 text-left border-b border-gray-100 flex items-center gap-2 hover:bg-blue-50 transition-colors",children:[(0,r.jsx)("span",{className:"text-blue-600",children:(0,r.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"})})}),(0,r.jsx)("span",{className:"text-gray-600",children:"Enter custom command..."})]}),(0,r.jsx)(o,{groups:p,onSelect:y,highlightedIndex:h,className:"flex-1 overflow-y-auto pb-20"})]})]}):(0,r.jsxs)("div",{role:"listbox",className:"absolute bg-white border border-gray-200 rounded-lg shadow-lg z-50 w-80 max-h-96 flex flex-col",style:d?{top:d.top,left:d.left}:{bottom:"100%",left:0,marginBottom:"4px"},children:[(0,r.jsx)("div",{className:"px-3 py-2 border-b border-gray-100",children:(0,r.jsx)("input",{ref:g,type:"text",value:x,onChange:e=>m(e.target.value),placeholder:"Search commands...",className:"w-full px-3 py-1.5 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"})}),u&&(0,r.jsxs)("button",{type:"button","data-testid":"free-input-button",onClick:()=>u(x),className:"w-full px-3 py-2 text-left border-b border-gray-100 flex items-center gap-2 hover:bg-blue-50 transition-colors text-sm",children:[(0,r.jsx)("span",{className:"text-blue-600",children:(0,r.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"})})}),(0,r.jsx)("span",{className:"text-gray-600",children:"Enter custom command..."})]}),(0,r.jsx)(o,{groups:p,onSelect:y,highlightedIndex:h,className:"flex-1 overflow-y-auto"}),(0,r.jsxs)("div",{className:"px-3 py-1.5 border-t border-gray-100 text-xs text-gray-400 flex gap-3",children:[(0,r.jsxs)("span",{children:[(0,r.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded",children:"Enter"})," select"]}),(0,r.jsxs)("span",{children:[(0,r.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded",children:"Esc"})," close"]})]})]}):null}function c(e){let{worktreeId:t,cliToolId:n,disabled:s=!1,onInterrupt:l}=e,[o,i]=(0,a.useState)(!1),c=(0,a.useRef)(0),u=(0,a.useCallback)(async()=>{let e=Date.now();if(!(e-c.current<1e3)){c.current=e,i(!0);try{let e=await fetch("/api/worktrees/".concat(t,"/interrupt"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cliToolId:n})});if(e.ok)null==l||l();else{let t=await e.json().catch(()=>({}));console.error("[InterruptButton] Failed to send interrupt:",t.error||e.statusText)}}catch(e){console.error("[InterruptButton] Error sending interrupt:",e)}finally{i(!1)}}},[t,n,l]);return(0,r.jsx)("button",{type:"button",onClick:u,disabled:s||o,className:"flex-shrink-0 p-2 text-orange-600 hover:bg-orange-50 rounded-full transition-colors disabled:text-gray-300 disabled:hover:bg-transparent","aria-label":"Stop processing","data-testid":"interrupt-button",children:o?(0,r.jsxs)("svg",{className:"animate-spin h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[(0,r.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,r.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}):(0,r.jsx)(d,{})})}function d(){return(0,r.jsx)("svg",{className:"h-5 w-5",fill:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})}var u=n(58819);function x(e){let{worktreeId:t,onMessageSent:n,cliToolId:o,isSessionRunning:d=!1}=e,[x,m]=(0,a.useState)(""),[h,f]=(0,a.useState)(!1),[g,p]=(0,a.useState)(null),[b,y]=(0,a.useState)(!1),[v,w]=(0,a.useState)(!1),[j,N]=(0,a.useState)(!1),k=(0,a.useRef)(null),C=(0,a.useRef)(null),S=(0,a.useRef)(!1),E=(0,a.useRef)(null),L=(0,u.d)(),{groups:z}=function(e,t){let[n,r]=(0,a.useState)([]),[o,i]=(0,a.useState)(!0),[c,d]=(0,a.useState)(null),[u,x]=(0,a.useState)(""),[m,h]=(0,a.useState)(t||"claude"),f=(0,a.useCallback)(async()=>{try{i(!0),d(null);let n=e?"/api/worktrees/".concat(e,"/slash-commands"):"/api/slash-commands";t&&(n+="?cliTool=".concat(t));let a=await fetch(n);if(!a.ok)throw Error("HTTP error ".concat(a.status));let s=await a.json();r(s.groups),h(s.cliTool||t||"claude")}catch(e){d((0,s.zG)(e)),r([])}finally{i(!1)}},[e,t]);(0,a.useEffect)(()=>{f()},[f]);let g=(0,a.useMemo)(()=>n.flatMap(e=>e.commands),[n]),p=(0,a.useMemo)(()=>l(n,u),[n,u]);return{groups:n,filteredGroups:p,allCommands:g,loading:o,error:c,filter:u,setFilter:x,refresh:(0,a.useCallback)(()=>{f()},[f]),cliTool:m}}(t,o);(0,a.useEffect)(()=>{let e=k.current;e&&(x?(e.style.height="auto",e.style.height="".concat(Math.min(e.scrollHeight,160),"px")):e.style.height="24px")},[x]);let M=async()=>{if(!b&&x.trim()&&!h)try{f(!0),p(null);let e=o||"claude";await s.Iv.sendMessage(t,x.trim(),e),m(""),N(!1),null==n||n(e)}catch(e){p((0,s.zG)(e))}finally{f(!1)}},T=async e=>{e.preventDefault(),await M()},I=()=>{var e;w(!1),N(!1),null===(e=k.current)||void 0===e||e.focus()};return(0,r.jsxs)("div",{ref:E,className:"space-y-2 relative",children:[g&&(0,r.jsx)("div",{className:"p-2 bg-red-50 border border-red-200 rounded text-sm text-red-800",children:g}),(0,r.jsxs)("form",{onSubmit:T,className:"flex items-end gap-2 bg-white border border-gray-300 rounded-lg px-4 py-2 focus-within:border-blue-500 focus-within:ring-1 focus-within:ring-blue-500",children:[L&&(0,r.jsx)("button",{type:"button",onClick:()=>{j&&N(!1),w(!0)},className:"flex-shrink-0 p-2 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded-full transition-colors","aria-label":"Show slash commands","data-testid":"mobile-command-button",children:(0,r.jsx)("svg",{className:"h-5 w-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"})})}),(0,r.jsx)("textarea",{ref:k,value:x,onChange:e=>{let t=e.target.value;if(m(t),""===t){N(!1),w(!1);return}j||("/"===t||t.startsWith("/")&&!t.includes(" ")?w(!0):w(!1))},onKeyDown:e=>{let{keyCode:t}=e.nativeEvent;if(229!==t){if("Escape"===e.key&&v){e.preventDefault(),I();return}if(S.current&&"Enter"===e.key){S.current=!1;return}if("Enter"===e.key&&!b&&(!v||j)){if(L)return;e.shiftKey||(e.preventDefault(),M())}}},onCompositionStart:()=>{y(!0),S.current=!1,C.current&&clearTimeout(C.current)},onCompositionEnd:()=>{y(!1),S.current=!0,C.current&&clearTimeout(C.current),C.current=setTimeout(()=>{S.current=!1},300)},placeholder:L?"Type your message...":"Type your message... (/ for commands, Shift+Enter for line break)",disabled:h,rows:1,className:"flex-1 outline-none bg-transparent resize-none py-1 overflow-y-auto scrollbar-thin",style:{minHeight:"24px",maxHeight:"160px"}}),(0,r.jsx)(c,{worktreeId:t,cliToolId:o||"claude",disabled:!d}),(0,r.jsx)("button",{type:"submit",disabled:!x.trim()||h,className:"flex-shrink-0 p-2 text-blue-600 hover:bg-blue-50 rounded-full transition-colors disabled:text-gray-300 disabled:hover:bg-transparent","aria-label":"Send message",children:h?(0,r.jsxs)("svg",{className:"animate-spin h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[(0,r.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,r.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}):(0,r.jsx)("svg",{className:"h-5 w-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 19l9 2-9-18-9 18 9-2zm0 0v-8"})})})]}),(0,r.jsx)(i,{isOpen:v,groups:z,onSelect:e=>{var t;m("/".concat(e.name," ")),w(!1),null===(t=k.current)||void 0===t||t.focus()},onClose:I,isMobile:L,onFreeInput:e=>{w(!1),N(!0),m(e?"/".concat(e):"/"),setTimeout(()=>{var e;null===(e=k.current)||void 0===e||e.focus()},50)}})]})}},8672:function(e,t,n){n.d(t,{F4:function(){return i},Ie:function(){return d},xh:function(){return c}});let r="bg-gray-500",a="bg-green-500",s="border-blue-500",l="bg-yellow-500",o="bg-red-500",i={idle:{className:r,label:"Idle",type:"dot"},ready:{className:a,label:"Ready",type:"dot"},running:{className:s,label:"Running",type:"spinner"},waiting:{className:l,label:"Waiting for response",type:"dot"},generating:{className:s,label:"Generating",type:"spinner"}},c={idle:{className:r,label:"Idle",type:"dot"},ready:{className:a,label:"Ready",type:"dot"},running:{className:s,label:"Running",type:"spinner"},waiting:{className:l,label:"Waiting for response",type:"dot"},error:{className:o,label:"Error",type:"dot"}},d={idle:{className:r,label:"Idle - No active session",type:"dot"},ready:{className:a,label:"Ready - Waiting for input",type:"dot"},running:{className:s,label:"Running - Processing",type:"spinner"},waiting:{className:l,label:"Waiting - User input required",type:"dot"},error:{className:o,label:"Error",type:"dot"}}},3468:function(e,t,n){n.d(t,{k:function(){return r}});let r={DROPDOWN:10,SIDEBAR:30,MODAL:50,MAXIMIZED_EDITOR:55,TOAST:60,CONTEXT_MENU:70}},58819:function(e,t,n){n.d(t,{d:function(){return a}});var r=n(2265);function a(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{breakpoint:t=768}=e,[n,a]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{let e=()=>window.innerWidth<t;a(e());let n=()=>{a(e())};return window.addEventListener("resize",n),()=>{window.removeEventListener("resize",n)}},[t]),n}},32636:function(e,t,n){n.d(t,{v:function(){return a}});let r=/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\[[0-9;]*m/g;async function a(e){if(!e||0===e.trim().length)return;let t=e.replace(r,"");await navigator.clipboard.writeText(t)}},98408:function(e,t,n){n.d(t,{G:function(){return l}});var r=n(69073),a=n(8854);let s={en:a._,ja:r.ja};function l(e){var t;return null!==(t=s[e])&&void 0!==t?t:a._}},93448:function(e,t,n){function r(e,t){let n=null;return function(){for(var r=arguments.length,a=Array(r),s=0;s<r;s++)a[s]=arguments[s];n&&clearTimeout(n),n=setTimeout(()=>{e(...a),n=null},t)}}function a(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e){let t=new Set;for(let n of e){t.add(n);let e=n.split("/"),r="";for(let n=0;n<e.length-1;n++)r=r?"".concat(r,"/").concat(e[n]):e[n],t.add(r)}return t}function l(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:30;return e.length<=t?e:"".concat(e.substring(0,t-3),"...")}function o(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{Ds:function(){return r},Ps:function(){return s},Xv:function(){return o},aS:function(){return l},hr:function(){return a}})},47712:function(e,t,n){function r(e){return e?e.isWaitingForResponse?"waiting":e.isProcessing?"running":e.isRunning?"ready":"idle":"idle"}function a(e){var t,n;let a=!!e.lastAssistantMessageAt&&(!e.lastViewedAt||new Date(e.lastAssistantMessageAt)>new Date(e.lastViewedAt));return{id:e.id,name:e.name,repositoryName:e.repositoryName,status:"idle",hasUnread:a,lastActivity:e.updatedAt,description:e.description,cliStatus:{claude:r(null===(t=e.sessionStatusByCli)||void 0===t?void 0:t.claude),codex:r(null===(n=e.sessionStatusByCli)||void 0===n?void 0:n.codex)}}}n.d(t,{He:function(){return r},I_:function(){return a}})}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5441],{20084:function(e,r,s){Promise.resolve().then(s.bind(s,50653))},50653:function(e,r,s){"use strict";s.r(r),s.d(r,{default:function(){return m}});var n=s(57437),t=s(2265),a=s(99376),o=s(38706),l=s(10789),c=s(53012),i=s(23260),d=s(12158);function m(){let e=(0,a.useRouter)(),r=(0,a.useParams)(),s=(0,o.T)("common"),m=r.id,x=r.path.join("/"),[u,h]=(0,t.useState)(null),[p,b]=(0,t.useState)(!0),[g,f]=(0,t.useState)(null),y=(null==u?void 0:u.extension)==="md"||(null==u?void 0:u.extension)==="markdown";return(0,t.useEffect)(()=>{(async()=>{b(!0),f(null);try{let e=await fetch("/api/worktrees/".concat(m,"/files/").concat(x));if(!e.ok){let r=await e.json();throw Error(r.error||"Failed to load file")}let r=await e.json();h(r)}catch(e){f(e instanceof Error?e.message:"Failed to load file")}finally{b(!1)}})()},[m,x]),(0,n.jsxs)("div",{className:"min-h-screen bg-gray-50",children:[(0,n.jsx)("div",{className:"sticky top-0 z-10 bg-white border-b border-gray-200 shadow-sm",children:(0,n.jsxs)("div",{className:"max-w-7xl mx-auto px-4 py-3 flex items-center gap-3",children:[(0,n.jsxs)("button",{onClick:()=>e.back(),className:"flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors","aria-label":s("back"),children:[(0,n.jsx)("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 19l-7-7m0 0l7-7m-7 7h18"})}),(0,n.jsx)("span",{className:"hidden sm:inline",children:s("back")})]}),(0,n.jsx)("div",{className:"flex-1 min-w-0",children:(0,n.jsx)("h1",{className:"text-lg font-semibold text-gray-900 truncate",children:x})})]})}),(0,n.jsxs)("div",{className:"max-w-7xl mx-auto px-4 py-6",children:[p&&(0,n.jsx)(l.Zb,{padding:"lg",children:(0,n.jsxs)("div",{className:"flex items-center justify-center py-12",children:[(0,n.jsx)("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-4 border-gray-300 border-t-blue-600"}),(0,n.jsx)("p",{className:"ml-3 text-gray-600",children:"Loading file..."})]})}),g&&(0,n.jsx)(l.Zb,{padding:"lg",children:(0,n.jsx)("div",{className:"bg-red-50 border border-red-200 rounded-lg p-4",children:(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("svg",{className:"w-5 h-5 text-red-600 flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),(0,n.jsx)("p",{className:"text-sm text-red-800",children:g})]})})}),u&&!p&&!g&&(0,n.jsxs)(l.Zb,{padding:"none",children:[(0,n.jsx)("div",{className:"bg-gray-100 px-4 py-3 border-b border-gray-200",children:(0,n.jsxs)("p",{className:"text-xs text-gray-600 font-mono break-all",children:[u.worktreePath,"/",u.path]})}),(0,n.jsx)("div",{className:"p-6 sm:p-8 bg-white",children:y?(0,n.jsx)("div",{className:"prose prose-slate max-w-none prose-headings:font-semibold prose-h1:text-3xl prose-h1:border-b prose-h1:pb-2 prose-h2:text-2xl prose-h2:border-b prose-h2:pb-2 prose-h3:text-xl prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline prose-pre:bg-gray-100 prose-pre:border prose-pre:border-gray-200 prose-code:text-sm prose-code:bg-gray-100 prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none prose-img:rounded-lg prose-img:shadow-md",children:(0,n.jsx)(c.UG,{remarkPlugins:[i.Z],rehypePlugins:[d.Z],components:{code:e=>{let{inline:r,className:s,children:t,...a}=e;return r?(0,n.jsx)("code",{className:"bg-gray-100 text-gray-800 px-1.5 py-0.5 rounded text-sm font-mono",...a,children:t}):(0,n.jsx)("code",{className:s,...a,children:t})},pre:e=>{let{children:r}=e;return(0,n.jsx)("pre",{className:"bg-gray-50 border border-gray-200 rounded-md p-4 overflow-x-auto",children:r})},table:e=>{let{children:r}=e;return(0,n.jsx)("div",{className:"overflow-x-auto",children:(0,n.jsx)("table",{className:"border-collapse border border-gray-300",children:r})})},th:e=>{let{children:r}=e;return(0,n.jsx)("th",{className:"border border-gray-300 bg-gray-100 px-4 py-2 text-left font-semibold",children:r})},td:e=>{let{children:r}=e;return(0,n.jsx)("td",{className:"border border-gray-300 px-4 py-2",children:r})},blockquote:e=>{let{children:r}=e;return(0,n.jsx)("blockquote",{className:"border-l-4 border-gray-300 pl-4 italic text-gray-700",children:r})}},children:u.content})}):(0,n.jsx)("pre",{className:"bg-gray-50 border border-gray-200 rounded-md p-4 overflow-x-auto text-sm",children:(0,n.jsx)("code",{className:"language-".concat(u.extension),children:u.content})})})]})]})]})}},98702:function(e,r,s){"use strict";s.d(r,{u:function(){return o}});var n=s(57437),t=s(2265),a=s(54887);function o(e){let{isOpen:r,onClose:s,title:o,children:l,size:c="lg",showCloseButton:i=!0,disableClose:d=!1}=e,m=(0,t.useRef)(null);return((0,t.useEffect)(()=>{if(d)return;let e=e=>{"Escape"===e.key&&r&&s()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[r,s,d]),(0,t.useEffect)(()=>(r?document.body.style.overflow="hidden":document.body.style.overflow="unset",()=>{document.body.style.overflow="unset"}),[r]),r)?(0,a.createPortal)((0,n.jsxs)("div",{className:"fixed inset-0 z-[9999] overflow-y-auto",children:[(0,n.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 transition-opacity",onClick:d?void 0:s}),(0,n.jsx)("div",{className:"relative flex min-h-full items-center justify-center p-2 sm:p-4",children:(0,n.jsxs)("div",{ref:m,className:"relative w-full ".concat({sm:"max-w-[calc(100vw-2rem)] sm:max-w-md",md:"max-w-[calc(100vw-2rem)] sm:max-w-2xl",lg:"max-w-[calc(100vw-2rem)] sm:max-w-4xl",xl:"max-w-[calc(100vw-2rem)] sm:max-w-6xl",full:"max-w-[calc(100vw-2rem)] sm:max-w-[95vw]"}[c]," max-h-[calc(100vh-1rem)] sm:max-h-[calc(100vh-2rem)] flex flex-col bg-white rounded-lg shadow-xl transform transition-all"),children:[(o||i)&&(0,n.jsxs)("div",{className:"flex items-center justify-between px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 flex-shrink-0",children:[(0,n.jsx)("h3",{className:"text-base sm:text-lg font-semibold text-gray-900 truncate pr-2",children:o}),i&&(0,n.jsx)("button",{onClick:s,className:"text-gray-400 hover:text-gray-600 transition-colors flex-shrink-0",children:(0,n.jsx)("svg",{className:"w-5 h-5 sm:w-6 sm:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),(0,n.jsx)("div",{className:"px-4 sm:px-6 py-3 sm:py-4 overflow-y-auto flex-1 min-h-0",children:l})]})})]}),document.body):null}},10789:function(e,r,s){"use strict";s.d(r,{Ct:function(){return i},zx:function(){return t},Zb:function(){return a},aY:function(){return c},Ol:function(){return o},ll:function(){return l},u_:function(){return d.u}});var n=s(57437);function t(e){let{variant:r="primary",size:s="md",fullWidth:t=!1,loading:a=!1,disabled:o,className:l="",children:c,...i}=e,d=["btn",{primary:"btn-primary",secondary:"btn-secondary",danger:"btn-danger",ghost:"bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-500"}[r],{sm:"btn-sm",md:"",lg:"btn-lg"}[s],t?"w-full":"",o||a?"opacity-50 cursor-not-allowed":"",l].filter(Boolean).join(" ");return(0,n.jsxs)("button",{className:d,disabled:o||a,...i,children:[a&&(0,n.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[(0,n.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,n.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),c]})}function a(e){let{hover:r=!1,padding:s="md",className:t="",children:a,...o}=e,l=["card",r?"card-hover":"",{none:"",sm:"p-3",md:"p-4",lg:"p-6"}[s],t].filter(Boolean).join(" ");return(0,n.jsx)("div",{className:l,...o,children:a})}function o(e){let{className:r="",children:s,...t}=e;return(0,n.jsx)("div",{className:"mb-3 ".concat(r),...t,children:s})}function l(e){let{className:r="",children:s,...t}=e;return(0,n.jsx)("h3",{className:"text-lg font-semibold text-gray-900 ".concat(r),...t,children:s})}function c(e){let{className:r="",children:s,...t}=e;return(0,n.jsx)("div",{className:r,...t,children:s})}function i(e){let{variant:r="gray",dot:s=!1,className:t="",children:a,...o}=e,l=["badge",{success:"badge-success",warning:"badge-warning",error:"badge-error",info:"badge-info",gray:"badge-gray"}[r],t].filter(Boolean).join(" ");return(0,n.jsxs)("span",{className:l,...o,children:[s&&(0,n.jsx)("span",{className:"mr-1.5 inline-block h-2 w-2 rounded-full ".concat({success:"bg-green-600",warning:"bg-yellow-600",error:"bg-red-600",info:"bg-blue-600",gray:"bg-gray-600"}[r]),"aria-hidden":"true"}),a]})}s(2265);var d=s(98702)}},function(e){e.O(0,[9234,1038,2971,2117,1744],function(){return e(e.s=20084)}),_N_E=e.O()}]);
|