bkper 4.27.0 → 4.29.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 +25 -31
- package/lib/agent/extensions/builtins.d.ts +1 -0
- package/lib/agent/extensions/builtins.d.ts.map +1 -1
- package/lib/agent/extensions/builtins.js.map +1 -1
- package/lib/agent/extensions/handoff-goal-editor.d.ts +38 -0
- package/lib/agent/extensions/handoff-goal-editor.d.ts.map +1 -0
- package/lib/agent/extensions/handoff-goal-editor.js +149 -0
- package/lib/agent/extensions/handoff-goal-editor.js.map +1 -0
- package/lib/agent/extensions/handoff.d.ts.map +1 -1
- package/lib/agent/extensions/handoff.js +2 -1
- package/lib/agent/extensions/handoff.js.map +1 -1
- package/lib/agent/extensions/startup.d.ts +3 -1
- package/lib/agent/extensions/startup.d.ts.map +1 -1
- package/lib/agent/extensions/startup.js +21 -7
- package/lib/agent/extensions/startup.js.map +1 -1
- package/lib/agent/interactive/interactive-mode.d.ts.map +1 -1
- package/lib/agent/interactive/interactive-mode.js +18 -2
- package/lib/agent/interactive/interactive-mode.js.map +1 -1
- package/lib/agent/interactive/prompt-history-search.d.ts +26 -0
- package/lib/agent/interactive/prompt-history-search.d.ts.map +1 -0
- package/lib/agent/interactive/prompt-history-search.js +139 -0
- package/lib/agent/interactive/prompt-history-search.js.map +1 -0
- package/lib/agent/interactive/prompt-history-store.d.ts +38 -0
- package/lib/agent/interactive/prompt-history-store.d.ts.map +1 -0
- package/lib/agent/interactive/prompt-history-store.js +156 -0
- package/lib/agent/interactive/prompt-history-store.js.map +1 -0
- package/lib/agent/interactive/run-agent-mode.d.ts.map +1 -1
- package/lib/agent/interactive/run-agent-mode.js +7 -2
- package/lib/agent/interactive/run-agent-mode.js.map +1 -1
- package/lib/agent/interactive/session-keybindings.d.ts +1 -1
- package/lib/agent/interactive/session-keybindings.d.ts.map +1 -1
- package/lib/agent/interactive/session-keybindings.js +10 -1
- package/lib/agent/interactive/session-keybindings.js.map +1 -1
- package/lib/agent/interactive/settings.d.ts +18 -1
- package/lib/agent/interactive/settings.d.ts.map +1 -1
- package/lib/agent/interactive/settings.js +50 -0
- package/lib/agent/interactive/settings.js.map +1 -1
- package/lib/agent/system-prompt.d.ts +1 -1
- package/lib/agent/system-prompt.d.ts.map +1 -1
- package/lib/agent/system-prompt.js +24 -10
- package/lib/agent/system-prompt.js.map +1 -1
- package/lib/docs/apps/app-listing.md +1 -0
- package/lib/docs/apps/architecture.md +42 -7
- package/lib/docs/apps/context-menu.md +2 -0
- package/lib/docs/apps/development.md +4 -4
- package/lib/docs/apps/event-handlers.md +1 -1
- package/lib/docs/apps/quality.md +86 -0
- package/lib/docs/apps/security.md +74 -0
- package/lib/docs/apps/self-hosted.md +1 -1
- package/lib/docs/cli/app-management.md +2 -0
- package/lib/docs/cli/data-management.md +9 -0
- package/lib/docs/index.md +4 -0
- package/lib/docs/sdk/bkper-js.md +2 -6
- package/package.json +14 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"AA6HA,wBAAgB,yBAAyB,CACrC,aAAa,GAAE,MAAM,EAAsC,GAC5D,MAAM,CAsDR;AA4BD,eAAO,MAAM,yBAAyB,QAKpC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createBashToolDefinition, createEditToolDefinition, createReadToolDefinition, createWriteToolDefinition, } from '@earendil-works/pi-coding-agent';
|
|
1
|
+
import { createBashToolDefinition, createEditToolDefinition, createPowerShellToolDefinition, createReadToolDefinition, createWriteToolDefinition, } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
@@ -58,16 +58,17 @@ function normalizePromptGuidelines(guidelines) {
|
|
|
58
58
|
}
|
|
59
59
|
return Array.from(unique);
|
|
60
60
|
}
|
|
61
|
-
function getCodingToolDefinitions() {
|
|
61
|
+
function getCodingToolDefinitions(selectedTools) {
|
|
62
62
|
return [
|
|
63
63
|
createReadToolDefinition(process.cwd()),
|
|
64
64
|
createBashToolDefinition(process.cwd()),
|
|
65
|
+
createPowerShellToolDefinition(process.cwd()),
|
|
65
66
|
createEditToolDefinition(process.cwd()),
|
|
66
67
|
createWriteToolDefinition(process.cwd()),
|
|
67
|
-
];
|
|
68
|
+
].filter(definition => selectedTools.includes(definition.name));
|
|
68
69
|
}
|
|
69
|
-
function buildToolPromptSection() {
|
|
70
|
-
const toolDefinitions = getCodingToolDefinitions();
|
|
70
|
+
function buildToolPromptSection(selectedTools) {
|
|
71
|
+
const toolDefinitions = getCodingToolDefinitions(selectedTools);
|
|
71
72
|
const toolLines = toolDefinitions
|
|
72
73
|
.flatMap(definition => {
|
|
73
74
|
const snippet = normalizePromptSnippet(definition.promptSnippet);
|
|
@@ -84,7 +85,12 @@ function buildToolPromptSection() {
|
|
|
84
85
|
seenGuidelines.add(normalized);
|
|
85
86
|
guidelineLines.push(`- ${normalized}`);
|
|
86
87
|
};
|
|
87
|
-
|
|
88
|
+
if (selectedTools.includes('powershell')) {
|
|
89
|
+
addGuideline('Use PowerShell for file operations like listing, searching, and finding files. Use it to run bkper CLI commands when relevant.');
|
|
90
|
+
}
|
|
91
|
+
else if (selectedTools.includes('bash')) {
|
|
92
|
+
addGuideline('Use bash for discovery and search like ls, rg, and find. Use it to run bkper CLI commands when relevant.');
|
|
93
|
+
}
|
|
88
94
|
for (const definition of toolDefinitions) {
|
|
89
95
|
for (const guideline of normalizePromptGuidelines(definition.promptGuidelines)) {
|
|
90
96
|
addGuideline(guideline);
|
|
@@ -94,14 +100,14 @@ function buildToolPromptSection() {
|
|
|
94
100
|
const toolsList = toolLines.length > 0 ? toolLines : '(none)';
|
|
95
101
|
return `Available tools:\n${toolsList}\n\nIn addition to the tools above, you may have access to other custom tools depending on the project.\n\nGuidelines:\n${guidelineLines.join('\n')}`;
|
|
96
102
|
}
|
|
97
|
-
export function getBkperAgentSystemPrompt() {
|
|
103
|
+
export function getBkperAgentSystemPrompt(selectedTools = ['read', 'bash', 'edit', 'write']) {
|
|
98
104
|
const coreConceptsPath = resolveReferenceDocPath('core/core-concepts.md');
|
|
99
105
|
const indexPath = resolveDocsIndexPath('index.md');
|
|
100
106
|
const referenceDocsDir = path.dirname(indexPath);
|
|
101
107
|
const piRoot = resolvePiPackageRoot();
|
|
102
108
|
const piDocsPath = path.resolve(piRoot, 'docs');
|
|
103
109
|
const piExamplesPath = path.resolve(piRoot, 'examples');
|
|
104
|
-
return `${
|
|
110
|
+
return `${buildBkperOperatingContext(selectedTools)}
|
|
105
111
|
## Required Reading
|
|
106
112
|
|
|
107
113
|
Bkper's accounting model is intentionally non-standard. Generic accounting knowledge — debit/credit, account categories, sign conventions — will lead you to wrong answers here.
|
|
@@ -149,7 +155,8 @@ ${piExamplesPath}
|
|
|
149
155
|
And follow the most relevant link to find the answer.
|
|
150
156
|
`;
|
|
151
157
|
}
|
|
152
|
-
|
|
158
|
+
function buildBkperOperatingContext(selectedTools) {
|
|
159
|
+
return `# Bkper Context
|
|
153
160
|
|
|
154
161
|
You are a Bkper team member.
|
|
155
162
|
|
|
@@ -157,7 +164,7 @@ Protect the zero-sum invariant above all else.
|
|
|
157
164
|
|
|
158
165
|
You help users by reading files, executing commands, editing code, and writing new files.
|
|
159
166
|
|
|
160
|
-
${buildToolPromptSection()}
|
|
167
|
+
${buildToolPromptSection(selectedTools)}
|
|
161
168
|
|
|
162
169
|
## IMPORTANT Operating Principles
|
|
163
170
|
|
|
@@ -172,4 +179,11 @@ ${buildToolPromptSection()}
|
|
|
172
179
|
- Model domain and flows before coding; represent business reality, not technical shortcuts.
|
|
173
180
|
- Prefer simplicity over cleverness; choose small, boring, maintainable solutions.
|
|
174
181
|
`;
|
|
182
|
+
}
|
|
183
|
+
export const BKPER_AGENT_SYSTEM_PROMPT = buildBkperOperatingContext([
|
|
184
|
+
'read',
|
|
185
|
+
'bash',
|
|
186
|
+
'edit',
|
|
187
|
+
'write',
|
|
188
|
+
]);
|
|
175
189
|
//# sourceMappingURL=system-prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,7 @@ To make your app available to all Bkper users, contact us at [support@bkper.com]
|
|
|
49
49
|
### What the review involves
|
|
50
50
|
|
|
51
51
|
- **Functionality check** — The app works correctly and handles errors gracefully
|
|
52
|
+
- **Quality review** — The implementation follows the [App Quality Guidelines](https://bkper.com/docs/build/apps/quality.md)
|
|
52
53
|
- **Security review** — Event handlers are idempotent and include loop prevention
|
|
53
54
|
- **Listing quality** — The app has a clear name, description, logo, and user-facing documentation
|
|
54
55
|
|
|
@@ -4,6 +4,8 @@ Bkper platform apps use one Worker bundle per app and environment. The same Work
|
|
|
4
4
|
|
|
5
5
|
Treat `/api/*` as the reusable surface for app behavior. The bundled web client is one consumer; scripts, external clients, and agents can call the same routes with bearer authentication.
|
|
6
6
|
|
|
7
|
+
Follow the [App Quality Guidelines](https://bkper.com/docs/build/apps/quality.md) when implementing, changing, or reviewing an app.
|
|
8
|
+
|
|
7
9
|
## Structure
|
|
8
10
|
|
|
9
11
|
```txt
|
|
@@ -14,7 +16,6 @@ my-app/
|
|
|
14
16
|
│ ├── vite.config.ts
|
|
15
17
|
│ └── src/
|
|
16
18
|
│ ├── api/
|
|
17
|
-
│ ├── app/
|
|
18
19
|
│ ├── auth/
|
|
19
20
|
│ ├── components/
|
|
20
21
|
│ └── services/
|
|
@@ -44,10 +45,14 @@ The client uses:
|
|
|
44
45
|
- [`@bkper/web-design`](https://www.npmjs.com/package/@bkper/web-design) for Bkper design tokens.
|
|
45
46
|
- [Vite](https://vitejs.dev/) for development and production builds, configured in `client/vite.config.ts`.
|
|
46
47
|
|
|
47
|
-
Client code has two data paths:
|
|
48
|
+
Client code has two data paths. Choose based on who owns the behavior:
|
|
49
|
+
|
|
50
|
+
- **Direct Bkper calls** use `bkper-js` for generic Bkper data needed only by the browser UI.
|
|
51
|
+
- **App API calls** use the generated typed client in `client/src/api/` with `auth.authenticatedFetch()` for app-owned behavior, especially when it needs server-only capabilities or more than one caller.
|
|
52
|
+
|
|
53
|
+
Keep app-owned behavior in one place. Do not implement the same behavior separately in the UI and the app API.
|
|
48
54
|
|
|
49
|
-
-
|
|
50
|
-
- **App API calls** use the generated typed client in `client/src/api/` with `auth.authenticatedFetch()`.
|
|
55
|
+
For stateful feature components, co-locate view, controller, and CSS files in one folder under `components/`. Simple presentational components can remain in one file.
|
|
51
56
|
|
|
52
57
|
### Client authentication
|
|
53
58
|
|
|
@@ -115,7 +120,7 @@ The default template publishes versioned routes under `/api/v1/*` and exposes th
|
|
|
115
120
|
| Business behavior | `server/src/services/` |
|
|
116
121
|
| Generated client types | `client/src/api/generated/types.d.ts` |
|
|
117
122
|
| Typed client wrapper | `client/src/api/app-api.ts` |
|
|
118
|
-
| Contract snapshot | `server/test/openapi.snapshot.json`
|
|
123
|
+
| Contract snapshot | `server/test/api/openapi.snapshot.json` |
|
|
119
124
|
|
|
120
125
|
When changing the API:
|
|
121
126
|
|
|
@@ -126,6 +131,30 @@ When changing the API:
|
|
|
126
131
|
|
|
127
132
|
Keep existing `/api/v1/*` contracts backward compatible. Additive fields and routes can remain in `v1`; breaking changes belong in a new namespace such as `/api/v2/*`.
|
|
128
133
|
|
|
134
|
+
### Reuse Bkper API types
|
|
135
|
+
|
|
136
|
+
When an app API returns payloads from the Bkper REST API, reference the canonical types from `@bkper/bkper-api-types` instead of recreating their fields in the app. The template's balances endpoint demonstrates this with `bkper.Book`:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
export const BookSchema = z
|
|
140
|
+
.custom<bkper.Book>(value => value !== undefined)
|
|
141
|
+
.openapi('Book', {
|
|
142
|
+
type: 'object',
|
|
143
|
+
additionalProperties: true,
|
|
144
|
+
'x-typescript-type': 'bkper.Book',
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The template's API generator recognizes `x-typescript-type`, imports `@bkper/bkper-api-types`, and emits the canonical reference in `client/src/api/generated/types.d.ts`:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
Book: bkper.Book;
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Both the server and client packages include `@bkper/bkper-api-types` for local typechecking. Run `npm run api` after adding or changing these schemas.
|
|
155
|
+
|
|
156
|
+
This bridge provides compile-time types but does not validate payload fields at runtime. Use it directly for trusted Bkper-owned responses. Request bodies, especially those used to create or modify Book resources, still require concrete Zod validation.
|
|
157
|
+
|
|
129
158
|
### URLs
|
|
130
159
|
|
|
131
160
|
```txt
|
|
@@ -145,7 +174,7 @@ TOKEN="$(bkper auth token)"
|
|
|
145
174
|
|
|
146
175
|
curl \
|
|
147
176
|
-H "Authorization: Bearer ${TOKEN}" \
|
|
148
|
-
"https://my-app.bkper.app/api/v1/
|
|
177
|
+
"https://my-app.bkper.app/api/v1/ping"
|
|
149
178
|
```
|
|
150
179
|
|
|
151
180
|
Replace `my-app` with the app id from `bkper.yaml`.
|
|
@@ -155,7 +184,7 @@ Replace `my-app` with the app id from `bkper.yaml`.
|
|
|
155
184
|
Deployed `/api/*` routes require a Bkper OAuth bearer token. The template client uses `authenticatedFetch()` so token attachment and refresh stay inside `@bkper/web-auth`:
|
|
156
185
|
|
|
157
186
|
```ts
|
|
158
|
-
const response = await auth.authenticatedFetch('/api/v1/
|
|
187
|
+
const response = await auth.authenticatedFetch('/api/v1/ping');
|
|
159
188
|
```
|
|
160
189
|
|
|
161
190
|
Dispatch validates the incoming bearer token and strips the `Authorization` header before the Worker runs. Server code should not read or forward the token.
|
|
@@ -171,6 +200,12 @@ const books = await bkper.getBooks();
|
|
|
171
200
|
|
|
172
201
|
Platform outbound authentication injects the validated user's OAuth token on Bkper API requests.
|
|
173
202
|
|
|
203
|
+
### Authorize app operations
|
|
204
|
+
|
|
205
|
+
Authentication identifies the Bkper user, but each app must authorize sensitive data and actions server-side. Client-side checks are not an authorization boundary.
|
|
206
|
+
|
|
207
|
+
See [App Security](https://bkper.com/docs/build/apps/security.md) for domain restrictions, Book permissions, and app installation checks.
|
|
208
|
+
|
|
174
209
|
## Event handlers
|
|
175
210
|
|
|
176
211
|
Platform event deliveries reach `/events` on the same Worker. Event adapters live in `server/src/events/`, while reusable business behavior belongs in `server/src/services/`.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Apps can add context menu items on the Transactions page **More** menu in your Books. This lets you open dynamically built URLs with reference to the current Book's context — the active query, selected account, date range, and more.
|
|
4
4
|
|
|
5
|
+
Embedded interfaces should follow the [App Quality Guidelines](https://bkper.com/docs/build/apps/quality.md) for visual consistency, startup behavior, and Book-context verification.
|
|
6
|
+
|
|
5
7
|
## How it works
|
|
6
8
|
|
|
7
9
|
Once you install an App with a menu configuration, a new menu item appears in your Book:
|
|
@@ -25,10 +25,10 @@ You can also run them independently: `npm run dev:client` for just the UI, or `n
|
|
|
25
25
|
| Client (Vite dev server) | `http://localhost:5173` |
|
|
26
26
|
| Server Worker (Miniflare) | `http://localhost:8787` |
|
|
27
27
|
| App API routes | `http://localhost:8787/api/*` |
|
|
28
|
-
| App OpenAPI spec | `http://localhost:
|
|
28
|
+
| App OpenAPI spec | `http://localhost:5173/openapi.json` |
|
|
29
29
|
| Events (via tunnel to the same Worker) | `https://<random>.trycloudflare.com/events` |
|
|
30
30
|
|
|
31
|
-
The Vite dev server proxies `/api` requests to `http://localhost:8787` through `client/vite.config.ts
|
|
31
|
+
The Vite dev server proxies `/api` and `/openapi.json` requests to `http://localhost:8787` through `client/vite.config.ts`, so the client and OpenAPI spec share the same local origin just as they do in production. The spec also remains available directly from the Worker at `http://localhost:8787/openapi.json`. The tunnel URL is automatically registered as `webhookUrlDev`, so development-mode events are routed to your local machine.
|
|
32
32
|
|
|
33
33
|
## Configuration flags
|
|
34
34
|
|
|
@@ -40,13 +40,13 @@ bkper app dev --sp 8787
|
|
|
40
40
|
|
|
41
41
|
## Client configuration
|
|
42
42
|
|
|
43
|
-
The client dev server is configured in `client/vite.config.ts`. This standard Vite configuration registers local auth middleware and proxies `/api` requests to the Worker.
|
|
43
|
+
The client dev server is configured in `client/vite.config.ts`. This standard Vite configuration registers local auth middleware and proxies `/api` and `/openapi.json` requests to the Worker.
|
|
44
44
|
|
|
45
45
|
### Local development authentication
|
|
46
46
|
|
|
47
47
|
During local development, the Vite dev server runs `createBkperAuthMiddleware()` from `bkper/dev`. It serves the local `/auth/refresh` endpoint used by `@bkper/web-auth`, obtaining OAuth tokens from your CLI credentials.
|
|
48
48
|
|
|
49
|
-
The separate Vite proxy configuration forwards `/api` requests to the Miniflare Worker.
|
|
49
|
+
The separate Vite proxy configuration forwards `/api` and `/openapi.json` requests to the Miniflare Worker.
|
|
50
50
|
|
|
51
51
|
Before starting development, run:
|
|
52
52
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Event Handlers
|
|
1
|
+
# Bkper Webhooks and Event Handlers
|
|
2
2
|
|
|
3
3
|
Event handlers are the code that reacts to events in your Bkper Books. When a transaction is checked, an account is created, or any other event occurs, your handler receives it and can take action — calculate taxes, sync data between books, post to external services, and more.
|
|
4
4
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# App Quality Guidelines
|
|
2
|
+
|
|
3
|
+
Use these guidelines when building, changing, or reviewing a Bkper app. They complement the detailed architecture, security, and feature documentation.
|
|
4
|
+
|
|
5
|
+
After implementation, review the changed code against these guidelines before considering the work complete. Automated checks support this review but do not replace it.
|
|
6
|
+
|
|
7
|
+
## Bkper behavior
|
|
8
|
+
|
|
9
|
+
Always:
|
|
10
|
+
|
|
11
|
+
- Model financial activity as balanced resource movements between Accounts.
|
|
12
|
+
- Keep calculations deterministic and cover financial behavior with focused unit tests.
|
|
13
|
+
- Use canonical Bkper SDK and API types instead of recreating Bkper data structures.
|
|
14
|
+
- Add meaning with properties before introducing new structural complexity.
|
|
15
|
+
|
|
16
|
+
## User interface
|
|
17
|
+
|
|
18
|
+
Always:
|
|
19
|
+
|
|
20
|
+
- Use Web Awesome as the primary component library.
|
|
21
|
+
- Style with Bkper design tokens instead of ad-hoc design constants.
|
|
22
|
+
- Support the active Bkper light or dark theme.
|
|
23
|
+
- Keep interactions accessible and provide clear loading, empty, and error states.
|
|
24
|
+
|
|
25
|
+
Apps opened from a Book context menu should feel like part of the Book. Keep their layout focused, make them work in the configured sidebar or expanded width, and preserve context when the Book URL changes.
|
|
26
|
+
|
|
27
|
+
## Startup
|
|
28
|
+
|
|
29
|
+
Always render the app shell or a meaningful loading state before waiting for authentication, API calls, or other initialization. Start asynchronous work after the first render and update the interface as results arrive.
|
|
30
|
+
|
|
31
|
+
Prefer loading only the client code and Web Awesome components needed for the initial experience.
|
|
32
|
+
|
|
33
|
+
## API contracts
|
|
34
|
+
|
|
35
|
+
When an app exposes its own HTTP API:
|
|
36
|
+
|
|
37
|
+
- Define and publish its OpenAPI contract at `/openapi.json`.
|
|
38
|
+
- Generate client types from that contract.
|
|
39
|
+
- Call the API through the generated typed boundary rather than duplicating request or response types.
|
|
40
|
+
- Validate untrusted request data at the server boundary.
|
|
41
|
+
- Keep published routes backward compatible or introduce a new API version for breaking changes.
|
|
42
|
+
|
|
43
|
+
UI-only and event-only apps without an app-owned HTTP API do not need to add one. Direct calls to Bkper should use the canonical Bkper SDK and API types.
|
|
44
|
+
|
|
45
|
+
## Focused modules
|
|
46
|
+
|
|
47
|
+
Prefer modules with one clear responsibility, high cohesion, and few dependencies.
|
|
48
|
+
|
|
49
|
+
- Components render state and communicate user intent. They should delegate API and Bkper operations to client API or service modules.
|
|
50
|
+
- HTTP routes and event handlers adapt transport concerns and delegate app behavior.
|
|
51
|
+
- Business modules contain domain decisions without depending on UI, HTTP, storage, or external-service details.
|
|
52
|
+
- Connectors isolate external APIs and storage concerns from business behavior.
|
|
53
|
+
- Add a repository or another layer when connection or storage complexity justifies it, not by default.
|
|
54
|
+
- Avoid layers that only forward calls without creating a useful boundary.
|
|
55
|
+
|
|
56
|
+
Split a module when unrelated behavior changes for different reasons or when mixed responsibilities make it difficult to understand or test.
|
|
57
|
+
|
|
58
|
+
## Security
|
|
59
|
+
|
|
60
|
+
Keep the security boundary simple and explicit:
|
|
61
|
+
|
|
62
|
+
- Authorize sensitive app operations on the server.
|
|
63
|
+
- Validate untrusted requests, events, and browser messages at their boundaries.
|
|
64
|
+
- Keep application secrets and privileged credentials out of client bundles.
|
|
65
|
+
- Access only the Book data needed for the operation.
|
|
66
|
+
- Make event handling safe to retry and prevent event loops.
|
|
67
|
+
|
|
68
|
+
See [App Security](https://bkper.com/docs/build/apps/security.md) and [Event Handlers](https://bkper.com/docs/build/apps/event-handlers.md) for implementation details.
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
|
|
72
|
+
After implementation:
|
|
73
|
+
|
|
74
|
+
1. Review the changed code against these guidelines.
|
|
75
|
+
2. Run the app's deterministic checks, including unit tests, typechecking, and production builds.
|
|
76
|
+
3. Confirm generated API types and contract snapshots are current when the API changed.
|
|
77
|
+
4. Verify user interfaces in their intended Book context, including first rendering, loading, errors, theme, and configured width.
|
|
78
|
+
|
|
79
|
+
App reviews should report concrete findings with file locations and suggested fixes. If no issues are found, a short confirmation is enough.
|
|
80
|
+
|
|
81
|
+
## Next Steps
|
|
82
|
+
|
|
83
|
+
- [App Architecture](https://bkper.com/docs/build/apps/architecture.md) — Client, server, API, and event structure.
|
|
84
|
+
- [App Security](https://bkper.com/docs/build/apps/security.md) — Authentication and authorization boundaries.
|
|
85
|
+
- [Context Menu](https://bkper.com/docs/build/apps/context-menu.md) — Embedded Book context and open modes.
|
|
86
|
+
- [Development Experience](https://bkper.com/docs/build/apps/development.md) — Local development and deterministic checks.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# App Security
|
|
2
|
+
|
|
3
|
+
Bkper and each platform app have separate security responsibilities. This guide explains the platform authentication boundary and common authorization checks an app must enforce.
|
|
4
|
+
|
|
5
|
+
## Authentication and authorization
|
|
6
|
+
|
|
7
|
+
Authentication identifies the Bkper user making a request. The platform handles this flow for deployed apps.
|
|
8
|
+
|
|
9
|
+
Authorization determines whether that user may perform a specific operation.
|
|
10
|
+
|
|
11
|
+
See [App Architecture](https://bkper.com/docs/build/apps/architecture.md) for the client and server authentication flow.
|
|
12
|
+
|
|
13
|
+
## Authorize app operations
|
|
14
|
+
|
|
15
|
+
Platform authentication identifies the Bkper user and provides outbound authentication for server-side Bkper requests. Your app must still decide which authenticated users may perform each operation. Protect sensitive data and actions in the server API; client-side checks may improve the UI, but they are not an authorization boundary.
|
|
16
|
+
|
|
17
|
+
### Restrict an internal app by user domain
|
|
18
|
+
|
|
19
|
+
For an app intended only for people in one organization, authorize the authenticated user's hosted domain:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const ALLOWED_DOMAIN = 'example.com';
|
|
23
|
+
|
|
24
|
+
const user = await context.bkper.getUser();
|
|
25
|
+
const domain = user.getHostedDomain()?.toLowerCase();
|
|
26
|
+
|
|
27
|
+
if (domain !== ALLOWED_DOMAIN) {
|
|
28
|
+
return c.json(buildApiError('FORBIDDEN', 'This app is restricted to your organization'), 403);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Authorize a Book-backed operation
|
|
33
|
+
|
|
34
|
+
When an operation acts on a Book, use an explicit permission allowlist appropriate to that operation. For an operation that requires edit access:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { Permission } from 'bkper-js';
|
|
38
|
+
|
|
39
|
+
const EDIT_PERMISSIONS: readonly Permission[] = [Permission.EDITOR, Permission.OWNER];
|
|
40
|
+
|
|
41
|
+
const book = await context.bkper.getBook(bookId);
|
|
42
|
+
|
|
43
|
+
if (!EDIT_PERMISSIONS.includes(book.getPermission())) {
|
|
44
|
+
return c.json(
|
|
45
|
+
buildApiError('FORBIDDEN', 'Editor or owner permission required for this operation'),
|
|
46
|
+
403
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Read, posting, and other operations may require different policies. Choose the minimum authorization appropriate to the behavior instead of treating every authenticated user as authorized.
|
|
52
|
+
|
|
53
|
+
### Require app installation
|
|
54
|
+
|
|
55
|
+
Having permission to access a Book does not mean the app is installed in that Book. If an app is only supposed to be used with Books where it is installed, verify installation:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const APP_ID = 'my-app';
|
|
59
|
+
|
|
60
|
+
const book = await context.bkper.getBook(bookId);
|
|
61
|
+
const installedApps = await book.getApps();
|
|
62
|
+
const isInstalled = installedApps.some(app => app.getId() === APP_ID);
|
|
63
|
+
|
|
64
|
+
if (!isInstalled) {
|
|
65
|
+
return c.json(buildApiError('FORBIDDEN', 'This app is not installed in this Book'), 403);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Next Steps
|
|
70
|
+
|
|
71
|
+
- [App Quality Guidelines](https://bkper.com/docs/build/apps/quality.md) — Review cross-cutting app quality and security expectations.
|
|
72
|
+
- [App Architecture](https://bkper.com/docs/build/apps/architecture.md) — Understand client and server authentication flows.
|
|
73
|
+
- [Building & Deploying](https://bkper.com/docs/build/apps/deploying.md#setting-secrets) — Store production and preview secrets.
|
|
74
|
+
- [Event Handlers](https://bkper.com/docs/build/apps/event-handlers.md#authentication) — Understand authentication for platform and self-hosted events.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Self-Hosted
|
|
1
|
+
# Bkper Self-Hosted Webhooks
|
|
2
2
|
|
|
3
3
|
The [Bkper Platform](https://bkper.com/docs/build/apps/overview.md) handles hosting, authentication, and deployment for you. However, you can host event handlers on your own infrastructure if you have specific requirements — existing cloud setup, compliance constraints, or legacy apps.
|
|
4
4
|
|
|
@@ -46,6 +46,8 @@ Sync preserves the existing App identity, activates managed source, configures i
|
|
|
46
46
|
|
|
47
47
|
When scaffolding, developing, or deploying an app, verify each step before proceeding. This prevents broken deployments and silent failures.
|
|
48
48
|
|
|
49
|
+
For app implementation, refactoring, or code review, first read the [App Quality Guidelines](https://bkper.com/docs/build/apps/quality.md). After implementation, review the changed code against the guidelines and run the project's deterministic checks. A successful build does not replace this quality review.
|
|
50
|
+
|
|
49
51
|
### 1. Init
|
|
50
52
|
|
|
51
53
|
```bash
|
|
@@ -238,6 +238,10 @@ bkper transaction create -b abc123 --description "Office supplies"
|
|
|
238
238
|
bkper transaction create -b abc123 --date 2025-01-15 --amount 100.50 \
|
|
239
239
|
--from "Bank Account" --to "Office Supplies" --description "Printer paper"
|
|
240
240
|
|
|
241
|
+
# Keep a complete AI-derived transaction as a draft
|
|
242
|
+
printf '%s\n' '[{"date":"2025-01-15","amount":"100.50","creditAccount":{"name":"Bank Account"},"debitAccount":{"name":"Office Supplies"},"description":"Extracted printer paper","draft":true}]' | \
|
|
243
|
+
bkper transaction create -b abc123
|
|
244
|
+
|
|
241
245
|
# Create a transaction with one local attachment
|
|
242
246
|
bkper transaction create -b abc123 --date 2025-01-15 --amount 23.90 \
|
|
243
247
|
--from "Cash" --to "Meals" --description "Team lunch" --file ./receipt.pdf
|
|
@@ -540,6 +544,10 @@ python export_bank.py | bkper transaction create -b abc123
|
|
|
540
544
|
|
|
541
545
|
The input follows the exact `bkper.Transaction` or `bkper.Account` type from the [Bkper API Types](https://raw.githubusercontent.com/bkper/bkper-api-types/refs/heads/master/index.d.ts). Custom properties go inside the `properties` object.
|
|
542
546
|
|
|
547
|
+
### AI-derived transaction safety
|
|
548
|
+
|
|
549
|
+
Always set `"draft": true` for AI-derived transactions, even when complete. It bypasses Book auto-posting, so the transaction stays out of balances until explicitly posted. Do not rely on missing fields; parsing or Account discovery may complete them.
|
|
550
|
+
|
|
543
551
|
Groups are created explicitly with `bkper group create --name` and optional `--parent` so hierarchy stays deterministic during setup.
|
|
544
552
|
|
|
545
553
|
The `--property` CLI flag can override or delete properties from the stdin payload:
|
|
@@ -604,6 +612,7 @@ Only the fields below are meaningful when creating or updating resources via std
|
|
|
604
612
|
| `creditAccount` | `{"name":"..."}` or `{"id":"..."}` | Reference to an existing account |
|
|
605
613
|
| `debitAccount` | `{"name":"..."}` or `{"id":"..."}` | Reference to an existing account |
|
|
606
614
|
| `description` | `string` | Free-text description |
|
|
615
|
+
| `draft` | `boolean` | `true` forces a draft and bypasses Book auto-posting |
|
|
607
616
|
| `urls` | `string[]` | Attached URLs (e.g. receipts) |
|
|
608
617
|
| `remoteIds` | `string[]` | External IDs to prevent duplicates |
|
|
609
618
|
| `properties` | `{"key": "value", ...}` | Custom key/value properties |
|
package/lib/docs/index.md
CHANGED
|
@@ -4,6 +4,8 @@ Reference docs for Bkper tasks. Load only the specific doc(s) relevant to the ta
|
|
|
4
4
|
|
|
5
5
|
For Bkper data, accounting, reporting, tax, or financial-flow tasks, read `core/core-concepts.md` first.
|
|
6
6
|
|
|
7
|
+
For Bkper app implementation, refactoring, or code review, always read `apps/quality.md` alongside the task-specific references. After implementation, review the changed code against the guidelines before considering the work complete.
|
|
8
|
+
|
|
7
9
|
- `core/core-concepts.md` — canonical Bkper data model: resources, movements, balances, accounts, groups, books, transactions, properties, and the zero-sum invariant.
|
|
8
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:), output formats (table/json/csv), human-review Bkper UI links, batch operations via stdin/piping, collections.
|
|
9
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).
|
|
@@ -11,6 +13,8 @@ For Bkper data, accounting, reporting, tax, or financial-flow tasks, read `core/
|
|
|
11
13
|
- `apps/ai.md` — Bkper AI integration for Platform apps: authenticated `/api/*` request flow, outbound authorization and app attribution, live model discovery, strict structured output, response validation, error preservation, data minimization, and unit-test boundaries.
|
|
12
14
|
- `apps/first-app.md` — First-app walkthrough: scaffold, install, run locally, trigger an event, customize the listing, establish shared source, check, and deploy.
|
|
13
15
|
- `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
|
+
- `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.
|
|
17
|
+
- `apps/security.md` — App security responsibilities and server-side authorization: platform authentication boundaries, user-domain restrictions, Book permission allowlists, and app installation checks.
|
|
14
18
|
- `apps/configuration.md` — Complete `bkper.yaml` reference: identity, branding, ownership, access, context menus, event subscriptions, property schemas, and single-Worker deployment settings.
|
|
15
19
|
- `apps/development.md` — Local development: Vite and Worker processes, ports, API proxy, local authentication, secrets, KV, generated environment types, development loop, and debugging.
|
|
16
20
|
- `apps/event-handlers.md` — Event handler behavior: `/events` routing, responses, replay, loop prevention, platform and self-hosted authentication, event payloads, and event types.
|
package/lib/docs/sdk/bkper-js.md
CHANGED
|
@@ -636,7 +636,8 @@ It contains all `Accounts` where `Transactions` are recorded/posted;
|
|
|
636
636
|
- `listEvents(options: ListEventsOptions)` → `Promise<EventList>` — Lists events in the Book based on the provided options.
|
|
637
637
|
- `listFiles(limit?: number, cursor?: string)` → `Promise<FileList>` — Lists files in the Book, for pagination.
|
|
638
638
|
- `listTransactions(query?: string, limit?: number, cursor?: string)` → `Promise<TransactionList>` — Lists transactions in the Book based on the provided query, limit, and cursor, for pagination.
|
|
639
|
-
- `mergeTransactions(
|
|
639
|
+
- `mergeTransactions(primary: string | bkper.Transaction | Transaction, secondary: string | bkper.Transaction | Transaction)` → `Promise<Transaction>` — Merge a primary and secondary `Transaction`. Submitted primary fields
|
|
640
|
+
have highest precedence; an id string sends no field overrides.
|
|
640
641
|
- `parseDate(date: string)` → `Date` — Parse a date string according to date pattern and timezone of the Book. Also parse ISO yyyy-mm-dd format.
|
|
641
642
|
- `parseValue(value: string)` → `Amount | undefined` — Parse a value string according to `DecimalSeparator` and fraction digits of the Book.
|
|
642
643
|
- `remove()` → `Promise<Book>` — Warning!
|
|
@@ -736,11 +737,6 @@ const groups2 = await bookWithGroups.getGroups(); // Already cached
|
|
|
736
737
|
|
|
737
738
|
Requests are sent sequentially in batches of up to 200 IDs.
|
|
738
739
|
|
|
739
|
-
**mergeTransactions**
|
|
740
|
-
|
|
741
|
-
The merged transaction is created synchronously. Cleanup of the two
|
|
742
|
-
originals is scheduled asynchronously by the backend.
|
|
743
|
-
|
|
744
740
|
**remove**
|
|
745
741
|
|
|
746
742
|
Deletes this Book and all its data (transactions, accounts, groups). Book owner only.
|
package/package.json
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bkper",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.29.0",
|
|
4
|
+
"description": "Official Bkper CLI for accounting data, automation, apps, and AI agents",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bkper": "./lib/cli.js"
|
|
7
7
|
},
|
|
8
8
|
"repository": "https://github.com/bkper/bkper-cli.git",
|
|
9
|
-
"homepage": "https://bkper.com/docs",
|
|
9
|
+
"homepage": "https://bkper.com/docs/build/tools/cli",
|
|
10
10
|
"author": "mael <mael@bkper.com>",
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"bkper",
|
|
14
|
+
"cli",
|
|
15
|
+
"accounting",
|
|
16
|
+
"bookkeeping",
|
|
17
|
+
"finance",
|
|
18
|
+
"automation",
|
|
19
|
+
"ai-agent"
|
|
20
|
+
],
|
|
12
21
|
"private": false,
|
|
13
22
|
"main": "./lib/index.js",
|
|
14
23
|
"module": "./lib/index.js",
|
|
@@ -52,8 +61,8 @@
|
|
|
52
61
|
"upgrade:api": "bun update @bkper/bkper-api-types --latest && bun update bkper-js --latest"
|
|
53
62
|
},
|
|
54
63
|
"dependencies": {
|
|
55
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
56
|
-
"@earendil-works/pi-tui": "0.84.
|
|
64
|
+
"@earendil-works/pi-coding-agent": "0.84.3",
|
|
65
|
+
"@earendil-works/pi-tui": "0.84.3",
|
|
57
66
|
"bkper-js": "^2.42.0",
|
|
58
67
|
"commander": "^13.1.0",
|
|
59
68
|
"dotenv": "^8.2.0",
|