Skip to content

feat(agents): add native plugins for Codex Claude and Cursor - #73

Open
vm wants to merge 4 commits into
hack-dance:mainfrom
vm:codex/native-agent-plugins
Open

feat(agents): add native plugins for Codex Claude and Cursor#73
vm wants to merge 4 commits into
hack-dance:mainfrom
vm:codex/native-agent-plugins

Conversation

@vm

@vm vm commented Aug 2, 2026

Copy link
Copy Markdown

Summary

  • Add native Hack plugins for Codex, Claude Code, and Cursor.
  • Gate all automatic, setup-sync, and interactive onboarding cleanup on the corresponding plugin being installed and enabled.
  • Preserve project/user legacy rules, hooks, skills, and MCP entries while a client, plugin, or enabled state is missing.
  • Remove only exact generated copies after readiness; preserve customized artifacts.
  • Report unavailable plugins as warnings with non-success exit status instead of successful installs.
  • Use Cursor's documented /add-plugin flow and Settings > Plugins guidance.
  • Share plugin inspection, preparation, cleanup aggregation, and setup command orchestration while retaining client-specific parsing and discovery.

Verification

  • 967 tests passed, 5 skipped, 0 failed; 3,275 assertions.
  • Added a 36-scenario cutover matrix: missing / disabled / enabled by project / user by generated / customized, across Codex, Claude Code, and Cursor, including MCP preservation.
  • Added direct automatic-sync gating and setup-result tests.
  • Live missing-client/plugin setup and check commands warn and exit 1; no cleanup runs.
  • Current stable Codex CLI successfully added the local marketplace, installed and enabled hack@hack-dance, and reported the expected source. Test registry entries were removed afterward.
  • Current stable Claude Code successfully added the local marketplace, installed and enabled hack@hack-dance, exposed hack mcp serve, and installed both skills, hooks, and the rule. Test registry entries were removed afterward.
  • Cursor's official 2.5 plugin documentation confirms /add-plugin. Cursor Agent CLI is not installed on the validation host, so a live Cursor CLI install remains a reviewer/manual verification item.
  • Ultracite, CLI and DB TypeScript checks, CLI build, generated CLI reference, generated plugin drift check, Codex plugin validation, Claude plugin validation, and git diff checks passed.

Release Signal

  • Commit / squash title: feat(agents): add native plugins for Codex Claude and Cursor
  • Release intent: feat
  • Should this PR trigger a release signal? yes
  • No changeset or equivalent release-artifact mechanism is configured in this repository; the Conventional Commit PR title carries the feature release signal.

Semantic Surfaces

  • Does this change affect hack run, hack exec, env resolution, runtime-state reconciliation, or lifecycle shell/process behavior? no

Risks / Follow-up

  • Plugin list JSON differs between clients; each parser remains client-owned and has targeted state tests.
  • Legacy cleanup is readiness-gated and only removes exact generated content or registered historical fingerprints.
  • A live Cursor install still needs validation on a host with current Cursor and Cursor Agent CLI; the documented editor flow is verified against Cursor's official current documentation.

@roodboi roodboi 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.

Requesting changes because the migration currently has no safe cutover boundary: a normal interactive Hack command can remove the working standalone integration before the native plugin is installed or enabled.

What I verified on this head:

  • full bun test exits successfully
  • the focused plugin/setup suite passes (48 tests, 193 assertions)
  • bun run typecheck, bun run check, and git diff --check pass
  • hosted CI is green across test, runtime-images, Docker E2E, and secret scan
  • live codex plugin list --json and claude plugin list --json output match the new parsers

What still needs direct verification before merge:

  1. Fresh marketplace add + plugin install for Codex, Claude Code, and Cursor using current stable clients.
  2. A cutover matrix for plugin missing / disabled / enabled × project / user legacy artifacts × generated / customized artifacts. Missing or disabled must retain the working legacy integration; enabled may remove only exact generated copies.
  3. After a new session, prove both skills, the Claude hooks / Cursor rule, and hack mcp serve are actually loaded from each installed plugin.
  4. Exercise interactive hack init and hack setup output so missing/disabled plugins are warnings with non-success status.

Please also complete the PR description's Summary, Verification, Release Signal, Semantic Surfaces, and Risks sections. This is a user-facing feat and the release decision must be explicit per repository policy.

