Skip to content

Commit e9be7ee

Browse files
patrikbraborecclaudeTC-MO
authored
feat: improve --help output for AI agents and humans (#1080)
## Summary - Enhances `--help` output across all CLI commands with structured metadata (descriptions, examples, flags, environment variables) that is useful for both human users and AI agents - Adds `interactiveNote`, `docsUrl`, `examples`, and `aiNote` static properties to commands for richer help text - Refactors the help rendering system (`_BaseCommandRenderer`, `CommandHelp`, `CommandWithSubcommands`) to support the new structured output format - Renders example descriptions as shell-style `#` comments (matches the `gh` CLI convention) in both per-command EXAMPLES and the main help menu, so each example is a self-contained copy-paste block - Updates the main-help `apify create` example to its interactive form with a `#`-commented description, instead of the misleading `apify create my-actor` invocation - Fixes lint and format issues (object destructuring, line length) ## Test plan - [x] `yarn lint` passes - [x] `yarn format` passes (only untracked `.claude/settings.local.json` fails, not part of the project) - [x] `yarn build` succeeds - [x] Verified `apify <cmd> --help` renders example descriptions as `# ` comments - [x] Verified `apify help` main menu shows the commented `apify create` example Closes #1060 ## Help command before <img width="897" height="653" alt="image" src="https://github.com/user-attachments/assets/b231dfc3-fd85-4b5a-bc82-aa5dfa75b4a5" /> ## Help command in this implementation <img width="897" height="1035" alt="image" src="https://github.com/user-attachments/assets/2b84f3c3-a9e2-4221-805a-08663d300bc9" /> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Michał Olender <92638966+TC-MO@users.noreply.github.com>
1 parent f8f91f7 commit e9be7ee

79 files changed

Lines changed: 1505 additions & 134 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/commands/actor/_index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ import { ActorSetValueCommand } from './set-value.js';
1111
export class ActorIndexCommand extends ApifyCommand<typeof ActorIndexCommand> {
1212
static override name = 'actor' as const;
1313

14-
static override description = 'Manages runtime data operations inside of a running Actor.';
14+
static override description =
15+
`Runtime data operations intended to be called from inside a running Actor: read input, push data, get/set records in the default key-value store, charge pay-per-event, generate schema types.\n\n` +
16+
`For platform-level management (deploy, list, call Actors), see 'apify actors' (plural).`;
17+
18+
static override group = 'Apify Console';
19+
20+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#apify-actor';
1521

1622
static override subcommands = [
1723
//

src/commands/actor/calculate-memory.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ export class ActorCalculateMemoryCommand extends ApifyCommand<typeof ActorCalcul
3131
static override description =
3232
`Calculates the Actor’s dynamic memory usage based on a memory expression from actor.json, input data, and run options.`;
3333

34+
static override group = 'Actor Runtime';
35+
36+
static override examples = [
37+
{
38+
description: 'Calculate memory using the expression and input defaults from actor.json.',
39+
command: 'actor calculate-memory',
40+
},
41+
{
42+
description: 'Override the memory expression and input file.',
43+
command: 'actor calculate-memory --defaultMemoryMbytes "input.length * 128" --input ./my-input.json',
44+
},
45+
];
46+
47+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-calculate-memory';
48+
3449
/**
3550
* Additional run options exist (e.g., memoryMbytes, disksMbytes, etc.),
3651
* but we intentionally omit them here. These options are rarely needed and

src/commands/actor/charge.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,46 @@ import { getLoggedClient } from '../../lib/utils.js';
1919
export class ActorChargeCommand extends ApifyCommand<typeof ActorChargeCommand> {
2020
static override name = 'charge' as const;
2121

22-
static override description = 'Charge for a specific event in the pay-per-event Actor run.';
22+
static override description = 'Charge for a specific event in a pay-per-event Actor run.';
23+
24+
static override group = 'Actor Runtime';
25+
26+
static override examples = [
27+
{
28+
description: 'Charge one event of the given type.',
29+
command: 'actor charge result-item',
30+
},
31+
{
32+
description: 'Charge 5 events with an idempotency key.',
33+
command: 'actor charge result-item --count 5 --idempotency-key req-123',
34+
},
35+
{
36+
description: 'Test locally without actually charging.',
37+
command: 'actor charge result-item --test-pay-per-event',
38+
},
39+
];
40+
41+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-charge';
2342

2443
static override args = {
2544
eventName: Args.string({
26-
description: 'Name of the event to charge for',
45+
description: 'Name of the event to charge for.',
2746
required: true,
2847
}),
2948
};
3049

3150
static override flags = {
3251
'count': Flags.integer({
33-
description: 'Number of events to charge',
52+
description: 'Number of events to charge.',
3453
required: false,
3554
default: 1,
3655
}),
3756
'idempotency-key': Flags.string({
38-
description: 'Idempotency key for the charge request',
57+
description: 'Idempotency key for the charge request.',
3958
required: false,
4059
}),
4160
'test-pay-per-event': Flags.boolean({
42-
description: 'Test pay-per-event charging without actually charging',
61+
description: 'Test pay-per-event charging without actually charging.',
4362
required: false,
4463
default: false,
4564
}),

src/commands/actor/generate-schema-types.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,25 @@ Reads the input schema from one of these locations (in priority order):
5656
5757
Optionally specify custom schema path to use.`;
5858

59+
static override group = 'Actor Runtime';
60+
61+
static override examples = [
62+
{
63+
description: 'Generate TypeScript types from the input schema into the default output directory.',
64+
command: 'actor generate-schema-types',
65+
},
66+
{
67+
description: 'Generate types from a custom schema path.',
68+
command: 'actor generate-schema-types ./schemas/my-input.json',
69+
},
70+
{
71+
description: 'Mark all generated properties as optional.',
72+
command: 'actor generate-schema-types --all-optional',
73+
},
74+
];
75+
76+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-generate-schema-types';
77+
5978
static override flags = {
6079
output: Flags.string({
6180
char: 'o',

src/commands/actor/get-input.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ export class ActorGetInputCommand extends ApifyCommand<typeof ActorGetInputComma
77
static override description =
88
'Gets the Actor input value from the default key-value store associated with the Actor run.';
99

10+
static override group = 'Actor Runtime';
11+
12+
static override examples = [
13+
{
14+
description: 'Print the current Actor input to stdout.',
15+
command: 'actor get-input',
16+
},
17+
];
18+
19+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-get-input';
20+
1021
async run() {
1122
await outputInputFromDefaultStore();
1223
}

src/commands/actor/get-public-url.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,21 @@ export class ActorGetPublicUrlCommand extends ApifyCommand<typeof ActorGetPublic
1313

1414
static override description = 'Get an HTTP URL that allows public access to a key-value store item.';
1515

16+
static override group = 'Actor Runtime';
17+
18+
static override examples = [
19+
{
20+
description: 'Get a public URL for the record stored under the given key.',
21+
command: 'actor get-public-url OUTPUT',
22+
},
23+
];
24+
25+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-get-public-url';
26+
1627
static override args = {
1728
key: Args.string({
1829
required: true,
19-
description: 'Key of the record in key-value store',
30+
description: 'Key of the record in the key-value store.',
2031
}),
2132
};
2233

src/commands/actor/get-value.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,21 @@ export class ActorGetValueCommand extends ApifyCommand<typeof ActorGetValueComma
77

88
static override description = 'Gets a value from the default key-value store associated with the Actor run.';
99

10+
static override group = 'Actor Runtime';
11+
12+
static override examples = [
13+
{
14+
description: 'Read the record stored under the key "INPUT".',
15+
command: 'actor get-value INPUT',
16+
},
17+
];
18+
19+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-get-value';
20+
1021
static override args = {
1122
key: Args.string({
1223
required: true,
13-
description: 'Key of the record in key-value store',
24+
description: 'Key of the record in the key-value store.',
1425
}),
1526
};
1627

src/commands/actor/push-data.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,22 @@ import { error } from '../../lib/outputs.js';
77
export class ActorPushDataCommand extends ApifyCommand<typeof ActorPushDataCommand> {
88
static override name = 'push-data' as const;
99

10-
static override description =
11-
"Saves data to Actor's run default dataset.\n\n" +
12-
'Accept input as:\n' +
13-
' - JSON argument:\n' +
14-
' $ apify actor push-data {"key": "value"}\n' +
15-
' - Piped stdin:\n' +
16-
' $ cat ./test.json | apify actor push-data';
10+
static override description = "Saves data to Actor's run default dataset.";
11+
12+
static override group = 'Actor Runtime';
13+
14+
static override examples = [
15+
{
16+
description: 'Push a single item as an inline JSON argument.',
17+
command: `actor push-data '{"key":"value"}'`,
18+
},
19+
{
20+
description: 'Push an array of items by piping from stdin.',
21+
command: 'cat ./items.json | actor push-data',
22+
},
23+
];
24+
25+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-push-data';
1726

1827
static override args = {
1928
item: Args.string({

src/commands/actor/set-value.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,26 @@ export class ActorSetValueCommand extends ApifyCommand<typeof ActorSetValueComma
77
static override name = 'set-value' as const;
88

99
static override description =
10-
'Sets or removes record into the default key-value store associated with the Actor run.\n\n' +
11-
'It is possible to pass data using argument or stdin.\n\n' +
12-
'Passing data using argument:\n' +
13-
'$ apify actor set-value KEY my-value\n\n' +
14-
'Passing data using stdin with pipe:\n' +
15-
'$ cat ./my-text-file.txt | apify actor set-value KEY --contentType text/plain';
10+
'Sets or removes a record in the default key-value store associated with the Actor run.';
11+
12+
static override group = 'Actor Runtime';
13+
14+
static override examples = [
15+
{
16+
description: 'Store a JSON value under the key "OUTPUT".',
17+
command: `actor set-value OUTPUT '{"status":"done"}'`,
18+
},
19+
{
20+
description: 'Store a file as a text record.',
21+
command: 'cat ./report.txt | actor set-value REPORT --contentType text/plain',
22+
},
23+
{
24+
description: 'Delete the record stored under the given key.',
25+
command: 'actor set-value OUTPUT',
26+
},
27+
];
28+
29+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#actor-set-value';
1630

1731
static override args = {
1832
key: Args.string({

src/commands/actors/_index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import { ActorsStartCommand } from './start.js';
1212
export class ActorsIndexCommand extends ApifyCommand<typeof ActorsIndexCommand> {
1313
static override name = 'actors' as const;
1414

15-
static override description = 'Manages Actor creation, deployment, and execution on the Apify platform.';
15+
static override description =
16+
`Search, list, deploy, and call Actors on the Apify platform.\n` +
17+
`For runtime operations inside a running Actor (push-data, get-input, set-value...), see 'apify actor' (singular).`;
18+
19+
static override group = 'Apify Console';
20+
21+
static override docsUrl = 'https://docs.apify.com/cli/docs/reference#apify-actors';
1622

1723
static override subcommands = [
1824
//

0 commit comments

Comments
 (0)