feat: wave 5 — config transparency + backup/restore - #24
Merged
Conversation
Wave 5.1 — /manage/config read view (closes #17) - GET /manage/config shows rendered opencode.json (with {env:VAR} placeholders intact — no raw API keys leaked) - Shows masked .setup.env (API keys masked as key[:4]…key[-4:]) - Read-only, session-auth required - Fixed README: removed 'edit opencode.json directly' claim (it's regenerated on every boot/reconfigure), replaced with /setup and /manage/config references - Added backup/restore and config viewer docs to README Wave 5.2 — /manage/backup + /manage/restore (closes #18) - GET /manage/backup: downloads a gzipped tarball containing .setup.env, opencode.json, users.json, sessions.jsonl, audit.jsonl - POST /manage/restore: accepts a tarball upload, validates structure (must contain .setup.env), extracts only known files (no path traversal), triggers apply_settings + restart - Both require session auth; audit entries recorded - Only whitelisted files are extracted from the tarball (security) Tests: 6 new test cases. 140 total, all passing. Lint + format clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wave 5 (final wave) of the opencode manager improvement plan. Two slices, one PR.
5.1 — /manage/config read view (closes #17)
New endpoint
GET /manage/config(session-auth required) showing:opencode.json— pretty-printed, with{env:VAR}placeholders intact (no raw API keys leaked).setup.env— each line shown with API keys masked (key[:4]…key[-4:]), non-secret env vars shown in fullFixed README: removed the "edit
opencode.jsondirectly" claim (it's regenerated on every boot and every reconfigure bygenerate_config.py), replaced with/setupand/manage/configreferences. Added backup/restore and config viewer docs.5.2 — /manage/backup + /manage/restore (closes #18)
GET /manage/backup— downloads a gzipped tarball containing.setup.env,opencode.json,users.json,sessions.jsonl,audit.jsonl. Requires session auth.POST /manage/restore— accepts a tarball upload, validates structure (must contain.setup.env), extracts only whitelisted files (no path traversal), triggersapply_settings+ restart.Testing — Step by Step
Prerequisites
pytestinstalled (pip install pytest)ruffinstalled (pip install ruff) — for lint/format checksopencodebinary spun up in-processStep 1 — Lint and format check
Expected: Both pass with zero errors.
Verified:
Step 2 — Run the full test suite
Expected:
140 passedwith zero failures, zero errors, zero skipped.Verified:
This runs all 5 test files:
tests/test_manager.py— 87 integration tests (manager lifecycle, auth, proxy, dashboard, all 5 waves)tests/test_wizard.py— 19 unit tests (helpers, rate limiting, env var parsing, volume detection)tests/test_generate_config.py— tests forgenerate_config.py(opencode.json generation)tests/test_seed_agents.py— tests forseed_agents.py(skill seeding)tests/test_toolkit.py— tests for the bundled MCP toolkitStep 3 — Run Wave 5 tests specifically
pytest tests/test_manager.py -k "manage_config or manage_backup or manage_restore" -vExpected: 6 tests pass:
test_manage_config_shows_rendered_json/manage/configreturns 200, showsopencode.json, no raw API keys in bodytest_manage_config_shows_masked_setup_env/manage/configshows.setup.envwithOPENCODE_SERVER_PASSWORDmasked (plaintext not present)test_manage_config_requires_auth/manage/configwithout cookie → 302 redirect to logintest_manage_backup_downloads_tarball/manage/backupreturns 200,Content-Type: application/gzip, valid tarball containing.setup.envtest_manage_backup_requires_auth/manage/backupwithout cookie → 302 redirect to logintest_manage_restore_rejects_bad_tarballPOST /manage/restorewith garbage body → 400/403 (not 200)Verified:
Step 4 — Run all Wave 1–5 tests (full manager integration suite)
Expected: 87 tests pass. Key categories:
Verified:
Step 5 — Run the toolkit MCP selftest
Expected: All 90 stdio test cases pass over the MCP handshake.
Verified:
Step 6 — Docker smoke test (optional, matches CI)
Expected: Health endpoint returns
{"healthy": true}, container runs asopencodeuser (not root).Step 7 — Manual testing after deploy (optional)
Once deployed to Railway, verify these endpoints end-to-end:
https://<your-app>.up.railway.app/manage/login, enter password → redirects to/manage/manage/config→ see renderedopencode.json(with{env:ANTHROPIC_API_KEY}placeholders, not raw keys) and masked.setup.env/manage/config, confirm no API keys or passwords appear in plaintextcurl -b cookie -o backup.tar.gz https://<your-app>.up.railway.app/manage/backup→ valid gzipped tarballtar tzf backup.tar.gz→ should list.setup.envandopencode.json(andusers.json/sessions.jsonl/audit.jsonlif they exist)curl -b cookie -X POST -F "file=@backup.tar.gz" https://<your-app>.up.railway.app/manage/restore→ 302 redirect to/manage, child restarts/manage/audit→ entries forbackup_downloadandrestore_uploadshould appearcurl https://<your-app>.up.railway.app/manage/config→ 302 to login (no config leaked)All waves complete
This is the final wave. All 17 issues (#2-#18) are now addressed across 5 PRs: