deltabox-lite 0.0.0-stage → 0.1.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 CHANGED
@@ -1,3 +1,34 @@
1
- # Temporary Holding Version
1
+ # deltabox-lite
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ This package installs the native `deltabox` runtime for supported Linux and
4
+ macOS systems. The matching optional platform package carries the binary and
5
+ the Node-API addon; `bin/deltabox.js` is a thin launcher that executes that
6
+ binary in place, so `npm install --global deltabox-lite` puts a `deltabox`
7
+ command on the PATH. No prestarted service is installed.
8
+
9
+ ```js
10
+ const { binaryPath, loadNative } = require('deltabox-lite')
11
+ const { NativeDeltabox } = loadNative()
12
+ const runtime = new NativeDeltabox(process.cwd(), binaryPath(), {
13
+ fsMode: 'cbcow-through',
14
+ isolation: 'deltabox',
15
+ })
16
+ ```
17
+
18
+ Native methods return promises backed by the addon's Tokio blocking runtime.
19
+ The coordinator and active filesystem state stay resident in the Node process;
20
+ storage mode and command isolation are fixed at construction. The default
21
+ `cbcow-through` + `deltabox` pair runs commands under the session's own sandbox
22
+ and deny set, which is why `isolation: 'none'` has to be asked for by name:
23
+ those commands share the Node process ambient environment instead. File reads
24
+ and writes use `Buffer`, while session, checkpoint, diff, commit, abort, and
25
+ review calls return protocol-shaped typed objects. Every session record names
26
+ its `isolation` profile and the resolved `isolation_provider` (`sandlock` or
27
+ `seatbelt`).
28
+
29
+ Linux CB-CoW modes require `/dev/fuse` and `fusermount3` or `fusermount` on the
30
+ host. Deltabox otherwise reports the reason and falls back to `copy-private`
31
+ unless the requested mode is required.
32
+
33
+ See the [deltabox-lite repository](https://github.com/delta-box/deltabox-lite)
34
+ for usage and policy documentation.
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ // Launcher for the `deltabox` command. The real binary ships in the
3
+ // platform-specific optional dependency; npm only links the bins that the
4
+ // top-level package declares, so a global install of `deltabox-lite` gets
5
+ // its command from this shim rather than from the platform package.
6
+ //
7
+ // The child runs with inherited stdio (so `deltabox serve` can speak
8
+ // JSON-RPC over the launcher's own stdin/stdout), termination signals sent to
9
+ // the launcher are forwarded to it, and its exit status is mirrored.
10
+ "use strict";
11
+
12
+ const { spawn } = require("node:child_process");
13
+ const { constants } = require("node:os");
14
+
15
+ let binary;
16
+ try {
17
+ binary = require("../index.cjs").binaryPath();
18
+ } catch (error) {
19
+ process.stderr.write(
20
+ `deltabox-lite: cannot locate the deltabox binary for this platform.\n` +
21
+ `${error.message}\n` +
22
+ `Reinstall with optional dependencies enabled (npm install --include=optional).\n`,
23
+ );
24
+ process.exit(1);
25
+ }
26
+
27
+ const child = spawn(binary, process.argv.slice(2), { stdio: "inherit" });
28
+
29
+ // A supervisor that signals only the launcher (rather than the whole
30
+ // process group) must still stop the real deltabox, so relay termination
31
+ // signals instead of dying and leaving the child orphaned.
32
+ const relayed = ["SIGINT", "SIGTERM", "SIGHUP"];
33
+ for (const signal of relayed) {
34
+ process.on(signal, () => {
35
+ if (child.exitCode === null && child.signalCode === null) child.kill(signal);
36
+ });
37
+ }
38
+
39
+ child.on("error", (error) => {
40
+ process.stderr.write(`deltabox-lite: failed to launch ${binary}: ${error.message}\n`);
41
+ process.exit(1);
42
+ });
43
+
44
+ child.on("exit", (code, signal) => {
45
+ if (signal) {
46
+ // Mirror the child's termination: raise the same signal on ourselves with
47
+ // the default disposition restored. Signals Node ignores (SIGPIPE) cannot
48
+ // terminate us that way, so fall back to the shell convention 128+n.
49
+ for (const relayedSignal of relayed) process.removeAllListeners(relayedSignal);
50
+ const number = constants.signals[signal];
51
+ process.exitCode = number ? 128 + number : 1;
52
+ try {
53
+ process.kill(process.pid, signal);
54
+ } catch {
55
+ // Unknown signal name: the fallback exit code above applies.
56
+ }
57
+ return;
58
+ }
59
+ process.exit(code ?? 1);
60
+ });
package/index.cjs ADDED
@@ -0,0 +1,28 @@
1
+ const { dirname, join } = require("node:path");
2
+
3
+ const packages = {
4
+ "darwin-arm64": "deltabox-lite-darwin-arm64",
5
+ "darwin-x64": "deltabox-lite-darwin-x64",
6
+ "linux-arm64": "deltabox-lite-linux-arm64",
7
+ "linux-x64": "deltabox-lite-linux-x64",
8
+ };
9
+
10
+ function platformPackageRoot() {
11
+ const name = packages[`${process.platform}-${process.arch}`];
12
+ if (!name) throw new Error(`deltabox-lite does not support ${process.platform}/${process.arch}`);
13
+ return dirname(require.resolve(`${name}/package.json`));
14
+ }
15
+
16
+ function binaryPath() {
17
+ return join(platformPackageRoot(), "bin", "deltabox");
18
+ }
19
+
20
+ function nativePath() {
21
+ return join(platformPackageRoot(), "native", "deltabox.node");
22
+ }
23
+
24
+ function loadNative() {
25
+ return require(nativePath());
26
+ }
27
+
28
+ module.exports = { binaryPath, nativePath, loadNative };
package/index.d.ts ADDED
@@ -0,0 +1,161 @@
1
+ /// <reference types="node" />
2
+
3
+ export interface NativeEnvironmentEntry {
4
+ key: string
5
+ value: string
6
+ }
7
+
8
+ /**
9
+ * Configuration snapshot for one embedded coordinator, fixed at construction.
10
+ * `fsMode` is the storage mode every session on this coordinator starts in;
11
+ * `isolation` picks how commands run. Neither can be changed later, because the
12
+ * coordinator and its active filesystem state live for the whole process.
13
+ */
14
+ export interface NativeDeltaboxOptions {
15
+ stateDir?: string
16
+ runtimeDir?: string
17
+ fsMode?: 'cbcow-through' | 'cbcow-private' | 'copy-private'
18
+ /**
19
+ * `deltabox` keeps the session's own sandbox and deny set. `none` lets
20
+ * commands share the Node process ambient environment, so a host has to name
21
+ * it explicitly; the native transport is the only one that can offer it.
22
+ */
23
+ isolation?: 'deltabox' | 'none'
24
+ }
25
+
26
+ export interface NativeSessionInfo {
27
+ session_id: string
28
+ project: string
29
+ started_at_ms: number
30
+ status: 'running' | 'stopped'
31
+ checkpoint_count: number
32
+ pending_changes: number
33
+ requested_fs_mode: 'cbcow-through' | 'cbcow-private' | 'copy-private'
34
+ resolved_fs_mode: 'cbcow-through' | 'cbcow-private' | 'copy-private'
35
+ host_visibility: 'immediate' | 'on-commit'
36
+ durability: string
37
+ group_commit_ms?: number
38
+ isolation: 'deltabox' | 'none'
39
+ /** Resolved OS mechanism behind `deltabox` isolation, absent under `none`. */
40
+ isolation_provider: string | null
41
+ state_provider: string | null
42
+ fallback_reason: string | null
43
+ rollback_guarantee: string
44
+ tainted: boolean
45
+ mountpoint?: string
46
+ }
47
+
48
+ export interface NativeExecResult {
49
+ exit_code: number | null
50
+ stdout: string
51
+ stderr: string
52
+ duration_ms: number
53
+ truncated: boolean
54
+ }
55
+
56
+ /**
57
+ * Filesystem breadth for one command. `workspace-write` (the default) keeps
58
+ * writes inside the session workspace; `read-write` additionally reaches the
59
+ * rest of the host filesystem while the workspace stays Deltabox-managed and
60
+ * the backing project stays denied.
61
+ */
62
+ export type NativeExecutionProfile = 'workspace-write' | 'read-write'
63
+
64
+ export interface NativeCheckpointInfo {
65
+ id: string
66
+ label: string | null
67
+ created_at_ms: number
68
+ change_count: number
69
+ committed: boolean
70
+ }
71
+
72
+ export interface NativeActiveReview {
73
+ checkpoint_id: string
74
+ kind: 'task' | 'tool' | 'risky'
75
+ label: string | null
76
+ started_at_ms: number
77
+ }
78
+
79
+ export interface NativeChange {
80
+ path: string
81
+ kind: 'added' | 'modified' | 'deleted'
82
+ old_size: number | null
83
+ new_size: number | null
84
+ is_binary: boolean
85
+ added_lines: number
86
+ removed_lines: number
87
+ text_diff?: string
88
+ }
89
+
90
+ export interface NativeDiffResult {
91
+ from: string | null
92
+ to: string | null
93
+ pending_changes: number
94
+ changes: NativeChange[]
95
+ }
96
+
97
+ export interface NativeCommitResult {
98
+ checkpoint_id: string
99
+ applied: number
100
+ /**
101
+ * How many sibling publications this commit's baseline was fast-forwarded
102
+ * over; absent when zero. When set, the host moved since this session's
103
+ * baseline and the orchestrator should re-verify (build, test) after
104
+ * integration.
105
+ */
106
+ folded_publications?: number
107
+ }
108
+
109
+ export interface NativeAbortResult {
110
+ checkpoint_id: string
111
+ restored: number
112
+ }
113
+
114
+ export interface NativeDeltaboxInstance {
115
+ startSession(
116
+ policy?: string,
117
+ durability?: 'fast' | 'strict',
118
+ groupCommitMs?: number,
119
+ filesystemMode?: 'auto' | 'cbcow-through' | 'cbcow-private' | 'copy-private',
120
+ requireFilesystemMode?: boolean,
121
+ ): Promise<NativeSessionInfo>
122
+ stopSession(sessionId: string): Promise<NativeSessionInfo>
123
+ sessionStatus(sessionId: string): Promise<NativeSessionInfo>
124
+ exec(
125
+ sessionId: string,
126
+ argv: string[],
127
+ cwd?: string,
128
+ environment?: NativeEnvironmentEntry[],
129
+ label?: string,
130
+ executionProfile?: NativeExecutionProfile,
131
+ ): Promise<NativeExecResult>
132
+ readFile(sessionId: string, path: string): Promise<Buffer>
133
+ writeFile(sessionId: string, path: string, content: Buffer): Promise<void>
134
+ recordFileChanges(sessionId: string, paths: string[]): Promise<void>
135
+ checkpoint(sessionId: string, label?: string): Promise<NativeCheckpointInfo>
136
+ diff(sessionId: string, from?: string, to?: string): Promise<NativeDiffResult>
137
+ commit(sessionId: string, checkpoint?: string): Promise<NativeCommitResult>
138
+ abort(sessionId: string, checkpoint?: string): Promise<NativeAbortResult>
139
+ beginReview(sessionId: string, kind: 'task' | 'tool' | 'risky', label?: string): Promise<NativeActiveReview>
140
+ reviewStatus(sessionId: string): Promise<NativeActiveReview | null>
141
+ reviewDiff(sessionId: string): Promise<NativeDiffResult>
142
+ reviewCommit(sessionId: string): Promise<NativeCommitResult>
143
+ reviewAbort(sessionId: string): Promise<NativeAbortResult>
144
+ reviewSkip(sessionId: string): Promise<NativeActiveReview>
145
+ }
146
+
147
+ export interface NativeDeltaboxConstructor {
148
+ new(
149
+ projectRoot: string,
150
+ helperBinary: string,
151
+ options?: NativeDeltaboxOptions,
152
+ ): NativeDeltaboxInstance
153
+ }
154
+
155
+ export interface DeltaboxNativeBinding {
156
+ NativeDeltabox: NativeDeltaboxConstructor
157
+ }
158
+
159
+ export function binaryPath(): string
160
+ export function nativePath(): string
161
+ export function loadNative(): DeltaboxNativeBinding
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
2
  "name": "deltabox-lite",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "license": "Apache-2.0",
5
+ "description": "Native sandbox runtime with diff, commit, and abort for AI coding agents",
6
+ "repository": "https://github.com/delta-box/deltabox-lite",
7
+ "main": "index.cjs",
8
+ "types": "index.d.ts",
9
+ "bin": {
10
+ "deltabox": "bin/deltabox.js"
11
+ },
12
+ "os": [
13
+ "darwin",
14
+ "linux"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "files": [
20
+ "index.cjs",
21
+ "index.d.ts",
22
+ "bin/deltabox.js",
23
+ "README.md"
24
+ ],
25
+ "optionalDependencies": {
26
+ "deltabox-lite-darwin-arm64": "0.1.0",
27
+ "deltabox-lite-darwin-x64": "0.1.0",
28
+ "deltabox-lite-linux-arm64": "0.1.0",
29
+ "deltabox-lite-linux-x64": "0.1.0"
30
+ }
31
+ }