1- """Tests for the per-integration `SPECIFY_INTEGRATION_ <KEY>_EXTRA_ARGS` env-var hook.
1+ """Tests for the per-integration `SPECKIT_INTEGRATION_ <KEY>_EXTRA_ARGS` env-var hook.
22
33The hook is implemented in `IntegrationBase._apply_extra_args_env_var`
44and wired into every concrete `build_exec_args` —
@@ -128,10 +128,10 @@ class _TomlAgentStub(TomlIntegration):
128128
129129@pytest .fixture (autouse = True )
130130def _clean_extra_args_env (monkeypatch ):
131- """Strip any leaked SPECIFY_INTEGRATION_ *_EXTRA_ARGS from the test
131+ """Strip any leaked SPECKIT_INTEGRATION_ *_EXTRA_ARGS from the test
132132 env so a developer's shell setting doesn't pollute results."""
133133 for key in list (os .environ ):
134- if key .startswith ("SPECIFY_INTEGRATION_ " ) and key .endswith (
134+ if key .startswith ("SPECKIT_INTEGRATION_ " ) and key .endswith (
135135 "_EXTRA_ARGS"
136136 ):
137137 monkeypatch .delenv (key , raising = False )
@@ -151,7 +151,7 @@ def test_env_var_set_flag_inserted_before_model_and_output_format(
151151 monkeypatch ,
152152):
153153 monkeypatch .setenv (
154- "SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS " , "--dangerously-skip-permissions"
154+ "SPECKIT_INTEGRATION_CLAUDE_EXTRA_ARGS " , "--dangerously-skip-permissions"
155155 )
156156 args = _ClaudeStub ().build_exec_args ("hello prompt" , model = "sonnet" )
157157 assert args == [
@@ -168,7 +168,7 @@ def test_env_var_set_flag_inserted_before_model_and_output_format(
168168
169169def test_env_var_multi_token_parsed_via_shlex (monkeypatch ):
170170 monkeypatch .setenv (
171- "SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS " ,
171+ "SPECKIT_INTEGRATION_CLAUDE_EXTRA_ARGS " ,
172172 "--dangerously-skip-permissions --max-turns 3" ,
173173 )
174174 args = _ClaudeStub ().build_exec_args ("p" )
@@ -189,36 +189,36 @@ def test_malformed_quoting_raises_actionable_value_error(monkeypatch):
189189 error naming the offending env var and showing the invalid value,
190190 rather than crashing workflow dispatch with a bare shlex traceback."""
191191 monkeypatch .setenv (
192- "SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS " ,
192+ "SPECKIT_INTEGRATION_CLAUDE_EXTRA_ARGS " ,
193193 '--flag "unterminated' ,
194194 )
195195 with pytest .raises (ValueError ) as excinfo :
196196 _ClaudeStub ().build_exec_args ("p" )
197197 msg = str (excinfo .value )
198- assert "SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS " in msg
198+ assert "SPECKIT_INTEGRATION_CLAUDE_EXTRA_ARGS " in msg
199199 assert "--flag \" unterminated" in msg
200200
201201
202202def test_env_var_empty_or_whitespace_is_noop (monkeypatch ):
203203 """An env var set to '' or ' ' is treated as unset."""
204- monkeypatch .setenv ("SPECIFY_INTEGRATION_CLAUDE_EXTRA_ARGS " , " " )
204+ monkeypatch .setenv ("SPECKIT_INTEGRATION_CLAUDE_EXTRA_ARGS " , " " )
205205 args = _ClaudeStub ().build_exec_args ("p" )
206206 assert args == ["claude" , "-p" , "p" , "--output-format" , "json" ]
207207
208208
209209def test_other_integration_env_var_ignored (monkeypatch ):
210- """`SPECIFY_INTEGRATION_GEMINI_EXTRA_ARGS ` set must NOT leak into
210+ """`SPECKIT_INTEGRATION_GEMINI_EXTRA_ARGS ` set must NOT leak into
211211 Claude's argv (per-integration scoping)."""
212- monkeypatch .setenv ("SPECIFY_INTEGRATION_GEMINI_EXTRA_ARGS " , "--gemini-only-flag" )
212+ monkeypatch .setenv ("SPECKIT_INTEGRATION_GEMINI_EXTRA_ARGS " , "--gemini-only-flag" )
213213 args = _ClaudeStub ().build_exec_args ("p" )
214214 assert args == ["claude" , "-p" , "p" , "--output-format" , "json" ]
215215
216216
217217def test_key_normalization_hyphen_to_underscore_uppercase (monkeypatch ):
218- """`kiro-cli` key looks up `SPECIFY_INTEGRATION_KIRO_CLI_EXTRA_ARGS `
218+ """`kiro-cli` key looks up `SPECKIT_INTEGRATION_KIRO_CLI_EXTRA_ARGS `
219219 (hyphens replaced with underscores, then uppercased)."""
220220 monkeypatch .setenv (
221- "SPECIFY_INTEGRATION_KIRO_CLI_EXTRA_ARGS " , "--some-kiro-flag"
221+ "SPECKIT_INTEGRATION_KIRO_CLI_EXTRA_ARGS " , "--some-kiro-flag"
222222 )
223223 args = _KiroCliStub ().build_exec_args ("p" )
224224 assert args == [
@@ -234,7 +234,7 @@ def test_key_normalization_hyphen_to_underscore_uppercase(monkeypatch):
234234def test_requires_cli_false_returns_none (monkeypatch ):
235235 """`requires_cli: False` short-circuits to None — the env-var
236236 hook is never reached and no argv is built."""
237- monkeypatch .setenv ("SPECIFY_INTEGRATION_NO_CLI_EXTRA_ARGS " , "--should-not-appear" )
237+ monkeypatch .setenv ("SPECKIT_INTEGRATION_NO_CLI_EXTRA_ARGS " , "--should-not-appear" )
238238 assert _NoCliStub ().build_exec_args ("p" ) is None
239239
240240
@@ -254,7 +254,7 @@ def test_markdown_integration_base_honours_extra_args(monkeypatch):
254254 `build_exec_args` — must honour the env var via the base
255255 implementation. Covers the most common integration pattern."""
256256 monkeypatch .setenv (
257- "SPECIFY_INTEGRATION_MD_AGENT_EXTRA_ARGS " , "--debug --max-tokens 100"
257+ "SPECKIT_INTEGRATION_MD_AGENT_EXTRA_ARGS " , "--debug --max-tokens 100"
258258 )
259259 args = _MarkdownAgentStub ().build_exec_args ("p" )
260260 assert args == [
@@ -274,7 +274,7 @@ def test_toml_integration_base_honours_extra_args(monkeypatch):
274274 `build_exec_args` — must honour the env var via the base
275275 implementation. Covers Gemini/Tabnine-style integrations."""
276276 monkeypatch .setenv (
277- "SPECIFY_INTEGRATION_TOML_AGENT_EXTRA_ARGS " , "--yolo"
277+ "SPECKIT_INTEGRATION_TOML_AGENT_EXTRA_ARGS " , "--yolo"
278278 )
279279 args = _TomlAgentStub ().build_exec_args ("p" , model = "gemini-pro" )
280280 # TomlIntegration uses `-m` for model (vs Markdown's `--model`).
@@ -304,7 +304,7 @@ def test_toml_integration_base_honours_extra_args(monkeypatch):
304304def test_codex_integration_honours_extra_args (monkeypatch ):
305305 from specify_cli .integrations .codex import CodexIntegration
306306
307- monkeypatch .setenv ("SPECIFY_INTEGRATION_CODEX_EXTRA_ARGS " , "--sandbox read-only" )
307+ monkeypatch .setenv ("SPECKIT_INTEGRATION_CODEX_EXTRA_ARGS " , "--sandbox read-only" )
308308 args = CodexIntegration ().build_exec_args ("p" , model = "gpt-5" )
309309 assert args == [
310310 "codex" ,
@@ -321,15 +321,15 @@ def test_codex_integration_honours_extra_args(monkeypatch):
321321def test_devin_integration_honours_extra_args (monkeypatch ):
322322 from specify_cli .integrations .devin import DevinIntegration
323323
324- monkeypatch .setenv ("SPECIFY_INTEGRATION_DEVIN_EXTRA_ARGS " , "--no-confirm" )
324+ monkeypatch .setenv ("SPECKIT_INTEGRATION_DEVIN_EXTRA_ARGS " , "--no-confirm" )
325325 args = DevinIntegration ().build_exec_args ("p" )
326326 assert args == ["devin" , "-p" , "p" , "--no-confirm" ]
327327
328328
329329def test_opencode_integration_honours_extra_args (monkeypatch ):
330330 from specify_cli .integrations .opencode import OpencodeIntegration
331331
332- monkeypatch .setenv ("SPECIFY_INTEGRATION_OPENCODE_EXTRA_ARGS " , "--quiet" )
332+ monkeypatch .setenv ("SPECKIT_INTEGRATION_OPENCODE_EXTRA_ARGS " , "--quiet" )
333333 args = OpencodeIntegration ().build_exec_args ("p" )
334334 assert args == [
335335 "opencode" ,
@@ -349,13 +349,13 @@ def test_opencode_extra_args_cannot_clobber_prompt_derived_command(
349349 repeated-flag CLI semantics (last value typically takes precedence).
350350
351351 Locks against the regression where an operator setting
352- ``SPECIFY_INTEGRATION_OPENCODE_EXTRA_ARGS ="--command malicious"`` could redirect
352+ ``SPECKIT_INTEGRATION_OPENCODE_EXTRA_ARGS ="--command malicious"`` could redirect
353353 a slash-prefixed prompt to a different command.
354354 """
355355 from specify_cli .integrations .opencode import OpencodeIntegration
356356
357357 monkeypatch .setenv (
358- "SPECIFY_INTEGRATION_OPENCODE_EXTRA_ARGS " , "--command operator-override"
358+ "SPECKIT_INTEGRATION_OPENCODE_EXTRA_ARGS " , "--command operator-override"
359359 )
360360 args = OpencodeIntegration ().build_exec_args ("/speckit body text" )
361361 # Prompt-derived "--command speckit" appears AFTER the
@@ -383,7 +383,7 @@ def test_copilot_integration_honours_extra_args(monkeypatch):
383383 # Disable --yolo so the argv shape stays deterministic.
384384 monkeypatch .setenv ("SPECKIT_COPILOT_ALLOW_ALL_TOOLS" , "0" )
385385 monkeypatch .setenv (
386- "SPECIFY_INTEGRATION_COPILOT_EXTRA_ARGS " , "--allow-tool 'shell(echo)'"
386+ "SPECKIT_INTEGRATION_COPILOT_EXTRA_ARGS " , "--allow-tool 'shell(echo)'"
387387 )
388388 args = CopilotIntegration ().build_exec_args ("p" )
389389 # `_copilot_executable()` returns "copilot.cmd" on Windows and
@@ -431,7 +431,7 @@ class _Result:
431431
432432def test_copilot_dispatch_command_includes_extra_args (monkeypatch ):
433433 """Locks the bypass fix: `CopilotIntegration.dispatch_command`
434- must honour `SPECIFY_INTEGRATION_COPILOT_EXTRA_ARGS `, not just `build_exec_args`.
434+ must honour `SPECKIT_INTEGRATION_COPILOT_EXTRA_ARGS `, not just `build_exec_args`.
435435 """
436436 import subprocess
437437
@@ -441,7 +441,7 @@ def test_copilot_dispatch_command_includes_extra_args(monkeypatch):
441441 monkeypatch .setattr (subprocess , "run" , capture )
442442 monkeypatch .setenv ("SPECKIT_COPILOT_ALLOW_ALL_TOOLS" , "0" )
443443 monkeypatch .setenv (
444- "SPECIFY_INTEGRATION_COPILOT_EXTRA_ARGS " , "--allow-tool 'shell(echo)'"
444+ "SPECKIT_INTEGRATION_COPILOT_EXTRA_ARGS " , "--allow-tool 'shell(echo)'"
445445 )
446446
447447 CopilotIntegration ().dispatch_command (
@@ -469,7 +469,7 @@ def test_codex_dispatch_command_includes_extra_args(monkeypatch):
469469
470470 capture = _RunCapture ()
471471 monkeypatch .setattr (subprocess , "run" , capture )
472- monkeypatch .setenv ("SPECIFY_INTEGRATION_CODEX_EXTRA_ARGS " , "--sandbox read-only" )
472+ monkeypatch .setenv ("SPECKIT_INTEGRATION_CODEX_EXTRA_ARGS " , "--sandbox read-only" )
473473
474474 CodexIntegration ().dispatch_command (
475475 "speckit.plan" , args = "body" , stream = False
0 commit comments