Skip to content

Keep development and production ide installs isolated - #68

Merged
GordonBeeming merged 6 commits into
mainfrom
gb/dev-prod-channel-isolation
Jul 27, 2026
Merged

Keep development and production ide installs isolated#68
GordonBeeming merged 6 commits into
mainfrom
gb/dev-prod-channel-isolation

Conversation

@GordonBeeming

@GordonBeeming GordonBeeming commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Why

I want development builds from this checkout to leave the Homebrew-installed production app alone. Running or packaging ide-dev should not stop production, replace /Applications/ide.app, reuse production state, or bind production's loopback port.

What changed

  • Give ide-dev its own bundle identifier, app-data directory, installed app bundle, and fixed loopback API port.
  • Keep the ide launcher and Finder Quick Action pinned to the production app while ide-dev continues to run this checkout.
  • Refuse unsafe development install paths and verify the locally signed development bundle before installation.
  • Add regression coverage for process ownership, port isolation, launcher routing, Tauri configuration, and install-path safety.
  • Update the PostCSS lockfile dependency after a new high-severity advisory caused the repository audit gate to fail.

Testing

  • ./run-tests.sh
    • 433 frontend tests passed
    • 247 Rust tests passed
    • Finder, launcher, native-menu, Tauri-config, theme, build, bundle-budget, and smoke checks passed
    • npm audit and cargo audit passed

Summary by CodeRabbit

  • New Features
    • Added a macOS development Tauri app with isolated configuration and a fixed loopback API port.
    • Enhanced Finder Quick Actions and CLI launchers for reliable dev/prod handoff.
  • Bug Fixes
    • Safer dev app signing/verification and constrained installation path handling.
    • Improved port ownership-aware cleanup and stricter loopback endpoint validation.
  • Documentation
    • Updated development workflow and acceptance-check guidance.
  • Tests
    • Added/expanded validation coverage for channel isolation, launch runners, and Tauri dev configuration.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR separates production and development channels with distinct Tauri metadata, loopback ports, runtime lifecycle handling, signed ide-dev.app packaging, production-pinned launchers, Finder handoff behavior, and isolated validation harnesses.

Changes

Development channel isolation

Layer / File(s) Summary
Fixed loopback channel and Tauri configuration
src-tauri/src/http_server.rs, src-tauri/src/lib.rs, src-tauri/tauri.dev.conf.json, scripts/validate-tauri-config.mjs
The HTTP server selects fixed production or development ports from the bundle identifier, validates overrides, canonicalizes host endpoints, and validates the development overlay.
Development runtime lifecycle
run.sh, src/tauri.ts, src/tauri.test.ts, docs/development.md
run.sh manages development API/Vite listeners, preserves unrelated processes, hands targets to reachable development instances, and starts the development Tauri configuration.
Development app packaging and installation
build.sh, dev-install.sh, scripts/install-cli-command.sh
The build flow creates, signs, verifies, and installs ide-dev.app at a constrained path while keeping the ide launcher pointed at /Applications/ide.app.
Production CLI and Finder handoff
scripts/install-cli-command.sh, scripts/install-macos-finder-quick-action.sh, docs/development.md
The CLI and Finder integrations use the production bundle, hand off targets through the production loopback API, and fall back to opening /Applications/ide.app.
Channel isolation validation
scripts/validate-channel-isolation.mjs, scripts/validate-finder-quick-action.mjs, scripts/validate-launch-runners.mjs
Validation covers listener ownership, development handoff, install-path rejection, signing and copying, launcher wiring, Finder behavior, and production mutation restrictions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant run.sh
  participant ide-dev
  participant OpenPathAPI
  run.sh->>ide-dev: Check development API reachability
  run.sh->>OpenPathAPI: POST /api/open-path with bearer token
  OpenPathAPI-->>run.sh: Return handoff result
  run.sh->>ide-dev: Stop or start development instance
Loading

Possibly related PRs

  • GordonBeeming/ide#57: Both changes modify the generated ide launcher and its app-bundle path handling.
  • GordonBeeming/ide#58: Both changes modify loopback host/port handling in src-tauri/src/http_server.rs.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: separating development and production IDE installations.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gb/dev-prod-channel-isolation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR isolates development (ide-dev) and production (ide) installs so running/building from a checkout cannot stop, overwrite, or reuse the Homebrew-installed production app, including separating bundle identifiers, app state, and loopback API ports.

Changes:

  • Split production vs development identity/config: new ide-dev bundle identifier, separate Tauri dev config overlay, and fixed dev loopback port 17878 (production remains 17877).
  • Reworked launch/install tooling so ide and Finder Quick Action remain pinned to /Applications/ide.app, while ide-dev continues to target the checkout runner and dev loopback endpoint.
  • Added regression harness/validations for channel isolation behaviors and updated the lockfile to address audit advisories.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/tauri.ts Updates hosted dev-server API base to the dev loopback port.
src/tauri.test.ts Adjusts tests to assert the dev loopback base and related edge cases.
src-tauri/tauri.dev.conf.json Adds a development-only Tauri overlay with distinct identifier/name and no file associations.
src-tauri/src/lib.rs Plumbs the app bundle identifier into HTTP server startup config.
src-tauri/src/http_server.rs Uses fixed per-channel loopback ports (17877/17878) and validates IDE_LOOPBACK_PORT.
scripts/validate-tauri-config.mjs Extends config validation to enforce development overlay invariants.
scripts/validate-launch-runners.mjs Shifts runner validation to focus on channel isolation and non-mutation of production.
scripts/validate-finder-quick-action.mjs Ensures generated Finder Quick Action targets production app and avoids dev-tooling.
scripts/validate-channel-isolation.mjs New harness validating port/process ownership, cleanup behavior, and install-path safety.
scripts/install-macos-finder-quick-action.sh Changes Finder runner to hand off to production loopback or open production app bundle.
scripts/install-cli-command.sh Pins ide launcher to /Applications/ide.app and links ide-dev to checkout run.sh.
run.sh Updates dev runner to use a dev-only loopback port and refuse interfering with unrelated listeners.
package-lock.json Updates PostCSS/nanoid dependencies in response to audit advisory.
docs/development.md Documents production vs development install behavior, ports, and new packaging/install flow.
dev-install.sh Simplifies to a compatibility wrapper delegating to build.sh.
build.sh Builds/signs/installs ide-dev.app to an isolated path with safety checks and verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src-tauri/src/http_server.rs Outdated
Address reviewer comments:
- Keep MCP endpoint fallbacks on the active channel port
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@GordonBeeming
GordonBeeming requested a review from Copilot July 27, 2026 05:25
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
scripts/validate-launch-runners.mjs (3)

21-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Surface the child harness output on failure.

With stdio: "pipe" and no try/catch, a failing validate-channel-isolation.mjs throws Command failed: node … and the harness's own assertion message (which names the failing scenario) is buried in error.stdout/error.stderr. Use stdio: "inherit", or catch and re-throw with the captured streams.

♻️ Proposed change
   execFileSync(process.execPath, [channelIsolationHarness], {
     cwd: rootDir,
-    stdio: "pipe",
+    stdio: "inherit",
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/validate-launch-runners.mjs` around lines 21 - 24, Update the
execFileSync invocation in validate-launch-runners.mjs to use stdio: "inherit"
so validate-channel-isolation.mjs output, including assertion details, is
visible directly when the child harness fails.

122-134: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Finder-runner assertions are duplicated across two harnesses. Both files assert the same set of strings against the same generated open-from-finder.sh, and both carry byte-identical assertNotIncludes/assertOrdered helpers; the shared root cause is the absence of a common assertion module, so any change to the runner requires editing two places.

  • scripts/validate-launch-runners.mjs#L122-L134: extract the Finder-runner assertion block (and the assertIncludes/assertNotIncludes/assertOrdered helpers) into a shared module, e.g. scripts/lib/assert.mjs, and import it here.
  • scripts/validate-finder-quick-action.mjs#L41-L55: import the shared assertion block/helpers instead of re-declaring them, keeping only this harness's unique setup.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/validate-launch-runners.mjs` around lines 122 - 134, The
Finder-runner assertions and assertion helpers are duplicated across both
harnesses. In scripts/validate-launch-runners.mjs lines 122-134, extract the
shared Finder-runner assertion block and
assertIncludes/assertNotIncludes/assertOrdered helpers into a common module such
as scripts/lib/assert.mjs, then import and reuse them; in
scripts/validate-finder-quick-action.mjs lines 41-55, remove the duplicate
definitions and import the shared module while preserving only its unique setup.

152-162: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

The forbidden-string list is exact-match and easy to bypass unintentionally.

Each entry must be spelled character-for-character, so a quoting change (ditto "$DEV_APP_BUNDLE" /Applications/ide.app), a variable rename, or rm -rf /Applications/ide.app all pass this guard. Matching on the target instead — e.g. a regex for a write/destructive command whose argument is /Applications/ide.app, plus com.gordonbeeming.ide (non-.dev) quit/pkill — makes the canary hold up as the scripts evolve.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/validate-launch-runners.mjs` around lines 152 - 162, Strengthen
assertNoProductionMutation so it detects production-app mutations by target
rather than exact command strings. Replace the brittle forbidden list with
checks covering write or destructive commands targeting /Applications/ide.app,
including quoting or variable variations, and checks for quitting or killing the
non-development com.gordonbeeming.ide application while preserving allowed
development-app operations.
run.sh (1)

240-255: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: silence SC2034 for the unused loop counters.

attempt is only a repeat counter; shellcheck flags it. Renaming to _attempt (or for _ in {1..20}) keeps the lint clean across all four wait loops.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@run.sh` around lines 240 - 255, Rename the unused loop counter variable
attempt to _attempt (or use _) in all four wait loops, including the loops
around running_dev_app_reachable, so ShellCheck no longer reports SC2034 while
preserving the existing retry behavior.

Source: Linters/SAST tools

build.sh (1)

118-133: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Avoid codesign --deep for signing development apps.

Apple discourages --deep for signing because it can apply the same entitlements across nested code and miss properly signed bundles. Sign inner code items first, then sign the outer app bundle with the desired --identifier; --deep remains useful for verification, but not for these codesign --sign actions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.sh` around lines 118 - 133, Update sign_dev_app so neither signing
action passes --deep to codesign. Sign nested code items explicitly before
signing the outer app bundle with --identifier "$DEV_BUNDLE_IDENTIFIER", while
preserving verify_dev_app_signature for deep verification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@build.sh`:
- Around line 27-51: Update the validation around resolve_dev_install_parent and
the parent comparison near the install path checks to canonicalize both the
requested parent and its existing ancestor before comparing them. Reject only
when canonical resolution shows the path escapes or aliases away from the
requested parent, while allowing legitimate symlinked prefixes such as /tmp or
$HOME; preserve the existing safety checks for non-directory components.

In `@scripts/validate-channel-isolation.mjs`:
- Around line 176-178: Update the harness setup around binDir and runShell so
harness.binDir is prepended to the PATH passed to every shell script, while
preserving the existing environment and avoiding reliance on the parent process
PATH. Ensure the resulting PATH uses the harness-specific bin directory before
system entries so all command stubs resolve first.

---

Nitpick comments:
In `@build.sh`:
- Around line 118-133: Update sign_dev_app so neither signing action passes
--deep to codesign. Sign nested code items explicitly before signing the outer
app bundle with --identifier "$DEV_BUNDLE_IDENTIFIER", while preserving
verify_dev_app_signature for deep verification.

In `@run.sh`:
- Around line 240-255: Rename the unused loop counter variable attempt to
_attempt (or use _) in all four wait loops, including the loops around
running_dev_app_reachable, so ShellCheck no longer reports SC2034 while
preserving the existing retry behavior.

In `@scripts/validate-launch-runners.mjs`:
- Around line 21-24: Update the execFileSync invocation in
validate-launch-runners.mjs to use stdio: "inherit" so
validate-channel-isolation.mjs output, including assertion details, is visible
directly when the child harness fails.
- Around line 122-134: The Finder-runner assertions and assertion helpers are
duplicated across both harnesses. In scripts/validate-launch-runners.mjs lines
122-134, extract the shared Finder-runner assertion block and
assertIncludes/assertNotIncludes/assertOrdered helpers into a common module such
as scripts/lib/assert.mjs, then import and reuse them; in
scripts/validate-finder-quick-action.mjs lines 41-55, remove the duplicate
definitions and import the shared module while preserving only its unique setup.
- Around line 152-162: Strengthen assertNoProductionMutation so it detects
production-app mutations by target rather than exact command strings. Replace
the brittle forbidden list with checks covering write or destructive commands
targeting /Applications/ide.app, including quoting or variable variations, and
checks for quitting or killing the non-development com.gordonbeeming.ide
application while preserving allowed development-app operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 51e6259d-5d62-475a-a4ff-1ce90c753c78

📥 Commits

Reviewing files that changed from the base of the PR and between afcb2da and 621c864.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • build.sh
  • dev-install.sh
  • docs/development.md
  • run.sh
  • scripts/install-cli-command.sh
  • scripts/install-macos-finder-quick-action.sh
  • scripts/validate-channel-isolation.mjs
  • scripts/validate-finder-quick-action.mjs
  • scripts/validate-launch-runners.mjs
  • scripts/validate-tauri-config.mjs
  • src-tauri/src/http_server.rs
  • src-tauri/src/lib.rs
  • src-tauri/tauri.dev.conf.json
  • src/tauri.test.ts
  • src/tauri.ts

Comment thread build.sh
Comment thread scripts/validate-channel-isolation.mjs
Address reviewer comments:
- Allow safe development install paths through symlinked prefixes
- Run channel-isolation scripts with harness command stubs first
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@GordonBeeming
GordonBeeming requested a review from Copilot July 27, 2026 05:34
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Comment thread build.sh
Comment thread build.sh
Comment thread dev-install.sh
Address reviewer comments:
- Guard macOS development packaging paths
- Protect canonical Applications aliases
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@GordonBeeming
GordonBeeming requested a review from Copilot July 27, 2026 05:40
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment thread docs/development.md Outdated
@GordonBeeming

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@GordonBeeming
GordonBeeming requested a review from Copilot July 27, 2026 07:12
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

@GordonBeeming
GordonBeeming marked this pull request as ready for review July 27, 2026 07:18
@GordonBeeming
GordonBeeming merged commit 07b9eee into main Jul 27, 2026
4 of 6 checks passed
@GordonBeeming
GordonBeeming deleted the gb/dev-prod-channel-isolation branch July 27, 2026 07:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b8ca80709

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread run.sh
ensure_dev_port_available

exec npm run tauri:dev
exec npm run tauri:dev -- --config src-tauri/tauri.dev.conf.json

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Route the npm dev command through the development config

When a developer runs the still-documented npm run tauri:dev, package.json expands it to plain tauri dev, so neither this --config argument nor IDE_LOOPBACK_PORT=17878 is applied. That launch therefore uses the base production identifier and port 17877, putting it back in the production single-instance and app-data channel and defeating the isolation this change promises. Make the npm entry point itself apply the development overlay, rather than applying it only in run.sh.

Useful? React with 👍 / 👎.

Comment on lines +114 to +115
const result = runShell(path.join(checkout, "build.sh"), [], harness, "build-success", buildEnv);
assertStatus(result, 0, "stubbed development build/install");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make the build harness portable outside macOS

On Linux or Windows, this unconditionally runs the copied build.sh, whose new uname -s != Darwin guard exits before any of the harness stubs execute; consequently npm run launch:check always fails on those supported development platforms. The harness should either skip this macOS-only install case off Darwin or stub the platform and macOS-only copy operation.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants