| name | dify-cli-docs |
| description | Rule pack for the Dify CLI (`difyctl`) doc set — en/cli/. Covers reader segments, the writing rules, content ownership, and codebase-verification rules. Loaded by dify-docs-write; not an entry point.
|
Dify CLI Documentation
Not an entry point — run under dify-docs-write; this pack's rules implement its stages for en/cli/ pages.
Procedures by stage
- S1: Confirm edition scope: CE-first; badge and defer Cloud-only content (see Editions below).
- S2/S7: Verify every behavior claim against
langgenius/dify cli/ on origin/main, read at the pinned SHA per writing-guides/index.md "Syncing the Dify codebase safely"; record that SHA in your report.
- S5: Mirror an existing page of the same type (see Before starting); draft per the Command Reference structure; apply the Writing rules and Content ownership (state each fact once, link elsewhere).
- S7 verifiers: the numbered checks under Verification below, after the spine's check chain.
Critical (source of truth): cli/ on origin/main only. Never feat/cli or cli/README.md; both drift from shipped reality.
Before starting
For page structure, mirror an existing page of the same type (command reference → en/cli/reference/apps.mdx; task page → en/cli/common-tasks.mdx). For the IA, see docs.json.
Reader segments
en/cli/ is CE + Cloud only (EE is separate), and launches CE-first (see Editions below).
- CE and Cloud users (default): have a Dify account, sign in with the browser device flow. Developers, DevOps, technical PMs; assume kubectl/gh familiarity. Explain Dify concepts by linking the main docs, never shell basics. One audience: don't split hairs over account type or token prefix in prose.
- Integrate Your Agents (a task section, not a persona): engineers wiring their own agent to call Dify apps as tools. Write for the human builder; engineering-deep. Disambiguate from building agents inside Dify Studio.
- SSO (
dfoe_) is EE-only; its docs live in the EE repo, not here.
Editions: CE-first and the Cloud badge
The CLI launches CE-first: the shipped docs are CE-only, with Cloud content added when Cloud supports the CLI. EE is a separate doc set (never add EE content here).
- CE = one workspace. No workspace switching, no
--workspace / -A multi-workspace flags, no "another/every workspace" framing; difyctl runs against your single workspace.
- Cloud-only content (workspace switching and membership, and anything that needs more than one workspace) gets a
<Badge color="blue">Cloud</Badge> on its heading or list item. Mark with the badge; don't write a "Cloud only" sentence. When a CE release requires removing Cloud-only sections, list the exact sections and STOP — do not remove until the user approves; then remove them in a dedicated commit so they can be restored from git history when Cloud ships.
- Host examples are self-hosted: use
dify.example.com, never cloud.dify.ai; the server edition shows self_hosted. (auth login's real default is still cloud.dify.ai, so steer the reader to enter their host rather than stating the default.)
- A
<Badge> inside a heading changes the heading's anchor: the badge text joins the slug (## Switch Your Workspace <Badge color="blue">Cloud</Badge> → #switch-your-workspace-cloud). Link to the real anchor; python3 tools/check-links.py --internal validates this.
Writing rules
House overrides on top of the writing-guides.
Non-negotiable (correctness and security):
- Never document
DIFY_TOKEN or any non-interactive token as working auth — the only path is the browser device flow.
- Never
<your-app-id> in runnable code (it fails validation; see Placeholders).
- No
--workspace / -A or multi-workspace framing in CE (one workspace; see Editions).
The non-obvious style rules:
- host vs server. "host" = the connection target (
--host, hosts.yml, use host, "Active host", "known hosts"). "server" = the backend as actor ("the server returns", "Network or server error") or its version ("client and server versions").
- No "envelope" jargon. Describe JSON plainly ("a
data array with the paging fields page/limit/total/has_more"); error JSON is "a structured JSON object".
- App types: Chatbot, Chatflow, Agent, Workflow, Text Generator in prose; API mode names (
chat, advanced-chat, ...) only inside literal output blocks.
- Configurable values: when a value is settable by flag, env var, and/or config, name the methods and make their precedence unambiguous, in prose or a numbered list, whichever is clearer (a list is often clearest for a multi-step chain). Clarity is the test, not a fixed phrase: avoid the chained "A overrides B, which overrides C" (the referent of "which" is unclear) and a bare "or" (hides the order). "Override" is fine with one clear referent ("the
--limit flag overrides DIFY_LIMIT") or a named target ("overrides the resolution chain", linking the owner).
- Openers stay general over volatile lists (don't enumerate config keys in an opener); the table carries the specifics.
- Cross-references: make the command the actor ("Run
auth devices list to see your sessions"), not "to do X, see [section]"; for an owned fact, link with a short payoff instead of re-explaining.
- Placeholders: app/workspace IDs are UUID-shaped (non-UUID fails validation); the reader's own identity is
<your-*>; received values stay concrete.
- Backtick the typeable token, not the category word ("list commands such as
get app"; never list).
- No version numbers in prose (the
version page shows real output); no See Also; shipped reality only, except a fix the user confirms is in flight may be documented as expected behavior, verified before publish.
- Task-oriented openers (lead with when/why you run it), front-load the key limitation, show real terminal output.
Style nits: ~3-4 line paragraphs, few semicolons, em dashes by judgment.
Command Reference structure
One page per resource; each command an H2, task-phrased (never the literal command). Per-command order:
- Synopsis (CLI notation
<required> [optional] ...repeatable) + a one-line description.
### Arguments — required wherever a positional arg exists, parallel to ### Flags; note an arg's source ("<app-id> from get app").
### Flags — Flag / Type / Default / Description; a recurring flag gets its full description in every command that takes it.
### Examples — a verb-led caption + the command block. No result samples here.
### Output — what stdout and stderr get in each mode, success included. -o commands get a | Format | What stdout gets | table + captioned samples (exempt: export, --json-only). Describe failures, don't quote error strings.
### Exit Codes — link to Output Formats and Exit Codes for the full table.
Multi-command pages open with a one-line lead-in + a mini-index of anchor links; one-command pages get a plain sentence. Put a page-level "how it works" / owned section at the END, after the commands, but when a section is tightly coupled to one command (pause/resume belongs with run/resume), keep it beside that command rather than exiled to the bottom.
Content ownership
Write each cross-cutting fact ONCE on its owner; link the anchor everywhere else. Never re-teach Dify platform concepts (one sentence + a link to the main docs).
| Content | Owner |
|---|
| Run dispatch across app types | Apps, "Run an App" |
HITL pause/resume (exit 0 + status:"paused") | Apps, "When a Workflow Pauses" |
| Workspace resolution chain | Workspaces |
-o schemas, exit codes, stdout/stderr discipline | Output Formats and Exit Codes |
| Global flag inventory | Global Flags |
| Help forms and topics | help |
Agent discovery (help -o json, agentGuide) | The Agent Contract |
| Sign-in and token storage | Authenticate |
| Env-var inventory | Environment Variables |
| Compat probe and range | version |
Verification
Source of truth is the code (per the Critical note above), not the docs or in-CLI help (both drift). Where to look: best source for exact strings and exit codes is the e2e suite cli/test/e2e/suites/**; flags/args → cli/src/commands/<verb>/<resource>/index.ts (verb-only commands: cli/src/commands/<verb>/index.ts); error codes → cli/src/errors/codes.ts; env vars → cli/src/env/registry.ts. Can't verify a claim? Skip it, soften it, or flag {/* VERIFY: ... */}.
For project context (known bugs, decisions, what's shipped vs planned), ask the user.
S7 verifiers — run after the spine's check chain:
- Run
python3 tools/check-links.py --internal; it must print Broken links: 0 and Broken anchors: 0.
- Confirm no owned fact is re-explained (check each changed page against the Content ownership table).