bkper 4.16.0 → 4.16.2

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 CHANGED
@@ -99,7 +99,7 @@ Bkper's agent mode is intentionally a **thin wrapper** around [Pi][Pi]:
99
99
 
100
100
  ### Startup maintenance (non-blocking)
101
101
 
102
- On each agent startup, bkper performs a background CLI auto-update check (same behavior as command mode).
102
+ On each agent startup, bkper performs a background CLI auto-update check. Normal command-mode invocations do not auto-update; use `bkper upgrade` when you want to upgrade explicitly.
103
103
 
104
104
  ### Pi passthrough
105
105
 
package/lib/cli.js CHANGED
@@ -22,7 +22,7 @@ import { registerFileCommands } from './commands/files/register.js';
22
22
  import { registerUpgradeCommand } from './commands/upgrade.js';
23
23
  import { registerAgentCommands, runAgentCommand } from './commands/agent-command.js';
24
24
  import { getAgentCommandArgs, shouldRunAgentCommand, shouldShowHelpForBareInvocation, } from './agent/cli-dispatch.js';
25
- import { VERSION, autoUpgrade } from './upgrade/index.js';
25
+ import { VERSION } from './upgrade/index.js';
26
26
  function main() {
27
27
  return __awaiter(this, void 0, void 0, function* () {
28
28
  if (shouldRunAgentCommand(process.argv)) {
@@ -56,10 +56,6 @@ function main() {
56
56
  registerAgentCommands(program);
57
57
  // Upgrade command
58
58
  registerUpgradeCommand(program);
59
- // Trigger silent auto-upgrade in the background (non-blocking, never fails)
60
- if (!process.env.BKPER_DISABLE_AUTOUPDATE) {
61
- autoUpgrade().catch(() => { });
62
- }
63
59
  if (shouldShowHelpForBareInvocation(process.argv)) {
64
60
  program.outputHelp();
65
61
  return;
package/lib/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,OAAO,eAAe,CAAC,CAAC,sDAAsD;AAE9E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EACH,mBAAmB,EACnB,qBAAqB,EACrB,+BAA+B,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,SAAe,IAAI;;QACf,IAAI,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC;gBACD,MAAM,eAAe,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzD,OAAO;YACX,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,CAAC;QACL,CAAC;QAED,UAAU;QACV,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAE1C,+BAA+B;QAC/B,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,EAAE,OAAO,CAAC,CAAC;QACnF,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,0CAA0C,CAAC,CAAC;QAErE,gBAAgB;QAChB,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE9B,oBAAoB;QACpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC/B,2BAA2B,CAAC,OAAO,CAAC,CAAC;QACrC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;QACpC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE9B,uBAAuB;QACvB,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAE/B,kBAAkB;QAClB,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEhC,IAAI,+BAA+B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -62,17 +62,26 @@ To make your app available to all Bkper users, contact us at [support@bkper.com]
62
62
  Your app's `README.md` is displayed to end users on the app listing page. Write it for the people who will install and use your app — not for developers.
63
63
 
64
64
  **README should explain:**
65
+
65
66
  - What the app does from a user's perspective
66
67
  - How to use it (step-by-step for non-technical users)
67
68
  - What features are available
69
+ - API access details when the app intentionally exposes `/api/*` routes for users or integrators
70
+
71
+ **API access details should stay concise:**
72
+
73
+ - App base URL for production and preview
74
+ - OpenAPI spec URL at `/openapi.json`
75
+ - One minimal authenticated example, such as a `curl` call with `Authorization: Bearer <token>`
68
76
 
69
77
  **README should NOT contain:**
78
+
70
79
  - Tech stack or architecture details
71
80
  - Build commands or development setup
72
81
  - Project structure or internal file paths
73
- - API documentation or SDK references
82
+ - Long API references, generated schemas, SDK internals, or route-by-route developer docs
74
83
 
75
- Put developer documentation in `AGENTS.md` or internal docs instead. Keep `README.md` focused on the user experience.
84
+ Put developer documentation in `AGENTS.md` or internal docs instead. Keep `README.md` focused on the user experience and any integration entry points users need.
76
85
 
77
86
  ### Where published apps appear
78
87
 
@@ -88,6 +97,8 @@ source: /docs/build/apps/architecture.md
88
97
 
89
98
  Bkper platform apps use one Worker bundle per app and environment. The same Worker serves the browser client, app-defined `/api/*` routes, and Bkper event ingress at `/events`.
90
99
 
100
+ Treat `/api/*` as the reusable surface for app behavior. The bundled web client is one consumer of that API; scripts, external clients, and agents can call the same routes with bearer auth.
101
+
91
102
  ## Structure
92
103
 
93
104
  ```txt
@@ -174,6 +185,47 @@ app.get('*', c => c.env.ASSETS.fetch(c.req.raw));
174
185
  export default app;
175
186
  ```
176
187
 
188
+ ### App API contract
189
+
190
+ Expose reusable app behavior through `/api/*` routes when it may be called by more than one client.
191
+
192
+ Use this shape:
193
+
194
+ - **Routes** — Thin Hono handlers under `/api/*`.
195
+ - **Schemas** — Typed request and response schemas for every route.
196
+ - **Services** — Business behavior in server-side service modules.
197
+ - **OpenAPI** — A machine-readable app API spec exposed at `/openapi.json`.
198
+
199
+ The default template generates typed client code from the same OpenAPI contract used by the shipped web client. Keep that contract current so scripts, external clients, and agents can connect without reverse-engineering the UI.
200
+
201
+ App API endpoints use these URLs:
202
+
203
+ ```txt
204
+ Production: https://{appId}.bkper.app/api/*
205
+ Preview: https://{appId}-preview.bkper.app/api/*
206
+ Local: http://localhost:8787/api/*
207
+ ```
208
+
209
+ The app OpenAPI spec lives at:
210
+
211
+ ```txt
212
+ Production: https://{appId}.bkper.app/openapi.json
213
+ Preview: https://{appId}-preview.bkper.app/openapi.json
214
+ Local: http://localhost:8787/openapi.json
215
+ ```
216
+
217
+ Example script call:
218
+
219
+ ```bash
220
+ TOKEN="$(bkper auth token)"
221
+
222
+ curl \
223
+ -H "Authorization: Bearer ${TOKEN}" \
224
+ "https://my-app.bkper.app/api/books"
225
+ ```
226
+
227
+ Replace `my-app` with the app id from `bkper.yaml`.
228
+
177
229
  ### Server API authentication
178
230
 
179
231
  For deployed apps, server API routes under `/api/*` require a standard bearer token on the incoming request:
@@ -253,11 +305,13 @@ See [Event Handlers](https://bkper.com/docs/build/apps/event-handlers.md) for pa
253
305
 
254
306
  ## When you don't need every part
255
307
 
256
- Not every app needs a UI, API, and event handler:
308
+ The platform can host different shapes, but the default template starts as a full app because `/api/*` routes give the app a reusable contract as it grows.
257
309
 
310
+ Use these shapes intentionally:
311
+
312
+ - **Full app** — Client UI, `/api/*` backend logic, and `/events` automation in one Worker. This is the default growth path.
258
313
  - **Event-only app** — Keep `server/` and omit `deployment.client`. Automates reactions to book events without a user interface.
259
- - **UI-only app** — Use `client/` and keep a minimal server Worker for static assets. Remove the `events` list and `webhookUrl` if you do not handle events.
260
- - **Full app** — Client UI, `/api/*` backend logic, and `/events` automation in one Worker.
314
+ - **UI-only app** — Use `client/` and keep a minimal server Worker for static assets only when the behavior is truly local to the browser. Add `/api/*` as soon as the behavior should be reusable by scripts, external clients, or agents.
261
315
 
262
316
  ## Simple App Patterns
263
317
 
@@ -265,7 +319,9 @@ These are the minimal, canonical patterns for common app tasks. Use them as star
265
319
 
266
320
  ### Client-only UI with authentication
267
321
 
268
- The smallest useful app can keep all business logic in `client/`. No custom server routes, no event handlers, no custom auth logic.
322
+ The smallest useful app can keep browser-only display logic in `client/`. No custom server routes, no event handlers, no custom auth logic.
323
+
324
+ If the behavior should be reused by scripts, external clients, or agents, expose it through `/api/*` instead of keeping it only in the UI.
269
325
 
270
326
  ```ts
271
327
  // client/src/app.ts
@@ -307,43 +363,43 @@ Use `bkper-js` for all API calls. Do not call the REST API directly when `bkper-
307
363
 
308
364
  ## Library Usage Reference
309
365
 
310
- | Task | Use | Do not use |
311
- |------|-----|------------|
312
- | Client authentication | `@bkper/web-auth` (`BkperAuth`, `getAccessToken`) | Custom OAuth flows, manual `fetch('/auth/refresh')`, `google-auth-library` in the browser |
313
- | API calls from client | `bkper-js` (`Bkper`, `Book`, `Account`, `Transaction`) | Direct `fetch()` to REST endpoints |
314
- | API calls from app server `/api/*` route | Incoming `Authorization: Bearer <token>` + server-side `new Bkper()` | Reading OAuth tokens in server code, relying on browser sessions for API auth |
315
- | API calls from platform event handler | Server-side `new Bkper()` in `/events` | Reading `bkper-oauth-token` or `bkper-agent-id` in platform app code |
316
- | Local development server | `npm run dev` (template script) | Manual `miniflare` + `cloudflared` invocations |
317
- | Event handler routing | `switch (event.type)` in `server/src/index.ts` or `server/src/handlers/` | Middleware frameworks, external webhook routers |
318
- | UI components | `@bkper/web-design` + Lit | Heavy UI frameworks unless the user explicitly requests them |
366
+ | Task | Use | Do not use |
367
+ | ---------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
368
+ | Client authentication | `@bkper/web-auth` (`BkperAuth`, `getAccessToken`) | Custom OAuth flows, manual `fetch('/auth/refresh')`, `google-auth-library` in the browser |
369
+ | API calls from client | `bkper-js` (`Bkper`, `Book`, `Account`, `Transaction`) | Direct `fetch()` to REST endpoints |
370
+ | API calls from app server `/api/*` route | Incoming `Authorization: Bearer <token>` + server-side `new Bkper()` | Reading OAuth tokens in server code, relying on browser sessions for API auth |
371
+ | API calls from platform event handler | Server-side `new Bkper()` in `/events` | Reading `bkper-oauth-token` or `bkper-agent-id` in platform app code |
372
+ | Local development server | `npm run dev` (template script) | Manual `miniflare` + `cloudflared` invocations |
373
+ | Event handler routing | `switch (event.type)` in `server/src/index.ts` or `server/src/handlers/` | Middleware frameworks, external webhook routers |
374
+ | UI components | `@bkper/web-design` + Lit | Heavy UI frameworks unless the user explicitly requests them |
319
375
 
320
376
  ## Common Pitfalls
321
377
 
322
378
  Avoid these patterns even if they seem necessary. The platform or SDK already solves the problem.
323
379
 
324
380
  1. **Implementing custom OAuth on the server**
325
- - `@bkper/web-auth` manages the full OAuth lifecycle on the client. The platform handles tokens. Adding a server-side auth layer is unnecessary and will break.
381
+ - `@bkper/web-auth` manages the full OAuth lifecycle on the client. The platform handles tokens. Adding a server-side auth layer is unnecessary and will break.
326
382
 
327
383
  2. **Adding `/api/auth/refresh` or similar routes**
328
- - Token refresh is internal to `@bkper/web-auth`. Exposing it via Hono routes creates security surface area and duplicates platform functionality.
384
+ - Token refresh is internal to `@bkper/web-auth`. Exposing it via Hono routes creates security surface area and duplicates platform functionality.
329
385
 
330
386
  3. **Relying on browser sessions for server API auth**
331
- - Sessions let users open app web pages, but `/api/*` routes require `Authorization: Bearer <token>`. Dispatch validates bearer tokens and platform outbound uses that validated context for Bkper API calls.
387
+ - Sessions let users open app web pages, but `/api/*` routes require `Authorization: Bearer <token>`. Dispatch validates bearer tokens and platform outbound uses that validated context for Bkper API calls.
332
388
 
333
389
  4. **Modifying `server/` for a simple UI task**
334
- - If the user only asked for a client-side feature, do not touch server routes. The Vite dev server proxies `/api` to the Miniflare worker automatically; you do not need to add routes unless the user explicitly asks for custom backend logic.
390
+ - If the user only asked for a client-side feature, do not touch server routes. The Vite dev server proxies `/api` to the Miniflare worker automatically. Add routes when the behavior should be reusable by the shipped client, scripts, external clients, or agents.
335
391
 
336
392
  5. **Installing additional auth or HTTP libraries**
337
- - `bkper-js` and `@bkper/web-auth` are the only packages you need for Bkper API access and authentication. Adding `axios`, `google-auth-library`, or similar is almost always wrong.
393
+ - `bkper-js` and `@bkper/web-auth` are the only packages you need for Bkper API access and authentication. Adding `axios`, `google-auth-library`, or similar is almost always wrong.
338
394
 
339
395
  6. **Creating event handlers when the user asked for a UI-only feature**
340
- - If the user says "show me a list of books in a popup," that is a client-only task. Do not add `/events` logic or subscribe to webhooks.
396
+ - If the user says "show me a list of books in a popup," that is a client-only task. Do not add `/events` logic or subscribe to webhooks.
341
397
 
342
398
  7. **Calling REST endpoints directly when `bkper-js` has the method**
343
- - If `bkper-js` exposes `book.getTransactions()`, use it. Do not `fetch('https://api.bkper.com/...')` and parse JSON manually.
399
+ - If `bkper-js` exposes `book.getTransactions()`, use it. Do not `fetch('https://api.bkper.com/...')` and parse JSON manually.
344
400
 
345
401
  8. **Reverse-engineering SDK internals**
346
- - Use the public API surface documented in the API reference. Do not read SDK source to find private methods or internal request patterns.
402
+ - Use the public API surface documented in the API reference. Do not read SDK source to find private methods or internal request patterns.
347
403
 
348
404
  ---
349
405
  source: /docs/build/apps/configuration.md
@@ -600,31 +656,31 @@ source: /docs/build/apps/deploying.md
600
656
 
601
657
  1. **Build** — Compile your code
602
658
 
603
- ```bash
604
- npm run build
605
- ```
659
+ ```bash
660
+ npm run build
661
+ ```
606
662
 
607
- This runs two build steps:
608
- - Client (Vite) to static assets in `dist/client/`
609
- - Server Worker bundle (esbuild) to `dist/server/`
663
+ This runs two build steps:
664
+ - Client (Vite) to static assets in `dist/client/`
665
+ - Server Worker bundle (esbuild) to `dist/server/`
610
666
 
611
- Build output includes size reporting so you can monitor bundle sizes.
667
+ Build output includes size reporting so you can monitor bundle sizes.
612
668
 
613
669
  2. **Sync** — Update app metadata
614
670
 
615
- ```bash
616
- bkper app sync
617
- ```
671
+ ```bash
672
+ bkper app sync
673
+ ```
618
674
 
619
- Syncs your `bkper.yaml` configuration to Bkper — name, description, menu URLs, webhook URLs, access control, and branding. Run this whenever you change app settings.
675
+ Syncs your `bkper.yaml` configuration to Bkper — name, description, menu URLs, webhook URLs, access control, and branding. Run this whenever you change app settings.
620
676
 
621
677
  3. **Deploy** — Upload code to the platform
622
678
 
623
- ```bash
624
- bkper app deploy
625
- ```
679
+ ```bash
680
+ bkper app deploy
681
+ ```
626
682
 
627
- Deploys your pre-built code from `dist/` to the Bkper Platform. Your app is live at `https://{appId}.bkper.app`.
683
+ Deploys your pre-built code from `dist/` to the Bkper Platform. Your app is live at `https://{appId}.bkper.app`.
628
684
 
629
685
  The typical workflow combines all three:
630
686
 
@@ -640,6 +696,15 @@ The default deployment target. Your app runs at `https://{appId}.bkper.app`.
640
696
  bkper app deploy
641
697
  ```
642
698
 
699
+ Production serves:
700
+
701
+ ```txt
702
+ Client: https://{appId}.bkper.app
703
+ API routes: https://{appId}.bkper.app/api/*
704
+ OpenAPI spec: https://{appId}.bkper.app/openapi.json
705
+ Events: https://{appId}.bkper.app/events
706
+ ```
707
+
643
708
  ### Preview
644
709
 
645
710
  Deploy to a separate preview environment for testing before production:
@@ -650,6 +715,15 @@ bkper app deploy --preview
650
715
 
651
716
  Preview URLs use a dash suffix: `https://{appId}-preview.bkper.app`. For example, an app with `id: my-app` deploys to `https://my-app-preview.bkper.app`.
652
717
 
718
+ Preview serves:
719
+
720
+ ```txt
721
+ Client: https://{appId}-preview.bkper.app
722
+ API routes: https://{appId}-preview.bkper.app/api/*
723
+ OpenAPI spec: https://{appId}-preview.bkper.app/openapi.json
724
+ Events: https://{appId}-preview.bkper.app/events
725
+ ```
726
+
653
727
  Preview has independent secrets and KV storage from production.
654
728
 
655
729
  There is one app deployment per environment. `/events` is handled by the same Worker as the client assets and `/api/*` routes.
@@ -691,7 +765,7 @@ bkper app secrets delete EXTERNAL_SERVICE_TOKEN
691
765
  Secrets are available as `c.env.SECRET_NAME` in your Hono handlers:
692
766
 
693
767
  ```ts
694
- app.get('/api/data', async (c) => {
768
+ app.get('/api/data', async c => {
695
769
  const token = c.env.EXTERNAL_SERVICE_TOKEN;
696
770
  // use token
697
771
  });
@@ -757,21 +831,23 @@ The project template runs both processes via `concurrently`:
757
831
 
758
832
  1. **`vite dev`** — Client dev server with HMR. Changes to Lit components reflect instantly in the browser. Configured in `vite.config.ts`.
759
833
  2. **`bkper app dev`** — The worker runtime:
760
- - **Miniflare** — Simulates the single Cloudflare Worker locally.
761
- - **Cloudflare tunnel** — Exposes `/events` via a public URL so Bkper can route webhook events to your machine.
762
- - **File watching** — Server changes trigger automatic rebuilds via esbuild.
834
+ - **Miniflare** — Simulates the single Cloudflare Worker locally.
835
+ - **Cloudflare tunnel** — Exposes `/events` via a public URL so Bkper can route webhook events to your machine.
836
+ - **File watching** — Server changes trigger automatic rebuilds via esbuild.
763
837
 
764
838
  You can also run them independently: `npm run dev:client` for just the UI, or `npm run dev:server` for the local Worker.
765
839
 
766
840
  ## URLs
767
841
 
768
- | Endpoint | URL |
769
- | --- | --- |
770
- | Client (Vite dev server) | `http://localhost:5173` |
771
- | Server Worker (Miniflare) | `http://localhost:8787` |
842
+ | Endpoint | URL |
843
+ | -------------------------------------- | ------------------------------------------- |
844
+ | Client (Vite dev server) | `http://localhost:5173` |
845
+ | Server Worker (Miniflare) | `http://localhost:8787` |
846
+ | App API routes | `http://localhost:8787/api/*` |
847
+ | App OpenAPI spec | `http://localhost:8787/openapi.json` |
772
848
  | Events (via tunnel to the same Worker) | `https://<random>.trycloudflare.com/events` |
773
849
 
774
- The Vite dev server proxies `/api` requests to `http://localhost:8787` (configured in `vite.config.ts`). The tunnel URL is automatically registered as the `webhookUrlDev` in Bkper, so events from books where you're the developer are routed to your local machine.
850
+ The Vite dev server proxies `/api` requests to `http://localhost:8787` (configured in `vite.config.ts`). The app OpenAPI spec is served by the Worker at `http://localhost:8787/openapi.json`. The tunnel URL is automatically registered as the `webhookUrlDev` in Bkper, so events from books where you're the developer are routed to your local machine.
775
851
 
776
852
  ## Configuration flags
777
853
 
@@ -1167,7 +1243,7 @@ This tutorial walks you through building and deploying a Bkper app from scratch.
1167
1243
 
1168
1244
  7. **Update the README**
1169
1245
 
1170
- Edit `README.md` for end users — what the app does and how to use it. Keep developer docs in `AGENTS.md`.
1246
+ Edit `README.md` for end users — what the app does and how to use it. If your app exposes `/api/*` routes for users or integrators, include the app API base URL, `/openapi.json` URL, and one minimal authenticated example. Keep deeper developer docs in `AGENTS.md`.
1171
1247
 
1172
1248
  8. **Deploy**
1173
1249
 
@@ -1181,11 +1257,11 @@ This tutorial walks you through building and deploying a Bkper app from scratch.
1181
1257
 
1182
1258
  ## What you built
1183
1259
 
1184
- | You wrote | Platform handled |
1185
- | --- | --- |
1186
- | ~30 lines of UI | OAuth, consent screen, token refresh |
1187
- | ~40 lines of event logic | Hosting, SSL, edge routing |
1188
- | `bkper.yaml` | Webhook tunnels, KV, type generation |
1260
+ | You wrote | Platform handled |
1261
+ | ------------------------ | ------------------------------------ |
1262
+ | ~30 lines of UI | OAuth, consent screen, token refresh |
1263
+ | ~40 lines of event logic | Hosting, SSL, edge routing |
1264
+ | `bkper.yaml` | Webhook tunnels, KV, type generation |
1189
1265
 
1190
1266
  ## Next steps
1191
1267
 
@@ -1207,6 +1283,14 @@ Apps are deployed to `{appId}.bkper.app` on a global edge network powered by [Cl
1207
1283
 
1208
1284
  Preview environments are built in — deploy to a preview URL to test before going to production.
1209
1285
 
1286
+ ### App APIs
1287
+
1288
+ The same Worker can expose app-defined `/api/*` routes. Treat those routes as the reusable contract for your app behavior:
1289
+
1290
+ - The bundled web client can call them.
1291
+ - Scripts, external clients, and agents can call them too.
1292
+ - The default template documents them with an app OpenAPI spec at `/openapi.json`.
1293
+
1210
1294
  ### Authentication
1211
1295
 
1212
1296
  OAuth is pre-configured. No client IDs, no redirect URIs, no consent screens to build.
@@ -1247,16 +1331,16 @@ Your app is live at `{appId}.bkper.app`. The platform handles routing, SSL, and
1247
1331
 
1248
1332
  Without the platform, creating a Bkper app with a UI, event handling, and authentication requires:
1249
1333
 
1250
- | Concern | Without the platform | With the platform |
1251
- | --- | --- | --- |
1252
- | **Hosting** | Provision servers, configure domains, SSL, CDN | `bkper app deploy` |
1253
- | **Authentication** | Register OAuth client, build consent screen, handle token refresh, manage redirect URIs | `auth.getAccessToken()` |
1254
- | **Event webhooks** | Set up a public endpoint, configure DNS, handle JWT verification | Declare in `bkper.yaml`, platform routes events |
1255
- | **Local dev webhooks** | Install ngrok or similar, manually configure tunnel URL | `bkper app dev` starts tunnel automatically |
1256
- | **Secrets** | Set up a secrets manager, configure access | `bkper app secrets put` |
1257
- | **KV storage** | Deploy Redis/Memcached, manage connections | Declare `KV` in `bkper.yaml` |
1258
- | **Preview environments** | Build a staging pipeline | `bkper app deploy --preview` |
1259
- | **Type safety** | Manually create type definitions | `env.d.ts` auto-generated |
1334
+ | Concern | Without the platform | With the platform |
1335
+ | ------------------------ | --------------------------------------------------------------------------------------- | ----------------------------------------------- |
1336
+ | **Hosting** | Provision servers, configure domains, SSL, CDN | `bkper app deploy` |
1337
+ | **Authentication** | Register OAuth client, build consent screen, handle token refresh, manage redirect URIs | `auth.getAccessToken()` |
1338
+ | **Event webhooks** | Set up a public endpoint, configure DNS, handle JWT verification | Declare in `bkper.yaml`, platform routes events |
1339
+ | **Local dev webhooks** | Install ngrok or similar, manually configure tunnel URL | `bkper app dev` starts tunnel automatically |
1340
+ | **Secrets** | Set up a secrets manager, configure access | `bkper app secrets put` |
1341
+ | **KV storage** | Deploy Redis/Memcached, manage connections | Declare `KV` in `bkper.yaml` |
1342
+ | **Preview environments** | Build a staging pipeline | `bkper app deploy --preview` |
1343
+ | **Type safety** | Manually create type definitions | `env.d.ts` auto-generated |
1260
1344
 
1261
1345
  The platform eliminates all of this. You write business logic, the platform handles infrastructure.
1262
1346
 
@@ -99,7 +99,7 @@ Bkper's agent mode is intentionally a **thin wrapper** around [Pi][Pi]:
99
99
 
100
100
  ### Startup maintenance (non-blocking)
101
101
 
102
- On each agent startup, bkper performs a background CLI auto-update check (same behavior as command mode).
102
+ On each agent startup, bkper performs a background CLI auto-update check. Normal command-mode invocations do not auto-update; use `bkper upgrade` when you want to upgrade explicitly.
103
103
 
104
104
  ### Pi passthrough
105
105
 
@@ -26,7 +26,7 @@ export declare function getAvailableUpgrade(dependencies?: AvailableUpgradeDepen
26
26
  /**
27
27
  * Runs the silent auto-upgrade check in the background.
28
28
  *
29
- * Called on every CLI invocation. This function:
29
+ * This function:
30
30
  * 1. Fetches the latest version from npm
31
31
  * 2. Compares with the current installed version
32
32
  * 3. If newer, starts a detached background upgrade using the detected install method
@@ -64,7 +64,7 @@ export function getAvailableUpgrade() {
64
64
  /**
65
65
  * Runs the silent auto-upgrade check in the background.
66
66
  *
67
- * Called on every CLI invocation. This function:
67
+ * This function:
68
68
  * 1. Fetches the latest version from npm
69
69
  * 2. Compares with the current installed version
70
70
  * 3. If newer, starts a detached background upgrade using the detected install method
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bkper",
3
- "version": "4.16.0",
3
+ "version": "4.16.2",
4
4
  "description": "Command line client for Bkper",
5
5
  "bin": {
6
6
  "bkper": "./lib/cli.js"
@@ -51,7 +51,7 @@
51
51
  "upgrade:api": "bun update @bkper/bkper-api-types --latest && bun update bkper-js --latest"
52
52
  },
53
53
  "dependencies": {
54
- "@earendil-works/pi-coding-agent": "0.77.0",
54
+ "@earendil-works/pi-coding-agent": "0.78.0",
55
55
  "bkper-js": "^2.35.2",
56
56
  "commander": "^13.1.0",
57
57
  "dotenv": "^8.2.0",