@keystrokehq/cli 0.0.94 → 0.0.96
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,23 @@ Right now the CLI exposes `init`, `build`, `dev`, `start`, `health`, `auth`, `--
|
|
|
19
19
|
|
|
20
20
|
### `auth`
|
|
21
21
|
|
|
22
|
-
Authenticate with
|
|
22
|
+
Authenticate with Keystroke via Better Auth device flow. Config lives in `~/.keystroke`; bearer tokens live in the OS keychain.
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
keystroke auth login
|
|
26
26
|
keystroke auth login --web-url http://localhost:3000
|
|
27
|
+
keystroke auth login --web-url https://app.keystroke.ai --platform-url https://api.keystroke.ai
|
|
27
28
|
keystroke auth status
|
|
28
29
|
keystroke auth logout
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
| Setting | Default
|
|
32
|
-
| ------------- |
|
|
33
|
-
| `webUrl` | `
|
|
34
|
-
| `platformUrl` | `
|
|
35
|
-
| `serverUrl` | `http://localhost:3001`
|
|
32
|
+
| Setting | Default | Purpose |
|
|
33
|
+
| ------------- | -------------------------- | ---------------------------------------------------------------- |
|
|
34
|
+
| `webUrl` | `https://app.keystroke.ai` | Web dashboard; device login and session checks |
|
|
35
|
+
| `platformUrl` | `https://api.keystroke.ai` | Platform API (direct; used by CLI platform commands) |
|
|
36
|
+
| `serverUrl` | `http://localhost:3001` | Local keystroke server API (`keystroke dev` / `keystroke start`) |
|
|
37
|
+
|
|
38
|
+
`auth login` persists both `webUrl` and `platformUrl`. Local dev: `--web-url http://localhost:3000` (platform URL resolves to `http://localhost:3002`). Cloud auth does not change `serverUrl` — local project commands still hit your dev server.
|
|
36
39
|
|
|
37
40
|
Existing commands do not require auth yet. Use `resolveCliAuth()` when adding protected commands.
|
|
38
41
|
|
package/dist/index.mjs
CHANGED
|
@@ -6129,6 +6129,12 @@ const OrganizationSlugSchema = string().trim().toLowerCase().min(2, "Slug must b
|
|
|
6129
6129
|
const ClaimableOrganizationSlugSchema = OrganizationSlugSchema.refine((slug) => !RESERVED_ORGANIZATION_SLUGS.has(slug), "This slug is reserved");
|
|
6130
6130
|
/** Browser→platform request budget (ping + small platform overhead). */
|
|
6131
6131
|
const PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS = 17e3;
|
|
6132
|
+
/** Normalize a public origin URL (no trailing slash). */
|
|
6133
|
+
function originFromPublicUrl(value, fallback) {
|
|
6134
|
+
const trimmed = value?.trim();
|
|
6135
|
+
if (!trimmed) return fallback.replace(/\/+$/, "");
|
|
6136
|
+
return trimmed.replace(/\/+$/, "");
|
|
6137
|
+
}
|
|
6132
6138
|
/** TCP port to bind for a local server, derived from a public URL. */
|
|
6133
6139
|
function listenPortFromUrl(url, fallback) {
|
|
6134
6140
|
const parsed = new URL(url);
|
|
@@ -7201,6 +7207,27 @@ function clearAccessToken(webUrl) {
|
|
|
7201
7207
|
new Entry(SERVICE, accountForWebUrl(webUrl)).deletePassword();
|
|
7202
7208
|
}
|
|
7203
7209
|
//#endregion
|
|
7210
|
+
//#region src/resolve-platform-url.ts
|
|
7211
|
+
const DEFAULT_WEB_URL = "https://app.keystroke.ai";
|
|
7212
|
+
const DEFAULT_PLATFORM_URL = "https://api.keystroke.ai";
|
|
7213
|
+
const LOCAL_PLATFORM_URL = "http://localhost:3002";
|
|
7214
|
+
function webOriginFromUrl(webUrl) {
|
|
7215
|
+
return originFromPublicUrl(webUrl, webUrl.replace(/\/+$/, ""));
|
|
7216
|
+
}
|
|
7217
|
+
/** Known web origins with a fixed platform API — undefined for custom/staging URLs. */
|
|
7218
|
+
function knownPlatformUrlForWebUrl(webUrl) {
|
|
7219
|
+
const webOrigin = webOriginFromUrl(webUrl);
|
|
7220
|
+
if (webOrigin === "http://localhost:3000" || webOrigin === "http://127.0.0.1:3000") return LOCAL_PLATFORM_URL;
|
|
7221
|
+
if (webOrigin === "https://app.keystroke.ai") return DEFAULT_PLATFORM_URL;
|
|
7222
|
+
}
|
|
7223
|
+
function resolvePlatformUrlForWebUrl(webUrl, options = {}) {
|
|
7224
|
+
const explicit = options.platformUrl?.trim();
|
|
7225
|
+
if (explicit) return explicit.replace(/\/+$/, "");
|
|
7226
|
+
const known = knownPlatformUrlForWebUrl(webUrl);
|
|
7227
|
+
if (known) return known;
|
|
7228
|
+
return (options.fallback?.trim() || "https://api.keystroke.ai").replace(/\/+$/, "");
|
|
7229
|
+
}
|
|
7230
|
+
//#endregion
|
|
7204
7231
|
//#region src/config.ts
|
|
7205
7232
|
function getCliConfigDir(cwd = join(homedir(), ".keystroke")) {
|
|
7206
7233
|
return cwd;
|
|
@@ -7213,8 +7240,13 @@ function getEffectiveApiTarget(config) {
|
|
|
7213
7240
|
if (explicit === "local" || explicit === "platform") return explicit;
|
|
7214
7241
|
return "local";
|
|
7215
7242
|
}
|
|
7243
|
+
function syncPlatformUrlWithWebUrl(config) {
|
|
7244
|
+
const known = knownPlatformUrlForWebUrl(config.get("webUrl"));
|
|
7245
|
+
if (!known) return;
|
|
7246
|
+
if (config.get("platformUrl") !== known) config.set("platformUrl", known);
|
|
7247
|
+
}
|
|
7216
7248
|
function createCliConfig(cwd = getCliConfigDir()) {
|
|
7217
|
-
|
|
7249
|
+
const config = new Conf({
|
|
7218
7250
|
projectName: "keystroke",
|
|
7219
7251
|
cwd,
|
|
7220
7252
|
schema: {
|
|
@@ -7224,11 +7256,11 @@ function createCliConfig(cwd = getCliConfigDir()) {
|
|
|
7224
7256
|
},
|
|
7225
7257
|
webUrl: {
|
|
7226
7258
|
type: "string",
|
|
7227
|
-
default:
|
|
7259
|
+
default: DEFAULT_WEB_URL
|
|
7228
7260
|
},
|
|
7229
7261
|
platformUrl: {
|
|
7230
7262
|
type: "string",
|
|
7231
|
-
default:
|
|
7263
|
+
default: DEFAULT_PLATFORM_URL
|
|
7232
7264
|
},
|
|
7233
7265
|
activeOrganizationId: { type: "string" },
|
|
7234
7266
|
activeProjectId: { type: "string" },
|
|
@@ -7238,6 +7270,8 @@ function createCliConfig(cwd = getCliConfigDir()) {
|
|
|
7238
7270
|
}
|
|
7239
7271
|
}
|
|
7240
7272
|
});
|
|
7273
|
+
syncPlatformUrlWithWebUrl(config);
|
|
7274
|
+
return config;
|
|
7241
7275
|
}
|
|
7242
7276
|
function getServerUrl(config) {
|
|
7243
7277
|
return config.get("serverUrl");
|
|
@@ -7246,7 +7280,7 @@ function getWebUrl(config) {
|
|
|
7246
7280
|
return config.get("webUrl");
|
|
7247
7281
|
}
|
|
7248
7282
|
function getPlatformUrl(config) {
|
|
7249
|
-
return config.get("platformUrl");
|
|
7283
|
+
return resolvePlatformUrlForWebUrl(getWebUrl(config), { fallback: config.get("platformUrl") });
|
|
7250
7284
|
}
|
|
7251
7285
|
//#endregion
|
|
7252
7286
|
//#region src/auth/resolve-cli-auth.ts
|
|
@@ -11781,7 +11815,7 @@ function registerCredentialsCommand(program) {
|
|
|
11781
11815
|
/** OAuth device-flow client id for `keystroke auth login`. */
|
|
11782
11816
|
const CLI_CLIENT_ID = "keystroke-cli";
|
|
11783
11817
|
//#endregion
|
|
11784
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
11818
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/version.mjs
|
|
11785
11819
|
const PACKAGE_VERSION = "1.6.11";
|
|
11786
11820
|
//#endregion
|
|
11787
11821
|
//#region ../../node_modules/.pnpm/better-call@1.3.5_zod@4.4.3/node_modules/better-call/dist/error.mjs
|
|
@@ -11906,7 +11940,7 @@ var BetterAuthError = class extends Error {
|
|
|
11906
11940
|
}
|
|
11907
11941
|
};
|
|
11908
11942
|
//#endregion
|
|
11909
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
11943
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/plugins/device-authorization/client.mjs
|
|
11910
11944
|
const deviceAuthorizationClient = () => {
|
|
11911
11945
|
return {
|
|
11912
11946
|
id: "device-authorization",
|
|
@@ -12051,7 +12085,7 @@ let onMount = ($store, initialize) => {
|
|
|
12051
12085
|
});
|
|
12052
12086
|
};
|
|
12053
12087
|
//#endregion
|
|
12054
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12088
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/query.mjs
|
|
12055
12089
|
const isServer = () => typeof window === "undefined";
|
|
12056
12090
|
const useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
12057
12091
|
const value = /* @__PURE__ */ atom({
|
|
@@ -12145,7 +12179,7 @@ const useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
|
12145
12179
|
return value;
|
|
12146
12180
|
};
|
|
12147
12181
|
//#endregion
|
|
12148
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12182
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/broadcast-channel.mjs
|
|
12149
12183
|
const kBroadcastChannel = Symbol.for("better-auth:broadcast-channel");
|
|
12150
12184
|
const now$1 = () => Math.floor(Date.now() / 1e3);
|
|
12151
12185
|
var WindowBroadcastChannel = class {
|
|
@@ -12188,7 +12222,7 @@ function getGlobalBroadcastChannel(name = "better-auth.message") {
|
|
|
12188
12222
|
return globalThis[kBroadcastChannel];
|
|
12189
12223
|
}
|
|
12190
12224
|
//#endregion
|
|
12191
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12225
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/focus-manager.mjs
|
|
12192
12226
|
const kFocusManager = Symbol.for("better-auth:focus-manager");
|
|
12193
12227
|
var WindowFocusManager = class {
|
|
12194
12228
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -12217,7 +12251,7 @@ function getGlobalFocusManager() {
|
|
|
12217
12251
|
return globalThis[kFocusManager];
|
|
12218
12252
|
}
|
|
12219
12253
|
//#endregion
|
|
12220
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12254
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/online-manager.mjs
|
|
12221
12255
|
const kOnlineManager = Symbol.for("better-auth:online-manager");
|
|
12222
12256
|
var WindowOnlineManager = class {
|
|
12223
12257
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -12249,7 +12283,7 @@ function getGlobalOnlineManager() {
|
|
|
12249
12283
|
return globalThis[kOnlineManager];
|
|
12250
12284
|
}
|
|
12251
12285
|
//#endregion
|
|
12252
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12286
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/parser.mjs
|
|
12253
12287
|
const PROTO_POLLUTION_PATTERNS = {
|
|
12254
12288
|
proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
|
|
12255
12289
|
constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
|
|
@@ -12319,7 +12353,7 @@ function parseJSON(value, options = { strict: true }) {
|
|
|
12319
12353
|
return betterJSONParse(value, options);
|
|
12320
12354
|
}
|
|
12321
12355
|
//#endregion
|
|
12322
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12356
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/session-refresh.mjs
|
|
12323
12357
|
const now = () => Math.floor(Date.now() / 1e3);
|
|
12324
12358
|
/**
|
|
12325
12359
|
* Normalize $fetch response: `throw: true` returns data directly, otherwise `{ data, error }`.
|
|
@@ -12517,7 +12551,7 @@ Object.freeze({
|
|
|
12517
12551
|
}
|
|
12518
12552
|
});
|
|
12519
12553
|
//#endregion
|
|
12520
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12554
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/utils/url.mjs
|
|
12521
12555
|
function checkHasPath(url) {
|
|
12522
12556
|
try {
|
|
12523
12557
|
return (new URL(url).pathname.replace(/\/+$/, "") || "/") !== "/";
|
|
@@ -12589,7 +12623,7 @@ function getOrigin(url) {
|
|
|
12589
12623
|
}
|
|
12590
12624
|
}
|
|
12591
12625
|
//#endregion
|
|
12592
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12626
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/fetch-plugins.mjs
|
|
12593
12627
|
const redirectPlugin = {
|
|
12594
12628
|
id: "redirect",
|
|
12595
12629
|
name: "Redirect",
|
|
@@ -12604,7 +12638,7 @@ const redirectPlugin = {
|
|
|
12604
12638
|
} }
|
|
12605
12639
|
};
|
|
12606
12640
|
//#endregion
|
|
12607
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
12641
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/session-atom.mjs
|
|
12608
12642
|
function getSessionAtom($fetch, options) {
|
|
12609
12643
|
const $signal = /* @__PURE__ */ atom(false);
|
|
12610
12644
|
const session = useAuthQuery($signal, "/get-session", $fetch, { method: "GET" });
|
|
@@ -13091,7 +13125,7 @@ var betterFetch = async (url, options) => {
|
|
|
13091
13125
|
};
|
|
13092
13126
|
};
|
|
13093
13127
|
//#endregion
|
|
13094
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
13128
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/config.mjs
|
|
13095
13129
|
const resolvePublicAuthUrl = (basePath) => {
|
|
13096
13130
|
if (typeof process === "undefined") return void 0;
|
|
13097
13131
|
const path = basePath ?? "/api/auth";
|
|
@@ -13189,12 +13223,12 @@ const getClientConfig = (options, loadEnv) => {
|
|
|
13189
13223
|
};
|
|
13190
13224
|
};
|
|
13191
13225
|
//#endregion
|
|
13192
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
13226
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/utils/is-atom.mjs
|
|
13193
13227
|
function isAtom(value) {
|
|
13194
13228
|
return typeof value === "object" && value !== null && "get" in value && typeof value.get === "function" && "lc" in value && typeof value.lc === "number";
|
|
13195
13229
|
}
|
|
13196
13230
|
//#endregion
|
|
13197
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
13231
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/proxy.mjs
|
|
13198
13232
|
function getMethod(path, knownPathMethods, args) {
|
|
13199
13233
|
const method = knownPathMethods[path];
|
|
13200
13234
|
const { fetchOptions, query: _query, ...body } = args || {};
|
|
@@ -13274,7 +13308,7 @@ function capitalizeFirstLetter(str) {
|
|
|
13274
13308
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
13275
13309
|
}
|
|
13276
13310
|
//#endregion
|
|
13277
|
-
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.
|
|
13311
|
+
//#region ../../node_modules/.pnpm/better-auth@1.6.11_@tanstack+react-start@1.168.22_crossws@0.4.5_srvx@0.11.15__react-dom_58aa013e967694c3ee75e7bc1076e12b/node_modules/better-auth/dist/client/vanilla.mjs
|
|
13278
13312
|
function createAuthClient(options) {
|
|
13279
13313
|
const { pluginPathMethods, pluginsActions, pluginsAtoms, $fetch, atomListeners, $store } = getClientConfig(options);
|
|
13280
13314
|
const resolvedHooks = {};
|
|
@@ -13362,10 +13396,15 @@ async function getSessionWithBearer(baseURL, accessToken) {
|
|
|
13362
13396
|
//#endregion
|
|
13363
13397
|
//#region src/commands/auth/login.ts
|
|
13364
13398
|
function registerAuthLoginCommand(auth) {
|
|
13365
|
-
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (default from config)").option("--org <id>", "Active organization id (skips prompt when you belong to several)").action(async (options) => {
|
|
13399
|
+
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (default from config)").option("--platform-url <url>", "Platform API origin (derived from web URL when omitted)").option("--org <id>", "Active organization id (skips prompt when you belong to several)").action(async (options) => {
|
|
13366
13400
|
const config = createCliConfig();
|
|
13367
13401
|
const webUrl = options.webUrl ?? getWebUrl(config);
|
|
13368
|
-
|
|
13402
|
+
const platformUrl = resolvePlatformUrlForWebUrl(webUrl, {
|
|
13403
|
+
platformUrl: options.platformUrl,
|
|
13404
|
+
fallback: getPlatformUrl(config)
|
|
13405
|
+
});
|
|
13406
|
+
config.set("webUrl", webUrl);
|
|
13407
|
+
config.set("platformUrl", platformUrl);
|
|
13369
13408
|
try {
|
|
13370
13409
|
const result = await runDeviceLogin({
|
|
13371
13410
|
baseURL: webUrl,
|
|
@@ -14312,7 +14351,7 @@ function registerConfigCommand(program) {
|
|
|
14312
14351
|
process.stdout.write(`${JSON.stringify({
|
|
14313
14352
|
serverUrl: cliConfig.get("serverUrl"),
|
|
14314
14353
|
webUrl: cliConfig.get("webUrl"),
|
|
14315
|
-
platformUrl: cliConfig
|
|
14354
|
+
platformUrl: getPlatformUrl(cliConfig),
|
|
14316
14355
|
activeOrganizationId: cliConfig.get("activeOrganizationId"),
|
|
14317
14356
|
activeProjectId: cliConfig.get("activeProjectId"),
|
|
14318
14357
|
apiTarget: getEffectiveApiTarget(cliConfig),
|