Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,37 @@
`client.ts`, and command-level error presentation in `intent-errors.ts`.
- Add or update the co-located `*.test.ts` file when changing command behavior.

## CLI UX Design Conventions

- **Entity references**: Commands that target a single entity must accept a
positional argument in `[kind:][namespace/]name` format (parsed by

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] correctness

The 'Entity references' convention claims entity refs are 'parsed by parseEntityRef / resolveEntityRef in kv.ts', but resolveEntityRef is never imported or called by any command file. All commands (api.ts, docs.ts, template.ts, catalog.ts) resolve entity refs via resolveEntityWithAmbiguityCheck from helpers.ts, which adds catalog-based ambiguity detection. A developer following this convention as written would call resolveEntityRef directly, bypassing ambiguity detection and producing inferior UX.

Suggested fix: Replace 'parsed by parseEntityRef / resolveEntityRef in kv.ts' with 'resolved via resolveEntityWithAmbiguityCheck from helpers.ts' (which internally calls parseEntityRef and adds catalog-based ambiguity detection).

`parseEntityRef` in `kv.ts`, resolved via `resolveEntityWithAmbiguityCheck`
in `helpers.ts` which adds catalog-based ambiguity detection). Do not
introduce per-command flags like `--entity-ref`, `--template-ref`, or
`--name`/`--kind`/`--namespace` as the primary entity input. Optional
`--kind` and `--namespace` flags may be offered to disambiguate short
names, but the positional ref is the canonical interface.
- **Filter and input flags**: Use repeatable `--flag key=value` syntax
(accumulated with `collect` and parsed by `resolveJsonInput` in `kv.ts`)
instead of JSON string arguments. Example:
`--filter kind=Component --filter spec.type=service`, not
`--filters '{"kind":"Component"}'`.
- **Plugin dependencies**: Commands that depend on optional Backstage plugins
(e.g., `techdocs-mcp-extras`, `search-backend-module-techdocs`) must detect
when the plugin is not configured and exit with a clear error message
suggesting how to enable it. Do not surface raw HTTP 400/500 responses.
- **Exit codes**: Commands must exit with a non-zero code when the requested
entity is not found or the operation fails. Use `handleCommandError` from
`intent-errors.ts` (which calls `process.exit(1)`) for all error paths.
Informational "not found" messages must not exit 0.
- **Error presentation**: Use `intent-errors.ts` to extract human-readable
reasons from Backstage error responses. Do not expose raw JSON schema
validation output or full stack traces to the user. The `formatError`
helper renders structured `{error, reason, suggestion}` objects in both
human and JSON modes.
- **Help text**: Passthrough commands must surface the underlying tool's
flags in `--help` output, not just the wrapper's flags.

## Architecture

- Intent-based commands invoke the bundled `@backstage/cli` through
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ rhdh-cli catalog list --kind Component --filter spec.lifecycle=production
rhdh-cli search "deployment guide" --types '["techdocs"]'

# Get API specification
rhdh-cli api get-spec --name my-api
rhdh-cli api get-spec my-api

# Execute a template
rhdh-cli template execute \
--template-ref template:default/nodejs-service \
template:default/nodejs-service \
--value name=my-app \
--value owner=team-platform
```
Expand Down
10 changes: 5 additions & 5 deletions docs/Intent-Based-CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ rhdh-cli catalog list \
rhdh-cli api list --type openapi --output json

# 2. Get the OpenAPI spec
rhdh-cli api get-spec --name my-api --output json
rhdh-cli api get-spec my-api --output json
```

### Workflow 3: Search Documentation and Retrieve Content
Expand All @@ -886,7 +886,7 @@ rhdh-cli api get-spec --name my-api --output json
rhdh-cli docs search "deployment" --output json

# 2. Get specific doc page (RHDH only)
rhdh-cli docs get --entity-ref component:default/my-service --page-path deployment
rhdh-cli docs get component:default/my-service --page-path deployment
```

### Workflow 4: Validate and Register New Entity
Expand All @@ -908,7 +908,7 @@ rhdh-cli template list

# 2. Execute template
rhdh-cli template execute \
--template-ref template:default/nodejs-microservice \
template:default/nodejs-microservice \
--value name=payment-service \
--value description="Payment processing service" \
--value owner=team-payments \
Expand Down Expand Up @@ -993,11 +993,11 @@ rhdh-cli catalog list \
--output json | jq '.entities[].metadata.name'

# 4. Get API spec
rhdh-cli api get-spec --name my-api --output json | jq '.definition'
rhdh-cli api get-spec my-api --output json | jq '.definition'

# 5. Execute template
rhdh-cli template execute \
--template-ref template:default/service \
template:default/service \
--value name=new-service \
--value owner=team-a \
--output json
Expand Down
Loading