@vm0/cli 9.90.1 → 9.90.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.90.1",
3
+ "version": "9.90.3",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -7,13 +7,13 @@ import {
7
7
  allowsCustomModel,
8
8
  configureGlobalProxyFromEnv,
9
9
  connectorTypeSchema,
10
- createAgentSkill,
10
+ createSkill,
11
11
  createZeroAgent,
12
12
  createZeroComputerConnector,
13
13
  createZeroConnectorSession,
14
14
  createZeroRun,
15
15
  decodeZeroTokenPayload,
16
- deleteAgentSkill,
16
+ deleteSkill,
17
17
  deleteZeroAgent,
18
18
  deleteZeroComputerConnector,
19
19
  deleteZeroConnector,
@@ -29,7 +29,6 @@ import {
29
29
  enableZeroSchedule,
30
30
  findMatchingPermissions,
31
31
  getActiveOrg,
32
- getAgentSkill,
33
32
  getApiUrl,
34
33
  getAskUserAnswer,
35
34
  getAuthMethodsForType,
@@ -44,6 +43,7 @@ import {
44
43
  getScopeDiff,
45
44
  getSecretsForAuthMethod,
46
45
  getSelectableProviderTypes,
46
+ getSkill,
47
47
  getToken,
48
48
  getZeroAgent,
49
49
  getZeroAgentInstructions,
@@ -64,7 +64,7 @@ import {
64
64
  isInteractive,
65
65
  isUUID,
66
66
  leaveZeroOrg,
67
- listAgentSkills,
67
+ listSkills,
68
68
  listZeroAgents,
69
69
  listZeroConnectors,
70
70
  listZeroOrgModelProviders,
@@ -93,7 +93,7 @@ import {
93
93
  setZeroSecret,
94
94
  setZeroVariable,
95
95
  switchZeroOrg,
96
- updateAgentSkill,
96
+ updateSkill,
97
97
  updateZeroAgent,
98
98
  updateZeroAgentInstructions,
99
99
  updateZeroOrg,
@@ -101,7 +101,7 @@ import {
101
101
  updateZeroUserPreferences,
102
102
  upsertZeroOrgModelProvider,
103
103
  withErrorHandler
104
- } from "./chunk-RJS4OQ2I.js";
104
+ } from "./chunk-HZQ6GQVS.js";
105
105
 
106
106
  // src/zero.ts
107
107
  import { Command as Command68 } from "commander";
@@ -1132,37 +1132,69 @@ Examples:
1132
1132
  import { Command as Command25 } from "commander";
1133
1133
  import { readFileSync as readFileSync2 } from "fs";
1134
1134
  import chalk22 from "chalk";
1135
+ function resolveCustomSkills(options, existing) {
1136
+ if (options.skills && (options.addSkill || options.removeSkill)) {
1137
+ throw new Error("Cannot use --skills with --add-skill or --remove-skill");
1138
+ }
1139
+ if (options.skills) {
1140
+ return options.skills.split(",").map((s) => s.trim());
1141
+ }
1142
+ if (options.addSkill) {
1143
+ if (existing.includes(options.addSkill)) {
1144
+ throw new Error(
1145
+ `Skill "${options.addSkill}" is already attached to this agent`
1146
+ );
1147
+ }
1148
+ return [...existing, options.addSkill];
1149
+ }
1150
+ if (options.removeSkill) {
1151
+ if (!existing.includes(options.removeSkill)) {
1152
+ throw new Error(
1153
+ `Skill "${options.removeSkill}" is not attached to this agent`
1154
+ );
1155
+ }
1156
+ return existing.filter((s) => s !== options.removeSkill);
1157
+ }
1158
+ return void 0;
1159
+ }
1135
1160
  var editCommand = new Command25().name("edit").description("Edit a zero agent").argument("<agent-id>", "Agent ID").option("--display-name <name>", "New display name").option("--description <text>", "New description").option(
1136
1161
  "--sound <tone>",
1137
1162
  "New tone: professional, friendly, direct, supportive"
1138
1163
  ).option(
1139
1164
  "--skills <items>",
1140
1165
  "Comma-separated custom skill names to attach (replaces existing)"
1141
- ).option("--instructions-file <path>", "Path to new instructions file").addHelpText(
1166
+ ).option("--add-skill <name>", "Add a custom skill to the agent").option("--remove-skill <name>", "Remove a custom skill from the agent").option("--instructions-file <path>", "Path to new instructions file").addHelpText(
1142
1167
  "after",
1143
1168
  `
1144
1169
  Examples:
1145
1170
  Update description: zero agent edit <agent-id> --description "new role"
1146
1171
  Update tone: zero agent edit <agent-id> --sound friendly
1147
- Update skills: zero agent edit <agent-id> --skills my-skill,other-skill
1172
+ Replace all skills: zero agent edit <agent-id> --skills my-skill,other-skill
1173
+ Add a skill: zero agent edit <agent-id> --add-skill my-skill
1174
+ Remove a skill: zero agent edit <agent-id> --remove-skill my-skill
1148
1175
  Update instructions: zero agent edit <agent-id> --instructions-file ./instructions.md
1149
1176
  Update yourself: zero agent edit $ZERO_AGENT_ID --description "new role"
1150
1177
 
1151
1178
  Notes:
1152
1179
  - At least one option is required
1153
- - Unspecified fields are preserved (not cleared)`
1180
+ - Unspecified fields are preserved (not cleared)
1181
+ - --skills replaces the entire skill list; --add-skill/--remove-skill modify incrementally
1182
+ - --skills cannot be combined with --add-skill or --remove-skill`
1154
1183
  ).action(
1155
1184
  withErrorHandler(
1156
1185
  async (agentId, options) => {
1157
- const hasAgentUpdate = options.displayName !== void 0 || options.description !== void 0 || options.sound !== void 0 || options.skills !== void 0;
1186
+ const hasAgentUpdate = options.displayName !== void 0 || options.description !== void 0 || options.sound !== void 0 || options.skills !== void 0 || options.addSkill !== void 0 || options.removeSkill !== void 0;
1158
1187
  if (!hasAgentUpdate && !options.instructionsFile) {
1159
1188
  throw new Error(
1160
- "At least one option is required (--display-name, --description, --sound, --skills, --instructions-file)"
1189
+ "At least one option is required (--display-name, --description, --sound, --skills, --add-skill, --remove-skill, --instructions-file)"
1161
1190
  );
1162
1191
  }
1163
1192
  if (hasAgentUpdate) {
1164
1193
  const current = await getZeroAgent(agentId);
1165
- const customSkills = options.skills ? options.skills.split(",").map((s) => s.trim()) : void 0;
1194
+ const customSkills = resolveCustomSkills(
1195
+ options,
1196
+ current.customSkills ?? []
1197
+ );
1166
1198
  await updateZeroAgent(agentId, {
1167
1199
  displayName: options.displayName !== void 0 ? options.displayName : current.displayName ?? void 0,
1168
1200
  description: options.description !== void 0 ? options.description : current.description ?? void 0,
@@ -3611,32 +3643,26 @@ import { Command as Command62 } from "commander";
3611
3643
  import { readFileSync as readFileSync4, existsSync } from "fs";
3612
3644
  import { join as join2 } from "path";
3613
3645
  import chalk48 from "chalk";
3614
- var createCommand2 = new Command62().name("create").description("Create a custom skill for a zero agent").argument("<name>", "Skill name (lowercase alphanumeric with hyphens)").requiredOption("--dir <path>", "Path to directory containing SKILL.md").option("--agent <id>", "Agent ID (defaults to $ZERO_AGENT_ID)").option("--display-name <name>", "Skill display name").option("--description <text>", "Skill description").addHelpText(
3646
+ var createCommand2 = new Command62().name("create").description("Create a custom skill in the organization").argument("<name>", "Skill name (lowercase alphanumeric with hyphens)").requiredOption("--dir <path>", "Path to directory containing SKILL.md").option("--display-name <name>", "Skill display name").option("--description <text>", "Skill description").addHelpText(
3615
3647
  "after",
3616
3648
  `
3617
3649
  Examples:
3618
3650
  zero skill create my-skill --dir ./skills/my-skill/
3619
- zero skill create my-skill --dir ./skills/my-skill/ --agent <id>
3620
3651
  zero skill create my-skill --dir ./skills/my-skill/ --display-name "My Skill" --description "Does things"
3621
3652
 
3622
3653
  Notes:
3623
3654
  - The directory must contain a SKILL.md file
3624
- - Agent ID defaults to $ZERO_AGENT_ID if --agent is not provided`
3655
+ - The skill is created in the organization but not bound to any agent
3656
+ - Use 'zero agent edit <id> --add-skill <name>' to bind a skill to an agent`
3625
3657
  ).action(
3626
3658
  withErrorHandler(
3627
3659
  async (name, options) => {
3628
- const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
3629
- if (!agentId) {
3630
- throw new Error(
3631
- "Agent ID required: use --agent <id> or set $ZERO_AGENT_ID"
3632
- );
3633
- }
3634
3660
  const skillMdPath = join2(options.dir, "SKILL.md");
3635
3661
  if (!existsSync(skillMdPath)) {
3636
3662
  throw new Error(`SKILL.md not found in ${options.dir}`);
3637
3663
  }
3638
3664
  const content = readFileSync4(skillMdPath, "utf-8");
3639
- const skill = await createAgentSkill(agentId, {
3665
+ const skill = await createSkill({
3640
3666
  name,
3641
3667
  content,
3642
3668
  displayName: options.displayName,
@@ -3644,7 +3670,6 @@ Notes:
3644
3670
  });
3645
3671
  console.log(chalk48.green(`\u2713 Skill "${skill.name}" created`));
3646
3672
  console.log(` Name: ${skill.name}`);
3647
- console.log(` Agent: ${agentId}`);
3648
3673
  if (skill.displayName) {
3649
3674
  console.log(` Display Name: ${skill.displayName}`);
3650
3675
  }
@@ -3663,50 +3688,34 @@ import chalk49 from "chalk";
3663
3688
  var editCommand2 = new Command63().name("edit").description("Update a custom skill's content").argument("<name>", "Skill name").requiredOption(
3664
3689
  "--dir <path>",
3665
3690
  "Path to directory containing updated SKILL.md"
3666
- ).option("--agent <id>", "Agent ID (defaults to $ZERO_AGENT_ID)").addHelpText(
3691
+ ).addHelpText(
3667
3692
  "after",
3668
3693
  `
3669
3694
  Examples:
3670
- zero skill edit my-skill --dir ./skills/my-skill/
3671
- zero skill edit my-skill --dir ./skills/my-skill/ --agent <id>`
3695
+ zero skill edit my-skill --dir ./skills/my-skill/`
3672
3696
  ).action(
3673
- withErrorHandler(
3674
- async (name, options) => {
3675
- const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
3676
- if (!agentId) {
3677
- throw new Error(
3678
- "Agent ID required: use --agent <id> or set $ZERO_AGENT_ID"
3679
- );
3680
- }
3681
- const skillMdPath = join3(options.dir, "SKILL.md");
3682
- if (!existsSync2(skillMdPath)) {
3683
- throw new Error(`SKILL.md not found in ${options.dir}`);
3684
- }
3685
- const content = readFileSync5(skillMdPath, "utf-8");
3686
- await updateAgentSkill(agentId, name, { content });
3687
- console.log(chalk49.green(`\u2713 Skill "${name}" updated`));
3697
+ withErrorHandler(async (name, options) => {
3698
+ const skillMdPath = join3(options.dir, "SKILL.md");
3699
+ if (!existsSync2(skillMdPath)) {
3700
+ throw new Error(`SKILL.md not found in ${options.dir}`);
3688
3701
  }
3689
- )
3702
+ const content = readFileSync5(skillMdPath, "utf-8");
3703
+ await updateSkill(name, { content });
3704
+ console.log(chalk49.green(`\u2713 Skill "${name}" updated`));
3705
+ })
3690
3706
  );
3691
3707
 
3692
3708
  // src/commands/zero/skill/view.ts
3693
3709
  import { Command as Command64 } from "commander";
3694
3710
  import chalk50 from "chalk";
3695
- var viewCommand2 = new Command64().name("view").description("View a custom skill").argument("<name>", "Skill name").option("--agent <id>", "Agent ID (defaults to $ZERO_AGENT_ID)").addHelpText(
3711
+ var viewCommand2 = new Command64().name("view").description("View a custom skill").argument("<name>", "Skill name").addHelpText(
3696
3712
  "after",
3697
3713
  `
3698
3714
  Examples:
3699
- zero skill view my-skill
3700
- zero skill view my-skill --agent <id>`
3715
+ zero skill view my-skill`
3701
3716
  ).action(
3702
- withErrorHandler(async (name, options) => {
3703
- const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
3704
- if (!agentId) {
3705
- throw new Error(
3706
- "Agent ID required: use --agent <id> or set $ZERO_AGENT_ID"
3707
- );
3708
- }
3709
- const skill = await getAgentSkill(agentId, name);
3717
+ withErrorHandler(async (name) => {
3718
+ const skill = await getSkill(name);
3710
3719
  console.log(chalk50.bold(skill.name));
3711
3720
  if (skill.displayName) console.log(chalk50.dim(skill.displayName));
3712
3721
  console.log();
@@ -3726,21 +3735,14 @@ Examples:
3726
3735
  // src/commands/zero/skill/list.ts
3727
3736
  import { Command as Command65 } from "commander";
3728
3737
  import chalk51 from "chalk";
3729
- var listCommand10 = new Command65().name("list").alias("ls").description("List custom skills for a zero agent").option("--agent <id>", "Agent ID (defaults to $ZERO_AGENT_ID)").addHelpText(
3738
+ var listCommand10 = new Command65().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
3730
3739
  "after",
3731
3740
  `
3732
3741
  Examples:
3733
- zero skill list
3734
- zero skill list --agent <id>`
3742
+ zero skill list`
3735
3743
  ).action(
3736
- withErrorHandler(async (options) => {
3737
- const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
3738
- if (!agentId) {
3739
- throw new Error(
3740
- "Agent ID required: use --agent <id> or set $ZERO_AGENT_ID"
3741
- );
3742
- }
3743
- const skills = await listAgentSkills(agentId);
3744
+ withErrorHandler(async () => {
3745
+ const skills = await listSkills();
3744
3746
  if (skills.length === 0) {
3745
3747
  console.log(chalk51.dim("No custom skills found"));
3746
3748
  console.log(
@@ -3773,58 +3775,52 @@ Examples:
3773
3775
  // src/commands/zero/skill/delete.ts
3774
3776
  import { Command as Command66 } from "commander";
3775
3777
  import chalk52 from "chalk";
3776
- var deleteCommand6 = new Command66().name("delete").alias("rm").description("Delete a custom skill").argument("<name>", "Skill name").option("--agent <id>", "Agent ID (defaults to $ZERO_AGENT_ID)").option("-y, --yes", "Skip confirmation prompt").addHelpText(
3778
+ var deleteCommand6 = new Command66().name("delete").alias("rm").description("Delete a custom skill from the organization").argument("<name>", "Skill name").option("-y, --yes", "Skip confirmation prompt").addHelpText(
3777
3779
  "after",
3778
3780
  `
3779
3781
  Examples:
3780
3782
  zero skill delete my-skill
3781
3783
  zero skill delete my-skill -y
3782
- zero skill delete my-skill --agent <id>
3783
3784
 
3784
3785
  Notes:
3786
+ - This removes the skill from the organization and unbinds it from all agents
3785
3787
  - Use -y to skip confirmation in non-interactive mode`
3786
3788
  ).action(
3787
- withErrorHandler(
3788
- async (name, options) => {
3789
- const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
3790
- if (!agentId) {
3791
- throw new Error(
3792
- "Agent ID required: use --agent <id> or set $ZERO_AGENT_ID"
3793
- );
3789
+ withErrorHandler(async (name, options) => {
3790
+ await getSkill(name);
3791
+ if (!options.yes) {
3792
+ if (!isInteractive()) {
3793
+ throw new Error("--yes flag is required in non-interactive mode");
3794
3794
  }
3795
- await getAgentSkill(agentId, name);
3796
- if (!options.yes) {
3797
- if (!isInteractive()) {
3798
- throw new Error("--yes flag is required in non-interactive mode");
3799
- }
3800
- const confirmed = await promptConfirm(
3801
- `Delete skill '${name}'?`,
3802
- false
3803
- );
3804
- if (!confirmed) {
3805
- console.log(chalk52.dim("Cancelled"));
3806
- return;
3807
- }
3795
+ const confirmed = await promptConfirm(
3796
+ `Delete skill '${name}'? This will unbind it from all agents.`,
3797
+ false
3798
+ );
3799
+ if (!confirmed) {
3800
+ console.log(chalk52.dim("Cancelled"));
3801
+ return;
3808
3802
  }
3809
- await deleteAgentSkill(agentId, name);
3810
- console.log(chalk52.green(`\u2713 Skill "${name}" deleted`));
3811
3803
  }
3812
- )
3804
+ await deleteSkill(name);
3805
+ console.log(chalk52.green(`\u2713 Skill "${name}" deleted`));
3806
+ })
3813
3807
  );
3814
3808
 
3815
3809
  // src/commands/zero/skill/index.ts
3816
- var zeroSkillCommand = new Command67("skill").description("Manage custom skills for zero agents").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand10).addCommand(deleteCommand6).addHelpText(
3810
+ var zeroSkillCommand = new Command67("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand10).addCommand(deleteCommand6).addHelpText(
3817
3811
  "after",
3818
3812
  `
3819
3813
  Examples:
3820
3814
  Create from directory: zero skill create my-skill --dir ./skills/my-skill/
3821
- List agent's skills: zero skill list --agent <id>
3815
+ List all skills: zero skill list
3822
3816
  View skill content: zero skill view my-skill
3823
3817
  Update skill content: zero skill edit my-skill --dir ./skills/my-skill/
3824
3818
  Delete a skill: zero skill delete my-skill -y
3825
3819
 
3826
- Notes:
3827
- Agent ID comes from --agent flag or $ZERO_AGENT_ID environment variable`
3820
+ Skill Binding:
3821
+ Bind to agent: zero agent edit <id> --add-skill my-skill
3822
+ Unbind from agent: zero agent edit <id> --remove-skill my-skill
3823
+ Replace all skills: zero agent edit <id> --skills a,b,c`
3828
3824
  );
3829
3825
 
3830
3826
  // src/zero.ts
@@ -3870,7 +3866,7 @@ function registerZeroCommands(prog, commands) {
3870
3866
  var program = new Command68();
3871
3867
  program.name("zero").description(
3872
3868
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
3873
- ).version("9.90.1").addHelpText(
3869
+ ).version("9.90.3").addHelpText(
3874
3870
  "after",
3875
3871
  `
3876
3872
  Examples: