Skip to content

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

Open
diazMelgarejo wants to merge 154 commits intochrysb:pr-4-macosfrom
diazMelgarejo:pr-4-macos
Open

AlphaClaw macOS Compatibility, building on pr-4-macos#63
diazMelgarejo wants to merge 154 commits intochrysb:pr-4-macosfrom
diazMelgarejo:pr-4-macos

Conversation

@diazMelgarejo
Copy link
Copy Markdown

@diazMelgarejo diazMelgarejo commented Apr 13, 2026

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.
chrysb and others added 27 commits April 10, 2026 10:10
# Conflicts:
#	package-lock.json
#	package.json
Fix git auth shim handling for global git options
…bal-options"

This reverts commit d333019, reversing
changes made to 0c6d538.
…-dir

Make managed OpenClaw plugin installs durable
Regenerate patch for server.impl-CsRRyd9F.js (clearUnboundScopes + sharedAuthOk).
…arding conflicts

Constraint: preserve read-only onboarding behavior while accepting all
mainline server/runtime refactors, route changes, and watchdog structure.

Resolution strategy per file:
- bin/alphaclaw.js: keep both git-sync + git-runtime imports; remove
  duplicate buildSecretReplacements (already declared lower in file)
- lib/server/onboarding/index.js:
  * add OPENCLAW_STATE_DIR env var (upstream durable state fix)
  * ensureManagedExecDefaults runs outside read-only guard (all modes)
  * ensureGatewayProxyConfig moved outside if-block (upstream refactor)
  * git-sync stays guarded: if (!validatedReadOnlyMode && githubToken)
  * gog/cron/authProfiles remain inside if (!validatedReadOnlyMode)
- lib/server/routes/system.js:
  * keep cron + readOnboardingMarker imports (HEAD)
  * accept watchdog/doctorService params (upstream)
  * keep safeRealpath/isSymlink + getRawSession* helpers (both)
  * buildStatusPayload() refactor accepted; diagnostics.readOnlyMode kept
  * /api/events/status SSE endpoint added (upstream)
- lib/public/js/components/onboarding/welcome-pre-step.js:
  * use bundler imports (upstream) but keep kGithubFlowReadOnly (HEAD)
- lib/public/js/components/onboarding/welcome-config.js:
  * upstream validate(); kGithubFlowReadOnly export preserved
- package-lock.json, gateway.js, general/index.js,
  welcome-form-step.js: take upstream/main
On macOS, SIP makes /usr/local/bin root-only. Extract the existing
isWritableDirectory() inline fallback into a tested getBinPath() utility
that explicitly routes darwin to ~/.local/bin (XDG user-space, no sudo)
and Linux to /usr/local/bin (writable) or managedBinDir (fallback).

Shims installed to ~/.local/bin are visible to all user processes,
not just alphaclaw child processes.
…law.js wiring

- use top-level fs require in platform.js (not inline require())
- homedir default: arrow function () => os.homedir() for type consistency
- import kSystemBinDir from lib/platform.js; remove local duplicate
- prependPathEntry(installBinDir) runs on all platforms; mkdirSync
  only on darwin where ~/.local/bin may not yet exist
The OpenClaw gateway JSON-schema validator requires every provider entry
to have a `models` key (even if empty). When alphaclaw generates config
for self-hosted providers (ollama, lmstudio) the key is absent, causing a
silent schema-validation crash that produces a 30-second startup timeout.

Add sanitizeOpenclawConfig() to lib/server/openclaw-config.js and call it
at config-read time in bin/alphaclaw.js so every provider always has
`models: provider.models || []` before the gateway process is spawned.
- revert const cfg → let cfg: variable is mutated downstream; const was misleading
- guard against array-typed providers (typeof [] === object passes incorrectly)
- null-safe map: skip sanitization for null/non-object provider entries
- add tests: null provider value, array-typed providers
- routes/system.js: call readSystemCronConfig() (local closure wrapper)
  instead of bare getSystemCronStatus() which requires explicit deps arg
- onboarding/index.js: guard ensureManagedExecDefaults behind
  !validatedReadOnlyMode — upstream added it unconditionally but
  read-only mode must not rewrite openclaw.json
- onboarding/index.js: remove duplicate ensureGatewayProxyConfig call
  outside the !validatedReadOnlyMode guard (merge left two calls;
  only the guarded one at line 561 should remain)
- tests/frontend/api.test.js: update runOnboard body expectation to
  include readOnlyMode: false added by this PR
…idation

Blocker 1 (chrysb review): fresh macOS onboarding installs the cron
config and script but never starts the in-process managed scheduler,
so hourly sync would not run until the next service restart. Fix:
call startManagedScheduler() in installHourlyGitSyncCron() after a
successful install. startManagedScheduler() is a no-op on Linux
(normalizeCronPlatform guard), so the linux/docker path is unchanged.

Blocker 2 (chrysb review): isValidCronSchedule() accepted any 5-token
expression including named weekday/month tokens (MON, SUN, JAN, etc.).
The managed scheduler parser uses Number.parseInt() which returns NaN
for named tokens, causing cronMatchesDate() to always return false —
sync silently never runs. Fix: tighten validation to numeric tokens
only (digits, *, -, /, comma). Named tokens are now rejected at save
time rather than silently failing at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@diazMelgarejo diazMelgarejo mentioned this pull request Apr 14, 2026
@diazMelgarejo
Copy link
Copy Markdown
Author

Addressed 2 blockers reviewed here: #4

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.

6 participants