@ory/claude-code 1.2.4 → 1.3.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.
package/README.md CHANGED
@@ -46,6 +46,8 @@ Installing the plugin drops the full Ory playbook catalog into Claude Code. **Sk
46
46
  | `ory-local-dev` | Develops and tests login/permission flows against a local Ory — no project, no account, offline |
47
47
  | `ory-permissions-onboarding` | Walks a fresh install from observe mode to enforced per-tool permissions without getting blocked |
48
48
  | `ory-build-agent` | Drops `@ory/argus` into an agent *you* own — Claude Agent SDK, OpenAI Agents, Mastra, Vercel AI, LangGraph/PydanticAI |
49
+ | `ory-deploy-agent` | Builds and deploys the canonical Claude Agent SDK agent through Agent Security with a generated runtime credential and Docker Compose |
50
+ | `ory-deploy-openai-e2b` | Builds and deploys a Python OpenAI Agents application on E2B with an immutable template and generated Talos runtime credential |
49
51
  | `ory-build-integration` | Wires Ory into your app: Action webhooks, JWT validation at a gateway, live event streams |
50
52
  | `ory-contribute-integration` | Authors and submits an integration to the public `ory/integrates` registry |
51
53
  | `ory-e2b-sandbox` | Scaffolds an E2B sandbox template that boots with this plugin preinstalled |
@@ -119,7 +121,7 @@ npx -y -p @ory/claude-code ory-claude configure \
119
121
 
120
122
  **Ory Network or OEL.** Either works. For an Ory Network project the URL is `https://<slug>.projects.oryapis.com`; for a self-hosted **Ory Enterprise License** deployment, point `--project-url` at that deployment's base URL and use the sign-in client id from its Agent Security configuration. Everything downstream — sign-in, checks, delegation — is identical.
121
123
 
122
- **There is nothing else for you to create.** The sign-in client, permission model, native-tool blocks, MCP grants, and observe/enforce posture are provisioned in the Console by someone with project access. At runtime the plugin only *reads* permissions, so installing it needs no workspace privilege. Each Claude session registers its own identity automatically on first use.
124
+ **There is nothing else for you to create.** The sign-in client, permission model, native-tool blocks, MCP grants, and observe/enforce posture are provisioned in the Console by someone with project access. At session start the plugin loads or enrolls Claude's Talos runtime credential in the OS credential store; tool paths only read it. Installing needs no workspace privilege.
123
125
 
124
126
  Sign-in runs at the start of every session and never blocks — a declined, skipped, or timed-out login simply leaves that session without a user identity.
125
127
 
@@ -132,7 +134,7 @@ ory-claude install | uninstall Install (add --project-url to also connect
132
134
  ory-claude status Show configuration, identities, native tool access, recent activity
133
135
  ory-claude permissions <cmd> status (read-only; blocks + posture live in the Ory Console)
134
136
  ory-claude configure <flags> Connect a project (--project-url) or --disconnect
135
- ory-claude agent <status|unregister> Manage Claude's own auto-created identity
137
+ ory-claude agent <status|unregister> Inspect runtime status / clear legacy OAuth state
136
138
  ory-claude local <up|down|status|…> Run / manage a local Ory in Docker
137
139
  ory-claude version Print plugin, core, and Node versions (--json for machine-readable)
138
140
  ```
@@ -142,7 +144,7 @@ All prefixed with `npx -y -p @ory/claude-code`.
142
144
  ## Troubleshooting
143
145
 
144
146
  - **`local-up` fails** — make sure Docker is running and ports `4000`, `4100`, and `4455` are free.
145
- - **Browser sign-in loops** (after connecting) — reset with `ory-claude agent unregister` and try again.
147
+ - **Browser sign-in loops** (after connecting) — confirm the reserved login client has all four documented loopback redirect URIs; `agent unregister` only clears legacy agent OAuth state.
146
148
  - **Running an older CLI than expected** — `npx -p @ory/claude-code` (no version pin) reuses a previously-downloaded copy instead of re-resolving to the latest. The install banner prints the running version; confirm it with `npx -y -p @ory/claude-code ory-claude version`. To force the current release, clear the cache and reinstall: `rm -rf ~/.npm/_npx` then `npx -y -p @ory/claude-code ory-claude install`. Pinning an exact version (`@ory/claude-code@<version>`) also bypasses the cached copy.
147
149
  - **Hooks stuck on an old version** — run `/plugin marketplace update ory` inside Claude Code, or re-run the installer.
148
150
 
@@ -0,0 +1,5 @@
1
+ /** Keep native arguments out of the shell; npm's Windows shims need cmd.exe. */
2
+ export declare function runClaude(args: string[], platform?: NodeJS.Platform): {
3
+ ok: boolean;
4
+ output: string;
5
+ };
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runClaude = runClaude;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const CAPTURE = {
6
+ encoding: "utf-8",
7
+ stdio: ["pipe", "pipe", "pipe"],
8
+ };
9
+ // cmd.exe parses a batch invocation twice: once to start the shim and again
10
+ // when an npm shim forwards %* to node.exe. Protect both parsing passes.
11
+ function escapeBatchArgument(argument) {
12
+ const quoted = `"${argument
13
+ .replace(/(\\*)"/g, '$1$1\\"')
14
+ .replace(/(\\*)$/, "$1$1")}"`;
15
+ const escape = (value) => value.replace(/([()\][%!^"`<>&|;, *?])/g, "^$1");
16
+ return escape(escape(quoted));
17
+ }
18
+ /** Keep native arguments out of the shell; npm's Windows shims need cmd.exe. */
19
+ function runClaude(args, platform = process.platform) {
20
+ let result;
21
+ if (platform !== "win32") {
22
+ result = (0, node_child_process_1.spawnSync)("claude", args, { ...CAPTURE, shell: false });
23
+ }
24
+ else {
25
+ // Resolve using Windows PATH/PATHEXT rules. `where` can also return npm's
26
+ // extensionless POSIX shim, which is not a Windows executable.
27
+ const lookup = (0, node_child_process_1.spawnSync)("where.exe", ["claude"], {
28
+ ...CAPTURE,
29
+ shell: false,
30
+ });
31
+ const executable = lookup.status === 0
32
+ ? lookup.stdout
33
+ .split(/\r?\n/)
34
+ .find((file) => /\.(exe|com|cmd|bat)$/i.test(file))
35
+ : undefined;
36
+ if (!executable) {
37
+ return {
38
+ ok: false,
39
+ output: lookup.error?.message || lookup.stderr.trim() || "claude was not found on PATH.",
40
+ };
41
+ }
42
+ if (/\.(exe|com)$/i.test(executable)) {
43
+ result = (0, node_child_process_1.spawnSync)(executable, args, { ...CAPTURE, shell: false });
44
+ }
45
+ else {
46
+ const command = executable.replace(/([()\][%!^"`<>&|;, *?])/g, "^$1");
47
+ const commandLine = [command, ...args.map(escapeBatchArgument)].join(" ");
48
+ result = (0, node_child_process_1.spawnSync)(process.env.ComSpec || "cmd.exe", [
49
+ "/d", "/s", "/v:off", "/c", `"${commandLine}"`,
50
+ ], {
51
+ ...CAPTURE,
52
+ shell: false,
53
+ windowsVerbatimArguments: true,
54
+ });
55
+ }
56
+ }
57
+ const output = ((result.stdout ?? "") + (result.stderr ?? "")).trim();
58
+ return {
59
+ ok: !result.error && result.status === 0,
60
+ output: output || result.error?.message || "",
61
+ };
62
+ }
package/dist/cli/main.js CHANGED
@@ -173,7 +173,7 @@ Commands:
173
173
  install [--global] Install Ory plugin via claude CLI marketplace
174
174
  uninstall [--global] Remove Ory plugin and marketplace
175
175
  configure Set or view Ory project URL and API key
176
- agent <cmd> Manage the agent's OAuth2 (DCR) identity (status, unregister)
176
+ agent <cmd> Inspect runtime status or clear legacy OAuth state
177
177
  permissions Show live mode and native allowed/blocked state
178
178
  status Show plugin status and configuration
179
179
  watch [--json] [--lines <count>]
package/dist/cli/setup.js CHANGED
@@ -57,9 +57,9 @@ exports.isPluginAssembled = isPluginAssembled;
57
57
  exports.install = install;
58
58
  exports.printInstallPlan = printInstallPlan;
59
59
  exports.uninstall = uninstall;
60
- const node_child_process_1 = require("node:child_process");
61
60
  const fs = __importStar(require("node:fs"));
62
61
  const path = __importStar(require("node:path"));
62
+ const claude_command_js_1 = require("./claude-command.js");
63
63
  const argus_1 = require("@ory/argus");
64
64
  const PACKAGE_ROOT = path.resolve(__dirname, "..", "..");
65
65
  const PACKAGE_NAME = "@ory/claude-code";
@@ -98,7 +98,7 @@ const RENDER_OPTS = {
98
98
  /**
99
99
  * Persistent install location: the marketplace root the `claude` CLI is
100
100
  * pointed at. Lives under the shared OS-agnostic data dir so all plugin state
101
- * — config, DCR creds, harness assets — sits in one place per platform.
101
+ * — config, legacy DCR cleanup state, harness assets — sits in one place per platform.
102
102
  *
103
103
  * Resolved on each call rather than captured at module load: `getHarnessDataDir`
104
104
  * reads `XDG_CONFIG_HOME`, so a module-level constant would freeze whatever the
@@ -227,29 +227,9 @@ function cleanPersistentDir() {
227
227
  function claudeScope(isGlobal) {
228
228
  return isGlobal ? "user" : "project";
229
229
  }
230
- /**
231
- * On Windows, npm-installed CLIs are `.cmd` shims that Node's spawn only
232
- * finds via the shell. POSIX shells resolve the bare name directly.
233
- */
234
- const SPAWN_VIA_SHELL = process.platform === "win32";
235
- /** Run a `claude` CLI command and capture output. */
236
- function runClaude(args) {
237
- const result = (0, node_child_process_1.spawnSync)("claude", args, {
238
- encoding: "utf-8",
239
- stdio: ["pipe", "pipe", "pipe"],
240
- shell: SPAWN_VIA_SHELL,
241
- });
242
- const output = ((result.stdout ?? "") + (result.stderr ?? "")).trim();
243
- return { ok: result.status === 0, output };
244
- }
245
230
  /** Check that the `claude` CLI is available. */
246
231
  function checkClaudeCli() {
247
- const result = (0, node_child_process_1.spawnSync)("claude", ["--version"], {
248
- encoding: "utf-8",
249
- stdio: ["pipe", "pipe", "pipe"],
250
- shell: SPAWN_VIA_SHELL,
251
- });
252
- return result.status === 0;
232
+ return (0, claude_command_js_1.runClaude)(["--version"]).ok;
253
233
  }
254
234
  /**
255
235
  * Install the Ory plugin via the `claude` CLI.
@@ -315,10 +295,10 @@ function installAssembled(scope, args) {
315
295
  // its marketplace first guarantees the current command set is picked up on
316
296
  // every dev iteration. Best-effort and quiet: a not-yet-installed plugin
317
297
  // just no-ops here.
318
- runClaude(["plugin", "uninstall", pluginName, "--scope", scope]);
319
- runClaude(["plugin", "marketplace", "remove", marketplaceName]);
298
+ (0, claude_command_js_1.runClaude)(["plugin", "uninstall", pluginName, "--scope", scope]);
299
+ (0, claude_command_js_1.runClaude)(["plugin", "marketplace", "remove", marketplaceName]);
320
300
  console.log("Adding local Ory plugin marketplace...");
321
- const addResult = runClaude([
301
+ const addResult = (0, claude_command_js_1.runClaude)([
322
302
  "plugin",
323
303
  "marketplace",
324
304
  "add",
@@ -329,7 +309,7 @@ function installAssembled(scope, args) {
329
309
  if (!addResult.ok) {
330
310
  if (addResult.output.toLowerCase().includes("already")) {
331
311
  console.log(" Marketplace already registered, updating...");
332
- runClaude(["plugin", "marketplace", "update", marketplaceName]);
312
+ (0, claude_command_js_1.runClaude)(["plugin", "marketplace", "update", marketplaceName]);
333
313
  }
334
314
  else {
335
315
  console.error(`Failed to add marketplace: ${addResult.output}`);
@@ -340,7 +320,7 @@ function installAssembled(scope, args) {
340
320
  console.log(" Marketplace added.");
341
321
  }
342
322
  console.log(`Installing ${pluginName} plugin...`);
343
- const installResult = runClaude([
323
+ const installResult = (0, claude_command_js_1.runClaude)([
344
324
  "plugin",
345
325
  "install",
346
326
  `${pluginName}@${marketplaceName}`,
@@ -378,7 +358,7 @@ function uninstall(args) {
378
358
  const pluginName = readLocalPluginName();
379
359
  const marketplaceName = readLocalMarketplaceName();
380
360
  console.log(`Uninstalling ${pluginName} plugin...`);
381
- const uninstallResult = runClaude([
361
+ const uninstallResult = (0, claude_command_js_1.runClaude)([
382
362
  "plugin",
383
363
  "uninstall",
384
364
  pluginName,
@@ -392,7 +372,7 @@ function uninstall(args) {
392
372
  console.log(" Plugin uninstalled.");
393
373
  }
394
374
  console.log("Removing Ory plugin marketplace...");
395
- const removeResult = runClaude([
375
+ const removeResult = (0, claude_command_js_1.runClaude)([
396
376
  "plugin",
397
377
  "marketplace",
398
378
  "remove",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ory/claude-code",
3
- "version": "1.2.4",
3
+ "version": "1.3.1",
4
4
  "description": "Ory plugin for Claude Code: 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://github.com/ory/claude-plugins/tree/master/plugins/ory-agent-plugin",
@@ -78,7 +78,7 @@
78
78
  ],
79
79
  "dependencies": {
80
80
  "reova": "^0.7.0",
81
- "@ory/argus": "1.2.4"
81
+ "@ory/argus": "1.3.1"
82
82
  },
83
83
  "engines": {
84
84
  "node": ">=22"