@vm0/cli 9.161.8 → 9.161.9

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/zero.js CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  connectorTypeSchema,
22
22
  createComputerUseReadCommand,
23
23
  createComputerUseWriteCommand,
24
+ createGithubLabelListener,
24
25
  createLocalBrowserReadCommand,
25
26
  createLocalBrowserWriteCommand,
26
27
  createSkill,
@@ -29,6 +30,7 @@ import {
29
30
  createZeroRun,
30
31
  decodeCliTokenPayload,
31
32
  decodeZeroTokenPayload,
33
+ deleteGithubLabelListener,
32
34
  deleteLocalBrowserHost,
33
35
  deleteSkill,
34
36
  deleteZeroAgent,
@@ -64,6 +66,7 @@ import {
64
66
  getConnectorGenerationTypes,
65
67
  getConnectorTypeForSecretName,
66
68
  getDefaultAuthMethod,
69
+ getGithubInstallation,
67
70
  getLocalBrowserReadCommand,
68
71
  getScopeDiff,
69
72
  getSecretsForAuthMethod,
@@ -139,6 +142,7 @@ import {
139
142
  source_default,
140
143
  submitDeveloperSupport,
141
144
  switchZeroOrg,
145
+ updateGithubLabelListener,
142
146
  updateSkill,
143
147
  updateZeroAgent,
144
148
  updateZeroAgentInstructions,
@@ -150,7 +154,7 @@ import {
150
154
  zeroAgentCustomSkillNameSchema,
151
155
  zeroLocalAgentCommand,
152
156
  zeroTokenAllowsFeatureSwitch
153
- } from "./chunk-BWCVGYRL.js";
157
+ } from "./chunk-JXO3PHAE.js";
154
158
  import {
155
159
  __commonJS,
156
160
  __require,
@@ -32432,6 +32436,160 @@ Notes:
32432
32436
  )
32433
32437
  );
32434
32438
 
32439
+ // src/commands/zero/github/label-listener/index.ts
32440
+ init_esm_shims();
32441
+ function parseTriggerMode(value) {
32442
+ if (value === "created_by_me" || value === "anyone") {
32443
+ return value;
32444
+ }
32445
+ throw new Error("trigger-mode must be one of: created_by_me, anyone");
32446
+ }
32447
+ function enabledLabel(listener) {
32448
+ return listener.enabled ? source_default.green("yes") : source_default.dim("no");
32449
+ }
32450
+ function manageableLabel(listener) {
32451
+ return listener.canManage ? source_default.green("yes") : source_default.dim("no");
32452
+ }
32453
+ function printListeners(listeners) {
32454
+ if (listeners.length === 0) {
32455
+ console.log(source_default.dim("No GitHub label listeners found"));
32456
+ return;
32457
+ }
32458
+ const idWidth = Math.max(
32459
+ 2,
32460
+ ...listeners.map((listener) => {
32461
+ return listener.id.length;
32462
+ })
32463
+ );
32464
+ const labelWidth = Math.max(
32465
+ 5,
32466
+ ...listeners.map((listener) => {
32467
+ return listener.labelName.length;
32468
+ })
32469
+ );
32470
+ const agentWidth = Math.max(
32471
+ 5,
32472
+ ...listeners.map((listener) => {
32473
+ return (listener.agent?.name ?? "-").length;
32474
+ })
32475
+ );
32476
+ console.log(
32477
+ source_default.dim(
32478
+ [
32479
+ "ID".padEnd(idWidth),
32480
+ "LABEL".padEnd(labelWidth),
32481
+ "AGENT".padEnd(agentWidth),
32482
+ "TRIGGER".padEnd(13),
32483
+ "ENABLED",
32484
+ "CAN MANAGE"
32485
+ ].join(" ")
32486
+ )
32487
+ );
32488
+ for (const listener of listeners) {
32489
+ console.log(
32490
+ [
32491
+ listener.id.padEnd(idWidth),
32492
+ listener.labelName.padEnd(labelWidth),
32493
+ (listener.agent?.name ?? "-").padEnd(agentWidth),
32494
+ listener.triggerMode.padEnd(13),
32495
+ enabledLabel(listener).padEnd(7),
32496
+ manageableLabel(listener)
32497
+ ].join(" ")
32498
+ );
32499
+ }
32500
+ }
32501
+ var listCommand9 = new Command().name("list").alias("ls").description("List GitHub label listeners for the active organization").option("--json", "Print raw JSON").action(
32502
+ withErrorHandler(async (options) => {
32503
+ const installation = await getGithubInstallation();
32504
+ if (options.json) {
32505
+ console.log(JSON.stringify(installation.labelListeners));
32506
+ return;
32507
+ }
32508
+ printListeners(installation.labelListeners);
32509
+ })
32510
+ );
32511
+ var createCommand2 = new Command().name("create").description("Create a GitHub label listener").requiredOption("--label <name>", "GitHub label name to watch").requiredOption(
32512
+ "--agent-id <id>",
32513
+ "Agent ID to run when the label is applied"
32514
+ ).requiredOption("--prompt <text>", "Prompt to pass to the agent").option(
32515
+ "--trigger-mode <mode>",
32516
+ "Who can trigger the listener: anyone | created_by_me",
32517
+ "anyone"
32518
+ ).option("--disabled", "Create the listener disabled").option("--json", "Print raw JSON").action(
32519
+ withErrorHandler(
32520
+ async (options) => {
32521
+ const result = await createGithubLabelListener({
32522
+ labelName: options.label,
32523
+ agentId: options.agentId,
32524
+ prompt: options.prompt,
32525
+ triggerMode: parseTriggerMode(options.triggerMode),
32526
+ enabled: options.disabled ? false : void 0
32527
+ });
32528
+ if (options.json) {
32529
+ console.log(JSON.stringify(result.listener));
32530
+ return;
32531
+ }
32532
+ console.log(`Created GitHub label listener ${result.listener.id}`);
32533
+ }
32534
+ )
32535
+ );
32536
+ var updateCommand = new Command().name("update").alias("edit").description("Update a GitHub label listener").argument("<listener-id>", "GitHub label listener ID").option("--label <name>", "New GitHub label name").option("--agent-id <id>", "New agent ID").option("--prompt <text>", "New prompt").option(
32537
+ "--trigger-mode <mode>",
32538
+ "Who can trigger the listener: anyone | created_by_me"
32539
+ ).option("--enable", "Enable the listener").option("--disable", "Disable the listener").option("--json", "Print raw JSON").action(
32540
+ withErrorHandler(
32541
+ async (listenerId, options) => {
32542
+ if (options.enable && options.disable) {
32543
+ throw new Error("Use only one of --enable or --disable");
32544
+ }
32545
+ const body = {};
32546
+ if (options.label !== void 0) body.labelName = options.label;
32547
+ if (options.agentId !== void 0) body.agentId = options.agentId;
32548
+ if (options.prompt !== void 0) body.prompt = options.prompt;
32549
+ if (options.triggerMode !== void 0) {
32550
+ body.triggerMode = parseTriggerMode(options.triggerMode);
32551
+ }
32552
+ if (options.enable) body.enabled = true;
32553
+ if (options.disable) body.enabled = false;
32554
+ if (Object.keys(body).length === 0) {
32555
+ throw new Error(
32556
+ "Provide at least one change: --label, --agent-id, --prompt, --trigger-mode, --enable, or --disable"
32557
+ );
32558
+ }
32559
+ const result = await updateGithubLabelListener(listenerId, body);
32560
+ if (options.json) {
32561
+ console.log(JSON.stringify(result.listener));
32562
+ return;
32563
+ }
32564
+ console.log(`Updated GitHub label listener ${result.listener.id}`);
32565
+ }
32566
+ )
32567
+ );
32568
+ var deleteCommand5 = new Command().name("delete").alias("rm").description("Delete a GitHub label listener").argument("<listener-id>", "GitHub label listener ID").option("--json", "Print raw JSON").action(
32569
+ withErrorHandler(
32570
+ async (listenerId, options) => {
32571
+ const result = await deleteGithubLabelListener(listenerId);
32572
+ if (options.json) {
32573
+ console.log(JSON.stringify(result));
32574
+ return;
32575
+ }
32576
+ console.log(`Deleted GitHub label listener ${listenerId}`);
32577
+ }
32578
+ )
32579
+ );
32580
+ var labelListenerCommand = new Command().name("label-listener").alias("label-listeners").alias("labels").description("Manage GitHub label listeners").addCommand(listCommand9).addCommand(createCommand2).addCommand(updateCommand).addCommand(deleteCommand5).addHelpText(
32581
+ "after",
32582
+ `
32583
+ Examples:
32584
+ List listeners: zero github label-listener list
32585
+ Create listener: zero github label-listener create --label zero --agent-id <agent-id> --prompt "Handle this issue"
32586
+ Edit listener: zero github label-listener update <listener-id> --disable
32587
+ Delete listener: zero github label-listener delete <listener-id>
32588
+
32589
+ Notes:
32590
+ - Updating or deleting a listener is allowed only for the listener owner or an org admin.`
32591
+ );
32592
+
32435
32593
  // src/commands/zero/github/upload-file.ts
32436
32594
  init_esm_shims();
32437
32595
  import { readFileSync as readFileSync5, statSync } from "fs";
@@ -32531,12 +32689,13 @@ Notes:
32531
32689
  );
32532
32690
 
32533
32691
  // src/commands/zero/github/index.ts
32534
- var zeroGithubCommand = new Command().name("github").description("Upload files to GitHub issues and download GitHub files").addCommand(downloadFileCommand).addCommand(uploadFileCommand).addHelpText(
32692
+ var zeroGithubCommand = new Command().name("github").description("Manage GitHub integration files and label listeners").addCommand(downloadFileCommand).addCommand(labelListenerCommand).addCommand(uploadFileCommand).addHelpText(
32535
32693
  "after",
32536
32694
  `
32537
32695
  Examples:
32538
32696
  Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42
32539
- Download a file: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/out.png`
32697
+ Download a file: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/out.png
32698
+ List labels: zero github label-listener list`
32540
32699
  );
32541
32700
 
32542
32701
  // src/commands/zero/slack/index.ts
@@ -32748,7 +32907,7 @@ function statusLabel(bot) {
32748
32907
  if (bot.tokenStatus === "invalid") return source_default.red("invalid");
32749
32908
  return source_default.yellow("unknown");
32750
32909
  }
32751
- var listCommand9 = new Command().name("list").alias("ls").description("List Telegram bots available in the active organization").addHelpText(
32910
+ var listCommand10 = new Command().name("list").alias("ls").description("List Telegram bots available in the active organization").addHelpText(
32752
32911
  "after",
32753
32912
  `
32754
32913
  Examples:
@@ -32807,7 +32966,7 @@ Notes:
32807
32966
  );
32808
32967
 
32809
32968
  // src/commands/zero/telegram/bot/index.ts
32810
- var zeroTelegramBotCommand = new Command().name("bot").description("Inspect Telegram bots").addCommand(listCommand9).addHelpText(
32969
+ var zeroTelegramBotCommand = new Command().name("bot").description("Inspect Telegram bots").addCommand(listCommand10).addHelpText(
32811
32970
  "after",
32812
32971
  `
32813
32972
  Examples:
@@ -33221,7 +33380,7 @@ function truncateValue2(value, maxLength = 60) {
33221
33380
  }
33222
33381
  return value.slice(0, maxLength - 15) + "... [truncated]";
33223
33382
  }
33224
- var listCommand10 = new Command().name("list").alias("ls").description("List all variables").action(
33383
+ var listCommand11 = new Command().name("list").alias("ls").description("List all variables").action(
33225
33384
  withErrorHandler(async () => {
33226
33385
  const result = await listZeroVariables();
33227
33386
  if (result.variables.length === 0) {
@@ -33277,7 +33436,7 @@ var setCommand5 = new Command().name("set").description("Create or update a vari
33277
33436
 
33278
33437
  // src/commands/zero/variable/delete.ts
33279
33438
  init_esm_shims();
33280
- var deleteCommand5 = new Command().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
33439
+ var deleteCommand6 = new Command().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
33281
33440
  withErrorHandler(async (name, options) => {
33282
33441
  if (!options.yes) {
33283
33442
  if (!isInteractive()) {
@@ -33298,7 +33457,7 @@ var deleteCommand5 = new Command().name("delete").description("Delete a variable
33298
33457
  );
33299
33458
 
33300
33459
  // src/commands/zero/variable/index.ts
33301
- var zeroVariableCommand = new Command().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand10).addCommand(setCommand5).addCommand(deleteCommand5);
33460
+ var zeroVariableCommand = new Command().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand11).addCommand(setCommand5).addCommand(deleteCommand6);
33302
33461
 
33303
33462
  // src/commands/zero/whoami.ts
33304
33463
  init_esm_shims();
@@ -33487,7 +33646,7 @@ function readSkillDirectory(dirPath) {
33487
33646
  }
33488
33647
 
33489
33648
  // src/commands/zero/skill/create.ts
33490
- var createCommand2 = new Command().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(
33649
+ var createCommand3 = new Command().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(
33491
33650
  "after",
33492
33651
  `
33493
33652
  Examples:
@@ -33577,7 +33736,7 @@ Examples:
33577
33736
 
33578
33737
  // src/commands/zero/skill/list.ts
33579
33738
  init_esm_shims();
33580
- var listCommand11 = new Command().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
33739
+ var listCommand12 = new Command().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
33581
33740
  "after",
33582
33741
  `
33583
33742
  Examples:
@@ -33623,7 +33782,7 @@ Examples:
33623
33782
 
33624
33783
  // src/commands/zero/skill/delete.ts
33625
33784
  init_esm_shims();
33626
- var deleteCommand6 = new Command().name("delete").alias("rm").description("Delete a custom skill from the organization").argument("<name>", "Skill name").option("-y, --yes", "Skip confirmation prompt").addHelpText(
33785
+ var deleteCommand7 = new Command().name("delete").alias("rm").description("Delete a custom skill from the organization").argument("<name>", "Skill name").option("-y, --yes", "Skip confirmation prompt").addHelpText(
33627
33786
  "after",
33628
33787
  `
33629
33788
  Examples:
@@ -33655,7 +33814,7 @@ Notes:
33655
33814
  );
33656
33815
 
33657
33816
  // src/commands/zero/skill/index.ts
33658
- var zeroSkillCommand = new Command("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand11).addCommand(deleteCommand6).addHelpText(
33817
+ var zeroSkillCommand = new Command("skill").description("Manage custom skills").addCommand(createCommand3).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand12).addCommand(deleteCommand7).addHelpText(
33659
33818
  "after",
33660
33819
  `
33661
33820
  Examples:
@@ -33696,7 +33855,7 @@ function formatStatus(status) {
33696
33855
  function formatTime(iso) {
33697
33856
  return new Date(iso).toISOString().replace(/\.\d{3}Z$/, "Z");
33698
33857
  }
33699
- var listCommand12 = new Command().name("list").alias("ls").description("List agent run logs").option("--agent <id>", "Filter by Zero agent ID").option(
33858
+ var listCommand13 = new Command().name("list").alias("ls").description("List agent run logs").option("--agent <id>", "Filter by Zero agent ID").option(
33700
33859
  "--status <status>",
33701
33860
  "Filter by status (queued|pending|running|completed|failed|timeout|cancelled)"
33702
33861
  ).option(
@@ -33959,7 +34118,7 @@ async function showAgentEvents(runId, options) {
33959
34118
  renderer.render(parsed);
33960
34119
  }
33961
34120
  }
33962
- var zeroLogsCommand = new Command().name("logs").description("View and search agent run logs").argument("[runId]", "Run ID to view agent events for").addCommand(listCommand12).addCommand(searchCommand2).option(
34121
+ var zeroLogsCommand = new Command().name("logs").description("View and search agent run logs").argument("[runId]", "Run ID to view agent events for").addCommand(listCommand13).addCommand(searchCommand2).option(
33963
34122
  "--since <time>",
33964
34123
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)"
33965
34124
  ).option("--tail <n>", "Show last N entries (default: 5)").option("--head <n>", "Show first N entries").option("--all", "Fetch all log entries").addHelpText(
@@ -34165,13 +34324,13 @@ var zeroSearchCommand = new Command().name("search").description("Search logs, c
34165
34324
  if (sources.length > 1) {
34166
34325
  throw new Error("Only one --source is allowed.");
34167
34326
  }
34168
- const source = sources[0];
34169
- if (!SUPPORTED_SOURCES.includes(source)) {
34327
+ const source2 = sources[0];
34328
+ if (!SUPPORTED_SOURCES.includes(source2)) {
34170
34329
  throw new Error(
34171
- `Unknown --source "${source}". Expected one of: ${SUPPORTED_SOURCES.join(", ")}`
34330
+ `Unknown --source "${source2}". Expected one of: ${SUPPORTED_SOURCES.join(", ")}`
34172
34331
  );
34173
34332
  }
34174
- switch (source) {
34333
+ switch (source2) {
34175
34334
  case "logs":
34176
34335
  await runLogsSource(query, options);
34177
34336
  return;
@@ -34748,12 +34907,335 @@ import { readFileSync as readFileSync14 } from "fs";
34748
34907
 
34749
34908
  // src/commands/zero/shared/html-artifact-authoring.ts
34750
34909
  init_esm_shims();
34910
+
34911
+ // src/commands/zero/shared/open-design-registry.ts
34912
+ init_esm_shims();
34913
+ var OPEN_DESIGN_REPO = "vm0-ai/open-design";
34914
+ var OPEN_DESIGN_COMMIT = "d021b04720ace133f1d6133d1487326f5fc28f07";
34915
+ var OPEN_DESIGN_REGISTRY_VERSION = `${OPEN_DESIGN_REPO}@${OPEN_DESIGN_COMMIT}`;
34916
+ function source(path) {
34917
+ return {
34918
+ repo: OPEN_DESIGN_REPO,
34919
+ commit: OPEN_DESIGN_COMMIT,
34920
+ path
34921
+ };
34922
+ }
34923
+ var OPEN_DESIGN_REGISTRY = [
34924
+ {
34925
+ id: "od:skill:data-report",
34926
+ kind: "skill",
34927
+ name: "Data Report",
34928
+ description: "Turns source-backed data, rankings, metrics, or lists into a concise analytical report.",
34929
+ source: source("skills/data-report/SKILL.md"),
34930
+ targets: ["presentation", "website", "dashboard", "report", "docs"],
34931
+ tags: ["analysis", "data", "report", "ranking", "sources", "table"],
34932
+ triggers: ["report", "top 10", "ranking", "metrics", "analysis"],
34933
+ bestFor: ["source-backed reports", "ranked lists", "data summaries"],
34934
+ status: "curated",
34935
+ priority: 40
34936
+ },
34937
+ {
34938
+ id: "od:skill:article-magazine",
34939
+ kind: "skill",
34940
+ name: "Article Magazine",
34941
+ description: "Shapes research or editorial material into a magazine-like narrative with strong hierarchy.",
34942
+ source: source("skills/article-magazine/SKILL.md"),
34943
+ targets: ["presentation", "website", "poster", "report", "docs"],
34944
+ tags: ["editorial", "magazine", "article", "narrative", "research"],
34945
+ triggers: ["magazine", "editorial", "story", "essay", "briefing"],
34946
+ bestFor: [
34947
+ "editorial reports",
34948
+ "narrative explainers",
34949
+ "research synthesis"
34950
+ ],
34951
+ status: "curated",
34952
+ priority: 28
34953
+ },
34954
+ {
34955
+ id: "od:skill:design-brief",
34956
+ kind: "skill",
34957
+ name: "Design Brief",
34958
+ description: "Converts a product, brand, or feature request into a structured design brief.",
34959
+ source: source("skills/design-brief/SKILL.md"),
34960
+ targets: ["presentation", "website", "mobile-app", "docs"],
34961
+ tags: ["design", "brief", "product", "brand", "requirements"],
34962
+ triggers: ["design brief", "brand", "product direction", "requirements"],
34963
+ bestFor: ["product design briefs", "brand-driven websites"],
34964
+ status: "curated",
34965
+ priority: 16
34966
+ },
34967
+ {
34968
+ id: "od:template:dashboard",
34969
+ kind: "template",
34970
+ name: "Dashboard",
34971
+ description: "Dense operational dashboard layout for KPIs, lists, filters, and repeated scanning.",
34972
+ source: source("design-templates/dashboard"),
34973
+ targets: ["website", "dashboard", "report"],
34974
+ tags: ["dashboard", "analytics", "kpi", "metrics", "operations", "table"],
34975
+ triggers: ["dashboard", "analytics", "monitoring", "metrics", "ops"],
34976
+ bestFor: ["metric-heavy pages", "status surfaces", "operational summaries"],
34977
+ compatibleWith: ["od:skill:data-report", "od:design-system:dashboard"],
34978
+ status: "curated",
34979
+ priority: 36
34980
+ },
34981
+ {
34982
+ id: "od:template:finance-report",
34983
+ kind: "template",
34984
+ name: "Finance Report",
34985
+ description: "Executive report layout with tables, callouts, trend blocks, and source notes.",
34986
+ source: source("design-templates/finance-report"),
34987
+ targets: ["presentation", "website", "report"],
34988
+ tags: ["report", "finance", "executive", "table", "analysis", "sources"],
34989
+ triggers: ["report", "brief", "analysis", "top 10", "finance"],
34990
+ bestFor: ["source-backed reports", "executive summaries", "ranked lists"],
34991
+ compatibleWith: ["od:skill:data-report", "od:design-system:dashboard"],
34992
+ status: "curated",
34993
+ priority: 34
34994
+ },
34995
+ {
34996
+ id: "od:template:docs-page",
34997
+ kind: "template",
34998
+ name: "Docs Page",
34999
+ description: "Documentation-style page layout for structured explanations, navigation, and examples.",
35000
+ source: source("design-templates/docs-page"),
35001
+ targets: ["website", "docs", "report"],
35002
+ tags: ["docs", "explanation", "guide", "structured", "reference"],
35003
+ triggers: ["docs", "documentation", "guide", "explain", "how to"],
35004
+ bestFor: ["technical explainers", "product docs", "implementation notes"],
35005
+ compatibleWith: ["od:skill:design-brief", "od:design-system:mono"],
35006
+ status: "curated",
35007
+ priority: 26
35008
+ },
35009
+ {
35010
+ id: "od:template:html-ppt-graphify-dark-graph",
35011
+ kind: "template",
35012
+ name: "Graphify Dark Graph",
35013
+ description: "Dark graph-heavy HTML presentation template for data stories and technical briefings.",
35014
+ source: source("design-templates/html-ppt-graphify-dark-graph"),
35015
+ targets: ["presentation", "report"],
35016
+ tags: ["presentation", "dark", "graph", "data", "technical", "metrics"],
35017
+ triggers: ["deck", "presentation", "graph", "dark", "data story"],
35018
+ bestFor: ["data presentations", "technical executive briefings"],
35019
+ compatibleWith: [
35020
+ "od:skill:data-report",
35021
+ "od:design-system:trading-terminal"
35022
+ ],
35023
+ status: "curated",
35024
+ priority: 32
35025
+ },
35026
+ {
35027
+ id: "od:template:html-ppt-zhangzara-retro-zine",
35028
+ kind: "template",
35029
+ name: "Zhangzara Retro Zine",
35030
+ description: "Expressive retro editorial HTML presentation template with zine-like composition.",
35031
+ source: source("design-templates/html-ppt-zhangzara-retro-zine"),
35032
+ targets: ["presentation", "poster", "report"],
35033
+ tags: ["presentation", "retro", "zine", "editorial", "expressive"],
35034
+ triggers: ["retro", "zine", "editorial", "magazine", "bold"],
35035
+ bestFor: [
35036
+ "editorial decks",
35037
+ "culture reports",
35038
+ "visually distinctive summaries"
35039
+ ],
35040
+ compatibleWith: [
35041
+ "od:skill:article-magazine",
35042
+ "od:design-system:warm-editorial"
35043
+ ],
35044
+ status: "curated",
35045
+ priority: 30
35046
+ },
35047
+ {
35048
+ id: "od:template:weekly-update",
35049
+ kind: "template",
35050
+ name: "Weekly Update",
35051
+ description: "Compact update deck/page structure for highlights, risks, next steps, and metrics.",
35052
+ source: source("design-templates/weekly-update"),
35053
+ targets: ["presentation", "report", "docs"],
35054
+ tags: ["update", "status", "briefing", "report", "metrics"],
35055
+ triggers: ["weekly", "status", "update", "briefing"],
35056
+ bestFor: ["team updates", "status reports", "progress summaries"],
35057
+ compatibleWith: ["od:skill:data-report", "od:design-system:dashboard"],
35058
+ status: "curated",
35059
+ priority: 24
35060
+ },
35061
+ {
35062
+ id: "od:template:web-prototype-taste-editorial",
35063
+ kind: "template",
35064
+ name: "Taste Editorial Web Prototype",
35065
+ description: "Editorial website prototype direction with image-led sections and strong copy hierarchy.",
35066
+ source: source("design-templates/web-prototype-taste-editorial"),
35067
+ targets: ["website", "poster"],
35068
+ tags: ["website", "editorial", "brand", "visual", "prototype"],
35069
+ triggers: ["landing", "site", "brand", "editorial", "launch"],
35070
+ bestFor: ["brand websites", "launch pages", "editorial product pages"],
35071
+ compatibleWith: ["od:skill:article-magazine", "od:design-system:editorial"],
35072
+ status: "curated",
35073
+ priority: 30
35074
+ },
35075
+ {
35076
+ id: "od:design-system:dashboard",
35077
+ kind: "design-system",
35078
+ name: "Dashboard",
35079
+ description: "Quiet, dense interface system for dashboards, tables, filters, and repeat workflows.",
35080
+ source: source("design-systems/dashboard"),
35081
+ targets: ["website", "dashboard", "report"],
35082
+ tags: ["dashboard", "neutral", "dense", "table", "operations", "charts"],
35083
+ triggers: ["dashboard", "analytics", "metrics", "ops", "report"],
35084
+ bestFor: ["operational UIs", "data reports", "admin surfaces"],
35085
+ status: "curated",
35086
+ priority: 36
35087
+ },
35088
+ {
35089
+ id: "od:design-system:trading-terminal",
35090
+ kind: "design-system",
35091
+ name: "Trading Terminal",
35092
+ description: "Dark dense market-terminal aesthetic for charts, feeds, tables, and high information density.",
35093
+ source: source("design-systems/trading-terminal"),
35094
+ targets: ["presentation", "website", "dashboard", "report"],
35095
+ tags: ["dark", "terminal", "finance", "data", "charts", "dense"],
35096
+ triggers: ["dark", "terminal", "trading", "chart", "graph"],
35097
+ bestFor: ["dark analytical reports", "graph-heavy dashboards"],
35098
+ status: "curated",
35099
+ priority: 32
35100
+ },
35101
+ {
35102
+ id: "od:design-system:warm-editorial",
35103
+ kind: "design-system",
35104
+ name: "Warm Editorial",
35105
+ description: "Warm editorial design system for readable narrative pages, zines, and reports.",
35106
+ source: source("design-systems/warm-editorial"),
35107
+ targets: ["presentation", "website", "poster", "report", "docs"],
35108
+ tags: ["warm", "editorial", "magazine", "narrative", "readable"],
35109
+ triggers: ["editorial", "magazine", "zine", "warm", "story"],
35110
+ bestFor: ["narrative reports", "editorial decks", "long-form pages"],
35111
+ status: "curated",
35112
+ priority: 30
35113
+ },
35114
+ {
35115
+ id: "od:design-system:editorial",
35116
+ kind: "design-system",
35117
+ name: "Editorial",
35118
+ description: "Clean editorial design system with strong typography, media framing, and section rhythm.",
35119
+ source: source("design-systems/editorial"),
35120
+ targets: ["presentation", "website", "poster", "report", "docs"],
35121
+ tags: ["editorial", "typography", "media", "brand", "article"],
35122
+ triggers: ["editorial", "article", "brand", "landing", "magazine"],
35123
+ bestFor: ["brand sites", "article-style reports", "visual narratives"],
35124
+ status: "curated",
35125
+ priority: 28
35126
+ },
35127
+ {
35128
+ id: "od:design-system:mono",
35129
+ kind: "design-system",
35130
+ name: "Mono",
35131
+ description: "Minimal monospace-oriented system for documentation, technical pages, and precise reports.",
35132
+ source: source("design-systems/mono"),
35133
+ targets: ["website", "docs", "report"],
35134
+ tags: ["mono", "docs", "technical", "minimal", "structured"],
35135
+ triggers: ["docs", "technical", "reference", "minimal", "api"],
35136
+ bestFor: ["technical documentation", "implementation reports"],
35137
+ status: "curated",
35138
+ priority: 20
35139
+ }
35140
+ ];
35141
+ function normalizeText(value) {
35142
+ return value.toLowerCase();
35143
+ }
35144
+ function tokenize(value) {
35145
+ return normalizeText(value).split(/[^a-z0-9]+/u).filter((token) => {
35146
+ return token.length >= 2;
35147
+ });
35148
+ }
35149
+ function phraseScore(values, prompt, weight) {
35150
+ if (!values) {
35151
+ return 0;
35152
+ }
35153
+ return values.reduce((score, value) => {
35154
+ return prompt.includes(normalizeText(value)) ? score + weight : score;
35155
+ }, 0);
35156
+ }
35157
+ function tokenScore(values, promptTokens, weight) {
35158
+ if (!values) {
35159
+ return 0;
35160
+ }
35161
+ return values.reduce((score, value) => {
35162
+ const matches = tokenize(value).filter((token) => {
35163
+ return promptTokens.has(token);
35164
+ });
35165
+ return score + matches.length * weight;
35166
+ }, 0);
35167
+ }
35168
+ function scoreEntry(entry, target, prompt) {
35169
+ const normalizedPrompt = normalizeText(prompt);
35170
+ const promptTokens = new Set(tokenize(prompt));
35171
+ const targetScore = entry.targets.includes(target) ? 100 : 0;
35172
+ const curationScore = entry.status === "curated" ? 20 : entry.status === "experimental" ? -20 : -1e3;
35173
+ return targetScore + curationScore + (entry.priority ?? 0) + phraseScore(entry.triggers, normalizedPrompt, 40) + phraseScore(entry.bestFor, normalizedPrompt, 15) + tokenScore(entry.tags, promptTokens, 10) + tokenScore(entry.description.split(" "), promptTokens, 2);
35174
+ }
35175
+ function selectByKind(kind, target, prompt, limit) {
35176
+ return OPEN_DESIGN_REGISTRY.filter((entry) => {
35177
+ return entry.kind === kind && entry.status !== "hidden";
35178
+ }).map((entry) => {
35179
+ return { entry, score: scoreEntry(entry, target, prompt) };
35180
+ }).filter(({ score }) => {
35181
+ return score > 0;
35182
+ }).sort((left, right) => {
35183
+ if (right.score !== left.score) {
35184
+ return right.score - left.score;
35185
+ }
35186
+ return left.entry.id.localeCompare(right.entry.id);
35187
+ }).slice(0, limit).map(({ entry }) => {
35188
+ return entry;
35189
+ });
35190
+ }
35191
+ function selectOpenDesignCandidates(options) {
35192
+ const limitPerKind = options.limitPerKind ?? 8;
35193
+ return {
35194
+ registryVersion: OPEN_DESIGN_REGISTRY_VERSION,
35195
+ source: {
35196
+ repo: OPEN_DESIGN_REPO,
35197
+ commit: OPEN_DESIGN_COMMIT
35198
+ },
35199
+ candidates: {
35200
+ skills: selectByKind(
35201
+ "skill",
35202
+ options.target,
35203
+ options.prompt,
35204
+ limitPerKind
35205
+ ),
35206
+ templates: selectByKind(
35207
+ "template",
35208
+ options.target,
35209
+ options.prompt,
35210
+ limitPerKind
35211
+ ),
35212
+ designSystems: selectByKind(
35213
+ "design-system",
35214
+ options.target,
35215
+ options.prompt,
35216
+ limitPerKind
35217
+ )
35218
+ }
35219
+ };
35220
+ }
35221
+
35222
+ // src/commands/zero/shared/html-artifact-authoring.ts
34751
35223
  function slugify(value) {
34752
35224
  const slug = value.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").replace(/-{2,}/gu, "-").slice(0, 48).replace(/-+$/u, "");
34753
35225
  return slug.length >= 3 ? slug : "html-artifact";
34754
35226
  }
34755
35227
  function titleForKind(kind) {
34756
- return kind === "presentation" ? "HTML presentation" : "hosted website";
35228
+ const titles = {
35229
+ presentation: "HTML presentation",
35230
+ website: "hosted website",
35231
+ dashboard: "dashboard",
35232
+ "mobile-app": "mobile app prototype",
35233
+ poster: "poster",
35234
+ "intro-video": "intro video storyboard",
35235
+ report: "report",
35236
+ docs: "documentation site"
35237
+ };
35238
+ return titles[kind];
34757
35239
  }
34758
35240
  function outputDirForSite(site) {
34759
35241
  return `./opendesign/mockups/${site}`;
@@ -34763,15 +35245,58 @@ function createHtmlArtifactAuthoringPacket(options) {
34763
35245
  const outputDir = outputDirForSite(site);
34764
35246
  const hostCommand = `zero host ${outputDir} --site ${site}${options.kind === "website" ? " --spa" : ""}`;
34765
35247
  const title = titleForKind(options.kind);
35248
+ const candidateSlice = selectOpenDesignCandidates({
35249
+ target: options.kind,
35250
+ prompt: [
35251
+ options.prompt,
35252
+ options.slugSource ?? "",
35253
+ ...options.details,
35254
+ ...options.artifactRules
35255
+ ].join("\n")
35256
+ });
35257
+ const selectionSchema = {
35258
+ skills: "string[]",
35259
+ template: "string",
35260
+ designSystem: "string | null",
35261
+ rationale: "string"
35262
+ };
34766
35263
  const instructions = [
34767
35264
  `# Zero built-in generate ${options.kind}`,
34768
35265
  "",
34769
- `You are the current agent. Author a production-quality ${title} as a static HTML artifact.`,
34770
- "Zero is not generating this artifact on the server. You are the author.",
35266
+ "This is an Open Design resource-selection packet for the current agent.",
35267
+ `Zero is not generating this ${title} on the server. You select resources, resolve them, and author the artifact.`,
34771
35268
  "",
34772
35269
  "## User Prompt",
34773
35270
  options.prompt,
34774
35271
  "",
35272
+ "## Stage 1: Resource Selection",
35273
+ "- Choose the Open Design resources from the bundled registry slice below.",
35274
+ "- Select one template, one or more skills, and zero or one design system.",
35275
+ "- Choose only IDs present in this packet; do not invent registry IDs.",
35276
+ "- Prefer compatible resources, but the user prompt is the highest-priority signal.",
35277
+ "- Treat the selection JSON as internal working state, then continue to authoring.",
35278
+ "",
35279
+ "## Selection Output Schema",
35280
+ "```json",
35281
+ JSON.stringify(selectionSchema, null, 2),
35282
+ "```",
35283
+ "",
35284
+ "## Candidate Registry Slice",
35285
+ `Registry: \`${candidateSlice.registryVersion}\``,
35286
+ "",
35287
+ "```json",
35288
+ JSON.stringify(candidateSlice.candidates, null, 2),
35289
+ "```",
35290
+ "",
35291
+ "## Stage 2: Resolve Selected Resources",
35292
+ "- For every selected resource, fetch or read the referenced Open Design source before authoring.",
35293
+ "- Source refs are pinned as `repo@commit:path`; use the commit in the packet for reproducibility.",
35294
+ "- For directory refs, inspect the most relevant files such as `SKILL.md`, `DESIGN.md`, `README.md`, tokens, examples, and templates.",
35295
+ "- If a source file cannot be fetched, state that limitation and fall back to the registry metadata for that resource.",
35296
+ "",
35297
+ "## Stage 3: Author Artifact",
35298
+ `Author a production-quality ${title} as a static HTML artifact using the selected Open Design resources.`,
35299
+ "",
34775
35300
  "## Output Contract",
34776
35301
  `- Write the artifact under \`${outputDir}/\`.`,
34777
35302
  `- The entry file must be \`${outputDir}/index.html\`.`,
@@ -34785,9 +35310,9 @@ function createHtmlArtifactAuthoringPacket(options) {
34785
35310
  return `- ${detail}`;
34786
35311
  }),
34787
35312
  "",
34788
- "## OpenDesign-Style Authoring Rules",
34789
- "- Read the local codebase, brand assets, and existing design systems before choosing a visual direction.",
34790
- "- If no design system is available, choose one clear aesthetic direction and hold it across the artifact.",
35313
+ "## Open Design Authoring Rules",
35314
+ "- Let the selected template define structure, the selected design system define visual language, and the selected skills define process.",
35315
+ "- Read the local codebase, brand assets, and existing design systems when the prompt depends on this repository.",
34791
35316
  "- Avoid generic AI design defaults: no stock SaaS gradients, no emoji-as-icons, no filler stats, no decorative chrome that does not help the artifact.",
34792
35317
  "- Build the actual artifact first, not a marketing explanation of the artifact.",
34793
35318
  "- Make controls and interactions real when they are visible.",
@@ -34810,9 +35335,18 @@ function createHtmlArtifactAuthoringPacket(options) {
34810
35335
  "```"
34811
35336
  ].join("\n");
34812
35337
  return {
34813
- type: "html-artifact-authoring",
35338
+ type: "open-design-resource-selection",
34814
35339
  kind: options.kind,
34815
35340
  prompt: options.prompt,
35341
+ registryVersion: candidateSlice.registryVersion,
35342
+ selection: {
35343
+ candidates: candidateSlice.candidates,
35344
+ outputSchema: selectionSchema
35345
+ },
35346
+ authoring: {
35347
+ details: options.details,
35348
+ artifactRules: options.artifactRules
35349
+ },
34816
35350
  outputDir,
34817
35351
  site,
34818
35352
  hostCommand,
@@ -34879,7 +35413,7 @@ Examples:
34879
35413
  ${config.examples}
34880
35414
 
34881
35415
  Output:
34882
- Prints the generated /f/ HTML presentation URL and metadata. With openDesignGenerate enabled, prints an OpenDesign-style authoring packet for the current agent instead.
35416
+ Prints the generated /f/ HTML presentation URL and metadata. With openDesignGenerate enabled, prints an Open Design registry-selection packet for the current agent instead.
34883
35417
 
34884
35418
  Notes:
34885
35419
  - Authenticates via ZERO_TOKEN
@@ -36378,7 +36912,7 @@ Examples:
36378
36912
  Pipe prompt: cat brief.txt | zero built-in generate website
36379
36913
 
36380
36914
  Output:
36381
- Generates and publishes a hosted website. With openDesignGenerate enabled, prints an OpenDesign-style authoring packet for the current agent instead.
36915
+ Generates and publishes a hosted website. With openDesignGenerate enabled, prints an Open Design registry-selection packet for the current agent instead.
36382
36916
 
36383
36917
  Notes:
36384
36918
  - Authenticates via ZERO_TOKEN
@@ -37290,7 +37824,7 @@ function getModelSwitchGuidance(integration = getCurrentIntegration()) {
37290
37824
  }
37291
37825
  return "Open https://app.vm0.ai and switch models from the model selector next to the input box.";
37292
37826
  }
37293
- var listCommand13 = new Command().name("list").alias("ls").description("List models allowed by the current organization").action(
37827
+ var listCommand14 = new Command().name("list").alias("ls").description("List models allowed by the current organization").action(
37294
37828
  withErrorHandler(async () => {
37295
37829
  const result = await listZeroModelPolicies();
37296
37830
  if (result.policies.length === 0) {
@@ -37326,7 +37860,7 @@ var listCommand13 = new Command().name("list").alias("ls").description("List mod
37326
37860
  var switchCommand = new Command().name("switch").description("Show how to switch models in the current environment").action(() => {
37327
37861
  console.log(getModelSwitchGuidance());
37328
37862
  });
37329
- var zeroModelCommand = new Command().name("model").description("List available models and model-switching guidance").addCommand(listCommand13).addCommand(switchCommand);
37863
+ var zeroModelCommand = new Command().name("model").description("List available models and model-switching guidance").addCommand(listCommand14).addCommand(switchCommand);
37330
37864
 
37331
37865
  // src/commands/zero/model-provider/index.ts
37332
37866
  init_esm_shims();
@@ -37337,7 +37871,7 @@ var MODEL_PROVIDER_SET_GUIDANCE = [
37337
37871
  "",
37338
37872
  "If an organization admin sets a model provider to subscription, members must use the bottom-left user menu, choose Preferences / Personal Models, and connect their personal subscription."
37339
37873
  ].join("\n");
37340
- var listCommand14 = new Command().name("list").alias("ls").description(
37874
+ var listCommand15 = new Command().name("list").alias("ls").description(
37341
37875
  "List provider routing for each model allowed by the organization"
37342
37876
  ).action(
37343
37877
  withErrorHandler(async () => {
@@ -37372,7 +37906,7 @@ var setCommand6 = new Command().name("set").description("Show where to adjust mo
37372
37906
  ${MODEL_PROVIDER_SET_GUIDANCE}`).action(() => {
37373
37907
  console.log(MODEL_PROVIDER_SET_GUIDANCE);
37374
37908
  });
37375
- var zeroModelProviderCommand = new Command().name("model-provider").description("Inspect model provider routing").addCommand(listCommand14).addCommand(setCommand6);
37909
+ var zeroModelProviderCommand = new Command().name("model-provider").description("Inspect model provider routing").addCommand(listCommand15).addCommand(setCommand6);
37376
37910
 
37377
37911
  // src/zero.ts
37378
37912
  var COMMAND_CAPABILITY_MAP = {
@@ -37493,7 +38027,7 @@ function registerZeroCommands(prog, commands) {
37493
38027
  var program = new Command();
37494
38028
  program.name("zero").description(
37495
38029
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
37496
- ).version("9.161.8").addHelpText("after", () => {
38030
+ ).version("9.161.9").addHelpText("after", () => {
37497
38031
  return buildZeroHelpText();
37498
38032
  });
37499
38033
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {