Skip to content

feat: add Codemod skill documentation and command structure#2226

Merged
mohebifar merged 1 commit into
mainfrom
feat/mcp-tools-via-cli
May 20, 2026
Merged

feat: add Codemod skill documentation and command structure#2226
mohebifar merged 1 commit into
mainfrom
feat/mcp-tools-via-cli

Conversation

@mohebifar

Copy link
Copy Markdown
Member

📚 Description

  • Introduced SKILL.md to outline the Codemod skill's purpose, usage, and CLI tools.
  • Created openai.yaml to define the interface for the Codemod agent.
  • Added codemod.md to specify command behavior for codemod tasks, including intent classification and routing for authoring and execution.

🔗 Linked Issue

🧪 Test Plan

📄 Documentation to Update

Copilot AI review requested due to automatic review settings May 19, 2026 23:22
Some(language.to_string())
}

fn resolve_tool<'a>(tools: &'a [CliToolInfo], name: &str) -> Option<&'a CliToolInfo> {

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.

[LOW] ai tool node-types alias is not resolved, unlike ai call node-types

handle_tool uses resolve_tool, which normalizes only - to _ (node-types -> node_types), but the advertised tool name in metadata is get_node_types. Meanwhile call_tool_text explicitly aliases node-types to get_node_types. This creates inconsistent behavior across sibling commands: ai call node-types works, but ai tool node-types returns unknown tool. Reuse the same normalization/alias mapping for metadata lookup to keep command behavior consistent.

@@ -0,0 +1,72 @@
use std::io::Write;

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.

[LOW] New CLI AI command branches are only partially covered by integration tests

The new integration test file validates dump-ast, node-types, docs (list mode), and tools JSON, but does not cover newly added tool, call, resources, resource, or docs query/read modes. Given the new parsing/dispatch logic and alias handling, this leaves key regression paths untested. Adding end-to-end coverage for at least one success and one failure case per new command would materially reduce risk.

@github-actions

Copy link
Copy Markdown
Contributor

Codex Review

The PR adds substantial new codemod ai CLI/MCP surface area and docs bundling behavior. I found one medium-confidence behavioral bug in docs fetching concurrency, one concrete command-alias inconsistency, and a notable test-coverage gap around newly added command paths.

Findings

  • [MEDIUM] crates/mcp/src/lib.rs:840 read_resource_text_live can still return fallback immediately when a fetch is already in progress
  • [LOW] crates/cli/src/commands/ai/cli_tools.rs:309 ai tool node-types alias is not resolved, unlike ai call node-types
  • [LOW] crates/cli/tests/ai_cli_tools.rs:1 New CLI AI command branches are only partially covered by integration tests

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 expands the Codemod “skill” and CLI to support an MCP-equivalent, CLI-first “Codemod AI tools” workflow (docs lookup, AST dumping, node-type introspection, and tool/resource discovery/calls), and updates the MCP server to bundle local documentation as an offline fallback.

Changes:

  • Updated the Codemod skill + command routing docs to prefer npx codemod ai ... as a reproducible fallback when MCP isn’t available.
  • Added codemod ai subcommands (dump-ast, node-types, docs, tools/tool, resources/resource, call) with integration tests.
  • Refactored codemod-mcp docs resources to build bundles from local docs/ content (and optionally fetch public docs), plus exposed “CLI tool/resource info” APIs.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
