Repository navigation
feat(cli): default to JSON output under AI coding agents - #2589
Conversation
The Tailor CLI records the agent politty detects at startup and uses it as the default of `--json`, so commands, argument errors, and refused prompts all follow it. An explicit `--json` value or TAILOR_JSON_OUTPUT still wins, and CLI plugins never record an agent, so they keep their output. `--help` starts with guidance for the agent.
Keep skills/tailor/SKILL.md identical to the bundled skill, and turn agent detection off by default in the CLI subprocess tests so a PATH or host marker cannot flip them to JSON.
🦋 Changeset detectedLatest commit: f81dc08 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
@tailor-platform/create-sdk
@tailor-platform/eslint-plugin-sdk
@tailor-platform/sdk
@tailor-platform/sdk-plugin-frontend
@tailor-platform/sdk-plugin-seed
@tailor-platform/sdk-plugin-setup
@tailor-platform/sdk-plugin-tailordb-erd
commit: |
There was a problem hiding this comment.
📖 Docs Quality & Consistency Check
✅ Recommended Actions
None — docs are consistent with the implementation and contain no user-facing internal-detail leaks.
⚠️ Consistency Issues
No consistency issues found.
📝 Reader-Perspective Issues
No reader-perspective issues found.
🔍 Details
This PR adds AI coding agent detection to the CLI, defaulting to JSON output when an agent is detected. The following areas were checked for consistency and reader-perspective issues:
Areas Checked:
-
CLI Reference Documentation (
packages/sdk/docs/cli-reference.mdandcli-reference.template.md)- Lines 53-61: Documents agent detection behavior, JSON output defaults, opt-out mechanisms (
--json=false,TAILOR_JSON_OUTPUT=false,POLITTY_NO_AGENT=1), and CLI plugin behavior - Lines 120-122: Documents that GitHub Actions annotations are suppressed under JSON mode, including when triggered by agent detection
- Verified against implementation in
packages/sdk/src/cli/main.ts(setup hook callingsetJsonDefaultAgent(agent?.id)) andpackages/sdk/src/cli/shared/args.ts(JSON default logic) - Result: Consistent ✓
- Lines 53-61: Documents agent detection behavior, JSON output defaults, opt-out mechanisms (
-
Agent Help Message (
packages/sdk/src/cli/main.tslines 62-67)- agentHelp constant matches the PR description and is correctly passed to politty's
runMainvia theagentHelpoption - Message correctly explains JSON output default, opt-out options, CLI plugin behavior, and references the CLI reference doc
- Result: Consistent ✓
- agentHelp constant matches the PR description and is correctly passed to politty's
-
Agent Skill Documentation (
packages/sdk/agent-skills/tailor/SKILL.mdandskills/tailor/SKILL.md)- Lines 29-32: Updated to reflect that the CLI defaults to JSON when it detects an AI coding agent
- Provides fallback guidance for undetected agents or CLI plugin commands
- Result: Consistent ✓
-
Implementation Behavior
packages/sdk/src/cli/shared/args.ts:requestedJsonModeSource()returns"agent"when agent is detected (line 268)createCommonArgs()defaults--jsontotruewhenjsonDefaultAgent() !== undefined(line 450)- JSDoc at line 317 correctly notes that only the host CLI records an agent, not plugins
packages/sdk/src/cli/shared/logger.ts:- New
JsonModeSourcetype includes"agent"(line 23) jsonModeRemedy()provides appropriate opt-out guidance based on source (lines 32-50)setJsonDefaultAgent()andjsonDefaultAgent()functions manage agent state (lines 551-562)
- New
- Tests in
packages/sdk/src/cli/main.test.ts(lines 154-185) verify:- JSON output by default with detected agent
--json=falseandTAILOR_JSON_OUTPUT=falseoverride the defaultPOLITTY_NO_AGENT=1turns detection off- Agent help appears in
--helpoutput only when agent is detected
- Result: Consistent ✓
-
Reader-Perspective Review
- All user-facing documentation (
packages/sdk/docs/cli-reference.mdand agent skills) describes the feature from the user's perspective - No SDK/Platform internal implementation details leaked (e.g., no mention of internal classes, parsers, or transport mechanisms)
POLITTY_NO_AGENTis appropriately documented as a user-facing control variable- The documentation focuses on user-observable behavior (what happens, how to control it) rather than implementation mechanics
- Result: No issues ✓
- All user-facing documentation (
Verification Summary:
- ✅ Documentation accurately describes agent detection behavior
- ✅ JSON output default is correctly documented for both host CLI and plugins
- ✅ Opt-out mechanisms (
--json=false,TAILOR_JSON_OUTPUT=false,POLITTY_NO_AGENT=1) are clearly documented - ✅
--env-filelimitation is documented (values loaded via--env-filedon't affect agent detection) - ✅ Agent help message implementation matches documentation
- ✅ All changes maintain appropriate user-facing perspective without exposing internals
Re-run this check by adding the
docs-checklabel to the PR.
Summary
When an AI coding agent such as Claude Code, Codex, Cursor, or Gemini CLI runs
tailor, commands default to JSON output and--helpstarts with guidance for the agent, even without the agent skill installed.Output under an agent
tailor workspace listtailor workspace list --json=falseTAILOR_JSON_OUTPUT=false tailor workspace listPOLITTY_NO_AGENT=1 tailor workspace listtailor tailordb erd export(CLI plugin)--jsonorTAILOR_JSON_OUTPUT=trueArgument errors become JSON error envelopes, and a refused prompt names the detected agent and how to opt out. Without a detected agent, nothing changes.
Help preamble
Notes
tailor workspace list | grep) now get JSON; setTAILOR_JSON_OUTPUT=falsefor them.detectAgent()(the vercel/detect-agent spec). Some of its markers can be present outside an agent, such asCOPILOT_GITHUB_TOKENexported for a whole CI job,REPL_IDin Replit, orGOOSE_PROVIDERin a shell profile; those sessions also get JSON and lose prompts until they opt out.--helpand--help-jsonstill show--jsonwith defaultfalse, because politty reads defaults before it detects the agent; the preamble states the actual default.runMain'ssetuphook instead of adding ajsonByAgentoption tocreateCommonArgs; plugins never record one, so they keep their output without a new public option.