Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add deterministic dev port runner for multi-instance local workflows - #20

Merged
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48
Feb 13, 2026
Merged

Add deterministic dev port runner for multi-instance local workflows#20
juliusmarminge merged 1 commit into
mainfrom
codething/6df7db48

Conversation

@juliusmarminge

@juliusmarmingejuliusmarminge commented Feb 13, 2026

Copy link
Copy Markdown
Member

Summary

  • add scripts/dev-runner.mjs to centralize dev script startup and compute coordinated server/web port offsets
  • support deterministic multi-instance setup via T3CODE_DEV_INSTANCE (hashed or numeric) and explicit override via T3CODE_PORT_OFFSET
  • propagate computed ports to all relevant env vars (T3CODE_PORT, PORT, VITE_WS_URL, VITE_DEV_SERVER_URL, ELECTRON_RENDERER_PORT)
  • update root package.json dev scripts to route through the new runner
  • make server dev URL configurable in apps/server/package.json instead of hardcoding http://localhost:5173
  • document isolated desktop/dev-instance usage and port-offset behavior in README.md
  • include ELECTRON_RENDERER_PORT in Turbo global env passthrough

Testing

  • Not run (no test or lint output included in the provided changes)
  • manual validation path available via bun run scripts/dev-runner.mjs <mode> --dry-run to confirm computed ports/env wiring

Open with Devin

Summary by CodeRabbit

  • New Features

    • Support for running multiple development instances simultaneously with automatic port management.
  • Documentation

    • Added guidance for launching isolated development environments using environment variables.
  • Chores

    • Updated development scripts infrastructure to support multi-instance orchestration with configurable port offsetting.

- Route `dev*` scripts through `scripts/dev-runner.mjs` to compute shared server/web port offsets
- Support `T3CODE_DEV_INSTANCE` (hashed or numeric) and explicit `T3CODE_PORT_OFFSET`
- Document multi-instance usage and allow server `VITE_DEV_SERVER_URL` override
@coderabbitai

coderabbitaiBot commented Feb 13, 2026

Copy link
Copy Markdown

Walkthrough

This change introduces support for running multiple development instances with deterministic port shifting. A new dev-runner script orchestrates Turbo-based development workflows, calculating port offsets from environment variables. Development scripts are updated to delegate to this runner, and documentation is added explaining the feature with example usage.

Changes

Cohort / File(s)Summary
Documentation
README.md
Added guidance on running multiple dev instances using T3CODE_DEV_INSTANCE to shift ports deterministically, with examples of base ports and offset calculation.
Dev Runner Implementation
scripts/dev-runner.mjs
New Node.js script that coordinates Turbo-based dev workflows with automatic port offset resolution from environment variables, port validation, child process spawning with inherited I/O, and error handling.
Script Updates
package.json, apps/server/package.json
Updated dev scripts to invoke new dev-runner script instead of direct Turbo commands; apps/server now reads VITE_DEV_SERVER_URL from environment with fallback default.
Turbo Configuration
turbo.json
Added ELECTRON_RENDERER_PORT to global environment variables for Turbo task consumption.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding a deterministic dev port runner to support multi-instance local development workflows, which is the core purpose of the new scripts/dev-runner.mjs and associated configuration updates.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/6df7db48

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

@macroscopeapp

Copy link
Copy Markdown
Contributor

Add a dev-runner to shift server and web dev ports deterministically for multi-instance local workflows via scripts/dev-runner.mjs and environment-controlled offsets

Introduce a Bun-based scripts/dev-runner.mjs that sets T3CODE_PORT, PORT, ELECTRON_RENDERER_PORT, VITE_WS_URL, and VITE_DEV_SERVER_URL using T3CODE_PORT_OFFSET or T3CODE_DEV_INSTANCE, route dev scripts through this runner, and make the server respect VITE_DEV_SERVER_URL. Update docs on instance-based port selection.

📍Where to Start

Start with the mode handling and offset calculation in scripts/dev-runner.mjs.


Macroscope summarized f4df41a.

@greptile-apps

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Adds a centralized dev script runner (scripts/dev-runner.mjs) to coordinate port allocation across server, web, and desktop packages, enabling deterministic multi-instance local development workflows. The runner computes port offsets using either an explicit numeric value (T3CODE_PORT_OFFSET) or by hashing a string identifier (T3CODE_DEV_INSTANCE), then propagates coordinated ports to all relevant environment variables before spawning Turbo.

Key changes:

  • Created dev-runner.mjs with FNV-1a hashing for deterministic port offsets (1-3000 range)
  • Updated root package.json dev scripts to route through the runner
  • Made server dev URL configurable via VITE_DEV_SERVER_URL with fallback
  • Added ELECTRON_RENDERER_PORT to Turbo's global env passthrough
  • Documented multi-instance usage patterns in README

The implementation correctly propagates environment variables and validates port ranges, though numeric T3CODE_DEV_INSTANCE values lack upfront validation and may produce confusing errors for large offsets.

