Skip to content

feat(skills): add cross-platform install fallback for non-brew environments#17687

Merged
sebslight merged 8 commits intoopenclaw:mainfrom
mcrolly:feat/cross-platform-skill-install
Feb 16, 2026
Merged

feat(skills): add cross-platform install fallback for non-brew environments#17687
sebslight merged 8 commits intoopenclaw:mainfrom
mcrolly:feat/cross-platform-skill-install

Conversation

@mcrolly
Copy link
Contributor

@mcrolly mcrolly commented Feb 16, 2026

Supersedes #17661 — addresses all review feedback from @sebslight and Greptile.

Changes

Adds cross-platform skill installation support for non-Homebrew environments (Linux distros, containers, CI).

New: src/infra/package-managers.ts

  • Linux distro family detection via /etc/os-release
  • Package manager discovery in priority order

Updated: src/agents/skills-install.ts

Go fallback (apt-get): Checks sudo -n true before attempting sudo apt-get install. If passwordless sudo is unavailable (containers, restricted environments), returns a helpful error with https://go.dev/doc/install link instead of hanging.

uv fallback: Removed curl-pipe-sh auto-install entirely (security anti-pattern, PATH issues). Returns clear error message with install link when uv is missing and brew is unavailable.

Feedback addressed

  1. ✅ sudo hanging/missing — passwordless sudo check before apt-get
  2. ✅ uv PATH issues — no more auto-install via curl
  3. ✅ curl-pipe-sh security concern — eliminated entirely
  4. ✅ sudo password hang — covered by fix: add @lid format support and allowFrom wildcard handling #1

Tests

  • apt-get available but sudo missing/unusable → helpful error, no apt-get call
  • uv not installed without brew → helpful error, no curl auto-install
  • Package manager detection and priority ordering

Greptile Summary

Adds cross-platform skill installation fallbacks for non-Homebrew environments. Key changes: apt-get fallback for Go with passwordless sudo check, removal of insecure curl-pipe-sh auto-install for uv, improved error messages with install links, and smarter install spec selection that skips brew when unavailable.

  • Type/parser mismatch: SkillInstallSpec.kind in types.ts was expanded with "apt" | "dnf" | "pacman" | "apk", but the frontmatter parser (frontmatter.ts:32) still rejects those kinds, and neither buildInstallCommand nor selectPreferredInstallSpec handle them. These new kind values are dead code that will silently fail if used.
  • Missing apt-get update: The new apt-get fallback for Go runs sudo apt-get install -y golang-go without a preceding apt-get update, which will fail on fresh containers with empty package lists — the primary target environment for this fallback.
  • Unused module: src/infra/package-managers.ts (Linux distro detection, PM discovery) is not imported anywhere outside its own tests. It appears to be groundwork for future use but is currently dead code.
  • The curl-pipe-sh removal and passwordless sudo check are well-implemented security improvements.

Confidence Score: 3/5

  • PR introduces good safety improvements but has a type/parser mismatch that creates dead code and a missing apt-get update that will cause the primary fallback to fail in its target environment.
  • Score of 3 reflects two concrete issues: (1) the new SkillInstallSpec kind values are accepted by the type system but rejected by the parser and unhandled by the installer, creating a confusing gap; (2) the apt-get install fallback will reliably fail on fresh containers without apt-get update. The security improvements (curl removal, sudo check) are solid.
  • Pay close attention to src/agents/skills/types.ts (dead type expansion), src/agents/skills/frontmatter.ts (parser doesn't accept new kinds), and src/agents/skills-install.ts (missing apt-get update).

Last reviewed commit: 196bec2

(5/5) You can turn off certain types of comments like style here!

@sebslight sebslight self-assigned this Feb 16, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

export type SkillInstallSpec = {
id?: string;
kind: "brew" | "node" | "go" | "uv" | "download";
kind: "brew" | "node" | "go" | "uv" | "download" | "apt" | "dnf" | "pacman" | "apk";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New kind values are dead code

The type was expanded with "apt" | "dnf" | "pacman" | "apk", but neither the parser nor the installer handles them:

  1. parseInstallSpec in src/agents/skills/frontmatter.ts:32 still only accepts brew, node, go, uv, download — any skill with kind: "apt" (etc.) will be silently dropped (returns undefined).
  2. buildInstallCommand in src/agents/skills-install.ts:168 has no cases for these new kinds — they'd hit the default branch returning "unsupported installer".
  3. selectPreferredInstallSpec in src/agents/skills-status.ts doesn't look for any of the new kinds.

The type union suggests these are intended install paths, but without corresponding implementation they'll only cause confusion. Either add handling throughout (parser + installer + status), or remove the new kinds from the type until they're ready.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/skills/types.ts
Line: 5:5

Comment:
**New `kind` values are dead code**

The type was expanded with `"apt" | "dnf" | "pacman" | "apk"`, but neither the parser nor the installer handles them:

1. `parseInstallSpec` in `src/agents/skills/frontmatter.ts:32` still only accepts `brew`, `node`, `go`, `uv`, `download` — any skill with `kind: "apt"` (etc.) will be silently dropped (returns `undefined`).
2. `buildInstallCommand` in `src/agents/skills-install.ts:168` has no cases for these new kinds — they'd hit the `default` branch returning `"unsupported installer"`.
3. `selectPreferredInstallSpec` in `src/agents/skills-status.ts` doesn't look for any of the new kinds.

The type union suggests these are intended install paths, but without corresponding implementation they'll only cause confusion. Either add handling throughout (parser + installer + status), or remove the new kinds from the type until they're ready.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 685 to 688
const aptResult = await runCommandWithTimeout(
["sudo", "apt-get", "install", "-y", "golang-go"],
{ timeoutMs },
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing apt-get update before install

On fresh containers and minimal Docker images, the apt package lists are typically empty (or stale). Running sudo apt-get install -y golang-go without a preceding sudo apt-get update will fail with "Unable to locate package golang-go" in most container environments — which is precisely the target use case for this fallback. Consider running apt-get update first, or at minimum mentioning it in the error message when apt-get install fails.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/skills-install.ts
Line: 685:688

Comment:
**Missing `apt-get update` before install**

On fresh containers and minimal Docker images, the apt package lists are typically empty (or stale). Running `sudo apt-get install -y golang-go` without a preceding `sudo apt-get update` will fail with "Unable to locate package golang-go" in most container environments — which is precisely the target use case for this fallback. Consider running `apt-get update` first, or at minimum mentioning it in the error message when `apt-get install` fails.

How can I resolve this? If you propose a fix, please make it concise.

@mcrolly mcrolly force-pushed the feat/cross-platform-skill-install branch from 196bec2 to e9be19c Compare February 16, 2026 02:56
@mcrolly
Copy link
Contributor Author

mcrolly commented Feb 16, 2026

Addressed both review comments:

  1. Dead code in types.ts — Reverted the kind union back to original (brew | node | go | uv | download). The native PM kinds (apt/dnf/pacman/apk) will be added in a follow-up when parser + installer + status all support them.

  2. Missing apt-get update — Added sudo apt-get update -qq before apt-get install so fresh containers with empty package lists don't fail.

Force-pushed with both fixes. Tests pass.

@sebslight sebslight force-pushed the feat/cross-platform-skill-install branch 3 times, most recently from 64b6ce4 to 0edc357 Compare February 16, 2026 03:22
sebslight added a commit to mcrolly/openclaw that referenced this pull request Feb 16, 2026
sebslight added a commit to mcrolly/openclaw that referenced this pull request Feb 16, 2026
mcrolly and others added 8 commits February 15, 2026 22:23
…nments

- Extend SkillInstallSpec to support native package managers (apt, dnf, pacman, apk)
- Add platform detection utilities to identify Linux distro and available package managers
- Update install selection logic to prefer native package managers on Linux
- Improve install fallback chain: native PM → brew → go → node → uv → download
- Enhance error messages when brew is unavailable with platform-specific guidance
- Respect existing preferBrew config; add automatic fallback for Linux without brew
- Add comprehensive tests for package manager detection

Closes openclaw#9420
Relates to openclaw#3987, #2478, openclaw#6654
@sebslight sebslight force-pushed the feat/cross-platform-skill-install branch from 0edc357 to 3ed4850 Compare February 16, 2026 03:25
@sebslight sebslight merged commit d19b746 into openclaw:main Feb 16, 2026
9 checks passed
@sebslight
Copy link
Member

Merged via squash.

Thanks @mcrolly!

Hansen1018 pushed a commit to Hansen1018/openclaw that referenced this pull request Feb 16, 2026
…nments (openclaw#17687)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 3ed4850
Co-authored-by: mcrolly <[email protected]>
Co-authored-by: sebslight <[email protected]>
Reviewed-by: @sebslight
@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: M labels Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments