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.
- package/dist/index.js +51 -7
- 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((
|
|
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
|
-
|
|
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((
|
|
1466
|
+
await new Promise((resolve3, reject) => {
|
|
1428
1467
|
req.on("data", (c) => chunks.push(Buffer.from(c)));
|
|
1429
|
-
req.on("end",
|
|
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
|
|
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((
|
|
1605
|
+
return new Promise((resolve3) => {
|
|
1562
1606
|
rl.question(question, (answer) => {
|
|
1563
1607
|
rl.close();
|
|
1564
|
-
|
|
1608
|
+
resolve3(answer.trim());
|
|
1565
1609
|
});
|
|
1566
1610
|
});
|
|
1567
1611
|
}
|