@vm0/cli 9.129.1 → 9.130.0

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.129.1",
3
+ "version": "9.130.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -130,7 +130,7 @@ import {
130
130
  upsertZeroOrgModelProvider,
131
131
  withErrorHandler,
132
132
  zeroAgentCustomSkillNameSchema
133
- } from "./chunk-TO65SA2M.js";
133
+ } from "./chunk-V5JAHNBR.js";
134
134
  import {
135
135
  __toESM,
136
136
  init_esm_shims
@@ -1167,17 +1167,135 @@ init_esm_shims();
1167
1167
  // src/commands/zero/agent/create.ts
1168
1168
  init_esm_shims();
1169
1169
  import { readFileSync } from "fs";
1170
+
1171
+ // src/commands/zero/agent/avatar.ts
1172
+ init_esm_shims();
1173
+ var SKIN_MAP = {
1174
+ light: 0,
1175
+ "light-medium": 1,
1176
+ medium: 2,
1177
+ "medium-dark": 3,
1178
+ dark: 4
1179
+ };
1180
+ var HAIR_COLOR_MAP = {
1181
+ blonde: 1,
1182
+ teal: 2,
1183
+ grey: 3,
1184
+ pink: 4,
1185
+ brown: 5
1186
+ };
1187
+ var EXPRESSION_MAP = {
1188
+ calm: 1,
1189
+ content: 2,
1190
+ neutral: 3,
1191
+ pleasant: 4,
1192
+ excited: 5
1193
+ };
1194
+ var INTENSITY_MAP = {
1195
+ chill: "d",
1196
+ normal: "m",
1197
+ hyped: "h"
1198
+ };
1199
+ function lookupRequired(value, map, flag) {
1200
+ if (!(value in map)) {
1201
+ throw new Error(
1202
+ `Invalid ${flag} "${value}". Must be one of: ${Object.keys(map).join(", ")}`
1203
+ );
1204
+ }
1205
+ return map[value];
1206
+ }
1207
+ function parseIntRange(value, flag, min, max) {
1208
+ const n = Number(value);
1209
+ if (!Number.isInteger(n) || n < min || n > max) {
1210
+ throw new Error(`Invalid ${flag} "${value}". Must be ${min}\u2013${max}`);
1211
+ }
1212
+ return n;
1213
+ }
1214
+ function buildCustomSvgAvatar(opts) {
1215
+ const r = opts.avatarRotation !== void 0 ? parseIntRange(opts.avatarRotation, "--avatar-rotation", 1, 5) : 3;
1216
+ const h = opts.avatarHairStyle !== void 0 ? parseIntRange(opts.avatarHairStyle, "--avatar-hair-style", 1, 5) : 1;
1217
+ const s = opts.avatarSkin !== void 0 ? lookupRequired(opts.avatarSkin, SKIN_MAP, "--avatar-skin") : 2;
1218
+ const c = opts.avatarHairColor !== void 0 ? lookupRequired(
1219
+ opts.avatarHairColor,
1220
+ HAIR_COLOR_MAP,
1221
+ "--avatar-hair-color"
1222
+ ) : 5;
1223
+ const f = opts.avatarExpression !== void 0 ? lookupRequired(
1224
+ opts.avatarExpression,
1225
+ EXPRESSION_MAP,
1226
+ "--avatar-expression"
1227
+ ) : 1;
1228
+ const i = opts.avatarIntensity !== void 0 ? lookupRequired(
1229
+ opts.avatarIntensity,
1230
+ INTENSITY_MAP,
1231
+ "--avatar-intensity"
1232
+ ) : "m";
1233
+ return `svg:r${r}s${s}h${h}c${c}f${f}${i}`;
1234
+ }
1235
+ function resolveAvatarUrl(opts) {
1236
+ const hasPreset = opts.avatar !== void 0;
1237
+ const hasCustom = opts.avatarRotation !== void 0 || opts.avatarSkin !== void 0 || opts.avatarHairStyle !== void 0 || opts.avatarHairColor !== void 0 || opts.avatarExpression !== void 0 || opts.avatarIntensity !== void 0;
1238
+ if (!hasPreset && !hasCustom) return void 0;
1239
+ if (hasPreset && hasCustom) {
1240
+ throw new Error(
1241
+ "--avatar cannot be combined with --avatar-* attribute options"
1242
+ );
1243
+ }
1244
+ if (hasPreset) {
1245
+ if (!/^preset:[0-4]$/.test(opts.avatar)) {
1246
+ throw new Error(
1247
+ `Invalid --avatar "${opts.avatar}". Use preset:0 through preset:4`
1248
+ );
1249
+ }
1250
+ return opts.avatar;
1251
+ }
1252
+ return buildCustomSvgAvatar(opts);
1253
+ }
1254
+
1255
+ // src/commands/zero/agent/create.ts
1170
1256
  var createCommand = new Command().name("create").description("Create a new zero agent").option(
1171
1257
  "--skills <items>",
1172
1258
  "Comma-separated custom skill names to attach (e.g. my-skill,other-skill)"
1173
1259
  ).option("--display-name <name>", "Agent display name").option("--description <text>", "Agent description").option(
1174
1260
  "--sound <tone>",
1175
1261
  "Agent tone: professional, friendly, direct, supportive"
1176
- ).option("--instructions-file <path>", "Path to instructions file").addHelpText(
1262
+ ).option("--avatar <preset>", "Avatar preset: preset:0 through preset:4").option(
1263
+ "--avatar-rotation <1-5>",
1264
+ "Head angle: 1=far-left 3=center 5=far-right"
1265
+ ).option(
1266
+ "--avatar-skin <tone>",
1267
+ "Skin tone: light | light-medium | medium | medium-dark | dark"
1268
+ ).option("--avatar-hair-style <1-5>", "Hair style: 1\u20135").option(
1269
+ "--avatar-hair-color <color>",
1270
+ "Hair color: blonde | teal | grey | pink | brown"
1271
+ ).option(
1272
+ "--avatar-expression <expr>",
1273
+ "Expression: calm | content | neutral | pleasant | excited"
1274
+ ).option("--avatar-intensity <level>", "Intensity: chill | normal | hyped").option("--instructions-file <path>", "Path to instructions file").addHelpText(
1177
1275
  "after",
1178
1276
  `
1277
+ Avatar:
1278
+ Quick presets (--avatar):
1279
+ preset:0 light skin, brown hair, calm, hyped
1280
+ preset:1 light-medium skin, grey hair, calm, normal
1281
+ preset:2 medium skin, pink hair, neutral, chill
1282
+ preset:3 medium-dark skin, blonde hair, pleasant, hyped
1283
+ preset:4 dark skin, teal hair, excited, normal
1284
+
1285
+ Custom attributes (--avatar-* flags, omitted fields use defaults):
1286
+ --avatar-rotation 1=far-left 3=center(default) 5=far-right
1287
+ --avatar-skin light / light-medium / medium(default) / medium-dark / dark
1288
+ --avatar-hair-style 1\u20135 (default: 1)
1289
+ --avatar-hair-color blonde / teal / grey / pink / brown(default)
1290
+ --avatar-expression calm(default) / content / neutral / pleasant / excited
1291
+ --avatar-intensity chill / normal(default) / hyped
1292
+
1293
+ Note: --avatar and --avatar-* cannot be used together.
1294
+
1179
1295
  Examples:
1180
1296
  Minimal: zero agent create --display-name "My Agent"
1297
+ Quick preset: zero agent create --display-name "My Agent" --avatar preset:2
1298
+ Custom avatar: zero agent create --display-name "My Agent" --avatar-skin dark --avatar-hair-color teal --avatar-intensity hyped
1181
1299
  With skills: zero agent create --skills my-skill,other-skill --display-name "My Agent"
1182
1300
  With instructions: zero agent create --display-name "My Agent" --instructions-file ./instructions.md`
1183
1301
  ).action(
@@ -1196,10 +1314,12 @@ Examples:
1196
1314
  }
1197
1315
  }
1198
1316
  }
1317
+ const avatarUrl = resolveAvatarUrl(options);
1199
1318
  const agent = await createZeroAgent({
1200
1319
  displayName: options.displayName,
1201
1320
  description: options.description,
1202
1321
  sound: options.sound,
1322
+ avatarUrl,
1203
1323
  customSkills
1204
1324
  });
1205
1325
  if (options.instructionsFile) {
@@ -1233,18 +1353,25 @@ Examples:
1233
1353
  // src/commands/zero/agent/edit.ts
1234
1354
  init_esm_shims();
1235
1355
  import { readFileSync as readFileSync2 } from "fs";
1356
+ function hasAvatarUpdate(options) {
1357
+ return options.avatar !== void 0 || options.avatarRotation !== void 0 || options.avatarSkin !== void 0 || options.avatarHairStyle !== void 0 || options.avatarHairColor !== void 0 || options.avatarExpression !== void 0 || options.avatarIntensity !== void 0;
1358
+ }
1236
1359
  function hasAgentFieldUpdate(options) {
1237
- return options.displayName !== void 0 || options.description !== void 0 || options.sound !== void 0 || options.skills !== void 0 || options.addSkill !== void 0 || options.removeSkill !== void 0 || options.modelProvider !== void 0 || options.model !== void 0;
1360
+ return options.displayName !== void 0 || options.description !== void 0 || options.sound !== void 0 || hasAvatarUpdate(options) || options.skills !== void 0 || options.addSkill !== void 0 || options.removeSkill !== void 0 || options.modelProvider !== void 0 || options.model !== void 0;
1238
1361
  }
1239
1362
  async function applyAgentUpdate(agentId, options) {
1363
+ const hasAvatar = hasAvatarUpdate(options);
1364
+ const resolvedAvatarUrl = hasAvatar ? resolveAvatarUrl(options) : void 0;
1240
1365
  const current = await getZeroAgent(agentId);
1241
1366
  const customSkills = resolveCustomSkills(options, current.customSkills ?? []);
1242
1367
  const modelProviderId = options.modelProvider !== void 0 ? parseModelFlag(options.modelProvider) : current.modelProviderId;
1243
1368
  const selectedModel = options.model !== void 0 ? parseModelFlag(options.model) : current.selectedModel;
1369
+ const avatarUrl = hasAvatar ? resolvedAvatarUrl : current.avatarUrl ?? void 0;
1244
1370
  await updateZeroAgent(agentId, {
1245
1371
  displayName: options.displayName !== void 0 ? options.displayName : current.displayName ?? void 0,
1246
1372
  description: options.description !== void 0 ? options.description : current.description ?? void 0,
1247
1373
  sound: options.sound !== void 0 ? options.sound : current.sound ?? void 0,
1374
+ avatarUrl,
1248
1375
  customSkills,
1249
1376
  modelProviderId,
1250
1377
  selectedModel
@@ -1295,7 +1422,19 @@ function resolveCustomSkills(options, existing) {
1295
1422
  var editCommand = new Command().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(
1296
1423
  "--sound <tone>",
1297
1424
  "New tone: professional, friendly, direct, supportive"
1425
+ ).option("--avatar <preset>", "Avatar preset: preset:0 through preset:4").option(
1426
+ "--avatar-rotation <1-5>",
1427
+ "Head angle: 1=far-left 3=center 5=far-right"
1428
+ ).option(
1429
+ "--avatar-skin <tone>",
1430
+ "Skin tone: light | light-medium | medium | medium-dark | dark"
1431
+ ).option("--avatar-hair-style <1-5>", "Hair style: 1\u20135").option(
1432
+ "--avatar-hair-color <color>",
1433
+ "Hair color: blonde | teal | grey | pink | brown"
1298
1434
  ).option(
1435
+ "--avatar-expression <expr>",
1436
+ "Expression: calm | content | neutral | pleasant | excited"
1437
+ ).option("--avatar-intensity <level>", "Intensity: chill | normal | hyped").option(
1299
1438
  "--skills <items>",
1300
1439
  "Comma-separated custom skill names to attach (replaces existing)"
1301
1440
  ).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").option(
@@ -1307,9 +1446,29 @@ var editCommand = new Command().name("edit").description("Edit a zero agent").ar
1307
1446
  ).addHelpText(
1308
1447
  "after",
1309
1448
  `
1449
+ Avatar:
1450
+ Quick presets (--avatar):
1451
+ preset:0 light skin, brown hair, calm, hyped
1452
+ preset:1 light-medium skin, grey hair, calm, normal
1453
+ preset:2 medium skin, pink hair, neutral, chill
1454
+ preset:3 medium-dark skin, blonde hair, pleasant, hyped
1455
+ preset:4 dark skin, teal hair, excited, normal
1456
+
1457
+ Custom attributes (--avatar-* flags, replace the entire avatar):
1458
+ --avatar-rotation 1=far-left 3=center(default) 5=far-right
1459
+ --avatar-skin light / light-medium / medium(default) / medium-dark / dark
1460
+ --avatar-hair-style 1\u20135 (default: 1)
1461
+ --avatar-hair-color blonde / teal / grey / pink / brown(default)
1462
+ --avatar-expression calm(default) / content / neutral / pleasant / excited
1463
+ --avatar-intensity chill / normal(default) / hyped
1464
+
1465
+ Note: --avatar and --avatar-* cannot be used together.
1466
+
1310
1467
  Examples:
1311
1468
  Update description: zero agent edit <agent-id> --description "new role"
1312
1469
  Update tone: zero agent edit <agent-id> --sound friendly
1470
+ Quick preset avatar: zero agent edit <agent-id> --avatar preset:2
1471
+ Custom avatar: zero agent edit <agent-id> --avatar-skin dark --avatar-hair-color teal --avatar-intensity hyped
1313
1472
  Replace all skills: zero agent edit <agent-id> --skills my-skill,other-skill
1314
1473
  Add a skill: zero agent edit <agent-id> --add-skill my-skill
1315
1474
  Remove a skill: zero agent edit <agent-id> --remove-skill my-skill
@@ -1330,7 +1489,7 @@ Notes:
1330
1489
  const hasAgentUpdate = hasAgentFieldUpdate(options);
1331
1490
  if (!hasAgentUpdate && !options.instructionsFile) {
1332
1491
  throw new Error(
1333
- "At least one option is required (--display-name, --description, --sound, --skills, --add-skill, --remove-skill, --model-provider, --model, --instructions-file)"
1492
+ "At least one option is required (--display-name, --description, --sound, --avatar, --avatar-*, --skills, --add-skill, --remove-skill, --model-provider, --model, --instructions-file)"
1334
1493
  );
1335
1494
  }
1336
1495
  if (hasAgentUpdate) {
@@ -6637,7 +6796,7 @@ function registerZeroCommands(prog, commands) {
6637
6796
  var program = new Command();
6638
6797
  program.name("zero").description(
6639
6798
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
6640
- ).version("9.129.1").addHelpText(
6799
+ ).version("9.130.0").addHelpText(
6641
6800
  "after",
6642
6801
  `
6643
6802
  Examples: