@ory/argus 0.13.9 → 1.0.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 (133) hide show
  1. package/README.md +31 -45
  2. package/assets/commands/temporal-up.md +1 -1
  3. package/assets/skills/auth-setup/SKILL.md +1 -1
  4. package/assets/skills/local-dev/SKILL.md +17 -7
  5. package/assets/skills/ory-build-agent/SKILL.md +43 -97
  6. package/assets/skills/ory-e2b-sandbox/SKILL.md +18 -18
  7. package/assets/skills/ory-temporal-worker/SKILL.md +38 -42
  8. package/assets/skills/permissions-onboarding/SKILL.md +131 -104
  9. package/dist/adapters.d.ts +93 -30
  10. package/dist/adapters.js +464 -136
  11. package/dist/agent-auth.d.ts +258 -68
  12. package/dist/agent-auth.js +998 -202
  13. package/dist/auth-store.d.ts +37 -2
  14. package/dist/auth-store.js +37 -3
  15. package/dist/auth.d.ts +40 -4
  16. package/dist/auth.js +247 -19
  17. package/dist/bash-parser.d.ts +98 -0
  18. package/dist/bash-parser.js +396 -0
  19. package/dist/branding.d.ts +128 -0
  20. package/dist/branding.js +151 -0
  21. package/dist/build-info.json +4 -4
  22. package/dist/cli-invocation.d.ts +1 -1
  23. package/dist/cli-invocation.js +2 -1
  24. package/dist/cli.d.ts +20 -29
  25. package/dist/cli.js +271 -278
  26. package/dist/client.d.ts +175 -138
  27. package/dist/client.js +672 -391
  28. package/dist/config.d.ts +249 -57
  29. package/dist/config.js +486 -62
  30. package/dist/context.d.ts +10 -0
  31. package/dist/context.js +21 -0
  32. package/dist/contract-suite.d.ts +8 -8
  33. package/dist/contract-suite.js +88 -69
  34. package/dist/denial.d.ts +36 -3
  35. package/dist/denial.js +79 -10
  36. package/dist/event-reporter.d.ts +77 -0
  37. package/dist/event-reporter.js +776 -0
  38. package/dist/external-registrations-main.d.ts +10 -0
  39. package/dist/external-registrations-main.js +38 -0
  40. package/dist/external-registrations.d.ts +79 -0
  41. package/dist/external-registrations.js +188 -0
  42. package/dist/help-cli.d.ts +39 -0
  43. package/dist/help-cli.js +55 -0
  44. package/dist/hook-timeout.d.ts +64 -0
  45. package/dist/hook-timeout.js +88 -0
  46. package/dist/index.d.ts +31 -19
  47. package/dist/index.js +182 -31
  48. package/dist/lifecycle.d.ts +3 -3
  49. package/dist/lifecycle.js +38 -6
  50. package/dist/local/cli.js +11 -6
  51. package/dist/local/configs.d.ts +74 -18
  52. package/dist/local/configs.js +291 -84
  53. package/dist/local/health.d.ts +14 -0
  54. package/dist/local/health.js +50 -4
  55. package/dist/local/index.d.ts +2 -2
  56. package/dist/local/index.js +24 -10
  57. package/dist/local/manager.d.ts +20 -1
  58. package/dist/local/manager.js +160 -39
  59. package/dist/local/ports.d.ts +158 -0
  60. package/dist/local/ports.js +443 -0
  61. package/dist/local/seed.d.ts +22 -25
  62. package/dist/local/seed.js +88 -56
  63. package/dist/logger.d.ts +54 -25
  64. package/dist/logger.js +329 -63
  65. package/dist/mcp.d.ts +2 -2
  66. package/dist/mcp.js +10 -5
  67. package/dist/mirror-bootstrap.d.ts +48 -0
  68. package/dist/mirror-bootstrap.js +254 -0
  69. package/dist/opl.d.ts +289 -0
  70. package/dist/opl.js +446 -0
  71. package/dist/permission-mode.d.ts +87 -0
  72. package/dist/permission-mode.js +307 -0
  73. package/dist/permissions-cli.d.ts +13 -49
  74. package/dist/permissions-cli.js +154 -348
  75. package/dist/permissions.d.ts +148 -38
  76. package/dist/permissions.js +591 -45
  77. package/dist/post-install.d.ts +33 -0
  78. package/dist/post-install.js +127 -0
  79. package/dist/read-credential.d.ts +65 -0
  80. package/dist/read-credential.js +86 -0
  81. package/dist/registry/cli.js +5 -2
  82. package/dist/registry/config.d.ts +0 -17
  83. package/dist/registry/config.js +0 -23
  84. package/dist/registry/index.d.ts +1 -1
  85. package/dist/registry/index.js +2 -2
  86. package/dist/registry/manager.d.ts +4 -21
  87. package/dist/registry/manager.js +83 -55
  88. package/dist/runtime-credential.d.ts +140 -0
  89. package/dist/runtime-credential.js +572 -0
  90. package/dist/runtime.d.ts +408 -0
  91. package/dist/runtime.js +748 -0
  92. package/dist/setup.d.ts +23 -28
  93. package/dist/setup.js +57 -84
  94. package/dist/status-cli.d.ts +29 -13
  95. package/dist/status-cli.js +124 -144
  96. package/dist/status-data.d.ts +195 -0
  97. package/dist/status-data.js +333 -0
  98. package/dist/status-system.d.ts +24 -0
  99. package/dist/status-system.js +56 -0
  100. package/dist/subject.d.ts +126 -20
  101. package/dist/subject.js +215 -30
  102. package/dist/testing.d.ts +74 -38
  103. package/dist/testing.js +185 -68
  104. package/dist/tool-catalog.d.ts +53 -11
  105. package/dist/tool-catalog.js +164 -13
  106. package/dist/tool-metadata.d.ts +7 -6
  107. package/dist/tool-metadata.js +6 -5
  108. package/dist/types.d.ts +11 -1
  109. package/dist/uninstall.d.ts +74 -19
  110. package/dist/uninstall.js +224 -49
  111. package/dist/user-login.d.ts +22 -16
  112. package/dist/user-login.js +67 -96
  113. package/dist/watch-cli.d.ts +6 -0
  114. package/dist/watch-cli.js +217 -0
  115. package/package.json +3 -11
  116. package/dist/dev.d.ts +0 -103
  117. package/dist/dev.js +0 -584
  118. package/dist/interactive-setup.d.ts +0 -165
  119. package/dist/interactive-setup.js +0 -1546
  120. package/dist/local/jaeger-main.d.ts +0 -13
  121. package/dist/local/jaeger-main.js +0 -85
  122. package/dist/local/jaeger.d.ts +0 -50
  123. package/dist/local/jaeger.js +0 -162
  124. package/dist/otel/exporter.d.ts +0 -17
  125. package/dist/otel/exporter.js +0 -12
  126. package/dist/otel/index.d.ts +0 -2
  127. package/dist/otel/index.js +0 -8
  128. package/dist/otel/otlp.d.ts +0 -103
  129. package/dist/otel/otlp.js +0 -385
  130. package/dist/tracer.d.ts +0 -190
  131. package/dist/tracer.js +0 -481
  132. package/dist/watch-sandbox.d.ts +0 -9
  133. package/dist/watch-sandbox.js +0 -81
@@ -2,18 +2,16 @@
2
2
  /**
3
3
  * Seed the local Ory environment with test data for development.
4
4
  *
5
- * Creates two principals:
5
+ * Creates the **User** (`user@ory-local.dev`) — a human identity with a
6
+ * known password (printed by the launcher) and an OAuth2
7
+ * `authorization_code` + PKCE client registered against the loopback
8
+ * redirect URIs. The launcher always runs the real PKCE browser flow; the
9
+ * user types these credentials into the login UI to complete the flow.
6
10
  *
7
- * 1. **Agent** (`agent@ory-local.dev`) a Kratos identity that the
8
- * harness will register a DCR OAuth2 client *for* on first session
9
- * start. No OAuth2 client is pre-registered here.
10
- *
11
- * 2. **User** (`user@ory-local.dev`) — a human identity with a known
12
- * password (printed by the launcher) and an OAuth2
13
- * `authorization_code` + PKCE client registered against the
14
- * loopback redirect URIs. The launcher always runs the real PKCE
15
- * browser flow; the user types these credentials into the login
16
- * UI to complete the flow.
11
+ * No agent principal is seeded: the harness self-registers a DCR OAuth2
12
+ * client for the agent on first session start (using the user's bearer as
13
+ * the initial access token), and permission checks are made against the
14
+ * user subject — so a pre-seeded agent Kratos identity would be unused.
17
15
  *
18
16
  * Permission tuples are written as SubjectSet `User:<identity.id>` so
19
17
  * the Console's *Add relationship* dialog (which always emits SubjectSet
@@ -28,27 +26,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
28
26
  exports.USER_SUBJECT_NAMESPACE = exports.USER_CLIENT_ID = void 0;
29
27
  exports.seedLocalEnvironment = seedLocalEnvironment;
30
28
  const auth_js_1 = require("../auth.js");
29
+ const branding_js_1 = require("../branding.js");
31
30
  const tool_catalog_js_1 = require("../tool-catalog.js");
31
+ const subject_js_1 = require("../subject.js");
32
+ const opl_js_1 = require("../opl.js");
32
33
  const configs_js_1 = require("./configs.js");
33
- const KRATOS_ADMIN = `http://localhost:${configs_js_1.KRATOS_ADMIN_PORT}`;
34
- const KETO_WRITE = `http://localhost:${configs_js_1.KETO_WRITE_PORT}`;
35
- const HYDRA_ADMIN = `http://localhost:${configs_js_1.HYDRA_ADMIN_PORT}`;
36
- const AGENT_EMAIL = "agent@ory-local.dev";
37
- const AGENT_PASSWORD = "ory-agent-local-dev-password!";
34
+ const ports_js_1 = require("./ports.js");
35
+ const health_js_1 = require("./health.js");
36
+ const KRATOS_ADMIN = (0, ports_js_1.hostUrl)(configs_js_1.LOCAL_STACK_HOST, configs_js_1.KRATOS_ADMIN_PORT);
37
+ const KETO_WRITE = (0, ports_js_1.hostUrl)(configs_js_1.LOCAL_STACK_HOST, configs_js_1.KETO_WRITE_PORT);
38
+ const HYDRA_ADMIN = (0, ports_js_1.hostUrl)(configs_js_1.LOCAL_STACK_HOST, configs_js_1.HYDRA_ADMIN_PORT);
38
39
  const USER_EMAIL = "user@ory-local.dev";
39
40
  const USER_PASSWORD = "ory-user-local-dev-password!";
40
- const USER_CLIENT_NAME = "ory-agent-plugins-local-user";
41
41
  /**
42
- * Stable client id Hydra issues to the seeded user PKCE client. Stable
43
- * so `local configure` can persist it to the shared config and downstream
44
- * runs can rely on `ORY_OAUTH2_CLIENT_ID` resolution without first
42
+ * The client id Hydra issues to the seeded user PKCE client: the same
43
+ * **reserved** id Ory Network's Agent Security setup uses, so local dev and a
44
+ * hosted project name the shared login client identically and the id — never a
45
+ * `client_name` — is what resolves it in both.
46
+ *
47
+ * Stable, so `local configure` can persist it to the shared config and
48
+ * downstream runs can rely on `ORY_OAUTH2_CLIENT_ID` resolution without first
45
49
  * dragging the value out of the `local up` banner.
46
50
  */
47
- exports.USER_CLIENT_ID = "ory-user-local";
51
+ exports.USER_CLIENT_ID = branding_js_1.USER_LOGIN_CLIENT_ID;
48
52
  /**
49
- * Tools the dev launcher seeds tuples for. Sourced from the shared
50
- * per-harness catalog so a single seed grants the local user identity
51
- * `use` on every harness's built-in tool set.
53
+ * Tools the explicit local-stack command seeds tuples for. Sourced from the
54
+ * shared catalog so one seed covers every harness's built-in tool set.
52
55
  */
53
56
  const COMMON_TOOLS = tool_catalog_js_1.ALL_TOOLS;
54
57
  async function jsonFetch(url, opts = {}) {
@@ -85,8 +88,12 @@ async function seedIdentity(email, password, name) {
85
88
  }));
86
89
  return { id: identity.id, email };
87
90
  }
88
- /** Subject namespace for user identities in seeded permission tuples. */
89
- exports.USER_SUBJECT_NAMESPACE = "User";
91
+ /**
92
+ * Subject namespace for user identities in seeded permission tuples. Re-exported
93
+ * from the core default so the seed, the runtime resolver, and the persisted
94
+ * install config all address the user under the same namespace.
95
+ */
96
+ exports.USER_SUBJECT_NAMESPACE = subject_js_1.DEFAULT_USER_SUBJECT_NAMESPACE;
90
97
  /**
91
98
  * Write permission tuples granting the user identity access to all
92
99
  * common tools. The subject is written as a SubjectSet
@@ -94,16 +101,16 @@ exports.USER_SUBJECT_NAMESPACE = "User";
94
101
  * dialog — which only emits SubjectSet subjects — can recreate the same
95
102
  * tuple by hand during the runbook walkthrough.
96
103
  */
97
- async function seedPermissions(userId, namespace) {
104
+ async function seedPermissions(userId, namespace, objects = COMMON_TOOLS) {
98
105
  let created = 0;
99
- for (const tool of COMMON_TOOLS) {
106
+ for (const object of objects) {
100
107
  try {
101
108
  await jsonFetch(`${KETO_WRITE}/admin/relation-tuples`, {
102
109
  method: "PUT",
103
110
  body: JSON.stringify({
104
111
  namespace,
105
- object: tool,
106
- relation: "use",
112
+ object,
113
+ relation: opl_js_1.RELATION_USERS,
107
114
  subject_set: {
108
115
  namespace: exports.USER_SUBJECT_NAMESPACE,
109
116
  object: userId,
@@ -116,7 +123,7 @@ async function seedPermissions(userId, namespace) {
116
123
  catch (err) {
117
124
  const msg = err instanceof Error ? err.message : String(err);
118
125
  if (!msg.includes("409")) {
119
- process.stderr.write(` Warning: failed to create permission for ${tool}: ${msg}\n`);
126
+ process.stderr.write(` Warning: failed to create permission for ${object}: ${msg}\n`);
120
127
  }
121
128
  else {
122
129
  created++;
@@ -126,25 +133,29 @@ async function seedPermissions(userId, namespace) {
126
133
  return created;
127
134
  }
128
135
  /**
129
- * Delete a Hydra OAuth2 client if it exists, then create it with a
130
- * known client_id/secret. We always recreate so the launcher knows the
131
- * exact credentials to inject into the harness env.
136
+ * Delete a Hydra OAuth2 client if it exists, then create it at a known
137
+ * client_id (with a known secret, for a confidential client). We always
138
+ * recreate so the launcher knows the exact credentials to inject into the
139
+ * harness env.
140
+ *
141
+ * The client is addressed **by id**, never by `client_name`. That mirrors how
142
+ * Ory Network resolves the shared login client — the name is a display label
143
+ * anyone can register a client under, so only the reserved id identifies it
144
+ * (see `USER_LOGIN_CLIENT_ID`) — so local dev cannot pass with a lookup shape
145
+ * that would be unsafe against a hosted project.
132
146
  */
133
147
  async function ensureOAuth2Client(spec) {
134
- // Look up by client_name; delete if present so we can recreate with a
135
- // deterministic secret.
136
- const existing = (await jsonFetch(`${HYDRA_ADMIN}/admin/clients?client_name=${encodeURIComponent(spec.clientName)}`));
137
- for (const c of existing) {
138
- if (c.client_name !== spec.clientName)
139
- continue;
140
- try {
141
- await jsonFetch(`${HYDRA_ADMIN}/admin/clients/${encodeURIComponent(c.client_id)}`, {
142
- method: "DELETE",
143
- });
144
- }
145
- catch {
146
- // best-effort cleanup
147
- }
148
+ // Delete the client at this id if one is already there, so the recreate
149
+ // below lands with the exact grants, scopes, and redirect URIs this seed
150
+ // declares. A 404 (nothing to delete) is the normal first-run case.
151
+ try {
152
+ await jsonFetch(`${HYDRA_ADMIN}/admin/clients/${encodeURIComponent(spec.clientId)}`, {
153
+ method: "DELETE",
154
+ });
155
+ }
156
+ catch {
157
+ // best-effort cleanup — absent, or Hydra refused; the create below reports
158
+ // the real problem if there is one.
148
159
  }
149
160
  const body = {
150
161
  client_id: spec.clientId,
@@ -177,12 +188,24 @@ function loopbackRedirectUris() {
177
188
  * Returns a `SeedResult` describing both identities, the user's
178
189
  * pre-minted session, and the OAuth2 clients registered for each.
179
190
  */
180
- async function seedLocalEnvironment(namespace = "AgentTools") {
191
+ async function seedLocalEnvironment(namespace = "AgentTool") {
181
192
  process.stderr.write("Seeding local Ory environment...\n\n");
182
- // 1. Identities
183
- process.stderr.write(" Creating agent identity...\n");
184
- const agentIdentity = await seedIdentity(AGENT_EMAIL, AGENT_PASSWORD, "Local Agent");
185
- process.stderr.write(` Agent: ${agentIdentity.id} (${agentIdentity.email})\n`);
193
+ // 0. Readiness barrier. The seed writes directly to Kratos (admin),
194
+ // Keto (write), and Hydra (admin). Neither the static nginx gateway
195
+ // `/health` nor `docker compose up -d --wait` (the Ory containers
196
+ // declare no healthcheck) proves those APIs are actually serving, so
197
+ // on a cold start the writes can race ahead of the services and
198
+ // silently create no identities or permission tuples. Block until all
199
+ // three report ready before touching them.
200
+ process.stderr.write(" Waiting for backend services to be ready...\n");
201
+ const readiness = await (0, health_js_1.waitForSeedTargets)();
202
+ if (!readiness.ready) {
203
+ throw new Error(`backend services not ready before seed: ${readiness.pending.join(", ")} ` +
204
+ `did not report ready within the timeout. The stack may still be starting — retry in a moment.`);
205
+ }
206
+ // 1. User identity. No agent identity is seeded — the harness
207
+ // self-registers a DCR OAuth2 client for the agent on first session
208
+ // start, and permission checks target the user subject.
186
209
  process.stderr.write(" Creating user identity...\n");
187
210
  const userIdentity = await seedIdentity(USER_EMAIL, USER_PASSWORD, "Local User");
188
211
  process.stderr.write(` User: ${userIdentity.id} (${userIdentity.email})\n`);
@@ -194,6 +217,14 @@ async function seedLocalEnvironment(namespace = "AgentTools") {
194
217
  process.stderr.write(` Creating permissions for ${COMMON_TOOLS.length} tools...\n`);
195
218
  const tupleCount = await seedPermissions(userIdentity.id, namespace);
196
219
  process.stderr.write(` Permissions: ${tupleCount} entries in '${namespace}' for ${subjectLabel}\n`);
220
+ // Shell-command sub-tools (issue #76): grant every catalog word in the
221
+ // ShellTool namespace so a launched harness can run `bash -c "curl …"`
222
+ // out of the box, and the enforce demo (revoke `ShellTool:curl#users`,
223
+ // watch it block) works without hand-writing tuples first.
224
+ const shellWords = (0, tool_catalog_js_1.getShellCommandCatalog)();
225
+ const shellNamespace = (0, tool_catalog_js_1.resolveShellCommandNamespace)();
226
+ const shellCount = await seedPermissions(userIdentity.id, shellNamespace, shellWords);
227
+ process.stderr.write(` Shell commands: ${shellCount} entries in '${shellNamespace}' for ${subjectLabel}\n`);
197
228
  // 3. User OAuth2 client (PKCE) — pre-registered so the user gate's
198
229
  // PKCE flow has somewhere to authenticate against. The agent's
199
230
  // OAuth2 client is intentionally NOT pre-registered; the harness
@@ -202,13 +233,15 @@ async function seedLocalEnvironment(namespace = "AgentTools") {
202
233
  let userClient = { clientId: exports.USER_CLIENT_ID };
203
234
  try {
204
235
  userClient = await ensureOAuth2Client({
205
- clientName: USER_CLIENT_NAME,
236
+ // Display label only, matching what a hosted project shows in the
237
+ // Console — the client is addressed by its id.
238
+ clientName: branding_js_1.USER_LOGIN_CLIENT_NAME,
206
239
  clientId: exports.USER_CLIENT_ID,
207
240
  // Public PKCE client — no secret. Hydra accepts an empty string
208
241
  // for `token_endpoint_auth_method=none`.
209
242
  grantTypes: ["authorization_code", "refresh_token"],
210
243
  responseTypes: ["code"],
211
- scope: "openid offline_access",
244
+ scope: branding_js_1.USER_LOGIN_SCOPE_OAUTH,
212
245
  tokenEndpointAuthMethod: "none",
213
246
  redirectUris: loopbackRedirectUris(),
214
247
  });
@@ -219,7 +252,6 @@ async function seedLocalEnvironment(namespace = "AgentTools") {
219
252
  process.stderr.write(` Warning: user OAuth2 client registration failed: ${msg}\n`);
220
253
  }
221
254
  return {
222
- agent: { identity: agentIdentity },
223
255
  user: { identity: userIdentity, password: USER_PASSWORD, client: userClient },
224
256
  permissions: { namespace, subject: subjectLabel, tuples: tupleCount },
225
257
  };
package/dist/logger.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export type ActivityStatus = "ok" | "error" | "denied" | "skipped";
2
3
  export interface LogEntry {
3
4
  timestamp: string;
4
5
  level: LogLevel;
@@ -6,45 +7,73 @@ export interface LogEntry {
6
7
  harness: string;
7
8
  data?: Record<string, unknown>;
8
9
  }
9
- /**
10
- * Recursively redact sensitive values from a structured log payload.
11
- * The original object is not modified.
12
- */
10
+ export interface ActivityEntry {
11
+ timestamp: string;
12
+ level: "activity";
13
+ event: string;
14
+ harness: string;
15
+ status: ActivityStatus;
16
+ durationMs: number;
17
+ sessionId?: string;
18
+ attributes?: Record<string, unknown>;
19
+ }
20
+ export type UnifiedLogEntry = LogEntry | ActivityEntry;
21
+ export type ActivityEnricher = () => Record<string, unknown> | undefined;
22
+ export type ActivitySink = (entry: ActivityEntry) => void;
13
23
  export declare function redactLogData(value: unknown): unknown;
24
+ export declare function activityValueHash(value: string): string;
25
+ /** Convert arbitrary strings to correlation-safe summaries for always-on activity. */
26
+ export declare function sanitizeActivityAttributes(attributes: Record<string, unknown>): Record<string, unknown>;
27
+ export declare class ActiveActivity {
28
+ private readonly logger;
29
+ private readonly event;
30
+ private readonly baseAttributes?;
31
+ private readonly sessionId?;
32
+ private readonly startedAt;
33
+ private readonly timestamp;
34
+ private endedEntry;
35
+ constructor(logger: DebugLogger, event: string, baseAttributes?: Record<string, unknown> | undefined, sessionId?: string | undefined);
36
+ get ended(): boolean;
37
+ end(status: ActivityStatus, attributes?: Record<string, unknown>): ActivityEntry;
38
+ }
14
39
  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
40
  static stderrSuppressed: boolean;
24
41
  enabled: boolean;
25
- harness: string;
26
- logFile: string | null;
42
+ readonly harness: string;
43
+ readonly logFile: string | null;
44
+ private readonly activityEntries;
45
+ private activityEnricher;
46
+ private activitySink;
27
47
  constructor(harness: string, opts?: {
28
48
  logFile?: string;
29
49
  });
30
50
  get isEnabled(): boolean;
31
51
  enable(): void;
32
52
  disable(): void;
53
+ setActivityEnricher(enricher: ActivityEnricher | null): void;
54
+ setActivitySink(sink: ActivitySink | null): void;
55
+ activities(): ReadonlyArray<ActivityEntry>;
56
+ startActivity(event: string, attributes?: Record<string, unknown>, sessionId?: string): ActiveActivity;
57
+ activity(event: string, status: ActivityStatus, options?: {
58
+ attributes?: Record<string, unknown>;
59
+ durationMs?: number;
60
+ sessionId?: string;
61
+ timestamp?: string;
62
+ }): ActivityEntry;
33
63
  log(level: LogLevel, event: string, data?: Record<string, unknown>): void;
34
64
  debug(event: string, data?: Record<string, unknown>): void;
35
65
  info(event: string, data?: Record<string, unknown>): void;
36
66
  warn(event: string, data?: Record<string, unknown>): void;
37
67
  error(event: string, data?: Record<string, unknown>): void;
68
+ private writeToStderr;
69
+ private writeToFile;
70
+ }
71
+ export interface FormattedLogEntryParts {
72
+ time: string;
73
+ event: string;
74
+ marker: string;
75
+ details: string[];
38
76
  }
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
- */
77
+ export declare function formatLogEntryParts(entry: UnifiedLogEntry): FormattedLogEntryParts;
78
+ export declare function formatLogEntry(entry: UnifiedLogEntry): string;
50
79
  export declare function withQuietStderr<T>(fn: () => Promise<T> | T): Promise<T>;