[1630 by Claude Opus 4.8] Add propr tunnel on|off service toggle command - #1642
Conversation
…dist/` build output and is pre-existing/unrelated to my changes — none of my source files appear in the lint output. Summary I implemented `propr tunnel on|off` as a service toggle, mirroring the existing `propr ui` / `propr docs` pattern. Changes New command — `packages/cli/src/commands/tunnelCommand.ts` - `propr tunnel on`: requires a configured token (`cfg.uiTunnelToken`). If missing, it fails clearly with a message pointing at `PROPR_UI_TUNNEL_TOKEN`. When present, it starts the cloudflared `tunnel` service and reports the public API URL. - `propr tunnel off`: stops and removes only the tunnel container; it explicitly never touches token/env values. - Persists the desired state via `setTunnelEnabled()` after the action succeeds. - Help text documents both `PROPR_UI_TUNNEL_TOKEN` and `PROPR_UI_PUBLIC_API_URL`. Config persistence - `config/types.ts`: added `tunnelEnabled` to `ConfigKey`, `CLIConfig`, and `DEFAULT_CONFIG`. - `config/ConfigManager.ts`: added `getTunnelEnabled()` / `setTunnelEnabled()`. Honoring persisted state on `propr start` - `docker/launcher/orchestrator.mjs`: `resolveConfig` now lets an explicit `uiTunnelEnabled` override win over the env-derived default (`overrides.uiTunnelEnabled ?? …`), so an explicit `off` wins even when a token is present. - `orchestrator/index.ts`: `getHostConfig` forwards the persisted `tunnelEnabled` config as a `uiTunnelEnabled` cliOverride (same mechanism as `docsEnabled`). - `tui/render.ts`: `propr start` passes `tunnel = cfg.uiTunnelEnabled` to `startStack`. Wiring & types - Registered the command and exports in `index.ts` / `commands/index.ts`, added `tunnel` to the Control Plane help line. - Updated the `startStack`/`startStackAsync` types to accept the `tunnel` option. Tests — added two cases to `test/orchestratorConfig.test.mjs` verifying the override wins over the env default (both directions) and that an absent override falls back to env. Verification - `npm run typecheck` (CLI): passes - `npm run build` (CLI): passes - `node --test test/orchestratorConfig.test.mjs test/orchestratorTunnelStatus.test.mjs`: all pass (29 + 34) All four acceptance criteria are satisfied.
|
/ultrafix |
|
🔄 Ultrafix loop started (goal: 8/10, max cycles: 10) First action:
|
|
✅ AI Code Review Complete requested by @propr-dev[bot] Posted 1 review: |
🔍 AI Code Review — codex:gpt-5.5Overall EvaluationThis PR adds Findings🔴 Persisted tunnel setting is discarded on load — 🟡 Getter default conflicts with documented fallback behavior — 🟢 Add config-level test coverage for persistence — The orchestrator tests cover ✅ Launcher override behavior is correctly scoped — ✅ ✅ User-facing tunnel command is clear — ScoreThe main implementation is coherent, but the missing Score: 6/10 🤖 Review Details
|
|
✅ Applied the requested follow-up changes in commit 393e534
Summary of ChangesI've addressed all the actionable findings from the review. Here's a summary: Changes1. 🔴 Persisted tunnel setting discarded on load (critical) 2. 🟡 Getter default conflicted with documented fallback semantics 3. 🟢 Config-level test coverage Verification
Note: the full 🤖 Implementation Details
💡 ProPR Slash Commands
|
… Here's a summary:
I've addressed all the actionable findings from the review. Here's a summary:
## Changes
**1. 🔴 Persisted tunnel setting discarded on load (critical)**
`packages/cli/src/config/ConfigManager.ts` — added the missing `tunnelEnabled` entry to `sanitizeConfig()`. Previously `setTunnelEnabled(false)` wrote the value, but the next CLI process dropped it during `load()`, so `propr start` would re-enable the tunnel from the env/token default despite a prior `propr tunnel off`. Now the boolean survives reload like `uiEnabled`/`docsEnabled`.
**2. 🟡 Getter default conflicted with documented fallback semantics**
Changed `getTunnelEnabled()` to return `boolean | undefined` instead of coercing unset to `false`. An unset value means "defer to the launcher's env-derived default" (per `types.ts`), so collapsing it to `false` encoded the wrong semantic and was easy to misuse. The orchestrator already reads the raw value via `get("tunnelEnabled")` and forwards it as an override only when set, so this aligns the public helper with that behavior. Updated the doc comment to explain why it differs from the UI/docs toggles.
**3. 🟢 Config-level test coverage**
`test/cliConfigManager.test.ts` — added two focused tests: one that writes `tunnelEnabled: false`, reloads a fresh `ConfigManager`, and asserts the value (and raw `get`) survive (regression guard for the sanitize omission, also covering the `true` round-trip), plus one asserting `getTunnelEnabled()` returns `undefined` when unset.
## Verification
- `npm run build` (CLI) — passes.
- Direct functional verification of all four scenarios (false persists, raw get persists, true persists, unset → undefined) via tsx against the source — **ALL PASS**.
- `tsc --noEmit` — no errors in the changed files.
Note: the full `cliConfigManager.test.ts` suite can't complete in this container because importing the `@propr/cli` barrel runs `propr check`, which aborts without Docker/a stack — this is a pre-existing environmental issue (the unmodified HEAD version of the file fails identically at the same subtest), not caused by my changes. I left the changes uncommitted as instructed.
PR: #1642
Comment by: @propr-ultrafix (ID: 0)
Model: claude-opus-4-8
|
✅ AI Code Review Complete requested by @propr-ultrafix Posted 1 review: |
🔍 AI Code Review — codex:gpt-5.5Overall EvaluationThis PR adds a persisted Findings🟡 🟢 Add command-level tests for the toggle flow — The config/orchestrator tests cover persistence and config resolution, but there is no direct coverage for 🟢 Avoid direct ✅ Good preservation of unset tunnel state — ✅ Config sanitization and regression coverage are solid — ✅ Launcher override precedence is correctly modeled — ScoreGood implementation overall, but the possible stale-config behavior in the main toggle command should be resolved or explicitly disproven before merging. 🤖 Review Details
|
AI Implementation Summary
Closes #1630
Branch:
1630/claude-opus-4-8-add-propr-tunnel-on-off-s-20260625-1421-pm3Commits: ✅ Changes committed (195b6b0)
AI Processing Completed
Execution Details:
propr tunnel on|offservice toggle command #1630Summary:
The lint error (
react-hooks/exhaustive-depsrule not found) is indist/build output and is pre-existing/unrelated to my changes — none of my source files appear in the lint output.Summary
I implemented
propr tunnel on|offas a service toggle, mirroring the existingpropr ui/propr docspattern.Changes
New command —
packages/cli/src/commands/tunnelCommand.tspropr tunnel on: requires a configured token (cfg.uiTunnelToken). If missing, it fails clearly with a message pointing atPROPR_UI_TUNNEL_TOKEN. When present, it starts the cloudflaredtunnelservice and reports the public API URL.propr tunnel off: stops and removes only the tunnel container; it explicitly never touches token/env values.setTunnelEnabled()after the action succeeds.PROPR_UI_TUNNEL_TOKENandPROPR_UI_PUBLIC_API_URL.Config persistence
config/types.ts: addedtunnelEnabledtoConfigKey,CLIConfig, andDEFAULT_CONFIG.config/ConfigManager.ts: addedgetTunnelEnabled()/setTunnelEnabled().Honoring persisted state on
propr startdocker/launcher/orchestrator.mjs:resolveConfignow lets an explicituiTunnelEnabledoverride win over the env-derived default (overrides.uiTunnelEnabled ?? …), so an explicitoffwins even when a token is present.orchestrator/index.ts:getHostConfigforwards the persistedtunnelEnabledconfig as auiTunnelEnabledcliOverride (same mechanism asdocsEnabled).tui/render.ts:propr startpassestunnel = cfg.uiTunnelEnabledtostartStack.Wiring & types
index.ts/commands/index.ts, addedtunnelto the Control Plane help line.startStack/startStackAsynctypes to accept thetunneloption.Tests — added two cases to
test/orchestratorConfig.test.mjsverifying the override wins over the env default (both directions) and that an absent override falls back to env.Verification
npm run typecheck(CLI): passesnpm run build(CLI): passesnode --test test/orchestratorConfig.test.mjs test/orchestratorTunnelStatus.test.mjs: all pass (29 + 34)All four acceptance criteria are satisfied.
Detailed Logs:
55834137-fe48-4a56-8d90-021305115f88Log files stored at:
/tmp/claude-logs/issue-1630-2026-06-25T14-29-03-776Z-conversation.json/tmp/claude-logs/issue-1630-2026-06-25T14-29-03-776Z-output.txtLatest Conversation Messages
This PR was created automatically by ProPR after processing issue #1630.
💡 Need changes?
Comment on this PR to request refinements — the AI agent monitors comments and will update the implementation based on your feedback. Keep iterating until you're satisfied!