@boxxy/server 0.0.0-stage → 0.1.3

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -2
  3. package/dist/auth/authorize-call.d.ts +11 -0
  4. package/dist/auth/is-browser-request.d.ts +1 -0
  5. package/dist/auth/pick-request-scope.d.ts +9 -0
  6. package/dist/config/pick-server-secrets.d.ts +16 -0
  7. package/dist/config/read-caller-proof.d.ts +10 -0
  8. package/dist/config/read-server-config.d.ts +9 -0
  9. package/dist/config/read-trusted-issuers.d.ts +8 -0
  10. package/dist/config/server-config-schema.d.ts +42 -0
  11. package/dist/create-capacity-backoff.d.ts +2 -0
  12. package/dist/handlers/api.d.ts +1683 -0
  13. package/dist/handlers/attempt-handlers.d.ts +130 -0
  14. package/dist/handlers/build-owner-fact.d.ts +3 -0
  15. package/dist/handlers/item-handlers.d.ts +168 -0
  16. package/dist/handlers/outbox-handlers.d.ts +7 -0
  17. package/dist/handlers/plan-handlers.d.ts +62 -0
  18. package/dist/handlers/read-item-ids.d.ts +10 -0
  19. package/dist/handlers/relation-handlers.d.ts +41 -0
  20. package/dist/handlers/report-handlers.d.ts +102 -0
  21. package/dist/handlers/rules-handlers.d.ts +20 -0
  22. package/dist/handlers/runner-handlers.d.ts +65 -0
  23. package/dist/handlers/to-wire-json.d.ts +5 -0
  24. package/dist/handlers/write-levers.d.ts +11 -0
  25. package/dist/index.d.ts +12 -0
  26. package/dist/main.d.ts +1 -0
  27. package/dist/no-caller-proof.d.ts +2 -0
  28. package/dist/outbox/create-off-outbox.d.ts +3 -0
  29. package/dist/outbox/start-outbox-sender.d.ts +10 -0
  30. package/dist/read-limited-request.d.ts +1 -0
  31. package/dist/rules/create-rules-holder.d.ts +20 -0
  32. package/dist/rules/load-server-rules.d.ts +7 -0
  33. package/dist/rules/read-rules-checkout.d.ts +9 -0
  34. package/dist/serve-api.d.ts +50 -0
  35. package/dist/start-server.d.ts +18 -0
  36. package/dist/test-utils/build-mcp-request.d.ts +8 -0
  37. package/dist/test-utils/build-rpc-request.d.ts +7 -0
  38. package/dist/test-utils/build-session-input.d.ts +1 -0
  39. package/dist/test-utils/create-fake-caller-proof.d.ts +5 -0
  40. package/dist/test-utils/create-test-server.d.ts +30 -0
  41. package/dist/test-utils/list-owner-procedures.d.ts +5 -0
  42. package/dist/test-utils/read-mcp-answer.d.ts +11 -0
  43. package/dist/test-utils/wait-for.d.ts +1 -0
  44. package/dist/tick/run-tick.d.ts +24 -0
  45. package/dist/tick/start-tick-loop.d.ts +12 -0
  46. package/dist/types.d.ts +41 -0
  47. package/package.json +62 -4
  48. package/src/auth/authorize-call.ts +50 -0
  49. package/src/auth/is-browser-request.ts +8 -0
  50. package/src/auth/pick-request-scope.ts +37 -0
  51. package/src/config/pick-server-secrets.ts +48 -0
  52. package/src/config/read-caller-proof.ts +36 -0
  53. package/src/config/read-server-config.ts +41 -0
  54. package/src/config/read-trusted-issuers.ts +60 -0
  55. package/src/config/server-config-schema.ts +71 -0
  56. package/src/create-capacity-backoff.ts +18 -0
  57. package/src/handlers/api.ts +23 -0
  58. package/src/handlers/attempt-handlers.ts +244 -0
  59. package/src/handlers/build-owner-fact.ts +20 -0
  60. package/src/handlers/item-handlers.ts +462 -0
  61. package/src/handlers/outbox-handlers.ts +15 -0
  62. package/src/handlers/plan-handlers.ts +75 -0
  63. package/src/handlers/read-item-ids.ts +31 -0
  64. package/src/handlers/relation-handlers.ts +143 -0
  65. package/src/handlers/report-handlers.ts +112 -0
  66. package/src/handlers/rules-handlers.ts +46 -0
  67. package/src/handlers/runner-handlers.ts +117 -0
  68. package/src/handlers/to-wire-json.ts +20 -0
  69. package/src/handlers/write-levers.ts +53 -0
  70. package/src/index.ts +12 -0
  71. package/src/main.ts +31 -0
  72. package/src/no-caller-proof.ts +7 -0
  73. package/src/outbox/create-off-outbox.ts +21 -0
  74. package/src/outbox/start-outbox-sender.ts +89 -0
  75. package/src/read-limited-request.ts +43 -0
  76. package/src/rules/create-rules-holder.ts +107 -0
  77. package/src/rules/load-server-rules.ts +24 -0
  78. package/src/rules/read-rules-checkout.ts +65 -0
  79. package/src/serve-api.ts +178 -0
  80. package/src/start-server.ts +308 -0
  81. package/src/test-utils/build-mcp-request.ts +34 -0
  82. package/src/test-utils/build-rpc-request.ts +23 -0
  83. package/src/test-utils/build-session-input.ts +16 -0
  84. package/src/test-utils/create-fake-caller-proof.ts +18 -0
  85. package/src/test-utils/create-test-server.ts +142 -0
  86. package/src/test-utils/list-owner-procedures.ts +38 -0
  87. package/src/test-utils/read-mcp-answer.ts +26 -0
  88. package/src/test-utils/wait-for.ts +14 -0
  89. package/src/tick/run-tick.ts +212 -0
  90. package/src/tick/start-tick-loop.ts +46 -0
  91. package/src/types.ts +86 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 the boxxy authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,59 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
+ <h1>@boxxy/server</h1>
2
3
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
4
+ <p>
5
+ <a href="https://www.npmjs.com/package/@boxxy/server"><img src="https://img.shields.io/npm/v/@boxxy/server" alt="npm version"></a>
6
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
7
+ </p>
8
+
9
+ <p>
10
+ <a href="../../docs/design/boxxy/README.md">Documentation</a>
11
+ </p>
12
+ </div>
13
+
14
+ The boxxy server: the API on its owner and worker listeners, and the runner tick that claims tasks,
15
+ reads sessions and sends the facts to pepys.
16
+
17
+ `startServer({ env, log })` reads the configuration file at `BOXXY_CONFIG`, the trust documents and
18
+ the tokens from the environment, then starts both listeners, the tick, the pull request watch and
19
+ the outbox sender. It answers `refused` with a message that names each missing variable and never a
20
+ secret value.
21
+
22
+ ## Install
23
+
24
+ Install the package from [npm](https://www.npmjs.com/package/@boxxy/server) with Bun:
25
+
26
+ ```bash
27
+ bun add @boxxy/server
28
+ ```
29
+
30
+ The package runs on [Bun](https://bun.sh) 1.3 or newer.
31
+
32
+ ## Usage
33
+
34
+ Set the configuration path and the tokens, then start the server from the package folder:
35
+
36
+ ```bash
37
+ BOXXY_CONFIG=/etc/boxxy/boxxy.json \
38
+ BOXXY_WORKER_TOKEN=<worker_token> \
39
+ BOXXY_ATC_TOKEN=<atc_token> \
40
+ bun run start
41
+ ```
42
+
43
+ - `<worker_token>` is the token the broker sends on every request to the worker listener.
44
+ - `<atc_token>` is the token the server sends to the atc daemon.
45
+
46
+ With a `pepys` section in the configuration, also set `BOXXY_PEPYS_SIGNING_SECRET`. With a `github`
47
+ section, set `BOXXY_GITHUB_TOKEN` unless a broker adds the GitHub credential.
48
+
49
+ ## Features
50
+
51
+ - `startServer`, which wires the store, the atc worker and notifier, pepys and both listeners.
52
+ - `serveApi`, the two listeners as Elysia apps, for a caller that builds its own dependencies.
53
+ - `serverConfigSchema`, the configuration file's schema.
54
+ - `./test-utils/create-test-server`, the API on in-memory fakes, for tests.
55
+
56
+ ## Documentation
57
+
58
+ [The API and its auth](../../docs/design/boxxy/v1-api-and-auth.md) sets out the listeners, the
59
+ tokens and which caller may call each procedure.
@@ -0,0 +1,11 @@
1
+ import type { ProvenCall, RequestContext } from '../types.ts';
2
+ export type CallAuthorization = {
3
+ readonly kind: 'owner';
4
+ } | {
5
+ readonly kind: 'session';
6
+ readonly call: ProvenCall | null;
7
+ } | {
8
+ readonly kind: 'refused';
9
+ readonly code: 'UNAUTHORIZED' | 'FORBIDDEN';
10
+ };
11
+ export declare function authorizeCall(ctx: RequestContext, path: readonly string[]): Promise<CallAuthorization>;
@@ -0,0 +1 @@
1
+ export declare function isBrowserRequest(headers: Headers): boolean;
@@ -0,0 +1,9 @@
1
+ import type { Listener, RequestScope } from '../types.ts';
2
+ interface ScopeInput {
3
+ readonly listener: Listener;
4
+ readonly authorization: string | null;
5
+ readonly workerTokenDigest: Uint8Array;
6
+ }
7
+ export declare function pickRequestScope(input: ScopeInput): RequestScope | null;
8
+ export declare function buildTokenDigest(token: string): Uint8Array;
9
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { ServerConfig } from './server-config-schema.ts';
2
+ interface ServerSecrets {
3
+ readonly workerToken: string;
4
+ readonly atcToken: string;
5
+ readonly pepysSigningSecret: string | null;
6
+ readonly githubToken: string | null;
7
+ }
8
+ export type SecretsAnswer = {
9
+ readonly kind: 'found';
10
+ readonly secrets: ServerSecrets;
11
+ } | {
12
+ readonly kind: 'missing';
13
+ readonly names: readonly string[];
14
+ };
15
+ export declare function pickServerSecrets(config: ServerConfig, env: Readonly<Record<string, string | undefined>>): SecretsAnswer;
16
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { CallerProof, Clock } from '@boxxy/model';
2
+ import type { ServerConfig } from './server-config-schema.ts';
3
+ export type ProofAnswer = {
4
+ readonly kind: 'read';
5
+ readonly callerProof: CallerProof;
6
+ } | {
7
+ readonly kind: 'refused';
8
+ readonly message: string;
9
+ };
10
+ export declare function readCallerProof(trustedIssuers: ServerConfig['trustedIssuers'], clock: Clock): Promise<ProofAnswer>;
@@ -0,0 +1,9 @@
1
+ import type { ServerConfig } from './server-config-schema.ts';
2
+ export type ConfigAnswer = {
3
+ readonly kind: 'read';
4
+ readonly config: ServerConfig;
5
+ } | {
6
+ readonly kind: 'invalid';
7
+ readonly message: string;
8
+ };
9
+ export declare function readServerConfig(path: string): Promise<ConfigAnswer>;
@@ -0,0 +1,8 @@
1
+ export type IssuersAnswer = {
2
+ readonly kind: 'read';
3
+ readonly issuers: readonly unknown[];
4
+ } | {
5
+ readonly kind: 'invalid';
6
+ readonly message: string;
7
+ };
8
+ export declare function readTrustedIssuers(folders: readonly string[]): Promise<IssuersAnswer>;
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ export declare const serverConfigSchema: z.ZodObject<{
3
+ runner: z.ZodString;
4
+ store: z.ZodObject<{
5
+ file: z.ZodString;
6
+ }, z.core.$strict>;
7
+ rules: z.ZodObject<{
8
+ folder: z.ZodString;
9
+ }, z.core.$strict>;
10
+ api: z.ZodObject<{
11
+ listen: z.ZodObject<{
12
+ hostname: z.ZodString;
13
+ port: z.ZodInt;
14
+ }, z.core.$strict>;
15
+ workerListen: z.ZodObject<{
16
+ hostname: z.ZodString;
17
+ port: z.ZodInt;
18
+ }, z.core.$strict>;
19
+ }, z.core.$strict>;
20
+ spawn: z.ZodObject<{
21
+ target: z.ZodString;
22
+ repoPaths: z.ZodRecord<z.ZodString, z.ZodString>;
23
+ }, z.core.$strict>;
24
+ atc: z.ZodObject<{
25
+ url: z.ZodURL;
26
+ trustedFolders: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
27
+ noticeSession: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strict>;
29
+ trustedIssuers: z.ZodOptional<z.ZodObject<{
30
+ folders: z.ZodArray<z.ZodString>;
31
+ audience: z.ZodString;
32
+ }, z.core.$strict>>;
33
+ pepys: z.ZodOptional<z.ZodObject<{
34
+ ingestUrl: z.ZodURL;
35
+ apiUrl: z.ZodURL;
36
+ environment: z.ZodString;
37
+ }, z.core.$strict>>;
38
+ github: z.ZodOptional<z.ZodObject<{
39
+ baseUrl: z.ZodURL;
40
+ }, z.core.$strict>>;
41
+ }, z.core.$strict>;
42
+ export type ServerConfig = z.infer<typeof serverConfigSchema>;
@@ -0,0 +1,2 @@
1
+ import type { CapacityBackoff } from '@boxxy/model';
2
+ export declare function createCapacityBackoff(): CapacityBackoff;