Skip to content

feat: add freestyle.sh delegated-run provider#148

Open
zozo123 wants to merge 12 commits into
openclaw:mainfrom
zozo123:feat/freestyle-provider
Open

feat: add freestyle.sh delegated-run provider#148
zozo123 wants to merge 12 commits into
openclaw:mainfrom
zozo123:feat/freestyle-provider

Conversation

@zozo123
Copy link
Copy Markdown
Contributor

@zozo123 zozo123 commented May 23, 2026

Summary

Adds a new freestyle delegated-run provider for Freestyle.sh virtual machines.

Addresses all ClawSweeper review blockers on #148 (env-only auth, argv-safe commands, forwarded env variables, actions-runner rejection, sync-only support), includes provider documentation, and is merged up to current main.

Provider details

  • Kind: DelegatedRun, Features: FeatureArchiveSync, Coordinator: CoordinatorNever
  • Uses the Freestyle v1 REST API (https://api.freestyle.sh) via direct HTTP
  • No SDK dependency — pure Go net/http client
  • Auth is env-only (FREESTYLE_API_KEY / CRABBOX_FREESTYLE_API_KEY); no API key CLI flag
  • Supports --sync-only; rejects --actions-runner and --checksum
  • User commands run via bash -lc with argv-safe shell rendering
  • Forwarded env vars are exported after entering the Freestyle workdir with validated names and shell-quoted values

Files

File Purpose
internal/providers/freestyle/provider.go Registration + Provider interface
internal/providers/freestyle/core.go Type aliases + helpers
internal/providers/freestyle/client.go HTTP client for Freestyle REST API
internal/providers/freestyle/backend.go Backend: Warmup, Run, List, Status, Stop, Doctor
internal/providers/freestyle/sync.go Archive sync (tar.gz → base64 upload → exec fallback)
internal/providers/freestyle/backend_test.go Unit tests covering lifecycle, sync, flags, argv, env forwarding
internal/cli/config.go FreestyleConfig struct, defaults, YAML, env vars
internal/cli/providers_builtin_test.go Test provider registration
internal/providers/all/all.go Import registration
internal/providers/all/all_test.go Doctor test entry
docs/providers/freestyle.md Provider reference docs

Config

export FREESTYLE_API_KEY=your-key
crabbox run --provider freestyle 'command'

# Optional flags
--freestyle-api-url   (default: https://api.freestyle.sh)
--freestyle-workdir   (default: crabbox)
--freestyle-vcpus     (default: 2)
--freestyle-memory-mb (default: 4096)

Verification

  • Branch merged with current main; GitHub reports the PR as mergeable.
  • Local verification after the latest env-forwarding fix:
go vet ./...
go test ./internal/providers/freestyle ./internal/cli ./internal/providers/all
go test ./...
go build -trimpath -o bin/crabbox ./cmd/crabbox
  • Live API proof after merge:
$ crabbox run --provider freestyle 'bash test.sh'
leased fsb_qrtcirm39hhr7s5y9e5y slug=jade-prawn provider=freestyle sandbox=qrtcirm39hhr7s5y9e5y
provider=freestyle lease=fsb_qrtcirm39hhr7s5y9e5y sandbox=qrtcirm39hhr7s5y9e5y
sync candidate: 2 files, 82 B
warning: freestyle file API upload failed; falling back to exec upload: freestyle write file: 404 Not Found:
sync complete in 1.769s
Sync proof works after merge!
freestyle run summary sync=1.769s command=299ms total=3.426s exit=0

$ GREETING='hello world' crabbox run --provider freestyle --no-sync --allow-env GREETING 'test "$GREETING" = "hello world" && echo "$GREETING"'
leased fsb_rzekfao9t9j4l7hv2dwb slug=swift-hermit provider=freestyle sandbox=rzekfao9t9j4l7hv2dwb
provider=freestyle lease=fsb_rzekfao9t9j4l7hv2dwb sandbox=rzekfao9t9j4l7hv2dwb
hello world
freestyle run summary sync_skipped=true command=300ms total=2.062s exit=0

$ crabbox warmup --provider freestyle --actions-runner
--actions-runner is not supported for provider=freestyle

$ crabbox doctor --provider freestyle
ok      provider provider=freestyle timeout=10s auth=ready control_plane=ready inventory=ready api=list mutation=false leases=4 runtime=unchecked

Adds a new provider backend for Freestyle.sh VMs using the v1 REST API.

Provider: freestyle (Kind: DelegatedRun, FeatureArchiveSync, CoordinatorNever)

Key behaviors:
- Create/manage VMs via POST/GET/DELETE /v1/vms
- Command execution via POST /v1/vms/{id}/exec-await
- Archive-based file sync via tar.gz + base64 upload + exec fallback
- List VMs filtered by crabbox name prefix
- Config via --freestyle-* flags, FREESTYLE_API_KEY env var, YAML
- Doctor support for inventory checks

Verified against live Freestyle API (api.freestyle.sh):
  create → sync → exec → list → stop all working.
@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels May 24, 2026
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 24, 2026

Codex review: needs changes before merge. Reviewed May 27, 2026, 4:23 AM ET / 08:23 UTC.

Summary
The PR adds a Freestyle.sh delegated-run provider with config, REST lifecycle/exec/sync implementation, registration, tests, and provider docs.

Reproducibility: not applicable. This PR adds a new provider rather than reporting a broken existing behavior. The changed behavior is source-reviewable and has live provider proof in the PR discussion.

Review metrics: 2 noteworthy metrics.

  • Provider surface: 1 provider added, 18 files changed. The PR adds a full built-in provider, so review should cover config, docs, registration, lifecycle, sync, and security boundary together.
  • Net diff size: 2060 added, 3 removed. The large additive surface makes provider-boundary and session-state review more important than ordinary unit-test success alone.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Add freestyle to providerHelpAll() and update the provider-help test coverage.

Risk before merge

  • Merging adds a new third-party delegated execution path that sends workspace archives, allowed env values, and user commands to Freestyle VMs, so maintainers need to accept that provider boundary explicitly.
  • The provider introduces new lease IDs, local claims, VM ownership checks, status, stop, and cleanup semantics; the PR has tests and live proof, but CI alone cannot fully prove provider-side session behavior.

Maintainer options:

  1. Approve The New Provider Boundary
    A maintainer can intentionally accept the Freestyle trust boundary after reviewing the docs, env-only auth, argv/env quoting, and live proof.
  2. Tighten Before Merge
    Ask for any additional provider-boundary or lease-ownership tests maintainers want before landing the new delegated execution backend.
  3. Pause If Freestyle Is Out Of Scope
    Close or defer the PR if maintainers do not want another built-in third-party delegated-run provider in core right now.

Next step before merge
A narrow mechanical repair can update the provider help string and focused test coverage without changing Freestyle provider behavior.

Security
Cleared: No concrete supply-chain issue was found; the main security concern is the intentional new third-party execution boundary, which is called out as merge risk.

Review findings

  • [P3] Add Freestyle to provider help — internal/providers/all/all.go:11
Review details

Best possible solution:

Keep the provider-specific lifecycle, sync, and credential handling inside the Freestyle adapter, add the missing CLI help entry, then let maintainers explicitly approve the new provider boundary.

Do we have a high-confidence way to reproduce the issue?

Not applicable; this PR adds a new provider rather than reporting a broken existing behavior. The changed behavior is source-reviewable and has live provider proof in the PR discussion.

Is this the best way to solve the issue?

Yes, with one small gap: a provider adapter is the right boundary for Freestyle-specific lifecycle, sync, and API behavior, but the CLI provider help should expose the new provider consistently.

Full review comments:

  • [P3] Add Freestyle to provider help — internal/providers/all/all.go:11
    The PR registers freestyle as a built-in provider, but providerHelpAll() is unchanged and still omits it, so commands using --provider will show stale help for the new backend. Please add freestyle to that help string and cover it with the existing provider-help test pattern.
    Confidence: 0.95

Overall correctness: patch is correct
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 0511f91aa357.

Label changes

Label justifications:

  • P2: This is a normal-priority provider feature with bounded but meaningful maintainer review scope.
  • merge-risk: 🚨 security-boundary: The new delegated provider forwards repo content, commands, and allowed environment values to a third-party execution API.
  • merge-risk: 🚨 session-state: The provider introduces new lease IDs, local claims, VM ownership checks, status, stop, and cleanup semantics.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body and latest comment include live Freestyle command output showing sync, env forwarding, actions-runner rejection, doctor, and cleanup after the latest fixes.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body and latest comment include live Freestyle command output showing sync, env forwarding, actions-runner rejection, doctor, and cleanup after the latest fixes.
Evidence reviewed

Acceptance criteria:

  • go test ./internal/cli

What I checked:

  • Repository policy applied: AGENTS.md was read fully; its provider-boundary and secret-handling guidance applies to this new delegated provider. (AGENTS.md:1, 0511f91aa357)
  • Freestyle is registered as a built-in provider: The PR head imports the Freestyle provider through the built-in provider set. (internal/providers/all/all.go:11, 1f58c077b7e1)
  • Freestyle stays provider-adapter scoped: The ProviderSpec declares a delegated-run Linux provider with archive sync and no coordinator, keeping Freestyle-specific behavior behind the adapter. (internal/providers/freestyle/provider.go:19, 1f58c077b7e1)
  • Credential handling is env-only in code: The HTTP client requires cfg.Freestyle.APIKey and provider flags expose URL/workdir/size settings without an API-key flag. (internal/providers/freestyle/client.go:72, 1f58c077b7e1)
  • Provider help remains stale: The PR head leaves providerHelpAll unchanged from main, and the static help string does not include freestyle. (internal/cli/provider_backend.go:462, 1f58c077b7e1)
  • Live proof is present in the PR discussion: The PR body and latest contributor comment include live Freestyle terminal output for direct sync, env forwarding, unsupported actions-runner rejection, doctor, and cleanup after the latest fixes. (1f58c077b7e1)

Likely related people:

  • Peter Steinberger: Current-main blame points provider help, provider registry, and config structure in the reviewed area to the v0.21.0 release commit, making this the strongest local routing signal for the existing provider surface. (role: recent area contributor; confidence: medium; commits: 7bd2c5099d9c, 0511f91aa357; files: internal/cli/provider_backend.go, internal/providers/all/all.go, internal/cli/config.go)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 24, 2026

ClawSweeper PR egg

✨ Hatched: 🥚 common Velvet Test Hopper

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: polishes edge cases.
Image traits: location CI tidepool; accessory miniature diff map; palette pearl, teal, and neon green; mood bright-eyed; pose guarding a tiny green check; shell translucent glimmer shell; lighting moonlit rim light; background little resolved-comment flags.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Velvet Test Hopper in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

zozo123 and others added 3 commits May 24, 2026 12:19
Remove env-secret CLI flag, preserve argv semantics, reject unsupported
actions-runner warmups, support sync-only, and run user commands via bash -lc.

Co-authored-by: Cursor <cursoragent@cursor.com>
Document env-only auth, archive sync behavior, CLI flags, and limitations
for the new delegated Freestyle VM provider.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	CHANGELOG.md
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels May 24, 2026
Export validated environment names with shell-quoted values after entering the
Freestyle workdir so forwarded values with spaces reach the user command.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 24, 2026
Resolve the changelog conflict, keep the Freestyle entry in the current unreleased section, and cover Freestyle config loading so the current coverage gate stays green.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 26, 2026
Make Freestyle no-sync preparation non-destructive for existing leases, cover the workspace-preservation path, and leave release notes to the release process.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. label May 26, 2026
Require Freestyle VM identifiers to resolve through a Crabbox claim or a Crabbox-named sandbox before run/status/stop operations.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels May 26, 2026
@zozo123
Copy link
Copy Markdown
Contributor Author

zozo123 commented May 26, 2026

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 26, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

Send absolute file paths below the Freestyle /files route so direct sync uses the file API instead of falling back to exec upload.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 26, 2026
Keep Freestyle authentication docs aligned with env-only API key handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zozo123
Copy link
Copy Markdown
Contributor Author

zozo123 commented May 26, 2026

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 26, 2026

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Omit VM sizing unless configured and encode Freestyle file paths as a single path parameter so the live file API path succeeds without exec-upload fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zozo123
Copy link
Copy Markdown
Contributor Author

zozo123 commented May 26, 2026

@clawsweeper re-review

Current-head Freestyle live proof on c8c49ecc77b9eeb4cb78195b8a30de6b82fb8439:

leased fsb_smh14z2qt5fkeswmxwf3 slug=swift-prawn provider=freestyle sandbox=smh14z2qt5fkeswmxwf3
provider=freestyle lease=fsb_smh14z2qt5fkeswmxwf3 sandbox=smh14z2qt5fkeswmxwf3
sync candidate: 530 files, 6.2 MiB dirty_delta=6 files, 155.6 KiB
sync complete in 8.095s
freestyle direct-sync proof pwd=/workspace/crabbox
freestyle direct-sync proof ok
freestyle run summary sync=8.095s command=356ms total=9.933s exit=0
{"provider":"freestyle","leaseId":"fsb_smh14z2qt5fkeswmxwf3","syncMs":8094,"syncPhases":[{"name":"manifest","ms":121},{"name":"preflight"},{"name":"prepare","ms":445},{"name":"archive","ms":227},{"name":"upload","ms":7300},{"name":"freestyle_sync","ms":8094}],"syncSkipped":false,"syncDelegated":true,"commandMs":356,"totalMs":9933,"exitCode":0}
PROOF_RESULT: no freestyle file API fallback warning observed

Validation:

gofmt -w internal/providers/freestyle/*.go internal/cli/config.go internal/cli/config_test.go
go test ./internal/providers/freestyle ./internal/cli
go build -trimpath -o bin/crabbox ./cmd/crabbox
go test ./...
go vet ./...

Proof resource cleanup: the proof VM was not present in the subsequent crabbox list --provider freestyle output.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 26, 2026

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 27, 2026
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 27, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@zozo123
Copy link
Copy Markdown
Contributor Author

zozo123 commented May 27, 2026

PR #148 is ready from my side on head 1f58c07.

What I did:

  • Merged current origin/main and resolved the internal/cli/config.go conflict.
  • Re-checked the Freestyle API key surface: docs say env-only, provider flags do not register an API-key flag, and YAML file config does not expose freestyle.apiKey.
  • Confirmed GitHub CI is green: Go, Worker, Plugin, Docs, Release Check.

Local validation run:

  • go test ./internal/providers/freestyle ./internal/cli ./internal/providers/all
  • go build -trimpath -o bin/crabbox ./cmd/crabbox
  • go test ./...
  • go vet ./...
  • npm test
  • npm run docs:check
  • npm --prefix worker test
  • npm --prefix worker run check
  • npm --prefix worker run build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant