diff --git a/CHANGELOG.md b/CHANGELOG.md index 15d1b8d..83cf68b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to Doable Agent Plugins are documented here. +## [0.2.6] - 2026-09-07 + +### Fixed + +- Wait for Cursor's asynchronous MCP refresh after replacing credentials, then + retry the original preflight before treating a `401` as a rejected new key. + ## [0.2.5] - 2026-09-07 ### Changed diff --git a/README.md b/README.md index b19b7b2..bfc8f7a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Official agent plugins for [Doable](https://getdoable.ai), supporting Codex, Cla | Plugin | Version | Purpose | Network | | --- | --- | --- | --- | -| `doable-code-context` | `0.2.5` | Resolve context requests or start a managed feature-testing workflow | Doable MCP | +| `doable-code-context` | `0.2.6` | Resolve context requests or start a managed feature-testing workflow | Doable MCP | ## Workflow diff --git a/TESTING.md b/TESTING.md index 5667f48..a393125 100644 --- a/TESTING.md +++ b/TESTING.md @@ -8,7 +8,7 @@ For every scenario, confirm that the agent inspects only evidence needed for the 1. **Cold install from the TRD Editor** — Start TRD creation, publish a fresh Code Context Round, and copy its prompt. Paste it into a Codex, Claude Code, or Cursor agent that has never installed Doable and has no Doable MCP entry. The agent detects the missing Skill from its loaded skill catalog, preserves the exact DQ and organization while installation completes, and loads the plugin-declared `doable` MCP connection. Cursor must request `DOABLE_API_KEY` during plugin installation; Codex and Claude Code must resolve it from their launch environment. The original DQ continues without another paste. No repository scan may start before the authenticated preflight succeeds. 2. **Plugin reinstall** — Install a newer plugin version over a prior release in each supported host. Expect the host to replace the packaged Skill and MCP declaration and expose the new version only after installation completes. Cursor also requests a missing required variable. A source checkout or symlink change alone is not an installed-plugin update. -3. **Copied-Round authentication preflight** — Paste a Round prompt with no working `doable` connection. Expect `get_code_context_connection` with the exact `round_code` before the agent uses `.doable` state or scans code; it may read only an optional `workspace.clientRef` for that preflight. After the user supplies the target organization's key once, expect the agent to configure only the host's user-scoped MCP connection. In Claude Code, the only remaining user action is `/mcp` → reconnect `doable`; the agent then retries and resumes the original Round without a restart, new session, or second prompt. +3. **Copied-Round authentication preflight** — Paste a Round prompt with no working `doable` connection. Expect `get_code_context_connection` with the exact `round_code` before the agent uses `.doable` state or scans code; it may read only an optional `workspace.clientRef` for that preflight. After the user supplies the target organization's key once, expect the agent to configure only the host's user-scoped MCP connection. In Cursor, make the old live transport return `401` immediately after replacement; expect the agent to wait for the asynchronous MCP refresh and retry before rejecting the new key. In Claude Code, the only remaining user action is `/mcp` → reconnect `doable`; the agent then retries and resumes the original Round without a restart, new session, or second prompt. 4. **Coding-agent-origin authentication preflight** — Start a feature-testing request without a copied Round. Expect `get_code_context_connection` before local workspace setup or remote suite search. Recover the connection once and resume the original feature request automatically. 5. **Demand-driven setup** — Paste a round prompt in a workspace with no `.doable` state. Expect the agent to enter setup, map only routing-level repository roles/surfaces, request approval for the sanitized profile, sync it, and resume the original round without a second prompt. 6. **Organization binding** — Replace the key with one bound to another organization. Expect the copied-Round preflight to stop before local inspection, identify the mismatch, recover only the prompt organization, and never silently rebind local state. diff --git a/package.json b/package.json index 67f6695..0c313f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doable-agent-plugins", - "version": "0.2.5", + "version": "0.2.6", "private": true, "description": "Official installable agent plugins for Doable.", "license": "MIT", diff --git a/plugins/doable-code-context/.claude-plugin/plugin.json b/plugins/doable-code-context/.claude-plugin/plugin.json index e8c9476..c2a91ef 100644 --- a/plugins/doable-code-context/.claude-plugin/plugin.json +++ b/plugins/doable-code-context/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "doable-code-context", - "version": "0.2.5", + "version": "0.2.6", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI", diff --git a/plugins/doable-code-context/.codex-plugin/plugin.json b/plugins/doable-code-context/.codex-plugin/plugin.json index 000b2f5..518978b 100644 --- a/plugins/doable-code-context/.codex-plugin/plugin.json +++ b/plugins/doable-code-context/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "doable-code-context", - "version": "0.2.5", + "version": "0.2.6", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI", diff --git a/plugins/doable-code-context/.cursor-plugin/plugin.json b/plugins/doable-code-context/.cursor-plugin/plugin.json index 2b2b5cb..e887226 100644 --- a/plugins/doable-code-context/.cursor-plugin/plugin.json +++ b/plugins/doable-code-context/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "doable-code-context", "displayName": "Doable Code Context", - "version": "0.2.5", + "version": "0.2.6", "description": "Connect private code to Doable through MCP, resolve grounded context requests, and start managed feature-testing workflows.", "author": { "name": "Doable AI" diff --git a/plugins/doable-code-context/skills/doable-connect/references/authentication.md b/plugins/doable-code-context/skills/doable-connect/references/authentication.md index eb0aa52..a78710b 100644 --- a/plugins/doable-code-context/skills/doable-connect/references/authentication.md +++ b/plugins/doable-code-context/skills/doable-connect/references/authentication.md @@ -14,7 +14,7 @@ Use this workflow only after a live `get_code_context_connection` preflight fail 2. Inspect the coding-agent host's MCP connection status without printing configured headers or environment values. Treat a missing/disabled `doable` server, an empty environment expansion, and `401` as different diagnostics with the same next goal: establish one valid user-scoped `doable` connection for the expected organization. 3. If the user already supplied the expected organization's API key in the current request, continue without asking for it again. Otherwise ask once for it and point them to that organization's Doable Settings. Prefer the host's masked credential input when it is available. Do not ask the user to run configuration commands themselves. Keep the request action-focused: “Doable is not connected to {organization}. Send its API key from Doable Settings; I will configure it and continue {round code or feature request}.” Do not narrate the diagnosis unless the user asks. 4. Configure or replace only the host's **user-scoped** `doable` MCP connection. Never write a credential into the repository, `.doable`, a project-scoped MCP file, shell history, a command-line argument, or assistant output. Do not print or repeat the key. The coding-agent host owns its credential storage. -5. Refresh the connection in the current conversation when the host exposes that operation. In Claude Code, the agent cannot invoke the interactive slash-command UI, so ask for exactly one action: “Open `/mcp` and reconnect `doable`; I will continue this request here.” Do not ask the user to restart Claude Code, open another session, rerun the skill, or paste the original request again. -6. Retry `get_code_context_connection` with the same preflight arguments. Continue the original request automatically only after it succeeds and, for a copied prompt, the returned organization matches the prompt. +5. Refresh the connection in the current conversation when the host exposes that operation. In Cursor, the user-scoped MCP configuration reloads asynchronously: wait for the host to refresh, then retry the exact preflight. Treat an immediate `401` as a potentially stale live transport, not proof that the newly stored key is invalid; allow one more refresh-and-retry cycle before asking for another key. In Claude Code, the agent cannot invoke the interactive slash-command UI, so ask for exactly one action: “Open `/mcp` and reconnect `doable`; I will continue this request here.” Do not ask the user to restart Claude Code, open another session, rerun the skill, or paste the original request again. +6. Retry `get_code_context_connection` with the same preflight arguments. Continue the original request automatically only after it succeeds and, for a copied prompt, the returned organization matches the prompt. Do not compare, print, or re-request a credential merely because the pre-refresh transport still returns `401`. If the refreshed connection still returns `401`, say that the supplied credential was rejected and ask for a current key from the expected organization's Settings. If authentication succeeds but the organization differs, state the expected and connected organization names and recover the expected organization's connection. If the exact Round then returns `404`, state that the Round is not available in the authenticated organization; do not call it an expired key. diff --git a/scripts/verify-release.mjs b/scripts/verify-release.mjs index c05469d..9754e4b 100644 --- a/scripts/verify-release.mjs +++ b/scripts/verify-release.mjs @@ -11,7 +11,7 @@ const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?: const plugins = [ { name: "doable-code-context", - version: "0.2.5", + version: "0.2.6", skillNames: ["doable-connect", "doable-answer-questions", "doable-test-feature"], network: "bundled-doable-mcp-config", }, @@ -220,6 +220,8 @@ for (const plugin of plugins) { "Do not ask the user to restart Claude Code", "Do not narrate the diagnosis unless the user asks", "paste the original request again", + "In Cursor, the user-scoped MCP configuration reloads asynchronously", + "Treat an immediate `401` as a potentially stale live transport", "Retry `get_code_context_connection` with the same preflight arguments", ], ],