@ory/argus 0.14.0 → 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 (150) hide show
  1. package/README.md +31 -46
  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 +39 -91
  6. package/assets/skills/ory-e2b-sandbox/SKILL.md +18 -17
  7. package/assets/skills/ory-temporal-worker/SKILL.md +31 -33
  8. package/assets/skills/permissions-onboarding/SKILL.md +131 -104
  9. package/dist/adapters.d.ts +88 -32
  10. package/dist/adapters.js +443 -164
  11. package/dist/agent-auth.d.ts +226 -67
  12. package/dist/agent-auth.js +951 -205
  13. package/dist/auth-store.d.ts +37 -2
  14. package/dist/auth-store.js +37 -3
  15. package/dist/auth.d.ts +33 -4
  16. package/dist/auth.js +163 -20
  17. package/dist/bash-parser.d.ts +98 -0
  18. package/dist/bash-parser.js +396 -0
  19. package/dist/branding.d.ts +77 -16
  20. package/dist/branding.js +93 -23
  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 -239
  26. package/dist/client.d.ts +175 -138
  27. package/dist/client.js +672 -391
  28. package/dist/config.d.ts +217 -54
  29. package/dist/config.js +461 -42
  30. package/dist/context.d.ts +10 -0
  31. package/dist/context.js +21 -0
  32. package/dist/contract-suite.d.ts +3 -5
  33. package/dist/contract-suite.js +75 -47
  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 +28 -23
  47. package/dist/index.js +173 -58
  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.js +7 -7
  54. package/dist/local/index.d.ts +2 -2
  55. package/dist/local/index.js +24 -10
  56. package/dist/local/manager.d.ts +20 -1
  57. package/dist/local/manager.js +159 -36
  58. package/dist/local/ports.d.ts +158 -0
  59. package/dist/local/ports.js +443 -0
  60. package/dist/local/seed.d.ts +13 -5
  61. package/dist/local/seed.js +62 -38
  62. package/dist/logger.d.ts +54 -25
  63. package/dist/logger.js +329 -63
  64. package/dist/mcp.d.ts +2 -2
  65. package/dist/mcp.js +10 -5
  66. package/dist/mirror-bootstrap.d.ts +48 -0
  67. package/dist/mirror-bootstrap.js +254 -0
  68. package/dist/opl.d.ts +289 -0
  69. package/dist/opl.js +446 -0
  70. package/dist/permission-mode.d.ts +87 -0
  71. package/dist/permission-mode.js +307 -0
  72. package/dist/permissions-cli.d.ts +13 -49
  73. package/dist/permissions-cli.js +154 -348
  74. package/dist/permissions.d.ts +148 -38
  75. package/dist/permissions.js +591 -45
  76. package/dist/post-install.d.ts +33 -0
  77. package/dist/post-install.js +127 -0
  78. package/dist/read-credential.d.ts +65 -0
  79. package/dist/read-credential.js +86 -0
  80. package/dist/registry/cli.js +5 -2
  81. package/dist/registry/config.d.ts +0 -17
  82. package/dist/registry/config.js +0 -23
  83. package/dist/registry/index.d.ts +1 -1
  84. package/dist/registry/index.js +2 -2
  85. package/dist/registry/manager.d.ts +4 -21
  86. package/dist/registry/manager.js +21 -37
  87. package/dist/runtime-credential.d.ts +140 -0
  88. package/dist/runtime-credential.js +572 -0
  89. package/dist/runtime.d.ts +408 -0
  90. package/dist/runtime.js +748 -0
  91. package/dist/setup.d.ts +23 -47
  92. package/dist/setup.js +59 -116
  93. package/dist/skills.js +0 -7
  94. package/dist/status-cli.d.ts +27 -11
  95. package/dist/status-cli.js +121 -115
  96. package/dist/status-data.d.ts +116 -17
  97. package/dist/status-data.js +121 -38
  98. package/dist/subject.d.ts +126 -20
  99. package/dist/subject.js +215 -30
  100. package/dist/testing.d.ts +74 -38
  101. package/dist/testing.js +185 -68
  102. package/dist/tool-catalog.d.ts +53 -11
  103. package/dist/tool-catalog.js +164 -13
  104. package/dist/tool-metadata.d.ts +7 -6
  105. package/dist/tool-metadata.js +6 -5
  106. package/dist/types.d.ts +11 -1
  107. package/dist/uninstall.d.ts +71 -34
  108. package/dist/uninstall.js +217 -85
  109. package/dist/user-login.d.ts +9 -10
  110. package/dist/user-login.js +56 -75
  111. package/dist/watch-cli.d.ts +6 -0
  112. package/dist/watch-cli.js +217 -0
  113. package/package.json +4 -27
  114. package/assets/commands/dashboard.md +0 -34
  115. package/dist/dashboard-cli.d.ts +0 -8
  116. package/dist/dashboard-cli.js +0 -70
  117. package/dist/dev.d.ts +0 -103
  118. package/dist/dev.js +0 -583
  119. package/dist/interactive-setup.d.ts +0 -286
  120. package/dist/interactive-setup.js +0 -1734
  121. package/dist/local/jaeger-main.d.ts +0 -13
  122. package/dist/local/jaeger-main.js +0 -85
  123. package/dist/local/jaeger.d.ts +0 -50
  124. package/dist/local/jaeger.js +0 -162
  125. package/dist/otel/exporter.d.ts +0 -17
  126. package/dist/otel/exporter.js +0 -12
  127. package/dist/otel/index.d.ts +0 -2
  128. package/dist/otel/index.js +0 -8
  129. package/dist/otel/otlp.d.ts +0 -103
  130. package/dist/otel/otlp.js +0 -385
  131. package/dist/project-api-key.d.ts +0 -69
  132. package/dist/project-api-key.js +0 -147
  133. package/dist/setup-actions.d.ts +0 -232
  134. package/dist/setup-actions.js +0 -507
  135. package/dist/tracer.d.ts +0 -190
  136. package/dist/tracer.js +0 -481
  137. package/dist/watch-sandbox.d.ts +0 -9
  138. package/dist/watch-sandbox.js +0 -81
  139. package/dist/web/api.d.ts +0 -33
  140. package/dist/web/api.js +0 -294
  141. package/dist/web/launch.d.ts +0 -11
  142. package/dist/web/launch.js +0 -96
  143. package/dist/web/server.d.ts +0 -20
  144. package/dist/web/server.js +0 -233
  145. package/dist/web/types.d.ts +0 -65
  146. package/dist/web/types.js +0 -2
  147. package/dist/webapp/assets/index-Wucl4SZs.css +0 -1
  148. package/dist/webapp/assets/index-m-GtEdq0.js +0 -49
  149. package/dist/webapp/favicon.ico +0 -0
  150. package/dist/webapp/index.html +0 -15
package/dist/uninstall.js CHANGED
@@ -2,132 +2,264 @@
2
2
  /**
3
3
  * Config teardown shared by every plugin's `uninstall` command.
4
4
  *
5
- * Uninstalling a plugin wipes the shared config file completely every
6
- * value is removed, both *authentication* state (user tokens, agent DCR
7
- * credentials, static API key) and *configuration* (project URL, OAuth2
8
- * client id, audit mode, permission mode, user-login flag). The file is
9
- * left as an empty object, so a later re-install starts from a clean
10
- * slate rather than inheriting any stale state.
5
+ * `config.json` is a **single shared file** every installed harness plugin
6
+ * reads, so teardown is scoped: uninstalling one plugin must not knock the
7
+ * others back to an unconfigured state. Two scopes exist, and which one runs is
8
+ * decided from the install registry, not from a flag the caller guesses at:
11
9
  *
12
- * What is removed:
10
+ * - **`harness` scope** — other plugins are still installed. Only the
11
+ * departing harness's own identities go: the agent and sub-agent DCR
12
+ * clients of **every session it retains** are revoked (RFC 7592), and its
13
+ * entries are removed from `agent.dynamic` / `agent.subAgents`. Shared
14
+ * state — `projectUrl`, `oauth2ClientId`, the user's tokens, the permission
15
+ * mode — is left exactly as it was.
16
+ * - **`all` scope** — the departing harness was the last one installed, or
17
+ * the caller passed `purge: true`. Every harness's clients are revoked and
18
+ * the config file is left as an empty object, so a re-install starts from a
19
+ * clean slate rather than inheriting stale state.
20
+ *
21
+ * What an `all` teardown removes:
13
22
  * - the user's persisted OAuth2 tokens (`user`)
14
- * - the agent's dynamic-registration credentials and every sub-agent
15
- * registration (`agent`)
16
- * - the operator-supplied static agent API key (`apiKey`)
23
+ * - every harness's agent and sub-agent registrations, across all sessions
24
+ * (`agent`)
17
25
  * - all configuration values (`projectUrl`, `projectId`, `projectName`,
18
- * `workspaceName`, `oauth2ClientId`, `auditOnly`, `permissionMode`,
19
- * `userLogin`, `userSubjectNamespace`)
26
+ * `workspaceName`, `oauth2ClientId`, `permissionModeCache`,
27
+ * `userSubjectNamespace`, `installedHarnesses`)
20
28
  * - any dangling PKCE-flight lock
21
29
  *
22
- * Server-side teardown runs first, best-effort:
23
- * - Each dynamically-registered OAuth2 client (the agent and every
24
- * sub-agent) is revoked via RFC 7592, so the Ory project isn't left
25
- * with orphaned clients accumulating across install/uninstall cycles.
26
- * - The project API key the installer minted is deleted via the Ory
27
- * Console API (addressed by the persisted token id).
30
+ * Server-side teardown runs first, best-effort, and covers exactly the
31
+ * resources the plugin itself created: each dynamically-registered OAuth2
32
+ * client in scope (the agent and every sub-agent, for every retained session)
33
+ * is revoked via RFC 7592, so the Ory project isn't left with orphaned clients
34
+ * accumulating across install/uninstall cycles.
28
35
  *
29
- * The one server-side resource deliberately **left behind** is the shared
30
- * user-login PKCE OAuth2 client (`oauth2ClientId`): it is a public,
31
- * identity-free client that every user and every harness install on the
32
- * project reuses, so deleting it would break other installations. It is
33
- * only forgotten locally (its id is wiped from the config file). Every
34
- * server-side step is best-effort: failures warn and local state is
35
- * cleared regardless.
36
+ * Nothing in the project's **permission** state is touched. Grants, blocks,
37
+ * delegation edges, and the permission model are provisioned in the Ory
38
+ * Console (Agent Security) and owned there the plugin has no Keto write
39
+ * path to unwind them with, and deleting an admin's grants on uninstall was
40
+ * never its call to make. The shared user-login PKCE OAuth2 client
41
+ * (`oauth2ClientId`) is likewise left in place: it is a public, identity-free
42
+ * client that every user and every harness install on the project reuses, so
43
+ * deleting it would break other installations. Both are only forgotten
44
+ * locally. Every server-side step is best-effort: failures warn and local
45
+ * state is cleared regardless.
36
46
  */
47
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
48
+ if (k2 === undefined) k2 = k;
49
+ var desc = Object.getOwnPropertyDescriptor(m, k);
50
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
51
+ desc = { enumerable: true, get: function() { return m[k]; } };
52
+ }
53
+ Object.defineProperty(o, k2, desc);
54
+ }) : (function(o, m, k, k2) {
55
+ if (k2 === undefined) k2 = k;
56
+ o[k2] = m[k];
57
+ }));
58
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
59
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
60
+ }) : function(o, v) {
61
+ o["default"] = v;
62
+ });
63
+ var __importStar = (this && this.__importStar) || (function () {
64
+ var ownKeys = function(o) {
65
+ ownKeys = Object.getOwnPropertyNames || function (o) {
66
+ var ar = [];
67
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
68
+ return ar;
69
+ };
70
+ return ownKeys(o);
71
+ };
72
+ return function (mod) {
73
+ if (mod && mod.__esModule) return mod;
74
+ var result = {};
75
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
76
+ __setModuleDefault(result, mod);
77
+ return result;
78
+ };
79
+ })();
37
80
  Object.defineProperty(exports, "__esModule", { value: true });
81
+ exports.resolveInstalledHarnesses = resolveInstalledHarnesses;
38
82
  exports.clearCredentialsForUninstall = clearCredentialsForUninstall;
83
+ const fs = __importStar(require("node:fs"));
39
84
  const config_js_1 = require("./config.js");
40
85
  const agent_auth_js_1 = require("./agent-auth.js");
41
86
  const auth_store_js_1 = require("./auth-store.js");
42
- const project_api_key_js_1 = require("./project-api-key.js");
87
+ const runtime_js_1 = require("./runtime.js");
43
88
  /**
44
- * Wipe the shared config file completely every value, both credentials
45
- * and configuration revoking dynamically-registered clients server-side
46
- * first. The file is left as an empty object. Never throws.
89
+ * The harness plugins installed against the shared config, reconciled from
90
+ * every source that evidences one.
91
+ *
92
+ * The `installedHarnesses` registry is authoritative, but it only exists on
93
+ * configs written since it was introduced. Treating its absence as "nothing is
94
+ * installed" would make the first uninstall on an upgraded machine wipe the
95
+ * config every other plugin depends on — precisely the failure being fixed. So
96
+ * the runtime manifest (what each harness has wired) and the persisted
97
+ * credentials (which harnesses hold an identity) are folded in as evidence.
98
+ */
99
+ function resolveInstalledHarnesses(config = (0, config_js_1.loadConfig)()) {
100
+ const names = new Set(config.installedHarnesses ?? []);
101
+ for (const harness of Object.keys((0, runtime_js_1.readRuntimeManifest)().harnesses))
102
+ names.add(harness);
103
+ for (const harness of Object.keys(config.agent?.dynamic ?? {}))
104
+ names.add(harness);
105
+ for (const harness of Object.keys(config.agent?.subAgents ?? {}))
106
+ names.add(harness);
107
+ return [...names].sort();
108
+ }
109
+ /**
110
+ * Tear down the departing harness's state, wiping the whole shared config only
111
+ * when nothing else still depends on it. Dynamically-registered clients in
112
+ * scope are revoked server-side first. Never throws.
47
113
  */
48
114
  async function clearCredentialsForUninstall(options = {}) {
49
115
  const log = options.log ?? ((msg) => console.log(msg));
50
116
  const revoke = options.revoke !== false;
117
+ const harness = options.harness?.trim() || undefined;
51
118
  const config = (0, config_js_1.loadConfig)();
52
- const dynamic = config.agent?.dynamic;
119
+ // Drop the departing harness from the registry first, so what remains is
120
+ // exactly the set of plugins that still need the shared config. Without a
121
+ // harness to attribute this uninstall to, nothing can be scoped — fall back
122
+ // to a full wipe.
123
+ const remainingHarnesses = harness
124
+ ? resolveInstalledHarnesses(config).filter((h) => h !== harness)
125
+ : [];
126
+ // Only write when there is something to remove — an uninstall against an
127
+ // already-empty config should not create a config file just to say so.
128
+ if (harness && config.installedHarnesses?.includes(harness)) {
129
+ (0, config_js_1.unregisterInstalledHarness)(harness);
130
+ }
131
+ const scope = harness && !options.purge && remainingHarnesses.length > 0 ? "harness" : "all";
132
+ const dynamic = config.agent?.dynamic ?? {};
53
133
  const subAgents = config.agent?.subAgents ?? {};
54
- const subAgentEntries = Object.entries(subAgents);
55
- const hadCredentials = Boolean(config.user || dynamic || subAgentEntries.length > 0 || config.apiKey);
134
+ const hadCredentials = Boolean(config.user ||
135
+ Object.keys(dynamic).length > 0 ||
136
+ Object.keys(subAgents).length > 0 ||
137
+ (config.agent?.retired?.length ?? 0) > 0);
56
138
  if (Object.keys(config).length === 0) {
57
139
  log("No Ory configuration to remove.");
58
- return { hadCredentials: false, revoked: 0, revokeFailures: 0, apiKeyDeleted: false };
140
+ return {
141
+ hadCredentials: false,
142
+ scope,
143
+ remainingHarnesses,
144
+ revoked: 0,
145
+ revokeFailures: 0,
146
+ };
147
+ }
148
+ // The clients this uninstall owns: this harness's on a scoped teardown, every
149
+ // harness's on a full one, across every retained session and child identity.
150
+ const inScope = (h) => scope === "all" || h === harness;
151
+ const targets = [];
152
+ for (const [h, bySession] of Object.entries(dynamic)) {
153
+ if (!inScope(h))
154
+ continue;
155
+ for (const [session, creds] of Object.entries(bySession)) {
156
+ targets.push({ label: `agent client (${h}/${session})`, creds });
157
+ }
158
+ }
159
+ for (const [h, bySession] of Object.entries(subAgents)) {
160
+ if (!inScope(h))
161
+ continue;
162
+ for (const [session, byType] of Object.entries(bySession)) {
163
+ for (const [type, creds] of Object.entries(byType)) {
164
+ targets.push({ label: `sub-agent client (${h}/${session}/${type})`, creds });
165
+ }
166
+ }
167
+ }
168
+ // Retention preserves the harness on retired records, so scoped teardown can
169
+ // revoke its own queue entries. Historical records without a harness remain
170
+ // unattributable and are swept only by a full teardown.
171
+ for (const creds of config.agent?.retired ?? []) {
172
+ if (scope === "all" || creds.harness === harness) {
173
+ targets.push({ label: "retired agent client", creds });
174
+ }
59
175
  }
60
176
  let revoked = 0;
61
177
  let revokeFailures = 0;
62
- let apiKeyDeleted = false;
63
178
  if (revoke) {
64
- const targets = [];
65
- if (dynamic) {
66
- targets.push({
67
- label: "agent client",
68
- clientId: dynamic.clientId,
69
- result: () => (0, agent_auth_js_1.revokeAgentDynamicClient)(dynamic),
70
- });
71
- }
72
- for (const [type, creds] of subAgentEntries) {
73
- targets.push({
74
- label: `sub-agent client (${type})`,
75
- clientId: creds.clientId,
76
- result: () => (0, agent_auth_js_1.revokeAgentDynamicClient)(creds),
77
- });
78
- }
79
179
  for (const target of targets) {
80
- const outcome = await target.result();
180
+ const outcome = await (0, agent_auth_js_1.revokeAgentDynamicClient)(target.creds);
81
181
  if (outcome.status === "deleted") {
82
182
  revoked++;
83
- log(` Revoked ${target.label} ${target.clientId}.`);
183
+ log(` Revoked ${target.label} ${target.creds.clientId}.`);
84
184
  }
85
185
  else if (outcome.status === "skipped") {
86
186
  // No management credentials to DELETE with — nothing we can do
87
187
  // server-side. Not counted as a failure.
88
- log(` Could not revoke ${target.label} ${target.clientId} server-side (${outcome.message}). Clearing local state anyway.`);
188
+ log(` Could not revoke ${target.label} ${target.creds.clientId} server-side (${outcome.message}). Clearing local state anyway.`);
89
189
  }
90
190
  else {
91
191
  revokeFailures++;
92
192
  const detail = typeof outcome.httpStatus === "number"
93
193
  ? `HTTP ${outcome.httpStatus}`
94
194
  : (outcome.message ?? "unknown error");
95
- log(` Warning: server-side revoke of ${target.label} ${target.clientId} failed (${detail}). Clearing local state anyway.`);
195
+ log(` Warning: server-side revoke of ${target.label} ${target.creds.clientId} failed (${detail}). Clearing local state anyway.`);
96
196
  }
97
197
  }
98
- // Delete the project API key the installer minted. Deletion addresses the
99
- // token by its id (its secret value can't be used), so it needs both the
100
- // project id and the persisted token id. A key present without a tracked id
101
- // (minted before id-tracking, or supplied by hand via `configure --api-key`)
102
- // can't be removed automatically warn so it can be pruned in the Console.
103
- if (config.apiKey) {
104
- if (config.projectId && config.apiKeyId) {
105
- const outcome = await (0, project_api_key_js_1.deleteProjectApiKeyViaConsole)({
106
- projectId: config.projectId,
107
- tokenId: config.apiKeyId,
108
- });
109
- if (outcome.status === "deleted") {
110
- apiKeyDeleted = true;
111
- log(" Deleted the project API key.");
112
- }
113
- else if (outcome.status === "skipped") {
114
- log(` Could not delete the project API key (${outcome.message}). Clearing local state anyway.`);
115
- }
116
- else {
117
- const detail = typeof outcome.httpStatus === "number"
118
- ? `HTTP ${outcome.httpStatus}`
119
- : (outcome.message ?? "unknown error");
120
- log(` Warning: server-side deletion of the project API key failed (${detail}). Clearing local state anyway.`);
121
- }
198
+ }
199
+ // The departing harness's asset tree (its skill/command trees, plus its
200
+ // unified activity/debug log) is state uniquely attributable to it, so
201
+ // it goes with the harness in either scope. On a full teardown every
202
+ // harness's tree goes, since the config they belong to is being wiped.
203
+ for (const h of scope === "all" ? resolveInstalledHarnesses(config) : [harness]) {
204
+ removeHarnessDataDir(h, log);
205
+ }
206
+ if (scope === "all") {
207
+ // Wipe the entire config file — credentials and configuration alike.
208
+ (0, config_js_1.mutateConfig)(() => ({}));
209
+ (0, auth_store_js_1.clearPkceFlightLock)();
210
+ log("Removed all Ory configuration and credentials.");
211
+ }
212
+ else {
213
+ (0, agent_auth_js_1.clearAgentDynamicCredentials)(harness);
214
+ (0, agent_auth_js_1.clearSubAgentDynamicCredentialsForHarness)(harness);
215
+ (0, config_js_1.mutateConfig)((current) => {
216
+ const next = { ...current };
217
+ if (current.agent?.retired) {
218
+ const agent = { ...current.agent };
219
+ agent.retired = current.agent.retired.filter((creds) => creds.harness !== harness);
220
+ if (agent.retired.length === 0)
221
+ delete agent.retired;
222
+ next.agent = agent;
122
223
  }
123
- else {
124
- log(" The stored project API key has no tracked token id — remove it manually in the Ory Console if it's no longer needed. Clearing local state anyway.");
224
+ if (current.delegationAnchors?.[harness]) {
225
+ const anchors = { ...current.delegationAnchors };
226
+ delete anchors[harness];
227
+ if (Object.keys(anchors).length > 0)
228
+ next.delegationAnchors = anchors;
229
+ else
230
+ delete next.delegationAnchors;
125
231
  }
126
- }
232
+ return next;
233
+ });
234
+ log(`Removed the ${harness} agent identities. Shared Ory configuration is kept for: ${remainingHarnesses.join(", ")}.`);
235
+ log(" Re-run with --purge to wipe the shared configuration and every harness's credentials.");
236
+ }
237
+ return {
238
+ hadCredentials,
239
+ scope,
240
+ remainingHarnesses,
241
+ revoked,
242
+ revokeFailures,
243
+ };
244
+ }
245
+ /**
246
+ * Remove a harness's asset tree under `<dataDir>/<harness>/`.
247
+ *
248
+ * Best-effort: the tree holds the harness's own skill/command assets plus its
249
+ * unified activity/debug log, and the log may still be open in this very
250
+ * process (or locked, on Windows). A failure to remove observability output is
251
+ * never a reason to fail an uninstall.
252
+ */
253
+ function removeHarnessDataDir(harness, log) {
254
+ const dir = (0, config_js_1.getHarnessDataDir)(harness);
255
+ try {
256
+ if (!fs.existsSync(dir))
257
+ return;
258
+ fs.rmSync(dir, { recursive: true, force: true });
259
+ log(` Removed ${harness} assets at ${dir}.`);
260
+ }
261
+ catch (err) {
262
+ const message = err instanceof Error ? err.message : String(err);
263
+ log(` Warning: could not remove ${dir} (${message}). Continuing.`);
127
264
  }
128
- // Wipe the entire config file — credentials and configuration alike.
129
- (0, config_js_1.mutateConfig)(() => ({}));
130
- (0, auth_store_js_1.clearPkceFlightLock)();
131
- log("Removed all Ory configuration and credentials.");
132
- return { hadCredentials, revoked, revokeFailures, apiKeyDeleted };
133
265
  }
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * 1. Resolve config (env + ~/.config/ory-agent-plugins/config.json).
6
6
  * 2. If no project URL, prompt for one when a TTY is available;
7
- * otherwise skip with an audit span.
7
+ * otherwise skip with an audit event.
8
8
  * 3. If a session/oauth2 token is already in env, short-circuit ok.
9
9
  * 4. If persisted tokens are valid, return ok.
10
10
  * 5. If they are expired with a refresh_token, refresh.
@@ -14,7 +14,7 @@
14
14
  * paste the URL into any browser that can reach 127.0.0.1. Only
15
15
  * truly unattended (CI=true) environments short-circuit early.
16
16
  *
17
- * Every terminal path emits exactly one `user.auth` trace span so that
17
+ * Every terminal path emits exactly one `user.auth` activity event so that
18
18
  * the audit trail is complete regardless of outcome.
19
19
  *
20
20
  * The flow runs on **every** session and is **never** blocking: it
@@ -22,8 +22,10 @@
22
22
  * and permission-subject resolution, but a failure to authenticate never
23
23
  * stops the session. Enforcement is governed solely by `permissionMode`
24
24
  * (observe/enforce) at tool-call time — see `checkAndDecide`. The one
25
- * exception is `auditOnly`, which disables auth entirely (mode
26
- * `audit_only`). When the user can't be authenticated the session still
25
+ * exception is Agent Security not being connected at all (no project URL
26
+ * and OAuth2 client id), in which case there is nothing to sign in to and
27
+ * the flow no-ops with mode `not_connected`. When the user can't be
28
+ * authenticated the session still
27
29
  * proceeds; under `enforce` a missing user identity naturally denies at
28
30
  * the tool (no matching tuples), and under `observe` it is audited.
29
31
  *
@@ -34,13 +36,12 @@
34
36
  */
35
37
  import { OryAgentClient } from "./client.js";
36
38
  import { type OryOAuth2Tokens } from "./config.js";
37
- import { promptForProjectUrl } from "./cli.js";
38
39
  import { pkceLogin } from "./auth.js";
39
- export type UserLoginMode = "audit_only" | "env_token" | "ok" | "refreshed" | "skipped" | "declined" | "error";
40
+ export type UserLoginMode = "not_connected" | "env_token" | "ok" | "refreshed" | "skipped" | "declined" | "error";
40
41
  export interface UserLoginOptions {
41
42
  /** Bin name used in user-facing prompts (e.g. "ory-claude"). */
42
43
  binName: string;
43
- /** Logical harness name (used by the tracer). */
44
+ /** Logical harness name used for activity attribution. */
44
45
  harness: string;
45
46
  /**
46
47
  * Optional override of the PKCE login function — used by tests and by
@@ -49,8 +50,6 @@ export interface UserLoginOptions {
49
50
  loginFn?: typeof pkceLogin;
50
51
  /** Override TTY detection (for tests). */
51
52
  isTtyAvailableFn?: () => boolean;
52
- /** Override the prompt-for-URL step (for tests). */
53
- promptForProjectUrlFn?: typeof promptForProjectUrl;
54
53
  }
55
54
  export interface UserLoginDecision {
56
55
  /**
@@ -60,7 +59,7 @@ export interface UserLoginDecision {
60
59
  * `permissionMode` at tool-call time, not here.
61
60
  */
62
61
  proceed: boolean;
63
- /** Stable mode identifier for telemetry and tests. */
62
+ /** Stable mode identifier for activity logging and tests. */
64
63
  mode: UserLoginMode;
65
64
  /** Human-readable reason; safe to surface to the operator. */
66
65
  reason: string;