@ory/argus 0.1.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.
Files changed (80) hide show
  1. package/README.md +134 -0
  2. package/assets/commands/local-down.md +19 -0
  3. package/assets/commands/local-up.md +27 -0
  4. package/assets/skills/auth-setup/SKILL.md +279 -0
  5. package/assets/skills/local-dev/SKILL.md +206 -0
  6. package/assets/skills/login-flow/SKILL.md +383 -0
  7. package/assets/skills/social-login/SKILL.md +312 -0
  8. package/dist/agent-auth.d.ts +204 -0
  9. package/dist/agent-auth.js +553 -0
  10. package/dist/auth-gate.d.ts +71 -0
  11. package/dist/auth-gate.js +308 -0
  12. package/dist/auth-store.d.ts +75 -0
  13. package/dist/auth-store.js +261 -0
  14. package/dist/auth.d.ts +93 -0
  15. package/dist/auth.js +323 -0
  16. package/dist/cli.d.ts +73 -0
  17. package/dist/cli.js +484 -0
  18. package/dist/client.d.ts +158 -0
  19. package/dist/client.js +679 -0
  20. package/dist/config.d.ts +135 -0
  21. package/dist/config.js +344 -0
  22. package/dist/denial.d.ts +79 -0
  23. package/dist/denial.js +103 -0
  24. package/dist/dev.d.ts +95 -0
  25. package/dist/dev.js +514 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +137 -0
  28. package/dist/local/cli.d.ts +12 -0
  29. package/dist/local/cli.js +95 -0
  30. package/dist/local/configs.d.ts +89 -0
  31. package/dist/local/configs.js +634 -0
  32. package/dist/local/health.d.ts +32 -0
  33. package/dist/local/health.js +65 -0
  34. package/dist/local/index.d.ts +6 -0
  35. package/dist/local/index.js +38 -0
  36. package/dist/local/jaeger-main.d.ts +13 -0
  37. package/dist/local/jaeger-main.js +85 -0
  38. package/dist/local/jaeger.d.ts +50 -0
  39. package/dist/local/jaeger.js +162 -0
  40. package/dist/local/main.d.ts +7 -0
  41. package/dist/local/main.js +14 -0
  42. package/dist/local/manager.d.ts +45 -0
  43. package/dist/local/manager.js +676 -0
  44. package/dist/local/seed.d.ts +71 -0
  45. package/dist/local/seed.js +237 -0
  46. package/dist/logger.d.ts +29 -0
  47. package/dist/logger.js +139 -0
  48. package/dist/mcp.d.ts +76 -0
  49. package/dist/mcp.js +122 -0
  50. package/dist/otel/exporter.d.ts +17 -0
  51. package/dist/otel/exporter.js +12 -0
  52. package/dist/otel/index.d.ts +2 -0
  53. package/dist/otel/index.js +8 -0
  54. package/dist/otel/otlp-http.d.ts +116 -0
  55. package/dist/otel/otlp-http.js +322 -0
  56. package/dist/registry/cli.d.ts +12 -0
  57. package/dist/registry/cli.js +76 -0
  58. package/dist/registry/config.d.ts +23 -0
  59. package/dist/registry/config.js +80 -0
  60. package/dist/registry/index.d.ts +3 -0
  61. package/dist/registry/index.js +21 -0
  62. package/dist/registry/main.d.ts +7 -0
  63. package/dist/registry/main.js +14 -0
  64. package/dist/registry/manager.d.ts +38 -0
  65. package/dist/registry/manager.js +674 -0
  66. package/dist/setup.d.ts +118 -0
  67. package/dist/setup.js +398 -0
  68. package/dist/skills.d.ts +78 -0
  69. package/dist/skills.js +264 -0
  70. package/dist/subject.d.ts +43 -0
  71. package/dist/subject.js +55 -0
  72. package/dist/tool-metadata.d.ts +41 -0
  73. package/dist/tool-metadata.js +127 -0
  74. package/dist/tracer.d.ts +172 -0
  75. package/dist/tracer.js +452 -0
  76. package/dist/types.d.ts +57 -0
  77. package/dist/types.js +3 -0
  78. package/dist/watch-sandbox.d.ts +9 -0
  79. package/dist/watch-sandbox.js +81 -0
  80. package/package.json +79 -0
