commandmate 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +19 -19
- 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/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/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]/cli-tool/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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route.js.nft.json +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 +5 -5
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/simple-terminal/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 +9 -9
- package/.next/server/chunks/7536.js +1 -1
- package/.next/server/chunks/8174.js +6 -6
- package/.next/server/chunks/9367.js +2 -2
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/6568-c65d7e4d7db7655b.js +1 -0
- package/.next/static/chunks/{2957-327e43ef4c12808f.js → 9325-9e98829c1e75f42f.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/files/[...path]/{page-9e5adf57cbbbdf05.js → page-7eb14f8043796805.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/page-912c3c4c66821d99.js +1 -0
- package/.next/static/css/d4b58a1129eff6af.css +3 -0
- package/.next/trace +5 -5
- package/dist/server/src/config/auto-yes-config.js +53 -0
- package/dist/server/src/lib/auto-yes-manager.js +6 -4
- package/dist/server/src/lib/claude-session.js +6 -0
- package/dist/server/src/lib/cli-patterns.js +41 -1
- package/dist/server/src/lib/cli-tools/codex.js +16 -3
- package/dist/server/src/lib/pasted-text-helper.js +58 -0
- package/dist/server/src/lib/response-poller.js +1 -0
- package/package.json +1 -1
- package/.next/static/chunks/6568-38a33aa67d82e12b.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-8bd88bdc29607413.js +0 -1
- package/.next/static/css/28be35e4727ae7ef.css +0 -3
- /package/.next/static/{oUD-A998xeBoez6zsrTH3 → HhG0EHeG9E4wTJ4sqnLdv}/_buildManifest.js +0 -0
- /package/.next/static/{oUD-A998xeBoez6zsrTH3 → HhG0EHeG9E4wTJ4sqnLdv}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-Yes Configuration Constants
|
|
4
|
+
*
|
|
5
|
+
* Shared config for Auto-Yes duration settings.
|
|
6
|
+
* Used by both server (auto-yes-manager.ts, route.ts) and client
|
|
7
|
+
* (AutoYesConfirmDialog.tsx, AutoYesToggle.tsx) components.
|
|
8
|
+
*
|
|
9
|
+
* Issue #225: Duration selection feature
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DURATION_LABELS = exports.DEFAULT_AUTO_YES_DURATION = exports.ALLOWED_DURATIONS = void 0;
|
|
13
|
+
exports.isAllowedDuration = isAllowedDuration;
|
|
14
|
+
exports.formatTimeRemaining = formatTimeRemaining;
|
|
15
|
+
/** Allowed Auto-Yes durations in milliseconds */
|
|
16
|
+
exports.ALLOWED_DURATIONS = [3600000, 10800000, 28800000];
|
|
17
|
+
/** Default Auto-Yes duration (1 hour = 3600000ms) */
|
|
18
|
+
exports.DEFAULT_AUTO_YES_DURATION = 3600000;
|
|
19
|
+
/** UI display labels for each duration value */
|
|
20
|
+
exports.DURATION_LABELS = {
|
|
21
|
+
3600000: '1時間',
|
|
22
|
+
10800000: '3時間',
|
|
23
|
+
28800000: '8時間',
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Type guard: check whether a value is a valid AutoYesDuration.
|
|
27
|
+
* Replaces `as AutoYesDuration` casts with a runtime-safe check.
|
|
28
|
+
*/
|
|
29
|
+
function isAllowedDuration(value) {
|
|
30
|
+
return typeof value === 'number' && exports.ALLOWED_DURATIONS.includes(value);
|
|
31
|
+
}
|
|
32
|
+
/** Milliseconds per second */
|
|
33
|
+
const MS_PER_SECOND = 1000;
|
|
34
|
+
/** Milliseconds per minute */
|
|
35
|
+
const MS_PER_MINUTE = 60000;
|
|
36
|
+
/** Milliseconds per hour */
|
|
37
|
+
const MS_PER_HOUR = 3600000;
|
|
38
|
+
/**
|
|
39
|
+
* Format remaining time as MM:SS (under 1 hour) or H:MM:SS (1 hour or more).
|
|
40
|
+
*
|
|
41
|
+
* Extracted from AutoYesToggle.tsx for direct testability and reuse.
|
|
42
|
+
* Negative remaining time is clamped to 0.
|
|
43
|
+
*/
|
|
44
|
+
function formatTimeRemaining(expiresAt) {
|
|
45
|
+
const remaining = Math.max(0, expiresAt - Date.now());
|
|
46
|
+
const hours = Math.floor(remaining / MS_PER_HOUR);
|
|
47
|
+
const minutes = Math.floor((remaining % MS_PER_HOUR) / MS_PER_MINUTE);
|
|
48
|
+
const seconds = Math.floor((remaining % MS_PER_MINUTE) / MS_PER_SECOND);
|
|
49
|
+
if (hours > 0) {
|
|
50
|
+
return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
51
|
+
}
|
|
52
|
+
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
53
|
+
}
|
|
@@ -28,6 +28,7 @@ const auto_yes_resolver_1 = require("./auto-yes-resolver");
|
|
|
28
28
|
const tmux_1 = require("./tmux");
|
|
29
29
|
const manager_1 = require("./cli-tools/manager");
|
|
30
30
|
const cli_patterns_1 = require("./cli-patterns");
|
|
31
|
+
const auto_yes_config_1 = require("../config/auto-yes-config");
|
|
31
32
|
// =============================================================================
|
|
32
33
|
// Constants (Issue #138)
|
|
33
34
|
// =============================================================================
|
|
@@ -39,8 +40,6 @@ exports.MAX_BACKOFF_MS = 60000;
|
|
|
39
40
|
exports.MAX_CONSECUTIVE_ERRORS = 5;
|
|
40
41
|
/** Maximum concurrent pollers (DoS protection) */
|
|
41
42
|
exports.MAX_CONCURRENT_POLLERS = 50;
|
|
42
|
-
/** Timeout duration: 1 hour in milliseconds */
|
|
43
|
-
const AUTO_YES_TIMEOUT_MS = 3600000;
|
|
44
43
|
/**
|
|
45
44
|
* Number of lines from the end to check for thinking indicators (Issue #191)
|
|
46
45
|
* Matches detectPrompt()'s multiple_choice scan range (50 lines in prompt-detector.ts)
|
|
@@ -116,14 +115,17 @@ function getAutoYesState(worktreeId) {
|
|
|
116
115
|
}
|
|
117
116
|
/**
|
|
118
117
|
* Set the auto-yes enabled state for a worktree
|
|
118
|
+
* @param duration - Optional duration in milliseconds (must be an ALLOWED_DURATIONS value).
|
|
119
|
+
* Defaults to DEFAULT_AUTO_YES_DURATION (1 hour) when omitted.
|
|
119
120
|
*/
|
|
120
|
-
function setAutoYesEnabled(worktreeId, enabled) {
|
|
121
|
+
function setAutoYesEnabled(worktreeId, enabled, duration) {
|
|
121
122
|
if (enabled) {
|
|
122
123
|
const now = Date.now();
|
|
124
|
+
const effectiveDuration = duration ?? auto_yes_config_1.DEFAULT_AUTO_YES_DURATION;
|
|
123
125
|
const state = {
|
|
124
126
|
enabled: true,
|
|
125
127
|
enabledAt: now,
|
|
126
|
-
expiresAt: now +
|
|
128
|
+
expiresAt: now + effectiveDuration,
|
|
127
129
|
};
|
|
128
130
|
autoYesStates.set(worktreeId, state);
|
|
129
131
|
return state;
|
|
@@ -17,6 +17,7 @@ exports.stopClaudeSession = stopClaudeSession;
|
|
|
17
17
|
exports.restartClaudeSession = restartClaudeSession;
|
|
18
18
|
const tmux_1 = require("./tmux");
|
|
19
19
|
const cli_patterns_1 = require("./cli-patterns");
|
|
20
|
+
const pasted_text_helper_1 = require("./pasted-text-helper");
|
|
20
21
|
const child_process_1 = require("child_process");
|
|
21
22
|
const util_1 = require("util");
|
|
22
23
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
@@ -359,6 +360,11 @@ async function sendMessageToClaude(worktreeId, message) {
|
|
|
359
360
|
// Send message using sendKeys consistently (CONS-001)
|
|
360
361
|
await (0, tmux_1.sendKeys)(sessionName, message, false);
|
|
361
362
|
await (0, tmux_1.sendKeys)(sessionName, '', true);
|
|
363
|
+
// Issue #212: Detect [Pasted text] and resend Enter for multi-line messages
|
|
364
|
+
// MF-001: Single-line messages skip detection (+0ms overhead)
|
|
365
|
+
if (message.includes('\n')) {
|
|
366
|
+
await (0, pasted_text_helper_1.detectAndResendIfPastedText)(sessionName);
|
|
367
|
+
}
|
|
362
368
|
console.log(`Sent message to Claude session: ${sessionName}`);
|
|
363
369
|
}
|
|
364
370
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Shared between response-poller.ts and API routes
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.GEMINI_PROMPT_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_TRUST_DIALOG_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
|
|
7
|
+
exports.GEMINI_PROMPT_PATTERN = exports.MAX_PASTED_TEXT_RETRIES = exports.PASTED_TEXT_DETECT_DELAY = exports.PASTED_TEXT_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_TRUST_DIALOG_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
|
|
8
8
|
exports.detectThinking = detectThinking;
|
|
9
9
|
exports.getCliToolPatterns = getCliToolPatterns;
|
|
10
10
|
exports.stripAnsi = stripAnsi;
|
|
@@ -74,6 +74,44 @@ exports.CODEX_PROMPT_PATTERN = /^›\s*/m;
|
|
|
74
74
|
* Codex separator pattern
|
|
75
75
|
*/
|
|
76
76
|
exports.CODEX_SEPARATOR_PATTERN = /^─.*Worked for.*─+$/m;
|
|
77
|
+
/**
|
|
78
|
+
* Pasted text pattern
|
|
79
|
+
*
|
|
80
|
+
* Claude CLI displays this when it detects multi-line text paste in the
|
|
81
|
+
* ink-based TextInput. The pattern matches the folded display format.
|
|
82
|
+
*
|
|
83
|
+
* @example "[Pasted text #1 +46 lines]"
|
|
84
|
+
* @see Issue #212, #163
|
|
85
|
+
* @designNote PASTE-001: Pattern matches the start of the indicator only.
|
|
86
|
+
* The line count (+XX lines) is variable, so we match the fixed prefix
|
|
87
|
+
* to minimize false negatives. False positive risk is low because
|
|
88
|
+
* "[Pasted text #" is a unique format generated by Claude CLI's ink renderer.
|
|
89
|
+
* @designNote PASTE-001-FP (SF-S4-002): When used in skipPatterns,
|
|
90
|
+
* line-level matching could filter legitimate response lines if Claude's
|
|
91
|
+
* answer text happens to contain "[Pasted text #". This is unlikely and
|
|
92
|
+
* acceptable -- only the affected line would be lost.
|
|
93
|
+
*/
|
|
94
|
+
exports.PASTED_TEXT_PATTERN = /\[Pasted text #\d+/;
|
|
95
|
+
/**
|
|
96
|
+
* Pasted text detection delay (milliseconds)
|
|
97
|
+
*
|
|
98
|
+
* Wait time after sendKeys for tmux buffer to reflect [Pasted text] display.
|
|
99
|
+
*
|
|
100
|
+
* @see Issue #212
|
|
101
|
+
* @designNote PASTE-002: 500ms is the empirically measured time for
|
|
102
|
+
* Claude CLI's ink rendering to complete. capturePane({ startLine: -10 })
|
|
103
|
+
* reads only the last 10 lines since [Pasted text] appears in the most
|
|
104
|
+
* recent few lines.
|
|
105
|
+
*/
|
|
106
|
+
exports.PASTED_TEXT_DETECT_DELAY = 500;
|
|
107
|
+
/**
|
|
108
|
+
* Pasted text detection max retries
|
|
109
|
+
*
|
|
110
|
+
* @see Issue #212
|
|
111
|
+
* @designNote PASTE-003: 3 retries x 500ms = max 1500ms additional delay.
|
|
112
|
+
* Typically resolves on the first attempt (+500ms).
|
|
113
|
+
*/
|
|
114
|
+
exports.MAX_PASTED_TEXT_RETRIES = 3;
|
|
77
115
|
/**
|
|
78
116
|
* Gemini shell prompt pattern
|
|
79
117
|
*/
|
|
@@ -120,6 +158,7 @@ function getCliToolPatterns(cliToolId) {
|
|
|
120
158
|
/^\s*Tip:/, // Tip lines
|
|
121
159
|
/^\s*\?\s*for shortcuts/, // Shortcuts hint
|
|
122
160
|
/to interrupt\)/, // Part of "esc to interrupt" message
|
|
161
|
+
exports.PASTED_TEXT_PATTERN, // [Pasted text #N +XX lines] (Issue #212)
|
|
123
162
|
],
|
|
124
163
|
};
|
|
125
164
|
case 'codex':
|
|
@@ -141,6 +180,7 @@ function getCliToolPatterns(cliToolId) {
|
|
|
141
180
|
/^\s*└/, // Tree output (completion indicator)
|
|
142
181
|
/^\s*│/, // Continuation lines
|
|
143
182
|
/\(.*esc to interrupt\)/, // Interrupt hint
|
|
183
|
+
exports.PASTED_TEXT_PATTERN, // [Pasted text #N +XX lines] (Issue #212, defensive)
|
|
144
184
|
],
|
|
145
185
|
};
|
|
146
186
|
case 'gemini':
|
|
@@ -9,7 +9,15 @@ const base_1 = require("./base");
|
|
|
9
9
|
const tmux_1 = require("../tmux");
|
|
10
10
|
const child_process_1 = require("child_process");
|
|
11
11
|
const util_1 = require("util");
|
|
12
|
+
const pasted_text_helper_1 = require("../pasted-text-helper");
|
|
12
13
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
14
|
+
/**
|
|
15
|
+
* Extract error message from unknown error type (DRY)
|
|
16
|
+
* Same pattern as claude-session.ts getErrorMessage()
|
|
17
|
+
*/
|
|
18
|
+
function getErrorMessage(error) {
|
|
19
|
+
return error instanceof Error ? error.message : String(error);
|
|
20
|
+
}
|
|
13
21
|
/**
|
|
14
22
|
* Codex initialization timing constants
|
|
15
23
|
* T2.6: Extracted as constants for maintainability
|
|
@@ -79,7 +87,7 @@ class CodexTool extends base_1.BaseCLITool {
|
|
|
79
87
|
console.log(`✓ Started Codex session: ${sessionName}`);
|
|
80
88
|
}
|
|
81
89
|
catch (error) {
|
|
82
|
-
const errorMessage =
|
|
90
|
+
const errorMessage = getErrorMessage(error);
|
|
83
91
|
throw new Error(`Failed to start Codex session: ${errorMessage}`);
|
|
84
92
|
}
|
|
85
93
|
}
|
|
@@ -105,10 +113,15 @@ class CodexTool extends base_1.BaseCLITool {
|
|
|
105
113
|
await execAsync(`tmux send-keys -t "${sessionName}" C-m`);
|
|
106
114
|
// Wait a moment for the message to be processed
|
|
107
115
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
116
|
+
// Issue #212: Detect [Pasted text] and resend Enter for multi-line messages
|
|
117
|
+
// MF-001: Single-line messages skip detection (+0ms overhead)
|
|
118
|
+
if (message.includes('\n')) {
|
|
119
|
+
await (0, pasted_text_helper_1.detectAndResendIfPastedText)(sessionName);
|
|
120
|
+
}
|
|
108
121
|
console.log(`✓ Sent message to Codex session: ${sessionName}`);
|
|
109
122
|
}
|
|
110
123
|
catch (error) {
|
|
111
|
-
const errorMessage =
|
|
124
|
+
const errorMessage = getErrorMessage(error);
|
|
112
125
|
throw new Error(`Failed to send message to Codex: ${errorMessage}`);
|
|
113
126
|
}
|
|
114
127
|
}
|
|
@@ -135,7 +148,7 @@ class CodexTool extends base_1.BaseCLITool {
|
|
|
135
148
|
}
|
|
136
149
|
}
|
|
137
150
|
catch (error) {
|
|
138
|
-
const errorMessage =
|
|
151
|
+
const errorMessage = getErrorMessage(error);
|
|
139
152
|
console.error(`Error stopping Codex session: ${errorMessage}`);
|
|
140
153
|
throw error;
|
|
141
154
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pasted text detection + Enter resend helper
|
|
4
|
+
*
|
|
5
|
+
* Shared helper for claude-session.ts and codex.ts to detect
|
|
6
|
+
* [Pasted text #N +XX lines] in tmux output and automatically
|
|
7
|
+
* resend Enter to start processing.
|
|
8
|
+
*
|
|
9
|
+
* @see Issue #212
|
|
10
|
+
* @designNote SF-001: Extracted as common helper to eliminate code duplication
|
|
11
|
+
* between claude-session.ts and codex.ts.
|
|
12
|
+
* @designNote MF-S4-001: sessionName is expected to be generated by
|
|
13
|
+
* getSessionName() in fixed format ('mcbd-{cli}-{worktreeId}').
|
|
14
|
+
* tmux.ts provides double-quote escaping as a defense layer.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.detectAndResendIfPastedText = detectAndResendIfPastedText;
|
|
18
|
+
const tmux_1 = require("./tmux");
|
|
19
|
+
const cli_patterns_1 = require("./cli-patterns");
|
|
20
|
+
const logger_1 = require("./logger");
|
|
21
|
+
// SF-S2-002: Logger is generated internally, not injected from callers
|
|
22
|
+
const logger = (0, logger_1.createLogger)('pasted-text');
|
|
23
|
+
/**
|
|
24
|
+
* Detect [Pasted text] in tmux buffer and resend Enter if found.
|
|
25
|
+
*
|
|
26
|
+
* Called after sending a multi-line message to handle Claude CLI's
|
|
27
|
+
* paste detection behavior. The caller is responsible for the
|
|
28
|
+
* message.includes('\n') guard condition.
|
|
29
|
+
*
|
|
30
|
+
* @param sessionName - tmux session name, generated by getSessionName()
|
|
31
|
+
* @returns Promise<void>
|
|
32
|
+
*
|
|
33
|
+
* @designNote PASTE-HELPER: Caller responsibilities vs helper responsibilities:
|
|
34
|
+
* Caller: message.includes('\n') guard + call timing control
|
|
35
|
+
* Helper: detect loop (setTimeout wait -> capturePane -> test -> Enter resend)
|
|
36
|
+
* @designNote SF-S2-005: Uses setTimeout+Promise pattern (project convention)
|
|
37
|
+
*/
|
|
38
|
+
async function detectAndResendIfPastedText(sessionName) {
|
|
39
|
+
for (let attempt = 0; attempt < cli_patterns_1.MAX_PASTED_TEXT_RETRIES; attempt++) {
|
|
40
|
+
// SF-S2-005: Project-standard delay pattern
|
|
41
|
+
await new Promise(resolve => setTimeout(resolve, cli_patterns_1.PASTED_TEXT_DETECT_DELAY));
|
|
42
|
+
// PASTE-002: Read only last 10 lines -- [Pasted text] appears in recent output
|
|
43
|
+
const output = await (0, tmux_1.capturePane)(sessionName, { startLine: -10 });
|
|
44
|
+
if (!cli_patterns_1.PASTED_TEXT_PATTERN.test((0, cli_patterns_1.stripAnsi)(output))) {
|
|
45
|
+
return; // Normal: no Pasted text detected
|
|
46
|
+
}
|
|
47
|
+
// Pasted text detected -- resend Enter
|
|
48
|
+
await (0, tmux_1.sendKeys)(sessionName, '', true);
|
|
49
|
+
if (attempt === cli_patterns_1.MAX_PASTED_TEXT_RETRIES - 1) {
|
|
50
|
+
// SF-S4-001: Log with attempt count for traceability
|
|
51
|
+
logger.warn('Pasted text detection: max retries reached', {
|
|
52
|
+
sessionName,
|
|
53
|
+
maxRetries: cli_patterns_1.MAX_PASTED_TEXT_RETRIES,
|
|
54
|
+
finalAttempt: attempt,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -139,6 +139,7 @@ function cleanClaudeResponse(response) {
|
|
|
139
139
|
/\?\s*for shortcuts\s*$/, // Shortcuts hint at end of line
|
|
140
140
|
/^─{10,}$/, // Separator lines
|
|
141
141
|
/^❯\s*$/, // Empty prompt lines
|
|
142
|
+
cli_patterns_1.PASTED_TEXT_PATTERN, // [Pasted text #N +XX lines] (Issue #212)
|
|
142
143
|
];
|
|
143
144
|
// Filter out UI elements and keep only the response content
|
|
144
145
|
const cleanedLines = [];
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6568],{66625:function(e,t,r){r.d(t,{Vw:function(){return j}});var n=r(57437),s=r(2265);r(27648);var a=r(43241),l=r(58819),o=r(99376),i=r(34021),c=r(8672);function d(e){let{status:t,label:r}=e,s=c.F4[t],a="".concat(r,": ").concat(s.label);return"spinner"===s.type?(0,n.jsx)("span",{className:"w-2 h-2 rounded-full flex-shrink-0 border-2 border-t-transparent animate-spin ".concat(s.className),title:a,"aria-label":a}):(0,n.jsx)("span",{className:"w-2 h-2 rounded-full flex-shrink-0 ".concat(s.className),title:a,"aria-label":a})}let u=(0,s.memo)(function(e){let{branch:t,isSelected:r,onClick:s}=e;return(0,n.jsxs)("button",{"data-testid":"branch-list-item",onClick:s,"aria-current":r?"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(r?"bg-gray-700 border-l-2 border-blue-500":"border-l-2 border-transparent","\n "),children:[(0,n.jsxs)("div",{className:"flex items-center gap-3 w-full",children:[t.cliStatus&&(0,n.jsxs)("div",{className:"flex items-center gap-1 flex-shrink-0","aria-label":"CLI tool status",children:[(0,n.jsx)(d,{status:t.cliStatus.claude,label:"Claude"}),(0,n.jsx)(d,{status:t.cliStatus.codex,label:"Codex"})]}),(0,n.jsxs)("div",{className:"flex-1 min-w-0 text-left",children:[(0,n.jsx)("p",{className:"text-sm font-medium text-white truncate",children:t.name}),(0,n.jsx)("p",{className:"text-xs text-gray-400 truncate",children:t.repositoryName})]}),t.hasUnread&&(0,n.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,n.jsx)("div",{"data-testid":"branch-description",className:"pl-6 pr-2 mt-1 text-left",children:(0,n.jsx)("p",{className:"text-xs text-gray-400 line-clamp-2",children:t.description})})]})}),m=[{key:"updatedAt",label:"Updated"},{key:"repositoryName",label:"Repository"},{key:"branchName",label:"Branch"},{key:"status",label:"Status"}],x=(0,s.memo)(function(){var e;let{sortKey:t,sortDirection:r,setSortKey:l,setSortDirection:o}=(0,a.Sz)(),[i,c]=(0,s.useState)(!1),d=(0,s.useRef)(null);(0,s.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,s.useEffect)(()=>{function e(e){"Escape"===e.key&&c(!1)}if(i)return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[i]);let u=(0,s.useCallback)(()=>{c(e=>!e)},[]),x=(0,s.useCallback)(e=>{e===t?o("asc"===r?"desc":"asc"):(l(e),o("updatedAt"===e?"desc":"asc")),c(!1)},[t,r,l,o]),b=(0,s.useCallback)(()=>{o("asc"===r?"desc":"asc")},[r,o]),g=(null===(e=m.find(e=>e.key===t))||void 0===e?void 0:e.label)||"Sort";return(0,n.jsxs)("div",{ref:d,className:"relative","data-testid":"sort-selector",children:[(0,n.jsxs)("div",{className:"flex items-center gap-1",children:[(0,n.jsxs)("button",{type:"button",onClick:u,"aria-expanded":i,"aria-haspopup":"listbox","aria-label":"Sort by ".concat(g),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,n.jsx)(h,{className:"w-3 h-3"}),(0,n.jsx)("span",{className:"hidden sm:inline",children:g})]}),(0,n.jsx)("button",{type:"button",onClick:b,"aria-label":"asc"===r?"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"===r?(0,n.jsx)(f,{className:"w-3 h-3"}):(0,n.jsx)(p,{className:"w-3 h-3"})})]}),i&&(0,n.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:m.map(e=>(0,n.jsxs)("button",{type:"button",role:"option","aria-selected":t===e.key,onClick:()=>x(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,n.jsx)("span",{children:e.label}),t===e.key&&(0,n.jsx)("span",{className:"text-xs",children:"asc"===r?"ASC":"DESC"})]},e.key))})]})});function h(e){let{className:t}=e;return(0,n.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,n.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,n.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"})})}function p(e){let{className:t}=e;return(0,n.jsx)("svg",{className:t,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})}var b=r(47712);let g={waiting:0,ready:1,running:2,generating:3,idle:4},y=(0,s.memo)(function(){let e=(0,o.useRouter)(),{worktrees:t,selectedWorktreeId:r,selectWorktree:l}=(0,i.Mu)(),{closeMobileDrawer:c,sortKey:d,sortDirection:m}=(0,a.Sz)(),[h,f]=(0,s.useState)(""),p=(0,s.useMemo)(()=>{let e=t.map(b.I_),r=e;if(h.trim()){let t=h.toLowerCase();r=e.filter(e=>e.name.toLowerCase().includes(t)||e.repositoryName.toLowerCase().includes(t))}return function(e,t,r){let n=[...e];return n.sort((e,n)=>{let s=0;switch(t){case"updatedAt":{let t=e=>e?e instanceof Date?e.getTime():new Date(e).getTime():0,r=t(e.lastActivity);s=t(n.lastActivity)-r;break}case"repositoryName":{let t=e.repositoryName.toLowerCase(),r=n.repositoryName.toLowerCase();s=t.localeCompare(r);break}case"branchName":{let t=e.name.toLowerCase(),r=n.name.toLowerCase();s=t.localeCompare(r);break}case"status":s=g[e.status]-g[n.status]}return("updatedAt"===t?"desc"===r:"asc"===r)?s:-s}),n}(r,d,m)},[t,h,d,m]),y=t=>{l(t),e.push("/worktrees/".concat(t)),c()};return(0,n.jsxs)("nav",{"data-testid":"sidebar","aria-label":"Branch navigation",className:"h-full flex flex-col bg-gray-900 text-white",role:"navigation",children:[(0,n.jsx)("div",{"data-testid":"sidebar-header",className:"flex-shrink-0 px-4 py-4 border-b border-gray-700",children:(0,n.jsxs)("div",{className:"flex items-center justify-between",children:[(0,n.jsx)("h2",{className:"text-lg font-semibold text-white",children:"Branches"}),(0,n.jsx)(x,{})]})}),(0,n.jsx)("div",{className:"flex-shrink-0 px-4 py-3 border-b border-gray-700",children:(0,n.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,n.jsx)("div",{"data-testid":"branch-list",className:"flex-1 overflow-y-auto",children:0===p.length?(0,n.jsx)("div",{className:"px-4 py-8 text-center text-gray-400",children:h?"No branches found":"No branches available"}):p.map(e=>(0,n.jsx)(u,{branch:e,isSelected:e.id===r,onClick:()=>y(e.id)},e.id))})]})});var v=r(3468);let w="transform transition-transform duration-300 ease-out",j=(0,s.memo)(function(e){let{children:t}=e,{isOpen:r,isMobileDrawerOpen:s,closeMobileDrawer:o}=(0,a.Sz)();return(0,l.d)()?(0,n.jsxs)("div",{"data-testid":"app-shell",className:"h-screen flex flex-col",children:[s&&(0,n.jsx)("div",{"data-testid":"drawer-overlay",className:"fixed inset-0 bg-black/50 z-40",onClick:o,"aria-hidden":"true"}),(0,n.jsx)("aside",{"data-testid":"sidebar-container",className:"\n fixed left-0 top-0 h-full w-72 z-50\n ".concat(w,"\n ").concat(s?"translate-x-0":"-translate-x-full","\n "),role:"complementary",children:(0,n.jsx)(y,{})}),(0,n.jsx)("main",{className:"flex-1 min-h-0 overflow-hidden",role:"main",children:t})]}):(0,n.jsxs)("div",{"data-testid":"app-shell",className:"h-screen flex",children:[(0,n.jsx)("aside",{"data-testid":"sidebar-container",className:"\n fixed left-0 top-0 h-full w-72\n ".concat(w,"\n ").concat(r?"translate-x-0":"-translate-x-full","\n "),style:{zIndex:v.k.SIDEBAR},role:"complementary","aria-hidden":!r,children:(0,n.jsx)(y,{})}),(0,n.jsx)("main",{className:"\n flex-1 min-w-0 h-full overflow-hidden\n transition-[padding] duration-300 ease-out\n ".concat(r?"md:pl-72":"md:pl-0","\n "),role:"main",children:t})]})})},98702:function(e,t,r){r.d(t,{u:function(){return a}});var n=r(57437),s=r(2265);function a(e){let{isOpen:t,onClose:r,title:a,children:l,size:o="lg",showCloseButton:i=!0,disableClose:c=!1}=e,d=(0,s.useRef)(null);return((0,s.useEffect)(()=>{if(c)return;let e=e=>{"Escape"===e.key&&t&&r()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[t,r,c]),(0,s.useEffect)(()=>(t?document.body.style.overflow="hidden":document.body.style.overflow="unset",()=>{document.body.style.overflow="unset"}),[t]),t)?(0,n.jsxs)("div",{className:"fixed inset-0 z-50 overflow-y-auto",children:[(0,n.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 transition-opacity",onClick:c?void 0:r}),(0,n.jsx)("div",{className:"flex min-h-full items-center justify-center p-2 sm:p-4",children:(0,n.jsxs)("div",{ref:d,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]"}[o]," bg-white rounded-lg shadow-xl transform transition-all"),children:[(a||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",children:[(0,n.jsx)("h3",{className:"text-base sm:text-lg font-semibold text-gray-900 truncate pr-2",children:a}),i&&(0,n.jsx)("button",{onClick:r,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",children:l})]})})]}):null}},10789:function(e,t,r){r.d(t,{Ct:function(){return c},zx:function(){return s},Zb:function(){return a},aY:function(){return i},Ol:function(){return l},ll:function(){return o},u_:function(){return d.u}});var n=r(57437);function s(e){let{variant:t="primary",size:r="md",fullWidth:s=!1,loading:a=!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"}[r],s?"w-full":"",l||a?"opacity-50 cursor-not-allowed":"",o].filter(Boolean).join(" ");return(0,n.jsxs)("button",{className:d,disabled:l||a,...c,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"})]}),i]})}function a(e){let{hover:t=!1,padding:r="md",className:s="",children:a,...l}=e,o=["card",t?"card-hover":"",{none:"",sm:"p-3",md:"p-4",lg:"p-6"}[r],s].filter(Boolean).join(" ");return(0,n.jsx)("div",{className:o,...l,children:a})}function l(e){let{className:t="",children:r,...s}=e;return(0,n.jsx)("div",{className:"mb-3 ".concat(t),...s,children:r})}function o(e){let{className:t="",children:r,...s}=e;return(0,n.jsx)("h3",{className:"text-lg font-semibold text-gray-900 ".concat(t),...s,children:r})}function i(e){let{className:t="",children:r,...s}=e;return(0,n.jsx)("div",{className:t,...s,children:r})}function c(e){let{variant:t="gray",dot:r=!1,className:s="",children:a,...l}=e,o=["badge",{success:"badge-success",warning:"badge-warning",error:"badge-error",info:"badge-info",gray:"badge-gray"}[t],s].filter(Boolean).join(" ");return(0,n.jsxs)("span",{className:o,...l,children:[r&&(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"}[t]),"aria-hidden":"true"}),a]})}r(2265);var d=r(98702)},6940:function(e,t,r){r.d(t,{R:function(){return m}});var n=r(57437),s=r(2265),a=r(3227);function l(e,t){if(!t.trim())return e;let r=t.toLowerCase();return e.map(e=>({...e,commands:e.commands.filter(e=>{let t=e.name.toLowerCase().includes(r),n=e.description.toLowerCase().includes(r);return t||n})})).filter(e=>e.commands.length>0)}function o(e){let{groups:t,onSelect:r,highlightedIndex:s=-1,className:a=""}=e,l=0;return 0===t.length?(0,n.jsx)("div",{className:"text-sm text-gray-500 p-4 text-center ".concat(a),children:"No commands available"}):(0,n.jsx)("div",{className:"overflow-y-auto ".concat(a),children:t.map(e=>(0,n.jsxs)("div",{className:"mb-2",children:[(0,n.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,n.jsx)("div",{children:e.commands.map(e=>{let t=l;l++;let a=t===s;return(0,n.jsxs)("button",{type:"button","data-command-item":!0,"data-highlighted":a,onClick:()=>r(e),className:"w-full px-3 py-2 text-left flex items-start gap-2 hover:bg-blue-50 transition-colors ".concat(a?"bg-blue-100":""),children:[(0,n.jsxs)("span",{className:"text-blue-600 font-mono text-sm flex-shrink-0",children:["/",e.name]}),(0,n.jsx)("span",{className:"text-gray-600 text-sm truncate",children:e.description})]},e.name)})})]},e.category))})}function i(e){let{isOpen:t,groups:r,onSelect:a,onClose:i,isMobile:c=!1,position:d,onFreeInput:u}=e,[m,x]=(0,s.useState)(""),[h,f]=(0,s.useState)(0),p=(0,s.useRef)(null),b=(0,s.useMemo)(()=>l(r,m),[r,m]),g=(0,s.useMemo)(()=>b.flatMap(e=>e.commands),[b]);(0,s.useEffect)(()=>{t&&(x(""),f(0),setTimeout(()=>{var e;null===(e=p.current)||void 0===e||e.focus()},50))},[t]);let y=(0,s.useCallback)(e=>{a(e),i()},[a,i]),v=(0,s.useCallback)(e=>{if(t)switch(e.key){case"Escape":e.preventDefault(),i();break;case"ArrowDown":e.preventDefault(),f(e=>Math.min(e+1,g.length-1));break;case"ArrowUp":e.preventDefault(),f(e=>Math.max(e-1,0));break;case"Enter":e.preventDefault(),g[h]&&y(g[h])}},[t,g,h,i,y]);return((0,s.useEffect)(()=>(document.addEventListener("keydown",v),()=>{document.removeEventListener("keydown",v)}),[v]),t)?c?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("div",{className:"fixed inset-0 bg-black/50 z-40",onClick:i,"aria-hidden":"true"}),(0,n.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,n.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-gray-200",children:[(0,n.jsx)("h2",{className:"text-lg font-semibold",children:"Commands"}),(0,n.jsx)("button",{type:"button",onClick:i,"aria-label":"Close",className:"p-2 rounded-full hover:bg-gray-100",children:(0,n.jsx)("svg",{className:"w-5 h-5",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 py-2 border-b border-gray-100",children:(0,n.jsx)("input",{ref:p,type:"text",value:m,onChange:e=>x(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,n.jsxs)("button",{type:"button","data-testid":"free-input-button",onClick:u,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,n.jsx)("span",{className:"text-blue-600",children:(0,n.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.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,n.jsx)("span",{className:"text-gray-600",children:"Enter custom command..."})]}),(0,n.jsx)(o,{groups:b,onSelect:y,highlightedIndex:h,className:"flex-1 overflow-y-auto pb-20"})]})]}):(0,n.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,n.jsx)("div",{className:"px-3 py-2 border-b border-gray-100",children:(0,n.jsx)("input",{ref:p,type:"text",value:m,onChange:e=>x(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,n.jsxs)("button",{type:"button","data-testid":"free-input-button",onClick:u,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,n.jsx)("span",{className:"text-blue-600",children:(0,n.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.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,n.jsx)("span",{className:"text-gray-600",children:"Enter custom command..."})]}),(0,n.jsx)(o,{groups:b,onSelect:y,highlightedIndex:h,className:"flex-1 overflow-y-auto"}),(0,n.jsxs)("div",{className:"px-3 py-1.5 border-t border-gray-100 text-xs text-gray-400 flex gap-3",children:[(0,n.jsxs)("span",{children:[(0,n.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded",children:"Enter"})," select"]}),(0,n.jsxs)("span",{children:[(0,n.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded",children:"Esc"})," close"]})]})]}):null}function c(e){let{worktreeId:t,cliToolId:r,disabled:a=!1,onInterrupt:l}=e,[o,i]=(0,s.useState)(!1),c=(0,s.useRef)(0),u=(0,s.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:r})});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,r,l]);return(0,n.jsx)("button",{type:"button",onClick:u,disabled:a||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,n.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,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"})]}):(0,n.jsx)(d,{})})}function d(){return(0,n.jsx)("svg",{className:"h-5 w-5",fill:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})}var u=r(58819);function m(e){let{worktreeId:t,onMessageSent:r,cliToolId:o,isSessionRunning:d=!1}=e,[m,x]=(0,s.useState)(""),[h,f]=(0,s.useState)(!1),[p,b]=(0,s.useState)(null),[g,y]=(0,s.useState)(!1),[v,w]=(0,s.useState)(!1),j=(0,s.useRef)(null),N=(0,s.useRef)(null),k=(0,s.useRef)(!1),C=(0,s.useRef)(null),S=(0,u.d)(),{groups:E}=function(e,t){let[r,n]=(0,s.useState)([]),[o,i]=(0,s.useState)(!0),[c,d]=(0,s.useState)(null),[u,m]=(0,s.useState)(""),[x,h]=(0,s.useState)(t||"claude"),f=(0,s.useCallback)(async()=>{try{i(!0),d(null);let r=e?"/api/worktrees/".concat(e,"/slash-commands"):"/api/slash-commands";t&&(r+="?cliTool=".concat(t));let s=await fetch(r);if(!s.ok)throw Error("HTTP error ".concat(s.status));let a=await s.json();n(a.groups),h(a.cliTool||t||"claude")}catch(e){d((0,a.zG)(e)),n([])}finally{i(!1)}},[e,t]);(0,s.useEffect)(()=>{f()},[f]);let p=(0,s.useMemo)(()=>r.flatMap(e=>e.commands),[r]),b=(0,s.useMemo)(()=>l(r,u),[r,u]);return{groups:r,filteredGroups:b,allCommands:p,loading:o,error:c,filter:u,setFilter:m,refresh:(0,s.useCallback)(()=>{f()},[f]),cliTool:x}}(t,o);(0,s.useEffect)(()=>{let e=j.current;e&&(m?(e.style.height="auto",e.style.height="".concat(Math.min(e.scrollHeight,160),"px")):e.style.height="24px")},[m]);let L=async()=>{if(!g&&m.trim()&&!h)try{f(!0),b(null);let e=o||"claude";await a.Iv.sendMessage(t,m.trim(),e),x(""),null==r||r(e)}catch(e){b((0,a.zG)(e))}finally{f(!1)}},M=async e=>{e.preventDefault(),await L()},z=()=>{var e;w(!1),null===(e=j.current)||void 0===e||e.focus()};return(0,n.jsxs)("div",{ref:C,className:"space-y-2 relative",children:[p&&(0,n.jsx)("div",{className:"p-2 bg-red-50 border border-red-200 rounded text-sm text-red-800",children:p}),(0,n.jsxs)("form",{onSubmit:M,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:[S&&(0,n.jsx)("button",{type:"button",onClick:()=>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,n.jsx)("svg",{className:"h-5 w-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 20l4-16m2 16l4-16M6 9h14M4 15h14"})})}),(0,n.jsx)("textarea",{ref:j,value:m,onChange:e=>{let t=e.target.value;x(t),"/"===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(),z();return}if(k.current&&"Enter"===e.key){k.current=!1;return}if("Enter"===e.key&&!g&&!v){if(S)return;e.shiftKey||(e.preventDefault(),L())}}},onCompositionStart:()=>{y(!0),k.current=!1,N.current&&clearTimeout(N.current)},onCompositionEnd:()=>{y(!1),k.current=!0,N.current&&clearTimeout(N.current),N.current=setTimeout(()=>{k.current=!1},300)},placeholder:S?"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,n.jsx)(c,{worktreeId:t,cliToolId:o||"claude",disabled:!d}),(0,n.jsx)("button",{type:"submit",disabled:!m.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,n.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,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"})]}):(0,n.jsx)("svg",{className:"h-5 w-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,n.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 19l9 2-9-18-9 18 9-2zm0 0v-8"})})})]}),(0,n.jsx)(i,{isOpen:v,groups:E,onSelect:e=>{var t;x("/".concat(e.name," ")),w(!1),null===(t=j.current)||void 0===t||t.focus()},onClose:z,isMobile:S,onFreeInput:()=>{w(!1),x("/"),setTimeout(()=>{var e;null===(e=j.current)||void 0===e||e.focus()},50)}})]})}},8672:function(e,t,r){r.d(t,{F4:function(){return i},Ie:function(){return d},xh:function(){return c}});let n="bg-gray-500",s="bg-green-500",a="border-blue-500",l="bg-yellow-500",o="bg-red-500",i={idle:{className:n,label:"Idle",type:"dot"},ready:{className:s,label:"Ready",type:"dot"},running:{className:a,label:"Running",type:"spinner"},waiting:{className:l,label:"Waiting for response",type:"dot"},generating:{className:a,label:"Generating",type:"spinner"}},c={idle:{className:n,label:"Idle",type:"dot"},ready:{className:s,label:"Ready",type:"dot"},running:{className:a,label:"Running",type:"spinner"},waiting:{className:l,label:"Waiting for response",type:"dot"},error:{className:o,label:"Error",type:"dot"}},d={idle:{className:n,label:"Idle - No active session",type:"dot"},ready:{className:s,label:"Ready - Waiting for input",type:"dot"},running:{className:a,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,r){r.d(t,{k:function(){return n}});let n={DROPDOWN:10,SIDEBAR:30,MODAL:50,MAXIMIZED_EDITOR:55,TOAST:60,CONTEXT_MENU:70}},58819:function(e,t,r){r.d(t,{d:function(){return s}});var n=r(2265);function s(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{breakpoint:t=768}=e,[r,s]=(0,n.useState)(!1);return(0,n.useEffect)(()=>{let e=()=>window.innerWidth<t;s(e());let r=()=>{s(e())};return window.addEventListener("resize",r),()=>{window.removeEventListener("resize",r)}},[t]),r}},47712:function(e,t,r){function n(e){return e?e.isWaitingForResponse?"waiting":e.isProcessing?"running":e.isRunning?"ready":"idle":"idle"}function s(e){var t,r;let s=!!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:s,lastActivity:e.updatedAt,description:e.description,cliStatus:{claude:n(null===(t=e.sessionStatusByCli)||void 0===t?void 0:t.claude),codex:n(null===(r=e.sessionStatusByCli)||void 0===r?void 0:r.codex)}}}r.d(t,{He:function(){return n},I_:function(){return s}})}}]);
|