@vm0/cli 9.168.3 → 9.169.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/{chunk-M3MX2TJ6.js → chunk-5KJLUOMN.js} +38 -9
- package/{chunk-M3MX2TJ6.js.map → chunk-5KJLUOMN.js.map} +1 -1
- package/index.js +9 -9
- package/package.json +1 -1
- package/zero.js +1385 -1166
- package/zero.js.map +1 -1
package/zero.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
completeSlackFileUpload,
|
|
19
19
|
completeTelegramFileUpload,
|
|
20
20
|
configureGlobalProxyFromEnv,
|
|
21
|
+
connectZeroConnectorApiToken,
|
|
21
22
|
connectorTypeSchema,
|
|
22
23
|
createComputerUseReadCommand,
|
|
23
24
|
createComputerUseWriteCommand,
|
|
@@ -152,7 +153,7 @@ import {
|
|
|
152
153
|
zeroAgentCustomSkillNameSchema,
|
|
153
154
|
zeroLocalAgentCommand,
|
|
154
155
|
zeroTokenAllowsFeatureSwitch
|
|
155
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-5KJLUOMN.js";
|
|
156
157
|
import {
|
|
157
158
|
__toESM,
|
|
158
159
|
init_esm_shims
|
|
@@ -1702,6 +1703,71 @@ Notes:
|
|
|
1702
1703
|
// src/commands/zero/connector/index.ts
|
|
1703
1704
|
init_esm_shims();
|
|
1704
1705
|
|
|
1706
|
+
// src/commands/zero/connector/connect.ts
|
|
1707
|
+
init_esm_shims();
|
|
1708
|
+
function collectValue(value, previous) {
|
|
1709
|
+
return [...previous, value];
|
|
1710
|
+
}
|
|
1711
|
+
function parseConnectorValues(rawValues) {
|
|
1712
|
+
if (!rawValues || rawValues.length === 0) {
|
|
1713
|
+
throw new Error("At least one --value NAME=VALUE is required", {
|
|
1714
|
+
cause: new Error(
|
|
1715
|
+
"Example: zero connector connect zendesk --value ZENDESK_API_TOKEN=token"
|
|
1716
|
+
)
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
const values = {};
|
|
1720
|
+
for (const rawValue of rawValues) {
|
|
1721
|
+
const separatorIndex = rawValue.indexOf("=");
|
|
1722
|
+
if (separatorIndex <= 0) {
|
|
1723
|
+
throw new Error("Invalid --value format", {
|
|
1724
|
+
cause: new Error("Use --value NAME=VALUE")
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
const name = rawValue.slice(0, separatorIndex);
|
|
1728
|
+
if (!name.trim()) {
|
|
1729
|
+
throw new Error("Invalid --value format", {
|
|
1730
|
+
cause: new Error("Field name cannot be empty")
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
values[name] = rawValue.slice(separatorIndex + 1);
|
|
1734
|
+
}
|
|
1735
|
+
return values;
|
|
1736
|
+
}
|
|
1737
|
+
function parseConnectorType(type) {
|
|
1738
|
+
const parsed = connectorTypeSchema.safeParse(type);
|
|
1739
|
+
if (parsed.success) {
|
|
1740
|
+
return parsed.data;
|
|
1741
|
+
}
|
|
1742
|
+
throw new Error(`Unknown connector type: ${type}`, {
|
|
1743
|
+
cause: new Error(`Available connectors: ${CONNECTOR_TYPE_KEYS.join(", ")}`)
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
var connectCommand = new Command().name("connect").description("Connect a connector with API-token credentials").argument("<type>", "Connector type (e.g., zendesk)").option(
|
|
1747
|
+
"--value <name=value>",
|
|
1748
|
+
"Connector field value; repeat for multiple fields",
|
|
1749
|
+
collectValue,
|
|
1750
|
+
[]
|
|
1751
|
+
).option("--json", "Print the connector response as JSON").action(
|
|
1752
|
+
withErrorHandler(async (type, options) => {
|
|
1753
|
+
const connectorType = parseConnectorType(type);
|
|
1754
|
+
const connector = await connectZeroConnectorApiToken(
|
|
1755
|
+
connectorType,
|
|
1756
|
+
parseConnectorValues(options.value)
|
|
1757
|
+
);
|
|
1758
|
+
if (options.json) {
|
|
1759
|
+
console.log(JSON.stringify(connector, null, 2));
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
console.log(
|
|
1763
|
+
source_default.green(`\u2713 ${CONNECTOR_TYPES[connectorType].label} connected`)
|
|
1764
|
+
);
|
|
1765
|
+
console.log(source_default.dim(` Type: ${connector.type}`));
|
|
1766
|
+
console.log(source_default.dim(` Auth Method: ${connector.authMethod}`));
|
|
1767
|
+
console.log(source_default.dim(` Run: zero connector status ${connector.type}`));
|
|
1768
|
+
})
|
|
1769
|
+
);
|
|
1770
|
+
|
|
1705
1771
|
// src/commands/zero/connector/list.ts
|
|
1706
1772
|
init_esm_shims();
|
|
1707
1773
|
|
|
@@ -2186,7 +2252,7 @@ var statusCommand2 = new Command().name("status").description("Show detailed sta
|
|
|
2186
2252
|
);
|
|
2187
2253
|
|
|
2188
2254
|
// src/commands/zero/connector/index.ts
|
|
2189
|
-
var zeroConnectorCommand = new Command().name("connector").description("Check third-party service connections (GitHub, Slack, etc.)").addCommand(listCommand6).addCommand(searchCommand).addCommand(statusCommand2);
|
|
2255
|
+
var zeroConnectorCommand = new Command().name("connector").description("Check third-party service connections (GitHub, Slack, etc.)").addCommand(connectCommand).addCommand(listCommand6).addCommand(searchCommand).addCommand(statusCommand2);
|
|
2190
2256
|
|
|
2191
2257
|
// src/commands/zero/credit.ts
|
|
2192
2258
|
init_esm_shims();
|
|
@@ -2683,740 +2749,171 @@ How connectors work:
|
|
|
2683
2749
|
})
|
|
2684
2750
|
);
|
|
2685
2751
|
|
|
2686
|
-
// src/commands/zero/doctor/
|
|
2752
|
+
// src/commands/zero/doctor/permission-deny.ts
|
|
2687
2753
|
init_esm_shims();
|
|
2688
|
-
var
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
reason: "available without connector setup"
|
|
2754
|
+
var permissionDenyCommand = new Command().name("permission-deny").description(
|
|
2755
|
+
"Diagnose a permission denial and find the permission that covers it"
|
|
2756
|
+
).argument("<connector-ref>", "The connector type (e.g. github)").addOption(
|
|
2757
|
+
new Option(
|
|
2758
|
+
"--method <method>",
|
|
2759
|
+
"The denied HTTP method"
|
|
2760
|
+
).makeOptionMandatory()
|
|
2761
|
+
).addOption(
|
|
2762
|
+
new Option("--path <path>", "The denied path").makeOptionMandatory()
|
|
2763
|
+
).addHelpText(
|
|
2764
|
+
"after",
|
|
2765
|
+
`
|
|
2766
|
+
Examples:
|
|
2767
|
+
zero doctor permission-deny github --method GET --path /repos/owner/repo/pulls
|
|
2768
|
+
zero doctor permission-deny slack --method POST --path /chat.postMessage
|
|
2769
|
+
|
|
2770
|
+
Notes:
|
|
2771
|
+
- Identifies which named permission covers a denied request
|
|
2772
|
+
- Use permission-change to request or enable the permission`
|
|
2773
|
+
).action(
|
|
2774
|
+
withErrorHandler(
|
|
2775
|
+
async (connectorRef, opts) => {
|
|
2776
|
+
if (!isFirewallConnectorType(connectorRef)) {
|
|
2777
|
+
throw new Error(`Unknown connector type: ${connectorRef}`);
|
|
2778
|
+
}
|
|
2779
|
+
const { label } = CONNECTOR_TYPES[connectorRef];
|
|
2780
|
+
const config = getConnectorFirewall(connectorRef);
|
|
2781
|
+
const permissions = findMatchingPermissions(
|
|
2782
|
+
opts.method,
|
|
2783
|
+
opts.path,
|
|
2784
|
+
config
|
|
2785
|
+
);
|
|
2786
|
+
console.log(
|
|
2787
|
+
`The ${label} permission filtered ${opts.method} ${opts.path}.`
|
|
2788
|
+
);
|
|
2789
|
+
if (permissions.length === 0) {
|
|
2790
|
+
console.log("No named permission was found covering this request.");
|
|
2791
|
+
return;
|
|
2792
|
+
}
|
|
2793
|
+
const ruleCount = /* @__PURE__ */ new Map();
|
|
2794
|
+
for (const api of config.apis) {
|
|
2795
|
+
if (!api.permissions) continue;
|
|
2796
|
+
for (const perm of api.permissions) {
|
|
2797
|
+
ruleCount.set(
|
|
2798
|
+
perm.name,
|
|
2799
|
+
(ruleCount.get(perm.name) ?? 0) + perm.rules.length
|
|
2800
|
+
);
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
const permission = permissions.reduce((narrowest, current) => {
|
|
2804
|
+
return (ruleCount.get(current) ?? Infinity) < (ruleCount.get(narrowest) ?? Infinity) ? current : narrowest;
|
|
2805
|
+
});
|
|
2806
|
+
console.log(`This is covered by the "${permission}" permission.`);
|
|
2807
|
+
console.log(
|
|
2808
|
+
`To request this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --reason "why this is needed"`
|
|
2809
|
+
);
|
|
2745
2810
|
}
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2811
|
+
)
|
|
2812
|
+
);
|
|
2813
|
+
|
|
2814
|
+
// src/commands/zero/doctor/permission-change.ts
|
|
2815
|
+
init_esm_shims();
|
|
2816
|
+
|
|
2817
|
+
// src/commands/zero/doctor/resolve-role.ts
|
|
2818
|
+
init_esm_shims();
|
|
2819
|
+
async function resolveUserId() {
|
|
2820
|
+
const zeroPayload = decodeZeroTokenPayload();
|
|
2821
|
+
if (zeroPayload?.userId) return zeroPayload.userId;
|
|
2822
|
+
const token = await getToken();
|
|
2823
|
+
const cliPayload = decodeCliTokenPayload(token);
|
|
2824
|
+
return cliPayload?.userId;
|
|
2825
|
+
}
|
|
2826
|
+
async function resolveAgentRole(agentId) {
|
|
2827
|
+
try {
|
|
2828
|
+
const org = await getZeroOrg();
|
|
2829
|
+
if (org.role === "admin") return "admin";
|
|
2830
|
+
if (org.role === "member") {
|
|
2831
|
+
const userId = await resolveUserId();
|
|
2832
|
+
if (userId) {
|
|
2833
|
+
const agent = await getZeroAgent(agentId);
|
|
2834
|
+
if (agent.ownerId === userId) return "owner";
|
|
2835
|
+
}
|
|
2836
|
+
return "member";
|
|
2753
2837
|
}
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2838
|
+
return "unknown";
|
|
2839
|
+
} catch (error) {
|
|
2840
|
+
console.debug("resolveAgentRole failed, falling back to unknown:", error);
|
|
2841
|
+
return "unknown";
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
// src/commands/zero/doctor/permission-change.ts
|
|
2846
|
+
function findPermissionInConfig(ref, permissionName) {
|
|
2847
|
+
if (!isFirewallConnectorType(ref)) return false;
|
|
2848
|
+
const config = getConnectorFirewall(ref);
|
|
2849
|
+
for (const api of config.apis) {
|
|
2850
|
+
if (!api.permissions) continue;
|
|
2851
|
+
for (const p of api.permissions) {
|
|
2852
|
+
if (p.name === permissionName) return true;
|
|
2761
2853
|
}
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
}
|
|
2826
|
-
],
|
|
2827
|
-
voice: [
|
|
2828
|
-
{
|
|
2829
|
-
label: "Built-in",
|
|
2830
|
-
model: "gpt-4o-mini-tts",
|
|
2831
|
-
command: "zero built-in generate voice -h",
|
|
2832
|
-
reason: "available without connector setup"
|
|
2833
|
-
}
|
|
2834
|
-
]
|
|
2835
|
-
};
|
|
2836
|
-
var BUILT_IN_GENERATION_COMMANDS = {
|
|
2837
|
-
image: {
|
|
2838
|
-
label: "Built-in image generation",
|
|
2839
|
-
command: "zero built-in generate image -h",
|
|
2840
|
-
models: "fal.ai: gpt-image-1 (default), gpt-image-2, gpt-image-1.5, gpt-image-1-mini, flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, seedream4"
|
|
2841
|
-
},
|
|
2842
|
-
video: {
|
|
2843
|
-
label: "Built-in video generation",
|
|
2844
|
-
command: "zero built-in generate video -h",
|
|
2845
|
-
models: "dreamina-seedance-2.0-fast (default), dreamina-seedance-2.0, seedance-1.5-pro, veo3.1-fast, kling-v3-4k"
|
|
2846
|
-
},
|
|
2847
|
-
presentation: {
|
|
2848
|
-
label: "Built-in presentation generation",
|
|
2849
|
-
command: "zero built-in generate presentation -h",
|
|
2850
|
-
models: "gpt-5.5"
|
|
2851
|
-
},
|
|
2852
|
-
report: {
|
|
2853
|
-
label: "Built-in report generation",
|
|
2854
|
-
command: "zero built-in generate report -h",
|
|
2855
|
-
models: "gpt-5.5"
|
|
2856
|
-
},
|
|
2857
|
-
"docs-design": {
|
|
2858
|
-
label: "Built-in docs design generation",
|
|
2859
|
-
command: "zero built-in generate docs-design -h",
|
|
2860
|
-
models: "gpt-5.5"
|
|
2861
|
-
},
|
|
2862
|
-
poster: {
|
|
2863
|
-
label: "Built-in poster generation",
|
|
2864
|
-
command: "zero built-in generate poster -h",
|
|
2865
|
-
models: "gpt-5.5"
|
|
2866
|
-
},
|
|
2867
|
-
"dashboard-design": {
|
|
2868
|
-
label: "Built-in dashboard design generation",
|
|
2869
|
-
command: "zero built-in generate dashboard-design -h",
|
|
2870
|
-
models: "gpt-5.5"
|
|
2871
|
-
},
|
|
2872
|
-
"mobile-app-design": {
|
|
2873
|
-
label: "Built-in mobile app design generation",
|
|
2874
|
-
command: "zero built-in generate mobile-app-design -h",
|
|
2875
|
-
models: "gpt-5.5"
|
|
2876
|
-
},
|
|
2877
|
-
website: {
|
|
2878
|
-
label: "Built-in website generation",
|
|
2879
|
-
command: "zero built-in generate website -h",
|
|
2880
|
-
models: "gpt-5.5"
|
|
2881
|
-
},
|
|
2882
|
-
voice: {
|
|
2883
|
-
label: "Built-in voice generation",
|
|
2884
|
-
command: "zero built-in generate voice -h",
|
|
2885
|
-
models: "gpt-4o-mini-tts"
|
|
2886
|
-
}
|
|
2887
|
-
};
|
|
2888
|
-
var GENERATION_CONTEXT = {
|
|
2889
|
-
website: {
|
|
2890
|
-
lines: [
|
|
2891
|
-
"Standalone static website artifacts can be authored locally and published with zero host for a public URL.",
|
|
2892
|
-
"zero host is for static directories with index.html; it is not a general deploy system for apps that need a backend, database, worker, or long-running process.",
|
|
2893
|
-
"Existing web app changes should usually follow the project's own build, test, and deploy workflow."
|
|
2894
|
-
]
|
|
2895
|
-
}
|
|
2896
|
-
};
|
|
2897
|
-
var GENERATION_TYPE_ORDER = [
|
|
2898
|
-
"image",
|
|
2899
|
-
"video",
|
|
2900
|
-
"audio",
|
|
2901
|
-
"voice",
|
|
2902
|
-
"text",
|
|
2903
|
-
"code",
|
|
2904
|
-
"document",
|
|
2905
|
-
"presentation",
|
|
2906
|
-
"website",
|
|
2907
|
-
"report",
|
|
2908
|
-
"docs-design",
|
|
2909
|
-
"poster",
|
|
2910
|
-
"dashboard-design",
|
|
2911
|
-
"mobile-app-design"
|
|
2912
|
-
];
|
|
2913
|
-
var GENERATION_TYPE_LABELS = {
|
|
2914
|
-
audio: "Audio",
|
|
2915
|
-
code: "Code",
|
|
2916
|
-
"dashboard-design": "Dashboard design",
|
|
2917
|
-
document: "Document",
|
|
2918
|
-
"docs-design": "Docs design",
|
|
2919
|
-
image: "Image",
|
|
2920
|
-
"mobile-app-design": "Mobile app design",
|
|
2921
|
-
poster: "Poster",
|
|
2922
|
-
presentation: "Presentation",
|
|
2923
|
-
report: "Report",
|
|
2924
|
-
text: "Text",
|
|
2925
|
-
video: "Video",
|
|
2926
|
-
voice: "Voice",
|
|
2927
|
-
website: "Website"
|
|
2928
|
-
};
|
|
2929
|
-
function getConnectorGenerationType(generationType) {
|
|
2930
|
-
switch (generationType) {
|
|
2931
|
-
case "voice":
|
|
2932
|
-
return "audio";
|
|
2933
|
-
case "dashboard-design":
|
|
2934
|
-
case "docs-design":
|
|
2935
|
-
case "mobile-app-design":
|
|
2936
|
-
case "poster":
|
|
2937
|
-
case "report":
|
|
2938
|
-
return null;
|
|
2939
|
-
case "audio":
|
|
2940
|
-
case "code":
|
|
2941
|
-
case "document":
|
|
2942
|
-
case "image":
|
|
2943
|
-
case "presentation":
|
|
2944
|
-
case "text":
|
|
2945
|
-
case "video":
|
|
2946
|
-
case "website":
|
|
2947
|
-
return generationType;
|
|
2948
|
-
}
|
|
2949
|
-
}
|
|
2950
|
-
function getBuiltInProviders(generationType) {
|
|
2951
|
-
return BUILT_IN_GENERATION_PROVIDERS[generationType] ?? [];
|
|
2952
|
-
}
|
|
2953
|
-
function getBuiltInCommand(generationType) {
|
|
2954
|
-
return BUILT_IN_GENERATION_COMMANDS[generationType] ?? null;
|
|
2955
|
-
}
|
|
2956
|
-
function getGenerationContext(generationType) {
|
|
2957
|
-
return GENERATION_CONTEXT[generationType] ?? null;
|
|
2958
|
-
}
|
|
2959
|
-
function getAvailableGenerationTypes() {
|
|
2960
|
-
const available = /* @__PURE__ */ new Set();
|
|
2961
|
-
for (const type of CONNECTOR_TYPE_KEYS) {
|
|
2962
|
-
for (const generationType of getConnectorGenerationTypes(type)) {
|
|
2963
|
-
available.add(generationType);
|
|
2964
|
-
}
|
|
2965
|
-
}
|
|
2966
|
-
return GENERATION_TYPE_ORDER.filter((type) => {
|
|
2967
|
-
const connectorGenerationType = getConnectorGenerationType(type);
|
|
2968
|
-
return getBuiltInProviders(type).length > 0 || connectorGenerationType !== null && available.has(connectorGenerationType);
|
|
2969
|
-
});
|
|
2970
|
-
}
|
|
2971
|
-
function parseGenerationType(value) {
|
|
2972
|
-
const availableTypes = getAvailableGenerationTypes();
|
|
2973
|
-
if (availableTypes.includes(value)) {
|
|
2974
|
-
return value;
|
|
2975
|
-
}
|
|
2976
|
-
throw new Error(`Unknown generation type: ${value}`, {
|
|
2977
|
-
cause: new Error(`Available types: ${availableTypes.join(", ")}`)
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
function getGenerationConnectors(generationType) {
|
|
2981
|
-
return CONNECTOR_TYPE_KEYS.map((type) => {
|
|
2982
|
-
return [type, CONNECTOR_TYPES[type]];
|
|
2983
|
-
}).filter(([type]) => {
|
|
2984
|
-
return getConnectorGenerationTypes(type).includes(generationType);
|
|
2985
|
-
}).sort(([a], [b]) => {
|
|
2986
|
-
return a.localeCompare(b);
|
|
2987
|
-
});
|
|
2988
|
-
}
|
|
2989
|
-
function isConnectorType5(type) {
|
|
2990
|
-
return type in CONNECTOR_TYPES;
|
|
2991
|
-
}
|
|
2992
|
-
async function getFeatureAvailableConnectorTypes() {
|
|
2993
|
-
const catalog = await searchZeroConnectors();
|
|
2994
|
-
return new Set(
|
|
2995
|
-
catalog.connectors.map((connector) => {
|
|
2996
|
-
return connector.id;
|
|
2997
|
-
}).filter(isConnectorType5)
|
|
2998
|
-
);
|
|
2999
|
-
}
|
|
3000
|
-
function formatAccount(connector) {
|
|
3001
|
-
if (connector.externalUsername) return `@${connector.externalUsername}`;
|
|
3002
|
-
if (connector.externalEmail) return connector.externalEmail;
|
|
3003
|
-
if (connector.externalId) return connector.externalId;
|
|
3004
|
-
return void 0;
|
|
3005
|
-
}
|
|
3006
|
-
function getAction(status, type, label, agentId, platformOrigin) {
|
|
3007
|
-
if (status === "needs-reconnect") {
|
|
3008
|
-
return {
|
|
3009
|
-
actionLabel: `Reconnect ${label}`,
|
|
3010
|
-
actionUrl: `${platformOrigin}/connectors`
|
|
3011
|
-
};
|
|
3012
|
-
}
|
|
3013
|
-
if (status === "not-authorized" && agentId) {
|
|
3014
|
-
return {
|
|
3015
|
-
actionLabel: `Authorize ${label}`,
|
|
3016
|
-
actionUrl: `${platformOrigin}/connectors/${type}/authorize?agentId=${agentId}`
|
|
3017
|
-
};
|
|
3018
|
-
}
|
|
3019
|
-
if (status === "not-connected") {
|
|
3020
|
-
if (agentId) {
|
|
3021
|
-
return {
|
|
3022
|
-
actionLabel: `Connect and authorize ${label}`,
|
|
3023
|
-
actionUrl: `${platformOrigin}/connectors/${type}/connect?agentId=${agentId}`
|
|
3024
|
-
};
|
|
3025
|
-
}
|
|
3026
|
-
return {
|
|
3027
|
-
actionLabel: `Connect ${label}`,
|
|
3028
|
-
actionUrl: `${platformOrigin}/connectors/${type}/connect`
|
|
3029
|
-
};
|
|
3030
|
-
}
|
|
3031
|
-
return {};
|
|
3032
|
-
}
|
|
3033
|
-
function toCandidate(params) {
|
|
3034
|
-
const {
|
|
3035
|
-
type,
|
|
3036
|
-
config,
|
|
3037
|
-
connector,
|
|
3038
|
-
configuredTypes,
|
|
3039
|
-
availableTypes,
|
|
3040
|
-
authorizedTypes,
|
|
3041
|
-
agentId,
|
|
3042
|
-
platformOrigin
|
|
3043
|
-
} = params;
|
|
3044
|
-
let status;
|
|
3045
|
-
let reason;
|
|
3046
|
-
if (!availableTypes.has(type)) {
|
|
3047
|
-
status = "not-available";
|
|
3048
|
-
reason = "not available for this account";
|
|
3049
|
-
} else if (connector?.needsReconnect) {
|
|
3050
|
-
status = "needs-reconnect";
|
|
3051
|
-
reason = "connected, reconnect required";
|
|
3052
|
-
} else if (!connector) {
|
|
3053
|
-
status = configuredTypes.has(type) ? "not-connected" : "not-available";
|
|
3054
|
-
reason = status === "not-connected" ? agentId ? "not connected or authorized for current agent" : "not connected" : "not available in this environment";
|
|
3055
|
-
} else if (authorizedTypes && !authorizedTypes.has(type)) {
|
|
3056
|
-
status = "not-authorized";
|
|
3057
|
-
reason = "connected, not authorized for current agent";
|
|
3058
|
-
} else {
|
|
3059
|
-
status = "ready";
|
|
3060
|
-
reason = agentId ? "connected and authorized for current agent" : "connected; agent authorization was not checked";
|
|
3061
|
-
}
|
|
3062
|
-
return {
|
|
3063
|
-
type,
|
|
3064
|
-
label: config.label,
|
|
3065
|
-
status,
|
|
3066
|
-
reason,
|
|
3067
|
-
account: connector ? formatAccount(connector) : void 0,
|
|
3068
|
-
authMethod: connector?.authMethod,
|
|
3069
|
-
...getAction(status, type, config.label, agentId, platformOrigin)
|
|
3070
|
-
};
|
|
3071
|
-
}
|
|
3072
|
-
function pad(value, width) {
|
|
3073
|
-
return value.padEnd(width);
|
|
3074
|
-
}
|
|
3075
|
-
function renderRows(candidates) {
|
|
3076
|
-
const typeWidth = Math.max(
|
|
3077
|
-
4,
|
|
3078
|
-
...candidates.map((candidate) => {
|
|
3079
|
-
return candidate.type.length;
|
|
3080
|
-
})
|
|
3081
|
-
);
|
|
3082
|
-
const labelWidth = Math.max(
|
|
3083
|
-
5,
|
|
3084
|
-
...candidates.map((candidate) => {
|
|
3085
|
-
return candidate.label.length;
|
|
3086
|
-
})
|
|
3087
|
-
);
|
|
3088
|
-
for (const candidate of candidates) {
|
|
3089
|
-
const suffix = candidate.status === "ready" ? candidate.account ?? candidate.authMethod ?? "" : candidate.reason;
|
|
3090
|
-
console.log(
|
|
3091
|
-
` ${pad(candidate.type, typeWidth)} ${pad(candidate.label, labelWidth)} ${suffix}`
|
|
3092
|
-
);
|
|
3093
|
-
}
|
|
3094
|
-
}
|
|
3095
|
-
function renderActions(candidates) {
|
|
3096
|
-
const actionable = candidates.filter((candidate) => {
|
|
3097
|
-
return candidate.actionLabel && candidate.actionUrl;
|
|
3098
|
-
});
|
|
3099
|
-
if (actionable.length === 0) return;
|
|
3100
|
-
console.log("");
|
|
3101
|
-
console.log("Next actions:");
|
|
3102
|
-
for (const candidate of actionable) {
|
|
3103
|
-
console.log(` [${candidate.actionLabel}](${candidate.actionUrl})`);
|
|
3104
|
-
}
|
|
3105
|
-
}
|
|
3106
|
-
function renderBuiltInProvider(generationType) {
|
|
3107
|
-
const command = getBuiltInCommand(generationType);
|
|
3108
|
-
if (command) {
|
|
3109
|
-
console.log("");
|
|
3110
|
-
console.log("Built-in command:");
|
|
3111
|
-
console.log(` vm0 ${command.label}`);
|
|
3112
|
-
console.log(` Models: ${command.models}`);
|
|
3113
|
-
console.log(` Use: ${command.command}`);
|
|
3114
|
-
return;
|
|
3115
|
-
}
|
|
3116
|
-
const providers = getBuiltInProviders(generationType);
|
|
3117
|
-
if (providers.length === 0) return;
|
|
3118
|
-
console.log("");
|
|
3119
|
-
console.log(
|
|
3120
|
-
providers.length === 1 ? "Built-in provider:" : "Built-in providers:"
|
|
3121
|
-
);
|
|
3122
|
-
for (const provider of providers) {
|
|
3123
|
-
console.log(` vm0 ${provider.label} Model: ${provider.model}`);
|
|
3124
|
-
console.log(` Use: ${provider.command}`);
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
function renderGenerationContext(generationType) {
|
|
3128
|
-
const context = getGenerationContext(generationType);
|
|
3129
|
-
if (!context) return;
|
|
3130
|
-
console.log("");
|
|
3131
|
-
console.log("Context:");
|
|
3132
|
-
for (const line of context.lines) {
|
|
3133
|
-
console.log(` - ${line}`);
|
|
3134
|
-
}
|
|
3135
|
-
}
|
|
3136
|
-
function renderText(params) {
|
|
3137
|
-
const { generationType, agentId, ready, other, showAll } = params;
|
|
3138
|
-
const label = GENERATION_TYPE_LABELS[generationType];
|
|
3139
|
-
const scope = agentId ? "for current agent" : "(connected connectors)";
|
|
3140
|
-
console.log(`${label} generation choices ${scope}`);
|
|
3141
|
-
console.log("");
|
|
3142
|
-
if (agentId) {
|
|
3143
|
-
console.log(`${"Agent:".padEnd(10)}${agentId}`);
|
|
3144
|
-
console.log("");
|
|
3145
|
-
} else {
|
|
3146
|
-
console.log(
|
|
3147
|
-
"ZERO_AGENT_ID is not set, so agent authorization could not be checked."
|
|
3148
|
-
);
|
|
3149
|
-
console.log("");
|
|
3150
|
-
}
|
|
3151
|
-
const hasBuiltInCommand = getBuiltInCommand(generationType) !== null;
|
|
3152
|
-
const showConnectorSummary = ready.length > 0 || !hasBuiltInCommand || showAll;
|
|
3153
|
-
if (showConnectorSummary) {
|
|
3154
|
-
console.log("Connectors:");
|
|
3155
|
-
if (ready.length > 0) {
|
|
3156
|
-
renderRows(ready);
|
|
3157
|
-
} else {
|
|
3158
|
-
console.log(` No ready ${generationType} generation connectors found.`);
|
|
3159
|
-
}
|
|
3160
|
-
}
|
|
3161
|
-
renderBuiltInProvider(generationType);
|
|
3162
|
-
renderGenerationContext(generationType);
|
|
3163
|
-
if (showAll && other.length > 0) {
|
|
3164
|
-
console.log("");
|
|
3165
|
-
console.log(`Other ${generationType} generation connectors`);
|
|
3166
|
-
console.log("");
|
|
3167
|
-
renderRows(other);
|
|
3168
|
-
}
|
|
3169
|
-
if (showAll) {
|
|
3170
|
-
renderActions(other);
|
|
3171
|
-
}
|
|
3172
|
-
}
|
|
3173
|
-
var generateCommand = new Command().name("generate").description("Show generation connector choices for the current agent").argument(
|
|
3174
|
-
"<type>",
|
|
3175
|
-
`Generation type (${getAvailableGenerationTypes().join(", ")})`
|
|
3176
|
-
).option("--all", "Also show unavailable or not-yet-authorized connectors").option("--json", "Output machine-readable JSON").action(
|
|
3177
|
-
withErrorHandler(async (type, options) => {
|
|
3178
|
-
const generationType = parseGenerationType(type);
|
|
3179
|
-
const connectorGenerationType = getConnectorGenerationType(generationType);
|
|
3180
|
-
const agentId = process.env.ZERO_AGENT_ID;
|
|
3181
|
-
const [connectorList, availableTypes, enabledTypes, platformOrigin] = await Promise.all([
|
|
3182
|
-
listZeroConnectors(),
|
|
3183
|
-
getFeatureAvailableConnectorTypes(),
|
|
3184
|
-
agentId ? getZeroAgentUserConnectors(agentId) : Promise.resolve(null),
|
|
3185
|
-
getPlatformOrigin()
|
|
3186
|
-
]);
|
|
3187
|
-
const connectedMap = new Map(
|
|
3188
|
-
connectorList.connectors.map((connector) => {
|
|
3189
|
-
return [connector.type, connector];
|
|
3190
|
-
})
|
|
3191
|
-
);
|
|
3192
|
-
const configuredTypes = new Set(connectorList.configuredTypes);
|
|
3193
|
-
const authorizedTypes = enabledTypes ? new Set(enabledTypes) : null;
|
|
3194
|
-
const candidates = connectorGenerationType ? getGenerationConnectors(connectorGenerationType).map(
|
|
3195
|
-
([connectorType, config]) => {
|
|
3196
|
-
return toCandidate({
|
|
3197
|
-
type: connectorType,
|
|
3198
|
-
config,
|
|
3199
|
-
connector: connectedMap.get(connectorType),
|
|
3200
|
-
configuredTypes,
|
|
3201
|
-
availableTypes,
|
|
3202
|
-
authorizedTypes,
|
|
3203
|
-
agentId,
|
|
3204
|
-
platformOrigin
|
|
3205
|
-
});
|
|
3206
|
-
}
|
|
3207
|
-
) : [];
|
|
3208
|
-
const ready = candidates.filter((candidate) => {
|
|
3209
|
-
return candidate.status === "ready";
|
|
3210
|
-
});
|
|
3211
|
-
const other = candidates.filter((candidate) => {
|
|
3212
|
-
return candidate.status !== "ready";
|
|
3213
|
-
});
|
|
3214
|
-
const builtInProviders = getBuiltInProviders(generationType);
|
|
3215
|
-
if (options.json) {
|
|
3216
|
-
console.log(
|
|
3217
|
-
JSON.stringify(
|
|
3218
|
-
{
|
|
3219
|
-
generationType,
|
|
3220
|
-
connectorGenerationType,
|
|
3221
|
-
availableTypes: getAvailableGenerationTypes(),
|
|
3222
|
-
agentId: agentId ?? null,
|
|
3223
|
-
choices: ready,
|
|
3224
|
-
otherCandidates: other,
|
|
3225
|
-
builtInCommand: getBuiltInCommand(generationType),
|
|
3226
|
-
generationContext: getGenerationContext(generationType),
|
|
3227
|
-
builtInProvider: builtInProviders[0] ?? null,
|
|
3228
|
-
builtInProviders
|
|
3229
|
-
},
|
|
3230
|
-
null,
|
|
3231
|
-
2
|
|
3232
|
-
)
|
|
3233
|
-
);
|
|
3234
|
-
return;
|
|
3235
|
-
}
|
|
3236
|
-
renderText({
|
|
3237
|
-
generationType,
|
|
3238
|
-
agentId,
|
|
3239
|
-
ready,
|
|
3240
|
-
other,
|
|
3241
|
-
showAll: options.all === true
|
|
3242
|
-
});
|
|
3243
|
-
const shouldShowOtherHint = !options.all && other.length > 0 && (ready.length > 0 || getBuiltInCommand(generationType) === null);
|
|
3244
|
-
if (shouldShowOtherHint) {
|
|
3245
|
-
console.log("");
|
|
3246
|
-
console.log(
|
|
3247
|
-
source_default.dim(
|
|
3248
|
-
`Use --all to see every ${generationType} generation candidate.`
|
|
3249
|
-
)
|
|
3250
|
-
);
|
|
3251
|
-
}
|
|
3252
|
-
})
|
|
3253
|
-
);
|
|
3254
|
-
|
|
3255
|
-
// src/commands/zero/doctor/permission-deny.ts
|
|
3256
|
-
init_esm_shims();
|
|
3257
|
-
var permissionDenyCommand = new Command().name("permission-deny").description(
|
|
3258
|
-
"Diagnose a permission denial and find the permission that covers it"
|
|
3259
|
-
).argument("<connector-ref>", "The connector type (e.g. github)").addOption(
|
|
3260
|
-
new Option(
|
|
3261
|
-
"--method <method>",
|
|
3262
|
-
"The denied HTTP method"
|
|
3263
|
-
).makeOptionMandatory()
|
|
3264
|
-
).addOption(
|
|
3265
|
-
new Option("--path <path>", "The denied path").makeOptionMandatory()
|
|
3266
|
-
).addHelpText(
|
|
3267
|
-
"after",
|
|
3268
|
-
`
|
|
3269
|
-
Examples:
|
|
3270
|
-
zero doctor permission-deny github --method GET --path /repos/owner/repo/pulls
|
|
3271
|
-
zero doctor permission-deny slack --method POST --path /chat.postMessage
|
|
3272
|
-
|
|
3273
|
-
Notes:
|
|
3274
|
-
- Identifies which named permission covers a denied request
|
|
3275
|
-
- Use permission-change to request or enable the permission`
|
|
3276
|
-
).action(
|
|
3277
|
-
withErrorHandler(
|
|
3278
|
-
async (connectorRef, opts) => {
|
|
3279
|
-
if (!isFirewallConnectorType(connectorRef)) {
|
|
3280
|
-
throw new Error(`Unknown connector type: ${connectorRef}`);
|
|
3281
|
-
}
|
|
3282
|
-
const { label } = CONNECTOR_TYPES[connectorRef];
|
|
3283
|
-
const config = getConnectorFirewall(connectorRef);
|
|
3284
|
-
const permissions = findMatchingPermissions(
|
|
3285
|
-
opts.method,
|
|
3286
|
-
opts.path,
|
|
3287
|
-
config
|
|
3288
|
-
);
|
|
3289
|
-
console.log(
|
|
3290
|
-
`The ${label} permission filtered ${opts.method} ${opts.path}.`
|
|
3291
|
-
);
|
|
3292
|
-
if (permissions.length === 0) {
|
|
3293
|
-
console.log("No named permission was found covering this request.");
|
|
3294
|
-
return;
|
|
3295
|
-
}
|
|
3296
|
-
const ruleCount = /* @__PURE__ */ new Map();
|
|
3297
|
-
for (const api of config.apis) {
|
|
3298
|
-
if (!api.permissions) continue;
|
|
3299
|
-
for (const perm of api.permissions) {
|
|
3300
|
-
ruleCount.set(
|
|
3301
|
-
perm.name,
|
|
3302
|
-
(ruleCount.get(perm.name) ?? 0) + perm.rules.length
|
|
3303
|
-
);
|
|
3304
|
-
}
|
|
3305
|
-
}
|
|
3306
|
-
const permission = permissions.reduce((narrowest, current) => {
|
|
3307
|
-
return (ruleCount.get(current) ?? Infinity) < (ruleCount.get(narrowest) ?? Infinity) ? current : narrowest;
|
|
3308
|
-
});
|
|
3309
|
-
console.log(`This is covered by the "${permission}" permission.`);
|
|
3310
|
-
console.log(
|
|
3311
|
-
`To request this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --reason "why this is needed"`
|
|
3312
|
-
);
|
|
3313
|
-
}
|
|
3314
|
-
)
|
|
3315
|
-
);
|
|
3316
|
-
|
|
3317
|
-
// src/commands/zero/doctor/permission-change.ts
|
|
3318
|
-
init_esm_shims();
|
|
3319
|
-
|
|
3320
|
-
// src/commands/zero/doctor/resolve-role.ts
|
|
3321
|
-
init_esm_shims();
|
|
3322
|
-
async function resolveUserId() {
|
|
3323
|
-
const zeroPayload = decodeZeroTokenPayload();
|
|
3324
|
-
if (zeroPayload?.userId) return zeroPayload.userId;
|
|
3325
|
-
const token = await getToken();
|
|
3326
|
-
const cliPayload = decodeCliTokenPayload(token);
|
|
3327
|
-
return cliPayload?.userId;
|
|
3328
|
-
}
|
|
3329
|
-
async function resolveAgentRole(agentId) {
|
|
3330
|
-
try {
|
|
3331
|
-
const org = await getZeroOrg();
|
|
3332
|
-
if (org.role === "admin") return "admin";
|
|
3333
|
-
if (org.role === "member") {
|
|
3334
|
-
const userId = await resolveUserId();
|
|
3335
|
-
if (userId) {
|
|
3336
|
-
const agent = await getZeroAgent(agentId);
|
|
3337
|
-
if (agent.ownerId === userId) return "owner";
|
|
3338
|
-
}
|
|
3339
|
-
return "member";
|
|
3340
|
-
}
|
|
3341
|
-
return "unknown";
|
|
3342
|
-
} catch (error) {
|
|
3343
|
-
console.debug("resolveAgentRole failed, falling back to unknown:", error);
|
|
3344
|
-
return "unknown";
|
|
3345
|
-
}
|
|
3346
|
-
}
|
|
3347
|
-
|
|
3348
|
-
// src/commands/zero/doctor/permission-change.ts
|
|
3349
|
-
function findPermissionInConfig(ref, permissionName) {
|
|
3350
|
-
if (!isFirewallConnectorType(ref)) return false;
|
|
3351
|
-
const config = getConnectorFirewall(ref);
|
|
3352
|
-
for (const api of config.apis) {
|
|
3353
|
-
if (!api.permissions) continue;
|
|
3354
|
-
for (const p of api.permissions) {
|
|
3355
|
-
if (p.name === permissionName) return true;
|
|
3356
|
-
}
|
|
3357
|
-
}
|
|
3358
|
-
return false;
|
|
3359
|
-
}
|
|
3360
|
-
var REASON_MAX_LENGTH = 500;
|
|
3361
|
-
async function outputPermissionChangeMessage(connectorRef, permission, action, reason) {
|
|
3362
|
-
const { label } = CONNECTOR_TYPES[connectorRef];
|
|
3363
|
-
const platformOrigin = await getPlatformOrigin();
|
|
3364
|
-
const agentId = process.env.ZERO_AGENT_ID;
|
|
3365
|
-
const role = agentId ? await resolveAgentRole(agentId) : "unknown";
|
|
3366
|
-
const urlParams = new URLSearchParams({
|
|
3367
|
-
ref: connectorRef,
|
|
3368
|
-
permission,
|
|
3369
|
-
action: action === "enable" ? "allow" : "deny"
|
|
3370
|
-
});
|
|
3371
|
-
if (role === "member" && reason) {
|
|
3372
|
-
const truncated = reason.length > REASON_MAX_LENGTH ? reason.slice(0, REASON_MAX_LENGTH) : reason;
|
|
3373
|
-
urlParams.set("reason", truncated);
|
|
3374
|
-
}
|
|
3375
|
-
const pagePath = agentId ? `/agents/${agentId}/permissions` : "/agents";
|
|
3376
|
-
const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
|
|
3377
|
-
if (connectorRef === "slack" && permission === "chat:write" && action === "enable") {
|
|
3378
|
-
console.log("");
|
|
3379
|
-
console.log(
|
|
3380
|
-
"IMPORTANT: Granting chat:write allows sending messages AS THE USER's identity, not as a bot."
|
|
3381
|
-
);
|
|
3382
|
-
console.log(
|
|
3383
|
-
"Use `zero slack message send -c <channel> -t <text>` to send messages as the bot instead \u2014 this is the recommended approach for most use cases."
|
|
3384
|
-
);
|
|
3385
|
-
console.log(
|
|
3386
|
-
"Only request user approval below if acting as the user is specifically required."
|
|
3387
|
-
);
|
|
3388
|
-
console.log("");
|
|
3389
|
-
}
|
|
3390
|
-
if (connectorRef === "gmail" && permission === "gmail.send" && action === "enable") {
|
|
3391
|
-
console.log("");
|
|
3392
|
-
console.log(
|
|
3393
|
-
"IMPORTANT: Granting gmail.send allows the agent to send emails directly as the user."
|
|
3394
|
-
);
|
|
3395
|
-
console.log(
|
|
3396
|
-
"Consider keeping gmail.send disabled and using gmail.compose instead \u2014 the agent can create drafts for the user to review and send manually."
|
|
3397
|
-
);
|
|
3398
|
-
console.log(
|
|
3399
|
-
"Only request user approval below if direct sending is specifically required."
|
|
3400
|
-
);
|
|
3401
|
-
console.log("");
|
|
3402
|
-
}
|
|
3403
|
-
if (role === "admin" || role === "owner") {
|
|
3404
|
-
console.log(
|
|
3405
|
-
`You can ${action} the "${permission}" permission directly: [Manage ${label} permissions](${url})`
|
|
3406
|
-
);
|
|
3407
|
-
} else if (role === "member") {
|
|
3408
|
-
if (!reason) {
|
|
3409
|
-
console.log(
|
|
3410
|
-
`IMPORTANT: Re-run with \`--reason "one sentence why this is needed"\` so the admin can review your request faster.`
|
|
3411
|
-
);
|
|
3412
|
-
} else if (action === "enable") {
|
|
3413
|
-
console.log(
|
|
3414
|
-
`Permission changes require admin approval. Request access at: [Request ${label} access](${url})`
|
|
3415
|
-
);
|
|
3416
|
-
} else {
|
|
3417
|
-
console.log(
|
|
3418
|
-
`Permission changes require admin approval. Contact an org admin to disable this permission: [View ${label} permissions](${url})`
|
|
3419
|
-
);
|
|
2854
|
+
}
|
|
2855
|
+
return false;
|
|
2856
|
+
}
|
|
2857
|
+
var REASON_MAX_LENGTH = 500;
|
|
2858
|
+
async function outputPermissionChangeMessage(connectorRef, permission, action, reason) {
|
|
2859
|
+
const { label } = CONNECTOR_TYPES[connectorRef];
|
|
2860
|
+
const platformOrigin = await getPlatformOrigin();
|
|
2861
|
+
const agentId = process.env.ZERO_AGENT_ID;
|
|
2862
|
+
const role = agentId ? await resolveAgentRole(agentId) : "unknown";
|
|
2863
|
+
const urlParams = new URLSearchParams({
|
|
2864
|
+
ref: connectorRef,
|
|
2865
|
+
permission,
|
|
2866
|
+
action: action === "enable" ? "allow" : "deny"
|
|
2867
|
+
});
|
|
2868
|
+
if (role === "member" && reason) {
|
|
2869
|
+
const truncated = reason.length > REASON_MAX_LENGTH ? reason.slice(0, REASON_MAX_LENGTH) : reason;
|
|
2870
|
+
urlParams.set("reason", truncated);
|
|
2871
|
+
}
|
|
2872
|
+
const pagePath = agentId ? `/agents/${agentId}/permissions` : "/agents";
|
|
2873
|
+
const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
|
|
2874
|
+
if (connectorRef === "slack" && permission === "chat:write" && action === "enable") {
|
|
2875
|
+
console.log("");
|
|
2876
|
+
console.log(
|
|
2877
|
+
"IMPORTANT: Granting chat:write allows sending messages AS THE USER's identity, not as a bot."
|
|
2878
|
+
);
|
|
2879
|
+
console.log(
|
|
2880
|
+
"Use `zero slack message send -c <channel> -t <text>` to send messages as the bot instead \u2014 this is the recommended approach for most use cases."
|
|
2881
|
+
);
|
|
2882
|
+
console.log(
|
|
2883
|
+
"Only request user approval below if acting as the user is specifically required."
|
|
2884
|
+
);
|
|
2885
|
+
console.log("");
|
|
2886
|
+
}
|
|
2887
|
+
if (connectorRef === "gmail" && permission === "gmail.send" && action === "enable") {
|
|
2888
|
+
console.log("");
|
|
2889
|
+
console.log(
|
|
2890
|
+
"IMPORTANT: Granting gmail.send allows the agent to send emails directly as the user."
|
|
2891
|
+
);
|
|
2892
|
+
console.log(
|
|
2893
|
+
"Consider keeping gmail.send disabled and using gmail.compose instead \u2014 the agent can create drafts for the user to review and send manually."
|
|
2894
|
+
);
|
|
2895
|
+
console.log(
|
|
2896
|
+
"Only request user approval below if direct sending is specifically required."
|
|
2897
|
+
);
|
|
2898
|
+
console.log("");
|
|
2899
|
+
}
|
|
2900
|
+
if (role === "admin" || role === "owner") {
|
|
2901
|
+
console.log(
|
|
2902
|
+
`You can ${action} the "${permission}" permission directly: [Manage ${label} permissions](${url})`
|
|
2903
|
+
);
|
|
2904
|
+
} else if (role === "member") {
|
|
2905
|
+
if (!reason) {
|
|
2906
|
+
console.log(
|
|
2907
|
+
`IMPORTANT: Re-run with \`--reason "one sentence why this is needed"\` so the admin can review your request faster.`
|
|
2908
|
+
);
|
|
2909
|
+
} else if (action === "enable") {
|
|
2910
|
+
console.log(
|
|
2911
|
+
`Permission changes require admin approval. Request access at: [Request ${label} access](${url})`
|
|
2912
|
+
);
|
|
2913
|
+
} else {
|
|
2914
|
+
console.log(
|
|
2915
|
+
`Permission changes require admin approval. Contact an org admin to disable this permission: [View ${label} permissions](${url})`
|
|
2916
|
+
);
|
|
3420
2917
|
}
|
|
3421
2918
|
} else {
|
|
3422
2919
|
console.log(
|
|
@@ -3537,14 +3034,12 @@ var creditCommand = new Command().name("credit").description("Diagnose current o
|
|
|
3537
3034
|
);
|
|
3538
3035
|
|
|
3539
3036
|
// src/commands/zero/doctor/index.ts
|
|
3540
|
-
var zeroDoctorCommand = new Command().name("doctor").description("Diagnose runtime issues (connector health, permission denials)").addCommand(checkConnectorCommand).addCommand(
|
|
3037
|
+
var zeroDoctorCommand = new Command().name("doctor").description("Diagnose runtime issues (connector health, permission denials)").addCommand(checkConnectorCommand).addCommand(creditCommand).addCommand(permissionDenyCommand).addCommand(permissionChangeCommand).addHelpText(
|
|
3541
3038
|
"after",
|
|
3542
3039
|
`
|
|
3543
3040
|
Examples:
|
|
3544
3041
|
Check a connector? zero doctor check-connector --env-name GITHUB_TOKEN
|
|
3545
3042
|
Check a URL? zero doctor check-connector --url https://api.github.com/repos/owner/repo
|
|
3546
|
-
Generate with image? zero doctor generate image
|
|
3547
|
-
Generate with video? zero doctor generate video
|
|
3548
3043
|
Check credits? zero doctor credit
|
|
3549
3044
|
Check with permission? zero doctor check-connector --env-name SLACK_TOKEN --check-permission chat:write
|
|
3550
3045
|
Permission denied? zero doctor permission-deny github --method GET --path /repos/owner/repo
|
|
@@ -3553,6 +3048,7 @@ Examples:
|
|
|
3553
3048
|
Notes:
|
|
3554
3049
|
- Use zero doctor credit when a run or generation fails because the org has insufficient credits, when a user asks how to recharge, or before trying to buy credits
|
|
3555
3050
|
- Use this when your task fails due to a missing environment variable or permission denial
|
|
3051
|
+
- Use zero generate <type> (no --prompt) to see every provider available for a given generation type
|
|
3556
3052
|
- The doctor will identify the issue and give the user a link to resolve it`
|
|
3557
3053
|
);
|
|
3558
3054
|
|
|
@@ -7243,18 +6739,14 @@ var openAppCommand = appOption(
|
|
|
7243
6739
|
);
|
|
7244
6740
|
var zeroComputerUseCommand = new Command().name("computer-use").description("Desktop app computer use through Zero CLI").addHelpText("after", COMPUTER_USE_HELP_TEXT).addCommand(listAppsCommand).addCommand(getAppStateCommand).addCommand(clickCommand).addCommand(scrollCommand).addCommand(setValueCommand).addCommand(typeTextCommand).addCommand(pressKeyCommand).addCommand(performActionCommand).addCommand(openAppCommand);
|
|
7245
6741
|
|
|
7246
|
-
// src/commands/zero/
|
|
7247
|
-
init_esm_shims();
|
|
7248
|
-
|
|
7249
|
-
// src/commands/zero/built-in/generate/index.ts
|
|
6742
|
+
// src/commands/zero/generate/index.ts
|
|
7250
6743
|
init_esm_shims();
|
|
7251
6744
|
|
|
7252
|
-
// src/commands/zero/
|
|
6745
|
+
// src/commands/zero/generate/image.ts
|
|
7253
6746
|
init_esm_shims();
|
|
7254
6747
|
|
|
7255
6748
|
// src/commands/zero/shared/image-generate.ts
|
|
7256
6749
|
init_esm_shims();
|
|
7257
|
-
import { readFileSync as readFileSync13 } from "fs";
|
|
7258
6750
|
|
|
7259
6751
|
// src/commands/zero/shared/image-style-authoring.ts
|
|
7260
6752
|
init_esm_shims();
|
|
@@ -9696,266 +9188,924 @@ var OPEN_DESIGN_REGISTRY = [
|
|
|
9696
9188
|
source: { path: "illustration-template/painterly-botanical" }
|
|
9697
9189
|
},
|
|
9698
9190
|
{
|
|
9699
|
-
id: "vm0:image-style:iso-scene",
|
|
9191
|
+
id: "vm0:image-style:iso-scene",
|
|
9192
|
+
kind: "image-style",
|
|
9193
|
+
name: "Isometric Editorial Scene",
|
|
9194
|
+
description: "Isometric editorial-magazine scene illustration with ultra-fine hairline outlines, flat fills, a saturated monochromatic background, and a scene-as-metaphor composition built from theme-native props.",
|
|
9195
|
+
desc: 'Isometric editorial-magazine scene illustration in a locked flat-vector style \u2014 ultra-fine hairline outlines, monochromatic saturated background filling the canvas, and a single composed scene whose props themselves embody the theme. Trigger when users say /iso-scene, ask for an "isometric editorial illustration", a "scene illustration in the editorial machine style", or brief with palette + scene archetype + complexity.',
|
|
9196
|
+
source: { path: "illustration-template/iso-scene" }
|
|
9197
|
+
},
|
|
9198
|
+
{
|
|
9199
|
+
id: "vm0:image-style:inkdab",
|
|
9200
|
+
kind: "image-style",
|
|
9201
|
+
name: "Inkdab Illustration",
|
|
9202
|
+
description: "Brush-pen editorial illustration where a free-floating color dab is painted first, then loose black ink linework is drawn freely on top \u2014 never as an outline around the color. Scribbled hatched hair, open-outline bodies, pure white background.",
|
|
9203
|
+
desc: 'Brush-pen editorial illustration style \u2014 a flat accent-color "dab" painted first, then loose black ink drawn freely on top. ONE flat accent-color shape per prop (painted-first, never outlined in black), black hand-wobbled ink on pure white background, scribbled hatched hair, open-outline bodies with zero fill, and one small solid-accent triangle floating freely as a recurring motif. Trigger when user says /inkdab, asks for an "inkdab illustration", a "brush-pen illustration with a single accent color", a "free-floating color block illustration", or briefs in the style of the included reference images.',
|
|
9204
|
+
source: { path: "illustration-template/inkdab" }
|
|
9205
|
+
},
|
|
9206
|
+
{
|
|
9207
|
+
id: "vm0:image-style:riso-relic",
|
|
9208
|
+
kind: "image-style",
|
|
9209
|
+
name: "Riso Relic",
|
|
9210
|
+
description: 'Pop-art retro risograph poster of a single nostalgic everyday object on a saturated single-hue field \u2014 bold black ink outlines, halftone grain, hand-drawn doodle accents, tiny "SMALL OBJECTS IN TIME" banner up top, chunky retro headline with offset drop-shadow at the bottom.',
|
|
9211
|
+
desc: 'Pop-art retro risograph poster of a single nostalgic everyday object \u2014 saturated single-color background, bold black ink outlines, halftone/riso grain, hand-drawn doodle accents (sparkles, squiggles, dots, music notes, lightning), tiny white "SMALL OBJECTS IN TIME" banner at top, chunky retro display headline at bottom with offset black drop-shadow. Trigger when user says /riso-relic, asks for a "riso poster", a "small objects in time" illustration, or any new piece in this nostalgic pop-art relic-object style.',
|
|
9212
|
+
source: { path: "illustration-template/riso-relic" }
|
|
9213
|
+
},
|
|
9214
|
+
{
|
|
9215
|
+
id: "vm0:image-style:inkstomp",
|
|
9216
|
+
kind: "image-style",
|
|
9217
|
+
name: "Inkstomp",
|
|
9218
|
+
description: "Loud indie-packaging poster style \u2014 full-bleed saturated flat color, a two-line hand-lettered headline, and one weird-cute black brush-ink character.",
|
|
9219
|
+
desc: 'Inkstomp \u2014 a loud, hand-screened indie-packaging poster style. Full-bleed saturated flat color filling the entire canvas, a two-line hand-lettered headline (thin arched caps over chunky drop-shadowed display), and one weird-cute character drawn in thick uniform black brush ink. Trigger when the user says /inkstomp, asks for an "inkstomp poster", a "Ray Fenwick / Hattie Stewart packaging poster", an "indie brush-ink flavor card", or briefs in a "palette + headline + character" shape.',
|
|
9220
|
+
source: { path: "illustration-template/inkstomp" }
|
|
9221
|
+
},
|
|
9222
|
+
{
|
|
9223
|
+
id: "vm0:image-style:folk-muse",
|
|
9224
|
+
kind: "image-style",
|
|
9225
|
+
name: "Folk Muse",
|
|
9226
|
+
description: "Flat folk-art gouache portrait style \u2014 a single contemplative chest-up figure framed by an asymmetric botanical surround, with painted irises, smooth flat hair, a hand against the cheek, and a patterned robe.",
|
|
9227
|
+
desc: 'Flat folk-art gouache portrait illustration in the contemporary editorial style of Carson Ellis, Maja Tomljanovic, and Bodil Jane. A single chest-up figure with an elongated mannerist oval face, tiny almond half-lidded eyes, smooth flat hair, one hand pressed against the face, a patterned robe filling the lower frame, and an asymmetric botanical surround filling the background edge-to-edge. Hand-painted matte gouache texture, flat color blocks, no harsh outlines, no photorealism. Calm, slightly melancholic, contemplative mood. Trigger when the user says /folk-muse, asks for a "folk-art portrait", "gouache portrait", "Carson Ellis style portrait", or any new piece in this contemplative folk-portrait style.',
|
|
9228
|
+
source: { path: "illustration-template/folk-muse" }
|
|
9229
|
+
},
|
|
9230
|
+
{
|
|
9231
|
+
id: "vm0:image-style:sunlit-gouache",
|
|
9232
|
+
kind: "image-style",
|
|
9233
|
+
name: "Sunlit Gouache",
|
|
9234
|
+
description: "Bright pastel travel-painting illustration in opaque gouache on textured paper with chunky flat brushstrokes, vertical one-point perspective, and figures walking into warm sunlight.",
|
|
9235
|
+
desc: 'Sunlit Gouache travel-painting illustration. Opaque gouache on textured paper, visible chunky flat brushstrokes with dry-brush highlights, locked six-color palette (cream, butter-yellow, sky-blue, sage-green, terracotta, one small red accent), vertical 2:3 one-point-perspective composition drawing the eye into a bright sunlit focal point, figures seen from behind walking into the scene, an overhead band of hanging elements (awning, prayer flags, catenary, bunting, lanterns) creating depth, dappled painterly reflections on the ground, airy optimistic warm mood. Trigger when user says /sunlit-gouache, asks for a "sunlit gouache illustration", "painterly travel scene", "gouache caf\xE9/market/temple/station scene", or a new piece in this bright pastel painted-light style.',
|
|
9236
|
+
source: { path: "illustration-template/sunlit-gouache" }
|
|
9237
|
+
},
|
|
9238
|
+
{
|
|
9239
|
+
id: "vm0:image-style:mosaic-still-life",
|
|
9240
|
+
kind: "image-style",
|
|
9241
|
+
name: "Mosaic Still Life",
|
|
9242
|
+
description: "Editorial still-life illustration in a mosaic-tile + painterly hybrid style \u2014 tessellated ground/sky/wall surfaces with crisp painterly objects, an animal companion, and a patterned textile peeking through.",
|
|
9243
|
+
desc: 'Mosaic-tile + painterly hybrid editorial illustration. Tessellated/pointillist mosaic surfaces (grass, sky, sand, walls, floors) anchor the scene, with crisp painterly still-life objects rendered ON TOP. Always features a still-life centerpiece on a table, an animal companion at the heart of the scene, and at least one patterned textile peeking through. Cozy, nostalgic, bucolic mood. Trigger when user says /mosaic-still-life, asks for a "mosaic illustration", "mosaic-tile editorial illustration", "tessellated still life", or briefs with a palette + scene + animal in this style.',
|
|
9244
|
+
source: { path: "illustration-template/mosaic-still-life" }
|
|
9245
|
+
},
|
|
9246
|
+
{
|
|
9247
|
+
id: "vm0:image-style:ink-mascot",
|
|
9248
|
+
kind: "image-style",
|
|
9249
|
+
name: "Ink Mascot",
|
|
9250
|
+
description: "Vintage editorial marketing card. Bold serif headline and short serif descriptor over a hand-drawn black-ink anthropomorphic mascot (stick limbs, chunky white sneakers) on a single solid saturated flat color background.",
|
|
9251
|
+
desc: 'Generate a 3:5 portrait editorial marketing card in a locked vintage-textbook style. Bold serif headline plus an optional short serif descriptor sit on a single solid saturated flat color background (no gradient, no divider, no ground line). A hand-drawn black-ink anthropomorphic hero object \u2014 paint bucket, magnifying glass, envelope, notebook, funnel, megaphone, rocket, seedling, gift box, compass, etc. \u2014 stands with two thin stick arms, two stick legs, and chunky white sneakers with black laces (the signature detail). Crosshatch and stipple shading on rounded surfaces; floating ink doodles (sparkles, arrows, hearts, percent or dollar signs, motion lines) at the requested density. Dialable along six axes: concept, palette, hero object, action, doodle density (L1 minimal, L2 balanced, L3 packed), and type layout (A title-top, B headline-bottom, C headline-only, D big-word + tiny-descriptor). Trigger when user says /ink-mascot, asks for a "marketing card illustration", a "retro editorial mascot poster", or briefs with a marketing concept plus palette plus character.',
|
|
9252
|
+
source: { path: "illustration-template/ink-mascot" }
|
|
9253
|
+
},
|
|
9254
|
+
{
|
|
9255
|
+
id: "vm0:image-style:sticker-sheet",
|
|
9256
|
+
kind: "image-style",
|
|
9257
|
+
name: "Sticker Sheet",
|
|
9258
|
+
description: "Hand-painted gouache sticker-sheet illustration with ~20 themed objects floating on white, punchy saturated palette, wobbly hand-drawn ink overlay, and tiny decorative marks on every item.",
|
|
9259
|
+
desc: 'Sticker Sheet \u2014 hand-painted gouache sticker-sheet illustration. ~20 small floating themed objects on pure white, punchy saturated palette (coral, mustard, sage, dusty pink, navy, cream, warm brown), flat brushy gouache fills with wobbly hand-drawn ink linework and tiny decorative marks (dots, hatches, squiggles) on every object. Each object slightly tilted, no drop shadows, cheerful cozy lifestyle journal mood. Trigger when user says /sticker-sheet, asks for a "sticker sheet illustration", "hand-painted gouache sticker pack", "themed object sheet", or briefs with a scene theme + object count in this house style.',
|
|
9260
|
+
source: { path: "illustration-template/sticker-sheet" }
|
|
9261
|
+
},
|
|
9262
|
+
{
|
|
9263
|
+
id: "vm0:image-style:flat-poster",
|
|
9700
9264
|
kind: "image-style",
|
|
9701
|
-
name: "
|
|
9702
|
-
description: "
|
|
9703
|
-
desc: '
|
|
9704
|
-
source: { path: "illustration-template/
|
|
9265
|
+
name: "Flat Poster",
|
|
9266
|
+
description: "Vertical flat-color editorial poster style \u2014 saturated solid background, one centered hand-drawn vector subject in bold deep-navy outlines with strict two-tone fill, headline pinned top-left, wordmark pinned bottom-right.",
|
|
9267
|
+
desc: 'Flat Poster \u2014 a vertical flat-color editorial poster style for brand benefit cards, marketing posters, and in-app campaign visuals. Portrait 2:3 canvas filled edge-to-edge with one saturated hue; a single centered hand-drawn vector subject in deep-navy outlines with strict two-tone fill (pure white plus one darker bg-tint accent); a bold rounded sans-serif headline pinned top-left; a short wordmark (default VM0) pinned bottom-right; small floating accent marks around the subject; no body copy. Six creative dials: palette, subject archetype, composition preset, accent marks, headline voice, mood. Trigger when the user says /flat-poster, asks for a "flat-color editorial poster", a "brand benefit card", a "marketing card in the bold outline + flat color style", or briefs with a palette + subject + headline shape.',
|
|
9268
|
+
source: { path: "illustration-template/flat-poster" }
|
|
9705
9269
|
},
|
|
9706
9270
|
{
|
|
9707
|
-
id: "vm0:image-style:
|
|
9271
|
+
id: "vm0:image-style:mellow-pop",
|
|
9708
9272
|
kind: "image-style",
|
|
9709
|
-
name: "
|
|
9710
|
-
description: "
|
|
9711
|
-
desc: '
|
|
9712
|
-
source: { path: "illustration-template/
|
|
9273
|
+
name: "Mellow Pop",
|
|
9274
|
+
description: "Chill flat-vector editorial poster of a serene recurring character on a fully saturated solid color background, with a signature pop of bright leaf-green and a scene-as-metaphor composition.",
|
|
9275
|
+
desc: 'Mellow-pop flat-vector editorial illustration: a recurring chill character with closed-eye smile, tiny nose hint, and short dark bobbed hair, posed inside a scene-as-metaphor composition on a single fully saturated solid color background, with a signature pop of bright leaf-green woven into every piece (hero prop, plants, motifs, or sweater). Thin uniform black outlines, flat solid fills only, no gradients or texture. Five dials per brief: palette, scene metaphor, complexity (L1/L2/L3), pose, outfit accent. Trigger when user says /mellow-pop, asks for a "mellow-pop illustration", "chill flat-vector poster", or briefs with a scene metaphor + palette + complexity.',
|
|
9276
|
+
source: { path: "illustration-template/mellow-pop" }
|
|
9277
|
+
}
|
|
9278
|
+
];
|
|
9279
|
+
function filterByKind(kind) {
|
|
9280
|
+
return OPEN_DESIGN_REGISTRY.filter((entry) => {
|
|
9281
|
+
return entry.kind === kind;
|
|
9282
|
+
});
|
|
9283
|
+
}
|
|
9284
|
+
function listImageStyles() {
|
|
9285
|
+
return filterByKind("image-style");
|
|
9286
|
+
}
|
|
9287
|
+
function findImageStyle(id) {
|
|
9288
|
+
return listImageStyles().find((entry) => {
|
|
9289
|
+
return entry.id === id;
|
|
9290
|
+
});
|
|
9291
|
+
}
|
|
9292
|
+
function toOpenDesignTarget(value) {
|
|
9293
|
+
if (value === "dashboard") {
|
|
9294
|
+
return "dashboard-design";
|
|
9295
|
+
}
|
|
9296
|
+
if (value === "docs") {
|
|
9297
|
+
return "docs-design";
|
|
9298
|
+
}
|
|
9299
|
+
if (value === "mobile-app") {
|
|
9300
|
+
return "mobile-app-design";
|
|
9301
|
+
}
|
|
9302
|
+
return value;
|
|
9303
|
+
}
|
|
9304
|
+
function selectOpenDesignCandidates() {
|
|
9305
|
+
return {
|
|
9306
|
+
registryVersion: OPEN_DESIGN_REGISTRY_VERSION,
|
|
9307
|
+
source: {
|
|
9308
|
+
repo: OPEN_DESIGN_REPO,
|
|
9309
|
+
commit: OPEN_DESIGN_COMMIT
|
|
9310
|
+
},
|
|
9311
|
+
sources: [
|
|
9312
|
+
{
|
|
9313
|
+
repo: OPEN_DESIGN_REPO,
|
|
9314
|
+
commit: OPEN_DESIGN_COMMIT
|
|
9315
|
+
},
|
|
9316
|
+
{
|
|
9317
|
+
repo: VM0_SKILLS_REPO,
|
|
9318
|
+
commit: VM0_SKILLS_REF
|
|
9319
|
+
}
|
|
9320
|
+
],
|
|
9321
|
+
candidates: {
|
|
9322
|
+
skills: filterByKind("skill"),
|
|
9323
|
+
templates: filterByKind("template"),
|
|
9324
|
+
designSystems: filterByKind("design-system"),
|
|
9325
|
+
imageStyles: filterByKind("image-style"),
|
|
9326
|
+
audioStyles: filterByKind("audio-style"),
|
|
9327
|
+
videoTemplates: filterByKind("video-template"),
|
|
9328
|
+
bundleTemplates: filterByKind("bundle-template")
|
|
9329
|
+
}
|
|
9330
|
+
};
|
|
9331
|
+
}
|
|
9332
|
+
|
|
9333
|
+
// src/commands/zero/shared/image-style-authoring.ts
|
|
9334
|
+
var outputDir = "./opendesign/images";
|
|
9335
|
+
var artifactRules = [
|
|
9336
|
+
"Resolve the selected style source before generating the image.",
|
|
9337
|
+
"Use the style skill's referenced assets and generation path when it provides one.",
|
|
9338
|
+
"Produce a single final image file and keep any temporary metadata under the output directory."
|
|
9339
|
+
];
|
|
9340
|
+
function createStyledImageAuthoringPacket(options) {
|
|
9341
|
+
const baseSlice = selectOpenDesignCandidates();
|
|
9342
|
+
const candidateSlice = {
|
|
9343
|
+
...baseSlice,
|
|
9344
|
+
candidates: {
|
|
9345
|
+
...baseSlice.candidates,
|
|
9346
|
+
imageStyles: [options.style]
|
|
9347
|
+
}
|
|
9348
|
+
};
|
|
9349
|
+
const selectionSchema = {
|
|
9350
|
+
imageStyle: "string",
|
|
9351
|
+
skills: "string[]",
|
|
9352
|
+
rationale: "string"
|
|
9353
|
+
};
|
|
9354
|
+
const artifact = {
|
|
9355
|
+
outputMode: "primary-image",
|
|
9356
|
+
primaryArtifact: {
|
|
9357
|
+
kind: "image",
|
|
9358
|
+
path: `${outputDir}/`
|
|
9359
|
+
},
|
|
9360
|
+
supportingAssets: [
|
|
9361
|
+
{
|
|
9362
|
+
kind: "metadata",
|
|
9363
|
+
path: `${outputDir}/metadata.json`,
|
|
9364
|
+
optional: true
|
|
9365
|
+
}
|
|
9366
|
+
],
|
|
9367
|
+
previewKind: "image",
|
|
9368
|
+
outputDir
|
|
9369
|
+
};
|
|
9370
|
+
const instructions = [
|
|
9371
|
+
`# Zero generate image --style ${options.style.id}`,
|
|
9372
|
+
"",
|
|
9373
|
+
"This is a federated generation resource-selection packet for the current agent.",
|
|
9374
|
+
"Zero is not generating this image on the server yet. The image style has already been selected by the caller \u2014 resolve it and generate the styled image.",
|
|
9375
|
+
"",
|
|
9376
|
+
"## User Prompt",
|
|
9377
|
+
options.prompt,
|
|
9378
|
+
"",
|
|
9379
|
+
"## Selected Image Style",
|
|
9380
|
+
`- \`${options.style.id}\` \u2014 ${options.style.name}`,
|
|
9381
|
+
"",
|
|
9382
|
+
"## Stage 1: Supporting Resource Selection",
|
|
9383
|
+
"- The image style is locked. Optionally pick supporting skills/templates from the candidate slice below.",
|
|
9384
|
+
"- Choose only IDs present in this packet; do not invent registry IDs.",
|
|
9385
|
+
"- Treat the selection JSON as internal working state, then continue to generation.",
|
|
9386
|
+
"",
|
|
9387
|
+
"## Selection Output Schema",
|
|
9388
|
+
"```json",
|
|
9389
|
+
JSON.stringify(selectionSchema, null, 2),
|
|
9390
|
+
"```",
|
|
9391
|
+
"",
|
|
9392
|
+
"## Candidate Registry Slice",
|
|
9393
|
+
`Registry: \`${candidateSlice.registryVersion}\``,
|
|
9394
|
+
"Sources:",
|
|
9395
|
+
...candidateSlice.sources.map((src) => {
|
|
9396
|
+
return `- \`${src.repo}@${src.commit}\``;
|
|
9397
|
+
}),
|
|
9398
|
+
"",
|
|
9399
|
+
"```json",
|
|
9400
|
+
JSON.stringify(candidateSlice.candidates, null, 2),
|
|
9401
|
+
"```",
|
|
9402
|
+
"",
|
|
9403
|
+
"## Stage 2: Resolve Selected Resources",
|
|
9404
|
+
"- Fetch or read the selected resource source before generation.",
|
|
9405
|
+
"- Source refs are pinned as `repo@commit:path`; use the commit in the packet for reproducibility.",
|
|
9406
|
+
"- For directory refs, inspect the most relevant files such as `SKILL.md`, references, examples, and templates.",
|
|
9407
|
+
"- If a source file cannot be fetched, state that limitation and fall back to the registry metadata for that resource.",
|
|
9408
|
+
"",
|
|
9409
|
+
"## Stage 3: Generate Image",
|
|
9410
|
+
"- Generate one production-quality image using the selected style.",
|
|
9411
|
+
"- Follow the selected style skill's generation path when it defines one.",
|
|
9412
|
+
"- If the style skill delegates to a model or connector, use that flow directly instead of restating the style text manually.",
|
|
9413
|
+
"",
|
|
9414
|
+
"## Artifact Output Model",
|
|
9415
|
+
`- Primary artifact: \`${artifact.primaryArtifact.kind}\` under \`${artifact.primaryArtifact.path}\`.`,
|
|
9416
|
+
`- Output mode: \`${artifact.outputMode}\`.`,
|
|
9417
|
+
"- Supporting metadata may live inside the same output directory when useful.",
|
|
9418
|
+
"",
|
|
9419
|
+
"## Requested Parameters",
|
|
9420
|
+
...options.details.map((detail) => {
|
|
9421
|
+
return `- ${detail}`;
|
|
9422
|
+
}),
|
|
9423
|
+
"",
|
|
9424
|
+
"## Image Authoring Rules",
|
|
9425
|
+
...artifactRules.map((rule) => {
|
|
9426
|
+
return `- ${rule}`;
|
|
9427
|
+
}),
|
|
9428
|
+
"",
|
|
9429
|
+
"## Verification",
|
|
9430
|
+
"- Verify the final image exists and is nonblank.",
|
|
9431
|
+
"- Check that the selected style's required reference anchors or source assets were used when applicable.",
|
|
9432
|
+
"- Report the final image URL or path and the selected registry resource ID."
|
|
9433
|
+
].join("\n");
|
|
9434
|
+
return {
|
|
9435
|
+
type: "open-design-resource-selection",
|
|
9436
|
+
kind: "image",
|
|
9437
|
+
prompt: options.prompt,
|
|
9438
|
+
registryVersion: candidateSlice.registryVersion,
|
|
9439
|
+
artifact,
|
|
9440
|
+
selection: {
|
|
9441
|
+
candidates: candidateSlice.candidates,
|
|
9442
|
+
outputSchema: selectionSchema
|
|
9443
|
+
},
|
|
9444
|
+
authoring: {
|
|
9445
|
+
details: options.details,
|
|
9446
|
+
artifactRules
|
|
9447
|
+
},
|
|
9448
|
+
outputDir,
|
|
9449
|
+
instructions
|
|
9450
|
+
};
|
|
9451
|
+
}
|
|
9452
|
+
|
|
9453
|
+
// src/commands/zero/generate/lib/dispatch.ts
|
|
9454
|
+
init_esm_shims();
|
|
9455
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
9456
|
+
|
|
9457
|
+
// src/commands/zero/generate/lib/connector-guidance.ts
|
|
9458
|
+
init_esm_shims();
|
|
9459
|
+
function toConnectorGenerationType(generationType) {
|
|
9460
|
+
switch (generationType) {
|
|
9461
|
+
case "voice":
|
|
9462
|
+
return "audio";
|
|
9463
|
+
case "dashboard-design":
|
|
9464
|
+
case "docs-design":
|
|
9465
|
+
case "mobile-app-design":
|
|
9466
|
+
case "poster":
|
|
9467
|
+
case "report":
|
|
9468
|
+
return null;
|
|
9469
|
+
default:
|
|
9470
|
+
return generationType;
|
|
9471
|
+
}
|
|
9472
|
+
}
|
|
9473
|
+
function isConnectorType5(value) {
|
|
9474
|
+
return value in CONNECTOR_TYPES;
|
|
9475
|
+
}
|
|
9476
|
+
function resolveConnector(provider, generationType) {
|
|
9477
|
+
if (!isConnectorType5(provider)) return null;
|
|
9478
|
+
const config = CONNECTOR_TYPES[provider];
|
|
9479
|
+
const connectorGenerationType = toConnectorGenerationType(generationType);
|
|
9480
|
+
const supports = connectorGenerationType !== null && getConnectorGenerationTypes(provider).some((entry) => {
|
|
9481
|
+
return entry === connectorGenerationType;
|
|
9482
|
+
});
|
|
9483
|
+
return {
|
|
9484
|
+
type: provider,
|
|
9485
|
+
label: config.label,
|
|
9486
|
+
supportsGenerationType: supports
|
|
9487
|
+
};
|
|
9488
|
+
}
|
|
9489
|
+
function printConnectorGuidance(generationType, provider) {
|
|
9490
|
+
const guidance = resolveConnector(provider, generationType);
|
|
9491
|
+
if (!guidance) {
|
|
9492
|
+
console.log(`Provider "${provider}" is not a known connector.`);
|
|
9493
|
+
console.log("");
|
|
9494
|
+
console.log(
|
|
9495
|
+
`Run "zero generate ${generationType}" to see every provider available for this generation type.`
|
|
9496
|
+
);
|
|
9497
|
+
return;
|
|
9498
|
+
}
|
|
9499
|
+
if (!guidance.supportsGenerationType) {
|
|
9500
|
+
console.log(
|
|
9501
|
+
`${guidance.label} (${guidance.type}) does not advertise ${generationType} generation.`
|
|
9502
|
+
);
|
|
9503
|
+
console.log("");
|
|
9504
|
+
console.log(
|
|
9505
|
+
`Run "zero generate ${generationType}" to see every provider that supports this generation type.`
|
|
9506
|
+
);
|
|
9507
|
+
return;
|
|
9508
|
+
}
|
|
9509
|
+
console.log(
|
|
9510
|
+
`${guidance.label} (${guidance.type}) handles ${generationType} generation through its own connector skill, not through "zero generate".`
|
|
9511
|
+
);
|
|
9512
|
+
console.log("");
|
|
9513
|
+
console.log(`Next steps:`);
|
|
9514
|
+
console.log(` - Use the "${guidance.type}" skill in this session.`);
|
|
9515
|
+
console.log(
|
|
9516
|
+
` - Or call the connector directly via its documented endpoints.`
|
|
9517
|
+
);
|
|
9518
|
+
console.log("");
|
|
9519
|
+
console.log(
|
|
9520
|
+
`Run "zero connector status ${guidance.type}" to verify the connector is connected and authorized for the current agent.`
|
|
9521
|
+
);
|
|
9522
|
+
}
|
|
9523
|
+
|
|
9524
|
+
// src/commands/zero/generate/lib/lister.ts
|
|
9525
|
+
init_esm_shims();
|
|
9526
|
+
var BUILT_IN_GENERATION_PROVIDERS = {
|
|
9527
|
+
image: [
|
|
9528
|
+
{
|
|
9529
|
+
label: "Built-in fal.ai",
|
|
9530
|
+
model: "gpt-image-1",
|
|
9531
|
+
command: "zero generate image --provider built-in --model gpt-image-1 -h",
|
|
9532
|
+
reason: "available without connector setup"
|
|
9533
|
+
},
|
|
9534
|
+
{
|
|
9535
|
+
label: "Built-in fal.ai",
|
|
9536
|
+
model: "gpt-image-2",
|
|
9537
|
+
command: "zero generate image --provider built-in --model gpt-image-2 -h",
|
|
9538
|
+
reason: "available without connector setup"
|
|
9539
|
+
},
|
|
9540
|
+
{
|
|
9541
|
+
label: "Built-in fal.ai",
|
|
9542
|
+
model: "gpt-image-1.5",
|
|
9543
|
+
command: "zero generate image --provider built-in --model gpt-image-1.5 -h",
|
|
9544
|
+
reason: "available without connector setup"
|
|
9545
|
+
},
|
|
9546
|
+
{
|
|
9547
|
+
label: "Built-in fal.ai",
|
|
9548
|
+
model: "gpt-image-1-mini",
|
|
9549
|
+
command: "zero generate image --provider built-in --model gpt-image-1-mini -h",
|
|
9550
|
+
reason: "available without connector setup"
|
|
9551
|
+
},
|
|
9552
|
+
{
|
|
9553
|
+
label: "Built-in fal.ai",
|
|
9554
|
+
model: "fal-ai/flux-pro/v1.1",
|
|
9555
|
+
command: "zero generate image --provider built-in --model flux-pro-1.1 -h",
|
|
9556
|
+
reason: "available without connector setup"
|
|
9557
|
+
},
|
|
9558
|
+
{
|
|
9559
|
+
label: "Built-in fal.ai",
|
|
9560
|
+
model: "fal-ai/flux-pro/v1.1-ultra",
|
|
9561
|
+
command: "zero generate image --provider built-in --model flux-pro-1.1-ultra -h",
|
|
9562
|
+
reason: "available without connector setup"
|
|
9563
|
+
},
|
|
9564
|
+
{
|
|
9565
|
+
label: "Built-in fal.ai",
|
|
9566
|
+
model: "fal-ai/qwen-image",
|
|
9567
|
+
command: "zero generate image --provider built-in --model qwen-image -h",
|
|
9568
|
+
reason: "available without connector setup"
|
|
9569
|
+
},
|
|
9570
|
+
{
|
|
9571
|
+
label: "Built-in fal.ai",
|
|
9572
|
+
model: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
9573
|
+
command: "zero generate image --provider built-in --model seedream4 -h",
|
|
9574
|
+
reason: "available without connector setup"
|
|
9575
|
+
}
|
|
9576
|
+
],
|
|
9577
|
+
presentation: [
|
|
9578
|
+
{
|
|
9579
|
+
label: "Built-in",
|
|
9580
|
+
model: "gpt-5.5",
|
|
9581
|
+
command: "zero generate presentation --provider built-in -h",
|
|
9582
|
+
reason: "available without connector setup"
|
|
9583
|
+
}
|
|
9584
|
+
],
|
|
9585
|
+
report: [
|
|
9586
|
+
{
|
|
9587
|
+
label: "Built-in",
|
|
9588
|
+
model: "gpt-5.5",
|
|
9589
|
+
command: "zero generate report --provider built-in -h",
|
|
9590
|
+
reason: "available without connector setup"
|
|
9591
|
+
}
|
|
9592
|
+
],
|
|
9593
|
+
"docs-design": [
|
|
9594
|
+
{
|
|
9595
|
+
label: "Built-in",
|
|
9596
|
+
model: "gpt-5.5",
|
|
9597
|
+
command: "zero generate docs-design --provider built-in -h",
|
|
9598
|
+
reason: "available without connector setup"
|
|
9599
|
+
}
|
|
9600
|
+
],
|
|
9601
|
+
poster: [
|
|
9602
|
+
{
|
|
9603
|
+
label: "Built-in",
|
|
9604
|
+
model: "gpt-5.5",
|
|
9605
|
+
command: "zero generate poster --provider built-in -h",
|
|
9606
|
+
reason: "available without connector setup"
|
|
9607
|
+
}
|
|
9608
|
+
],
|
|
9609
|
+
"dashboard-design": [
|
|
9610
|
+
{
|
|
9611
|
+
label: "Built-in",
|
|
9612
|
+
model: "gpt-5.5",
|
|
9613
|
+
command: "zero generate dashboard-design --provider built-in -h",
|
|
9614
|
+
reason: "available without connector setup"
|
|
9615
|
+
}
|
|
9616
|
+
],
|
|
9617
|
+
"mobile-app-design": [
|
|
9618
|
+
{
|
|
9619
|
+
label: "Built-in",
|
|
9620
|
+
model: "gpt-5.5",
|
|
9621
|
+
command: "zero generate mobile-app-design --provider built-in -h",
|
|
9622
|
+
reason: "available without connector setup"
|
|
9623
|
+
}
|
|
9624
|
+
],
|
|
9625
|
+
website: [
|
|
9626
|
+
{
|
|
9627
|
+
label: "Built-in",
|
|
9628
|
+
model: "gpt-5.5",
|
|
9629
|
+
command: "zero generate website --provider built-in -h",
|
|
9630
|
+
reason: "available without connector setup"
|
|
9631
|
+
}
|
|
9632
|
+
],
|
|
9633
|
+
video: [
|
|
9634
|
+
{
|
|
9635
|
+
label: "Built-in",
|
|
9636
|
+
model: "dreamina-seedance-2-0-260128",
|
|
9637
|
+
command: "zero generate video --provider built-in --model dreamina-seedance-2.0 -h",
|
|
9638
|
+
reason: "available without connector setup"
|
|
9639
|
+
},
|
|
9640
|
+
{
|
|
9641
|
+
label: "Built-in",
|
|
9642
|
+
model: "dreamina-seedance-2-0-fast-260128",
|
|
9643
|
+
command: "zero generate video --provider built-in --model dreamina-seedance-2.0-fast -h",
|
|
9644
|
+
reason: "available without connector setup"
|
|
9645
|
+
},
|
|
9646
|
+
{
|
|
9647
|
+
label: "Built-in",
|
|
9648
|
+
model: "seedance-1-5-pro-251215",
|
|
9649
|
+
command: "zero generate video --provider built-in --model seedance-1.5-pro -h",
|
|
9650
|
+
reason: "available without connector setup"
|
|
9651
|
+
},
|
|
9652
|
+
{
|
|
9653
|
+
label: "Built-in fal.ai",
|
|
9654
|
+
model: "fal-ai/veo3.1/fast",
|
|
9655
|
+
command: "zero generate video --provider built-in --model veo3.1-fast -h",
|
|
9656
|
+
reason: "available without connector setup"
|
|
9657
|
+
},
|
|
9658
|
+
{
|
|
9659
|
+
label: "Built-in fal.ai",
|
|
9660
|
+
model: "fal-ai/kling-video/v3/4k/text-to-video",
|
|
9661
|
+
command: "zero generate video --provider built-in --model kling-v3-4k -h",
|
|
9662
|
+
reason: "available without connector setup"
|
|
9663
|
+
}
|
|
9664
|
+
],
|
|
9665
|
+
voice: [
|
|
9666
|
+
{
|
|
9667
|
+
label: "Built-in",
|
|
9668
|
+
model: "gpt-4o-mini-tts",
|
|
9669
|
+
command: "zero generate voice --provider built-in -h",
|
|
9670
|
+
reason: "available without connector setup"
|
|
9671
|
+
}
|
|
9672
|
+
]
|
|
9673
|
+
};
|
|
9674
|
+
var BUILT_IN_GENERATION_COMMANDS = {
|
|
9675
|
+
image: {
|
|
9676
|
+
label: "Built-in image generation",
|
|
9677
|
+
command: "zero generate image --provider built-in -h",
|
|
9678
|
+
models: "fal.ai: gpt-image-1 (default), gpt-image-2, gpt-image-1.5, gpt-image-1-mini, flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, seedream4"
|
|
9713
9679
|
},
|
|
9714
|
-
{
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
description: 'Pop-art retro risograph poster of a single nostalgic everyday object on a saturated single-hue field \u2014 bold black ink outlines, halftone grain, hand-drawn doodle accents, tiny "SMALL OBJECTS IN TIME" banner up top, chunky retro headline with offset drop-shadow at the bottom.',
|
|
9719
|
-
desc: 'Pop-art retro risograph poster of a single nostalgic everyday object \u2014 saturated single-color background, bold black ink outlines, halftone/riso grain, hand-drawn doodle accents (sparkles, squiggles, dots, music notes, lightning), tiny white "SMALL OBJECTS IN TIME" banner at top, chunky retro display headline at bottom with offset black drop-shadow. Trigger when user says /riso-relic, asks for a "riso poster", a "small objects in time" illustration, or any new piece in this nostalgic pop-art relic-object style.',
|
|
9720
|
-
source: { path: "illustration-template/riso-relic" }
|
|
9680
|
+
video: {
|
|
9681
|
+
label: "Built-in video generation",
|
|
9682
|
+
command: "zero generate video --provider built-in -h",
|
|
9683
|
+
models: "dreamina-seedance-2.0-fast (default), dreamina-seedance-2.0, seedance-1.5-pro, veo3.1-fast, kling-v3-4k"
|
|
9721
9684
|
},
|
|
9722
|
-
{
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
description: "Loud indie-packaging poster style \u2014 full-bleed saturated flat color, a two-line hand-lettered headline, and one weird-cute black brush-ink character.",
|
|
9727
|
-
desc: 'Inkstomp \u2014 a loud, hand-screened indie-packaging poster style. Full-bleed saturated flat color filling the entire canvas, a two-line hand-lettered headline (thin arched caps over chunky drop-shadowed display), and one weird-cute character drawn in thick uniform black brush ink. Trigger when the user says /inkstomp, asks for an "inkstomp poster", a "Ray Fenwick / Hattie Stewart packaging poster", an "indie brush-ink flavor card", or briefs in a "palette + headline + character" shape.',
|
|
9728
|
-
source: { path: "illustration-template/inkstomp" }
|
|
9685
|
+
presentation: {
|
|
9686
|
+
label: "Built-in presentation generation",
|
|
9687
|
+
command: "zero generate presentation --provider built-in -h",
|
|
9688
|
+
models: "gpt-5.5"
|
|
9729
9689
|
},
|
|
9730
|
-
{
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
description: "Flat folk-art gouache portrait style \u2014 a single contemplative chest-up figure framed by an asymmetric botanical surround, with painted irises, smooth flat hair, a hand against the cheek, and a patterned robe.",
|
|
9735
|
-
desc: 'Flat folk-art gouache portrait illustration in the contemporary editorial style of Carson Ellis, Maja Tomljanovic, and Bodil Jane. A single chest-up figure with an elongated mannerist oval face, tiny almond half-lidded eyes, smooth flat hair, one hand pressed against the face, a patterned robe filling the lower frame, and an asymmetric botanical surround filling the background edge-to-edge. Hand-painted matte gouache texture, flat color blocks, no harsh outlines, no photorealism. Calm, slightly melancholic, contemplative mood. Trigger when the user says /folk-muse, asks for a "folk-art portrait", "gouache portrait", "Carson Ellis style portrait", or any new piece in this contemplative folk-portrait style.',
|
|
9736
|
-
source: { path: "illustration-template/folk-muse" }
|
|
9690
|
+
report: {
|
|
9691
|
+
label: "Built-in report generation",
|
|
9692
|
+
command: "zero generate report --provider built-in -h",
|
|
9693
|
+
models: "gpt-5.5"
|
|
9737
9694
|
},
|
|
9738
|
-
{
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
description: "Bright pastel travel-painting illustration in opaque gouache on textured paper with chunky flat brushstrokes, vertical one-point perspective, and figures walking into warm sunlight.",
|
|
9743
|
-
desc: 'Sunlit Gouache travel-painting illustration. Opaque gouache on textured paper, visible chunky flat brushstrokes with dry-brush highlights, locked six-color palette (cream, butter-yellow, sky-blue, sage-green, terracotta, one small red accent), vertical 2:3 one-point-perspective composition drawing the eye into a bright sunlit focal point, figures seen from behind walking into the scene, an overhead band of hanging elements (awning, prayer flags, catenary, bunting, lanterns) creating depth, dappled painterly reflections on the ground, airy optimistic warm mood. Trigger when user says /sunlit-gouache, asks for a "sunlit gouache illustration", "painterly travel scene", "gouache caf\xE9/market/temple/station scene", or a new piece in this bright pastel painted-light style.',
|
|
9744
|
-
source: { path: "illustration-template/sunlit-gouache" }
|
|
9695
|
+
"docs-design": {
|
|
9696
|
+
label: "Built-in docs design generation",
|
|
9697
|
+
command: "zero generate docs-design --provider built-in -h",
|
|
9698
|
+
models: "gpt-5.5"
|
|
9745
9699
|
},
|
|
9746
|
-
{
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
description: "Editorial still-life illustration in a mosaic-tile + painterly hybrid style \u2014 tessellated ground/sky/wall surfaces with crisp painterly objects, an animal companion, and a patterned textile peeking through.",
|
|
9751
|
-
desc: 'Mosaic-tile + painterly hybrid editorial illustration. Tessellated/pointillist mosaic surfaces (grass, sky, sand, walls, floors) anchor the scene, with crisp painterly still-life objects rendered ON TOP. Always features a still-life centerpiece on a table, an animal companion at the heart of the scene, and at least one patterned textile peeking through. Cozy, nostalgic, bucolic mood. Trigger when user says /mosaic-still-life, asks for a "mosaic illustration", "mosaic-tile editorial illustration", "tessellated still life", or briefs with a palette + scene + animal in this style.',
|
|
9752
|
-
source: { path: "illustration-template/mosaic-still-life" }
|
|
9700
|
+
poster: {
|
|
9701
|
+
label: "Built-in poster generation",
|
|
9702
|
+
command: "zero generate poster --provider built-in -h",
|
|
9703
|
+
models: "gpt-5.5"
|
|
9753
9704
|
},
|
|
9754
|
-
{
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
description: "Vintage editorial marketing card. Bold serif headline and short serif descriptor over a hand-drawn black-ink anthropomorphic mascot (stick limbs, chunky white sneakers) on a single solid saturated flat color background.",
|
|
9759
|
-
desc: 'Generate a 3:5 portrait editorial marketing card in a locked vintage-textbook style. Bold serif headline plus an optional short serif descriptor sit on a single solid saturated flat color background (no gradient, no divider, no ground line). A hand-drawn black-ink anthropomorphic hero object \u2014 paint bucket, magnifying glass, envelope, notebook, funnel, megaphone, rocket, seedling, gift box, compass, etc. \u2014 stands with two thin stick arms, two stick legs, and chunky white sneakers with black laces (the signature detail). Crosshatch and stipple shading on rounded surfaces; floating ink doodles (sparkles, arrows, hearts, percent or dollar signs, motion lines) at the requested density. Dialable along six axes: concept, palette, hero object, action, doodle density (L1 minimal, L2 balanced, L3 packed), and type layout (A title-top, B headline-bottom, C headline-only, D big-word + tiny-descriptor). Trigger when user says /ink-mascot, asks for a "marketing card illustration", a "retro editorial mascot poster", or briefs with a marketing concept plus palette plus character.',
|
|
9760
|
-
source: { path: "illustration-template/ink-mascot" }
|
|
9705
|
+
"dashboard-design": {
|
|
9706
|
+
label: "Built-in dashboard design generation",
|
|
9707
|
+
command: "zero generate dashboard-design --provider built-in -h",
|
|
9708
|
+
models: "gpt-5.5"
|
|
9761
9709
|
},
|
|
9762
|
-
{
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
description: "Hand-painted gouache sticker-sheet illustration with ~20 themed objects floating on white, punchy saturated palette, wobbly hand-drawn ink overlay, and tiny decorative marks on every item.",
|
|
9767
|
-
desc: 'Sticker Sheet \u2014 hand-painted gouache sticker-sheet illustration. ~20 small floating themed objects on pure white, punchy saturated palette (coral, mustard, sage, dusty pink, navy, cream, warm brown), flat brushy gouache fills with wobbly hand-drawn ink linework and tiny decorative marks (dots, hatches, squiggles) on every object. Each object slightly tilted, no drop shadows, cheerful cozy lifestyle journal mood. Trigger when user says /sticker-sheet, asks for a "sticker sheet illustration", "hand-painted gouache sticker pack", "themed object sheet", or briefs with a scene theme + object count in this house style.',
|
|
9768
|
-
source: { path: "illustration-template/sticker-sheet" }
|
|
9710
|
+
"mobile-app-design": {
|
|
9711
|
+
label: "Built-in mobile app design generation",
|
|
9712
|
+
command: "zero generate mobile-app-design --provider built-in -h",
|
|
9713
|
+
models: "gpt-5.5"
|
|
9769
9714
|
},
|
|
9770
|
-
{
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
description: "Vertical flat-color editorial poster style \u2014 saturated solid background, one centered hand-drawn vector subject in bold deep-navy outlines with strict two-tone fill, headline pinned top-left, wordmark pinned bottom-right.",
|
|
9775
|
-
desc: 'Flat Poster \u2014 a vertical flat-color editorial poster style for brand benefit cards, marketing posters, and in-app campaign visuals. Portrait 2:3 canvas filled edge-to-edge with one saturated hue; a single centered hand-drawn vector subject in deep-navy outlines with strict two-tone fill (pure white plus one darker bg-tint accent); a bold rounded sans-serif headline pinned top-left; a short wordmark (default VM0) pinned bottom-right; small floating accent marks around the subject; no body copy. Six creative dials: palette, subject archetype, composition preset, accent marks, headline voice, mood. Trigger when the user says /flat-poster, asks for a "flat-color editorial poster", a "brand benefit card", a "marketing card in the bold outline + flat color style", or briefs with a palette + subject + headline shape.',
|
|
9776
|
-
source: { path: "illustration-template/flat-poster" }
|
|
9715
|
+
website: {
|
|
9716
|
+
label: "Built-in website generation",
|
|
9717
|
+
command: "zero generate website --provider built-in -h",
|
|
9718
|
+
models: "gpt-5.5"
|
|
9777
9719
|
},
|
|
9778
|
-
{
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9720
|
+
voice: {
|
|
9721
|
+
label: "Built-in voice generation",
|
|
9722
|
+
command: "zero generate voice --provider built-in -h",
|
|
9723
|
+
models: "gpt-4o-mini-tts"
|
|
9724
|
+
}
|
|
9725
|
+
};
|
|
9726
|
+
var GENERATION_CONTEXT = {
|
|
9727
|
+
website: {
|
|
9728
|
+
lines: [
|
|
9729
|
+
"Standalone static website artifacts can be authored locally and published with zero host for a public URL.",
|
|
9730
|
+
"zero host is for static directories with index.html; it is not a general deploy system for apps that need a backend, database, worker, or long-running process.",
|
|
9731
|
+
"Existing web app changes should usually follow the project's own build, test, and deploy workflow."
|
|
9732
|
+
]
|
|
9733
|
+
}
|
|
9734
|
+
};
|
|
9735
|
+
var GENERATION_TYPE_ORDER = [
|
|
9736
|
+
"image",
|
|
9737
|
+
"video",
|
|
9738
|
+
"audio",
|
|
9739
|
+
"voice",
|
|
9740
|
+
"text",
|
|
9741
|
+
"code",
|
|
9742
|
+
"document",
|
|
9743
|
+
"presentation",
|
|
9744
|
+
"website",
|
|
9745
|
+
"report",
|
|
9746
|
+
"docs-design",
|
|
9747
|
+
"poster",
|
|
9748
|
+
"dashboard-design",
|
|
9749
|
+
"mobile-app-design"
|
|
9750
|
+
];
|
|
9751
|
+
var GENERATION_TYPE_LABELS = {
|
|
9752
|
+
audio: "Audio",
|
|
9753
|
+
code: "Code",
|
|
9754
|
+
"dashboard-design": "Dashboard design",
|
|
9755
|
+
document: "Document",
|
|
9756
|
+
"docs-design": "Docs design",
|
|
9757
|
+
image: "Image",
|
|
9758
|
+
"mobile-app-design": "Mobile app design",
|
|
9759
|
+
poster: "Poster",
|
|
9760
|
+
presentation: "Presentation",
|
|
9761
|
+
report: "Report",
|
|
9762
|
+
text: "Text",
|
|
9763
|
+
video: "Video",
|
|
9764
|
+
voice: "Voice",
|
|
9765
|
+
website: "Website"
|
|
9766
|
+
};
|
|
9767
|
+
function getConnectorGenerationType(generationType) {
|
|
9768
|
+
switch (generationType) {
|
|
9769
|
+
case "voice":
|
|
9770
|
+
return "audio";
|
|
9771
|
+
case "dashboard-design":
|
|
9772
|
+
case "docs-design":
|
|
9773
|
+
case "mobile-app-design":
|
|
9774
|
+
case "poster":
|
|
9775
|
+
case "report":
|
|
9776
|
+
return null;
|
|
9777
|
+
case "audio":
|
|
9778
|
+
case "code":
|
|
9779
|
+
case "document":
|
|
9780
|
+
case "image":
|
|
9781
|
+
case "presentation":
|
|
9782
|
+
case "text":
|
|
9783
|
+
case "video":
|
|
9784
|
+
case "website":
|
|
9785
|
+
return generationType;
|
|
9785
9786
|
}
|
|
9786
|
-
|
|
9787
|
-
function
|
|
9788
|
-
return
|
|
9789
|
-
|
|
9787
|
+
}
|
|
9788
|
+
function getBuiltInProviders(generationType) {
|
|
9789
|
+
return BUILT_IN_GENERATION_PROVIDERS[generationType] ?? [];
|
|
9790
|
+
}
|
|
9791
|
+
function getBuiltInCommand(generationType) {
|
|
9792
|
+
return BUILT_IN_GENERATION_COMMANDS[generationType] ?? null;
|
|
9793
|
+
}
|
|
9794
|
+
function getGenerationContext(generationType) {
|
|
9795
|
+
return GENERATION_CONTEXT[generationType] ?? null;
|
|
9796
|
+
}
|
|
9797
|
+
function getAvailableGenerationTypes() {
|
|
9798
|
+
const available = /* @__PURE__ */ new Set();
|
|
9799
|
+
for (const type of CONNECTOR_TYPE_KEYS) {
|
|
9800
|
+
for (const generationType of getConnectorGenerationTypes(type)) {
|
|
9801
|
+
available.add(generationType);
|
|
9802
|
+
}
|
|
9803
|
+
}
|
|
9804
|
+
return GENERATION_TYPE_ORDER.filter((type) => {
|
|
9805
|
+
const connectorGenerationType = getConnectorGenerationType(type);
|
|
9806
|
+
return getBuiltInProviders(type).length > 0 || connectorGenerationType !== null && available.has(connectorGenerationType);
|
|
9790
9807
|
});
|
|
9791
9808
|
}
|
|
9792
|
-
function
|
|
9793
|
-
return
|
|
9809
|
+
function getGenerationConnectors(generationType) {
|
|
9810
|
+
return CONNECTOR_TYPE_KEYS.map((type) => {
|
|
9811
|
+
return [type, CONNECTOR_TYPES[type]];
|
|
9812
|
+
}).filter(([type]) => {
|
|
9813
|
+
return getConnectorGenerationTypes(type).includes(generationType);
|
|
9814
|
+
}).sort(([a], [b]) => {
|
|
9815
|
+
return a.localeCompare(b);
|
|
9816
|
+
});
|
|
9794
9817
|
}
|
|
9795
|
-
function
|
|
9796
|
-
return
|
|
9797
|
-
|
|
9818
|
+
function isConnectorType6(type) {
|
|
9819
|
+
return type in CONNECTOR_TYPES;
|
|
9820
|
+
}
|
|
9821
|
+
async function getFeatureAvailableConnectorTypes() {
|
|
9822
|
+
const catalog = await searchZeroConnectors();
|
|
9823
|
+
return new Set(
|
|
9824
|
+
catalog.connectors.map((connector) => {
|
|
9825
|
+
return connector.id;
|
|
9826
|
+
}).filter(isConnectorType6)
|
|
9827
|
+
);
|
|
9828
|
+
}
|
|
9829
|
+
function formatAccount(connector) {
|
|
9830
|
+
if (connector.externalUsername) return `@${connector.externalUsername}`;
|
|
9831
|
+
if (connector.externalEmail) return connector.externalEmail;
|
|
9832
|
+
if (connector.externalId) return connector.externalId;
|
|
9833
|
+
return void 0;
|
|
9834
|
+
}
|
|
9835
|
+
function getAction(status, type, label, agentId, platformOrigin) {
|
|
9836
|
+
if (status === "needs-reconnect") {
|
|
9837
|
+
return {
|
|
9838
|
+
actionLabel: `Reconnect ${label}`,
|
|
9839
|
+
actionUrl: `${platformOrigin}/connectors`
|
|
9840
|
+
};
|
|
9841
|
+
}
|
|
9842
|
+
if (status === "not-authorized" && agentId) {
|
|
9843
|
+
return {
|
|
9844
|
+
actionLabel: `Authorize ${label}`,
|
|
9845
|
+
actionUrl: `${platformOrigin}/connectors/${type}/authorize?agentId=${agentId}`
|
|
9846
|
+
};
|
|
9847
|
+
}
|
|
9848
|
+
if (status === "not-connected") {
|
|
9849
|
+
if (agentId) {
|
|
9850
|
+
return {
|
|
9851
|
+
actionLabel: `Connect and authorize ${label}`,
|
|
9852
|
+
actionUrl: `${platformOrigin}/connectors/${type}/connect?agentId=${agentId}`
|
|
9853
|
+
};
|
|
9854
|
+
}
|
|
9855
|
+
return {
|
|
9856
|
+
actionLabel: `Connect ${label}`,
|
|
9857
|
+
actionUrl: `${platformOrigin}/connectors/${type}/connect`
|
|
9858
|
+
};
|
|
9859
|
+
}
|
|
9860
|
+
return {};
|
|
9861
|
+
}
|
|
9862
|
+
function toCandidate(params) {
|
|
9863
|
+
const {
|
|
9864
|
+
type,
|
|
9865
|
+
config,
|
|
9866
|
+
connector,
|
|
9867
|
+
configuredTypes,
|
|
9868
|
+
availableTypes,
|
|
9869
|
+
authorizedTypes,
|
|
9870
|
+
agentId,
|
|
9871
|
+
platformOrigin
|
|
9872
|
+
} = params;
|
|
9873
|
+
let status;
|
|
9874
|
+
let reason;
|
|
9875
|
+
if (!availableTypes.has(type)) {
|
|
9876
|
+
status = "not-available";
|
|
9877
|
+
reason = "not available for this account";
|
|
9878
|
+
} else if (connector?.needsReconnect) {
|
|
9879
|
+
status = "needs-reconnect";
|
|
9880
|
+
reason = "connected, reconnect required";
|
|
9881
|
+
} else if (!connector) {
|
|
9882
|
+
status = configuredTypes.has(type) ? "not-connected" : "not-available";
|
|
9883
|
+
reason = status === "not-connected" ? agentId ? "not connected or authorized for current agent" : "not connected" : "not available in this environment";
|
|
9884
|
+
} else if (authorizedTypes && !authorizedTypes.has(type)) {
|
|
9885
|
+
status = "not-authorized";
|
|
9886
|
+
reason = "connected, not authorized for current agent";
|
|
9887
|
+
} else {
|
|
9888
|
+
status = "ready";
|
|
9889
|
+
reason = agentId ? "connected and authorized for current agent" : "connected; agent authorization was not checked";
|
|
9890
|
+
}
|
|
9891
|
+
return {
|
|
9892
|
+
type,
|
|
9893
|
+
label: config.label,
|
|
9894
|
+
status,
|
|
9895
|
+
reason,
|
|
9896
|
+
account: connector ? formatAccount(connector) : void 0,
|
|
9897
|
+
authMethod: connector?.authMethod,
|
|
9898
|
+
...getAction(status, type, config.label, agentId, platformOrigin)
|
|
9899
|
+
};
|
|
9900
|
+
}
|
|
9901
|
+
function pad(value, width) {
|
|
9902
|
+
return value.padEnd(width);
|
|
9903
|
+
}
|
|
9904
|
+
function renderRows(candidates) {
|
|
9905
|
+
const typeWidth = Math.max(
|
|
9906
|
+
4,
|
|
9907
|
+
...candidates.map((candidate) => {
|
|
9908
|
+
return candidate.type.length;
|
|
9909
|
+
})
|
|
9910
|
+
);
|
|
9911
|
+
const labelWidth = Math.max(
|
|
9912
|
+
5,
|
|
9913
|
+
...candidates.map((candidate) => {
|
|
9914
|
+
return candidate.label.length;
|
|
9915
|
+
})
|
|
9916
|
+
);
|
|
9917
|
+
for (const candidate of candidates) {
|
|
9918
|
+
const suffix = candidate.status === "ready" ? candidate.account ?? candidate.authMethod ?? "" : candidate.reason;
|
|
9919
|
+
console.log(
|
|
9920
|
+
` ${pad(candidate.type, typeWidth)} ${pad(candidate.label, labelWidth)} ${suffix}`
|
|
9921
|
+
);
|
|
9922
|
+
}
|
|
9923
|
+
}
|
|
9924
|
+
function renderActions(candidates) {
|
|
9925
|
+
const actionable = candidates.filter((candidate) => {
|
|
9926
|
+
return candidate.actionLabel && candidate.actionUrl;
|
|
9798
9927
|
});
|
|
9928
|
+
if (actionable.length === 0) return;
|
|
9929
|
+
console.log("");
|
|
9930
|
+
console.log("Next actions:");
|
|
9931
|
+
for (const candidate of actionable) {
|
|
9932
|
+
console.log(` [${candidate.actionLabel}](${candidate.actionUrl})`);
|
|
9933
|
+
}
|
|
9799
9934
|
}
|
|
9800
|
-
function
|
|
9801
|
-
|
|
9802
|
-
|
|
9935
|
+
function renderBuiltInProvider(generationType) {
|
|
9936
|
+
const command = getBuiltInCommand(generationType);
|
|
9937
|
+
if (command) {
|
|
9938
|
+
console.log("");
|
|
9939
|
+
console.log("Built-in command:");
|
|
9940
|
+
console.log(` vm0 ${command.label}`);
|
|
9941
|
+
console.log(` Models: ${command.models}`);
|
|
9942
|
+
console.log(` Use: ${command.command}`);
|
|
9943
|
+
return;
|
|
9944
|
+
}
|
|
9945
|
+
const providers = getBuiltInProviders(generationType);
|
|
9946
|
+
if (providers.length === 0) return;
|
|
9947
|
+
console.log("");
|
|
9948
|
+
console.log(
|
|
9949
|
+
providers.length === 1 ? "Built-in provider:" : "Built-in providers:"
|
|
9950
|
+
);
|
|
9951
|
+
for (const provider of providers) {
|
|
9952
|
+
console.log(` vm0 ${provider.label} Model: ${provider.model}`);
|
|
9953
|
+
console.log(` Use: ${provider.command}`);
|
|
9954
|
+
}
|
|
9955
|
+
}
|
|
9956
|
+
function renderGenerationContext(generationType) {
|
|
9957
|
+
const context = getGenerationContext(generationType);
|
|
9958
|
+
if (!context) return;
|
|
9959
|
+
console.log("");
|
|
9960
|
+
console.log("Context:");
|
|
9961
|
+
for (const line of context.lines) {
|
|
9962
|
+
console.log(` - ${line}`);
|
|
9963
|
+
}
|
|
9964
|
+
}
|
|
9965
|
+
function renderText(params) {
|
|
9966
|
+
const { generationType, agentId, ready, other, showAll } = params;
|
|
9967
|
+
const label = GENERATION_TYPE_LABELS[generationType];
|
|
9968
|
+
const scope = agentId ? "for current agent" : "(connected connectors)";
|
|
9969
|
+
console.log(`${label} generation choices ${scope}`);
|
|
9970
|
+
console.log("");
|
|
9971
|
+
if (agentId) {
|
|
9972
|
+
console.log(`${"Agent:".padEnd(10)}${agentId}`);
|
|
9973
|
+
console.log("");
|
|
9974
|
+
} else {
|
|
9975
|
+
console.log(
|
|
9976
|
+
"ZERO_AGENT_ID is not set, so agent authorization could not be checked."
|
|
9977
|
+
);
|
|
9978
|
+
console.log("");
|
|
9979
|
+
}
|
|
9980
|
+
const hasBuiltInCommand = getBuiltInCommand(generationType) !== null;
|
|
9981
|
+
const showConnectorSummary = ready.length > 0 || !hasBuiltInCommand || showAll;
|
|
9982
|
+
if (showConnectorSummary) {
|
|
9983
|
+
console.log("Connectors:");
|
|
9984
|
+
if (ready.length > 0) {
|
|
9985
|
+
renderRows(ready);
|
|
9986
|
+
} else {
|
|
9987
|
+
console.log(` No ready ${generationType} generation connectors found.`);
|
|
9988
|
+
}
|
|
9989
|
+
}
|
|
9990
|
+
renderBuiltInProvider(generationType);
|
|
9991
|
+
renderGenerationContext(generationType);
|
|
9992
|
+
if (showAll && other.length > 0) {
|
|
9993
|
+
console.log("");
|
|
9994
|
+
console.log(`Other ${generationType} generation connectors`);
|
|
9995
|
+
console.log("");
|
|
9996
|
+
renderRows(other);
|
|
9997
|
+
}
|
|
9998
|
+
if (showAll) {
|
|
9999
|
+
renderActions(other);
|
|
10000
|
+
}
|
|
10001
|
+
}
|
|
10002
|
+
async function runLister(generationType, options = {}) {
|
|
10003
|
+
const connectorGenerationType = getConnectorGenerationType(generationType);
|
|
10004
|
+
const agentId = process.env.ZERO_AGENT_ID;
|
|
10005
|
+
const [connectorList, availableTypes, enabledTypes, platformOrigin] = await Promise.all([
|
|
10006
|
+
listZeroConnectors(),
|
|
10007
|
+
getFeatureAvailableConnectorTypes(),
|
|
10008
|
+
agentId ? getZeroAgentUserConnectors(agentId) : Promise.resolve(null),
|
|
10009
|
+
getPlatformOrigin()
|
|
10010
|
+
]);
|
|
10011
|
+
const connectedMap = new Map(
|
|
10012
|
+
connectorList.connectors.map((connector) => {
|
|
10013
|
+
return [connector.type, connector];
|
|
10014
|
+
})
|
|
10015
|
+
);
|
|
10016
|
+
const configuredTypes = new Set(connectorList.configuredTypes);
|
|
10017
|
+
const authorizedTypes = enabledTypes ? new Set(enabledTypes) : null;
|
|
10018
|
+
const candidates = connectorGenerationType ? getGenerationConnectors(connectorGenerationType).map(
|
|
10019
|
+
([connectorType, config]) => {
|
|
10020
|
+
return toCandidate({
|
|
10021
|
+
type: connectorType,
|
|
10022
|
+
config,
|
|
10023
|
+
connector: connectedMap.get(connectorType),
|
|
10024
|
+
configuredTypes,
|
|
10025
|
+
availableTypes,
|
|
10026
|
+
authorizedTypes,
|
|
10027
|
+
agentId,
|
|
10028
|
+
platformOrigin
|
|
10029
|
+
});
|
|
10030
|
+
}
|
|
10031
|
+
) : [];
|
|
10032
|
+
const ready = candidates.filter((candidate) => {
|
|
10033
|
+
return candidate.status === "ready";
|
|
10034
|
+
});
|
|
10035
|
+
const other = candidates.filter((candidate) => {
|
|
10036
|
+
return candidate.status !== "ready";
|
|
10037
|
+
});
|
|
10038
|
+
const builtInProviders = getBuiltInProviders(generationType);
|
|
10039
|
+
if (options.json) {
|
|
10040
|
+
console.log(
|
|
10041
|
+
JSON.stringify(
|
|
10042
|
+
{
|
|
10043
|
+
generationType,
|
|
10044
|
+
connectorGenerationType,
|
|
10045
|
+
availableTypes: getAvailableGenerationTypes(),
|
|
10046
|
+
agentId: agentId ?? null,
|
|
10047
|
+
choices: ready,
|
|
10048
|
+
otherCandidates: other,
|
|
10049
|
+
builtInCommand: getBuiltInCommand(generationType),
|
|
10050
|
+
generationContext: getGenerationContext(generationType),
|
|
10051
|
+
builtInProvider: builtInProviders[0] ?? null,
|
|
10052
|
+
builtInProviders
|
|
10053
|
+
},
|
|
10054
|
+
null,
|
|
10055
|
+
2
|
|
10056
|
+
)
|
|
10057
|
+
);
|
|
10058
|
+
return;
|
|
10059
|
+
}
|
|
10060
|
+
renderText({
|
|
10061
|
+
generationType,
|
|
10062
|
+
agentId,
|
|
10063
|
+
ready,
|
|
10064
|
+
other,
|
|
10065
|
+
showAll: options.all === true
|
|
10066
|
+
});
|
|
10067
|
+
const shouldShowOtherHint = !options.all && other.length > 0 && (ready.length > 0 || getBuiltInCommand(generationType) === null);
|
|
10068
|
+
if (shouldShowOtherHint) {
|
|
10069
|
+
console.log("");
|
|
10070
|
+
console.log(
|
|
10071
|
+
source_default.dim(
|
|
10072
|
+
`Use --all to see every ${generationType} generation candidate.`
|
|
10073
|
+
)
|
|
10074
|
+
);
|
|
9803
10075
|
}
|
|
9804
|
-
|
|
9805
|
-
|
|
10076
|
+
}
|
|
10077
|
+
|
|
10078
|
+
// src/commands/zero/generate/lib/dispatch.ts
|
|
10079
|
+
async function dispatchGenerate(options) {
|
|
10080
|
+
const provider = options.provider?.trim();
|
|
10081
|
+
if (provider && provider !== "built-in") {
|
|
10082
|
+
printConnectorGuidance(options.generationType, provider);
|
|
10083
|
+
return { outcome: "handled" };
|
|
9806
10084
|
}
|
|
9807
|
-
|
|
9808
|
-
|
|
10085
|
+
const resolvedPrompt = resolvePrompt(options.prompt);
|
|
10086
|
+
if (resolvedPrompt === null) {
|
|
10087
|
+
await runLister(options.generationType, {
|
|
10088
|
+
all: options.all,
|
|
10089
|
+
json: options.json
|
|
10090
|
+
});
|
|
10091
|
+
return { outcome: "handled" };
|
|
9809
10092
|
}
|
|
9810
|
-
return
|
|
10093
|
+
return { outcome: "execute", prompt: resolvedPrompt };
|
|
9811
10094
|
}
|
|
9812
|
-
function
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
repo: OPEN_DESIGN_REPO,
|
|
9822
|
-
commit: OPEN_DESIGN_COMMIT
|
|
9823
|
-
},
|
|
9824
|
-
{
|
|
9825
|
-
repo: VM0_SKILLS_REPO,
|
|
9826
|
-
commit: VM0_SKILLS_REF
|
|
10095
|
+
function resolvePrompt(prompt) {
|
|
10096
|
+
if (prompt?.trim()) {
|
|
10097
|
+
return prompt.trim();
|
|
10098
|
+
}
|
|
10099
|
+
if (process.stdin.isTTY === false) {
|
|
10100
|
+
try {
|
|
10101
|
+
const piped = readFileSync13("/dev/stdin", "utf8").trim();
|
|
10102
|
+
if (piped.length > 0) {
|
|
10103
|
+
return piped;
|
|
9827
10104
|
}
|
|
9828
|
-
|
|
9829
|
-
candidates: {
|
|
9830
|
-
skills: filterByKind("skill"),
|
|
9831
|
-
templates: filterByKind("template"),
|
|
9832
|
-
designSystems: filterByKind("design-system"),
|
|
9833
|
-
imageStyles: filterByKind("image-style"),
|
|
9834
|
-
audioStyles: filterByKind("audio-style"),
|
|
9835
|
-
videoTemplates: filterByKind("video-template"),
|
|
9836
|
-
bundleTemplates: filterByKind("bundle-template")
|
|
9837
|
-
}
|
|
9838
|
-
};
|
|
9839
|
-
}
|
|
9840
|
-
|
|
9841
|
-
// src/commands/zero/shared/image-style-authoring.ts
|
|
9842
|
-
var outputDir = "./opendesign/images";
|
|
9843
|
-
var artifactRules = [
|
|
9844
|
-
"Resolve the selected style source before generating the image.",
|
|
9845
|
-
"Use the style skill's referenced assets and generation path when it provides one.",
|
|
9846
|
-
"Produce a single final image file and keep any temporary metadata under the output directory."
|
|
9847
|
-
];
|
|
9848
|
-
function createStyledImageAuthoringPacket(options) {
|
|
9849
|
-
const baseSlice = selectOpenDesignCandidates();
|
|
9850
|
-
const candidateSlice = {
|
|
9851
|
-
...baseSlice,
|
|
9852
|
-
candidates: {
|
|
9853
|
-
...baseSlice.candidates,
|
|
9854
|
-
imageStyles: [options.style]
|
|
10105
|
+
} catch {
|
|
9855
10106
|
}
|
|
9856
|
-
}
|
|
9857
|
-
|
|
9858
|
-
imageStyle: "string",
|
|
9859
|
-
skills: "string[]",
|
|
9860
|
-
rationale: "string"
|
|
9861
|
-
};
|
|
9862
|
-
const artifact = {
|
|
9863
|
-
outputMode: "primary-image",
|
|
9864
|
-
primaryArtifact: {
|
|
9865
|
-
kind: "image",
|
|
9866
|
-
path: `${outputDir}/`
|
|
9867
|
-
},
|
|
9868
|
-
supportingAssets: [
|
|
9869
|
-
{
|
|
9870
|
-
kind: "metadata",
|
|
9871
|
-
path: `${outputDir}/metadata.json`,
|
|
9872
|
-
optional: true
|
|
9873
|
-
}
|
|
9874
|
-
],
|
|
9875
|
-
previewKind: "image",
|
|
9876
|
-
outputDir
|
|
9877
|
-
};
|
|
9878
|
-
const instructions = [
|
|
9879
|
-
`# Zero built-in generate image --style ${options.style.id}`,
|
|
9880
|
-
"",
|
|
9881
|
-
"This is a federated generation resource-selection packet for the current agent.",
|
|
9882
|
-
"Zero is not generating this image on the server yet. The image style has already been selected by the caller \u2014 resolve it and generate the styled image.",
|
|
9883
|
-
"",
|
|
9884
|
-
"## User Prompt",
|
|
9885
|
-
options.prompt,
|
|
9886
|
-
"",
|
|
9887
|
-
"## Selected Image Style",
|
|
9888
|
-
`- \`${options.style.id}\` \u2014 ${options.style.name}`,
|
|
9889
|
-
"",
|
|
9890
|
-
"## Stage 1: Supporting Resource Selection",
|
|
9891
|
-
"- The image style is locked. Optionally pick supporting skills/templates from the candidate slice below.",
|
|
9892
|
-
"- Choose only IDs present in this packet; do not invent registry IDs.",
|
|
9893
|
-
"- Treat the selection JSON as internal working state, then continue to generation.",
|
|
9894
|
-
"",
|
|
9895
|
-
"## Selection Output Schema",
|
|
9896
|
-
"```json",
|
|
9897
|
-
JSON.stringify(selectionSchema, null, 2),
|
|
9898
|
-
"```",
|
|
9899
|
-
"",
|
|
9900
|
-
"## Candidate Registry Slice",
|
|
9901
|
-
`Registry: \`${candidateSlice.registryVersion}\``,
|
|
9902
|
-
"Sources:",
|
|
9903
|
-
...candidateSlice.sources.map((src) => {
|
|
9904
|
-
return `- \`${src.repo}@${src.commit}\``;
|
|
9905
|
-
}),
|
|
9906
|
-
"",
|
|
9907
|
-
"```json",
|
|
9908
|
-
JSON.stringify(candidateSlice.candidates, null, 2),
|
|
9909
|
-
"```",
|
|
9910
|
-
"",
|
|
9911
|
-
"## Stage 2: Resolve Selected Resources",
|
|
9912
|
-
"- Fetch or read the selected resource source before generation.",
|
|
9913
|
-
"- Source refs are pinned as `repo@commit:path`; use the commit in the packet for reproducibility.",
|
|
9914
|
-
"- For directory refs, inspect the most relevant files such as `SKILL.md`, references, examples, and templates.",
|
|
9915
|
-
"- If a source file cannot be fetched, state that limitation and fall back to the registry metadata for that resource.",
|
|
9916
|
-
"",
|
|
9917
|
-
"## Stage 3: Generate Image",
|
|
9918
|
-
"- Generate one production-quality image using the selected style.",
|
|
9919
|
-
"- Follow the selected style skill's generation path when it defines one.",
|
|
9920
|
-
"- If the style skill delegates to a model or connector, use that flow directly instead of restating the style text manually.",
|
|
9921
|
-
"",
|
|
9922
|
-
"## Artifact Output Model",
|
|
9923
|
-
`- Primary artifact: \`${artifact.primaryArtifact.kind}\` under \`${artifact.primaryArtifact.path}\`.`,
|
|
9924
|
-
`- Output mode: \`${artifact.outputMode}\`.`,
|
|
9925
|
-
"- Supporting metadata may live inside the same output directory when useful.",
|
|
9926
|
-
"",
|
|
9927
|
-
"## Requested Parameters",
|
|
9928
|
-
...options.details.map((detail) => {
|
|
9929
|
-
return `- ${detail}`;
|
|
9930
|
-
}),
|
|
9931
|
-
"",
|
|
9932
|
-
"## Image Authoring Rules",
|
|
9933
|
-
...artifactRules.map((rule) => {
|
|
9934
|
-
return `- ${rule}`;
|
|
9935
|
-
}),
|
|
9936
|
-
"",
|
|
9937
|
-
"## Verification",
|
|
9938
|
-
"- Verify the final image exists and is nonblank.",
|
|
9939
|
-
"- Check that the selected style's required reference anchors or source assets were used when applicable.",
|
|
9940
|
-
"- Report the final image URL or path and the selected registry resource ID."
|
|
9941
|
-
].join("\n");
|
|
9942
|
-
return {
|
|
9943
|
-
type: "open-design-resource-selection",
|
|
9944
|
-
kind: "image",
|
|
9945
|
-
prompt: options.prompt,
|
|
9946
|
-
registryVersion: candidateSlice.registryVersion,
|
|
9947
|
-
artifact,
|
|
9948
|
-
selection: {
|
|
9949
|
-
candidates: candidateSlice.candidates,
|
|
9950
|
-
outputSchema: selectionSchema
|
|
9951
|
-
},
|
|
9952
|
-
authoring: {
|
|
9953
|
-
details: options.details,
|
|
9954
|
-
artifactRules
|
|
9955
|
-
},
|
|
9956
|
-
outputDir,
|
|
9957
|
-
instructions
|
|
9958
|
-
};
|
|
10107
|
+
}
|
|
10108
|
+
return null;
|
|
9959
10109
|
}
|
|
9960
10110
|
|
|
9961
10111
|
// src/commands/zero/shared/image-generate.ts
|
|
@@ -9996,20 +10146,6 @@ function unknownStyleError(id, usageCommand) {
|
|
|
9996
10146
|
].join("\n");
|
|
9997
10147
|
return new Error(message);
|
|
9998
10148
|
}
|
|
9999
|
-
function readPrompt(options, usageCommand) {
|
|
10000
|
-
if (options.prompt?.trim()) {
|
|
10001
|
-
return options.prompt.trim();
|
|
10002
|
-
}
|
|
10003
|
-
if (process.stdin.isTTY === false) {
|
|
10004
|
-
const prompt = readFileSync13("/dev/stdin", "utf8").trim();
|
|
10005
|
-
if (prompt.length > 0) {
|
|
10006
|
-
return prompt;
|
|
10007
|
-
}
|
|
10008
|
-
}
|
|
10009
|
-
throw new Error("--prompt is required", {
|
|
10010
|
-
cause: new Error(`Usage: ${usageCommand} --prompt "A watercolor fox"`)
|
|
10011
|
-
});
|
|
10012
|
-
}
|
|
10013
10149
|
function parseCompression(value) {
|
|
10014
10150
|
if (value === void 0) {
|
|
10015
10151
|
return void 0;
|
|
@@ -10051,6 +10187,12 @@ function parseImagePromptStrength(value) {
|
|
|
10051
10187
|
}
|
|
10052
10188
|
function createImageGenerateCommand(config) {
|
|
10053
10189
|
return new Command().name(config.name).description("Generate a billed image file from a prompt").option("--prompt <text>", "Image prompt; can also be piped via stdin").option(
|
|
10190
|
+
"--provider <name>",
|
|
10191
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name to get its skill-invocation guidance"
|
|
10192
|
+
).option(
|
|
10193
|
+
"--all",
|
|
10194
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
10195
|
+
).option(
|
|
10054
10196
|
"--model <model>",
|
|
10055
10197
|
"Model: gpt-image-1 (default), gpt-image-2, gpt-image-1.5, gpt-image-1-mini, flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, or seedream4",
|
|
10056
10198
|
"gpt-image-1"
|
|
@@ -10142,13 +10284,21 @@ Image Styles:
|
|
|
10142
10284
|
${formatStyleListing(styles)}`;
|
|
10143
10285
|
}).action(
|
|
10144
10286
|
withErrorHandler(async (options, command) => {
|
|
10287
|
+
const dispatch = await dispatchGenerate({
|
|
10288
|
+
generationType: config.generationType,
|
|
10289
|
+
provider: options.provider,
|
|
10290
|
+
prompt: options.prompt,
|
|
10291
|
+
all: options.all,
|
|
10292
|
+
json: options.json
|
|
10293
|
+
});
|
|
10294
|
+
if (dispatch.outcome === "handled") return;
|
|
10295
|
+
const prompt = dispatch.prompt;
|
|
10145
10296
|
if (options.style && options.skipStyle) {
|
|
10146
10297
|
throw new Error("--style and --skip-style cannot be combined");
|
|
10147
10298
|
}
|
|
10148
10299
|
if (!options.style && !options.skipStyle) {
|
|
10149
10300
|
throw requireStyleError(config.usageCommand);
|
|
10150
10301
|
}
|
|
10151
|
-
const prompt = readPrompt(options, config.usageCommand);
|
|
10152
10302
|
if (options.style) {
|
|
10153
10303
|
const style = findImageStyle(options.style);
|
|
10154
10304
|
if (!style) {
|
|
@@ -10228,24 +10378,26 @@ ${formatStyleListing(styles)}`;
|
|
|
10228
10378
|
);
|
|
10229
10379
|
}
|
|
10230
10380
|
|
|
10231
|
-
// src/commands/zero/
|
|
10381
|
+
// src/commands/zero/generate/image.ts
|
|
10232
10382
|
var imageCommand = createImageGenerateCommand({
|
|
10233
10383
|
name: "image",
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10384
|
+
generationType: "image",
|
|
10385
|
+
usageCommand: "zero generate image",
|
|
10386
|
+
examples: ` Styled image: zero generate image --style vm0:image-style:notion-illustration --prompt "A product manager mapping a launch plan"
|
|
10387
|
+
Skip style: zero generate image --skip-style --prompt "A watercolor fox"
|
|
10388
|
+
Pipe prompt: cat prompt.txt | zero generate image --skip-style
|
|
10389
|
+
GPT Image model: zero generate image --skip-style --model gpt-image-1.5 --prompt "A poster" --size 1024x1536 --quality high
|
|
10390
|
+
Flux model: zero generate image --skip-style --model flux-pro-1.1 --prompt "A product hero shot" --seed 42
|
|
10391
|
+
Image-to-image: zero generate image --skip-style --model flux-pro-1.1 --image-url https://example.com/mockup.png --prompt "Turn this mockup into a polished product shot"
|
|
10392
|
+
List providers: zero generate image
|
|
10393
|
+
Use a connector: zero generate image --provider replicate`
|
|
10241
10394
|
});
|
|
10242
10395
|
|
|
10243
|
-
// src/commands/zero/
|
|
10396
|
+
// src/commands/zero/generate/open-design-artifacts.ts
|
|
10244
10397
|
init_esm_shims();
|
|
10245
10398
|
|
|
10246
10399
|
// src/commands/zero/shared/open-design-artifact-generate.ts
|
|
10247
10400
|
init_esm_shims();
|
|
10248
|
-
import { readFileSync as readFileSync14 } from "fs";
|
|
10249
10401
|
|
|
10250
10402
|
// src/commands/zero/shared/html-artifact-authoring.ts
|
|
10251
10403
|
init_esm_shims();
|
|
@@ -10318,7 +10470,7 @@ function createHtmlArtifactAuthoringPacket(options) {
|
|
|
10318
10470
|
outputDir: outputDir2
|
|
10319
10471
|
};
|
|
10320
10472
|
const instructions = [
|
|
10321
|
-
`# Zero
|
|
10473
|
+
`# Zero generate ${options.kind}`,
|
|
10322
10474
|
"",
|
|
10323
10475
|
"This is a federated generation resource-selection packet for the current agent.",
|
|
10324
10476
|
`Zero is not generating this ${title} on the server. You select resources, resolve them, and author the artifact.`,
|
|
@@ -10425,22 +10577,14 @@ function createHtmlArtifactAuthoringPacket(options) {
|
|
|
10425
10577
|
}
|
|
10426
10578
|
|
|
10427
10579
|
// src/commands/zero/shared/open-design-artifact-generate.ts
|
|
10428
|
-
function readPrompt2(options, usageCommand) {
|
|
10429
|
-
if (options.prompt?.trim()) {
|
|
10430
|
-
return options.prompt.trim();
|
|
10431
|
-
}
|
|
10432
|
-
if (process.stdin.isTTY === false) {
|
|
10433
|
-
const prompt = readFileSync14("/dev/stdin", "utf8").trim();
|
|
10434
|
-
if (prompt.length > 0) {
|
|
10435
|
-
return prompt;
|
|
10436
|
-
}
|
|
10437
|
-
}
|
|
10438
|
-
throw new Error("--prompt is required", {
|
|
10439
|
-
cause: new Error(`Usage: ${usageCommand} --prompt "A product report"`)
|
|
10440
|
-
});
|
|
10441
|
-
}
|
|
10442
10580
|
function createOpenDesignArtifactGenerateCommand(config) {
|
|
10443
|
-
return new Command().name(config.name).description(config.description).option("--prompt <text>", "Artifact prompt; can also be piped via stdin").option(
|
|
10581
|
+
return new Command().name(config.name).description(config.description).option("--prompt <text>", "Artifact prompt; can also be piped via stdin").option(
|
|
10582
|
+
"--provider <name>",
|
|
10583
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name to get its skill-invocation guidance"
|
|
10584
|
+
).option(
|
|
10585
|
+
"--all",
|
|
10586
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
10587
|
+
).option("--site <slug>", "Hosted site slug; defaults to generated name").option("--title <text>", "Requested artifact title or name").option("--audience <text>", "Audience context").option("--json", "Print metadata as JSON").addHelpText(
|
|
10444
10588
|
"after",
|
|
10445
10589
|
`
|
|
10446
10590
|
Examples:
|
|
@@ -10448,13 +10592,22 @@ ${config.examples}
|
|
|
10448
10592
|
|
|
10449
10593
|
Output:
|
|
10450
10594
|
Prints an Open Design resource-selection packet for the current agent. The
|
|
10451
|
-
agent authors a static HTML artifact and hosts it with zero host.
|
|
10595
|
+
agent authors a static HTML artifact and hosts it with zero host. With no
|
|
10596
|
+
--prompt and no piped input, prints the provider menu instead.
|
|
10452
10597
|
|
|
10453
10598
|
Notes:
|
|
10454
10599
|
- Authenticates via ZERO_TOKEN`
|
|
10455
10600
|
).action(
|
|
10456
10601
|
withErrorHandler(async (options) => {
|
|
10457
|
-
const
|
|
10602
|
+
const dispatch = await dispatchGenerate({
|
|
10603
|
+
generationType: config.generationType,
|
|
10604
|
+
provider: options.provider,
|
|
10605
|
+
prompt: options.prompt,
|
|
10606
|
+
all: options.all,
|
|
10607
|
+
json: options.json
|
|
10608
|
+
});
|
|
10609
|
+
if (dispatch.outcome === "handled") return;
|
|
10610
|
+
const prompt = dispatch.prompt;
|
|
10458
10611
|
const packet = createHtmlArtifactAuthoringPacket({
|
|
10459
10612
|
kind: toOpenDesignTarget(config.target),
|
|
10460
10613
|
prompt,
|
|
@@ -10472,7 +10625,7 @@ Notes:
|
|
|
10472
10625
|
);
|
|
10473
10626
|
}
|
|
10474
10627
|
|
|
10475
|
-
// src/commands/zero/
|
|
10628
|
+
// src/commands/zero/generate/open-design-artifacts.ts
|
|
10476
10629
|
function standardDetails(kind) {
|
|
10477
10630
|
return (options) => {
|
|
10478
10631
|
return [
|
|
@@ -10484,11 +10637,13 @@ function standardDetails(kind) {
|
|
|
10484
10637
|
}
|
|
10485
10638
|
var reportCommand = createOpenDesignArtifactGenerateCommand({
|
|
10486
10639
|
name: "report",
|
|
10640
|
+
generationType: "report",
|
|
10487
10641
|
target: "report",
|
|
10488
10642
|
description: "Generate an Open Design HTML report from a prompt",
|
|
10489
|
-
usageCommand: "zero
|
|
10490
|
-
examples: ` Generate report: zero
|
|
10491
|
-
Stable hosted slug: zero
|
|
10643
|
+
usageCommand: "zero generate report",
|
|
10644
|
+
examples: ` Generate report: zero generate report --prompt "A Q2 usage report for the API team"
|
|
10645
|
+
Stable hosted slug: zero generate report --site api-usage-q2 --prompt "A Q2 usage report"
|
|
10646
|
+
List providers: zero generate report`,
|
|
10492
10647
|
details: standardDetails("report"),
|
|
10493
10648
|
artifactRules: [
|
|
10494
10649
|
"Produce an analytical report, not a marketing page.",
|
|
@@ -10499,11 +10654,13 @@ var reportCommand = createOpenDesignArtifactGenerateCommand({
|
|
|
10499
10654
|
});
|
|
10500
10655
|
var docsDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
10501
10656
|
name: "docs-design",
|
|
10657
|
+
generationType: "docs-design",
|
|
10502
10658
|
target: "docs-design",
|
|
10503
10659
|
description: "Generate an Open Design documentation design from a prompt",
|
|
10504
|
-
usageCommand: "zero
|
|
10505
|
-
examples: ` Generate docs design: zero
|
|
10506
|
-
Stable hosted slug: zero
|
|
10660
|
+
usageCommand: "zero generate docs-design",
|
|
10661
|
+
examples: ` Generate docs design: zero generate docs-design --prompt "Docs for adding OpenDesign artifact targets"
|
|
10662
|
+
Stable hosted slug: zero generate docs-design --site opendesign-target-docs --prompt "OpenDesign target docs"
|
|
10663
|
+
List providers: zero generate docs-design`,
|
|
10507
10664
|
details: standardDetails("docs-design"),
|
|
10508
10665
|
artifactRules: [
|
|
10509
10666
|
"Produce a documentation design mockup, not a production documentation system.",
|
|
@@ -10514,11 +10671,13 @@ var docsDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
|
10514
10671
|
});
|
|
10515
10672
|
var posterCommand = createOpenDesignArtifactGenerateCommand({
|
|
10516
10673
|
name: "poster",
|
|
10674
|
+
generationType: "poster",
|
|
10517
10675
|
target: "poster",
|
|
10518
10676
|
description: "Generate an Open Design HTML poster from a prompt",
|
|
10519
|
-
usageCommand: "zero
|
|
10520
|
-
examples: ` Generate poster: zero
|
|
10521
|
-
Stable hosted slug: zero
|
|
10677
|
+
usageCommand: "zero generate poster",
|
|
10678
|
+
examples: ` Generate poster: zero generate poster --prompt "A launch poster for OpenDesign artifact targets"
|
|
10679
|
+
Stable hosted slug: zero generate poster --site opendesign-poster --prompt "A launch poster"
|
|
10680
|
+
List providers: zero generate poster`,
|
|
10522
10681
|
details: standardDetails("poster"),
|
|
10523
10682
|
artifactRules: [
|
|
10524
10683
|
"Produce a poster-style HTML artifact with strong hierarchy and composition.",
|
|
@@ -10529,11 +10688,13 @@ var posterCommand = createOpenDesignArtifactGenerateCommand({
|
|
|
10529
10688
|
});
|
|
10530
10689
|
var dashboardDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
10531
10690
|
name: "dashboard-design",
|
|
10691
|
+
generationType: "dashboard-design",
|
|
10532
10692
|
target: "dashboard-design",
|
|
10533
10693
|
description: "Generate an Open Design dashboard design from a prompt",
|
|
10534
|
-
usageCommand: "zero
|
|
10535
|
-
examples: ` Generate dash design: zero
|
|
10536
|
-
Stable hosted slug: zero
|
|
10694
|
+
usageCommand: "zero generate dashboard-design",
|
|
10695
|
+
examples: ` Generate dash design: zero generate dashboard-design --prompt "An ops dashboard for generation runs"
|
|
10696
|
+
Stable hosted slug: zero generate dashboard-design --site generation-ops --prompt "A generation ops dashboard"
|
|
10697
|
+
List providers: zero generate dashboard-design`,
|
|
10537
10698
|
details: standardDetails("dashboard-design"),
|
|
10538
10699
|
artifactRules: [
|
|
10539
10700
|
"Produce a dashboard design mockup, not a live operational dashboard.",
|
|
@@ -10544,11 +10705,13 @@ var dashboardDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
|
10544
10705
|
});
|
|
10545
10706
|
var mobileAppDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
10546
10707
|
name: "mobile-app-design",
|
|
10708
|
+
generationType: "mobile-app-design",
|
|
10547
10709
|
target: "mobile-app-design",
|
|
10548
10710
|
description: "Generate an Open Design mobile app design prototype from a prompt",
|
|
10549
|
-
usageCommand: "zero
|
|
10550
|
-
examples: ` Generate mobile UI: zero
|
|
10551
|
-
Stable hosted slug: zero
|
|
10711
|
+
usageCommand: "zero generate mobile-app-design",
|
|
10712
|
+
examples: ` Generate mobile UI: zero generate mobile-app-design --prompt "A mobile review screen for generation artifacts"
|
|
10713
|
+
Stable hosted slug: zero generate mobile-app-design --site generation-mobile-review --prompt "A mobile review screen"
|
|
10714
|
+
List providers: zero generate mobile-app-design`,
|
|
10552
10715
|
details: standardDetails("mobile-app-design"),
|
|
10553
10716
|
artifactRules: [
|
|
10554
10717
|
"Produce a design prototype, not a runnable or installable mobile app.",
|
|
@@ -10558,12 +10721,11 @@ var mobileAppDesignCommand = createOpenDesignArtifactGenerateCommand({
|
|
|
10558
10721
|
]
|
|
10559
10722
|
});
|
|
10560
10723
|
|
|
10561
|
-
// src/commands/zero/
|
|
10724
|
+
// src/commands/zero/generate/presentation.ts
|
|
10562
10725
|
init_esm_shims();
|
|
10563
10726
|
|
|
10564
10727
|
// src/commands/zero/shared/presentation-generate.ts
|
|
10565
10728
|
init_esm_shims();
|
|
10566
|
-
import { readFileSync as readFileSync15 } from "fs";
|
|
10567
10729
|
var PRESENTATION_MAX_IMAGES = 8;
|
|
10568
10730
|
function parseSlideCount(value) {
|
|
10569
10731
|
const slideCount = Number(value);
|
|
@@ -10584,26 +10746,16 @@ function parseImageCount(value) {
|
|
|
10584
10746
|
}
|
|
10585
10747
|
return imageCount;
|
|
10586
10748
|
}
|
|
10587
|
-
function readPrompt3(options, usageCommand) {
|
|
10588
|
-
if (options.prompt?.trim()) {
|
|
10589
|
-
return options.prompt.trim();
|
|
10590
|
-
}
|
|
10591
|
-
if (process.stdin.isTTY === false) {
|
|
10592
|
-
const prompt = readFileSync15("/dev/stdin", "utf8").trim();
|
|
10593
|
-
if (prompt.length > 0) {
|
|
10594
|
-
return prompt;
|
|
10595
|
-
}
|
|
10596
|
-
}
|
|
10597
|
-
throw new Error("--prompt is required", {
|
|
10598
|
-
cause: new Error(
|
|
10599
|
-
`Usage: ${usageCommand} --prompt "A product roadmap deck"`
|
|
10600
|
-
)
|
|
10601
|
-
});
|
|
10602
|
-
}
|
|
10603
10749
|
function createPresentationGenerateCommand(config) {
|
|
10604
10750
|
return new Command().name(config.name).description("Generate an HTML presentation from a prompt").option(
|
|
10605
10751
|
"--prompt <text>",
|
|
10606
10752
|
"Presentation prompt; can also be piped via stdin"
|
|
10753
|
+
).option(
|
|
10754
|
+
"--provider <name>",
|
|
10755
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name to get its skill-invocation guidance"
|
|
10756
|
+
).option(
|
|
10757
|
+
"--all",
|
|
10758
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
10607
10759
|
).option("--style <style>", "Style: editorial or swiss", "editorial").option("--slides <count>", "Slide count: 4-20", parseSlideCount, 8).option(
|
|
10608
10760
|
"--images <count>",
|
|
10609
10761
|
`Generated image count: 0-${PRESENTATION_MAX_IMAGES}`,
|
|
@@ -10629,7 +10781,15 @@ Notes:
|
|
|
10629
10781
|
- The agent authors the HTML presentation artifact and hosts it with zero host`
|
|
10630
10782
|
).action(
|
|
10631
10783
|
withErrorHandler(async (options) => {
|
|
10632
|
-
const
|
|
10784
|
+
const dispatch = await dispatchGenerate({
|
|
10785
|
+
generationType: config.generationType,
|
|
10786
|
+
provider: options.provider,
|
|
10787
|
+
prompt: options.prompt,
|
|
10788
|
+
all: options.all,
|
|
10789
|
+
json: options.json
|
|
10790
|
+
});
|
|
10791
|
+
if (dispatch.outcome === "handled") return;
|
|
10792
|
+
const prompt = dispatch.prompt;
|
|
10633
10793
|
const packet = createHtmlArtifactAuthoringPacket({
|
|
10634
10794
|
kind: "presentation",
|
|
10635
10795
|
prompt,
|
|
@@ -10660,22 +10820,23 @@ Notes:
|
|
|
10660
10820
|
);
|
|
10661
10821
|
}
|
|
10662
10822
|
|
|
10663
|
-
// src/commands/zero/
|
|
10823
|
+
// src/commands/zero/generate/presentation.ts
|
|
10664
10824
|
var presentationCommand = createPresentationGenerateCommand({
|
|
10665
10825
|
name: "presentation",
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10826
|
+
generationType: "presentation",
|
|
10827
|
+
usageCommand: "zero generate presentation",
|
|
10828
|
+
examples: ` Generate deck: zero generate presentation --prompt "A strategy deck for reducing support volume"
|
|
10829
|
+
Pipe prompt: cat brief.txt | zero generate presentation
|
|
10830
|
+
Swiss style: zero generate presentation --style swiss --theme ikb --slides 10 --images 8 --image-model gpt-image-1.5 --prompt "A product launch narrative"
|
|
10831
|
+
Audience context: zero generate presentation --audience "engineering leadership" --prompt "API migration plan"
|
|
10832
|
+
List providers: zero generate presentation`
|
|
10671
10833
|
});
|
|
10672
10834
|
|
|
10673
|
-
// src/commands/zero/
|
|
10835
|
+
// src/commands/zero/generate/video.ts
|
|
10674
10836
|
init_esm_shims();
|
|
10675
10837
|
|
|
10676
10838
|
// src/commands/zero/shared/video-generate.ts
|
|
10677
10839
|
init_esm_shims();
|
|
10678
|
-
import { readFileSync as readFileSync16 } from "fs";
|
|
10679
10840
|
var FRAME_ASPECT_RATIO_TOLERANCE = 0.02;
|
|
10680
10841
|
var JPEG_START_OF_FRAME_MARKERS = /* @__PURE__ */ new Set([
|
|
10681
10842
|
192,
|
|
@@ -10869,22 +11030,14 @@ async function validateVideoOptions(options) {
|
|
|
10869
11030
|
)
|
|
10870
11031
|
]);
|
|
10871
11032
|
}
|
|
10872
|
-
function readPrompt4(options, usageCommand) {
|
|
10873
|
-
if (options.prompt?.trim()) {
|
|
10874
|
-
return options.prompt.trim();
|
|
10875
|
-
}
|
|
10876
|
-
if (process.stdin.isTTY === false) {
|
|
10877
|
-
const prompt = readFileSync16("/dev/stdin", "utf8").trim();
|
|
10878
|
-
if (prompt.length > 0) {
|
|
10879
|
-
return prompt;
|
|
10880
|
-
}
|
|
10881
|
-
}
|
|
10882
|
-
throw new Error("--prompt is required", {
|
|
10883
|
-
cause: new Error(`Usage: ${usageCommand} --prompt "A cinematic city shot"`)
|
|
10884
|
-
});
|
|
10885
|
-
}
|
|
10886
11033
|
function createVideoGenerateCommand(config) {
|
|
10887
11034
|
return new Command().name(config.name).description("Generate a billed video file from a prompt").option("--prompt <text>", "Video prompt; can also be piped via stdin").option(
|
|
11035
|
+
"--provider <name>",
|
|
11036
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name to get its skill-invocation guidance"
|
|
11037
|
+
).option(
|
|
11038
|
+
"--all",
|
|
11039
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
11040
|
+
).option(
|
|
10888
11041
|
"--model <model>",
|
|
10889
11042
|
"Model: dreamina-seedance-2.0-fast, dreamina-seedance-2.0, seedance-1.5-pro, veo3.1-fast, or kling-v3-4k",
|
|
10890
11043
|
"dreamina-seedance-2.0-fast"
|
|
@@ -10939,7 +11092,15 @@ Models:
|
|
|
10939
11092
|
4k output, negative prompts, and optional audio.`
|
|
10940
11093
|
).action(
|
|
10941
11094
|
withErrorHandler(async (options) => {
|
|
10942
|
-
const
|
|
11095
|
+
const dispatch = await dispatchGenerate({
|
|
11096
|
+
generationType: config.generationType,
|
|
11097
|
+
provider: options.provider,
|
|
11098
|
+
prompt: options.prompt,
|
|
11099
|
+
all: options.all,
|
|
11100
|
+
json: options.json
|
|
11101
|
+
});
|
|
11102
|
+
if (dispatch.outcome === "handled") return;
|
|
11103
|
+
const prompt = dispatch.prompt;
|
|
10943
11104
|
await validateVideoOptions(options);
|
|
10944
11105
|
const result = await generateWebVideo({
|
|
10945
11106
|
prompt,
|
|
@@ -10976,20 +11137,22 @@ Models:
|
|
|
10976
11137
|
);
|
|
10977
11138
|
}
|
|
10978
11139
|
|
|
10979
|
-
// src/commands/zero/
|
|
11140
|
+
// src/commands/zero/generate/video.ts
|
|
10980
11141
|
var videoCommand = createVideoGenerateCommand({
|
|
10981
11142
|
name: "video",
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
Use
|
|
10987
|
-
|
|
11143
|
+
generationType: "video",
|
|
11144
|
+
usageCommand: "zero generate video",
|
|
11145
|
+
examples: ` Generate video: zero generate video --prompt "A tracking shot through a neon market"
|
|
11146
|
+
Pipe prompt: cat prompt.txt | zero generate video
|
|
11147
|
+
Use Dreamina 2.0: zero generate video --model dreamina-seedance-2.0 --prompt "A cinematic product reveal" --duration 6s --resolution 1080p
|
|
11148
|
+
Use Seedance 1.5 Pro: zero generate video --model seedance-1.5-pro --prompt "A multi-shot chase scene" --duration 8s --resolution 720p
|
|
11149
|
+
Add a first frame: zero generate video --first-frame-image-url https://example.com/frame.png --prompt "Animate this frame"
|
|
11150
|
+
List providers: zero generate video
|
|
11151
|
+
Use HeyGen: zero generate video --provider heygen`
|
|
10988
11152
|
});
|
|
10989
11153
|
|
|
10990
|
-
// src/commands/zero/
|
|
11154
|
+
// src/commands/zero/generate/website.ts
|
|
10991
11155
|
init_esm_shims();
|
|
10992
|
-
import { readFileSync as readFileSync17 } from "fs";
|
|
10993
11156
|
var WEBSITE_TEMPLATES = ["auto", "launch", "profile"];
|
|
10994
11157
|
var WEBSITE_MAX_IMAGES = 3;
|
|
10995
11158
|
function parseTemplate(value) {
|
|
@@ -11012,23 +11175,13 @@ function parseImageCount2(value) {
|
|
|
11012
11175
|
}
|
|
11013
11176
|
return imageCount;
|
|
11014
11177
|
}
|
|
11015
|
-
function readPrompt5(options) {
|
|
11016
|
-
if (options.prompt?.trim()) {
|
|
11017
|
-
return options.prompt.trim();
|
|
11018
|
-
}
|
|
11019
|
-
if (process.stdin.isTTY === false) {
|
|
11020
|
-
const prompt = readFileSync17("/dev/stdin", "utf8").trim();
|
|
11021
|
-
if (prompt.length > 0) {
|
|
11022
|
-
return prompt;
|
|
11023
|
-
}
|
|
11024
|
-
}
|
|
11025
|
-
throw new Error("--prompt is required", {
|
|
11026
|
-
cause: new Error(
|
|
11027
|
-
'Usage: zero built-in generate website --prompt "A launch site for a developer tool"'
|
|
11028
|
-
)
|
|
11029
|
-
});
|
|
11030
|
-
}
|
|
11031
11178
|
var websiteCommand = new Command().name("website").description("Prepare website authoring instructions from a prompt").option("--prompt <text>", "Website prompt; can also be piped via stdin").option(
|
|
11179
|
+
"--provider <name>",
|
|
11180
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name to get its skill-invocation guidance"
|
|
11181
|
+
).option(
|
|
11182
|
+
"--all",
|
|
11183
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
11184
|
+
).option(
|
|
11032
11185
|
"--template <template>",
|
|
11033
11186
|
"Template: auto, launch, or profile",
|
|
11034
11187
|
parseTemplate,
|
|
@@ -11045,20 +11198,30 @@ var websiteCommand = new Command().name("website").description("Prepare website
|
|
|
11045
11198
|
"after",
|
|
11046
11199
|
`
|
|
11047
11200
|
Examples:
|
|
11048
|
-
Generate site: zero
|
|
11049
|
-
Pick template: zero
|
|
11050
|
-
Stable hosted slug: zero
|
|
11051
|
-
Pipe prompt: cat brief.txt | zero
|
|
11201
|
+
Generate site: zero generate website --prompt "A launch site for a developer observability tool"
|
|
11202
|
+
Pick template: zero generate website --template profile --images 2 --image-model gpt-image-1.5 --prompt "Portfolio for a robotics photographer"
|
|
11203
|
+
Stable hosted slug: zero generate website --site api-migration-demo --prompt "An internal migration microsite"
|
|
11204
|
+
Pipe prompt: cat brief.txt | zero generate website
|
|
11205
|
+
List providers: zero generate website
|
|
11052
11206
|
|
|
11053
11207
|
Output:
|
|
11054
11208
|
Prints an Open Design registry-selection packet for the current agent.
|
|
11209
|
+
With no --prompt and no piped input, prints the provider menu instead.
|
|
11055
11210
|
|
|
11056
11211
|
Notes:
|
|
11057
11212
|
- Authenticates via ZERO_TOKEN
|
|
11058
11213
|
- The agent authors the HTML artifact and hosts it with zero host`
|
|
11059
11214
|
).action(
|
|
11060
11215
|
withErrorHandler(async (options) => {
|
|
11061
|
-
const
|
|
11216
|
+
const dispatch = await dispatchGenerate({
|
|
11217
|
+
generationType: "website",
|
|
11218
|
+
provider: options.provider,
|
|
11219
|
+
prompt: options.prompt,
|
|
11220
|
+
all: options.all,
|
|
11221
|
+
json: options.json
|
|
11222
|
+
});
|
|
11223
|
+
if (dispatch.outcome === "handled") return;
|
|
11224
|
+
const prompt = dispatch.prompt;
|
|
11062
11225
|
const packet = createHtmlArtifactAuthoringPacket({
|
|
11063
11226
|
kind: "website",
|
|
11064
11227
|
prompt,
|
|
@@ -11086,35 +11249,27 @@ Notes:
|
|
|
11086
11249
|
})
|
|
11087
11250
|
);
|
|
11088
11251
|
|
|
11089
|
-
// src/commands/zero/
|
|
11252
|
+
// src/commands/zero/generate/voice.ts
|
|
11090
11253
|
init_esm_shims();
|
|
11091
11254
|
|
|
11092
11255
|
// src/commands/zero/shared/voice-generate.ts
|
|
11093
11256
|
init_esm_shims();
|
|
11094
|
-
import { readFileSync as readFileSync18 } from "fs";
|
|
11095
|
-
function readText(options, usageCommand) {
|
|
11096
|
-
if (options.text?.trim()) {
|
|
11097
|
-
return options.text.trim();
|
|
11098
|
-
}
|
|
11099
|
-
if (process.stdin.isTTY === false) {
|
|
11100
|
-
const text = readFileSync18("/dev/stdin", "utf8").trim();
|
|
11101
|
-
if (text.length > 0) {
|
|
11102
|
-
return text;
|
|
11103
|
-
}
|
|
11104
|
-
}
|
|
11105
|
-
throw new Error("--text is required", {
|
|
11106
|
-
cause: new Error(`Usage: ${usageCommand} --text "Hello"`)
|
|
11107
|
-
});
|
|
11108
|
-
}
|
|
11109
11257
|
function createVoiceGenerateCommand(config) {
|
|
11110
|
-
return new Command().name(config.name).description("Generate a billed speech audio file from text").option("--
|
|
11258
|
+
return new Command().name(config.name).description("Generate a billed speech audio file from text").option("--prompt <text>", "Text to speak; can also be piped via stdin").addOption(new Option("--text <text>", "Alias for --prompt").hideHelp()).option(
|
|
11259
|
+
"--provider <name>",
|
|
11260
|
+
"Provider: 'built-in' to run vm0's pipeline, or a connector name (heygen, elevenlabs, ...) to get its skill-invocation guidance"
|
|
11261
|
+
).option(
|
|
11262
|
+
"--all",
|
|
11263
|
+
"When listing providers (no --prompt given), include unavailable or not-yet-authorized connectors"
|
|
11264
|
+
).option("--voice <voice>", "OpenAI voice to use", "marin").option("--instructions <text>", "Voice style instructions").option("--json", "Print metadata as JSON").addHelpText(
|
|
11111
11265
|
"after",
|
|
11112
11266
|
`
|
|
11113
11267
|
Examples:
|
|
11114
11268
|
${config.examples}
|
|
11115
11269
|
|
|
11116
11270
|
Output:
|
|
11117
|
-
Prints the generated /f/ audio file URL and metadata
|
|
11271
|
+
Prints the generated /f/ audio file URL and metadata. With no --prompt
|
|
11272
|
+
and no piped input, prints the provider menu instead.
|
|
11118
11273
|
|
|
11119
11274
|
Notes:
|
|
11120
11275
|
- Authenticates via ZERO_TOKEN (requires file:write capability)
|
|
@@ -11122,7 +11277,15 @@ Notes:
|
|
|
11122
11277
|
- Uses gpt-4o-mini-tts with WAV output`
|
|
11123
11278
|
).action(
|
|
11124
11279
|
withErrorHandler(async (options) => {
|
|
11125
|
-
const
|
|
11280
|
+
const dispatch = await dispatchGenerate({
|
|
11281
|
+
generationType: config.generationType,
|
|
11282
|
+
provider: options.provider,
|
|
11283
|
+
prompt: options.prompt ?? options.text,
|
|
11284
|
+
all: options.all,
|
|
11285
|
+
json: options.json
|
|
11286
|
+
});
|
|
11287
|
+
if (dispatch.outcome === "handled") return;
|
|
11288
|
+
const text = dispatch.prompt;
|
|
11126
11289
|
const result = await generateWebVoice({
|
|
11127
11290
|
text,
|
|
11128
11291
|
voice: options.voice,
|
|
@@ -11142,53 +11305,108 @@ Notes:
|
|
|
11142
11305
|
);
|
|
11143
11306
|
}
|
|
11144
11307
|
|
|
11145
|
-
// src/commands/zero/
|
|
11308
|
+
// src/commands/zero/generate/voice.ts
|
|
11146
11309
|
var voiceCommand = createVoiceGenerateCommand({
|
|
11147
11310
|
name: "voice",
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
|
|
11151
|
-
|
|
11311
|
+
generationType: "voice",
|
|
11312
|
+
usageCommand: "zero generate voice",
|
|
11313
|
+
examples: ` Generate speech: zero generate voice --prompt "Hello from vm0"
|
|
11314
|
+
Pipe prompt: cat script.txt | zero generate voice
|
|
11315
|
+
Pick a voice: zero generate voice --prompt "Ship it" --voice cedar
|
|
11316
|
+
List providers: zero generate voice
|
|
11317
|
+
Use ElevenLabs: zero generate voice --provider elevenlabs`
|
|
11152
11318
|
});
|
|
11153
11319
|
|
|
11154
|
-
// src/commands/zero/
|
|
11320
|
+
// src/commands/zero/generate/lister-only.ts
|
|
11321
|
+
init_esm_shims();
|
|
11322
|
+
function createListerOnlyCommand(config) {
|
|
11323
|
+
return new Command().name(config.name).description(config.description).option(
|
|
11324
|
+
"--provider <name>",
|
|
11325
|
+
"Connector name; prints that connector's skill-invocation guidance"
|
|
11326
|
+
).option("--all", "Include unavailable or not-yet-authorized connectors").option("--json", "Print the provider list as JSON").addHelpText(
|
|
11327
|
+
"after",
|
|
11328
|
+
`
|
|
11329
|
+
Notes:
|
|
11330
|
+
- vm0 does not provide a built-in ${config.generationType} pipeline.
|
|
11331
|
+
- Use --provider <connector-name> to get skill-invocation guidance for a
|
|
11332
|
+
specific connector, or run with no flags to see every available provider.`
|
|
11333
|
+
).action(
|
|
11334
|
+
withErrorHandler(async (options) => {
|
|
11335
|
+
const provider = options.provider?.trim();
|
|
11336
|
+
if (provider && provider !== "built-in") {
|
|
11337
|
+
printConnectorGuidance(config.generationType, provider);
|
|
11338
|
+
return;
|
|
11339
|
+
}
|
|
11340
|
+
if (provider === "built-in") {
|
|
11341
|
+
console.log(
|
|
11342
|
+
`vm0 has no built-in ${config.generationType} generation pipeline.`
|
|
11343
|
+
);
|
|
11344
|
+
console.log("");
|
|
11345
|
+
console.log(
|
|
11346
|
+
`Run "zero generate ${config.generationType}" to see every connector-backed provider.`
|
|
11347
|
+
);
|
|
11348
|
+
return;
|
|
11349
|
+
}
|
|
11350
|
+
await runLister(config.generationType, {
|
|
11351
|
+
all: options.all,
|
|
11352
|
+
json: options.json
|
|
11353
|
+
});
|
|
11354
|
+
})
|
|
11355
|
+
);
|
|
11356
|
+
}
|
|
11357
|
+
|
|
11358
|
+
// src/commands/zero/generate/index.ts
|
|
11359
|
+
var audioCommand = createListerOnlyCommand({
|
|
11360
|
+
name: "audio",
|
|
11361
|
+
generationType: "audio",
|
|
11362
|
+
description: "List connectors that provide audio generation (alias of voice for non-speech audio)"
|
|
11363
|
+
});
|
|
11364
|
+
var textCommand = createListerOnlyCommand({
|
|
11365
|
+
name: "text",
|
|
11366
|
+
generationType: "text",
|
|
11367
|
+
description: "List connectors that provide text generation"
|
|
11368
|
+
});
|
|
11369
|
+
var codeCommand = createListerOnlyCommand({
|
|
11370
|
+
name: "code",
|
|
11371
|
+
generationType: "code",
|
|
11372
|
+
description: "List connectors that provide code generation"
|
|
11373
|
+
});
|
|
11374
|
+
var documentCommand = createListerOnlyCommand({
|
|
11375
|
+
name: "document",
|
|
11376
|
+
generationType: "document",
|
|
11377
|
+
description: "List connectors that provide document generation"
|
|
11378
|
+
});
|
|
11155
11379
|
function buildGenerateHelpText() {
|
|
11156
11380
|
const examples = [
|
|
11157
|
-
' Generate image:
|
|
11158
|
-
' Generate deck:
|
|
11159
|
-
' Generate report:
|
|
11160
|
-
' Generate docs:
|
|
11161
|
-
' Generate video:
|
|
11381
|
+
' Generate image: zero generate image --prompt "A watercolor fox"',
|
|
11382
|
+
' Generate deck: zero generate presentation --prompt "A product roadmap"',
|
|
11383
|
+
' Generate report: zero generate report --prompt "A Q2 usage report"',
|
|
11384
|
+
' Generate docs: zero generate docs-design --prompt "A setup guide"',
|
|
11385
|
+
' Generate video: zero generate video --prompt "A cinematic city shot"',
|
|
11162
11386
|
...zeroTokenAllowsFeatureSwitch("hostedSites" /* HostedSites */) ? [
|
|
11163
|
-
' Generate site:
|
|
11387
|
+
' Generate site: zero generate website --prompt "A launch site"'
|
|
11164
11388
|
] : [],
|
|
11165
|
-
' Generate speech:
|
|
11389
|
+
' Generate speech: zero generate voice --prompt "Hello"',
|
|
11390
|
+
"",
|
|
11391
|
+
" List image providers: zero generate image",
|
|
11392
|
+
" Use a connector: zero generate video --provider heygen",
|
|
11393
|
+
" Force built-in: zero generate image --provider built-in --model gpt-image-1.5 --prompt ..."
|
|
11166
11394
|
];
|
|
11167
11395
|
return `
|
|
11168
11396
|
Examples:
|
|
11169
|
-
${examples.join("\n")}
|
|
11397
|
+
${examples.join("\n")}
|
|
11398
|
+
|
|
11399
|
+
Notes:
|
|
11400
|
+
- Run "zero generate <type>" with no --prompt to list every provider available for that type.
|
|
11401
|
+
- --provider built-in (default when --prompt is provided) runs the vm0-hosted pipeline.
|
|
11402
|
+
- --provider <connector-name> prints how to invoke that connector's skill instead.`;
|
|
11170
11403
|
}
|
|
11171
|
-
var
|
|
11404
|
+
var generateCommand = new Command().name("generate").description(
|
|
11405
|
+
"Generate assets via vm0's built-in pipelines or get connector skill-invocation guidance"
|
|
11406
|
+
).addCommand(imageCommand).addCommand(presentationCommand).addCommand(reportCommand).addCommand(docsDesignCommand).addCommand(posterCommand).addCommand(dashboardDesignCommand).addCommand(mobileAppDesignCommand).addCommand(videoCommand).addCommand(
|
|
11172
11407
|
websiteCommand,
|
|
11173
11408
|
zeroTokenAllowsFeatureSwitch("hostedSites" /* HostedSites */) ? {} : { hidden: true }
|
|
11174
|
-
).addCommand(voiceCommand).addHelpText("after", buildGenerateHelpText);
|
|
11175
|
-
|
|
11176
|
-
// src/commands/zero/built-in/index.ts
|
|
11177
|
-
function buildBuiltInHelpText() {
|
|
11178
|
-
const examples = [
|
|
11179
|
-
' Generate image: zero built-in generate image --prompt "A watercolor fox"',
|
|
11180
|
-
' Generate deck: zero built-in generate presentation --prompt "A product roadmap"',
|
|
11181
|
-
' Generate video: zero built-in generate video --prompt "A cinematic city shot"',
|
|
11182
|
-
...zeroTokenAllowsFeatureSwitch("hostedSites" /* HostedSites */) ? [
|
|
11183
|
-
' Generate site: zero built-in generate website --prompt "A launch site"'
|
|
11184
|
-
] : [],
|
|
11185
|
-
' Generate speech: zero built-in generate voice --text "Hello"'
|
|
11186
|
-
];
|
|
11187
|
-
return `
|
|
11188
|
-
Examples:
|
|
11189
|
-
${examples.join("\n")}`;
|
|
11190
|
-
}
|
|
11191
|
-
var zeroBuiltInCommand = new Command().name("built-in").description("Use built-in vm0 services").addCommand(generateCommand2).addHelpText("after", buildBuiltInHelpText);
|
|
11409
|
+
).addCommand(voiceCommand).addCommand(audioCommand).addCommand(textCommand).addCommand(codeCommand).addCommand(documentCommand).addHelpText("after", buildGenerateHelpText);
|
|
11192
11410
|
|
|
11193
11411
|
// src/commands/zero/web/index.ts
|
|
11194
11412
|
init_esm_shims();
|
|
@@ -12247,7 +12465,7 @@ var COMMAND_CAPABILITY_MAP = {
|
|
|
12247
12465
|
whoami: null,
|
|
12248
12466
|
"developer-support": null,
|
|
12249
12467
|
"computer-use": "computer-use:write",
|
|
12250
|
-
|
|
12468
|
+
generate: "file:write",
|
|
12251
12469
|
web: null,
|
|
12252
12470
|
host: "host:write",
|
|
12253
12471
|
maps: "maps:read",
|
|
@@ -12278,7 +12496,7 @@ var DEFAULT_COMMANDS = [
|
|
|
12278
12496
|
zeroSkillCommand,
|
|
12279
12497
|
zeroDeveloperSupportCommand,
|
|
12280
12498
|
zeroComputerUseCommand,
|
|
12281
|
-
|
|
12499
|
+
generateCommand,
|
|
12282
12500
|
zeroWebCommand,
|
|
12283
12501
|
zeroHostCommand,
|
|
12284
12502
|
zeroMapsCommand,
|
|
@@ -12287,7 +12505,7 @@ var DEFAULT_COMMANDS = [
|
|
|
12287
12505
|
];
|
|
12288
12506
|
function shouldHideCommand(name, payload) {
|
|
12289
12507
|
if (!payload) return false;
|
|
12290
|
-
if (name === "
|
|
12508
|
+
if (name === "generate") {
|
|
12291
12509
|
return !payload.capabilities.includes("file:write") && !zeroTokenAllowsFeatureSwitch("hostedSites" /* HostedSites */, payload);
|
|
12292
12510
|
}
|
|
12293
12511
|
const requiredCap = COMMAND_CAPABILITY_MAP[name];
|
|
@@ -12320,9 +12538,10 @@ function buildZeroHelpText(payload = decodeZeroTokenPayload()) {
|
|
|
12320
12538
|
" Model routing? zero model-provider ls",
|
|
12321
12539
|
" Update yourself? zero agent --help",
|
|
12322
12540
|
" Manage custom skills? zero skill --help",
|
|
12323
|
-
"
|
|
12324
|
-
|
|
12325
|
-
" Generate
|
|
12541
|
+
" List generators? zero generate --help",
|
|
12542
|
+
' Generate image? zero generate image --prompt "..."',
|
|
12543
|
+
...zeroTokenAllowsFeatureSwitch("hostedSites" /* HostedSites */, payload) ? [' Generate website? zero generate website --prompt "..."'] : [],
|
|
12544
|
+
' Generate voice? zero generate voice --prompt "..."',
|
|
12326
12545
|
...shouldHideCommand("local-browser", payload) ? [] : [" Read browser context? zero local-browser --help"],
|
|
12327
12546
|
...shouldHideCommand("host", payload) ? [] : [" Host a static site? zero host ./dist --site my-site --spa"],
|
|
12328
12547
|
...shouldHideCommand("maps", payload) ? [] : [
|
|
@@ -12345,7 +12564,7 @@ function registerZeroCommands(prog, commands) {
|
|
|
12345
12564
|
var program = new Command();
|
|
12346
12565
|
program.name("zero").description(
|
|
12347
12566
|
"Zero CLI \u2014 interact with the zero platform from inside the sandbox"
|
|
12348
|
-
).version("9.
|
|
12567
|
+
).version("9.169.0").addHelpText("after", () => {
|
|
12349
12568
|
return buildZeroHelpText();
|
|
12350
12569
|
});
|
|
12351
12570
|
if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {
|