docs(sdk-cli): add spec for dotcms agent setup - #37392
Conversation
Spec-Kit PR 1 of 2 for #37390 — spec only, no implementation. Specifies a `dotcms agent setup` command that collapses the four manual steps needed to connect an AI coding agent to dotCMS (find the admin panel, mint a token, hand-edit an IDE config, install skills) into one command across seven agent targets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
❌ Linked Issue Needs Team LabelThis PR is linked to issue #37390, but that issue has no How to fix this:Apply a This comment was automatically generated by the issue linking workflow |
|
Claude finished @fmontes's task in 1m 47s —— View job Spec review —
|
…semantics Addresses two gaps found reviewing the spec. Setup proved the token was valid but never that the MCP server actually starts, so a stale package cache or unsupported runtime would produce a green summary and a broken agent. Confirmation now runs by default (FR-024a-e, SC-002a): it launches the server as configured, confirms it reports its tools, and reports a non-start distinctly from a credential failure without rolling back written configs. Writing spans up to seven files and nothing said what happens when one fails after others succeeded. Setup now continues, reports per-target outcomes, and exits non-zero on any failure (FR-020a-d, SC-006a). Also: FR-013 annotated as a structural constraint rather than a testable requirement, FR-023a covers project scope outside version control, concurrent writes documented as a known limitation, and SC-001/SC-002 labelled design intent rather than automated gates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records four /speckit-clarify decisions. Folder is now the default scope, not the user account: one dotcms entry per config file, multiple instances via different folders. Because that makes the credential-into-a-repo path the default, FR-023 is strengthened so assume-yes takes the safe answer on the gitignore offer rather than skipping it. status and remove are cut from this release; only agent setup ships. User Story 5 withdrawn, FR-029/030/031 and SC-007/008 retired, and everything that leaned on those commands reworded. The agent sub-command group stays as the seam for adding them later. The written entry references the latest published server rather than pinning a version (FR-020e). The instance address plus one auth mode are the only required inputs; supply both and setup completes without prompting, terminal or not (FR-003i-l). Targets default to every detected editor and scope to the folder, so neither blocks a run. assume-yes and force govern confirmation prompts only and can never suppress a prompt for a missing required input. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No diagnostic mode ships — no verbose flag, no debug output, no log file. Recorded as a deliberate decision rather than an omission, with FR-032a requiring every failure message to be self-sufficient, since "re-run with more detail" is not available as a remedy. Terminology normalized to "token" for the thing minted, supplied, verified and written; a username and password are named as such rather than called "credentials". No behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The /speckit-plan ADR gate found that ADR-0019 (accepted) requires SDK packages to compare the instance's dotCMS version against their own and warn, fail-open, when the instance is older. dotcms ships from libs/sdk/, is published by the SDK release pipeline, and is date-lockstep versioned, so the requirement applies. FR-005a reuses the response already fetched for the reachability check, so it costs no additional request. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Minting happens before configurations are written, so a run that mints and then fails leaves a real 365-day token on the instance that was never displayed and never recorded. Re-running mints another, and nothing identifies or revokes them. Accepted rather than mitigated. The alternative that actually recovers the credential is printing it, which contradicts FR-022 -- a rule User Story 3 rates P1. Orphans expire within a year and the failure requires an already-broken environment. Recorded in Assumptions rather than left silent, so a reviewer sees the trade-off instead of rediscovering it later. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FR-007 gave three attempts when a username and password fail to mint, but said nothing about a supplied token that fails to verify. Running the CLI by hand showed why that gap matters: one mistyped paste ended the run. The two are the same user error and now share the retry. FR-007a limits it to rejections -- an unreachable instance or a TLS error is not retried, because retyping a credential cannot fix it. FR-007b keeps a non-interactive run failing at the first attempt, since a script has nowhere to retype. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…alive FR-005 only required that something answer. A proxy, CDN error page or unrelated app answering 200 passed the check, and setup would write a configuration pointing at it -- producing an agent that fails every call later with nothing to explain why. FR-005b requires confirming the response is a dotCMS configuration, and reporting a non-dotCMS host distinctly from an unreachable one. The two have different remedies, so collapsing them costs the developer the one piece of information that helps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng or missing FR-003b said the conflict error must name the conflicting "options". The conflict can come from environment variables, and reporting --authToken to someone who set DOTCMS_AUTH_TOKEN sends them hunting for a flag they never typed. Now: name the inputs actually used. FR-003c1 is new. Nothing said the skip options are independent, and the implementation read --skip-mcp as "skip everything downstream", so it silently installed no skills and printed no summary. The only permitted implication is FR-024b's: with nothing written there is no configuration for the connection check to prove. FR-016a is new. "Preserves everything else exactly" was read as data only, so the TOML writer re-serialized a parsed document and deleted the developer's comments. For a hand-maintained format that is data loss even though every value survives. Not changed, because the spec was already right and the code was not: FR-021 says "any directory setup CREATES" (the implementation re-chmodded pre-existing ones), FR-023 says "every file it PLACED A TOKEN INTO" (it named files that were only skipped), and FR-024b already covered the connection check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Spec-Kit PR 1 of 2 —
spec.mdonly, no implementation. Approve this and PR 2 branches off it; you're not blocked on this merging.Refs #37390
What this specifies
One command that replaces the four manual steps needed to point an AI coding agent at a dotCMS instance — find the admin panel, mint a token by hand, hand-edit whichever config file your editor reads, install the skills separately.
It asks for a URL, credentials, and which editors to wire up; mints a token and verifies it before touching any file; writes the dotCMS MCP server into each editor's own config by merging rather than overwriting; installs the skills; and launches the server to confirm it responds before calling itself done.
Give it a URL and one auth mode up front and it runs unprompted. Targets default to every detected editor, scope to the folder you ran it in.
Seven targets: Claude Code, Cursor, VS Code/Copilot, Codex, Antigravity, Devin, OpenCode.
62 functional requirements · 11 success criteria · 4 user stories · 9 recorded clarifications.
What to review for
Is this the right problem, scoped right, with measurable criteria? The calls worth arguing with:
agent setupalone.statusandremovewere specified, then cut — re-running setup replaces a stale entry, and removing one is a hand edit of a single named key.create-appstays where it is; the dotCLI port isn't started. Theagentsub-command group is the seam all of these fold into later. Right line?dotcmsentry per config file; a second instance means a second folder. This makes the credential-into-a-repo path the common one, so FR-023 compensates:--yestakes the safe answer on the.gitignoreoffer instead of skipping it. Enough?--user/--passwordmints a token;--authTokenuses one you have. Passing both is a usage error, not a silent precedence rule — silent preference hides a mistake in exactly the scripted runs these flags exist for.--yes/--forcecannot disable the check.Three risks the spec accepts on purpose
Each is recorded in Assumptions with its reasoning rather than left as a silent gap:
--helpwarning, and never persisting it.ADR gate
ADR-0019 (accepted) governs this package and produced two conflicts. The secrets ADRs were checked and rejected explicitly — they cover AWS Secrets Manager for Kubernetes, not a CLI writing to a developer's own disk.
@latest), against the ADR's pin-exact-versions guidance.@dotcms/mcp-serveris at0.1.1, is not date-lockstep, and has no release workflow anywhere in.github/— there is no CLI-matched version to pin to. Recorded in the plan's Complexity Tracking.Verified while specifying, worth a look
deploy-javascript-sdk/action.ymlpublishes generically, but its "already published" guard isnpm view "@dotcms/${dir}@${version}"— scope hardcoded, name from the directory. An unscopeddotcmspackage can never match it: the first publish succeeds, then any re-run tries to re-publish an existing version and fails the release step. Captured as FR-034.dotCMS/agent-toolkitis now public (verified, including an unauthenticated clone). That was the feature's one hard release gate; it's cleared.dotcmsnpm name replaces a dormant0.0.21library. Unpinned consumers break at first publish — confirm download volume before shipping.Open items carried into planning
None block approval; all are in Assumptions.
chmod 0600is a no-op on Windows, so FR-021 is POSIX-only and the summary must say when permissions couldn't be appliedNot in this PR
plan.md,tasks.md, and any code — PR 1 carriesspec.mdalone. Note that this repo gitignoresplan.md/research.md/quickstart.mdas process artifacts, so the design work lands in PR 2 asdata-model.mdandcontracts/.🤖 Generated with Claude Code