@ory/argus 0.11.1 → 0.12.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/dist/agent-auth.d.ts +23 -0
- package/dist/agent-auth.js +42 -1
- package/dist/auth.js +76 -3
- package/dist/cli-invocation.d.ts +34 -0
- package/dist/cli-invocation.js +60 -0
- package/dist/cli.d.ts +15 -5
- package/dist/cli.js +161 -53
- package/dist/client.d.ts +27 -0
- package/dist/client.js +85 -5
- package/dist/config.d.ts +61 -0
- package/dist/config.js +81 -5
- package/dist/dev.d.ts +8 -0
- package/dist/dev.js +12 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +17 -3
- package/dist/interactive-setup.d.ts +123 -0
- package/dist/interactive-setup.js +1203 -0
- package/dist/local/cli.js +12 -11
- package/dist/local/index.d.ts +1 -1
- package/dist/local/index.js +3 -1
- package/dist/local/manager.js +1 -1
- package/dist/permissions-cli.js +55 -19
- package/dist/registry/config.js +7 -0
- package/dist/setup.d.ts +43 -3
- package/dist/setup.js +116 -23
- package/dist/status-cli.d.ts +2 -1
- package/dist/status-cli.js +34 -13
- package/dist/subject.d.ts +8 -5
- package/dist/subject.js +9 -6
- package/dist/tool-catalog.d.ts +2 -2
- package/dist/tool-catalog.js +14 -6
- package/dist/ui.d.ts +144 -0
- package/dist/ui.js +270 -0
- package/dist/uninstall.d.ts +47 -0
- package/dist/uninstall.js +90 -0
- package/dist/user-login.d.ts +5 -3
- package/dist/user-login.js +13 -9
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -73,7 +73,21 @@ export interface OryAgentCredentialsBlock {
|
|
|
73
73
|
*/
|
|
74
74
|
export type PermissionMode = "observe" | "enforce";
|
|
75
75
|
export interface OryPluginConfig {
|
|
76
|
+
/**
|
|
77
|
+
* Ory project API URL — the SDK base path all API calls target. The Ory
|
|
78
|
+
* Console "Get Started" panel calls this `ORY_SDK_URL`; the env var of that
|
|
79
|
+
* name is accepted as an alias for `ORY_PROJECT_URL` (see {@link resolveConfig}).
|
|
80
|
+
*/
|
|
76
81
|
projectUrl?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Ory project UUID — the other half of the Console "Get Started" pair
|
|
84
|
+
* (`ORY_PROJECT_ID`). Persisted by the interactive installer because the
|
|
85
|
+
* admin `ory` CLI operations key off it (`--project <id>`). It is an
|
|
86
|
+
* identifier for admin APIs, **not** an SDK URL source: the SDK base URL is
|
|
87
|
+
* always the slug-based {@link projectUrl}, and a project id (a UUID) must
|
|
88
|
+
* never be substituted for a slug when building it.
|
|
89
|
+
*/
|
|
90
|
+
projectId?: string;
|
|
77
91
|
apiKey?: string;
|
|
78
92
|
/**
|
|
79
93
|
* Public OAuth2 client id used by the user PKCE browser flow when
|
|
@@ -93,6 +107,23 @@ export interface OryPluginConfig {
|
|
|
93
107
|
* tuple set is correct. See {@link PermissionMode}.
|
|
94
108
|
*/
|
|
95
109
|
permissionMode?: PermissionMode;
|
|
110
|
+
/**
|
|
111
|
+
* Whether the interactive user PKCE login runs at session start. When
|
|
112
|
+
* true, every session runs `ensureUserAuthenticated`; when unset the
|
|
113
|
+
* flow is a no-op. Set via `configure --user-login` / `--no-user-login`.
|
|
114
|
+
* The `ORY_USER_LOGIN` env var overrides this when set. Requires an
|
|
115
|
+
* OAuth2 client id ({@link oauth2ClientId}) to actually complete a login.
|
|
116
|
+
*/
|
|
117
|
+
userLogin?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Permission-check subject namespace for the human user. When set, the
|
|
120
|
+
* user is addressed as a SubjectSet `<namespace>:<subject>` in permission
|
|
121
|
+
* checks instead of a direct SubjectID — this must match how the tuples
|
|
122
|
+
* were written in Keto. The local stack seeds tuples as `User:<id>`, so the
|
|
123
|
+
* local-stack install path persists `"User"` here to make enforce mode work
|
|
124
|
+
* out of the box. The `ORY_USER_SUBJECT_NAMESPACE` env var overrides this.
|
|
125
|
+
*/
|
|
126
|
+
userSubjectNamespace?: string;
|
|
96
127
|
/** Credentials for the human user (interactive PKCE login). */
|
|
97
128
|
user?: OryUserCredentials;
|
|
98
129
|
/** Credentials for the AI agent process (machine identity). */
|
|
@@ -128,6 +159,14 @@ export declare function getConfigPath(): string;
|
|
|
128
159
|
* does not exist or is invalid.
|
|
129
160
|
*/
|
|
130
161
|
export declare function loadConfig(): OryPluginConfig;
|
|
162
|
+
/**
|
|
163
|
+
* Read `ORY_USER_LOGIN` from the environment. Returns `true`/`false` when
|
|
164
|
+
* the var is set (any recognized truthy value enables it; anything else
|
|
165
|
+
* disables it), or `undefined` when the var is absent/empty so callers
|
|
166
|
+
* fall back to the config file. Centralized here so the user gate, status
|
|
167
|
+
* CLI, and configure command resolve it identically.
|
|
168
|
+
*/
|
|
169
|
+
export declare function parseUserLoginEnv(): boolean | undefined;
|
|
131
170
|
/**
|
|
132
171
|
* Save config to the config file. Merges with existing values — only
|
|
133
172
|
* provided fields are overwritten. Concurrent processes serialize via a
|
|
@@ -147,18 +186,40 @@ export declare function saveConfig(update: Partial<{
|
|
|
147
186
|
* atomic via write-temp + rename.
|
|
148
187
|
*/
|
|
149
188
|
export declare function mutateConfig(mutator: (current: OryPluginConfig) => OryPluginConfig): void;
|
|
189
|
+
/**
|
|
190
|
+
* True when `value` looks like an Ory project **id** (a UUID) rather than a
|
|
191
|
+
* project **slug**. Project slugs are human-readable tokens (e.g.
|
|
192
|
+
* `nervous-galileo-1a2b3c`) and are never UUIDs, so this cleanly distinguishes
|
|
193
|
+
* the two. Used to guard the SDK-URL derivation: the URL subdomain must be the
|
|
194
|
+
* slug — a project id must never be substituted for it (see
|
|
195
|
+
* {@link projectUrlFromSlug}). The id addresses project-scoped **admin** APIs
|
|
196
|
+
* (the `ory` CLI's `--project` flag), which is a different concern from the SDK
|
|
197
|
+
* base URL.
|
|
198
|
+
*/
|
|
199
|
+
export declare function looksLikeProjectId(value: string): boolean;
|
|
150
200
|
/**
|
|
151
201
|
* Resolve config by checking environment variables first, then the config file.
|
|
152
202
|
* Returns the merged result with the source of each value.
|
|
203
|
+
*
|
|
204
|
+
* `projectUrl` accepts `ORY_SDK_URL` as an alias for `ORY_PROJECT_URL` (the two
|
|
205
|
+
* names the Console "Get Started" uses). The SDK URL is **always** slug-based;
|
|
206
|
+
* `projectId` (`ORY_PROJECT_ID`) is a distinct identifier for admin APIs and is
|
|
207
|
+
* never turned into an SDK URL — a project id is not a slug.
|
|
153
208
|
*/
|
|
154
209
|
export declare function resolveConfig(): {
|
|
155
210
|
projectUrl?: string;
|
|
211
|
+
projectId?: string;
|
|
156
212
|
apiKey?: string;
|
|
157
213
|
oauth2ClientId?: string;
|
|
158
214
|
auditOnly: boolean;
|
|
159
215
|
permissionMode: PermissionMode;
|
|
160
216
|
permissionModeSource: "env" | "config" | "default";
|
|
217
|
+
userLogin: boolean;
|
|
218
|
+
userLoginSource: "env" | "config" | "default";
|
|
219
|
+
userSubjectNamespace?: string;
|
|
220
|
+
userSubjectNamespaceSource: "env" | "config" | "none";
|
|
161
221
|
projectUrlSource: "env" | "config" | "none";
|
|
222
|
+
projectIdSource: "env" | "config" | "none";
|
|
162
223
|
apiKeySource: "env" | "config" | "none";
|
|
163
224
|
oauth2ClientIdSource: "env" | "config" | "none";
|
|
164
225
|
};
|
package/dist/config.js
CHANGED
|
@@ -37,13 +37,16 @@ exports.getDataDir = getDataDir;
|
|
|
37
37
|
exports.getHarnessDataDir = getHarnessDataDir;
|
|
38
38
|
exports.getConfigPath = getConfigPath;
|
|
39
39
|
exports.loadConfig = loadConfig;
|
|
40
|
+
exports.parseUserLoginEnv = parseUserLoginEnv;
|
|
40
41
|
exports.saveConfig = saveConfig;
|
|
41
42
|
exports.mutateConfig = mutateConfig;
|
|
43
|
+
exports.looksLikeProjectId = looksLikeProjectId;
|
|
42
44
|
exports.resolveConfig = resolveConfig;
|
|
43
45
|
exports.configPromptMessage = configPromptMessage;
|
|
44
46
|
const fs = __importStar(require("node:fs"));
|
|
45
47
|
const os = __importStar(require("node:os"));
|
|
46
48
|
const path = __importStar(require("node:path"));
|
|
49
|
+
const cli_invocation_js_1 = require("./cli-invocation.js");
|
|
47
50
|
/**
|
|
48
51
|
* Single OS-agnostic data directory for *all* Ory agent plugin state:
|
|
49
52
|
* the shared config file, persisted DCR credentials, and any harness
|
|
@@ -114,10 +117,17 @@ function loadConfig() {
|
|
|
114
117
|
const parsed = JSON.parse(raw);
|
|
115
118
|
return {
|
|
116
119
|
projectUrl: typeof parsed.projectUrl === "string" ? parsed.projectUrl : undefined,
|
|
120
|
+
projectId: typeof parsed.projectId === "string" && parsed.projectId.trim()
|
|
121
|
+
? parsed.projectId.trim()
|
|
122
|
+
: undefined,
|
|
117
123
|
apiKey: typeof parsed.apiKey === "string" ? parsed.apiKey : undefined,
|
|
118
124
|
oauth2ClientId: typeof parsed.oauth2ClientId === "string" ? parsed.oauth2ClientId : undefined,
|
|
119
125
|
auditOnly: parsed.auditOnly === true ? true : undefined,
|
|
120
126
|
permissionMode: parsePermissionMode(parsed.permissionMode),
|
|
127
|
+
userLogin: typeof parsed.userLogin === "boolean" ? parsed.userLogin : undefined,
|
|
128
|
+
userSubjectNamespace: typeof parsed.userSubjectNamespace === "string" && parsed.userSubjectNamespace.trim()
|
|
129
|
+
? parsed.userSubjectNamespace.trim()
|
|
130
|
+
: undefined,
|
|
121
131
|
user: parseUserCredentials(parsed),
|
|
122
132
|
agent: parseAgentCredentials(parsed),
|
|
123
133
|
};
|
|
@@ -129,6 +139,21 @@ function loadConfig() {
|
|
|
129
139
|
function parsePermissionMode(value) {
|
|
130
140
|
return value === "observe" || value === "enforce" ? value : undefined;
|
|
131
141
|
}
|
|
142
|
+
/** Env values that turn the interactive user login on. */
|
|
143
|
+
const USER_LOGIN_ENABLED_VALUES = new Set(["1", "true", "yes", "on"]);
|
|
144
|
+
/**
|
|
145
|
+
* Read `ORY_USER_LOGIN` from the environment. Returns `true`/`false` when
|
|
146
|
+
* the var is set (any recognized truthy value enables it; anything else
|
|
147
|
+
* disables it), or `undefined` when the var is absent/empty so callers
|
|
148
|
+
* fall back to the config file. Centralized here so the user gate, status
|
|
149
|
+
* CLI, and configure command resolve it identically.
|
|
150
|
+
*/
|
|
151
|
+
function parseUserLoginEnv() {
|
|
152
|
+
const raw = process.env.ORY_USER_LOGIN;
|
|
153
|
+
if (raw === undefined || raw.trim() === "")
|
|
154
|
+
return undefined;
|
|
155
|
+
return USER_LOGIN_ENABLED_VALUES.has(raw.trim().toLowerCase());
|
|
156
|
+
}
|
|
132
157
|
function parseAgentCredentials(parsed) {
|
|
133
158
|
const raw = parsed.agent;
|
|
134
159
|
if (!raw || typeof raw !== "object")
|
|
@@ -350,33 +375,84 @@ function writeConfigAtomic(config) {
|
|
|
350
375
|
fs.writeFileSync(tmp, JSON.stringify(config, null, 2) + "\n", { mode: 0o600 });
|
|
351
376
|
fs.renameSync(tmp, target);
|
|
352
377
|
}
|
|
378
|
+
/** Matches an Ory project UUID (the value `ORY_PROJECT_ID` carries). */
|
|
379
|
+
const PROJECT_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
380
|
+
/**
|
|
381
|
+
* True when `value` looks like an Ory project **id** (a UUID) rather than a
|
|
382
|
+
* project **slug**. Project slugs are human-readable tokens (e.g.
|
|
383
|
+
* `nervous-galileo-1a2b3c`) and are never UUIDs, so this cleanly distinguishes
|
|
384
|
+
* the two. Used to guard the SDK-URL derivation: the URL subdomain must be the
|
|
385
|
+
* slug — a project id must never be substituted for it (see
|
|
386
|
+
* {@link projectUrlFromSlug}). The id addresses project-scoped **admin** APIs
|
|
387
|
+
* (the `ory` CLI's `--project` flag), which is a different concern from the SDK
|
|
388
|
+
* base URL.
|
|
389
|
+
*/
|
|
390
|
+
function looksLikeProjectId(value) {
|
|
391
|
+
return PROJECT_ID_RE.test(value.trim());
|
|
392
|
+
}
|
|
353
393
|
/**
|
|
354
394
|
* Resolve config by checking environment variables first, then the config file.
|
|
355
395
|
* Returns the merged result with the source of each value.
|
|
396
|
+
*
|
|
397
|
+
* `projectUrl` accepts `ORY_SDK_URL` as an alias for `ORY_PROJECT_URL` (the two
|
|
398
|
+
* names the Console "Get Started" uses). The SDK URL is **always** slug-based;
|
|
399
|
+
* `projectId` (`ORY_PROJECT_ID`) is a distinct identifier for admin APIs and is
|
|
400
|
+
* never turned into an SDK URL — a project id is not a slug.
|
|
356
401
|
*/
|
|
357
402
|
function resolveConfig() {
|
|
358
403
|
const file = loadConfig();
|
|
359
|
-
|
|
404
|
+
// ORY_PROJECT_URL is the documented name; ORY_SDK_URL is the name the Ory
|
|
405
|
+
// Console "Get Started" panel and the Ory SDKs use — accepted as an alias.
|
|
406
|
+
const envProjectUrl = process.env.ORY_PROJECT_URL?.trim() || process.env.ORY_SDK_URL?.trim() || undefined;
|
|
407
|
+
const envProjectId = process.env.ORY_PROJECT_ID?.trim() || undefined;
|
|
360
408
|
// ORY_AGENT_API_KEY is the documented name; ORY_API_KEY is the deprecated
|
|
361
409
|
// alias kept for back-compat (agent-auth emits a warning when only the
|
|
362
410
|
// legacy form is set).
|
|
363
411
|
const envApiKey = process.env.ORY_AGENT_API_KEY ?? process.env.ORY_API_KEY;
|
|
364
412
|
const envClientId = process.env.ORY_OAUTH2_CLIENT_ID;
|
|
365
413
|
const envMode = parsePermissionMode(process.env.ORY_PERMISSION_MODE);
|
|
414
|
+
const envUserLogin = parseUserLoginEnv();
|
|
415
|
+
const envUserSubjectNamespace = process.env.ORY_USER_SUBJECT_NAMESPACE?.trim() || undefined;
|
|
366
416
|
const permissionMode = envMode ?? file.permissionMode ?? "observe";
|
|
367
417
|
const permissionModeSource = envMode
|
|
368
418
|
? "env"
|
|
369
419
|
: file.permissionMode
|
|
370
420
|
? "config"
|
|
371
421
|
: "default";
|
|
422
|
+
const userLogin = envUserLogin ?? file.userLogin ?? false;
|
|
423
|
+
const userLoginSource = envUserLogin !== undefined
|
|
424
|
+
? "env"
|
|
425
|
+
: file.userLogin !== undefined
|
|
426
|
+
? "config"
|
|
427
|
+
: "default";
|
|
428
|
+
const projectId = envProjectId ?? file.projectId;
|
|
429
|
+
// The SDK URL is only ever an explicit, slug-based URL (from ORY_PROJECT_URL,
|
|
430
|
+
// ORY_SDK_URL, or the config file). The project id is NOT a URL source — it
|
|
431
|
+
// addresses admin APIs, and its value is a UUID, not a slug.
|
|
432
|
+
const projectUrl = envProjectUrl ?? file.projectUrl;
|
|
433
|
+
const projectUrlSource = envProjectUrl
|
|
434
|
+
? "env"
|
|
435
|
+
: file.projectUrl
|
|
436
|
+
? "config"
|
|
437
|
+
: "none";
|
|
372
438
|
return {
|
|
373
|
-
projectUrl
|
|
439
|
+
projectUrl,
|
|
440
|
+
projectId,
|
|
374
441
|
apiKey: envApiKey ?? file.apiKey,
|
|
375
442
|
oauth2ClientId: envClientId ?? file.oauth2ClientId,
|
|
376
443
|
auditOnly: file.auditOnly === true,
|
|
377
444
|
permissionMode,
|
|
378
445
|
permissionModeSource,
|
|
379
|
-
|
|
446
|
+
userLogin,
|
|
447
|
+
userLoginSource,
|
|
448
|
+
userSubjectNamespace: envUserSubjectNamespace ?? file.userSubjectNamespace,
|
|
449
|
+
userSubjectNamespaceSource: envUserSubjectNamespace
|
|
450
|
+
? "env"
|
|
451
|
+
: file.userSubjectNamespace
|
|
452
|
+
? "config"
|
|
453
|
+
: "none",
|
|
454
|
+
projectUrlSource,
|
|
455
|
+
projectIdSource: envProjectId ? "env" : file.projectId ? "config" : "none",
|
|
380
456
|
apiKeySource: envApiKey ? "env" : file.apiKey ? "config" : "none",
|
|
381
457
|
oauth2ClientIdSource: envClientId ? "env" : file.oauth2ClientId ? "config" : "none",
|
|
382
458
|
};
|
|
@@ -388,10 +464,10 @@ function configPromptMessage(binName) {
|
|
|
388
464
|
return ("The Ory agent plugin is installed but not yet configured.\n" +
|
|
389
465
|
"\n" +
|
|
390
466
|
" Option 1 — Connect to Ory (enables authentication and permission checks):\n" +
|
|
391
|
-
`
|
|
467
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]\n` +
|
|
392
468
|
"\n" +
|
|
393
469
|
" Option 2 — Continue without authentication (audit logging only):\n" +
|
|
394
|
-
`
|
|
470
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --audit-only\n` +
|
|
395
471
|
"\n" +
|
|
396
472
|
`Configuration is saved to ${configFile()} and shared across all agent plugins.`);
|
|
397
473
|
}
|
package/dist/dev.d.ts
CHANGED
|
@@ -40,6 +40,14 @@ export interface DevLauncherConfig {
|
|
|
40
40
|
install(ctx: InstallContext): void;
|
|
41
41
|
/** Extra tip lines to print before launch */
|
|
42
42
|
extraTips?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Base args always passed to the harness binary at launch, prepended to any
|
|
45
|
+
* args forwarded from the dev-launcher CLI. Use for dev-only flags a plugin
|
|
46
|
+
* needs to exercise its hooks — e.g. Codex requires
|
|
47
|
+
* `--dangerously-bypass-hook-trust` so freshly installed (untrusted) plugin
|
|
48
|
+
* hooks run without the interactive trust prompt.
|
|
49
|
+
*/
|
|
50
|
+
launchArgs?: string[];
|
|
43
51
|
}
|
|
44
52
|
/**
|
|
45
53
|
* Parse the dev-launcher CLI args, splitting out launcher-only flags from the
|
package/dist/dev.js
CHANGED
|
@@ -259,6 +259,16 @@ async function runDevLauncher(config) {
|
|
|
259
259
|
if ((0, auth_store_js_1.clearPkceFlightLock)()) {
|
|
260
260
|
console.log("[ory-dev] Cleared stale PKCE flight lock from a previous run.");
|
|
261
261
|
}
|
|
262
|
+
// Local dev demonstrates the full interactive PKCE browser login on every
|
|
263
|
+
// launch. `buildLocalOryEnv` already clears env-supplied tokens, but a
|
|
264
|
+
// still-valid *persisted* token from a prior run would short-circuit
|
|
265
|
+
// `ensureUserAuthenticated` (mode "ok", "Re-using persisted access token")
|
|
266
|
+
// so no browser prompt appears. Drop persisted user tokens too, so each
|
|
267
|
+
// local launch reliably fires the login. Runs only in local-Ory mode — when
|
|
268
|
+
// pointed at a real project (`ORY_DEV_LOCAL=0`), persisted tokens are kept.
|
|
269
|
+
if (localEnabled) {
|
|
270
|
+
(0, auth_store_js_1.clearTokens)();
|
|
271
|
+
}
|
|
262
272
|
assertNpmAvailable();
|
|
263
273
|
console.log(`[ory-dev] Ensuring local npm registry is running...`);
|
|
264
274
|
await (0, manager_js_1.ensureRegistryRunning)();
|
|
@@ -325,7 +335,8 @@ async function runDevLauncher(config) {
|
|
|
325
335
|
? buildOtelEnv(otelEndpoint, config.harnessName)
|
|
326
336
|
: {}),
|
|
327
337
|
};
|
|
328
|
-
const
|
|
338
|
+
const launchArgs = [...(config.launchArgs ?? []), ...forwardedArgs];
|
|
339
|
+
const result = (0, node_child_process_1.spawnSync)(config.command, launchArgs, {
|
|
329
340
|
cwd: sandbox,
|
|
330
341
|
stdio: "inherit",
|
|
331
342
|
env,
|
package/dist/index.d.ts
CHANGED
|
@@ -5,12 +5,15 @@ export { loadConfig, saveConfig, resolveConfig, mutateConfig, getConfigPath, get
|
|
|
5
5
|
export { pkceLogin, refreshAccessToken, detectHeadless, generateCodeVerifier, sha256Base64Url, buildAuthorizeUrl, LOOPBACK_PORTS, DEFAULT_LOGIN_TIMEOUT_MS, type PkceLoginOptions, type PkceLoginOutcome, type PkceDeclineReason, } from "./auth.js";
|
|
6
6
|
export { loadTokens, saveTokens, clearTokens, isExpired, refreshAndSave, tryAcquirePkceFlightLock, clearPkceFlightLock, waitForPeerTokens, waitForPeerTokensSync, TOKEN_EXPIRY_SKEW_SEC, type PkceFlightLock, } from "./auth-store.js";
|
|
7
7
|
export { ensureUserAuthenticated, ensureAuthenticated, type UserLoginDecision, type UserLoginMode, type UserLoginOptions, } from "./user-login.js";
|
|
8
|
-
export { resolveAgentCredentials, ensureAgentIdentity, ensureSubAgentIdentity, fetchClientCredentialsToken, registerAgentClient, loadAgentDynamicCredentials, saveAgentDynamicCredentials, clearAgentDynamicCredentials, loadSubAgentDynamicCredentials, saveSubAgentDynamicCredentials, clearSubAgentDynamicCredentials, AGENT_TOKEN_EXPIRY_SKEW_SEC, type AgentCredentials, type AgentCredentialKind, type ResolveAgentCredentialsOptions, type EnsureAgentIdentityOptions, type RegisterAgentClientArgs, type SubAgentIdentity, type EnsureSubAgentIdentityOptions, } from "./agent-auth.js";
|
|
8
|
+
export { resolveAgentCredentials, ensureAgentIdentity, ensureSubAgentIdentity, fetchClientCredentialsToken, registerAgentClient, loadAgentDynamicCredentials, saveAgentDynamicCredentials, clearAgentDynamicCredentials, loadSubAgentDynamicCredentials, saveSubAgentDynamicCredentials, clearSubAgentDynamicCredentials, revokeAgentDynamicClient, AGENT_TOKEN_EXPIRY_SKEW_SEC, type AgentCredentials, type AgentCredentialKind, type ResolveAgentCredentialsOptions, type EnsureAgentIdentityOptions, type RegisterAgentClientArgs, type RevokeAgentClientResult, type SubAgentIdentity, type EnsureSubAgentIdentityOptions, } from "./agent-auth.js";
|
|
9
|
+
export { clearCredentialsForUninstall, type ClearCredentialsOptions, type ClearCredentialsResult, } from "./uninstall.js";
|
|
9
10
|
export { type SessionInfo, type OAuth2TokenInfo, type PermissionCheck, type PermissionResult, type BatchPermissionResult, type OryError, type OryErrorCode, } from "./types.js";
|
|
10
11
|
export { runConfigureCommand, runAgentCommand, printOryConfig, printEnvironment, printLogTail, printEnvHelp, printTraceTail, runWatchCommand, isTtyAvailable, promptOnTty, promptForProjectUrl, interactiveConfigPrompt, } from "./cli.js";
|
|
12
|
+
export { oryNpx } from "./cli-invocation.js";
|
|
11
13
|
export { runPermissionsCommand, isUserIdentityCached, maybeAutoBootstrap, printPermissionsOnboardingHelp, } from "./permissions-cli.js";
|
|
14
|
+
export { runInteractiveSetup, runPostInstall, projectUrlFromSlug, LOOPBACK_REDIRECT_URIS, type OryCliRunner, type OryExecResult, type InteractiveSetupDeps, type InteractiveSetupOutcome, type InteractiveSetupResult, } from "./interactive-setup.js";
|
|
12
15
|
export { runStatusCommand, printUserIdentitySection, printAgentIdentitySection, printPermissionsSection, type StatusCommandOptions, } from "./status-cli.js";
|
|
13
|
-
export { parseSetupArgs, readJsonFile, writeJsonFile, isOryHookCommand, resolveHookCommand, matcherHookEntry, mergeMatcherHooks, removeMatcherHooks, flatHookEntry, mergeFlatHooks, removeFlatHooks, printSetupHelp, printNextSteps, resolveMcpServerCommand, mcpServerEntry, mergeMcpServer, removeMcpServer, registerPlugin, unregisterPlugin, type SetupArgs, type HookCommand, type MatcherEntry, } from "./setup.js";
|
|
16
|
+
export { parseSetupArgs, readJsonFile, writeJsonFile, isOryHookCommand, resolveHookCommand, matcherHookEntry, mergeMatcherHooks, removeMatcherHooks, flatHookEntry, mergeFlatHooks, removeFlatHooks, printSetupHelp, printNextSteps, nextStepsSink, beginDeferNextSteps, emitDeferredNextSteps, resolveMcpServerCommand, mcpServerEntry, mergeMcpServer, removeMcpServer, registerPlugin, unregisterPlugin, type SetupArgs, type HookCommand, type MatcherEntry, } from "./setup.js";
|
|
14
17
|
export { runDevLauncher, type DevLauncherConfig, type InstallContext, } from "./dev.js";
|
|
15
18
|
export { renderOrySkills, renderOryCommands, commandToSkill, commandToToml, commandToFrontmatterMarkdown, commandToPlainMarkdown, toSkillMarkdown, writeSkillTree, removeSkillDirs, ORY_SKILL_NAMES, ORY_COMMAND_SKILL_NAMES, ORY_COMMAND_SLUGS, type RenderedSkill, type RenderedCommand, type RenderProfileOptions, } from "./skills.js";
|
|
16
19
|
export { runLocalCommand, ensureDevJaeger, stopDevJaeger, DEV_JAEGER_CONTAINER, type EnsureDevJaegerResult, type StopDevJaegerResult, } from "./local/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
3
|
+
exports.runConfigureCommand = exports.clearCredentialsForUninstall = exports.AGENT_TOKEN_EXPIRY_SKEW_SEC = exports.revokeAgentDynamicClient = exports.clearSubAgentDynamicCredentials = exports.saveSubAgentDynamicCredentials = exports.loadSubAgentDynamicCredentials = exports.clearAgentDynamicCredentials = exports.saveAgentDynamicCredentials = exports.loadAgentDynamicCredentials = exports.registerAgentClient = exports.fetchClientCredentialsToken = exports.ensureSubAgentIdentity = exports.ensureAgentIdentity = exports.resolveAgentCredentials = exports.ensureAuthenticated = exports.ensureUserAuthenticated = exports.TOKEN_EXPIRY_SKEW_SEC = exports.waitForPeerTokensSync = exports.waitForPeerTokens = exports.clearPkceFlightLock = exports.tryAcquirePkceFlightLock = exports.refreshAndSave = exports.isExpired = exports.clearTokens = exports.saveTokens = exports.loadTokens = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.LOOPBACK_PORTS = exports.buildAuthorizeUrl = exports.sha256Base64Url = exports.generateCodeVerifier = exports.detectHeadless = exports.refreshAccessToken = exports.pkceLogin = exports.getHarnessDataDir = exports.getDataDir = exports.getConfigPath = exports.mutateConfig = exports.resolveConfig = exports.saveConfig = exports.loadConfig = exports.watchTraceFile = exports.formatSpan = exports.deriveTraceId = exports.ActiveSpan = exports.Tracer = exports.redactLogData = exports.DebugLogger = exports.OryAgentClient = void 0;
|
|
4
|
+
exports.commandToSkill = exports.renderOryCommands = exports.renderOrySkills = exports.runDevLauncher = exports.unregisterPlugin = exports.registerPlugin = exports.removeMcpServer = exports.mergeMcpServer = exports.mcpServerEntry = exports.resolveMcpServerCommand = exports.emitDeferredNextSteps = exports.beginDeferNextSteps = exports.nextStepsSink = exports.printNextSteps = exports.printSetupHelp = exports.removeFlatHooks = exports.mergeFlatHooks = exports.flatHookEntry = exports.removeMatcherHooks = exports.mergeMatcherHooks = exports.matcherHookEntry = exports.resolveHookCommand = exports.isOryHookCommand = exports.writeJsonFile = exports.readJsonFile = exports.parseSetupArgs = exports.printPermissionsSection = exports.printAgentIdentitySection = exports.printUserIdentitySection = exports.runStatusCommand = exports.LOOPBACK_REDIRECT_URIS = exports.projectUrlFromSlug = exports.runPostInstall = exports.runInteractiveSetup = exports.printPermissionsOnboardingHelp = exports.maybeAutoBootstrap = exports.isUserIdentityCached = exports.runPermissionsCommand = exports.oryNpx = exports.interactiveConfigPrompt = exports.promptForProjectUrl = exports.promptOnTty = exports.isTtyAvailable = exports.runWatchCommand = exports.printTraceTail = exports.printEnvHelp = exports.printLogTail = exports.printEnvironment = exports.printOryConfig = exports.runAgentCommand = void 0;
|
|
5
|
+
exports.sessionStart = exports.resolveNamespace = exports.parseKeyValueList = exports.otlpExporterFromEnv = exports.OtlpExporter = exports.summarizeToolOutput = exports.summarizeToolInput = exports.OryDenialError = exports.alertAttributes = exports.formatAlertSummary = exports.formatAlertMessage = exports.formatDenialSummary = exports.formatDenialMessage = exports.subjectLabel = exports.runWithUserSubject = exports.resolveUserSubject = exports.checkMcpPermission = exports.parseMcpToolGeneric = exports.parseGeminiMcpTool = exports.parseClaudeCodeMcpTool = exports.TOOL_EXECUTION_PHASES = exports.USER_FACING_PHASES = exports.HARNESS_LIFECYCLE_MAP = exports.isToolExecutionPhase = exports.isUserFacingPhase = exports.classifyLifecycle = exports.isInteractiveTool = exports.getInteractiveToolCatalog = exports.INTERACTIVE_TOOL_CATALOG = exports.getToolCatalog = exports.ALL_TOOLS = exports.KNOWN_HARNESSES = exports.HARNESS_TOOL_CATALOG = exports.gateToolCall = exports.applyPermissionMode = exports.checkAndDecide = exports.runRegistryCommand = exports.DEV_JAEGER_CONTAINER = exports.stopDevJaeger = exports.ensureDevJaeger = exports.runLocalCommand = exports.ORY_COMMAND_SLUGS = exports.ORY_COMMAND_SKILL_NAMES = exports.ORY_SKILL_NAMES = exports.removeSkillDirs = exports.writeSkillTree = exports.toSkillMarkdown = exports.commandToPlainMarkdown = exports.commandToFrontmatterMarkdown = exports.commandToToml = void 0;
|
|
6
|
+
exports.wrapTool = exports.registerSubagent = exports.complete = exports.gate = void 0;
|
|
6
7
|
var client_js_1 = require("./client.js");
|
|
7
8
|
Object.defineProperty(exports, "OryAgentClient", { enumerable: true, get: function () { return client_js_1.OryAgentClient; } });
|
|
8
9
|
var logger_js_1 = require("./logger.js");
|
|
@@ -57,7 +58,10 @@ Object.defineProperty(exports, "clearAgentDynamicCredentials", { enumerable: tru
|
|
|
57
58
|
Object.defineProperty(exports, "loadSubAgentDynamicCredentials", { enumerable: true, get: function () { return agent_auth_js_1.loadSubAgentDynamicCredentials; } });
|
|
58
59
|
Object.defineProperty(exports, "saveSubAgentDynamicCredentials", { enumerable: true, get: function () { return agent_auth_js_1.saveSubAgentDynamicCredentials; } });
|
|
59
60
|
Object.defineProperty(exports, "clearSubAgentDynamicCredentials", { enumerable: true, get: function () { return agent_auth_js_1.clearSubAgentDynamicCredentials; } });
|
|
61
|
+
Object.defineProperty(exports, "revokeAgentDynamicClient", { enumerable: true, get: function () { return agent_auth_js_1.revokeAgentDynamicClient; } });
|
|
60
62
|
Object.defineProperty(exports, "AGENT_TOKEN_EXPIRY_SKEW_SEC", { enumerable: true, get: function () { return agent_auth_js_1.AGENT_TOKEN_EXPIRY_SKEW_SEC; } });
|
|
63
|
+
var uninstall_js_1 = require("./uninstall.js");
|
|
64
|
+
Object.defineProperty(exports, "clearCredentialsForUninstall", { enumerable: true, get: function () { return uninstall_js_1.clearCredentialsForUninstall; } });
|
|
61
65
|
var cli_js_1 = require("./cli.js");
|
|
62
66
|
Object.defineProperty(exports, "runConfigureCommand", { enumerable: true, get: function () { return cli_js_1.runConfigureCommand; } });
|
|
63
67
|
Object.defineProperty(exports, "runAgentCommand", { enumerable: true, get: function () { return cli_js_1.runAgentCommand; } });
|
|
@@ -71,11 +75,18 @@ Object.defineProperty(exports, "isTtyAvailable", { enumerable: true, get: functi
|
|
|
71
75
|
Object.defineProperty(exports, "promptOnTty", { enumerable: true, get: function () { return cli_js_1.promptOnTty; } });
|
|
72
76
|
Object.defineProperty(exports, "promptForProjectUrl", { enumerable: true, get: function () { return cli_js_1.promptForProjectUrl; } });
|
|
73
77
|
Object.defineProperty(exports, "interactiveConfigPrompt", { enumerable: true, get: function () { return cli_js_1.interactiveConfigPrompt; } });
|
|
78
|
+
var cli_invocation_js_1 = require("./cli-invocation.js");
|
|
79
|
+
Object.defineProperty(exports, "oryNpx", { enumerable: true, get: function () { return cli_invocation_js_1.oryNpx; } });
|
|
74
80
|
var permissions_cli_js_1 = require("./permissions-cli.js");
|
|
75
81
|
Object.defineProperty(exports, "runPermissionsCommand", { enumerable: true, get: function () { return permissions_cli_js_1.runPermissionsCommand; } });
|
|
76
82
|
Object.defineProperty(exports, "isUserIdentityCached", { enumerable: true, get: function () { return permissions_cli_js_1.isUserIdentityCached; } });
|
|
77
83
|
Object.defineProperty(exports, "maybeAutoBootstrap", { enumerable: true, get: function () { return permissions_cli_js_1.maybeAutoBootstrap; } });
|
|
78
84
|
Object.defineProperty(exports, "printPermissionsOnboardingHelp", { enumerable: true, get: function () { return permissions_cli_js_1.printPermissionsOnboardingHelp; } });
|
|
85
|
+
var interactive_setup_js_1 = require("./interactive-setup.js");
|
|
86
|
+
Object.defineProperty(exports, "runInteractiveSetup", { enumerable: true, get: function () { return interactive_setup_js_1.runInteractiveSetup; } });
|
|
87
|
+
Object.defineProperty(exports, "runPostInstall", { enumerable: true, get: function () { return interactive_setup_js_1.runPostInstall; } });
|
|
88
|
+
Object.defineProperty(exports, "projectUrlFromSlug", { enumerable: true, get: function () { return interactive_setup_js_1.projectUrlFromSlug; } });
|
|
89
|
+
Object.defineProperty(exports, "LOOPBACK_REDIRECT_URIS", { enumerable: true, get: function () { return interactive_setup_js_1.LOOPBACK_REDIRECT_URIS; } });
|
|
79
90
|
var status_cli_js_1 = require("./status-cli.js");
|
|
80
91
|
Object.defineProperty(exports, "runStatusCommand", { enumerable: true, get: function () { return status_cli_js_1.runStatusCommand; } });
|
|
81
92
|
Object.defineProperty(exports, "printUserIdentitySection", { enumerable: true, get: function () { return status_cli_js_1.printUserIdentitySection; } });
|
|
@@ -95,6 +106,9 @@ Object.defineProperty(exports, "mergeFlatHooks", { enumerable: true, get: functi
|
|
|
95
106
|
Object.defineProperty(exports, "removeFlatHooks", { enumerable: true, get: function () { return setup_js_1.removeFlatHooks; } });
|
|
96
107
|
Object.defineProperty(exports, "printSetupHelp", { enumerable: true, get: function () { return setup_js_1.printSetupHelp; } });
|
|
97
108
|
Object.defineProperty(exports, "printNextSteps", { enumerable: true, get: function () { return setup_js_1.printNextSteps; } });
|
|
109
|
+
Object.defineProperty(exports, "nextStepsSink", { enumerable: true, get: function () { return setup_js_1.nextStepsSink; } });
|
|
110
|
+
Object.defineProperty(exports, "beginDeferNextSteps", { enumerable: true, get: function () { return setup_js_1.beginDeferNextSteps; } });
|
|
111
|
+
Object.defineProperty(exports, "emitDeferredNextSteps", { enumerable: true, get: function () { return setup_js_1.emitDeferredNextSteps; } });
|
|
98
112
|
Object.defineProperty(exports, "resolveMcpServerCommand", { enumerable: true, get: function () { return setup_js_1.resolveMcpServerCommand; } });
|
|
99
113
|
Object.defineProperty(exports, "mcpServerEntry", { enumerable: true, get: function () { return setup_js_1.mcpServerEntry; } });
|
|
100
114
|
Object.defineProperty(exports, "mergeMcpServer", { enumerable: true, get: function () { return setup_js_1.mergeMcpServer; } });
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive install wizard. Runs after a harness plugin has been
|
|
3
|
+
* registered, stepping the user through connecting the plugin to Ory:
|
|
4
|
+
*
|
|
5
|
+
* 1. Choose a connection: **Ory Network** (browser login / account
|
|
6
|
+
* creation) or **local / audit-only** (no project, audit logging only).
|
|
7
|
+
* 2. Ory Network branch: shell out to the official `ory` CLI to log in,
|
|
8
|
+
* pick a workspace, pick a project (→ `projectUrl`), and create the
|
|
9
|
+
* public OAuth2 client the PKCE user login needs (→ `oauth2ClientId`).
|
|
10
|
+
* 3. Persist the resolved values to the shared config file and enable the
|
|
11
|
+
* interactive user login.
|
|
12
|
+
* 4. Best-effort "full setup": run the PKCE user login now (we hold the
|
|
13
|
+
* project URL + client id), resolve the agent DCR identity, and let the
|
|
14
|
+
* caller bootstrap permissions from the freshly-cached user identity.
|
|
15
|
+
*
|
|
16
|
+
* The whole wizard is **fail-open and skippable**: on a missing TTY, a
|
|
17
|
+
* `--no-configure` flag, an already-configured plugin (without
|
|
18
|
+
* `--reconfigure`), a missing `ory` CLI, or any `ory` failure it prints the
|
|
19
|
+
* manual `configure` instructions and returns without throwing. Install must
|
|
20
|
+
* never crash because setup was declined or the network was unreachable.
|
|
21
|
+
*
|
|
22
|
+
* The Ory Network integration deliberately reuses the official `ory` CLI
|
|
23
|
+
* rather than re-implementing the Console API: the CLI already owns Network
|
|
24
|
+
* browser login + account creation, workspace/project listing, and OAuth2
|
|
25
|
+
* client creation, and the client it creates is exactly the one the plugin
|
|
26
|
+
* READMEs document for manual setup.
|
|
27
|
+
*/
|
|
28
|
+
import { OryAgentClient } from "./client.js";
|
|
29
|
+
import { ensureUserAuthenticated } from "./user-login.js";
|
|
30
|
+
import { ensureAgentIdentity } from "./agent-auth.js";
|
|
31
|
+
import { ensureLocalOryStack, seedLocalEnvironment } from "./local/index.js";
|
|
32
|
+
/** Loopback redirect URIs the PKCE user login expects on the OAuth2 client. */
|
|
33
|
+
export declare const LOOPBACK_REDIRECT_URIS: readonly string[];
|
|
34
|
+
/** Result of running a captured `ory` command. */
|
|
35
|
+
export interface OryExecResult {
|
|
36
|
+
/** Exit code; `null` when the process could not be spawned (CLI missing). */
|
|
37
|
+
status: number | null;
|
|
38
|
+
stdout: string;
|
|
39
|
+
stderr: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Thin, injectable wrapper around the `ory` binary. Tests stub this to drive
|
|
43
|
+
* the wizard without a real CLI; the default implementation shells out.
|
|
44
|
+
*/
|
|
45
|
+
export interface OryCliRunner {
|
|
46
|
+
/** Run `ory <args>` capturing stdout/stderr. `opts.input` is written to
|
|
47
|
+
* the child's stdin (used to feed JSON to `ory create relationships -f -`). */
|
|
48
|
+
exec(args: string[], opts?: {
|
|
49
|
+
input?: string;
|
|
50
|
+
}): OryExecResult;
|
|
51
|
+
/** Run `ory <args>` inheriting the terminal (for the browser login). */
|
|
52
|
+
execInteractive(args: string[]): number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a runner bound to a specific `ory` binary (a bare command resolved on
|
|
56
|
+
* `PATH`, or an absolute path to a plugin-installed binary). {@link defaultRunner}
|
|
57
|
+
* uses the bare `"ory"`; {@link installOryCli} returns one bound to the binary
|
|
58
|
+
* it just installed.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createOryRunner(oryBin: string): OryCliRunner;
|
|
61
|
+
/**
|
|
62
|
+
* npm spec for the Ory CLI installed on demand when the `ory` binary isn't on
|
|
63
|
+
* `PATH`. `@ory/cli` ships the platform `ory` binary and exposes it as its
|
|
64
|
+
* `bin`, so an isolated `npm install` gives us a working CLI without touching
|
|
65
|
+
* the user's global environment. Pinned to a major to stay reproducible while
|
|
66
|
+
* still picking up patch/minor fixes.
|
|
67
|
+
*/
|
|
68
|
+
export declare const ORY_CLI_NPM_SPEC = "@ory/cli@^1";
|
|
69
|
+
export interface InteractiveSetupDeps {
|
|
70
|
+
runner?: OryCliRunner;
|
|
71
|
+
isTtyAvailableFn?: () => boolean;
|
|
72
|
+
promptFn?: (prompt: string) => Promise<string | null>;
|
|
73
|
+
clientFactory?: (harness: string) => OryAgentClient;
|
|
74
|
+
userLoginFn?: typeof ensureUserAuthenticated;
|
|
75
|
+
agentGateFn?: typeof ensureAgentIdentity;
|
|
76
|
+
/** Injectable local-stack bring-up (defaults to {@link ensureLocalOryStack}). */
|
|
77
|
+
localStackFn?: typeof ensureLocalOryStack;
|
|
78
|
+
/** Injectable local-stack seeder (defaults to {@link seedLocalEnvironment}). */
|
|
79
|
+
seedFn?: typeof seedLocalEnvironment;
|
|
80
|
+
/**
|
|
81
|
+
* Injectable Ory-CLI installer used when the `ory` binary isn't on `PATH`.
|
|
82
|
+
* Returns a runner bound to the installed binary, or null if the install
|
|
83
|
+
* failed. Defaults to a real `npm install` of {@link ORY_CLI_NPM_SPEC}.
|
|
84
|
+
*/
|
|
85
|
+
installOryCliFn?: () => Promise<OryCliRunner | null>;
|
|
86
|
+
}
|
|
87
|
+
export type InteractiveSetupOutcome = "skipped_flag" | "skipped_no_tty" | "skipped_configured" | "audit_only" | "local_configured" | "network_configured" | "network_fallback";
|
|
88
|
+
export interface InteractiveSetupResult {
|
|
89
|
+
outcome: InteractiveSetupOutcome;
|
|
90
|
+
projectUrl?: string;
|
|
91
|
+
oauth2ClientId?: string;
|
|
92
|
+
/** Whether a user identity was authenticated during the wizard. */
|
|
93
|
+
userAuthenticated?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* When true, the caller should NOT run the DCR-token-based
|
|
96
|
+
* {@link maybeAutoBootstrap}. The wizard bootstraps permissions itself via
|
|
97
|
+
* the admin-authenticated `ory` CLI on the Ory Network path — the runtime
|
|
98
|
+
* agent/user tokens can't write relation tuples on a hosted project, so
|
|
99
|
+
* running maybeAutoBootstrap there would only produce 403s.
|
|
100
|
+
*/
|
|
101
|
+
skipAutoBootstrap?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The shared post-install entry point every harness's `install` command
|
|
105
|
+
* calls. Runs the interactive setup wizard, then (using whatever identity the
|
|
106
|
+
* wizard cached) bootstraps permissions and prints the onboarding banner.
|
|
107
|
+
*
|
|
108
|
+
* This is the single seam that centralizes what each harness previously
|
|
109
|
+
* open-coded as a local `postInstallPermissions` helper.
|
|
110
|
+
*/
|
|
111
|
+
export declare function runPostInstall(binName: string, harness: string, args?: string[], deps?: InteractiveSetupDeps): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Run the interactive setup wizard. Always resolves; never throws.
|
|
114
|
+
*/
|
|
115
|
+
export declare function runInteractiveSetup(binName: string, harness: string, args?: string[], deps?: InteractiveSetupDeps): Promise<InteractiveSetupResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Derive the canonical Ory Network project SDK/API URL from a project **slug**.
|
|
118
|
+
* The subdomain is always the slug — never the project id. A project id (a
|
|
119
|
+
* UUID) reaching here means a slug and an id were confused upstream, which
|
|
120
|
+
* would build a URL that points nowhere, so we refuse it loudly rather than
|
|
121
|
+
* silently misconfigure the plugin.
|
|
122
|
+
*/
|
|
123
|
+
export declare function projectUrlFromSlug(slug: string): string;
|