@nimbus-sh/worker 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -43
- package/dist/_shared/preview-host.d.ts +33 -2
- package/dist/_shared/preview-host.d.ts.map +1 -1
- package/dist/_shared/preview-host.js +73 -8
- package/dist/_shared/session-router.d.ts +43 -0
- package/dist/_shared/session-router.d.ts.map +1 -1
- package/dist/_shared/session-router.js +59 -12
- package/dist/facets/durable-images.d.ts +59 -0
- package/dist/facets/durable-images.d.ts.map +1 -0
- package/dist/facets/durable-images.js +94 -0
- package/dist/facets/durable-slots.d.ts +45 -0
- package/dist/facets/durable-slots.d.ts.map +1 -0
- package/dist/facets/durable-slots.js +95 -0
- package/dist/facets/esbuild-transform.d.ts +10 -0
- package/dist/facets/esbuild-transform.d.ts.map +1 -0
- package/dist/facets/esbuild-transform.js +36 -0
- package/dist/facets/manager.d.ts +244 -6
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +901 -117
- package/dist/facets/resident-identity.d.ts +23 -0
- package/dist/facets/resident-identity.d.ts.map +1 -0
- package/dist/facets/resident-identity.js +31 -0
- package/dist/git/commands.d.ts +22 -1
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +429 -425
- package/dist/git-bundle.generated.d.ts +2 -2
- package/dist/git-bundle.generated.d.ts.map +1 -1
- package/dist/git-bundle.generated.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/node-shims-artifact.generated.js +3 -3
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +97 -3
- package/dist/router/public-directory-do.d.ts +17 -0
- package/dist/router/public-directory-do.d.ts.map +1 -0
- package/dist/router/public-directory-do.js +16 -0
- package/dist/router/public-directory.d.ts +79 -0
- package/dist/router/public-directory.d.ts.map +1 -0
- package/dist/router/public-directory.js +122 -0
- package/dist/router/remote-api.d.ts +27 -1
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +48 -2
- package/dist/runtime/cpython-resident.d.ts.map +1 -1
- package/dist/runtime/cpython-resident.js +3 -1
- package/dist/runtime/node-shims.d.ts +4 -1
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +324 -6
- package/dist/runtime/package-manager.d.ts +44 -1
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +168 -3
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +2 -0
- package/dist/session/agent.d.ts +11 -0
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +28 -1
- package/dist/session/helpers.js +1 -1
- package/dist/session/init-phases.d.ts +17 -23
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +17 -41
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +28 -15
- package/dist/session/keys.d.ts +12 -0
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +12 -0
- package/dist/session/nimbus-session.d.ts +63 -5
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +131 -17
- package/dist/session/port-capability.d.ts +141 -8
- package/dist/session/port-capability.d.ts.map +1 -1
- package/dist/session/port-capability.js +265 -8
- package/dist/session/programmatic.d.ts +145 -3
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +434 -12
- package/dist/session/routes.d.ts +26 -0
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +117 -25
- package/dist/session/rpc.d.ts +24 -1
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +65 -98
- package/dist/session/shell-socket.d.ts +76 -0
- package/dist/session/shell-socket.d.ts.map +1 -0
- package/dist/session/shell-socket.js +172 -0
- package/dist/session/start-real-vite.js +1 -1
- package/dist/session/supervisor-op.d.ts +42 -0
- package/dist/session/supervisor-op.d.ts.map +1 -0
- package/dist/session/supervisor-op.js +96 -0
- package/dist/session/supervisor-rpc.d.ts +6 -10
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +91 -71
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +19 -4
- package/package.json +4 -4
- package/public/_assets/runtime/{node-shims-fea906843f6d594e.js → node-shims-9e1380d9ee430fcc.js} +320 -5
- package/public/s/index.html +101 -5
package/dist/session/agent.d.ts
CHANGED
|
@@ -15,6 +15,17 @@ interface AgentStorage {
|
|
|
15
15
|
delete(key: string): Promise<void>;
|
|
16
16
|
deleteAll(): Promise<void>;
|
|
17
17
|
deleteAlarm(): Promise<void>;
|
|
18
|
+
list<T = unknown>(options: {
|
|
19
|
+
prefix: string;
|
|
20
|
+
}): Promise<Map<string, T>>;
|
|
21
|
+
transaction<T>(body: (txn: {
|
|
22
|
+
get(key: string): Promise<unknown>;
|
|
23
|
+
put(key: string, value: unknown): Promise<void>;
|
|
24
|
+
delete(key: string): Promise<unknown>;
|
|
25
|
+
list<T2 = unknown>(options: {
|
|
26
|
+
prefix: string;
|
|
27
|
+
}): Promise<Map<string, T2>>;
|
|
28
|
+
}) => Promise<T>): Promise<T>;
|
|
18
29
|
}
|
|
19
30
|
interface Host extends ProgrammaticHost, SessionAiHost {
|
|
20
31
|
ctx: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/session/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/session/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAiB3B,UAAU,YAAY;IACpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE;QACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;KAC3E,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/B;AAED,UAAU,IAAK,SAAQ,gBAAgB,EAAE,aAAa;IACpD,GAAG,EAAE;QAAE,OAAO,EAAE,YAAY,CAAA;KAAE,CAAC;IAC/B,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxD;AAED,UAAU,iBAAiB;IACzB,CAAC,EAAE,CAAC,CAAC;IACL,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA2BD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2ClG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAQxF"}
|
package/dist/session/agent.js
CHANGED
|
@@ -12,7 +12,7 @@ import { BASE_PATH_HEADER, TENANT_HEADER } from '../_shared/session-router.js';
|
|
|
12
12
|
import { 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
|
-
import { ensureProgrammaticReady, rpcExec, rpcEnsureRuntimes, rpcInstallRuntime, rpcKillProcess, rpcListPorts, rpcListProcesses, rpcProcessLogs, rpcStartProcess, } from './programmatic.js';
|
|
15
|
+
import { ensureProgrammaticReady, rpcExec, rpcEnsureRuntimes, rpcInstallRuntime, rpcExposeApp, rpcKillProcess, rpcListApps, rpcListPorts, rpcListProcesses, rpcProcessLogs, rpcStartProcess, } from './programmatic.js';
|
|
16
16
|
import { resolveVfsPath } from '@nimbus-sh/core/vfs/path.js';
|
|
17
17
|
import { appendTextPart, interruptRunningTools, textFromParts, upsertStoredMessage, upsertToolPart, } from './agent-contract.js';
|
|
18
18
|
import { CRED_KERNEL } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
@@ -645,6 +645,20 @@ function createAiSdkTools(self) {
|
|
|
645
645
|
inputSchema: toolSchema({}, []),
|
|
646
646
|
execute: async (args) => runTool(self, 'list_ports', args),
|
|
647
647
|
}),
|
|
648
|
+
expose_app: aiTool({
|
|
649
|
+
description: 'Expose a running application by port, pid or name: reserves its port under its identity, optionally names it and makes it public, and returns its URL.',
|
|
650
|
+
inputSchema: toolSchema({
|
|
651
|
+
target: stringProp('Port number, process id, or app name.'),
|
|
652
|
+
visibility: stringProp("'scoped' (default) or 'public' — public mints a shareable capability URL."),
|
|
653
|
+
name: stringProp('Optional DNS-label name for the app, e.g. "api".'),
|
|
654
|
+
}, ['target']),
|
|
655
|
+
execute: async (args) => runTool(self, 'expose_app', args),
|
|
656
|
+
}),
|
|
657
|
+
list_apps: aiTool({
|
|
658
|
+
description: 'List every application the session knows: owner, name, port, pid, status, visibility, restart policy and URL.',
|
|
659
|
+
inputSchema: toolSchema({}, []),
|
|
660
|
+
execute: async (args) => runTool(self, 'list_apps', args),
|
|
661
|
+
}),
|
|
648
662
|
};
|
|
649
663
|
}
|
|
650
664
|
function collectTurnParts(result) {
|
|
@@ -872,6 +886,19 @@ async function runTool(self, name, args) {
|
|
|
872
886
|
}
|
|
873
887
|
if (name === 'list_ports')
|
|
874
888
|
return rpcListPorts(self);
|
|
889
|
+
if (name === 'expose_app') {
|
|
890
|
+
const raw = String(args.target ?? '').trim();
|
|
891
|
+
if (!raw)
|
|
892
|
+
return { error: 'target is required' };
|
|
893
|
+
const visibility = args.visibility === 'public' ? 'public' : args.visibility === 'scoped' ? 'scoped' : undefined;
|
|
894
|
+
const appName = typeof args.name === 'string' && args.name.trim() ? args.name.trim() : undefined;
|
|
895
|
+
return rpcExposeApp(self, /^\d+$/.test(raw) ? Number(raw) : raw, {
|
|
896
|
+
...(visibility !== undefined ? { visibility } : {}),
|
|
897
|
+
...(appName !== undefined ? { name: appName } : {}),
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
if (name === 'list_apps')
|
|
901
|
+
return rpcListApps(self);
|
|
875
902
|
return { error: `unknown tool: ${name}` };
|
|
876
903
|
}
|
|
877
904
|
catch (e) {
|
package/dist/session/helpers.js
CHANGED
|
@@ -370,7 +370,7 @@ export const _CP_PURE_BUILTIN = new Set([
|
|
|
370
370
|
'sleep', 'date', 'whoami', 'id', 'hostname', 'uname', 'clear',
|
|
371
371
|
'tree', 'find', 'grep', 'head', 'tail', 'wc', 'sort', 'uniq', 'sed',
|
|
372
372
|
'awk', 'xargs', 'tee', 'du', 'diff', 'base64', 'seq', 'realpath',
|
|
373
|
-
'basename', 'dirname', 'printf', 'sha256sum', 'file', 'xxd',
|
|
373
|
+
'basename', 'dirname', 'printf', 'sha256sum', 'file', 'xxd', 'od', 'hexdump',
|
|
374
374
|
'chmod', 'chown', 'ln', 'test', '[', 'read', 'exit', 'set', 'shopt',
|
|
375
375
|
'trap', 'umask', 'ulimit', 'which', 'uptime',
|
|
376
376
|
]);
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* additional ring entries, not replacements.
|
|
34
34
|
*/
|
|
35
35
|
import { type SessionState } from '@nimbus-sh/platform/oom-discriminator.js';
|
|
36
|
+
import { type AutoResponseHost } from './shell-socket.js';
|
|
36
37
|
/**
|
|
37
38
|
* Set the current phase + record a transition. Fail-soft on the
|
|
38
39
|
* observability call; the phase update on `self` is direct and
|
|
@@ -42,37 +43,30 @@ export declare function setPhase(self: {
|
|
|
42
43
|
_b4Phase: SessionState | null;
|
|
43
44
|
ctx?: unknown;
|
|
44
45
|
}, toState: SessionState, trigger: string): void;
|
|
46
|
+
type WsUpgradeDecision = 'warm-join' | 'conflict' | 'cold';
|
|
45
47
|
/**
|
|
46
|
-
*
|
|
47
|
-
* upgrade classifier below also recognizes headless sessions whose
|
|
48
|
-
* lifecycle phase does not describe a real terminal attachment.
|
|
48
|
+
* Decide what a /ws upgrade should do with the session it lands on.
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
50
|
+
* - cold: no session to join. Either nothing was ever built, or a
|
|
51
|
+
* previous teardown left the object half-built. A Shell
|
|
52
|
+
* without its Kernel or its Terminal serves nobody, and
|
|
53
|
+
* nothing else rebuilds one, so the upgrade does.
|
|
54
|
+
* - conflict: another browser terminal holds this session. The caller
|
|
55
|
+
* answers 409, which is what stops two tabs from driving
|
|
56
|
+
* one shell. See `shell-socket.ts` for what proves that a
|
|
57
|
+
* socket still has a peer on it.
|
|
58
|
+
* - warm-join: the session is built and unattended. Skip the rebuild
|
|
59
|
+
* and hand the live Shell to the incoming socket.
|
|
55
60
|
*
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_b4Phase: SessionState | null;
|
|
59
|
-
shell: any;
|
|
60
|
-
terminal: any;
|
|
61
|
-
kernel: any;
|
|
62
|
-
}): boolean;
|
|
63
|
-
type WsUpgradeDecision = 'warm-join' | 'conflict' | 'cold';
|
|
64
|
-
/**
|
|
65
|
-
* Classify a shell WebSocket upgrade from the actual attachment state.
|
|
66
|
-
* A non-null Shell can belong to a headless programmatic boot, so only an
|
|
67
|
-
* open socket tagged as `shell` proves that another browser terminal is
|
|
68
|
-
* currently attached.
|
|
61
|
+
* The caller classifies BEFORE it accepts the incoming socket, so the
|
|
62
|
+
* upgrade cannot count itself as the incumbent.
|
|
69
63
|
*/
|
|
70
64
|
export declare function classifyWsUpgrade(self: {
|
|
71
|
-
_b4Phase: SessionState | null;
|
|
72
65
|
shell: unknown;
|
|
73
66
|
terminal: unknown;
|
|
74
67
|
kernel: unknown;
|
|
75
|
-
|
|
68
|
+
ctx?: AutoResponseHost;
|
|
69
|
+
}, sockets: readonly WebSocket[], now?: number): WsUpgradeDecision;
|
|
76
70
|
/**
|
|
77
71
|
* [B'.5] Run the warm-rejoin path. Skips Phase B (kernel + shell are
|
|
78
72
|
* already built and alive in-memory). Phase R loads any state that
|
|
@@ -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;
|
|
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,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAChE,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAsCN"}
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
*/
|
|
35
35
|
import { recordRecoveryEvent } from '@nimbus-sh/platform/oom-discriminator.js';
|
|
36
36
|
import { generation } from '@nimbus-sh/fabric/generation.js';
|
|
37
|
+
import { hasLiveShellOwner } from './shell-socket.js';
|
|
37
38
|
/**
|
|
38
39
|
* Set the current phase + record a transition. Fail-soft on the
|
|
39
40
|
* observability call; the phase update on `self` is direct and
|
|
@@ -56,51 +57,26 @@ export function setPhase(self, toState, trigger) {
|
|
|
56
57
|
catch { /* observability is non-critical */ }
|
|
57
58
|
}
|
|
58
59
|
/**
|
|
59
|
-
*
|
|
60
|
-
* upgrade classifier below also recognizes headless sessions whose
|
|
61
|
-
* lifecycle phase does not describe a real terminal attachment.
|
|
60
|
+
* Decide what a /ws upgrade should do with the session it lands on.
|
|
62
61
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
62
|
+
* - cold: no session to join. Either nothing was ever built, or a
|
|
63
|
+
* previous teardown left the object half-built. A Shell
|
|
64
|
+
* without its Kernel or its Terminal serves nobody, and
|
|
65
|
+
* nothing else rebuilds one, so the upgrade does.
|
|
66
|
+
* - conflict: another browser terminal holds this session. The caller
|
|
67
|
+
* answers 409, which is what stops two tabs from driving
|
|
68
|
+
* one shell. See `shell-socket.ts` for what proves that a
|
|
69
|
+
* socket still has a peer on it.
|
|
70
|
+
* - warm-join: the session is built and unattended. Skip the rebuild
|
|
71
|
+
* and hand the live Shell to the incoming socket.
|
|
68
72
|
*
|
|
73
|
+
* The caller classifies BEFORE it accepts the incoming socket, so the
|
|
74
|
+
* upgrade cannot count itself as the incumbent.
|
|
69
75
|
*/
|
|
70
|
-
export function
|
|
71
|
-
|
|
72
|
-
&& self.shell != null
|
|
73
|
-
&& self.terminal != null
|
|
74
|
-
&& self.kernel != null;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Classify a shell WebSocket upgrade from the actual attachment state.
|
|
78
|
-
* A non-null Shell can belong to a headless programmatic boot, so only an
|
|
79
|
-
* open socket tagged as `shell` proves that another browser terminal is
|
|
80
|
-
* currently attached.
|
|
81
|
-
*/
|
|
82
|
-
export function classifyWsUpgrade(self, sockets) {
|
|
83
|
-
if (isWarmRejoin(self))
|
|
84
|
-
return 'warm-join';
|
|
85
|
-
if (self.shell == null)
|
|
76
|
+
export function classifyWsUpgrade(self, sockets, now = Date.now()) {
|
|
77
|
+
if (self.shell == null || self.terminal == null || self.kernel == null)
|
|
86
78
|
return 'cold';
|
|
87
|
-
|
|
88
|
-
return 'conflict';
|
|
89
|
-
const hasOpenShellSocket = sockets.some((socket) => {
|
|
90
|
-
if (socket.readyState !== WebSocket.OPEN)
|
|
91
|
-
return false;
|
|
92
|
-
try {
|
|
93
|
-
const attachment = socket.deserializeAttachment();
|
|
94
|
-
return typeof attachment === 'object'
|
|
95
|
-
&& attachment !== null
|
|
96
|
-
&& 'kind' in attachment
|
|
97
|
-
&& attachment.kind === 'shell';
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
return hasOpenShellSocket ? 'conflict' : 'warm-join';
|
|
79
|
+
return hasLiveShellOwner(self.ctx, sockets, now) ? 'conflict' : 'warm-join';
|
|
104
80
|
}
|
|
105
81
|
/**
|
|
106
82
|
* [B'.5] Run the warm-rejoin path. Skips Phase B (kernel + shell are
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA+EH,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;AAa3E,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA+EH,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;AAa3E,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAitF9E"}
|
package/dist/session/init.js
CHANGED
|
@@ -58,8 +58,8 @@ import { installNpmBinFallbackResolver } from '../shell/npm-bin-entrypoints.js';
|
|
|
58
58
|
import { parseNpmInstallInvocation } from '../npm/install-args.js';
|
|
59
59
|
import { npmLogEnabled } from '../npm/npm-log.js';
|
|
60
60
|
import { materializeNpmBinShims } from '../npm/bin-links.js';
|
|
61
|
-
import { registerGitCommands } from '../git/commands.js';
|
|
62
61
|
import { makeNimbusVerbHandler, createRuntimeCommandHintResolver, } from '../runtime/package-manager.js';
|
|
62
|
+
import { rpcExposeApp, rpcListApps, rpcRemoveApp, rpcRotateLink } from './programmatic.js';
|
|
63
63
|
import { listInstalledRuntimes, rehydrateInstalledRuntimes, registerRunnerFactory, } from '@nimbus-sh/core/runtime/installed-runtimes.js';
|
|
64
64
|
// Runtime factories (clang/python/ruby/bash/wasm) are imported lazily at
|
|
65
65
|
// first-use inside their registered handlers — see the registrations below.
|
|
@@ -454,8 +454,13 @@ export async function initSession(self, ws) {
|
|
|
454
454
|
}));
|
|
455
455
|
// ── Git integration (isomorphic-git) ──
|
|
456
456
|
// ctx + env are passed for clone/fetch/pull which run in a facet to avoid
|
|
457
|
-
// exhausting the supervisor DO's CPU budget on large repos.
|
|
458
|
-
|
|
457
|
+
// exhausting the supervisor DO's CPU budget on large repos. The command
|
|
458
|
+
// module (+ its ~106 KB network-facet dependency) is loaded lazily on the
|
|
459
|
+
// first `git` invocation so it stays out of the cold script-eval graph.
|
|
460
|
+
registry.register('git', async (ctx) => {
|
|
461
|
+
const { runGitCommand } = await import('../git/commands.js');
|
|
462
|
+
return runGitCommand(ctx, sqliteFs, self.ctx, self.env);
|
|
463
|
+
});
|
|
459
464
|
// ── runtime package manager: `nimbus install` package manager + runner registry.
|
|
460
465
|
//
|
|
461
466
|
// 1. Register the clang-runner factory FIRST so the rehydration step
|
|
@@ -585,6 +590,14 @@ export async function initSession(self, ws) {
|
|
|
585
590
|
vfs: sqliteFs,
|
|
586
591
|
registry: pkgRegistry,
|
|
587
592
|
getHome: nimbusGetHome,
|
|
593
|
+
// The application verbs are the session's own (programmatic.ts):
|
|
594
|
+
// the shell, the SDK and the Agent all reach the same policy.
|
|
595
|
+
apps: {
|
|
596
|
+
expose: (target, options) => rpcExposeApp(self, target, options),
|
|
597
|
+
list: () => rpcListApps(self),
|
|
598
|
+
rotateLink: (target) => rpcRotateLink(self, target),
|
|
599
|
+
remove: (target) => rpcRemoveApp(self, target),
|
|
600
|
+
},
|
|
588
601
|
warmRuntime: async (target, ctx) => {
|
|
589
602
|
// The runtime name, which is what `nimbus install python` installs
|
|
590
603
|
// — not the name the user typed. Left as 'python' through the
|
|
@@ -689,7 +702,7 @@ export async function initSession(self, ws) {
|
|
|
689
702
|
getEsbuild: () => {
|
|
690
703
|
if (!self.esbuildService) {
|
|
691
704
|
self.ensureSqliteFs();
|
|
692
|
-
self.esbuildService = new EsbuildService(
|
|
705
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
693
706
|
}
|
|
694
707
|
return self.esbuildService;
|
|
695
708
|
},
|
|
@@ -838,7 +851,7 @@ export async function initSession(self, ws) {
|
|
|
838
851
|
getEsbuild: () => {
|
|
839
852
|
if (!self.esbuildService) {
|
|
840
853
|
self.ensureSqliteFs();
|
|
841
|
-
self.esbuildService = new EsbuildService(
|
|
854
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
842
855
|
}
|
|
843
856
|
return self.esbuildService;
|
|
844
857
|
},
|
|
@@ -886,7 +899,7 @@ export async function initSession(self, ws) {
|
|
|
886
899
|
getEsbuild: () => {
|
|
887
900
|
if (!self.esbuildService) {
|
|
888
901
|
self.ensureSqliteFs();
|
|
889
|
-
self.esbuildService = new EsbuildService(
|
|
902
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
890
903
|
}
|
|
891
904
|
return self.esbuildService;
|
|
892
905
|
},
|
|
@@ -956,7 +969,7 @@ export async function initSession(self, ws) {
|
|
|
956
969
|
// Lazy-init esbuild service
|
|
957
970
|
if (!self.esbuildService) {
|
|
958
971
|
self.ensureSqliteFs();
|
|
959
|
-
self.esbuildService = new EsbuildService(
|
|
972
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
960
973
|
}
|
|
961
974
|
// Parse flags
|
|
962
975
|
const flags = {};
|
|
@@ -1091,7 +1104,7 @@ export async function initSession(self, ws) {
|
|
|
1091
1104
|
// Transform TS to JS
|
|
1092
1105
|
if (cfgName.endsWith('.ts')) {
|
|
1093
1106
|
if (!self.esbuildService)
|
|
1094
|
-
self.esbuildService = new EsbuildService(
|
|
1107
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
1095
1108
|
const t = await self.esbuildService.transform(cfgCode, { loader: 'ts', format: 'esm' });
|
|
1096
1109
|
cfgCode = t.code;
|
|
1097
1110
|
}
|
|
@@ -1106,7 +1119,7 @@ export async function initSession(self, ws) {
|
|
|
1106
1119
|
// ── vite build ──
|
|
1107
1120
|
if (args[0] === 'build') {
|
|
1108
1121
|
if (!self.esbuildService)
|
|
1109
|
-
self.esbuildService = new EsbuildService(
|
|
1122
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
1110
1123
|
const htmlPath = cwd + '/index.html';
|
|
1111
1124
|
let entryPoint = cwd + '/src/main.tsx';
|
|
1112
1125
|
let origHtml = '';
|
|
@@ -1222,7 +1235,7 @@ export async function initSession(self, ws) {
|
|
|
1222
1235
|
}
|
|
1223
1236
|
// Start vite on the dist directory
|
|
1224
1237
|
if (!self.esbuildService)
|
|
1225
|
-
self.esbuildService = new EsbuildService(
|
|
1238
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
1226
1239
|
if (self.viteDevServer?.isRunning)
|
|
1227
1240
|
self.viteDevServer.stop();
|
|
1228
1241
|
const previewBasePath = self.viteBasePath;
|
|
@@ -1395,7 +1408,7 @@ export async function initSession(self, ws) {
|
|
|
1395
1408
|
}
|
|
1396
1409
|
}
|
|
1397
1410
|
if (!self.esbuildService)
|
|
1398
|
-
self.esbuildService = new EsbuildService(
|
|
1411
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
1399
1412
|
const previewBasePath = self.viteBasePath;
|
|
1400
1413
|
const viteDefine = viteConfig.define;
|
|
1401
1414
|
// Vite dev servers are represented as long-running process-table
|
|
@@ -1563,7 +1576,7 @@ export async function initSession(self, ws) {
|
|
|
1563
1576
|
// Lazy-init esbuild
|
|
1564
1577
|
if (!self.esbuildService) {
|
|
1565
1578
|
self.ensureSqliteFs();
|
|
1566
|
-
self.esbuildService = new EsbuildService(
|
|
1579
|
+
self.esbuildService = new EsbuildService(kernelFs);
|
|
1567
1580
|
}
|
|
1568
1581
|
// Parse --root flag; default to the shell cwd so `npm run dev` from
|
|
1569
1582
|
// a project directory picks up that project's wrangler.jsonc.
|
|
@@ -1666,7 +1679,7 @@ export async function initSession(self, ws) {
|
|
|
1666
1679
|
kernelFs.writeFile(pkgJsonPath, '{"name":"project","version":"1.0.0","dependencies":{}}\n');
|
|
1667
1680
|
}
|
|
1668
1681
|
ctx.stdout.write('\x1b[36mNimbus npm v2 (batched writes)\x1b[0m\n');
|
|
1669
|
-
self.ensureNpmInstaller((msg) => {
|
|
1682
|
+
await self.ensureNpmInstaller((msg) => {
|
|
1670
1683
|
ctx.stdout.write('[npm] ' + msg + '\n');
|
|
1671
1684
|
});
|
|
1672
1685
|
const result = await self.npmInstaller.install(cwd, { packages, pid: ctx.pid });
|
|
@@ -2164,7 +2177,7 @@ export async function initSession(self, ws) {
|
|
|
2164
2177
|
? `${explicitPkgs.length} packages`
|
|
2165
2178
|
: 'dependencies from package.json';
|
|
2166
2179
|
ctx.stdout.write(`\x1b[36mInstalling ${pkgLabel} (npm v2 — batched writes)...\x1b[0m\n`);
|
|
2167
|
-
self.ensureNpmInstaller((msg) => {
|
|
2180
|
+
await self.ensureNpmInstaller((msg) => {
|
|
2168
2181
|
ctx.stdout.write('[npm] ' + msg + '\n');
|
|
2169
2182
|
});
|
|
2170
2183
|
// `--loglevel` selects npm's own log protocol on stderr, where npm
|
|
@@ -2333,7 +2346,7 @@ export async function initSession(self, ws) {
|
|
|
2333
2346
|
}
|
|
2334
2347
|
// Nimbus-native npx install + run path. Routes package installation
|
|
2335
2348
|
// through NpmInstaller's full-packument resolver.
|
|
2336
|
-
self.ensureNpmInstaller((msg) => ctx.stdout.write('[npm] ' + msg + '\n'));
|
|
2349
|
+
await self.ensureNpmInstaller((msg) => ctx.stdout.write('[npm] ' + msg + '\n'));
|
|
2337
2350
|
self.ensureSqliteFs();
|
|
2338
2351
|
const installer = self.npmInstaller;
|
|
2339
2352
|
const resolveResult = await resolveNpxBinary(installer, self.sqliteFs.as(requireVfsCred('cred' in ctx ? ctx.cred : undefined, 'npx')), ctx.cwd || '/home/user', npxArgs, (msg) => ctx.stdout.write(msg + '\n'), ctx.pid);
|
package/dist/session/keys.d.ts
CHANGED
|
@@ -51,6 +51,18 @@ export declare const ATTACH_BOOTSTRAP_JTI_KEY_PREFIX = "attach-bootstrap-jti:";
|
|
|
51
51
|
* these rows.
|
|
52
52
|
*/
|
|
53
53
|
export declare const PORT_CAPABILITY_KEY_PREFIX = "nimbus_preview_capability:";
|
|
54
|
+
/**
|
|
55
|
+
* Prefix for a durable application's facet-slot row, keyed by owner.
|
|
56
|
+
* `durable-slot:next` and `durable-slot:free` under the same prefix are the
|
|
57
|
+
* allocator's counter and free list; `durable-slot:<owner>` pins the owner to
|
|
58
|
+
* its `app-slot-<n>` facet name for the application's whole life. Owned by
|
|
59
|
+
* `facets/durable-slots.ts`, the only module that reads or writes these rows.
|
|
60
|
+
*/
|
|
61
|
+
export declare const DURABLE_SLOT_KEY_PREFIX = "durable-slot:";
|
|
62
|
+
/** Atomic resident identity claim: owner → winning pid, released at process termination. */
|
|
63
|
+
export declare const RESIDENT_OWNER_KEY_PREFIX = "resident-owner:";
|
|
64
|
+
/** Owner → retained durable image digests, including images of stopped processes. */
|
|
65
|
+
export declare const DURABLE_IMAGES_KEY_PREFIX = "durable-images:";
|
|
54
66
|
/**
|
|
55
67
|
* Prefix for a named programmatic shell's durable cwd+env, keyed by shell id.
|
|
56
68
|
* One row per id the embedder has actually used; bounded by the embedder's own
|
|
@@ -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;;;;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;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"}
|
package/dist/session/keys.js
CHANGED
|
@@ -55,6 +55,18 @@ export const ATTACH_BOOTSTRAP_JTI_KEY_PREFIX = 'attach-bootstrap-jti:';
|
|
|
55
55
|
* these rows.
|
|
56
56
|
*/
|
|
57
57
|
export const PORT_CAPABILITY_KEY_PREFIX = 'nimbus_preview_capability:';
|
|
58
|
+
/**
|
|
59
|
+
* Prefix for a durable application's facet-slot row, keyed by owner.
|
|
60
|
+
* `durable-slot:next` and `durable-slot:free` under the same prefix are the
|
|
61
|
+
* allocator's counter and free list; `durable-slot:<owner>` pins the owner to
|
|
62
|
+
* its `app-slot-<n>` facet name for the application's whole life. Owned by
|
|
63
|
+
* `facets/durable-slots.ts`, the only module that reads or writes these rows.
|
|
64
|
+
*/
|
|
65
|
+
export const DURABLE_SLOT_KEY_PREFIX = 'durable-slot:';
|
|
66
|
+
/** Atomic resident identity claim: owner → winning pid, released at process termination. */
|
|
67
|
+
export const RESIDENT_OWNER_KEY_PREFIX = 'resident-owner:';
|
|
68
|
+
/** Owner → retained durable image digests, including images of stopped processes. */
|
|
69
|
+
export const DURABLE_IMAGES_KEY_PREFIX = 'durable-images:';
|
|
58
70
|
/**
|
|
59
71
|
* Prefix for a named programmatic shell's durable cwd+env, keyed by shell id.
|
|
60
72
|
* One row per id the embedder has actually used; bounded by the embedder's own
|
|
@@ -15,13 +15,14 @@ import { SqliteRuntimeFsBridge } from '@nimbus-sh/core/runtime/sqlite-runtime-fs
|
|
|
15
15
|
import { type VfsAcquireResult, type VfsListPage } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
16
16
|
import type { WsHibernationConfigResult } from './hibernation.js';
|
|
17
17
|
import { PortRegistry } from '@nimbus-sh/core/runtime/port-registry.js';
|
|
18
|
-
import { EsbuildService } from '@nimbus-sh/core/runtime/esbuild-service.js';
|
|
19
18
|
import { ViteDevServer } from '../facets/vite-dev-server.js';
|
|
20
19
|
import { CirrusReal } from '../facets/cirrus-real.js';
|
|
20
|
+
import { EsbuildService } from '@nimbus-sh/core/runtime/esbuild-service.js';
|
|
21
21
|
import { NimbusWrangler } from '../wrangler/nimbus-wrangler.js';
|
|
22
|
-
import { NpmInstaller } from '../npm/installer.js';
|
|
22
|
+
import type { NpmInstaller } from '../npm/installer.js';
|
|
23
23
|
import { type TryEnableReplicasResult as _W12EnableResult } from '../replica/routing.js';
|
|
24
24
|
import * as _rpc from './rpc.js';
|
|
25
|
+
import type { SupervisorOpEnvelope } from '@nimbus-sh/core/workspace/supervisor-op.js';
|
|
25
26
|
import type { HostedHttpRequest, HostedHttpResponse } from '@nimbus-sh/fabric/process-host.js';
|
|
26
27
|
import { WebSocketRelay } from './ws-relay.js';
|
|
27
28
|
import * as _programmatic from './programmatic.js';
|
|
@@ -48,7 +49,6 @@ export declare function renderMotdBanner(version: string): string;
|
|
|
48
49
|
export declare function renderWelcomeMarkdown(version: string): string;
|
|
49
50
|
export declare class NimbusSession extends CloudflareDurableObject {
|
|
50
51
|
sqliteFs: SqliteVFS | null;
|
|
51
|
-
runtimeFsBridges: Map<number, SqliteRuntimeFsBridge> | null;
|
|
52
52
|
kernel: Kernel | null;
|
|
53
53
|
shell: Shell | null;
|
|
54
54
|
shellProcessPid: number | null;
|
|
@@ -179,6 +179,13 @@ export declare class NimbusSession extends CloudflareDurableObject {
|
|
|
179
179
|
sessionBasePath: string;
|
|
180
180
|
/** Have we attempted to hydrate sessionBasePath from storage yet? */
|
|
181
181
|
sessionBasePathHydrated: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* The origin this session was last reached at (`https://host`), remembered
|
|
184
|
+
* beside the base path so the session can spell a path-form URL for one
|
|
185
|
+
* of its own applications — `nimbus expose` printing one, `apps.list`
|
|
186
|
+
* carrying one — on a deployment with no preview-host suffix.
|
|
187
|
+
*/
|
|
188
|
+
sessionOrigin: string;
|
|
182
189
|
/**
|
|
183
190
|
* Has the "wrangler is aliased to nimbus-wrangler" banner been shown
|
|
184
191
|
* this session? Reset on WebSocket close/reopen so a reconnecting user
|
|
@@ -249,6 +256,20 @@ export declare class NimbusSession extends CloudflareDurableObject {
|
|
|
249
256
|
* get/put, so two concurrent exchanges cannot both observe "absent".
|
|
250
257
|
*/
|
|
251
258
|
_rpcConsumeAttachBootstrap(jti: string): Promise<boolean>;
|
|
259
|
+
/**
|
|
260
|
+
* The one supervisor-op handler this session's bindings, loopback stubs and
|
|
261
|
+
* `_rpc*` delegates all dispatch through — native filesystem ops against
|
|
262
|
+
* the shared bridge store, session overrides for the accounting-carrying
|
|
263
|
+
* reads and the output stream, and the canonical route table for the rest.
|
|
264
|
+
* Lazy: sqliteFs exists only after ensureSqliteFs().
|
|
265
|
+
*/
|
|
266
|
+
private _supervisorOps;
|
|
267
|
+
private supervisorOps;
|
|
268
|
+
/** The pid-keyed filesystem bridge behind the supervisor ops. */
|
|
269
|
+
supervisorBridge(pid?: number): SqliteRuntimeFsBridge;
|
|
270
|
+
/** Drop a dead pid's supervisor bridge — its credential stops being valid. */
|
|
271
|
+
supervisorForgetBridge(pid: number): void;
|
|
272
|
+
supervisorOp(envelope: SupervisorOpEnvelope): Promise<unknown>;
|
|
252
273
|
_rpcReadFile(path: string, pid?: number): Promise<string | null>;
|
|
253
274
|
_rpcReadFileBytes(path: string, pid?: number): Promise<Uint8Array | null>;
|
|
254
275
|
_rpcInnerDoFetch(req: any): Promise<any>;
|
|
@@ -437,12 +458,43 @@ export declare class NimbusSession extends CloudflareDurableObject {
|
|
|
437
458
|
exit: import("@nimbus-sh/core/runtime/process-logs.js").ProcessExitInfo | null;
|
|
438
459
|
}>;
|
|
439
460
|
_rpcListPorts(): Promise<_programmatic.SerializedPort[]>;
|
|
440
|
-
_rpcExposePort(port: number
|
|
461
|
+
_rpcExposePort(port: number, options?: {
|
|
462
|
+
visibility?: 'scoped' | 'public';
|
|
463
|
+
name?: string;
|
|
464
|
+
}): Promise<{
|
|
441
465
|
port: number;
|
|
442
466
|
listening: boolean;
|
|
443
467
|
pid: number | null;
|
|
444
468
|
registeredAt: number | null;
|
|
445
469
|
capability: string | null;
|
|
470
|
+
visibility: "scoped" | "public";
|
|
471
|
+
owner: string | null;
|
|
472
|
+
name: string | null;
|
|
473
|
+
}>;
|
|
474
|
+
_rpcExposeApp(target: _programmatic.AppTarget, options?: {
|
|
475
|
+
visibility?: 'scoped' | 'public';
|
|
476
|
+
name?: string;
|
|
477
|
+
}): Promise<_programmatic.ExposedAppResult>;
|
|
478
|
+
_rpcListApps(): Promise<_programmatic.ListedApp[]>;
|
|
479
|
+
_rpcRotateLink(target: _programmatic.AppTarget): Promise<_programmatic.ExposedAppResult>;
|
|
480
|
+
_rpcRemoveApp(target: _programmatic.AppTarget): Promise<{
|
|
481
|
+
owner: string;
|
|
482
|
+
removed: boolean;
|
|
483
|
+
port: number | null;
|
|
484
|
+
}>;
|
|
485
|
+
_rpcEnsureDurableApp(input: {
|
|
486
|
+
owner: string;
|
|
487
|
+
preferredPort?: number;
|
|
488
|
+
visibility?: 'scoped' | 'public';
|
|
489
|
+
}): Promise<{
|
|
490
|
+
port: number;
|
|
491
|
+
capability: string | null;
|
|
492
|
+
visibility: "scoped" | "public";
|
|
493
|
+
}>;
|
|
494
|
+
_rpcRemoveDurableApp(owner: string): Promise<{
|
|
495
|
+
owner: string;
|
|
496
|
+
removed: boolean;
|
|
497
|
+
port: number | null;
|
|
446
498
|
}>;
|
|
447
499
|
_rpcUnexposePort(port: number): Promise<{
|
|
448
500
|
port: number;
|
|
@@ -450,6 +502,12 @@ export declare class NimbusSession extends CloudflareDurableObject {
|
|
|
450
502
|
}>;
|
|
451
503
|
/** Capability-authenticated port route, for an embedder holding the token. */
|
|
452
504
|
_rpcRouteCapabilityPort(port: number, capability: string, request: Request, innerPath: string): Promise<Response>;
|
|
505
|
+
/**
|
|
506
|
+
* The port route's recovery seam: a durable application journalled but
|
|
507
|
+
* dead is re-driven on demand rather than left for the alarm pump. The
|
|
508
|
+
* manager decides 'started' | 'absent' | 'failed'; the route maps them.
|
|
509
|
+
*/
|
|
510
|
+
ensureDurableAppOnPort(port: number): Promise<'started' | 'absent' | 'failed'>;
|
|
453
511
|
_rpcDeleteFile(path: string, options?: {
|
|
454
512
|
recursive?: boolean;
|
|
455
513
|
}): Promise<void>;
|
|
@@ -546,7 +604,7 @@ export declare class NimbusSession extends CloudflareDurableObject {
|
|
|
546
604
|
* All concurrent fetches share ONE worker — no port exhaustion.
|
|
547
605
|
*/
|
|
548
606
|
buildFetchFn(log?: (msg: string) => void): ((url: string, init?: RequestInit) => Promise<Response>) | undefined;
|
|
549
|
-
ensureNpmInstaller(onProgress?: (msg: string) => void): void
|
|
607
|
+
ensureNpmInstaller(onProgress?: (msg: string) => void): Promise<void>;
|
|
550
608
|
/**
|
|
551
609
|
* Read an environment flag with default-on semantics. Mirrors the
|
|
552
610
|
* shouldUseFacetPool / shouldUseFacetResolver / shouldUseBatchFacet
|