storyforge 0.4.10 → 0.4.12

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.
@@ -134,7 +134,14 @@ var BridgePoller = class {
134
134
  let lastErr = "";
135
135
  for (const m of candidates) {
136
136
  try {
137
- const args = cli === "codex" ? ["exec", "-", "--model", m] : ["-p", "--model", m, "--no-session-persistence"];
137
+ const args = cli === "codex" ? ["exec", "-", "--model", m, "--search"] : [
138
+ "-p",
139
+ "--model",
140
+ m,
141
+ "--no-session-persistence",
142
+ "--allowedTools",
143
+ "WebSearch,WebFetch"
144
+ ];
138
145
  const text = await runSpawn(cli, args, prompt, CLI_TIMEOUT_MS);
139
146
  if (text.trim()) return { text, modelUsed: `${cli}:${m}` };
140
147
  lastErr = `${cli}/${m} returned empty stdout`;
package/dist/index.js CHANGED
@@ -17,6 +17,12 @@ import * as path from "path";
17
17
  import * as os from "os";
18
18
  var FORGE_DIR = path.join(os.homedir(), ".forge");
19
19
  var CREDS_PATH = path.join(FORGE_DIR, "credentials.json");
20
+ var FORGE_ENV_PATHS = [
21
+ path.join(FORGE_DIR, ".env"),
22
+ // ~/.forge/.env
23
+ path.join(os.homedir(), ".forge.env")
24
+ // ~/.forge.env (legacy short form)
25
+ ];
20
26
  function getForgeDir() {
21
27
  fs.mkdirSync(FORGE_DIR, { recursive: true });
22
28
  return FORGE_DIR;
@@ -32,6 +38,35 @@ function loadCredentials() {
32
38
  return null;
33
39
  }
34
40
  }
41
+ function loadDotEnv() {
42
+ const loaded = [];
43
+ const sources = [];
44
+ const candidates = [path.resolve(process.cwd(), ".env"), ...FORGE_ENV_PATHS];
45
+ for (const file of candidates) {
46
+ let content;
47
+ try {
48
+ content = fs.readFileSync(file, "utf-8");
49
+ } catch {
50
+ continue;
51
+ }
52
+ sources.push(file);
53
+ for (const rawLine of content.split(/\r?\n/)) {
54
+ const line = rawLine.trim();
55
+ if (!line || line.startsWith("#")) continue;
56
+ const eq = line.indexOf("=");
57
+ if (eq < 0) continue;
58
+ const key = line.slice(0, eq).trim();
59
+ let val = line.slice(eq + 1).trim();
60
+ if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
61
+ val = val.slice(1, -1);
62
+ }
63
+ if (!key || process.env[key] != null) continue;
64
+ process.env[key] = val;
65
+ loaded.push(key);
66
+ }
67
+ }
68
+ return { loaded, sources };
69
+ }
35
70
 
36
71
  // src/utils/script-prompt.ts
37
72
  var STYLE_GUIDES = {
@@ -512,7 +547,7 @@ var exec = promisify(execCb);
512
547
  var PORT = 4444;
513
548
  function runCliPipingStdin(cmd, args, stdinData, opts = {}) {
514
549
  const maxBytes = (opts.maxBufferMB ?? 16) * 1024 * 1024;
515
- return new Promise((resolve2, reject) => {
550
+ return new Promise((resolve3, reject) => {
516
551
  const proc = spawn(cmd, args, { stdio: ["pipe", "pipe", "pipe"] });
517
552
  let stdout = "";
518
553
  let stderr = "";
@@ -545,7 +580,7 @@ function runCliPipingStdin(cmd, args, stdinData, opts = {}) {
545
580
  });
546
581
  proc.on("close", (code) => {
547
582
  if (timer) clearTimeout(timer);
548
- resolve2({ stdout, stderr, code });
583
+ resolve3({ stdout, stderr, code });
549
584
  });
550
585
  proc.stdin.end(stdinData);
551
586
  });
@@ -796,10 +831,14 @@ function openBrowser(url) {
796
831
  });
797
832
  }
798
833
  async function devCommand(options) {
834
+ const env = loadDotEnv();
799
835
  const port = parseInt(options.port || String(PORT), 10);
800
836
  const dir = path2.resolve(options.dir || process.cwd());
801
837
  console.log("");
802
838
  log.info(`Forge \u2014 ${dir}`);
839
+ if (env.loaded.length > 0) {
840
+ log.info(`Loaded env: ${env.loaded.join(", ")} from ${env.sources.join(", ")}`);
841
+ }
803
842
  const counts = scanAssets(dir);
804
843
  const total = Object.values(counts).reduce((a, b) => a + b, 0);
805
844
  if (total > 0) {
@@ -1026,7 +1065,14 @@ async function devCommand(options) {
1026
1065
  }
1027
1066
  try {
1028
1067
  log.info(`[script-gen] Generating via ${cli} CLI \xB7 model=${model}`);
1029
- const args = cli === "codex" ? ["exec", "-", "--model", model] : ["-p", "--model", model, "--no-session-persistence"];
1068
+ const args = cli === "codex" ? ["exec", "-", "--model", model, "--search"] : [
1069
+ "-p",
1070
+ "--model",
1071
+ model,
1072
+ "--no-session-persistence",
1073
+ "--allowedTools",
1074
+ "WebSearch,WebFetch"
1075
+ ];
1030
1076
  const timeoutMs = Number(process.env.SCRIPT_GEN_TIMEOUT_MS) || 12e5;
1031
1077
  const { stdout, code, stderr } = await runCliPipingStdin(cli, args, prompt2, {
1032
1078
  timeoutMs,
@@ -1424,9 +1470,9 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1424
1470
  }
1425
1471
  const boundary = boundaryM[1];
1426
1472
  const chunks = [];
1427
- await new Promise((resolve2, reject) => {
1473
+ await new Promise((resolve3, reject) => {
1428
1474
  req.on("data", (c) => chunks.push(Buffer.from(c)));
1429
- req.on("end", resolve2);
1475
+ req.on("end", resolve3);
1430
1476
  req.on("error", reject);
1431
1477
  });
1432
1478
  const body = Buffer.concat(chunks);
@@ -1538,7 +1584,7 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1538
1584
  return "0.0.0";
1539
1585
  })();
1540
1586
  void (async () => {
1541
- const { BridgePoller } = await import("./bridge-poller-IRROEZID.js");
1587
+ const { BridgePoller } = await import("./bridge-poller-YWYLEYOD.js");
1542
1588
  const poller = new BridgePoller({ baseUrl: bridgeUrl, token: bridgeToken, clientVersion: `storyforge ${pkgVersion}` });
1543
1589
  poller.start();
1544
1590
  })();
@@ -1546,7 +1592,12 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1546
1592
  console.log(` Bridge tunnel \u2192 ${bridgeUrl}/api/cli-bridge/* (outbound polling)`);
1547
1593
  } else {
1548
1594
  console.log("");
1549
- console.log(" Bridge tunnel disabled \u2014 set FORGE_BRIDGE_TOKEN to expose your CLI seats to forge.algo-thinker.com");
1595
+ console.log(" Bridge tunnel disabled \u2014 set FORGE_BRIDGE_TOKEN to expose your CLI seats.");
1596
+ console.log(" Vercel env vars do NOT reach this laptop. Pick ONE of these:");
1597
+ console.log(" a) export FORGE_BRIDGE_TOKEN=xxx in your shell, then re-run storyforge");
1598
+ console.log(" b) drop FORGE_BRIDGE_TOKEN=xxx into ./.env (cwd) or ~/.forge/.env");
1599
+ console.log(" c) one-shot: FORGE_BRIDGE_TOKEN=xxx npx storyforge");
1600
+ console.log(` Use the SAME token value you set on Vercel as FORGE_BRIDGE_TOKEN.`);
1550
1601
  }
1551
1602
  console.log("");
1552
1603
  console.log(" Ctrl+C to stop");
@@ -1558,10 +1609,10 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1558
1609
  import * as readline from "readline";
1559
1610
  function prompt(question) {
1560
1611
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1561
- return new Promise((resolve2) => {
1612
+ return new Promise((resolve3) => {
1562
1613
  rl.question(question, (answer) => {
1563
1614
  rl.close();
1564
- resolve2(answer.trim());
1615
+ resolve3(answer.trim());
1565
1616
  });
1566
1617
  });
1567
1618
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyforge",
3
- "version": "0.4.10",
3
+ "version": "0.4.12",
4
4
  "description": "StoryForge — local bridge for the Forge video production web app. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "bin": {