You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(cline): keep .md extension on speckit.* file names in command bodies - #5168
Depends on #5215, which adds the shared IntegrationBase.process_registered_command() hook. Please merge #5215 first; this branch contains it via a merge commit, so the diff here shows both until #5215 lands.
With #5215 in place, this PR removes the is_cline_ext branch and the _hyphenate_* helpers from agents.py and applies the rewrite in src/specify_cli/integrations/cline/ through ClineIntegration.process_registered_command(), still only for non-core commands. docs/integrations/cline.md documents the behavior.
For Cline extension/preset commands, _hyphenate_body_refs (and _hyphenate_frontmatter_refs) rewrite every speckit.<a>.<b> token. A file name such as speckit.git.commit.md matches as a reference, so .specify/extensions/git/commands/speckit.git.commit.md becomes .../speckit-git-commit-md (extension lost).
Fix
Both helpers now share one compiled pattern and a small replacer that leaves a match ending in .md unchanged. Command references such as /speckit.git.commit are still hyphenated.
Evidence
Added test_cline_body_refs_keep_md_file_names and test_cline_frontmatter_refs_keep_md_file_names in tests/integrations/test_integration_cline.py.
Implemented by Grok Bot (an AI coding agent) acting on behalf of @kevin9327, running autonomously; model unknown/not exposed to the agent. Extent: code generation, tests, and this description. The commit carries an Assisted-by: trailer. I ran the tests above locally.
Cline's dot-to-hyphen rewrite matched `speckit.git.commit.md` as a command
reference and produced `speckit-git-commit-md`, dropping the extension.
Leave matches that end in `.md` untouched in both body and frontmatter.
Fixesgithub#5097
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
A moderate active issue remains because the .md suffix check misclassifies valid command references such as /speckit.foo.md, leaving required transformations incorrect in both body and frontmatter without a regression test.
This pull request updates Cline reference rewriting so command filenames ending in .md retain their extension while dotted command references remain hyphenated.
Changes:
Shares compiled matching and replacement logic for body and frontmatter references.
Preserves .md-suffixed command filenames.
Adds regression tests for body and frontmatter handling.
File
Summary
tests/integrations/test_integration_cline.py
Adds regression coverage for preserving .md command filenames in body and frontmatter references.
src/specify_cli/agents.py
Centralizes Cline reference rewriting, but the .md suffix check also leaves valid command references such as /speckit.foo.md unchanged; this requires a context-aware distinction.
A speckit.<ext>.md token is a command reference unless it has more
segments than a command can have or sits inside a path.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
An active moderate issue remains because dotted preset command names can be misclassified as filenames, producing incorrect Cline references without a regression test.
Preset command names may contain dots, so speckit.foo.bar.md can be a
valid command whose last segment is md. The segment count therefore
cannot identify a file name. Keep a .md token unchanged only when it sits
inside a path; hyphenate bare and slash-prefixed tokens.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
An active moderate finding remains because bracketed slash-prefixed references are still transformed incorrectly, affecting body and frontmatter processing.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Handle bracketed slash command references
src/specify_cli/agents.py:118
The slash-prefixed command rule still fails when the reference is immediately preceded by a Markdown [ (for example [/speckit.foo.md]): text[start - 2] is [ here, so this branch returns the dotted token unchanged instead of producing /speckit-foo-md. This can affect both body and recursively processed frontmatter strings; treat bracketed command delimiters as command context (or use an explicit path check) and add a regression case.
Please address Copilot feedback. Note that all of this should be really replaced by the author using SPECKIT_COMMAND_MYEXT_MYCMD style and we will eventually mandate that
Thanks, addressed the latest Copilot finding in d00721f. A speckit.*.md token is now kept as a file name only when the slash before it follows a path-name character (letter, digit, ., _, -, ~, /, \, }, $), so [/speckit.foo.md] and {/speckit.foo.md} are hyphenated like any other slash command, in the body and in frontmatter. Added test_cline_refs_hyphenate_bracketed_slash_command_named_md, which fails on the previous commit and passes now; tests/integrations: 3149 passed, 8 skipped.
Noted on the __SPECKIT_COMMAND_MYEXT_MYCMD__ placeholders. This PR only keeps the existing dotted-reference rewrite from breaking .md file names until that becomes the required form.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
A moderate active issue remains because valid Windows root-level paths can still be rewritten incorrectly, dropping filename protection and lacking regression coverage for both slash styles.
C:\speckit.foo.md and C:/speckit.foo.md were hyphenated because the drive colon before the separator is not a path-name character. A lone drive letter and colon before the separator now count as path context, so these stay file names; ab:/speckit.foo.md is still treated as a command reference.
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because the change alters user-visible Cline registration behavior and carries integration-documentation implications not covered by the published review.
The Cline-only gate explains the test scope, but it also highlights an architectural issue: agents.py should not contain integration-specific branches. As described in design/integration.md under “Integration delivery boundary,” shared behavior belongs in shared infrastructure, while Cline-specific behavior belongs in src/specify_cli/integrations/cline/. Please move this rewriting into the Cline integration through the integration contract, preserving its current non-core-only scope, and add registration-level regression coverage rather than only testing the private helpers directly. This can remain one focused PR if the existing contract supports it; if a shared capability is needed first, please split that prerequisite into a separate PR. Please also update the Cline integration documentation.
AI disclosure: Drafted for @mnriem by GitHub Copilot using GPT-6.1 Sol in interactive mode; AI assistance covered code/design assessment and drafting this response.
post_process_command_content() only sees rendered text, so an integration
cannot tell a core command from an extension or preset command, and any
rewrite that depends on the source has to live as an agent-name branch in
CommandRegistrar.register_commands(). Add IntegrationBase
.process_registered_command(frontmatter, body, *, source_id), called for
every registered command after name injection and before placeholder
resolution and rendering. The default returns both values unchanged, so
no output changes.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
…gration
The dotted-reference rewrite for extension and preset commands, including
the .md file-name handling from this PR, lived in CommandRegistrar as an
is_cline_ext branch. Move it into src/specify_cli/integrations/cline/ and
apply it through ClineIntegration.process_registered_command(), keeping
the non-core-only scope. Add registration-level tests that go through
CommandRegistrar.register_commands() for an extension and a core command,
and document the behavior in docs/integrations/cline.md.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
Moved the rewrite into the Cline integration in ab5d147, with the shared prerequisite split out as #5215.
feat(integrations): add process_registered_command hook with source_id #5215 adds IntegrationBase.process_registered_command(frontmatter, body, *, source_id). register_commands() calls it for every command after name injection and before $ARGUMENTS/__SPECKIT_COMMAND_*__ resolution and rendering. The default is a no-op, and it is tested on its own with existing integrations (opencode, claude skills layout, aliases).
This PR merges that branch, then removes is_cline_ext and the _hyphenate_* helpers from agents.py. ClineIntegration.process_registered_command() applies the rewrite and returns core commands unchanged, so the scope stays non-core-only.
Added registration-level tests that call CommandRegistrar.register_commands("cline", ...). The extension-command test fails on main (the output contains commands/speckit-git-commit-md) and passes here. A second test confirms a core command is not rewritten. The existing helper tests now target the Cline module.
Updated docs/integrations/cline.md.
Tests: pytest -n 8 tests/integrations tests/test_post_process.py tests/test_extensions.py tests/test_registered_command_hook.py tests/test_presets.py gave 3790 passed and 8 skipped. uvx ruff@0.15.0 check src tests is clean. In the full tests run, 9 tests fail in this environment, all outside the touched code: Rich table truncation in test_installed_adapters.py list output and four shell-script parity tests. I did not investigate them further.
AI disclosure: posted on behalf of @kevin9327 by Grok Bot, an AI coding agent running autonomously (model unknown, not exposed to the agent). It did the code, tests and this comment. Each new commit carries an Assisted-by: trailer. The agent ran the tests; no personal human review is claimed.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The path-character whitelist still rewrites valid paths with parentheses, percent signs, or brackets, stripping file extensions in both body and frontmatter processing.
OpenCode keeps $ARGUMENTS unchanged and the old fixture had no
__SPECKIT_COMMAND_*__ token, so the existing test still passed if
process_registered_command() ran after argument conversion or command
reference resolution. Add a Gemini case whose source contains both
placeholders: the hook must receive them unresolved, and tokens the hook
adds must come out resolved ({{args}}, /speckit.tasks) in the written
TOML command.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
The path check only accepted a separator after a plain path-name
character, so valid paths such as C:\Program Files (x86)\speckit.git.commit.md,
%TEMP%\speckit.git.commit.md and ./commands[old]/speckit.git.commit.md were
rewritten to speckit-git-commit-md in the body and frontmatter. Treat a
closing ) or ] that closes a whitespace-free group, and a %VAR% reference,
as a directory ending. Opening brackets and prose groups such as
"(see docs)" still precede command references, so [/speckit.foo.md] and
(/speckit.foo.md) keep being hyphenated.
Assisted-by: Grok Bot (model: unknown, autonomous)
Signed-off-by: kevin9327 <5299031+kevin9327@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prerequisite
Depends on #5215, which adds the shared
IntegrationBase.process_registered_command()hook. Please merge #5215 first; this branch contains it via a merge commit, so the diff here shows both until #5215 lands.With #5215 in place, this PR removes the
is_cline_extbranch and the_hyphenate_*helpers fromagents.pyand applies the rewrite insrc/specify_cli/integrations/cline/throughClineIntegration.process_registered_command(), still only for non-core commands.docs/integrations/cline.mddocuments the behavior.Fixes #5097
Problem
For Cline extension/preset commands,
_hyphenate_body_refs(and_hyphenate_frontmatter_refs) rewrite everyspeckit.<a>.<b>token. A file name such asspeckit.git.commit.mdmatches as a reference, so.specify/extensions/git/commands/speckit.git.commit.mdbecomes.../speckit-git-commit-md(extension lost).Fix
Both helpers now share one compiled pattern and a small replacer that leaves a match ending in
.mdunchanged. Command references such as/speckit.git.commitare still hyphenated.Evidence
test_cline_body_refs_keep_md_file_namesandtest_cline_frontmatter_refs_keep_md_file_namesintests/integrations/test_integration_cline.py.mainboth fail; with this change both pass.pytest tests/integrations tests/test_extensions.py: 3632 passed, 8 skipped.AI disclosure
Implemented by Grok Bot (an AI coding agent) acting on behalf of @kevin9327, running autonomously; model unknown/not exposed to the agent. Extent: code generation, tests, and this description. The commit carries an
Assisted-by:trailer. I ran the tests above locally.