Skip to content

feat(cursor): refresh plugin contract coverage against the 2026-09-02 public docs (#189) - #375

Merged
ScriptedAlchemy merged 9 commits into
mainfrom
feat/189-cursor-contract-refresh
Sep 3, 2026
Merged

feat(cursor): refresh plugin contract coverage against the 2026-09-02 public docs (#189)#375
ScriptedAlchemy merged 9 commits into
mainfrom
feat/189-cursor-contract-refresh

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Closes the #189 Cursor contract-matrix umbrella against the public docs retrieved 2026-09-02 (https://cursor.com/docs/plugins, https://cursor.com/docs/reference/plugins, https://cursor.com/docs/hooks).

  • Subagent lifecycle with real envelopes. Cursor subagentStart/subagentStop were advertised supported with no fixture: the config-hook wrapper would have rejected every real payload (loop_count check), the event-route validator checked nothing, and the projection emitted an undocumented additional_context while refusing the documented permission: "deny". Now: envelope validation for the documented subagent_* fields (route + wrapper), projection to { permission: "deny", user_message } / { followup_message } only, Agent.Context fails closed on both (no documented channel), documented-payload fixtures (tests/fixtures/events/cursor-subagent-{start,stop}.json), lifecycle starters, playground codecs, and an executed-wrapper test.
  • cursor.* config extension. Schema-admitted manifest metadata (author{name,email}, homepage, repository, license, keywords, publisher, category, tags, minClientVersions) is validated against the pinned cursor/plugins@0701892 shapes and emitted into .cursor-plugin/plugin.json on the cursor target and the Cursor half of plugin; cursor.manifest.* errors, no partial emission, author.url/unknown keys rejected. AgentBundleConfig now merges CursorConfigExtension.
  • Complete contract matrix in the capability table. hooks.nativeEvents pins all 21 documented events (18 agent, 2 tab, workspaceOpen) with category, cloud availability, matcher subject, output fields, and the row that owns each; every supported route carries availability.{desktop,cloud} per the docs' cloud table (the stale beforeSubmitPrompt-cloud deferral is removed — the docs list it as cloud-supported). New dated rows: hooks.cloud (config sources; plugin hooks not a documented cloud source), hooks.options (command, timeout, matcher supported; failClosed, loop_limit, prompt hooks unavailable with the fail-open consequence spelled out), plugin.formats (Cursor Plugin supported; Agent Plugin owned by portable, never mixed), componentDiscovery, rootSkill, variables, manifestMetadata, marketplaceManifest (500-entry cap, manifest-over-entry precedence), distributionPolicy (install modes, marketplace access, local plugin imports, auto refresh, review/publish, team marketplaces, symlink install), canvases, and the G5-gated agents.component. Each row is a cursor adapter capability and is mirrored through the unified plugin adapter (manifestMetadata now intersects Cursor for real).
  • Local install re-verified. Docs now show ln -s for local iteration; the loader observed 2026-08-31 rejected symlinks escaping ~/.cursor/plugins/local (Cursor install instruction 'clone (or symlink)' fails: Cursor rejects local-plugin symlinks resolving outside ~/.cursor/plugins/local #127); Cursor IDE 3.18.25 loaded three physical local directories on this machine (2026-09-03 UTC). Installer/doctor keep copying, which satisfies both readings; recorded in install.evidence, distributionPolicy.localSymlinkInstall, and PROVENANCE.publicDocsObservation.
  • Revisions: cursor 1.8.0 → 1.9.0, unified plugin 1.21.0 → 1.22.0. Changeset: minor, agent-bundle. Docs: root README (cursor.*), example README + walkthrough canvas event matrices.

Evidence

  • Public docs fetched 2026-09-02; every table row cites its page. Live cursor-agent 2026.08.31-4057e58 capture for subagentStart/subagentStop was attempted with trusted project hooks and could not dispatch (Authentication required), so the pinned reference plus fixture replay are the evidence source (recorded in provenance.evidence).
  • wave/cursor-workspace-open (PR feat(cursor): support workspace/open event routes as fire-and-forget observation #298, squash 69a413b) has no surviving delta: its 13-file/318-line diff is byte-present on origin/main.

Test plan

  • pnpm typecheck
  • pnpm lint — 0 errors, 0 warnings
  • pnpm test:unit — 2671 passed, 5 skipped; two unrelated files (event-ipc, native-claude-contract) flaked under parallel-lane load and passed on re-run
  • pnpm test:route-unit — 36 passed
  • pnpm test:projection — 63 passed
  • pnpm build && pnpm test:integration:run — running locally; CI is authoritative

Closes #189.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4255928

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T11:21:30.542918Z 4255928 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@375
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@375
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@375

commit: 4255928

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e3bc972a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/adapters/cursor.ts
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch 3 times, most recently from af79347 to b3e3452 Compare September 3, 2026 06:25
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…he pinned uri format

Addresses Codex review on #375: new URL() normalizes whitespace and unescaped
characters that the pinned plugin schema's format: uri rejects, so the plan
reported a generic cursor.schema.plugin error and kept the invalid metadata.
homepage/repository now go through the schema's own uri format checker first
and fail closed with cursor.manifest.<field>.invalid.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Re-triggering CI: the pull_request synchronize event for 429c6bd produced no workflow run; closing and reopening to fire it.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 429c6bdfbc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/adapters/cursor.ts Outdated
Comment thread packages/agent-bundle/src/events/projection.ts Outdated
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…idate author.email with the pinned format

Addresses the second Codex review round on #375:
- subagentStart: parent_conversation_id, tool_call_id, subagent_model, and
  is_parallel_worker are required (only git_branch is documented optional) in
  both the route envelope validator and the generated wrapper validator.
- subagentStop: task, description, summary, duration_ms, message_count,
  tool_call_count, modified_files, and agent_transcript_path (string|null) are
  required to match the documented input, which marks no field optional.
- Simulation encoders carry neutral values for the mandatory fields canonical
  input lacks so hook simulation still passes the tightened validators.
- author.email goes through the pinned schema's format: email checker so
  values like dev@example..com fail closed as cursor.manifest.author.email.invalid.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e982d50eec

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/events/projection.ts Outdated
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…he pinned uri format

Addresses Codex review on #375: new URL() normalizes whitespace and unescaped
characters that the pinned plugin schema's format: uri rejects, so the plan
reported a generic cursor.schema.plugin error and kept the invalid metadata.
homepage/repository now go through the schema's own uri format checker first
and fail closed with cursor.manifest.<field>.invalid.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…idate author.email with the pinned format

Addresses the second Codex review round on #375:
- subagentStart: parent_conversation_id, tool_call_id, subagent_model, and
  is_parallel_worker are required (only git_branch is documented optional) in
  both the route envelope validator and the generated wrapper validator.
- subagentStop: task, description, summary, duration_ms, message_count,
  tool_call_count, modified_files, and agent_transcript_path (string|null) are
  required to match the documented input, which marks no field optional.
- Simulation encoders carry neutral values for the mandatory fields canonical
  input lacks so hook simulation still passes the tightened validators.
- author.email goes through the pinned schema's format: email checker so
  values like dev@example..com fail closed as cursor.manifest.author.email.invalid.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch from e982d50 to 2b338a2 Compare September 3, 2026 07:22
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b338a23fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/events/projection.ts Outdated
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…gnore and on reasons without deny

Addresses the third and fourth Codex review rounds on #375:
- projectEventDocument accepts the validated native envelope (all production
  callers pass it); a denied agent/stop on Cursor throws unless the subagent
  status is completed, since followup_message is consumed only then. The
  generated wrapper's encodeOutput applies the same check.
- The Cursor agent/stop route branch rejects a reason without outcome deny,
  matching the generated wrapper validator instead of swallowing it.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: d1ec84f26c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…he pinned uri format

Addresses Codex review on #375: new URL() normalizes whitespace and unescaped
characters that the pinned plugin schema's format: uri rejects, so the plan
reported a generic cursor.schema.plugin error and kept the invalid metadata.
homepage/repository now go through the schema's own uri format checker first
and fail closed with cursor.manifest.<field>.invalid.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…idate author.email with the pinned format

Addresses the second Codex review round on #375:
- subagentStart: parent_conversation_id, tool_call_id, subagent_model, and
  is_parallel_worker are required (only git_branch is documented optional) in
  both the route envelope validator and the generated wrapper validator.
- subagentStop: task, description, summary, duration_ms, message_count,
  tool_call_count, modified_files, and agent_transcript_path (string|null) are
  required to match the documented input, which marks no field optional.
- Simulation encoders carry neutral values for the mandatory fields canonical
  input lacks so hook simulation still passes the tightened validators.
- author.email goes through the pinned schema's format: email checker so
  values like dev@example..com fail closed as cursor.manifest.author.email.invalid.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…gnore and on reasons without deny

Addresses the third and fourth Codex review rounds on #375:
- projectEventDocument accepts the validated native envelope (all production
  callers pass it); a denied agent/stop on Cursor throws unless the subagent
  status is completed, since followup_message is consumed only then. The
  generated wrapper's encodeOutput applies the same check.
- The Cursor agent/stop route branch rejects a reason without outcome deny,
  matching the generated wrapper validator instead of swallowing it.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch from d1ec84f to 0de3c4a Compare September 3, 2026 08:10
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 0de3c4a23e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch from fe257d2 to 4bb55e9 Compare September 3, 2026 10:07
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…art wrappers

Addresses the fifth Codex review round on #375: parent_conversation_id is a
subagent field, not a substitute for the common envelope's conversation_id, so
the generated wrapper no longer accepts it in place of session_id/conversation_id
and no longer falls back to it for sessionId. This matches the route envelope
validator in events/projection.ts.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bb55e9acb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/adapters/hook-contract.ts
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…subagentStart

Addresses the sixth Codex review round on #375: the generated wrapper now
mirrors the simulation codec (model <-> subagent_model) so handlers observe
event.model for real Cursor subagentStart payloads.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…he pinned uri format

Addresses Codex review on #375: new URL() normalizes whitespace and unescaped
characters that the pinned plugin schema's format: uri rejects, so the plan
reported a generic cursor.schema.plugin error and kept the invalid metadata.
homepage/repository now go through the schema's own uri format checker first
and fail closed with cursor.manifest.<field>.invalid.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…idate author.email with the pinned format

Addresses the second Codex review round on #375:
- subagentStart: parent_conversation_id, tool_call_id, subagent_model, and
  is_parallel_worker are required (only git_branch is documented optional) in
  both the route envelope validator and the generated wrapper validator.
- subagentStop: task, description, summary, duration_ms, message_count,
  tool_call_count, modified_files, and agent_transcript_path (string|null) are
  required to match the documented input, which marks no field optional.
- Simulation encoders carry neutral values for the mandatory fields canonical
  input lacks so hook simulation still passes the tightened validators.
- author.email goes through the pinned schema's format: email checker so
  values like dev@example..com fail closed as cursor.manifest.author.email.invalid.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…gnore and on reasons without deny

Addresses the third and fourth Codex review rounds on #375:
- projectEventDocument accepts the validated native envelope (all production
  callers pass it); a denied agent/stop on Cursor throws unless the subagent
  status is completed, since followup_message is consumed only then. The
  generated wrapper's encodeOutput applies the same check.
- The Cursor agent/stop route branch rejects a reason without outcome deny,
  matching the generated wrapper validator instead of swallowing it.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…art wrappers

Addresses the fifth Codex review round on #375: parent_conversation_id is a
subagent field, not a substitute for the common envelope's conversation_id, so
the generated wrapper no longer accepts it in place of session_id/conversation_id
and no longer falls back to it for sessionId. This matches the route envelope
validator in events/projection.ts.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…subagentStart

Addresses the sixth Codex review round on #375: the generated wrapper now
mirrors the simulation codec (model <-> subagent_model) so handlers observe
event.model for real Cursor subagentStart payloads.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch from 13097de to 5cd1f89 Compare September 3, 2026 10:37
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cd1f898df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .changeset/cursor-contract-refresh.md Outdated
… public docs (#189)

Validate and project Cursor subagentStart/subagentStop through their documented
subagent_* envelopes and output channels (permission deny + user_message;
followup_message) in event routes, config-hook wrappers, playground codecs, and
lifecycle starters. Add the cursor.* config extension for schema-admitted
manifest metadata (author, homepage, repository, license, keywords, publisher,
category, tags, minClientVersions) with cursor.manifest.* diagnostics. Pin the
complete 21-event Cursor hook inventory with cloud availability, hook options,
plugin formats, discovery, variables, marketplace limits, distribution and
local-install surfaces, canvases, and the G5-gated agents component as dated
capability rows mirrored through the unified bundle. Cursor adapterRevision
1.9.0, plugin 1.22.0.
…he pinned uri format

Addresses Codex review on #375: new URL() normalizes whitespace and unescaped
characters that the pinned plugin schema's format: uri rejects, so the plan
reported a generic cursor.schema.plugin error and kept the invalid metadata.
homepage/repository now go through the schema's own uri format checker first
and fail closed with cursor.manifest.<field>.invalid.
…idate author.email with the pinned format

Addresses the second Codex review round on #375:
- subagentStart: parent_conversation_id, tool_call_id, subagent_model, and
  is_parallel_worker are required (only git_branch is documented optional) in
  both the route envelope validator and the generated wrapper validator.
- subagentStop: task, description, summary, duration_ms, message_count,
  tool_call_count, modified_files, and agent_transcript_path (string|null) are
  required to match the documented input, which marks no field optional.
- Simulation encoders carry neutral values for the mandatory fields canonical
  input lacks so hook simulation still passes the tightened validators.
- author.email goes through the pinned schema's format: email checker so
  values like dev@example..com fail closed as cursor.manifest.author.email.invalid.
…gnore and on reasons without deny

Addresses the third and fourth Codex review rounds on #375:
- projectEventDocument accepts the validated native envelope (all production
  callers pass it); a denied agent/stop on Cursor throws unless the subagent
  status is completed, since followup_message is consumed only then. The
  generated wrapper's encodeOutput applies the same check.
- The Cursor agent/stop route branch rejects a reason without outcome deny,
  matching the generated wrapper validator instead of swallowing it.
…art wrappers

Addresses the fifth Codex review round on #375: parent_conversation_id is a
subagent field, not a substitute for the common envelope's conversation_id, so
the generated wrapper no longer accepts it in place of session_id/conversation_id
and no longer falls back to it for sessionId. This matches the route envelope
validator in events/projection.ts.
…subagentStart

Addresses the sixth Codex review round on #375: the generated wrapper now
mirrors the simulation codec (model <-> subagent_model) so handlers observe
event.model for real Cursor subagentStart payloads.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/189-cursor-contract-refresh branch from 5cd1f89 to 4255928 Compare September 3, 2026 11:15
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 4255928eb6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy
ScriptedAlchemy merged commit 60445ec into main Sep 3, 2026
18 of 19 checks passed
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…per in cursor adapter, bump cursor 1.10.0 / plugin 1.26.0
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.

Refresh Cursor plugin contract coverage against current public docs

1 participant