@asteroidai/cli 1.9.11 → 1.9.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -128,6 +128,7 @@ export const COMMANDS: CliCommand[] = [
128
128
  binary: false,
129
129
  readOnly: false,
130
130
  destructive: false,
131
+ capability: "run_execution",
131
132
  },
132
133
  {
133
134
  command: "context",
@@ -1092,6 +1093,7 @@ export const COMMANDS: CliCommand[] = [
1092
1093
  files: [],
1093
1094
  credentialOrganization: false,
1094
1095
  },
1096
+ capability: "run_execution",
1095
1097
  },
1096
1098
  {
1097
1099
  command: "execution resume",
@@ -1113,6 +1115,7 @@ export const COMMANDS: CliCommand[] = [
1113
1115
  binary: false,
1114
1116
  readOnly: false,
1115
1117
  destructive: false,
1118
+ capability: "run_execution",
1116
1119
  },
1117
1120
  {
1118
1121
  command: "insight get",
@@ -2004,6 +2007,7 @@ export const COMMANDS: CliCommand[] = [
2004
2007
  files: [],
2005
2008
  credentialOrganization: false,
2006
2009
  },
2010
+ capability: "run_execution",
2007
2011
  },
2008
2012
  {
2009
2013
  command: "schedule delete",
@@ -2031,6 +2035,7 @@ export const COMMANDS: CliCommand[] = [
2031
2035
  binary: false,
2032
2036
  readOnly: false,
2033
2037
  destructive: true,
2038
+ capability: "run_execution",
2034
2039
  },
2035
2040
  {
2036
2041
  command: "schedule get",
@@ -2222,6 +2227,7 @@ export const COMMANDS: CliCommand[] = [
2222
2227
  files: [],
2223
2228
  credentialOrganization: false,
2224
2229
  },
2230
+ capability: "run_execution",
2225
2231
  },
2226
2232
  {
2227
2233
  command: "scheduled-execution cancel",
@@ -2243,6 +2249,7 @@ export const COMMANDS: CliCommand[] = [
2243
2249
  binary: false,
2244
2250
  readOnly: false,
2245
2251
  destructive: false,
2252
+ capability: "run_execution",
2246
2253
  },
2247
2254
  {
2248
2255
  command: "scheduled-execution create",
@@ -2315,6 +2322,7 @@ export const COMMANDS: CliCommand[] = [
2315
2322
  files: [],
2316
2323
  credentialOrganization: false,
2317
2324
  },
2325
+ capability: "run_execution",
2318
2326
  },
2319
2327
  {
2320
2328
  command: "scheduled-execution list",
@@ -2421,6 +2429,7 @@ export const COMMANDS: CliCommand[] = [
2421
2429
  files: [],
2422
2430
  credentialOrganization: false,
2423
2431
  },
2432
+ capability: "run_execution",
2424
2433
  },
2425
2434
  {
2426
2435
  command: "schema validate",
@@ -3621,6 +3630,7 @@ export const COMMANDS: CliCommand[] = [
3621
3630
  files: [],
3622
3631
  credentialOrganization: false,
3623
3632
  },
3633
+ capability: "run_execution",
3624
3634
  },
3625
3635
  {
3626
3636
  command: "workflow execute-sync",
@@ -3731,119 +3741,7 @@ export const COMMANDS: CliCommand[] = [
3731
3741
  files: [],
3732
3742
  credentialOrganization: false,
3733
3743
  },
3734
- },
3735
- {
3736
- command: "workflow file list",
3737
- tool: "workflow_files_list",
3738
- title: "List workflow files",
3739
- description:
3740
- "List the workflow's editable head as a directory of files: the graph rendered as structural files (settings.yaml, per-node instructions.md, scripts) alongside the workflow's own files. Those files are referenced by fileId unless contents=all is set. Pass paths to read named files only, or contents=none for a manifest with no bodies. The returned rev is what you pass as baseRev to write.",
3741
- method: "GET",
3742
- path: "/agents/v2/workflows/{workflowId}/head/files",
3743
- args: [
3744
- {
3745
- name: "workflowId",
3746
- flag: "workflow-id",
3747
- type: "string",
3748
- required: true,
3749
- },
3750
- ],
3751
- query: [
3752
- {
3753
- name: "contents",
3754
- flag: "contents",
3755
- type: "string",
3756
- required: false,
3757
- description:
3758
- "Which contents come inline: none (a pure manifest), structural (the default), or all (structural plus file bytes within the response budget).",
3759
- enum: ["none", "structural", "all"],
3760
- },
3761
- {
3762
- name: "paths",
3763
- flag: "paths",
3764
- type: "string[]",
3765
- required: false,
3766
- description:
3767
- "Return only the files at these exact tree paths. A path that names nothing yields no entry. The inline budget applies to the filtered set, so a narrow read can inline files a whole-tree read would have to skip.",
3768
- },
3769
- {
3770
- name: "variants",
3771
- flag: "variants",
3772
- type: "string",
3773
- required: false,
3774
- description:
3775
- 'Narrow which variants/<key>/ files the tree carries: "none" strips every variant, a comma-separated list keeps only those variant keys. Files outside variants/ are always kept, and the response\'s variantKeys still names every variant. Ignored unless the workflow has variant mode enabled; absent keeps every variant.',
3776
- },
3777
- {
3778
- name: "maxFileBytes",
3779
- flag: "max-file-bytes",
3780
- type: "integer",
3781
- required: false,
3782
- description:
3783
- "Per-file ceiling, in bytes, for inlined file contents. Clamped to the server maximum. Files above the ceiling stay references.",
3784
- },
3785
- {
3786
- name: "maxTotalBytes",
3787
- flag: "max-total-bytes",
3788
- type: "integer",
3789
- required: false,
3790
- description:
3791
- "Ceiling, in bytes, on the total inlined file contents in one response. Clamped to the server maximum. Files are admitted in path order until the ceiling is reached; the rest stay references.",
3792
- },
3793
- ],
3794
- binary: false,
3795
- readOnly: true,
3796
- destructive: false,
3797
- },
3798
- {
3799
- command: "workflow file patch",
3800
- tool: "workflow_files_patch",
3801
- title: "Write workflow files",
3802
- description:
3803
- "Write and delete files on the workflow's editable head in one patch. Structural files re-derive the graph; the workflow's own files go to its file store, you just write paths. Pass the rev from `workflow_files_list` as baseRev; a stale value is rejected with 409, so re-read and retry. Editing a published or already-executed version forks a new one instead of rewriting it. Each write carries `contentBase64`: base64-encode the file content, plain text is rejected with 400.",
3804
- method: "PATCH",
3805
- path: "/agents/v2/workflows/{workflowId}/head/files",
3806
- args: [
3807
- {
3808
- name: "workflowId",
3809
- flag: "workflow-id",
3810
- type: "string",
3811
- required: true,
3812
- },
3813
- ],
3814
- query: [],
3815
- binary: false,
3816
- readOnly: false,
3817
- destructive: true,
3818
- body: {
3819
- required: true,
3820
- contentType: "application/json",
3821
- fields: [
3822
- {
3823
- name: "baseRev",
3824
- flag: "base-rev",
3825
- type: "integer",
3826
- required: true,
3827
- description:
3828
- "The revision this edit is based on. Agent-file-only patches overlay the current head even when this is stale. A structural-file patch is rejected with 409 when it does not match the stored head revision.",
3829
- },
3830
- {
3831
- name: "writes",
3832
- flag: "writes",
3833
- type: "json",
3834
- required: true,
3835
- description: "Files to upsert.",
3836
- },
3837
- {
3838
- name: "deletes",
3839
- flag: "deletes",
3840
- type: "string[]",
3841
- required: true,
3842
- },
3843
- ],
3844
- files: [],
3845
- credentialOrganization: false,
3846
- },
3744
+ capability: "run_execution",
3847
3745
  },
3848
3746
  {
3849
3747
  command: "workflow get",
@@ -3894,6 +3792,7 @@ export const COMMANDS: CliCommand[] = [
3894
3792
  binary: false,
3895
3793
  readOnly: false,
3896
3794
  destructive: false,
3795
+ capability: "publish",
3897
3796
  },
3898
3797
  {
3899
3798
  command: "workflow head revert",
@@ -4024,6 +3923,121 @@ export const COMMANDS: CliCommand[] = [
4024
3923
  readOnly: true,
4025
3924
  destructive: false,
4026
3925
  },
3926
+ {
3927
+ command: "workflow pull",
3928
+ tool: "workflow_files_list",
3929
+ title: "List workflow files",
3930
+ description:
3931
+ "List the workflow's editable head as a directory of files: the graph rendered as structural files (settings.yaml, per-node instructions.md, scripts) alongside the workflow's own files. Those files are referenced by fileId unless contents=all is set. Pass paths to read named files only, or contents=none for a manifest with no bodies. The returned rev is what you pass as baseRev to write.",
3932
+ method: "GET",
3933
+ path: "/agents/v2/workflows/{workflowId}/head/files",
3934
+ args: [
3935
+ {
3936
+ name: "workflowId",
3937
+ flag: "workflow-id",
3938
+ type: "string",
3939
+ required: true,
3940
+ },
3941
+ ],
3942
+ query: [
3943
+ {
3944
+ name: "contents",
3945
+ flag: "contents",
3946
+ type: "string",
3947
+ required: false,
3948
+ description:
3949
+ "Which contents come inline: none (a pure manifest), structural (the default), or all (structural plus file bytes within the response budget).",
3950
+ enum: ["none", "structural", "all"],
3951
+ },
3952
+ {
3953
+ name: "paths",
3954
+ flag: "paths",
3955
+ type: "string[]",
3956
+ required: false,
3957
+ description:
3958
+ "Return only the files at these exact tree paths. A path that names nothing yields no entry. The inline budget applies to the filtered set, so a narrow read can inline files a whole-tree read would have to skip.",
3959
+ },
3960
+ {
3961
+ name: "variants",
3962
+ flag: "variants",
3963
+ type: "string",
3964
+ required: false,
3965
+ description:
3966
+ 'Narrow which variants/<key>/ files the tree carries: "none" strips every variant, a comma-separated list keeps only those variant keys. Files outside variants/ are always kept, and the response\'s variantKeys still names every variant. Ignored unless the workflow has variant mode enabled; absent keeps every variant.',
3967
+ },
3968
+ {
3969
+ name: "maxFileBytes",
3970
+ flag: "max-file-bytes",
3971
+ type: "integer",
3972
+ required: false,
3973
+ description:
3974
+ "Per-file ceiling, in bytes, for inlined file contents. Clamped to the server maximum. Files above the ceiling stay references.",
3975
+ },
3976
+ {
3977
+ name: "maxTotalBytes",
3978
+ flag: "max-total-bytes",
3979
+ type: "integer",
3980
+ required: false,
3981
+ description:
3982
+ "Ceiling, in bytes, on the total inlined file contents in one response. Clamped to the server maximum. Files are admitted in path order until the ceiling is reached; the rest stay references.",
3983
+ },
3984
+ ],
3985
+ binary: false,
3986
+ readOnly: true,
3987
+ destructive: false,
3988
+ files: "pull",
3989
+ },
3990
+ {
3991
+ command: "workflow push",
3992
+ tool: "workflow_files_patch",
3993
+ title: "Write workflow files",
3994
+ description:
3995
+ "Write and delete files on the workflow's editable head in one patch. Structural files re-derive the graph; the workflow's own files go to its file store, you just write paths. Pass the rev from `workflow_files_list` as baseRev; a stale value is rejected with 409, so re-read and retry. Editing a published or already-executed version forks a new one instead of rewriting it. Each write carries `contentBase64`: base64-encode the file content, plain text is rejected with 400.",
3996
+ method: "PATCH",
3997
+ path: "/agents/v2/workflows/{workflowId}/head/files",
3998
+ args: [
3999
+ {
4000
+ name: "workflowId",
4001
+ flag: "workflow-id",
4002
+ type: "string",
4003
+ required: true,
4004
+ },
4005
+ ],
4006
+ query: [],
4007
+ binary: false,
4008
+ readOnly: false,
4009
+ destructive: true,
4010
+ body: {
4011
+ required: true,
4012
+ contentType: "application/json",
4013
+ fields: [
4014
+ {
4015
+ name: "baseRev",
4016
+ flag: "base-rev",
4017
+ type: "integer",
4018
+ required: true,
4019
+ description:
4020
+ "The revision this edit is based on. Agent-file-only patches overlay the current head even when this is stale. A structural-file patch is rejected with 409 when it does not match the stored head revision.",
4021
+ },
4022
+ {
4023
+ name: "writes",
4024
+ flag: "writes",
4025
+ type: "json",
4026
+ required: true,
4027
+ description: "Files to upsert.",
4028
+ },
4029
+ {
4030
+ name: "deletes",
4031
+ flag: "deletes",
4032
+ type: "string[]",
4033
+ required: true,
4034
+ },
4035
+ ],
4036
+ files: [],
4037
+ credentialOrganization: false,
4038
+ },
4039
+ files: "push",
4040
+ },
4027
4041
  {
4028
4042
  command: "workflow rename",
4029
4043
  tool: "workflow_rename",
@@ -4449,75 +4463,7 @@ export const COMMANDS: CliCommand[] = [
4449
4463
  files: [],
4450
4464
  credentialOrganization: false,
4451
4465
  },
4452
- },
4453
- {
4454
- command: "workflow version file list",
4455
- tool: "workflow_version_files_list",
4456
- title: "List workflow version files",
4457
- description:
4458
- "List a version's files, like `workflow_files_list` does for the editable head. Versions are immutable, so this is read-only.",
4459
- method: "GET",
4460
- path: "/agents/v2/workflows/{workflowId}/versions/{versionId}/files",
4461
- args: [
4462
- {
4463
- name: "workflowId",
4464
- flag: "workflow-id",
4465
- type: "string",
4466
- required: true,
4467
- },
4468
- {
4469
- name: "versionId",
4470
- flag: "version-id",
4471
- type: "string",
4472
- required: true,
4473
- },
4474
- ],
4475
- query: [
4476
- {
4477
- name: "contents",
4478
- flag: "contents",
4479
- type: "string",
4480
- required: false,
4481
- description:
4482
- "Which contents come inline: none (a pure manifest), structural (the default), or all (structural plus file bytes within the response budget).",
4483
- enum: ["none", "structural", "all"],
4484
- },
4485
- {
4486
- name: "paths",
4487
- flag: "paths",
4488
- type: "string[]",
4489
- required: false,
4490
- description:
4491
- "Return only the files at these exact tree paths. A path that names nothing yields no entry. The inline budget applies to the filtered set, so a narrow read can inline files a whole-tree read would have to skip.",
4492
- },
4493
- {
4494
- name: "variants",
4495
- flag: "variants",
4496
- type: "string",
4497
- required: false,
4498
- description:
4499
- 'Narrow which variants/<key>/ files the tree carries: "none" strips every variant, a comma-separated list keeps only those variant keys. Files outside variants/ are always kept, and the response\'s variantKeys still names every variant. Ignored unless the workflow has variant mode enabled; absent keeps every variant.',
4500
- },
4501
- {
4502
- name: "maxFileBytes",
4503
- flag: "max-file-bytes",
4504
- type: "integer",
4505
- required: false,
4506
- description:
4507
- "Per-file ceiling, in bytes, for inlined file contents. Clamped to the server maximum. Files above the ceiling stay references.",
4508
- },
4509
- {
4510
- name: "maxTotalBytes",
4511
- flag: "max-total-bytes",
4512
- type: "integer",
4513
- required: false,
4514
- description:
4515
- "Ceiling, in bytes, on the total inlined file contents in one response. Clamped to the server maximum. Files are admitted in path order until the ceiling is reached; the rest stay references.",
4516
- },
4517
- ],
4518
- binary: false,
4519
- readOnly: true,
4520
- destructive: false,
4466
+ capability: "run_execution",
4521
4467
  },
4522
4468
  {
4523
4469
  command: "workflow version file url",
@@ -4680,6 +4626,77 @@ export const COMMANDS: CliCommand[] = [
4680
4626
  binary: false,
4681
4627
  readOnly: false,
4682
4628
  destructive: false,
4629
+ capability: "publish",
4630
+ },
4631
+ {
4632
+ command: "workflow version pull",
4633
+ tool: "workflow_version_files_list",
4634
+ title: "List workflow version files",
4635
+ description:
4636
+ "List a version's files, like `workflow_files_list` does for the editable head. Versions are immutable, so this is read-only.",
4637
+ method: "GET",
4638
+ path: "/agents/v2/workflows/{workflowId}/versions/{versionId}/files",
4639
+ args: [
4640
+ {
4641
+ name: "workflowId",
4642
+ flag: "workflow-id",
4643
+ type: "string",
4644
+ required: true,
4645
+ },
4646
+ {
4647
+ name: "versionId",
4648
+ flag: "version-id",
4649
+ type: "string",
4650
+ required: true,
4651
+ },
4652
+ ],
4653
+ query: [
4654
+ {
4655
+ name: "contents",
4656
+ flag: "contents",
4657
+ type: "string",
4658
+ required: false,
4659
+ description:
4660
+ "Which contents come inline: none (a pure manifest), structural (the default), or all (structural plus file bytes within the response budget).",
4661
+ enum: ["none", "structural", "all"],
4662
+ },
4663
+ {
4664
+ name: "paths",
4665
+ flag: "paths",
4666
+ type: "string[]",
4667
+ required: false,
4668
+ description:
4669
+ "Return only the files at these exact tree paths. A path that names nothing yields no entry. The inline budget applies to the filtered set, so a narrow read can inline files a whole-tree read would have to skip.",
4670
+ },
4671
+ {
4672
+ name: "variants",
4673
+ flag: "variants",
4674
+ type: "string",
4675
+ required: false,
4676
+ description:
4677
+ 'Narrow which variants/<key>/ files the tree carries: "none" strips every variant, a comma-separated list keeps only those variant keys. Files outside variants/ are always kept, and the response\'s variantKeys still names every variant. Ignored unless the workflow has variant mode enabled; absent keeps every variant.',
4678
+ },
4679
+ {
4680
+ name: "maxFileBytes",
4681
+ flag: "max-file-bytes",
4682
+ type: "integer",
4683
+ required: false,
4684
+ description:
4685
+ "Per-file ceiling, in bytes, for inlined file contents. Clamped to the server maximum. Files above the ceiling stay references.",
4686
+ },
4687
+ {
4688
+ name: "maxTotalBytes",
4689
+ flag: "max-total-bytes",
4690
+ type: "integer",
4691
+ required: false,
4692
+ description:
4693
+ "Ceiling, in bytes, on the total inlined file contents in one response. Clamped to the server maximum. Files are admitted in path order until the ceiling is reached; the rest stay references.",
4694
+ },
4695
+ ],
4696
+ binary: false,
4697
+ readOnly: true,
4698
+ destructive: false,
4699
+ files: "pull",
4683
4700
  },
4684
4701
  {
4685
4702
  command: "workflow version validate",
package/src/program.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Command, CommanderError } from "commander";
1
+ import { Command, CommanderError, Option as Flag } from "commander";
2
2
 
3
3
  import { type Parsed, UsageError } from "./args";
4
4
  import { type BuiltinCommand, GLOBAL_FLAGS } from "./reference";
@@ -91,6 +91,16 @@ function leafOptions(leaf: Command, command: CliCommand) {
91
91
  for (const file of command.body?.files ?? []) {
92
92
  leaf.option(`--${file} <path>`, "File to upload. Repeatable.", collect);
93
93
  }
94
+ if (command.files === "pull")
95
+ leaf.option(
96
+ "--out <dir>",
97
+ "Write here instead of ./<workflow-name>/head (a version: ./<workflow-name>/.versions/...). --json prints the file listing instead.",
98
+ );
99
+ if (command.files === "push")
100
+ leaf.option(
101
+ "--from <dir>",
102
+ "The pulled head folder to push. Defaults to the current folder.",
103
+ );
94
104
  }
95
105
 
96
106
  function toParsed(
@@ -136,6 +146,8 @@ export function defineCommands(
136
146
  for (const builtin of options.builtins ?? []) {
137
147
  const leaf = root.command(builtin.command).description(builtin.description);
138
148
  if (builtin.arg) leaf.argument(`[${builtin.arg}]`);
149
+ for (const [flags, text] of builtin.hiddenOptions ?? [])
150
+ leaf.addOption(new Flag(flags, text).hideHelp());
139
151
  leaf.action((...args: unknown[]) => {
140
152
  const cmd = args.at(-1) as Command;
141
153
  onInvocation({
package/src/reference.ts CHANGED
@@ -6,6 +6,8 @@ export interface BuiltinCommand {
6
6
  description: string;
7
7
  args: number;
8
8
  arg?: string;
9
+ /** Flags left out of `--help` and the reference: staff only. */
10
+ hiddenOptions?: [string, string][];
9
11
  }
10
12
 
11
13
  export const BUILTINS: BuiltinCommand[] = [
@@ -36,6 +38,16 @@ export const BUILTINS: BuiltinCommand[] = [
36
38
  description:
37
39
  "Make an organization, by id or name, the default for later commands. Without one, pick from a list.",
38
40
  args: 1,
41
+ hiddenOptions: [
42
+ [
43
+ "--reason <why>",
44
+ "Staff only. Why you need access to an organization you are not a member of, such as a ticket id. It is audited. Asked for in a terminal.",
45
+ ],
46
+ [
47
+ "--exit",
48
+ "Staff only. Revoke every staff token now and go back to your own organization.",
49
+ ],
50
+ ],
39
51
  },
40
52
  {
41
53
  command: "complete",
@@ -75,7 +87,11 @@ export const GLOBAL_FLAGS: [string, string][] = [
75
87
  ];
76
88
 
77
89
  export function usage(command: CliCommand): string {
78
- const args = command.args.map((arg) => `<${arg.flag}>`).join(" ");
90
+ const args = command.args
91
+ .map((arg) =>
92
+ command.files === "push" ? `[${arg.flag}]` : `<${arg.flag}>`,
93
+ )
94
+ .join(" ");
79
95
  return `asteroid ${command.command}${args ? ` ${args}` : ""} [flags]`;
80
96
  }
81
97
 
@@ -109,6 +125,14 @@ export function flagLines(command: CliCommand): string[] {
109
125
  for (const file of command.body?.files ?? []) {
110
126
  lines.push(`--${file} <path> File to upload (repeatable)`);
111
127
  }
128
+ if (command.files === "pull")
129
+ lines.push(
130
+ "--out <dir> Write here instead of ./<workflow-name>/head (a version: ./<workflow-name>/.versions/...). --json prints the file listing instead",
131
+ );
132
+ if (command.files === "push")
133
+ lines.push(
134
+ "--from <dir> The pulled head folder to push. Defaults to the current folder",
135
+ );
112
136
  return lines;
113
137
  }
114
138