hyperbrane 0.2.0 → 0.2.1
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 +43 -3
- package/dist/agent/agentService.js +3 -2
- package/dist/agent/api.d.ts +26 -2
- package/dist/agent/control.js +1 -1
- package/dist/agent/dimensionAgentClient.d.ts +8 -0
- package/dist/agent/dimensionAgentClient.js +99 -0
- package/dist/agent/session/backend.d.ts +2 -1
- package/dist/agent/session/claude/transcript.d.ts +1 -0
- package/dist/agent/session/claude/transcript.js +1 -1
- package/dist/agent/session/worker/protocol.d.ts +6 -3
- package/dist/agent/session/worker/protocol.js +1 -1
- package/dist/agent/session/worker/workerParams.js +10 -3
- package/dist/agent/vendor-types/manifest.json +5 -60
- package/dist/agent/workerBundle.generated.js +1 -1
- package/dist/dimension/api.d.ts +3 -0
- package/dist/dimension/control.d.ts +2 -1
- package/dist/dimension/control.js +18 -0
- package/dist/dimension/service.js +27 -1
- package/dist/dimension/transportBundle.generated.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/lib/control.d.ts +4 -1
- package/dist/lib/control.js +2 -2
- package/dist/lib/jsonDirectory.js +24 -3
- package/dist/lib/unixSocket.d.ts +2 -0
- package/dist/lib/unixSocket.js +28 -0
- package/dist/portal-gateway/api.d.ts +1 -0
- package/dist/portal-gateway/gatewayService.js +14 -0
- package/dist/portal-gateway/transportBundle.generated.js +1 -1
- package/dist/restore.d.ts +9 -0
- package/dist/restore.js +10 -0
- package/dist/sandbox/api.d.ts +5 -0
- package/dist/sandbox/client.d.ts +2 -1
- package/dist/sandbox/client.js +4 -1
- package/dist/sandbox/lib/sshKey.d.ts +6 -0
- package/dist/sandbox/lib/sshKey.js +75 -0
- package/dist/sandbox/providers/boat/boatService.d.ts +2 -1
- package/dist/sandbox/providers/boat/boatService.js +72 -20
- package/dist/sandbox/providers/exedev/exeDevService.js +4 -2
- package/dist/sandbox/providers/exedev/exeDevToken.js +2 -6
- package/dist/sandbox/providers/local/localService.js +4 -26
- package/dist/sandbox/providers/ssh/sshService.js +2 -1
- package/dist/sandbox/service.d.ts +2 -1
- package/dist/sandbox/service.js +9 -1
- package/dist/vendor-types/claude/agent-sdk/bridge.d.ts +20 -4
- package/dist/vendor-types/claude/agent-sdk/browser-sdk.d.ts +24 -0
- package/dist/vendor-types/claude/agent-sdk/core.d.ts +2 -0
- package/dist/vendor-types/claude/agent-sdk/sdk-tools.d.ts +75 -6
- package/dist/vendor-types/claude/agent-sdk/sdk.d.ts +569 -100
- package/package.json +2 -1
package/dist/dimension/api.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RunCommandOptions, RunCommandResult } from "../sandbox/api.ts";
|
|
1
2
|
export { dimensionLayout } from "./paths.ts";
|
|
2
3
|
export type MemoryLimit = number & {
|
|
3
4
|
readonly __brand: "MemoryLimit";
|
|
@@ -59,6 +60,7 @@ export interface DimensionClient {
|
|
|
59
60
|
createDimension(dimension: Dimension): Promise<Dimension>;
|
|
60
61
|
destroyDimension(dimensionName: string): Promise<void>;
|
|
61
62
|
restartDimension(dimensionName: string): Promise<void>;
|
|
63
|
+
restoreDimensions(): Promise<string[]>;
|
|
62
64
|
updateDimension(dimensionName: string, limits: DimensionLimits): Promise<Dimension>;
|
|
63
65
|
listDimensions(): Promise<DimensionInfo[]>;
|
|
64
66
|
getDimensionUsage(): Promise<DimensionUsage[]>;
|
|
@@ -68,6 +70,7 @@ export interface DimensionClient {
|
|
|
68
70
|
}): Promise<ReadableStream<Uint8Array>>;
|
|
69
71
|
writeFile(dimensionName: string, path: string, data: Uint8Array | ReadableStream<Uint8Array>): Promise<void>;
|
|
70
72
|
statFile(dimensionName: string, path: string): Promise<DimensionFileInfo>;
|
|
73
|
+
runCommand(dimensionName: string, cmd: string[], options?: RunCommandOptions): Promise<RunCommandResult>;
|
|
71
74
|
}
|
|
72
75
|
export declare class DimensionInvalidError extends Error {
|
|
73
76
|
name: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ControlOptions } from "../lib/control.ts";
|
|
2
|
-
import type { Sandbox } from "../sandbox/api.ts";
|
|
2
|
+
import type { RunCommandOptions, RunCommandResult, Sandbox } from "../sandbox/api.ts";
|
|
3
3
|
import { type Dimension, type DimensionLimits, type DimensionStatus, type DimensionUsage } from "./api.ts";
|
|
4
4
|
export type { ControlOptions };
|
|
5
5
|
export type DimensionRecord = Dimension & {
|
|
@@ -19,3 +19,4 @@ export declare function dimensionUsageScript(host: Sandbox, options?: ControlOpt
|
|
|
19
19
|
export declare function startTransportScript(host: Sandbox, dimensionName: string, options: ControlOptions, { restart, }: {
|
|
20
20
|
restart: boolean;
|
|
21
21
|
}): Promise<void>;
|
|
22
|
+
export declare function runInDimensionScript(host: Sandbox, dimensionName: string, cmd: string[], { cwd, env, stdin }: RunCommandOptions, options?: ControlOptions): Promise<RunCommandResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
1
2
|
import { exitEnv, records, runControl } from "../lib/control.js";
|
|
2
3
|
import { sh } from "../lib/sh.js";
|
|
3
4
|
import { HYPERBRANE_VERSION } from "../lib/version.js";
|
|
@@ -96,6 +97,13 @@ export async function startTransportScript(host, dimensionName, options, { resta
|
|
|
96
97
|
}
|
|
97
98
|
check(result, `starting dimension ${dimensionName}'s transport worker`);
|
|
98
99
|
}
|
|
100
|
+
export async function runInDimensionScript(host, dimensionName, cmd, { cwd, env = {}, stdin }, options = {}) {
|
|
101
|
+
const envFlags = Object.entries(env).flatMap(([name, value]) => ["-e", `${name}=${value}`]);
|
|
102
|
+
const result = await runControl(host, PRELUDE, RUN_IN_DIMENSION, { ...exitEnv(EXIT), ...dimensionEnv(dimensionName, options), WORKDIR: posix.resolve(WORKSPACE_PATH, cwd ?? "."), INTERACTIVE: stdin === undefined ? "" : "1" }, {}, { args: [...envFlags, containerName(dimensionName), ...cmd], stdin });
|
|
103
|
+
if (!result.stdout.startsWith(COMMAND_START))
|
|
104
|
+
check(result, `running a command in dimension ${dimensionName}`);
|
|
105
|
+
return { ...result, stdout: result.stdout.slice(COMMAND_START.length) };
|
|
106
|
+
}
|
|
99
107
|
function dataEnv({ dataDirectory }) {
|
|
100
108
|
return { ...(dataDirectory === undefined ? {} : { DATA: dataDirectory }), CONTAINER_PREFIX: containerName(""), RUN_PATH, STATE_PATH };
|
|
101
109
|
}
|
|
@@ -121,6 +129,7 @@ function check(result, what) {
|
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
131
|
const CONTAINERS_START = "\n\x1d\n";
|
|
132
|
+
const COMMAND_START = "\x1e";
|
|
124
133
|
const PRELUDE = sh `
|
|
125
134
|
# shellcheck disable=SC2034
|
|
126
135
|
dimension_paths() {
|
|
@@ -326,3 +335,12 @@ done
|
|
|
326
335
|
# shellcheck disable=SC2086
|
|
327
336
|
[ -z "$containers" ] || docker stats --no-stream --format '{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}' $containers
|
|
328
337
|
`;
|
|
338
|
+
const RUN_IN_DIMENSION = sh `
|
|
339
|
+
set -eu
|
|
340
|
+
dimension_paths
|
|
341
|
+
require_dimension
|
|
342
|
+
[ "$RUNNING" = true ] || refuse "$E_CONFLICT" "dimension $DIMENSION isn't running"
|
|
343
|
+
user="$(docker inspect -f '{{.Config.User}}' "$CONTAINER")"
|
|
344
|
+
printf '\036'
|
|
345
|
+
exec docker exec \${INTERACTIVE:+-i} -u "\${user:-0:0}" -w "$WORKDIR" "$@"
|
|
346
|
+
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DimensionInvalidError, isDimensionName } from "./api.js";
|
|
2
|
-
import { createDimensionScript, destroyDimensionScript, dimensionUsageScript, listDimensionsScript, restartDimensionScript, startTransportScript, updateDimensionScript, } from "./control.js";
|
|
2
|
+
import { createDimensionScript, destroyDimensionScript, dimensionUsageScript, listDimensionsScript, restartDimensionScript, runInDimensionScript, startTransportScript, updateDimensionScript, } from "./control.js";
|
|
3
3
|
import { createDimensionImage } from "./image.js";
|
|
4
4
|
import { RUN_PATH, STATE_PATH, WORKSPACE_PATH, containerName, dimensionLayout } from "./paths.js";
|
|
5
5
|
import { transportFiles } from "./transportClient.js";
|
|
@@ -41,6 +41,20 @@ export function createDimensionService(host, { dataDirectory } = {}) {
|
|
|
41
41
|
await portals.restorePortals({ dimensionName });
|
|
42
42
|
await startTransportScript(host, dimensionName, options, { restart: true });
|
|
43
43
|
}
|
|
44
|
+
async function restoreDimensions() {
|
|
45
|
+
const running = (await listDimensionsScript(host, options)).filter(({ status }) => status === "running");
|
|
46
|
+
const restored = await Promise.all(running.map(async ({ record: { name } }) => {
|
|
47
|
+
try {
|
|
48
|
+
await startTransportScript(host, name, options, { restart: false });
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.warn(`starting dimension ${name}'s transport worker failed:`, error.message);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
return restored.filter((name) => name !== null);
|
|
57
|
+
}
|
|
44
58
|
async function transportSocket(dimensionName) {
|
|
45
59
|
assertValidName(dimensionName);
|
|
46
60
|
const data = dataDirectory ?? `${await host.homeDirectory()}/.local/share/hyperbrane`;
|
|
@@ -53,6 +67,16 @@ export function createDimensionService(host, { dataDirectory } = {}) {
|
|
|
53
67
|
const { state: _state, ...updated } = await updateDimensionScript(host, dimensionName, limits, options);
|
|
54
68
|
return updated;
|
|
55
69
|
}
|
|
70
|
+
async function runCommand(dimensionName, cmd, commandOptions = {}) {
|
|
71
|
+
assertValidName(dimensionName);
|
|
72
|
+
if (cmd.length === 0)
|
|
73
|
+
throw new DimensionInvalidError("a command needs at least its program");
|
|
74
|
+
for (const name of Object.keys(commandOptions.env ?? {})) {
|
|
75
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
76
|
+
throw new DimensionInvalidError(`not an environment variable name: "${name}"`);
|
|
77
|
+
}
|
|
78
|
+
return runInDimensionScript(host, dimensionName, cmd, commandOptions, options);
|
|
79
|
+
}
|
|
56
80
|
return {
|
|
57
81
|
listDimensions,
|
|
58
82
|
getDimensionUsage: () => dimensionUsageScript(host, options),
|
|
@@ -62,7 +86,9 @@ export function createDimensionService(host, { dataDirectory } = {}) {
|
|
|
62
86
|
createDimension: (dimension) => createDimension(dimension),
|
|
63
87
|
destroyDimension: (dimensionName) => destroyDimension(dimensionName),
|
|
64
88
|
restartDimension: (dimensionName) => restartDimension(dimensionName),
|
|
89
|
+
restoreDimensions,
|
|
65
90
|
updateDimension: (dimensionName, limits) => updateDimension(dimensionName, limits),
|
|
91
|
+
runCommand: (dimensionName, cmd, commandOptions) => runCommand(dimensionName, cmd, commandOptions),
|
|
66
92
|
};
|
|
67
93
|
}
|
|
68
94
|
function assertLimits(limits) {
|