Skip to content

feat: update Bob integration to skills-based layout for Bob 2.0#3415

Merged
mnriem merged 35 commits into
github:mainfrom
davidebibm:feat/update-bob-skills-integration
Jul 21, 2026
Merged

feat: update Bob integration to skills-based layout for Bob 2.0#3415
mnriem merged 35 commits into
github:mainfrom
davidebibm:feat/update-bob-skills-integration

Conversation

@davidebibm

@davidebibm davidebibm commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Bob 2.0 replaces the command-based workflow with a skills-based layout.

https://bob.ibm.com/blog/bob-v2-release-announcement

Description

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

Very simple code generated by Bob but verified by me

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)
@davidebibm
davidebibm requested a review from mnriem as a code owner July 8, 2026 18:26
@davidebibm

Copy link
Copy Markdown
Contributor Author

@mnriem please review, we need to make this work with new Bob... Thankyou so much

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 BobIntegration from MarkdownIntegration to SkillsIntegration and update output paths to .bob/skills/.../SKILL.md.
  • Update Bob integration tests to use the shared SkillsIntegrationTests mixin.
  • Bump the Bob entry in integrations/catalog.json to 2.0.0 with 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

Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
Comment thread src/specify_cli/integrations/bob/__init__.py

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@davidebibm

Copy link
Copy Markdown
Contributor Author

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
this should not break for Bob 1 user cause it was already compatible with skill mode.
Still needed this?

@mnriem

