@ory/argus 0.9.1 → 0.11.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.
- package/assets/skills/auth-setup/SKILL.md +3 -1
- package/assets/skills/login-flow/SKILL.md +118 -4
- package/dist/adapters.d.ts +104 -0
- package/dist/adapters.js +216 -0
- package/dist/agent-auth.js +33 -0
- package/dist/config.js +35 -3
- package/dist/contract-suite.d.ts +87 -0
- package/dist/contract-suite.js +239 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +9 -1
- package/dist/lifecycle.js +130 -0
- package/dist/local/configs.d.ts +2 -2
- package/dist/local/configs.js +10 -1
- package/dist/local/manager.d.ts +6 -4
- package/dist/local/manager.js +91 -16
- package/dist/permissions.d.ts +36 -8
- package/dist/permissions.js +62 -7
- package/dist/subject.d.ts +13 -1
- package/dist/subject.js +29 -2
- package/dist/testing.d.ts +214 -0
- package/dist/testing.js +372 -0
- package/dist/tool-catalog.d.ts +7 -0
- package/dist/tool-catalog.js +73 -0
- package/dist/user-login.js +7 -2
- package/package.json +1 -1
package/dist/testing.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared test utilities for Ory agent plugin integration tests.
|
|
4
|
+
*
|
|
5
|
+
* These helpers provide mock Ory API responses, error factories, and
|
|
6
|
+
* common assertion patterns so that harness plugin tests focus on
|
|
7
|
+
* harness-specific behavior rather than duplicating boilerplate.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.BATCH_SERVER_DENIED = exports.BATCH_SERVER_ALLOWED_TOOL_DENIED = exports.BATCH_BOTH_ALLOWED = exports.PERMISSION_DENIED = exports.PERMISSION_ALLOWED = exports.MOCK_INACTIVE_OAUTH2_RESPONSE = exports.MOCK_OAUTH2_RESPONSE = exports.MOCK_INACTIVE_SESSION_RESPONSE = exports.MOCK_SESSION_RESPONSE = exports.runHarnessContractSuite = void 0;
|
|
44
|
+
exports.createMockClient = createMockClient;
|
|
45
|
+
exports.stubApi = stubApi;
|
|
46
|
+
exports.makeAxiosError = makeAxiosError;
|
|
47
|
+
exports.makeNetworkError = makeNetworkError;
|
|
48
|
+
exports.makeRateLimitError = makeRateLimitError;
|
|
49
|
+
exports.makeMfaRequiredError = makeMfaRequiredError;
|
|
50
|
+
exports.makeSessionInactiveError = makeSessionInactiveError;
|
|
51
|
+
exports.getTraceSpans = getTraceSpans;
|
|
52
|
+
exports.expectTracedTools = expectTracedTools;
|
|
53
|
+
exports.setOryEnv = setOryEnv;
|
|
54
|
+
exports.useTempConfigDir = useTempConfigDir;
|
|
55
|
+
exports.clearOryEnv = clearOryEnv;
|
|
56
|
+
exports.stubSessionSuccess = stubSessionSuccess;
|
|
57
|
+
exports.stubSessionInactive = stubSessionInactive;
|
|
58
|
+
exports.stubSessionNetworkError = stubSessionNetworkError;
|
|
59
|
+
exports.stubSessionMfaRequired = stubSessionMfaRequired;
|
|
60
|
+
exports.stubSessionExpired = stubSessionExpired;
|
|
61
|
+
exports.stubOAuth2Success = stubOAuth2Success;
|
|
62
|
+
exports.stubOAuth2Inactive = stubOAuth2Inactive;
|
|
63
|
+
exports.stubPermissionAllowed = stubPermissionAllowed;
|
|
64
|
+
exports.stubPermissionDenied = stubPermissionDenied;
|
|
65
|
+
exports.stubPermissionNetworkError = stubPermissionNetworkError;
|
|
66
|
+
exports.stubPermissionRateLimited = stubPermissionRateLimited;
|
|
67
|
+
exports.spyRelationshipCreated = spyRelationshipCreated;
|
|
68
|
+
exports.spyRelationshipCreateError = spyRelationshipCreateError;
|
|
69
|
+
exports.stubMcpAllowed = stubMcpAllowed;
|
|
70
|
+
exports.stubMcpServerDenied = stubMcpServerDenied;
|
|
71
|
+
exports.stubMcpToolDenied = stubMcpToolDenied;
|
|
72
|
+
exports.stubMcpNetworkError = stubMcpNetworkError;
|
|
73
|
+
const fs = __importStar(require("node:fs"));
|
|
74
|
+
const os = __importStar(require("node:os"));
|
|
75
|
+
const path = __importStar(require("node:path"));
|
|
76
|
+
const vitest_1 = require("vitest");
|
|
77
|
+
const client_js_1 = require("./client.js");
|
|
78
|
+
// Shared per-harness contract scenarios (session fail-open, gate
|
|
79
|
+
// translation, audit-only). See contract-suite.ts for the adapter shape.
|
|
80
|
+
var contract_suite_js_1 = require("./contract-suite.js");
|
|
81
|
+
Object.defineProperty(exports, "runHarnessContractSuite", { enumerable: true, get: function () { return contract_suite_js_1.runHarnessContractSuite; } });
|
|
82
|
+
// ─── Client Helpers ────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Create an OryAgentClient with session caching disabled.
|
|
85
|
+
* Pass overrides to customize (e.g. a different harness name).
|
|
86
|
+
*/
|
|
87
|
+
function createMockClient(overrides) {
|
|
88
|
+
return new client_js_1.OryAgentClient({
|
|
89
|
+
projectUrl: "https://test.projects.oryapis.com",
|
|
90
|
+
apiKey: "test-api-key",
|
|
91
|
+
harness: "test",
|
|
92
|
+
sessionCacheTtlMs: 0,
|
|
93
|
+
...overrides,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stub an internal API instance method on the client.
|
|
98
|
+
* Returns a vi.fn mock so callers can assert on calls.
|
|
99
|
+
*/
|
|
100
|
+
function stubApi(client, api, method, impl) {
|
|
101
|
+
const instance = client[api];
|
|
102
|
+
instance[method] = vitest_1.vi.fn(impl);
|
|
103
|
+
return instance[method];
|
|
104
|
+
}
|
|
105
|
+
// ─── Mock API Responses ────────────────────────────────────────────
|
|
106
|
+
/** Successful session verification response (wraps Ory API shape). */
|
|
107
|
+
exports.MOCK_SESSION_RESPONSE = {
|
|
108
|
+
data: {
|
|
109
|
+
id: "session-abc",
|
|
110
|
+
active: true,
|
|
111
|
+
authenticated_at: "2026-04-17T10:00:00Z",
|
|
112
|
+
expires_at: "2026-04-18T10:00:00Z",
|
|
113
|
+
authenticator_assurance_level: "aal1",
|
|
114
|
+
authentication_methods: [
|
|
115
|
+
{ method: "password", completed_at: "2026-04-17T10:00:00Z" },
|
|
116
|
+
],
|
|
117
|
+
identity: {
|
|
118
|
+
id: "identity-123",
|
|
119
|
+
traits: { email: "dev@example.com" },
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
/** Inactive session (same shape, active: false). */
|
|
124
|
+
exports.MOCK_INACTIVE_SESSION_RESPONSE = {
|
|
125
|
+
data: { ...exports.MOCK_SESSION_RESPONSE.data, active: false },
|
|
126
|
+
};
|
|
127
|
+
/** Successful OAuth2 token introspection response. */
|
|
128
|
+
exports.MOCK_OAUTH2_RESPONSE = {
|
|
129
|
+
data: {
|
|
130
|
+
active: true,
|
|
131
|
+
client_id: "agent-client",
|
|
132
|
+
sub: "user:alice",
|
|
133
|
+
scope: "tools:invoke",
|
|
134
|
+
aud: ["api"],
|
|
135
|
+
exp: 1700000000,
|
|
136
|
+
iat: 1699999000,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
/** Inactive OAuth2 token response. */
|
|
140
|
+
exports.MOCK_INACTIVE_OAUTH2_RESPONSE = {
|
|
141
|
+
data: { active: false },
|
|
142
|
+
};
|
|
143
|
+
/** Permission check allowed response. */
|
|
144
|
+
exports.PERMISSION_ALLOWED = { data: { allowed: true } };
|
|
145
|
+
/** Permission check denied response. */
|
|
146
|
+
exports.PERMISSION_DENIED = { data: { allowed: false } };
|
|
147
|
+
/** Batch permission check: both results allowed. */
|
|
148
|
+
exports.BATCH_BOTH_ALLOWED = {
|
|
149
|
+
data: { results: [{ allowed: true }, { allowed: true }] },
|
|
150
|
+
};
|
|
151
|
+
/** Batch permission check: server allowed, tool denied. */
|
|
152
|
+
exports.BATCH_SERVER_ALLOWED_TOOL_DENIED = {
|
|
153
|
+
data: { results: [{ allowed: true }, { allowed: false }] },
|
|
154
|
+
};
|
|
155
|
+
/** Batch permission check: server denied. */
|
|
156
|
+
exports.BATCH_SERVER_DENIED = {
|
|
157
|
+
data: { results: [{ allowed: false }, { allowed: true }] },
|
|
158
|
+
};
|
|
159
|
+
// ─── Error Factories ───────────────────────────────────────────────
|
|
160
|
+
/** Create an Axios-shaped error with a response. */
|
|
161
|
+
function makeAxiosError(status, body, code) {
|
|
162
|
+
const err = {
|
|
163
|
+
isAxiosError: true,
|
|
164
|
+
message: `Request failed with status code ${status}`,
|
|
165
|
+
response: { status, data: body ?? {} },
|
|
166
|
+
};
|
|
167
|
+
if (code)
|
|
168
|
+
err.code = code;
|
|
169
|
+
return err;
|
|
170
|
+
}
|
|
171
|
+
/** Create a Node.js network error (ECONNREFUSED, ETIMEDOUT, etc.). */
|
|
172
|
+
function makeNetworkError(code = "ECONNREFUSED") {
|
|
173
|
+
const err = new Error(`connect ${code}`);
|
|
174
|
+
err.code = code;
|
|
175
|
+
return err;
|
|
176
|
+
}
|
|
177
|
+
/** Axios 429 rate-limit error. */
|
|
178
|
+
function makeRateLimitError() {
|
|
179
|
+
return makeAxiosError(429);
|
|
180
|
+
}
|
|
181
|
+
/** Axios 403 with session_aal2_required error id. */
|
|
182
|
+
function makeMfaRequiredError() {
|
|
183
|
+
return makeAxiosError(403, {
|
|
184
|
+
error: { id: "session_aal2_required", message: "MFA required" },
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/** Axios 401 with session_inactive error id. */
|
|
188
|
+
function makeSessionInactiveError() {
|
|
189
|
+
return makeAxiosError(401, {
|
|
190
|
+
error: { id: "session_inactive", message: "No active session" },
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// ─── Trace Span Assertions ────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* Get all recorded trace spans from a client, optionally filtered by event.
|
|
196
|
+
*/
|
|
197
|
+
function getTraceSpans(client, event) {
|
|
198
|
+
const all = client.tracer.spans();
|
|
199
|
+
return event ? all.filter((s) => s.event === event) : all;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Assert the tracer recorded the expected tool names for a given event type.
|
|
203
|
+
* Checks the `toolName` attribute on each span.
|
|
204
|
+
*/
|
|
205
|
+
function expectTracedTools(client, event, expectedTools) {
|
|
206
|
+
const spans = getTraceSpans(client, event);
|
|
207
|
+
const tools = spans.map((s) => s.attributes?.toolName);
|
|
208
|
+
for (const tool of expectedTools) {
|
|
209
|
+
if (!tools.includes(tool)) {
|
|
210
|
+
throw new Error(`Expected trace event "${event}" for tool "${tool}" but got: [${tools.join(", ")}]`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (spans.length !== expectedTools.length) {
|
|
214
|
+
throw new Error(`Expected ${expectedTools.length} "${event}" spans but got ${spans.length}: [${tools.join(", ")}]`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// ─── Environment Helpers ───────────────────────────────────────────
|
|
218
|
+
/**
|
|
219
|
+
* Set standard Ory env vars for a configured + authenticated test.
|
|
220
|
+
* Returns a cleanup function that restores the previous state.
|
|
221
|
+
*/
|
|
222
|
+
function setOryEnv(overrides = {}) {
|
|
223
|
+
const saved = {};
|
|
224
|
+
const vars = {
|
|
225
|
+
ORY_PROJECT_URL: "projectUrl" in overrides
|
|
226
|
+
? overrides.projectUrl
|
|
227
|
+
: "https://test.projects.oryapis.com",
|
|
228
|
+
ORY_SESSION_TOKEN: "sessionToken" in overrides ? overrides.sessionToken : "valid-token",
|
|
229
|
+
ORY_OAUTH2_TOKEN: overrides.oauth2Token,
|
|
230
|
+
ORY_AGENT_SUBJECT_ID: overrides.subjectId,
|
|
231
|
+
ORY_PERMISSION_NAMESPACE: overrides.namespace,
|
|
232
|
+
ORY_PERMISSION_MODE: "permissionMode" in overrides ? overrides.permissionMode : "enforce",
|
|
233
|
+
};
|
|
234
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
235
|
+
saved[key] = process.env[key];
|
|
236
|
+
if (value !== undefined) {
|
|
237
|
+
process.env[key] = value;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
delete process.env[key];
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return () => {
|
|
244
|
+
for (const [key, value] of Object.entries(saved)) {
|
|
245
|
+
if (value !== undefined) {
|
|
246
|
+
process.env[key] = value;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
delete process.env[key];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Point `XDG_CONFIG_HOME` at a fresh temp directory so `resolveConfig()`
|
|
256
|
+
* reads from a known-empty state instead of the developer's real
|
|
257
|
+
* `~/.config/ory-agent-plugins/config.json`. Returns a cleanup function
|
|
258
|
+
* that restores the env var and removes the temp directory.
|
|
259
|
+
*
|
|
260
|
+
* Use `saveConfig(...)` from `./config.js` inside the test to shape the
|
|
261
|
+
* isolated config (e.g. `saveConfig({ auditOnly: true })`).
|
|
262
|
+
*/
|
|
263
|
+
function useTempConfigDir() {
|
|
264
|
+
const saved = process.env.XDG_CONFIG_HOME;
|
|
265
|
+
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "ory-test-config-"));
|
|
266
|
+
process.env.XDG_CONFIG_HOME = tmpHome;
|
|
267
|
+
return () => {
|
|
268
|
+
if (saved !== undefined)
|
|
269
|
+
process.env.XDG_CONFIG_HOME = saved;
|
|
270
|
+
else
|
|
271
|
+
delete process.env.XDG_CONFIG_HOME;
|
|
272
|
+
fs.rmSync(tmpHome, { recursive: true, force: true });
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Clear all Ory env vars (simulate unconfigured state).
|
|
277
|
+
*/
|
|
278
|
+
function clearOryEnv() {
|
|
279
|
+
delete process.env.ORY_PROJECT_URL;
|
|
280
|
+
delete process.env.ORY_API_KEY;
|
|
281
|
+
delete process.env.ORY_SESSION_TOKEN;
|
|
282
|
+
delete process.env.ORY_OAUTH2_TOKEN;
|
|
283
|
+
delete process.env.ORY_AGENT_SUBJECT_ID;
|
|
284
|
+
delete process.env.ORY_USER_SUBJECT_ID;
|
|
285
|
+
delete process.env.ORY_USER_SUBJECT_NAMESPACE;
|
|
286
|
+
delete process.env.ORY_PERMISSION_NAMESPACE;
|
|
287
|
+
// Intentionally leave ORY_PERMISSION_MODE alone — it's typically set
|
|
288
|
+
// once at the top of a test file to pin the historical enforce-mode
|
|
289
|
+
// behavior, and unconfigured-Ory tests don't exercise permission
|
|
290
|
+
// checks anyway.
|
|
291
|
+
}
|
|
292
|
+
// ─── Stub Presets ──────────────────────────────────────────────────
|
|
293
|
+
/** Stub verifySession to succeed. */
|
|
294
|
+
function stubSessionSuccess(client) {
|
|
295
|
+
return stubApi(client, "frontend", "toSession", () => Promise.resolve(exports.MOCK_SESSION_RESPONSE));
|
|
296
|
+
}
|
|
297
|
+
/** Stub verifySession to return inactive. */
|
|
298
|
+
function stubSessionInactive(client) {
|
|
299
|
+
return stubApi(client, "frontend", "toSession", () => Promise.resolve(exports.MOCK_INACTIVE_SESSION_RESPONSE));
|
|
300
|
+
}
|
|
301
|
+
/** Stub verifySession to throw a network error. */
|
|
302
|
+
function stubSessionNetworkError(client) {
|
|
303
|
+
return stubApi(client, "frontend", "toSession", () => Promise.reject(makeNetworkError()));
|
|
304
|
+
}
|
|
305
|
+
/** Stub verifySession to throw MFA required. */
|
|
306
|
+
function stubSessionMfaRequired(client) {
|
|
307
|
+
return stubApi(client, "frontend", "toSession", () => Promise.reject(makeMfaRequiredError()));
|
|
308
|
+
}
|
|
309
|
+
/** Stub verifySession to throw session_inactive. */
|
|
310
|
+
function stubSessionExpired(client) {
|
|
311
|
+
return stubApi(client, "frontend", "toSession", () => Promise.reject(makeSessionInactiveError()));
|
|
312
|
+
}
|
|
313
|
+
/** Stub introspectToken to succeed. */
|
|
314
|
+
function stubOAuth2Success(client) {
|
|
315
|
+
return stubApi(client, "oauth2", "introspectOAuth2Token", () => Promise.resolve(exports.MOCK_OAUTH2_RESPONSE));
|
|
316
|
+
}
|
|
317
|
+
/** Stub introspectToken to return inactive. */
|
|
318
|
+
function stubOAuth2Inactive(client) {
|
|
319
|
+
return stubApi(client, "oauth2", "introspectOAuth2Token", () => Promise.resolve(exports.MOCK_INACTIVE_OAUTH2_RESPONSE));
|
|
320
|
+
}
|
|
321
|
+
/** Stub checkPermission to allow. */
|
|
322
|
+
function stubPermissionAllowed(client) {
|
|
323
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.resolve(exports.PERMISSION_ALLOWED));
|
|
324
|
+
}
|
|
325
|
+
/** Stub checkPermission to deny. */
|
|
326
|
+
function stubPermissionDenied(client) {
|
|
327
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.resolve(exports.PERMISSION_DENIED));
|
|
328
|
+
}
|
|
329
|
+
/** Stub checkPermission to throw a network error. */
|
|
330
|
+
function stubPermissionNetworkError(client) {
|
|
331
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.reject(makeNetworkError()));
|
|
332
|
+
}
|
|
333
|
+
/** Stub checkPermission to throw a rate-limit error. */
|
|
334
|
+
function stubPermissionRateLimited(client) {
|
|
335
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.reject(makeRateLimitError()));
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Spy on the public `createRelationship` method and resolve successfully.
|
|
339
|
+
* Prefer this over stubbing the internal relationship API: `setAgentPrincipal`
|
|
340
|
+
* rebuilds the API instances when the agent token changes (e.g. inside
|
|
341
|
+
* `sessionStart`), which silently discards API-level stubs.
|
|
342
|
+
*/
|
|
343
|
+
function spyRelationshipCreated(client) {
|
|
344
|
+
return vitest_1.vi
|
|
345
|
+
.spyOn(client, "createRelationship")
|
|
346
|
+
.mockResolvedValue({ created: true, alreadyExisted: false });
|
|
347
|
+
}
|
|
348
|
+
/** Spy on the public `createRelationship` method and reject. */
|
|
349
|
+
function spyRelationshipCreateError(client) {
|
|
350
|
+
return vitest_1.vi
|
|
351
|
+
.spyOn(client, "createRelationship")
|
|
352
|
+
.mockRejectedValue(new Error("relationship write failed"));
|
|
353
|
+
}
|
|
354
|
+
// ─── MCP Stub Presets ─────────────────────────────────────────────
|
|
355
|
+
/** Stub both checkPermission (server allow) and batchCheckPermission (both allow). */
|
|
356
|
+
function stubMcpAllowed(client) {
|
|
357
|
+
stubApi(client, "permission", "checkPermission", () => Promise.resolve(exports.PERMISSION_ALLOWED));
|
|
358
|
+
return stubApi(client, "permission", "batchCheckPermission", () => Promise.resolve(exports.BATCH_BOTH_ALLOWED));
|
|
359
|
+
}
|
|
360
|
+
/** Stub checkPermission to deny (server-only MCP check). */
|
|
361
|
+
function stubMcpServerDenied(client) {
|
|
362
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.resolve(exports.PERMISSION_DENIED));
|
|
363
|
+
}
|
|
364
|
+
/** Stub batchCheckPermission: server allowed, tool denied. */
|
|
365
|
+
function stubMcpToolDenied(client) {
|
|
366
|
+
stubApi(client, "permission", "checkPermission", () => Promise.resolve(exports.PERMISSION_ALLOWED));
|
|
367
|
+
return stubApi(client, "permission", "batchCheckPermission", () => Promise.resolve(exports.BATCH_SERVER_ALLOWED_TOOL_DENIED));
|
|
368
|
+
}
|
|
369
|
+
/** Stub checkPermission to throw network error (MCP fail-open). */
|
|
370
|
+
function stubMcpNetworkError(client) {
|
|
371
|
+
return stubApi(client, "permission", "checkPermission", () => Promise.reject(makeNetworkError()));
|
|
372
|
+
}
|
package/dist/tool-catalog.d.ts
CHANGED
|
@@ -16,10 +16,17 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export declare const HARNESS_TOOL_CATALOG: {
|
|
18
18
|
readonly "claude-code": readonly ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "WebFetch", "WebSearch", "NotebookEdit", "TodoWrite", "Task"];
|
|
19
|
+
readonly "claude-agent-sdk": readonly ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "WebFetch", "WebSearch", "NotebookEdit", "TodoWrite", "Task"];
|
|
19
20
|
readonly codex: readonly ["shell", "apply_patch", "read_file"];
|
|
20
21
|
readonly "gemini-cli": readonly ["read_file", "write_file", "edit_file", "list_files", "search_files", "shell", "web_search"];
|
|
21
22
|
readonly openclaw: readonly ["execute_command", "read_file", "write_file", "list_directory", "search_files", "browser"];
|
|
22
23
|
readonly opencode: readonly ["read", "write", "edit", "bash", "glob", "grep", "webfetch"];
|
|
24
|
+
readonly continue: readonly ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "WebSearch"];
|
|
25
|
+
readonly goose: readonly ["shell", "text_editor", "read_file", "write_file", "list_windows", "screen_capture"];
|
|
26
|
+
readonly cline: readonly ["execute_command", "read_file", "write_to_file", "replace_in_file", "search_files", "list_files", "use_mcp_tool"];
|
|
27
|
+
readonly amp: readonly ["Bash", "Read", "create_file", "edit_file", "undo_edit", "glob", "Grep", "finder", "read_web_page", "web_search", "todo_read", "todo_write", "oracle", "Task"];
|
|
28
|
+
readonly pi: readonly ["read", "write", "edit", "bash", "grep", "find", "ls"];
|
|
29
|
+
readonly antigravity: readonly ["run_command", "view_file", "write_to_file", "replace_file_content", "multi_replace_file_content", "list_directory", "grep_search", "find", "read_url_content", "search_web", "call_mcp_tool"];
|
|
23
30
|
};
|
|
24
31
|
/** Names of the harnesses with a known tool catalog. */
|
|
25
32
|
export type KnownHarness = keyof typeof HARNESS_TOOL_CATALOG;
|
package/dist/tool-catalog.js
CHANGED
|
@@ -34,6 +34,22 @@ exports.HARNESS_TOOL_CATALOG = {
|
|
|
34
34
|
"TodoWrite",
|
|
35
35
|
"Task",
|
|
36
36
|
],
|
|
37
|
+
// The Claude Agent SDK exposes the same built-in tool surface as Claude
|
|
38
|
+
// Code (it is the embeddable form of the same runtime), so the catalog
|
|
39
|
+
// mirrors claude-code's and `permissions bootstrap` can seed it.
|
|
40
|
+
"claude-agent-sdk": [
|
|
41
|
+
"Read",
|
|
42
|
+
"Write",
|
|
43
|
+
"Edit",
|
|
44
|
+
"Bash",
|
|
45
|
+
"Glob",
|
|
46
|
+
"Grep",
|
|
47
|
+
"WebFetch",
|
|
48
|
+
"WebSearch",
|
|
49
|
+
"NotebookEdit",
|
|
50
|
+
"TodoWrite",
|
|
51
|
+
"Task",
|
|
52
|
+
],
|
|
37
53
|
codex: ["shell", "apply_patch", "read_file"],
|
|
38
54
|
"gemini-cli": [
|
|
39
55
|
"read_file",
|
|
@@ -53,6 +69,54 @@ exports.HARNESS_TOOL_CATALOG = {
|
|
|
53
69
|
"browser",
|
|
54
70
|
],
|
|
55
71
|
opencode: ["read", "write", "edit", "bash", "glob", "grep", "webfetch"],
|
|
72
|
+
continue: ["Bash", "Read", "Edit", "Write", "Grep", "Glob", "WebSearch"],
|
|
73
|
+
goose: [
|
|
74
|
+
"shell",
|
|
75
|
+
"text_editor",
|
|
76
|
+
"read_file",
|
|
77
|
+
"write_file",
|
|
78
|
+
"list_windows",
|
|
79
|
+
"screen_capture",
|
|
80
|
+
],
|
|
81
|
+
cline: [
|
|
82
|
+
"execute_command",
|
|
83
|
+
"read_file",
|
|
84
|
+
"write_to_file",
|
|
85
|
+
"replace_in_file",
|
|
86
|
+
"search_files",
|
|
87
|
+
"list_files",
|
|
88
|
+
"use_mcp_tool",
|
|
89
|
+
],
|
|
90
|
+
amp: [
|
|
91
|
+
"Bash",
|
|
92
|
+
"Read",
|
|
93
|
+
"create_file",
|
|
94
|
+
"edit_file",
|
|
95
|
+
"undo_edit",
|
|
96
|
+
"glob",
|
|
97
|
+
"Grep",
|
|
98
|
+
"finder",
|
|
99
|
+
"read_web_page",
|
|
100
|
+
"web_search",
|
|
101
|
+
"todo_read",
|
|
102
|
+
"todo_write",
|
|
103
|
+
"oracle",
|
|
104
|
+
"Task",
|
|
105
|
+
],
|
|
106
|
+
pi: ["read", "write", "edit", "bash", "grep", "find", "ls"],
|
|
107
|
+
antigravity: [
|
|
108
|
+
"run_command",
|
|
109
|
+
"view_file",
|
|
110
|
+
"write_to_file",
|
|
111
|
+
"replace_file_content",
|
|
112
|
+
"multi_replace_file_content",
|
|
113
|
+
"list_directory",
|
|
114
|
+
"grep_search",
|
|
115
|
+
"find",
|
|
116
|
+
"read_url_content",
|
|
117
|
+
"search_web",
|
|
118
|
+
"call_mcp_tool",
|
|
119
|
+
],
|
|
56
120
|
};
|
|
57
121
|
exports.KNOWN_HARNESSES = Object.keys(exports.HARNESS_TOOL_CATALOG);
|
|
58
122
|
/**
|
|
@@ -88,10 +152,19 @@ exports.ALL_TOOLS = Array.from(new Set(Object.values(exports.HARNESS_TOOL_CATALO
|
|
|
88
152
|
*/
|
|
89
153
|
exports.INTERACTIVE_TOOL_CATALOG = {
|
|
90
154
|
"claude-code": ["AskUserQuestion", "ExitPlanMode", "TodoWrite"],
|
|
155
|
+
// Same runtime as Claude Code — the SDK delivers the same
|
|
156
|
+
// user-interaction primitives through PreToolUse.
|
|
157
|
+
"claude-agent-sdk": ["AskUserQuestion", "ExitPlanMode", "TodoWrite"],
|
|
91
158
|
codex: [],
|
|
92
159
|
"gemini-cli": [],
|
|
93
160
|
openclaw: [],
|
|
94
161
|
opencode: [],
|
|
162
|
+
continue: [],
|
|
163
|
+
goose: [],
|
|
164
|
+
cline: [],
|
|
165
|
+
amp: [],
|
|
166
|
+
pi: [],
|
|
167
|
+
antigravity: [],
|
|
95
168
|
};
|
|
96
169
|
function parseEnvInteractiveTools() {
|
|
97
170
|
const raw = process.env.ORY_INTERACTIVE_TOOLS;
|
package/dist/user-login.js
CHANGED
|
@@ -165,8 +165,13 @@ async function runUserLogin(client, options) {
|
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
// 2. Pre-supplied env tokens short-circuit the browser flow (CI, scripted
|
|
169
|
-
|
|
168
|
+
// 2. Pre-supplied env tokens short-circuit the browser flow (CI, scripted
|
|
169
|
+
// runs). ORY_USER_* are the documented names; the legacy single-identity
|
|
170
|
+
// ORY_SESSION_TOKEN / ORY_OAUTH2_TOKEN are still honored.
|
|
171
|
+
if (process.env.ORY_USER_SESSION_TOKEN ||
|
|
172
|
+
process.env.ORY_USER_OAUTH2_TOKEN ||
|
|
173
|
+
process.env.ORY_SESSION_TOKEN ||
|
|
174
|
+
process.env.ORY_OAUTH2_TOKEN) {
|
|
170
175
|
return {
|
|
171
176
|
proceed: true,
|
|
172
177
|
mode: "env_token",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|