@ory/cline 0.13.8 → 0.14.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 +10 -7
- package/dist/cli/main.js +7 -0
- package/dist/cli/setup.js +1 -1
- package/dist/handlers.js +6 -109
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,12 +21,14 @@ Run one command. It installs the plugin and walks you through connecting:
|
|
|
21
21
|
npx -y -p @ory/cline ory-cline install
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
It opens a guided setup **in your browser** where you pick how to connect — the default takes just a click:
|
|
25
25
|
|
|
26
26
|
- **Ory Network** *(default)* — sign in, or create a free account, in your browser. The project, keys, permissions, and login are all set up for you. Nothing to configure by hand.
|
|
27
27
|
- **Local** — run a complete Ory on your laptop with Docker. No account, no signup, no keys. Great for trying it out.
|
|
28
28
|
- **Audit-only** — skip Ory entirely and just log what Cline does.
|
|
29
29
|
|
|
30
|
+
> No browser available (CI, SSH, headless)? The same walkthrough runs right in your terminal instead — or force it with `--no-web`.
|
|
31
|
+
|
|
30
32
|
That's it. Confirm everything landed with:
|
|
31
33
|
|
|
32
34
|
```bash
|
|
@@ -52,6 +54,7 @@ If Ory is ever unreachable, the plugin gets out of the way and lets Cline keep w
|
|
|
52
54
|
Everything the plugin does is observable out of the box — no configuration required:
|
|
53
55
|
|
|
54
56
|
- **Status at a glance.** `npx -y -p @ory/cline ory-cline status` shows what's configured, who's signed in, how many built-in tools your permissions cover, and the most recent tool-call activity.
|
|
57
|
+
- **Live dashboard.** `npx -y -p @ory/cline ory-cline dashboard` opens the same picture in your browser — configuration, identities, permission coverage, Ory service health, and the latest tool-call activity, all refreshing live. From there you can flip **enforcement** on or off, toggle **user login**, and use **Change stack** to reconnect to a different Ory — no CLI required.
|
|
55
58
|
- **Live traces.** Every tool call is recorded as an OpenTelemetry-style span. Watch them stream as the agent works:
|
|
56
59
|
|
|
57
60
|
```bash
|
|
@@ -69,7 +72,7 @@ When the watch-mode logs look right, turn on blocking with one command (setup al
|
|
|
69
72
|
npx -y -p @ory/cline ory-cline permissions enforce
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
Now a denied tool is actually blocked and Cline shows why. Go back to watch mode anytime with `permissions observe`. Use `permissions status` to see what's covered and `permissions bootstrap` to (re-)grant the built-in tools.
|
|
75
|
+
Now a denied tool is actually blocked and Cline shows why. Go back to watch mode anytime with `permissions observe`. Prefer clicking? The dashboard has the same **Enforce** switch — flip it on, or back to watch mode, without touching the CLI. Use `permissions status` to see what's covered and `permissions bootstrap` to (re-)grant the built-in tools.
|
|
73
76
|
|
|
74
77
|
## Also: add login to your own app
|
|
75
78
|
|
|
@@ -84,11 +87,10 @@ The guided setup covers most people. For scripted or CI setups, or to point at a
|
|
|
84
87
|
```bash
|
|
85
88
|
npx -y -p @ory/cline ory-cline configure \
|
|
86
89
|
--project-url https://<slug>.projects.oryapis.com \
|
|
87
|
-
--oauth2-client-id <sign-in client id>
|
|
88
|
-
--user-login
|
|
90
|
+
--oauth2-client-id <sign-in client id>
|
|
89
91
|
```
|
|
90
92
|
|
|
91
|
-
Cline's own identity registers itself automatically on first run — nothing to create. The `--oauth2-client-id` is the one piece browser sign-in needs (a **public sign-in client** registered with the loopback URLs `http://127.0.0.1:47823..47826/callback`); the guided setup makes it for you. For logging-only with no checks, use `--audit-only`.
|
|
93
|
+
Cline's own identity registers itself automatically on first run — nothing to create. The `--oauth2-client-id` is the one piece browser sign-in needs (a **public sign-in client** registered with the loopback URLs `http://127.0.0.1:47823..47826/callback`); the guided setup makes it for you. For logging-only with no checks, use `--audit-only`. The interactive user login runs every session (always on, non-blocking) and only needs `ORY_OAUTH2_CLIENT_ID` to complete the browser flow.
|
|
92
94
|
|
|
93
95
|
With nothing configured, the plugin still loads and runs in **pass-through mode**: skills and logging work, but no checks run and nothing is blocked. Perfectly fine if you only want the app-building features.
|
|
94
96
|
|
|
@@ -110,11 +112,12 @@ The hook filenames are PascalCase (`TaskStart`, `PreToolUse`, …); the payload
|
|
|
110
112
|
## Commands
|
|
111
113
|
|
|
112
114
|
```
|
|
113
|
-
ory-cline install | uninstall Install/remove; --
|
|
115
|
+
ory-cline install | uninstall Install/remove; --reconfigure re-runs setup, --no-web forces the terminal wizard, --no-configure skips it
|
|
114
116
|
ory-cline status Show configuration, identities, permission coverage, recent activity
|
|
117
|
+
ory-cline dashboard Open the live browser dashboard (status + service health + Change stack)
|
|
115
118
|
ory-cline watch Tail the live trace stream (OTel spans)
|
|
116
119
|
ory-cline permissions <cmd> status | bootstrap | observe (watch) | enforce (block)
|
|
117
|
-
ory-cline configure <flags> Point at a project by hand (--project-url, --oauth2-client-id, --
|
|
120
|
+
ory-cline configure <flags> Point at a project by hand (--project-url, --oauth2-client-id, --audit-only)
|
|
118
121
|
ory-cline agent <status|unregister> Manage Cline's own auto-created identity
|
|
119
122
|
```
|
|
120
123
|
|
package/dist/cli/main.js
CHANGED
|
@@ -103,6 +103,12 @@ function main() {
|
|
|
103
103
|
case "watch":
|
|
104
104
|
(0, argus_1.runWatchCommand)("cline", args);
|
|
105
105
|
break;
|
|
106
|
+
case "dashboard":
|
|
107
|
+
(0, argus_1.runDashboardCommand)("ory-cline", "cline", args).then((code) => process.exit(code), (err) => {
|
|
108
|
+
console.error(err.message ?? err);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
break;
|
|
106
112
|
case "version":
|
|
107
113
|
case "--version":
|
|
108
114
|
case "-v":
|
|
@@ -166,6 +172,7 @@ Commands:
|
|
|
166
172
|
permissions <cmd> Manage permission mode and tool permissions (status, bootstrap, observe, enforce)
|
|
167
173
|
setup [options] Write hook scripts directly to the hooks directory (fallback)
|
|
168
174
|
status Show plugin status and configuration
|
|
175
|
+
dashboard Open the Ory Agent dashboard (system health + configuration)
|
|
169
176
|
watch [trace-file] Tail the trace stream (OTel spans) live
|
|
170
177
|
version Show version and the ory-agent-plugins build commit
|
|
171
178
|
local <cmd> Manage local Ory dev environment (up, down, status, seed, ...)
|
package/dist/cli/setup.js
CHANGED
|
@@ -68,7 +68,7 @@ const HOOK_BIN = "ory-cline-hook";
|
|
|
68
68
|
* generated with (read from this package's own package.json).
|
|
69
69
|
*/
|
|
70
70
|
function hookCommand() {
|
|
71
|
-
return `npx -y -p ${shims_js_1.PACKAGE_NAME}@${readPackageVersion()} ${HOOK_BIN}
|
|
71
|
+
return (0, argus_1.pinHookToLocalRegistry)(`npx -y -p ${shims_js_1.PACKAGE_NAME}@${readPackageVersion()} ${HOOK_BIN}`);
|
|
72
72
|
}
|
|
73
73
|
function readPackageVersion() {
|
|
74
74
|
// dist/cli/setup.js -> package root is two levels up.
|
package/dist/handlers.js
CHANGED
|
@@ -68,13 +68,12 @@ async function handleTaskStart(input, client, deps) {
|
|
|
68
68
|
client.tracer.record("session.start", "ok", {
|
|
69
69
|
attributes: { clineVersion: input.clineVersion },
|
|
70
70
|
});
|
|
71
|
-
// 1. User gate.
|
|
72
|
-
//
|
|
71
|
+
// 1. User gate. The user login runs every session and never blocks;
|
|
72
|
+
// enforcement is governed solely by permissionMode at tool-call time.
|
|
73
73
|
const userGate = deps.userLogin ?? argus_1.ensureUserAuthenticated;
|
|
74
|
-
|
|
74
|
+
await userGate(client, {
|
|
75
75
|
binName: "ory-cline",
|
|
76
76
|
harness: "cline",
|
|
77
|
-
allowBlock: true,
|
|
78
77
|
});
|
|
79
78
|
// 2. Agent gate. Never blocks; attaches the agent's bearer token to
|
|
80
79
|
// outgoing Ory API calls.
|
|
@@ -83,113 +82,11 @@ async function handleTaskStart(input, client, deps) {
|
|
|
83
82
|
projectUrl: (0, argus_1.resolveConfig)().projectUrl,
|
|
84
83
|
harness: "cline",
|
|
85
84
|
});
|
|
86
|
-
// 3. User → agent delegation tuple. Best-effort; never blocks.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
cancel: true,
|
|
91
|
-
errorMessage: decision.reason ?? "Ory user login was declined or could not complete.",
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
if (decision.mode !== "disabled") {
|
|
95
|
-
return {};
|
|
96
|
-
}
|
|
97
|
-
// Legacy verify/log path (ORY_USER_LOGIN unset).
|
|
98
|
-
const resolved = (0, argus_1.resolveConfig)();
|
|
99
|
-
if (resolved.auditOnly) {
|
|
100
|
-
client.logger.info("config.audit_only", {
|
|
101
|
-
message: "Audit-only mode enabled. Auth and permission checks are disabled.",
|
|
102
|
-
});
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
if (!resolved.projectUrl) {
|
|
106
|
-
client.logger.warn("config.not_configured", {
|
|
107
|
-
message: "Ory plugin is not configured. Auth and permission checks are disabled. " +
|
|
108
|
-
"Run 'npx ory-cline configure' to connect to an Ory project.",
|
|
109
|
-
});
|
|
110
|
-
return {};
|
|
111
|
-
}
|
|
112
|
-
const sessionToken = process.env.ORY_SESSION_TOKEN;
|
|
113
|
-
const oauth2Token = process.env.ORY_OAUTH2_TOKEN;
|
|
114
|
-
if (sessionToken) {
|
|
115
|
-
await verifySessionToken(sessionToken, client);
|
|
116
|
-
return {};
|
|
117
|
-
}
|
|
118
|
-
if (oauth2Token) {
|
|
119
|
-
await verifyOAuth2Token(oauth2Token, client);
|
|
120
|
-
return {};
|
|
121
|
-
}
|
|
122
|
-
client.logger.warn("session.no_credentials", {
|
|
123
|
-
message: "Neither ORY_SESSION_TOKEN nor ORY_OAUTH2_TOKEN is set. " +
|
|
124
|
-
"Skipping authentication.",
|
|
125
|
-
});
|
|
85
|
+
// 3. User → agent delegation tuple. Best-effort; never blocks. Written at
|
|
86
|
+
// most once per install.
|
|
87
|
+
await (0, argus_1.writeUserDelegatesAgent)(client);
|
|
126
88
|
return {};
|
|
127
89
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Write the user → agent delegation tuple once both principal subjects are
|
|
130
|
-
* populated. Idempotent (409s absorbed by the core). Failures are logged and
|
|
131
|
-
* swallowed — delegation tuples are audit-trail only.
|
|
132
|
-
*/
|
|
133
|
-
async function writeDelegation(client) {
|
|
134
|
-
const userSubject = client.userPrincipal?.subject;
|
|
135
|
-
const agentSubject = client.agentPrincipal?.subject;
|
|
136
|
-
if (!userSubject || !agentSubject)
|
|
137
|
-
return;
|
|
138
|
-
const namespace = resolveNamespace();
|
|
139
|
-
try {
|
|
140
|
-
await client.createRelationship({
|
|
141
|
-
namespace,
|
|
142
|
-
object: `agent:${agentSubject}`,
|
|
143
|
-
relation: "delegate",
|
|
144
|
-
subjectId: `user:${userSubject}`,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
catch (err) {
|
|
148
|
-
client.logger.warn("delegation.write_failed", {
|
|
149
|
-
message: err?.message ?? String(err),
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
async function verifySessionToken(token, client) {
|
|
154
|
-
try {
|
|
155
|
-
const session = await client.verifySession(token);
|
|
156
|
-
if (!session.active) {
|
|
157
|
-
client.logger.warn("session.inactive", {
|
|
158
|
-
message: "Ory session is not active. Re-authenticate to enable auth checks.",
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
catch (err) {
|
|
163
|
-
const oryErr = err;
|
|
164
|
-
client.logger.warn("session.verify_failed", {
|
|
165
|
-
code: oryErr.code,
|
|
166
|
-
message: oryErr.message,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
async function verifyOAuth2Token(token, client) {
|
|
171
|
-
try {
|
|
172
|
-
const tokenInfo = await client.introspectToken(token);
|
|
173
|
-
if (!tokenInfo.active) {
|
|
174
|
-
client.logger.warn("oauth2.token_inactive", {
|
|
175
|
-
message: "Ory OAuth2 token is not active. Obtain a new token to enable auth checks.",
|
|
176
|
-
});
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
client.logger.info("oauth2.session_authenticated", {
|
|
180
|
-
clientId: tokenInfo.clientId,
|
|
181
|
-
subject: tokenInfo.subject,
|
|
182
|
-
scope: tokenInfo.scope,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
catch (err) {
|
|
186
|
-
const oryErr = err;
|
|
187
|
-
client.logger.warn("oauth2.introspect_failed", {
|
|
188
|
-
code: oryErr.code,
|
|
189
|
-
message: oryErr.message,
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
90
|
// ─── tool_call (tool.before, blocking) ─────────────────────────────
|
|
194
91
|
async function handlePreToolUse(input, client) {
|
|
195
92
|
const toolName = input.preToolUse?.toolName ?? "unknown";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/cline",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Ory plugin for Cline: 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",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
],
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"reo-census": "^1.2.8",
|
|
70
|
-
"@ory/argus": "0.
|
|
70
|
+
"@ory/argus": "0.14.0"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"typescript": "^6.0.2",
|