@uluops/ops-sdk 6.4.1 → 6.5.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/CHANGELOG.md +52 -5
- package/README.md +158 -39
- package/dist/client.d.ts +31 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +43 -2
- package/dist/client.js.map +1 -1
- package/dist/config/constants.d.ts +1 -1
- package/dist/config/generated-version.d.ts +1 -1
- package/dist/config/generated-version.js +1 -1
- package/dist/config/workspace-org.d.ts +25 -4
- package/dist/config/workspace-org.d.ts.map +1 -1
- package/dist/config/workspace-org.js +71 -18
- package/dist/config/workspace-org.js.map +1 -1
- package/dist/http/http-client.d.ts +5 -0
- package/dist/http/http-client.d.ts.map +1 -1
- package/dist/http/http-client.js +40 -3
- package/dist/http/http-client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/operations/analytics.d.ts +1 -1
- package/dist/operations/analytics.js +1 -1
- package/dist/operations/orgs.d.ts +26 -0
- package/dist/operations/orgs.d.ts.map +1 -1
- package/dist/operations/orgs.js +31 -0
- package/dist/operations/orgs.js.map +1 -1
- package/dist/operations/projects.d.ts +28 -0
- package/dist/operations/projects.d.ts.map +1 -1
- package/dist/operations/projects.js +61 -0
- package/dist/operations/projects.js.map +1 -1
- package/dist/operations/runs.d.ts +1 -1
- package/dist/operations/runs.d.ts.map +1 -1
- package/dist/operations/runs.js +9 -4
- package/dist/operations/runs.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/log.d.ts +410 -0
- package/dist/types/log.d.ts.map +1 -0
- package/dist/types/log.js +191 -0
- package/dist/types/log.js.map +1 -0
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,55 @@ All notable changes to `@uluops/ops-sdk` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [6.5.1] - 2026-09-16
|
|
10
|
+
|
|
11
|
+
Patch: the ship-run-#48 fixes — three runtime defects under the org-scoped and session paths, the README/JSDoc corrections from consumer-validate run #47, and package metadata. No new surface; `client.runs.save`'s declared return type widens to what it already returned.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **README: the Quick Start's "Requires a `plus` tier subscription or higher" notice on Project Analytics is gone.** Every tracker analytics feature moved to `free` in `@uluops/tier-gate` 0.5.0/0.6.0 (2026-08-21; the API pins 0.6.0), so the notice described a `ForbiddenError` no caller has been able to receive for weeks. No SDK behavior changes — the methods, the `ForbiddenError` class and the 403 mapping are unchanged; only the claim about who gets one.
|
|
16
|
+
- **The no-credentials warning now says where to get a key** — `https://app.uluops.ai` (Settings → API keys) is in the runtime message, not only in README prose. Message text only; the condition and log level are unchanged (consumer-validate run #47, dx-validator).
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **README API-reference examples caught up with the 6.0.0 envelope change** (consumer-validate run #47 — docs-validator and public-interface-validator, the latter's AF-003). `projects.list`, `projects.listIssues` and `runs.listByProject` return `{data, total}` since 6.0.0 but three examples still iterated the raw result (`TypeError: … is not iterable` on copy-paste); `runs.getAgentRunsAnalysis` was destructured as `{items}` after the 6.0.0 `items → data` rename; and `projects.listIssuesWithCount` — removed in 6.0.0 — still had a full section and a stale prose mention. The section is gone, the examples show the envelope, and the prose names the two surviving list methods. Also added the two methods that had no README presence at all — `projects.mergeProjects` (spec v0.3.4) and `auth.totpLogin` — plus `ULUOPS_ORG_SLUG` in the environment-variables table and the `orgs`/`admin` domains in the Features list (8 domains, not 7). The Quick Start guards the nullable `correlation` so it typechecks under `strict`.
|
|
21
|
+
- **CHANGELOG hygiene**: the `[Unreleased]` section had drifted to the middle of the file (below six released versions) and three headers used an em dash before the date; both normalized.
|
|
22
|
+
- **README: the `runs.update` example passed a nested `tokens` object** — `UpdateAgentInput` is flat by design (`inputTokens`, `outputTokens`, …) and the update path forwards `agents` verbatim, so the documented example sent a key the server drops and reported success. The example now shows the flat fields (ship run #48 — anxiety-reader F1, release-readiness). Also: "Three org-routing errors" above a five-row table; the `#org-routing` anchor pointed at a slug that does not exist; the idempotency-key row states that the content hash is key-order-sensitive inside caller-supplied objects; the "Type-Safe" feature bullet says what write-side validation does and does not do; `findWorkspaceOrgFile` / `WORKSPACE_ORG_FILE` / `PERSONAL_ORG_SENTINEL` and `ApiKeyAuth` / `JwtSessionAuth` are named where their documented siblings are.
|
|
23
|
+
- **`client.runs.save` is typed `Promise<SaveRunResponseWithEcho>`** — what the operation has returned since 5.22.0 (`analysisWrite: AnalysisWriteEcho | null`); the facade narrowed it to `SaveRunResponse`, so the echo the 5.22.0 entry advertises was unreachable through the typed client. Type-only widening; no runtime change.
|
|
24
|
+
- **JSDoc**: `runs.getAgentRunsAnalysis` `@returns` said `items` (the 6.0.0 rename made it `data`); `analytics.getVelocity` `@returns` named a `period` the parsed shape does not carry. A sweep of every `@returns` mentioning `items` found only these two.
|
|
25
|
+
- **`withOrg`'s catch guards the error type** (`instanceof InputValidationError`) instead of asserting it, matching every other catch site; and its comment no longer claims the override covers `requestRaw` / `requestBinary` / `requestStream` (it does not — see Known below).
|
|
26
|
+
- **package.json** carries `homepage`, `bugs` and `sideEffects: false` (the npm page had no Homepage/Issues links; bundlers could not tree-shake an ESM-only package without the flag).
|
|
27
|
+
- **Tests**: `issues.get(id, { org })` is now actually exercised (the previous test's name promised it and the body called only `analytics.getAgentPerformance`); the update-preview scope guard's documented explicit-`null` rejection is pinned; `validateUuid`'s version/variant nibbles are pinned against a widened regex.
|
|
28
|
+
|
|
29
|
+
### Fixed (runtime — ship run #48, code-auditor; each verified against source and `dist/` before the fix, each pinned by a test written first and watched fail)
|
|
30
|
+
|
|
31
|
+
- **`logout()` now clears the installed session.** It revoked every session server-side and returned, leaving the `JwtSessionAuth` — token and, with `autoRefresh` (the default), the password — in place: `isAuthenticated()` stayed true on a revoked token, and the next 401 re-logged-in and silently undid the logout. It now calls the strategy's `clearSession()` after `logoutAll` resolves; the next request fails `UnauthorizedError` before it is sent and `login()` is the only way back. An API-key strategy is left alone (keys are not sessions). Behaviour change on the auth lifecycle; test: `client.test.ts` "logout() clears the local session".
|
|
32
|
+
- **Org-scoped views share the root client's resilience state.** `withOrg` returns a prototype-chained view, and sdk-core writes its token-refresh dedup gate (`refreshPromise`), the last rate-limit headers and the once-per-threshold warning latch through `this` — so each per-call view got its own copy: N concurrent scoped 401s started N re-logins (which revoke each other under the API's single-session default), and `getRateLimitInfo()` / `onRateLimitApproaching` never saw org-scoped traffic. Views now forward those fields (and `authStrategy`) to the one root by accessor; views of views chain to the root, not to each other. The field list is the census of sdk-core 0.17.0's mutable instance fields, and the new org-scope tests exercise refresh dedup and rate-limit visibility THROUGH views rather than trusting the list. The pre-existing dedup test only ever hit the root client.
|
|
33
|
+
- **`save()` uses the same analysis-bearing predicate as `update()`.** Its own copy tested `analysisSummary !== undefined`, so `analysisSummary: []` demanded an echo the server does not emit for an empty write and threw `AnalysisEchoMismatchError` ("the run WAS saved, do not retry") on a wholly successful save. The empty-array boundary is now pinned on the save path too.
|
|
34
|
+
|
|
35
|
+
### Known, not fixed here
|
|
36
|
+
|
|
37
|
+
- **`requestRaw` / `requestBinary` / `requestStream` bypass the org override** — they reach fetch without `request()`, so on a scoped view they send no `X-Org-Slug` and skip the `orgInvalid` rejection. No ops-sdk operation uses them on a scoped path; the `withOrg` comment now says so instead of claiming full coverage (ship run #48).
|
|
38
|
+
|
|
39
|
+
## [6.5.0] - 2026-09-15
|
|
40
|
+
|
|
41
|
+
ulu log, Phase 3 (spec v0.1.13 §3.2/§3.3/§3.5/§3.6; checklist Phase 3). Additive — nothing existing changes shape or signature; one existing function changes what it *accepts* (below, under Changed, because that is the kind of change a signature does not show).
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **`projects.getLog(idOrName, query?, options?)`** — the project log: `run`, `decision` and `regression` events interleaved newest first, keyset-paged (`{ data, count, hasMore, nextCursor? }`; pass `nextCursor` back verbatim). The event union is closed (`LogEvent`, discriminated on `type`) and parsed strictly; `counts` on a `run` is typed `... | null` and IS null on runs saved before migration 065. **Query keys go to the wire as named** (`workflowType`, `includeArchived`) — the API's log schema is camelCase and non-strict, so a snake_cased key is silently ignored with a 200 (the filter vanishes); this call therefore does not use the SDK's generic `toApiQuery`, and the test carries the control showing the generic path would have produced `workflow_type`.
|
|
46
|
+
- **`projects.getLogStat(idOrName, query?, options?)`** — the rollup (`ProjectLogStat`): two frames on two clocks, `decided` = current status of the found issues (sums to `found.issues`), D12's `cameBack.detected` / `reopened` as distinct issues with row counts beside them, D13's `activity.restated`, D14's seven-key `byStatus`.
|
|
47
|
+
- **`orgs.list()`** — `GET /orgs`: the orgs the key holder belongs to, personal included (`OrgListEntry`). What `ulu log --orgs` iterates.
|
|
48
|
+
- **`orgs.getLogStat(slug, query?)`** — the org rollup (`OrgLogStat`): the same body over the org's live projects plus `projects[]` (D15's summary shape, capped at 100 with `hasMoreProjects`) and **`computedAt`** — the org rollup is served from a 60 s TTL cache per (org, window) (D16), and this field is required by the parse: an older API that omits it fails loudly rather than reporting numbers of unknown age.
|
|
49
|
+
- **`readWorkspaceFile(path, uid?)`** → `{ org?, project? } | undefined` — the full workspace file, beside the unchanged `readWorkspaceOrgFile`, which now delegates to it. `project` is validated like the API validates a project name (1–200 chars, no control characters) and is **not** trimmed — a name is matched exactly. **A file carrying `project` without `org` throws** (`"project" requires "org"; use "personal" for no org`), so a project-only file can never shadow an outer org. No resolver is added here: the read-only ladder (`--project` → file → `ULUOPS_PROJECT` → error) belongs to the one command that reads it (D5).
|
|
50
|
+
- Types: `LogEvent` / `LogRunEvent` / `LogDecisionEvent` / `LogRegressionEvent`, `ProjectLogPage`, `ProjectLogQuery`, `LogStatQuery`, `LogStatBody`, `ProjectLogStat`, `OrgLogStat`, `OrgLogProjectSummary`, `OrgListEntry`, `WorkspaceFile`; the Zod schemas beside them.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- **`readWorkspaceOrgFile` no longer throws on a `.uluops.json` that carries `project`** — the allowlist is `org`, `project`, `$schema` (was `org`, `$schema`), and the refusal message now names all three. Same signature, same return; a file that was refused in 6.4.x is read in 6.5.0. This is a semantics-without-signature change and this entry is the only place it shows. **Rollout rule (spec §3.5, by provenance):** because every 6.4.x-and-older reader throws on the key — for every command, not only `ulu log` — `project` may not be written into any checkout, and no docs may describe writing it, until every *installed* copy of this package in that tree is ≥ 6.5.0. The checklist carries the enumeration (`find … -path '*/@uluops/ops-sdk/dist/config/workspace-org.js'`) and the 13-consumer census.
|
|
55
|
+
|
|
7
56
|
## [6.4.1] - 2026-09-15
|
|
8
57
|
|
|
9
58
|
6.4.0 reached Verdaccio only; the review of that change set (anxiety-reader 84 / docs-validator 81 / dx-validator 83 / code-auditor 98, all on the `feat/rehome-surfaces` diff) folded into this release before npm. What changed against 6.4.0:
|
|
@@ -182,9 +231,7 @@ deploys; SDK 6.0.0 (after the flip) re-pins the new shapes strictly.
|
|
|
182
231
|
wire always carried. This is the nullable-score class one ring out from the
|
|
183
232
|
run schemas, which were fixed earlier (fix the pattern, not the citation).
|
|
184
233
|
|
|
185
|
-
## [
|
|
186
|
-
|
|
187
|
-
## [5.22.0] — 2026-08-21
|
|
234
|
+
## [5.22.0] - 2026-08-21
|
|
188
235
|
|
|
189
236
|
> Numbered past 5.21.0, which is reserved by the in-flight per-key-scopes train
|
|
190
237
|
> (staged on Verdaccio 2026-08-21). If this train merges first, scopes rebases and
|
|
@@ -217,7 +264,7 @@ deploys; SDK 6.0.0 (after the flip) re-pins the new shapes strictly.
|
|
|
217
264
|
not throw (nothing was written). Return type is `SaveRunResponseWithEcho` (a superset of
|
|
218
265
|
the previous `SaveRunResponse` — source-compatible).
|
|
219
266
|
|
|
220
|
-
## [5.21.0]
|
|
267
|
+
## [5.21.0] - 2026-08-22
|
|
221
268
|
|
|
222
269
|
### Added — per-key scope on API keys (platform v1.27.0)
|
|
223
270
|
|
|
@@ -236,7 +283,7 @@ deploys; SDK 6.0.0 (after the flip) re-pins the new shapes strictly.
|
|
|
236
283
|
job. (A `.strict()` was tried and reverted after review, 2026-08-22.)
|
|
237
284
|
- `--json` output carries `scope` automatically (plain stringify, no re-parse).
|
|
238
285
|
|
|
239
|
-
## [5.20.0]
|
|
286
|
+
## [5.20.0] - 2026-08-21
|
|
240
287
|
|
|
241
288
|
### Changed
|
|
242
289
|
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
**[UluOps](https://uluops.ai)** ·
|
|
1
|
+
**[UluOps](https://uluops.ai)** · The operations layer for agentic work
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
@@ -45,7 +45,8 @@ const result = await client.runs.save({
|
|
|
45
45
|
],
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
// `correlation` is null on an idempotent replay of a run saved before correlation persistence
|
|
49
|
+
console.log(`Run #${result.run.runNumber} saved: ${result.correlation?.newIssues ?? 'n/a'} new issues`);
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
### Search Issues
|
|
@@ -64,12 +65,6 @@ for (const issue of issues) {
|
|
|
64
65
|
|
|
65
66
|
### Project Analytics
|
|
66
67
|
|
|
67
|
-
> **Requires a `plus` tier subscription or higher.** Every method under
|
|
68
|
-
> [Analytics Operations](#analytics-operations) is tier-gated server-side. On a `free`
|
|
69
|
-
> account — which is the default for a newly registered user — these calls reject with
|
|
70
|
-
> `ForbiddenError: This feature requires plus tier or higher.` The rest of this Quick Start
|
|
71
|
-
> works on any tier; this section does not.
|
|
72
|
-
|
|
73
68
|
```typescript
|
|
74
69
|
const burndown = await client.analytics.getBurndown({
|
|
75
70
|
project: 'my-project',
|
|
@@ -115,12 +110,12 @@ The UluOps SDK provides programmatic access to the UluOps platform API, enabling
|
|
|
115
110
|
- **Analyze Trends**: Get burndown charts, velocity metrics, and taxonomy distribution analytics
|
|
116
111
|
- **Automate Workflows**: Integrate execution tracking into CI/CD and agent pipelines
|
|
117
112
|
|
|
118
|
-
The SDK covers the full platform API surface across
|
|
113
|
+
The SDK covers the full platform API surface across 8 operation domains with full TypeScript support.
|
|
119
114
|
|
|
120
115
|
## Features
|
|
121
116
|
|
|
122
|
-
- **Full API Coverage**: auth, projects, runs, issues, analytics, and
|
|
123
|
-
- **Type-Safe**: Complete TypeScript definitions
|
|
117
|
+
- **Full API Coverage**: auth, projects, runs, issues, analytics, taxonomy, orgs, and admin domains
|
|
118
|
+
- **Type-Safe**: Complete TypeScript definitions; every response is Zod-parsed before it is returned. Write inputs are Zod-validated as a gate (the raw input is what goes to the wire, and the primary writers may pass `_skipClientValidation`) — see [Runs Operations](#runs-operations) for which fields each write validates
|
|
124
119
|
- **Dual Authentication**: API key (preferred) and JWT session support
|
|
125
120
|
- **Automatic Retries**: Exponential backoff for transient errors (502, 503, 504, 429, network failures)
|
|
126
121
|
- **Error Hierarchy**: Typed errors for precise error handling
|
|
@@ -186,7 +181,7 @@ const { sessionToken, user } = await client.login(
|
|
|
186
181
|
);
|
|
187
182
|
|
|
188
183
|
// Client is now authenticated — subsequent requests use the session token
|
|
189
|
-
const projects = await client.projects.list();
|
|
184
|
+
const { data: projects } = await client.projects.list();
|
|
190
185
|
|
|
191
186
|
// Logout when done
|
|
192
187
|
await client.logout();
|
|
@@ -379,7 +374,7 @@ await client.projects.list(); // → constructo
|
|
|
379
374
|
name: a call that names no org creates or targets the *personal* project of that name, even when
|
|
380
375
|
a work org has one by the same name (spec D2). Name the org.
|
|
381
376
|
|
|
382
|
-
|
|
377
|
+
These org-routing errors are worth branching on (all exported with type guards):
|
|
383
378
|
|
|
384
379
|
| Code | Status | Guard | What to do |
|
|
385
380
|
|---|---|---|---|
|
|
@@ -395,13 +390,22 @@ Low-level: `new OpsHttpClient(cfg).withOrg('acme')` returns a view of the client
|
|
|
395
390
|
MCP), `resolveWorkspaceOrg({ explicit, cwd })` implements the spec's D13 rule: an explicit value
|
|
396
391
|
wins; else the nearest `.uluops.json` above `cwd` (`{ "org": "ulu-labs" }`, or `{ "org": "personal" }`
|
|
397
392
|
to stop the walk in a personal repo nested under a work tree); else `ULUOPS_ORG_SLUG`; else your
|
|
398
|
-
personal org. The file may carry only `org`
|
|
393
|
+
personal org. The file may carry only `org`, `project` and `$schema` — any other key is refused, not ignored.
|
|
394
|
+
**`project` (6.5.0, ulu log D5)** is the project name a *read* command resolves when given none —
|
|
395
|
+
`ulu log` today; it governs reads only (no write path consumes it; `ulu exec` keeps flag → env →
|
|
396
|
+
inferred basename). Read it with `readWorkspaceFile(path)` → `{ org?, project? }`; a file carrying
|
|
397
|
+
`project` **must** carry `org` (`"personal"` allowed) or the reader throws, so a project-only file can
|
|
398
|
+
never shadow an outer org. `readWorkspaceOrgFile(path)` keeps its signature and now returns the org
|
|
399
|
+
of such a file instead of refusing it. **Do not write `project` into a checkout until every installed
|
|
400
|
+
`@uluops/ops-sdk` in that tree is ≥ 6.5.0** — older readers throw on the key, for every command.
|
|
399
401
|
Two more refusals since 6.3.1 (security audit run #187): the walk never rises above your home
|
|
400
402
|
directory (a file at `/` or `/Users` cannot become everyone's default), and a file owned by another
|
|
401
403
|
user is refused (a shared parent directory is the planting vector). `"personal"` is also honoured as
|
|
402
404
|
an explicit value — `{ org: 'personal' }` sends no header. On a scoped call the per-call org header
|
|
403
405
|
is set last and an `X-Org-Slug`/`X-Org-Id` in `options.headers` is refused.
|
|
404
406
|
|
|
407
|
+
The pieces it is built from are exported too: `findWorkspaceOrgFile(cwd)` (the bounded upward walk, returning the path of the `.uluops.json` that answered), `WORKSPACE_ORG_FILE` (the file name, `.uluops.json`) and `PERSONAL_ORG_SENTINEL` (`"personal"`, the value that stops the walk and means "no org"). Reach for them when a tool wants to report *which* file answered, as the CLI does.
|
|
408
|
+
|
|
405
409
|
---
|
|
406
410
|
|
|
407
411
|
### Security Events
|
|
@@ -471,6 +475,25 @@ const { user, sessionToken } = await client.auth.login({
|
|
|
471
475
|
});
|
|
472
476
|
```
|
|
473
477
|
|
|
478
|
+
#### `client.auth.totpLogin(input)`
|
|
479
|
+
|
|
480
|
+
Complete an MFA challenge with a TOTP code. Returns the session **without installing it** on the
|
|
481
|
+
client — use the top-level [`client.loginWithTotp()`](#authentication) wrapper when you want the
|
|
482
|
+
session installed. The challenge token is single-use and is consumed before the code is checked.
|
|
483
|
+
|
|
484
|
+
| Parameter | Type | Required | Description |
|
|
485
|
+
|-----------|------|----------|-------------|
|
|
486
|
+
| `mfaChallengeToken` | `string` | Yes | From the `MfaRequiredError` thrown by `login()` |
|
|
487
|
+
| `code` | `string` | Yes | Six-digit TOTP code |
|
|
488
|
+
| `rememberMe` | `boolean` | No | Long-lived session |
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
const { sessionToken, expiresAt } = await client.auth.totpLogin({
|
|
492
|
+
mfaChallengeToken: err.mfaChallengeToken,
|
|
493
|
+
code: '123456',
|
|
494
|
+
});
|
|
495
|
+
```
|
|
496
|
+
|
|
474
497
|
#### `client.auth.logoutAll()`
|
|
475
498
|
|
|
476
499
|
Revoke all active sessions for the current user.
|
|
@@ -654,7 +677,7 @@ Manage projects.
|
|
|
654
677
|
List all projects.
|
|
655
678
|
|
|
656
679
|
```typescript
|
|
657
|
-
const projects = await client.projects.list();
|
|
680
|
+
const { data: projects, total } = await client.projects.list();
|
|
658
681
|
for (const project of projects) {
|
|
659
682
|
console.log(project.id, project.name, project.createdAt);
|
|
660
683
|
}
|
|
@@ -772,6 +795,58 @@ for (const point of trends) {
|
|
|
772
795
|
}
|
|
773
796
|
```
|
|
774
797
|
|
|
798
|
+
#### `client.projects.getLog(idOrName, query?, options?)` — the project log (ulu log §3.2)
|
|
799
|
+
|
|
800
|
+
The project's second history: `run` events (what was examined) and `decision` / `regression`
|
|
801
|
+
events (what was decided, with reasons — and what came back) interleaved newest first,
|
|
802
|
+
keyset-paged. Pass `nextCursor` back verbatim. Three things to keep straight when rendering:
|
|
803
|
+
`reason: null` is *no reason recorded*; `source: null` is *unattributed*, never *human*; a
|
|
804
|
+
`regression` is a row a **run** re-detected, while a `resolved → open` `decision` with no run is
|
|
805
|
+
*reopened by decision* (D12) — the SDK types both and does not collapse them. `counts` is `null`
|
|
806
|
+
on runs saved before migration 065.
|
|
807
|
+
|
|
808
|
+
| Parameter | Type | Required | Description |
|
|
809
|
+
|-----------|------|----------|-------------|
|
|
810
|
+
| `since` / `until` | `string` | No | ISO 8601 window; `since <= until` or 400 |
|
|
811
|
+
| `limit` | `number` | No | 1–500, default 50; outside the range is a 400 |
|
|
812
|
+
| `cursor` | `string` | No | A `nextCursor` from the previous page, verbatim |
|
|
813
|
+
| `kind` | `('run'\|'decision'\|'regression')[]` | No | Subset of event kinds |
|
|
814
|
+
| `workflowType` | `string` | No | Filters `run` events only |
|
|
815
|
+
| `agent` | `string` | No | Runs by snapshot agent name; ledger rows by `issues.agent` |
|
|
816
|
+
| `includeArchived` | `boolean` | No | Archived runs are excluded unless `true` |
|
|
817
|
+
|
|
818
|
+
Query keys go to the wire as named (`workflowType`, not `workflow_type`): the API's schema is
|
|
819
|
+
camelCase and silently ignores a snake_cased key, so this call does not use the SDK's generic
|
|
820
|
+
snake_casing.
|
|
821
|
+
|
|
822
|
+
```typescript
|
|
823
|
+
let cursor: string | undefined;
|
|
824
|
+
do {
|
|
825
|
+
const page = await client.projects.getLog('my-project', { limit: 100, cursor }, { org: 'ulu-labs' });
|
|
826
|
+
for (const e of page.data) {
|
|
827
|
+
if (e.type === 'run') console.log(e.at, `run #${e.runNumber}`, e.workflowType, e.counts ?? '-');
|
|
828
|
+
else if (e.type === 'decision') console.log(e.at, e.fingerprint, `${e.from} -> ${e.to}`, e.reason ?? 'no reason recorded');
|
|
829
|
+
else console.log(e.at, e.fingerprint, 'regressed', e.viaRunNumber === null ? 'via run ?' : `via run #${e.viaRunNumber}`);
|
|
830
|
+
}
|
|
831
|
+
cursor = page.hasMore ? page.nextCursor : undefined;
|
|
832
|
+
} while (cursor);
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
#### `client.projects.getLogStat(idOrName, query?, options?)` — the rollup (§3.3)
|
|
836
|
+
|
|
837
|
+
`{ projectId, window, examined, found, decided, cameBack, activity }`. Two frames on two clocks:
|
|
838
|
+
the **cohort** frame (`examined`, `found`, `decided`) windows on run timestamps; the **activity**
|
|
839
|
+
frame (`activity`, `cameBack`) on ledger timestamps. `decided` is the *current* status of each
|
|
840
|
+
found issue and sums to `found.issues` — it is not "decisions made in the window"; that is
|
|
841
|
+
`activity.decisions`. `activity.byStatus.open` counts transitions **into** open (render it
|
|
842
|
+
*reopened*). `cameBack.detected` / `reopened` are distinct issues with the row counts beside
|
|
843
|
+
them; `lastDetectedAtAllTime` ignores the window by definition. `since` / `until` as above.
|
|
844
|
+
|
|
845
|
+
```typescript
|
|
846
|
+
const stat = await client.projects.getLogStat('my-project');
|
|
847
|
+
console.log(`${stat.examined.runs} runs, ${stat.found.issues} findings, ${stat.decided.completed} fixed, ${stat.cameBack.detected} regressions caught by re-running`);
|
|
848
|
+
```
|
|
849
|
+
|
|
775
850
|
#### `client.projects.listIssues(idOrName, query)`
|
|
776
851
|
|
|
777
852
|
List issues for a project with filters.
|
|
@@ -793,34 +868,21 @@ List issues for a project with filters.
|
|
|
793
868
|
|
|
794
869
|
> **Filter convention:** Passing `'all'` for any filter (e.g., `status: 'all'`) is equivalent to omitting the parameter — the SDK strips `'all'` values before sending the request. This applies to all query methods across the SDK.
|
|
795
870
|
>
|
|
796
|
-
> **The table above is the canonical filter set** for `projects.listIssues
|
|
797
|
-
> `
|
|
798
|
-
> query shape. `issues.search` is the exception: it accepts `failureDomains` (an array)
|
|
871
|
+
> **The table above is the canonical filter set** for `projects.listIssues` and
|
|
872
|
+
> `issues.listByProject` — both take the same query shape. `issues.search` is the exception: it accepts `failureDomains` (an array)
|
|
799
873
|
> and **does not accept `failureMode` at all**, because the server-side search path has no
|
|
800
|
-
> mode predicate. If you need to filter by mode, use one of the
|
|
874
|
+
> mode predicate. If you need to filter by mode, use one of the two list methods.
|
|
801
875
|
|
|
802
876
|
```typescript
|
|
803
|
-
|
|
877
|
+
// {data, total} since 6.0.0 — `total` is the full matching count, for pagination
|
|
878
|
+
const { data: issues, total } = await client.projects.listIssues('my-project', {
|
|
804
879
|
status: 'open',
|
|
805
880
|
priority: 'critical',
|
|
806
881
|
limit: 10,
|
|
807
882
|
});
|
|
883
|
+
console.log(`Showing ${issues.length} of ${total} open critical issues`);
|
|
808
884
|
```
|
|
809
885
|
|
|
810
|
-
#### `client.projects.listIssuesWithCount(idOrName, query)`
|
|
811
|
-
|
|
812
|
-
List issues with total count for pagination. Same filters as `listIssues`.
|
|
813
|
-
|
|
814
|
-
```typescript
|
|
815
|
-
const { issues, count } = await client.projects.listIssuesWithCount('my-project', {
|
|
816
|
-
status: 'open',
|
|
817
|
-
limit: 10,
|
|
818
|
-
});
|
|
819
|
-
console.log(`Showing ${issues.length} of ${count} total issues`);
|
|
820
|
-
```
|
|
821
|
-
|
|
822
|
-
> **Note:** Returns both the issues array and the total count for building paginated UIs.
|
|
823
|
-
|
|
824
886
|
#### `client.projects.bulkUpdateIssueStatus(idOrName, updates)`
|
|
825
887
|
|
|
826
888
|
Bulk update issue statuses.
|
|
@@ -850,6 +912,35 @@ const result = await client.projects.mergeIssues('my-project', {
|
|
|
850
912
|
});
|
|
851
913
|
```
|
|
852
914
|
|
|
915
|
+
#### `client.projects.mergeProjects(input)`
|
|
916
|
+
|
|
917
|
+
Merge one project into another (merge-projects spec v0.3.4). The source's runs and issues are
|
|
918
|
+
re-keyed into the target inside one advisory-locked transaction; the source is soft-deleted by
|
|
919
|
+
default. Pairwise only — chain calls for multi-source merges. Dry-run first.
|
|
920
|
+
|
|
921
|
+
| Parameter | Type | Required | Description |
|
|
922
|
+
|-----------|------|----------|-------------|
|
|
923
|
+
| `source` | `string` | Yes | Source project name or UUID (consumed by the merge) |
|
|
924
|
+
| `target` | `string` | Yes | Target project name or UUID (survives, absorbs the source) |
|
|
925
|
+
| `dryRun` | `boolean` | No | Preview only — the merge transaction is rolled back (default `false`) |
|
|
926
|
+
| `deleteSource` | `boolean` | No | Soft-delete the source after the merge (default `true`) |
|
|
927
|
+
| `confirmCrossOrg` | `boolean` | No | Required `true` for system-actor cross-org merges; human cross-org merges are always rejected |
|
|
928
|
+
|
|
929
|
+
```typescript
|
|
930
|
+
const preview = await client.projects.mergeProjects({
|
|
931
|
+
source: 'old-project',
|
|
932
|
+
target: 'my-project',
|
|
933
|
+
dryRun: true,
|
|
934
|
+
});
|
|
935
|
+
console.log(`Would move ${preview.moved.runs} runs and ${preview.moved.issues} issues`);
|
|
936
|
+
if (preview.conflicts.length === 0) {
|
|
937
|
+
const result = await client.projects.mergeProjects({ source: 'old-project', target: 'my-project' });
|
|
938
|
+
console.log(result.source.statusAfter); // 'soft-deleted'
|
|
939
|
+
}
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
Returns `{ source, target, moved, conflicts }` — `source.statusAfter` is `'soft-deleted' | 'retained' | 'dry-run'`, `moved` counts runs, issues, dedupes and reparented occurrences/notes/history.
|
|
943
|
+
|
|
853
944
|
#### `client.projects.rehome(idOrName, input, options?)` — move a project to another org
|
|
854
945
|
|
|
855
946
|
Moves the project and its whole history (runs, issues, analytics) into another org
|
|
@@ -914,7 +1005,7 @@ Save a new execution run. Pass `{ _skipClientValidation: true }` as the second a
|
|
|
914
1005
|
| `recommendations` | `Recommendation[]` | Yes | Array of issues/recommendations (use `[]` for empty). Multi-agent pipelines: see [Convergence clustering](#convergence-clustering-clusterkey) before collapsing findings |
|
|
915
1006
|
| `summary` | `object` | No | Summary statistics |
|
|
916
1007
|
| `rawMarkdown` | `string` | No | Raw markdown report |
|
|
917
|
-
| `idempotencyKey` | `string` | No | Key for duplicate prevention. When omitted, the SDK derives it from the payload content (sha256), so a byte-identical retry returns the original run (`deduplicated: true`) instead of creating a second one. Pass explicit distinct keys to deliberately save identical payloads twice |
|
|
1008
|
+
| `idempotencyKey` | `string` | No | Key for duplicate prevention. When omitted, the SDK derives it from the payload content (sha256), so a byte-identical retry returns the original run (`deduplicated: true`) instead of creating a second one. The hash is over `JSON.stringify` of the payload, so it is key-order-sensitive inside caller-supplied objects (`agents[]`, `recommendations[]`, `analysisRecords[].data`): a retry that rebuilds those with a different insertion order is a different key and writes a second run. Pass an explicit key when the retry path does not preserve object shape; pass explicit distinct keys to deliberately save identical payloads twice |
|
|
918
1009
|
| `definitionType` | `string` | No | Definition type (`'agent'`, `'command'`, `'workflow'`, `'pipeline'`) |
|
|
919
1010
|
| `definitionName` | `string` | No | Definition name (e.g., `'code-validator'`) |
|
|
920
1011
|
| `definitionVersion` | `string` | No | Definition version (e.g., `'1.2.0'`) |
|
|
@@ -1056,7 +1147,8 @@ List runs for a project.
|
|
|
1056
1147
|
| `offset` | `number` | No | Pagination offset |
|
|
1057
1148
|
|
|
1058
1149
|
```typescript
|
|
1059
|
-
|
|
1150
|
+
// {data, total} since 6.0.0
|
|
1151
|
+
const { data: runs, total } = await client.runs.listByProject('my-project', {
|
|
1060
1152
|
workflowType: 'ship',
|
|
1061
1153
|
limit: 10,
|
|
1062
1154
|
});
|
|
@@ -1141,7 +1233,8 @@ const run = await client.runs.update({
|
|
|
1141
1233
|
project: 'my-project',
|
|
1142
1234
|
runNumber: 5,
|
|
1143
1235
|
agents: [
|
|
1144
|
-
|
|
1236
|
+
// Token fields are FLAT on update (UpdateAgentInput) — a nested `tokens` object is not a field the update path sends
|
|
1237
|
+
{ name: 'code-validator', score: 90, inputTokens: 1500 },
|
|
1145
1238
|
],
|
|
1146
1239
|
});
|
|
1147
1240
|
```
|
|
@@ -1328,11 +1421,11 @@ Get analysis summaries with run context for a specific agent. Returns analysis d
|
|
|
1328
1421
|
| `query.offset` | `number` | No | Pagination offset |
|
|
1329
1422
|
|
|
1330
1423
|
```typescript
|
|
1331
|
-
const {
|
|
1424
|
+
const { data, total } = await client.runs.getAgentRunsAnalysis('epictetus-validator', {
|
|
1332
1425
|
project: 'my-project',
|
|
1333
1426
|
limit: 10,
|
|
1334
1427
|
});
|
|
1335
|
-
//
|
|
1428
|
+
// data[0]: { decision, score, categoryScores, runNumber, runTimestamp, workflowType, snapshotScore, ... }
|
|
1336
1429
|
```
|
|
1337
1430
|
|
|
1338
1431
|
---
|
|
@@ -1944,6 +2037,29 @@ target's). A non-member gets `403 ORG_ACCESS_DENIED`.
|
|
|
1944
2037
|
|
|
1945
2038
|
---
|
|
1946
2039
|
|
|
2040
|
+
#### `client.orgs.list()` — the orgs you belong to
|
|
2041
|
+
|
|
2042
|
+
`GET /orgs`: every org the key holder is a member of, personal org included (`isPersonal: true`),
|
|
2043
|
+
each with `slug`, `role`, `memberCount`, `subscriptionTier`. A key bound to one org still lists all
|
|
2044
|
+
of its holder's orgs; the binding governs what it may *read*.
|
|
2045
|
+
|
|
2046
|
+
#### `client.orgs.getLogStat(slug, query?)` — the org rollup (ulu log §3.6)
|
|
2047
|
+
|
|
2048
|
+
The same body as `projects.getLogStat` computed over the org's live projects, plus `projects[]` —
|
|
2049
|
+
the summary shape `{ name, runs, issues, fixed, regressions, lastRunAt }` where each column is that
|
|
2050
|
+
project's own rollup measure (`regressions` = `cameBack.detected`, run-caught only), ordered by last
|
|
2051
|
+
run desc then name, capped at 100 with `hasMoreProjects`. Any member reads. Served from a **60 s
|
|
2052
|
+
TTL cache** per (org, window) — `computedAt` says how old the numbers are. Unknown slug → 404
|
|
2053
|
+
`ORG_NOT_FOUND`; a key bound to another org → 403 `ORG_ACCESS_DENIED`. The slug in the path is the
|
|
2054
|
+
org — no `OrgScopedOptions` here.
|
|
2055
|
+
|
|
2056
|
+
```typescript
|
|
2057
|
+
for (const org of await client.orgs.list()) {
|
|
2058
|
+
const s = await client.orgs.getLogStat(org.slug);
|
|
2059
|
+
console.log(org.slug, `${s.projects.length}${s.hasMoreProjects ? '+' : ''} projects`, `${s.examined.runs} runs`, `${s.found.issues} findings`, `${s.decided.completed} fixed`, `${s.cameBack.detected} regressions`, `(as of ${s.computedAt})`);
|
|
2060
|
+
}
|
|
2061
|
+
```
|
|
2062
|
+
|
|
1947
2063
|
### Admin Operations
|
|
1948
2064
|
|
|
1949
2065
|
The **platform-admin** surface (`users.role = 'admin'` — a platform role, not an org role). The two
|
|
@@ -2041,6 +2157,7 @@ For command-line usage, see the dedicated CLI package: [`@uluops/cli`](https://w
|
|
|
2041
2157
|
| `ULUOPS_EMAIL` | Email for session auth | - |
|
|
2042
2158
|
| `ULUOPS_PASSWORD` | Password for session auth | - |
|
|
2043
2159
|
| `ULUOPS_SESSION_TOKEN` | Session token for auth | - |
|
|
2160
|
+
| `ULUOPS_ORG_SLUG` | Org slug for org-scoped requests (lowest precedence in [Org routing](#org-routing--which-org-a-call-lands-in)) | personal org |
|
|
2044
2161
|
| `ULUOPS_BASE_URL` | API base URL | `https://api.uluops.ai/api/v1` (localhost:3100 when `NODE_ENV=development`) |
|
|
2045
2162
|
| `ULUOPS_DEBUG` | Enable debug logging | `false` |
|
|
2046
2163
|
|
|
@@ -2207,6 +2324,8 @@ const raw = await http.requestRaw('GET', '/endpoint'); // Without data unwrappin
|
|
|
2207
2324
|
|
|
2208
2325
|
### Custom Authentication Strategy
|
|
2209
2326
|
|
|
2327
|
+
The two strategies the client installs itself — `ApiKeyAuth` and `JwtSessionAuth` — are exported at the package root (re-exports of `@uluops/sdk-core/http`) for callers that construct one directly instead of through `createAuthStrategy`; the factory is the documented path and the constructors' signatures are sdk-core's.
|
|
2328
|
+
|
|
2210
2329
|
```typescript
|
|
2211
2330
|
import { OpsHttpClient, createAuthStrategy } from '@uluops/ops-sdk';
|
|
2212
2331
|
|
package/dist/client.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { type HttpClientConfig } from './http/http-client.js';
|
|
|
2
2
|
import * as analyticsOps from './operations/analytics.js';
|
|
3
3
|
import type { RegisterInput, LoginInput, TotpLoginInput, LoginResponse, RegisterResponse, UpdateProfileInput, ChangePasswordInput, ResetPasswordInput, CreateApiKeyInput, ApiKeyCreatedResponse, PublicApiKey, PublicSession, AuthUser, PublicUser } from './types/auth.js';
|
|
4
4
|
import type { Project, CreateProjectInput, UpdateProjectInput, DeleteProjectInput, RenameProjectInput, ProjectSummaryResponse, ProjectTrends, ProjectTrendsQuery, ListProjectIssuesQuery, BulkIssueStatusUpdate, BulkIssueStatusResult, MergeIssuesInput, MergeIssuesResult, MergeProjectsInput, MergeProjectsResult } from './types/projects.js';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ProjectLogQuery, ProjectLogPage, LogStatQuery, ProjectLogStat, OrgLogStat, OrgListEntry } from './types/log.js';
|
|
6
|
+
import type { Run, RunSummary, RunAnalysis, ProjectAnalysisList, AnalysisRecordsList, AgentRunsAnalysis, SaveRunInput, SaveRunResponseWithEcho, ValidateRunResponse, RunDiffQuery, RunDiffResult, ArchiveRunsInput, ArchiveRunsResult, UpdateRunInput, UpdateRunByNumberInput, UpdateRunPreviewInput, UpdateRunPreviewByNumberInput, RunUpdatePreview, UpdateRunWithEchoResult, ListRunsQuery, RunDetails, ProjectAnalysisQuery, AnalysisRecordsQuery, AgentRunsAnalysisQuery, RunWriteEcho } from './types/runs.js';
|
|
6
7
|
import type { Issue, CreateUserIssueInput, UpdateIssueInput, UpdateIssueStatusInput, CreateIssueNoteInput, IssueNote, IssueDetails, IssueHistoryEnvelope, IssueSearchQuery, ListIssuesQuery, BulkStatusUpdateItem, StatusUpdateResult } from './types/issues.js';
|
|
7
8
|
import type { AnalyticsQuery, AgentPerformance, AgentInfo, AgentLifecycleEntry, AgentReliabilityQuery, BurndownQuery, VelocityQuery, DiscoveryQuery, AgentMatrixQuery, TaxonomyResponse, AgentReliabilityResult, ResolutionRateResult, FileHotspotResult, TaxonomyDistributionResult, FullTaxonomyAnalyticsResult, BurndownResultResponse, VelocityResultResponse, DiscoveryResultResponse, AgentMatrixResultResponse, TrendSummaryResult } from './types/analytics.js';
|
|
8
9
|
import type { MessageResponse, DeleteResult } from './types/responses.js';
|
|
@@ -91,6 +92,11 @@ export declare class OpsClient {
|
|
|
91
92
|
/**
|
|
92
93
|
* Logout current session (revokes all sessions for this user).
|
|
93
94
|
*
|
|
95
|
+
* Revoke every session for the current user server-side AND clear the
|
|
96
|
+
* session installed on this client (token and retained password), so
|
|
97
|
+
* `isAuthenticated()` is false afterwards and no automatic re-login can
|
|
98
|
+
* follow. An API-key strategy is untouched — keys are not sessions.
|
|
99
|
+
*
|
|
94
100
|
* @returns Number of sessions revoked
|
|
95
101
|
* @throws {UnauthorizedError} If client is not authenticated
|
|
96
102
|
* @throws {OpsApiError} On network or server errors
|
|
@@ -215,6 +221,19 @@ export declare class OpsClient {
|
|
|
215
221
|
* address becomes a `410 PROJECT_REHOMED` tombstone, not a fork.
|
|
216
222
|
*/
|
|
217
223
|
rehome: (idOrName: string, input: RehomeProjectInput, options?: OrgScopedOptions) => Promise<RehomeResponse>;
|
|
224
|
+
/**
|
|
225
|
+
* The project log (ulu log spec §3.2) — runs, decisions and regressions
|
|
226
|
+
* interleaved newest first, keyset-paged; pass `nextCursor` back verbatim.
|
|
227
|
+
* A `regression` is a row a run re-detected; a `resolved → open` decision
|
|
228
|
+
* with no run is *reopened by decision* (D12) — keep them apart.
|
|
229
|
+
*/
|
|
230
|
+
getLog: (idOrName: string, query?: ProjectLogQuery, options?: OrgScopedOptions) => Promise<ProjectLogPage>;
|
|
231
|
+
/**
|
|
232
|
+
* The log's rollup (§3.3): examined / found / decided / cameBack /
|
|
233
|
+
* activity — a cohort frame on run timestamps and an activity frame on
|
|
234
|
+
* ledger timestamps; `decided` is the CURRENT status of the found issues.
|
|
235
|
+
*/
|
|
236
|
+
getLogStat: (idOrName: string, query?: LogStatQuery, options?: OrgScopedOptions) => Promise<ProjectLogStat>;
|
|
218
237
|
};
|
|
219
238
|
/** Org reads a member can make. (Org CRUD and membership are dashboard/platform surfaces, not wrapped here.) */
|
|
220
239
|
readonly orgs: {
|
|
@@ -225,6 +244,16 @@ export declare class OpsClient {
|
|
|
225
244
|
* `readRehomeAuditDetails()`.
|
|
226
245
|
*/
|
|
227
246
|
getVisibleAuditLog: (slug: string, query?: OrgAuditFeedQuery) => Promise<OrgAuditFeed>;
|
|
247
|
+
/** The orgs the caller belongs to (personal included) — what `ulu log --orgs` iterates. */
|
|
248
|
+
list: () => Promise<OrgListEntry[]>;
|
|
249
|
+
/**
|
|
250
|
+
* The org rollup (ulu log §3.6): the §3.3 body over the org's live projects
|
|
251
|
+
* plus a per-project table (`projects[]`, capped at 100). Any member reads;
|
|
252
|
+
* cached 60 s server-side — `computedAt` says how old. The slug in the
|
|
253
|
+
* path is the org; no `OrgScopedOptions` here for the same reason as
|
|
254
|
+
* `getVisibleAuditLog`.
|
|
255
|
+
*/
|
|
256
|
+
getLogStat: (slug: string, query?: LogStatQuery) => Promise<OrgLogStat>;
|
|
228
257
|
};
|
|
229
258
|
/**
|
|
230
259
|
* Platform-admin surface. Requires `users.role = 'admin'`; the writes also
|
|
@@ -250,7 +279,7 @@ export declare class OpsClient {
|
|
|
250
279
|
/** Execution run save, preview, diff, archive, and retrieval */
|
|
251
280
|
readonly runs: {
|
|
252
281
|
/** Save an execution run (agents, scores, recommendations). */
|
|
253
|
-
save: (input: SaveRunInput, options?: RunCallOptions) => Promise<
|
|
282
|
+
save: (input: SaveRunInput, options?: RunCallOptions) => Promise<SaveRunResponseWithEcho>;
|
|
254
283
|
/** Preview a save without persisting (dry-run). */
|
|
255
284
|
validate: (input: SaveRunInput, options?: RunCallOptions) => Promise<ValidateRunResponse>;
|
|
256
285
|
/** Diff two runs to surface regressions/improvements. */
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAS7E,OAAO,KAAK,YAAY,MAAM,2BAA2B,CAAC;AAI1D,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACV,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAS7E,OAAO,KAAK,YAAY,MAAM,2BAA2B,CAAC;AAI1D,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACV,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9H,OAAO,KAAK,EACV,GAAG,EACH,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACV,KAAK,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,SAAS,EACT,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,0BAA0B,EAC1B,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,EAC3B,YAAY,EACZ,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAE3C;;;;OAIG;gBACS,MAAM,GAAE,eAAoB;IAiCxC;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAiBhG;;;;;;;;;;OAUG;IACG,aAAa,CAAC,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAa1G;;;;;;;;;;;OAWG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAepD;;;;OAIG;IACH,eAAe,IAAI,OAAO;IAK1B;;;;OAIG;IACH,WAAW,IAAI,SAAS,GAAG,SAAS,GAAG,IAAI;IAK3C;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAQb,sEAAsE;IACtE,QAAQ,CAAC,IAAI;QACX,mCAAmC;0BACjB,aAAa,KAAG,OAAO,CAAC,gBAAgB,CAAC;QAG3D,sHAAsH;uBACvG,UAAU,KAAG,OAAO,CAAC,aAAa,CAAC;QAGlD,yHAAyH;2BACtG,cAAc,KAAG,OAAO,CAAC,aAAa,CAAC;QAG1D,uDAAuD;yBACxC,OAAO,CAAC;YAAE,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC;QAGnD,4DAA4D;gCACpC,MAAM,KAAG,OAAO,CAAC,eAAe,CAAC;QAGzD,oEAAoE;+BAC7C,kBAAkB,KAAG,OAAO,CAAC,eAAe,CAAC;QAGpE,sEAAsE;gCAC9C,mBAAmB,KAAG,OAAO,CAAC,eAAe,CAAC;QAGtE,kEAAkE;gCAC1C,MAAM,KAAG,OAAO,CAAC,eAAe,CAAC;QAGzD,qDAAqD;qBAC1C,OAAO,CAAC,QAAQ,CAAC;QAG5B,6CAA6C;0BAC7B,OAAO,CAAC;YAAE,IAAI,EAAE,UAAU,CAAA;SAAE,CAAC;QAG7C,uEAAuE;+BAChD,kBAAkB,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,UAAU,CAAA;SAAE,CAAC;QAGzE,8DAA8D;yBAC/C,OAAO,CAAC;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QAGlE,wCAAwC;4BACtB,OAAO,CAAC,IAAI,CAAC;QAG/B,wDAAwD;2BACvC,OAAO,CAAC,YAAY,EAAE,CAAC;QAGxC,mEAAmE;+BAC5C,iBAAiB,KAAG,OAAO,CAAC,qBAAqB,CAAC;QAGzE,+BAA+B;8BACT,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;QAG5C,+CAA+C;4BAC7B,OAAO,CAAC,aAAa,EAAE,CAAC;QAG1C,qCAAqC;mCACV,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;MAEjD;IAMF,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ;QACf,4EAA4E;yBAC3D,gBAAgB,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QAG/E,mCAAmC;wBACnB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGrE,4BAA4B;wBACZ,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGjF,mCAAmC;2BAChB,MAAM,SAAS,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGnG,4DAA4D;2BACzC,MAAM,SAAS,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,YAAY,CAAC;QAGxG,yDAAyD;+BAClC,MAAM,SAAS,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,YAAY,CAAC;QAG5G,sCAAsC;4BAClB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGzE,wBAAwB;wBACR,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGjF,iDAAiD;+BAC1B,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,sBAAsB,CAAC;QAG3F,4CAA4C;8BACtB,MAAM,UAAU,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,aAAa,CAAC;QAG7G;;2CAEmC;+BACZ,MAAM,UAAU,sBAAsB,YAAY,gBAAgB,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QAGrI,0DAA0D;0CACxB,MAAM,WAAW,qBAAqB,EAAE,YAAY,gBAAgB,KAAG,OAAO,CAAC,qBAAqB,CAAC;QAGvI,+CAA+C;gCACvB,MAAM,SAAS,gBAAgB,YAAY,gBAAgB,KAAG,OAAO,CAAC,iBAAiB,CAAC;QAGhH;;;;;WAKG;+BACoB,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,mBAAmB,CAAC;QAGpG;;;;;;WAMG;2BACgB,MAAM,SAAS,kBAAkB,YAAY,gBAAgB,KAAG,OAAO,CAAC,cAAc,CAAC;QAG1G;;;;;WAKG;2BACgB,MAAM,UAAU,eAAe,YAAY,gBAAgB,KAAG,OAAO,CAAC,cAAc,CAAC;QAGxG;;;;WAIG;+BACoB,MAAM,UAAU,YAAY,YAAY,gBAAgB,KAAG,OAAO,CAAC,cAAc,CAAC;MAEzG;IAMF,gHAAgH;IAChH,QAAQ,CAAC,IAAI;QACX;;;;;WAKG;mCACwB,MAAM,UAAU,iBAAiB,KAAG,OAAO,CAAC,YAAY,CAAC;QAGpF,2FAA2F;oBACjF,OAAO,CAAC,YAAY,EAAE,CAAC;QAEjC;;;;;;WAMG;2BACgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,UAAU,CAAC;MAErE;IAMF;;;;;OAKG;IACH,QAAQ,CAAC,KAAK;QACZ;;;WAGG;mCACwB,MAAM,SAAS,uBAAuB,KAAG,OAAO,CAAC,cAAc,CAAC;QAG3F,iGAAiG;qCACpE,sBAAsB,KAAG,OAAO,CAAC,iBAAiB,CAAC;QAGhF,6GAA6G;0CAC3E,2BAA2B,KAAG,OAAO,CAAC,sBAAsB,CAAC;QAG/F,2GAA2G;yCAC1E,MAAM,KAAG,OAAO,CAAC;YAAE,QAAQ,EAAE,IAAI,CAAA;SAAE,CAAC;MAErE;IAMF,gEAAgE;IAChE,QAAQ,CAAC,IAAI;QACX,+DAA+D;sBACjD,YAAY,YAAY,cAAc,KAAG,OAAO,CAAC,uBAAuB,CAAC;QAGvF,mDAAmD;0BACjC,YAAY,YAAY,cAAc,KAAG,OAAO,CAAC,mBAAmB,CAAC;QAGvF,yDAAyD;sBAC3C,YAAY,YAAY,gBAAgB,KAAG,OAAO,CAAC,aAAa,CAAC;QAG/E,wDAAwD;yBACvC,gBAAgB,YAAY,gBAAgB,KAAG,OAAO,CAAC,iBAAiB,CAAC;QAG1F,wLAAwL;wBACxK,sBAAsB,YAAY,cAAc,KAAG,OAAO,CAAC,YAAY,CAAC;QAGxF,sKAAsK;+BAC/I,6BAA6B,YAAY,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;QAG1G,qJAAqJ;gCAC7H,sBAAsB,YAAY,cAAc,KAAG,OAAO,CAAC,uBAAuB,CAAC;QAG3G,qEAAqE;mCAC1C,MAAM,UAAU,aAAa,YAAY,gBAAgB,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,UAAU,EAAE,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QAGrI,sEAAsE;+BAC/C,MAAM,iBAAiB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,GAAG,CAAC;QAG/F,8EAA8E;gCACtD,MAAM,cAAc,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,UAAU,CAAC;QAGpG,kCAAkC;qBACrB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,GAAG,CAAC;QAG9D,2KAA2K;4BACvJ,MAAM,SAAS,cAAc,YAAY,cAAc,KAAG,OAAO,CAAC,YAAY,CAAC;QAGnG,qFAAqF;mCAC1D,MAAM,SAAS,qBAAqB,YAAY,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;QAGrH,6CAA6C;oCACjB,MAAM,SAAS,cAAc,YAAY,cAAc,KAAG,OAAO,CAAC,uBAAuB,CAAC;QAGtH,0BAA0B;wBACV,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,YAAY,CAAC;QAI1E,qDAAqD;6BAChC,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,WAAW,CAAC;QAG9E,6CAA6C;wCACb,MAAM,UAAU,oBAAoB,YAAY,gBAAgB,KAAG,OAAO,CAAC,mBAAmB,CAAC;QAG/H,qDAAqD;uCACtB,oBAAoB,YAAY,gBAAgB,KAAG,OAAO,CAAC,mBAAmB,CAAC;QAG9G,uDAAuD;0CACrB,MAAM,SAAS,sBAAsB,YAAY,gBAAgB,KAAG,OAAO,CAAC,iBAAiB,CAAC;MAEhI;IAMF,wEAAwE;IACxE,QAAQ,CAAC,MAAM;QACb,qCAAqC;wBACrB,oBAAoB,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAGjF,qCAAqC;wBACrB,gBAAgB,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAG/E,wDAAwD;wCACxB,MAAM,WAAW,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAGpG,yDAAyD;iDAChB,MAAM,WAAW,MAAM,SAAS,sBAAsB,YAAY,gBAAgB,KAAG,OAAO,CAAC,kBAAkB,CAAC;QAGzJ,0BAA0B;uBACX,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAGlE,kDAAkD;8BAC5B,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,YAAY,CAAC;QAGhF,qCAAqC;8BACf,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,oBAAoB,CAAC;QAGxF,sCAAsC;gCACd,MAAM,SAAS,sBAAsB,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAG1G,wCAAwC;0BACtB,MAAM,SAAS,gBAAgB,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAG9F,8BAA8B;2BACX,MAAM,SAAS,oBAAoB,YAAY,gBAAgB,KAAG,OAAO,CAAC,SAAS,CAAC;QAGvG,oCAAoC;2BACjB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAGtE,+DAA+D;8BACzC,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,YAAY,CAAC;QAGhF,+CAA+C;kCACrB,MAAM,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC;QAG7E,iEAAiE;oCACrC,oBAAoB,EAAE,YAAY,gBAAgB,KAAG,OAAO,CAAC,qBAAqB,CAAC;QAG/G,wDAAwD;mCAC7B,MAAM,UAAU,eAAe,YAAY,gBAAgB,KAAG,OAAO,CAAC,KAAK,EAAE,CAAC;MAEzG;IAMF,+EAA+E;IAC/E,QAAQ,CAAC,SAAS;QAChB,yCAAyC;sCACX,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAGtG,8DAA8D;sCAChC,qBAAqB,YAAY,gBAAgB,KAAG,OAAO,CAAC,sBAAsB,CAAC;QAGjH,yCAAyC;uCACV,MAAM,UAAU,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAG1H,yCAAyC;qCACZ,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAGzG,gDAAgD;kCACtB,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAGnG,kEAAkE;0CAChC,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,0BAA0B,EAAE,CAAC;QAGpH,iDAAiD;kCACvB,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,2BAA2B,CAAC;QAG3G,oCAAoC;8BACd,aAAa,YAAY,gBAAgB,KAAG,OAAO,CAAC,sBAAsB,CAAC;QAGjG,yCAAyC;8BACnB,aAAa,YAAY,gBAAgB,KAAG,OAAO,CAAC,sBAAsB,CAAC;QAGjG,wCAAwC;+BACjB,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,uBAAuB,CAAC;QAGpG,uCAAuC;iCACd,gBAAgB,YAAY,gBAAgB,KAAG,OAAO,CAAC,yBAAyB,CAAC;QAG1G,sCAAsC;kCACZ,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAGpG;;;;WAIG;8BACmB,YAAY,CAAC,eAAe,UAAU,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAAC;QAGzH,gDAAgD;6BAC3B,cAAc,YAAY,gBAAgB,KAAG,OAAO,CAAC,SAAS,EAAE,CAAC;MAGtF;IAMF,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ;QACf,oEAAoE;mBAC3D,OAAO,CAAC,gBAAgB,CAAC;MAElC;CAEH"}
|
package/dist/client.js
CHANGED
|
@@ -59,7 +59,8 @@ export class OpsClient {
|
|
|
59
59
|
}
|
|
60
60
|
if (!this.isAuthenticated() && !(config.email && config.password)) {
|
|
61
61
|
logger.warn(`No credentials found (checked: constructor config, ${ENV_VARS.API_KEY} env, .env files, ~/.uluops/credentials.json). ` +
|
|
62
|
-
'Call client.login() or set ULUOPS_API_KEY before making API requests.'
|
|
62
|
+
'Call client.login() or set ULUOPS_API_KEY before making API requests. ' +
|
|
63
|
+
'Create a key at https://app.uluops.ai (Settings → API keys).');
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
// ============================================
|
|
@@ -101,12 +102,29 @@ export class OpsClient {
|
|
|
101
102
|
/**
|
|
102
103
|
* Logout current session (revokes all sessions for this user).
|
|
103
104
|
*
|
|
105
|
+
* Revoke every session for the current user server-side AND clear the
|
|
106
|
+
* session installed on this client (token and retained password), so
|
|
107
|
+
* `isAuthenticated()` is false afterwards and no automatic re-login can
|
|
108
|
+
* follow. An API-key strategy is untouched — keys are not sessions.
|
|
109
|
+
*
|
|
104
110
|
* @returns Number of sessions revoked
|
|
105
111
|
* @throws {UnauthorizedError} If client is not authenticated
|
|
106
112
|
* @throws {OpsApiError} On network or server errors
|
|
107
113
|
*/
|
|
108
114
|
async logout() {
|
|
109
|
-
|
|
115
|
+
const result = await authOps.logoutAll(this.httpClient);
|
|
116
|
+
// The server has revoked every session; forget ours too. Until ship run
|
|
117
|
+
// #48 this returned without touching the installed strategy, so
|
|
118
|
+
// `isAuthenticated()` stayed true on a revoked token and — with
|
|
119
|
+
// `autoRefresh` (the default) — the next 401 re-logged-in with the
|
|
120
|
+
// retained password, silently undoing the logout. `clearSession()` drops
|
|
121
|
+
// the token AND the password, so the next request fails `UnauthorizedError`
|
|
122
|
+
// before it is sent, and a fresh `login()` is the only way back. An API-key
|
|
123
|
+
// strategy is not a session and is left alone.
|
|
124
|
+
const strategy = this.httpClient.getAuthStrategy();
|
|
125
|
+
if (strategy instanceof JwtSessionAuth)
|
|
126
|
+
strategy.clearSession();
|
|
127
|
+
return result;
|
|
110
128
|
}
|
|
111
129
|
/**
|
|
112
130
|
* Check if client has valid credentials installed (API key or session token).
|
|
@@ -224,6 +242,19 @@ export class OpsClient {
|
|
|
224
242
|
* address becomes a `410 PROJECT_REHOMED` tombstone, not a fork.
|
|
225
243
|
*/
|
|
226
244
|
rehome: (idOrName, input, options) => projectOps.rehome(this.scope(options), idOrName, input),
|
|
245
|
+
/**
|
|
246
|
+
* The project log (ulu log spec §3.2) — runs, decisions and regressions
|
|
247
|
+
* interleaved newest first, keyset-paged; pass `nextCursor` back verbatim.
|
|
248
|
+
* A `regression` is a row a run re-detected; a `resolved → open` decision
|
|
249
|
+
* with no run is *reopened by decision* (D12) — keep them apart.
|
|
250
|
+
*/
|
|
251
|
+
getLog: (idOrName, query, options) => projectOps.getLog(this.scope(options), idOrName, query),
|
|
252
|
+
/**
|
|
253
|
+
* The log's rollup (§3.3): examined / found / decided / cameBack /
|
|
254
|
+
* activity — a cohort frame on run timestamps and an activity frame on
|
|
255
|
+
* ledger timestamps; `decided` is the CURRENT status of the found issues.
|
|
256
|
+
*/
|
|
257
|
+
getLogStat: (idOrName, query, options) => projectOps.getLogStat(this.scope(options), idOrName, query),
|
|
227
258
|
};
|
|
228
259
|
// ============================================
|
|
229
260
|
// ORG OPERATIONS
|
|
@@ -237,6 +268,16 @@ export class OpsClient {
|
|
|
237
268
|
* `readRehomeAuditDetails()`.
|
|
238
269
|
*/
|
|
239
270
|
getVisibleAuditLog: (slug, query) => orgOps.getVisibleAuditLog(this.httpClient, slug, query),
|
|
271
|
+
/** The orgs the caller belongs to (personal included) — what `ulu log --orgs` iterates. */
|
|
272
|
+
list: () => orgOps.list(this.httpClient),
|
|
273
|
+
/**
|
|
274
|
+
* The org rollup (ulu log §3.6): the §3.3 body over the org's live projects
|
|
275
|
+
* plus a per-project table (`projects[]`, capped at 100). Any member reads;
|
|
276
|
+
* cached 60 s server-side — `computedAt` says how old. The slug in the
|
|
277
|
+
* path is the org; no `OrgScopedOptions` here for the same reason as
|
|
278
|
+
* `getVisibleAuditLog`.
|
|
279
|
+
*/
|
|
280
|
+
getLogStat: (slug, query) => orgOps.getLogStat(this.httpClient, slug, query),
|
|
240
281
|
};
|
|
241
282
|
// ============================================
|
|
242
283
|
// ADMIN OPERATIONS (platform role)
|