@lunnoa/client 1.5.0 → 2.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunnoa/client",
3
- "version": "1.5.0",
3
+ "version": "2.1.0",
4
4
  "description": "TypeScript SDK for building applications on top of Lunnoa Automate — typed client for the Public API (agents, workflows, executions, entities, knowledge, queues), SSE agent chat streaming, and deployment-specific codegen",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -2,10 +2,10 @@
2
2
  name: lunnoa-client
3
3
  description: >-
4
4
  Builds custom frontends and backends on top of a Lunnoa Automate deployment
5
- using the @lunnoa/client TypeScript SDK. Covers the two auth patterns
6
- (server-side lna_ API keys via createServerClient, browser user JWTs via
7
- createBrowserClient + lunnoa.auth.login / refresh / SSO — never lna_ keys in a
8
- browser), discovery of the deployment's agents, workflows, and entity
5
+ using the @lunnoa/client TypeScript SDK. App login is always a Lunnoa user
6
+ (createBrowserClient + lunnoa.auth.login / refresh / SSO). lna_ API keys are
7
+ for the CLI only (discovery, codegen, deploy), never for the app session and
8
+ never in a browser. Covers discovery of the deployment's agents, workflows, and entity
9
9
  types, running the deployment codegen first for typed accessors, querying
10
10
  and creating entities, triggering workflows and polling executions,
11
11
  resuming NEEDS_INPUT executions from custom forms, streaming agent chat
@@ -49,56 +49,55 @@ Human docs (detail): Lunnoa Docs → Develop → TypeScript client SDK.
49
49
 
50
50
  Run these before inventing resources or shipping UI code:
51
51
 
52
- 1. **Auth** — Pattern A (`createServerClient` + `lna_` on the server) or
53
- Pattern B (`createBrowserClient` + JWT). **Never** put `lna_` in the
54
- browser (SDK throws when `window` exists).
52
+ 1. **Auth** — Lunnoa user JWT via `createBrowserClient` + `lunnoa.auth.login`
53
+ (or SSO). **Never** call Lunnoa as the app's users with an `lna_` key, and
54
+ **never** put `lna_` in the browser (SDK throws when `window` exists).
55
+ `lna_` keys are for CLI discovery, codegen, and deploy only.
55
56
  2. **Codegen** — When building typed UIs, run
56
57
  `npx @lunnoa/client codegen` against the deployment first.
57
58
  3. **Discover before inventing** — prefer the CLI (JSON for agents), then
58
59
  the SDK: `npx @lunnoa/client tools list --json --for-agent`,
59
60
  `tools get <actionId> --json`, `apps list`, `connections list`,
60
- `agents|workflows|entity-types|tables|projects list`, `tables get <slugOrId>`,
61
+ `agents|workflows|entity-types|tables list`, `tables get <slugOrId>`,
61
62
  `features`.
62
63
  SDK equivalents: `workflowApps.list()`, `agents.list`, `workflows.list`,
63
64
  `entityTypes.list`, `tables.list`, `discovery.enabledFeatures()`.
64
65
  Do not invent catalogue action ids.
65
66
  4. **Run vs deploy** — Ad-hoc: `actions.run` / `runs.start` /
66
67
  `workflows.execute`. Durable shared automation: CLI
67
- `npx @lunnoa/client workflows|agents deploy` (upsert by slug).
68
+ `npx @lunnoa/client workflows|agents deploy`. Upsert is by slug
69
+ inside the workspace on the API key. URL and API key are enough.
68
70
  5. **Toolkit boundary** — Client `defineAction` ≠ toolkit `createAction`.
69
71
 
70
72
  ---
71
73
 
72
- ## 1. Auth: decide the pattern first
74
+ ## 1. Auth: Lunnoa users only
73
75
 
74
- | Pattern | Credential | Use when |
75
- |---|---|---|
76
- | **A. Backend holds the key** | `createServerClient({ apiKey: 'lna_...' })` | The app has its own users/login; Lunnoa never needs to know them. All Lunnoa calls go through the app's backend. |
77
- | **B. End users are Lunnoa users** | `createBrowserClient({ baseUrl })` + `lunnoa.auth.login` | Per-user permissions, agent shares, and task history must apply. The browser talks to Lunnoa directly. |
76
+ Every person who uses the app is a Lunnoa user. If they are not in the
77
+ workspace yet, they are provisioned there first (invite, SSO, or SCIM). The
78
+ app does not keep its own user directory and does not call Lunnoa with an
79
+ `lna_` key on their behalf.
80
+
81
+ | Caller | Credential |
82
+ |---|---|
83
+ | **Person using the app** | `createBrowserClient({ baseUrl })` + `lunnoa.auth.login` (password, 2FA, or SSO). Permissions, agent shares, and task history are that user's. |
84
+ | **CLI (codegen, discovery, deploy)** | `lna_` API key in `.env` / `--api-key`. Not the app session. |
78
85
 
79
86
  Hard rules:
80
87
 
81
88
  - **NEVER put an `lna_` key in browser code, env vars bundled into the client,
82
89
  or anything shipped to the browser.** The SDK throws if an `lna_` key is
83
90
  used while `window` exists. A leaked key exposes the whole workspace.
84
- - For browser apps with their own user base, use the **backend-for-frontend
85
- pattern**: the browser calls your backend; your backend holds the key and
86
- calls Lunnoa. Next.js route handlers / server actions count as backend.
87
- - Pattern B needs the deployment to allow the app's origin via
88
- `CORS_ALLOWED_ORIGINS`.
89
- - Keys are minted by a SuperAdmin in **Adminspace → API keys** (workspace +
91
+ - **NEVER build a backend-for-frontend that holds an `lna_` key so the app
92
+ can have its own users.** Next.js route handlers and server actions count
93
+ as the app: they must forward the signed-in user's JWT, not a service key.
94
+ - The deployment must allow the app's origin via `CORS_ALLOWED_ORIGINS`.
95
+ - CLI keys are minted by a SuperAdmin in **Adminspace → API keys** (workspace +
90
96
  RBAC role + optional expiry; secret shown once). Recommend a minimal custom
91
97
  role (e.g. `entities:read`, `entities:create`, `agents:use`), not Admin.
92
98
 
93
99
  ```typescript
94
- // Pattern A (server only)
95
- import { createServerClient } from '@lunnoa/client';
96
- const lunnoa = createServerClient({
97
- baseUrl: process.env.LUNNOA_URL!,
98
- apiKey: process.env.LUNNOA_API_KEY!,
99
- });
100
-
101
- // Pattern B (browser) — login + localStorage token store + auto-refresh on 401
100
+ // App session — login + localStorage token store + auto-refresh on 401
102
101
  import { createBrowserClient, isLoginRequires2FA } from '@lunnoa/client';
103
102
  const lunnoa = createBrowserClient({ baseUrl });
104
103
  const result = await lunnoa.auth.login({ email, password });
@@ -149,7 +148,7 @@ const { data, setPage } = useEntityList({ objectTypeSlug: 'invoice' });
149
148
 
150
149
  Peer: `react` ≥ 18 for `/react`. `@ai-sdk/react` ships with the SDK (no extra install).
151
150
  Errors are `LunnoaApiError` with `.status`, `.body`, `.isUnauthorized`,
152
- `.isForbidden`, `.isRateLimited`. A 403 means the key's role or the
151
+ `.isForbidden`, `.isRateLimited`. A 403 means the user's role or the
153
152
  deployment's licence edition does not cover the endpoint.
154
153
 
155
154
  ---
@@ -168,8 +167,9 @@ npx @lunnoa/client codegen --url <deployment-url> --api-key <lna_key> --out ./sr
168
167
  This emits `src/lunnoa/lunnoa.generated.ts` with `createDeploymentClient`:
169
168
 
170
169
  ```typescript
170
+ import { createBrowserClient } from '@lunnoa/client';
171
171
  import { createDeploymentClient } from './lunnoa/lunnoa.generated';
172
- const lunnoa = createDeploymentClient(new LunnoaClient({ baseUrl, apiKey }));
172
+ const lunnoa = createDeploymentClient(createBrowserClient({ baseUrl }));
173
173
 
174
174
  await lunnoa.entities.invoice.list({ state: 'pending' }); // typed attributes + states
175
175
  await lunnoa.workflows.processInvoice.execute({ invoiceId }); // typed trigger inputs
@@ -319,7 +319,6 @@ const result = await lunnoa.actions.run({
319
319
  appId: 'http',
320
320
  actionId: 'http_action_send-request',
321
321
  // connectionId: '<Connection.id UUID>', // required if needsConnection + multiple
322
- // projectId: '<project UUID>', // required if multiple projects
323
322
  input: { method: 'GET', url: 'https://example.com' },
324
323
  name: 'Ping example',
325
324
  });
@@ -390,11 +389,11 @@ npx @lunnoa/client connections list --app gmail --json
390
389
  `tools get` returns `inputConfig` / `inputFields` and a `defineAction` sketch.
391
390
  `tools list` is compact; use `get` for the schema. `--json` is for coding agents.
392
391
 
393
- Deploy to Automate UI (upsert by slug; prefer CLI):
392
+ Deploy to Automate UI (upsert by slug inside the workspace on the API key; prefer CLI):
394
393
 
395
394
  ```bash
396
- npx @lunnoa/client workflows deploy ./ping.ts --url … --api-key … --project-id …
397
- npx @lunnoa/client agents deploy ./triage.ts --url … --api-key … --project-id …
395
+ npx @lunnoa/client workflows deploy ./ping.ts --url … --api-key …
396
+ npx @lunnoa/client agents deploy ./triage.ts --url … --api-key …
398
397
  ```
399
398
 
400
399
  `defineAction` binds catalogue actions only. Toolkit `createAction` is a
@@ -500,7 +499,7 @@ const { items: work } = await lunnoa.queueItems.listByObject(ticket.id);
500
499
  `lunnoa.approvals` mirrors Automate **Approvals** (`/approvals`). It uses the
501
500
  workspace API (`/api/approvals/...`), not Public API v1. The inbox is filtered
502
501
  to requests where the **current user** is eligible and has not decided yet.
503
- Prefer pattern B (user JWT). Role needs `approvals:read` / `approvals:decide`.
502
+ The caller is the signed-in Lunnoa user. Role needs `approvals:read` / `approvals:decide`.
504
503
 
505
504
  ```typescript
506
505
  const { items } = await lunnoa.approvals.inbox(); // pending + partially_approved
@@ -531,9 +530,10 @@ with emails (capped; not Azure object IDs).
531
530
 
532
531
  ## 10. Ship checklist (after the mandatory checklist)
533
532
 
534
- 1. Confirm base URL + credential pattern (A or B); wire the key server-side only.
535
- For Pattern B prefer `createBrowserClient` and `lunnoa.auth.login` (not raw
536
- localStorage getters unless you already hold a JWT).
533
+ 1. Confirm the base URL. Sign people in with `createBrowserClient` and
534
+ `lunnoa.auth.login` (not an `lna_` key, and not raw localStorage getters
535
+ unless you already hold that user's JWT). Allow the origin in
536
+ `CORS_ALLOWED_ORIGINS`.
537
537
  2. Run `npx @lunnoa/client codegen` against the deployment; commit the output.
538
538
  3. Call `discovery.enabledFeatures()` and hide unsupported areas.
539
539
  4. Build forms/tables from `attributeSchema` / `customInputConfig` (or the generated types).
@@ -42,10 +42,11 @@ interrogation.
42
42
 
43
43
  ### Actors
44
44
 
45
- - Who uses the custom UI: Lunnoa employees (workspace users), external
46
- customers (not Lunnoa users), or a backend system only?
47
- - That choice drives auth: JWT (Pattern B) vs API key BFF (Pattern A). Never
48
- put `lna_` keys in a browser.
45
+ - Who uses the custom UI? They sign in as Lunnoa users. If they are not in
46
+ the workspace yet, they are provisioned there first (invite, SSO, or SCIM).
47
+ - The app does not keep its own login and does not call Lunnoa with an `lna_`
48
+ key on their behalf. `lna_` keys are for the CLI only. Never put one in a
49
+ browser.
49
50
 
50
51
  ### Data and knowledge
51
52
 
@@ -70,10 +71,10 @@ interrogation.
70
71
 
71
72
  ### Auth for any custom UI
72
73
 
73
- | End users | Prefer |
74
+ | End users | Auth |
74
75
  |---|---|
75
- | App has its own login; Lunnoa is a backend | Pattern A: server holds `lna_` |
76
- | End users are Lunnoa users; per-user history/permissions | Pattern B: browser JWT |
76
+ | People using the app | Lunnoa user JWT: `createBrowserClient` + `lunnoa.auth.login` (or SSO). Provision missing people with invite, SSO, or SCIM first. |
77
+ | Coding agent / CLI | `LUNNOA_API_KEY` for discovery, codegen, and deploy. Not the app session. |
77
78
  | Anonymous embed chat (no full login) | Out of scope for v1 client path; scoped embed tokens are a later platform bet |
78
79
 
79
80
  ---
@@ -145,11 +146,11 @@ can execute. Use this shape:
145
146
 
146
147
  ### Auth
147
148
  - Pattern: A (server API key) | B (browser JWT)
148
- - Notes: <CORS, BFF, project id, env vars>
149
+ - Notes: <CORS, BFF, env vars LUNNOA_URL and LUNNOA_API_KEY>
149
150
 
150
151
  ### Discovery (run first)
151
152
  - [ ] `npx @lunnoa/client tools list --json --for-agent` then `tools get <id>`
152
- - [ ] agents / workflows / entity-types / tables / projects list — reuse before create
153
+ - [ ] agents / workflows / entity-types / tables list — reuse before create
153
154
  - [ ] codegen — if building typed entity/workflow accessors
154
155
 
155
156
  ### Resources (every row says REUSED or CREATED)
@@ -192,7 +193,7 @@ continue in a coding turn with that skill loaded.
192
193
  **You ask:** Who chats (customers or staff)? Data source (entities vs ERP
193
194
  action)? Need approvals? Existing HTTP/CRM connections?
194
195
 
195
- **You conclude (example):** Pattern A BFF; Agent `order-status` with tools
196
+ **You conclude (example):** Customers are Lunnoa users (SCIM or invite) and sign in with a browser JWT; Agent `order-status` with tools
196
197
  `defineAction` for ERP lookup (after `tools list` / `tools get`) + optional
197
198
  workflow for staff notifications; UI = chat only; no agent schedule.
198
199