pennyrouter 0.2.35 → 0.3.1
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/package.json +1 -1
- package/src/cli.js +47 -4
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -185,8 +185,18 @@ function parseArgs(argv) {
|
|
|
185
185
|
else if (arg.startsWith("--harness=")) flags.harness = arg.slice("--harness=".length);
|
|
186
186
|
else if (arg === "--app-url") flags.appUrl = rest[++i] || "";
|
|
187
187
|
else if (arg.startsWith("--app-url=")) flags.appUrl = arg.slice("--app-url=".length);
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
// A --gateway-base-url is a *private* gateway: an admin-run deployment that issues its own
|
|
189
|
+
// keys. Flag it so install can require the matching admin-issued key. --local/--prod are
|
|
190
|
+
// developer shortcuts against gateways that honor prod keys, so they do not set this.
|
|
191
|
+
else if (arg === "--gateway-base-url") { flags.gatewayBaseUrl = rest[++i] || ""; flags.privateGateway = true; }
|
|
192
|
+
else if (arg.startsWith("--gateway-base-url=")) {
|
|
193
|
+
flags.gatewayBaseUrl = arg.slice("--gateway-base-url=".length);
|
|
194
|
+
flags.privateGateway = true;
|
|
195
|
+
}
|
|
196
|
+
// Admin-issued key for a private gateway (see scripts/provision_local_key.py). Overrides the
|
|
197
|
+
// key returned by the browser claim, which is only valid against the hosted gateway.
|
|
198
|
+
else if (arg === "--private-key") flags.privateKey = rest[++i] || "";
|
|
199
|
+
else if (arg.startsWith("--private-key=")) flags.privateKey = arg.slice("--private-key=".length);
|
|
190
200
|
// --local: point the installed harness at a locally-running gateway (default
|
|
191
201
|
// http://localhost:8400), for developing/testing against your own gateway. Auth still goes
|
|
192
202
|
// to prod (pennyrouter.com) so you get a real key; only the harness's serving URL is local.
|
|
@@ -608,7 +618,35 @@ export async function install(flags = {}) {
|
|
|
608
618
|
const privateGateway = (await promptText(
|
|
609
619
|
"PennyRouter gateway URL for this proxy (blank for hosted gateway): ",
|
|
610
620
|
)).trim();
|
|
611
|
-
if (privateGateway)
|
|
621
|
+
if (privateGateway) {
|
|
622
|
+
gatewayBaseUrl = privateGateway;
|
|
623
|
+
flags.privateGateway = true;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// A private gateway has its own key store, so the hosted key from the browser claim is
|
|
628
|
+
// meaningless there. Require the admin-issued key and use it for every subsequent gateway
|
|
629
|
+
// call (credential storage, probing, harness config).
|
|
630
|
+
if (flags.privateGateway) {
|
|
631
|
+
let privateKey = (flags.privateKey || "").trim();
|
|
632
|
+
if (!privateKey && !flags.yes && input.isTTY && output.isTTY) {
|
|
633
|
+
console.log("");
|
|
634
|
+
console.log(`Private gateway: ${gatewayBaseUrl}`);
|
|
635
|
+
console.log("Your PennyRouter administrator issues keys for this gateway.");
|
|
636
|
+
privateKey = (await promptText("Paste your private gateway key (pr-...): ")).trim();
|
|
637
|
+
}
|
|
638
|
+
if (!privateKey) {
|
|
639
|
+
throw new Error(
|
|
640
|
+
`A private gateway (${gatewayBaseUrl}) needs its own key. `
|
|
641
|
+
+ "Ask your PennyRouter administrator for one and pass `--private-key pr-...`.",
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
if (!privateKey.startsWith("pr-")) {
|
|
645
|
+
throw new Error(`That does not look like a PennyRouter key — expected it to start with "pr-".`);
|
|
646
|
+
}
|
|
647
|
+
claim.api_key = privateKey;
|
|
648
|
+
console.log(`Using private gateway key ${maskKey(privateKey)}.`);
|
|
649
|
+
console.log("");
|
|
612
650
|
}
|
|
613
651
|
|
|
614
652
|
for (const credential of funding.credentials) {
|
|
@@ -2067,7 +2105,7 @@ function printHelp() {
|
|
|
2067
2105
|
console.log(`PennyRouter CLI
|
|
2068
2106
|
|
|
2069
2107
|
Usage:
|
|
2070
|
-
pennyrouter install [--harness ${SUPPORTED_HARNESS_IDS}] [--all] [--yes] [--dry-run] [--make-default|--penny-only] [--no-path-update] [--no-mcp] [--anthropic-auth|--no-anthropic-auth] [--anthropic-api-key KEY] [--openai-api-key KEY] [--openai-proxy-base-url URL --openai-proxy-api-key KEY] [--openrouter-api-key KEY] [--proxy-base-url URL --proxy-api-key KEY] [--local[=URL]|--prod] [--config PATH]
|
|
2108
|
+
pennyrouter install [--harness ${SUPPORTED_HARNESS_IDS}] [--all] [--yes] [--dry-run] [--make-default|--penny-only] [--no-path-update] [--no-mcp] [--anthropic-auth|--no-anthropic-auth] [--anthropic-api-key KEY] [--openai-api-key KEY] [--openai-proxy-base-url URL --openai-proxy-api-key KEY] [--openrouter-api-key KEY] [--proxy-base-url URL --proxy-api-key KEY] [--gateway-base-url URL --private-key pr-...] [--local[=URL]|--prod] [--config PATH]
|
|
2071
2109
|
pennyrouter update [--harness ${SUPPORTED_HARNESS_IDS}] [--all] [--dry-run] [--penny-key pr-...] [--gateway-base-url URL|--local[=URL]|--prod] [--no-mcp]
|
|
2072
2110
|
pennyrouter auth anthropic [--penny-key pr-...] [--token oauth-token] [--token-command CMD] [--gateway-base-url URL] [--forget]
|
|
2073
2111
|
pennyrouter disable [--harness ${SUPPORTED_HARNESS_IDS}] [--all] [--yes]
|
|
@@ -2080,6 +2118,10 @@ When an interactive install selects an Anthropic or OpenAI-compatible proxy, it
|
|
|
2080
2118
|
that can reach that proxy. Leave it blank for the hosted gateway, or enter a private/self-hosted
|
|
2081
2119
|
gateway URL. Use --gateway-base-url (or --local for localhost:8400 development) for non-interactive installs.
|
|
2082
2120
|
|
|
2121
|
+
A private gateway keeps its own keys, so the key from the browser login does not work there. Whenever
|
|
2122
|
+
you point install at one — with --gateway-base-url or by entering a URL at that prompt — you must also
|
|
2123
|
+
supply the key your PennyRouter administrator issued you: paste it when asked, or pass --private-key pr-...
|
|
2124
|
+
|
|
2083
2125
|
Install and update both register the Threads MCP server with Claude Code and Codex (--no-mcp to
|
|
2084
2126
|
skip a run). Run "pennyrouter mcp install" if you skipped it or had to rename a conflicting
|
|
2085
2127
|
server, "pennyrouter mcp status" to see whether it is wired up, and "pennyrouter mcp uninstall"
|
|
@@ -2110,6 +2152,7 @@ Examples:
|
|
|
2110
2152
|
npx pennyrouter install --harness codex --openai-api-key <key>
|
|
2111
2153
|
npx pennyrouter install --harness claude-code --proxy-base-url https://proxy.example.com --proxy-api-key <key>
|
|
2112
2154
|
npx pennyrouter install --openrouter-api-key <key>
|
|
2155
|
+
npx pennyrouter install --gateway-base-url https://gateway.internal.example.com --private-key pr-...
|
|
2113
2156
|
npx pennyrouter auth anthropic
|
|
2114
2157
|
npx pennyrouter install --all
|
|
2115
2158
|
npx pennyrouter install --harness windsurf,zed,codegpt,aider --yes
|