Confidence Score: 4/5

  • Safe to merge with one validation issue that should be fixed to prevent confusing runtime errors
  • Well-structured implementation with proper error handling and documentation. The core logic for port coordination is sound, using a proven hash function and proper environment variable propagation. One logical issue exists where numeric T3CODE_DEV_INSTANCE values aren't validated upfront, which could lead to confusing port-range errors later. The change is additive and maintains backward compatibility (default behavior unchanged).
  • scripts/dev-runner.mjs needs validation fix for numeric instance values

Important Files Changed

FilenameOverview
scripts/dev-runner.mjsNew script centralizes dev mode startup with deterministic port offset calculation via hashing or explicit env vars; has validation gap for numeric instance values
package.jsonRoutes all dev scripts through new dev-runner wrapper, replacing inline env var definitions
apps/server/package.jsonMakes dev server URL configurable via VITE_DEV_SERVER_URL env var with fallback to default localhost:5173

Sequence Diagram

sequenceDiagram
participant Dev as Developer
participant Runner as dev-runner.mjs
participant Turbo as Turbo Build System
participant Server as apps/server
participant Web as apps/web
participant Desktop as apps/desktop
Dev->>Runner: bun run dev (or dev:desktop)
Runner->>Runner: Resolve port offset<br/>(T3CODE_PORT_OFFSET or<br/>T3CODE_DEV_INSTANCE hash)
Runner->>Runner: Compute ports<br/>server=3773+offset<br/>web=5173+offset
Runner->>Runner: Set env vars:<br/>T3CODE_PORT, PORT,<br/>ELECTRON_RENDERER_PORT,<br/>VITE_WS_URL, VITE_DEV_SERVER_URL
Runner->>Turbo: spawn turbo with computed env
Turbo->>Server: Start with T3CODE_PORT
Turbo->>Web: Start with PORT & VITE_WS_URL
opt Desktop Mode
Turbo->>Desktop: Start with ELECTRON_RENDERER_PORT
Desktop->>Desktop: Wait for web server on port
Desktop->>Desktop: Launch Electron with VITE_DEV_SERVER_URL
end
Server->>Web: WebSocket connection on coordinated ports
Loading

Last reviewed commit: f4df41a

@greptile-appsgreptile-appsBot 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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +53 to +54
if (/^\d+$/.test(seed)) {
return { offset: Number(seed), source: `numeric T3CODE_DEV_INSTANCE=${seed}` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

numeric T3CODE_DEV_INSTANCE values aren't validated before use - large numbers like "70000" will pass through but fail port validation later with a confusing error

Suggested change
if(/^\d+$/.test(seed)){
return{offset: Number(seed),source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
if(/^\d+$/.test(seed)){
constoffset=Number(seed);
if(offset<0||offset>65535-Math.max(BASE_SERVER_PORT,BASE_WEB_PORT)){
thrownewError(`T3CODE_DEV_INSTANCE numeric offset ${offset} would exceed valid port range`);
}
return{ offset,source: `numeric T3CODE_DEV_INSTANCE=${seed}`};
}

@coderabbitaicoderabbitaiBot 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: 1

🤖 Fix all issues with AI agents
In `@scripts/dev-runner.mjs`:
- Around line 61-67: The usage string thrown in main() is misleading because the
script is invoked via "bun run"; update the thrown Error message inside the mode
validation (the block that checks mode and MODE_ARGS) to reflect the actual
invocation (e.g., include "bun run" and mention optional flags like --dry-run)
so the message matches how users run this script; locate the error creation in
function main() where MODE_ARGS is referenced and replace the existing Usage
text with the corrected invocation text.

Comment on lines +61 to +67
function main() {
const mode = process.argv[2];
const isDryRun = process.argv.includes("--dry-run");
if (!mode || !(mode in MODE_ARGS)) {
const supportedModes = Object.keys(MODE_ARGS).join(", ");
throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align usage message with actual invocation.
The scripts call this via bun run, so the error text is slightly misleading.

✏️ Suggested tweak
- throw new Error(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);+ throw new Error(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
functionmain(){
constmode=process.argv[2];
constisDryRun=process.argv.includes("--dry-run");
if(!mode||!(modeinMODE_ARGS)){
constsupportedModes=Object.keys(MODE_ARGS).join(", ");
thrownewError(`Usage: bun run scripts/dev-runner.mjs <mode>. Supported modes: ${supportedModes}`);
}
🤖 Prompt for AI Agents
In `@scripts/dev-runner.mjs` around lines 61 - 67, The usage string thrown in
main() is misleading because the script is invoked via "bun run"; update the
thrown Error message inside the mode validation (the block that checks mode and
MODE_ARGS) to reflect the actual invocation (e.g., include "bun run" and mention
optional flags like --dry-run) so the message matches how users run this script;
locate the error creation in function main() where MODE_ARGS is referenced and
replace the existing Usage text with the corrected invocation text.

@juliusmarminge
juliusmarminge merged commit 15380f2 into mainFeb 13, 2026
4 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Aug 2, 2026
Sign up for freeto 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.

1 participant

@juliusmarminge