wholestack 0.5.0 → 0.5.2

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.
@@ -1806,16 +1806,37 @@ ${transcript}`
1806
1806
 
1807
1807
  // src/model.ts
1808
1808
  import { createOpenAI } from "@ai-sdk/openai";
1809
- var CEREBRAS_URL = "https://api.cerebras.ai/v1";
1810
- var OPENROUTER_URL = "https://openrouter.ai/api/v1";
1811
- var CEREBRAS_KEY = "CEREBRAS_API_KEY";
1812
- var KEY_ENV = "OPENROUTER_API_KEY";
1813
- var DEFAULT_CUSTOM_MODEL = "anthropic/claude-sonnet-4.6";
1814
- var VISION_MODEL = process.env.ZETA_VISION_MODEL?.trim() || "anthropic/claude-sonnet-4.6";
1809
+
1810
+ // ../zeta-models/dist/index.js
1811
+ var readEnv = (k) => {
1812
+ const v = typeof process !== "undefined" ? process.env?.[k] : void 0;
1813
+ const t = v?.trim();
1814
+ return t && t.length > 0 ? t : void 0;
1815
+ };
1816
+ var PROVIDERS = {
1817
+ cerebras: { id: "cerebras", baseURL: "https://api.cerebras.ai/v1", keyEnv: "CEREBRAS_API_KEY" },
1818
+ openrouter: { id: "openrouter", baseURL: "https://openrouter.ai/api/v1", keyEnv: "OPENROUTER_API_KEY" }
1819
+ };
1820
+ var MODEL_IDS = {
1821
+ /** BUILD lane — writes ISL, generates the full stack. Cerebras. The 80%. */
1822
+ gptOss: readEnv("ZETA_GPTOSS_MODEL") || "gpt-oss-120b",
1823
+ /** BRAIN lane — frontend swarm, decisions, debugging, editing, planning. Cerebras. The 20%. */
1824
+ glm: readEnv("ZETA_GLM_MODEL") || "zai-glm-4.7",
1825
+ /** VISION lane — accepts image input. OpenRouter (Cerebras text lanes can't see). */
1826
+ vision: readEnv("ZETA_VISION_MODEL") || "anthropic/claude-sonnet-4.6"
1827
+ };
1828
+
1829
+ // src/model.ts
1830
+ var CEREBRAS_URL = PROVIDERS.cerebras.baseURL;
1831
+ var OPENROUTER_URL = PROVIDERS.openrouter.baseURL;
1832
+ var CEREBRAS_KEY = PROVIDERS.cerebras.keyEnv;
1833
+ var KEY_ENV = PROVIDERS.openrouter.keyEnv;
1834
+ var DEFAULT_CUSTOM_MODEL = MODEL_IDS.vision;
1835
+ var VISION_MODEL = MODEL_IDS.vision;
1815
1836
  var MODELS = /* @__PURE__ */ new Map([
1816
- ["zeta-g1-lite", { modelId: "gpt-oss-120b", label: "Zeta-G1.0 Lite", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1817
- ["zeta-g1", { modelId: "zai-glm-4.7", label: "Zeta-G1.0", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1818
- ["zeta-g1-max", { modelId: "zai-glm-4.7", label: "Zeta-G1.0 MAX", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1837
+ ["zeta-g1-lite", { modelId: MODEL_IDS.gptOss, label: "Zeta-G1.0 Lite", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1838
+ ["zeta-g1", { modelId: MODEL_IDS.glm, label: "Zeta-G1.0", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1839
+ ["zeta-g1-max", { modelId: MODEL_IDS.glm, label: "Zeta-G1.0 MAX", keyEnv: CEREBRAS_KEY, baseURL: CEREBRAS_URL, contextWindow: 128e3, thinking: "budget" }],
1819
1840
  // The vision tier — accepts image input (screenshots, mocks, diagrams). Routed
1820
1841
  // over OpenRouter because the Cerebras tiers are text-only.
1821
1842
  ["zeta-g1-vision", { modelId: VISION_MODEL, label: "Zeta-G1.0 Vision", keyEnv: KEY_ENV, baseURL: OPENROUTER_URL, contextWindow: 2e5, thinking: null }]
package/dist/cli.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  tasks,
31
31
  userBox,
32
32
  visionCapable
33
- } from "./chunk-PGKDYDAR.js";
33
+ } from "./chunk-TDSLCPQL.js";
34
34
 
35
35
  // src/cli.ts
36
36
  import { createInterface } from "readline/promises";
@@ -137,16 +137,29 @@ async function loginBrowser(opts) {
137
137
  };
138
138
  const server = createServer((req, res) => {
139
139
  const url = new URL(req.url ?? "/", "http://127.0.0.1");
140
+ const corsHeaders = {
141
+ "access-control-allow-origin": "*",
142
+ "access-control-allow-methods": "GET, OPTIONS",
143
+ "access-control-allow-headers": "*",
144
+ "access-control-allow-private-network": "true"
145
+ };
146
+ if (req.method === "OPTIONS") {
147
+ res.writeHead(204, corsHeaders).end();
148
+ return;
149
+ }
140
150
  if (url.pathname !== "/callback") {
141
- res.writeHead(404).end();
151
+ res.writeHead(404, corsHeaders).end();
142
152
  return;
143
153
  }
144
154
  if (url.searchParams.get("state") !== state) {
145
- res.writeHead(400).end("state mismatch");
155
+ res.writeHead(400, corsHeaders).end("state mismatch");
146
156
  return;
147
157
  }
148
158
  const token = url.searchParams.get("token")?.trim();
149
- res.writeHead(token ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
159
+ res.writeHead(token ? 200 : 400, {
160
+ ...corsHeaders,
161
+ "content-type": "text/html; charset=utf-8"
162
+ });
150
163
  res.end(token ? SUCCESS_HTML : "missing token");
151
164
  if (token) {
152
165
  const path = saveKey("ZETA_API_KEY", token);
@@ -770,7 +783,7 @@ async function checkForUpdate(current) {
770
783
  }
771
784
 
772
785
  // src/access.ts
773
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
786
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync4 } from "fs";
774
787
  import { homedir as homedir3 } from "os";
775
788
  import { join as join5 } from "path";
776
789
  var CACHE2 = join5(homedir3(), ".zeta-g", "access.json");
@@ -789,9 +802,15 @@ function writeCache2(c2) {
789
802
  } catch {
790
803
  }
791
804
  }
792
- async function verifyAccess(webUrl, token) {
805
+ function clearAccessCache() {
806
+ try {
807
+ rmSync(CACHE2, { force: true });
808
+ } catch {
809
+ }
810
+ }
811
+ async function verifyAccess(webUrl, token, force = false) {
793
812
  if (!token) return { active: false, tier: null, degraded: false };
794
- const cached = readCache2();
813
+ const cached = force ? null : readCache2();
795
814
  if (cached && Date.now() - cached.checkedAt < TTL_MS) {
796
815
  return { active: cached.active, tier: cached.tier, degraded: false };
797
816
  }
@@ -803,7 +822,10 @@ async function verifyAccess(webUrl, token) {
803
822
  signal: ctrl.signal
804
823
  });
805
824
  clearTimeout(t);
806
- if (res.status === 401) {
825
+ if (res.status >= 500) {
826
+ return { active: true, tier: cached?.tier ?? null, degraded: true };
827
+ }
828
+ if (!res.ok) {
807
829
  writeCache2({ checkedAt: Date.now(), active: false, tier: null });
808
830
  return { active: false, tier: null, degraded: false };
809
831
  }
@@ -1018,6 +1040,7 @@ async function runLogin(raw) {
1018
1040
  if (raw[0] !== "login" && raw[0] !== "logout") return null;
1019
1041
  const rest = raw.slice(1);
1020
1042
  if (raw[0] === "logout") {
1043
+ clearAccessCache();
1021
1044
  saveKey("ZETA_API_KEY", "");
1022
1045
  line(c.green(" \u2713 logged out") + c.dim(" (token cleared)"));
1023
1046
  return 0;
@@ -1029,7 +1052,9 @@ async function runLogin(raw) {
1029
1052
  line(c.red(" usage: zeta login --token <vbfl_\u2026>"));
1030
1053
  return 1;
1031
1054
  }
1032
- return loginWithToken(tok) ? 0 : 1;
1055
+ const ok = loginWithToken(tok);
1056
+ if (ok) clearAccessCache();
1057
+ return ok ? 0 : 1;
1033
1058
  }
1034
1059
  const pick = (flag) => {
1035
1060
  const i = rest.indexOf(flag);
@@ -1044,6 +1069,7 @@ async function runLogin(raw) {
1044
1069
  if (!hit(memberFlags) && !hit(brainFlags) && !hit(buildFlags)) {
1045
1070
  const noBrowser = rest.includes("--no-browser");
1046
1071
  const token = await loginBrowser({ webBase: webBaseUrl(), noBrowser });
1072
+ if (token) clearAccessCache();
1047
1073
  return token ? 0 : 1;
1048
1074
  }
1049
1075
  if (hit(memberFlags)) {
@@ -1075,6 +1101,7 @@ async function runLogin(raw) {
1075
1101
  }
1076
1102
  const what = name === "ZETA_API_KEY" ? "membership (keep + deploy your apps)" : name === "OPENROUTER_API_KEY" ? "brain (Zeta-G1.0 tiers)" : "ZETA build engine";
1077
1103
  const path = saveKey(name, value);
1104
+ if (name === "ZETA_API_KEY") clearAccessCache();
1078
1105
  line(c.green(` \u2713 saved key for the ${what}`) + c.dim(` \u2192 ${path} (chmod 600)`));
1079
1106
  line(c.dim(" now just run `zeta-g`."));
1080
1107
  return 0;
@@ -1117,8 +1144,23 @@ async function main() {
1117
1144
  return;
1118
1145
  }
1119
1146
  {
1120
- const token = process.env.ZETA_API_KEY;
1121
- const access = await verifyAccess(webBaseUrl(), token);
1147
+ let token = process.env.ZETA_API_KEY;
1148
+ let access = await verifyAccess(webBaseUrl(), token);
1149
+ if (!access.active && stdin.isTTY) {
1150
+ const rl = createInterface({ input: stdin, output: stdout });
1151
+ const ans = (await rl.question(
1152
+ "\n " + (token ? c.dim("No active plan on this account. ") + "Log in to a different account? " : "Log in now? ") + c.dim("[Y/n] ")
1153
+ )).trim().toLowerCase();
1154
+ rl.close();
1155
+ if (ans === "" || ans === "y" || ans === "yes") {
1156
+ const minted = await loginBrowser({ webBase: webBaseUrl(), noBrowser: false });
1157
+ if (minted) {
1158
+ token = minted;
1159
+ process.env.ZETA_API_KEY = minted;
1160
+ access = await verifyAccess(webBaseUrl(), token, true);
1161
+ }
1162
+ }
1163
+ }
1122
1164
  if (!access.active) {
1123
1165
  showPaywall(Boolean(token), webBaseUrl());
1124
1166
  exit(1);
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ import {
49
49
  resolveModelKey,
50
50
  severityRank,
51
51
  supportsThinking
52
- } from "./chunk-PGKDYDAR.js";
52
+ } from "./chunk-TDSLCPQL.js";
53
53
 
54
54
  // src/prompts/template.ts
55
55
  var PLACEHOLDER = /\{\{([A-Za-z0-9_.]+)\}\}/g;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wholestack",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Wholestack — a pro-grade conversational terminal agent for the Wholestack codegen engine. Talk to it in plain language: it writes ISL, generates full-stack or Solidity apps, and proves them with ShipGate. Browser login, membership-gated builds, slash commands, sessions, plan mode, diffs, MCP, plugins.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -62,6 +62,7 @@
62
62
  "zod": "^3.25.76"
63
63
  },
64
64
  "devDependencies": {
65
+ "@isl-lang/zeta-models": "workspace:*",
65
66
  "@types/diff": "^5.2.0",
66
67
  "@types/node": "^20.10.0",
67
68
  "tsup": "^8.0.1",