feat: update Bob integration to skills-based layout for Bob 2.0#3415
feat: update Bob integration to skills-based layout for Bob 2.0#3415davidebibm wants to merge 32 commits into
Conversation
Bob 2.0 replaces the command-based workflow (.bob/commands/*.md) with a skills-based layout (.bob/skills/speckit-<name>/SKILL.md), matching the pattern used by Claude Code, Codex, and other skills-first agents. - Switch BobIntegration from MarkdownIntegration to SkillsIntegration - Update folder/dir from .bob/commands to .bob/skills - Change extension from .md to /SKILL.md (skills layout) - Add --skills option (default: True) consistent with Codex pattern - Update tests to inherit from SkillsIntegrationTests (28 tests pass) - Bump catalog entry to version 2.0.0 with updated description Assisted-by: IBM Bob (model: claude-sonnet-4-5, autonomous)
|
@mnriem please review, we need to make this work with new Bob... Thankyou so much |
There was a problem hiding this comment.
Pull request overview
This PR updates the built-in IBM Bob integration to align with Bob 2.0’s skills-based layout, switching installation output from command files to speckit-<name>/SKILL.md skills directories and bumping the integration’s catalog version accordingly.
Changes:
- Migrate
BobIntegrationfromMarkdownIntegrationtoSkillsIntegrationand update output paths to.bob/skills/.../SKILL.md. - Update Bob integration tests to use the shared
SkillsIntegrationTestsmixin. - Bump the Bob entry in
integrations/catalog.jsonto2.0.0with an updated description.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/bob/__init__.py |
Switch Bob to SkillsIntegration and update registrar/config output to .bob/skills + /SKILL.md. |
tests/integrations/test_integration_bob.py |
Update base test mixin and expected output directories for the skills layout. |
integrations/catalog.json |
Bump Bob integration version/description to reflect the 2.0.0 skills-based update. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Low
mnriem
left a comment
There was a problem hiding this comment.
As this fundamentally changes the layout for any Bob users what is the migration strategy? This will break them once they adopt a new version of Spec Kit so you need to make sure this goes through a deprecation cycle so they can migrate to the new Bob version. E.g make it an opt-in to the new version of Bob first and then in 2 minor releases (X.Y.Z where Y is minor) you can then remove the non-skill variant
Hi @mnriem |
|
Thanks @davidebibm — but I think we're talking about two different layers, and this still needs to change before it can land. Your point is about Bob the tool — that Bob 1.x can already read the skills layout. My concern is about Spec Kit's generated output: this PR changes what A hard cutover isn't acceptable here — we shouldn't catch existing users off guard. This needs to go through a proper deprecation cycle:
As it stands the Can you rework it along those lines — genuine dual-mode with skills opt-in first — so we phase this in without breaking anyone? |
|
Ok, thankyou @mnriem i'll do that |
|
@mnriem Done, hope this is what you are expecting |
|
Please address Copilot feedback. You will need to update the description to reflect the reality |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@mnriem Addressed Copilot comments and aligned with main |
|
Please address Copilot feedback and resolve conflicts |
…te legacy commands to opt-in
6b3a18c to
674a8db
Compare
…to ALWAYS_SLASH_AGENTS - init.py: suppress ai_skills=True when --legacy-commands is passed so extensions and presets target .bob/commands, not .bob/skills - _invocation_style.py: add 'bob' to ALWAYS_SLASH_AGENTS so init next-steps and hook invocations always show /speckit-<name> (skills is the default layout; no ai_skills flag required)
|
@mnriem Solved Copilot fb and rebased to avoid get Copilot feedback on other devs code 👍 |
| **opts: Any, | ||
| ) -> list[Path]: | ||
| parsed_options = parsed_options or {} | ||
| if self.is_skills_mode(parsed_options): |
| registrar_config = { | ||
| "dir": ".bob/commands", | ||
| "format": "markdown", | ||
| "args": "$ARGUMENTS", | ||
| "extension": ".md", | ||
| } |
…ill post-processing (review github#3415) Two issues from review 4723782860: 1. `BobIntegration.setup()` resolved the layout via `is_skills_mode(parsed_options)` WITHOUT `project_root`, so `integration upgrade bob` on a Bob 1.x install (managed `.bob/commands/speckit.*.md`, no stored options) ignored the existing command files, generated skills, and stale-deleted the legacy commands — silently migrating the project. Pass `project_root` so the same managed-artifact detection used by `use` also governs upgrades. 2. Only `_BobSkillsHelper` overrode `post_process_skill_content` to suppress the shared slash-command hook note. Preset/extension skill generators call that hook on the registered `BobIntegration`, which inherited `IntegrationBase`'s note-injecting default. Repeat the no-op (delegating to the skills helper) on the registered class so every Bob skill-generation path is consistent with intent-activated core Bob skills. Add regression tests for the upgrade-preservation and post-processing paths. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 63f93544-a77f-4f01-bf04-c88806a97dbf
|
Addressed review 4723782860 in Comment 1 ( Comment 2 (skill post-processing inconsistency) — valid. Only Added regression tests for both (upgrade preservation + post-processing no-op). Full suite green: 4536 passed, 5 skipped. Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously. |
| if project_root is not None: | ||
| bob_dir = Path(project_root) / ".bob" | ||
| has_managed_skills = any((bob_dir / "skills").glob("speckit-*")) | ||
| has_managed_commands = any((bob_dir / "commands").glob("speckit.*.md")) | ||
| if has_managed_commands and not has_managed_skills: | ||
| return False |
| if _opts.get("ai") == agent_name: | ||
| _sep = _integ.invoke_separator_for_mode( | ||
| is_ai_skills_enabled(_opts) | ||
| ) |
| "version": "2.0.0", | ||
| "description": "IBM Bob 2.0 IDE skills-based integration", | ||
| "author": "spec-kit-core", | ||
| "repository": "https://github.com/github/spec-kit", | ||
| "tags": ["ide", "ibm"] | ||
| "tags": ["ide", "ibm", "skills"] |
…-review-bob-skills-pr-3415 # Conflicts: # tests/test_workflows.py
…ss (review github#3415) Address review github#3415 (4724160183): - Comment 1: Add an explicit `--skills` opt-in to BobIntegration. It forces the skills layout over on-disk auto-detection, giving legacy Bob 1.x installs a supported migration path (`integration upgrade bob --integration-options="--skills"`). `--skills` and `--legacy-commands` are mutually exclusive (clean exit-1 error). - Comment 2: In CommandRegistrar.register_commands, derive the command-ref separator from the output layout (agent_config["extension"]) for the active agent too, not the persisted ai_skills flag. A command-layout file (.bob/commands/*.md, .github/agents/*.agent.md) always renders /speckit.*; only a /SKILL.md scaffold uses /speckit-*. Dual-layout agents (Bob, Copilot) write skills via their own setup()/skills path, so register_commands only ever emits their command-layout files. - Comment 3: Update docs/reference/integrations.md Bob entry to document the skills-based default (.bob/skills/), the deprecated --legacy-commands opt-out, and the --skills migration path. Also fix a latent manifest-loss bug surfaced by the migration path: the upgrade Phase 2 stale-file cleanup built a throwaway manifest sharing the integration key and called uninstall(), which always deleted {key}.manifest.json. Any layout-shrinking upgrade (e.g. legacy->skills) thus wiped the freshly-saved manifest, leaving the project untracked and un-upgradeable. uninstall() now takes remove_manifest (default True); the stale-cleanup pass passes False. Adds regression tests for the --skills opt-in, mutual exclusion, corrected active-agent separator, remove_manifest=False, and an end-to-end legacy->skills migration that verifies the manifest survives and the project remains upgradeable. Full suite: 4555 passed, 5 skipped. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 63f93544-a77f-4f01-bf04-c88806a97dbf
|
Addressed review 4724160183 and resolved the merge conflict with Comment 1 — no migration path from legacy → skills. Added an explicit Comment 2 — active-agent separator ignored the output layout. Comment 3 — docs. Updated the Bob entry in While validating the migration end-to-end I found a latent bug it surfaces: the upgrade Phase 2 stale-file cleanup built a throwaway manifest sharing the integration key and called Added regression tests for each of the above (opt-in, mutual exclusion, corrected active-agent separator, Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously. |
| # For dual-layout agents (e.g. Bob) the separator differs between the | ||
| # skills and command layouts, so a single static AGENT_CONFIGS value is | ||
| # insufficient. Resolve it from the integration using the project's | ||
| # persisted skills state; single-layout agents fall back to the static | ||
| # AGENT_CONFIGS value unchanged (invoke_separator_for_mode default). |
…ator rule (review github#3415) Address review github#3415 (4725516805). The comment above resolve_command_refs still described the removed state-based behavior ("resolve it from the integration using the project's persisted skills state"). Update it to describe the output-layout rule that register_commands now uses: _sep is derived from the layout this registrar writes (a /SKILL.md scaffold uses the skills separator; a command-layout file uses the command separator), not the persisted ai_skills state. Comment-only change; no behavior change. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 63f93544-a77f-4f01-bf04-c88806a97dbf
|
Addressed review 4725516805. Pushed as The comment above Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously. |
| stale_removed, _ = stale_manifest.uninstall( | ||
| project_root, force=True, remove_manifest=False | ||
| ) |
…ub#3415) When a dual-mode agent (Bob) flips between the legacy commands layout and the skills layout during `integration upgrade` (via `--skills` / `--legacy-commands`), the old layout's extension command/skill files were left orphaned: Phase 2 stale cleanup only removes files tracked by the *integration* manifest, while extension artifacts are tracked in the extension registry. Detect the layout flip by comparing whether the old vs new manifest tracks a `/SKILL.md` scaffold, and when it changed, unregister the agent's extension artifacts before the existing re-registration so they are recreated in the new layout (and the per-agent registry is updated). Preset artifacts are documented as a known, pre-existing cross-cutting gap: no agent-scoped preset re-registration exists in use/switch/upgrade for any agent, so reconciling them is out of scope for this Bob migration. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 63f93544-a77f-4f01-bf04-c88806a97dbf
|
Addressed review 4725829110 in Extension artifacts — reconciled. When a dual-mode agent (Bob) flips between the legacy commands layout and the skills layout during Preset artifacts — documented as a known, pre-existing limitation. There is no agent-scoped preset re-registration mechanism anywhere in the CLI: Full suite green after merging the latest Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously. |
| # Known limitation: preset command/skill artifacts are NOT reconciled on a | ||
| # layout change. There is no agent-scoped preset re-registration mechanism | ||
| # anywhere in the CLI — ``use`` / ``switch`` / ``upgrade`` never reconcile | ||
| # presets for any agent (presets are only (un)registered at preset | ||
| # install/remove time). Reconciling them here would require a new | ||
| # cross-cutting PresetManager subsystem affecting every dual-layout agent, | ||
| # which is out of scope for this Bob migration. A project that changes Bob's | ||
| # layout while a preset override is installed should re-run | ||
| # ``preset remove``/``preset install`` to refresh those artifacts. |
… (review github#3415) A command↔skills layout change during `integration upgrade` cannot reconcile preset artifacts: presets track their command/skill files in per-preset `registered_commands`/`registered_skills` metadata, and there is no agent-scoped preset re-registration anywhere in the CLI. Migrating would delete a preset's old-layout files without recreating them in the new layout and leave the preset registry claiming artifacts that no longer exist. Detect the intended layout via `is_skills_mode` (so a plain same-layout upgrade is unaffected) and, when it flips while preset overrides are installed for the agent, reject the upgrade *before any mutation* with an actionable error pointing at the remove → upgrade → reinstall workaround. Extension artifacts are still reconciled for the safe (no-preset) case. Adds a regression test and documents the migration caveat in the Bob integration reference entry. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 63f93544-a77f-4f01-bf04-c88806a97dbf
|
Addressed review 4726193915 in Took the reviewer's second option — reject the migration with an actionable error — since full preset reconciliation would require a new cross-cutting A layout-changing Because the guard runs before shared-infra install and Full suite green: 4582 passed, 5 skipped. Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously. |
| if _manifest_tracks_skill_layout(old_manifest) != _manifest_tracks_skill_layout( | ||
| new_manifest | ||
| ): | ||
| _unregister_extensions_for_agent( | ||
| project_root, |
Bob 2.0 replaces the command-based workflow with a skills-based layout.
https://bob.ibm.com/blog/bob-v2-release-announcement
Description
Testing
uv run specify --helpuv sync && uv run pytestAI Disclosure
Very simple code generated by Bob but verified by me