Skip to content

[luv-245] feat: add Cursor Agent CLI integration (beta)#245

Merged
NiveditJain merged 3 commits into
mainfrom
luv-245
Apr 30, 2026
Merged

[luv-245] feat: add Cursor Agent CLI integration (beta)#245
NiveditJain merged 3 commits into
mainfrom
luv-245

Conversation

@NiveditJain
Copy link
Copy Markdown
Member

@NiveditJain NiveditJain commented Apr 29, 2026

Summary

  • Adds Cursor Agent CLI as a 4th supported agent CLI alongside Claude Code, OpenAI Codex, and GitHub Copilot — full feature parity (hooks install/uninstall, dashboard activity feed, /projects merge, session viewer fallback chain). Bumps version to 0.0.10-beta.1.
  • Cursor's hook protocol differs from the others on several axes; the integration handles each:
    • camelCase event keys (preToolUse, beforeSubmitPrompt, …) — handler.ts canonicalizes via CURSOR_EVENT_MAP so existing builtin policies fire unchanged.
    • Flat array per event (no Claude-style {hooks: [...]} matcher wrapper) — writeHookEntries / removeHooksFromFile / hooksInstalledInSettings walk the flat structure.
    • Different stdout shape ({permission, user_message, agent_message, additional_context, followup_message}) — policy-evaluator.ts branches on session.cli === "cursor" for deny / instruct / allow-with-info.
    • No documented permission-mode equivalent — falls into the existing default branch.
    • Detected via cursor-agent (preferred) or agent (legacy alias).
  • Settings paths: ~/.cursor/hooks.json (user) / <cwd>/.cursor/hooks.json (project).
  • Path-protection (isAgentInternalPath + isAgentSettingsFile) extended to cover ~/.cursor/ and .cursor/hooks.json.
  • Frontend: lib/cli-registry.ts adds a Cursor Agent entry with an emerald badge; lib/projects.ts merges Cursor projects; the project page and session viewer extend the external-CLI fallback chain. Activity feed recognizes /.cursor/ transcript paths.
  • Adds lib/cursor-projects.ts + lib/cursor-sessions.ts as scaffold parsers — Cursor's transcript layout is undocumented, so the modules probe candidate subdirs (agent-sessions/, conversations/, sessions/) and metadata files (meta.json / session.json / workspace.{json,yaml}) and gracefully return [] when the layout doesn't match. Once the user reports the real layout the parser is one constant change away from a precise match.
  • Drops .cursor/hooks.json at the project root so contributors using Cursor get hooks active automatically (mirrors the existing .codex/hooks.json and .github/hooks/failproofai.json). .gitignore adjusted to track that single file.
  • Adds light/dark Cursor logo SVGs in assets/logos/ and the visual <picture> block in README.md.
  • Pre-existing parity fix: app/project/[name]/page.tsx previously listed only Claude + Codex sessions, missing Copilot (and now Cursor); it now merges all four sources.

Test plan

  • bun run lint — clean (1 unrelated <img> warning)
  • bun run test:run — 60 suites / 1228 tests pass (including new __tests__/lib/cursor-sessions.test.ts, __tests__/lib/cursor-projects.test.ts, extended cli-registry.test.ts, projects.test.ts, project-list.test.tsx, integrations.test.ts, install-prompt.test.ts, handler.test.ts)
  • bun run build — Next.js + dist/index.js build succeeds; type-check passes
  • bun run test:e2e — 9 suites / 235 tests pass (including the new __tests__/e2e/hooks/cursor-integration.e2e.test.ts)
  • Local smoke test — failproofai policies --install --cli cursor --scope project writes .cursor/hooks.json with 6 camelCase entries; --uninstall cleans it
  • Docker clean-install test — to follow up if CI needs it; the e2e binary path test already covers the install flow

Open follow-ups

  • Cursor's on-disk transcript format isn't documented. The scaffold parsers + path probes return [] gracefully; once we observe a real install, swap the candidate constants in lib/cursor-{sessions,projects}.ts for precise matches.
  • i18n READMEs (docs/i18n/README.*.md) and docs/zh/, docs/pt-br/ translations will pick up the Cursor mentions on the next bun run translate cycle (same pattern as [luv-236] feat: add GitHub Copilot CLI integration (beta) #236 / [auto] update translations #233).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added support for Cursor Agent CLI integration (beta)
    • Dashboard now discovers and displays Cursor Agent sessions
    • Policy installation works with Cursor Agent via --cli cursor flag
    • Session viewer displays Cursor Agent activity logs
    • Activity dashboard includes Cursor Agent event filtering

Update the README beta callout to clarify that GitHub Copilot CLI
support is still under active testing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

Warning

Rate limit exceeded

@NiveditJain has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 51 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eaf8bb14-9ee0-4a69-8252-6e0867b6a340

📥 Commits

Reviewing files that changed from the base of the PR and between b4c1f64 and 69da6f6.

📒 Files selected for processing (4)
  • .cursor/hooks.json
  • CHANGELOG.md
  • lib/cursor-projects.ts
  • lib/cursor-sessions.ts
📝 Walkthrough

Walkthrough

Adds Cursor Agent CLI integration across the failproofai hook system, project/session discovery, policy evaluation, and dashboard. Includes new Cursor-specific modules for session/project scanning, hook configuration support, event-name canonicalization, decision output formatting, registry entries, comprehensive test coverage, and documentation updates.

Changes

Cohort / File(s) Summary
Configuration & Gitignore
.cursor/hooks.json, .gitignore
Introduces Cursor hook configuration file and updates ignore patterns to track it while excluding other .cursor/ contents.
Documentation
README.md, CLAUDE.md, CHANGELOG.md, docs/*
Advertises Cursor Agent (beta) as supported CLI, documents hook installation/event-mapping for Cursor, updates dashboard discovery/viewer descriptions, and logs changelog entries.
CLI & Hook System Core
bin/failproofai.mjs, src/hooks/handler.ts, src/hooks/install-prompt.ts, src/hooks/resolve-permission-mode.ts, src/hooks/builtin-policies.ts
Extends CLI argument validation and help text to accept --cli cursor, adds Cursor-specific event-name canonicalization from camelCase to PascalCase, updates builtin policy matchers to guard .cursor/hooks.json, and adjusts permission-mode fallback comments.
Hook Integration & Types
src/hooks/types.ts, src/hooks/integrations.ts
Defines Cursor-specific constants (CURSOR_HOOK_EVENT_TYPES, CURSOR_HOOK_SCOPES, CURSOR_EVENT_MAP) and implements new cursor integration adapter that reads/writes .cursor/hooks.json, manages hook lifecycle, and ensures camelCase event keys.
Policy Evaluation
src/hooks/policy-evaluator.ts
Adds Cursor-specific stdout formatting: flat {permission, user_message, agent_message} on deny, {followup_message} or {permission, additional_context} on instruct/allow, replacing previous event-specific wrappers.
CLI Registry
lib/cli-registry.ts
Adds "cursor" to KNOWN_CLI_IDS type and CLI_ENTRIES metadata with label and emerald badge CSS classes.
Project & Session Discovery
lib/cursor-projects.ts, lib/cursor-sessions.ts, lib/projects.ts
Introduces new Cursor session/project discovery modules that scan ~/.cursor/agent-sessions/ (respecting CURSOR_HOME), parse Cursor JSONL event logs with cwd extraction and tool correlation, and integrate discovered projects into the main project-folder merging pipeline.
Dashboard & Session Viewers
app/policies/hooks-client.tsx, app/project/[name]/page.tsx, app/project/[name]/session/[sessionId]/page.tsx
Extends SessionCell to detect and link Cursor sessions, updates project detail page to query external Cursor sessions in parallel, and adds Cursor session log loading and UI rendering to the session viewer.
Hook System Tests
__tests__/hooks/handler.test.ts, __tests__/hooks/install-prompt.test.ts, __tests__/hooks/integrations.test.ts
Adds test coverage for Cursor event-name normalization, telemetry tracking, integration lifecycle (install/uninstall/detection), hook entry construction, and event-map completeness.
Library Tests
__tests__/lib/cursor-projects.test.ts, __tests__/lib/cursor-sessions.test.ts, __tests__/lib/projects.test.ts, __tests__/lib/cli-registry.test.ts
Introduces comprehensive test suites for Cursor project/session discovery with metadata scanning fallbacks, JSONL parsing with tool correlation, project merging, and CLI registry Cursor entry validation.
E2E & Component Tests
__tests__/e2e/hooks/cursor-integration.e2e.test.ts, __tests__/e2e/helpers/hook-runner.ts, __tests__/e2e/helpers/payloads.ts, __tests__/components/project-list.test.tsx
Adds end-to-end hook runner tests verifying deny/instruct/allow paths, activity logging, and install/uninstall behavior; introduces Cursor payload factories and assertion helpers; extends project-list component tests to verify Cursor badge rendering and CLI filter options.
Package Metadata
package.json
Increments version from 0.0.10-beta.0 to 0.0.10-beta.1.

Sequence Diagram

sequenceDiagram
    participant CursorCLI as Cursor CLI
    participant Hook as Hook Runner
    participant Handler as Event Handler
    participant Evaluator as Policy Evaluator
    participant Output as Decision Output

    CursorCLI->>Hook: Invokes hook with camelCase event<br/>(preToolUse, postToolUse, etc.)
    Hook->>Handler: Passes stdin payload to failproofai
    Handler->>Handler: Canonicalizes camelCase to PascalCase<br/>(preToolUse → PreToolUse)
    Handler->>Evaluator: Evaluates policy against<br/>canonical event type
    Evaluator->>Evaluator: Determines decision<br/>(deny/instruct/allow)
    alt Deny Decision
        Evaluator->>Output: Build blocked message
        Output->>CursorCLI: Return flat Cursor format<br/>{permission: "deny",<br/>user_message, agent_message}
    else Instruct Decision
        Evaluator->>Output: Build followup/context message
        Output->>CursorCLI: Return Cursor format<br/>{followup_message} or<br/>{permission: "allow",<br/>additional_context}
    else Allow Decision
        Evaluator->>Output: Build allow response
        Output->>CursorCLI: Return {permission: "allow",<br/>additional_context}
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Hop, hop, the Cursor comes to play,
Events camelCase'd, then cast to Pascal's way,
Projects and sessions cached in burrows deep,
Hook events evaluated—promises we keep! ✨🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.66% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[luv-245] feat: add Cursor Agent CLI integration (beta)' directly and clearly summarizes the primary change: adding Cursor Agent CLI support as a new integration alongside existing agent CLIs.
Description check ✅ Passed The PR description comprehensively covers the work: Summary section explains what was added and why, detailed subsections describe protocol differences, settings paths, frontend changes, and new modules, Test plan documents all test suites with pass counts, and Open follow-ups clarify future refinements. All required template sections (Description, Type of Change, Checklist) are addressed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch luv-245

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 47 minutes and 51 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Mirrors the Codex (#220, #226, #232) and Copilot (#236) rollouts for
Cursor Agent CLI. Hook install/uninstall, handler canonicalization,
policy-evaluator output adapter, path-protection, activity dashboard
filter + per-CLI badge, /projects merge, and session viewer fallback.

Cursor's hook protocol differs from Claude/Codex/Copilot:
  - camelCase event keys (preToolUse, beforeSubmitPrompt, …) — handler
    canonicalizes via CURSOR_EVENT_MAP before policy lookup.
  - Flat array of hook entries per event (no Claude-style {hooks: [...]}
    matcher wrapper); writeHookEntries / removeHooksFromFile /
    hooksInstalledInSettings all walk the flat structure directly.
  - Stdout decision shape is {permission, user_message, agent_message,
    additional_context, followup_message} (not hookSpecificOutput).
    policy-evaluator.ts now branches on session.cli === "cursor" for the
    deny / instruct / allow-with-info paths and emits the Cursor shape.
  - No documented permission-mode equivalent; resolve-permission-mode.ts
    falls into the existing "default" branch (same as Copilot).
  - Detected via cursor-agent (preferred) or agent (legacy alias).

Settings paths:
  user    → ~/.cursor/hooks.json
  project → <cwd>/.cursor/hooks.json

Path-protection (isAgentInternalPath + isAgentSettingsFile) extended to
cover ~/.cursor/ and .cursor/hooks.json so the agent can't disable its
own hooks.

Frontend: lib/cli-registry.ts adds a "Cursor Agent" entry with an
emerald badge; lib/projects.ts merges cursor projects; the project page
(app/project/[name]/page.tsx) and session viewer
(app/project/[name]/session/[sessionId]/page.tsx) extend the
external-CLI fallback chain. The activity feed (hooks-client.tsx)
recognizes /.cursor/ transcript paths.

Adds lib/cursor-projects.ts + lib/cursor-sessions.ts as scaffold
parsers — Cursor's transcript layout is undocumented, so the modules
probe candidate subdirs (agent-sessions/, conversations/, sessions/)
and metadata files (meta.json/session.json/workspace.{json,yaml}) and
gracefully return [] when the directory layout doesn't match. The
parser handles dotted-path record types (session.start, user.message,
…) and degrades to system entries for unknown types so nothing is
silently dropped — same shape as the Copilot parser.

Drops the .cursor/hooks.json file at the project root (mirrors the
existing .codex/hooks.json and .github/hooks/failproofai.json) so
contributors developing failproofai with Cursor get hooks active
automatically. Adjusts .gitignore to track that single file while
leaving the rest of .cursor/ ignored.

Tests: 60 unit suites / 1228 tests pass; 9 e2e suites / 235 tests pass
(including the new __tests__/e2e/hooks/cursor-integration.e2e.test.ts
which covers PreToolUse deny + agent-settings guard +
beforeSubmitPrompt allow + activity tagging + install/uninstall flows).

Bumps version to 0.0.10-beta.1.

Also fixes a pre-existing parity gap: the project detail page
(app/project/[name]/page.tsx) only listed Claude + Codex sessions,
missing Copilot (and now Cursor); it now merges all four sources.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@NiveditJain NiveditJain changed the title [luv-245] docs: note GitHub Copilot CLI testing is ongoing [luv-245] feat: add Cursor Agent CLI integration (beta) Apr 29, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.cursor/hooks.json:
- Line 9: Remove the non-schema field "__failproofai_hook__" from all hook
objects in .cursor/hooks.json; Cursor only allows "type", "command", and
"timeout" per hook, so locate each hook entry containing the
"__failproofai_hook__" property and delete that key/value pair (preserving the
allowed fields like "type", "command", and "timeout") so the file conforms to
the hooks.json schema.

In `@CHANGELOG.md`:
- Around line 12-17: The changelog added a second "### Features" block under "##
Unreleased"; instead, merge the new Cursor Agent and Project page bullets into
the existing Unreleased subsections (fold the Cursor Agent CLI integration
details and the Project page bullet into the existing "### Features" and fold
README/logo note into "### Docs"), remove the duplicate "### Features" heading,
and keep references to the implemented symbols (CURSOR_EVENT_MAP,
isAgentInternalPath, isAgentSettingsFile, lib/cli-registry.ts, lib/projects.ts,
app/project/[name], /session/[id], and assets/logos/cursor-light.svg +
cursor-dark.svg) in-line within the appropriate subsection so the Unreleased
block remains a single coherent set of subsections.

In `@lib/cursor-projects.ts`:
- Around line 71-78: The JSON branch in parseCwdFromMetaText returns the raw
escaped string; instead try to JSON.parse the input text (inside a try/catch)
and read the cwd property so escape sequences (e.g. Windows backslashes) are
decoded, returning parsed.cwd if present; if JSON.parse throws or cwd is
missing, fall back to the existing regex checks (the YAML regex and the current
string-unquote step) so behavior remains unchanged for non-JSON metadata.

In `@lib/cursor-sessions.ts`:
- Around line 165-200: The user/assistant message branches in
lib/cursor-sessions.ts currently cast data.content/data.text with "as string"
and may push non-string values; update the user.message and assistant.message
handling (the lines that set `text = (data.content as string) ?? (data.text as
string) ?? ""` and the assistant ContentBlock creation) to first check typeof
data.content === "string" or typeof data.text === "string" and only use those
values when true, otherwise fall back to "" (and keep existing fallback to
pushing a GenericEntry when no text); ensure the produced entries (UserEntry,
AssistantEntry) always have string message content/ContentBlock.text to avoid
passing objects to the renderer while keeping baseEntry and rawCopy usage
intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: de718b89-4db5-4f7a-b48d-d35b627cb013

📥 Commits

Reviewing files that changed from the base of the PR and between 6c259fc and b4c1f64.

⛔ Files ignored due to path filters (2)
  • assets/logos/cursor-dark.svg is excluded by !**/*.svg
  • assets/logos/cursor-light.svg is excluded by !**/*.svg
📒 Files selected for processing (35)
  • .cursor/hooks.json
  • .gitignore
  • CHANGELOG.md
  • CLAUDE.md
  • README.md
  • __tests__/components/project-list.test.tsx
  • __tests__/e2e/helpers/hook-runner.ts
  • __tests__/e2e/helpers/payloads.ts
  • __tests__/e2e/hooks/cursor-integration.e2e.test.ts
  • __tests__/hooks/handler.test.ts
  • __tests__/hooks/install-prompt.test.ts
  • __tests__/hooks/integrations.test.ts
  • __tests__/lib/cli-registry.test.ts
  • __tests__/lib/cursor-projects.test.ts
  • __tests__/lib/cursor-sessions.test.ts
  • __tests__/lib/projects.test.ts
  • app/policies/hooks-client.tsx
  • app/project/[name]/page.tsx
  • app/project/[name]/session/[sessionId]/page.tsx
  • bin/failproofai.mjs
  • docs/configuration.mdx
  • docs/dashboard.mdx
  • docs/getting-started.mdx
  • lib/cli-registry.ts
  • lib/cursor-projects.ts
  • lib/cursor-sessions.ts
  • lib/projects.ts
  • package.json
  • src/hooks/builtin-policies.ts
  • src/hooks/handler.ts
  • src/hooks/install-prompt.ts
  • src/hooks/integrations.ts
  • src/hooks/policy-evaluator.ts
  • src/hooks/resolve-permission-mode.ts
  • src/hooks/types.ts

Comment thread .cursor/hooks.json Outdated
Comment thread CHANGELOG.md Outdated
Comment thread lib/cursor-projects.ts
Comment thread lib/cursor-projects.ts Outdated
Comment thread lib/cursor-sessions.ts
Five fixes from the bot review on PR #245:

1. .cursor/hooks.json: drop the `__failproofai_hook__` marker from the
   static dev config so the file matches Cursor's documented hook entry
   schema ({type, command, timeout}). The marker is still written by
   `cursor.buildHookEntry` for dynamically installed hooks; the legacy
   command-substring fallback in `isMarkedHook` identifies these static
   entries during uninstall.

2. CHANGELOG.md: fold the new Cursor entries into the existing Unreleased
   subsections (Features / Fixes / Docs) instead of creating a duplicate
   `### Features` heading. Resolves the MD024 markdownlint complaint.

3. lib/cursor-projects.ts: parse meta.json with `JSON.parse` first so
   escape sequences in JSON strings (Windows paths like
   `C:\\Users\\alice\\repo`) are decoded. Falls back to the YAML-ish regex
   only when the file isn't valid JSON.

4. lib/cursor-projects.ts: replace `findFirstExisting` (returns first
   existing path) with `findFirstUsableMeta` (returns first path whose
   parsed cwd is non-empty). Stops a stale `meta.json` from shadowing a
   valid `workspace.yaml` and dropping the session.

5. lib/cursor-sessions.ts: validate `data.content` / `data.text` with
   `typeof === "string"` before treating them as text in the user.message
   and assistant.message branches. Avoids surfacing non-string values via
   the `as string` casts.

All 1228 unit + 235 e2e tests still pass. Lint clean (one pre-existing
unrelated `<img>` warning).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@NiveditJain NiveditJain merged commit 21cf469 into main Apr 30, 2026
9 checks passed
NiveditJain added a commit that referenced this pull request May 1, 2026
Convention: each Unreleased bullet ends with `(#<PR>)`. Also extends the
Features bullet to mention this repo dogfoods `.pi/settings.json`,
matching the wording style used for the Cursor entry in #245.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NiveditJain added a commit that referenced this pull request May 5, 2026
…ion-bumps policy (#285)

* [luv-cut-0.0.10-beta.0] chore: cut 0.0.10-beta.0 release

Bumps package.json from 0.0.9-beta.3 to 0.0.10-beta.0 and rolls the
## Unreleased changelog section into ## 0.0.10-beta.0 — 2026-05-04.

Why 0.0.10-beta.0 and not 0.0.9-beta.3:
0.0.9 is already published as `latest` on npm. Per semver,
0.0.9-beta.3 < 0.0.9 — publishing it would point the `beta` dist-tag
at a version semver-older than the released 0.0.9, while shipping
*more* features than 0.0.9 ever had. The next pre-release after a
shipped 0.0.9 must live in the 0.0.10 line.

Why the version had drifted to 0.0.13-beta.1 before #284 reset it:
PRs #266 (OpenCode) and #267 (Pi) each speculatively bumped
package.json in their feature branches even though no release was
being cut. When unified into #270, the bumps stacked
(0.0.10-beta.1 → .2 → 0.0.11-beta.1 → 0.0.12-beta.1 → 0.0.13-beta.1).
Going forward, feature PRs should leave package.json alone — only
release-cut PRs touch the version.

Adds since v0.0.9:

Features:
- Add Gemini CLI integration (beta) (#277)
- Add OpenCode (sst/opencode) integration (beta) (#270)
- Add Pi (pi-coding-agent) integration (beta) (#270)
- Add GitHub Copilot CLI integration (beta) (#236)
- Add Cursor Agent CLI integration (beta) (#245)
- Project page lists Copilot and Cursor sessions (#245)

Fixes:
- Pi integration: cache sessionId in shim (#284)
- Cursor integration: support cursor-agent 2026-04+ layout (#283)
- block-read-outside-cwd: deny message for all 6 CLIs (#270)
- require-ci-green-before-stop: scope to current HEAD (#266)
- failproofai policies --uninstall: correct selector wording (#236)
- README: replace broken Copilot and Cursor logos (#236, #257)
- Auto-translated MDX: sanitize JSX attribute quotes (#247)

Docs:
- README: drop "more coming soon" tagline (#281)
- README: add Gemini, Pi, Cursor to supported-CLIs list (#277, #264, #245)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: add block-version-bumps custom policy

Prevents the kind of drift that caused this very release. PRs #266
(OpenCode) and #267 (Pi) each speculatively bumped package.json in
their feature branches, and when unified into #270 the bumps stacked
all the way to 0.0.13-beta.1. PR #284 then over-corrected to
0.0.9-beta.3 — older than the already-published 0.0.9.

The policy lives at .failproofai/policies/block-version-bumps.mjs
(auto-loaded by failproofai's project-scope hooks). It blocks:
- Edit/Write/MultiEdit on package.json that touches the "version" key
- Bash:  npm|yarn|pnpm|bun (pm) version <args>
- Bash:  sed|awk|jq mutating package.json referencing "version"

Allowed when on a `luv-cut-*` branch — the established release-cut
branch convention. Branch detection is a best-effort `git rev-parse`
that fails open (returns false) so a missing/unusable git tree never
blocks a legitimate edit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: address CodeRabbit review on block-version-bumps

Three valid findings, all fixed:

1. sed/awk/jq detection (line 26): regex required `package.json`
   to appear before `version`, missing forms like
   `jq '.version="x"' package.json`. Switched to two non-consuming
   lookaheads so either ordering matches within a shell segment.

2. Value-only Edit/MultiEdit bypass (lines 74-84): an agent could
   issue `Edit { old_string: '"0.0.9-beta.3"', new_string:
   '"0.0.10-beta.0"' }` — neither string contains the literal
   `"version"` key, so the previous check let it through. Added
   STANDALONE_SEMVER_VALUE_RE plus an editTouchesVersion() helper
   that catches a value-only swap when both sides are bare
   semver-quoted strings that differ. The anchors (^ / $) and
   leading-digit requirement intentionally exclude
   range-prefixed dep entries (`"^1.2.3"`) and key-prefixed ones
   (`"react": "18.2.0"`), so dep-version Edits aren't false-positive.

3. Loose cut-branch match (line 36): `^luv-cut-/` allowed any
   suffix (e.g. `luv-cut-feature`). Tightened to require a
   semver-shape suffix:
   `^luv-cut-\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$`.

Verified via 16 regex test cases (sed orderings, dep edits with
keys, range prefixes, cut branch shapes).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
NiveditJain added a commit that referenced this pull request May 8, 2026
…a.6 (#318)

* [luv-319] fix: enforce Stop hook on Cursor Agent CLI (followup_message + SubagentStop parity)

Cursor's `stop` hook ignores the flat `{permission: "deny"}` shape — that's
honored on tool events only. The only force-retry channel for Stop is
`{followup_message}` on stdout (exit 0), per https://cursor.com/docs/hooks.
The instruct branch already used this shape correctly since #245; the deny
path needed the same treatment, mirroring Copilot's #299 fix.

Without this, the 5 require-*-before-stop builtins were observation-only on
Cursor — the deny was logged but the agent stopped cleanly. User repro:
session 1b510ad4-906c-4f30-9467-ff2e6c581cce at /home/nivedit/dev-purge.

Also subscribes to `subagentStop` (CURSOR_HOOK_EVENT_TYPES + CURSOR_EVENT_MAP)
and widens both deny and instruct branches to match it, for parity with the
Copilot SubagentStop widening from #299.

Cloud Agents caveat: Cursor Cloud Agent VMs do NOT run stop/subagentStop
hooks at all, so this fix only covers local Cursor sessions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: cut 0.0.10-beta.6 release in CHANGELOG

Promote the six entries accumulated under `## Unreleased` to a versioned
heading `## 0.0.10-beta.6 — 2026-05-08`. Add a fresh `## Unreleased`
heading at the top for the next development cycle.

package.json was already at 0.0.10-beta.6 (pre-bumped); no version edit
needed here. The CHANGELOG cut completes the release-prep handshake.

Entries promoted:
- Cursor Stop hook enforcement fix (this PR)
- 5 scripts/translate-docs fixes from #305, #306, #307, #312, #313

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant