Skip to content

Commit 674a8db

Browse files
committed
feat(bob): address copilot comments, make skills layout default, demote legacy commands to opt-in
1 parent 1c3d1cf commit 674a8db

2 files changed

Lines changed: 180 additions & 191 deletions

File tree

Lines changed: 47 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"""IBM Bob integration.
22
3-
Bob 2.0 supports the ``.bob/skills/speckit-<name>/SKILL.md`` layout.
4-
The legacy ``.bob/commands/*.md`` layout (Bob 1.x) remains the default
5-
for this release and will be deprecated in a future Spec Kit release.
3+
Bob 2.0 uses the ``.bob/skills/speckit-<name>/SKILL.md`` layout.
4+
The legacy ``.bob/commands/*.md`` layout (Bob 1.x) is available as an
5+
opt-in for projects that have not yet migrated, via
6+
``--integration-options "--legacy-commands"``.
67
78
Deprecation cycle:
8-
This release: Markdown layout is default; skills layout is opt-in via
9-
``--integration-options "--skills"``.
10-
Next cycle: Skills layout becomes default; markdown remains opt-in.
11-
Cycle after: Markdown layout removed.
9+
This release: Skills layout is the default; legacy ``.bob/commands/``
10+
is opt-in via ``--legacy-commands``.
11+
Next cycle: ``--legacy-commands`` flag removed.
1212
"""
1313

1414
from __future__ import annotations
@@ -17,93 +17,85 @@
1717
from pathlib import Path
1818
from typing import Any
1919

20-
from ..base import IntegrationBase, IntegrationOption, SkillsIntegration
20+
from ..base import IntegrationOption, MarkdownIntegration, SkillsIntegration
2121
from ..manifest import IntegrationManifest
2222

2323

24-
def _warn_legacy_markdown_default() -> None:
25-
"""Warn that Bob's default markdown scaffold is being phased out."""
24+
def _warn_legacy_commands_deprecated() -> None:
25+
"""Warn that Bob's legacy markdown layout is being phased out."""
2626
warnings.warn(
27-
"Bob legacy markdown mode (.bob/commands/) is deprecated and will stop "
28-
"being the default in a future Spec Kit release; pass "
29-
'--integration-options "--skills" to opt in to Bob skills mode now.',
27+
"Bob legacy commands mode (.bob/commands/) is deprecated and will be "
28+
"removed in a future Spec Kit release. Omit --legacy-commands to use "
29+
"the default skills layout (.bob/skills/).",
3030
UserWarning,
3131
stacklevel=3,
3232
)
3333

3434

35-
class _BobSkillsHelper(SkillsIntegration):
36-
"""Internal helper used when Bob is scaffolded in skills mode.
35+
class _BobMarkdownHelper(MarkdownIntegration):
36+
"""Internal helper used when Bob is scaffolded in legacy commands mode.
3737
3838
Not registered in the integration registry — only used as a delegate
39-
by ``BobIntegration`` when ``--skills`` is passed.
39+
by ``BobIntegration`` when ``--legacy-commands`` is passed.
4040
"""
4141

4242
key = "bob"
4343
config = {
4444
"name": "IBM Bob",
4545
"folder": ".bob/",
46-
"commands_subdir": "skills",
46+
"commands_subdir": "commands",
4747
"install_url": None,
4848
"requires_cli": False,
4949
}
5050
registrar_config = {
51-
"dir": ".bob/skills",
51+
"dir": ".bob/commands",
5252
"format": "markdown",
5353
"args": "$ARGUMENTS",
54-
"extension": "/SKILL.md",
54+
"extension": ".md",
5555
}
5656

5757

58-
class BobIntegration(IntegrationBase):
58+
class BobIntegration(SkillsIntegration):
5959
"""Integration for IBM Bob IDE.
6060
61-
Default mode: installs ``.bob/commands/speckit.<name>.md`` files
62-
(Bob 1.x markdown layout — legacy, will be deprecated).
61+
Default mode: installs ``.bob/skills/speckit-<name>/SKILL.md`` files
62+
(Bob 2.0 skills layout).
6363
64-
Skills mode (``--skills``): installs
65-
``.bob/skills/speckit-<name>/SKILL.md`` files (Bob 2.0 layout).
64+
Legacy mode (``--legacy-commands``): installs
65+
``.bob/commands/speckit.<name>.md`` files (Bob 1.x layout — deprecated).
66+
67+
Inheriting ``SkillsIntegration`` ensures ``invoke_separator = "-"`` is
68+
set at the class level so ``CommandRegistrar.AGENT_CONFIGS`` (which reads
69+
the class attribute directly) generates correct hyphenated
70+
``/speckit-<name>`` references for skills.
6671
"""
6772

6873
key = "bob"
6974
config = {
7075
"name": "IBM Bob",
7176
"folder": ".bob/",
72-
"commands_subdir": "commands",
77+
"commands_subdir": "skills",
7378
"install_url": None,
7479
"requires_cli": False,
7580
}
7681
registrar_config = {
77-
"dir": ".bob/commands",
82+
"dir": ".bob/skills",
7883
"format": "markdown",
7984
"args": "$ARGUMENTS",
80-
"extension": ".md",
85+
"extension": "/SKILL.md",
8186
}
8287

83-
# Mutable flag set by setup() — indicates the active scaffolding mode.
84-
_skills_mode: bool = False
85-
86-
def effective_invoke_separator(
87-
self, parsed_options: dict[str, Any] | None = None
88-
) -> str:
89-
"""Return ``"-"`` when skills mode is requested, ``"."`` otherwise."""
90-
if parsed_options and parsed_options.get("skills"):
91-
return "-"
92-
if self._skills_mode:
93-
return "-"
94-
return self.invoke_separator
95-
9688
@classmethod
9789
def options(cls) -> list[IntegrationOption]:
9890
return [
9991
IntegrationOption(
100-
"--skills",
92+
"--legacy-commands",
10193
is_flag=True,
10294
default=False,
10395
help=(
104-
"Scaffold commands as agent skills "
105-
"(.bob/skills/speckit-<name>/SKILL.md) instead of "
106-
"the legacy .bob/commands/*.md layout"
96+
"Scaffold commands as legacy .bob/commands/*.md files "
97+
"(Bob 1.x layout, deprecated) instead of the default "
98+
"skills layout"
10799
),
108100
),
109101
]
@@ -117,42 +109,23 @@ def setup(
117109
) -> list[Path]:
118110
"""Install Bob commands.
119111
120-
When ``parsed_options["skills"]`` is truthy, delegates to skills
121-
scaffolding (``.bob/skills/speckit-<name>/SKILL.md``).
122-
Otherwise uses the default ``.bob/commands/speckit.<name>.md`` layout
123-
and emits a deprecation warning.
112+
Default: skills layout (``.bob/skills/speckit-<name>/SKILL.md``).
113+
When ``parsed_options["legacy_commands"]`` is truthy, falls back to
114+
the deprecated ``.bob/commands/speckit.<name>.md`` layout.
124115
"""
125116
parsed_options = parsed_options or {}
126-
self._skills_mode = bool(parsed_options.get("skills"))
127-
if self._skills_mode:
128-
return self._setup_skills(project_root, manifest, parsed_options, **opts)
129-
if "skills" not in parsed_options:
130-
_warn_legacy_markdown_default()
131-
return self._setup_default(project_root, manifest, parsed_options, **opts)
132-
133-
def _setup_default(
134-
self,
135-
project_root: Path,
136-
manifest: IntegrationManifest,
137-
parsed_options: dict[str, Any] | None = None,
138-
**opts: Any,
139-
) -> list[Path]:
140-
"""Default mode: ``.bob/commands/speckit.<name>.md`` layout."""
141-
from ..base import MarkdownIntegration
117+
if parsed_options.get("legacy_commands"):
118+
_warn_legacy_commands_deprecated()
119+
return self._setup_legacy(project_root, manifest, parsed_options, **opts)
120+
return SkillsIntegration.setup(self, project_root, manifest, parsed_options, **opts)
142121

143-
return MarkdownIntegration.setup(self, project_root, manifest, parsed_options, **opts)
144-
145-
def _setup_skills(
122+
def _setup_legacy(
146123
self,
147124
project_root: Path,
148125
manifest: IntegrationManifest,
149126
parsed_options: dict[str, Any] | None = None,
150127
**opts: Any,
151128
) -> list[Path]:
152-
"""Skills mode: delegate to ``_BobSkillsHelper``."""
153-
helper = _BobSkillsHelper()
154-
return SkillsIntegration.setup(helper, project_root, manifest, parsed_options, **opts)
155-
156-
def post_process_skill_content(self, content: str) -> str:
157-
"""Apply shared skills post-processing to externally generated skills."""
158-
return _BobSkillsHelper().post_process_skill_content(content)
129+
"""Legacy mode: ``.bob/commands/speckit.<name>.md`` layout."""
130+
helper = _BobMarkdownHelper()
131+
return MarkdownIntegration.setup(helper, project_root, manifest, parsed_options, **opts)

0 commit comments

Comments
 (0)