pi-forge 1.1.6 → 1.2.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/README.md CHANGED
@@ -19,20 +19,30 @@ Open <http://localhost:3000> and pick a workspace folder.
19
19
 
20
20
  ## Configuration
21
21
 
22
- All knobs are environment variables. Sensible defaults set only what
23
- you need.
22
+ Every knob is settable as a `--flag` on the `pi-forge` command OR as
23
+ an environment variable. **Flags win when both are set.** Run
24
+ `pi-forge --help` for the full grouped list.
24
25
 
25
- | Variable | Default | Purpose |
26
- |---|---|---|
27
- | `PORT` | `3000` | HTTP listen port |
28
- | `WORKSPACE_PATH` | `~/.pi-forge/workspace` | Where project code lives |
29
- | `PI_CONFIG_DIR` | `~/.pi/agent` | Pi SDK config (auth, models, settings) |
30
- | `FORGE_DATA_DIR` | `~/.pi-forge` | pi-forge state (project list) |
31
- | `UI_PASSWORD` | (unset) | Enables browser login if set |
32
- | `API_KEY` | (unset) | Enables `Authorization: Bearer` for programmatic use |
26
+ ```bash
27
+ pi-forge --port 4000 --workspace-path ~/Code
28
+ pi-forge --api-key @/run/secrets/api-key --no-expose-docs
29
+ ```
30
+
31
+ The most common knobs:
32
+
33
+ | Flag | Env var | Default | Purpose |
34
+ |---|---|---|---|
35
+ | `--port` | `PORT` | `3000` | HTTP listen port |
36
+ | `--workspace-path` | `WORKSPACE_PATH` | `~/.pi-forge/workspace` | Where project code lives |
37
+ | `--pi-config-dir` | `PI_CONFIG_DIR` | `~/.pi/agent` | Pi SDK config (auth, models, settings) |
38
+ | `--forge-data-dir` | `FORGE_DATA_DIR` | `~/.pi-forge` | pi-forge state (project list) |
39
+ | `--ui-password` | `UI_PASSWORD` | (unset) | Enables browser login if set |
40
+ | `--api-key` | `API_KEY` | (unset) | Enables `Authorization: Bearer` for programmatic use |
33
41
 
34
- If both `UI_PASSWORD` and `API_KEY` are unset, auth is disabled. For
35
- production, set at minimum `API_KEY`.
42
+ `--ui-password`, `--api-key`, and `--jwt-secret` accept `@<path>` to
43
+ read the value from a file (avoids shell history leakage). If both
44
+ `--ui-password` and `--api-key` are unset, auth is disabled — for
45
+ production, set at minimum `--api-key`.
36
46
 
37
47
  ## Programmatic API
38
48
 
@@ -42,7 +52,7 @@ for the full surface and example curl flows.
42
52
 
43
53
  ## Versioning
44
54
 
45
- This package version (`1.1.6`) tracks the [GitHub release](https://github.com/Devin-Marks/pi-forge/releases)
55
+ This package version (`1.2.0`) tracks the [GitHub release](https://github.com/Devin-Marks/pi-forge/releases)
46
56
  of the same name. Docker images and the npm package are published in
47
57
  lockstep on each `v*` tag.
48
58
 
package/bin/pi-forge.mjs CHANGED
@@ -17,12 +17,14 @@
17
17
  * package. We override `CLIENT_DIST_PATH` here so the same server entry
18
18
  * works in all three deployment shapes without touching server code.
19
19
  *
20
- * Everything else (workspace path, pi config dir, forge data dir, port,
21
- * auth) is read from env vars and uses the server's existing defaults
22
- * (`~/.pi-forge/workspace`, `~/.pi/agent`, `~/.pi-forge`, port 3000)
23
- * users who installed via `npm i -g pi-forge` get sensible per-user
24
- * paths under their home directory without any setup.
20
+ * Flag parsing: `cli.js` translates argv into env-var writes BEFORE
21
+ * `index.js` is imported, because config.js reads `process.env` at
22
+ * module-load time. Every server env var has an equivalent --flag
23
+ * see `pi-forge --help` or `packages/server/src/cli.ts` for the
24
+ * complete table. Env vars still work as fallbacks for users who
25
+ * already have them set; flag values win when both are present.
25
26
  */
27
+ import { readFileSync } from "node:fs";
26
28
  import { dirname, resolve } from "node:path";
27
29
  import { fileURLToPath, pathToFileURL } from "node:url";
28
30
 
@@ -32,6 +34,33 @@ const packageRoot = resolve(here, "..");
32
34
  process.env.CLIENT_DIST_PATH ??= resolve(packageRoot, "dist", "client");
33
35
  process.env.NODE_ENV ??= "production";
34
36
 
37
+ const cliEntry = resolve(packageRoot, "dist", "server", "cli.js");
38
+ const { parseCliArgs, applyCliEnv, buildHelpText } = await import(pathToFileURL(cliEntry).href);
39
+
40
+ const parsed = parseCliArgs(process.argv.slice(2));
41
+
42
+ if (parsed.errors.length > 0) {
43
+ for (const err of parsed.errors) {
44
+ process.stderr.write(`pi-forge: ${err}\n`);
45
+ }
46
+ process.stderr.write(`pi-forge: run with --help for usage.\n`);
47
+ process.exit(2);
48
+ }
49
+
50
+ if (parsed.helpRequested) {
51
+ const pkg = JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8"));
52
+ process.stdout.write(buildHelpText(pkg.version));
53
+ process.exit(0);
54
+ }
55
+
56
+ if (parsed.versionRequested) {
57
+ const pkg = JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8"));
58
+ process.stdout.write(`pi-forge ${pkg.version}\n`);
59
+ process.exit(0);
60
+ }
61
+
62
+ applyCliEnv(parsed);
63
+
35
64
  const serverEntry = resolve(packageRoot, "dist", "server", "index.js");
36
65
  const { start } = await import(pathToFileURL(serverEntry).href);
37
66
  await start();