From 55290cf9f78d6b0271fd2efe2e7b9400ac25f049 Mon Sep 17 00:00:00 2001 From: chemica_tan Date: Tue, 14 Jul 2026 20:32:50 +0900 Subject: [PATCH] fix(spawn): convert team config paths for readfile() via agmsg_sql_readfile_path resolve_team was the only readfile() caller that passed a raw sed-escaped path into SQL. With a native Windows sqlite3.exe first on PATH (e.g. the WinGet build), readfile() on a POSIX-form path returns NULL, the JSON probe yields no rows, and spawn dies with 'no team is registered' even though join succeeded. Every other caller (join.sh, whoami.sh, identities.sh, api.sh, resolve-project.sh) already uses the helper, which cygpath-converts and SQL-escapes; align spawn.sh with them. Real-world impact is masked in normal use because registrations hold C:/-form project paths, but the test suite runs under a POSIX-form $TMPDIR, so on such a machine every join->spawn test fails. Adds a source-level regression assert (no portable runtime probe exists: it would need a native sqlite3 plus a POSIX-form tmpdir). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_013Hh8w1h5CJJH77a6N4gwN2 --- scripts/spawn.sh | 3 ++- tests/test_spawn.bats | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/spawn.sh b/scripts/spawn.sh index ebf26278..3a306d1b 100755 --- a/scripts/spawn.sh +++ b/scripts/spawn.sh @@ -292,7 +292,8 @@ resolve_team() { project_sql_in=$(agmsg_project_sql_in_list "$PROJECT") for config_file in "$TEAMS_DIR"/*/config.json; do [ -f "$config_file" ] || continue - cfg_sql=$(printf '%s' "$config_file" | sed "s/'/''/g") + # readfile() needs a native-Windows path — agmsg_sql_readfile_path converts and SQL-escapes it. + cfg_sql=$(agmsg_sql_readfile_path "$config_file") team_name=$(agmsg_sqlite_mem \ "SELECT json_extract(CAST(readfile('$cfg_sql') AS TEXT), '\$.name');") # Does any agent in this team have a registration for PROJECT (any type)? diff --git a/tests/test_spawn.bats b/tests/test_spawn.bats index cecc90e8..681e6948 100644 --- a/tests/test_spawn.bats +++ b/tests/test_spawn.bats @@ -650,6 +650,17 @@ YAML [[ "$output" == *"reviewer"* ]] } +@test "spawn: resolve_team reads team configs via agmsg_sql_readfile_path (Windows-native sqlite3 regression)" { + # sqlite3.exe (native Windows) cannot readfile() a POSIX-form path: it returns + # NULL, the JSON probe yields no rows, and spawn dies with 'no team is + # registered' even though join succeeded. The helper cygpath-converts and + # SQL-escapes; a bare sed-escape here reintroduces the bug. No portable + # runtime probe exists (it needs a native sqlite3 plus a POSIX-form tmpdir), + # so assert the source directly. + run grep -F 'cfg_sql=$(agmsg_sql_readfile_path "$config_file")' "$SCRIPTS/spawn.sh" + [ "$status" -eq 0 ] +} + @test "spawn: codex boot prompt uses the \$ skill prefix, not / (#283)" { # codex invokes a skill with \$, not Claude Code's /. The boot script # must carry \$ actas, never / actas. (%q escapes the space as "\ ",