@ory/argus 0.14.0 → 1.0.1

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 +413 -0
  90. package/dist/runtime.js +825 -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
@@ -1,507 +0,0 @@
1
- "use strict";
2
- /**
3
- * Headless setup actions — the prompt-free, presentation-free core of the
4
- * install walkthrough, driven by the local web installer's JSON API (and
5
- * reusable anywhere the interactive TTY wizard's step *decisions* live outside
6
- * the process, e.g. in a browser).
7
- *
8
- * Each function performs exactly one step of the same flow the TTY wizard in
9
- * {@link file://./interactive-setup.ts} runs — sign in, pick / create a
10
- * workspace and project, enable DCR, provision the OAuth2 client, grant tool
11
- * permissions, provision the project API key — but returns a plain result
12
- * object instead of prompting or printing. The heavy lifting (CLI arg shapes,
13
- * OPL model inspection/merge, Console-API key minting) is imported from
14
- * `interactive-setup.ts` so there is a single source of truth for it; only the
15
- * thin, prompt-free orchestration lives here.
16
- *
17
- * Everything is fail-open: an action never throws for an expected failure
18
- * (CLI error, network blip, missing session) — it returns `{ ok: false }` with
19
- * a short message the UI can surface.
20
- */
21
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
- if (k2 === undefined) k2 = k;
23
- var desc = Object.getOwnPropertyDescriptor(m, k);
24
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
- desc = { enumerable: true, get: function() { return m[k]; } };
26
- }
27
- Object.defineProperty(o, k2, desc);
28
- }) : (function(o, m, k, k2) {
29
- if (k2 === undefined) k2 = k;
30
- o[k2] = m[k];
31
- }));
32
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
- Object.defineProperty(o, "default", { enumerable: true, value: v });
34
- }) : function(o, v) {
35
- o["default"] = v;
36
- });
37
- var __importStar = (this && this.__importStar) || (function () {
38
- var ownKeys = function(o) {
39
- ownKeys = Object.getOwnPropertyNames || function (o) {
40
- var ar = [];
41
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
- return ar;
43
- };
44
- return ownKeys(o);
45
- };
46
- return function (mod) {
47
- if (mod && mod.__esModule) return mod;
48
- var result = {};
49
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
- __setModuleDefault(result, mod);
51
- return result;
52
- };
53
- })();
54
- Object.defineProperty(exports, "__esModule", { value: true });
55
- exports.PROJECT_CAP = void 0;
56
- exports.resolveNamespace = resolveNamespace;
57
- exports.ensureOryCli = ensureOryCli;
58
- exports.isSignedIn = isSignedIn;
59
- exports.startSignIn = startSignIn;
60
- exports.listWorkspaces = listWorkspaces;
61
- exports.createWorkspace = createWorkspace;
62
- exports.listProjects = listProjects;
63
- exports.createProject = createProject;
64
- exports.resolveProjectUrl = resolveProjectUrl;
65
- exports.getDcrState = getDcrState;
66
- exports.enableDcrAction = enableDcrAction;
67
- exports.ensureManagedLoginUi = ensureManagedLoginUi;
68
- exports.resolveIdentityName = resolveIdentityName;
69
- exports.resourceUserLabel = resourceUserLabel;
70
- exports.provisionOAuth2Client = provisionOAuth2Client;
71
- exports.saveNetworkConfig = saveNetworkConfig;
72
- exports.runFullSetup = runFullSetup;
73
- exports.inspectPermissions = inspectPermissions;
74
- exports.provisionPermissions = provisionPermissions;
75
- exports.grantToolPermissions = grantToolPermissions;
76
- exports.provisionProjectApiKey = provisionProjectApiKey;
77
- exports.configureAuditOnly = configureAuditOnly;
78
- exports.setPermissionMode = setPermissionMode;
79
- exports.configureLocalStack = configureLocalStack;
80
- const node_child_process_1 = require("node:child_process");
81
- const interactive_setup_js_1 = require("./interactive-setup.js");
82
- const project_api_key_js_1 = require("./project-api-key.js");
83
- const config_js_1 = require("./config.js");
84
- const branding_js_1 = require("./branding.js");
85
- const auth_js_1 = require("./auth.js");
86
- const auth_store_js_1 = require("./auth-store.js");
87
- const tool_catalog_js_1 = require("./tool-catalog.js");
88
- const user_login_js_1 = require("./user-login.js");
89
- const agent_auth_js_1 = require("./agent-auth.js");
90
- const client_js_1 = require("./client.js");
91
- const subject_js_1 = require("./subject.js");
92
- const index_js_1 = require("./local/index.js");
93
- const os = __importStar(require("node:os"));
94
- function resolveNamespace() {
95
- return process.env.ORY_PERMISSION_NAMESPACE ?? "AgentTools";
96
- }
97
- /**
98
- * Ensure the `ory` CLI is available. Probes the default (or injected) runner;
99
- * if the binary isn't on `PATH`, installs `@ory/cli` into a plugin-managed dir
100
- * and returns a runner bound to it. Never throws.
101
- */
102
- async function ensureOryCli(deps = {}) {
103
- const runner = deps.runner ?? (0, interactive_setup_js_1.createOryRunner)("ory");
104
- if ((0, interactive_setup_js_1.oryCliPresent)(runner))
105
- return { present: true, installed: false, runner };
106
- const install = deps.installOryCliFn ?? interactive_setup_js_1.installOryCli;
107
- let installed;
108
- try {
109
- installed = await install();
110
- }
111
- catch {
112
- installed = null;
113
- }
114
- return { present: !!installed, installed: !!installed, runner: installed };
115
- }
116
- // ─── sign in ──────────────────────────────────────────────────────────────
117
- /** Whether the `ory` CLI already holds a valid Ory Network session. */
118
- function isSignedIn(runner) {
119
- return runner.exec(["list", "workspaces", "--format", "json"]).status === 0;
120
- }
121
- /**
122
- * Launch the interactive `ory auth` browser sign-in as a detached child so the
123
- * HTTP server's event loop stays free (unlike `runner.exec`, which is
124
- * spawnSync). The Ory CLI opens its own browser window and runs a local
125
- * callback listener; we only watch its exit code. Returns a handle whose
126
- * `done` promise resolves when sign-in completes. Requires `runner.bin`.
127
- */
128
- function startSignIn(runner) {
129
- const bin = runner.bin;
130
- if (!bin) {
131
- return { done: Promise.resolve(false), cancel() { } };
132
- }
133
- const child = (0, node_child_process_1.spawn)(bin, ["auth"], { stdio: "ignore" });
134
- const done = new Promise((resolve) => {
135
- child.on("exit", (code) => resolve(code === 0));
136
- child.on("error", () => resolve(false));
137
- });
138
- return { done, cancel: () => child.kill() };
139
- }
140
- // ─── workspaces & projects ──────────────────────────────────────────────────
141
- function listWorkspaces(runner) {
142
- const r = runner.exec(["list", "workspaces", "--format", "json"]);
143
- if (r.status !== 0)
144
- return null;
145
- return (0, interactive_setup_js_1.parseList)(r.stdout, "workspaces");
146
- }
147
- function createWorkspace(runner, name) {
148
- const r = runner.exec(["create", "workspace", "--name", name, "--format", "json", "--yes"]);
149
- if (r.status !== 0)
150
- return { ok: false, error: r.stderr.trim() || "unknown error" };
151
- const workspace = (0, interactive_setup_js_1.parseObject)(r.stdout);
152
- if (!workspace?.id)
153
- return { ok: false, error: "created workspace had no id" };
154
- return { ok: true, value: workspace };
155
- }
156
- function listProjects(runner, workspaceId) {
157
- return (0, interactive_setup_js_1.listProjects)(runner, workspaceId);
158
- }
159
- function createProject(runner, workspaceId, name) {
160
- const r = runner.exec([
161
- "create",
162
- "project",
163
- "--name",
164
- name,
165
- "--workspace",
166
- workspaceId,
167
- "--format",
168
- "json",
169
- "--yes",
170
- ]);
171
- if (r.status !== 0)
172
- return { ok: false, error: r.stderr.trim() || "unknown error" };
173
- const project = (0, interactive_setup_js_1.parseObject)(r.stdout);
174
- if (!project?.id)
175
- return { ok: false, error: "created project had no id" };
176
- return { ok: true, value: project };
177
- }
178
- /** Ory Network Developer-plan project cap per workspace. */
179
- exports.PROJECT_CAP = 2;
180
- /**
181
- * Resolve a project's canonical SDK URL from its slug, refusing a missing slug
182
- * or one that is actually the project id (a UUID) — either would build a URL
183
- * that points nowhere.
184
- */
185
- function resolveProjectUrl(project) {
186
- if (!project.slug || (0, config_js_1.looksLikeProjectId)(project.slug)) {
187
- return { ok: false, error: "could not resolve the project slug (needed for the SDK URL)" };
188
- }
189
- try {
190
- return { ok: true, value: (0, interactive_setup_js_1.projectUrlFromSlug)(project.slug) };
191
- }
192
- catch (err) {
193
- return { ok: false, error: err instanceof Error ? err.message : String(err) };
194
- }
195
- }
196
- // ─── DCR & OAuth2 client ──────────────────────────────────────────────────
197
- /** Current DCR state: true/false when known, null when it couldn't be read. */
198
- function getDcrState(runner, projectId) {
199
- return (0, interactive_setup_js_1.dcrEnabled)(runner, projectId);
200
- }
201
- /** Enable DCR on the project. Returns true on success. */
202
- function enableDcrAction(runner, projectId) {
203
- return (0, interactive_setup_js_1.enableDcr)(runner, projectId);
204
- }
205
- /**
206
- * Ensure the project's OAuth2 login/consent UI works for a hosted browser
207
- * login. A CLI-created project defaults these to the `localhost:3000`
208
- * quickstart sample; this clears them so the Ory Managed Account Experience
209
- * renders the login instead. Returns the resulting state so the UI can report
210
- * it: `managed` (fixed or already managed), `custom_external` (a deliberate
211
- * custom UI, left as-is), or `unknown` (couldn't read the config).
212
- */
213
- function ensureManagedLoginUi(runner, projectId) {
214
- const state = (0, interactive_setup_js_1.projectLoginUiState)(runner, projectId);
215
- if (state === "loopback") {
216
- return (0, interactive_setup_js_1.useManagedAccountExperience)(runner, projectId) ? "managed" : "unknown";
217
- }
218
- return state;
219
- }
220
- /**
221
- * Best-effort human-readable name for a signed-in identity, resolved via the
222
- * admin `ory` CLI (`ory get identity`). The PKCE login's id_token carries only
223
- * an opaque subject id under the default `openid` scope, so rather than show a
224
- * UUID we look the identity up by id and read a display trait (email → username
225
- * → name). Returns undefined on any CLI/parse failure so callers fall back to
226
- * the id.
227
- */
228
- function resolveIdentityName(runner, projectId, subjectId) {
229
- const r = runner.exec([
230
- "get",
231
- "identity",
232
- subjectId,
233
- "--project",
234
- projectId,
235
- "--format",
236
- "json",
237
- ]);
238
- if (r.status !== 0)
239
- return undefined;
240
- const identity = (0, interactive_setup_js_1.parseObject)(r.stdout);
241
- return displayNameFromTraits(identity?.traits);
242
- }
243
- /** Pull a display name out of a Kratos identity's traits (best-effort). */
244
- function displayNameFromTraits(traits) {
245
- if (!traits || typeof traits !== "object")
246
- return undefined;
247
- const t = traits;
248
- if (typeof t.email === "string" && t.email.trim())
249
- return t.email.trim();
250
- if (typeof t.username === "string" && t.username.trim())
251
- return t.username.trim();
252
- const name = t.name;
253
- if (typeof name === "string" && name.trim())
254
- return name.trim();
255
- if (name && typeof name === "object") {
256
- const n = name;
257
- const parts = [n.first, n.last].filter((x) => typeof x === "string" && x.trim().length > 0);
258
- if (parts.length)
259
- return parts.join(" ");
260
- }
261
- return undefined;
262
- }
263
- /**
264
- * Readable label for a signed-in user when naming a resource (e.g. a project
265
- * API key), so a shared project's resource list shows an email/username rather
266
- * than an opaque `user:<uuid>`. Looks the identity up via the admin CLI and
267
- * falls back to the subject label when no name resolves (no runner, or the
268
- * lookup fails). The raw subject id is read from either subject shape.
269
- */
270
- function resourceUserLabel(runner, projectId, subject) {
271
- const sid = "subjectId" in subject ? subject.subjectId : subject.subjectSet.object;
272
- const name = runner ? resolveIdentityName(runner, projectId, sid) : undefined;
273
- return name ?? (0, subject_js_1.subjectLabel)(subject);
274
- }
275
- /**
276
- * Find or create the public PKCE OAuth2 client the user login needs. Reuses an
277
- * existing plugin-provisioned client on the project so a re-run never mints a
278
- * duplicate.
279
- */
280
- function provisionOAuth2Client(runner, projectId) {
281
- const existing = (0, interactive_setup_js_1.findExistingOAuth2Client)(runner, projectId);
282
- if (existing)
283
- return { ok: true, clientId: existing, name: branding_js_1.USER_LOGIN_CLIENT_NAME, reused: true };
284
- const clientId = (0, interactive_setup_js_1.createOAuth2Client)(runner, projectId);
285
- return {
286
- ok: !!clientId,
287
- clientId: clientId ?? undefined,
288
- name: branding_js_1.USER_LOGIN_CLIENT_NAME,
289
- reused: false,
290
- };
291
- }
292
- /** Persist the resolved Ory Network connection and enable the user login. */
293
- function saveNetworkConfig(input) {
294
- (0, config_js_1.saveConfig)({
295
- projectUrl: input.projectUrl,
296
- projectId: input.projectId,
297
- projectName: input.projectName,
298
- workspaceName: input.workspaceName,
299
- oauth2ClientId: input.oauth2ClientId,
300
- auditOnly: false,
301
- });
302
- }
303
- /**
304
- * Run the PKCE user login (opens a browser and awaits the loopback callback)
305
- * and resolve the agent DCR identity, so the next session is fully wired.
306
- * Best-effort: a declined or failed login just reports `authenticated: false`.
307
- *
308
- * `target` pins the project the wizard just selected. The login gate resolves
309
- * its URL/client id through `resolveConfig()`, which is **env-first** — so a
310
- * stale `ORY_PROJECT_URL` / `ORY_SDK_URL` / `ORY_OAUTH2_CLIENT_ID` left in the
311
- * user's shell (e.g. `http://localhost:3000` from a local app) would otherwise
312
- * override the project they just picked and launch the browser at the wrong
313
- * URL. During install the fresh selection is ground truth, so we pin it into
314
- * the environment for the login. (The process exits after install, so this
315
- * doesn't leak into a long-lived session.)
316
- */
317
- async function runFullSetup(binName, harness, deps = {}, target = {}) {
318
- const clientFactory = deps.clientFactory ?? client_js_1.OryAgentClient.fromEnv;
319
- const userLogin = deps.userLoginFn ?? user_login_js_1.ensureUserAuthenticated;
320
- const agentGate = deps.agentGateFn ?? agent_auth_js_1.ensureAgentIdentity;
321
- // Scoped to the login call (restored after) so a stale ORY_PROJECT_URL /
322
- // ORY_OAUTH2_CLIENT_ID can't override the selected project, and the override
323
- // doesn't leak past the login — later steps address the project by id.
324
- const prevUrl = process.env.ORY_PROJECT_URL;
325
- const prevClient = process.env.ORY_OAUTH2_CLIENT_ID;
326
- if (target.projectUrl)
327
- process.env.ORY_PROJECT_URL = target.projectUrl;
328
- if (target.oauth2ClientId)
329
- process.env.ORY_OAUTH2_CLIENT_ID = target.oauth2ClientId;
330
- try {
331
- const client = clientFactory(harness);
332
- const decision = await userLogin(client, { binName, harness });
333
- await agentGate(client, { harness });
334
- const authenticated = decision.proceed && !!decision.subject;
335
- const subject = authenticated ? (0, subject_js_1.resolveUserSubject)(client) : null;
336
- const usable = subject && (0, subject_js_1.subjectLabel)(subject) !== "agent:unknown" ? subject : null;
337
- // Prefer a human-readable name (email/name) from the login's id_token over
338
- // the opaque subject id, so the UI shows who signed in rather than a UUID.
339
- const displayName = usable ? (0, auth_js_1.displayNameFromIdToken)((0, auth_store_js_1.loadTokens)()?.idToken) : undefined;
340
- return {
341
- authenticated,
342
- subject: usable,
343
- subjectLabel: usable ? (displayName ?? (0, subject_js_1.subjectLabel)(usable)) : null,
344
- };
345
- }
346
- catch {
347
- return { authenticated: false, subject: null, subjectLabel: null };
348
- }
349
- finally {
350
- if (prevUrl === undefined)
351
- delete process.env.ORY_PROJECT_URL;
352
- else
353
- process.env.ORY_PROJECT_URL = prevUrl;
354
- if (prevClient === undefined)
355
- delete process.env.ORY_OAUTH2_CLIENT_ID;
356
- else
357
- process.env.ORY_OAUTH2_CLIENT_ID = prevClient;
358
- }
359
- }
360
- /** Inspect how the project's permission model relates to the namespace. */
361
- async function inspectPermissions(runner, projectId, namespace = resolveNamespace()) {
362
- const model = await (0, interactive_setup_js_1.inspectPermissionModel)(runner, projectId, namespace);
363
- return model.kind === "merge" ? { model: "merge", opl: model.opl } : { model: model.kind };
364
- }
365
- /**
366
- * Provision (or merge) the namespace into the project's permission model.
367
- * Pass `opl` (from a prior `inspectPermissions` "merge" result) to append the
368
- * namespace non-destructively; omit it to create a fresh minimal model.
369
- */
370
- function provisionPermissions(runner, projectId, namespace = resolveNamespace(), opl) {
371
- return (0, interactive_setup_js_1.provisionPermissionModel)(runner, projectId, namespace, opl);
372
- }
373
- /**
374
- * Grant `<subject>` the `use` relation on every built-in tool by writing the
375
- * relation tuples through the admin-authenticated `ory` CLI. Assumes the
376
- * namespace already exists (call {@link inspectPermissions} /
377
- * {@link provisionPermissions} first).
378
- */
379
- function grantToolPermissions(runner, projectId, harness, subject, namespace = resolveNamespace()) {
380
- const tools = (0, tool_catalog_js_1.getToolCatalog)(harness);
381
- if (tools.length === 0)
382
- return { ok: true, count: 0 };
383
- const subjectPatch = "subjectSet" in subject
384
- ? {
385
- subject_set: {
386
- namespace: subject.subjectSet.namespace,
387
- object: subject.subjectSet.object,
388
- relation: subject.subjectSet.relation,
389
- },
390
- }
391
- : { subject_id: subject.subjectId };
392
- const tuples = tools.map((object) => ({ namespace, object, relation: "use", ...subjectPatch }));
393
- const r = runner.exec(["create", "relationships", "--project", projectId, "--format", "json", "-f", "-", "--yes"], { input: JSON.stringify(tuples) });
394
- if (r.status === 0)
395
- return { ok: true, count: tools.length };
396
- return { ok: false, count: 0, error: r.stderr.trim().split("\n")[0] || "unknown error" };
397
- }
398
- /**
399
- * Ensure a valid project API key is stored for runtime permission *checks*.
400
- * No-ops for an env-provided key; validates a stored key and re-mints if it is
401
- * dead; otherwise mints one via the Console API and persists it. Best-effort.
402
- */
403
- async function provisionProjectApiKey(input, deps = {}) {
404
- const createFn = deps.createProjectApiKeyFn ?? project_api_key_js_1.createProjectApiKeyViaConsole;
405
- const validateFn = deps.validateApiKeyFn ?? interactive_setup_js_1.apiKeyAuthenticates;
406
- const resolved = (0, config_js_1.resolveConfig)();
407
- if (resolved.apiKey) {
408
- if (resolved.apiKeySource === "env")
409
- return { status: "env" };
410
- if (await validateFn(resolved.apiKey, input.projectUrl))
411
- return { status: "valid_existing" };
412
- }
413
- let host = "unknown-host";
414
- try {
415
- host = os.hostname();
416
- }
417
- catch {
418
- /* keep fallback */
419
- }
420
- let created = null;
421
- try {
422
- // Named for the signed-in user + host so a shared project's key list (every
423
- // user mints their own) stays attributable and prunable; the Console's
424
- // "Date Added" column supplies the timestamp.
425
- created = await createFn({
426
- projectId: input.projectId,
427
- name: (0, branding_js_1.projectApiKeyName)({ host, user: input.user }),
428
- });
429
- }
430
- catch {
431
- created = null;
432
- }
433
- if (created) {
434
- // Persist the token id too so uninstall can delete the key server-side.
435
- (0, config_js_1.saveConfig)({ apiKey: created.value, apiKeyId: created.id ?? null });
436
- return { status: "created" };
437
- }
438
- return { status: "failed" };
439
- }
440
- // ─── audit-only & local stack ─────────────────────────────────────────────
441
- /** Configure audit-only mode (no project, no auth, no checks). */
442
- function configureAuditOnly() {
443
- (0, config_js_1.saveConfig)({ auditOnly: true });
444
- }
445
- // ─── dashboard toggles ────────────────────────────────────────────────────
446
- /** Set the permission deny posture — `observe` (log) vs `enforce` (block). */
447
- function setPermissionMode(mode) {
448
- (0, config_js_1.saveConfig)({ permissionMode: mode });
449
- }
450
- /**
451
- * Bring up and seed the local Ory stack, persisting the (stable) local
452
- * connection details regardless of whether Docker came up. Mirrors the TTY
453
- * wizard's local branch minus the login (the UI drives {@link runFullSetup}
454
- * separately). Best-effort throughout.
455
- */
456
- async function configureLocalStack(deps = {}) {
457
- const bringUp = deps.localStackFn ?? index_js_1.ensureLocalOryStack;
458
- const seed = deps.seedFn ?? index_js_1.seedLocalEnvironment;
459
- let status;
460
- let detail;
461
- try {
462
- const stack = await bringUp();
463
- status = stack.status;
464
- detail = stack.detail;
465
- }
466
- catch (err) {
467
- status = "compose-failed";
468
- detail = err instanceof Error ? err.message : String(err);
469
- }
470
- const running = status === "started" || status === "already-running";
471
- (0, config_js_1.saveConfig)({
472
- projectUrl: index_js_1.GATEWAY_URL,
473
- oauth2ClientId: index_js_1.USER_CLIENT_ID,
474
- userSubjectNamespace: index_js_1.USER_SUBJECT_NAMESPACE,
475
- auditOnly: false,
476
- // The local stack is not an Ory Network project — clear any workspace /
477
- // project identifiers left over from a previous Network connection so they
478
- // don't linger in config or surface in the dashboard (null deletes the key).
479
- projectId: null,
480
- projectName: null,
481
- workspaceName: null,
482
- });
483
- const base = {
484
- running,
485
- detail: running ? undefined : detail ?? status,
486
- seeded: false,
487
- projectUrl: index_js_1.GATEWAY_URL,
488
- oauth2ClientId: index_js_1.USER_CLIENT_ID,
489
- subjectNamespace: index_js_1.USER_SUBJECT_NAMESPACE,
490
- };
491
- if (!running)
492
- return base;
493
- try {
494
- const result = await seed();
495
- return {
496
- ...base,
497
- seeded: true,
498
- credentials: {
499
- email: result.user.identity.email,
500
- password: result.user.password,
501
- },
502
- };
503
- }
504
- catch (err) {
505
- return { ...base, seedError: err instanceof Error ? err.message : String(err) };
506
- }
507
- }