@ory/argus 0.11.0 → 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/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
- const envProjectUrl = process.env.ORY_PROJECT_URL;
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: envProjectUrl ?? file.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
- projectUrlSource: envProjectUrl ? "env" : file.projectUrl ? "config" : "none",
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
- ` npx ${binName} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]\n` +
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
- ` npx ${binName} configure --audit-only\n` +
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 result = (0, node_child_process_1.spawnSync)(config.command, forwardedArgs, {
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.printOryConfig = exports.runAgentCommand = exports.runConfigureCommand = exports.AGENT_TOKEN_EXPIRY_SKEW_SEC = 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.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 = exports.commandToSkill = exports.renderOryCommands = exports.renderOrySkills = exports.runDevLauncher = exports.unregisterPlugin = exports.registerPlugin = exports.removeMcpServer = exports.mergeMcpServer = exports.mcpServerEntry = exports.resolveMcpServerCommand = 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.printPermissionsOnboardingHelp = exports.maybeAutoBootstrap = exports.isUserIdentityCached = exports.runPermissionsCommand = exports.interactiveConfigPrompt = exports.promptForProjectUrl = exports.promptOnTty = exports.isTtyAvailable = exports.runWatchCommand = exports.printTraceTail = exports.printEnvHelp = exports.printLogTail = exports.printEnvironment = void 0;
5
- exports.wrapTool = exports.registerSubagent = exports.complete = exports.gate = 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 = void 0;
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;