@cofy-x/axern-sdk 0.2.0-bootstrap.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 (92) hide show
  1. package/README.md +169 -0
  2. package/dist/client/index.d.ts +63 -0
  3. package/dist/client/index.js +213 -0
  4. package/dist/config/index.d.ts +15 -0
  5. package/dist/config/index.js +65 -0
  6. package/dist/errors/index.d.ts +46 -0
  7. package/dist/errors/index.js +123 -0
  8. package/dist/generated/proto.d.ts +10 -0
  9. package/dist/generated/proto.js +80 -0
  10. package/dist/index.d.ts +19 -0
  11. package/dist/index.js +13 -0
  12. package/dist/node/archive.d.ts +9 -0
  13. package/dist/node/archive.js +41 -0
  14. package/dist/node/attached_process.d.ts +10 -0
  15. package/dist/node/attached_process.js +60 -0
  16. package/dist/node/capabilities.d.ts +8 -0
  17. package/dist/node/capabilities.js +51 -0
  18. package/dist/node/client.d.ts +44 -0
  19. package/dist/node/client.js +96 -0
  20. package/dist/node/computer_use.d.ts +12 -0
  21. package/dist/node/computer_use.js +81 -0
  22. package/dist/node/context.d.ts +22 -0
  23. package/dist/node/context.js +37 -0
  24. package/dist/node/exec.d.ts +12 -0
  25. package/dist/node/exec.js +93 -0
  26. package/dist/node/files.d.ts +18 -0
  27. package/dist/node/files.js +101 -0
  28. package/dist/node/process.d.ts +36 -0
  29. package/dist/node/process.js +144 -0
  30. package/dist/node/streams.d.ts +8 -0
  31. package/dist/node/streams.js +70 -0
  32. package/dist/proto/axern/common/file/v1/file.proto +31 -0
  33. package/dist/proto/axern/control/admin/v1/allocation_lifecycle.proto +91 -0
  34. package/dist/proto/axern/control/admin/v1/audit.proto +53 -0
  35. package/dist/proto/axern/control/admin/v1/node.proto +49 -0
  36. package/dist/proto/axern/control/admin/v1/reliability.proto +184 -0
  37. package/dist/proto/axern/control/admin/v1/service.proto +18 -0
  38. package/dist/proto/axern/control/admin/v1/storage.proto +81 -0
  39. package/dist/proto/axern/control/agentprofile/v1/agent_profile.proto +169 -0
  40. package/dist/proto/axern/control/catalog/v1/catalog.proto +127 -0
  41. package/dist/proto/axern/control/common/v1/common.proto +171 -0
  42. package/dist/proto/axern/control/environment/v1/environment.proto +94 -0
  43. package/dist/proto/axern/control/function/v1/function.proto +130 -0
  44. package/dist/proto/axern/control/function/v1/function_types.proto +233 -0
  45. package/dist/proto/axern/control/gateway/v1/gateway.proto +60 -0
  46. package/dist/proto/axern/control/namespace/v1/namespace.proto +52 -0
  47. package/dist/proto/axern/control/node/v1/node_control.proto +302 -0
  48. package/dist/proto/axern/control/quota/v1/quota.proto +113 -0
  49. package/dist/proto/axern/control/rollout/v1/rollout.proto +344 -0
  50. package/dist/proto/axern/control/run/v1/run.proto +88 -0
  51. package/dist/proto/axern/control/secret/v1/secret.proto +75 -0
  52. package/dist/proto/axern/control/service/v1/service.proto +96 -0
  53. package/dist/proto/axern/control/service/v1/service_event.proto +47 -0
  54. package/dist/proto/axern/control/service/v1/service_replica.proto +74 -0
  55. package/dist/proto/axern/control/service/v1/service_types.proto +155 -0
  56. package/dist/proto/axern/control/storage/v1/storage.proto +107 -0
  57. package/dist/proto/axern/control/storage/v1/storage_types.proto +125 -0
  58. package/dist/proto/axern/control/tunnel/v1/tunnel.proto +195 -0
  59. package/dist/proto/axern/data/artifact/v1/artifact.proto +19 -0
  60. package/dist/proto/axern/node/sandbox/v1/node.proto +652 -0
  61. package/dist/proto/axern/tunnel/v1/tunnel.proto +50 -0
  62. package/dist/resources.d.ts +13 -0
  63. package/dist/resources.js +107 -0
  64. package/dist/sandbox/archive.d.ts +8 -0
  65. package/dist/sandbox/archive.js +228 -0
  66. package/dist/sandbox/index.d.ts +86 -0
  67. package/dist/sandbox/index.js +204 -0
  68. package/dist/sandbox/lifecycle.d.ts +11 -0
  69. package/dist/sandbox/lifecycle.js +57 -0
  70. package/dist/tunnel/connector.d.ts +34 -0
  71. package/dist/tunnel/connector.js +141 -0
  72. package/dist/tunnel/control.d.ts +22 -0
  73. package/dist/tunnel/control.js +91 -0
  74. package/dist/tunnel/debug.d.ts +6 -0
  75. package/dist/tunnel/debug.js +19 -0
  76. package/dist/tunnel/relay.d.ts +17 -0
  77. package/dist/tunnel/relay.js +41 -0
  78. package/dist/tunnel/runtime.d.ts +34 -0
  79. package/dist/tunnel/runtime.js +118 -0
  80. package/dist/tunnel/session.d.ts +25 -0
  81. package/dist/tunnel/session.js +95 -0
  82. package/dist/tunnel/target.d.ts +7 -0
  83. package/dist/tunnel/target.js +28 -0
  84. package/dist/tunnel/types.d.ts +25 -0
  85. package/dist/tunnel/types.js +6 -0
  86. package/dist/types.d.ts +219 -0
  87. package/dist/types.js +8 -0
  88. package/dist/validation.d.ts +10 -0
  89. package/dist/validation.js +37 -0
  90. package/dist/version.d.ts +7 -0
  91. package/dist/version.js +9 -0
  92. package/package.json +57 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import * as grpc from "@grpc/grpc-js";
7
+ export declare function axernProtoRoot(): string;
8
+ export declare function loadAxernPackage(): grpc.GrpcObject;
9
+ export declare function serviceConstructor(pathParts: string[]): grpc.ServiceClientConstructor;
10
+ export declare function unary<TRequest extends object, TResponse>(client: grpc.Client, method: string, request: TRequest, deadlineMs?: number): Promise<TResponse>;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import path from "node:path";
7
+ import { existsSync } from "node:fs";
8
+ import { fileURLToPath } from "node:url";
9
+ import * as grpc from "@grpc/grpc-js";
10
+ import * as protoLoader from "@grpc/proto-loader";
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+ const defaultProtoRootCandidates = [
13
+ path.resolve(__dirname, "../proto"),
14
+ path.resolve(__dirname, "../../../proto"),
15
+ ];
16
+ const protoFiles = [
17
+ "axern/control/environment/v1/environment.proto",
18
+ "axern/control/gateway/v1/gateway.proto",
19
+ "axern/control/service/v1/service.proto",
20
+ "axern/control/tunnel/v1/tunnel.proto",
21
+ "axern/node/sandbox/v1/node.proto",
22
+ "axern/tunnel/v1/tunnel.proto",
23
+ ];
24
+ let loadedPackage;
25
+ export function axernProtoRoot() {
26
+ if (process.env.AXERN_PROTO_ROOT !== undefined && process.env.AXERN_PROTO_ROOT !== "") {
27
+ return process.env.AXERN_PROTO_ROOT;
28
+ }
29
+ const protoRoot = defaultProtoRootCandidates.find((candidate) => existsSync(path.join(candidate, "axern/control/environment/v1/environment.proto")));
30
+ if (protoRoot === undefined) {
31
+ throw new Error("AXERN_PROTO_ROOT is required because bundled proto files were not found");
32
+ }
33
+ return protoRoot;
34
+ }
35
+ export function loadAxernPackage() {
36
+ if (loadedPackage !== undefined) {
37
+ return loadedPackage;
38
+ }
39
+ const protoRoot = axernProtoRoot();
40
+ const definition = protoLoader.loadSync(protoFiles.map((file) => path.join(protoRoot, file)), {
41
+ includeDirs: [protoRoot],
42
+ keepCase: true,
43
+ longs: String,
44
+ enums: Number,
45
+ defaults: false,
46
+ oneofs: true,
47
+ });
48
+ loadedPackage = grpc.loadPackageDefinition(definition);
49
+ return loadedPackage;
50
+ }
51
+ export function serviceConstructor(pathParts) {
52
+ let current = loadAxernPackage();
53
+ for (const part of pathParts) {
54
+ current = current[part];
55
+ if (current === undefined) {
56
+ throw new Error(`missing proto service path: ${pathParts.join(".")}`);
57
+ }
58
+ }
59
+ return current;
60
+ }
61
+ export function unary(client, method, request, deadlineMs) {
62
+ return new Promise((resolve, reject) => {
63
+ const callback = (error, response) => {
64
+ if (error) {
65
+ reject(error);
66
+ }
67
+ else {
68
+ resolve(response);
69
+ }
70
+ };
71
+ const options = deadlineMs === undefined ? undefined : { deadline: Date.now() + deadlineMs };
72
+ const fn = client[method];
73
+ if (options === undefined) {
74
+ fn.call(client, request, callback);
75
+ }
76
+ else {
77
+ fn.call(client, request, options, callback);
78
+ }
79
+ });
80
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export { AxernClient } from "./client/index.js";
7
+ export type { AxernClientOptions, CreateEnvironmentOptions, CreateServiceOptions, } from "./client/index.js";
8
+ export { loadAxernContext, loadAxernEnv } from "./config/index.js";
9
+ export type { AxernConfig } from "./config/index.js";
10
+ export { AxernError, AxernRpcError, isNotFound, isCancelled, isUnavailable, errorRetryable, isPermissionDenied, isTimeout, rpcCode, SandboxExecError, SandboxStateError, SandboxTimeoutError, SandboxValidationError, } from "./errors/index.js";
11
+ export { NodeSandboxClient } from "./node/client.js";
12
+ export type { NodeSandboxClientOptions } from "./node/client.js";
13
+ export { SandboxProcess } from "./node/process.js";
14
+ export type { ResourceQuantity } from "./resources.js";
15
+ export { Sandbox } from "./sandbox/index.js";
16
+ export type { SandboxMetadata, SandboxOptions, SandboxState } from "./sandbox/index.js";
17
+ export type { ChmodOptions, CapabilityDependencyStatus, CapabilityProviderStatus, CapabilityProviderSummary, CapabilityStatus, Command, ComputerUseDependencyStatus, ComputerUseDisplay, ComputerUseKeyboardOptions, ComputerUseMouseOptions, ComputerUseRegion, ComputerUseScreenshot, ComputerUseScreenshotOptions, ComputerUseStatus, CopyOptions, DownloadArchiveOptions, DownloadDirOptions, ExecOptions, ExecResult, ImageExecOptions, ImageProcessMount, ImageProcessOptions, MkdirOptions, MoveOptions, NodeCallOptions, ProcessEvent, ProcessOptions, ProcessResult, RemoveOptions, SandboxFileInfo, SandboxFileKind, TouchOptions, TunnelConnectorOptions, TunnelMetadata, TunnelOptions, UploadArchiveOptions, UploadDirOptions, VolumeMount, WriteFileOptions, } from "./types.js";
18
+ export { workspaceMount } from "./types.js";
19
+ export { AXERN_VERSION, platformName } from "./version.js";
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export { AxernClient } from "./client/index.js";
7
+ export { loadAxernContext, loadAxernEnv } from "./config/index.js";
8
+ export { AxernError, AxernRpcError, isNotFound, isCancelled, isUnavailable, errorRetryable, isPermissionDenied, isTimeout, rpcCode, SandboxExecError, SandboxStateError, SandboxTimeoutError, SandboxValidationError, } from "./errors/index.js";
9
+ export { NodeSandboxClient } from "./node/client.js";
10
+ export { SandboxProcess } from "./node/process.js";
11
+ export { Sandbox } from "./sandbox/index.js";
12
+ export { workspaceMount } from "./types.js";
13
+ export { AXERN_VERSION, platformName } from "./version.js";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { DownloadArchiveOptions, UploadArchiveOptions } from "../types.js";
7
+ import type { NodeClientContext } from "./context.js";
8
+ export declare function uploadArchive(ctx: NodeClientContext, path: string, chunks: () => AsyncIterable<Buffer | Uint8Array>, options?: UploadArchiveOptions): Promise<void>;
9
+ export declare function downloadArchive(ctx: NodeClientContext, path: string, options?: DownloadArchiveOptions): AsyncIterable<Buffer>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { mapRpcError } from "../errors/index.js";
7
+ import { nonEmptyPath } from "../validation.js";
8
+ import { downloadArchiveStream, uploadArchiveStream } from "./streams.js";
9
+ export async function uploadArchive(ctx, path, chunks, options = {}) {
10
+ try {
11
+ await ctx.withAuthRetry(options.leaseTtlSeconds ?? 300, (client) => uploadArchiveStream(client, ctx.authRequest({
12
+ path: nonEmptyPath(path),
13
+ format: 1,
14
+ create_parents: options.createParents ?? true,
15
+ overwrite: options.overwrite ?? true,
16
+ symlink_policy: 1,
17
+ }), chunks(), options.rpcTimeoutMs));
18
+ }
19
+ catch (error) {
20
+ throw mapRpcError(error, "sandbox upload archive", ctx.allocationId);
21
+ }
22
+ }
23
+ export async function* downloadArchive(ctx, path, options = {}) {
24
+ const client = ctx.rpcClient();
25
+ try {
26
+ const chunks = downloadArchiveStream(client, ctx.authRequest({
27
+ path: nonEmptyPath(path),
28
+ format: 1,
29
+ symlink_policy: 1,
30
+ }), options.rpcTimeoutMs);
31
+ for await (const chunk of chunks) {
32
+ yield chunk;
33
+ }
34
+ }
35
+ catch (error) {
36
+ throw mapRpcError(error, "sandbox download archive", ctx.allocationId);
37
+ }
38
+ finally {
39
+ client.close();
40
+ }
41
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { Command, ImageProcessOptions, ProcessOptions } from "../types.js";
7
+ import { NodeClientContext } from "./context.js";
8
+ import { SandboxProcess } from "./process.js";
9
+ export declare function process(ctx: NodeClientContext, command: Command, options?: ProcessOptions): Promise<SandboxProcess>;
10
+ export declare function processImage(ctx: NodeClientContext, image: string, command: Command, options?: ImageProcessOptions): Promise<SandboxProcess>;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { mapRpcError } from "../errors/index.js";
7
+ import { normalizeCommand } from "../validation.js";
8
+ import { execSpec, imageProcessSpec } from "./exec.js";
9
+ import { SandboxProcess } from "./process.js";
10
+ export async function process(ctx, command, options = {}) {
11
+ const argv = normalizeCommand(command);
12
+ const client = ctx.rpcClient();
13
+ const call = client
14
+ .Process();
15
+ const sandboxProcess = new SandboxProcess({
16
+ allocationId: ctx.allocationId,
17
+ call,
18
+ closeClient: () => client.close(),
19
+ });
20
+ call.write({
21
+ open: ctx.authRequest({
22
+ spec: execSpec(argv, options),
23
+ }),
24
+ });
25
+ try {
26
+ await sandboxProcess.waitReady();
27
+ return sandboxProcess;
28
+ }
29
+ catch (error) {
30
+ await sandboxProcess.close();
31
+ throw mapRpcError(error, "sandbox process", ctx.allocationId);
32
+ }
33
+ }
34
+ export async function processImage(ctx, image, command, options = {}) {
35
+ if (image.trim() === "") {
36
+ throw new Error("image is required");
37
+ }
38
+ const argv = normalizeCommand(command);
39
+ const client = ctx.rpcClient();
40
+ const call = client
41
+ .ProcessImage();
42
+ const sandboxProcess = new SandboxProcess({
43
+ allocationId: ctx.allocationId,
44
+ call,
45
+ closeClient: () => client.close(),
46
+ });
47
+ call.write({
48
+ open: ctx.authRequest({
49
+ spec: imageProcessSpec(image, argv, options),
50
+ }),
51
+ });
52
+ try {
53
+ await sandboxProcess.waitReady();
54
+ return sandboxProcess;
55
+ }
56
+ catch (error) {
57
+ await sandboxProcess.close();
58
+ throw mapRpcError(error, "sandbox image process", ctx.allocationId);
59
+ }
60
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { CapabilityStatus, NodeCallOptions } from "../types.js";
7
+ import type { NodeClientContext } from "./context.js";
8
+ export declare function capabilityStatus(ctx: NodeClientContext, options?: NodeCallOptions): Promise<CapabilityStatus>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { mapRpcError } from "../errors/index.js";
7
+ import { unary } from "../generated/proto.js";
8
+ export async function capabilityStatus(ctx, options = {}) {
9
+ try {
10
+ const response = await ctx.withAuthRetry(60, (client) => unary(client, "CapabilityStatus", ctx.authRequest({}), options.rpcTimeoutMs));
11
+ return {
12
+ ready: response.ready === true,
13
+ capabilities: strings(response.capabilities),
14
+ providers: records(response.providers).map((provider) => ({
15
+ name: String(provider.name ?? ""),
16
+ state: String(provider.state ?? ""),
17
+ available: provider.available === true,
18
+ capabilities: strings(provider.capabilities),
19
+ backend: String(provider.backend ?? ""),
20
+ reason: String(provider.reason ?? ""),
21
+ dependencies: records(provider.dependencies).map((dependency) => ({
22
+ name: String(dependency.name ?? ""),
23
+ available: dependency.available === true,
24
+ reason: String(dependency.reason ?? ""),
25
+ })),
26
+ })),
27
+ providerSummary: providerSummary(response.provider_summary),
28
+ };
29
+ }
30
+ catch (error) {
31
+ throw mapRpcError(error, "sandbox capability status", ctx.allocationId);
32
+ }
33
+ }
34
+ function providerSummary(input) {
35
+ const summary = record(input);
36
+ return {
37
+ total: Number(summary.total ?? 0),
38
+ available: Number(summary.available ?? 0),
39
+ degraded: Number(summary.degraded ?? 0),
40
+ unavailable: Number(summary.unavailable ?? 0),
41
+ };
42
+ }
43
+ function strings(input) {
44
+ return Array.isArray(input) ? input.map(String) : [];
45
+ }
46
+ function records(input) {
47
+ return Array.isArray(input) ? input.map(record) : [];
48
+ }
49
+ function record(input) {
50
+ return typeof input === "object" && input !== null ? input : {};
51
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type * as grpc from "@grpc/grpc-js";
7
+ import type { ChmodOptions, CapabilityStatus, Command, ComputerUseDisplay, ComputerUseKeyboardOptions, ComputerUseMouseOptions, ComputerUseScreenshot, ComputerUseScreenshotOptions, ComputerUseStatus, CopyOptions, DownloadArchiveOptions, ExecOptions, ExecResult, ImageExecOptions, ImageProcessOptions, MkdirOptions, MoveOptions, NodeCallOptions, ProcessOptions, RemoveOptions, SandboxFileInfo, TouchOptions, UploadArchiveOptions, WriteFileOptions } from "../types.js";
8
+ import type { SandboxProcess } from "./process.js";
9
+ export interface NodeSandboxClientOptions {
10
+ allocationId: string;
11
+ target: string;
12
+ credentials: grpc.ChannelCredentials;
13
+ channelOptions?: grpc.ChannelOptions;
14
+ }
15
+ export declare class NodeSandboxClient {
16
+ readonly allocationId: string;
17
+ private readonly ctx;
18
+ constructor(options: NodeSandboxClientOptions);
19
+ exec(command: Command, options?: ExecOptions): Promise<ExecResult>;
20
+ process(command: Command, options?: ProcessOptions): Promise<SandboxProcess>;
21
+ execImage(image: string, command: Command, options?: ImageExecOptions): Promise<ExecResult>;
22
+ processImage(image: string, command: Command, options?: ImageProcessOptions): Promise<SandboxProcess>;
23
+ capabilityStatus(options?: NodeCallOptions): Promise<CapabilityStatus>;
24
+ computerUseStatus(options?: NodeCallOptions): Promise<ComputerUseStatus>;
25
+ computerUseScreenshot(options?: ComputerUseScreenshotOptions): Promise<ComputerUseScreenshot>;
26
+ computerUseDisplay(options?: NodeCallOptions): Promise<ComputerUseDisplay>;
27
+ computerUseMouse(options?: ComputerUseMouseOptions): Promise<void>;
28
+ computerUseKeyboard(options?: ComputerUseKeyboardOptions): Promise<void>;
29
+ stat(path: string): Promise<SandboxFileInfo>;
30
+ listDir(path: string): Promise<SandboxFileInfo[]>;
31
+ exists(path: string): Promise<boolean>;
32
+ readFile(path: string): Promise<Buffer>;
33
+ readText(path: string, encoding?: BufferEncoding): Promise<string>;
34
+ writeFile(path: string, data: Buffer | Uint8Array | string, options?: WriteFileOptions): Promise<void>;
35
+ writeText(path: string, data: string, options?: WriteFileOptions): Promise<void>;
36
+ mkdir(path: string, options?: MkdirOptions): Promise<void>;
37
+ remove(path: string, options?: RemoveOptions): Promise<void>;
38
+ copy(srcPath: string, dstPath: string, options?: CopyOptions): Promise<void>;
39
+ move(srcPath: string, dstPath: string, options?: MoveOptions): Promise<void>;
40
+ chmod(path: string, mode: number, options?: ChmodOptions): Promise<void>;
41
+ touch(path: string, options?: TouchOptions): Promise<void>;
42
+ uploadArchive(path: string, chunks: () => AsyncIterable<Buffer | Uint8Array>, options?: UploadArchiveOptions): Promise<void>;
43
+ downloadArchive(path: string, options?: DownloadArchiveOptions): AsyncIterable<Buffer>;
44
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { uploadArchive, downloadArchive } from "./archive.js";
7
+ import { capabilityStatus } from "./capabilities.js";
8
+ import * as computerUse from "./computer_use.js";
9
+ import { process as startProcess } from "./attached_process.js";
10
+ import { processImage as startImageProcess } from "./attached_process.js";
11
+ import { NodeClientContext } from "./context.js";
12
+ import { exec, execImage } from "./exec.js";
13
+ import * as files from "./files.js";
14
+ export class NodeSandboxClient {
15
+ allocationId;
16
+ ctx;
17
+ constructor(options) {
18
+ this.allocationId = options.allocationId;
19
+ this.ctx = new NodeClientContext(options);
20
+ }
21
+ async exec(command, options = {}) {
22
+ return exec(this.ctx, command, options);
23
+ }
24
+ async process(command, options = {}) {
25
+ return startProcess(this.ctx, command, options);
26
+ }
27
+ async execImage(image, command, options = {}) {
28
+ return execImage(this.ctx, image, command, options);
29
+ }
30
+ async processImage(image, command, options = {}) {
31
+ return startImageProcess(this.ctx, image, command, options);
32
+ }
33
+ async capabilityStatus(options = {}) {
34
+ return capabilityStatus(this.ctx, options);
35
+ }
36
+ async computerUseStatus(options = {}) {
37
+ return computerUse.computerUseStatus(this.ctx, options);
38
+ }
39
+ async computerUseScreenshot(options = {}) {
40
+ return computerUse.computerUseScreenshot(this.ctx, options);
41
+ }
42
+ async computerUseDisplay(options = {}) {
43
+ return computerUse.computerUseDisplay(this.ctx, options);
44
+ }
45
+ async computerUseMouse(options = {}) {
46
+ return computerUse.computerUseMouse(this.ctx, options);
47
+ }
48
+ async computerUseKeyboard(options = {}) {
49
+ return computerUse.computerUseKeyboard(this.ctx, options);
50
+ }
51
+ async stat(path) {
52
+ return files.stat(this.ctx, path);
53
+ }
54
+ async listDir(path) {
55
+ return files.listDir(this.ctx, path);
56
+ }
57
+ async exists(path) {
58
+ return files.exists(this.ctx, path);
59
+ }
60
+ async readFile(path) {
61
+ return files.readFile(this.ctx, path);
62
+ }
63
+ async readText(path, encoding = "utf8") {
64
+ return (await this.readFile(path)).toString(encoding);
65
+ }
66
+ async writeFile(path, data, options = {}) {
67
+ return files.writeFile(this.ctx, path, data, options);
68
+ }
69
+ async writeText(path, data, options = {}) {
70
+ return this.writeFile(path, data, options);
71
+ }
72
+ async mkdir(path, options = {}) {
73
+ return files.mkdir(this.ctx, path, options);
74
+ }
75
+ async remove(path, options = {}) {
76
+ return files.remove(this.ctx, path, options);
77
+ }
78
+ async copy(srcPath, dstPath, options = {}) {
79
+ return files.copy(this.ctx, srcPath, dstPath, options);
80
+ }
81
+ async move(srcPath, dstPath, options = {}) {
82
+ return files.move(this.ctx, srcPath, dstPath, options);
83
+ }
84
+ async chmod(path, mode, options = {}) {
85
+ return files.chmod(this.ctx, path, mode, options);
86
+ }
87
+ async touch(path, options = {}) {
88
+ return files.touch(this.ctx, path, options);
89
+ }
90
+ async uploadArchive(path, chunks, options = {}) {
91
+ return uploadArchive(this.ctx, path, chunks, options);
92
+ }
93
+ downloadArchive(path, options = {}) {
94
+ return downloadArchive(this.ctx, path, options);
95
+ }
96
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { ComputerUseDisplay, ComputerUseKeyboardOptions, ComputerUseMouseOptions, ComputerUseScreenshot, ComputerUseScreenshotOptions, ComputerUseStatus, NodeCallOptions } from "../types.js";
7
+ import type { NodeClientContext } from "./context.js";
8
+ export declare function computerUseStatus(ctx: NodeClientContext, options?: NodeCallOptions): Promise<ComputerUseStatus>;
9
+ export declare function computerUseScreenshot(ctx: NodeClientContext, options?: ComputerUseScreenshotOptions): Promise<ComputerUseScreenshot>;
10
+ export declare function computerUseDisplay(ctx: NodeClientContext, options?: NodeCallOptions): Promise<ComputerUseDisplay>;
11
+ export declare function computerUseMouse(ctx: NodeClientContext, options?: ComputerUseMouseOptions): Promise<void>;
12
+ export declare function computerUseKeyboard(ctx: NodeClientContext, options?: ComputerUseKeyboardOptions): Promise<void>;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { mapRpcError } from "../errors/index.js";
7
+ import { unary } from "../generated/proto.js";
8
+ export async function computerUseStatus(ctx, options = {}) {
9
+ const response = await computerUseUnary(ctx, "ComputerUseStatus", {}, options.rpcTimeoutMs);
10
+ return {
11
+ available: response.available === true,
12
+ display: String(response.display ?? ""),
13
+ backend: String(response.backend ?? ""),
14
+ reason: String(response.reason ?? ""),
15
+ dependencies: records(response.dependencies).map((dependency) => ({
16
+ name: String(dependency.name ?? ""),
17
+ available: dependency.available === true,
18
+ reason: String(dependency.reason ?? ""),
19
+ })),
20
+ };
21
+ }
22
+ export async function computerUseScreenshot(ctx, options = {}) {
23
+ const response = await computerUseUnary(ctx, "ComputerUseScreenshot", {
24
+ show_cursor: options.showCursor ?? false,
25
+ region: options.region === undefined ? undefined : {
26
+ x: options.region.x,
27
+ y: options.region.y,
28
+ width: options.region.width,
29
+ height: options.region.height,
30
+ },
31
+ format: options.format ?? "",
32
+ quality: options.quality ?? 0,
33
+ scale: options.scale ?? 0,
34
+ }, options.rpcTimeoutMs);
35
+ return {
36
+ data: Buffer.from(response.data ?? []),
37
+ contentType: String(response.content_type ?? ""),
38
+ };
39
+ }
40
+ export async function computerUseDisplay(ctx, options = {}) {
41
+ const response = await computerUseUnary(ctx, "ComputerUseDisplay", {}, options.rpcTimeoutMs);
42
+ return {
43
+ display: String(response.display ?? ""),
44
+ backend: String(response.backend ?? ""),
45
+ width: Number(response.width ?? 0),
46
+ height: Number(response.height ?? 0),
47
+ };
48
+ }
49
+ export async function computerUseMouse(ctx, options = {}) {
50
+ await computerUseUnary(ctx, "ComputerUseMouse", {
51
+ action: options.action ?? "click",
52
+ x: options.x ?? 0,
53
+ y: options.y ?? 0,
54
+ to_x: options.toX ?? 0,
55
+ to_y: options.toY ?? 0,
56
+ button: options.button ?? "",
57
+ direction: options.direction ?? "",
58
+ amount: options.amount ?? 0,
59
+ }, options.rpcTimeoutMs);
60
+ }
61
+ export async function computerUseKeyboard(ctx, options = {}) {
62
+ await computerUseUnary(ctx, "ComputerUseKeyboard", {
63
+ text: options.text ?? "",
64
+ key: options.key ?? "",
65
+ keys: options.keys ?? [],
66
+ delay_ms: options.delayMs ?? 0,
67
+ }, options.rpcTimeoutMs);
68
+ }
69
+ async function computerUseUnary(ctx, method, payload, rpcTimeoutMs) {
70
+ try {
71
+ return await ctx.withAuthRetry(60, (client) => unary(client, method, ctx.authRequest(payload), rpcTimeoutMs));
72
+ }
73
+ catch (error) {
74
+ throw mapRpcError(error, `sandbox ${method}`, ctx.allocationId);
75
+ }
76
+ }
77
+ function records(input) {
78
+ return Array.isArray(input)
79
+ ? input.map((item) => typeof item === "object" && item !== null ? item : {})
80
+ : [];
81
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import * as grpc from "@grpc/grpc-js";
7
+ export interface NodeClientContextOptions {
8
+ allocationId: string;
9
+ target: string;
10
+ credentials: grpc.ChannelCredentials;
11
+ channelOptions?: grpc.ChannelOptions;
12
+ }
13
+ export declare class NodeClientContext {
14
+ readonly allocationId: string;
15
+ private readonly target;
16
+ private readonly credentials;
17
+ private readonly channelOptions;
18
+ constructor(options: NodeClientContextOptions);
19
+ withAuthRetry<T>(_leaseTtlSeconds: number, operation: (client: grpc.Client) => Promise<T>): Promise<T>;
20
+ rpcClient(): grpc.Client;
21
+ authRequest(payload: Record<string, unknown>): Record<string, unknown>;
22
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { serviceConstructor } from "../generated/proto.js";
7
+ export class NodeClientContext {
8
+ allocationId;
9
+ target;
10
+ credentials;
11
+ channelOptions;
12
+ constructor(options) {
13
+ this.allocationId = options.allocationId;
14
+ this.target = options.target;
15
+ this.credentials = options.credentials;
16
+ this.channelOptions = options.channelOptions ?? {};
17
+ }
18
+ async withAuthRetry(_leaseTtlSeconds, operation) {
19
+ const client = this.rpcClient();
20
+ try {
21
+ return await operation(client);
22
+ }
23
+ finally {
24
+ client.close();
25
+ }
26
+ }
27
+ rpcClient() {
28
+ const NodeSandbox = serviceConstructor(["axern", "node", "sandbox", "v1", "NodeSandbox"]);
29
+ return new NodeSandbox(this.target, this.credentials, this.channelOptions);
30
+ }
31
+ authRequest(payload) {
32
+ return {
33
+ allocation_id: this.allocationId,
34
+ ...payload,
35
+ };
36
+ }
37
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 cofy-x
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { Command, ExecOptions, ExecResult, ImageExecOptions, ImageProcessOptions, ProcessOptions } from "../types.js";
7
+ import type { NodeClientContext } from "./context.js";
8
+ export declare function exec(ctx: NodeClientContext, command: Command, options?: ExecOptions): Promise<ExecResult>;
9
+ export declare function execImage(ctx: NodeClientContext, image: string, command: Command, options?: ImageExecOptions): Promise<ExecResult>;
10
+ export declare function execSpec(argv: string[], options: ExecOptions | ProcessOptions): Record<string, unknown>;
11
+ export declare function imageProcessSpec(image: string, argv: string[], options: ImageExecOptions | ImageProcessOptions): Record<string, unknown>;
12
+ export declare function execResult(response: Record<string, unknown>): ExecResult;