fix(opencode): use commands/ directory (plural) to match OpenCode docs#2453
fix(opencode): use commands/ directory (plural) to match OpenCode docs#2453marcusburghardt wants to merge 2 commits intogithub:mainfrom
Conversation
OpenCode documentation (https://opencode.ai/docs/commands/) uses .opencode/commands/ (plural) as the canonical command directory. The OpenCode runtime supports both .opencode/command/ and .opencode/commands/ via a {command,commands} glob, but the singular form was the original convention and is now outdated. Update the OpenCode integration to write to .opencode/commands/ instead of .opencode/command/, aligning with the documented standard and the OpenSpec fix (Fission-AI/OpenSpec#748). Signed-off-by: Marcus Burghardt <maburgha@redhat.com> Assisted-by: OpenCode (claude-opus-4-6)
There was a problem hiding this comment.
Pull request overview
This PR updates the OpenCode integration to use OpenCode’s documented .opencode/commands/ directory instead of the legacy singular .opencode/command/, and adjusts the related tests accordingly. The change fits the integration layer by aligning Spec Kit’s generated command paths with the current OpenCode convention.
Changes:
- Switches the OpenCode integration’s command output directory from
commandtocommands. - Updates the registrar path for OpenCode command registration to the plural directory.
- Refreshes OpenCode integration and integration-switch tests to assert the new path.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/opencode/__init__.py |
Updates OpenCode integration config and registrar paths to the plural commands directory. |
tests/integrations/test_integration_opencode.py |
Updates Opencode integration test constants to match the new directory layout. |
tests/integrations/test_integration_subcommand.py |
Updates integration-switch extension assertions to expect .opencode/commands/. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/opencode/init.py:16
- This path change also breaks cleanup of commands that were previously registered for OpenCode. Extension/preset registries only store command names, and
unregister_commands()reconstructs the file path from the currentAGENT_CONFIGSentry; after this change it will try to delete.opencode/commands/...and leave legacy.opencode/command/...files behind. Because OpenCode still loads both directories, removed/disabled/upgraded commands can remain active.
registrar_config = {
"dir": ".opencode/commands",
- Files reviewed: 3/3 changed files
- Comments generated: 2
|
Please support both models so we are not breaking existing installs. If the old one is detected we should warn the user that they need to upgrade their code agent integration (see https://github.github.com/spec-kit/reference/integrations.html#upgrade-an-integration)? |
…ctory migration Add _resolve_agent_dir() to CommandRegistrar that checks a legacy_dir fallback when the canonical directory does not exist. When legacy_dir is found, a deprecation warning directs users to run "specify integration upgrade" to migrate. The OpenCode integration declares legacy_dir: ".opencode/command" so that extension and preset registration, as well as command cleanup, continue working for projects that have not yet migrated to .opencode/commands/. The legacy_dir mechanism is opt-in: integrations that do not declare it get no fallback and no behavioral change. Add end-to-end test verifying that "specify integration upgrade opencode" migrates commands from legacy .opencode/command/ to canonical .opencode/commands/ and removes stale files. Signed-off-by: Marcus Burghardt <maburgha@redhat.com> Assisted-by: OpenCode (claude-opus-4-6)
Thanks for the feedback @mnriem . I addressed the comments in fe32984 and updated the PR description to reflect the last changes . Essentially introduced an optional I also noticed there was no end-to-end test to simulate the |
Description
Align the OpenCode integration's command directory with OpenCode's
documented standard:
.opencode/commands/(plural) instead of.opencode/command/(singular), while maintaining full backwardcompatibility with existing projects.
OpenCode's documentation (https://opencode.ai/docs/commands/) uses
commands/as the canonical directory name. The OpenCode runtimesupports both via a
{command,commands}glob, so the singular formworks but is outdated. OpenSpec already fixed this in
Fission-AI/OpenSpec#748.
Changes
Commit 1 — directory rename:
commands_subdir:"command"→"commands"registrar_config.dir:".opencode/command"→".opencode/commands"test_integration_opencode.pyandtest_integration_subcommand.pyCommit 2 — backward compatibility (
legacy_dir):legacy_dir: ".opencode/command"to OpenCode'sregistrar_config_resolve_agent_dir()toCommandRegistrarthat falls back tolegacy_dirwhen the canonical directory does not exist, emitting adeprecation warning directing users to
specify integration upgraderegister_commands(),register_commands_for_all_agents(),register_commands_for_non_skill_agents(), andunregister_commands()legacy_dirmechanism is opt-in: integrations that do notdeclare it get no fallback and no behavioral change
Backward compatibility
Existing projects with
.opencode/command/(singular) continueworking without changes:
_resolve_agent_dir()detectsthe legacy directory and registers commands there, with a warning
unregister_commands()finds and removescommands from the legacy directory
specify integration upgrade opencodewritesnew commands to
.opencode/commands/and removes stale files from.opencode/command/via manifest diff (end-to-end test included)setup()always writes to.opencode/commands/Previously deployed Speckit commands in
.opencode/command/remainfunctional. Users can migrate by running:
Or manually remove only the Speckit-owned orphans:
Testing
uv run specify --helpuv sync && uv run pytestRan
specify init /tmp/speckit-test --integration opencode --script shand verified commands are created in
.opencode/commands/(plural)with no
.opencode/command/(singular) directory created.Also ran
uv run python -m pytest tests/test_agent_config_consistency.py(24/24 pass) and all 105 affected tests pass.
New tests added
test_registrar_config_has_legacy_dir— config has legacy_dir fieldtest_legacy_dir_extension_registration— extensions register inlegacy dir with deprecation warning
test_legacy_dir_unregister— unregister finds commands in legacy dirtest_canonical_dir_preferred_over_legacy— canonical dir takesprecedence when both exist, no warning emitted
test_setup_writes_to_canonical_dir— new installs use canonical pathtest_upgrade_migrates_opencode_legacy_dir— end-to-end: upgrademoves commands from legacy to canonical, removes stale files
AI Disclosure
This fix was identified through codebase analysis using OpenCode
(claude-opus-4-6). The source changes,
_resolve_agent_dir()helper,and all tests were authored with AI assistance. All tests were run
and verified locally.