aegis-platform-sdk 0.1.0 → 1.3.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/CHANGELOG.md CHANGED
@@ -1,11 +1,127 @@
1
- # Changelog
2
-
3
- ## 0.1.0 — 2026-07-08
4
-
5
- First cut of the TypeScript SDK, mirroring `aegis-platform-sdk` (Python) v0.10.0.
6
-
7
- - `AegisClient` fetch-based transport, zero runtime dependencies, ESM + CJS.
8
- - Auth: `login` (JWT attach), `me`, `enableDevMode`; env fallbacks `AEGIS_API_URL` / `AEGIS_TOKEN`.
9
- - Error hierarchy: `AegisAPIError`, `AuthError` (401), `PermissionDeniedError` (403), `NotFoundError` (404).
10
- - Resources: `iam` (users/roles/groups/permissions/nav), `osdk` (token lifecycle), `operator.tasks`, `ontology` (objects, graph, explorer, object-types, link-types, OSDK manifest/codegen), `aip` (flows, agents, models, budget), `functions` + `codeRepositories` (Code Functions v26), `datasets` (branches, transactions, classification, markings).
11
- - Generic `client.request(method, path, opts)` escape hatch for unwrapped endpoints.
1
+ # Changelog
2
+
3
+ ## 1.3.0 — 2026-07-31
4
+
5
+ Two operator gestures born with the desk app. Additive; no breaking changes.
6
+ Parity with the Python SDK (`edge.create_pairing_code(grants=…)`,
7
+ `alerts.set_channel` / `delete_channel`).
8
+
9
+ - **`client.edge.createPairingCode({ grants })`** a pairing code can now
10
+ **grant gestures** to whichever device redeems it. Empty the default is
11
+ **read only**: least privilege, and granting has to be a choice. The grant
12
+ travels from the code to the node and dies with it on `revoke`. Even when
13
+ granted, the device never receives the gesture's ADDRESS
14
+ (`agent_id`/`skill_key`): it sends the verb and the server routes it.
15
+ - **`client.alerts.setChannel(ref, config)` / `deleteChannel(ref)`** —
16
+ `PUT`/`DELETE /alerts/channels/{ref}`, pointing a delivery channel at its
17
+ destination. Exists so this is a GESTURE: before it, sending alerts to the
18
+ team's Discord meant editing the tenant's JSONB in the database. Audited
19
+ (`alert_channel.configured` / `.removed`). Reads return the config
20
+ **masked** — a webhook URL is the credential.
21
+ - New `discord` channel in the horizontal messaging registry: shows up in
22
+ `client.alerts.channels()` on its own, no contract change.
23
+
24
+ ## 1.2.0 — 2026-07-09
25
+
26
+ New method on `publicGuest`. No breaking changes.
27
+
28
+ - **`client.publicGuest.position(token)`** — `GET /public/v1/guest/{token}/position`.
29
+ The resident-side read of a visitor's live location: the operator issues the
30
+ resident's token with `geo.live_ref` = the visitor's guest-token id, and this
31
+ returns `{available, lat, lng, ts, inside_fence, arrived, deviated,
32
+ distance_to_target_m, visit_status}`. Least-privilege — the resident sees only
33
+ that one visit. Poll it (no push; the bus→SSE bridge is a later wave).
34
+ Dogfooded by the Safe-Tag `residentmap` SPA.
35
+ - 2 new tests (194 total).
36
+
37
+ ## 1.1.0 — 2026-07-09
38
+
39
+ New resource. No breaking changes.
40
+
41
+ - **`client.publicGuest`** — the consumer side of a public guest token
42
+ (`/public/v1/guest/{token}/*`), the counterpart to `client.guestTokens`
43
+ (operator issue/list/revoke). 8 request methods (`menu`, `fix`, `invoke`,
44
+ `document`, `queryObjectSet`, `documentNode`, `page`, `evaluatePage`) plus
45
+ `mediaUrl(token, key)` — a string builder for `<img src>` (media bytes are
46
+ binary; the JSON transport doesn't fetch them). Anonymous by design: build
47
+ `new AegisClient({ baseUrl })` with no token; the token travels in the path.
48
+ Dogfooded by the Safe-Tag SPAs (livetracker/residentmap repointed off
49
+ Firebase onto AEGIS).
50
+ - 15 new tests (192 total).
51
+
52
+ ## 1.0.0 — 2026-07-08
53
+
54
+ F5 — Hardening. No breaking API changes; new default behaviors noted below.
55
+
56
+ - **Retry/backoff** (new default behavior): transient failures (network
57
+ errors, timeouts, 429/502/503/504) are retried with exponential backoff +
58
+ full jitter — GET/HEAD only, 2 retries. Configure via `retry` option
59
+ (`{retries, baseDelayMs, maxDelayMs, retryPost}`); `{retries: 0}` disables.
60
+ - **Automatic JWT refresh**: `auth.login` now captures the refresh token; on
61
+ a 401 the client rotates it via `POST /auth/refresh` (single-flight) and
62
+ retries the request once. A rejected refresh clears the token (no loops).
63
+ Seed manually via `refreshToken` option / `setRefreshToken()`; explicit
64
+ `auth.refresh(token)` added.
65
+ - **Per-method generics**: 510 resource methods now accept a type parameter —
66
+ `client.geo.nodes<GeoNodesOut>()` instead of `as unknown as` casts
67
+ (`T = Json` default keeps all existing code compiling).
68
+ - All resource classes and their option types are exported from the package
69
+ root (typed params in consumer code + full typedoc coverage).
70
+ - `npm run docs` (typedoc) + `examples/` (OSDK-token server usage, browser
71
+ proxy mode with SSE).
72
+ - 12 new tests (177 total).
73
+
74
+ ## 0.4.0 — 2026-07-08
75
+
76
+ F3 (OSDK codegen CLI) + F4 groundwork (proxy-mode, dogfooded in security-app).
77
+
78
+ - **`aegis-osdk` CLI** (`npx aegis-osdk generate|manifest`): fetches
79
+ `GET /ontology/osdk/generate?lang=typescript|python` from a live deployment
80
+ and writes the typed module; prints the contract version. Proven live against
81
+ a real AEGIS backend (generated module passes strict `tsc`).
82
+ - **`asOsdkClient(client)`** adapter — bridges `AegisClient` to the `OSDKClient`
83
+ `{get, post}` contract expected by generated modules.
84
+ - **Proxy mode** (cookie-auth frontends like security-app): relative `baseUrl`
85
+ (e.g. `/api`, resolved against the browser origin) + `fetchInit` option
86
+ (`{credentials: "include", cache: "no-store"}` merged into every request,
87
+ including `stream()`).
88
+ - `geo.referenceLayers()` / `geo.referenceLayer(id, {uf, municipio})` — gap
89
+ found while dogfooding (endpoints existed in the backend but in neither SDK).
90
+ - 12 new tests (165 total).
91
+
92
+ ## 0.3.0 — 2026-07-08
93
+
94
+ F1.5 (full parity closure) + F2 (SSE streaming). **Every Python SDK module now has a TS mirror.**
95
+
96
+ - **Domain**: `atlas` (layers + KML import + evaluator), `briefing`, `cctv` (streams/detections/recordings/exports/bookmarks/GCPs/LPR hotlist, raw m3u8 playlist), `edge` (pairing/fleet version), `video` (streams/detections/tags/soak/exports), `comunicados`, `campaign.briefing`.
97
+ - **Collaboration/apps**: `forms`, `appShell` (banner/footer/user-menu/sidenav/homepage), `groups` (alias of `iam.groups`), `projects` (move + constraints), `organizations`, `spaces`, `solutions` (design/materialize/diagrams/teardown/marketplace), `workspaces` (+versions/navigation/promotions/kiosk), `workspaceUpdates`, `marketplace` (v23 storefront + install wizard).
98
+ - **Versioned surfaces**: `platformV22` (action-log, notepad templates, quiver, variable transforms, usage), `platformV23` (aip-logic, action-types, assist, pipeline, quiver, connectors, automate, health, contour, vertex, repos, object-sets, carbon, styles incl. multipart logo upload), `platformV24` (flat: rules, checkpoints, expectations, change requests, scenarios, object-set search-around/aggregate, …), `platformV25` (machinery, branch protection, kiosk, analyst threads, dataset rollback/snapshot/limits, freshness, code scan, evals), `platformV26` (promotions, object/core views, capacity, listeners, scanner, monitoring, health checks, media versions, insight, peers, run history).
99
+ - **Static catalogs**: full IAM permission catalog (`NAV_PERMISSIONS`/`CAPABILITY_PERMISSIONS`/`PermissionKey` union, `isSystemPermission`) and the OSDK `APPLICATIONS` catalog (7 apps) with `validateApplication`.
100
+ - **F2 — SSE**: `client.stream(path)` async iterator + spec-compliant `parseSseStream` (chunk-boundary safe, CRLF, comments, sticky id/retry); errors map through the exception hierarchy.
101
+ - Transport: multipart `form` option; array query params (repeated keys).
102
+ - 60 new tests (153 total).
103
+
104
+ ## 0.2.0 — 2026-07-08
105
+
106
+ F1 — resource parity, 27 new client surfaces (mirror of Python SDK v0.10.0):
107
+
108
+ - **Reading**: `geo`, `mapTemplates` (incl. `exportSvg` raw-SVG), `media`, `docs`, `pages`, `dossier` (async start → poll), `timeseries`.
109
+ - **Operational**: `alerts` (feeds/watches/geofences/shares/routes/inbox + escalate/channels), `alarms`, `events` (pipeline + DLQ, ids-XOR-all guard), `connectors` (incl. two-step `register`), `pipelines`, `chat`, `notepad`.
110
+ - **Governance**: `lineage`, `accessAudit`, `markings` (+categories/eligibility), `resourceMarkings`, `propertyMarkings`, `rowPolicies`, `erasure` (preview/forget), `retention`, `guestTokens`.
111
+ - **Platform**: `workshop` (briefings/dossiers/covs/widgetCatalog), `compute` (providers/releases/vision + per-provider `control()` plane), `inference` (complete/chat/chatWithRag/models/collections/auditTrail), `codegen`, `correlation`, `situational`, `merge`.
112
+ - Client-side classification helpers: `maxLevel`, `validateInvariant`, `ClassificationInvariantViolation` (mirror of `aegis.classification`).
113
+ - 64 new tests (93 total).
114
+
115
+ Deliberate deviations from Python (documented in `docs/PLAN.md`): the stdout-based
116
+ `aegis.maps` builder is sandbox-IDE-only and was not ported (only `MapTemplates` HTTP
117
+ surface); `inference` is a client resource here instead of a functional namespace.
118
+
119
+ ## 0.1.0 — 2026-07-08
120
+
121
+ First cut of the TypeScript SDK, mirroring `aegis-platform-sdk` (Python) v0.10.0.
122
+
123
+ - `AegisClient` — fetch-based transport, zero runtime dependencies, ESM + CJS.
124
+ - Auth: `login` (JWT attach), `me`, `enableDevMode`; env fallbacks `AEGIS_API_URL` / `AEGIS_TOKEN`.
125
+ - Error hierarchy: `AegisAPIError`, `AuthError` (401), `PermissionDeniedError` (403), `NotFoundError` (404).
126
+ - Resources: `iam` (users/roles/groups/permissions/nav), `osdk` (token lifecycle), `operator.tasks`, `ontology` (objects, graph, explorer, object-types, link-types, OSDK manifest/codegen), `aip` (flows, agents, models, budget), `functions` + `codeRepositories` (Code Functions v26), `datasets` (branches, transactions, classification, markings).
127
+ - Generic `client.request(method, path, opts)` escape hatch for unwrapped endpoints.
package/README.md CHANGED
@@ -1,105 +1,144 @@
1
- # AEGIS SDK — TypeScript (`aegis-platform-sdk`)
2
-
3
- Typed TypeScript client for the AEGIS HTTPS API (Safe-Core Technologies).
4
- Mirrors the Python SDK ([`aegis-platform-sdk` on PyPI](https://pypi.org/project/aegis-platform-sdk/))
5
- — same resource layout, same error hierarchy, same auth model.
6
-
7
- - **Zero runtime dependencies** — platform `fetch` (Node ≥ 18, browsers, edge runtimes).
8
- - **ESM + CJS** with full `.d.ts` types.
9
- - **Same surface as Python**: `client.iam.users.list()` ⇄ `client.iam.users.list()`.
10
-
11
- ## Install
12
-
13
- ```bash
14
- npm install aegis-platform-sdk
15
- ```
16
-
17
- ## Programmatic auth (OSDK Application)
18
-
19
- Issue a token in the AEGIS UI: **Governance → OSDK Applications**. The
20
- plaintext appears once; stash it like any other secret.
21
-
22
- ```ts
23
- import { AegisClient } from "aegis-platform-sdk";
24
-
25
- const client = new AegisClient({
26
- baseUrl: "https://aegis.example.com",
27
- token: "osdk_xK9pQzR2L8mYvN4w...",
28
- });
29
-
30
- const me = await client.auth.me();
31
- console.log(me.username, me.permissions);
32
- ```
33
-
34
- Env fallbacks (`AEGIS_API_URL`, `AEGIS_TOKEN`) let you construct
35
- `new AegisClient()` with no arguments in server-side code.
36
-
37
- ## Human auth (login)
38
-
39
- ```ts
40
- const client = new AegisClient({ baseUrl: "https://aegis.example.com" });
41
- await client.auth.login("operador", "senha", { totpCode: "123456" }); // JWT attaches automatically
42
- const tree = await client.iam.nav.tree();
43
- ```
44
-
45
- ## Error handling
46
-
47
- ```ts
48
- import { AegisAPIError, PermissionDeniedError } from "aegis-platform-sdk";
49
-
50
- try {
51
- await client.iam.users.list();
52
- } catch (err) {
53
- if (err instanceof PermissionDeniedError) console.error("missing perm:", err.detail);
54
- else if (err instanceof AegisAPIError) console.error(err.statusCode, err.detail, err.payload);
55
- }
56
- ```
57
-
58
- 401 → `AuthError` · 403 → `PermissionDeniedError` · 404 → `NotFoundError` · everything else → `AegisAPIError`.
59
-
60
- ## Resources
61
-
62
- | Resource | Surface |
63
- |----------|---------|
64
- | `client.auth` | `login`, `me`, `enableDevMode` |
65
- | `client.iam` | `users`, `roles`, `groups` (CRUD + members), `permissions`, `nav.tree` |
66
- | `client.osdk` | OSDK token lifecycle: `list/get/create/rotate/revoke` |
67
- | `client.operator.tasks` | NL task queue: `list/get/create/cancel/retry/reprioritize` |
68
- | `client.ontology` | `objects` (CRUD, bulk, links, history, timeseries), `graph.expand`, `explorer` (histogram/timeline), `objectTypes`, `linkTypes`, `osdkManifest/osdkFunctions/osdkGenerate` |
69
- | `client.aip` | `flows`, `agents`, `models` (catalog/defaults), `budget` |
70
- | `client.functions` | Code Functions: CRUD, `invoke`, tests, publish, versions, pull requests + CI |
71
- | `client.codeRepositories` | repos, branches, CI, merge |
72
- | `client.datasets` | datasets, branches, transactions (begin/commit/abort), merges, classification, markings |
73
-
74
- Anything not wrapped yet is reachable via the escape hatch:
75
-
76
- ```ts
77
- const rows = await client.request("GET", "/entities/aggregate", {
78
- params: { property: "kind" },
79
- });
80
- ```
81
-
82
- ## Claude Code skill
83
-
84
- The npm package ships a Claude Code skill under `skills/aegis-sdk/`. In an
85
- external project that consumes this SDK, copy it into the project's
86
- `.claude/skills/` so Claude Code knows the SDK surface and conventions:
87
-
88
- ```bash
89
- mkdir -p .claude/skills
90
- cp -r node_modules/aegis-platform-sdk/skills/aegis-sdk .claude/skills/aegis-sdk
91
- ```
92
-
93
- ## Development
94
-
95
- ```bash
96
- npm install
97
- npm run typecheck && npm test && npm run build
98
- ```
99
-
100
- Releases: see [`PUBLISHING.md`](./PUBLISHING.md). Roadmap and extension
101
- plan: [`docs/PLAN.md`](./docs/PLAN.md).
102
-
103
- ## License
104
-
105
- Proprietary — Safe-Core Technologies. See [LICENSE](./LICENSE).
1
+ # AEGIS SDK — TypeScript (`aegis-platform-sdk`)
2
+
3
+ Typed TypeScript client for the AEGIS HTTPS API (Safe-Core Technologies).
4
+ Mirrors the Python SDK ([`aegis-platform-sdk` on PyPI](https://pypi.org/project/aegis-platform-sdk/))
5
+ — same resource layout, same error hierarchy, same auth model.
6
+
7
+ - **Zero runtime dependencies** — platform `fetch` (Node ≥ 18, browsers, edge runtimes).
8
+ - **ESM + CJS** with full `.d.ts` types.
9
+ - **Same surface as Python**: `client.iam.users.list()` ⇄ `client.iam.users.list()`.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install aegis-platform-sdk
15
+ ```
16
+
17
+ ## Programmatic auth (OSDK Application)
18
+
19
+ Issue a token in the AEGIS UI: **Governance → OSDK Applications**. The
20
+ plaintext appears once; stash it like any other secret.
21
+
22
+ ```ts
23
+ import { AegisClient } from "aegis-platform-sdk";
24
+
25
+ const client = new AegisClient({
26
+ baseUrl: "https://aegis.example.com",
27
+ token: "osdk_xK9pQzR2L8mYvN4w...",
28
+ });
29
+
30
+ const me = await client.auth.me();
31
+ console.log(me.username, me.permissions);
32
+ ```
33
+
34
+ Env fallbacks (`AEGIS_API_URL`, `AEGIS_TOKEN`) let you construct
35
+ `new AegisClient()` with no arguments in server-side code.
36
+
37
+ ## Human auth (login)
38
+
39
+ ```ts
40
+ const client = new AegisClient({ baseUrl: "https://aegis.example.com" });
41
+ await client.auth.login("operador", "senha", { totpCode: "123456" }); // JWT attaches automatically
42
+ const tree = await client.iam.nav.tree();
43
+ ```
44
+
45
+ ## Error handling
46
+
47
+ ```ts
48
+ import { AegisAPIError, PermissionDeniedError } from "aegis-platform-sdk";
49
+
50
+ try {
51
+ await client.iam.users.list();
52
+ } catch (err) {
53
+ if (err instanceof PermissionDeniedError) console.error("missing perm:", err.detail);
54
+ else if (err instanceof AegisAPIError) console.error(err.statusCode, err.detail, err.payload);
55
+ }
56
+ ```
57
+
58
+ 401 → `AuthError` · 403 → `PermissionDeniedError` · 404 → `NotFoundError` · everything else → `AegisAPIError`.
59
+
60
+ ## Resources
61
+
62
+ | Resource | Surface |
63
+ |----------|---------|
64
+ | `client.auth` | `login`, `me`, `enableDevMode` |
65
+ | `client.iam` | `users`, `roles`, `groups` (CRUD + members), `permissions`, `nav.tree` |
66
+ | `client.osdk` | OSDK token lifecycle: `list/get/create/rotate/revoke` |
67
+ | `client.operator.tasks` | NL task queue: `list/get/create/cancel/retry/reprioritize` |
68
+ | `client.ontology` | `objects` (CRUD, bulk, links, history, timeseries), `graph.expand`, `explorer` (histogram/timeline), `objectTypes`, `linkTypes`, `osdkManifest/osdkFunctions/osdkGenerate` |
69
+ | `client.aip` | `flows`, `agents`, `models` (catalog/defaults), `budget` |
70
+ | `client.functions` | Code Functions: CRUD, `invoke`, tests, publish, versions, pull requests + CI |
71
+ | `client.codeRepositories` | repos, branches, CI, merge |
72
+ | `client.datasets` | datasets, branches, transactions (begin/commit/abort), merges, classification, markings |
73
+ | `client.geo` / `mapTemplates` / `media` / `docs` / `pages` / `dossier` / `timeseries` | reading & consumption surfaces |
74
+ | `client.publicGuest` | public guest-token consumer (`/public/v1/guest/{token}/*`): `menu`, `fix`, `invoke`, `position` (resident reads visitor's live location), `document`, `page`, `evaluatePage`, `mediaUrl` — anonymous, token in the path |
75
+ | `client.alerts` / `alarms` / `events` / `connectors` / `pipelines` / `chat` / `notepad` | operational surfaces |
76
+ | `client.lineage` / `accessAudit` / `markings` / `resourceMarkings` / `propertyMarkings` / `rowPolicies` / `erasure` / `retention` / `guestTokens` | governance surfaces |
77
+ | `client.workshop` / `compute` / `inference` / `codegen` / `correlation` / `situational` / `merge` | platform surfaces |
78
+ | `client.atlas` / `briefing` / `cctv` / `edge` / `video` / `comunicados` / `campaign` | domain surfaces |
79
+ | `client.forms` / `appShell` / `groups` / `projects` / `organizations` / `spaces` / `solutions` / `workspaces` / `workspaceUpdates` / `marketplace` | collaboration & apps |
80
+ | `client.platformV22` … `client.platformV26` | versioned platform surfaces |
81
+ | `client.stream(path)` | SSE async iterator (task progress, AIP streaming) |
82
+ | `NAV_PERMISSIONS` / `CAPABILITY_PERMISSIONS` / `APPLICATIONS` | static permission + OSDK app catalogs |
83
+
84
+ Anything not wrapped yet is reachable via the escape hatch:
85
+
86
+ ```ts
87
+ const rows = await client.request("GET", "/entities/aggregate", {
88
+ params: { property: "kind" },
89
+ });
90
+ ```
91
+
92
+ ## Hardening (1.0)
93
+
94
+ - **Typed results**: `client.geo.nodes<GeoNodesOut>()` — every direct method
95
+ takes a type parameter (default `Json`).
96
+ - **Retry/backoff**: transient failures (network, timeout, 429/5xx-gateway)
97
+ retried on GET/HEAD with jittered exponential backoff tune via
98
+ `retry: { retries, baseDelayMs, maxDelayMs, retryPost }`.
99
+ - **Auto JWT refresh**: after `auth.login`, a 401 rotates the refresh token
100
+ and retries once, transparently.
101
+
102
+ ## OSDK codegen CLI
103
+
104
+ ```bash
105
+ npx aegis-osdk generate --lang typescript # typed module from the LIVE ontology
106
+ npx aegis-osdk manifest # raw manifest JSON
107
+ ```
108
+
109
+ Auth via `AEGIS_API_URL`/`AEGIS_TOKEN` or `--base-url`/`--token`. Wire the
110
+ generated module with `asOsdkClient(client)`.
111
+
112
+ ## Proxy mode (cookie-auth frontends)
113
+
114
+ ```ts
115
+ const aegis = new AegisClient({
116
+ baseUrl: "/api", // relative — resolved against the browser origin
117
+ fetchInit: { credentials: "include", cache: "no-store" },
118
+ });
119
+ ```
120
+
121
+ ## Claude Code skill
122
+
123
+ The npm package ships a Claude Code skill under `skills/aegis-sdk/`. In an
124
+ external project that consumes this SDK, copy it into the project's
125
+ `.claude/skills/` so Claude Code knows the SDK surface and conventions:
126
+
127
+ ```bash
128
+ mkdir -p .claude/skills
129
+ cp -r node_modules/aegis-platform-sdk/skills/aegis-sdk .claude/skills/aegis-sdk
130
+ ```
131
+
132
+ ## Development
133
+
134
+ ```bash
135
+ npm install
136
+ npm run typecheck && npm test && npm run build
137
+ ```
138
+
139
+ Releases: see [`PUBLISHING.md`](./PUBLISHING.md). Roadmap and extension
140
+ plan: [`docs/PLAN.md`](./docs/PLAN.md).
141
+
142
+ ## License
143
+
144
+ Proprietary — Safe-Core Technologies. See [LICENSE](./LICENSE).