feat(cli-module-actions): improve CLI formatting, help output, and UX (#33517)

* fix(cli-module-actions): show schema flags in execute --help

When an action ID is provided with --help, fetch the action schema and
display action-specific flags. Falls back to generic help if auth fails.

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(cli-module-actions): show schema flags in execute --help and fix build errors (#33518)

* feat(cli-module-actions): improve CLI output formatting and UX

- Pretty grouped list output with colored headers and action titles
- Custom help rendering for execute --help with markdown descriptions
- Support complex schema types (object, array, union) as JSON flags
- Show server error details instead of generic status codes
- Accept multiple plugin IDs in sources add/remove

Signed-off-by: benjdlambert <ben@blam.sh>

* fix(cli-module-auth): preserve instance metadata on re-login

Signed-off-by: benjdlambert <ben@blam.sh>

* fix: address code review feedback

- Extract triplicated cli() config into showGenericHelp helper
- Strip ANSI escape sequences before rendering server markdown
- Configure marked-terminal extension once via lazy singleton
- Parallelize listGrouped HTTP requests with Promise.all
- Log actual error message in execute help catch block
- Fix marked version in declarations.d.ts comment
- Add tests for sourcesAdd/sourcesRemove batch operations
- Add test for execute JSON parse error path
- Add tests for login metadata preservation on re-auth

Signed-off-by: benjdlambert <ben@blam.sh>

* fix: use RegExp constructor to satisfy no-control-regex lint rule

Signed-off-by: benjdlambert <ben@blam.sh>

* fix: improve ANSI stripping, default info.usage, add renderMarkdown comment

- Extend stripAnsiEscapes to cover OSC, DCS, APC, PM sequences
- Default info.usage to avoid undefined in help output
- Document why marked.use() is called per invocation

Signed-off-by: benjdlambert <ben@blam.sh>

* fix: use strip-ansi, fresh Marked instance, add allOf support

- Replace hand-rolled ANSI stripping with strip-ansi package
- Use fresh Marked instance per call instead of mutating global singleton
- Add allOf to complex type detection alongside anyOf/oneOf
- Add happy-path test for valid JSON complex flag parsing
- Bump changeset to minor for new user-facing capabilities

Signed-off-by: benjdlambert <ben@blam.sh>

* refactor: collapse listGrouped into list on ActionsClient

Signed-off-by: benjdlambert <ben@blam.sh>

* refactor: clean up cli-module-actions structure

- Extract shared pluginSourcesSchema into lib/pluginSources.ts
- Merge schemaToFlags and getComplexKeys into single return value
- Move CleyeFlag-to-FlagInfo conversion into format.ts
- Extract parseArgs and showActionHelp from execute command body

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Ben Lambert
2026-04-09 13:53:44 +02:00
committed by GitHub
parent ee0c95d971
commit c705d44e4b
24 changed files with 1535 additions and 123 deletions
+144 -10
View File
@@ -2832,7 +2832,11 @@ __metadata:
"@backstage/cli": "workspace:^"
"@backstage/cli-node": "workspace:^"
"@backstage/errors": "workspace:^"
chalk: "npm:^4.0.0"
cleye: "npm:^2.3.0"
marked: "npm:^15.0.12"
marked-terminal: "npm:^7.3.0"
strip-ansi: "npm:^7.1.0"
zod: "npm:^3.25.76 || ^4.0.0"
bin:
cli-module-actions: bin/backstage-cli-module-actions
@@ -8389,6 +8393,13 @@ __metadata:
languageName: node
linkType: hard
"@colors/colors@npm:1.5.0":
version: 1.5.0
resolution: "@colors/colors@npm:1.5.0"
checksum: 10/9d226461c1e91e95f067be2bdc5e6f99cfe55a721f45afb44122e23e4b8602eeac4ff7325af6b5a369f36396ee1514d3809af3f57769066d80d83790d8e53339
languageName: node
linkType: hard
"@colors/colors@npm:1.6.0, @colors/colors@npm:^1.6.0":
version: 1.6.0
resolution: "@colors/colors@npm:1.6.0"
@@ -18043,10 +18054,10 @@ __metadata:
languageName: node
linkType: hard
"@sindresorhus/is@npm:^4.0.0":
version: 4.0.0
resolution: "@sindresorhus/is@npm:4.0.0"
checksum: 10/850804ccabb3e85b8c1395777a3b0e816bfcc308d4b7a65142bfd657f0753c31866ae5245f7a6d74d08191a4e63edab59c75b96bd19140d37b104efd683709d1
"@sindresorhus/is@npm:^4.0.0, @sindresorhus/is@npm:^4.6.0":
version: 4.6.0
resolution: "@sindresorhus/is@npm:4.6.0"
checksum: 10/e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0
languageName: node
linkType: hard
@@ -24538,7 +24549,7 @@ __metadata:
languageName: node
linkType: hard
"ansi-regex@npm:*, ansi-regex@npm:^6.0.1, ansi-regex@npm:^6.2.2":
"ansi-regex@npm:*, ansi-regex@npm:^6.0.1, ansi-regex@npm:^6.1.0, ansi-regex@npm:^6.2.2":
version: 6.2.2
resolution: "ansi-regex@npm:6.2.2"
checksum: 10/9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f
@@ -26476,6 +26487,13 @@ __metadata:
languageName: node
linkType: hard
"chalk@npm:^5.4.1":
version: 5.6.2
resolution: "chalk@npm:5.6.2"
checksum: 10/1b2f48f6fba1370670d5610f9cd54c391d6ede28f4b7062dd38244ea5768777af72e5be6b74fb6c6d54cb84c4a2dff3f3afa9b7cb5948f7f022cfd3d087989e0
languageName: node
linkType: hard
"char-regex@npm:^1.0.2":
version: 1.0.2
resolution: "char-regex@npm:1.0.2"
@@ -26743,6 +26761,22 @@ __metadata:
languageName: node
linkType: hard
"cli-highlight@npm:^2.1.11":
version: 2.1.11
resolution: "cli-highlight@npm:2.1.11"
dependencies:
chalk: "npm:^4.0.0"
highlight.js: "npm:^10.7.1"
mz: "npm:^2.4.0"
parse5: "npm:^5.1.1"
parse5-htmlparser2-tree-adapter: "npm:^6.0.0"
yargs: "npm:^16.0.0"
bin:
highlight: bin/highlight
checksum: 10/05d2b5beb8a4d3259f693517d013bf53d04ad20f470b77c3d02e051963092fae388388e3127f67d3679884a0c32cb855bf590292017c5e68c0f8d86f4b8e146e
languageName: node
linkType: hard
"cli-spinners@npm:^2.5.0, cli-spinners@npm:^2.9.2":
version: 2.9.2
resolution: "cli-spinners@npm:2.9.2"
@@ -26762,6 +26796,19 @@ __metadata:
languageName: node
linkType: hard
"cli-table3@npm:^0.6.5":
version: 0.6.5
resolution: "cli-table3@npm:0.6.5"
dependencies:
"@colors/colors": "npm:1.5.0"
string-width: "npm:^4.2.0"
dependenciesMeta:
"@colors/colors":
optional: true
checksum: 10/8dca71256f6f1367bab84c33add3f957367c7c43750a9828a4212ebd31b8df76bd7419d386e3391ac7419698a8540c25f1a474584028f35b170841cde2e055c5
languageName: node
linkType: hard
"cli-table@npm:^0.3.1, cli-table@npm:^0.3.11":
version: 0.3.11
resolution: "cli-table@npm:0.3.11"
@@ -29492,6 +29539,13 @@ __metadata:
languageName: node
linkType: hard
"emojilib@npm:^2.4.0":
version: 2.4.0
resolution: "emojilib@npm:2.4.0"
checksum: 10/bef767eca49acaa881388d91bee6936ea57ae367d603d5227ff0a9da3e2d1e774a61c447e5f2f4901797d023c4b5239bc208285b6172a880d3655024a0f44980
languageName: node
linkType: hard
"emojis-list@npm:^3.0.0":
version: 3.0.0
resolution: "emojis-list@npm:3.0.0"
@@ -33319,7 +33373,7 @@ __metadata:
languageName: node
linkType: hard
"highlight.js@npm:^10.1.0, highlight.js@npm:^10.4.1, highlight.js@npm:^10.7.2, highlight.js@npm:~10.7.0":
"highlight.js@npm:^10.1.0, highlight.js@npm:^10.4.1, highlight.js@npm:^10.7.1, highlight.js@npm:^10.7.2, highlight.js@npm:~10.7.0":
version: 10.7.3
resolution: "highlight.js@npm:10.7.3"
checksum: 10/db8d10a541936b058e221dbde77869664b2b45bca75d660aa98065be2cd29f3924755fbc7348213f17fd931aefb6e6597448ba6fe82afba6d8313747a91983ee
@@ -37809,6 +37863,32 @@ __metadata:
languageName: node
linkType: hard
"marked-terminal@npm:^7.3.0":
version: 7.3.0
resolution: "marked-terminal@npm:7.3.0"
dependencies:
ansi-escapes: "npm:^7.0.0"
ansi-regex: "npm:^6.1.0"
chalk: "npm:^5.4.1"
cli-highlight: "npm:^2.1.11"
cli-table3: "npm:^0.6.5"
node-emoji: "npm:^2.2.0"
supports-hyperlinks: "npm:^3.1.0"
peerDependencies:
marked: ">=1 <16"
checksum: 10/1dfdfe752a4ebe6aec8de4a51180612a5f29982026b104a86215efb46b82b2a1942531a6bb840163c8d827e3eadc5cf93272e6eb29ec549f72b73b8b2eb97cfe
languageName: node
linkType: hard
"marked@npm:^15.0.12":
version: 15.0.12
resolution: "marked@npm:15.0.12"
bin:
marked: bin/marked.js
checksum: 10/deeb619405c0c46af00c99b18b3365450abeb309104b24e3658f46142344f6b7c4117608c3b5834084d8738e92f81240c19f596e6ee369260f96e52b3457eaee
languageName: node
linkType: hard
"marked@npm:^4.0.14":
version: 4.3.0
resolution: "marked@npm:4.3.0"
@@ -39400,7 +39480,7 @@ __metadata:
languageName: node
linkType: hard
"mz@npm:^2.7.0":
"mz@npm:^2.4.0, mz@npm:^2.7.0":
version: 2.7.0
resolution: "mz@npm:2.7.0"
dependencies:
@@ -39676,6 +39756,18 @@ __metadata:
languageName: node
linkType: hard
"node-emoji@npm:^2.2.0":
version: 2.2.0
resolution: "node-emoji@npm:2.2.0"
dependencies:
"@sindresorhus/is": "npm:^4.6.0"
char-regex: "npm:^1.0.2"
emojilib: "npm:^2.4.0"
skin-tone: "npm:^2.0.0"
checksum: 10/2548668f5cc9f781c94dc39971a630b2887111e0970c29fc523e924819d1b39b53a2694a4d1046861adf538c4462d06ee0269c48717ccad30336a918d9a911d5
languageName: node
linkType: hard
"node-fetch-commonjs@npm:^3.3.2":
version: 3.3.2
resolution: "node-fetch-commonjs@npm:3.3.2"
@@ -41206,7 +41298,23 @@ __metadata:
languageName: node
linkType: hard
"parse5@npm:^6.0.0":
"parse5-htmlparser2-tree-adapter@npm:^6.0.0":
version: 6.0.1
resolution: "parse5-htmlparser2-tree-adapter@npm:6.0.1"
dependencies:
parse5: "npm:^6.0.1"
checksum: 10/3400a2cd1ad450b2fe148544154f86ea53d3ed6b6eab56c78bb43b9629d3dfe9f580dffd75bbf32be134ffef645b68081fc764bf75c210f236ab9c5c8c38c252
languageName: node
linkType: hard
"parse5@npm:^5.1.1":
version: 5.1.1
resolution: "parse5@npm:5.1.1"
checksum: 10/5b509744cfe81488a33be05578df490c460690e64519fa67f0a0acb9c1bca05914e8acad17a977e2cf5964a000e43959b40024f0c243dd6595dd0cca8a32f71b
languageName: node
linkType: hard
"parse5@npm:^6.0.0, parse5@npm:^6.0.1":
version: 6.0.1
resolution: "parse5@npm:6.0.1"
checksum: 10/dfb110581f62bd1425725a7c784ae022a24669bd0efc24b58c71fc731c4d868193e2ebd85b74cde2dbb965e4dcf07059b1e651adbec1b3b5267531bd132fdb75
@@ -46147,6 +46255,15 @@ __metadata:
languageName: node
linkType: hard
"skin-tone@npm:^2.0.0":
version: 2.0.0
resolution: "skin-tone@npm:2.0.0"
dependencies:
unicode-emoji-modifier-base: "npm:^1.0.0"
checksum: 10/19de157586b8019cacc55eb25d9d640f00fc02415761f3e41a4527142970fd4e7f6af0333bc90e879858766c20a976107bb386ffd4c812289c01d51f2c8d182c
languageName: node
linkType: hard
"slash@npm:^3.0.0":
version: 3.0.0
resolution: "slash@npm:3.0.0"
@@ -47384,7 +47501,7 @@ __metadata:
languageName: node
linkType: hard
"supports-color@npm:^7, supports-color@npm:^7.1.0":
"supports-color@npm:^7, supports-color@npm:^7.0.0, supports-color@npm:^7.1.0":
version: 7.2.0
resolution: "supports-color@npm:7.2.0"
dependencies:
@@ -47393,6 +47510,16 @@ __metadata:
languageName: node
linkType: hard
"supports-hyperlinks@npm:^3.1.0":
version: 3.2.0
resolution: "supports-hyperlinks@npm:3.2.0"
dependencies:
has-flag: "npm:^4.0.0"
supports-color: "npm:^7.0.0"
checksum: 10/f7924de6049fc30bc808f98d3561318c1a4e3d55d786f9fede5e23dc5a7b0f625485bd1143135b496d521ccd0110463f2c077eb71a4ce0cf783b8b31f7909242
languageName: node
linkType: hard
"supports-preserve-symlinks-flag@npm:^1.0.0":
version: 1.0.0
resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
@@ -49018,6 +49145,13 @@ __metadata:
languageName: node
linkType: hard
"unicode-emoji-modifier-base@npm:^1.0.0":
version: 1.0.0
resolution: "unicode-emoji-modifier-base@npm:1.0.0"
checksum: 10/6e1521d35fa69493207eb8b41f8edb95985d8b3faf07c01d820a1830b5e8403e20002563e2f84683e8e962a49beccae789f0879356bf92a4ec7a4dd8e2d16fdb
languageName: node
linkType: hard
"unified@npm:^10.0.0":
version: 10.1.0
resolution: "unified@npm:10.1.0"
@@ -50725,7 +50859,7 @@ __metadata:
languageName: node
linkType: hard
"yargs@npm:^16.2.0":
"yargs@npm:^16.0.0, yargs@npm:^16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
dependencies: