storyforge 0.4.10 → 0.4.11

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.
Files changed (2) hide show
  1. package/dist/index.js +51 -7
  2. package/package.json +1 -1
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) {
@@ -1424,9 +1463,9 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1424
1463
  }
1425
1464
  const boundary = boundaryM[1];
1426
1465
  const chunks = [];
1427
- await new Promise((resolve2, reject) => {
1466
+ await new Promise((resolve3, reject) => {
1428
1467
  req.on("data", (c) => chunks.push(Buffer.from(c)));
1429
- req.on("end", resolve2);
1468
+ req.on("end", resolve3);
1430
1469
  req.on("error", reject);
1431
1470
  });
1432
1471
  const body = Buffer.concat(chunks);
@@ -1546,7 +1585,12 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1546
1585
  console.log(` Bridge tunnel \u2192 ${bridgeUrl}/api/cli-bridge/* (outbound polling)`);
1547
1586
  } else {
1548
1587
  console.log("");
1549
- console.log(" Bridge tunnel disabled \u2014 set FORGE_BRIDGE_TOKEN to expose your CLI seats to forge.algo-thinker.com");
1588
+ console.log(" Bridge tunnel disabled \u2014 set FORGE_BRIDGE_TOKEN to expose your CLI seats.");
1589
+ console.log(" Vercel env vars do NOT reach this laptop. Pick ONE of these:");
1590
+ console.log(" a) export FORGE_BRIDGE_TOKEN=xxx in your shell, then re-run storyforge");
1591
+ console.log(" b) drop FORGE_BRIDGE_TOKEN=xxx into ./.env (cwd) or ~/.forge/.env");
1592
+ console.log(" c) one-shot: FORGE_BRIDGE_TOKEN=xxx npx storyforge");
1593
+ console.log(` Use the SAME token value you set on Vercel as FORGE_BRIDGE_TOKEN.`);
1550
1594
  }
1551
1595
  console.log("");
1552
1596
  console.log(" Ctrl+C to stop");
@@ -1558,10 +1602,10 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1558
1602
  import * as readline from "readline";
1559
1603
  function prompt(question) {
1560
1604
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1561
- return new Promise((resolve2) => {
1605
+ return new Promise((resolve3) => {
1562
1606
  rl.question(question, (answer) => {
1563
1607
  rl.close();
1564
- resolve2(answer.trim());
1608
+ resolve3(answer.trim());
1565
1609
  });
1566
1610
  });
1567
1611
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyforge",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "description": "StoryForge — local bridge for the Forge video production web app. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "bin": {