authflow-cli 0.1.0 → 0.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/LICENSE +201 -201
- package/README.md +337 -260
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/get.d.ts +7 -0
- package/dist/commands/get.js +34 -0
- package/dist/commands/get.js.map +1 -0
- package/dist/commands/init.js +5 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +44 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/register.js +24 -0
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/rotate-origin-key.d.ts +6 -0
- package/dist/commands/rotate-origin-key.js +56 -0
- package/dist/commands/rotate-origin-key.js.map +1 -0
- package/dist/commands/scaffold.js +31 -31
- package/dist/commands/set-origin.d.ts +5 -0
- package/dist/commands/set-origin.js +55 -19
- package/dist/commands/set-origin.js.map +1 -1
- package/dist/commands/signup.js +3 -3
- package/dist/commands/signup.js.map +1 -1
- package/dist/commands/status.d.ts +10 -0
- package/dist/commands/status.js +40 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/mcp/server.js +52 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/rail.d.ts +5 -0
- package/dist/rail.js +12 -0
- package/dist/rail.js.map +1 -1
- package/dist/status.d.ts +34 -0
- package/dist/status.js +112 -0
- package/dist/status.js.map +1 -0
- package/package.json +56 -56
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,8BAA8B,CAAC;KAC3C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,UAAU,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Reading back a receipt without re-registering. Its absence pushed the first tenant into calling
|
|
4
|
+
* the admin API by hand to work out who owned a slug, and a plain `authflow get` is the command
|
|
5
|
+
* anyone reaches for first.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getCommand(program: Command): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { requireAdminKey, requireIssuer } from "../config.js";
|
|
2
|
+
import { getResource } from "../rail.js";
|
|
3
|
+
import { formatCursorMcpConfig } from "../status.js";
|
|
4
|
+
/**
|
|
5
|
+
* Reading back a receipt without re-registering. Its absence pushed the first tenant into calling
|
|
6
|
+
* the admin API by hand to work out who owned a slug, and a plain `authflow get` is the command
|
|
7
|
+
* anyone reaches for first.
|
|
8
|
+
*/
|
|
9
|
+
export function getCommand(program) {
|
|
10
|
+
program
|
|
11
|
+
.command("get")
|
|
12
|
+
.description("Fetch a resource's registration receipt")
|
|
13
|
+
.requiredOption("--slug <slug>", "Resource slug")
|
|
14
|
+
.option("--issuer <url>", "Authflow issuer (default: AUTHFLOW_ISSUER)")
|
|
15
|
+
.option("--admin-key <key>", "Admin API key (default: AUTHFLOW_ADMIN_API_KEY)")
|
|
16
|
+
.option("--json", "Emit the receipt as JSON and nothing else")
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const auth = { issuer: requireIssuer(opts.issuer), adminKey: requireAdminKey(opts.adminKey) };
|
|
19
|
+
const receipt = await getResource(auth, opts.slug);
|
|
20
|
+
if (opts.json) {
|
|
21
|
+
console.log(JSON.stringify(receipt, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log(JSON.stringify(receipt, null, 2));
|
|
25
|
+
const mcpConfig = formatCursorMcpConfig(receipt);
|
|
26
|
+
if (mcpConfig.length > 0) {
|
|
27
|
+
console.log("");
|
|
28
|
+
for (const line of mcpConfig) {
|
|
29
|
+
console.log(line);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,yCAAyC,CAAC;SACtD,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC;SAChD,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,mBAAmB,EAAE,iDAAiD,CAAC;SAC9E,MAAM,CAAC,QAAQ,EAAE,2CAA2C,CAAC;SAC7D,MAAM,CAAC,KAAK,EAAE,IAA0E,EAAE,EAAE;QAC3F,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAE9C,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,6 +2,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { apiJson, bearer, requireAdminKey, requireIssuer } from "../config.js";
|
|
3
3
|
import { describePending, startConnect } from "../rail.js";
|
|
4
4
|
import { originApiKeyConfigKey, secretTargets, writeOriginApiKey } from "../secrets.js";
|
|
5
|
+
import { formatCursorMcpConfig } from "../status.js";
|
|
5
6
|
/**
|
|
6
7
|
* One command from nothing to a registered, configured origin.
|
|
7
8
|
*
|
|
@@ -78,6 +79,10 @@ export function initCommand(program) {
|
|
|
78
79
|
}
|
|
79
80
|
console.log("");
|
|
80
81
|
printOriginConfig(opts.integration, receipt, storedAt !== undefined);
|
|
82
|
+
console.log("");
|
|
83
|
+
for (const line of formatCursorMcpConfig(receipt)) {
|
|
84
|
+
console.log(line);
|
|
85
|
+
}
|
|
81
86
|
if (opts.connect && !opts.connectedAccount) {
|
|
82
87
|
console.log("");
|
|
83
88
|
await printConnectLink(issuer, adminKey, opts.slug);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,EAA4B,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAqB,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { requireAdminKey, requireIssuer } from "../config.js";
|
|
2
|
+
import { listResources } from "../rail.js";
|
|
3
|
+
export function listCommand(program) {
|
|
4
|
+
program
|
|
5
|
+
.command("list")
|
|
6
|
+
.description("List every resource this admin key owns")
|
|
7
|
+
.option("--issuer <url>", "Authflow issuer (default: AUTHFLOW_ISSUER)")
|
|
8
|
+
.option("--admin-key <key>", "Admin API key (default: AUTHFLOW_ADMIN_API_KEY)")
|
|
9
|
+
.option("--json", "Emit the list as JSON")
|
|
10
|
+
.action(async (opts) => {
|
|
11
|
+
const auth = { issuer: requireIssuer(opts.issuer), adminKey: requireAdminKey(opts.adminKey) };
|
|
12
|
+
const resources = await listResources(auth);
|
|
13
|
+
if (opts.json) {
|
|
14
|
+
console.log(JSON.stringify(resources, null, 2));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (resources.length === 0) {
|
|
18
|
+
console.log("No resources registered with this admin key.");
|
|
19
|
+
console.log("");
|
|
20
|
+
console.log("If you expected one here, you are probably using a different tenant's key or");
|
|
21
|
+
console.log("a different environment. Check AUTHFLOW_ISSUER and AUTHFLOW_ADMIN_API_KEY.");
|
|
22
|
+
console.log("");
|
|
23
|
+
console.log("Register one: authflow init --slug <slug>");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const slugWidth = Math.max(4, ...resources.map((r) => (r.slug ?? "").length));
|
|
27
|
+
const statusWidth = Math.max(6, ...resources.map((r) => (r.status ?? "").length));
|
|
28
|
+
console.log(`${pad("SLUG", slugWidth)} ${pad("STATUS", statusWidth)} GATEWAY URL`);
|
|
29
|
+
for (const resource of resources) {
|
|
30
|
+
const gateway = resource.gateway_url ?? resource.resource ?? "-";
|
|
31
|
+
console.log(`${pad(resource.slug ?? "-", slugWidth)} ${pad(resource.status ?? "-", statusWidth)} ${gateway}`);
|
|
32
|
+
const pending = resource.pending_requirements ?? [];
|
|
33
|
+
if (pending.length > 0) {
|
|
34
|
+
console.log(`${"".padEnd(slugWidth)} ${"".padEnd(statusWidth)} pending: ${pending.join(", ")}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log("Full state for one resource: authflow status --slug <slug>");
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function pad(value, width) {
|
|
42
|
+
return value.length >= width ? value : value + " ".repeat(width - value.length);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -9,7 +9,7 @@ export function mcpCommand(program) {
|
|
|
9
9
|
"against the codebase it already has open:",
|
|
10
10
|
"",
|
|
11
11
|
' { "mcpServers": { "authflow": {',
|
|
12
|
-
' "command": "npx", "args": ["-y", "authflow-cli", "mcp"],',
|
|
12
|
+
' "command": "npx", "args": ["-y", "-p", "authflow-cli", "authflow", "mcp"],',
|
|
13
13
|
' "env": { "AUTHFLOW_ISSUER": "https://…", "AUTHFLOW_ADMIN_API_KEY": "…" } } } }',
|
|
14
14
|
"",
|
|
15
15
|
"Mint AUTHFLOW_ADMIN_API_KEY with `authflow signup --email you@example.com` if you do not",
|
package/dist/commands/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,iDAAiD,CAAC;SAC9D,WAAW,CACV,OAAO,EACP;QACE,EAAE;QACF,sFAAsF;QACtF,2CAA2C;QAC3C,EAAE;QACF,mCAAmC;QACnC,
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,iDAAiD,CAAC;SAC9D,WAAW,CACV,OAAO,EACP;QACE,EAAE;QACF,sFAAsF;QACtF,2CAA2C;QAC3C,EAAE;QACF,mCAAmC;QACnC,kFAAkF;QAClF,sFAAsF;QACtF,EAAE;QACF,0FAA0F;QAC1F,+EAA+E;QAC/E,EAAE;QACF,yEAAyE;KAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CACb;SACA,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,cAAc,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { apiJson, bearer, requireAdminKey, requireIssuer } from "../config.js";
|
|
3
3
|
import { secretTargets, writeOriginApiKey } from "../secrets.js";
|
|
4
|
+
import { formatCursorMcpConfig, formatReadiness, resourceReadiness } from "../status.js";
|
|
4
5
|
export function registerCommand(program) {
|
|
5
6
|
program
|
|
6
7
|
.command("register")
|
|
@@ -11,6 +12,7 @@ export function registerCommand(program) {
|
|
|
11
12
|
.option("-o, --out <path>", "Receipt output path", "receipt.json")
|
|
12
13
|
.option("--write-secrets <target>", `Store the origin API key and redact it from the receipt (${secretTargets.join(" | ")})`)
|
|
13
14
|
.option("--secret-destination <value>", "user-secrets: project dir (default .) · env-file: path (default .env.local) · keyvault: vault name")
|
|
15
|
+
.option("--keep-secret-in-receipt", "Leave the origin API key in the receipt file as plaintext (not recommended)")
|
|
14
16
|
.action(async (opts) => {
|
|
15
17
|
const issuer = requireIssuer(opts.issuer);
|
|
16
18
|
const adminKey = requireAdminKey(opts.adminKey);
|
|
@@ -45,6 +47,12 @@ export function registerCommand(program) {
|
|
|
45
47
|
});
|
|
46
48
|
body.origin_api_key = `<stored in ${storedAt}>`;
|
|
47
49
|
}
|
|
50
|
+
else if (originApiKey && !opts.keepSecretInReceipt) {
|
|
51
|
+
// Redacted by default. The receipt is a file people commit, paste into issues, and hand to
|
|
52
|
+
// an agent, and the key it carried was a live bearer credential for the usage endpoint. It
|
|
53
|
+
// is printed below instead, so nothing is lost by keeping it out of the file.
|
|
54
|
+
body.origin_api_key = "<not written to the receipt — see terminal output>";
|
|
55
|
+
}
|
|
48
56
|
await writeFile(opts.out, `${JSON.stringify(body, null, 2)}\n`, "utf8");
|
|
49
57
|
console.log(`Registered (${status}). Receipt written to ${opts.out}`);
|
|
50
58
|
if (typeof body.slug === "string") {
|
|
@@ -59,10 +67,26 @@ export function registerCommand(program) {
|
|
|
59
67
|
if (storedAt) {
|
|
60
68
|
console.log(` origin_api_key: stored in ${storedAt} (redacted from the receipt)`);
|
|
61
69
|
}
|
|
70
|
+
else if (originApiKey && !opts.keepSecretInReceipt) {
|
|
71
|
+
console.log(` origin_api_key: ${originApiKey} (shown once — store it now)`);
|
|
72
|
+
console.log(" Kept out of the receipt file. Use --write-secrets to store it automatically.");
|
|
73
|
+
}
|
|
62
74
|
else if (originApiKey) {
|
|
63
75
|
console.log(` origin_api_key: ${originApiKey} (store now — shown once)`);
|
|
64
76
|
console.log(` Note: ${opts.out} now holds a plaintext credential. Re-run with --write-secrets to avoid that.`);
|
|
65
77
|
}
|
|
78
|
+
const receipt = body;
|
|
79
|
+
console.log("");
|
|
80
|
+
for (const line of formatCursorMcpConfig(receipt)) {
|
|
81
|
+
console.log(line);
|
|
82
|
+
}
|
|
83
|
+
// A registered resource is not a reachable one, and the difference is invisible from the
|
|
84
|
+
// gateway: both answer with an error. Say so here rather than let it be discovered later.
|
|
85
|
+
const readiness = resourceReadiness(receipt);
|
|
86
|
+
if (!readiness.ready) {
|
|
87
|
+
console.log("");
|
|
88
|
+
console.log(formatReadiness(readiness));
|
|
89
|
+
}
|
|
66
90
|
});
|
|
67
91
|
}
|
|
68
92
|
function parseTarget(raw) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* The recovery path for a lost origin API key. It existed as an MCP tool but not as a command, so a
|
|
4
|
+
* creator who lost the key — it is shown once — had no way back without an agent in the loop.
|
|
5
|
+
*/
|
|
6
|
+
export declare function rotateOriginKeyCommand(program: Command): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { requireAdminKey, requireIssuer } from "../config.js";
|
|
2
|
+
import { rotateOriginKey } from "../rail.js";
|
|
3
|
+
import { secretTargets, writeOriginApiKey } from "../secrets.js";
|
|
4
|
+
/**
|
|
5
|
+
* The recovery path for a lost origin API key. It existed as an MCP tool but not as a command, so a
|
|
6
|
+
* creator who lost the key — it is shown once — had no way back without an agent in the loop.
|
|
7
|
+
*/
|
|
8
|
+
export function rotateOriginKeyCommand(program) {
|
|
9
|
+
program
|
|
10
|
+
.command("rotate-origin-key")
|
|
11
|
+
.description("Issue a new origin API key and immediately invalidate the previous one")
|
|
12
|
+
.requiredOption("--slug <slug>", "Resource slug")
|
|
13
|
+
.option("--issuer <url>", "Authflow issuer (default: AUTHFLOW_ISSUER)")
|
|
14
|
+
.option("--admin-key <key>", "Admin API key (default: AUTHFLOW_ADMIN_API_KEY)")
|
|
15
|
+
.option("--write-secrets <target>", `Store the new key (${secretTargets.join(" | ")})`)
|
|
16
|
+
.option("--secret-destination <value>", "Project dir, env-file path, or Key Vault name")
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const auth = {
|
|
19
|
+
issuer: requireIssuer(opts.issuer),
|
|
20
|
+
adminKey: requireAdminKey(opts.adminKey),
|
|
21
|
+
};
|
|
22
|
+
const target = parseTarget(opts.writeSecrets);
|
|
23
|
+
const receipt = await rotateOriginKey(auth, opts.slug);
|
|
24
|
+
const key = receipt.origin_api_key;
|
|
25
|
+
if (!key) {
|
|
26
|
+
throw new Error("The rail did not return a new origin API key.");
|
|
27
|
+
}
|
|
28
|
+
if (target) {
|
|
29
|
+
const storedAt = await writeOriginApiKey({
|
|
30
|
+
target,
|
|
31
|
+
value: key,
|
|
32
|
+
destination: opts.secretDestination,
|
|
33
|
+
});
|
|
34
|
+
console.log(`Rotated ${opts.slug}. New key stored in ${storedAt}.`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`Rotated ${opts.slug}. New origin API key (shown once):`);
|
|
38
|
+
console.log("");
|
|
39
|
+
console.log(` ${key}`);
|
|
40
|
+
}
|
|
41
|
+
console.log("");
|
|
42
|
+
console.log("The previous key stopped working the moment this returned. Update the origin's");
|
|
43
|
+
console.log("secret store now, or its usage reports and probes will fail.");
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function parseTarget(raw) {
|
|
47
|
+
if (raw === undefined) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const value = raw.trim();
|
|
51
|
+
if (!secretTargets.includes(value)) {
|
|
52
|
+
throw new Error(`--write-secrets must be one of: ${secretTargets.join(", ")}`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=rotate-origin-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotate-origin-key.js","sourceRoot":"","sources":["../../src/commands/rotate-origin-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAqB,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpF;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,wEAAwE,CAAC;SACrF,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC;SAChD,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,mBAAmB,EAAE,iDAAiD,CAAC;SAC9E,MAAM,CAAC,0BAA0B,EAAE,sBAAsB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;SACtF,MAAM,CAAC,8BAA8B,EAAE,+CAA+C,CAAC;SACvF,MAAM,CACL,KAAK,EAAE,IAMN,EAAE,EAAE;QACH,MAAM,IAAI,GAAG;YACX,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;YAClC,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;SACzC,CAAC;QAEF,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;QAEnC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC;gBACvC,MAAM;gBACN,KAAK,EAAE,GAAG;gBACV,WAAW,EAAE,IAAI,CAAC,iBAAiB;aACpC,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,uBAAuB,QAAQ,GAAG,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,oCAAoC,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC,CACF,CAAC;AACN,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAkB,CAAC;IACzC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -26,37 +26,37 @@ export function scaffoldCommand(program) {
|
|
|
26
26
|
"",
|
|
27
27
|
];
|
|
28
28
|
await writeFile(opts.envOut, envLines.join("\n"), "utf8");
|
|
29
|
-
const compose = `# Generated by authflow scaffold from ${opts.receipt}
|
|
30
|
-
# Put authflow-origin-proxy in front of your MCP upstream.
|
|
31
|
-
# Build the image from the Authflow.Rail repo:
|
|
32
|
-
# docker build -f src/Rail.OriginProxy/Dockerfile -t authflow-origin-proxy .
|
|
33
|
-
#
|
|
34
|
-
# Replay protection is process-local until you set Authflow__NonceCacheRedis.
|
|
35
|
-
# Set it before raising replicas above 1.
|
|
36
|
-
# See docs/onboarding/origin-proxy.md
|
|
37
|
-
|
|
38
|
-
services:
|
|
39
|
-
authflow-origin-proxy:
|
|
40
|
-
image: authflow-origin-proxy
|
|
41
|
-
ports:
|
|
42
|
-
- "${opts.proxyPort}:8080"
|
|
43
|
-
environment:
|
|
44
|
-
Authflow__Issuer: \${AUTHFLOW_ISSUER}
|
|
45
|
-
Authflow__Resource: \${AUTHFLOW_RESOURCE}
|
|
46
|
-
Authflow__UpstreamBaseUri: \${AUTHFLOW_UPSTREAM_BASE_URI}
|
|
47
|
-
# Authflow__NonceCacheRedis: \${AUTHFLOW_NONCE_CACHE_REDIS}
|
|
48
|
-
env_file:
|
|
49
|
-
- ${opts.envOut}
|
|
50
|
-
# Safe to raise once Authflow__NonceCacheRedis is set.
|
|
51
|
-
deploy:
|
|
52
|
-
replicas: 1
|
|
53
|
-
|
|
54
|
-
# Replace with your MCP origin, or point Authflow__UpstreamBaseUri at an
|
|
55
|
-
# existing host and drop this service.
|
|
56
|
-
upstream:
|
|
57
|
-
image: your-mcp-origin:latest
|
|
58
|
-
expose:
|
|
59
|
-
- "3000"
|
|
29
|
+
const compose = `# Generated by authflow scaffold from ${opts.receipt}
|
|
30
|
+
# Put authflow-origin-proxy in front of your MCP upstream.
|
|
31
|
+
# Build the image from the Authflow.Rail repo:
|
|
32
|
+
# docker build -f src/Rail.OriginProxy/Dockerfile -t authflow-origin-proxy .
|
|
33
|
+
#
|
|
34
|
+
# Replay protection is process-local until you set Authflow__NonceCacheRedis.
|
|
35
|
+
# Set it before raising replicas above 1.
|
|
36
|
+
# See docs/onboarding/origin-proxy.md
|
|
37
|
+
|
|
38
|
+
services:
|
|
39
|
+
authflow-origin-proxy:
|
|
40
|
+
image: authflow-origin-proxy
|
|
41
|
+
ports:
|
|
42
|
+
- "${opts.proxyPort}:8080"
|
|
43
|
+
environment:
|
|
44
|
+
Authflow__Issuer: \${AUTHFLOW_ISSUER}
|
|
45
|
+
Authflow__Resource: \${AUTHFLOW_RESOURCE}
|
|
46
|
+
Authflow__UpstreamBaseUri: \${AUTHFLOW_UPSTREAM_BASE_URI}
|
|
47
|
+
# Authflow__NonceCacheRedis: \${AUTHFLOW_NONCE_CACHE_REDIS}
|
|
48
|
+
env_file:
|
|
49
|
+
- ${opts.envOut}
|
|
50
|
+
# Safe to raise once Authflow__NonceCacheRedis is set.
|
|
51
|
+
deploy:
|
|
52
|
+
replicas: 1
|
|
53
|
+
|
|
54
|
+
# Replace with your MCP origin, or point Authflow__UpstreamBaseUri at an
|
|
55
|
+
# existing host and drop this service.
|
|
56
|
+
upstream:
|
|
57
|
+
image: your-mcp-origin:latest
|
|
58
|
+
expose:
|
|
59
|
+
- "3000"
|
|
60
60
|
`;
|
|
61
61
|
await writeFile(opts.composeOut, compose, "utf8");
|
|
62
62
|
console.log(`Wrote ${opts.envOut}`);
|
|
@@ -2,5 +2,10 @@ import type { Command } from "commander";
|
|
|
2
2
|
/**
|
|
3
3
|
* Second half of the register-now / deploy-later flow: point a draft resource at its origin, which
|
|
4
4
|
* promotes it to live and makes it routable.
|
|
5
|
+
*
|
|
6
|
+
* The probe runs straight afterwards rather than being suggested. This is the moment the resource
|
|
7
|
+
* starts accepting real traffic, and "verify before you go live" printed as a closing line is a step
|
|
8
|
+
* that gets skipped — the first tenant through never ran it, and shipped an origin whose fail-closed
|
|
9
|
+
* behaviour nobody had checked.
|
|
5
10
|
*/
|
|
6
11
|
export declare function setOriginCommand(program: Command): void;
|
|
@@ -1,38 +1,74 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireAdminKey, requireIssuer } from "../config.js";
|
|
2
|
+
import { assertNotMcpSuffixed, probeConformance, setOrigin } from "../rail.js";
|
|
3
|
+
import { formatCursorMcpConfig, formatReadiness, resourceReadiness } from "../status.js";
|
|
2
4
|
/**
|
|
3
5
|
* Second half of the register-now / deploy-later flow: point a draft resource at its origin, which
|
|
4
6
|
* promotes it to live and makes it routable.
|
|
7
|
+
*
|
|
8
|
+
* The probe runs straight afterwards rather than being suggested. This is the moment the resource
|
|
9
|
+
* starts accepting real traffic, and "verify before you go live" printed as a closing line is a step
|
|
10
|
+
* that gets skipped — the first tenant through never ran it, and shipped an origin whose fail-closed
|
|
11
|
+
* behaviour nobody had checked.
|
|
5
12
|
*/
|
|
6
13
|
export function setOriginCommand(program) {
|
|
7
14
|
program
|
|
8
15
|
.command("set-origin")
|
|
9
|
-
.description("Set a resource's origin base URI, promoting a draft to live")
|
|
16
|
+
.description("Set a resource's origin base URI, promoting a draft to live, then probe it")
|
|
10
17
|
.requiredOption("--slug <slug>", "Resource slug")
|
|
11
18
|
.requiredOption("--origin-url <url>", "Origin base URI (no /mcp suffix — the gateway appends it)")
|
|
12
19
|
.option("--issuer <url>", "Authflow issuer (default: AUTHFLOW_ISSUER)")
|
|
13
20
|
.option("--admin-key <key>", "Admin API key (default: AUTHFLOW_ADMIN_API_KEY)")
|
|
21
|
+
.option("--origin-key <key>", "Origin API key for the probe (default: AUTHFLOW_ORIGIN_API_KEY)")
|
|
22
|
+
.option("--no-probe", "Skip the conformance probe after setting the origin")
|
|
14
23
|
.action(async (opts) => {
|
|
15
24
|
const issuer = requireIssuer(opts.issuer);
|
|
16
25
|
const adminKey = requireAdminKey(opts.adminKey);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
assertNotMcpSuffixed(opts.originUrl);
|
|
27
|
+
const receipt = await setOrigin({ issuer, adminKey }, opts.slug, opts.originUrl);
|
|
28
|
+
console.log(`${receipt.slug ?? opts.slug} -> ${receipt.origin_base_uri ?? opts.originUrl}`);
|
|
29
|
+
console.log(`status: ${receipt.status ?? "live"}`);
|
|
30
|
+
console.log("");
|
|
31
|
+
for (const line of formatCursorMcpConfig(receipt)) {
|
|
32
|
+
console.log(line);
|
|
33
|
+
}
|
|
34
|
+
const readiness = resourceReadiness(receipt);
|
|
35
|
+
if (!readiness.ready) {
|
|
36
|
+
console.log("");
|
|
37
|
+
console.log(formatReadiness(readiness));
|
|
38
|
+
}
|
|
39
|
+
if (opts.probe === false) {
|
|
40
|
+
console.log("");
|
|
41
|
+
console.log("Probe skipped. Run it before real traffic: authflow probe");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const originKey = (opts.originKey ?? process.env.AUTHFLOW_ORIGIN_API_KEY ?? "").trim();
|
|
45
|
+
if (!originKey) {
|
|
46
|
+
console.log("");
|
|
47
|
+
console.log("Cannot probe: no origin API key. The probe authenticates as the origin, and");
|
|
48
|
+
console.log("the admin key cannot stand in for it.");
|
|
49
|
+
console.log("");
|
|
50
|
+
console.log(" Set AUTHFLOW_ORIGIN_API_KEY (or pass --origin-key) and run: authflow probe");
|
|
51
|
+
console.log(` Lost the key? authflow rotate-origin-key --slug ${opts.slug}`);
|
|
52
|
+
return;
|
|
21
53
|
}
|
|
22
|
-
const { body } = await apiJson(`${issuer}/admin/resources/${encodeURIComponent(opts.slug)}/origin`, {
|
|
23
|
-
method: "PUT",
|
|
24
|
-
headers: {
|
|
25
|
-
...bearer(adminKey),
|
|
26
|
-
"Content-Type": "application/json",
|
|
27
|
-
Accept: "application/json",
|
|
28
|
-
},
|
|
29
|
-
body: JSON.stringify({ origin_base_uri: opts.originUrl }),
|
|
30
|
-
expectedStatuses: [200],
|
|
31
|
-
});
|
|
32
|
-
console.log(`${body.slug ?? opts.slug} -> ${body.origin_base_uri ?? opts.originUrl}`);
|
|
33
|
-
console.log(`status: ${body.status ?? "live"}`);
|
|
34
54
|
console.log("");
|
|
35
|
-
console.log("
|
|
55
|
+
console.log("Probing the origin for fail-closed behaviour...");
|
|
56
|
+
console.log("");
|
|
57
|
+
const report = await probeConformance(issuer, originKey);
|
|
58
|
+
for (const check of report.checks) {
|
|
59
|
+
console.log(` ${check.pass ? "PASS" : "FAIL"} ${check.name}`);
|
|
60
|
+
if (!check.pass) {
|
|
61
|
+
console.log(` expected ${check.expected}, got ${check.observed}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log("");
|
|
65
|
+
if (report.pass) {
|
|
66
|
+
console.log("Conformance: PASS. The origin is ready for paid traffic.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log("Conformance: FAIL. The resource is live but the origin does not fail closed,");
|
|
70
|
+
console.log("which means unauthenticated callers may reach paid tools. Fix before cutover.");
|
|
71
|
+
process.exitCode = 1;
|
|
36
72
|
});
|
|
37
73
|
}
|
|
38
74
|
//# sourceMappingURL=set-origin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set-origin.js","sourceRoot":"","sources":["../../src/commands/set-origin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"set-origin.js","sourceRoot":"","sources":["../../src/commands/set-origin.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/signup.js
CHANGED
|
@@ -29,7 +29,7 @@ export function signupCommand(program) {
|
|
|
29
29
|
mcpServers: {
|
|
30
30
|
authflow: {
|
|
31
31
|
command: "npx",
|
|
32
|
-
args: ["-y", "authflow-cli", "mcp"],
|
|
32
|
+
args: ["-y", "-p", "authflow-cli", "authflow", "mcp"],
|
|
33
33
|
env: {
|
|
34
34
|
AUTHFLOW_ISSUER: receipt.issuer,
|
|
35
35
|
AUTHFLOW_ADMIN_API_KEY: storedAt ? `<from ${storedAt}>` : receipt.admin_api_key,
|
|
@@ -43,8 +43,8 @@ export function signupCommand(program) {
|
|
|
43
43
|
mcp_config: mcpConfig,
|
|
44
44
|
next_steps: [
|
|
45
45
|
storedAt
|
|
46
|
-
? `Load ${storedAt} (or copy the key into Cursor's MCP env) and run: npx -y authflow-cli init --slug <your-slug>`
|
|
47
|
-
: "Store the admin_api_key, then: npx -y authflow-cli init --slug <your-slug>",
|
|
46
|
+
? `Load ${storedAt} (or copy the key into Cursor's MCP env) and run: npx -y -p authflow-cli authflow init --slug <your-slug>`
|
|
47
|
+
: "Store the admin_api_key, then: npx -y -p authflow-cli authflow init --slug <your-slug>",
|
|
48
48
|
"Or paste mcp_config into Cursor and let the agent finish onboarding.",
|
|
49
49
|
],
|
|
50
50
|
}, null, 2) + "\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/commands/signup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AASjD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,cAAc,CAAC,mBAAmB,EAAE,4BAA4B,CAAC;SACjE,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,iBAAiB,EAAE,oDAAoD,EAAE,IAAI,CAAC;SACrF,MAAM,CAAC,oBAAoB,EAAE,6CAA6C,CAAC;SAC3E,MAAM,CAAC,6BAA6B,EAAE,mCAAmC,CAAC;SAC1E,WAAW,CACV,OAAO,EACP;QACE,EAAE;QACF,0EAA0E;QAC1E,qEAAqE;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb;SACA,MAAM,CAAC,KAAK,EAAE,IAAmB,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvD,IAAI,QAA4B,CAAC;QACjC,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YAChC,QAAQ,GAAG,MAAM,gBAAgB,CAAC;gBAChC,KAAK,EAAE,OAAO,CAAC,aAAa;gBAC5B,WAAW,EAAE,IAAI,CAAC,iBAAiB;aACpC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG;YAChB,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/commands/signup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AASjD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,cAAc,CAAC,mBAAmB,EAAE,4BAA4B,CAAC;SACjE,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,iBAAiB,EAAE,oDAAoD,EAAE,IAAI,CAAC;SACrF,MAAM,CAAC,oBAAoB,EAAE,6CAA6C,CAAC;SAC3E,MAAM,CAAC,6BAA6B,EAAE,mCAAmC,CAAC;SAC1E,WAAW,CACV,OAAO,EACP;QACE,EAAE;QACF,0EAA0E;QAC1E,qEAAqE;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb;SACA,MAAM,CAAC,KAAK,EAAE,IAAmB,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvD,IAAI,QAA4B,CAAC;QACjC,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YAChC,QAAQ,GAAG,MAAM,gBAAgB,CAAC;gBAChC,KAAK,EAAE,OAAO,CAAC,aAAa;gBAC5B,WAAW,EAAE,IAAI,CAAC,iBAAiB;aACpC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG;YAChB,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,CAAC;oBACrD,GAAG,EAAE;wBACH,eAAe,EAAE,OAAO,CAAC,MAAM;wBAC/B,sBAAsB,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa;qBAChF;iBACF;aACF;SACF,CAAC;QAEF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CACZ;YACE,GAAG,OAAO;YACV,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,QAAQ,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa;YAC3E,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE;gBACV,QAAQ;oBACN,CAAC,CAAC,QAAQ,QAAQ,2GAA2G;oBAC7H,CAAC,CAAC,wFAAwF;gBAC5F,sEAAsE;aACvE;SACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Where onboarding actually got to, in one command.
|
|
4
|
+
*
|
|
5
|
+
* `doctor` answers "is the rail up", which is a different question: the rail can be perfectly
|
|
6
|
+
* healthy while a resource sits half-configured and 403s every request. This reads the live receipt
|
|
7
|
+
* and prints the remaining steps with the command for each, so a run interrupted halfway — a deploy
|
|
8
|
+
* that got backgrounded, a terminal that was closed — can be picked up without guessing.
|
|
9
|
+
*/
|
|
10
|
+
export declare function statusCommand(program: Command): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { requireAdminKey, requireIssuer } from "../config.js";
|
|
2
|
+
import { getResource } from "../rail.js";
|
|
3
|
+
import { formatCursorMcpConfig, formatReadiness, resourceReadiness } from "../status.js";
|
|
4
|
+
/**
|
|
5
|
+
* Where onboarding actually got to, in one command.
|
|
6
|
+
*
|
|
7
|
+
* `doctor` answers "is the rail up", which is a different question: the rail can be perfectly
|
|
8
|
+
* healthy while a resource sits half-configured and 403s every request. This reads the live receipt
|
|
9
|
+
* and prints the remaining steps with the command for each, so a run interrupted halfway — a deploy
|
|
10
|
+
* that got backgrounded, a terminal that was closed — can be picked up without guessing.
|
|
11
|
+
*/
|
|
12
|
+
export function statusCommand(program) {
|
|
13
|
+
program
|
|
14
|
+
.command("status")
|
|
15
|
+
.description("Show how far a resource is from taking paid traffic, and the next command to run")
|
|
16
|
+
.requiredOption("--slug <slug>", "Resource slug")
|
|
17
|
+
.option("--issuer <url>", "Authflow issuer (default: AUTHFLOW_ISSUER)")
|
|
18
|
+
.option("--admin-key <key>", "Admin API key (default: AUTHFLOW_ADMIN_API_KEY)")
|
|
19
|
+
.option("--json", "Emit the readiness report as JSON")
|
|
20
|
+
.action(async (opts) => {
|
|
21
|
+
const auth = { issuer: requireIssuer(opts.issuer), adminKey: requireAdminKey(opts.adminKey) };
|
|
22
|
+
const receipt = await getResource(auth, opts.slug);
|
|
23
|
+
const readiness = resourceReadiness(receipt);
|
|
24
|
+
if (opts.json) {
|
|
25
|
+
console.log(JSON.stringify(readiness, null, 2));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log(formatReadiness(readiness));
|
|
29
|
+
if (readiness.ready) {
|
|
30
|
+
console.log("");
|
|
31
|
+
for (const line of formatCursorMcpConfig(receipt)) {
|
|
32
|
+
console.log(line);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Non-zero on a resource that cannot serve paid traffic, so this is usable as a deploy gate.
|
|
37
|
+
process.exitCode = readiness.ready ? 0 : 1;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEzF;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,kFAAkF,CAAC;SAC/F,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC;SAChD,MAAM,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,mBAAmB,EAAE,iDAAiD,CAAC;SAC9E,MAAM,CAAC,QAAQ,EAAE,mCAAmC,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,IAA0E,EAAE,EAAE;QAC3F,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE7C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;YAExC,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,KAAK,MAAM,IAAI,IAAI,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QAED,6FAA6F;QAC7F,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACP,CAAC"}
|