@percher/shared 0.1.9 → 1.0.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/LICENSE +132 -0
- package/dist/brand.d.ts +64 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +67 -0
- package/dist/brand.js.map +1 -0
- package/dist/client-ip-attestation.d.ts +67 -0
- package/dist/client-ip-attestation.d.ts.map +1 -0
- package/dist/client-ip-attestation.js +74 -0
- package/dist/client-ip-attestation.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/legal-changes.d.ts +118 -0
- package/dist/legal-changes.d.ts.map +1 -0
- package/dist/legal-changes.js +135 -0
- package/dist/legal-changes.js.map +1 -0
- package/dist/legal.d.ts +52 -9
- package/dist/legal.d.ts.map +1 -1
- package/dist/legal.js +47 -8
- package/dist/legal.js.map +1 -1
- package/dist/limits.d.ts +8 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +8 -0
- package/dist/limits.js.map +1 -1
- package/dist/oauth-client-name.d.ts +22 -0
- package/dist/oauth-client-name.d.ts.map +1 -0
- package/dist/oauth-client-name.js +37 -0
- package/dist/oauth-client-name.js.map +1 -0
- package/dist/oauth-scopes.d.ts +19 -0
- package/dist/oauth-scopes.d.ts.map +1 -0
- package/dist/oauth-scopes.js +31 -0
- package/dist/oauth-scopes.js.map +1 -0
- package/dist/platform-env.d.ts.map +1 -1
- package/dist/platform-env.js +6 -0
- package/dist/platform-env.js.map +1 -1
- package/dist/platform.d.ts +1 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +1 -1
- package/dist/platform.js.map +1 -1
- package/dist/signup-invite-hash.d.ts +8 -0
- package/dist/signup-invite-hash.d.ts.map +1 -0
- package/dist/signup-invite-hash.js +11 -0
- package/dist/signup-invite-hash.js.map +1 -0
- package/dist/signup-invite.d.ts +23 -0
- package/dist/signup-invite.d.ts.map +1 -0
- package/dist/signup-invite.js +29 -0
- package/dist/signup-invite.js.map +1 -0
- package/dist/timeouts.d.ts +85 -0
- package/dist/timeouts.d.ts.map +1 -1
- package/dist/timeouts.js +84 -0
- package/dist/timeouts.js.map +1 -1
- package/package.json +12 -2
package/dist/timeouts.d.ts
CHANGED
|
@@ -64,4 +64,89 @@ export declare const TIMEOUTS: {
|
|
|
64
64
|
readonly mcpWaitDeployMax: number;
|
|
65
65
|
};
|
|
66
66
|
export type TimeoutKey = keyof typeof TIMEOUTS;
|
|
67
|
+
/**
|
|
68
|
+
* Bun refuses a `Bun.serve({ idleTimeout })` above this and throws at boot
|
|
69
|
+
* ("Bun.serve expects idleTimeout to be 255 or less"). Measured on Bun 1.3.14,
|
|
70
|
+
* the version `packages/api/Dockerfile` and `packages/mcp/Dockerfile` both
|
|
71
|
+
* digest-pin, on linux and win32. It is a hard ceiling, not a guideline: an
|
|
72
|
+
* operation whose budget exceeds it can never be covered by a server-wide
|
|
73
|
+
* value and has to be exempted per route
|
|
74
|
+
* (`packages/api/src/http/scoped-idle-timeout.ts`) or made job-based.
|
|
75
|
+
*/
|
|
76
|
+
export declare const BUN_MAX_IDLE_TIMEOUT_SECONDS = 255;
|
|
77
|
+
/**
|
|
78
|
+
* Transport-level idle timeout, in SECONDS, for each `Bun.serve` Percher runs.
|
|
79
|
+
* (Every other budget in this file is in milliseconds; Bun's option is
|
|
80
|
+
* seconds, so the unit is in the name.)
|
|
81
|
+
*
|
|
82
|
+
* Bun's default is 10 s, and leaving it there is how a healthy request dies of
|
|
83
|
+
* something unrelated to itself. 2026-09-08: a supervised admin POST to
|
|
84
|
+
* `/admin/migrate-networks` returned `curl: (52) Empty reply from server`
|
|
85
|
+
* while the same log window held `[watchdog] WARNING: disk usage 80% —
|
|
86
|
+
* triggering auto-prune` and `[Bun.serve]: request timed out after 10
|
|
87
|
+
* seconds`. Identical earlier runs answered in under 10 s; concurrent pruning
|
|
88
|
+
* was observed, but the log timing alone does not prove the cause of the delay.
|
|
89
|
+
* The client had budgeted 900 s.
|
|
90
|
+
*
|
|
91
|
+
* Two measurements shape these numbers. Both were taken with curl against a
|
|
92
|
+
* real `Bun.serve` on the pinned 1.3.14 linux image:
|
|
93
|
+
*
|
|
94
|
+
* - A request whose body is EMPTY (`GET`, or `curl -X POST` with no `-d`) is
|
|
95
|
+
* reset at the idle timeout: 200 at 8 s, `curl: (52)` at ~12 s.
|
|
96
|
+
* - A request carrying a non-empty body survived the measured 30 s handler,
|
|
97
|
+
* answering 200 under both the 10 s default and a 2 s override.
|
|
98
|
+
*
|
|
99
|
+
* That asymmetry is undocumented, so nothing may depend on it, but it does
|
|
100
|
+
* explain the shape of the incident report: the long-held bodied calls
|
|
101
|
+
* (`/build/nixpacks`, held for up to `workerBuildSubprocess`) never showed a
|
|
102
|
+
* symptom, while every bodyless operator `-X POST` and the watchdog's own
|
|
103
|
+
* non-aggressive `POST /docker/prune` were being cut at 10 s.
|
|
104
|
+
*
|
|
105
|
+
* Each value must outlive the longest SYNCHRONOUS request that surface
|
|
106
|
+
* legitimately serves. Anything longer than {@link BUN_MAX_IDLE_TIMEOUT_SECONDS}
|
|
107
|
+
* cannot be expressed here at all and stays on the per-route exemption list.
|
|
108
|
+
*/
|
|
109
|
+
export declare const HTTP_IDLE_TIMEOUT_SECONDS: {
|
|
110
|
+
/**
|
|
111
|
+
* `packages/api/src/server.ts`. Deliberately the most conservative of the
|
|
112
|
+
* three: this one `Bun.serve` also carries the anonymous lane and every
|
|
113
|
+
* signed-in user route, and the caps that bound that traffic (anon global
|
|
114
|
+
* 20, the per-network concurrency ceiling, the 25 MiB anon upload, the
|
|
115
|
+
* per-IP rate limits) all bound REQUESTS — a connection that sends nothing
|
|
116
|
+
* is bounded by this value and nothing else, so raising it is a real, if
|
|
117
|
+
* small, increase in what one idle socket can hold.
|
|
118
|
+
*
|
|
119
|
+
* 120 s is what the API's own downstream budgets ask for: a single
|
|
120
|
+
* `RemotePocketBaseManager.post()` is 90 s, `RemoteDeployer.post()` is 60 s,
|
|
121
|
+
* `waitHealthy` is its deadline + 10 s. Below those the transport, not the
|
|
122
|
+
* deadline, would decide the outcome — the misalignment the rest of this
|
|
123
|
+
* file exists to prevent. The operator routes that legitimately run longer
|
|
124
|
+
* (`/admin/backup/verify` at 10 min, `/admin/migrate-networks` at the
|
|
125
|
+
* runbook's 180 s and beyond) are on the exact-route exemption list, which
|
|
126
|
+
* is narrower than any process-wide number could be.
|
|
127
|
+
*/
|
|
128
|
+
readonly api: 120;
|
|
129
|
+
/**
|
|
130
|
+
* `packages/api/bin/percher-worker.ts`. The internal control plane: reached
|
|
131
|
+
* over the private networks with the shared worker secret, never from the
|
|
132
|
+
* public internet. Its unexempted routes are the ones the API budgets 60–90 s
|
|
133
|
+
* for, and the prune ladder the 2026-09-08 window was running has no API-side
|
|
134
|
+
* budget at all — the watchdog's non-aggressive `POST /docker/prune` sends no
|
|
135
|
+
* body and no signal, so it was being reset at 10 s and reported as
|
|
136
|
+
* `auto-prune failed` while the worker kept pruning unobserved. 240 s covers
|
|
137
|
+
* those with room for the IO stalls this exists for, and leaves the ceiling
|
|
138
|
+
* visible rather than sitting on it.
|
|
139
|
+
*/
|
|
140
|
+
readonly worker: 240;
|
|
141
|
+
/**
|
|
142
|
+
* `packages/mcp/bin/percher-mcp-http.ts`. Public through Caddy, so not the
|
|
143
|
+
* place for the ceiling either. Its longest legitimate single POST is
|
|
144
|
+
* `percher_wait_for_deploy`, whose hosted schema clamps `timeoutSeconds` to
|
|
145
|
+
* 120; 180 s covers that plus the internal API hop and JSON-RPC framing.
|
|
146
|
+
* Every hosted call carries a JSON-RPC body, so this is a guard rather than
|
|
147
|
+
* a fix for an observed failure.
|
|
148
|
+
*/
|
|
149
|
+
readonly hostedMcp: 180;
|
|
150
|
+
};
|
|
151
|
+
export type HttpIdleTimeoutSurface = keyof typeof HTTP_IDLE_TIMEOUT_SECONDS;
|
|
67
152
|
//# sourceMappingURL=timeouts.d.ts.map
|
package/dist/timeouts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../src/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;;OAKG;aACH,qBAAqB;IAErB;;;;;;OAMG;aACH,qBAAqB;IAErB;;;;;OAKG;aACH,iBAAiB;IAEjB,2CAA2C;aAC3C,iBAAiB,EAAE,IAAK;IAExB,2CAA2C;aAC3C,YAAY,EAAE,KAAM;IAEpB,uEAAuE;aACvE,oBAAoB,EAAE,KAAM;IAE5B;;;;;;OAMG;aACH,gBAAgB;CACR,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../src/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;;OAKG;aACH,qBAAqB;IAErB;;;;;;OAMG;aACH,qBAAqB;IAErB;;;;;OAKG;aACH,iBAAiB;IAEjB,2CAA2C;aAC3C,iBAAiB,EAAE,IAAK;IAExB,2CAA2C;aAC3C,YAAY,EAAE,KAAM;IAEpB,uEAAuE;aACvE,oBAAoB,EAAE,KAAM;IAE5B;;;;;;OAMG;aACH,gBAAgB;CACR,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,QAAQ,CAAC;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,yBAAyB;IACpC;;;;;;;;;;;;;;;;;OAiBG;aACH,GAAG,EAAE,GAAG;IACR;;;;;;;;;;OAUG;aACH,MAAM,EAAE,GAAG;IACX;;;;;;;OAOG;aACH,SAAS,EAAE,GAAG;CACN,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,yBAAyB,CAAC"}
|
package/dist/timeouts.js
CHANGED
|
@@ -63,4 +63,88 @@ export const TIMEOUTS = {
|
|
|
63
63
|
*/
|
|
64
64
|
mcpWaitDeployMax: 12 * 60_000,
|
|
65
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Bun refuses a `Bun.serve({ idleTimeout })` above this and throws at boot
|
|
68
|
+
* ("Bun.serve expects idleTimeout to be 255 or less"). Measured on Bun 1.3.14,
|
|
69
|
+
* the version `packages/api/Dockerfile` and `packages/mcp/Dockerfile` both
|
|
70
|
+
* digest-pin, on linux and win32. It is a hard ceiling, not a guideline: an
|
|
71
|
+
* operation whose budget exceeds it can never be covered by a server-wide
|
|
72
|
+
* value and has to be exempted per route
|
|
73
|
+
* (`packages/api/src/http/scoped-idle-timeout.ts`) or made job-based.
|
|
74
|
+
*/
|
|
75
|
+
export const BUN_MAX_IDLE_TIMEOUT_SECONDS = 255;
|
|
76
|
+
/**
|
|
77
|
+
* Transport-level idle timeout, in SECONDS, for each `Bun.serve` Percher runs.
|
|
78
|
+
* (Every other budget in this file is in milliseconds; Bun's option is
|
|
79
|
+
* seconds, so the unit is in the name.)
|
|
80
|
+
*
|
|
81
|
+
* Bun's default is 10 s, and leaving it there is how a healthy request dies of
|
|
82
|
+
* something unrelated to itself. 2026-09-08: a supervised admin POST to
|
|
83
|
+
* `/admin/migrate-networks` returned `curl: (52) Empty reply from server`
|
|
84
|
+
* while the same log window held `[watchdog] WARNING: disk usage 80% —
|
|
85
|
+
* triggering auto-prune` and `[Bun.serve]: request timed out after 10
|
|
86
|
+
* seconds`. Identical earlier runs answered in under 10 s; concurrent pruning
|
|
87
|
+
* was observed, but the log timing alone does not prove the cause of the delay.
|
|
88
|
+
* The client had budgeted 900 s.
|
|
89
|
+
*
|
|
90
|
+
* Two measurements shape these numbers. Both were taken with curl against a
|
|
91
|
+
* real `Bun.serve` on the pinned 1.3.14 linux image:
|
|
92
|
+
*
|
|
93
|
+
* - A request whose body is EMPTY (`GET`, or `curl -X POST` with no `-d`) is
|
|
94
|
+
* reset at the idle timeout: 200 at 8 s, `curl: (52)` at ~12 s.
|
|
95
|
+
* - A request carrying a non-empty body survived the measured 30 s handler,
|
|
96
|
+
* answering 200 under both the 10 s default and a 2 s override.
|
|
97
|
+
*
|
|
98
|
+
* That asymmetry is undocumented, so nothing may depend on it, but it does
|
|
99
|
+
* explain the shape of the incident report: the long-held bodied calls
|
|
100
|
+
* (`/build/nixpacks`, held for up to `workerBuildSubprocess`) never showed a
|
|
101
|
+
* symptom, while every bodyless operator `-X POST` and the watchdog's own
|
|
102
|
+
* non-aggressive `POST /docker/prune` were being cut at 10 s.
|
|
103
|
+
*
|
|
104
|
+
* Each value must outlive the longest SYNCHRONOUS request that surface
|
|
105
|
+
* legitimately serves. Anything longer than {@link BUN_MAX_IDLE_TIMEOUT_SECONDS}
|
|
106
|
+
* cannot be expressed here at all and stays on the per-route exemption list.
|
|
107
|
+
*/
|
|
108
|
+
export const HTTP_IDLE_TIMEOUT_SECONDS = {
|
|
109
|
+
/**
|
|
110
|
+
* `packages/api/src/server.ts`. Deliberately the most conservative of the
|
|
111
|
+
* three: this one `Bun.serve` also carries the anonymous lane and every
|
|
112
|
+
* signed-in user route, and the caps that bound that traffic (anon global
|
|
113
|
+
* 20, the per-network concurrency ceiling, the 25 MiB anon upload, the
|
|
114
|
+
* per-IP rate limits) all bound REQUESTS — a connection that sends nothing
|
|
115
|
+
* is bounded by this value and nothing else, so raising it is a real, if
|
|
116
|
+
* small, increase in what one idle socket can hold.
|
|
117
|
+
*
|
|
118
|
+
* 120 s is what the API's own downstream budgets ask for: a single
|
|
119
|
+
* `RemotePocketBaseManager.post()` is 90 s, `RemoteDeployer.post()` is 60 s,
|
|
120
|
+
* `waitHealthy` is its deadline + 10 s. Below those the transport, not the
|
|
121
|
+
* deadline, would decide the outcome — the misalignment the rest of this
|
|
122
|
+
* file exists to prevent. The operator routes that legitimately run longer
|
|
123
|
+
* (`/admin/backup/verify` at 10 min, `/admin/migrate-networks` at the
|
|
124
|
+
* runbook's 180 s and beyond) are on the exact-route exemption list, which
|
|
125
|
+
* is narrower than any process-wide number could be.
|
|
126
|
+
*/
|
|
127
|
+
api: 120,
|
|
128
|
+
/**
|
|
129
|
+
* `packages/api/bin/percher-worker.ts`. The internal control plane: reached
|
|
130
|
+
* over the private networks with the shared worker secret, never from the
|
|
131
|
+
* public internet. Its unexempted routes are the ones the API budgets 60–90 s
|
|
132
|
+
* for, and the prune ladder the 2026-09-08 window was running has no API-side
|
|
133
|
+
* budget at all — the watchdog's non-aggressive `POST /docker/prune` sends no
|
|
134
|
+
* body and no signal, so it was being reset at 10 s and reported as
|
|
135
|
+
* `auto-prune failed` while the worker kept pruning unobserved. 240 s covers
|
|
136
|
+
* those with room for the IO stalls this exists for, and leaves the ceiling
|
|
137
|
+
* visible rather than sitting on it.
|
|
138
|
+
*/
|
|
139
|
+
worker: 240,
|
|
140
|
+
/**
|
|
141
|
+
* `packages/mcp/bin/percher-mcp-http.ts`. Public through Caddy, so not the
|
|
142
|
+
* place for the ceiling either. Its longest legitimate single POST is
|
|
143
|
+
* `percher_wait_for_deploy`, whose hosted schema clamps `timeoutSeconds` to
|
|
144
|
+
* 120; 180 s covers that plus the internal API hop and JSON-RPC framing.
|
|
145
|
+
* Every hosted call carries a JSON-RPC body, so this is a guard rather than
|
|
146
|
+
* a fix for an observed failure.
|
|
147
|
+
*/
|
|
148
|
+
hostedMcp: 180,
|
|
149
|
+
};
|
|
66
150
|
//# sourceMappingURL=timeouts.js.map
|
package/dist/timeouts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeouts.js","sourceRoot":"","sources":["../src/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB;;;;;OAKG;IACH,qBAAqB,EAAE,EAAE,GAAG,MAAM;IAElC;;;;;;OAMG;IACH,qBAAqB,EAAE,EAAE,GAAG,MAAM;IAElC;;;;;OAKG;IACH,iBAAiB,EAAE,EAAE,GAAG,MAAM;IAE9B,2CAA2C;IAC3C,iBAAiB,EAAE,KAAK;IAExB,2CAA2C;IAC3C,YAAY,EAAE,MAAM;IAEpB,uEAAuE;IACvE,oBAAoB,EAAE,MAAM;IAE5B;;;;;;OAMG;IACH,gBAAgB,EAAE,EAAE,GAAG,MAAM;CACrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"timeouts.js","sourceRoot":"","sources":["../src/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB;;;;;OAKG;IACH,qBAAqB,EAAE,EAAE,GAAG,MAAM;IAElC;;;;;;OAMG;IACH,qBAAqB,EAAE,EAAE,GAAG,MAAM;IAElC;;;;;OAKG;IACH,iBAAiB,EAAE,EAAE,GAAG,MAAM;IAE9B,2CAA2C;IAC3C,iBAAiB,EAAE,KAAK;IAExB,2CAA2C;IAC3C,YAAY,EAAE,MAAM;IAEpB,uEAAuE;IACvE,oBAAoB,EAAE,MAAM;IAE5B;;;;;;OAMG;IACH,gBAAgB,EAAE,EAAE,GAAG,MAAM;CACrB,CAAC;AAIX;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC;;;;;;;;;;;;;;;;;OAiBG;IACH,GAAG,EAAE,GAAG;IACR;;;;;;;;;;OAUG;IACH,MAAM,EAAE,GAAG;IACX;;;;;;;OAOG;IACH,SAAS,EAAE,GAAG;CACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percher/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Shared constants and contracts (timeouts, etc.) used across the Percher CLI, API, MCP, and worker. Internal — values change in lockstep across packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
13
|
},
|
|
14
|
+
"./brand": {
|
|
15
|
+
"types": "./dist/brand.d.ts",
|
|
16
|
+
"import": "./dist/brand.js",
|
|
17
|
+
"default": "./dist/brand.js"
|
|
18
|
+
},
|
|
14
19
|
"./timeouts": {
|
|
15
20
|
"types": "./dist/timeouts.d.ts",
|
|
16
21
|
"import": "./dist/timeouts.js",
|
|
@@ -30,6 +35,11 @@
|
|
|
30
35
|
"types": "./dist/pow.d.ts",
|
|
31
36
|
"import": "./dist/pow.js",
|
|
32
37
|
"default": "./dist/pow.js"
|
|
38
|
+
},
|
|
39
|
+
"./signup-invite-hash": {
|
|
40
|
+
"types": "./dist/signup-invite-hash.d.ts",
|
|
41
|
+
"import": "./dist/signup-invite-hash.js",
|
|
42
|
+
"default": "./dist/signup-invite-hash.js"
|
|
33
43
|
}
|
|
34
44
|
},
|
|
35
45
|
"files": [
|
|
@@ -44,7 +54,7 @@
|
|
|
44
54
|
"bun-types": "^1.1.0",
|
|
45
55
|
"tsc-alias": "^1.8.17"
|
|
46
56
|
},
|
|
47
|
-
"license": "MIT",
|
|
57
|
+
"license": "FSL-1.1-MIT",
|
|
48
58
|
"author": "Mattias Malmborg",
|
|
49
59
|
"repository": {
|
|
50
60
|
"type": "git",
|