@ory/codex 0.10.0 → 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/README.md +3 -3
- package/dist/handlers.d.ts +10 -0
- package/dist/handlers.js +53 -0
- package/dist/hook.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,8 +30,8 @@ If you're just exploring, do the Quickstart first.
|
|
|
30
30
|
No prior `npm install` required:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npx @ory/codex install # registers the Ory marketplace + plugin with `codex`
|
|
34
|
-
npx @ory/codex uninstall # removes both
|
|
33
|
+
npx -y -p @ory/codex ory-codex install # registers the Ory marketplace + plugin with `codex`
|
|
34
|
+
npx -y -p @ory/codex ory-codex uninstall # removes both
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Then confirm everything landed:
|
|
@@ -255,7 +255,7 @@ Highlights:
|
|
|
255
255
|
- **`ory-local-up` fails.** Make sure Docker is running and ports `4455` (login UI), `4000`, `4100`, and `16686` are free.
|
|
256
256
|
- **PKCE login loops.** Clear persisted state with `npx -y -p @ory/codex ory-codex agent unregister` and retry.
|
|
257
257
|
- **`npx` fetches an old version.** Force a fresh fetch: `npx -y -p @ory/codex@latest ory-codex …`.
|
|
258
|
-
- **`npm install … ENOVERSIONS`.** If your `~/.npmrc` sets `min-release-age`, npm filters out package versions newer than that threshold. Override per-call with `npm_config_min_release_age=0 npx @ory/codex install`.
|
|
258
|
+
- **`npm install … ENOVERSIONS`.** If your `~/.npmrc` sets `min-release-age`, npm filters out package versions newer than that threshold. Override per-call with `npm_config_min_release_age=0 npx -y -p @ory/codex ory-codex install`.
|
|
259
259
|
- **`codex doctor` reports `ory-mcp-server is not resolvable`.** The bundled MCP server resolves via `npx -y -p @ory/mcp-server` on demand — make sure `npm`/`npx` is on PATH. The first session start fetches the server tarball; subsequent sessions reuse the cache.
|
|
260
260
|
- **Need more signal.** Set `ORY_AGENT_DEBUG=true` and `ORY_AGENT_LOG_FILE=/tmp/ory.log` to capture structured logs.
|
|
261
261
|
|
package/dist/handlers.d.ts
CHANGED
|
@@ -14,3 +14,13 @@ export interface HandleHookEventDeps {
|
|
|
14
14
|
* `[features] codex_hooks = true` in `~/.codex/config.toml`.
|
|
15
15
|
*/
|
|
16
16
|
export declare function handleHookEvent(input: CodexHookInput, client: OryAgentClient, deps?: HandleHookEventDeps): Promise<CodexHookOutput>;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a hook output carries anything Codex needs to see on stdout.
|
|
19
|
+
*
|
|
20
|
+
* The hook entry point handles `decision === "block"` (exit code 2 + stdout)
|
|
21
|
+
* before consulting this. Everything else with at least one populated field
|
|
22
|
+
* must be written to stdout — most importantly `hookSpecificOutput`, which
|
|
23
|
+
* carries the PermissionRequest allow/deny decision. Empty outputs stay
|
|
24
|
+
* silent to keep stdout clean for the harness.
|
|
25
|
+
*/
|
|
26
|
+
export declare function shouldEmitOutput(output: CodexHookOutput): boolean;
|
package/dist/handlers.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleHookEvent = handleHookEvent;
|
|
4
|
+
exports.shouldEmitOutput = shouldEmitOutput;
|
|
4
5
|
const argus_1 = require("@ory/argus");
|
|
5
6
|
/**
|
|
6
7
|
* Route a Codex hook event to the appropriate Ory integration.
|
|
@@ -68,6 +69,12 @@ async function handleSessionStart(input, client, deps) {
|
|
|
68
69
|
// attaches the agent's bearer token to outgoing Ory API calls.
|
|
69
70
|
const agentGate = deps.agentGate ?? argus_1.ensureAgentIdentity;
|
|
70
71
|
await agentGate(client, { projectUrl: (0, argus_1.resolveConfig)().projectUrl, harness: "codex" });
|
|
72
|
+
// Record the user→agent delegation so the audit trail captures that
|
|
73
|
+
// this user authorized this agent for this session. Best-effort:
|
|
74
|
+
// requires both principals to be populated, and any failure is logged
|
|
75
|
+
// and swallowed (fail-open — delegation tracking is for audit, not
|
|
76
|
+
// enforcement).
|
|
77
|
+
await recordUserDelegatesAgent(client);
|
|
71
78
|
if (!decision.proceed) {
|
|
72
79
|
return { decision: "block", reason: decision.reason };
|
|
73
80
|
}
|
|
@@ -416,9 +423,55 @@ async function handleStop(input, client) {
|
|
|
416
423
|
return {};
|
|
417
424
|
}
|
|
418
425
|
// ─── Helpers ────────────────────────────────────────────────────────
|
|
426
|
+
/**
|
|
427
|
+
* Whether a hook output carries anything Codex needs to see on stdout.
|
|
428
|
+
*
|
|
429
|
+
* The hook entry point handles `decision === "block"` (exit code 2 + stdout)
|
|
430
|
+
* before consulting this. Everything else with at least one populated field
|
|
431
|
+
* must be written to stdout — most importantly `hookSpecificOutput`, which
|
|
432
|
+
* carries the PermissionRequest allow/deny decision. Empty outputs stay
|
|
433
|
+
* silent to keep stdout clean for the harness.
|
|
434
|
+
*/
|
|
435
|
+
function shouldEmitOutput(output) {
|
|
436
|
+
return Object.values(output).some((value) => value !== undefined);
|
|
437
|
+
}
|
|
419
438
|
function resolveNamespace() {
|
|
420
439
|
return process.env.ORY_PERMISSION_NAMESPACE ?? "AgentTools";
|
|
421
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Write the user→agent delegation tuple. Idempotent and fail-open:
|
|
443
|
+
* requires both principal subjects to be populated; any error (including
|
|
444
|
+
* an unconfigured projectUrl, which manifests as a network_error) is
|
|
445
|
+
* logged and swallowed. Purely audit-trail data — does not affect
|
|
446
|
+
* enforcement.
|
|
447
|
+
*/
|
|
448
|
+
async function recordUserDelegatesAgent(client) {
|
|
449
|
+
const user = client.userPrincipal.subject;
|
|
450
|
+
const agent = client.agentPrincipal.subject;
|
|
451
|
+
if (!user || !agent) {
|
|
452
|
+
client.logger.debug("delegation.skip", {
|
|
453
|
+
reason: "missing principal",
|
|
454
|
+
hasUser: !!user,
|
|
455
|
+
hasAgent: !!agent,
|
|
456
|
+
});
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
await client.createRelationship({
|
|
461
|
+
namespace: resolveNamespace(),
|
|
462
|
+
object: `agent:${agent}`,
|
|
463
|
+
relation: "delegate",
|
|
464
|
+
subjectId: `user:${user}`,
|
|
465
|
+
}, { spanAttributes: { delegation: "user-to-agent" } });
|
|
466
|
+
}
|
|
467
|
+
catch (err) {
|
|
468
|
+
const oryErr = err;
|
|
469
|
+
client.logger.warn("delegation.user_to_agent.failed", {
|
|
470
|
+
code: oryErr.code,
|
|
471
|
+
message: oryErr.message,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
422
475
|
function handlePermissionError(oryErr, toolName, client) {
|
|
423
476
|
if (oryErr.code === "network_error") {
|
|
424
477
|
client.logger.warn("permission.network_error", {
|
package/dist/hook.js
CHANGED
|
@@ -62,7 +62,7 @@ async function main() {
|
|
|
62
62
|
await client.tracer.shutdown();
|
|
63
63
|
process.exit(2);
|
|
64
64
|
}
|
|
65
|
-
if (
|
|
65
|
+
if ((0, handlers_js_1.shouldEmitOutput)(output)) {
|
|
66
66
|
process.stdout.write(JSON.stringify(output));
|
|
67
67
|
}
|
|
68
68
|
await client.tracer.shutdown();
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { handleHookEvent } from "./handlers.js";
|
|
1
|
+
export { handleHookEvent, shouldEmitOutput } from "./handlers.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.handleHookEvent = void 0;
|
|
3
|
+
exports.shouldEmitOutput = exports.handleHookEvent = void 0;
|
|
4
4
|
var handlers_js_1 = require("./handlers.js");
|
|
5
5
|
Object.defineProperty(exports, "handleHookEvent", { enumerable: true, get: function () { return handlers_js_1.handleHookEvent; } });
|
|
6
|
+
Object.defineProperty(exports, "shouldEmitOutput", { enumerable: true, get: function () { return handlers_js_1.shouldEmitOutput; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/codex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Ory plugin for Codex: scaffolding skills, a local Ory instance, and authentication, authorization, and audit for every tool call",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"marketplace"
|
|
67
67
|
],
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@ory/argus": "0.
|
|
69
|
+
"@ory/argus": "0.11.0"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
72
72
|
"node": ">=22"
|