@ora-ai/cli 0.1.0 → 0.2.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 CHANGED
@@ -36,6 +36,81 @@ key is stored at `~/.config/ora/config.json` (0600) and exchanged for a
36
36
  short-lived token on every call — the key itself never travels beyond the
37
37
  token exchange.
38
38
 
39
+ ### Point the CLI at an environment (`--api-url`)
40
+
41
+ By default the CLI talks to the URL embedded in its spec
42
+ (`https://api.agentfront.sh`). To target staging, a dev cluster, or any
43
+ self-hosted ora, set the API base **once at login** — it's remembered in
44
+ `~/.config/ora/config.json`:
45
+
46
+ ora login --api-url https://api.staging.agentfront.sh # staging
47
+ ora login --api-url http://api.localhost:8081 # local k3d dev
48
+
49
+ Precedence for every command: `--api-url` flag > `ORA_API_URL` env >
50
+ `config.json` > the spec's default. So one-off calls can override without
51
+ re-logging-in:
52
+
53
+ ora tunnels list --api-url https://api.staging.agentfront.sh
54
+ ORA_API_URL=https://api.staging.agentfront.sh ora whoami
55
+
56
+ ## Tunnels — expose your localhost to ora (like `ngrok http`)
57
+
58
+ Let ora's scans and journeys reach a dev site running on your machine.
59
+ One command, prints a working URL, forwards until Ctrl-C:
60
+
61
+ ora tunnel 3000
62
+
63
+ 🚇 ora tunnel — dev-3000
64
+ forwards localhost:3000 → 924649e0…
65
+ url https://924649e0-….t.agentfront.sh/?ora_token=ora_tt_…
66
+ only holders of this link reach it — paste it as a journey targetDomain
67
+ ● connected — Ctrl-C to stop
68
+ 200 GET / 8ms
69
+
70
+ The port is chosen here, at connect time — the server can only ask your
71
+ connected CLI to fetch; it never reaches into your machine. Re-running
72
+ `ora tunnel 3000` reuses the same tunnel (and URL): the per-tunnel secret is
73
+ remembered in `~/.config/ora/tunnel-secrets.json` (0600), like ngrok's
74
+ authtoken.
75
+
76
+ ### Access modes (`--access`)
77
+
78
+ ora tunnel 3000 # protected (default): the printed
79
+ # link works; strangers get 404
80
+ ora tunnel 3000 --access public # open URL — answer engines can
81
+ # browse/index the dev site
82
+ ora tunnel 3000 --access private # no URL; only ora's own scanners
83
+
84
+ | mode | who reaches `https://<id>.t.<domain>` | use it for |
85
+ |---|---|---|
86
+ | `protected` | holders of the printed link (`?ora_token=…` or an `X-Ora-Tunnel-Token` header) | journeys, sharing with a teammate |
87
+ | `public` | anyone — no credential | letting real answer engines measure the dev site |
88
+ | `private` | nobody — 404; only ora's in-cluster scanners via `tunnel://<id>/` | scan-only workflows |
89
+
90
+ Everything else answers 404 identically (a private tunnel is
91
+ indistinguishable from a nonexistent one), revoked answers 410, and a tunnel
92
+ whose CLI isn't currently connected answers 502 `TUNNEL_NOT_CONNECTED`.
93
+
94
+ ### Point a run at your tunnel
95
+
96
+ - **Journey**: create the tunnel `--access public`, then use the hostname as
97
+ the journey's `targetDomain` — e.g. `924649e0-….t.agentfront.sh`. The
98
+ agent browses it like any site.
99
+ - **Scan**: `{ "url": "tunnel://<tunnelId>/", "url_kind": "tunnel" }` — works
100
+ for any access mode, including `private`.
101
+
102
+ ### Manage tunnels
103
+
104
+ ora tunnels list # status-glyph table (● connected ✖ revoked …)
105
+ ora tunnels get <id>
106
+ ora tunnels revoke <id> # kill the live connection, keep the row
107
+ ora tunnels delete <id> # revoke + remove the row entirely
108
+
109
+ Quick local target to test with:
110
+
111
+ node -e 'require("http").createServer((q,r)=>{r.writeHead(200,{"content-type":"text/html"});r.end("<h1>it works</h1>")}).listen(3000)'
112
+ ora tunnel 3000 # then open the printed url
113
+
39
114
  ## Use
40
115
 
41
116
  Every command's `--help` ends with a ready-to-run example (including a request
@@ -15,6 +15,7 @@ export interface BodyFieldMeta {
15
15
  required: boolean;
16
16
  kind: "string" | "number" | "boolean" | "object" | "array";
17
17
  enum?: string[];
18
+ description?: string;
18
19
  placeholder: string;
19
20
  }
20
21
  export interface OperationMeta {
@@ -39,7 +40,7 @@ export interface OperationMeta {
39
40
  }
40
41
  export declare const SPEC: {
41
42
  readonly version: "1.0.0";
42
- readonly contentHash: "d1aeca5bf5255cdfbdf7836aace5a10fc4242ce23a30dd16761092e8383291b0";
43
+ readonly contentHash: "65bdf7f72ee8c25653714f60593e05cbeccce8c16fb39785e985383be0f6ad72";
43
44
  readonly server: "https://api.agentfront.sh";
44
45
  readonly bin: "ora";
45
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/generated/operations.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,eAAO,MAAM,IAAI;;;;;CAKP,CAAC;AAEX,eAAO,MAAM,UAAU,EAAE,aAAa,EAu/DrC,CAAC"}
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/generated/operations.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,eAAO,MAAM,IAAI;;;;;CAKP,CAAC;AAEX,eAAO,MAAM,UAAU,EAAE,aAAa,EAk9ErC,CAAC"}
@@ -1,9 +1,9 @@
1
1
  // GENERATED by scripts/generate.mjs — DO NOT EDIT.
2
- // Source: openapi/ora-public.openapi.json (sha256 d1aeca5bf5255cdfbdf7836aace5a10fc4242ce23a30dd16761092e8383291b0)
2
+ // Source: openapi/ora-public.openapi.json (sha256 65bdf7f72ee8c25653714f60593e05cbeccce8c16fb39785e985383be0f6ad72)
3
3
  // Regenerate: yarn nx run ora-cli:generate
4
4
  export const SPEC = {
5
5
  "version": "1.0.0",
6
- "contentHash": "d1aeca5bf5255cdfbdf7836aace5a10fc4242ce23a30dd16761092e8383291b0",
6
+ "contentHash": "65bdf7f72ee8c25653714f60593e05cbeccce8c16fb39785e985383be0f6ad72",
7
7
  "server": "https://api.agentfront.sh",
8
8
  "bin": "ora"
9
9
  };
@@ -210,6 +210,394 @@ export const OPERATIONS = [
210
210
  "command": "ora analytics overview"
211
211
  }
212
212
  },
213
+ {
214
+ "id": "benchmarks.create",
215
+ "commandPath": [
216
+ "benchmarks",
217
+ "create"
218
+ ],
219
+ "method": "post",
220
+ "pathTemplate": "/experiment/v1/benchmarks",
221
+ "summary": "Create a benchmark and start async task generation (poll get until status 'ready', then launch)",
222
+ "scope": "benchmarks:write",
223
+ "product": "experiment",
224
+ "pathParams": [],
225
+ "queryParams": [],
226
+ "hasBody": true,
227
+ "bodyRequired": true,
228
+ "isStream": false,
229
+ "bodyFields": [
230
+ {
231
+ "name": "name",
232
+ "required": true,
233
+ "kind": "string",
234
+ "description": "Display name for the benchmark (≤160 chars).",
235
+ "placeholder": "tavily-search A/B"
236
+ },
237
+ {
238
+ "name": "description",
239
+ "required": false,
240
+ "kind": "string",
241
+ "description": "Optional longer description shown on the benchmark card.",
242
+ "placeholder": "<description>"
243
+ },
244
+ {
245
+ "name": "subjectKind",
246
+ "required": false,
247
+ "kind": "string",
248
+ "enum": [
249
+ "skill",
250
+ "tools",
251
+ "addon",
252
+ "custom"
253
+ ],
254
+ "description": "What the benchmark measures — defaults to 'skill'. See the enum description for each kind's rules.",
255
+ "placeholder": "addon"
256
+ },
257
+ {
258
+ "name": "skillRef",
259
+ "required": false,
260
+ "kind": "string",
261
+ "description": "The skill under test as '<source>:<id>' — sources: 'custom' (an org-authored skill, id from the skills API), 'builtin' (a starter example), 'git' (a git-imported skill). E.g. 'custom:8c1d…'. REQUIRED iff subjectKind 'skill'; forbidden otherwise.",
262
+ "placeholder": "<skillRef>"
263
+ },
264
+ {
265
+ "name": "subjectName",
266
+ "required": false,
267
+ "kind": "string",
268
+ "description": "Display name of a NON-skill subject (e.g. 'Tavily search', 'monday.com remote MCP'). Required iff subjectKind ≠ 'skill'; forbidden for 'skill' (the skill's own name is used).",
269
+ "placeholder": "Tavily search"
270
+ },
271
+ {
272
+ "name": "armConfig",
273
+ "required": false,
274
+ "kind": "object",
275
+ "description": "Frozen per-arm run-payload deltas. Required for subjectKind 'custom' and comparisonMode 'ab_custom'; for 'tools'/'addon' subjects the treatment side is derived when omitted.",
276
+ "placeholder": "{\"treatment\":{\"addons\":{\"tavily\":{\"secretId\":\"<org-secret-uuid>\"}}}}"
277
+ },
278
+ {
279
+ "name": "comparisonMode",
280
+ "required": false,
281
+ "kind": "string",
282
+ "enum": [
283
+ "ab_vs_none",
284
+ "ab_custom",
285
+ "single"
286
+ ],
287
+ "description": "The baseline design — defaults to 'ab_vs_none'. See the enum description for each mode.",
288
+ "placeholder": "ab_vs_none"
289
+ },
290
+ {
291
+ "name": "baselineLabel",
292
+ "required": false,
293
+ "kind": "string",
294
+ "description": "Baseline arm's display label (e.g. 'REST API'). Required iff comparisonMode 'ab_custom'; forbidden otherwise.",
295
+ "placeholder": "<baselineLabel>"
296
+ },
297
+ {
298
+ "name": "treatmentLabel",
299
+ "required": false,
300
+ "kind": "string",
301
+ "description": "Treatment arm's display label (e.g. 'Remote MCP'). Required iff comparisonMode 'ab_custom'; forbidden otherwise.",
302
+ "placeholder": "<treatmentLabel>"
303
+ },
304
+ {
305
+ "name": "taskCount",
306
+ "required": false,
307
+ "kind": "number",
308
+ "description": "How many tasks to auto-generate (1–50, default 5). Runs launched = taskCount × matrix cells × arms (2 arms unless 'single').",
309
+ "placeholder": "5"
310
+ },
311
+ {
312
+ "name": "matrix",
313
+ "required": true,
314
+ "kind": "array",
315
+ "description": "The (harness, model) cells to fan out over — 1 to 12 cells.",
316
+ "placeholder": "[{\"harness\":\"claude-code\",\"model\":\"claude-sonnet-5\"},{\"harness\":\"codex\",\"model\":\"gpt-5.5\"}]"
317
+ },
318
+ {
319
+ "name": "promise",
320
+ "required": false,
321
+ "kind": "string",
322
+ "description": "The claim under test, driving task generation and the pre-registered rubrics (e.g. 'Tavily search finds fresher, better-sourced answers than no web access'). Optional for subjectKind 'skill' (omitted → extracted from the skill body); REQUIRED for every other kind.",
323
+ "placeholder": "Web search via Tavily produces fresher, better-sourced answers than no web access"
324
+ }
325
+ ],
326
+ "watchable": true,
327
+ "help": {
328
+ "command": "ora benchmarks create --file run.json --watch",
329
+ "body": "{\n \"name\": \"tavily-search A/B\",\n \"subjectKind\": \"addon\",\n \"subjectName\": \"Tavily search\",\n \"promise\": \"Web search via Tavily produces fresher, better-sourced answers than no web access\",\n \"armConfig\": {\n \"treatment\": {\n \"addons\": {\n \"tavily\": {\n \"secretId\": \"<org-secret-uuid>\"\n }\n }\n }\n },\n \"taskCount\": 5,\n \"matrix\": [\n {\n \"harness\": \"claude-code\",\n \"model\": \"claude-sonnet-5\"\n },\n {\n \"harness\": \"codex\",\n \"model\": \"gpt-5.5\"\n }\n ]\n}"
330
+ }
331
+ },
332
+ {
333
+ "id": "benchmarks.delete",
334
+ "commandPath": [
335
+ "benchmarks",
336
+ "delete"
337
+ ],
338
+ "method": "delete",
339
+ "pathTemplate": "/experiment/v1/benchmarks/{id}",
340
+ "summary": "Delete a benchmark and its tasks/facts (409 while running)",
341
+ "scope": "benchmarks:write",
342
+ "product": "experiment",
343
+ "pathParams": [
344
+ {
345
+ "name": "id"
346
+ }
347
+ ],
348
+ "queryParams": [],
349
+ "hasBody": false,
350
+ "bodyRequired": false,
351
+ "isStream": false,
352
+ "watchable": false,
353
+ "help": {
354
+ "command": "ora benchmarks delete <id>"
355
+ }
356
+ },
357
+ {
358
+ "id": "benchmarks.generate",
359
+ "commandPath": [
360
+ "benchmarks",
361
+ "generate"
362
+ ],
363
+ "method": "post",
364
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/generate",
365
+ "summary": "Regenerate the task corpus (status ready/failed only — wipes existing tasks and their rubrics)",
366
+ "scope": "benchmarks:write",
367
+ "product": "experiment",
368
+ "pathParams": [
369
+ {
370
+ "name": "id"
371
+ }
372
+ ],
373
+ "queryParams": [],
374
+ "hasBody": false,
375
+ "bodyRequired": false,
376
+ "isStream": false,
377
+ "watchable": true,
378
+ "help": {
379
+ "command": "ora benchmarks generate <id> --watch"
380
+ }
381
+ },
382
+ {
383
+ "id": "benchmarks.get",
384
+ "commandPath": [
385
+ "benchmarks",
386
+ "get"
387
+ ],
388
+ "method": "get",
389
+ "pathTemplate": "/experiment/v1/benchmarks/{id}",
390
+ "summary": "Benchmark detail: status to poll, tasks + rubrics, per-run facts, live aggregate + verdict",
391
+ "scope": "benchmarks:read",
392
+ "product": "experiment",
393
+ "pathParams": [
394
+ {
395
+ "name": "id"
396
+ }
397
+ ],
398
+ "queryParams": [],
399
+ "hasBody": false,
400
+ "bodyRequired": false,
401
+ "isStream": false,
402
+ "watchable": false,
403
+ "help": {
404
+ "command": "ora benchmarks get 1f7e4d1c-4b2a-4f3e-9d8c-5a6b7c8d9e0f"
405
+ }
406
+ },
407
+ {
408
+ "id": "benchmarks.launch",
409
+ "commandPath": [
410
+ "benchmarks",
411
+ "launch"
412
+ ],
413
+ "method": "post",
414
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/launch",
415
+ "summary": "Launch: fan out task × matrix-cell × arm runs (async — poll get until status 'completed')",
416
+ "scope": "benchmarks:write",
417
+ "product": "experiment",
418
+ "pathParams": [
419
+ {
420
+ "name": "id"
421
+ }
422
+ ],
423
+ "queryParams": [],
424
+ "hasBody": false,
425
+ "bodyRequired": false,
426
+ "isStream": false,
427
+ "watchable": true,
428
+ "help": {
429
+ "command": "ora benchmarks launch <id> --watch"
430
+ }
431
+ },
432
+ {
433
+ "id": "benchmarks.list",
434
+ "commandPath": [
435
+ "benchmarks",
436
+ "list"
437
+ ],
438
+ "method": "get",
439
+ "pathTemplate": "/experiment/v1/benchmarks",
440
+ "summary": "List the org's benchmarks (id, status, verdict, subject)",
441
+ "scope": "benchmarks:read",
442
+ "product": "experiment",
443
+ "pathParams": [],
444
+ "queryParams": [],
445
+ "hasBody": false,
446
+ "bodyRequired": false,
447
+ "isStream": false,
448
+ "watchable": false,
449
+ "help": {
450
+ "command": "ora benchmarks list"
451
+ }
452
+ },
453
+ {
454
+ "id": "benchmarks.publish",
455
+ "commandPath": [
456
+ "benchmarks",
457
+ "publish"
458
+ ],
459
+ "method": "post",
460
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/publish",
461
+ "summary": "Publish a completed benchmark to the anonymous public catalog (idempotent slug upsert)",
462
+ "scope": "benchmarks:write",
463
+ "product": "experiment",
464
+ "pathParams": [
465
+ {
466
+ "name": "id"
467
+ }
468
+ ],
469
+ "queryParams": [],
470
+ "hasBody": true,
471
+ "bodyRequired": true,
472
+ "isStream": false,
473
+ "bodyFields": [
474
+ {
475
+ "name": "slug",
476
+ "required": false,
477
+ "kind": "string",
478
+ "description": "Public catalog URL slug (lowercase [a-z0-9-], ≤80). Omitted → the benchmark's own generated slug. 409 benchmark_slug_taken if another published benchmark holds it.",
479
+ "placeholder": "tavily-search-ab"
480
+ }
481
+ ],
482
+ "watchable": false,
483
+ "help": {
484
+ "command": "ora benchmarks publish 1f7e4d1c-4b2a-4f3e-9d8c-5a6b7c8d9e0f --file run.json",
485
+ "body": "{\n \"slug\": \"tavily-search-ab\"\n}"
486
+ }
487
+ },
488
+ {
489
+ "id": "benchmarks.regrade",
490
+ "commandPath": [
491
+ "benchmarks",
492
+ "regrade"
493
+ ],
494
+ "method": "post",
495
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/regrade",
496
+ "summary": "Clear and re-run judge-panel grading (rubrics + blind pairwise) for a completed benchmark",
497
+ "scope": "benchmarks:write",
498
+ "product": "experiment",
499
+ "pathParams": [
500
+ {
501
+ "name": "id"
502
+ }
503
+ ],
504
+ "queryParams": [],
505
+ "hasBody": false,
506
+ "bodyRequired": false,
507
+ "isStream": false,
508
+ "watchable": true,
509
+ "help": {
510
+ "command": "ora benchmarks regrade <id> --watch"
511
+ }
512
+ },
513
+ {
514
+ "id": "benchmarks.stream",
515
+ "commandPath": [
516
+ "benchmarks",
517
+ "stream"
518
+ ],
519
+ "method": "get",
520
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/stream",
521
+ "summary": "Live SSE stream: status transitions, per-run facts, grading, publish state (terminal status closes it)",
522
+ "scope": "benchmarks:read",
523
+ "product": "experiment",
524
+ "pathParams": [
525
+ {
526
+ "name": "id"
527
+ }
528
+ ],
529
+ "queryParams": [],
530
+ "hasBody": false,
531
+ "bodyRequired": false,
532
+ "isStream": true,
533
+ "watchable": false,
534
+ "help": {
535
+ "command": "ora benchmarks stream 1f7e4d1c-4b2a-4f3e-9d8c-5a6b7c8d9e0f"
536
+ }
537
+ },
538
+ {
539
+ "id": "benchmarks.unpublish",
540
+ "commandPath": [
541
+ "benchmarks",
542
+ "unpublish"
543
+ ],
544
+ "method": "post",
545
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/unpublish",
546
+ "summary": "Remove a benchmark from the public catalog (data kept; re-publish any time)",
547
+ "scope": "benchmarks:write",
548
+ "product": "experiment",
549
+ "pathParams": [
550
+ {
551
+ "name": "id"
552
+ }
553
+ ],
554
+ "queryParams": [],
555
+ "hasBody": false,
556
+ "bodyRequired": false,
557
+ "isStream": false,
558
+ "watchable": false,
559
+ "help": {
560
+ "command": "ora benchmarks unpublish <id>"
561
+ }
562
+ },
563
+ {
564
+ "id": "benchmarks.updateTask",
565
+ "commandPath": [
566
+ "benchmarks",
567
+ "update-task"
568
+ ],
569
+ "method": "put",
570
+ "pathTemplate": "/experiment/v1/benchmarks/{id}/tasks/{taskId}",
571
+ "summary": "Edit a generated task's prompt before launch (status 'ready' only)",
572
+ "scope": "benchmarks:write",
573
+ "product": "experiment",
574
+ "pathParams": [
575
+ {
576
+ "name": "id"
577
+ },
578
+ {
579
+ "name": "taskId"
580
+ }
581
+ ],
582
+ "queryParams": [],
583
+ "hasBody": true,
584
+ "bodyRequired": true,
585
+ "isStream": false,
586
+ "bodyFields": [
587
+ {
588
+ "name": "prompt",
589
+ "required": true,
590
+ "kind": "string",
591
+ "description": "The replacement task prompt, dispatched verbatim as each run's intent. Editable only while the benchmark is 'ready' (pre-launch).",
592
+ "placeholder": "Research the three largest EU battery-storage tenders announced this quarter and cite each source."
593
+ }
594
+ ],
595
+ "watchable": false,
596
+ "help": {
597
+ "command": "ora benchmarks update-task 1f7e4d1c-4b2a-4f3e-9d8c-5a6b7c8d9e0f 8a9b0c1d-2e3f-4a5b-8c7d-6e5f4a3b2c1d --file run.json",
598
+ "body": "{\n \"prompt\": \"Research the three largest EU battery-storage tenders announced this quarter and cite each source.\"\n}"
599
+ }
600
+ },
213
601
  {
214
602
  "id": "domains.add",
215
603
  "commandPath": [
@@ -587,6 +975,93 @@ export const OPERATIONS = [
587
975
  "command": "ora experiment runs trajectory <id>"
588
976
  }
589
977
  },
978
+ {
979
+ "id": "experiment.secrets.create",
980
+ "commandPath": [
981
+ "experiment",
982
+ "secrets",
983
+ "create"
984
+ ],
985
+ "method": "post",
986
+ "pathTemplate": "/experiment/v1/secrets",
987
+ "summary": "Create an org secret (encrypted at rest; the value is never readable back through this surface)",
988
+ "scope": "secrets:write",
989
+ "product": "platform",
990
+ "pathParams": [],
991
+ "queryParams": [],
992
+ "hasBody": true,
993
+ "bodyRequired": true,
994
+ "isStream": false,
995
+ "bodyFields": [
996
+ {
997
+ "name": "name",
998
+ "required": true,
999
+ "kind": "string",
1000
+ "description": "Secret name (letters, numbers, '.', '_', '-') — how add-on configs and env bindings will refer to it in the UI; the wire references use the returned id.",
1001
+ "placeholder": "MONDAY_API_KEY"
1002
+ },
1003
+ {
1004
+ "name": "value",
1005
+ "required": true,
1006
+ "kind": "string",
1007
+ "description": "The secret value (an API token, key, …). Encrypted at rest; NEVER echoed back by any read this surface offers — reads return metadata only.",
1008
+ "placeholder": "<the token — never logged, never echoed>"
1009
+ }
1010
+ ],
1011
+ "watchable": false,
1012
+ "help": {
1013
+ "command": "ora experiment secrets create --file run.json",
1014
+ "body": "{\n \"name\": \"MONDAY_API_KEY\",\n \"value\": \"<the token — never logged, never echoed>\"\n}"
1015
+ }
1016
+ },
1017
+ {
1018
+ "id": "experiment.secrets.delete",
1019
+ "commandPath": [
1020
+ "experiment",
1021
+ "secrets",
1022
+ "delete"
1023
+ ],
1024
+ "method": "delete",
1025
+ "pathTemplate": "/experiment/v1/secrets/{id}",
1026
+ "summary": "Delete an org secret (runs already launched keep nothing; future boot-fetches fail closed)",
1027
+ "scope": "secrets:write",
1028
+ "product": "platform",
1029
+ "pathParams": [
1030
+ {
1031
+ "name": "id"
1032
+ }
1033
+ ],
1034
+ "queryParams": [],
1035
+ "hasBody": false,
1036
+ "bodyRequired": false,
1037
+ "isStream": false,
1038
+ "watchable": false,
1039
+ "help": {
1040
+ "command": "ora experiment secrets delete <id>"
1041
+ }
1042
+ },
1043
+ {
1044
+ "id": "experiment.secrets.list",
1045
+ "commandPath": [
1046
+ "experiment",
1047
+ "secrets",
1048
+ "list"
1049
+ ],
1050
+ "method": "get",
1051
+ "pathTemplate": "/experiment/v1/secrets",
1052
+ "summary": "List the org's secrets (metadata only — ids for armConfig/envBindings references)",
1053
+ "scope": "secrets:read",
1054
+ "product": "platform",
1055
+ "pathParams": [],
1056
+ "queryParams": [],
1057
+ "hasBody": false,
1058
+ "bodyRequired": false,
1059
+ "isStream": false,
1060
+ "watchable": false,
1061
+ "help": {
1062
+ "command": "ora experiment secrets list"
1063
+ }
1064
+ },
590
1065
  {
591
1066
  "id": "intents.addPrompt",
592
1067
  "commandPath": [