skills/codemod/SKILL.md Updates core skill guidance to include CLI AI tooling and MCP-optional authoring flow.
skills/codemod/commands/codemod.md Updates intent routing to prefer codemod ai CLI fallbacks and documents ai call validate_codemod_package.
skills/codemod/agents/openai.yaml Adds an agent interface descriptor for the Codemod skill.
crates/mcp/src/lib.rs Adds local-doc bundling, CLI tool/resource metadata, CLI-style tool calling, and adjusts docs fetch behavior.
crates/mcp/src/handlers/node_types.rs Extracts node-types output formatting into a helper and adds a text-returning API.
crates/mcp/src/handlers/ast_dump.rs Adds a text-returning API and reuses it from the MCP tool handler.
crates/mcp/src/data/prompts/sharding-instructions.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/jssg-utils-instructions.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/jssg-runtime-capabilities.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/jssg-instructions.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/jssg-gotchas.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/codemod-troubleshooting.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/codemod-maintainer-monorepo.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/codemod-creation-workflow.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/codemod-cli-instructions.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/mcp/src/data/prompts/ast-grep-gotchas.md Deletes old prompt fallback (now replaced by local docs/ bundling).
crates/cli/tests/ai_cli_tools.rs Adds integration tests for the new codemod ai CLI tools.
crates/cli/src/commands/harness_adapter.rs Bumps skill version and embeds the updated skill/command markdown from skills/.
crates/cli/src/commands/ai/mod.rs Wires new codemod ai subcommands into the CLI.
crates/cli/src/commands/ai/cli_tools.rs Implements the new codemod ai tool/resource/docs commands backed by codemod-mcp.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cli/src/commands/harness_adapter.rs Outdated
Comment on lines +36 to +40
"/../../skills/codemod/SKILL.md"
));
const MCS_COMMAND_MD: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../../skills/codemod/commands/codemod.md"
Comment thread crates/mcp/src/lib.rs Outdated
Comment thread crates/mcp/src/lib.rs
Comment on lines 418 to 423
reqwest::Client::builder()
.timeout(Duration::from_secs(PUBLIC_DOCS_TIMEOUT_SECS))
.no_proxy()
.user_agent(format!("codemod-mcp/{}", env!("CARGO_PKG_VERSION")))
.build()
.ok()
Comment thread crates/mcp/src/lib.rs Outdated
Comment on lines +1080 to +1082
fallback.clone(),
initial_wait,
move || async move {
Comment thread crates/mcp/src/handlers/node_types.rs Outdated
Comment on lines +68 to +72
format!(
r#"<TREE_SITTER_NODE_TYPES>
{node_types}
</TREE_SITTER_NODE_TYPES>

@github-actions

github-actions Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

TUI Perf Comparison

Focused Perf Regression Tests

Test Result
should_redraw_is_false_for_static_idle_ui_without_changes PASS
draw_counter_counts_only_initial_draw_for_static_idle_screen PASS
draw_counter_counts_one_redraw_for_burst_of_drained_workflow_events PASS
draw_counter_counts_deadline_tick_for_running_screen PASS
reduce_workflow_receiver_requests_snapshot_after_receiver_lag PASS
await_js_ast_grep_execution_task_returns_prompt_completion_without_polling_delay PASS
await_js_ast_grep_execution_task_prefers_completed_result_over_later_idle_signal PASS

Timed Perf Benchmarks

Benchmark Baseline median Candidate median Delta Ratio Result
jssg_wait_completion_latency 6 us 7 us +1 us 1.17x PASS
large_task_list_render_latency 7056 us 6934 us -122 us 0.98x PASS
publish_log_heavy_task_list_render_latency 7732 us 7603 us -129 us 0.98x PASS
log_modal_render_latency 592919 us 587631 us -5288 us 0.99x PASS

Fails only when candidate median is more than 25% slower and exceeds the benchmark-specific absolute floor.

TUI Perf Comparison

  • Baseline dir: perf-results/baseline
  • Candidate dir: perf-results/candidate

Completed

Metric Baseline Candidate Delta
deadline_wakeups 1 1 0
draws 1 1 0

Awaiting Trigger

Metric Baseline Candidate Delta
deadline_wakeups 1 1 0
draws 1 1 0

Active

Metric Baseline Candidate Delta
deadline_wakeups 4 4 0
draws 4 4 0

Awaiting Trigger Resume

Metric Baseline Candidate Delta
deadline_wakeups 1 1 0
draws 1 1 0

Active Busy

Metric Baseline Candidate Delta
deadline_wakeups 4 4 0
draws 4 4 0

Terminal Activity

Metric Baseline Candidate Delta
deadline_wakeups 1 1 0
draws 3 3 0
terminal_events 2 2 0
terminal_key_events 1 1 0
terminal_resize_events 1 1 0

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

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

Comment on lines +67 to +86
fn format_node_types_response(node_types: &str) -> String {
format!(
r#"<TREE_SITTER_NODE_TYPES>
{node_types}
</TREE_SITTER_NODE_TYPES>

<LEGEND>
Legends for field notation:
- \`?\` - optional field (may not be present in all instances)
- \`*\` - multiple values allowed (array/list of values)

In tree-sitter grammar:
- Fields are named children with specific roles in the syntax tree
- Format: \`fieldName=nodeType\` (e.g., "body=block")
- When a field is not named, it's represented as \`children=nodeType\`
- Multiple possible types are comma-separated (e.g., "value=string,number")
</LEGEND>
"#
)
}
Comment thread crates/mcp/build.rs
Comment on lines +5 to +23
const DOCS: &[&str] = &[
"README.md",
"cli.mdx",
"model-context-protocol.mdx",
"oss.mdx",
"oss-quickstart.mdx",
"package-structure.mdx",
"workflows/introduction.mdx",
"workflows/reference.mdx",
"workflows/sharding.mdx",
"jssg/intro.mdx",
"jssg/reference.mdx",
"jssg/security.mdx",
"jssg/advanced.mdx",
"jssg/testing.mdx",
"jssg/metrics.mdx",
"jssg/utils.mdx",
"jssg/semantic-analysis.mdx",
];
Comment thread crates/mcp/src/data/docs/README.md Outdated

### Publishing Changes

Install our Github App to autopropagate changes from youre repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
Comment on lines +352 to +374
for resource in resources {
if resource.name.to_lowercase().contains(&query_lower)
|| resource
.description
.unwrap_or_default()
.to_lowercase()
.contains(&query_lower)
{
matches.push(DocsSearchMatch {
name: resource.name.to_string(),
uri: resource.uri.to_string(),
line: 0,
snippet: resource.description.unwrap_or_default().to_string(),
});
continue;
}

let content = server.read_resource_text(resource.uri).await?;
if let Some((index, line)) = content
.lines()
.enumerate()
.find(|(_, line)| line.to_lowercase().contains(&query_lower))
{

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

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

Comment thread crates/mcp/src/handlers/node_types.rs Outdated
Comment on lines +67 to +72
fn format_node_types_response(node_types: &str) -> String {
format!(
r#"<TREE_SITTER_NODE_TYPES>
{node_types}
</TREE_SITTER_NODE_TYPES>

Comment thread crates/mcp/build.rs
Comment on lines +5 to +23
const DOCS: &[&str] = &[
"README.md",
"cli.mdx",
"model-context-protocol.mdx",
"oss.mdx",
"oss-quickstart.mdx",
"package-structure.mdx",
"workflows/introduction.mdx",
"workflows/reference.mdx",
"workflows/sharding.mdx",
"jssg/intro.mdx",
"jssg/reference.mdx",
"jssg/security.mdx",
"jssg/advanced.mdx",
"jssg/testing.mdx",
"jssg/metrics.mdx",
"jssg/utils.mdx",
"jssg/semantic-analysis.mdx",
];
Comment thread crates/mcp/src/data/docs/README.md Outdated

### Publishing Changes

Install our Github App to autopropagate changes from youre repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
Comment on lines +344 to +381
async fn search_docs(
server: &CodemodMcpServer,
resources: &[CliResourceInfo],
query: &str,
) -> Result<Vec<DocsSearchMatch>> {
let query_lower = query.to_lowercase();
let mut matches = Vec::new();

for resource in resources {
if resource.name.to_lowercase().contains(&query_lower)
|| resource
.description
.unwrap_or_default()
.to_lowercase()
.contains(&query_lower)
{
matches.push(DocsSearchMatch {
name: resource.name.to_string(),
uri: resource.uri.to_string(),
line: 0,
snippet: resource.description.unwrap_or_default().to_string(),
});
continue;
}

let content = server.read_resource_text(resource.uri).await?;
if let Some((index, line)) = content
.lines()
.enumerate()
.find(|(_, line)| line.to_lowercase().contains(&query_lower))
{
matches.push(DocsSearchMatch {
name: resource.name.to_string(),
uri: resource.uri.to_string(),
line: index + 1,
snippet: line.trim().to_string(),
});
}
- Introduced SKILL.md to outline the Codemod skill's purpose, usage, and CLI tools.
- Created openai.yaml to define the interface for the Codemod agent.
- Added codemod.md to specify command behavior for codemod tasks, including intent classification and routing for authoring and execution.

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

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Comment on lines +320 to +341
let normalized = query.to_lowercase();

resources
.iter()
.find(|resource| {
resource.uri.eq_ignore_ascii_case(query)
|| resource.name.eq_ignore_ascii_case(query)
|| resource
.name
.strip_suffix("-instructions")
.is_some_and(|name| name.eq_ignore_ascii_case(query))
|| resource
.uri
.split_once("://")
.is_some_and(|(scheme, _)| scheme.eq_ignore_ascii_case(query))
})
.or_else(|| {
resources.iter().find(|resource| {
resource.name.to_lowercase().contains(&normalized)
|| resource.uri.to_lowercase().contains(&normalized)
})
})
Comment on lines +369 to +381
let content = server.read_resource_text_cached(resource.uri).await?;
if let Some((index, line)) = content
.lines()
.enumerate()
.find(|(_, line)| line.to_lowercase().contains(&query_lower))
{
matches.push(DocsSearchMatch {
name: resource.name.to_string(),
uri: resource.uri.to_string(),
line: index + 1,
snippet: line.trim().to_string(),
});
}
@mohebifar mohebifar merged commit de23bf3 into main May 20, 2026
10 checks passed
@mohebifar mohebifar deleted the feat/mcp-tools-via-cli branch May 20, 2026 18:49
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