wholestack 0.6.1 → 0.7.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/dist/{chunk-KJ5INI3M.js → chunk-NHABZZTE.js} +788 -186
- package/dist/cli.js +443 -61
- package/dist/index.d.ts +249 -13
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
buildWebTools,
|
|
21
21
|
c,
|
|
22
22
|
collectLocalFiles,
|
|
23
|
+
deliverBuild,
|
|
24
|
+
demoBootBuild,
|
|
23
25
|
deployBuild,
|
|
24
26
|
drawCanvas,
|
|
25
27
|
escalationBus,
|
|
@@ -28,8 +30,11 @@ import {
|
|
|
28
30
|
generateLegal,
|
|
29
31
|
getBusiness,
|
|
30
32
|
getLaunchKit,
|
|
33
|
+
httpBuild,
|
|
31
34
|
inspectUrl,
|
|
35
|
+
installDeps,
|
|
32
36
|
isPermissionMode,
|
|
37
|
+
isolateFromWorkspace,
|
|
33
38
|
killRunningApps,
|
|
34
39
|
line,
|
|
35
40
|
listBusinesses,
|
|
@@ -62,6 +67,7 @@ import {
|
|
|
62
67
|
rollbackDeployment,
|
|
63
68
|
runProver,
|
|
64
69
|
runRepoAuditStream,
|
|
70
|
+
runVolitionSubcommand,
|
|
65
71
|
saveKey,
|
|
66
72
|
searchLessons,
|
|
67
73
|
stateDir,
|
|
@@ -75,11 +81,11 @@ import {
|
|
|
75
81
|
webBaseUrl,
|
|
76
82
|
writeProjectLink,
|
|
77
83
|
writeWorkingTree
|
|
78
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-NHABZZTE.js";
|
|
79
85
|
|
|
80
86
|
// src/cli.ts
|
|
81
87
|
import { createInterface } from "readline/promises";
|
|
82
|
-
import { stdin, stdout as
|
|
88
|
+
import { stdin, stdout as stdout4, argv, exit, cwd as cwd3 } from "process";
|
|
83
89
|
|
|
84
90
|
// src/cli-login.ts
|
|
85
91
|
import { createServer } from "http";
|
|
@@ -107,7 +113,7 @@ async function loginBrowser(opts) {
|
|
|
107
113
|
const state = randomBytes(16).toString("hex");
|
|
108
114
|
const device = hostname().slice(0, 60);
|
|
109
115
|
const timeoutMs = (opts.timeoutSec ?? 240) * 1e3;
|
|
110
|
-
return new Promise((
|
|
116
|
+
return new Promise((resolve5) => {
|
|
111
117
|
let settled = false;
|
|
112
118
|
const finish = (token) => {
|
|
113
119
|
if (settled) return;
|
|
@@ -117,7 +123,7 @@ async function loginBrowser(opts) {
|
|
|
117
123
|
server.close();
|
|
118
124
|
} catch {
|
|
119
125
|
}
|
|
120
|
-
|
|
126
|
+
resolve5(token);
|
|
121
127
|
};
|
|
122
128
|
const server = createServer((req, res) => {
|
|
123
129
|
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
@@ -334,7 +340,7 @@ async function renderTree(absDir, relDir) {
|
|
|
334
340
|
return `${relDir || "."}/ (directory tree)
|
|
335
341
|
${lines.join("\n")}`;
|
|
336
342
|
}
|
|
337
|
-
async function expandMentions(message,
|
|
343
|
+
async function expandMentions(message, cwd4, tokenBudget = DEFAULT_TOKEN_BUDGET) {
|
|
338
344
|
const mentions = extractMentions(message);
|
|
339
345
|
if (mentions.length === 0) return { context: "", notice: null };
|
|
340
346
|
const blocks = [];
|
|
@@ -344,7 +350,7 @@ async function expandMentions(message, cwd3, tokenBudget = DEFAULT_TOKEN_BUDGET)
|
|
|
344
350
|
for (const mention of mentions) {
|
|
345
351
|
if (spent >= tokenBudget) break;
|
|
346
352
|
const raw = mention.startsWith("~/") ? join(process.env.HOME ?? "", mention.slice(2)) : mention;
|
|
347
|
-
const direct = isAbsolute(raw) ? raw : resolve(
|
|
353
|
+
const direct = isAbsolute(raw) ? raw : resolve(cwd4, raw);
|
|
348
354
|
let isDir = false;
|
|
349
355
|
try {
|
|
350
356
|
isDir = (await stat(direct)).isDirectory();
|
|
@@ -352,7 +358,7 @@ async function expandMentions(message, cwd3, tokenBudget = DEFAULT_TOKEN_BUDGET)
|
|
|
352
358
|
isDir = false;
|
|
353
359
|
}
|
|
354
360
|
if (isDir) {
|
|
355
|
-
const rel = relative(
|
|
361
|
+
const rel = relative(cwd4, direct);
|
|
356
362
|
const tree = await renderTree(direct, rel);
|
|
357
363
|
const cost = estTokens(tree);
|
|
358
364
|
if (spent + cost <= tokenBudget) {
|
|
@@ -365,7 +371,7 @@ async function expandMentions(message, cwd3, tokenBudget = DEFAULT_TOKEN_BUDGET)
|
|
|
365
371
|
let files = [];
|
|
366
372
|
try {
|
|
367
373
|
files = await fg(raw, {
|
|
368
|
-
cwd:
|
|
374
|
+
cwd: cwd4,
|
|
369
375
|
ignore: IGNORE,
|
|
370
376
|
onlyFiles: true,
|
|
371
377
|
dot: true,
|
|
@@ -377,7 +383,7 @@ async function expandMentions(message, cwd3, tokenBudget = DEFAULT_TOKEN_BUDGET)
|
|
|
377
383
|
}
|
|
378
384
|
if (files.length === 0) {
|
|
379
385
|
try {
|
|
380
|
-
if ((await stat(direct)).isFile()) files = [relative(
|
|
386
|
+
if ((await stat(direct)).isFile()) files = [relative(cwd4, direct)];
|
|
381
387
|
} catch {
|
|
382
388
|
}
|
|
383
389
|
}
|
|
@@ -388,7 +394,7 @@ async function expandMentions(message, cwd3, tokenBudget = DEFAULT_TOKEN_BUDGET)
|
|
|
388
394
|
seen.add(rel);
|
|
389
395
|
let buf;
|
|
390
396
|
try {
|
|
391
|
-
buf = await readFile2(resolve(
|
|
397
|
+
buf = await readFile2(resolve(cwd4, rel), "utf8");
|
|
392
398
|
} catch {
|
|
393
399
|
continue;
|
|
394
400
|
}
|
|
@@ -563,9 +569,9 @@ function workerToolset(worktreeCtx) {
|
|
|
563
569
|
return out;
|
|
564
570
|
}
|
|
565
571
|
var WORKER_SYSTEM = "You are an autonomous engineer spawned by a lead engineer to complete ONE focused, self-contained slice of a larger task. You have a full coding toolset (read_file, write_file, edit_file, multi_edit, list_dir, glob, grep, run_command) and you are working in your OWN isolated git worktree \u2014 your edits cannot affect anyone else, so edit freely. Approach: (1) explore the relevant files, (2) make the change, (3) verify it (build/test/typecheck where it makes sense), (4) report. Stay strictly within your assigned slice \u2014 do not refactor unrelated code. When done, return a tight summary: what you changed, which files, and how you verified it.";
|
|
566
|
-
function git(args,
|
|
572
|
+
function git(args, cwd4, timeoutMs = 3e4) {
|
|
567
573
|
return new Promise((res) => {
|
|
568
|
-
const child = spawn2("git", args, { cwd:
|
|
574
|
+
const child = spawn2("git", args, { cwd: cwd4, shell: false });
|
|
569
575
|
let out = "";
|
|
570
576
|
const timer = setTimeout(() => child.kill("SIGKILL"), timeoutMs);
|
|
571
577
|
const sink = (b) => {
|
|
@@ -846,6 +852,365 @@ async function runOpsSubcommand(raw) {
|
|
|
846
852
|
return 1;
|
|
847
853
|
}
|
|
848
854
|
|
|
855
|
+
// src/factory.ts
|
|
856
|
+
import { existsSync, mkdirSync, readFileSync } from "fs";
|
|
857
|
+
import { join as join3, resolve as resolve2 } from "path";
|
|
858
|
+
import { cwd as cwd2, stderr, stdout as stdout2 } from "process";
|
|
859
|
+
var HELP = `${c.bold("wholestack make")} \u2014 the app factory. One idea in, a full-stack app out.
|
|
860
|
+
|
|
861
|
+
${c.bold("USAGE")}
|
|
862
|
+
wholestack make ${c.dim('"<idea>"')} make one app from an idea
|
|
863
|
+
wholestack make --batch ${c.dim("<file>")} make one app per non-blank line of a file
|
|
864
|
+
|
|
865
|
+
${c.bold("OPTIONS")}
|
|
866
|
+
--out ${c.dim("<dir>")} parent dir for delivered apps ${c.dim("(default: ./out)")}
|
|
867
|
+
--batch ${c.dim("<file>")} a file of ideas, one per line (# comments allowed)
|
|
868
|
+
--concurrency ${c.dim("<n>")} build N apps at once ${c.dim("(default: 1; engine may rate-limit)")}
|
|
869
|
+
--json emit NDJSON results to stdout, human chrome to stderr
|
|
870
|
+
--boot boot a free live URL instead of delivering code ${c.dim("(no paywall)")}
|
|
871
|
+
--install run pnpm install in each delivered app
|
|
872
|
+
--max use the zeta-g1-max build model ${c.dim("(default: zeta-g1)")}
|
|
873
|
+
--theme ${c.dim("<id>")} force a theme id
|
|
874
|
+
--style ${c.dim("<id>")} force a Launch Style id (e.g. mono-noir, voltage)
|
|
875
|
+
--color ${c.dim("<d|l>")} force dark or light
|
|
876
|
+
--tier ${c.dim("<t>")} app size: solo\xB7team\xB7enterprise ${c.dim("(default: inferred from the idea)")}
|
|
877
|
+
--feature ${c.dim("<f>")} force a feature on (repeatable); prefix ${c.dim("no-")} to force off
|
|
878
|
+
--mobile add the Capacitor store-shippable iOS/Android shell
|
|
879
|
+
--archetype ${c.dim("<a>")} pin the interior layout: analytics\xB7document-editor\xB7collaboration\xB7kanban\xB7calendar\xB7marketplace\xB7studio
|
|
880
|
+
--vibe ${c.dim("<v>")} look filter: cinematic-dark\xB7editorial-luxe\xB7warm-minimal\xB7bold-brutalist\xB7glass-futuristic\xB7vibrant-playful\xB7corporate-clean
|
|
881
|
+
--verbose stream the engine's build phases
|
|
882
|
+
-h, --help show this help
|
|
883
|
+
|
|
884
|
+
${c.bold("FEATURES")} ${c.dim("(for --feature)")}
|
|
885
|
+
${c.dim("socialAuth \xB7 multiTenant \xB7 billing \xB7 search \xB7 files \xB7 admin \xB7 compliance \xB7 infra \xB7 mobile \xB7 analytics")}
|
|
886
|
+
${c.dim("e.g. --tier solo --feature billing --feature no-infra (a lean app + payments, no terraform)")}
|
|
887
|
+
|
|
888
|
+
${c.bold("NOTES")}
|
|
889
|
+
\u2022 Delivering code requires a Wholestack membership and spends one build credit per
|
|
890
|
+
app. Run ${c.cyan("wholestack login")} first. ${c.dim("--boot is free but keeps no code.")}
|
|
891
|
+
\u2022 Exit code is 0 only when every requested app shipped.`;
|
|
892
|
+
var FEATURE_KEYS = [
|
|
893
|
+
"socialAuth",
|
|
894
|
+
"multiTenant",
|
|
895
|
+
"billing",
|
|
896
|
+
"search",
|
|
897
|
+
"files",
|
|
898
|
+
"admin",
|
|
899
|
+
"compliance",
|
|
900
|
+
"infra",
|
|
901
|
+
"mobile",
|
|
902
|
+
"analytics"
|
|
903
|
+
];
|
|
904
|
+
var KNOWN = /* @__PURE__ */ new Set([
|
|
905
|
+
"--out",
|
|
906
|
+
"--batch",
|
|
907
|
+
"--concurrency",
|
|
908
|
+
"--json",
|
|
909
|
+
"--boot",
|
|
910
|
+
"--install",
|
|
911
|
+
"--max",
|
|
912
|
+
"--theme",
|
|
913
|
+
"--style",
|
|
914
|
+
"--color",
|
|
915
|
+
"--tier",
|
|
916
|
+
"--feature",
|
|
917
|
+
"--mobile",
|
|
918
|
+
"--archetype",
|
|
919
|
+
"--vibe",
|
|
920
|
+
"--verbose",
|
|
921
|
+
"-h",
|
|
922
|
+
"--help"
|
|
923
|
+
]);
|
|
924
|
+
function parseFlags(rest) {
|
|
925
|
+
const f = {
|
|
926
|
+
out: "out",
|
|
927
|
+
concurrency: 1,
|
|
928
|
+
json: false,
|
|
929
|
+
boot: false,
|
|
930
|
+
install: false,
|
|
931
|
+
buildModel: "zeta-g1",
|
|
932
|
+
verbose: false,
|
|
933
|
+
help: false,
|
|
934
|
+
ideaParts: []
|
|
935
|
+
};
|
|
936
|
+
for (let i = 0; i < rest.length; i++) {
|
|
937
|
+
const a = rest[i];
|
|
938
|
+
const need = (label) => {
|
|
939
|
+
const v = rest[++i];
|
|
940
|
+
if (v == null || v.startsWith("-")) throw new Error(`${label} needs a value`);
|
|
941
|
+
return v;
|
|
942
|
+
};
|
|
943
|
+
switch (a) {
|
|
944
|
+
case "-h":
|
|
945
|
+
case "--help":
|
|
946
|
+
f.help = true;
|
|
947
|
+
break;
|
|
948
|
+
case "--json":
|
|
949
|
+
f.json = true;
|
|
950
|
+
break;
|
|
951
|
+
case "--boot":
|
|
952
|
+
f.boot = true;
|
|
953
|
+
break;
|
|
954
|
+
case "--install":
|
|
955
|
+
f.install = true;
|
|
956
|
+
break;
|
|
957
|
+
case "--max":
|
|
958
|
+
f.buildModel = "zeta-g1-max";
|
|
959
|
+
break;
|
|
960
|
+
case "--verbose":
|
|
961
|
+
f.verbose = true;
|
|
962
|
+
break;
|
|
963
|
+
case "--out":
|
|
964
|
+
f.out = need("--out");
|
|
965
|
+
break;
|
|
966
|
+
case "--batch":
|
|
967
|
+
f.batch = need("--batch");
|
|
968
|
+
break;
|
|
969
|
+
case "--concurrency": {
|
|
970
|
+
const n = Number(need("--concurrency"));
|
|
971
|
+
if (!Number.isInteger(n) || n < 1 || n > 16)
|
|
972
|
+
throw new Error("--concurrency must be an integer 1\u201316");
|
|
973
|
+
f.concurrency = n;
|
|
974
|
+
break;
|
|
975
|
+
}
|
|
976
|
+
case "--theme":
|
|
977
|
+
f.themeId = need("--theme");
|
|
978
|
+
break;
|
|
979
|
+
case "--style":
|
|
980
|
+
f.styleId = need("--style");
|
|
981
|
+
break;
|
|
982
|
+
case "--color": {
|
|
983
|
+
const v = need("--color").toLowerCase();
|
|
984
|
+
if (v === "d" || v === "dark") f.colorScheme = "dark";
|
|
985
|
+
else if (v === "l" || v === "light") f.colorScheme = "light";
|
|
986
|
+
else throw new Error("--color must be dark or light");
|
|
987
|
+
break;
|
|
988
|
+
}
|
|
989
|
+
case "--tier": {
|
|
990
|
+
const v = need("--tier").toLowerCase();
|
|
991
|
+
if (v !== "solo" && v !== "team" && v !== "enterprise")
|
|
992
|
+
throw new Error("--tier must be solo, team, or enterprise");
|
|
993
|
+
f.tier = v;
|
|
994
|
+
break;
|
|
995
|
+
}
|
|
996
|
+
case "--feature": {
|
|
997
|
+
const raw = need("--feature");
|
|
998
|
+
const off = raw.startsWith("no-");
|
|
999
|
+
const key = off ? raw.slice(3) : raw;
|
|
1000
|
+
if (!FEATURE_KEYS.includes(key))
|
|
1001
|
+
throw new Error(`unknown --feature "${raw}" (one of: ${FEATURE_KEYS.join(", ")}, optionally no-<feature>)`);
|
|
1002
|
+
(f.features ??= {})[key] = !off;
|
|
1003
|
+
break;
|
|
1004
|
+
}
|
|
1005
|
+
case "--mobile":
|
|
1006
|
+
f.mobile = true;
|
|
1007
|
+
break;
|
|
1008
|
+
case "--archetype":
|
|
1009
|
+
f.archetype = need("--archetype");
|
|
1010
|
+
break;
|
|
1011
|
+
case "--vibe":
|
|
1012
|
+
f.styleVibe = need("--vibe");
|
|
1013
|
+
break;
|
|
1014
|
+
default:
|
|
1015
|
+
if (a.startsWith("-") && !KNOWN.has(a)) throw new Error(`unknown flag: ${a}`);
|
|
1016
|
+
f.ideaParts.push(a);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return f;
|
|
1020
|
+
}
|
|
1021
|
+
function slugify(idea) {
|
|
1022
|
+
const s = idea.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").split("-").filter(Boolean).slice(0, 5).join("-");
|
|
1023
|
+
return s || "app";
|
|
1024
|
+
}
|
|
1025
|
+
function readBatch(file) {
|
|
1026
|
+
const path = resolve2(cwd2(), file);
|
|
1027
|
+
if (!existsSync(path)) throw new Error(`batch file not found: ${file}`);
|
|
1028
|
+
return readFileSync(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
1029
|
+
}
|
|
1030
|
+
function destFor(outRoot, idea, buildId) {
|
|
1031
|
+
const base2 = join3(outRoot, slugify(idea));
|
|
1032
|
+
if (!existsSync(base2)) return base2;
|
|
1033
|
+
return `${base2}-${buildId.slice(-6)}`;
|
|
1034
|
+
}
|
|
1035
|
+
async function buildOne(engine, idea, flags, outRoot, onPhase) {
|
|
1036
|
+
const slug2 = slugify(idea);
|
|
1037
|
+
try {
|
|
1038
|
+
if (flags.boot) {
|
|
1039
|
+
const booted = await demoBootBuild(
|
|
1040
|
+
engine,
|
|
1041
|
+
{ idea, buildModel: flags.buildModel, ...flags.themeId ? { themeId: flags.themeId } : {}, lean: true },
|
|
1042
|
+
onPhase
|
|
1043
|
+
);
|
|
1044
|
+
if (booted.ok && booted.liveUrl) {
|
|
1045
|
+
return {
|
|
1046
|
+
idea,
|
|
1047
|
+
slug: slug2,
|
|
1048
|
+
ok: true,
|
|
1049
|
+
verdict: booted.verdict,
|
|
1050
|
+
files: booted.files,
|
|
1051
|
+
liveUrl: booted.liveUrl,
|
|
1052
|
+
buildId: booted.buildId
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
return { idea, slug: slug2, ok: false, error: booted.error ?? "boot failed" };
|
|
1056
|
+
}
|
|
1057
|
+
const appScope = flags.tier || flags.features ? { ...flags.tier ? { tier: flags.tier } : {}, ...flags.features ? { features: flags.features } : {} } : void 0;
|
|
1058
|
+
const result = await httpBuild(
|
|
1059
|
+
engine,
|
|
1060
|
+
{
|
|
1061
|
+
idea,
|
|
1062
|
+
buildModel: flags.buildModel,
|
|
1063
|
+
install: false,
|
|
1064
|
+
scope: "full",
|
|
1065
|
+
...flags.themeId ? { themeId: flags.themeId } : {},
|
|
1066
|
+
...flags.styleId ? { styleId: flags.styleId } : {},
|
|
1067
|
+
...flags.colorScheme ? { colorScheme: flags.colorScheme } : {},
|
|
1068
|
+
...appScope ? { appScope } : {},
|
|
1069
|
+
...flags.mobile ? { platform: "mobile" } : {},
|
|
1070
|
+
...flags.archetype ? { archetype: flags.archetype } : {},
|
|
1071
|
+
...flags.styleVibe ? { styleVibe: flags.styleVibe } : {},
|
|
1072
|
+
lean: true
|
|
1073
|
+
},
|
|
1074
|
+
onPhase
|
|
1075
|
+
);
|
|
1076
|
+
if (!result.ok) return { idea, slug: slug2, ok: false, error: result.error ?? "build failed" };
|
|
1077
|
+
if (result.paywalled || !result.buildId) {
|
|
1078
|
+
return {
|
|
1079
|
+
idea,
|
|
1080
|
+
slug: slug2,
|
|
1081
|
+
ok: false,
|
|
1082
|
+
error: `preview only \u2014 subscribe to keep code: ${result.upgradeUrl ?? `${engine.replace(/\/$/, "")}/pricing`}`
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
const dest = destFor(outRoot, idea, String(result.buildId));
|
|
1086
|
+
mkdirSync(dest, { recursive: true });
|
|
1087
|
+
const delivered = await deliverBuild(engine, String(result.buildId), dest, onPhase);
|
|
1088
|
+
if (!delivered.ok) {
|
|
1089
|
+
const why = delivered.paywalled ? `subscribe to keep code: ${delivered.upgradeUrl ?? "/pricing"}` : delivered.error ?? "delivery failed";
|
|
1090
|
+
return { idea, slug: slug2, ok: false, buildId: String(result.buildId), error: why };
|
|
1091
|
+
}
|
|
1092
|
+
isolateFromWorkspace(dest);
|
|
1093
|
+
if (flags.install) {
|
|
1094
|
+
const inst = await installDeps(dest, onPhase);
|
|
1095
|
+
if (!inst.ok) onPhase(`install failed \u2014 fix package.json then run pnpm install`);
|
|
1096
|
+
}
|
|
1097
|
+
return {
|
|
1098
|
+
idea,
|
|
1099
|
+
slug: slug2,
|
|
1100
|
+
ok: true,
|
|
1101
|
+
verdict: result.verdict,
|
|
1102
|
+
files: result.fileCount,
|
|
1103
|
+
dir: dest,
|
|
1104
|
+
buildId: String(result.buildId)
|
|
1105
|
+
};
|
|
1106
|
+
} catch (e) {
|
|
1107
|
+
return { idea, slug: slug2, ok: false, error: e.message };
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
async function runPool(items, n, worker, onDone) {
|
|
1111
|
+
const results = new Array(items.length);
|
|
1112
|
+
let next = 0;
|
|
1113
|
+
async function lane() {
|
|
1114
|
+
for (; ; ) {
|
|
1115
|
+
const i = next++;
|
|
1116
|
+
if (i >= items.length) return;
|
|
1117
|
+
const r = await worker(items[i], i);
|
|
1118
|
+
results[i] = r;
|
|
1119
|
+
onDone(r, i);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
await Promise.all(Array.from({ length: Math.min(n, items.length) }, () => lane()));
|
|
1123
|
+
return results;
|
|
1124
|
+
}
|
|
1125
|
+
async function runMakeSubcommand(rawArgs) {
|
|
1126
|
+
const verb = rawArgs[0];
|
|
1127
|
+
if (verb !== "make" && verb !== "factory") return null;
|
|
1128
|
+
let flags;
|
|
1129
|
+
try {
|
|
1130
|
+
flags = parseFlags(rawArgs.slice(1));
|
|
1131
|
+
} catch (e) {
|
|
1132
|
+
line(c.red(` ${e.message}`));
|
|
1133
|
+
line(c.dim(" wholestack make --help"));
|
|
1134
|
+
return 1;
|
|
1135
|
+
}
|
|
1136
|
+
if (flags.help) {
|
|
1137
|
+
line(HELP);
|
|
1138
|
+
return 0;
|
|
1139
|
+
}
|
|
1140
|
+
const chrome = flags.json ? (s = "") => stderr.write(s + "\n") : line;
|
|
1141
|
+
let ideas;
|
|
1142
|
+
try {
|
|
1143
|
+
if (flags.batch) {
|
|
1144
|
+
if (flags.ideaParts.length) throw new Error("pass an idea OR --batch, not both");
|
|
1145
|
+
ideas = readBatch(flags.batch);
|
|
1146
|
+
} else {
|
|
1147
|
+
const inline = flags.ideaParts.join(" ").trim();
|
|
1148
|
+
ideas = inline ? [inline] : [];
|
|
1149
|
+
}
|
|
1150
|
+
} catch (e) {
|
|
1151
|
+
chrome(c.red(` ${e.message}`));
|
|
1152
|
+
return 1;
|
|
1153
|
+
}
|
|
1154
|
+
if (!ideas.length) {
|
|
1155
|
+
chrome(c.red(" no idea given."));
|
|
1156
|
+
chrome(c.dim(' wholestack make "a CRM for dog groomers" \xB7 wholestack make --batch ideas.txt'));
|
|
1157
|
+
return 1;
|
|
1158
|
+
}
|
|
1159
|
+
if (!process.env.ZETA_API_KEY?.trim()) {
|
|
1160
|
+
chrome(c.red(" login required."));
|
|
1161
|
+
chrome(c.dim(" run `wholestack login` \u2014 the factory uses your membership and build credits."));
|
|
1162
|
+
return 1;
|
|
1163
|
+
}
|
|
1164
|
+
const engine = webBaseUrl();
|
|
1165
|
+
const outRoot = resolve2(cwd2(), flags.out);
|
|
1166
|
+
const conc = Math.min(flags.concurrency, ideas.length);
|
|
1167
|
+
chrome(
|
|
1168
|
+
c.dim(
|
|
1169
|
+
` factory \xB7 ${ideas.length} app${ideas.length > 1 ? "s" : ""} \xB7 ${flags.boot ? "boot (live URL)" : `deliver \u2192 ${flags.out}/`} \xB7 ${flags.buildModel}${conc > 1 ? ` \xB7 ${conc}\xD7 parallel` : ""}`
|
|
1170
|
+
)
|
|
1171
|
+
);
|
|
1172
|
+
const render = (r, idx) => {
|
|
1173
|
+
if (flags.json) {
|
|
1174
|
+
stdout2.write(JSON.stringify(r) + "\n");
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
const tag = ideas.length > 1 ? c.dim(`[${idx + 1}/${ideas.length}] `) : "";
|
|
1178
|
+
if (r.ok) {
|
|
1179
|
+
const verdict = r.verdict === "SHIP" ? c.green("SHIP") : c.yellow(r.verdict ?? "?");
|
|
1180
|
+
const where = r.liveUrl ? c.cyan(r.liveUrl) : r.dir ? c.cyan(relOut(flags.out, outRoot, r.dir)) : "";
|
|
1181
|
+
const bits = [`${r.files ?? 0} files`, verdict, where].filter(Boolean);
|
|
1182
|
+
chrome(` ${tag}${c.green("\u2713")} ${r.slug} \xB7 ${bits.join(" \xB7 ")}`);
|
|
1183
|
+
} else {
|
|
1184
|
+
chrome(` ${tag}${c.red("\u2717")} ${r.slug} \xB7 ${r.error ?? "failed"}`);
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const results = await runPool(
|
|
1188
|
+
ideas,
|
|
1189
|
+
conc,
|
|
1190
|
+
(idea, i) => {
|
|
1191
|
+
if (conc === 1 && !flags.json) {
|
|
1192
|
+
const short = idea.length > 56 ? idea.slice(0, 55) + "\u2026" : idea;
|
|
1193
|
+
chrome(`${c.bold("\u2192")} ${short}`);
|
|
1194
|
+
}
|
|
1195
|
+
const tagged = (m) => flags.verbose ? chrome(c.dim(` \u21B3 ${conc > 1 ? `${slugify(idea)}: ` : ""}${m}`)) : void 0;
|
|
1196
|
+
return buildOne(engine, idea, flags, outRoot, tagged);
|
|
1197
|
+
},
|
|
1198
|
+
render
|
|
1199
|
+
);
|
|
1200
|
+
const failures = results.filter((r) => !r.ok).length;
|
|
1201
|
+
if (ideas.length > 1) {
|
|
1202
|
+
const made = ideas.length - failures;
|
|
1203
|
+
chrome(
|
|
1204
|
+
` ${c.bold("factory done")} \xB7 ${made}/${ideas.length} shipped` + (failures ? c.red(` \xB7 ${failures} failed`) : "")
|
|
1205
|
+
);
|
|
1206
|
+
}
|
|
1207
|
+
return failures ? 1 : 0;
|
|
1208
|
+
}
|
|
1209
|
+
function relOut(outFlag, outRoot, dest) {
|
|
1210
|
+
const tail = dest.startsWith(outRoot) ? dest.slice(outRoot.length).replace(/^[\\/]/, "") : dest;
|
|
1211
|
+
return join3(outFlag, tail);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
849
1214
|
// src/learned-tools.ts
|
|
850
1215
|
import { tool as tool3 } from "ai";
|
|
851
1216
|
import { z as z3 } from "zod";
|
|
@@ -931,7 +1296,7 @@ function buildLearnedMemoryTools(deps) {
|
|
|
931
1296
|
}
|
|
932
1297
|
|
|
933
1298
|
// src/skills-cli.ts
|
|
934
|
-
import { stdout as
|
|
1299
|
+
import { stdout as stdout3 } from "process";
|
|
935
1300
|
async function runSkillsSubcommand(raw) {
|
|
936
1301
|
if (raw[0] !== "skills") return null;
|
|
937
1302
|
const rest = raw.slice(1);
|
|
@@ -951,7 +1316,7 @@ async function runSkillsSubcommand(raw) {
|
|
|
951
1316
|
return 1;
|
|
952
1317
|
}
|
|
953
1318
|
if (rest.includes("--json")) {
|
|
954
|
-
|
|
1319
|
+
stdout3.write(
|
|
955
1320
|
JSON.stringify(
|
|
956
1321
|
{
|
|
957
1322
|
name: skill.name,
|
|
@@ -974,7 +1339,7 @@ async function runSkillsSubcommand(raw) {
|
|
|
974
1339
|
}
|
|
975
1340
|
const skills = registry.list();
|
|
976
1341
|
if (rest.includes("--json")) {
|
|
977
|
-
|
|
1342
|
+
stdout3.write(
|
|
978
1343
|
JSON.stringify(
|
|
979
1344
|
skills.map((s) => ({
|
|
980
1345
|
name: s.name,
|
|
@@ -1005,7 +1370,7 @@ async function runSkillsSubcommand(raw) {
|
|
|
1005
1370
|
|
|
1006
1371
|
// src/images.ts
|
|
1007
1372
|
import { readFile as readFile3, stat as stat2 } from "fs/promises";
|
|
1008
|
-
import { resolve as
|
|
1373
|
+
import { resolve as resolve3, extname, relative as relative2, isAbsolute as isAbsolute2, join as join4 } from "path";
|
|
1009
1374
|
import { execFile } from "child_process";
|
|
1010
1375
|
import { tmpdir as tmpdir2, platform as platform2 } from "os";
|
|
1011
1376
|
var EXT_TO_MEDIA = {
|
|
@@ -1026,7 +1391,7 @@ function run(cmd, args) {
|
|
|
1026
1391
|
});
|
|
1027
1392
|
}
|
|
1028
1393
|
async function grabClipboardImage() {
|
|
1029
|
-
const out =
|
|
1394
|
+
const out = join4(tmpdir2(), `zeta-clip-${process.pid}-${process.hrtime.bigint()}.png`);
|
|
1030
1395
|
const os = platform2();
|
|
1031
1396
|
if (os === "darwin") {
|
|
1032
1397
|
const script = `set thePath to "${out}"
|
|
@@ -1060,7 +1425,7 @@ function imageTokens(message) {
|
|
|
1060
1425
|
for (let m = re.exec(message); m; m = re.exec(message)) out.add(m[1]);
|
|
1061
1426
|
return [...out];
|
|
1062
1427
|
}
|
|
1063
|
-
async function scanImages(message,
|
|
1428
|
+
async function scanImages(message, cwd4) {
|
|
1064
1429
|
const tokens = imageTokens(message);
|
|
1065
1430
|
const images = [];
|
|
1066
1431
|
const skipped = [];
|
|
@@ -1089,8 +1454,8 @@ async function scanImages(message, cwd3) {
|
|
|
1089
1454
|
}
|
|
1090
1455
|
}
|
|
1091
1456
|
for (const tok of tokens) {
|
|
1092
|
-
const raw = tok.startsWith("~/") ?
|
|
1093
|
-
const abs = isAbsolute2(raw) ? raw :
|
|
1457
|
+
const raw = tok.startsWith("~/") ? join4(process.env.HOME ?? "", tok.slice(2)) : tok;
|
|
1458
|
+
const abs = isAbsolute2(raw) ? raw : resolve3(cwd4, raw);
|
|
1094
1459
|
const mediaType = EXT_TO_MEDIA[extname(abs).toLowerCase()];
|
|
1095
1460
|
if (!mediaType) continue;
|
|
1096
1461
|
let bytes;
|
|
@@ -1101,7 +1466,7 @@ async function scanImages(message, cwd3) {
|
|
|
1101
1466
|
} catch {
|
|
1102
1467
|
continue;
|
|
1103
1468
|
}
|
|
1104
|
-
const label = isAbsolute2(raw) ? raw : relative2(
|
|
1469
|
+
const label = isAbsolute2(raw) ? raw : relative2(cwd4, abs);
|
|
1105
1470
|
if (bytes > PER_IMAGE_BYTES || total + bytes > TOTAL_BYTES) {
|
|
1106
1471
|
skipped.push(`${label} (${Math.round(bytes / 1024)}KB \u2014 over the size cap)`);
|
|
1107
1472
|
continue;
|
|
@@ -1197,7 +1562,7 @@ ${body}`);
|
|
|
1197
1562
|
|
|
1198
1563
|
// src/export.ts
|
|
1199
1564
|
import { writeFileSync } from "fs";
|
|
1200
|
-
import { resolve as
|
|
1565
|
+
import { resolve as resolve4 } from "path";
|
|
1201
1566
|
function renderContent(content) {
|
|
1202
1567
|
if (typeof content === "string") return content.trim();
|
|
1203
1568
|
if (!Array.isArray(content)) return "";
|
|
@@ -1235,32 +1600,32 @@ ${text}`;
|
|
|
1235
1600
|
${body}
|
|
1236
1601
|
`;
|
|
1237
1602
|
}
|
|
1238
|
-
function writeTranscript(messages, meta, file,
|
|
1239
|
-
const abs =
|
|
1603
|
+
function writeTranscript(messages, meta, file, cwd4) {
|
|
1604
|
+
const abs = resolve4(cwd4, file);
|
|
1240
1605
|
writeFileSync(abs, renderTranscript(messages, meta), "utf8");
|
|
1241
1606
|
return abs;
|
|
1242
1607
|
}
|
|
1243
1608
|
|
|
1244
1609
|
// src/cli.ts
|
|
1245
|
-
import { existsSync as
|
|
1246
|
-
import { join as
|
|
1610
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
1611
|
+
import { join as join7 } from "path";
|
|
1247
1612
|
|
|
1248
1613
|
// src/update-check.ts
|
|
1249
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1250
|
-
import { join as
|
|
1614
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1615
|
+
import { join as join5 } from "path";
|
|
1251
1616
|
var PKG = "wholestack";
|
|
1252
|
-
var CACHE =
|
|
1617
|
+
var CACHE = join5(stateDir(), "update-check.json");
|
|
1253
1618
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
1254
1619
|
function readCache() {
|
|
1255
1620
|
try {
|
|
1256
|
-
return JSON.parse(
|
|
1621
|
+
return JSON.parse(readFileSync2(CACHE, "utf8"));
|
|
1257
1622
|
} catch {
|
|
1258
1623
|
return { lastCheck: 0, latest: null };
|
|
1259
1624
|
}
|
|
1260
1625
|
}
|
|
1261
1626
|
function writeCache(c2) {
|
|
1262
1627
|
try {
|
|
1263
|
-
|
|
1628
|
+
mkdirSync2(stateDir(), { recursive: true });
|
|
1264
1629
|
writeFileSync2(CACHE, JSON.stringify(c2));
|
|
1265
1630
|
} catch {
|
|
1266
1631
|
}
|
|
@@ -1276,7 +1641,7 @@ function isNewer(a, b) {
|
|
|
1276
1641
|
return false;
|
|
1277
1642
|
}
|
|
1278
1643
|
async function checkForUpdate(current) {
|
|
1279
|
-
if (process.env.ZETA_NO_UPDATE_CHECK || !
|
|
1644
|
+
if (process.env.ZETA_NO_UPDATE_CHECK || !existsSync2) return null;
|
|
1280
1645
|
const cache = readCache();
|
|
1281
1646
|
const fresh = Date.now() - cache.lastCheck < DAY_MS;
|
|
1282
1647
|
let latest = cache.latest;
|
|
@@ -1302,20 +1667,20 @@ async function checkForUpdate(current) {
|
|
|
1302
1667
|
}
|
|
1303
1668
|
|
|
1304
1669
|
// src/access.ts
|
|
1305
|
-
import { mkdirSync as
|
|
1306
|
-
import { join as
|
|
1307
|
-
var CACHE2 =
|
|
1670
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
1671
|
+
import { join as join6 } from "path";
|
|
1672
|
+
var CACHE2 = join6(stateDir(), "access.json");
|
|
1308
1673
|
var TTL_MS = 60 * 60 * 1e3;
|
|
1309
1674
|
function readCache2() {
|
|
1310
1675
|
try {
|
|
1311
|
-
return JSON.parse(
|
|
1676
|
+
return JSON.parse(readFileSync3(CACHE2, "utf8"));
|
|
1312
1677
|
} catch {
|
|
1313
1678
|
return null;
|
|
1314
1679
|
}
|
|
1315
1680
|
}
|
|
1316
1681
|
function writeCache2(c2) {
|
|
1317
1682
|
try {
|
|
1318
|
-
|
|
1683
|
+
mkdirSync3(stateDir(), { recursive: true });
|
|
1319
1684
|
writeFileSync3(CACHE2, JSON.stringify(c2));
|
|
1320
1685
|
} catch {
|
|
1321
1686
|
}
|
|
@@ -1405,27 +1770,27 @@ function showPaywall(loggedIn, webUrl) {
|
|
|
1405
1770
|
}
|
|
1406
1771
|
row("");
|
|
1407
1772
|
row(c.dim("Free: make \xB7 edit \xB7 preview (watermarked)"));
|
|
1408
|
-
row(c.dim("
|
|
1773
|
+
row(c.dim("Starter $49/mo \xB7 Pro $99/mo \u2014 ship & own apps"));
|
|
1409
1774
|
row(c.cyan(`${webUrl.replace(/\/$/, "")}/pricing`));
|
|
1410
1775
|
line(" " + c.cyan("\u2570" + "\u2500".repeat(w) + "\u256F"));
|
|
1411
1776
|
line();
|
|
1412
1777
|
}
|
|
1413
1778
|
|
|
1414
1779
|
// src/cli.ts
|
|
1415
|
-
import { readFileSync as
|
|
1780
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1416
1781
|
import { basename as basename2, dirname as dirname2 } from "path";
|
|
1417
1782
|
import { fileURLToPath } from "url";
|
|
1418
1783
|
var VERSION = (() => {
|
|
1419
1784
|
try {
|
|
1420
1785
|
const here = dirname2(fileURLToPath(import.meta.url));
|
|
1421
|
-
return JSON.parse(
|
|
1786
|
+
return JSON.parse(readFileSync4(join7(here, "..", "package.json"), "utf8")).version;
|
|
1422
1787
|
} catch {
|
|
1423
1788
|
return "0.0.0";
|
|
1424
1789
|
}
|
|
1425
1790
|
})();
|
|
1426
1791
|
function gitBranch(dir) {
|
|
1427
1792
|
try {
|
|
1428
|
-
const head =
|
|
1793
|
+
const head = readFileSync4(join7(dir, ".git", "HEAD"), "utf8").trim();
|
|
1429
1794
|
const m = head.match(/ref:\s*refs\/heads\/(.+)$/);
|
|
1430
1795
|
return m ? m[1] : head.slice(0, 7);
|
|
1431
1796
|
} catch {
|
|
@@ -1480,13 +1845,19 @@ function parse(raw) {
|
|
|
1480
1845
|
a.prompt = rest.join(" ").trim();
|
|
1481
1846
|
return a;
|
|
1482
1847
|
}
|
|
1483
|
-
var
|
|
1848
|
+
var HELP2 = `${c.cyan("wholestack")} \u2014 conversational coding agent for the Wholestack engine ${c.dim("(alias: zeta)")}
|
|
1484
1849
|
|
|
1485
1850
|
${c.bold("Usage")}
|
|
1486
1851
|
wholestack start an interactive session
|
|
1487
1852
|
wholestack "build me a todo app" run one prompt and exit
|
|
1488
1853
|
wholestack -m zeta-g1-max "..." drive it with the most capable brain
|
|
1489
1854
|
|
|
1855
|
+
${c.bold("Factory")} ${c.dim("(strict \xB7 no chat \xB7 ~0 client tokens \xB7 one idea in, app out)")}
|
|
1856
|
+
wholestack make "a barbershop booking app" make one app \u2192 ./out/<slug>
|
|
1857
|
+
wholestack make --batch ideas.txt one app per line of a file
|
|
1858
|
+
wholestack make "..." --boot free live URL instead of code
|
|
1859
|
+
${c.dim("wholestack make --help for all flags (--out, --install, --style, --max, \u2026)")}
|
|
1860
|
+
|
|
1490
1861
|
${c.bold("Projects")} ${c.dim("(one spine across terminal, dashboard and the web IDE)")}
|
|
1491
1862
|
wholestack projects list your platform projects
|
|
1492
1863
|
wholestack pull <id> [dir] download a project's working tree
|
|
@@ -1510,6 +1881,13 @@ ${c.bold("Launch")} ${c.dim("(the studio's Launch HQ \u2014 go-to-market, in the
|
|
|
1510
1881
|
wholestack business [buildId] one workspace + its readiness scorecard
|
|
1511
1882
|
${c.dim("add --json for machine-readable output")}
|
|
1512
1883
|
|
|
1884
|
+
${c.bold("Operation Volition")} ${c.dim("(the autonomous operate-plane \u2014 a proof-gated crew RUNS the business)")}
|
|
1885
|
+
wholestack volition <name|projectId> [--live] hand a business to the crew (sandbox default)
|
|
1886
|
+
wholestack volition status [projectId] operator state + recent shifts
|
|
1887
|
+
wholestack volition actions [projectId] the action ledger (every move has a proof hash)
|
|
1888
|
+
wholestack volition run [projectId] run one crew cycle right now
|
|
1889
|
+
${c.dim("sandbox simulates external actions; --live goes real ($99/mo add-on, gated server-side)")}
|
|
1890
|
+
|
|
1513
1891
|
${c.bold("Prove gate (web2)")} ${c.dim("(deterministic \xB7 fail-closed \xB7 blocking exit code)")}
|
|
1514
1892
|
wholestack prove <dir> [--json] gate a checked-out repo (local lockstep mirror)
|
|
1515
1893
|
wholestack prove --remote --github o/r [--ref b] hosted, HMAC-signed verdict via /api/v1/prove
|
|
@@ -1728,7 +2106,7 @@ async function runProveSubcommand(raw) {
|
|
|
1728
2106
|
}
|
|
1729
2107
|
const data = await resp.json().catch(() => null);
|
|
1730
2108
|
if (wantsJson) {
|
|
1731
|
-
|
|
2109
|
+
stdout4.write(JSON.stringify(data) + "\n");
|
|
1732
2110
|
return data?.verdict === "SHIP" ? 0 : 1;
|
|
1733
2111
|
}
|
|
1734
2112
|
if (resp.status === 401 || resp.status === 402 || resp.status === 503 || !data) {
|
|
@@ -1744,14 +2122,14 @@ async function runProveSubcommand(raw) {
|
|
|
1744
2122
|
);
|
|
1745
2123
|
return data.verdict === "SHIP" ? 0 : 1;
|
|
1746
2124
|
}
|
|
1747
|
-
const path = rest.find((a) => !a.startsWith("-")) ??
|
|
1748
|
-
if (!
|
|
2125
|
+
const path = rest.find((a) => !a.startsWith("-")) ?? cwd3();
|
|
2126
|
+
if (!existsSync3(path)) {
|
|
1749
2127
|
line(c.red(` path not found: ${path}`));
|
|
1750
2128
|
return 1;
|
|
1751
2129
|
}
|
|
1752
2130
|
const result = proveLocalRepo(path);
|
|
1753
2131
|
if (wantsJson) {
|
|
1754
|
-
|
|
2132
|
+
stdout4.write(JSON.stringify(result) + "\n");
|
|
1755
2133
|
return result.verdict === "SHIP" ? 0 : 1;
|
|
1756
2134
|
}
|
|
1757
2135
|
line();
|
|
@@ -1796,7 +2174,7 @@ async function runSecuritySubcommand(raw) {
|
|
|
1796
2174
|
line();
|
|
1797
2175
|
line(c.cyan(` \u259F ShipGate ${verb}`) + c.dim(" \xB7 forge \xB7 slither \xB7 firewall \xB7 halmos"));
|
|
1798
2176
|
line();
|
|
1799
|
-
const r = await runProver(proverArgs, { cwd:
|
|
2177
|
+
const r = await runProver(proverArgs, { cwd: cwd3(), inherit: true });
|
|
1800
2178
|
if (r.missing) {
|
|
1801
2179
|
line(c.red(` ${r.out}`));
|
|
1802
2180
|
return 1;
|
|
@@ -1808,12 +2186,12 @@ async function runSecuritySubcommand(raw) {
|
|
|
1808
2186
|
function maybeYoloNotice() {
|
|
1809
2187
|
try {
|
|
1810
2188
|
const dir = stateDir();
|
|
1811
|
-
const marker =
|
|
1812
|
-
if (
|
|
2189
|
+
const marker = join7(dir, "yolo-notice-seen");
|
|
2190
|
+
if (existsSync3(marker)) return;
|
|
1813
2191
|
line(
|
|
1814
2192
|
" " + c.yellow("\u26A1 yolo mode") + c.dim(" \u2014 actions run without confirmation. ") + c.cyan("/mode default") + c.dim(" to require approvals \xB7 /undo reverts.") + "\n"
|
|
1815
2193
|
);
|
|
1816
|
-
|
|
2194
|
+
mkdirSync4(dir, { recursive: true });
|
|
1817
2195
|
writeFileSync4(marker, (/* @__PURE__ */ new Date()).toISOString());
|
|
1818
2196
|
} catch {
|
|
1819
2197
|
}
|
|
@@ -1869,7 +2247,7 @@ async function runLogin(raw) {
|
|
|
1869
2247
|
line(c.red(" usage: wholestack login --member <key> | --brain <key> | --build <key>"));
|
|
1870
2248
|
return 1;
|
|
1871
2249
|
}
|
|
1872
|
-
const rl = createInterface({ input: stdin, output:
|
|
2250
|
+
const rl = createInterface({ input: stdin, output: stdout4 });
|
|
1873
2251
|
if (!name) {
|
|
1874
2252
|
const which = (await rl.question(c.cyan(" key for [member/brain/engine]: "))).trim().toLowerCase();
|
|
1875
2253
|
name = which.startsWith("m") ? "ZETA_API_KEY" : "CEREBRAS_API_KEY";
|
|
@@ -2051,7 +2429,7 @@ async function runLaunchSubcommand(raw) {
|
|
|
2051
2429
|
return 1;
|
|
2052
2430
|
}
|
|
2053
2431
|
if (wantsJson) {
|
|
2054
|
-
|
|
2432
|
+
stdout4.write(JSON.stringify(r2.plan, null, 2) + "\n");
|
|
2055
2433
|
return 0;
|
|
2056
2434
|
}
|
|
2057
2435
|
for (const ln of renderGtmPlanLines(r2.plan)) line(ln);
|
|
@@ -2067,7 +2445,7 @@ async function runLaunchSubcommand(raw) {
|
|
|
2067
2445
|
return 1;
|
|
2068
2446
|
}
|
|
2069
2447
|
if (wantsJson) {
|
|
2070
|
-
|
|
2448
|
+
stdout4.write(JSON.stringify(r.kit, null, 2) + "\n");
|
|
2071
2449
|
return 0;
|
|
2072
2450
|
}
|
|
2073
2451
|
for (const ln of renderLaunchKitLines(r.kit)) line(ln);
|
|
@@ -2093,7 +2471,7 @@ async function runHqSubcommand(raw) {
|
|
|
2093
2471
|
line(c.red(` \u2717 ${r2.error ?? "no document produced"}`));
|
|
2094
2472
|
return 1;
|
|
2095
2473
|
}
|
|
2096
|
-
|
|
2474
|
+
stdout4.write(r2.markdown.trimEnd() + "\n");
|
|
2097
2475
|
return 0;
|
|
2098
2476
|
}
|
|
2099
2477
|
if (verb === "styles") {
|
|
@@ -2110,7 +2488,7 @@ async function runHqSubcommand(raw) {
|
|
|
2110
2488
|
return 1;
|
|
2111
2489
|
}
|
|
2112
2490
|
if (wantsJson) {
|
|
2113
|
-
|
|
2491
|
+
stdout4.write(JSON.stringify(data, null, 2) + "\n");
|
|
2114
2492
|
return 0;
|
|
2115
2493
|
}
|
|
2116
2494
|
if (data.recommended) {
|
|
@@ -2138,7 +2516,7 @@ async function runHqSubcommand(raw) {
|
|
|
2138
2516
|
return 1;
|
|
2139
2517
|
}
|
|
2140
2518
|
if (wantsJson) {
|
|
2141
|
-
|
|
2519
|
+
stdout4.write(JSON.stringify(r2.metrics, null, 2) + "\n");
|
|
2142
2520
|
return 0;
|
|
2143
2521
|
}
|
|
2144
2522
|
for (const ln of renderMetricsLines(r2.metrics)) line(ln);
|
|
@@ -2166,7 +2544,7 @@ async function runHqSubcommand(raw) {
|
|
|
2166
2544
|
return 1;
|
|
2167
2545
|
}
|
|
2168
2546
|
if (wantsJson) {
|
|
2169
|
-
|
|
2547
|
+
stdout4.write(JSON.stringify(r2.businesses ?? [], null, 2) + "\n");
|
|
2170
2548
|
return 0;
|
|
2171
2549
|
}
|
|
2172
2550
|
const rows = r2.businesses ?? [];
|
|
@@ -2189,7 +2567,7 @@ async function runHqSubcommand(raw) {
|
|
|
2189
2567
|
line(c.red(` \u2717 ${r.error}`));
|
|
2190
2568
|
return 1;
|
|
2191
2569
|
}
|
|
2192
|
-
|
|
2570
|
+
stdout4.write(JSON.stringify({ business: r.business, readiness: r.readiness }, null, 2) + "\n");
|
|
2193
2571
|
return 0;
|
|
2194
2572
|
}
|
|
2195
2573
|
var EMPTY_PLUGINS = {
|
|
@@ -2220,6 +2598,8 @@ async function main() {
|
|
|
2220
2598
|
const rawArgs = argv.slice(2);
|
|
2221
2599
|
const loggedIn = await runLogin(rawArgs);
|
|
2222
2600
|
if (loggedIn !== null) exit(loggedIn);
|
|
2601
|
+
const made = await runMakeSubcommand(rawArgs);
|
|
2602
|
+
if (made !== null) exit(made);
|
|
2223
2603
|
const gh = await runGithubSubcommand(rawArgs);
|
|
2224
2604
|
if (gh !== null) exit(gh);
|
|
2225
2605
|
const provePath = await runProveSubcommand(rawArgs);
|
|
@@ -2238,6 +2618,8 @@ async function main() {
|
|
|
2238
2618
|
if (eyes !== null) exit(eyes);
|
|
2239
2619
|
const ops = await runOpsSubcommand(rawArgs);
|
|
2240
2620
|
if (ops !== null) exit(ops);
|
|
2621
|
+
const volition = await runVolitionSubcommand(rawArgs);
|
|
2622
|
+
if (volition !== null) exit(volition);
|
|
2241
2623
|
const skillsSub = await runSkillsSubcommand(rawArgs);
|
|
2242
2624
|
if (skillsSub !== null) exit(skillsSub);
|
|
2243
2625
|
const args = parse(rawArgs);
|
|
@@ -2246,7 +2628,7 @@ async function main() {
|
|
|
2246
2628
|
return;
|
|
2247
2629
|
}
|
|
2248
2630
|
if (args.help) {
|
|
2249
|
-
line(
|
|
2631
|
+
line(HELP2);
|
|
2250
2632
|
return;
|
|
2251
2633
|
}
|
|
2252
2634
|
{
|
|
@@ -2260,7 +2642,7 @@ async function main() {
|
|
|
2260
2642
|
token ? "Your session expired." : "The agent is free \u2014 make, edit & preview unlimited. Sign in to start."
|
|
2261
2643
|
)
|
|
2262
2644
|
);
|
|
2263
|
-
const rl = createInterface({ input: stdin, output:
|
|
2645
|
+
const rl = createInterface({ input: stdin, output: stdout4 });
|
|
2264
2646
|
const ans = (await rl.question(
|
|
2265
2647
|
" " + c.dim("Open the browser to sign in with Google? ") + c.dim("[Y/n] ")
|
|
2266
2648
|
)).trim().toLowerCase();
|
|
@@ -2312,7 +2694,7 @@ async function main() {
|
|
|
2312
2694
|
}
|
|
2313
2695
|
const isTty = !!stdin.isTTY;
|
|
2314
2696
|
const oneShot = args.prompt.length > 0;
|
|
2315
|
-
const workdir =
|
|
2697
|
+
const workdir = cwd3();
|
|
2316
2698
|
const persistedMode = isPermissionMode(
|
|
2317
2699
|
process.env.ZETA_PERMISSION_MODE
|
|
2318
2700
|
) ? process.env.ZETA_PERMISSION_MODE : void 0;
|