package/dist/auth.d.ts ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Browser-based OAuth2 PKCE login for Ory agent plugins.
3
+ *
4
+ * Spins up a transient localhost callback server on a fixed-port range
5
+ * (option (a) — operators register the same loopback URIs once with the
6
+ * Ory OAuth2 client), generates a PKCE verifier/challenge, launches the
7
+ * user's browser at the project's authorize URL, and exchanges the
8
+ * resulting code for a token set via /oauth2/token.
9
+ *
10
+ * This module never writes to stdout. Browser launching uses the `open`
11
+ * package via dynamic import so the CJS-emitted core stays compatible
12
+ * with its ESM-only export shape.
13
+ */
14
+ import { OryOAuth2Tokens } from "./config.js";
15
+ /** Loopback ports tried in order. All must be registered as redirect URIs on the Ory OAuth2 client. */
16
+ export declare const LOOPBACK_PORTS: readonly [47823, 47824, 47825, 47826];
17
+ /** Hard timeout if the user never returns to the browser. */
18
+ export declare const DEFAULT_LOGIN_TIMEOUT_MS = 120000;
19
+ export interface PkceLoginOptions {
20
+ /** Ory project URL (e.g. https://your-project.projects.oryapis.com). */
21
+ projectUrl: string;
22
+ /** Public OAuth2 client id registered with the loopback redirect URIs. */
23
+ clientId: string;
24
+ /** Scopes to request. Defaults to `openid offline_access`. */
25
+ scope?: string;
26
+ /** Audience to request, if any. */
27
+ audience?: string;
28
+ /** Login timeout in ms. Defaults to {@link DEFAULT_LOGIN_TIMEOUT_MS}. */
29
+ timeoutMs?: number;
30
+ /** Override the loopback port list (mostly for testing). */
31
+ ports?: ReadonlyArray<number>;
32
+ /** Hook for opening the browser. Defaults to the `open` npm package. */
33
+ openBrowser?: (url: string) => Promise<void>;
34
+ /** Override headless detection (mostly for testing). */
35
+ isHeadless?: () => boolean;
36
+ /** Optional AbortSignal to cancel the login (e.g. on shutdown). */
37
+ signal?: AbortSignal;
38
+ }
39
+ export type PkceLoginOutcome = {
40
+ kind: "ok";
41
+ tokens: OryOAuth2Tokens;
42
+ } | {
43
+ kind: "declined";
44
+ reason: PkceDeclineReason;
45
+ };
46
+ export type PkceDeclineReason = "headless" | "timeout" | "user_denied" | "state_mismatch" | "no_port" | "browser_launch_failed" | "aborted" | "token_exchange_failed";
47
+ /**
48
+ * Default headless heuristic. Returns true only for unattended runs
49
+ * (CI=true / CI=1) so {@link pkceLogin} can short-circuit instead of
50
+ * waiting on a callback that will never arrive.
51
+ *
52
+ * Heuristics like `SSH_TTY` and "Linux without DISPLAY" used to live here
53
+ * but turned out to be wrong in practice: an SSH user can paste the
54
+ * printed authorize URL into their workstation browser, and a Linux box
55
+ * without a display still works as long as the operator can reach the
56
+ * loopback callback port (e.g. via `ssh -L`). The PKCE flow always
57
+ * prints the URL to stderr, so anything short of "no human at all" is
58
+ * recoverable.
59
+ */
60
+ export declare function detectHeadless(env?: NodeJS.ProcessEnv): boolean;
61
+ /**
62
+ * Run a PKCE login and return either a token set or the reason the flow
63
+ * could not complete. The function never throws on user-driven failures
64
+ * (timeout, decline, headless); it throws only on programmer error or
65
+ * unrecoverable I/O failures.
66
+ */
67
+ export declare function pkceLogin(options: PkceLoginOptions): Promise<PkceLoginOutcome>;
68
+ /** Generate a 64-byte (≈86-char base64url) code verifier per RFC 7636. */
69
+ export declare function generateCodeVerifier(): string;
70
+ /** SHA-256 + base64url, the only supported PKCE challenge method (`S256`). */
71
+ export declare function sha256Base64Url(input: string): string;
72
+ export declare function buildAuthorizeUrl(params: {
73
+ projectUrl: string;
74
+ clientId: string;
75
+ redirectUri: string;
76
+ state: string;
77
+ codeChallenge: string;
78
+ scope: string;
79
+ audience?: string;
80
+ }): string;
81
+ /**
82
+ * Refresh an access token using a refresh token. Throws on any non-2xx
83
+ * response so callers can decide whether to fall back to a fresh login.
84
+ *
85
+ * Kept as raw fetch for parity with the other two /oauth2/token flows;
86
+ * see `exchangeCodeForTokens` and `fetchClientCredentialsToken` for why
87
+ * @ory/client's OAuth2Api.oauth2TokenExchange isn't used.
88
+ */
89
+ export declare function refreshAccessToken(args: {
90
+ projectUrl: string;
91
+ clientId: string;
92
+ refreshToken: string;
93
+ }): Promise<OryOAuth2Tokens>;
package/dist/auth.js ADDED
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ /**
3
+ * Browser-based OAuth2 PKCE login for Ory agent plugins.
4
+ *
5
+ * Spins up a transient localhost callback server on a fixed-port range
6
+ * (option (a) — operators register the same loopback URIs once with the
7
+ * Ory OAuth2 client), generates a PKCE verifier/challenge, launches the
8
+ * user's browser at the project's authorize URL, and exchanges the
9
+ * resulting code for a token set via /oauth2/token.
10
+ *
11
+ * This module never writes to stdout. Browser launching uses the `open`
12
+ * package via dynamic import so the CJS-emitted core stays compatible
13
+ * with its ESM-only export shape.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.LOOPBACK_PORTS = void 0;
17
+ exports.detectHeadless = detectHeadless;
18
+ exports.pkceLogin = pkceLogin;
19
+ exports.generateCodeVerifier = generateCodeVerifier;
20
+ exports.sha256Base64Url = sha256Base64Url;
21
+ exports.buildAuthorizeUrl = buildAuthorizeUrl;
22
+ exports.refreshAccessToken = refreshAccessToken;
23
+ const node_crypto_1 = require("node:crypto");
24
+ const node_http_1 = require("node:http");
25
+ const node_url_1 = require("node:url");
26
+ /** Loopback ports tried in order. All must be registered as redirect URIs on the Ory OAuth2 client. */
27
+ exports.LOOPBACK_PORTS = [47823, 47824, 47825, 47826];
28
+ /** Hard timeout if the user never returns to the browser. */
29
+ exports.DEFAULT_LOGIN_TIMEOUT_MS = 120_000;
30
+ /**
31
+ * Default headless heuristic. Returns true only for unattended runs
32
+ * (CI=true / CI=1) so {@link pkceLogin} can short-circuit instead of
33
+ * waiting on a callback that will never arrive.
34
+ *
35
+ * Heuristics like `SSH_TTY` and "Linux without DISPLAY" used to live here
36
+ * but turned out to be wrong in practice: an SSH user can paste the
37
+ * printed authorize URL into their workstation browser, and a Linux box
38
+ * without a display still works as long as the operator can reach the
39
+ * loopback callback port (e.g. via `ssh -L`). The PKCE flow always
40
+ * prints the URL to stderr, so anything short of "no human at all" is
41
+ * recoverable.
42
+ */
43
+ function detectHeadless(env = process.env) {
44
+ return env.CI === "true" || env.CI === "1";
45
+ }
46
+ /**
47
+ * Run a PKCE login and return either a token set or the reason the flow
48
+ * could not complete. The function never throws on user-driven failures
49
+ * (timeout, decline, headless); it throws only on programmer error or
50
+ * unrecoverable I/O failures.
51
+ */
52
+ async function pkceLogin(options) {
53
+ const isHeadless = options.isHeadless ?? detectHeadless;
54
+ const headless = isHeadless();
55
+ if (headless) {
56
+ // Unattended environment (CI). No human to follow the URL, so we
57
+ // skip the loopback listener entirely instead of timing out.
58
+ return { kind: "declined", reason: "headless" };
59
+ }
60
+ const { server, port } = await listenOnFirstAvailablePort(options.ports ?? exports.LOOPBACK_PORTS);
61
+ if (!server || port === null) {
62
+ return { kind: "declined", reason: "no_port" };
63
+ }
64
+ const codeVerifier = generateCodeVerifier();
65
+ const codeChallenge = sha256Base64Url(codeVerifier);
66
+ const state = (0, node_crypto_1.randomBytes)(16).toString("base64url");
67
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
68
+ const scope = options.scope ?? "openid offline_access";
69
+ const authorizeUrl = buildAuthorizeUrl({
70
+ projectUrl: options.projectUrl,
71
+ clientId: options.clientId,
72
+ redirectUri,
73
+ state,
74
+ codeChallenge,
75
+ scope,
76
+ audience: options.audience,
77
+ });
78
+ const timeoutMs = options.timeoutMs ?? exports.DEFAULT_LOGIN_TIMEOUT_MS;
79
+ // Print the URL to stderr *before* attempting to launch the browser.
80
+ // Users in non-TTY environments (SSH without `-t`, IDE terminals, etc.)
81
+ // can paste this into any browser that can reach 127.0.0.1 on the
82
+ // loopback port (locally on the same machine, or via `ssh -L
83
+ // <port>:localhost:<port>` from a remote box).
84
+ process.stderr.write(`\nOry sign-in required. Open this URL in a browser that can reach ${redirectUri}:\n\n ${authorizeUrl}\n\n` +
85
+ `Waiting up to ${Math.round(timeoutMs / 1000)}s for the callback…\n\n`);
86
+ const callback = waitForCallback(server, {
87
+ expectedState: state,
88
+ timeoutMs,
89
+ signal: options.signal,
90
+ });
91
+ // Browser launch is best-effort. If `open` throws or the platform has
92
+ // no usable browser, we keep the callback server alive and rely on the
93
+ // user opening the printed URL themselves. Decline only on a real
94
+ // callback failure (timeout, state mismatch, user_denied).
95
+ try {
96
+ await launchBrowser(authorizeUrl, options.openBrowser);
97
+ }
98
+ catch (err) {
99
+ process.stderr.write(`Could not auto-launch a browser (${err instanceof Error ? err.message : String(err)}). ` +
100
+ `Open the URL above manually to continue.\n\n`);
101
+ }
102
+ const result = await callback;
103
+ server.close();
104
+ if (result.kind !== "ok")
105
+ return result;
106
+ try {
107
+ const tokens = await exchangeCodeForTokens({
108
+ projectUrl: options.projectUrl,
109
+ clientId: options.clientId,
110
+ redirectUri,
111
+ code: result.code,
112
+ codeVerifier,
113
+ });
114
+ return { kind: "ok", tokens };
115
+ }
116
+ catch {
117
+ return { kind: "declined", reason: "token_exchange_failed" };
118
+ }
119
+ }
120
+ // ─── PKCE primitives ──────────────────────────────────────────────────
121
+ /** Generate a 64-byte (≈86-char base64url) code verifier per RFC 7636. */
122
+ function generateCodeVerifier() {
123
+ return (0, node_crypto_1.randomBytes)(64).toString("base64url");
124
+ }
125
+ /** SHA-256 + base64url, the only supported PKCE challenge method (`S256`). */
126
+ function sha256Base64Url(input) {
127
+ return (0, node_crypto_1.createHash)("sha256").update(input).digest("base64url");
128
+ }
129
+ function buildAuthorizeUrl(params) {
130
+ const url = new node_url_1.URL("/oauth2/auth", params.projectUrl);
131
+ url.searchParams.set("response_type", "code");
132
+ url.searchParams.set("client_id", params.clientId);
133
+ url.searchParams.set("redirect_uri", params.redirectUri);
134
+ url.searchParams.set("state", params.state);
135
+ url.searchParams.set("scope", params.scope);
136
+ url.searchParams.set("code_challenge", params.codeChallenge);
137
+ url.searchParams.set("code_challenge_method", "S256");
138
+ if (params.audience)
139
+ url.searchParams.set("audience", params.audience);
140
+ return url.toString();
141
+ }
142
+ // ─── Callback server ──────────────────────────────────────────────────
143
+ async function listenOnFirstAvailablePort(ports) {
144
+ for (const requested of ports) {
145
+ try {
146
+ const server = await new Promise((resolve, reject) => {
147
+ const s = (0, node_http_1.createServer)();
148
+ const onError = (err) => {
149
+ s.removeListener("listening", onListening);
150
+ reject(err);
151
+ };
152
+ const onListening = () => {
153
+ s.removeListener("error", onError);
154
+ resolve(s);
155
+ };
156
+ s.once("error", onError);
157
+ s.once("listening", onListening);
158
+ s.listen(requested, "127.0.0.1");
159
+ });
160
+ const addr = server.address();
161
+ const port = typeof addr === "object" && addr ? addr.port : requested;
162
+ return { server, port };
163
+ }
164
+ catch (err) {
165
+ if (err.code === "EADDRINUSE")
166
+ continue;
167
+ throw err;
168
+ }
169
+ }
170
+ return { server: null, port: null };
171
+ }
172
+ function waitForCallback(server, opts) {
173
+ return new Promise((resolve) => {
174
+ let settled = false;
175
+ const settle = (r) => {
176
+ if (settled)
177
+ return;
178
+ settled = true;
179
+ clearTimeout(timer);
180
+ if (opts.signal)
181
+ opts.signal.removeEventListener("abort", onAbort);
182
+ server.removeListener("request", onRequest);
183
+ resolve(r);
184
+ };
185
+ const timer = setTimeout(() => settle({ kind: "declined", reason: "timeout" }), opts.timeoutMs);
186
+ const onAbort = () => settle({ kind: "declined", reason: "aborted" });
187
+ if (opts.signal) {
188
+ if (opts.signal.aborted) {
189
+ settle({ kind: "declined", reason: "aborted" });
190
+ return;
191
+ }
192
+ opts.signal.addEventListener("abort", onAbort);
193
+ }
194
+ const onRequest = (req, res) => {
195
+ if (!isLoopbackHost(req.headers.host)) {
196
+ respond(res, 400, "Bad Host");
197
+ return;
198
+ }
199
+ const url = new node_url_1.URL(req.url ?? "/", `http://127.0.0.1`);
200
+ if (url.pathname !== "/callback") {
201
+ respond(res, 404, "Not Found");
202
+ return;
203
+ }
204
+ const error = url.searchParams.get("error");
205
+ if (error) {
206
+ respond(res, 400, "Authentication declined. You may close this window.");
207
+ settle({ kind: "declined", reason: "user_denied" });
208
+ return;
209
+ }
210
+ const state = url.searchParams.get("state");
211
+ const code = url.searchParams.get("code");
212
+ if (!code || state !== opts.expectedState) {
213
+ respond(res, 400, "State mismatch.");
214
+ settle({ kind: "declined", reason: "state_mismatch" });
215
+ return;
216
+ }
217
+ respond(res, 200, "Sign-in complete. You may close this window and return to your terminal.");
218
+ settle({ kind: "ok", code });
219
+ };
220
+ server.on("request", onRequest);
221
+ });
222
+ }
223
+ function isLoopbackHost(host) {
224
+ if (!host)
225
+ return false;
226
+ const hostOnly = host.split(":")[0];
227
+ return hostOnly === "127.0.0.1" || hostOnly === "localhost" || hostOnly === "[::1]";
228
+ }
229
+ function respond(res, status, body) {
230
+ res.writeHead(status, { "content-type": "text/plain; charset=utf-8" });
231
+ res.end(body + "\n");
232
+ }
233
+ // ─── Browser launch ───────────────────────────────────────────────────
234
+ async function launchBrowser(url, override) {
235
+ if (override) {
236
+ await override(url);
237
+ return;
238
+ }
239
+ // `open` is ESM-only; dynamic import works from CJS output.
240
+ const mod = (await import("open"));
241
+ await mod.default(url);
242
+ }
243
+ // Kept as raw fetch (rather than @ory/client's OAuth2Api.oauth2TokenExchange)
244
+ // because the SDK method's signature does not expose code_verifier, which
245
+ // PKCE requires. Ory's own SDK docstring on that method says it should not
246
+ // be used via the SDK.
247
+ async function exchangeCodeForTokens(args) {
248
+ const body = new URLSearchParams({
249
+ grant_type: "authorization_code",
250
+ client_id: args.clientId,
251
+ code: args.code,
252
+ redirect_uri: args.redirectUri,
253
+ code_verifier: args.codeVerifier,
254
+ });
255
+ const tokenUrl = new node_url_1.URL("/oauth2/token", args.projectUrl).toString();
256
+ const res = await fetch(tokenUrl, {
257
+ method: "POST",
258
+ headers: { "content-type": "application/x-www-form-urlencoded" },
259
+ body: body.toString(),
260
+ });
261
+ if (!res.ok) {
262
+ throw new Error(`Token exchange failed: HTTP ${res.status}`);
263
+ }
264
+ const json = (await res.json());
265
+ return tokensFromTokenResponse(json, args.clientId);
266
+ }
267
+ /**
268
+ * Refresh an access token using a refresh token. Throws on any non-2xx
269
+ * response so callers can decide whether to fall back to a fresh login.
270
+ *
271
+ * Kept as raw fetch for parity with the other two /oauth2/token flows;
272
+ * see `exchangeCodeForTokens` and `fetchClientCredentialsToken` for why
273
+ * @ory/client's OAuth2Api.oauth2TokenExchange isn't used.
274
+ */
275
+ async function refreshAccessToken(args) {
276
+ const body = new URLSearchParams({
277
+ grant_type: "refresh_token",
278
+ client_id: args.clientId,
279
+ refresh_token: args.refreshToken,
280
+ });
281
+ const tokenUrl = new node_url_1.URL("/oauth2/token", args.projectUrl).toString();
282
+ const res = await fetch(tokenUrl, {
283
+ method: "POST",
284
+ headers: { "content-type": "application/x-www-form-urlencoded" },
285
+ body: body.toString(),
286
+ });
287
+ if (!res.ok) {
288
+ throw new Error(`Token refresh failed: HTTP ${res.status}`);
289
+ }
290
+ const json = (await res.json());
291
+ return tokensFromTokenResponse(json, args.clientId, args.refreshToken);
292
+ }
293
+ function tokensFromTokenResponse(json, clientId, fallbackRefreshToken) {
294
+ const accessToken = typeof json.access_token === "string" ? json.access_token : "";
295
+ if (!accessToken)
296
+ throw new Error("Token response missing access_token");
297
+ const expiresIn = typeof json.expires_in === "number" ? json.expires_in : 3600;
298
+ const refreshToken = typeof json.refresh_token === "string" ? json.refresh_token : fallbackRefreshToken;
299
+ return {
300
+ accessToken,
301
+ refreshToken,
302
+ expiresAt: Math.floor(Date.now() / 1000) + expiresIn,
303
+ clientId,
304
+ idToken: typeof json.id_token === "string" ? json.id_token : undefined,
305
+ scope: typeof json.scope === "string" ? json.scope : undefined,
306
+ subject: subjectFromIdToken(typeof json.id_token === "string" ? json.id_token : undefined),
307
+ };
308
+ }
309
+ /** Best-effort sub-claim extraction from a JWT id_token. Returns undefined on any failure. */
310
+ function subjectFromIdToken(idToken) {
311
+ if (!idToken)
312
+ return undefined;
313
+ const parts = idToken.split(".");
314
+ if (parts.length < 2)
315
+ return undefined;
316
+ try {
317
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8"));
318
+ return typeof payload.sub === "string" ? payload.sub : undefined;
319
+ }
320
+ catch {
321
+ return undefined;
322
+ }
323
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Shared `configure` command implementation for all plugin CLIs.
3
+ *
4
+ * Parses --project-url and --api-key from args. If neither is provided,
5
+ * shows the current configuration. Otherwise saves the provided values.
6
+ */
7
+ export declare function runConfigureCommand(binName: string, args: string[]): void;
8
+ /**
9
+ * Print the "Configuration:" block showing Ory project URL and API key status.
10
+ */
11
+ export declare function printOryConfig(): void;
12
+ /**
13
+ * Print the "Environment:" block showing Ory-related environment variables.
14
+ */
15
+ export declare function printEnvironment(): void;
16
+ /**
17
+ * Print the last 5 debug log entries if ORY_AGENT_LOG_FILE is set and exists.
18
+ */
19
+ export declare function printLogTail(): void;
20
+ /**
21
+ * Print the "Configure your Ory credentials" help text.
22
+ */
23
+ export declare function printEnvHelp(binName: string): void;
24
+ /**
25
+ * Print the last 5 trace entries if ORY_AGENT_TRACE_FILE is set and exists.
26
+ */
27
+ export declare function printTraceTail(): void;
28
+ /**
29
+ * Run the live trace watcher. Tails the NDJSON trace file and prints
30
+ * formatted spans to stdout as they arrive. Blocks until interrupted.
31
+ */
32
+ export declare function runWatchCommand(args: string[]): void;
33
+ /**
34
+ * Returns true if `/dev/tty` can be opened for reading. Use this before
35
+ * attempting to prompt the user — the harness has already taken stdin so
36
+ * we cannot use `process.stdin`.
37
+ */
38
+ export declare function isTtyAvailable(): boolean;
39
+ /**
40
+ * Prompt the user to enter a value on /dev/tty. Returns the trimmed
41
+ * line, or null if no TTY is available. The prompt is written to stderr
42
+ * — never stdout.
43
+ */
44
+ export declare function promptOnTty(prompt: string): Promise<string | null>;
45
+ /**
46
+ * Inline prompt for the Ory project URL. Persists the entered URL to the
47
+ * shared config file and returns it. Returns null if the user cancels
48
+ * (empty input) or no TTY is available.
49
+ *
50
+ * This is the structured counterpart to {@link interactiveConfigPrompt},
51
+ * which only blocks until the user runs `configure` in another terminal.
52
+ */
53
+ export declare function promptForProjectUrl(binName: string): Promise<string | null>;
54
+ /**
55
+ * Display a friendly configuration prompt on stderr and block until the
56
+ * user presses Enter. After the user continues, re-checks config from
57
+ * disk and returns true if Ory is now configured.
58
+ *
59
+ * Falls back to non-interactive mode (returns false immediately) when
60
+ * no TTY is available (e.g. CI).
61
+ */
62
+ export declare function interactiveConfigPrompt(binName: string): Promise<boolean>;
63
+ /**
64
+ * Run the `agent <subcommand>` family of CLI commands. These manage the
65
+ * agent's dynamic OAuth2 client registration (RFC 7591). Subcommands:
66
+ *
67
+ * - `status` — print the persisted DCR identity, if any.
68
+ * - `unregister` — best-effort RFC 7592 DELETE on the registered
69
+ * client, then clear the persisted block.
70
+ *
71
+ * Returns the process exit code (0 on success, non-zero on usage error).
72
+ */
73
+ export declare function runAgentCommand(binName: string, args: string[]): Promise<number>;