mnriem commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

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 specify writes for the bob integration from .bob/commands/*.md to .bob/skills/speckit-<name>/SKILL.md. Any project someone already initialized has .bob/commands/*.md on disk. When they upgrade Spec Kit and re-init or switch, that layout is orphaned/replaced. That's a breaking change in our contract regardless of whether the Bob app happens to read both directories.

A hard cutover isn't acceptable here — we shouldn't catch existing users off guard. This needs to go through a proper deprecation cycle:

  1. This release: make skills an opt-in and keep the existing .bob/commands markdown layout as the default. That's real dual-mode — setup() branching between the two layouts, the way Copilot does it — not the --skills flag as written now.
  2. Next cycle: flip the default to skills, with the legacy layout still available.
  3. Cycle after that: remove the legacy markdown mode.

As it stands the --skills flag is a no-op: BobIntegration is hardwired to SkillsIntegration and the MarkdownIntegration variant is deleted, so --skills=False still emits skills. There's no path that produces the old layout, so it doesn't actually provide the opt-in it implies.

Can you rework it along those lines — genuine dual-mode with skills opt-in first — so we phase this in without breaking anyone?

@davidebibm

Copy link
Copy Markdown
Contributor Author

Ok, thankyou @mnriem i'll do that

@davidebibm
davidebibm requested a review from mnriem July 13, 2026 15:01
@davidebibm

Copy link
Copy Markdown
Contributor Author

@mnriem Done, hope this is what you are expecting

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/bob/__init__.py
Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
@mnriem

mnriem commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

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>
@davidebibm

Copy link
Copy Markdown
Contributor Author

@mnriem Addressed Copilot comments and aligned with main

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 38/38 changed files
  • Comments generated: 4
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
Comment thread src/specify_cli/integrations/kiro_cli/__init__.py
Comment thread CHANGELOG.md
@mnriem

mnriem commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Please address Copilot feedback and resolve conflicts

@davidebibm
davidebibm force-pushed the feat/update-bob-skills-integration branch from 6b3a18c to 674a8db Compare July 14, 2026 14:44
…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)
@davidebibm

Copy link
Copy Markdown
Contributor Author

@mnriem Solved Copilot fb and rebased to avoid get Copilot feedback on other devs code 👍

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/agents.py Outdated
…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
@mnriem

mnriem commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4725516805. Pushed as d3408e6.

The comment above resolve_command_refs still described the state-based behavior that the previous round removed ("resolve it from the integration using the project's persisted skills state"). Updated it to describe the output-layout rule register_commands now uses: _sep is derived from the layout this registrar writes — a /SKILL.md scaffold uses the skills separator, any command-layout file uses the command separator — not the persisted ai_skills state. Comment-only change; no behavior change. Full suite: 4555 passed, 5 skipped.


Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/_migrate_commands.py
mnriem and others added 2 commits July 17, 2026 16:07
…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
@mnriem

mnriem commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4725829110 in 779eb89.

Extension artifacts — reconciled. When a dual-mode agent (Bob) flips between the legacy commands layout and the skills layout during integration upgrade (--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, whereas extension artifacts live in the extension registry. The upgrade now detects the layout flip (comparing whether the old vs new manifest tracks a /SKILL.md scaffold) and, when it changed, unregisters the agent's extension artifacts via the existing unregister_agent_artifacts() before the existing re-registration — so they're removed from the old layout and recreated in the new one, with the per-agent registry updated. Verified both directions (legacy→skills and skills→legacy), plus that same-layout upgrades don't churn. Regression test added (test_upgrade_bob_layout_change_reconciles_extension_artifacts).

Preset artifacts — documented as a known, pre-existing limitation. There is no agent-scoped preset re-registration mechanism anywhere in the CLI: use / switch / upgrade never reconcile presets for any agent (Copilot included) — presets are only (un)registered at preset install/remove time. Reconciling them on a layout change would require a new cross-cutting PresetManager subsystem affecting every dual-layout agent, which is out of scope for this Bob migration. This is now called out in an in-code comment next to the extension reconciliation, with the workaround (preset remove / preset install to refresh) noted.

Full suite green after merging the latest upstream/main: 4581 passed, 5 skipped.

Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/_migrate_commands.py Outdated
… (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
@mnriem

mnriem commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4726193915 in d2321b2.

Took the reviewer's second option — reject the migration with an actionable error — since full preset reconciliation would require a new cross-cutting PresetManager subsystem (no agent-scoped preset re-registration exists anywhere in the CLI).

A layout-changing integration upgrade now checks, before any mutation, whether preset overrides are installed for the agent. It detects the intended layout via is_skills_mode (so a plain, same-layout upgrade is unaffected) and compares it to the installed layout. When the layout would flip while a preset registered command/skill artifacts for the agent, it exits 1 with an actionable message:

Error: Cannot change 'bob' command layout while preset override(s) are installed: my-preset.
Preset artifacts cannot yet be reconciled across a command↔skills layout change, so the
migration would orphan their files and leave the preset registry inconsistent.
Remove the preset(s), run the upgrade, then reinstall them:
  specify preset remove <id>
  specify integration upgrade bob --integration-options "..."
  specify preset add <id>

Because the guard runs before shared-infra install and setup(), the project is never left half-migrated. The extension reconciliation from the previous round still handles the safe (no-preset) case. Verified end-to-end: layout flip + presets → rejected with no mutation; same-layout upgrade + presets → succeeds; layout flip without presets → succeeds and reconciles extensions. Regression test added (test_upgrade_bob_layout_change_rejected_with_presets_installed) and the caveat is documented in the Bob integration reference entry.

Full suite green: 4582 passed, 5 skipped.

Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/_migrate_commands.py Outdated
…eview github#3415)

`integration_upgrade` supports upgrading a secondary (non-active) integration,
but the layout-change extension reconciliation was unsafe there.
`ExtensionManager.unregister_agent_artifacts()` treats the unscoped
per-extension `registered_skills` list as belonging to the passed agent and,
when that agent's skills directory is absent, falls back to scanning every
agent's skills directory — so reconciling a secondary Bob layout flip could
delete or untrack the *active* agent's extension skills. The subsequent
re-registration cannot repair that because extension skill rendering is
intentionally scoped to the active agent (github#2948).

Gate the unregister-before-register reconciliation on `installed_key == key`
so it only runs for the active integration. Secondary agents only ever have
extension command files (skills are active-agent-only), which the existing
re-registration rewrites in place, so skipping the unregister orphans nothing
new. Adds a regression test asserting a secondary Bob layout change leaves the
active agent's extension skill intact on disk and in the registry.

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
@mnriem

mnriem commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4726347306 in 9cdc8d0.

Good catch — took the first option and restricted the layout-change reconciliation to the active integration. The unregister-before-register block is now gated on installed_key == key, so it only runs when upgrading the active/default agent.

Rationale: ExtensionManager.unregister_agent_artifacts() treats the unscoped per-extension registered_skills list as belonging to the passed agent and, when that agent's skills dir is absent, falls back to scanning every agent's skills dir — so reconciling a secondary Bob layout flip could delete/untrack the active agent's extension skills, and the follow-up re-registration can't repair it (skill rendering is active-agent-scoped, #2948). Skipping the unregister for secondary agents orphans nothing new: a non-active agent only ever has extension command files, which the existing re-registration rewrites in place regardless of layout.

Added a regression test (test_upgrade_secondary_bob_layout_change_preserves_active_agent_skills): active copilot in skills mode with the git extension skill + secondary Bob (legacy) → flip Bob to skills → the active agent's git skill remains on disk and in the registry. Verified it fails without the gate and passes with it, preserving the invariant at test_upgrade_non_active_agent_preserves_active_agent_skills.

Full suite green: 4583 passed, 5 skipped.

Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/_migrate_commands.py Outdated
Comment thread src/specify_cli/integrations/bob/__init__.py Outdated
…ub#3415)

Address review 4744636079:

- _migrate_commands: the preset guard previously failed *open* — a
  registry read/parse error returned an empty "no presets" list, so a
  --force layout-changing upgrade could delete preset-overridden command
  files while their registry state was unknown. Read the registry file
  directly and raise _PresetRegistryUnreadableError on any read/parse
  failure or malformed structure, rejecting the migration before any
  mutation. A genuinely absent registry still returns [] (safe).

- bob: correct the is_skills_mode docstring — upgrade *does* run setup();
  disk detection is needed because legacy Bob 1.x installs never persisted
  a legacy_commands option, so the stored mode is unavailable.

- tests: add fail-closed E2E (corrupted registry rejected, valid-empty
  allowed) plus a unit test for _installed_presets_affecting_agent covering
  absent / corrupted / malformed / valid / affecting-agent cases.

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
@mnriem

mnriem commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4744636079 in 44bc562:

  • Preset guard now fails closed (_migrate_commands.py): the helper previously returned an empty "no presets" list when the registry couldn't be read, letting a --force layout-changing upgrade delete preset-overridden command files while their registry state was unknown. It now reads .specify/presets/.registry directly and raises _PresetRegistryUnreadableError on any read/parse failure or malformed structure, rejecting the migration before any mutation. A genuinely absent registry still returns [] (safe to proceed).
  • is_skills_mode docstring corrected (bob/__init__.py): removed the inaccurate claim that upgrade doesn't run setup(). It does; disk detection is needed because legacy Bob 1.x installs never persisted a legacy_commands option, so the stored mode is unavailable.
  • Tests: added a fail-closed E2E (corrupted registry rejected with no mutation, valid-empty allowed) and a unit test for _installed_presets_affecting_agent covering absent / corrupted / malformed / valid / affecting-agent cases. Full suite: 4585 passed, 5 skipped.

Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Comments suppressed due to low confidence (1)

src/specify_cli/integrations/_migrate_commands.py:115

  • The guard claims to fail closed on a corrupted registry, but malformed per-preset metadata is skipped, and a malformed registered_commands value is treated as no matching artifacts. A parseable registry such as {"presets":{"p1":[]}} therefore allows the layout migration even though p1's ownership is unknown, which can delete preset-managed files. Reject malformed entry/registration shapes with _PresetRegistryUnreadableError instead of interpreting them as empty.
    for preset_id, meta in data.get("presets", {}).items():
        if not isinstance(meta, dict):
            continue
        registered_commands = meta.get("registered_commands", {})
        has_commands = (
            isinstance(registered_commands, dict)
            and bool(registered_commands.get(agent_key))
        )
        has_skills = bool(meta.get("registered_skills"))
  • Files reviewed: 19/19 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/integrations/bob/__init__.py
…3415)

Address review 4745191015: the preset guard read a parseable registry but
silently skipped malformed per-preset metadata and treated a malformed
registered_commands value as "no matching artifacts". A registry such as
{"presets":{"p1":[]}} therefore allowed a layout migration even though p1's
ownership is unknown, risking deletion of preset-managed files. Now raise
_PresetRegistryUnreadableError for a non-dict preset entry, a non-dict
registered_commands, or a non-list registered_skills. Extend the unit test
to cover these malformed shapes.

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
@mnriem

mnriem commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Addressed review 4745191015 in 0aace65:

The preset guard read a parseable registry but silently skipped malformed per-preset metadata, and treated a malformed registered_commands value as "no matching artifacts". A registry such as {"presets":{"p1":[]}} therefore allowed the layout migration even though p1's ownership was unknown — the exact deletion risk the guard exists to prevent.

_installed_presets_affecting_agent now raises _PresetRegistryUnreadableError for a non-dict preset entry, a non-dict registered_commands, or a non-list registered_skills, rejecting the migration before any mutation. Extended the unit test to cover these malformed shapes. Full suite: 4585 passed, 5 skipped.

Posted on behalf of @mnriem by GitHub Copilot (model: Claude Opus 4.8), acting autonomously.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Comments suppressed due to low confidence (2)

src/specify_cli/integrations/_migrate_commands.py:92

  • The unreadable-registry guard does not cover this existence probe. On supported Python versions, Path.exists() may raise PermissionError here before it can be translated into _PresetRegistryUnreadableError; on newer versions that suppress probe errors, it can return False and incorrectly treat an inaccessible registry as absent. Probe with stat() inside the protected path, distinguishing only FileNotFoundError from other OSErrors, so permission failures consistently fail closed with the actionable CLI error.
    if not registry_path.exists():

src/specify_cli/integrations/bob/init.py:59

  • This migration guidance is inaccurate for auto-detected Bob 1.x projects: a plain integration upgrade bob already omits --legacy-commands, but is_skills_mode() deliberately preserves the on-disk command layout. Such users must explicitly pass --integration-options "--skills"; distinguish new-project behavior from the migration command so the warning provides an action that actually changes layouts.
        "Bob legacy commands mode (.bob/commands/) is deprecated and will be "
        "removed in a future Spec Kit release. Omit --legacy-commands to use "
        "the default skills layout (.bob/skills/).",
  • Files reviewed: 19/19 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

@mnriem

mnriem commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants