fix(spawn): strip ANSI codes from zellij list-sessions output
Zellij outputs colored text with ANSI escape codes, which caused session name parsing to fail. Now strips escape codes before parsing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
1
.playwright-mcp/console-2026-02-26T22-17-15-253Z.log
Normal file
1
.playwright-mcp/console-2026-02-26T22-17-15-253Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 94144ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://127.0.0.1:7400/api/spawn:0
|
||||||
1
.playwright-mcp/console-2026-02-26T22-19-49-481Z.log
Normal file
1
.playwright-mcp/console-2026-02-26T22-19-49-481Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 398ms] [WARNING] cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation @ https://cdn.tailwindcss.com/:63
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -99,9 +99,11 @@ class SpawnMixin:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Check rate limit inside lock
|
# Check rate limit inside lock
|
||||||
|
# Use None sentinel to distinguish "never spawned" from "spawned at time 0"
|
||||||
|
# (time.monotonic() can be close to 0 on fresh process start)
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
last_spawn = _spawn_timestamps.get(project, 0)
|
last_spawn = _spawn_timestamps.get(project)
|
||||||
if now - last_spawn < SPAWN_COOLDOWN_SEC:
|
if last_spawn is not None and now - last_spawn < SPAWN_COOLDOWN_SEC:
|
||||||
remaining = SPAWN_COOLDOWN_SEC - (now - last_spawn)
|
remaining = SPAWN_COOLDOWN_SEC - (now - last_spawn)
|
||||||
self._send_json(429, {
|
self._send_json(429, {
|
||||||
'ok': False,
|
'ok': False,
|
||||||
@@ -177,8 +179,11 @@ class SpawnMixin:
|
|||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
return False
|
return False
|
||||||
|
# Strip ANSI escape codes (Zellij outputs colored text)
|
||||||
|
ansi_pattern = re.compile(r'\x1b\[[0-9;]*m')
|
||||||
|
output = ansi_pattern.sub('', result.stdout)
|
||||||
# Parse line-by-line to avoid substring false positives
|
# Parse line-by-line to avoid substring false positives
|
||||||
for line in result.stdout.splitlines():
|
for line in output.splitlines():
|
||||||
# Zellij outputs "session_name [Created ...]" or just "session_name"
|
# Zellij outputs "session_name [Created ...]" or just "session_name"
|
||||||
session_name = line.strip().split()[0] if line.strip() else ''
|
session_name = line.strip().split()[0] if line.strip() else ''
|
||||||
if session_name == ZELLIJ_SESSION:
|
if session_name == ZELLIJ_SESSION:
|
||||||
|
|||||||
@@ -75,12 +75,15 @@ export function SpawnModal({ isOpen, onClose, onSpawn, currentProject }) {
|
|||||||
}, [isOpen, handleClose]);
|
}, [isOpen, handleClose]);
|
||||||
|
|
||||||
const handleSpawn = async () => {
|
const handleSpawn = async () => {
|
||||||
const project = currentProject || selectedProject;
|
const rawProject = currentProject || selectedProject;
|
||||||
if (!project) {
|
if (!rawProject) {
|
||||||
setError('Please select a project');
|
setError('Please select a project');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract project name from full path (sidebar passes projectDir like "/Users/.../projects/amc")
|
||||||
|
const project = rawProject.includes('/') ? rawProject.split('/').pop() : rawProject;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
@@ -169,7 +172,7 @@ export function SpawnModal({ isOpen, onClose, onSpawn, currentProject }) {
|
|||||||
<div class="flex flex-col gap-1.5">
|
<div class="flex flex-col gap-1.5">
|
||||||
<label class="text-label font-medium text-dim">Project</label>
|
<label class="text-label font-medium text-dim">Project</label>
|
||||||
<div class="rounded-xl border border-selection/75 bg-bg/70 px-3 py-2 text-sm text-bright">
|
<div class="rounded-xl border border-selection/75 bg-bg/70 px-3 py-2 text-sm text-bright">
|
||||||
${currentProject}
|
${currentProject.includes('/') ? currentProject.split('/').pop() : currentProject}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`}
|
`}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 368 KiB |
Reference in New Issue
Block a user