diff --git a/.playwright-mcp/console-2026-02-26T22-17-15-253Z.log b/.playwright-mcp/console-2026-02-26T22-17-15-253Z.log new file mode 100644 index 0000000..8640c72 --- /dev/null +++ b/.playwright-mcp/console-2026-02-26T22-17-15-253Z.log @@ -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 diff --git a/.playwright-mcp/console-2026-02-26T22-19-49-481Z.log b/.playwright-mcp/console-2026-02-26T22-19-49-481Z.log new file mode 100644 index 0000000..33b7193 --- /dev/null +++ b/.playwright-mcp/console-2026-02-26T22-19-49-481Z.log @@ -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 diff --git a/amc_server/__pycache__/context.cpython-313.pyc b/amc_server/__pycache__/context.cpython-313.pyc index 6183698..d64dcb7 100644 Binary files a/amc_server/__pycache__/context.cpython-313.pyc and b/amc_server/__pycache__/context.cpython-313.pyc differ diff --git a/amc_server/__pycache__/handler.cpython-313.pyc b/amc_server/__pycache__/handler.cpython-313.pyc index 81d731f..a508aba 100644 Binary files a/amc_server/__pycache__/handler.cpython-313.pyc and b/amc_server/__pycache__/handler.cpython-313.pyc differ diff --git a/amc_server/__pycache__/server.cpython-313.pyc b/amc_server/__pycache__/server.cpython-313.pyc index f454a5a..0be8b72 100644 Binary files a/amc_server/__pycache__/server.cpython-313.pyc and b/amc_server/__pycache__/server.cpython-313.pyc differ diff --git a/amc_server/mixins/__pycache__/http.cpython-313.pyc b/amc_server/mixins/__pycache__/http.cpython-313.pyc index 408f027..050d7c3 100644 Binary files a/amc_server/mixins/__pycache__/http.cpython-313.pyc and b/amc_server/mixins/__pycache__/http.cpython-313.pyc differ diff --git a/amc_server/mixins/__pycache__/parsing.cpython-313.pyc b/amc_server/mixins/__pycache__/parsing.cpython-313.pyc index 26553a6..d302a00 100644 Binary files a/amc_server/mixins/__pycache__/parsing.cpython-313.pyc and b/amc_server/mixins/__pycache__/parsing.cpython-313.pyc differ diff --git a/amc_server/mixins/__pycache__/skills.cpython-313.pyc b/amc_server/mixins/__pycache__/skills.cpython-313.pyc index 7ca31d4..ff4f9ec 100644 Binary files a/amc_server/mixins/__pycache__/skills.cpython-313.pyc and b/amc_server/mixins/__pycache__/skills.cpython-313.pyc differ diff --git a/amc_server/mixins/__pycache__/spawn.cpython-313.pyc b/amc_server/mixins/__pycache__/spawn.cpython-313.pyc index 59b1392..be81ef4 100644 Binary files a/amc_server/mixins/__pycache__/spawn.cpython-313.pyc and b/amc_server/mixins/__pycache__/spawn.cpython-313.pyc differ diff --git a/amc_server/mixins/__pycache__/state.cpython-313.pyc b/amc_server/mixins/__pycache__/state.cpython-313.pyc index e14a55a..bb317ea 100644 Binary files a/amc_server/mixins/__pycache__/state.cpython-313.pyc and b/amc_server/mixins/__pycache__/state.cpython-313.pyc differ diff --git a/amc_server/mixins/spawn.py b/amc_server/mixins/spawn.py index 5021297..b974309 100644 --- a/amc_server/mixins/spawn.py +++ b/amc_server/mixins/spawn.py @@ -99,9 +99,11 @@ class SpawnMixin: try: # 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() - last_spawn = _spawn_timestamps.get(project, 0) - if now - last_spawn < SPAWN_COOLDOWN_SEC: + last_spawn = _spawn_timestamps.get(project) + if last_spawn is not None and now - last_spawn < SPAWN_COOLDOWN_SEC: remaining = SPAWN_COOLDOWN_SEC - (now - last_spawn) self._send_json(429, { 'ok': False, @@ -177,8 +179,11 @@ class SpawnMixin: ) if result.returncode != 0: 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 - for line in result.stdout.splitlines(): + for line in output.splitlines(): # Zellij outputs "session_name [Created ...]" or just "session_name" session_name = line.strip().split()[0] if line.strip() else '' if session_name == ZELLIJ_SESSION: diff --git a/dashboard/components/SpawnModal.js b/dashboard/components/SpawnModal.js index 8a3901a..bbb2ce6 100644 --- a/dashboard/components/SpawnModal.js +++ b/dashboard/components/SpawnModal.js @@ -75,12 +75,15 @@ export function SpawnModal({ isOpen, onClose, onSpawn, currentProject }) { }, [isOpen, handleClose]); const handleSpawn = async () => { - const project = currentProject || selectedProject; - if (!project) { + const rawProject = currentProject || selectedProject; + if (!rawProject) { setError('Please select a project'); return; } + // Extract project name from full path (sidebar passes projectDir like "/Users/.../projects/amc") + const project = rawProject.includes('/') ? rawProject.split('/').pop() : rawProject; + setLoading(true); setError(null); @@ -169,7 +172,7 @@ export function SpawnModal({ isOpen, onClose, onSpawn, currentProject }) {