Skip to content

Commit ef2cb53

Browse files
committed
fix pr comment
1 parent c6edc66 commit ef2cb53

2 files changed

Lines changed: 34 additions & 6 deletions

File tree

src/specify_cli/integrations/_helpers.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,18 @@ def _update_init_options_for_integration(
279279
opts["speckit_version"] = _get_speckit_version()
280280
if script_type:
281281
opts["script"] = script_type
282-
# Skills mode is either intrinsic (SkillsIntegration), set on the instance
283-
# during setup() (_skills_mode), or requested via parsed options (e.g.
284-
# Copilot's --skills, persisted as parsed_options["skills"]). The latter is
285-
# the only signal available on the `use` path, where no setup() runs and a
286-
# fresh integration instance has _skills_mode == False (issue #3550).
282+
# Skills mode is either intrinsic (SkillsIntegration), derived from
283+
# parsed_options via a callable _skills_mode method (e.g. Bob), set on
284+
# the instance during setup() as a bool attribute (e.g. Copilot), or
285+
# requested via parsed options (e.g. Copilot's --skills, persisted as
286+
# parsed_options["skills"]). The latter is the only signal available on
287+
# the `use` path, where no setup() runs and a fresh integration instance
288+
# has _skills_mode == False (issue #3550).
289+
_skills_mode_attr = getattr(integration, "_skills_mode", None)
287290
skills_mode = (
288291
isinstance(integration, SkillsIntegration)
289-
or getattr(integration, "_skills_mode", False)
292+
or (callable(_skills_mode_attr) and _skills_mode_attr(parsed_options))
293+
or (not callable(_skills_mode_attr) and bool(_skills_mode_attr))
290294
or bool((parsed_options or {}).get("skills"))
291295
)
292296
if skills_mode:

tests/integrations/test_integration_bob.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,30 @@ def test_init_legacy_creates_commands(self, tmp_path):
300300
assert (target / ".bob" / "commands" / "speckit.plan.md").exists()
301301
assert not (target / ".bob" / "skills").exists()
302302

303+
def test_init_legacy_does_not_set_ai_skills(self, tmp_path):
304+
"""Legacy install must NOT write ai_skills=True to init-options.json.
305+
306+
Regression test: _update_init_options_for_integration previously called
307+
getattr(integration, "_skills_mode", False) which returned the bound method
308+
object (always truthy) instead of calling it, so legacy projects incorrectly
309+
got ai_skills=True and used hyphenated skill invocations.
310+
"""
311+
from typer.testing import CliRunner
312+
from specify_cli import app
313+
from specify_cli import load_init_options
314+
315+
target = tmp_path / "test-proj"
316+
result = CliRunner().invoke(app, [
317+
"init", str(target), "--integration", "bob",
318+
"--integration-options", "--legacy-commands",
319+
"--ignore-agent-tools", "--script", "sh",
320+
])
321+
assert result.exit_code == 0, f"init failed: {result.output}"
322+
init_opts = load_init_options(target)
323+
assert init_opts.get("ai_skills") is not True, (
324+
"Legacy Bob project must not have ai_skills=True in init-options.json"
325+
)
326+
303327

304328
class TestBobRegistrarConfig:
305329
"""Verify AGENT_CONFIGS["bob"] follows the Copilot pattern for extension registration."""

0 commit comments

Comments
 (0)