@atolis-hq/wake 0.4.28 → 0.4.29

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.
@@ -531,8 +531,8 @@ function createOperationalApplications(root) {
531
531
  if (arguments_.includes('--loop')) {
532
532
  const intervalMs = selfUpdateLoopInterval(arguments_);
533
533
  if (updateTag !== undefined)
534
- return runSelfUpdateLatestLoop(async () => application.update(updateTag, force), () => delay(intervalMs));
535
- return runSelfUpdateLatestLoop(async () => application.updateLatest(force), () => delay(intervalMs));
534
+ return runSelfUpdateLatestLoop(async () => application.update(updateTag, force), () => delay(intervalMs), (message) => process.stderr.write(`${message}\n`));
535
+ return runSelfUpdateLatestLoop(async () => application.updateLatest(force), () => delay(intervalMs), (message) => process.stderr.write(`${message}\n`));
536
536
  }
537
537
  if (updateTag !== undefined)
538
538
  return { tag: updateTag, updated: await application.update(updateTag, force) };
@@ -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.28";
127
+ export const wakeVersion = "v0.4.29";
128
128
  /** The registry-installable version used by packaged sandbox images. */
129
129
  export const wakePackageVersion = packageVersion(defaultRepoRoot) ?? wakeVersion;
@@ -7,9 +7,10 @@ export interface SelfUpdateDependencies {
7
7
  readonly health?: () => Promise<boolean>;
8
8
  readonly rollback?: (priorTag: string) => Promise<void>;
9
9
  }
10
+ export type SelfUpdateLog = (message: string) => void;
10
11
  /** Updates application files only; journal and projection ownership stay outside this command. */
11
12
  export declare function runSelfUpdate(input: SelfUpdateDependencies): Promise<boolean>;
12
13
  /** Runs update checks resiliently; the injected wait boundary owns shutdown. */
13
- export declare function runSelfUpdateLoop(input: SelfUpdateDependencies, wait: () => Promise<void>): Promise<never>;
14
+ export declare function runSelfUpdateLoop(input: SelfUpdateDependencies, wait: () => Promise<void>, log?: SelfUpdateLog): Promise<never>;
14
15
  /** Re-discovers the source tag per iteration so a resident updater does not retain stale version state. */
15
- export declare function runSelfUpdateLatestLoop(updateLatest: () => Promise<unknown>, wait: () => Promise<void>): Promise<never>;
16
+ export declare function runSelfUpdateLatestLoop(updateLatest: () => Promise<unknown>, wait: () => Promise<void>, log?: SelfUpdateLog): Promise<never>;
@@ -20,26 +20,41 @@ export async function runSelfUpdate(input) {
20
20
  return true;
21
21
  }
22
22
  /** Runs update checks resiliently; the injected wait boundary owns shutdown. */
23
- export async function runSelfUpdateLoop(input, wait) {
23
+ export async function runSelfUpdateLoop(input, wait, log) {
24
24
  for (;;) {
25
25
  try {
26
- await runSelfUpdate(input);
26
+ const updated = await runSelfUpdate(input);
27
+ log?.(`wake self-update: ${updated ? 'applied' : 'already current'} ${input.tag}`);
27
28
  }
28
- catch {
29
- // A failed update is already rolled back when possible; the resident host retries later.
29
+ catch (error) {
30
+ log?.(`wake self-update: ${formatError(error)}`);
30
31
  }
31
32
  await wait();
32
33
  }
33
34
  }
34
35
  /** Re-discovers the source tag per iteration so a resident updater does not retain stale version state. */
35
- export async function runSelfUpdateLatestLoop(updateLatest, wait) {
36
+ export async function runSelfUpdateLatestLoop(updateLatest, wait, log) {
36
37
  for (;;) {
37
38
  try {
38
- await updateLatest();
39
+ const result = await updateLatest();
40
+ log?.(describeLatestUpdate(result));
39
41
  }
40
- catch {
41
- // Update failures are isolated to this iteration; the wait boundary controls retry cadence and shutdown.
42
+ catch (error) {
43
+ log?.(`wake self-update: ${formatError(error)}`);
42
44
  }
43
45
  await wait();
44
46
  }
45
47
  }
48
+ function describeLatestUpdate(result) {
49
+ if (typeof result === 'object' &&
50
+ result !== null &&
51
+ 'tag' in result &&
52
+ typeof result.tag === 'string' &&
53
+ 'updated' in result &&
54
+ typeof result.updated === 'boolean')
55
+ return `wake self-update: ${result.updated ? 'applied' : 'no eligible update'} ${result.tag}`;
56
+ return 'wake self-update: check completed';
57
+ }
58
+ function formatError(error) {
59
+ return error instanceof Error ? error.message : String(error);
60
+ }
@@ -79,7 +79,9 @@ EXPOSE 4317
79
79
  # that's fine since it's the very first thing that runs.
80
80
  ENV WAKE_MAIN_JS=/app/dist/src/main.js
81
81
 
82
+ # The supervised entrypoint stays alive when its resident child fails, so the
83
+ # sandbox remains reachable for setup and ownership repair after a failed boot.
82
84
  # Startup ownership repair is best effort because bind-mounted paths or host
83
85
  # permissions may prevent chown. The bounded direct-child pass avoids traversing
84
86
  # accumulated runtime data.
85
- ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces /wake/.wake/auth; chown wake:wake /wake/.wake /wake/workspaces /wake/.wake/auth || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; find /wake/.wake/auth -mindepth 1 -maxdepth 1 -type f -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'"]
87
+ ENTRYPOINT ["sh", "-c", "set -eu; mkdir -p /wake/.wake /wake/workspaces /wake/.wake/auth; chown wake:wake /wake/.wake /wake/workspaces /wake/.wake/auth || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; find /wake/.wake/auth -mindepth 1 -maxdepth 1 -type f -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'"]
@@ -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 /wake/workspaces /wake/.wake/auth; chown wake:wake /wake/.wake /wake/workspaces /wake/.wake/auth || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; find /wake/.wake/auth -mindepth 1 -maxdepth 1 -type f -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 /wake/.wake/auth; chown wake:wake /wake/.wake /wake/workspaces /wake/.wake/auth || true; find /wake/.wake -mindepth 1 -maxdepth 1 -type d -exec chown wake:wake {} + || true; find /wake/.wake/auth -mindepth 1 -maxdepth 1 -type f -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 --wake-root /wake'"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.4.28",
3
+ "version": "0.4.29",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {