@atolis-hq/wake 0.4.22 → 0.4.23

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.
@@ -401,7 +401,7 @@ ENV WAKE_MAIN_JS=/app/dist/src/main.js
401
401
  # Startup ownership repair is best effort because bind-mounted paths or host
402
402
  # permissions may prevent chown. The bounded direct-child pass avoids traversing
403
403
  # accumulated runtime data.
404
- ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake; chown wake:wake /wake/.wake || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; if [ -n \\"$WAKE_HOME_INIT_DIRS\\" ]; then printf '%s\\n' \\"$WAKE_HOME_INIT_DIRS\\" | while IFS= read -r directory; do case \\"$directory\\" in \\"$WAKE_HOME_INIT_ROOT\\"/*) mkdir -p \\"$directory\\"; chown wake:wake \\"$directory\\" ;; *) exit 1 ;; esac; done; fi; exec su wake -s /bin/sh -c 'HOME=/home/wake exec node \\"$WAKE_MAIN_JS\\" sandbox-entrypoint --wake-root /wake'"]
404
+ ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces; chown wake:wake /wake/.wake /wake/workspaces || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; if [ -n \\"$WAKE_HOME_INIT_DIRS\\" ]; then printf '%s\\n' \\"$WAKE_HOME_INIT_DIRS\\" | while IFS= read -r directory; do case \\"$directory\\" in \\"$WAKE_HOME_INIT_ROOT\\"/*) mkdir -p \\"$directory\\"; chown wake:wake \\"$directory\\" ;; *) exit 1 ;; esac; done; fi; exec su wake -s /bin/sh -c 'HOME=/home/wake exec node \\"$WAKE_MAIN_JS\\" sandbox-entrypoint --wake-root /wake'"]
405
405
  `;
406
406
  const packagedDockerfile = `# syntax=docker/dockerfile:1
407
407
  FROM node:24-bookworm-slim
@@ -468,7 +468,7 @@ EXPOSE 4317
468
468
  # Startup ownership repair is best effort because bind-mounted paths or host
469
469
  # permissions may prevent chown. The bounded direct-child pass avoids traversing
470
470
  # accumulated runtime data.
471
- ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake; chown wake:wake /wake/.wake || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; if [ -n \\"$WAKE_HOME_INIT_DIRS\\" ]; then printf '%s\\n' \\"$WAKE_HOME_INIT_DIRS\\" | while IFS= read -r directory; do case \\"$directory\\" in \\"$WAKE_HOME_INIT_ROOT\\"/*) mkdir -p \\"$directory\\"; chown wake:wake \\"$directory\\" ;; *) exit 1 ;; esac; done; fi; exec su wake -s /bin/sh -c 'HOME=/home/wake exec wake sandbox-entrypoint'"]
471
+ ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces; chown wake:wake /wake/.wake /wake/workspaces || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; if [ -n \\"$WAKE_HOME_INIT_DIRS\\" ]; then printf '%s\\n' \\"$WAKE_HOME_INIT_DIRS\\" | while IFS= read -r directory; do case \\"$directory\\" in \\"$WAKE_HOME_INIT_ROOT\\"/*) mkdir -p \\"$directory\\"; chown wake:wake \\"$directory\\" ;; *) exit 1 ;; esac; done; fi; exec su wake -s /bin/sh -c 'HOME=/home/wake exec wake sandbox-entrypoint'"]
472
472
  `;
473
473
  /** Creates an immediately-valid, human-readable target Wake root. */
474
474
  export async function initialiseWakeRoot(wakeRoot) {
@@ -124,6 +124,6 @@ export function resolveWakeVersion(options = {}) {
124
124
  return `g${headHash.slice(0, 7)}`;
125
125
  return '0.1.0-dev';
126
126
  }
127
- export const wakeVersion = "v0.4.22";
127
+ export const wakeVersion = "v0.4.23";
128
128
  /** The registry-installable version used by packaged sandbox images. */
129
129
  export const wakePackageVersion = packageVersion(defaultRepoRoot) ?? wakeVersion;
@@ -1,6 +1,7 @@
1
1
  import { dirname, normalize } from 'node:path/posix';
2
2
  import { DockerProcessError, } from './docker-invocation.js';
3
3
  import { scrubProcessLog } from './process-log.js';
4
+ import { ensureSandboxWorkspaceOwnership } from './sandbox-workspace-ownership.js';
4
5
  export { DockerProcessError, } from './docker-invocation.js';
5
6
  export { verifyResidentStart } from './resident-start.js';
6
7
  const emptyDockerInvocationResult = { stdout: '', stderr: '' };
@@ -82,13 +83,13 @@ export function createSandboxDockerPort(docker, options) {
82
83
  up: async () => {
83
84
  await requireImage(inspect, options.image);
84
85
  const state = await inspect.containerState(options.containerName);
85
- if (state === 'live')
86
- return;
87
86
  if (state === 'halted') {
88
87
  await docker.invoke(['start', options.containerName]);
89
- return;
90
88
  }
91
- await createContainer(docker, options);
89
+ else if (state === null) {
90
+ await createContainer(docker, options);
91
+ }
92
+ await ensureSandboxWorkspaceOwnership(docker, options);
92
93
  },
93
94
  down: () => docker.invoke(['stop', '--time', '60', options.containerName]),
94
95
  update: async () => {
@@ -99,6 +100,7 @@ export function createSandboxDockerPort(docker, options) {
99
100
  if (state !== null)
100
101
  await docker.invoke(['rm', options.containerName]);
101
102
  await createContainer(docker, options);
103
+ await ensureSandboxWorkspaceOwnership(docker, options);
102
104
  },
103
105
  exec: (command) => docker.invoke(command.length === 0
104
106
  ? ['exec', '-u', 'wake', '-it', options.containerName, 'bash']
@@ -0,0 +1,10 @@
1
+ interface RootDockerExecutor {
2
+ invoke(arguments_: readonly string[]): Promise<unknown>;
3
+ }
4
+ interface WorkspaceSandbox {
5
+ readonly containerName: string;
6
+ readonly wakeMountPath?: string;
7
+ }
8
+ /** Ensures the bind-mounted workspace root is usable by the unprivileged sandbox process. */
9
+ export declare function ensureSandboxWorkspaceOwnership(docker: RootDockerExecutor, options: WorkspaceSandbox): Promise<void>;
10
+ export {};
@@ -0,0 +1,14 @@
1
+ /** Ensures the bind-mounted workspace root is usable by the unprivileged sandbox process. */
2
+ export async function ensureSandboxWorkspaceOwnership(docker, options) {
3
+ await docker.invoke([
4
+ 'exec',
5
+ '-u',
6
+ 'root',
7
+ options.containerName,
8
+ 'sh',
9
+ '-c',
10
+ 'mkdir -p "$1" && chown wake:wake "$1"',
11
+ 'wake-workspace-ownership',
12
+ `${options.wakeMountPath ?? '/wake'}/workspaces`,
13
+ ]);
14
+ }
package/docker/Dockerfile CHANGED
@@ -82,4 +82,4 @@ ENV WAKE_MAIN_JS=/app/dist/src/main.js
82
82
  # Startup ownership repair is best effort because bind-mounted paths or host
83
83
  # permissions may prevent chown. The bounded direct-child pass avoids traversing
84
84
  # accumulated runtime data.
85
- ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake; chown wake:wake /wake/.wake || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; exec su wake -s /bin/sh -c 'if [ \"$WAKE_START_ENABLED\" = \"true\" ]; then exec node /app/dist/src/main.js start --wake-root /wake --no-sandbox; else exec sleep infinity; fi'"]
85
+ ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces; chown wake:wake /wake/.wake /wake/workspaces || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; exec su wake -s /bin/sh -c 'if [ \"$WAKE_START_ENABLED\" = \"true\" ]; then exec node /app/dist/src/main.js start --wake-root /wake --no-sandbox; else exec sleep infinity; fi'"]
@@ -65,4 +65,4 @@ EXPOSE 4317
65
65
  # Startup ownership repair is best effort because bind-mounted paths or host
66
66
  # permissions may prevent chown. The bounded direct-child pass avoids traversing
67
67
  # accumulated runtime data.
68
- ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake; chown wake:wake /wake/.wake || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; exec su wake -s /bin/sh -c 'exec wake sandbox-entrypoint'"]
68
+ ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces; chown wake:wake /wake/.wake /wake/workspaces || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; exec su wake -s /bin/sh -c 'exec wake sandbox-entrypoint'"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {