Skip to content

AlphaClaw macOS Compatibility, building on pr-4-macos#63

Open
diazMelgarejo wants to merge 188 commits into
chrysb:pr-4-macosfrom
diazMelgarejo:pr-4-macos
Open

AlphaClaw macOS Compatibility, building on pr-4-macos#63
diazMelgarejo wants to merge 188 commits into
chrysb:pr-4-macosfrom
diazMelgarejo:pr-4-macos

Conversation

@diazMelgarejo

@diazMelgarejo diazMelgarejo commented Apr 13, 2026

Copy link
Copy Markdown

Summary

  • macOS bin-path routing: Extracts getBinPath() into lib/platform.js — darwin routes to ~/.local/bin (user-writable, no sudo), Linux keeps /usr/local/bin with managed fallback.
  • Read-only onboarding: New readOnlyMode flow attaches AlphaClaw to an existing local OpenClaw setup without modifying any config files, writing git state, or touching the gateway proxy config.
  • sanitizeOpenclawConfig: Ensures every provider in openclaw.json has models: [], preventing the OpenClaw gateway JSON-schema crash that causes a 30s startup timeout.
  • Rebase on 0.9.3: Merges upstream/main — preserves all new route structure, SSE /api/events/status, buildStatusPayload() refactor, and bundler-style frontend imports while keeping the read-only onboarding invariants.
  • Test fixes (merge conflict residue): getSystemCronStatus missing deps arg, duplicate ensureGatewayProxyConfig outside read-only guard, ensureManagedExecDefaults modifying config in read-only mode, and api.test.js body expectation missing readOnlyMode.

Test plan

  • All 538 tests pass: npx vitest run
  • getBinPath() unit tests: 4 passing
  • sanitizeOpenclawConfig() unit tests: 7 passing
  • Read-only onboarding: passes without writing openclaw.json
  • macOS: alphaclaw start installs binary to ~/.local/bin without sudo
  • macOS: { readOnlyMode: true } to /api/onboard completes without rewriting existing config

Branch pr-4-macos (pushed from diazMelgarejo/AlphaClaw)

Commit Change
ad2325f Merge upstream/main (0.9.3) into pr-4-macos: 9 conflicts resolved, read-only onboarding preserved
3bbf43d fix(macos): lib/platform.js with getBinPath(), 4 tests
3d99697 fix(platform): code review fixes — fs top-level, homedir arrow fn, import kSystemBinDir, Linux prependPathEntry
4d04616 fix(gateway): sanitizeOpenclawConfig() in openclaw-config.js, 5 tests, wired into bin/alphaclaw.js
61c8284 fix(gateway): harden against null providers, array-typed providers, revert let cfg — 7 tests total

Full suite: 535 passed, 3 failures (after merging main to pr-4-macos)


Fixed: post main -> pr-4-macos

Failure Root cause Fix
routes-system.test.js — "reports running gateway status" getSystemCronStatus() called with no args at line 501; needs deps {fs, openclawDir, platform} Changed to readSystemCronConfig() (the local wrapper that captures deps)
routes-onboarding.test.js — "supports read-only onboarding" Two issues from merge: (1) duplicate ensureGatewayProxyConfig call outside the !readOnly guard; (2) ensureManagedExecDefaults (added by upstream) runs unconditionally and writes to openclaw.json Removed the duplicate call; guarded ensureManagedExecDefaults behind !validatedReadOnlyMode
tests/frontend/api.test.js — "runOnboard sends vars and modelKey" Test expected old body without readOnlyMode; our PR added readOnlyMode to the payload Updated expected body to include readOnlyMode: false

All 3 failures were merge conflict residue — the fixes preserve the correct invariant that read-only onboarding must not write to openclaw.json or call ensureGatewayProxyConfig.

chrysb added 30 commits March 10, 2026 22:16
…ns and richer tool guidance.

This adds URL-sticky tools tab behavior, robust tools config persistence/reset handling, and contextual tooltips so advanced capabilities are easier to understand.
…silient history loading so chat works reliably in local and containerized setups.

