@nimbus-sh/worker 0.10.0 → 0.11.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.
Files changed (260) hide show
  1. package/NOTICE.md +5 -0
  2. package/README.md +10 -0
  3. package/dist/_shared/session-router.d.ts +7 -0
  4. package/dist/_shared/session-router.d.ts.map +1 -1
  5. package/dist/_shared/session-router.js +7 -0
  6. package/dist/bindings/body.d.ts +6 -0
  7. package/dist/bindings/body.d.ts.map +1 -0
  8. package/dist/bindings/body.js +37 -0
  9. package/dist/bindings/kv.d.ts +0 -2
  10. package/dist/bindings/kv.d.ts.map +1 -1
  11. package/dist/bindings/kv.js +3 -42
  12. package/dist/bindings/r2.d.ts +0 -2
  13. package/dist/bindings/r2.d.ts.map +1 -1
  14. package/dist/bindings/r2.js +4 -44
  15. package/dist/esbuild-cli-artifact.generated.d.ts +18 -0
  16. package/dist/esbuild-cli-artifact.generated.d.ts.map +1 -0
  17. package/dist/esbuild-cli-artifact.generated.js +17 -0
  18. package/dist/facets/cirrus-real.d.ts.map +1 -1
  19. package/dist/facets/cirrus-real.js +9 -4
  20. package/dist/facets/compose.d.ts +11 -7
  21. package/dist/facets/compose.d.ts.map +1 -1
  22. package/dist/facets/compose.js +8 -38
  23. package/dist/facets/data-plan.d.ts +79 -0
  24. package/dist/facets/data-plan.d.ts.map +1 -0
  25. package/dist/facets/data-plan.js +477 -0
  26. package/dist/facets/esbuild-transform.d.ts +36 -10
  27. package/dist/facets/esbuild-transform.d.ts.map +1 -1
  28. package/dist/facets/esbuild-transform.js +216 -20
  29. package/dist/facets/exec-telemetry.d.ts +7 -3
  30. package/dist/facets/exec-telemetry.d.ts.map +1 -1
  31. package/dist/facets/manager.d.ts +179 -78
  32. package/dist/facets/manager.d.ts.map +1 -1
  33. package/dist/facets/manager.js +1221 -649
  34. package/dist/facets/opencode-staging.d.ts +0 -2
  35. package/dist/facets/opencode-staging.d.ts.map +1 -1
  36. package/dist/facets/opencode-staging.js +5 -11
  37. package/dist/facets/process.d.ts +4 -0
  38. package/dist/facets/process.d.ts.map +1 -1
  39. package/dist/facets/process.js +3 -0
  40. package/dist/facets/read-profile.d.ts +149 -0
  41. package/dist/facets/read-profile.d.ts.map +1 -0
  42. package/dist/facets/read-profile.js +483 -0
  43. package/dist/facets/resident-identity.d.ts +0 -1
  44. package/dist/facets/resident-identity.d.ts.map +1 -1
  45. package/dist/facets/resident-identity.js +0 -3
  46. package/dist/facets/wasm-swap-registry.d.ts +34 -25
  47. package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
  48. package/dist/facets/wasm-swap-registry.js +62 -56
  49. package/dist/facets/ws-terminal.d.ts +4 -4
  50. package/dist/facets/ws-terminal.d.ts.map +1 -1
  51. package/dist/facets/ws-terminal.js +4 -5
  52. package/dist/git/commands.d.ts +16 -9
  53. package/dist/git/commands.d.ts.map +1 -1
  54. package/dist/git/commands.js +1818 -188
  55. package/dist/git/network-facet.d.ts +10 -2
  56. package/dist/git/network-facet.d.ts.map +1 -1
  57. package/dist/git/network-facet.js +62 -16
  58. package/dist/git/unified-diff.d.ts +74 -0
  59. package/dist/git/unified-diff.d.ts.map +1 -0
  60. package/dist/git/unified-diff.js +676 -0
  61. package/dist/git-bundle.generated.d.ts +7 -11
  62. package/dist/git-bundle.generated.d.ts.map +1 -1
  63. package/dist/git-bundle.generated.js +7 -11
  64. package/dist/hosted/commands.d.ts.map +1 -1
  65. package/dist/hosted/commands.js +62 -243
  66. package/dist/hosted/runtime.d.ts +19 -13
  67. package/dist/hosted/runtime.d.ts.map +1 -1
  68. package/dist/hosted/runtime.js +71 -14
  69. package/dist/hosted/services.d.ts +6 -7
  70. package/dist/hosted/services.d.ts.map +1 -1
  71. package/dist/hosted/services.js +10 -14
  72. package/dist/hosted/session.d.ts +165 -0
  73. package/dist/hosted/session.d.ts.map +1 -0
  74. package/dist/hosted/session.js +132 -0
  75. package/dist/loaders/generated-workers.d.ts +5 -2
  76. package/dist/loaders/generated-workers.d.ts.map +1 -1
  77. package/dist/loaders/generated-workers.js +6 -3
  78. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
  79. package/dist/loaders/npm-resolve-preamble.js +0 -27
  80. package/dist/node-shims-artifact.generated.d.ts +13 -4
  81. package/dist/node-shims-artifact.generated.d.ts.map +1 -1
  82. package/dist/node-shims-artifact.generated.js +16 -7
  83. package/dist/npm/bin-links.d.ts +3 -1
  84. package/dist/npm/bin-links.d.ts.map +1 -1
  85. package/dist/npm/bin-links.js +32 -8
  86. package/dist/npm/cache.d.ts +5 -0
  87. package/dist/npm/cache.d.ts.map +1 -1
  88. package/dist/npm/cache.js +13 -1
  89. package/dist/npm/install-batch-facet.d.ts +2 -2
  90. package/dist/npm/install-batch-facet.js +3 -3
  91. package/dist/npm/installer.d.ts +17 -1
  92. package/dist/npm/installer.d.ts.map +1 -1
  93. package/dist/npm/installer.js +159 -20
  94. package/dist/npm/package-lock.d.ts +32 -0
  95. package/dist/npm/package-lock.d.ts.map +1 -0
  96. package/dist/npm/package-lock.js +65 -0
  97. package/dist/npm/pre-bundle-facet.d.ts +1 -30
  98. package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
  99. package/dist/npm/pre-bundle-facet.js +3 -5
  100. package/dist/npm/r2-cache.d.ts +2 -0
  101. package/dist/npm/r2-cache.d.ts.map +1 -1
  102. package/dist/npm/r2-cache.js +2 -0
  103. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  104. package/dist/npm/resolve-one-facet.js +14 -3
  105. package/dist/npm/resolver.d.ts +0 -7
  106. package/dist/npm/resolver.d.ts.map +1 -1
  107. package/dist/npm/resolver.js +0 -22
  108. package/dist/opencode-artifact.generated.js +2 -2
  109. package/dist/replica/routing.d.ts +2 -38
  110. package/dist/replica/routing.d.ts.map +1 -1
  111. package/dist/replica/routing.js +3 -55
  112. package/dist/router/index.d.ts.map +1 -1
  113. package/dist/router/index.js +15 -2
  114. package/dist/router/public-directory.d.ts +18 -0
  115. package/dist/router/public-directory.d.ts.map +1 -1
  116. package/dist/router/public-directory.js +1 -1
  117. package/dist/router/remote-api.d.ts +3 -1
  118. package/dist/router/remote-api.d.ts.map +1 -1
  119. package/dist/router/remote-api.js +42 -79
  120. package/dist/runtime/bash-repl.js +2 -2
  121. package/dist/runtime/bun-repl.d.ts.map +1 -1
  122. package/dist/runtime/bun-repl.js +2 -13
  123. package/dist/runtime/esbuild-wasm-bytes.d.ts +17 -5
  124. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -1
  125. package/dist/runtime/esbuild-wasm-bytes.js +43 -94
  126. package/dist/runtime/git-bundle-artifact.d.ts +17 -0
  127. package/dist/runtime/git-bundle-artifact.d.ts.map +1 -0
  128. package/dist/runtime/git-bundle-artifact.js +25 -0
  129. package/dist/runtime/node-repl.d.ts.map +1 -1
  130. package/dist/runtime/node-repl.js +2 -13
  131. package/dist/runtime/node-shims-artifact.d.ts +22 -23
  132. package/dist/runtime/node-shims-artifact.d.ts.map +1 -1
  133. package/dist/runtime/node-shims-artifact.js +48 -78
  134. package/dist/runtime/node-shims.d.ts.map +1 -1
  135. package/dist/runtime/node-shims.js +1567 -864
  136. package/dist/runtime/opencode-artifact.d.ts.map +1 -1
  137. package/dist/runtime/opencode-artifact.js +17 -53
  138. package/dist/runtime/opencode-facet-runner.d.ts +3 -6
  139. package/dist/runtime/opencode-facet-runner.d.ts.map +1 -1
  140. package/dist/runtime/opencode-facet-runner.js +45 -10
  141. package/dist/runtime/opentui-wasm-bytes.d.ts.map +1 -1
  142. package/dist/runtime/opentui-wasm-bytes.js +16 -49
  143. package/dist/runtime/package-manager.d.ts +0 -2
  144. package/dist/runtime/package-manager.d.ts.map +1 -1
  145. package/dist/runtime/package-manager.js +0 -3
  146. package/dist/runtime/python-repl.d.ts.map +1 -1
  147. package/dist/runtime/python-repl.js +2 -2
  148. package/dist/runtime/repl-session.d.ts +10 -0
  149. package/dist/runtime/repl-session.d.ts.map +1 -1
  150. package/dist/runtime/repl-session.js +7 -0
  151. package/dist/runtime/ruby-repl.d.ts.map +1 -1
  152. package/dist/runtime/ruby-repl.js +2 -2
  153. package/dist/runtime/ruby-resident.d.ts.map +1 -1
  154. package/dist/runtime/ruby-resident.js +36 -35
  155. package/dist/runtime/runtime-catalog.d.ts +10 -3
  156. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  157. package/dist/runtime/runtime-catalog.js +125 -15
  158. package/dist/runtime/sqlite-wasm-bytes.d.ts +4 -4
  159. package/dist/runtime/sqlite-wasm-bytes.d.ts.map +1 -1
  160. package/dist/runtime/sqlite-wasm-bytes.js +21 -57
  161. package/dist/runtime/staged-source.d.ts +67 -0
  162. package/dist/runtime/staged-source.d.ts.map +1 -0
  163. package/dist/runtime/staged-source.js +113 -0
  164. package/dist/runtime/wasi/preamble.d.ts.map +1 -1
  165. package/dist/runtime/wasi/preamble.js +0 -24
  166. package/dist/runtime-catalog.generated.js +1 -1
  167. package/dist/session/agent.d.ts +14 -2
  168. package/dist/session/agent.d.ts.map +1 -1
  169. package/dist/session/agent.js +57 -19
  170. package/dist/session/ai.d.ts +0 -11
  171. package/dist/session/ai.d.ts.map +1 -1
  172. package/dist/session/ai.js +0 -4
  173. package/dist/session/fs-watch.d.ts +0 -11
  174. package/dist/session/fs-watch.d.ts.map +1 -1
  175. package/dist/session/fs-watch.js +0 -21
  176. package/dist/session/hibernation.d.ts +34 -11
  177. package/dist/session/hibernation.d.ts.map +1 -1
  178. package/dist/session/hibernation.js +46 -29
  179. package/dist/session/init-phases.d.ts +1 -2
  180. package/dist/session/init-phases.d.ts.map +1 -1
  181. package/dist/session/init-phases.js +1 -2
  182. package/dist/session/init.d.ts.map +1 -1
  183. package/dist/session/init.js +7 -20
  184. package/dist/session/keys.d.ts +0 -3
  185. package/dist/session/keys.d.ts.map +1 -1
  186. package/dist/session/keys.js +0 -3
  187. package/dist/session/legacy-reset.d.ts +11 -0
  188. package/dist/session/legacy-reset.d.ts.map +1 -0
  189. package/dist/session/legacy-reset.js +16 -0
  190. package/dist/session/nimbus-session.d.ts +41 -15
  191. package/dist/session/nimbus-session.d.ts.map +1 -1
  192. package/dist/session/nimbus-session.js +64 -70
  193. package/dist/session/npm-install-port.d.ts.map +1 -1
  194. package/dist/session/npm-install-port.js +1 -0
  195. package/dist/session/programmatic.d.ts +13 -18
  196. package/dist/session/programmatic.d.ts.map +1 -1
  197. package/dist/session/programmatic.js +53 -39
  198. package/dist/session/replica-routes.d.ts +2 -3
  199. package/dist/session/replica-routes.d.ts.map +1 -1
  200. package/dist/session/replica-routes.js +3 -10
  201. package/dist/session/routes.d.ts.map +1 -1
  202. package/dist/session/routes.js +7 -10
  203. package/dist/session/rpc.d.ts +104 -20
  204. package/dist/session/rpc.d.ts.map +1 -1
  205. package/dist/session/rpc.js +184 -37
  206. package/dist/session/start-real-vite.js +2 -2
  207. package/dist/session/state-store.d.ts +1 -17
  208. package/dist/session/state-store.d.ts.map +1 -1
  209. package/dist/session/state-store.js +3 -53
  210. package/dist/session/supervisor-op.d.ts +7 -0
  211. package/dist/session/supervisor-op.d.ts.map +1 -1
  212. package/dist/session/supervisor-op.js +6 -1
  213. package/dist/session/supervisor-rpc.d.ts +104 -15
  214. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  215. package/dist/session/supervisor-rpc.js +188 -71
  216. package/dist/session/vite-command.d.ts.map +1 -1
  217. package/dist/session/vite-command.js +17 -14
  218. package/dist/session/ws.d.ts.map +1 -1
  219. package/dist/session/ws.js +20 -8
  220. package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
  221. package/dist/shell/npm-bin-entrypoints.js +30 -5
  222. package/dist/vfs/facet-resident-limits.d.ts +33 -0
  223. package/dist/vfs/facet-resident-limits.d.ts.map +1 -0
  224. package/dist/vfs/facet-resident-limits.js +33 -0
  225. package/dist/vfs/facet-resident-store.d.ts +2 -10
  226. package/dist/vfs/facet-resident-store.d.ts.map +1 -1
  227. package/dist/vfs/facet-resident-store.js +1594 -219
  228. package/dist/workspace-host.d.ts +2 -0
  229. package/dist/workspace-host.d.ts.map +1 -1
  230. package/dist/workspace-host.js +2 -0
  231. package/dist/wrangler/nimbus-wrangler.d.ts +0 -2
  232. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -1
  233. package/dist/wrangler/nimbus-wrangler.js +5 -22
  234. package/package.json +8 -7
  235. package/public/_assets/opencode/1.16.2/index-attach.js +2 -2
  236. package/public/_assets/runtime/esbuild-cli-c4fda380d52befc1.js +6892 -0
  237. package/public/_assets/runtime/git-de3e60c9f3ff006a.js +103 -0
  238. package/public/_assets/runtime/{node-shims-7b4dd7a76d95d21e.js → node-shims-06565b121555c194.js} +2089 -861
  239. package/public/_assets/runtime/resident-store-6ffb1939c53d982f.js +2264 -0
  240. package/public/_assets/runtime/vfs-write-ledger-e501e8fc793bc2c1.js +889 -0
  241. package/scripts/build-opencode-attach-entry.mjs +51 -1
  242. package/scripts/bundle-facet-workers.mjs +114 -3
  243. package/scripts/bundle-git.mjs +88 -27
  244. package/scripts/bundle-node-shims.mjs +72 -46
  245. package/scripts/bundle-runtime.mjs +18 -421
  246. package/scripts/cf-git-patch.mjs +137 -0
  247. package/scripts/patch-install-deps.mjs +49 -96
  248. package/scripts/runtime-specs.mjs +435 -0
  249. package/vendor/git-http.generated.d.ts +82 -0
  250. package/vendor/git-upstream.generated.d.ts +4378 -0
  251. package/vendor/git.LICENSE +7 -0
  252. package/vendor/git.generated.d.mts +21 -0
  253. package/vendor/git.generated.mjs +103 -0
  254. package/dist/replica/suspension.d.ts +0 -36
  255. package/dist/replica/suspension.d.ts.map +0 -1
  256. package/dist/replica/suspension.js +0 -49
  257. package/dist/runtime/static-server.d.ts +0 -3
  258. package/dist/runtime/static-server.d.ts.map +0 -1
  259. package/dist/runtime/static-server.js +0 -133
  260. package/scripts/clean-dist.mjs +0 -7
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { generateText, isLoopFinished, jsonSchema, streamText, tool as aiTool, } from 'ai';
11
11
  import { BASE_PATH_HEADER, TENANT_HEADER } from '../_shared/session-router.js';
12
- import { decodeJsonBase64Url, encodeJsonBase64Url, pkceChallenge, randomBase64Url, sealJson, unsealJson, } from '@nimbus-sh/core/_shared/crypto.js';
12
+ import { base64Url, base64UrlDecode, decodeJsonBase64Url, encodeJsonBase64Url, pkceChallenge, randomBase64Url, sealJson, unsealJson, } from '@nimbus-sh/core/_shared/crypto.js';
13
13
  import { clearNimbusAgentOAuthCookie, fetchNimbusCloudflareAccounts, isNimbusCloudflareAccountId, isNimbusTenantSegment, NIMBUS_CF_OAUTH_AUTH_URL, readNimbusCookie, readNimbusAgentCookieSecret, readNimbusAgentOAuthConfig, requestNimbusCloudflareOAuthToken, serializeNimbusCookie, } from './agent-oauth.js';
14
14
  import { clearSessionAiCredential, createSessionAiModel, describeSessionAiConnection, readSessionAiConfig, resolveSessionAiCredential, sessionAiAccountIsAvailable, setSessionAiAccount, storeSessionAiCredential, } from './ai.js';
15
15
  import { ensureProgrammaticReady, rpcExec, rpcEnsureRuntimes, rpcInstallRuntime, rpcExposeApp, rpcKillProcess, rpcListApps, rpcListPorts, rpcListProcesses, rpcProcessLogs, rpcStartProcess, } from './programmatic.js';
@@ -68,12 +68,29 @@ export async function handleAgentRequest(self, request, url) {
68
68
  }
69
69
  return json({ error: 'unknown agent endpoint' }, 404);
70
70
  }
71
- export function parseAgentOAuthStateParam(state) {
71
+ /**
72
+ * The OAuth `state` a callback carries, if this deployment signed it. The
73
+ * router routes a callback by the session and tenant segment in `state`, so an
74
+ * unsigned one would let any client wake or create a Durable Object under any
75
+ * tenant segment; the signature (HMAC-SHA256 under the agent cookie secret)
76
+ * makes the router refuse it before routing. An expired one (its signed `exp`
77
+ * at or before `now`) is refused the same way. Null for anything else.
78
+ */
79
+ export async function parseAgentOAuthStateParam(state, env, now = Date.now()) {
72
80
  if (!state)
73
81
  return null;
74
- const payload = decodeState(state);
82
+ let secret;
83
+ try {
84
+ secret = readNimbusAgentCookieSecret(env);
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ const payload = await decodeState(state, secret);
75
90
  if (!payload || payload.v !== 1)
76
91
  return null;
92
+ if (!Number.isSafeInteger(payload.exp) || payload.exp <= now)
93
+ return null;
77
94
  if (!isSessionId(payload.sessionId))
78
95
  return null;
79
96
  if (!isNimbusTenantSegment(payload.tenantSegment))
@@ -139,16 +156,19 @@ async function oauthStart(self, request, url) {
139
156
  const codeVerifier = randomBase64Url(48);
140
157
  const codeChallenge = await pkceChallenge(codeVerifier);
141
158
  const redirectUri = config.redirectUri;
142
- const payload = { v: 1, nonce, sessionId, tenantSegment };
143
- const state = encodeState(payload);
144
159
  const now = Date.now();
145
- const stored = {
146
- ...payload,
147
- codeVerifier,
148
- redirectUri,
149
- createdAt: now,
150
- expiresAt: now + OAUTH_STATE_TTL_MS,
151
- };
160
+ const payload = { v: 1, nonce, sessionId, tenantSegment, exp: now + OAUTH_STATE_TTL_MS };
161
+ let state;
162
+ try {
163
+ state = await signAgentOAuthState(payload, self.env);
164
+ }
165
+ catch (e) {
166
+ return json({
167
+ error: e?.message || String(e),
168
+ code: 'E_AGENT_COOKIE_SECRET',
169
+ }, 409);
170
+ }
171
+ const stored = { ...payload, codeVerifier, redirectUri, createdAt: now };
152
172
  const authUrl = new URL(NIMBUS_CF_OAUTH_AUTH_URL);
153
173
  authUrl.searchParams.set('client_id', config.oauthClientId);
154
174
  authUrl.searchParams.set('response_type', 'code');
@@ -169,18 +189,18 @@ async function oauthStart(self, request, url) {
169
189
  code: 'E_AGENT_COOKIE_SECRET',
170
190
  }, 409);
171
191
  }
172
- return json({ ok: true, authUrl: authUrl.toString(), expiresAt: stored.expiresAt }, 200, headers);
192
+ return json({ ok: true, authUrl: authUrl.toString(), expiresAt: stored.exp }, 200, headers);
173
193
  }
174
194
  async function oauthCallback(self, request, url) {
175
195
  const code = url.searchParams.get('code');
176
196
  const error = url.searchParams.get('error');
177
- const payload = parseAgentOAuthStateParam(url.searchParams.get('state'));
197
+ const payload = await parseAgentOAuthStateParam(url.searchParams.get('state'), self.env);
178
198
  if (error)
179
199
  return oauthResultHtml(false, 'Cloudflare authorization failed.', payload?.sessionId);
180
200
  if (!code || !payload)
181
201
  return oauthResultHtml(false, 'OAuth callback is missing code or state.', payload?.sessionId);
182
202
  const stored = await loadStateCookie(self, request);
183
- if (!stored || stored.expiresAt < Date.now()) {
203
+ if (!stored || !Number.isSafeInteger(stored.exp) || stored.exp <= Date.now()) {
184
204
  return oauthResultHtml(false, 'OAuth session expired. Connect again.', payload.sessionId);
185
205
  }
186
206
  if (stored.sessionId !== payload.sessionId ||
@@ -1071,12 +1091,30 @@ setTimeout(function(){ try { window.close(); } catch {} }, 700);
1071
1091
  headers: responseHeaders,
1072
1092
  });
1073
1093
  }
1074
- function encodeState(payload) {
1075
- return encodeJsonBase64Url(payload);
1094
+ const STATE_SIGNATURE_PURPOSE = 'nimbus-agent-oauth-state:v1';
1095
+ function stateSigningKey(secret, usage) {
1096
+ return crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, [usage]);
1097
+ }
1098
+ function stateSigned(body) {
1099
+ return new TextEncoder().encode(`${STATE_SIGNATURE_PURPOSE}\0${body}`);
1076
1100
  }
1077
- function decodeState(state) {
1101
+ /** The `state` an OAuth flow carries: `<payload>.<signature>`, both base64url. */
1102
+ export async function signAgentOAuthState(payload, env) {
1103
+ const secret = readNimbusAgentCookieSecret(env);
1104
+ const body = encodeJsonBase64Url(payload);
1105
+ const signature = await crypto.subtle.sign('HMAC', await stateSigningKey(secret, 'sign'), stateSigned(body));
1106
+ return `${body}.${base64Url(new Uint8Array(signature))}`;
1107
+ }
1108
+ async function decodeState(state, secret) {
1109
+ const dot = state.indexOf('.');
1110
+ if (dot <= 0 || dot !== state.lastIndexOf('.'))
1111
+ return null;
1112
+ const body = state.slice(0, dot);
1078
1113
  try {
1079
- return decodeJsonBase64Url(state);
1114
+ const signature = base64UrlDecode(state.slice(dot + 1));
1115
+ if (!await crypto.subtle.verify('HMAC', await stateSigningKey(secret, 'verify'), signature, stateSigned(body)))
1116
+ return null;
1117
+ return decodeJsonBase64Url(body);
1080
1118
  }
1081
1119
  catch {
1082
1120
  return null;
@@ -39,7 +39,6 @@
39
39
  * session; `captureSessionAiCredential` is the one place it is read.
40
40
  */
41
41
  import type { LanguageModel } from 'ai';
42
- import { z } from 'zod/v4';
43
42
  import type { PortRegistry } from '@nimbus-sh/core/runtime/port-registry.js';
44
43
  import { type NimbusCloudflareAccount } from './agent-oauth.js';
45
44
  export interface SessionAiHost {
@@ -82,13 +81,6 @@ export type SessionAiResolution = {
82
81
  ok: false;
83
82
  reason: SessionAiUnavailable;
84
83
  };
85
- declare const StoredCredentialSchema: z.ZodObject<{
86
- accessToken: z.ZodString;
87
- refreshToken: z.ZodOptional<z.ZodString>;
88
- accountId: z.ZodNullable<z.ZodString>;
89
- expiresAt: z.ZodNullable<z.ZodNumber>;
90
- }, z.core.$strip>;
91
- type StoredCredential = z.infer<typeof StoredCredentialSchema>;
92
84
  /** Base URL of the in-session endpoint. The one true address of this gateway. */
93
85
  export declare function sessionAiBaseUrl(): string;
94
86
  /**
@@ -183,13 +175,10 @@ export declare function createSessionAiModel(self: SessionAiHost): LanguageModel
183
175
  export declare function setSessionAiAccount(self: SessionAiHost, accountId: string): Promise<boolean>;
184
176
  /** Forget this session's credential (agent logout). */
185
177
  export declare function clearSessionAiCredential(self: SessionAiHost): Promise<void>;
186
- /** The stored credential, for surfaces that report connection state. */
187
- export declare function readSessionAiCredential(self: SessionAiHost): Promise<StoredCredential | null>;
188
178
  /**
189
179
  * Serve one OpenAI-compatible request. This is the whole gateway: the loopback
190
180
  * router calls it for the session's tools, and agent.ts calls it directly for
191
181
  * the Nimbus agent.
192
182
  */
193
183
  export declare function handleSessionAiRequest(self: SessionAiHost, request: Request): Promise<Response>;
194
- export {};
195
184
  //# sourceMappingURL=ai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/session/ai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/session/ai.ts"],"names":[],"mappings":"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"}
@@ -320,10 +320,6 @@ export async function clearSessionAiCredential(self) {
320
320
  lastSeenCookie.delete(self);
321
321
  await self.ctx.storage.delete(SESSION_AI_CREDENTIAL_KEY);
322
322
  }
323
- /** The stored credential, for surfaces that report connection state. */
324
- export async function readSessionAiCredential(self) {
325
- return readStoredCredential(self);
326
- }
327
323
  // ── The OpenAI-compatible endpoint ────────────────────────────────────────
328
324
  /**
329
325
  * Serve one OpenAI-compatible request. This is the whole gateway: the loopback
@@ -118,15 +118,4 @@ export declare function handleFsWatchUnsubscribe(host: FsWatchHost, ws: WebSocke
118
118
  * wsError. Idempotent + no-op when nothing pending.
119
119
  */
120
120
  export declare function cleanupFsWatchOnClose(host: FsWatchHost, ws: WebSocket): void;
121
- /**
122
- * Diagnostic: total subscriber + pending-event counts across the host.
123
- * Useful for /api/_diag/* surfaces and leak-detection probes (the
124
- * cleanup-on-disconnect probe asserts counts return to 0 after WS close).
125
- */
126
- export declare function getFsWatchStats(host: FsWatchHost): {
127
- wsCount: number;
128
- subCount: number;
129
- pendingTotal: number;
130
- droppedTotal: number;
131
- };
132
121
  //# sourceMappingURL=fs-watch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs-watch.d.ts","sourceRoot":"","sources":["../../src/session/fs-watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,2DAA2D;IAC3D,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,UAAU,EAAE,GAAG,CAAC;CACjB;AAiBD,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,SAAS,EACb,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA6F5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,SAAS,EACb,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgB/B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAS5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAcA"}
1
+ {"version":3,"file":"fs-watch.d.ts","sourceRoot":"","sources":["../../src/session/fs-watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,2DAA2D;IAC3D,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,UAAU,EAAE,GAAG,CAAC;CACjB;AAiBD,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,SAAS,EACb,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA6F5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,SAAS,EACb,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgB/B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAS5E"}
@@ -232,24 +232,3 @@ export function cleanupFsWatchOnClose(host, ws) {
232
232
  }
233
233
  map.delete(ws);
234
234
  }
235
- /**
236
- * Diagnostic: total subscriber + pending-event counts across the host.
237
- * Useful for /api/_diag/* surfaces and leak-detection probes (the
238
- * cleanup-on-disconnect probe asserts counts return to 0 after WS close).
239
- */
240
- export function getFsWatchStats(host) {
241
- const map = host._fsWatchSubs;
242
- if (!map)
243
- return { wsCount: 0, subCount: 0, pendingTotal: 0, droppedTotal: 0 };
244
- let subCount = 0;
245
- let pendingTotal = 0;
246
- let droppedTotal = 0;
247
- for (const list of map.values()) {
248
- subCount += list.length;
249
- for (const sub of list) {
250
- pendingTotal += sub.pending.length;
251
- droppedTotal += sub.dropped;
252
- }
253
- }
254
- return { wsCount: map.size, subCount, pendingTotal, droppedTotal };
255
- }
@@ -113,6 +113,12 @@ export declare function installLogPersistence(host: Pick<HibHost, '_w9PersistWir
113
113
  */
114
114
  export declare function clearDestroyedTombstone(host: HibHost, ctx: any): void;
115
115
  export declare function ensureLogJanitor(host: HibHost, ctx: any): void;
116
+ /** The fields the keep-alive rule reads and keeps; both hosts carry them. */
117
+ export type ResidentKeepaliveHost = Pick<HibHost, 'processes' | '_w1KeepaliveArmed' | '_w1LastClientActivityAt' | '_w1SessionDestroyed'>;
118
+ /** Arm the host's `resident-keepalive` alarm at `at`; resolves false when it could not. */
119
+ export type ResidentKeepaliveSchedule = (at: number) => Promise<boolean>;
120
+ /** Where a host's attached clients are counted: its hibernatable sockets. */
121
+ export type KeepaliveClients = Partial<Pick<DurableObjectState, 'getWebSockets'>>;
116
122
  /**
117
123
  * W1: arm the keep-alive alarm cycle for this instance, from the spawn hook
118
124
  * of a LONG-RUNNING process only.
@@ -121,14 +127,36 @@ export declare function ensureLogJanitor(host: HibHost, ctx: any): void;
121
127
  * platform evicts an idle object after roughly ten seconds, and a pending
122
128
  * `ctx.waitUntil` is not the in-flight event that counts (see
123
129
  * RESIDENT_KEEPALIVE_MS). A quiet process sends no RPC, so without this the
124
- * session idles out and the launch journal re-drives the process under a new
130
+ * host idles out and the launch journal re-drives the process under a new
125
131
  * pid namespace, dropping its attached terminal and its port. The alarm is
126
132
  * the event; its dispatch is the whole payload.
127
133
  *
128
- * Idempotent per instance via `_w1KeepaliveArmed`; dispatchAlarm clears the
129
- * flag when the last resident process is gone, so the next resident spawn
130
- * re-arms the cycle.
134
+ * The one rule for both hosts: the session DO schedules through the fabric
135
+ * timer mux, a hosted runtime through its embedder's lifecycle. Idempotent
136
+ * per instance via `_w1KeepaliveArmed`; `residentKeepaliveFired` clears the
137
+ * flag when the cycle ends, so the next resident spawn re-arms it.
131
138
  */
139
+ export declare function armResidentKeepalive(host: ResidentKeepaliveHost, schedule: ResidentKeepaliveSchedule): void;
140
+ /**
141
+ * W1: the keep-alive alarm fired. Deliberately no work: the alarm exists so
142
+ * the object HAS an event, and being dispatched is the entire payload.
143
+ * Returns when to fire next, or null after clearing the armed flag.
144
+ *
145
+ * Re-arms only while a resident process runs AND a client is present — the
146
+ * rule the janitor learned the hard way (see dispatchAlarm): an
147
+ * unconditional self-renewal makes every session boot its DO forever, and
148
+ * the fleet doing that resets live ones. Bounded by the resident alone, an
149
+ * abandoned dev server did exactly that. The next resident spawn, or the
150
+ * client's return, re-arms the cycle.
151
+ */
152
+ export declare function residentKeepaliveFired(host: ResidentKeepaliveHost, ctx: KeepaliveClients, now: number): number | null;
153
+ /**
154
+ * W1: a client reached the host. Records the moment, and re-arms the
155
+ * keep-alive if a resident is running and the cycle had lapsed: a host
156
+ * whose client came back before the platform evicted it still holds its
157
+ * process, and the next quiet stretch must not idle it out mid-session.
158
+ */
159
+ export declare function noteResidentClient(host: ResidentKeepaliveHost, schedule: ResidentKeepaliveSchedule): void;
132
160
  export declare function ensureResidentKeepalive(host: HibHost, ctx: any): void;
133
161
  /** W9: idempotent SQL schema bootstrap. */
134
162
  export declare function ensureHibSchema(host: Pick<HibHost, '_w9SchemaInit'>, ctx: any): void;
@@ -138,13 +166,8 @@ export declare function ensureHibSchema(host: Pick<HibHost, '_w9SchemaInit'>, ct
138
166
  * keep-alive re-arms on this and on a running resident, never on the
139
167
  * resident alone.
140
168
  */
141
- export declare function residentClientPresent(host: HibHost, ctx: any, now: number): boolean;
142
- /**
143
- * W1: a client reached the session. Records the moment, and re-arms the
144
- * keep-alive if a resident is running and the cycle had lapsed: a session
145
- * whose client came back before the platform evicted it still holds its
146
- * process, and the next quiet stretch must not idle it out mid-session.
147
- */
169
+ export declare function residentClientPresent(host: ResidentKeepaliveHost, ctx: KeepaliveClients, now: number): boolean;
170
+ /** W1: a client reached the session DO (see noteResidentClient). */
148
171
  export declare function noteClientActivity(host: HibHost, ctx: any): void;
149
172
  /**
150
173
  * W1: this session's canonical alarm-reason strings, registered on the
@@ -1 +1 @@
1
- {"version":3,"file":"hibernation.d.ts","sourceRoot":"","sources":["../../src/session/hibernation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,EAA0B,KAAK,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACpH,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAIrE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,SAAS,EAAE,wBAAwB,CAAC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,GAAG,GAAG,yBAAyB,CAY9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAKnE;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,GAAG,WAAW,CAAC,EACtE,GAAG,EAAE,kBAAkB,EACvB,UAAU,EAAE,MAAM,IAAI,GACrB,IAAI,CA0GN;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAc9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAerE;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqBpF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAInF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAGhE;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAEhG;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqB9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,GAAG,EACR,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC7C,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC1C,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAMhD"}
1
+ {"version":3,"file":"hibernation.d.ts","sourceRoot":"","sources":["../../src/session/hibernation.ts"],"names":[],"mappings":"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"}
@@ -239,15 +239,16 @@ export function ensureLogJanitor(host, ctx) {
239
239
  * platform evicts an idle object after roughly ten seconds, and a pending
240
240
  * `ctx.waitUntil` is not the in-flight event that counts (see
241
241
  * RESIDENT_KEEPALIVE_MS). A quiet process sends no RPC, so without this the
242
- * session idles out and the launch journal re-drives the process under a new
242
+ * host idles out and the launch journal re-drives the process under a new
243
243
  * pid namespace, dropping its attached terminal and its port. The alarm is
244
244
  * the event; its dispatch is the whole payload.
245
245
  *
246
- * Idempotent per instance via `_w1KeepaliveArmed`; dispatchAlarm clears the
247
- * flag when the last resident process is gone, so the next resident spawn
248
- * re-arms the cycle.
246
+ * The one rule for both hosts: the session DO schedules through the fabric
247
+ * timer mux, a hosted runtime through its embedder's lifecycle. Idempotent
248
+ * per instance via `_w1KeepaliveArmed`; `residentKeepaliveFired` clears the
249
+ * flag when the cycle ends, so the next resident spawn re-arms it.
249
250
  */
250
- export function ensureResidentKeepalive(host, ctx) {
251
+ export function armResidentKeepalive(host, schedule) {
251
252
  if (host._w1KeepaliveArmed)
252
253
  return;
253
254
  if (host.processes.residentRunning === 0)
@@ -258,15 +259,46 @@ export function ensureResidentKeepalive(host, ctx) {
258
259
  if (host._w1SessionDestroyed)
259
260
  return;
260
261
  // Optimistic flag (dedupes same-turn spawns), CONFIRMED by the schedule
261
- // outcome: timers.schedule swallows storage errors, and a failure with the
262
- // flag left set would mean no alarm AND nothing ever re-arming until the
263
- // instance recycles.
262
+ // outcome: a failure with the flag left set would mean no alarm AND
263
+ // nothing ever re-arming until the instance recycles.
264
264
  host._w1KeepaliveArmed = true;
265
- void timers(host, ctx).schedule('resident-keepalive', Date.now() + RESIDENT_KEEPALIVE_MS).then((ok) => {
265
+ void schedule(Date.now() + RESIDENT_KEEPALIVE_MS).then((ok) => {
266
266
  if (!ok)
267
267
  host._w1KeepaliveArmed = false;
268
268
  });
269
269
  }
270
+ /**
271
+ * W1: the keep-alive alarm fired. Deliberately no work: the alarm exists so
272
+ * the object HAS an event, and being dispatched is the entire payload.
273
+ * Returns when to fire next, or null after clearing the armed flag.
274
+ *
275
+ * Re-arms only while a resident process runs AND a client is present — the
276
+ * rule the janitor learned the hard way (see dispatchAlarm): an
277
+ * unconditional self-renewal makes every session boot its DO forever, and
278
+ * the fleet doing that resets live ones. Bounded by the resident alone, an
279
+ * abandoned dev server did exactly that. The next resident spawn, or the
280
+ * client's return, re-arms the cycle.
281
+ */
282
+ export function residentKeepaliveFired(host, ctx, now) {
283
+ if (host.processes.residentRunning > 0 && residentClientPresent(host, ctx, now)) {
284
+ return now + RESIDENT_KEEPALIVE_MS;
285
+ }
286
+ host._w1KeepaliveArmed = false;
287
+ return null;
288
+ }
289
+ /**
290
+ * W1: a client reached the host. Records the moment, and re-arms the
291
+ * keep-alive if a resident is running and the cycle had lapsed: a host
292
+ * whose client came back before the platform evicted it still holds its
293
+ * process, and the next quiet stretch must not idle it out mid-session.
294
+ */
295
+ export function noteResidentClient(host, schedule) {
296
+ host._w1LastClientActivityAt = Date.now();
297
+ armResidentKeepalive(host, schedule);
298
+ }
299
+ export function ensureResidentKeepalive(host, ctx) {
300
+ armResidentKeepalive(host, (at) => timers(host, ctx).schedule('resident-keepalive', at));
301
+ }
270
302
  /** W9: idempotent SQL schema bootstrap. */
271
303
  export function ensureHibSchema(host, ctx) {
272
304
  if (host._w9SchemaInit)
@@ -300,15 +332,9 @@ export function residentClientPresent(host, ctx, now) {
300
332
  return true;
301
333
  return now - host._w1LastClientActivityAt < RESIDENT_KEEPALIVE_DETACHED_MS;
302
334
  }
303
- /**
304
- * W1: a client reached the session. Records the moment, and re-arms the
305
- * keep-alive if a resident is running and the cycle had lapsed: a session
306
- * whose client came back before the platform evicted it still holds its
307
- * process, and the next quiet stretch must not idle it out mid-session.
308
- */
335
+ /** W1: a client reached the session DO (see noteResidentClient). */
309
336
  export function noteClientActivity(host, ctx) {
310
- host._w1LastClientActivityAt = Date.now();
311
- ensureResidentKeepalive(host, ctx);
337
+ noteResidentClient(host, (at) => timers(host, ctx).schedule('resident-keepalive', at));
312
338
  }
313
339
  /**
314
340
  * W9: ensure the alarm is set for the next flush window. Cheap to
@@ -385,18 +411,9 @@ export function dispatchAlarm(host, ctx, janitorOrphanCheck, pumpResidentLaunche
385
411
  host._w1JanitorArmed = false;
386
412
  },
387
413
  'resident-keepalive': (now) => {
388
- // Deliberately no work: this alarm exists so the object HAS an event,
389
- // and being dispatched is the entire payload. Re-arm only while a
390
- // resident process runs AND a client is present — the same rule the
391
- // janitor learned the hard way (see its comment above): an
392
- // unconditional self-renewal makes every session boot its DO forever,
393
- // and the fleet doing that resets live ones. Bounded by the resident
394
- // alone, an abandoned dev server did exactly that. The next resident
395
- // spawn, or the client's return, re-arms the cycle.
396
- if (host.processes.residentRunning > 0 && residentClientPresent(host, ctx, now)) {
397
- return { rearmAt: now + RESIDENT_KEEPALIVE_MS };
398
- }
399
- host._w1KeepaliveArmed = false;
414
+ const rearmAt = residentKeepaliveFired(host, ctx, now);
415
+ if (rearmAt !== null)
416
+ return { rearmAt };
400
417
  },
401
418
  }, () => {
402
419
  // Legacy path: pre-W1 deploys had no map. dispatchAlarm was called
@@ -15,8 +15,7 @@
15
15
  * (cwd, env, mounts, scrollback). Pure SQL reads;
16
16
  * sets up locals consumed by later phases.
17
17
  * - build: Phase B — constructing Kernel + Shell + registry +
18
- * installing 60+ commands + wiring SqliteVFSProvider
19
- * mounts. Most CPU-intensive phase.
18
+ * installing 60+ commands. Most CPU-intensive phase.
20
19
  * - wire: Phase W — attaching the WebSocketTerminal to the
21
20
  * Shell, replaying persisted scrollback into the WS.
22
21
  * This is the phase B'.5 will be able to re-run on
@@ -1 +1 @@
1
- {"version":3,"file":"init-phases.d.ts","sourceRoot":"","sources":["../../src/session/init-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAElG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EACtD,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,iBAAiB,CAG7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE;IACJ,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC5B,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAiCN"}
1
+ {"version":3,"file":"init-phases.d.ts","sourceRoot":"","sources":["../../src/session/init-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAElG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EACtD,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,iBAAiB,CAG7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE;IACJ,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC5B,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAiCN"}
@@ -15,8 +15,7 @@
15
15
  * (cwd, env, mounts, scrollback). Pure SQL reads;
16
16
  * sets up locals consumed by later phases.
17
17
  * - build: Phase B — constructing Kernel + Shell + registry +
18
- * installing 60+ commands + wiring SqliteVFSProvider
19
- * mounts. Most CPU-intensive phase.
18
+ * installing 60+ commands. Most CPU-intensive phase.
20
19
  * - wire: Phase W — attaching the WebSocketTerminal to the
21
20
  * Shell, replaying persisted scrollback into the WS.
22
21
  * This is the phase B'.5 will be able to re-run on
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;GAQG;AACH,KAAK,QAAQ,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAAC;AAQ3E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC/B;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,SAAS,GAAG,IAAI,EACpB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAkcf"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;GAQG;AACH,KAAK,QAAQ,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAAC;AAQ3E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC/B;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,SAAS,GAAG,IAAI,EACpB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqbf"}
@@ -17,8 +17,8 @@ import { errorText } from '@nimbus-sh/core/_shared/error-text.js';
17
17
  // one-time Worker Startup Time paid on every fresh-isolate cold run.
18
18
  import { hasSeededProject, SEED_PROJECT_DIR, SEED_PROJECT_NAME, SEED_PROJECT_TILDE } from '@nimbus-sh/core/vfs/seed-project.js';
19
19
  import { generation } from '@nimbus-sh/fabric/generation.js';
20
- import { DEFAULT_MOUNT_POINTS } from '@nimbus-sh/core/constants.js';
21
- import { ensureSessionStateSchema, loadShellState, stampHydratedAt, countSessionStateKeys, loadKernelMounts, persistKernelMounts, loadScrollback } from './state-store.js';
20
+ import { takeLegacyResetNotice } from './legacy-reset.js';
21
+ import { ensureSessionStateSchema, loadShellState, stampHydratedAt, countSessionStateKeys, loadScrollback } from './state-store.js';
22
22
  import { recordRecoveryEvent } from '@nimbus-sh/platform/oom-discriminator.js';
23
23
  import { sessionAiEnv } from './ai.js';
24
24
  import { setPhase } from './init-phases.js';
@@ -49,6 +49,8 @@ export async function initSession(self, ws, options = {}) {
49
49
  // later phases.
50
50
  setPhase(self, 'rehydrate', 'init-session');
51
51
  ensureSessionStateSchema(self.ctx);
52
+ // Files a pre-v2 Nimbus wrote are not read: say so, and start cold.
53
+ const legacyNotice = takeLegacyResetNotice(self.sqliteFs, self.ctx);
52
54
  const persisted = loadShellState(self.ctx);
53
55
  // [B'.4] Phase W (early-wire) — construct WebSocketTerminal with
54
56
  // the B'.3 scrollback tee. Marked as 'wire' here even though
@@ -115,18 +117,6 @@ export async function initSession(self, ws, options = {}) {
115
117
  // commands and wiring on top. CPU-intensive phase. Spans from here
116
118
  // through Phase O.
117
119
  setPhase(self, 'build', 'init-session');
118
- // ── Mount list = DEFAULT_MOUNT_POINTS ∪ persisted-mounts [B'.2] ──
119
- //
120
- // The defaults are always present (they're platform invariants);
121
- // any extras a future custom-mount feature might add survive
122
- // reconnect via the nimbus_kernel_mounts table. The persist step
123
- // below writes the merged list back so the table tracks the live
124
- // mount tree — today the same 7 rows every initSession.
125
- const persistedMounts = loadKernelMounts(self.ctx);
126
- const mountPoints = Array.from(new Set([
127
- ...DEFAULT_MOUNT_POINTS,
128
- ...persistedMounts,
129
- ]));
130
120
  // ── What the session adds to the workspace's environment [B'.1] ──
131
121
  //
132
122
  // The platform defaults — PATH, PS1, HOME, PORT, HOST and the rest —
@@ -179,8 +169,7 @@ export async function initSession(self, ws, options = {}) {
179
169
  // have been called many requests ago; a second SqliteVFS over the
180
170
  // same rows would be a second cache serving stale reads.
181
171
  vfs: self.sqliteFs,
182
- filesystem: () => self.getFilesystemAuthority(),
183
- mounts: mountPoints,
172
+ filesystem: self.getFilesystemAuthority(),
184
173
  env: envOverlay,
185
174
  terminal: self.terminal,
186
175
  processes: self.processes,
@@ -196,10 +185,6 @@ export async function initSession(self, ws, options = {}) {
196
185
  const env = workspace.env;
197
186
  const sqliteFs = self.sqliteFs;
198
187
  const facetMgr = self.facetManager;
199
- try {
200
- persistKernelMounts(self.ctx, mountPoints);
201
- }
202
- catch { /* fail-soft */ }
203
188
  // ── editor/monaco (2026-05-13): editor-pane fs bridge ──
204
189
  //
205
190
  // The terminal hosts the WS that the editor pane reuses for
@@ -377,6 +362,8 @@ export async function initSession(self, ws, options = {}) {
377
362
  self.terminal.write(motd + '\r\n');
378
363
  }
379
364
  catch { }
365
+ if (legacyNotice)
366
+ self.terminal.write(`\x1b[33m${legacyNotice}\x1b[0m\r\n\r\n`);
380
367
  // ── Starter-app hint (only if seed sentinel still exists) ──
381
368
  // We check the live VFS, not a static file, so that if the user
382
369
  // deletes ~/.nimbus-seeded (or the project dir) the hint stops
@@ -24,9 +24,6 @@ export declare const W9_FLUSH_DEBOUNCE_MS = 250;
24
24
  * Bounded ≤20 KB by oom-discriminator.ts; persisted on ws close/error
25
25
  * so cf-tail-style forensics survive DO hibernation. */
26
26
  export declare const W5_RING_STORAGE_KEY = "w5_oom_ring_v1";
27
- /** Storage key for the session URL prefix (e.g. /s/nimble-otter-4271).
28
- * Set once per session from the X-Nimbus-Base header. */
29
- export declare const SESSION_BASE_PATH_KEY = "session-base-path";
30
27
  /** Storage key for the persisted vite-config blob. Survives DO
31
28
  * hibernation so vite resumes serving after wake without re-running
32
29
  * /api/start-vite. */
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH;2EAC2E;AAC3E,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;yDAEyD;AACzD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD;0DAC0D;AAC1D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;uBAEuB;AACvB,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;;4EAG4E;AAC5E,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,4FAA4F;AAC5F,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH;2EAC2E;AAC3E,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;yDAEyD;AACzD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAKpD;;uBAEuB;AACvB,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;;4EAG4E;AAC5E,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,4FAA4F;AAC5F,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC"}
@@ -28,9 +28,6 @@ export const W9_FLUSH_DEBOUNCE_MS = 250;
28
28
  * Bounded ≤20 KB by oom-discriminator.ts; persisted on ws close/error
29
29
  * so cf-tail-style forensics survive DO hibernation. */
30
30
  export const W5_RING_STORAGE_KEY = 'w5_oom_ring_v1';
31
- /** Storage key for the session URL prefix (e.g. /s/nimble-otter-4271).
32
- * Set once per session from the X-Nimbus-Base header. */
33
- export const SESSION_BASE_PATH_KEY = 'session-base-path';
34
31
  /** Storage key for the persisted vite-config blob. Survives DO
35
32
  * hibernation so vite resumes serving after wake without re-running
36
33
  * /api/start-vite. */
@@ -0,0 +1,11 @@
1
+ import type { SqliteVFS } from '@nimbus-sh/core/vfs/sqlite-vfs.js';
2
+ /** What a session says when its files were written by a pre-v2 Nimbus. */
3
+ export declare const LEGACY_RESET_NOTICE = "This session's files were created by an older Nimbus and were reset: this version stores files differently and cannot read them.";
4
+ /**
5
+ * The notice a session owes for a filesystem schema v2 did not read, once:
6
+ * the persisted shell state goes with it (its cwd pointed into the lost
7
+ * tree), so the session starts cold in the fresh one. Null when nothing
8
+ * was lost, or it was already told.
9
+ */
10
+ export declare function takeLegacyResetNotice(vfs: SqliteVFS, ctx: unknown): string | null;
11
+ //# sourceMappingURL=legacy-reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-reset.d.ts","sourceRoot":"","sources":["../../src/session/legacy-reset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAGnE,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,qIACoG,CAAC;AAErI;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKjF"}
@@ -0,0 +1,16 @@
1
+ import { clearSessionState } from './state-store.js';
2
+ /** What a session says when its files were written by a pre-v2 Nimbus. */
3
+ export const LEGACY_RESET_NOTICE = "This session's files were created by an older Nimbus and were reset: this version stores files differently and cannot read them.";
4
+ /**
5
+ * The notice a session owes for a filesystem schema v2 did not read, once:
6
+ * the persisted shell state goes with it (its cwd pointed into the lost
7
+ * tree), so the session starts cold in the fresh one. Null when nothing
8
+ * was lost, or it was already told.
9
+ */
10
+ export function takeLegacyResetNotice(vfs, ctx) {
11
+ if (!vfs.legacyReset)
12
+ return null;
13
+ clearSessionState(ctx);
14
+ vfs.acknowledgeLegacyReset();
15
+ return LEGACY_RESET_NOTICE;
16
+ }