bkper 5.0.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/lib/agent/extensions/bkper-ai-provider.d.ts.map +1 -1
- package/lib/agent/extensions/bkper-ai-provider.js +47 -16
- package/lib/agent/extensions/bkper-ai-provider.js.map +1 -1
- package/lib/agent/extensions/builtins.d.ts.map +1 -1
- package/lib/agent/extensions/builtins.js +10 -2
- package/lib/agent/extensions/builtins.js.map +1 -1
- package/lib/agent/extensions/startup-logo.d.ts +9 -0
- package/lib/agent/extensions/startup-logo.d.ts.map +1 -0
- package/lib/agent/extensions/startup-logo.js +96 -0
- package/lib/agent/extensions/startup-logo.js.map +1 -0
- package/lib/agent/extensions/startup.d.ts.map +1 -1
- package/lib/agent/extensions/startup.js +63 -33
- package/lib/agent/extensions/startup.js.map +1 -1
- package/lib/agent/interactive/prompt-history-store.d.ts +1 -0
- package/lib/agent/interactive/prompt-history-store.d.ts.map +1 -1
- package/lib/agent/interactive/prompt-history-store.js +19 -5
- package/lib/agent/interactive/prompt-history-store.js.map +1 -1
- package/lib/agent/interactive/run-agent-mode.d.ts.map +1 -1
- package/lib/agent/interactive/run-agent-mode.js +5 -2
- package/lib/agent/interactive/run-agent-mode.js.map +1 -1
- package/lib/agent/interactive/settings.d.ts +26 -4
- package/lib/agent/interactive/settings.d.ts.map +1 -1
- package/lib/agent/interactive/settings.js +106 -16
- package/lib/agent/interactive/settings.js.map +1 -1
- package/lib/agent/interactive/themes.d.ts +13 -0
- package/lib/agent/interactive/themes.d.ts.map +1 -0
- package/lib/agent/interactive/themes.js +36 -0
- package/lib/agent/interactive/themes.js.map +1 -0
- package/lib/agent/startup-maintenance.d.ts +7 -4
- package/lib/agent/startup-maintenance.d.ts.map +1 -1
- package/lib/agent/startup-maintenance.js +13 -29
- package/lib/agent/startup-maintenance.js.map +1 -1
- package/lib/agent/system-prompt.d.ts.map +1 -1
- package/lib/agent/system-prompt.js +19 -7
- package/lib/agent/system-prompt.js.map +1 -1
- package/lib/agent/themes/bkper-dark.json +80 -0
- package/lib/agent/themes/bkper-light.json +80 -0
- package/lib/cli.js +6 -2
- package/lib/cli.js.map +1 -1
- package/lib/commands/agent-command.d.ts.map +1 -1
- package/lib/commands/agent-command.js +2 -1
- package/lib/commands/agent-command.js.map +1 -1
- package/lib/commands/upgrade.d.ts.map +1 -1
- package/lib/commands/upgrade.js +2 -3
- package/lib/commands/upgrade.js.map +1 -1
- package/lib/docs/ai/decision-models.md +316 -0
- package/lib/docs/apps/ai.md +120 -88
- package/lib/docs/apps/event-handlers.md +12 -0
- package/lib/docs/apps/overview.md +1 -1
- package/lib/docs/cli/app-management.md +1 -0
- package/lib/docs/index.md +2 -1
- package/lib/docs/sdk/bkper-api-types.md +4 -2
- package/lib/docs/sdk/bkper-js.md +1 -0
- package/lib/upgrade/index.d.ts +5 -4
- package/lib/upgrade/index.d.ts.map +1 -1
- package/lib/upgrade/index.js +3 -2
- package/lib/upgrade/index.js.map +1 -1
- package/lib/upgrade/installation.d.ts +54 -20
- package/lib/upgrade/installation.d.ts.map +1 -1
- package/lib/upgrade/installation.js +222 -122
- package/lib/upgrade/installation.js.map +1 -1
- package/lib/upgrade/update-check.d.ts +69 -0
- package/lib/upgrade/update-check.d.ts.map +1 -0
- package/lib/upgrade/update-check.js +253 -0
- package/lib/upgrade/update-check.js.map +1 -0
- package/lib/upgrade/update-worker.d.ts +2 -0
- package/lib/upgrade/update-worker.d.ts.map +1 -0
- package/lib/upgrade/update-worker.js +6 -0
- package/lib/upgrade/update-worker.js.map +1 -0
- package/lib/upgrade/upgrade.d.ts +11 -28
- package/lib/upgrade/upgrade.d.ts.map +1 -1
- package/lib/upgrade/upgrade.js +49 -96
- package/lib/upgrade/upgrade.js.map +1 -1
- package/package.json +6 -4
package/lib/docs/apps/ai.md
CHANGED
|
@@ -1,123 +1,155 @@
|
|
|
1
1
|
# Add Bkper AI to an App
|
|
2
2
|
|
|
3
|
-
Bkper Platform apps can call [Bkper AI](https://bkper.com/docs/ai/ai-gateway.md) without storing a model-provider key. The platform authorizes
|
|
3
|
+
Bkper Platform apps can call [Bkper AI](https://bkper.com/docs/ai/ai-gateway.md) without storing a model-provider key. The platform authorizes each request as the current user and attributes usage to the app. Scripts and servers outside the platform use the same code with their own Bkper token.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Model output is a suggestion, not permission to change a Book. Keep decisions about resource movements, and any resulting writes, in application code.
|
|
6
6
|
|
|
7
7
|
## Choose the kind of response
|
|
8
8
|
|
|
9
|
-
- **A
|
|
10
|
-
- **
|
|
9
|
+
- **A yes/no, a choice, or a level on a scale?** Ask a decision model, such as `jev`, with TypeSafe's SDK, `@typesafe-ai/sdk`.
|
|
10
|
+
- **Text or a custom JSON object?** Ask a language model (LLM), such as `gpt-luna`, with AI SDK's Open Responses provider, `@ai-sdk/open-responses`.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Add the SDK to the **Worker** package. Keep the call in a server service used by your authenticated app API route, and define the route's request and response in the app's Zod/OpenAPI contract.
|
|
13
13
|
|
|
14
14
|
## Keep authentication in the platform
|
|
15
15
|
|
|
16
16
|
For an interactive app, the flow is:
|
|
17
17
|
|
|
18
|
-
1. The client calls a typed app `/api/*` route through `auth.authenticatedFetch()`
|
|
18
|
+
1. The client calls a typed app `/api/*` route through `auth.authenticatedFetch()` or another authenticated client.
|
|
19
19
|
2. Bkper verifies the user's token, removes it before invoking the Worker, and establishes user and app context for outbound requests.
|
|
20
|
-
3. The Worker calls
|
|
20
|
+
3. The Worker calls Bkper AI. Platform outbound adds authorization and app attribution. **Do not read, forward, or store the user's token in the Worker.**
|
|
21
21
|
|
|
22
|
-
An authenticated `/events` handler has the same outbound context. A page request does not; start
|
|
22
|
+
An authenticated `/events` handler has the same outbound context. A page request does not; start inference from an authenticated `/api/*` route, not from the page handler or the browser.
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## Ask a decision model
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
```ts
|
|
27
|
+
import { score, TypeSafeClient } from '@typesafe-ai/sdk';
|
|
28
|
+
|
|
29
|
+
const decisionClient = new TypeSafeClient({
|
|
30
|
+
apiKey: 'bkper-platform-outbound',
|
|
31
|
+
baseURL: 'https://ai.bkper.app',
|
|
32
|
+
defaultModel: 'jev',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export async function scoreRecurring(description: string) {
|
|
36
|
+
const { answers } = await decisionClient.systemOne({
|
|
37
|
+
state: { description },
|
|
38
|
+
questions: {
|
|
39
|
+
recurring: score('How likely is this a recurring charge?', [
|
|
40
|
+
'Unlikely',
|
|
41
|
+
'Possible',
|
|
42
|
+
'Likely',
|
|
43
|
+
]),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
return answers.recurring;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- **`apiKey`** is required by the SDK. In a Platform Worker, pass any placeholder: platform outbound replaces it with the user's authorization.
|
|
51
|
+
- **`baseURL`** has no `/v1`. The SDK calls `POST /v1/systemone`, which behaves exactly like `POST /v1/decisions`.
|
|
52
|
+
- **The answer is typed** from the question. Bkper AI validates every answer against its question before responding, so your code can use it directly.
|
|
53
|
+
|
|
54
|
+
The Decision Models guide covers questions, state, answers, and thresholds. The open-source [Merge Duplicates app](https://github.com/bkper/bkper-apps/tree/main/merge-duplicates) uses this setup to suggest duplicate pairs for human review.
|
|
55
|
+
|
|
56
|
+
## Generate a language response
|
|
27
57
|
|
|
28
58
|
```ts
|
|
29
59
|
import { createOpenResponses } from '@ai-sdk/open-responses';
|
|
30
60
|
import { generateText, Output } from 'ai';
|
|
31
61
|
import { z } from 'zod';
|
|
32
62
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
): Promise<{ note: string }> {
|
|
40
|
-
const response = await fetcher(`${BASE_URL}/models`);
|
|
41
|
-
if (!response.ok) throw new Error(`Model discovery failed (${response.status}).`);
|
|
42
|
-
|
|
43
|
-
const catalog = z
|
|
44
|
-
.object({
|
|
45
|
-
default_model: z.string(),
|
|
46
|
-
data: z.array(
|
|
47
|
-
z.object({
|
|
48
|
-
id: z.string(),
|
|
49
|
-
type: z.string(),
|
|
50
|
-
structured_output: z
|
|
51
|
-
.object({
|
|
52
|
-
json_schema: z.boolean(),
|
|
53
|
-
strict: z.boolean(),
|
|
54
|
-
})
|
|
55
|
-
.optional(),
|
|
56
|
-
})
|
|
57
|
-
),
|
|
58
|
-
})
|
|
59
|
-
.parse(await response.json());
|
|
60
|
-
const model = catalog.data.find(item => item.id === catalog.default_model);
|
|
61
|
-
if (
|
|
62
|
-
model?.type !== 'language' ||
|
|
63
|
-
!model.structured_output?.json_schema ||
|
|
64
|
-
!model.structured_output.strict
|
|
65
|
-
) {
|
|
66
|
-
throw new Error('The default model does not support strict JSON output.');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const provider = createOpenResponses({
|
|
70
|
-
name: 'bkper-ai',
|
|
71
|
-
url: `${BASE_URL}/responses`,
|
|
72
|
-
fetch: fetcher,
|
|
73
|
-
});
|
|
63
|
+
const llmClient = createOpenResponses({
|
|
64
|
+
name: 'bkper-ai',
|
|
65
|
+
url: 'https://ai.bkper.app/v1/responses',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export async function draftReviewNote(description: string) {
|
|
74
69
|
const { output } = await generateText({
|
|
75
|
-
model:
|
|
76
|
-
system: 'Draft a short, neutral review note. Do not invent facts
|
|
70
|
+
model: llmClient('gpt-luna'),
|
|
71
|
+
system: 'Draft a short, neutral review note. Do not invent facts.',
|
|
77
72
|
prompt: description,
|
|
78
|
-
output: Output.object({ schema:
|
|
79
|
-
maxRetries: 0,
|
|
73
|
+
output: Output.object({ schema: z.object({ note: z.string() }) }),
|
|
80
74
|
});
|
|
81
|
-
return
|
|
75
|
+
return output;
|
|
82
76
|
}
|
|
83
77
|
```
|
|
84
78
|
|
|
85
|
-
**
|
|
79
|
+
- **No `apiKey`.** The provider then sends no `Authorization` header, and platform outbound adds it.
|
|
80
|
+
- **`url`** is the full `/v1/responses` URL.
|
|
81
|
+
- **`output`** is parsed and validated against your schema by AI SDK. The provider requests strict structured output, which every Bkper language model supports.
|
|
86
82
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
## Before using the result
|
|
83
|
+
Keep schemas simple. Constraints such as a string's minimum or maximum length may not be supported by every model's strict JSON Schema subset; check them in code after generation.
|
|
90
84
|
|
|
91
|
-
|
|
92
|
-
- If model discovery fails or output does not match the schema, fail safely. Avoid automatic retries on actions that may consume allowance.
|
|
93
|
-
- When the AI request fails, preserve the upstream HTTP status, error code, and message **when Bkper AI supplies them**, so users can understand failures such as an exhausted allowance. AI SDK exposes HTTP failures as `APICallError`; read the Bkper AI error envelope from `responseBody`, not from the SDK's generic message. For `NoObjectGeneratedError` or transport errors, return a safe app-defined error instead. Do not return prompts, raw responses, or stack traces to clients.
|
|
94
|
-
- Unit-test the server service with a mocked `fetch`: verify the model's type and capability, that no `Authorization` or attribution headers leave the Worker, that only necessary data is sent and `store: true` is never requested, that malformed output is rejected, and that errors remain actionable. Then run the app's normal check/build.
|
|
85
|
+
## Outside a Platform app
|
|
95
86
|
|
|
96
|
-
|
|
87
|
+
Scripts, servers, and tools send their own Bkper token. Pass it as `apiKey`: both SDKs send it as a bearer token. Get a client each time you need one, so every call uses a current token:
|
|
97
88
|
|
|
98
89
|
```ts
|
|
99
|
-
import {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
90
|
+
import { createOpenResponses } from '@ai-sdk/open-responses';
|
|
91
|
+
import { noul, TypeSafeClient } from '@typesafe-ai/sdk';
|
|
92
|
+
import { generateText } from 'ai';
|
|
93
|
+
import { getOAuthToken } from 'bkper';
|
|
94
|
+
|
|
95
|
+
const decisionClient = async () =>
|
|
96
|
+
new TypeSafeClient({
|
|
97
|
+
apiKey: await getOAuthToken(),
|
|
98
|
+
baseURL: 'https://ai.bkper.app',
|
|
99
|
+
defaultModel: 'jev',
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const llmClient = async () =>
|
|
103
|
+
createOpenResponses({
|
|
104
|
+
name: 'bkper-ai',
|
|
105
|
+
url: 'https://ai.bkper.app/v1/responses',
|
|
106
|
+
apiKey: await getOAuthToken(),
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const client = await decisionClient();
|
|
110
|
+
const { answers } = await client.systemOne({
|
|
111
|
+
state: { description: 'NETFLIX.COM monthly plan' },
|
|
112
|
+
questions: { streaming: noul('Is this a streaming service?') },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const { text } = await generateText({
|
|
116
|
+
model: (await llmClient())('gpt-luna'),
|
|
117
|
+
prompt: 'Describe NETFLIX.COM monthly plan in five words.',
|
|
118
|
+
});
|
|
121
119
|
```
|
|
122
120
|
|
|
123
|
-
|
|
121
|
+
- **`getOAuthToken()`** reads the credentials from `bkper auth login` and refreshes them when needed. In your own server, use your own token provider.
|
|
122
|
+
- **Creating a client is cheap.** Neither SDK makes a request until you ask a question.
|
|
123
|
+
- **Label your usage** with a `bkper-ai-source` header, such as `my-script`: `defaultHeaders` in the TypeSafe SDK, `headers` in Open Responses. In a Platform app, outbound sets the source to the app.
|
|
124
|
+
|
|
125
|
+
## Handle errors
|
|
126
|
+
|
|
127
|
+
Every Bkper AI error has the same envelope: `{ error: { message, type, param, code } }`. Branch on `error.code`, not only on the HTTP status: a `429` can mean an exhausted allowance or a throttled provider.
|
|
128
|
+
|
|
129
|
+
- **TypeSafe SDK:** an `APIError` with `status` and the envelope in `body`, so read `error.body.error.code`. Network failures and timeouts throw `APIConnectionError`.
|
|
130
|
+
- **AI SDK:** an `APICallError` with `statusCode` and the envelope in `data`, so read `error.data.error.code`. Output that does not match your schema throws `NoObjectGeneratedError`.
|
|
131
|
+
|
|
132
|
+
Both SDKs retry rate limits and server errors twice by default. A failed attempt costs nothing: Bkper AI charges only successful answers.
|
|
133
|
+
|
|
134
|
+
Map these errors to your route's typed error response. Keep the code and message so users understand failures such as an exhausted allowance, but never return prompts, raw responses, or stack traces.
|
|
135
|
+
|
|
136
|
+
## SDK notes
|
|
137
|
+
|
|
138
|
+
- **Passing your own `fetch`.** The TypeSafe SDK calls `fetch` as its own method, which the Workers runtime rejects with `Illegal invocation`. Wrap it: `fetch: (input, init) => myFetch(input, init)`. Without the option, the SDK's default works.
|
|
139
|
+
- **No `null` values.** The TypeSafe SDK's types accept `null` for state, instructions, and some criteria. Bkper AI rejects them with `400`.
|
|
140
|
+
- **No `client.models.list()`.** It expects TypeSafe's catalog shape. Use the [`GET /v1/models`](https://ai.bkper.app/v1/models) catalog.
|
|
141
|
+
- **Other System One clients** take `https://ai.bkper.app/v1` as their base URL.
|
|
142
|
+
- **Flexible JSON schemas.** Open Responses always requests `strict: true`. For a schema that needs `strict: false`, such as a typed dynamic map, use `@ai-sdk/openai` with base URL `https://ai.bkper.app/v1`, its `.responses()` model, and `strictJsonSchema: false`.
|
|
143
|
+
|
|
144
|
+
## Before using the result
|
|
145
|
+
|
|
146
|
+
- **Send only task-relevant data.** Validate input and Book permissions at the app API boundary.
|
|
147
|
+
- **Keep writes deterministic.** An answer or generated text must not create, merge, or alter a Transaction without application rules and any required human confirmation.
|
|
148
|
+
- **Test the service.** Mock `fetch` and check what is sent, that the Worker adds no user token, and that errors stay actionable. Then run the app's normal check and build.
|
|
149
|
+
|
|
150
|
+
## Next steps
|
|
151
|
+
|
|
152
|
+
- [Decision Models](https://bkper.com/docs/ai/decision-models.md): questions, answers, thresholds, and caching.
|
|
153
|
+
- [Bkper AI Gateway](https://bkper.com/docs/ai/ai-gateway.md): tokens, raw HTTP requests, errors, and privacy.
|
|
154
|
+
- [Models and Usage](https://bkper.com/docs/ai/models.md): model IDs, capabilities, and usage rates.
|
|
155
|
+
- [Bkper AI API reference](https://bkper.com/docs/api/ai.md): every request and response field.
|
|
@@ -244,5 +244,17 @@ The complete API set of event types is listed below. `COMMENT_CREATED` and `COMM
|
|
|
244
244
|
| `INTEGRATION_DELETED` | An integration was deleted. |
|
|
245
245
|
| `BOOK_CREATED` | A book was created. |
|
|
246
246
|
| `BOOK_AUDITED` | A balances audit completed for the book. |
|
|
247
|
+
| `BOOK_OVERNIGHT` | Daily scheduled event for the book, delivered at or after 01:00 in the book's time zone. |
|
|
247
248
|
| `BOOK_UPDATED` | Book settings were updated. |
|
|
248
249
|
| `BOOK_DELETED` | The book was deleted. |
|
|
250
|
+
|
|
251
|
+
### Scheduled work with `BOOK_OVERNIGHT`
|
|
252
|
+
|
|
253
|
+
`BOOK_OVERNIGHT` lets your app run daily work on a book without waiting for a user action — for example, end-of-day recalculations, fetching external data, or consistency checks.
|
|
254
|
+
|
|
255
|
+
- **When:** once per day, at or after 01:00 in the book's time zone (UTC if the book has no time zone). Delivery may be up to about an hour later.
|
|
256
|
+
- **Which books:** only books where an installed app subscribes to `BOOK_OVERNIGHT`. Books without such an app receive nothing.
|
|
257
|
+
- **What day:** each event represents the local day that just ended. A book gets at most one `BOOK_OVERNIGHT` event per local day.
|
|
258
|
+
- **Idempotency:** the event `id` is stable for the book and day, so use it to skip repeated deliveries.
|
|
259
|
+
- **User:** the event `user` is the book owner. Your handler still runs on behalf of the user who installed the app.
|
|
260
|
+
- **Development webhook:** `webhookUrlDev` is used when the user who installed the app is its owner or one of its developers.
|
|
@@ -20,7 +20,7 @@ The same Worker can expose app-defined `/api/*` routes. Treat those routes as th
|
|
|
20
20
|
|
|
21
21
|
When an app needs model inference, use Bkper AI by default. An authenticated app API route or event establishes the user and app identity, then platform outbound supplies authorization and usage attribution for the Worker's Bkper AI requests. The app does not need provider credentials.
|
|
22
22
|
|
|
23
|
-
See [Add Bkper AI to an App](https://bkper.com/docs/platform/apps/ai.md) for
|
|
23
|
+
See [Add Bkper AI to an App](https://bkper.com/docs/platform/apps/ai.md) for the client-to-Worker authentication flow and SDK setup for decision and language models.
|
|
24
24
|
|
|
25
25
|
### Authentication
|
|
26
26
|
|
|
@@ -459,6 +459,7 @@ events:
|
|
|
459
459
|
- BOOK_UPDATED
|
|
460
460
|
- BOOK_DELETED
|
|
461
461
|
- BOOK_AUDITED
|
|
462
|
+
- BOOK_OVERNIGHT # Daily per-Book event, at or after 01:00 in the Book's time zone
|
|
462
463
|
|
|
463
464
|
# -----------------------------------------------------------------------------
|
|
464
465
|
# FILE PATTERNS (optional)
|
package/lib/docs/index.md
CHANGED
|
@@ -10,7 +10,8 @@ For Bkper app implementation, refactoring, or code review, always read `apps/qua
|
|
|
10
10
|
- `cli/data-management.md` — CLI reference for managing financial data and files: books, accounts, groups, files, transactions, per-account balance queries, query operators (on:, after:, before:, account:, group:), JSON output shapes and jq reshaping, human-review Bkper UI links, batch operations via stdin/piping, collections.
|
|
11
11
|
- `cli/app-management.md` — CLI reference for building and deploying Bkper apps: init/git clone/credential helpers, dev/build/deploy workflow, app install/uninstall, secrets management, app logs, bkper.yaml configuration reference (identity, branding, events, menu integration, deployment).
|
|
12
12
|
- `apps/overview.md` — Platform evaluation and capability overview: use when comparing managed Bkper hosting with self-managed infrastructure or clarifying platform responsibilities; use the task-specific app references for implementation.
|
|
13
|
-
- `apps/ai.md` — Bkper AI in
|
|
13
|
+
- `apps/ai.md` — Bkper AI in apps, scripts, and tools: ask the Jev decision model with TypeSafe's SDK or language models with AI SDK Open Responses, authenticate through app `/api/*` routes or a Bkper token outside the platform, handle errors, and keep Book writes under deterministic application control.
|
|
14
|
+
- `ai/decision-models.md` — Automating recurring judgments in code, such as categorizing bank lines, matching duplicates, or flagging entries, with Bkper AI decision models: writing questions and state, reading calibrated answers, and acting only above thresholds while routing uncertain cases to a person.
|
|
14
15
|
- `apps/first-app.md` — First-app walkthrough: scaffold, install, run locally, trigger an event, customize the listing, establish shared source, check, and deploy.
|
|
15
16
|
- `apps/architecture.md` — App and template architecture: npm workspace structure, Lit/Vite client, Hono Worker, typed `/api/*` contracts, authentication, `/events`, static assets, and supported app shapes.
|
|
16
17
|
- `apps/quality.md` — Cross-cutting quality guidance for Bkper apps: UI consistency, immediate first rendering, typed API contracts, cohesive low-coupling modules, separation of business behavior from connectors and storage, security, and final implementation review. Load for app implementation, refactoring, or review tasks.
|
|
@@ -89,7 +89,7 @@ More information at the [Bkper Developer Documentation](https://bkper.com/docs/#
|
|
|
89
89
|
- `deprecated?`: `boolean` — Whether the app is deprecated
|
|
90
90
|
- `description?`: `string` — The App description
|
|
91
91
|
- `developers?`: `string` — The developers (usernames and domain patterns), comma or space separated
|
|
92
|
-
- `events?`: `("FILE_CREATED" | "FILE_UPDATED" | "FILE_DELETED" | "TRANSACTION_CREATED" | "TRANSACTION_UPDATED" | "TRANSACTION_DELETED" | "TRANSACTION_POSTED" | "TRANSACTION_CHECKED" | "TRANSACTION_UNCHECKED" | "TRANSACTION_RESTORED" | "ACCOUNT_CREATED" | "ACCOUNT_UPDATED" | "ACCOUNT_DELETED" | "QUERY_CREATED" | "QUERY_UPDATED" | "QUERY_DELETED" | "GROUP_CREATED" | "GROUP_UPDATED" | "GROUP_DELETED" | "COMMENT_CREATED" | "COMMENT_DELETED" | "COLLABORATOR_ADDED" | "COLLABORATOR_UPDATED" | "COLLABORATOR_REMOVED" | "INTEGRATION_CREATED" | "INTEGRATION_UPDATED" | "INTEGRATION_DELETED" | "BOOK_CREATED" | "BOOK_AUDITED" | "BOOK_UPDATED" | "BOOK_DELETED")[]` — Event types the App listen to
|
|
92
|
+
- `events?`: `("FILE_CREATED" | "FILE_UPDATED" | "FILE_DELETED" | "TRANSACTION_CREATED" | "TRANSACTION_UPDATED" | "TRANSACTION_DELETED" | "TRANSACTION_POSTED" | "TRANSACTION_CHECKED" | "TRANSACTION_UNCHECKED" | "TRANSACTION_RESTORED" | "ACCOUNT_CREATED" | "ACCOUNT_UPDATED" | "ACCOUNT_DELETED" | "QUERY_CREATED" | "QUERY_UPDATED" | "QUERY_DELETED" | "GROUP_CREATED" | "GROUP_UPDATED" | "GROUP_DELETED" | "COMMENT_CREATED" | "COMMENT_DELETED" | "COLLABORATOR_ADDED" | "COLLABORATOR_UPDATED" | "COLLABORATOR_REMOVED" | "INTEGRATION_CREATED" | "INTEGRATION_UPDATED" | "INTEGRATION_DELETED" | "BOOK_CREATED" | "BOOK_AUDITED" | "BOOK_OVERNIGHT" | "BOOK_UPDATED" | "BOOK_DELETED")[]` — Event types the App listen to
|
|
93
93
|
- `filePatterns?`: `string[]` — File patterns the App handles - wildcard accepted. E.g. *.pdf, *-bank.csv
|
|
94
94
|
- `id?`: `string` — The unique agent id of the App - this can't be changed after created
|
|
95
95
|
- `installable?`: `boolean` — Whether this app is installable in a book
|
|
@@ -331,7 +331,7 @@ More information at the [Bkper Developer Documentation](https://bkper.com/docs/#
|
|
|
331
331
|
- `data?`: `bkper.EventData`
|
|
332
332
|
- `id?`: `string` — The unique id that identifies the Event
|
|
333
333
|
- `resource?`: `string` — The resource associated to the Event
|
|
334
|
-
- `type?`: `"FILE_CREATED" | "FILE_UPDATED" | "FILE_DELETED" | "TRANSACTION_CREATED" | "TRANSACTION_UPDATED" | "TRANSACTION_DELETED" | "TRANSACTION_POSTED" | "TRANSACTION_CHECKED" | "TRANSACTION_UNCHECKED" | "TRANSACTION_RESTORED" | "ACCOUNT_CREATED" | "ACCOUNT_UPDATED" | "ACCOUNT_DELETED" | "QUERY_CREATED" | "QUERY_UPDATED" | "QUERY_DELETED" | "GROUP_CREATED" | "GROUP_UPDATED" | "GROUP_DELETED" | "COMMENT_CREATED" | "COMMENT_DELETED" | "COLLABORATOR_ADDED" | "COLLABORATOR_UPDATED" | "COLLABORATOR_REMOVED" | "INTEGRATION_CREATED" | "INTEGRATION_UPDATED" | "INTEGRATION_DELETED" | "BOOK_CREATED" | "BOOK_AUDITED" | "BOOK_UPDATED" | "BOOK_DELETED"` — The type of the Event
|
|
334
|
+
- `type?`: `"FILE_CREATED" | "FILE_UPDATED" | "FILE_DELETED" | "TRANSACTION_CREATED" | "TRANSACTION_UPDATED" | "TRANSACTION_DELETED" | "TRANSACTION_POSTED" | "TRANSACTION_CHECKED" | "TRANSACTION_UNCHECKED" | "TRANSACTION_RESTORED" | "ACCOUNT_CREATED" | "ACCOUNT_UPDATED" | "ACCOUNT_DELETED" | "QUERY_CREATED" | "QUERY_UPDATED" | "QUERY_DELETED" | "GROUP_CREATED" | "GROUP_UPDATED" | "GROUP_DELETED" | "COMMENT_CREATED" | "COMMENT_DELETED" | "COLLABORATOR_ADDED" | "COLLABORATOR_UPDATED" | "COLLABORATOR_REMOVED" | "INTEGRATION_CREATED" | "INTEGRATION_UPDATED" | "INTEGRATION_DELETED" | "BOOK_CREATED" | "BOOK_AUDITED" | "BOOK_OVERNIGHT" | "BOOK_UPDATED" | "BOOK_DELETED"` — The type of the Event
|
|
335
335
|
- `user?`: `bkper.User`
|
|
336
336
|
|
|
337
337
|
### EventData
|
|
@@ -547,6 +547,8 @@ More information at the [Bkper Developer Documentation](https://bkper.com/docs/#
|
|
|
547
547
|
- `id?`: `string` — The user unique id
|
|
548
548
|
- `name?`: `string` — The user display name
|
|
549
549
|
- `plan?`: `string` — The user plan
|
|
550
|
+
- `planAmount?`: `number` — The confirmed recurring plan total in currency minor units
|
|
551
|
+
- `planCurrency?`: `string` — The confirmed recurring plan currency
|
|
550
552
|
- `planCycle?`: `"MONTHLY" | "YEARLY"` — The user plan billing cycle
|
|
551
553
|
- `planOverdue?`: `boolean` — True if subscription payment is overdue
|
|
552
554
|
- `startedTrial?`: `boolean` — True if user started trial
|
package/lib/docs/sdk/bkper-js.md
CHANGED
|
@@ -1403,6 +1403,7 @@ Enum that represents event types.
|
|
|
1403
1403
|
- `BOOK_AUDITED`
|
|
1404
1404
|
- `BOOK_CREATED`
|
|
1405
1405
|
- `BOOK_DELETED`
|
|
1406
|
+
- `BOOK_OVERNIGHT` — Daily per-Book event for Apps subscribed to it, delivered at or after 01:00 in the Book's time zone.
|
|
1406
1407
|
- `BOOK_UPDATED`
|
|
1407
1408
|
- `COLLABORATOR_ADDED`
|
|
1408
1409
|
- `COLLABORATOR_REMOVED`
|
package/lib/upgrade/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export
|
|
4
|
-
export type {
|
|
1
|
+
export { PACKAGE_DIR, VERSION, detectInstallMethod, fetchLatestVersion, getInstallCommand, getSelfUpdatePlan, } from './installation.js';
|
|
2
|
+
export { foregroundUpgrade, isNewerVersion, runUpgrade } from './upgrade.js';
|
|
3
|
+
export { formatUpdateNotice, getUpdateNotice, isUpdateCheckDisabled, maybeStartUpdateCheck, readUpdateState, runCommandUpdateCheck, } from './update-check.js';
|
|
4
|
+
export type { InstallMethod, SelfUpdatePlan } from './installation.js';
|
|
5
|
+
export type { UpdateNotice } from './update-check.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,EACP,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACH,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/lib/upgrade/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { PACKAGE_DIR, VERSION, detectInstallMethod, fetchLatestVersion, getInstallCommand, getSelfUpdatePlan, } from './installation.js';
|
|
2
|
+
export { foregroundUpgrade, isNewerVersion, runUpgrade } from './upgrade.js';
|
|
3
|
+
export { formatUpdateNotice, getUpdateNotice, isUpdateCheckDisabled, maybeStartUpdateCheck, readUpdateState, runCommandUpdateCheck, } from './update-check.js';
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/lib/upgrade/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/upgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,EACP,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/upgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACH,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACxB,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,38 +1,72 @@
|
|
|
1
1
|
/** Current installed version of the CLI. */
|
|
2
2
|
export declare const VERSION: string;
|
|
3
|
+
/** Directory of the running bkper package (the folder holding its package.json). */
|
|
4
|
+
export declare const PACKAGE_DIR: string;
|
|
3
5
|
/** Supported installation methods. */
|
|
4
|
-
export type InstallMethod = 'npm' | '
|
|
5
|
-
|
|
6
|
-
export
|
|
6
|
+
export type InstallMethod = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown';
|
|
7
|
+
/** Where the running CLI lives and how it was started. */
|
|
8
|
+
export interface RuntimeLocation {
|
|
9
|
+
packageDir: string;
|
|
10
|
+
/** process.argv[1], not symlink-resolved. */
|
|
11
|
+
entrypoint?: string;
|
|
12
|
+
execPath: string;
|
|
13
|
+
isBunRuntime: boolean;
|
|
14
|
+
platform: NodeJS.Platform;
|
|
15
|
+
}
|
|
16
|
+
/** Side effects needed to decide whether the running copy can upgrade itself. */
|
|
17
|
+
export interface SelfUpdateEnvironment {
|
|
18
|
+
homedir: string;
|
|
19
|
+
readCommandOutput: (command: string) => string | undefined;
|
|
20
|
+
isWritable: (dir: string) => boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface InstallPlan {
|
|
23
|
+
kind: 'install';
|
|
24
|
+
method: InstallMethod;
|
|
25
|
+
packageDir: string;
|
|
26
|
+
command: string;
|
|
27
|
+
/** package.json to read after installing, reached through the global root. */
|
|
28
|
+
packageJsonPath: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ManualPlan {
|
|
31
|
+
kind: 'manual';
|
|
32
|
+
method: InstallMethod;
|
|
33
|
+
packageDir: string;
|
|
34
|
+
instruction: string;
|
|
35
|
+
}
|
|
36
|
+
export type SelfUpdatePlan = InstallPlan | ManualPlan;
|
|
37
|
+
export declare function getRuntimeLocation(): RuntimeLocation;
|
|
7
38
|
/**
|
|
8
|
-
* Detects
|
|
9
|
-
*
|
|
39
|
+
* Detects the package manager from the location of the running code
|
|
40
|
+
* (same rules as Pi's detectInstallMethod).
|
|
10
41
|
*/
|
|
11
|
-
export declare function
|
|
42
|
+
export declare function detectInstallMethod(location?: RuntimeLocation): InstallMethod;
|
|
12
43
|
/**
|
|
13
|
-
*
|
|
44
|
+
* Infers the npm prefix from a `<prefix>/lib/node_modules/bkper` layout.
|
|
45
|
+
* Windows prefixes look like project installs, so they are never inferred.
|
|
14
46
|
*/
|
|
15
|
-
export declare function
|
|
47
|
+
export declare function inferNpmPrefix(packageDir: string, platform: NodeJS.Platform): string | undefined;
|
|
16
48
|
/**
|
|
17
|
-
*
|
|
49
|
+
* Returns the shell command that installs a version with a package manager.
|
|
18
50
|
*/
|
|
19
|
-
export declare function
|
|
51
|
+
export declare function getInstallCommand(method: InstallMethod, version: string, npmPrefix?: string): string | null;
|
|
20
52
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
53
|
+
* Decides whether the running copy can safely upgrade itself: it must be
|
|
54
|
+
* inside its package manager's global root and writable. Otherwise returns
|
|
55
|
+
* the manual instruction to show. Never suggests sudo.
|
|
23
56
|
*/
|
|
24
|
-
export declare function
|
|
57
|
+
export declare function getSelfUpdatePlan(version: string, location?: RuntimeLocation, environment?: SelfUpdateEnvironment): SelfUpdatePlan;
|
|
25
58
|
/**
|
|
26
|
-
*
|
|
59
|
+
* Reads a package version from disk, bypassing the module cache.
|
|
27
60
|
*/
|
|
28
|
-
export declare function
|
|
61
|
+
export declare function readInstalledVersion(packageJsonPath: string): string | undefined;
|
|
29
62
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
63
|
+
* Runs an install command synchronously. BKPER_AUTOUPDATE_COMMAND replaces
|
|
64
|
+
* the command (for tests) but never the safety checks that lead here.
|
|
32
65
|
*/
|
|
33
|
-
export declare function
|
|
66
|
+
export declare function runInstallCommand(command: string): void;
|
|
34
67
|
/**
|
|
35
|
-
*
|
|
68
|
+
* Fetches the latest published version from the npm registry.
|
|
69
|
+
* Returns null if the fetch fails.
|
|
36
70
|
*/
|
|
37
|
-
export declare function
|
|
71
|
+
export declare function fetchLatestVersion(timeoutMs?: number): Promise<string | null>;
|
|
38
72
|
//# sourceMappingURL=installation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../src/upgrade/installation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../src/upgrade/installation.ts"],"names":[],"mappings":"AAUA,4CAA4C;AAC5C,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC;AAK3C,oFAAoF;AACpF,eAAO,MAAM,WAAW,EAAE,MAGzB,CAAC;AAEF,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAExE,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC7B;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC;AAEtD,wBAAgB,kBAAkB,IAAI,eAAe,CAQpD;AAiCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,eAAsC,GAAG,aAAa,CAkBnG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,GAAG,SAAS,CAWhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,IAAI,CAgBf;AA+FD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,eAAsC,EAChD,WAAW,GAAE,qBAAyD,GACvE,cAAc,CA6ChB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOhF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGvD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBjF"}
|