Polish chat UX with markdown rendering, better spacing, per-session drafts, stop-generation control, and streaming behavior improvements.
Show tool activity as minimal per-call rows with expandable payload/result details, preserve richer history metadata, and keep chat styling isolated from agents styles for easier maintenance.
Resolve gateway event targets more reliably across payload shapes and attach streamed tool results to the correct inline tool rows so users see tool activity in real time.
Add API-layer stale-while-revalidate caching, unmount inactive panes, pause polling when hidden, and stream status/watchdog/doctor updates over SSE to cut redundant first-load and background requests while keeping tab switching fast.
This introduces OAuth callback middleware and webhook route/database updates while decomposing the webhooks UI into folder-based components with co-located hooks, so webhook flows are easier to maintain and safer to extend.
This aligns the frontend API test with the new createWebhook request body that always includes the oauthCallback flag.
This hydrates webhook detail and agents from cache first, then shows an explicit loading state so OAuth callback routes do not render a transient non-OAuth auth mode block.
ensureGatewayProxyConfig was called before the onboarding marker
file was written, so its isOnboarded() guard bailed out silently.
Move the call after the marker write so the gateway host origin
is persisted to openclaw.json on first onboard.
Use OAuth-specific callback test URLs, refresh request history immediately after webhook test responses, and prepopulate OAuth webhook transforms with fallback message content so callback payloads without message fields still map successfully.
…ities.

This updates webhook routing management with destination editing in detail view, adds robust session parsing for agent session lists, and introduces OAuth/webhook route destination update coverage across server and frontend tests.
This sorts direct/group session keys ahead of non-destination sessions so routing-related picks stay visible first while preserving all other session options.
This reuses one shared config-normalization path so both startup and onboarding enforce usage-tracker allow/load/entry fields consistently.
This prevents the modal from collapsing from 5 steps to 3 after enabling watch and showing an undefined step title.
This keeps destination selectors stable while sessions load and surfaces clearer GitHub API error context during repo setup.
This adds dismiss support that clears the underlying restart-required status and prevents stale env cache payloads from reverting saved values.
This writes renamed agents to identity.name, keeps backward compatibility for legacy name fields, and normalizes session labels when an agent has no explicit name.
…ding.

Repos initialized with just a README and .gitignore now pass the
empty-repo check so "Start fresh" onboarding can reuse them instead
of rejecting them as non-empty.
Delay fallback status polling on first load, stop background browser re-check loops after failed attaches, bootstrap persisted attach state once, and increase browser invoke/check timeouts for slower Chrome attach flows.
nimbosa added 3 commits April 16, 2026 07:54
Add explicit Linux install path test:
- calls installHourlyGitSyncCron() with platform 'linux'
- asserts kSystemCronPath (/etc/cron.d/openclaw-hourly-sync) exists
  in the memory-fs after install
- asserts cron file content contains the default schedule
- asserts getSystemCronStatus() returns installed: true,
  installMethod: 'system_cron' for linux

Previously the only integration test exercised the darwin path.
Linux activation via applySystemCronConfig() was untested at the
installHourlyGitSyncCron() level.
Adds a three-phase test against installHourlyGitSyncCron():
  1. Install on darwin -> assert installed: true
  2. stopManagedScheduler() (simulates user disabling sync) ->
     assert installed: false via getSystemCronStatus()
  3. Re-install on darwin -> assert installed: true again

This confirms the re-enable code path works correctly: after
stopManagedScheduler() clears kSchedulerState.active, calling
installHourlyGitSyncCron() with platform 'darwin' and an
enabled config restarts the managed scheduler and the function
returns true.
Add two tests confirming installHourlyGitSyncCron() returns exactly
getSystemCronStatus().installed after install, not a broadened boolean:

  darwin: result === getSystemCronStatus({ platform: 'darwin' }).installed
  linux:  result === getSystemCronStatus({ platform: 'linux'  }).installed

Both assert true. If the return expression is ever changed back to the
broader (installed || (darwin && enabled)) form, these tests break on
any scenario where enabled is true but installed is still false (e.g.
a partially-failed scheduler start on darwin).

Pairs with fix(macos): tighten installHourlyGitSyncCron return contract.
@diazMelgarejo

Copy link
Copy Markdown
Author

No open test gaps remain from the original checklist.

a05cbe9 — fix: return contract

-   return status.installed || (status.platform === "darwin" && status.enabled);
+   const finalStatus = getSystemCronStatus({ fs, openclawDir, platform });
+   return finalStatus.installed;

startManagedScheduler() sets kSchedulerState.active synchronously, so the re-read sees the correct runtime state immediately. getSystemCronStatus was already imported; one import line added for it.

7641a7f — test: Linux install path

Calls installHourlyGitSyncCron() with platform: "linux", then asserts kSystemCronPath exists in the memory-fs, contains the default schedule string, and getSystemCronStatus() returns { installed: true, installMethod: "system_cron" }.

a7bd4b2 — test: darwin disable → re-enable

Three phases against the same memory-fs:

  1. Install → installed: true
  2. stopManagedScheduler() → installed: false
  3. Re-install → installed: true again

4cba0d8 — test: return value semantics

Asserts result === getSystemCronStatus().installed for both darwin and linux. If the broadened installed || (darwin && enabled) expression ever comes back, these tests break as soon as enabled is true but installed is still false.

chrysb and others added 13 commits April 16, 2026 08:02
…se (chrysb#68)

Templates that omit a direct openclaw pin should still resolve OpenClaw from the same AlphaClaw version the template pins. This change reuses the template-pinned version when reading registry metadata and adds a regression for the mismatch case.

Constraint: Managed templates now intentionally pin only @chrysb/alphaclaw
Rejected: Continue resolving dist-tags.latest for template fallbacks | mixes template-pinned AlphaClaw with unrelated OpenClaw metadata
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep template fallback metadata tied to the same pinned AlphaClaw version unless template semantics change again
Tested: node --check lib/server/alphaclaw-version.js; node --check tests/server/alphaclaw-version.test.js; direct mocked fetch validation for fallback/latest/direct-pin cases
Not-tested: Full Vitest run in this local environment (Vite/esbuild spawn error -88 during config startup)
Add WhatsApp channel support and QR login flow parity
@chrysb

chrysb commented Apr 18, 2026

Copy link
Copy Markdown
Owner

Thank you! I will inspect this over the weekend.

diazMelgarejo and others added 4 commits April 18, 2026 21:52
…guards

Absorbs upstream commits d7b9161→092df06 (v0.9.5–v0.9.9):
- gogcli HOME compat: HOME/OPENCLAW_HOME now set to kRootDir in gatewayEnv
  and onboard shellCmd env (commits e0f9fa8, b0be220)
- SQLite handle-close fix: explicit close() in db module tests to fix
  WAL-lock flakiness — the root-cause fix that replaced our singleFork PR
  (commit 092df06)
- Package updates: openclaw patch refresh, package-lock bump

Conflict resolution:
- lib/server/gateway.js: accepted HOME/kRootDir addition; added kRootDir
  to constants import
- lib/server/onboarding/index.js: accepted HOME/kRootDir addition; added
  kRootDir to constants import; all 16 !validatedReadOnlyMode guard sites
  preserved — upstream's removal of read-only logic was NOT accepted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After upstream commit e0f9fa8 (gogcli HOME compat), gatewayEnv() and the
onboard shellCmd env now set HOME=kRootDir and OPENCLAW_HOME=kRootDir,
with OPENCLAW_STATE_DIR carrying the old OPENCLAW_DIR value.

Update two tests that still expected the pre-refactor layout:
- gateway.test.js: add HOME/OPENCLAW_STATE_DIR to launch env assertion
- routes-onboarding.test.js: switch toEqual→toMatchObject, replace
  OPENCLAW_HOME with HOME+OPENCLAW_STATE_DIR expectations

All 575 tests and 29 watchdog tests now pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rkers

Root cause (two layers):
1. routes-browse.test.js + routes-models.test.js called mkdtempSync per test
   but never cleaned up. 30+ leaked dirs/run add I/O overhead on macOS
   /var/folders/ (memory-mapped filesystem).
2. db-layer parallel workers (doctor, watchdog, webhooks) leave DatabaseSync
   .db-shm pages mmap'd. Under 60+ workers on ARM64, OS memory pressure slows
   ALL workers — including pure-mock routes tests — past the 5s timeout.

Fix:
- routes-browse.test.js: track created dirs in createdTestRoots[]; afterEach
  splices and rmSync({recursive,force}) each entry
- routes-models.test.js: same pattern for createApp() temp dirs (createdTempRoots)
- vitest.config.js: testTimeout 5000 → 10000ms; gives pure-mock workers breathing
  room while db-layer .db-shm pressure fix propagates (doctor/watchdog/webhooks-db
  still need afterEach closeXyzDb() — tracked as remaining upstream work)

Verified: npm run test:coverage passes 594/594 sequentially.
Target: npm test 594/594 (was 584/594 before this fix).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
E.1 — package.json: add @esbuild/darwin-arm64 + @esbuild/darwin-x64 0.25.x as
      optionalDependencies so ARM64 Macs pick up the correct native binary without
      requiring manual postinstall.

E.2 — bin/alphaclaw.js: print darwin-specific npm prefix advisory on `alphaclaw start`
      (guides users to set prefix=$HOME/.local to avoid sudo-required installs).

E.3 — bin/alphaclaw.js + lib/scripts/macos-hourly-sync.plist.template: on darwin,
      write a LaunchAgent plist to ~/Library/LaunchAgents/ instead of /etc/cron.d
      (which requires root and does not exist on macOS).

E.5 — .github/workflows/ci.yml: extend CI matrix to include macos-latest alongside
      ubuntu-latest; add watchdog suite and coverage steps so macOS-specific failures
      are caught before merge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants