Skip to content

Commit 93dbf6d

Browse files
jawwad-aliclaude
andauthored
fix(integrations): recompute invoke_separator from retained parsed_options (#3664)
with_integration_setting recomputed invoke_separator from the raw parsed_options argument. When only script_type changes (parsed_options and raw_options both None), the previously-stored parsed_options are retained on the setting, but the separator was derived from the None argument — dropping an options-dependent separator (e.g. Copilot --skills -> "-") back to the default ".", desynchronizing invoke_separator from the stored options. Derive the separator from current.get("parsed_options") — the options actually stored after the update — so it stays consistent in every branch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4fc0a5b commit 93dbf6d

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/specify_cli/integration_runtime.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,15 @@ def with_integration_setting(
6464
elif raw_options is not None:
6565
current.pop("parsed_options", None)
6666

67+
# Recompute the separator from the options actually STORED on ``current``
68+
# after the update, not the raw ``parsed_options`` argument. When only
69+
# ``script_type`` changes (``parsed_options`` and ``raw_options`` both
70+
# None), the previously-stored ``parsed_options`` are retained above, so
71+
# deriving the separator from the argument (None) would drop an
72+
# options-dependent separator (e.g. Copilot ``--skills`` -> "-") back to
73+
# the default ".".
6774
current["invoke_separator"] = integration.effective_invoke_separator(
68-
parsed_options, project_root
75+
current.get("parsed_options"), project_root
6976
)
7077
settings[key] = current
7178
return settings

tests/integrations/test_integration_state.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,31 @@ def test_write_integration_json_strips_integration_key(tmp_path):
8484
assert state["integration"] == "claude"
8585
assert state["default_integration"] == "claude"
8686
assert state["installed_integrations"] == ["claude"]
87+
88+
89+
def test_with_integration_setting_recomputes_separator_from_retained_options():
90+
"""Updating only script_type must not drop an options-dependent separator.
91+
92+
Copilot resolves the command-ref separator to '-' when '--skills' options
93+
are stored and '.' otherwise. A second call that changes only script_type
94+
(parsed_options=None, raw_options=None) retains the stored parsed_options,
95+
so invoke_separator must stay '-', not be recomputed from the None argument.
96+
"""
97+
from specify_cli.integrations import get_integration
98+
from specify_cli.integration_runtime import with_integration_setting
99+
100+
copilot = get_integration("copilot")
101+
102+
settings = with_integration_setting(
103+
{}, "copilot", copilot, parsed_options={"skills": True}
104+
)
105+
assert settings["copilot"]["invoke_separator"] == "-"
106+
107+
settings2 = with_integration_setting(
108+
{"integration_settings": settings}, "copilot", copilot, script_type="ps"
109+
)
110+
# parsed_options are retained (only script_type changed) ...
111+
assert settings2["copilot"]["parsed_options"] == {"skills": True}
112+
assert settings2["copilot"]["script"] == "ps"
113+
# ... so the separator must reflect them, not the (None) argument.
114+
assert settings2["copilot"]["invoke_separator"] == "-"

0 commit comments

Comments
 (0)