Comment thread src/cli/integration-sync.ts Outdated
installClaudeHooks({ scope: "user" }),
installCodexSkill({ scope: "project", projectRoot: opts.projectRoot }),
installCodexSkill({ scope: "user" }),
removeDeprecatedHackCursorIntegration({

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.

[P1] Gate legacy cleanup on native-plugin readiness. maybeEnsureAgentIntegrations() reaches this auto-sync from any normal interactive project command, and this block removes project and user Cursor/Claude/Codex artifacts without first proving the corresponding plugin is installed and enabled. After upgrading Hack, a user's first hack up can therefore delete working rules, hooks, skills, and MCP config while leaving only install guidance. Make auto-sync warn-only until checkHack*Plugin() returns noop, or otherwise make the cutover atomic. Please add a matrix test for plugin missing / disabled / enabled × project / user × generated / customized legacy artifacts, asserting that missing or disabled retains every working artifact.

Comment thread src/commands/project.ts
}

logger.success({ message: `Updated ${opts.label} at ${opts.path}` });
logger.success({

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.

[P1] Do not render a missing plugin as a successful install. Each prepareHack*Plugin() returns missing when the user selects an integration but has not installed the native plugin; this fallthrough sends that result through logger.success, potentially immediately after legacy artifacts were removed. Handle missing, stale, and deprecated as warnings/failures here, and test interactive onboarding with the client executable absent, the marketplace absent, and the plugin disabled so the flow never claims the integration was updated.

Comment thread docs/integrations.md Outdated
cursor-agent plugin marketplace add hack-dance/hack
```

Open `/plugin` in Cursor, choose the **Hack Dance** marketplace, and install **Hack**. Cursor bundles

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.

[P2] Validate and document the current Cursor installation surface. Cursor's current official plugin documentation says to install in the editor with /add-plugin (or Settings → Plugins), while /plugin is not documented: https://cursor.com/changelog/2-5. Because this is the only recovery path printed after cleanup, an invalid slash command strands the user without either integration. Update the canonical guidance and all generated copies, then verify on current stable Cursor and Cursor Agent CLI that the marketplace is accepted, Hack installs/enables, and its rules, skills, and MCP server appear after a new session.

@roodboi roodboi 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.

Re-reviewed the two new commits (e21feee and 6808a21). The original unsafe-cleanup, missing-plugin success, Cursor guidance, and PR-description findings are substantially addressed.

What I verified on this head:

  • focused plugin/cutover/setup suite: 36 tests, 217 assertions, 0 failures
  • direct CLI TypeScript check and direct Ultracite check on all changed TS/test files
  • CLI build and git diff --check
  • the readiness matrix preserves legacy content while plugins are missing/disabled

Two false-green cases remain when the plugin is enabled but customized legacy content is preserved; see the inline comments. Please test enabled-plugin cutover with a customized primary artifact and customized MCP entry for all three clients, both scopes, through hack setup <client>, hack setup sync --all-scopes, automatic sync, and interactive hack init. Every path must preserve the customization, warn, and exit nonzero until the duplicate legacy integration is manually reconciled.

Hosted CI has not executed: run 243 is action_required with zero jobs, consistent with the fork workflow awaiting maintainer approval. Please approve/run CI and get it green. A live current-stable Cursor + Cursor Agent CLI marketplace/install/load check also remains outstanding before approval.

Comment thread src/agents/plugin-lifecycle.ts Outdated
let status: AgentPluginResult<TScope>["status"] = "absent";
if (error) {
status = "error";
} else if (results.some((result) => result.status === "removed")) {

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.

[P1] Let preserved content outrank successful removals. In every enabled/customized matrix case there can be both outcomes—for example, a customized Cursor rule is preserved while its generated MCP sibling is removed. This branch selects removed first, so prepareNativeAgentPlugin() returns cleanupStatus: "removed"; hack setup sync exits 0 and automatic sync reports a full repair even though the customized legacy integration remains and the next check is still stale. Use precedence error > preserved > removed > absent, and add mixed removed + preserved assertions for customized rules/skills and customized MCP entries across all three clients and both scopes.

Comment thread src/commands/setup.ts
return 1;
}

if (outcome === "unchanged") {

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.

[P1] Treat a preserved cleanup as an incomplete cutover here and in interactive init. Even after the cleanup aggregator reports preserved, the plugin result remains status: "noop", cleanupStatus: "preserved"; this block only special-cases removed and therefore logs info and exits 0. src/commands/project.ts::logInstallResult() drops cleanupStatus entirely and has the same false-success behavior. Propagate the cleanup outcome, warn, and return nonzero for preserved. Please exercise enabled plugin + customized rule/skill and customized MCP through each direct hack setup <client> command and interactive hack init, asserting preserved bytes and non-success status.

@roodboi roodboi 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.

CI is now running, and the main test/typecheck/build, runtime-image, and secret-scan jobs pass. Docker E2E fails deterministically in agent-docs-sync because this PR changed missing native plugins to a non-success sync result without updating the existing E2E contract. See the inline comment for the required coverage. After updating it, run bun run test:e2e:local:docker and keep the earlier customized-artifact cutover cases in scope.

Comment thread src/commands/setup.ts
return true;
}
return (
entry.requiresReadyPlugin &&

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.

[P1] Update the agent-docs-sync E2E for this new failure contract. CI run 243 now reaches the Docker E2E job but fails at tests/e2e/scenarios/agent-docs-sync.ts:194-202: the fixture has no Cursor, Claude, or Codex client, so these branches make hack setup sync --all-scopes exit 1 while the unchanged scenario still requires exit 0 and then a clean --check. Please make the scenario assert the missing-plugin warning/non-success path while also proving the generated AGENTS/CLAUDE docs and deprecated Tickets artifacts are still reconciled; add a ready-plugin fixture (or split the scenario) to retain positive coverage for exit 0 followed by a clean check. Run bun run test:e2e:local:docker and get the hosted docker-e2e job green.

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.

2 participants