@ory/argus 0.13.6 → 0.13.8
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 +8 -0
- package/dist/agent-auth.js +33 -5
- package/dist/build-info.json +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -4
- package/dist/interactive-setup.js +53 -5
- package/dist/logger.d.ts +21 -0
- package/dist/logger.js +38 -2
- package/dist/permissions-cli.js +7 -2
- package/dist/status-cli.js +31 -23
- package/package.json +1 -1
package/dist/agent-auth.d.ts
CHANGED
|
@@ -48,6 +48,14 @@ export interface AgentCredentials {
|
|
|
48
48
|
* via deprecated alias). Never blocks resolution.
|
|
49
49
|
*/
|
|
50
50
|
warnings: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Set on a `kind: "none"` result when the token endpoint rejected the
|
|
53
|
+
* credentials for an auth reason (401/403) — i.e. the client is genuinely
|
|
54
|
+
* dead (revoked/invalid). A transient failure (network, rate-limit, 5xx)
|
|
55
|
+
* leaves this false so callers don't discard otherwise-good persisted
|
|
56
|
+
* credentials. See the persisted-DCR branch in {@link resolveAgentCredentials}.
|
|
57
|
+
*/
|
|
58
|
+
authRejected?: boolean;
|
|
51
59
|
}
|
|
52
60
|
export interface ResolveAgentCredentialsOptions {
|
|
53
61
|
/** Ory project URL — required for client_credentials grant + DCR. */
|
package/dist/agent-auth.js
CHANGED
|
@@ -275,10 +275,20 @@ async function resolveAgentCredentials(options = {}) {
|
|
|
275
275
|
});
|
|
276
276
|
if (result.kind !== "none")
|
|
277
277
|
return result;
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
278
|
+
// Only a genuine auth rejection (401/403 — client revoked/invalid) means
|
|
279
|
+
// the persisted creds are dead. Clear them and fall through to a fresh
|
|
280
|
+
// registration. A transient failure (network, rate-limit, 5xx) must NOT
|
|
281
|
+
// discard good creds: doing so would orphan the server-side client
|
|
282
|
+
// (clearDynamicFn never revokes it) and register a brand-new one on every
|
|
283
|
+
// blip. Keep the persisted creds and report the transient failure instead.
|
|
284
|
+
if (result.authRejected) {
|
|
285
|
+
warnings.push(`Persisted dynamic agent credentials rejected (${result.reason}); re-registering.`);
|
|
286
|
+
clearDynamicFn();
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
warnings.push(`Persisted dynamic agent credentials temporarily unavailable (${result.reason}); keeping them for the next session.`);
|
|
290
|
+
return { ...result, warnings };
|
|
291
|
+
}
|
|
282
292
|
}
|
|
283
293
|
}
|
|
284
294
|
// 4. Fresh dynamic registration — bootstrap using the user's bearer
|
|
@@ -377,11 +387,27 @@ async function resolveClientCredentials(args) {
|
|
|
377
387
|
catch (err) {
|
|
378
388
|
return {
|
|
379
389
|
kind: "none",
|
|
390
|
+
authRejected: isAuthRejectionError(err),
|
|
380
391
|
reason: `${reasonNoun} client_credentials grant failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
381
392
|
warnings: args.warnings,
|
|
382
393
|
};
|
|
383
394
|
}
|
|
384
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Whether a token-grant error is an auth rejection (401/403) — meaning the
|
|
398
|
+
* credentials themselves are dead — as opposed to a transient failure
|
|
399
|
+
* (network, rate-limit, 5xx). Reads a `status` property when the thrower
|
|
400
|
+
* attaches one ({@link fetchClientCredentialsToken} does), and falls back to
|
|
401
|
+
* matching `HTTP 401`/`HTTP 403` in the message so injected/stubbed grant
|
|
402
|
+
* functions that throw a plain `Error` are classified correctly too.
|
|
403
|
+
*/
|
|
404
|
+
function isAuthRejectionError(err) {
|
|
405
|
+
const status = err?.status;
|
|
406
|
+
if (status === 401 || status === 403)
|
|
407
|
+
return true;
|
|
408
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
409
|
+
return /\bHTTP 40[13]\b/.test(msg);
|
|
410
|
+
}
|
|
385
411
|
// Kept as raw fetch (rather than @ory/client's OAuth2Api.oauth2TokenExchange)
|
|
386
412
|
// because the SDK method's signature does not expose client_secret, audience,
|
|
387
413
|
// or scope — all of which this grant needs. Ory's own SDK docstring on that
|
|
@@ -404,7 +430,9 @@ async function fetchClientCredentialsToken(args) {
|
|
|
404
430
|
body: body.toString(),
|
|
405
431
|
});
|
|
406
432
|
if (!res.ok) {
|
|
407
|
-
|
|
433
|
+
const err = new Error(`HTTP ${res.status}`);
|
|
434
|
+
err.status = res.status;
|
|
435
|
+
throw err;
|
|
408
436
|
}
|
|
409
437
|
const json = (await res.json());
|
|
410
438
|
const accessToken = typeof json.access_token === "string" ? json.access_token : "";
|
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "ory-agent-plugins",
|
|
3
|
-
"commit": "
|
|
4
|
-
"commitShort": "
|
|
3
|
+
"commit": "ff55031f181ceec7e06f8d7f3a6b2555c130a091",
|
|
4
|
+
"commitShort": "ff55031",
|
|
5
5
|
"branch": "main",
|
|
6
|
-
"commitDate": "2026-07-
|
|
6
|
+
"commitDate": "2026-07-15T13:59:17-07:00",
|
|
7
7
|
"dirty": false,
|
|
8
|
-
"builtAt": "2026-07-
|
|
8
|
+
"builtAt": "2026-07-15T21:03:15.277Z"
|
|
9
9
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { OryAgentClient, type OryAgentConfig, type PrincipalIdentity, } from "./client.js";
|
|
2
|
-
export { DebugLogger, redactLogData, type LogEntry, type LogLevel, } from "./logger.js";
|
|
2
|
+
export { DebugLogger, redactLogData, withQuietStderr, type LogEntry, type LogLevel, } from "./logger.js";
|
|
3
3
|
export { Tracer, ActiveSpan, deriveTraceId, formatSpan, watchTraceFile, type TraceEvent, type SpanStatus, type TraceSpan, type SpanOptions, type TracerOptions, type TracerContext, type SpanAttributeEnricher, } from "./tracer.js";
|
|
4
4
|
export { loadConfig, saveConfig, resolveConfig, mutateConfig, getConfigPath, getDataDir, getHarnessDataDir, type OryPluginConfig, type OryOAuth2Tokens, type OryUserCredentials, type OryAgentCredentialsBlock, type OryAgentDynamicCredentials, type PermissionMode, } from "./config.js";
|
|
5
5
|
export { pkceLogin, refreshAccessToken, detectHeadless, generateCodeVerifier, sha256Base64Url, buildAuthorizeUrl, LOOPBACK_PORTS, DEFAULT_LOGIN_TIMEOUT_MS, type PkceLoginOptions, type PkceLoginOutcome, type PkceDeclineReason, } from "./auth.js";
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.wrapTool = exports.registerSubagent = exports.complete = exports.gate = exports.sessionStart = exports.resolveNamespace = exports.parseKeyValueList = void 0;
|
|
3
|
+
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.withQuietStderr = exports.redactLogData = exports.DebugLogger = exports.OryAgentClient = void 0;
|
|
4
|
+
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.resolveBuildInfo = exports.collectVersionInfo = exports.runVersionCommand = 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 = exports.runConfigureCommand = void 0;
|
|
5
|
+
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 = exports.commandToSkill = exports.renderOryCommands = exports.renderOrySkills = exports.runDevLauncher = void 0;
|
|
6
|
+
exports.wrapTool = exports.registerSubagent = exports.complete = exports.gate = exports.sessionStart = exports.resolveNamespace = exports.parseKeyValueList = exports.otlpExporterFromEnv = void 0;
|
|
7
7
|
var client_js_1 = require("./client.js");
|
|
8
8
|
Object.defineProperty(exports, "OryAgentClient", { enumerable: true, get: function () { return client_js_1.OryAgentClient; } });
|
|
9
9
|
var logger_js_1 = require("./logger.js");
|
|
10
10
|
Object.defineProperty(exports, "DebugLogger", { enumerable: true, get: function () { return logger_js_1.DebugLogger; } });
|
|
11
11
|
Object.defineProperty(exports, "redactLogData", { enumerable: true, get: function () { return logger_js_1.redactLogData; } });
|
|
12
|
+
Object.defineProperty(exports, "withQuietStderr", { enumerable: true, get: function () { return logger_js_1.withQuietStderr; } });
|
|
12
13
|
var tracer_js_1 = require("./tracer.js");
|
|
13
14
|
Object.defineProperty(exports, "Tracer", { enumerable: true, get: function () { return tracer_js_1.Tracer; } });
|
|
14
15
|
Object.defineProperty(exports, "ActiveSpan", { enumerable: true, get: function () { return tracer_js_1.ActiveSpan; } });
|
|
@@ -82,6 +82,7 @@ const cli_js_1 = require("./cli.js");
|
|
|
82
82
|
const cli_invocation_js_1 = require("./cli-invocation.js");
|
|
83
83
|
const auth_js_1 = require("./auth.js");
|
|
84
84
|
const client_js_1 = require("./client.js");
|
|
85
|
+
const logger_js_1 = require("./logger.js");
|
|
85
86
|
const user_login_js_1 = require("./user-login.js");
|
|
86
87
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
87
88
|
const tool_catalog_js_1 = require("./tool-catalog.js");
|
|
@@ -261,8 +262,12 @@ async function runInteractiveSetup(binName, harness, args = [], deps = {}) {
|
|
|
261
262
|
ttyPrompter = createTtyPrompter();
|
|
262
263
|
}
|
|
263
264
|
};
|
|
265
|
+
// Quiet the structured stderr firehose for the duration of the wizard so
|
|
266
|
+
// `[ory-agent] {...}` debug lines don't interleave with the human-facing UI
|
|
267
|
+
// when a session runs with ORY_AGENT_DEBUG=true (the dev launcher always
|
|
268
|
+
// sets it). Debug still lands in the log file.
|
|
264
269
|
try {
|
|
265
|
-
return await runWizard(binName, harness, { runner, prompt, deps, runInteractive });
|
|
270
|
+
return await (0, logger_js_1.withQuietStderr)(() => runWizard(binName, harness, { runner, prompt, deps, runInteractive }));
|
|
266
271
|
}
|
|
267
272
|
catch (err) {
|
|
268
273
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -568,10 +573,20 @@ async function configureNetwork(binName, harness, ctx) {
|
|
|
568
573
|
// self-register at runtime. Ory Network projects ship with DCR disabled,
|
|
569
574
|
// so without this the default agent-identity path would never resolve.
|
|
570
575
|
await maybeEnableDcr(runner, prompt, project.id);
|
|
571
|
-
// 6.
|
|
576
|
+
// 6. Provision the public OAuth2 client for the PKCE user login. Reuse an
|
|
577
|
+
// existing one on this project first — a re-run (`install --reconfigure`)
|
|
578
|
+
// against the same project must not mint a duplicate public client and
|
|
579
|
+
// orphan the old one (the CLI-created client is never cleaned up by
|
|
580
|
+
// uninstall). Only create when no prior client is found.
|
|
572
581
|
ui.heading("OAuth2 client");
|
|
573
|
-
|
|
574
|
-
|
|
582
|
+
let clientId = findExistingOAuth2Client(runner, project.id);
|
|
583
|
+
if (clientId) {
|
|
584
|
+
ui.step(`Reusing the existing OAuth2 client for user login (${clientId}).`);
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
ui.step("Creating the OAuth2 client for user login...");
|
|
588
|
+
clientId = createOAuth2Client(runner, project.id);
|
|
589
|
+
}
|
|
575
590
|
if (!clientId) {
|
|
576
591
|
ui.warning("Could not create the OAuth2 client automatically.");
|
|
577
592
|
ui.warnDetail(`Project URL resolved: ${projectUrl}`);
|
|
@@ -604,6 +619,14 @@ async function configureNetwork(binName, harness, ctx) {
|
|
|
604
619
|
// runtime agent/user tokens can't write relation tuples on a hosted
|
|
605
620
|
// project (that's a project-admin operation), but the `ory` session can.
|
|
606
621
|
if (subject) {
|
|
622
|
+
// Persist the subject *shape* this grant used. If the install resolved a
|
|
623
|
+
// SubjectSet (ORY_USER_SUBJECT_NAMESPACE was set), a later runtime session
|
|
624
|
+
// that lacks the env var would otherwise resolve a direct subject_id and
|
|
625
|
+
// check/write a divergent tuple for the same user. Persisting the namespace
|
|
626
|
+
// keeps install-time and runtime writes on one canonical subject shape.
|
|
627
|
+
if ("subjectSet" in subject) {
|
|
628
|
+
(0, config_js_1.saveConfig)({ userSubjectNamespace: subject.subjectSet.namespace });
|
|
629
|
+
}
|
|
607
630
|
await bootstrapPermissionsViaOry(runner, project.id, harness, subject, prompt);
|
|
608
631
|
}
|
|
609
632
|
// 10. Provision the project API key runtime permission *checks* need. Same
|
|
@@ -1166,6 +1189,31 @@ async function maybeEnableDcr(runner, prompt, projectId) {
|
|
|
1166
1189
|
ui.warnDetail(`Enable it later with: ${manual}`);
|
|
1167
1190
|
}
|
|
1168
1191
|
}
|
|
1192
|
+
/** The `client_name` every plugin-provisioned public PKCE client carries. */
|
|
1193
|
+
const OAUTH2_CLIENT_NAME = "ory-agent-plugin";
|
|
1194
|
+
/**
|
|
1195
|
+
* Look for an already-provisioned public PKCE client on the project so a
|
|
1196
|
+
* re-run reuses it instead of minting a duplicate. Matches by the fixed
|
|
1197
|
+
* `client_name` {@link createOAuth2Client} assigns. Best-effort: any CLI or
|
|
1198
|
+
* parse failure returns null and the caller falls back to creating one.
|
|
1199
|
+
*/
|
|
1200
|
+
function findExistingOAuth2Client(runner, projectId) {
|
|
1201
|
+
const r = runner.exec([
|
|
1202
|
+
"list",
|
|
1203
|
+
"oauth2-clients",
|
|
1204
|
+
"--project",
|
|
1205
|
+
projectId,
|
|
1206
|
+
"--format",
|
|
1207
|
+
"json",
|
|
1208
|
+
]);
|
|
1209
|
+
if (r.status !== 0)
|
|
1210
|
+
return null;
|
|
1211
|
+
const clients = parseList(r.stdout, "items");
|
|
1212
|
+
if (!clients)
|
|
1213
|
+
return null;
|
|
1214
|
+
const match = clients.find((c) => c.client_name === OAUTH2_CLIENT_NAME && c.client_id);
|
|
1215
|
+
return match?.client_id ?? null;
|
|
1216
|
+
}
|
|
1169
1217
|
function createOAuth2Client(runner, projectId) {
|
|
1170
1218
|
const args = [
|
|
1171
1219
|
"create",
|
|
@@ -1173,7 +1221,7 @@ function createOAuth2Client(runner, projectId) {
|
|
|
1173
1221
|
"--project",
|
|
1174
1222
|
projectId,
|
|
1175
1223
|
"--name",
|
|
1176
|
-
|
|
1224
|
+
OAUTH2_CLIENT_NAME,
|
|
1177
1225
|
"--grant-type",
|
|
1178
1226
|
"authorization_code,refresh_token",
|
|
1179
1227
|
"--response-type",
|
package/dist/logger.d.ts
CHANGED
|
@@ -12,6 +12,15 @@ export interface LogEntry {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function redactLogData(value: unknown): unknown;
|
|
14
14
|
export declare class DebugLogger {
|
|
15
|
+
/**
|
|
16
|
+
* Process-global switch to suppress the stderr firehose while still writing
|
|
17
|
+
* to the log file. The interactive installer sets this so structured debug
|
|
18
|
+
* JSON (`[ory-agent] {...}`) doesn't interleave with the wizard's
|
|
19
|
+
* human-facing UI when a session runs with `ORY_AGENT_DEBUG=true` (the dev
|
|
20
|
+
* launcher, for one, always sets it). File logging — the real observability
|
|
21
|
+
* channel — is unaffected.
|
|
22
|
+
*/
|
|
23
|
+
static stderrSuppressed: boolean;
|
|
15
24
|
enabled: boolean;
|
|
16
25
|
harness: string;
|
|
17
26
|
logFile: string | null;
|
|
@@ -27,3 +36,15 @@ export declare class DebugLogger {
|
|
|
27
36
|
warn(event: string, data?: Record<string, unknown>): void;
|
|
28
37
|
error(event: string, data?: Record<string, unknown>): void;
|
|
29
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Run `fn` with the structured stderr firehose suppressed, restoring the
|
|
41
|
+
* previous state afterward (even on throw). File logging is unaffected.
|
|
42
|
+
*
|
|
43
|
+
* Human-facing CLI commands (the interactive installer, `status`,
|
|
44
|
+
* `permissions status`/`bootstrap`) spin up a client and emit debug/info
|
|
45
|
+
* events; when the process runs with `ORY_AGENT_DEBUG=true` (the dev launcher
|
|
46
|
+
* always sets it) those `[ory-agent] {...}` lines would interleave with the
|
|
47
|
+
* command's polished output. Wrapping the command body in this keeps the
|
|
48
|
+
* terminal clean while the log file still captures everything.
|
|
49
|
+
*/
|
|
50
|
+
export declare function withQuietStderr<T>(fn: () => Promise<T> | T): Promise<T>;
|
package/dist/logger.js
CHANGED
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.DebugLogger = void 0;
|
|
37
37
|
exports.redactLogData = redactLogData;
|
|
38
|
+
exports.withQuietStderr = withQuietStderr;
|
|
38
39
|
const fs = __importStar(require("node:fs"));
|
|
39
40
|
const path = __importStar(require("node:path"));
|
|
40
41
|
/**
|
|
@@ -82,6 +83,15 @@ function redactLogData(value) {
|
|
|
82
83
|
return value;
|
|
83
84
|
}
|
|
84
85
|
class DebugLogger {
|
|
86
|
+
/**
|
|
87
|
+
* Process-global switch to suppress the stderr firehose while still writing
|
|
88
|
+
* to the log file. The interactive installer sets this so structured debug
|
|
89
|
+
* JSON (`[ory-agent] {...}`) doesn't interleave with the wizard's
|
|
90
|
+
* human-facing UI when a session runs with `ORY_AGENT_DEBUG=true` (the dev
|
|
91
|
+
* launcher, for one, always sets it). File logging — the real observability
|
|
92
|
+
* channel — is unaffected.
|
|
93
|
+
*/
|
|
94
|
+
static stderrSuppressed = false;
|
|
85
95
|
enabled;
|
|
86
96
|
harness;
|
|
87
97
|
logFile;
|
|
@@ -113,8 +123,13 @@ class DebugLogger {
|
|
|
113
123
|
...(safeData ? { data: safeData } : {}),
|
|
114
124
|
};
|
|
115
125
|
const line = JSON.stringify(entry);
|
|
116
|
-
//
|
|
117
|
-
|
|
126
|
+
// Write to stderr (never stdout) so we don't interfere with hook stdout,
|
|
127
|
+
// unless the stderr firehose is globally suppressed (e.g. during the
|
|
128
|
+
// interactive installer, so it doesn't clutter the wizard UI). The log
|
|
129
|
+
// file below still captures everything.
|
|
130
|
+
if (!DebugLogger.stderrSuppressed) {
|
|
131
|
+
process.stderr.write(`[ory-agent] ${line}\n`);
|
|
132
|
+
}
|
|
118
133
|
if (this.logFile) {
|
|
119
134
|
const dir = path.dirname(this.logFile);
|
|
120
135
|
if (!fs.existsSync(dir)) {
|
|
@@ -137,3 +152,24 @@ class DebugLogger {
|
|
|
137
152
|
}
|
|
138
153
|
}
|
|
139
154
|
exports.DebugLogger = DebugLogger;
|
|
155
|
+
/**
|
|
156
|
+
* Run `fn` with the structured stderr firehose suppressed, restoring the
|
|
157
|
+
* previous state afterward (even on throw). File logging is unaffected.
|
|
158
|
+
*
|
|
159
|
+
* Human-facing CLI commands (the interactive installer, `status`,
|
|
160
|
+
* `permissions status`/`bootstrap`) spin up a client and emit debug/info
|
|
161
|
+
* events; when the process runs with `ORY_AGENT_DEBUG=true` (the dev launcher
|
|
162
|
+
* always sets it) those `[ory-agent] {...}` lines would interleave with the
|
|
163
|
+
* command's polished output. Wrapping the command body in this keeps the
|
|
164
|
+
* terminal clean while the log file still captures everything.
|
|
165
|
+
*/
|
|
166
|
+
async function withQuietStderr(fn) {
|
|
167
|
+
const prev = DebugLogger.stderrSuppressed;
|
|
168
|
+
DebugLogger.stderrSuppressed = true;
|
|
169
|
+
try {
|
|
170
|
+
return await fn();
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
DebugLogger.stderrSuppressed = prev;
|
|
174
|
+
}
|
|
175
|
+
}
|
package/dist/permissions-cli.js
CHANGED
|
@@ -61,6 +61,7 @@ exports.printPermissionsOnboardingHelp = printPermissionsOnboardingHelp;
|
|
|
61
61
|
exports.maybeAutoBootstrap = maybeAutoBootstrap;
|
|
62
62
|
const config_js_1 = require("./config.js");
|
|
63
63
|
const client_js_1 = require("./client.js");
|
|
64
|
+
const logger_js_1 = require("./logger.js");
|
|
64
65
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
65
66
|
const auth_store_js_1 = require("./auth-store.js");
|
|
66
67
|
const tool_catalog_js_1 = require("./tool-catalog.js");
|
|
@@ -85,10 +86,14 @@ async function runPermissionsCommand(binName, harness, args) {
|
|
|
85
86
|
return sub ? 0 : 1;
|
|
86
87
|
}
|
|
87
88
|
switch (sub) {
|
|
89
|
+
// `status` and `bootstrap` spin up a client and probe/grant per tool,
|
|
90
|
+
// emitting debug/info events. Quiet the stderr firehose so those don't
|
|
91
|
+
// interleave with the command's human-facing output under
|
|
92
|
+
// ORY_AGENT_DEBUG=true; the log file still captures everything.
|
|
88
93
|
case "status":
|
|
89
|
-
return await runPermissionsStatus(binName, harness);
|
|
94
|
+
return await (0, logger_js_1.withQuietStderr)(() => runPermissionsStatus(binName, harness));
|
|
90
95
|
case "bootstrap":
|
|
91
|
-
return await runPermissionsBootstrap(binName, harness, args.slice(1));
|
|
96
|
+
return await (0, logger_js_1.withQuietStderr)(() => runPermissionsBootstrap(binName, harness, args.slice(1)));
|
|
92
97
|
case "observe":
|
|
93
98
|
return runPermissionsSetMode(binName, "observe");
|
|
94
99
|
case "enforce":
|
package/dist/status-cli.js
CHANGED
|
@@ -17,6 +17,7 @@ const config_js_1 = require("./config.js");
|
|
|
17
17
|
const auth_store_js_1 = require("./auth-store.js");
|
|
18
18
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
19
19
|
const client_js_1 = require("./client.js");
|
|
20
|
+
const logger_js_1 = require("./logger.js");
|
|
20
21
|
const agent_auth_js_2 = require("./agent-auth.js");
|
|
21
22
|
const subject_js_1 = require("./subject.js");
|
|
22
23
|
const tool_catalog_js_1 = require("./tool-catalog.js");
|
|
@@ -279,28 +280,35 @@ function formatModeSuffix(source) {
|
|
|
279
280
|
* than aborting the command.
|
|
280
281
|
*/
|
|
281
282
|
async function runStatusCommand(binName, harness, options) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
283
|
+
// Quiet the structured stderr firehose for the duration of the report so
|
|
284
|
+
// `[ory-agent] {...}` debug lines (the permissions probe runs a client and
|
|
285
|
+
// per-tool checks) don't interleave with this human-facing output when the
|
|
286
|
+
// command runs with ORY_AGENT_DEBUG=true. Debug still lands in the log file,
|
|
287
|
+
// and the "Recent activity" section below surfaces its tail regardless.
|
|
288
|
+
await (0, logger_js_1.withQuietStderr)(async () => {
|
|
289
|
+
const heading = `Ory Agent Plugin Status (${options.title})`;
|
|
290
|
+
console.log(heading);
|
|
291
|
+
console.log("=".repeat(heading.length));
|
|
291
292
|
console.log("");
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
293
|
+
(0, cli_js_1.printOryConfig)();
|
|
294
|
+
printUserIdentitySection();
|
|
295
|
+
printAgentIdentitySection();
|
|
296
|
+
await printPermissionsSection(binName, harness);
|
|
297
|
+
if (options.printPluginSection) {
|
|
298
|
+
console.log("");
|
|
299
|
+
options.printPluginSection();
|
|
300
|
+
}
|
|
301
|
+
(0, cli_js_1.printEnvironment)();
|
|
302
|
+
console.log("");
|
|
303
|
+
console.log("Recent activity:");
|
|
304
|
+
(0, cli_js_1.printTraceTail)(harness);
|
|
305
|
+
(0, cli_js_1.printLogTail)(harness);
|
|
306
|
+
console.log("");
|
|
307
|
+
console.log(` Watch traces live: ${(0, cli_invocation_js_1.oryNpx)(binName)} watch`);
|
|
308
|
+
console.log("");
|
|
309
|
+
console.log(`Drill into any section with:`);
|
|
310
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} agent status`);
|
|
311
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} permissions status`);
|
|
312
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure`);
|
|
313
|
+
});
|
|
306
314
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.8",
|
|
4
4
|
"description": "Ory Argus: the core API for building authentication, authorization, and audit into AI agent harness plugins, extensions, and custom integrations",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|