Skip to content

Migrate host-adaptation logic (PATH symlink, sandbox hints) from the plugin hook into selat-cli #46

Description

@SELAT-DEV

Summary

Host-adaptation fixes (the OpenClaw ~/.openclaw/bin PATH symlink, the Cursor sandbox.json egress guidance) currently live in the plugin bundle hook (selat-plugins's ensure-runner.sh). They should move into selat-cli so they propagate reliably.

Why (the propagation gap)

The two update channels have very different reach:

Channel Updates how Reaches existing users?
Plugin bundle (selat-plugins) harness plugin-manager, manual on OpenClaw (openclaw plugins update) — no auto-update ❌ not until they manually update
npm runner (@selat-ai/selat-cli) SessionStart hook tracks latest, reinstalls each session — even on a stale bundle ✅ automatically, next session

A fix in the hook reaches no existing OpenClaw user until they manually update; a fix in the runner reaches everyone automatically. The adaptive logic is currently on the channel that doesn't propagate.

Principle

Thin bootstrap hook (bundle) + fat self-updating runner (npm). The hook's only irreducible job is the chicken-and-egg bootstrap (install/refresh the runner before it exists) + emit the SessionStart context. Everything host-adaptive moves into the runner.

What moves into selat-cli

  1. OpenClaw PATH symlink — runner self-links realpath(process.argv[1]) into known on-PATH harness bin dirs when their marker dir exists (OpenClaw: ~/.openclaw~/.openclaw/bin/selat). Idempotent, fail-safe.
  2. Cursor sandbox-egress hint — emit the .cursor/sandbox.json allowlist guidance when a catalog fetch actually fails in search/run (truer signal than the hook's preflight probe). Guidance only — never auto-write.

Tasks

  • Add lib/host.mjs: ensureHarnessPath() (generalized link table) + describeEgressBlock() (sandbox.json hint string).
  • Call ensureHarnessPath() at the start of doctor, init, search, run (cheap, idempotent).
  • On search/run catalog-fetch failure, surface describeEgressBlock() instead of bare "fetch failed".
  • Release selat-cli (trusted-publishing CI) → propagates via the hook's latest tracking.
  • Follow-up plugin release: slim ensure-runner.sh (drop the now-duplicated link_into + sandbox probe; keep bootstrap + SessionStart context). Bump plugin once.
  • Companion fix (same PR): selat init currently falls through to createWallets() and fails when the wallet slot is full — detect an existing agent wallet (listAgentWalletsDetailed/pickAgentAddress) and skip creation when the lookup missed it.

Sequencing

Ship the runner change first; slim the hook in a later plugin release. During overlap both perform the symlink — harmless (idempotent).

Guardrails (unchanged)

  • Never auto-widen a security boundary: Cursor sandbox.json stays guidance only, never auto-written. (A PATH symlink into a harness's own bin dir is benign — auto-doing it is fine.)
  • Self-custody invariant unchanged: no wallet auto-create/fund, no auto-pay.

Net

A host-adaptation fix becomes one selat-cli npm release → every existing install picks it up next session, across all harnesses, with zero bundle update.


Design doc: selat-pay/selat-distribution/2026-06-30-host-adaptation-migration.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions