@nominalso/vibe-bridge 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +64 -0
- package/README.md +275 -13
- package/dist/index.cjs +508 -63
- package/dist/index.d.cts +367 -29
- package/dist/index.d.ts +367 -29
- package/dist/index.js +506 -63
- package/docs/connect-lifecycle.md +56 -0
- package/docs/data-fetching.md +71 -0
- package/docs/file-upload.md +55 -0
- package/docs/getting-started.md +53 -0
- package/llms.txt +20 -0
- package/package.json +5 -12
package/AGENTS.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# AGENTS.md — @nominalso/vibe-bridge
|
|
2
|
+
|
|
3
|
+
Instructions for AI coding agents (Claude Code, Cursor, Copilot, Lovable, etc.) integrating this package. This is a **consumer usage guide**, not repo build config.
|
|
4
|
+
|
|
5
|
+
## What this package is
|
|
6
|
+
|
|
7
|
+
`@nominalso/vibe-bridge` is the **iframe-side** SDK for a Nominal Vibe App — a standalone browser app (often built with Lovable) embedded in the Nominal platform via a cross-origin `<iframe>`. The app cannot call Nominal APIs directly; it talks to its Nominal host over a typed `postMessage` bridge. This package is that bridge. It is **browser-only** (uses `window`, `postMessage`, `crypto.randomUUID`) and has **zero runtime dependencies**.
|
|
8
|
+
|
|
9
|
+
The host counterpart is `@nominalso/vibe-host` (used by Nominal's own app — you do not install it in a Vibe App).
|
|
10
|
+
|
|
11
|
+
## The one rule
|
|
12
|
+
|
|
13
|
+
**Construct → `await connect()` once → then everything else.** `connect()` establishes the session context (tenant, subsidiary, user). Every data method, `upload()`, and subroute reporting requires it to have resolved first.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { VibeAppBridge, type ContextPayload } from '@nominalso/vibe-bridge'
|
|
17
|
+
|
|
18
|
+
const bridge = new VibeAppBridge({
|
|
19
|
+
parentOrigin: import.meta.env.VITE_PARENT_ORIGIN, // exact origin of the embedding Nominal app
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const ctx: ContextPayload = await bridge.connect() // call ONCE, await before anything else
|
|
23
|
+
|
|
24
|
+
const accounts = await bridge.getChartOfAccounts({ path: { subsidiary_id: ctx.subsidiaryId } })
|
|
25
|
+
|
|
26
|
+
await bridge.upload(file, { entityType: 'JOURNAL_ENTRY', entityId: '123' })
|
|
27
|
+
|
|
28
|
+
await bridge.postTaskOutput({ path: { task_instance_id: 'task-1' }, body: {} }) // only write path
|
|
29
|
+
|
|
30
|
+
bridge.destroy() // on unmount
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Core surface
|
|
34
|
+
|
|
35
|
+
- `new VibeAppBridge({ parentOrigin, requestTimeout? })` — `requestTimeout` is optional; omit it and each op uses a tuned default (API `30000`, `UPLOAD_FILE` `120000`, `INVALIDATE_CACHE` `10000`, `GET_CONTEXT` `5000` ms).
|
|
36
|
+
- `connect(): Promise<ContextPayload>` — call once; rejects after 10 s on `parentOrigin` mismatch / host not mounted.
|
|
37
|
+
- ~46 typed data methods, e.g. `getChartOfAccounts`, `getSubsidiaries`, `getPeriods`, `getJournalEntries`, `getAccounts`, `postTaskOutput`. Each takes the operation's `payload` and returns its `data`.
|
|
38
|
+
- `request('<OPERATION>', payload, onProgress?)` — typed escape hatch for any operation; `'<OPERATION>'` autocompletes and narrows the payload/return types.
|
|
39
|
+
- `upload(file: File, { entityType, entityId?, onProgress? }): Promise<{ attachmentId, name }>`.
|
|
40
|
+
- `navigate`/`navigateTo`/`refresh` and `ui.setSideNav`/`ui.switchSubsidiary` — drive the host's chrome (router, side nav, subsidiary switcher); `invalidateCache(...)` busts host caches.
|
|
41
|
+
- `reportSubroute(subroute, { replace? })`, `onSubrouteRequest(cb): () => void` — usually unnecessary; standard SPA navigation is auto-tracked.
|
|
42
|
+
- `destroy()`.
|
|
43
|
+
|
|
44
|
+
A failed operation throws a `BridgeError` (`extends Error`) with a machine-readable `code` (`'RATE_LIMITED'`, `'FILE_TOO_LARGE'`, `'TIMEOUT'`, …); branch on `err.code` rather than the message. A failed Nominal API call throws the `HttpBridgeError` subtype (`code: 'REQUEST_FAILED'`) carrying the HTTP `status` — branch on `err.status` (e.g. `404`).
|
|
45
|
+
|
|
46
|
+
Exported values/types: `VibeAppBridge`, `BridgeError`, `BRIDGE_VERSION`, and types `VibeAppBridgeOptions`, `UploadOptions`, `ContextPayload`, `BridgeSubsidiary`, `UploadResponse`, `UploadProgress`, `RequestRegistry`.
|
|
47
|
+
|
|
48
|
+
`ContextPayload` shape: `{ tenant, subsidiaryId, subsidiaries: { id, displayName }[], user: { id, displayName }, subroute?, lastClosedPeriodSlug?, hostVersion }`.
|
|
49
|
+
|
|
50
|
+
The full method/operation list is in `README.md` ("Operation catalog") and in `docs/data-fetching.md`. The detailed wire-up guides are in `docs/`.
|
|
51
|
+
|
|
52
|
+
## Gotchas (wrong → right)
|
|
53
|
+
|
|
54
|
+
- **Don't call data methods before `connect()` resolves.** Always `await bridge.connect()` first.
|
|
55
|
+
- **`parentOrigin` is an origin, not a URL.** `https://app.nominal.so` ✅ — not `https://app.nominal.so/app` and not a trailing slash. A mismatch makes `connect()` time out after 10 s.
|
|
56
|
+
- **`upload()` takes a `File`**, not a path or `FormData`.
|
|
57
|
+
- **Writes go through `postTaskOutput` only.** Vibe Apps never write Nominal data directly.
|
|
58
|
+
- **Call `bridge.destroy()` on unmount** to remove listeners and reject pending requests.
|
|
59
|
+
|
|
60
|
+
## Don't
|
|
61
|
+
|
|
62
|
+
- Don't poll or busy-wait for context — `await connect()` resolves when it's ready.
|
|
63
|
+
- Don't hardcode `parentOrigin`; read it from an env var so dev and prod differ.
|
|
64
|
+
- Don't import from `@nominalso/vibe-protocol-types` / `vibe-api-types` — they are not published; all public types are re-exported from `@nominalso/vibe-bridge`.
|
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @nominalso/vibe-bridge
|
|
2
2
|
|
|
3
|
-
Iframe-side SDK for building **Nominal Vibe Apps** — standalone web apps (typically built with Lovable) embedded in the Nominal platform via a cross-origin `<iframe>`. The bridge connects your app to its Nominal host over a typed `postMessage` protocol:
|
|
3
|
+
Iframe-side SDK for building **Nominal Vibe Apps** — standalone web apps (typically built with [Lovable](https://lovable.dev)) embedded in the Nominal platform via a cross-origin `<iframe>`. The bridge connects your app to its Nominal host over a typed `postMessage` protocol: read Nominal data, submit Close-Management task outputs, upload files, and keep deep-link routing in sync.
|
|
4
|
+
|
|
5
|
+
> **For AI agents / Lovable:** this is a browser-only SDK. The wiring is always the same — construct `VibeAppBridge` with the host `parentOrigin`, `await bridge.connect()` **once**, then call data methods. Copy the quickstart below verbatim; it is the complete happy path.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -8,30 +10,290 @@ Iframe-side SDK for building **Nominal Vibe Apps** — standalone web apps (typi
|
|
|
8
10
|
npm install @nominalso/vibe-bridge
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Zero runtime dependencies. Ships ESM + CJS and self-contained TypeScript types.
|
|
14
|
+
|
|
15
|
+
## Quickstart
|
|
12
16
|
|
|
13
17
|
```ts
|
|
14
|
-
import { VibeAppBridge } from '@nominalso/vibe-bridge'
|
|
18
|
+
import { VibeAppBridge, type ContextPayload } from '@nominalso/vibe-bridge'
|
|
15
19
|
|
|
20
|
+
// 1. Construct with the origin of the Nominal app embedding this iframe.
|
|
21
|
+
// Must match exactly — drive it from an env var.
|
|
16
22
|
const bridge = new VibeAppBridge({
|
|
17
|
-
// Must match the Nominal app origin exactly.
|
|
18
23
|
parentOrigin: import.meta.env.VITE_PARENT_ORIGIN,
|
|
19
24
|
})
|
|
20
25
|
|
|
21
|
-
//
|
|
22
|
-
|
|
26
|
+
// 2. Connect ONCE on init and await it before any other call.
|
|
27
|
+
// Resolves with the tenant/user context (or rejects after 10s).
|
|
28
|
+
const ctx: ContextPayload = await bridge.connect()
|
|
29
|
+
// ctx.tenant, ctx.subsidiaryId, ctx.subsidiaries, ctx.user, ctx.lastClosedPeriodSlug
|
|
30
|
+
|
|
31
|
+
// 3. Read Nominal data (any of the ~46 named operations).
|
|
32
|
+
const accounts = await bridge.getChartOfAccounts({
|
|
33
|
+
path: { subsidiary_id: ctx.subsidiaryId },
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// 4. Upload a file through the host.
|
|
37
|
+
const uploaded = await bridge.upload(file, {
|
|
38
|
+
entityType: 'JOURNAL_ENTRY',
|
|
39
|
+
entityId: '123',
|
|
40
|
+
onProgress: (p) => console.log(`${p.progress}%`),
|
|
41
|
+
})
|
|
23
42
|
|
|
24
|
-
|
|
25
|
-
await bridge.postTaskOutput(
|
|
26
|
-
await bridge.upload(file, { entityType: 'JOURNAL_ENTRY', entityId: '123' })
|
|
43
|
+
// 5. Submit a Close-Management task output — the ONLY write path into Nominal.
|
|
44
|
+
await bridge.postTaskOutput({ path: { task_instance_id: 'task-1' }, body: {} })
|
|
27
45
|
|
|
28
|
-
//
|
|
46
|
+
// 6. Tear down on unmount.
|
|
29
47
|
bridge.destroy()
|
|
30
48
|
```
|
|
31
49
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
`parentOrigin` via environment variable:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
# .env (committed — standalone/dev default)
|
|
54
|
+
VITE_PARENT_ORIGIN=http://localhost:5173
|
|
55
|
+
|
|
56
|
+
# .env.local (git-ignored — override when testing inside nom-ui)
|
|
57
|
+
VITE_PARENT_ORIGIN=http://localhost:3000
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
### `new VibeAppBridge(options)`
|
|
63
|
+
|
|
64
|
+
| Option | Type | Default | Description |
|
|
65
|
+
| ---------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `parentOrigin` | `string` | — | Origin of the Nominal app embedding this iframe. **Must match the host origin exactly.** |
|
|
67
|
+
| `requestTimeout` | `number` | _per-op_ | Global timeout (ms) before a call rejects with `BridgeError` code `'TIMEOUT'`. Omit to use per-operation defaults: API `30000`, `UPLOAD_FILE` `120000`, `INVALIDATE_CACHE` `10000`, `GET_CONTEXT` `5000`. |
|
|
68
|
+
|
|
69
|
+
### `connect(): Promise<ContextPayload>`
|
|
70
|
+
|
|
71
|
+
Call **once** on init and `await` it before anything else. Polls the host every 500 ms until context arrives; rejects with `Bridge connect timed out` after 10 s (usually a `parentOrigin` mismatch or the host hasn't mounted). Concurrent calls return the same promise.
|
|
72
|
+
|
|
73
|
+
### Data operations
|
|
74
|
+
|
|
75
|
+
Every operation has a typed named method (e.g. `bridge.getChartOfAccounts(payload)`); payloads and return types come straight from the Nominal API. For any operation, you can also call the generic escape hatch:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// `type` autocompletes to every operation name and narrows payload + return.
|
|
79
|
+
const accounts = await bridge.request('GET_ACCOUNTS', { query: { account_ids: ['acc-1'] } })
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
See the [operation catalog](#operation-catalog) for the full list.
|
|
83
|
+
|
|
84
|
+
### `upload(file, options): Promise<UploadResponse>`
|
|
85
|
+
|
|
86
|
+
Uploads a `File` through the host (converts to `ArrayBuffer` first — sandboxed iframes cannot pass `File` handles across windows). Resolves with `{ attachmentId, name }` once Nominal has stored it.
|
|
87
|
+
|
|
88
|
+
| Option | Type | Description |
|
|
89
|
+
| ------------ | ----------------------------- | ----------------------------------------------------------- |
|
|
90
|
+
| `entityType` | `string` | Domain entity the file attaches to, e.g. `'JOURNAL_ENTRY'`. |
|
|
91
|
+
| `entityId` | `string \| number` (optional) | Id of the entity, when applicable. |
|
|
92
|
+
| `onProgress` | `(p: UploadProgress) => void` | Called with incremental progress (`0`–`100`). |
|
|
93
|
+
|
|
94
|
+
### Subroute deep-linking
|
|
95
|
+
|
|
96
|
+
- `reportSubroute(subroute, { replace? })` — manually report the current subroute. **Usually unnecessary** — standard SPA navigation (`history.pushState`/`replaceState`) is auto-detected. Use it for hash-based or non-standard routers.
|
|
97
|
+
- `onSubrouteRequest(cb): () => void` — register a callback for host-initiated navigation (browser back/forward). Returns an unsubscribe function. If you don't register one, the SDK falls back to `history.pushState` + a `popstate` event, which works for most SPA routers.
|
|
98
|
+
|
|
99
|
+
### `destroy()`
|
|
100
|
+
|
|
101
|
+
Removes listeners, rejects pending requests, and restores patched history methods. Call on unmount.
|
|
102
|
+
|
|
103
|
+
### Exports
|
|
104
|
+
|
|
105
|
+
`VibeAppBridge`, `BridgeError`, `BRIDGE_VERSION`, and the types `VibeAppBridgeOptions`, `UploadOptions`, `ContextPayload`, `BridgeSubsidiary`, `UploadResponse`, `UploadProgress`, `RequestRegistry`.
|
|
106
|
+
|
|
107
|
+
## Common recipes
|
|
108
|
+
|
|
109
|
+
**React — connect on mount, tear down on unmount:**
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { useEffect, useState } from 'react'
|
|
113
|
+
import { VibeAppBridge, type ContextPayload } from '@nominalso/vibe-bridge'
|
|
114
|
+
|
|
115
|
+
function useVibeBridge() {
|
|
116
|
+
const [ctx, setCtx] = useState<ContextPayload | null>(null)
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
const bridge = new VibeAppBridge({ parentOrigin: import.meta.env.VITE_PARENT_ORIGIN })
|
|
119
|
+
bridge.connect().then(setCtx).catch(console.error)
|
|
120
|
+
return () => bridge.destroy()
|
|
121
|
+
}, [])
|
|
122
|
+
return ctx
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Upload with a progress bar:**
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
await bridge.upload(file, {
|
|
130
|
+
entityType: 'JOURNAL_ENTRY',
|
|
131
|
+
onProgress: (p) => (progressBar.style.width = `${p.progress}%`),
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**An operation without a named method — use the typed `request()`:**
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const events = await bridge.request('GET_AUDIT_EVENTS', {})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Handle a failure by its code:**
|
|
142
|
+
|
|
143
|
+
A rejected operation throws a `BridgeError` carrying the host's `code` (`'RATE_LIMITED'`, `'FILE_TOO_LARGE'`, `'TIMEOUT'`, …); branch on it instead of string-matching the message. A failed Nominal API call throws the `HttpBridgeError` subtype (`code: 'REQUEST_FAILED'`), which adds the HTTP `status` — branch on `err.status` (e.g. `404`).
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { BridgeError, HttpBridgeError } from '@nominalso/vibe-bridge'
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
await bridge.getAccounts({})
|
|
150
|
+
} catch (err) {
|
|
151
|
+
if (err instanceof HttpBridgeError && err.status === 404) {
|
|
152
|
+
// handle not-found
|
|
153
|
+
}
|
|
154
|
+
if (err instanceof BridgeError && err.code === 'RATE_LIMITED') {
|
|
155
|
+
// back off and retry
|
|
156
|
+
}
|
|
157
|
+
throw err
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Common mistakes
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// ❌ WRONG — calling a data method before connect() resolves.
|
|
165
|
+
const bridge = new VibeAppBridge({ parentOrigin })
|
|
166
|
+
const accounts = await bridge.getChartOfAccounts({ path: { subsidiary_id: 1 } })
|
|
167
|
+
|
|
168
|
+
// ✅ CORRECT — await connect() first; it establishes the session context.
|
|
169
|
+
const bridge = new VibeAppBridge({ parentOrigin })
|
|
170
|
+
const ctx = await bridge.connect()
|
|
171
|
+
const accounts = await bridge.getChartOfAccounts({ path: { subsidiary_id: ctx.subsidiaryId } })
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
// ❌ WRONG — parentOrigin must be an ORIGIN, not a URL with a path, and must match exactly.
|
|
176
|
+
new VibeAppBridge({ parentOrigin: 'https://app.nominal.so/some/path' })
|
|
177
|
+
// ❌ a trailing slash or wrong port also fails → connect() times out after 10s.
|
|
178
|
+
new VibeAppBridge({ parentOrigin: 'http://localhost:3000/' })
|
|
179
|
+
|
|
180
|
+
// ✅ CORRECT — scheme + host + port only, exact match to the embedding app.
|
|
181
|
+
new VibeAppBridge({ parentOrigin: 'https://app.nominal.so' })
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
// ❌ WRONG — upload takes a File object, not a path or FormData.
|
|
186
|
+
await bridge.upload('/tmp/report.pdf', { entityType: 'JOURNAL_ENTRY' })
|
|
187
|
+
|
|
188
|
+
// ✅ CORRECT — pass the File (e.g. from an <input type="file">).
|
|
189
|
+
await bridge.upload(fileInput.files![0], { entityType: 'JOURNAL_ENTRY' })
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Operation catalog
|
|
193
|
+
|
|
194
|
+
All operations are reachable as `bridge.<method>(payload)` or `bridge.request('<OPERATION>', payload)`.
|
|
195
|
+
|
|
196
|
+
**Accounting — chart of accounts**
|
|
197
|
+
|
|
198
|
+
| Method | Operation |
|
|
199
|
+
| ---------------------------------- | ------------------------------------- |
|
|
200
|
+
| `getChartOfAccounts` | `GET_CHART_OF_ACCOUNTS` |
|
|
201
|
+
| `getCoaTree` | `GET_COA_TREE` |
|
|
202
|
+
| `getCoaFlatSimple` | `GET_COA_FLAT_SIMPLE` |
|
|
203
|
+
| `getCoaGrouped` | `GET_COA_GROUPED` |
|
|
204
|
+
| `getCoaAccount` | `GET_COA_ACCOUNT` |
|
|
205
|
+
| `getSubsidiaryAvailableCurrencies` | `GET_SUBSIDIARY_AVAILABLE_CURRENCIES` |
|
|
206
|
+
| `getAccounts` | `GET_ACCOUNTS` |
|
|
207
|
+
| `getAccount` | `GET_ACCOUNT` |
|
|
208
|
+
|
|
209
|
+
**Accounting — exchange rates**
|
|
210
|
+
|
|
211
|
+
| Method | Operation |
|
|
212
|
+
| -------------------------- | ----------------------------- |
|
|
213
|
+
| `getConversionRates` | `GET_CONVERSION_RATES` |
|
|
214
|
+
| `getEffectiveExchangeRate` | `GET_EFFECTIVE_EXCHANGE_RATE` |
|
|
215
|
+
| `getExchangeRateByDate` | `GET_EXCHANGE_RATE_BY_DATE` |
|
|
216
|
+
|
|
217
|
+
**Accounting — dimensions**
|
|
218
|
+
|
|
219
|
+
| Method | Operation |
|
|
220
|
+
| -------------------------------- | ----------------------------------- |
|
|
221
|
+
| `getDimensions` | `GET_DIMENSIONS` |
|
|
222
|
+
| `getDimensionValues` | `GET_DIMENSION_VALUES` |
|
|
223
|
+
| `getDimensionValuesHierarchical` | `GET_DIMENSION_VALUES_HIERARCHICAL` |
|
|
224
|
+
| `getDimensionAccountAssignments` | `GET_DIMENSION_ACCOUNT_ASSIGNMENTS` |
|
|
225
|
+
|
|
226
|
+
**Accounting — journal entries**
|
|
227
|
+
|
|
228
|
+
| Method | Operation |
|
|
229
|
+
| ------------------- | --------------------- |
|
|
230
|
+
| `getJournalEntries` | `GET_JOURNAL_ENTRIES` |
|
|
231
|
+
| `getJournalLines` | `GET_JOURNAL_LINES` |
|
|
232
|
+
| `getJournalEntry` | `GET_JOURNAL_ENTRY` |
|
|
233
|
+
|
|
234
|
+
**Activity — period instances**
|
|
235
|
+
|
|
236
|
+
| Method | Operation |
|
|
237
|
+
| ---------------------------- | ------------------------------- |
|
|
238
|
+
| `getPeriods` | `GET_PERIODS` |
|
|
239
|
+
| `getPeriodInstance` | `GET_PERIOD_INSTANCE` |
|
|
240
|
+
| `getPeriodInstanceBySlug` | `GET_PERIOD_INSTANCE_BY_SLUG` |
|
|
241
|
+
| `getPeriodProgressBreakdown` | `GET_PERIOD_PROGRESS_BREAKDOWN` |
|
|
242
|
+
|
|
243
|
+
**Activity — activity definitions & instances**
|
|
244
|
+
|
|
245
|
+
| Method | Operation |
|
|
246
|
+
| ----------------------------- | --------------------------------- |
|
|
247
|
+
| `getActivityDefinitions` | `GET_ACTIVITY_DEFINITIONS` |
|
|
248
|
+
| `getActivityDefinition` | `GET_ACTIVITY_DEFINITION` |
|
|
249
|
+
| `getActivityInstances` | `GET_ACTIVITY_INSTANCES` |
|
|
250
|
+
| `getActivityInstance` | `GET_ACTIVITY_INSTANCE` |
|
|
251
|
+
| `getActivityInstanceByPeriod` | `GET_ACTIVITY_INSTANCE_BY_PERIOD` |
|
|
252
|
+
| `getActivityInstanceTasks` | `GET_ACTIVITY_INSTANCE_TASKS` |
|
|
253
|
+
| `getActivityPeriodTasks` | `GET_ACTIVITY_PERIOD_TASKS` |
|
|
254
|
+
|
|
255
|
+
**Activity — task definitions & instances**
|
|
256
|
+
|
|
257
|
+
| Method | Operation |
|
|
258
|
+
| ---------------------------- | -------------------------------- |
|
|
259
|
+
| `getTaskDefinitions` | `GET_TASK_DEFINITIONS` |
|
|
260
|
+
| `getTaskDefinition` | `GET_TASK_DEFINITION` |
|
|
261
|
+
| `createTaskDefinition` | `CREATE_TASK_DEFINITION` |
|
|
262
|
+
| `updateTaskDefinition` | `UPDATE_TASK_DEFINITION` |
|
|
263
|
+
| `getTaskDefinitionsByFilter` | `GET_TASK_DEFINITIONS_BY_FILTER` |
|
|
264
|
+
| `getTaskInstances` | `GET_TASK_INSTANCES` |
|
|
265
|
+
| `getTaskInstance` | `GET_TASK_INSTANCE` |
|
|
266
|
+
| `getTaskInstancesByFilter` | `GET_TASK_INSTANCES_BY_FILTER` |
|
|
267
|
+
| `postTaskOutput` | `POST_TASK_OUTPUT` |
|
|
268
|
+
|
|
269
|
+
**Audit trail**
|
|
270
|
+
|
|
271
|
+
| Method | Operation |
|
|
272
|
+
| ---------------------- | ------------------------- |
|
|
273
|
+
| `getAuditEvents` | `GET_AUDIT_EVENTS` |
|
|
274
|
+
| `getEntityAuditEvents` | `GET_ENTITY_AUDIT_EVENTS` |
|
|
275
|
+
|
|
276
|
+
**Period manager — fiscal calendars**
|
|
277
|
+
|
|
278
|
+
| Method | Operation |
|
|
279
|
+
| -------------------- | ---------------------- |
|
|
280
|
+
| `getFiscalCalendars` | `GET_FISCAL_CALENDARS` |
|
|
281
|
+
| `getFiscalCalendar` | `GET_FISCAL_CALENDAR` |
|
|
282
|
+
|
|
283
|
+
**Tenancy**
|
|
284
|
+
|
|
285
|
+
| Method | Operation |
|
|
286
|
+
| ------------------------------- | ---------------------------------- |
|
|
287
|
+
| `getSubsidiaries` | `GET_SUBSIDIARIES` |
|
|
288
|
+
| `getSubsidiary` | `GET_SUBSIDIARY` |
|
|
289
|
+
| `getSubsidiaryParentCurrencies` | `GET_SUBSIDIARY_PARENT_CURRENCIES` |
|
|
290
|
+
| `getTenantUsers` | `GET_TENANT_USERS` |
|
|
291
|
+
|
|
292
|
+
> `connect()` (context) and `upload()` (file upload) have dedicated methods and are not in this table.
|
|
293
|
+
|
|
294
|
+
## How it fits together
|
|
295
|
+
|
|
296
|
+
The host side is [`@nominalso/vibe-host`](https://www.npmjs.com/package/@nominalso/vibe-host), used by the Nominal app (nom-ui). See the [repository](https://github.com/nominalso/vibe-apps-sdk#readme) for the full protocol, architecture, and `connect()` semantics. Bundled agent docs ship in this package under `docs/` and `AGENTS.md`.
|
|
35
297
|
|
|
36
298
|
## License
|
|
37
299
|
|