@ory/argus 0.7.1 → 0.7.3
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/commands/temporal-up.md +43 -0
- package/assets/skills/ory-temporal-worker/SKILL.md +285 -0
- package/dist/config.js +2 -1
- package/dist/setup.js +3 -3
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +22 -0
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Start Local Temporal Dev Server
|
|
2
|
+
|
|
3
|
+
Start a local [Temporal](https://temporal.io) development server alongside the
|
|
4
|
+
local Ory stack so the worker scaffolded by `ory-temporal-worker` can connect.
|
|
5
|
+
This runs Temporal's bundled dev server (Temporal Server + Postgres + Web UI in
|
|
6
|
+
one process) — not a production cluster.
|
|
7
|
+
|
|
8
|
+
Prerequisite: the [Temporal CLI](https://docs.temporal.io/cli) is installed and
|
|
9
|
+
`temporal` is on `PATH`. On macOS: `brew install temporal`. On Linux/Windows:
|
|
10
|
+
download from <https://temporal.download>.
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
temporal server start-dev
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This will:
|
|
19
|
+
|
|
20
|
+
1. Start the Temporal Server on `localhost:7233` (the gRPC endpoint workers and
|
|
21
|
+
clients connect to)
|
|
22
|
+
2. Expose the Web UI on <http://localhost:8233>
|
|
23
|
+
3. Persist state under `~/.config/temporalio/` so workflows survive a restart
|
|
24
|
+
|
|
25
|
+
The process runs in the foreground. Stop it with `Ctrl+C`; data is preserved.
|
|
26
|
+
For a clean reset, delete `~/.config/temporalio/` and start again.
|
|
27
|
+
|
|
28
|
+
For the matching Ory side of the stack (Identities, Permissions, OAuth2, login
|
|
29
|
+
UI, Jaeger), use {{REF_LOCAL_UP}}. The two stacks are independent — Temporal
|
|
30
|
+
runs on `:7233/:8233`, Ory runs on `:4000` and friends — so they can run side
|
|
31
|
+
by side without port conflicts.
|
|
32
|
+
|
|
33
|
+
Once both are up, point the worker at them:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
export ORY_PROJECT_URL=http://localhost:4000
|
|
37
|
+
export ORY_AUTH_GATE=1
|
|
38
|
+
cd temporal-worker
|
|
39
|
+
npm run start
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
See the `ory-temporal-worker` skill for the full worker scaffold and the
|
|
43
|
+
permission-gate wiring.
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ory-temporal-worker
|
|
3
|
+
description: Scaffold a [Temporal](https://temporal.io) TypeScript worker where every Activity execution is gated by Ory — the user is authenticated, the worker's agent identity is resolved via DCR, each Activity invocation runs an Ory Permission check, and the full lifecycle emits trace spans. Use when the user asks to "add Ory to my Temporal worker", "wire Ory permissions into Temporal activities", "create a Temporal worker with Ory auth", "build a Temporal TypeScript project with the Ory agent client", or any close variant. The skill scaffolds the project in the user's repo following <https://docs.temporal.io/develop/typescript/set-up-your-local-typescript> — it does not run the worker.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ory-authed Temporal TypeScript worker
|
|
7
|
+
|
|
8
|
+
You are helping the user scaffold a [Temporal](https://temporal.io) TypeScript
|
|
9
|
+
worker where every Activity execution is gated by Ory: the user is
|
|
10
|
+
authenticated, the worker's agent identity is resolved via OAuth2 Dynamic Client
|
|
11
|
+
Registration, each Activity invocation runs an Ory Permission check, and the
|
|
12
|
+
full lifecycle emits trace spans. **Workflows stay deterministic** — only
|
|
13
|
+
Activities call out to Ory.
|
|
14
|
+
|
|
15
|
+
This skill carries the workflow. You generate the files in the user's repo; the
|
|
16
|
+
user runs the Temporal CLI and the worker.
|
|
17
|
+
|
|
18
|
+
> **Precondition:** Node.js 20+ is installed, and the user has installed (or
|
|
19
|
+
> will install) the [Temporal CLI](https://docs.temporal.io/cli). On macOS:
|
|
20
|
+
> `brew install temporal`. On Linux/Windows: download from
|
|
21
|
+
> <https://temporal.download> and put `temporal` on `PATH`. If the binary is
|
|
22
|
+
> missing, point the user at the docs and stop — do not fabricate it.
|
|
23
|
+
|
|
24
|
+
## Step 1 — Confirm the target
|
|
25
|
+
|
|
26
|
+
Before writing files, confirm with the user:
|
|
27
|
+
|
|
28
|
+
1. **Where the worker should live.** Default to `temporal-worker/` at the repo
|
|
29
|
+
root unless the user says otherwise.
|
|
30
|
+
2. **Task queue name.** Default `agent-tools`. The worker and the workflow
|
|
31
|
+
starter must agree on this string.
|
|
32
|
+
3. **Ory project URL.** For local development point at the local Ory stack
|
|
33
|
+
({{REF_LOCAL_UP}}) on `http://localhost:4000`. For Ory Network, the user
|
|
34
|
+
plumbs their project URL through the worker's env. Either way the worker
|
|
35
|
+
needs network reachability to the Ory APIs at runtime.
|
|
36
|
+
|
|
37
|
+
## Step 2 — Scaffold the Temporal project
|
|
38
|
+
|
|
39
|
+
Run the official Temporal scaffold and select the `hello-world` sample when
|
|
40
|
+
prompted. Then add the Ory agent client:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx @temporalio/create@latest temporal-worker
|
|
44
|
+
cd temporal-worker
|
|
45
|
+
npm install @ory/argus
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The scaffold lays down `src/{activities.ts, workflows.ts, worker.ts, client.ts}`
|
|
49
|
+
and pre-configures the Worker to connect to the Temporal dev server at
|
|
50
|
+
`localhost:7233`. The Web UI lives at <http://localhost:8233> once the dev
|
|
51
|
+
server is running.
|
|
52
|
+
|
|
53
|
+
## Step 3 — Wrap Activities with the Ory gate
|
|
54
|
+
|
|
55
|
+
Activities are where side effects happen, so they are the right place to put
|
|
56
|
+
the permission check. **Never call Ory from inside a Workflow** — Workflows are
|
|
57
|
+
deterministic and replayed; a live Ory call would break replay safety.
|
|
58
|
+
|
|
59
|
+
Replace the scaffold's `src/activities.ts` with:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { Context } from "@temporalio/activity";
|
|
63
|
+
import {
|
|
64
|
+
OryAgentClient,
|
|
65
|
+
ensureUserAuthenticated,
|
|
66
|
+
ensureAgentIdentity,
|
|
67
|
+
checkAndDecide,
|
|
68
|
+
resolveUserSubject,
|
|
69
|
+
subjectLabel,
|
|
70
|
+
} from "@ory/argus";
|
|
71
|
+
|
|
72
|
+
// One client per worker process. `harness` is a label that shows up on
|
|
73
|
+
// every trace span so worker-originated audit lives in its own namespace
|
|
74
|
+
// alongside the CLI plugins.
|
|
75
|
+
const ory = OryAgentClient.fromEnv("temporal");
|
|
76
|
+
|
|
77
|
+
// Run the user + agent gates exactly once per process. Activities call
|
|
78
|
+
// `bootstrap()` lazily and await the same promise on subsequent calls.
|
|
79
|
+
let bootstrapped: Promise<void> | undefined;
|
|
80
|
+
function bootstrap(): Promise<void> {
|
|
81
|
+
if (!bootstrapped) {
|
|
82
|
+
bootstrapped = (async () => {
|
|
83
|
+
await ensureUserAuthenticated(ory, {
|
|
84
|
+
binName: "temporal-worker",
|
|
85
|
+
harness: "temporal",
|
|
86
|
+
// Temporal's Activity entry point has no channel to carry a
|
|
87
|
+
// session-start block, so the user gate runs in advisory mode:
|
|
88
|
+
// it still refreshes tokens and emits the audit span, but the
|
|
89
|
+
// worker proceeds even if the user is unauthenticated. Hard
|
|
90
|
+
// enforcement happens at the per-Activity permission check.
|
|
91
|
+
allowBlock: false,
|
|
92
|
+
});
|
|
93
|
+
await ensureAgentIdentity(ory, {
|
|
94
|
+
projectUrl: process.env.ORY_PROJECT_URL,
|
|
95
|
+
});
|
|
96
|
+
})();
|
|
97
|
+
}
|
|
98
|
+
return bootstrapped;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function gate(toolName: string, userSubject: string): Promise<void> {
|
|
102
|
+
await bootstrap();
|
|
103
|
+
const subject = resolveUserSubject(ory, userSubject);
|
|
104
|
+
const decision = await checkAndDecide(
|
|
105
|
+
ory,
|
|
106
|
+
{
|
|
107
|
+
namespace: process.env.ORY_PERMISSION_NAMESPACE ?? "AgentTools",
|
|
108
|
+
object: toolName,
|
|
109
|
+
relation: "use",
|
|
110
|
+
...subject,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
spanAttributes: {
|
|
114
|
+
toolName,
|
|
115
|
+
workflowId: Context.current().info.workflowExecution.workflowId,
|
|
116
|
+
activityId: Context.current().info.activityId,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
switch (decision.kind) {
|
|
122
|
+
case "allow":
|
|
123
|
+
case "observe":
|
|
124
|
+
case "fail_open":
|
|
125
|
+
return;
|
|
126
|
+
case "deny":
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Ory denied use of ${toolName} for ${subjectLabel(subject)}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function sendEmail(input: {
|
|
134
|
+
user: string;
|
|
135
|
+
to: string;
|
|
136
|
+
subject: string;
|
|
137
|
+
}): Promise<string> {
|
|
138
|
+
await gate("send_email", input.user);
|
|
139
|
+
// …real side effect here…
|
|
140
|
+
return `sent to ${input.to}`;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Key choices:
|
|
145
|
+
|
|
146
|
+
- **Activities call Ory, Workflows don't.** Anything that needs a live decision
|
|
147
|
+
goes in an Activity. Workflows only orchestrate.
|
|
148
|
+
- **`allowBlock: false`.** The Activity boundary can't carry a session-start
|
|
149
|
+
block, so the user gate runs in advisory mode. Enforcement is at the
|
|
150
|
+
permission check, which throws on deny — Temporal will mark the Activity as
|
|
151
|
+
failed and surface the error via the Workflow result or retry policy.
|
|
152
|
+
- **`harness: "temporal"`.** Distinguishes worker-originated spans in the trace
|
|
153
|
+
file from CLI plugin spans.
|
|
154
|
+
- **Span attributes carry the Workflow + Activity IDs.** This is how operators
|
|
155
|
+
correlate Ory denials back to Temporal executions in the Web UI.
|
|
156
|
+
|
|
157
|
+
## Step 4 — Pass the user subject through the Workflow
|
|
158
|
+
|
|
159
|
+
Workflows must be deterministic, so they cannot read `process.env` or call out
|
|
160
|
+
to Ory. The user subject travels as Workflow input. Update `src/workflows.ts`:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { proxyActivities } from "@temporalio/workflow";
|
|
164
|
+
import type * as activities from "./activities";
|
|
165
|
+
|
|
166
|
+
const { sendEmail } = proxyActivities<typeof activities>({
|
|
167
|
+
startToCloseTimeout: "1 minute",
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export async function notifyUser(input: {
|
|
171
|
+
user: string;
|
|
172
|
+
to: string;
|
|
173
|
+
}): Promise<string> {
|
|
174
|
+
return sendEmail({
|
|
175
|
+
user: input.user,
|
|
176
|
+
to: input.to,
|
|
177
|
+
subject: "hello",
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
And `src/client.ts`:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { Connection, Client } from "@temporalio/client";
|
|
186
|
+
import { nanoid } from "nanoid";
|
|
187
|
+
import { notifyUser } from "./workflows";
|
|
188
|
+
|
|
189
|
+
const client = new Client({ connection: await Connection.connect() });
|
|
190
|
+
const handle = await client.workflow.start(notifyUser, {
|
|
191
|
+
taskQueue: "agent-tools",
|
|
192
|
+
workflowId: `notify-${nanoid()}`,
|
|
193
|
+
args: [{ user: "user@example.com", to: "alice@example.com" }],
|
|
194
|
+
});
|
|
195
|
+
console.log("workflow started:", handle.workflowId);
|
|
196
|
+
console.log("result:", await handle.result());
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`src/worker.ts` stays as the scaffold writes it — `Worker.create` already
|
|
200
|
+
registers Workflows and Activities together and listens on the task queue.
|
|
201
|
+
|
|
202
|
+
## Step 5 — Run it
|
|
203
|
+
|
|
204
|
+
Three terminals. See {{REF_LOCAL_UP}} for the Ory side; the Temporal side uses
|
|
205
|
+
the Temporal CLI's bundled dev server (Postgres + Temporal Server + Web UI in
|
|
206
|
+
one process):
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Terminal 1 — local Ory stack (Kratos, Keto, Hydra, gateway)
|
|
210
|
+
{{REF_LOCAL_UP}}
|
|
211
|
+
|
|
212
|
+
# Terminal 2 — local Temporal dev server (Web UI at http://localhost:8233)
|
|
213
|
+
temporal server start-dev
|
|
214
|
+
|
|
215
|
+
# Terminal 3 — the worker, pointed at both
|
|
216
|
+
cd temporal-worker
|
|
217
|
+
export ORY_PROJECT_URL=http://localhost:4000
|
|
218
|
+
export ORY_AUTH_GATE=1
|
|
219
|
+
export ORY_AGENT_DEBUG=true
|
|
220
|
+
export ORY_AGENT_TRACE_FILE=$PWD/ory-trace.ndjson
|
|
221
|
+
npm run start # boots the worker, polls task queue
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
In a fourth terminal, kick the workflow once:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
cd temporal-worker
|
|
228
|
+
npm run workflow
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Tail the trace file to confirm the gates fired:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
tail -f ory-trace.ndjson | jq .
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
You should see:
|
|
238
|
+
|
|
239
|
+
- exactly one `user.auth` span (the worker's first Activity triggered
|
|
240
|
+
`bootstrap()`),
|
|
241
|
+
- exactly one `agent.auth` span,
|
|
242
|
+
- one `tool.invoke` (allow) or `tool.block` (deny) span **per Activity
|
|
243
|
+
execution**.
|
|
244
|
+
|
|
245
|
+
The Workflow itself produces no Ory spans — only its Activities do.
|
|
246
|
+
|
|
247
|
+
## Step 6 — Promotion from observe to enforce
|
|
248
|
+
|
|
249
|
+
The worker starts in `observe` mode by default: denies pass through but each is
|
|
250
|
+
recorded as a `permission.observe_deny` audit span. Once the user has confirmed
|
|
251
|
+
the deny set is what they expect, promote to enforcement:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
export ORY_PERMISSION_MODE=enforce
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
On a fresh Ory project, run the permissions bootstrap once before flipping the
|
|
258
|
+
switch so the `use` tuples for each Activity name (`send_email`, …) exist —
|
|
259
|
+
see {{REF_PERMISSIONS_ONBOARDING}}.
|
|
260
|
+
|
|
261
|
+
To exercise the deny path locally, write a tuple that explicitly removes `use`
|
|
262
|
+
for the test user against one Activity object, kick the Workflow, and watch the
|
|
263
|
+
Activity fail with the `Ory denied use of …` error in the Temporal Web UI.
|
|
264
|
+
|
|
265
|
+
## Step 7 — Beyond the dev server
|
|
266
|
+
|
|
267
|
+
This skill stops at the local dev server. For production:
|
|
268
|
+
|
|
269
|
+
- Pin a static agent identity with `ORY_AGENT_API_KEY` (single key) or
|
|
270
|
+
`ORY_AGENT_CLIENT_ID + ORY_AGENT_CLIENT_SECRET` (client_credentials) so the
|
|
271
|
+
worker doesn't re-register on every cold start.
|
|
272
|
+
- Persist the worker's `ory-trace.ndjson` somewhere durable, or replace the
|
|
273
|
+
file tracer with an OpenTelemetry exporter wired up around `ory.tracer`.
|
|
274
|
+
- Use Temporal Cloud or a self-hosted Temporal cluster instead of
|
|
275
|
+
`temporal server start-dev`; the worker code does not change.
|
|
276
|
+
|
|
277
|
+
## What this skill does NOT do
|
|
278
|
+
|
|
279
|
+
- It does not modify the user's Ory project — use {{REF_AUTH_SETUP}} for that.
|
|
280
|
+
- It does not call Ory from inside a Workflow. Workflows are deterministic and
|
|
281
|
+
must never make non-deterministic calls; all gating lives in Activities.
|
|
282
|
+
- It does not deploy the worker. The user runs `temporal server start-dev` and
|
|
283
|
+
`npm run start` locally; production deployment is out of scope.
|
|
284
|
+
- It does not pin Temporal or `@ory/argus` versions. For reproducibility, pin
|
|
285
|
+
both in the generated `package.json` before committing.
|
package/dist/config.js
CHANGED
|
@@ -42,6 +42,7 @@ exports.mutateConfig = mutateConfig;
|
|
|
42
42
|
exports.resolveConfig = resolveConfig;
|
|
43
43
|
exports.configPromptMessage = configPromptMessage;
|
|
44
44
|
const fs = __importStar(require("node:fs"));
|
|
45
|
+
const os = __importStar(require("node:os"));
|
|
45
46
|
const path = __importStar(require("node:path"));
|
|
46
47
|
/**
|
|
47
48
|
* Single OS-agnostic data directory for *all* Ory agent plugin state:
|
|
@@ -92,7 +93,7 @@ const LOCK_POLL_MS = 25;
|
|
|
92
93
|
/** Maximum total time to wait for the lock before giving up. */
|
|
93
94
|
const LOCK_TIMEOUT_MS = 5_000;
|
|
94
95
|
function getHomeDir() {
|
|
95
|
-
return
|
|
96
|
+
return os.homedir();
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
99
|
* Return the path to the config file.
|
package/dist/setup.js
CHANGED
|
@@ -53,6 +53,7 @@ exports.unregisterPlugin = unregisterPlugin;
|
|
|
53
53
|
exports.printSetupHelp = printSetupHelp;
|
|
54
54
|
exports.printNextSteps = printNextSteps;
|
|
55
55
|
const fs = __importStar(require("node:fs"));
|
|
56
|
+
const os = __importStar(require("node:os"));
|
|
56
57
|
const path = __importStar(require("node:path"));
|
|
57
58
|
// ─── Arg Parsing ───────────────────────────────────────────────────
|
|
58
59
|
/**
|
|
@@ -126,7 +127,7 @@ function resolveHookCommand(packageName, binName) {
|
|
|
126
127
|
// The package root resolves to the main entry (dist/index.js).
|
|
127
128
|
// The hook script lives alongside it as dist/hook.js.
|
|
128
129
|
const hookPath = path.resolve(path.dirname(binPath), "hook.js");
|
|
129
|
-
return `node ${hookPath}`;
|
|
130
|
+
return `node "${hookPath}"`;
|
|
130
131
|
}
|
|
131
132
|
catch {
|
|
132
133
|
return binName;
|
|
@@ -273,8 +274,7 @@ function removeMcpServer(existing) {
|
|
|
273
274
|
* Get the path to the Claude Code plugins registry file.
|
|
274
275
|
*/
|
|
275
276
|
function getPluginsRegistryPath() {
|
|
276
|
-
|
|
277
|
-
return path.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
277
|
+
return path.join(os.homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
278
278
|
}
|
|
279
279
|
/**
|
|
280
280
|
* Read the Claude Code plugins registry.
|
package/dist/skills.d.ts
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* permissions-onboarding, contribute-integration, build-integration,
|
|
6
6
|
* e2b-sandbox, build-agent) and the local-stack commands (local-up, local-down) live once,
|
|
7
7
|
* as token-bearing templates under `packages/core/assets/`. Every harness plugin renders them
|
|
8
|
+
* e2b-sandbox, temporal-worker) and the local-stack commands (local-up,
|
|
9
|
+
* local-down, temporal-up) live once, as token-bearing templates under
|
|
10
|
+
* `packages/core/assets/`. Every harness plugin renders them
|
|
8
11
|
* through {@link renderOrySkills} / {@link renderOryCommands}, substituting the
|
|
9
12
|
* harness's CLI binary, package name, and the way it references sibling skills
|
|
10
13
|
* and commands. Plugins then write the rendered docs into whatever location
|
package/dist/skills.js
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* permissions-onboarding, contribute-integration, build-integration,
|
|
7
7
|
* e2b-sandbox, build-agent) and the local-stack commands (local-up, local-down) live once,
|
|
8
8
|
* as token-bearing templates under `packages/core/assets/`. Every harness plugin renders them
|
|
9
|
+
* e2b-sandbox, temporal-worker) and the local-stack commands (local-up,
|
|
10
|
+
* local-down, temporal-up) live once, as token-bearing templates under
|
|
11
|
+
* `packages/core/assets/`. Every harness plugin renders them
|
|
9
12
|
* through {@link renderOrySkills} / {@link renderOryCommands}, substituting the
|
|
10
13
|
* harness's CLI binary, package name, and the way it references sibling skills
|
|
11
14
|
* and commands. Plugins then write the rendered docs into whatever location
|
|
@@ -91,6 +94,11 @@ const SKILL_SOURCES = [
|
|
|
91
94
|
name: "ory-build-agent",
|
|
92
95
|
file: "skills/ory-build-agent/SKILL.md",
|
|
93
96
|
},
|
|
97
|
+
{
|
|
98
|
+
id: "temporal-worker",
|
|
99
|
+
name: "ory-temporal-worker",
|
|
100
|
+
file: "skills/ory-temporal-worker/SKILL.md",
|
|
101
|
+
},
|
|
94
102
|
];
|
|
95
103
|
const COMMAND_SOURCES = [
|
|
96
104
|
{
|
|
@@ -107,6 +115,13 @@ const COMMAND_SOURCES = [
|
|
|
107
115
|
description: "Stop the local Ory dev stack, preserving data volumes.",
|
|
108
116
|
file: "commands/local-down.md",
|
|
109
117
|
},
|
|
118
|
+
{
|
|
119
|
+
id: "temporal-up",
|
|
120
|
+
name: "ory-temporal-up",
|
|
121
|
+
slug: "temporal-up",
|
|
122
|
+
description: "Start the local Temporal TypeScript dev server (Temporal Server + Web UI) for the Ory-authed worker scaffold.",
|
|
123
|
+
file: "commands/temporal-up.md",
|
|
124
|
+
},
|
|
110
125
|
];
|
|
111
126
|
/** Names of the skills materialized by the plugins (for uninstall cleanup). */
|
|
112
127
|
exports.ORY_SKILL_NAMES = SKILL_SOURCES.map((s) => s.name);
|
|
@@ -133,21 +148,25 @@ function buildProfile(harness, opts) {
|
|
|
133
148
|
const skillRef = (name) => harness === "claude-code" ? code(`/project:${name}`) : code(name);
|
|
134
149
|
let localUp;
|
|
135
150
|
let localDown;
|
|
151
|
+
let temporalUp;
|
|
136
152
|
switch (harness) {
|
|
137
153
|
case "claude-code":
|
|
138
154
|
localUp = code("/ory-agent-plugin:local-up");
|
|
139
155
|
localDown = code("/ory-agent-plugin:local-down");
|
|
156
|
+
temporalUp = code("/ory-agent-plugin:temporal-up");
|
|
140
157
|
break;
|
|
141
158
|
case "gemini-cli":
|
|
142
159
|
case "opencode":
|
|
143
160
|
localUp = code("/ory:local-up");
|
|
144
161
|
localDown = code("/ory:local-down");
|
|
162
|
+
temporalUp = code("/ory:temporal-up");
|
|
145
163
|
break;
|
|
146
164
|
case "codex":
|
|
147
165
|
case "openclaw":
|
|
148
166
|
default:
|
|
149
167
|
localUp = code("ory-local-up");
|
|
150
168
|
localDown = code("ory-local-down");
|
|
169
|
+
temporalUp = code("ory-temporal-up");
|
|
151
170
|
break;
|
|
152
171
|
}
|
|
153
172
|
return {
|
|
@@ -161,8 +180,11 @@ function buildProfile(harness, opts) {
|
|
|
161
180
|
"{{REF_LOGIN_FLOW}}": skillRef("ory-login-flow"),
|
|
162
181
|
"{{REF_SOCIAL_LOGIN}}": skillRef("ory-social-login"),
|
|
163
182
|
"{{REF_LOCAL_DEV}}": skillRef("ory-local-dev"),
|
|
183
|
+
"{{REF_PERMISSIONS_ONBOARDING}}": skillRef("ory-permissions-onboarding"),
|
|
184
|
+
"{{REF_TEMPORAL_WORKER}}": skillRef("ory-temporal-worker"),
|
|
164
185
|
"{{REF_LOCAL_UP}}": localUp,
|
|
165
186
|
"{{REF_LOCAL_DOWN}}": localDown,
|
|
187
|
+
"{{REF_TEMPORAL_UP}}": temporalUp,
|
|
166
188
|
},
|
|
167
189
|
};
|
|
168
190
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
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",
|