Skip to content

Commit 7edf5b5

Browse files
committed
feat(bob): add bob skills integration with registrar-based mode detection
1 parent 6ab8d61 commit 7edf5b5

4 files changed

Lines changed: 19 additions & 6 deletions

File tree

src/specify_cli/_invocation_style.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
CONDITIONAL_SLASH_AGENTS: frozenset[str] = frozenset(
1919
{
2020
"agy",
21+
"bob",
2122
"claude",
2223
"copilot",
2324
"cursor-agent",

src/specify_cli/commands/init.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ def init(
658658
kimi_skill_mode = selected_ai == "kimi"
659659
agy_skill_mode = selected_ai == "agy" and _is_skills_integration
660660
trae_skill_mode = selected_ai == "trae"
661+
bob_skill_mode = selected_ai == "bob" and _is_skills_integration
661662
cursor_agent_skill_mode = (
662663
selected_ai == "cursor-agent" and _is_skills_integration
663664
)
@@ -672,6 +673,7 @@ def init(
672673
or kimi_skill_mode
673674
or agy_skill_mode
674675
or trae_skill_mode
676+
or bob_skill_mode
675677
or cursor_agent_skill_mode
676678
or copilot_skill_mode
677679
or devin_skill_mode

src/specify_cli/integrations/_helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,14 @@ def _update_init_options_for_integration(
263263
load_init_options,
264264
save_init_options,
265265
)
266+
from .base import SkillsIntegration
266267
opts = load_init_options(project_root)
267268
opts["integration"] = integration.key
268269
opts["ai"] = integration.key
269270
opts["speckit_version"] = _get_speckit_version()
270271
if script_type:
271272
opts["script"] = script_type
272-
if getattr(integration, "_skills_mode", False):
273+
if isinstance(integration, SkillsIntegration) or getattr(integration, "_skills_mode", False):
273274
opts["ai_skills"] = True
274275
else:
275276
opts.pop("ai_skills", None)

src/specify_cli/integrations/bob/__init__.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def effective_invoke_separator(
106106
if parsed_options and parsed_options.get("legacy_commands"):
107107
return "."
108108
return "-"
109+
109110
config = {
110111
"name": "IBM Bob",
111112
"folder": ".bob/",
@@ -120,9 +121,17 @@ def effective_invoke_separator(
120121
"extension": "/SKILL.md",
121122
}
122123

123-
# Set by setup() to reflect the active mode; read by _helpers.py and
124-
# init.py via getattr(integration, "_skills_mode", False).
125-
_skills_mode: bool = False
124+
@property
125+
def _skills_mode(self) -> bool:
126+
"""True when the instance is configured in skills (default) mode.
127+
128+
Derived from the current ``registrar_config`` so that the value
129+
reflects whichever mode ``setup()`` last activated, without relying
130+
on mutable instance state that is unavailable in a fresh process
131+
(e.g. ``specify integration use bob`` or ``_set_default_integration``).
132+
"""
133+
rc = self.registrar_config or {}
134+
return rc.get("extension") == "/SKILL.md"
126135

127136
@classmethod
128137
def options(cls) -> list[IntegrationOption]:
@@ -154,10 +163,10 @@ def setup(
154163
"""
155164
parsed_options = parsed_options or {}
156165
if parsed_options.get("legacy_commands"):
157-
self._skills_mode = False
166+
self.registrar_config = dict(_BobMarkdownHelper.registrar_config)
158167
_warn_legacy_commands_deprecated()
159168
return self._setup_legacy(project_root, manifest, parsed_options, **opts)
160-
self._skills_mode = True
169+
self.registrar_config = dict(_BobSkillsHelper.registrar_config)
161170
return SkillsIntegration.setup(
162171
_BobSkillsHelper(), project_root, manifest, parsed_options, **opts
163172
)

0 commit comments

Comments
 (0)