Repository navigation
feat(development): add source-watched Bun stack - #417
Conversation
|
Warning Review limit reached
Next review available in: 20 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdded a Bun-based local development stack with isolated state, coordinated web and worker processes, HTTP/WebSocket proxies, optional Tailscale HTTPS access, development logging, source-boundary updates, Unicode validation changes, and local-development documentation. ChangesDevelopment stack
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (15)
greenfield/scripts/development/developmentProcessGuard.ts (1)
7-17: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winApply the same argument validation as the privileged variant.
guardedDevelopmentPrivilegedCommandrejects an empty command, a relative executable, and an invalidparentProcessIdat lines 43-50.guardedDevelopmentChildCommandperforms no such check. Ifcommandis empty, the generated shell runsexecwith no operands, which exits 0 and looks like a clean child exit to the runtime coordinator. Add the same guard so the failure is explicit.♻️ Proposed validation
export function guardedDevelopmentChildCommand( command: readonly string[], parentProcessId = process.pid ): readonly string[] { + if (command.length === 0 || !command[0]?.startsWith("/")) { + throw new TypeError("Development child command must use an absolute executable"); + } + if (!Number.isSafeInteger(parentProcessId) || parentProcessId <= 1) { + throw new TypeError("Development child command parent PID is invalid"); + } const setpriv = Bun.which("setpriv");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentProcessGuard.ts` around lines 7 - 17, Update guardedDevelopmentChildCommand to apply the same validation as guardedDevelopmentPrivilegedCommand: reject an empty command, reject a relative executable, and reject an invalid parentProcessId before checking dependencies or generating the command. Preserve the privileged variant’s validation behavior and error semantics.greenfield/scripts/development/developmentRuntime.ts (1)
199-212: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConfirm the intended exit code when a child exits with code 0.
Line 211 returns
exited.code || 1. If a child exits cleanly with code 0 and no stop was requested, the stack reports 1. That behavior is defensible, because an unrequested child exit is abnormal. Line 209 still writes "exited with code 0", which does not match the returned 1. Confirm the intent, and consider logging the reported exit code so the message and the return value agree.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentRuntime.ts` around lines 199 - 212, Align the unrequested child-exit reporting in the development runtime with the value returned by the final return statement: update the process.stderr message around exited and the exited.code || 1 fallback so a clean child exit does not log code 0 while returning 1. Preserve the existing stopRequested early return and abnormal-exit behavior.greenfield/scripts/development/developmentStateLease.ts (1)
187-196: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winConsider naming the offending lease file when parsing fails.
readLeaseMarkerthrows for any file that matchesleaseFilePatternbut has invalid contents, ownership, or mode.activeLeaseFilespropagates that error. Every entry point that needs the lease then fails, includingresetDevelopmentStateandresetDevelopmentDatabaseingreenfield/scripts/development/developmentState.ts. A single damaged lease file therefore blocks both normal startup and the documented recovery commands, and the message "Development state lease is invalid" does not identify the file to delete.Include
fileNamein the thrown message so the operator can remove the exact file.♻️ Proposed change in
readLeaseMarker- throw new Error("Development state lease is invalid", { cause: error }); + throw new Error(`Development state lease is invalid: ${fileName}`, { + cause: error, + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentStateLease.ts` around lines 187 - 196, Update readLeaseMarker to include the offending fileName in the thrown “Development state lease is invalid” error message, preserving the existing validation and error behavior so operators can identify and remove the damaged lease file.greenfield/scripts/development/developmentRuntime.test.ts (1)
39-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThe fake child exits on any signal, so the forced-termination path stays untested.
killrecords the signal and immediately resolvesexitedwith 0.settleChildreningreenfield/scripts/development/developmentRuntime.tstherefore always observes a fast graceful exit. The 10-second timeout branch and the follow-upSIGKILLescalation at lines 111-114 never run in these tests. Consider a fake child that ignoresSIGTERMuntil the test releases it, so the escalation path gains coverage.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentRuntime.test.ts` around lines 39 - 42, Update the fake child’s kill behavior in the development runtime tests so it records SIGTERM without resolving exited, allowing settleChildren’s timeout and SIGKILL escalation path to execute. Provide a test-controlled release that resolves exited after the graceful path is explicitly triggered, while preserving immediate exit behavior for SIGKILL.greenfield/src/worker/developmentTaskNotifications.test.ts (1)
7-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the interrupt exit instead of fiber existence.
expect(fiber).toBeDefined()always passes. It does not verify the interruption. Capture the result ofFiber.interruptand assert that the exit is an interruption.♻️ Proposed change
-import { Effect, Fiber } from "effect"; +import { Effect, Exit, Fiber } from "effect"; import { developmentTaskNotificationLoop } from "./developmentTaskNotifications.ts"; test("development task notifications stay inert and remain interruptible", async () => { const fiber = Effect.runFork(developmentTaskNotificationLoop()); - await Effect.runPromise(Fiber.interrupt(fiber)); - expect(fiber).toBeDefined(); + const exit = await Effect.runPromise(Fiber.interrupt(fiber)); + expect(Exit.isFailure(exit)).toBeTrue(); });Confirm the
Fiber.interruptreturn shape on the pinned Effect beta before you apply this change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/worker/developmentTaskNotifications.test.ts` around lines 7 - 12, Update the test around developmentTaskNotificationLoop to capture the result returned by Fiber.interrupt(fiber) and assert that its exit represents interruption, rather than merely checking the fiber is defined. Confirm the pinned Effect beta’s Fiber.interrupt return shape and use the corresponding interruption assertion.greenfield/src/app/developmentWeb.ts (2)
17-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
developmentSourceCommitis duplicated across the two entry points. Both files define the same argument-count check, the same/^[\da-f]{40}$/upattern, and the same non-null assertion. Only the error text differs. If the commit format changes, one copy can drift. Extract one helper that accepts the process label and use it in both entry points.
greenfield/src/app/developmentWeb.ts#L17-L22: replace the local definition with a call to the shared helper, passing the "web" label.greenfield/src/app/developmentWorker.ts#L19-L24: replace the local definition with a call to the same shared helper, passing the "worker" label.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/app/developmentWeb.ts` around lines 17 - 22, Extract the duplicated developmentSourceCommit validation into one shared helper that accepts the process label and preserves the existing argument-count, 40-character hexadecimal validation, and returned commit behavior. In greenfield/src/app/developmentWeb.ts:17-22, remove the local definition and use the helper with the "web" label; make the corresponding replacement in greenfield/src/app/developmentWorker.ts:19-24 using the "worker" label.
67-74: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winBoth development entry points discard the startup error. The
import.meta.mainguard in each file uses a barecatchand writes only a fixed line to stderr. A developer then has no cause for a failed local start. Include the failure detail in the stderr output at both sites.
greenfield/src/app/developmentWeb.ts#L67-L74: bind the caught error and append its message to the "development web startup failed" line.greenfield/src/app/developmentWorker.ts#L84-L91: bind the caught error and append its message to the "development worker startup failed" line.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/app/developmentWeb.ts` around lines 67 - 74, Update the import.meta.main startup handlers in greenfield/src/app/developmentWeb.ts#L67-L74 and greenfield/src/app/developmentWorker.ts#L84-L91: bind the caught error and append its message to the existing development web or worker startup failure stderr output, preserving the current exitCode behavior.greenfield/src/app/developmentWorker.ts (1)
43-72: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftConsider extracting the shared worker runtime builder.
This
createRuntimebody repeatsgreenfield/src/app/worker.tslines 170-199. OnlystartupModeandtaskNotificationLoopdiffer. If the production runtime options change later, this copy can silently drift. Extract a builder inworker.tsthat accepts those two values and use it in both places.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/app/developmentWorker.ts` around lines 43 - 72, Extract the shared dashboard worker runtime construction from createRuntime into a builder in worker.ts, parameterized by startupMode and taskNotificationLoop. Update both the production worker and developmentWorker createRuntime paths to call this builder while preserving their existing values for those two options and all other runtime configuration.greenfield/src/worker/logs/developmentLogMaintenance.ts (1)
23-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winState the platform requirement in the error message.
runtimeOwnerIdthrows on any non-Linux host. The message "Development log maintenance is unavailable" does not name the cause. A developer on macOS or Windows sees a worker startup failure with no actionable detail. Name the Linux requirement in the message.♻️ Proposed change
function runtimeOwnerId(): number { if (process.platform !== "linux" || typeof process.getuid !== "function") { - throw new Error("Development log maintenance is unavailable"); + throw new Error( + "Development log maintenance requires a Linux host with process.getuid" + ); } return process.getuid(); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/worker/logs/developmentLogMaintenance.ts` around lines 23 - 28, Update the error thrown by runtimeOwnerId to explicitly state that development log maintenance requires Linux, while preserving the existing platform and getuid checks.greenfield/scripts/development/developmentProxy.ts (3)
193-206: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd upstream failure handling for the HTTP proxy.
fetchrejects when the development web process is not listening. The rejection escapesproxyDevelopmentHttpand reaches Bun's default error path. The remote proxy handles the same condition and returns 502 (greenfield/scripts/development/developmentRemoteProxy.tslines 169-171). Align both proxies so a restarting backend produces a deterministic response.♻️ Proposed change
- const upstream = await fetch(target, { - body: request.body, - decompress: false, - duplex: "half", - headers, - method: request.method, - redirect: "manual", - signal: request.signal, - }); + let upstream: Response; + try { + upstream = await fetch(target, { + body: request.body, + decompress: false, + duplex: "half", + headers, + method: request.method, + redirect: "manual", + signal: request.signal, + }); + } catch { + return new Response("Development backend unavailable", { status: 502 }); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentProxy.ts` around lines 193 - 206, Update proxyDevelopmentHttp around the upstream fetch to catch fetch rejections and return an HTTP 502 response, matching the failure behavior of the remote proxy. Preserve the existing successful upstream response construction and request options unchanged.
499-504: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueGuard the backend socket construction.
The
WebSocketconstructor can throw for an unusable URL. The throw would escape the Bunopencallback. The remote proxy wraps the same call and closes the relay instead (greenfield/scripts/development/developmentRemoteProxy.tslines 491-500). Apply the same guard here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentProxy.ts` around lines 499 - 504, Wrap the backend WebSocket construction in the development proxy’s open callback with the same try/catch behavior used by the remote proxy, covering the `new WebSocket(...)` call and assignment to `socket.data.backend`. When construction throws for an unusable backend URL, close the relay socket instead of allowing the exception to escape.
250-272: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueReturn
undefinedafter a successful upgrade.Bun ignores the returned
Responseafter a successful upgrade, so the current204does not change client behavior. Useundefinedfor consistency with Bun's pattern anddevelopmentRemoteProxy.ts; update the return types ingreenfield/scripts/developmentFrontend.tsaccordingly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentProxy.ts` around lines 250 - 272, The WebSocket upgrade handler currently returns a 204 Response after success; update the upgrade flow in developmentProxy.ts to return undefined when server.upgrade succeeds while preserving the 400 failure response. Adjust the corresponding return types and callers in developmentFrontend.ts to accept the undefined success result, matching developmentRemoteProxy.ts.greenfield/scripts/developmentFrontend.ts (1)
41-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the duplicated backend path test in
fetch.
routesalready maps/api,/api/*,/trpc,/trpc/*, and/*. The/*entry matches every remaining path, so thefetchhandler is not reachable. The inline path test also duplicates the exportedisDevelopmentBackendPathhelper ingreenfield/scripts/development/developmentProxy.tslines 111-118. Keep one source for this rule.♻️ Proposed change
const frontend = Bun.serve<DevelopmentProxySocketData>({ development: { console: true, hmr: configuration.hotReload }, - fetch(request, bunServer) { - const pathname = new URL(request.url).pathname; - if ( - pathname === "/api" || - pathname.startsWith("/api/") || - pathname === "/trpc" || - pathname.startsWith("/trpc/") - ) { - return backendRequest(request, bunServer); - } - return new Response("Not found", { status: 404 }); - }, + fetch: (request, bunServer) => + isDevelopmentBackendPath(new URL(request.url).pathname) + ? backendRequest(request, bunServer) + : new Response("Not found", { status: 404 }), hostname: configuration.host,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/developmentFrontend.ts` around lines 41 - 61, Remove the custom fetch handler path checks and rely on the existing routes mapping, including the dashboard fallback. Keep backend-path matching defined by the routes configuration and the shared isDevelopmentBackendPath helper rather than duplicating it inline.greenfield/scripts/development/developmentProxy.test.ts (1)
116-191: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the WebSocket upgrade validation.
proxyDevelopmentWebSocketenforces the method, the exact terminal path, an empty query, the Origin match, and the two-value subprotocol list. These are the security-relevant branches of the proxy, and no test exercises them. Add cases that assert a 400 response for a wrong Origin, a non-terminal path, and a missing or malformed connection token.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentProxy.test.ts` around lines 116 - 191, Add tests covering proxyDevelopmentWebSocket upgrade validation: assert a 400 response for a mismatched Origin, a non-terminal request path, and missing or malformed connection-token/subprotocol input. Use the existing upgrade request and response helpers or fixtures, and preserve valid requests that satisfy the exact terminal path, empty query, matching Origin, and two-value subprotocol requirements.greenfield/scripts/development/developmentTailscaleLock.test.ts (1)
5-6: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winTwo suites derive the same host-local Tailscale lock port. Both files compute
40_000 + (process.pid % 20_000). The lock is host-local and keyed only by the port, so the two suites contend for one lock path when they run in the same process or concurrently on one host.
greenfield/scripts/development/developmentTailscaleLock.test.ts#L5-L6: apply a distinct offset, for example40_000 + ((process.pid + 1) % 20_000).greenfield/scripts/development/developmentTailscale.test.ts#L150-L151: keep the current derivation, or move both formulas into one shared helper that returns a unique port per suite.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentTailscaleLock.test.ts` around lines 5 - 6, Use distinct host-local Tailscale lock ports in the two suites: update developmentTailscaleLock.test.ts lines 5-6 to apply a separate process-based offset, while developmentTailscale.test.ts lines 150-151 requires no direct change and should retain its current derivation. Keep the existing test behavior otherwise unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@greenfield/scripts/development/developmentFrontend.test.ts`:
- Around line 5-26: Update reserveLoopbackPorts and the frontend spawn flow so
selected ports cannot be released before the child binds them; prefer binding
the frontend to port 0 and reading its assigned port from startup output, or
retrying the spawn when binding fails. Preserve the existing port-count behavior
and ensure the test uses the successfully bound ports.
In `@greenfield/scripts/development/developmentProxy.ts`:
- Around line 335-346: Update enqueueBrowserMessage and enqueueBackendMessage to
enforce developmentRemoteProxyQueuedMessageMaximum before appending, in addition
to the existing byte-based guard. Reject or close the proxy socket using the
established backpressure behavior when the message-count limit is reached,
including for zero-byte messages, while preserving the current byte accounting
and queue updates for accepted messages.
In `@greenfield/scripts/development/developmentRuntime.ts`:
- Around line 59-81: Make readSourceCommit injectable through
DevelopmentRuntimeDependencies by adding a commit-resolver dependency defaulting
to readSourceCommit, then use dependencies at both commit-resolution call sites
in runDevelopmentStack (developmentRuntime.ts lines 266 and 299). Update
developmentRuntime.test.ts lines 82-96 to provide a stub resolver returning a
fixed 40-character hexadecimal commit; no direct change is needed elsewhere.
In `@greenfield/scripts/development/developmentTailscaleLock.ts`:
- Around line 154-170: Update the mismatch branch around the first-output
validation to call stopLockHolder(child) before awaiting child.exited and
reading stderr. Preserve the normal flock conflict behavior, including exit code
1 when the child has already exited, and then construct the existing error
messages from the collected exit status and stderr.
In `@greenfield/scripts/developmentStack.ts`:
- Around line 56-61: Update the message construction in the --reset-database
branch to report “Removed” when resetDevelopmentDatabase returns true and a
non-destructive message indicating no database existed when it returns false;
preserve the existing config.databasePath output and return behavior.
In `@greenfield/src/worker/logs/developmentLogMaintenance.test.ts`:
- Around line 24-37: Update the test “never advertises fixed host policies” to
assert the exact expected policy array, including “docker-managed”, instead of
relying on policies.every(...). Ensure availablePolicies can resolve that policy
by deriving the layout from an existing temporary state directory when the
managed status lookup requires one; keep the fixed-policy failure and message
assertions unchanged.
---
Nitpick comments:
In `@greenfield/scripts/development/developmentProcessGuard.ts`:
- Around line 7-17: Update guardedDevelopmentChildCommand to apply the same
validation as guardedDevelopmentPrivilegedCommand: reject an empty command,
reject a relative executable, and reject an invalid parentProcessId before
checking dependencies or generating the command. Preserve the privileged
variant’s validation behavior and error semantics.
In `@greenfield/scripts/development/developmentProxy.test.ts`:
- Around line 116-191: Add tests covering proxyDevelopmentWebSocket upgrade
validation: assert a 400 response for a mismatched Origin, a non-terminal
request path, and missing or malformed connection-token/subprotocol input. Use
the existing upgrade request and response helpers or fixtures, and preserve
valid requests that satisfy the exact terminal path, empty query, matching
Origin, and two-value subprotocol requirements.
In `@greenfield/scripts/development/developmentProxy.ts`:
- Around line 193-206: Update proxyDevelopmentHttp around the upstream fetch to
catch fetch rejections and return an HTTP 502 response, matching the failure
behavior of the remote proxy. Preserve the existing successful upstream response
construction and request options unchanged.
- Around line 499-504: Wrap the backend WebSocket construction in the
development proxy’s open callback with the same try/catch behavior used by the
remote proxy, covering the `new WebSocket(...)` call and assignment to
`socket.data.backend`. When construction throws for an unusable backend URL,
close the relay socket instead of allowing the exception to escape.
- Around line 250-272: The WebSocket upgrade handler currently returns a 204
Response after success; update the upgrade flow in developmentProxy.ts to return
undefined when server.upgrade succeeds while preserving the 400 failure
response. Adjust the corresponding return types and callers in
developmentFrontend.ts to accept the undefined success result, matching
developmentRemoteProxy.ts.
In `@greenfield/scripts/development/developmentRuntime.test.ts`:
- Around line 39-42: Update the fake child’s kill behavior in the development
runtime tests so it records SIGTERM without resolving exited, allowing
settleChildren’s timeout and SIGKILL escalation path to execute. Provide a
test-controlled release that resolves exited after the graceful path is
explicitly triggered, while preserving immediate exit behavior for SIGKILL.
In `@greenfield/scripts/development/developmentRuntime.ts`:
- Around line 199-212: Align the unrequested child-exit reporting in the
development runtime with the value returned by the final return statement:
update the process.stderr message around exited and the exited.code || 1
fallback so a clean child exit does not log code 0 while returning 1. Preserve
the existing stopRequested early return and abnormal-exit behavior.
In `@greenfield/scripts/development/developmentStateLease.ts`:
- Around line 187-196: Update readLeaseMarker to include the offending fileName
in the thrown “Development state lease is invalid” error message, preserving the
existing validation and error behavior so operators can identify and remove the
damaged lease file.
In `@greenfield/scripts/development/developmentTailscaleLock.test.ts`:
- Around line 5-6: Use distinct host-local Tailscale lock ports in the two
suites: update developmentTailscaleLock.test.ts lines 5-6 to apply a separate
process-based offset, while developmentTailscale.test.ts lines 150-151 requires
no direct change and should retain its current derivation. Keep the existing
test behavior otherwise unchanged.
In `@greenfield/scripts/developmentFrontend.ts`:
- Around line 41-61: Remove the custom fetch handler path checks and rely on the
existing routes mapping, including the dashboard fallback. Keep backend-path
matching defined by the routes configuration and the shared
isDevelopmentBackendPath helper rather than duplicating it inline.
In `@greenfield/src/app/developmentWeb.ts`:
- Around line 17-22: Extract the duplicated developmentSourceCommit validation
into one shared helper that accepts the process label and preserves the existing
argument-count, 40-character hexadecimal validation, and returned commit
behavior. In greenfield/src/app/developmentWeb.ts:17-22, remove the local
definition and use the helper with the "web" label; make the corresponding
replacement in greenfield/src/app/developmentWorker.ts:19-24 using the "worker"
label.
- Around line 67-74: Update the import.meta.main startup handlers in
greenfield/src/app/developmentWeb.ts#L67-L74 and
greenfield/src/app/developmentWorker.ts#L84-L91: bind the caught error and
append its message to the existing development web or worker startup failure
stderr output, preserving the current exitCode behavior.
In `@greenfield/src/app/developmentWorker.ts`:
- Around line 43-72: Extract the shared dashboard worker runtime construction
from createRuntime into a builder in worker.ts, parameterized by startupMode and
taskNotificationLoop. Update both the production worker and developmentWorker
createRuntime paths to call this builder while preserving their existing values
for those two options and all other runtime configuration.
In `@greenfield/src/worker/developmentTaskNotifications.test.ts`:
- Around line 7-12: Update the test around developmentTaskNotificationLoop to
capture the result returned by Fiber.interrupt(fiber) and assert that its exit
represents interruption, rather than merely checking the fiber is defined.
Confirm the pinned Effect beta’s Fiber.interrupt return shape and use the
corresponding interruption assertion.
In `@greenfield/src/worker/logs/developmentLogMaintenance.ts`:
- Around line 23-28: Update the error thrown by runtimeOwnerId to explicitly
state that development log maintenance requires Linux, while preserving the
existing platform and getuid checks.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6cfe8897-1584-4ee5-88ba-a9fd8adc9711
📒 Files selected for processing (42)
greenfield/.oxlintrc.jsongreenfield/README.mdgreenfield/docs/development/local-development.mdgreenfield/package.jsongreenfield/scripts/development/developmentEnvironment.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/development/developmentFrontendConfig.test.tsgreenfield/scripts/development/developmentFrontendConfig.tsgreenfield/scripts/development/developmentProcessGuard.tsgreenfield/scripts/development/developmentProxy.test.tsgreenfield/scripts/development/developmentProxy.tsgreenfield/scripts/development/developmentRemoteProxy.test.tsgreenfield/scripts/development/developmentRemoteProxy.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentRuntime.tsgreenfield/scripts/development/developmentStackConfig.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentState.tsgreenfield/scripts/development/developmentStateLease.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/scripts/development/developmentTailscale.tsgreenfield/scripts/development/developmentTailscaleLock.test.tsgreenfield/scripts/development/developmentTailscaleLock.tsgreenfield/scripts/developmentFrontend.tsgreenfield/scripts/developmentStack.tsgreenfield/scripts/sourceBoundaries/boundaryConfiguration.tsgreenfield/scripts/sourceBoundaries/externalAuthorityPolicy.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/scripts/sourceBoundaries/policy.tsgreenfield/scripts/sourceBoundaries/sourceTopologyPolicy.tsgreenfield/src/app/dashboardServer.tsgreenfield/src/app/developmentWeb.tsgreenfield/src/app/developmentWorker.tsgreenfield/src/app/worker.tsgreenfield/src/browser/main.tsxgreenfield/src/server/platform/release/developmentRuntimeRelease.test.tsgreenfield/src/server/platform/release/developmentRuntimeRelease.tsgreenfield/src/worker/developmentTaskNotifications.test.tsgreenfield/src/worker/developmentTaskNotifications.tsgreenfield/src/worker/logs/developmentLogMaintenance.test.tsgreenfield/src/worker/logs/developmentLogMaintenance.tsgreenfield/tsconfig.browser.json
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze JavaScript and TypeScript
- GitHub Check: storybook
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-08-07T17:05:36.638Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 397
File: greenfield/src/server/domains/agents/service.test.ts:225-239
Timestamp: 2026-08-07T17:05:36.638Z
Learning: In Bun test files, write rejection assertions as `expect(promise).rejects...` without `await`. The repository's installed matcher types return `void`, and ESLint's `typescript(await-thenable)` rule rejects awaiting these matcher assertions.
Applied to files:
greenfield/src/worker/developmentTaskNotifications.test.tsgreenfield/src/server/platform/release/developmentRuntimeRelease.test.tsgreenfield/src/worker/logs/developmentLogMaintenance.test.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentFrontendConfig.test.tsgreenfield/scripts/development/developmentTailscaleLock.test.tsgreenfield/scripts/development/developmentProxy.test.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/development/developmentRemoteProxy.test.ts
📚 Learning: 2026-08-07T18:47:49.639Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 398
File: greenfield/src/server/domains/monitoring/catalogErrors.ts:3-3
Timestamp: 2026-08-07T18:47:49.639Z
Learning: In the greenfield TypeScript application, use the pinned Effect version 4.0.0-beta.104 API. Preserve `Schema.Literals` for readonly literal tuples and arrays, and do not replace it with variadic `Schema.Literal(...)` unless the replacement has been validated against the pinned Effect version.
Applied to files:
greenfield/src/worker/developmentTaskNotifications.test.tsgreenfield/src/worker/developmentTaskNotifications.tsgreenfield/src/server/platform/release/developmentRuntimeRelease.test.tsgreenfield/src/app/worker.tsgreenfield/scripts/development/developmentFrontendConfig.tsgreenfield/src/worker/logs/developmentLogMaintenance.test.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentFrontendConfig.test.tsgreenfield/scripts/development/developmentTailscaleLock.test.tsgreenfield/src/app/dashboardServer.tsgreenfield/scripts/sourceBoundaries/externalAuthorityPolicy.tsgreenfield/scripts/development/developmentProxy.test.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/scripts/sourceBoundaries/boundaryConfiguration.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/src/server/platform/release/developmentRuntimeRelease.tsgreenfield/scripts/sourceBoundaries/policy.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentStackConfig.tsgreenfield/src/app/developmentWeb.tsgreenfield/scripts/development/developmentProcessGuard.tsgreenfield/src/app/developmentWorker.tsgreenfield/scripts/development/developmentEnvironment.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/developmentStack.tsgreenfield/scripts/development/developmentStateLease.tsgreenfield/scripts/sourceBoundaries/sourceTopologyPolicy.tsgreenfield/scripts/developmentFrontend.tsgreenfield/src/worker/logs/developmentLogMaintenance.tsgreenfield/scripts/development/developmentTailscaleLock.tsgreenfield/scripts/development/developmentRemoteProxy.test.tsgreenfield/scripts/development/developmentRemoteProxy.tsgreenfield/scripts/development/developmentTailscale.tsgreenfield/scripts/development/developmentState.tsgreenfield/scripts/development/developmentRuntime.tsgreenfield/scripts/development/developmentProxy.ts
🪛 GitHub Check: dashboard-checks
greenfield/scripts/development/developmentRuntime.test.ts
[failure] 94-94: error: expect(received).toContain(expected)
Expected to contain: "simulated worker spawn failure"
Received: "Could not resolve development source commit: git failed"
at <anonymous> (/home/runner/work/_temp/mira-dashboard-greenfield/scripts/development/developmentRuntime.test.ts:94:37)
🪛 OpenGrep (1.26.0)
greenfield/scripts/development/developmentFrontendConfig.ts
[ERROR] 40-40: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
greenfield/scripts/development/developmentFrontend.test.ts
[ERROR] 99-99: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
greenfield/scripts/development/developmentStateLease.ts
[ERROR] 130-130: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🔇 Additional comments (59)
greenfield/.oxlintrc.json (1)
466-485: LGTM!greenfield/README.md (1)
43-43: LGTM!greenfield/scripts/sourceBoundaries/boundaryConfiguration.ts (1)
73-73: LGTM!greenfield/scripts/sourceBoundaries/externalAuthorityPolicy.ts (1)
9-11: LGTM!greenfield/scripts/sourceBoundaries/policy.test.ts (1)
100-105: LGTM!Also applies to: 458-465
greenfield/scripts/sourceBoundaries/policy.ts (1)
12-12: LGTM!Also applies to: 329-334
greenfield/scripts/sourceBoundaries/sourceTopologyPolicy.ts (1)
26-36: LGTM!Also applies to: 64-70, 87-105, 210-210
greenfield/tsconfig.browser.json (1)
11-11: LGTM!greenfield/package.json (1)
7-7: 🔒 Security & PrivacyKeep
rajohan/prdfor the trusted development flow. Development intentionally connects to the live OpenClaw Gateway. Isolated Dashboard state and blocked production operations define the documented safety boundary.> Likely an incorrect or invalid review comment.greenfield/scripts/development/developmentStackConfig.ts (1)
1-207: LGTM!greenfield/scripts/development/developmentEnvironment.ts (1)
1-144: LGTM!greenfield/scripts/development/developmentState.ts (1)
1-544: LGTM!greenfield/scripts/development/developmentStateLease.ts (1)
254-291: LGTM!greenfield/scripts/development/developmentState.test.ts (2)
46-247: LGTM!Also applies to: 287-311
278-280: 🗄️ Data Integrity & IntegrationKeep the assertion; the producer emits the asserted wording.
> Likely an incorrect or invalid review comment.greenfield/scripts/development/developmentProcessGuard.ts (1)
39-121: LGTM!greenfield/src/server/platform/release/developmentRuntimeRelease.ts (2)
22-46: LGTM!Also applies to: 54-72
47-53: 🗄️ Data Integrity & IntegrationKeep the placeholder migration entry. Startup loads the canonical
migrationManifestand does not consumerelease.manifest.migrations.> Likely an incorrect or invalid review comment.greenfield/scripts/development/developmentRuntime.ts (1)
83-198: LGTM!Also applies to: 214-324
greenfield/scripts/developmentStack.ts (1)
1-55: LGTM!Also applies to: 63-80
greenfield/scripts/development/developmentRuntime.test.ts (1)
102-143: LGTM!greenfield/scripts/development/developmentFrontendConfig.ts (2)
18-33: LGTM!Also applies to: 35-52, 54-79, 81-86
93-133: LGTM!greenfield/scripts/development/developmentFrontendConfig.test.ts (1)
6-15: LGTM!Also applies to: 17-35, 37-59
greenfield/src/server/platform/release/developmentRuntimeRelease.test.ts (1)
7-17: LGTM!Also applies to: 19-26
greenfield/src/app/dashboardServer.ts (1)
1160-1169: LGTM!greenfield/src/app/worker.ts (1)
210-219: LGTM!greenfield/src/app/developmentWeb.ts (1)
29-65: LGTM!greenfield/src/worker/logs/developmentLogMaintenance.ts (1)
30-48: LGTM!Also applies to: 56-98, 100-103, 110-119
greenfield/src/worker/logs/developmentLogMaintenance.test.ts (1)
11-22: LGTM!greenfield/src/worker/developmentTaskNotifications.ts (1)
8-10: 🩺 Stability & AvailabilityKeep
Effect.neveras a value. Effect4.0.0-beta.106exportsneverasEffect<never>, soreturn Effect.neveris correct.> Likely an incorrect or invalid review comment.greenfield/scripts/development/developmentProxy.ts (4)
10-104: LGTM!
283-333: LGTM!
392-445: LGTM!
452-498: LGTM!Also applies to: 505-543
greenfield/scripts/development/developmentProxy.test.ts (1)
1-115: LGTM!Also applies to: 192-192
greenfield/scripts/development/developmentRemoteProxy.ts (6)
58-127: LGTM!
129-172: LGTM!
174-248: LGTM!
250-448: LGTM!
454-538: LGTM!
545-568: LGTM!greenfield/scripts/development/developmentRemoteProxy.test.ts (1)
1-451: LGTM!greenfield/scripts/developmentFrontend.ts (2)
64-90: LGTM!
92-111: LGTM!greenfield/scripts/development/developmentFrontend.test.ts (1)
28-115: LGTM!greenfield/docs/development/local-development.md (2)
1-43: LGTM!Also applies to: 48-126
44-47: 📐 Maintainability & Code QualityBoth Bun documentation links resolve successfully.
greenfield/scripts/development/developmentTailscaleLock.ts (3)
26-64: LGTM!
66-99: LGTM!
172-180: LGTM!greenfield/scripts/development/developmentTailscaleLock.test.ts (1)
7-22: LGTM!greenfield/scripts/development/developmentTailscale.ts (5)
49-128: LGTM!
135-218: LGTM!
220-337: LGTM!
339-403: LGTM!
405-467: LGTM!greenfield/scripts/development/developmentTailscale.test.ts (1)
1-149: LGTM!Also applies to: 152-226
greenfield/src/browser/main.tsx (1)
15-18: 🩺 Stability & AvailabilityDo not add a runtime guard for
import.meta.hot.data. Bun rewrites direct HMR data access in production, soimport.meta.hotis not dereferenced at runtime.> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2bc2e90c11
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@greenfield/src/shared/developmentProcessSupport.ts`:
- Around line 31-46: Update hasNoUnicodeControlOrFormat to reject Unicode
separator categories Zl and Zp in addition to Cc and Cf, ensuring U+2028 and
U+2029 are invalid startup failure details. Add focused tests covering both
separators while preserving acceptance of permitted characters.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2b3df886-47e8-4502-bbc8-4caf2b10e576
📒 Files selected for processing (30)
greenfield/.bun-browser-test-timings.jsongreenfield/.bun-test-timings.jsongreenfield/docs/development/local-development.mdgreenfield/scripts/development/developmentEnvironment.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/development/developmentFrontendConfig.tsgreenfield/scripts/development/developmentPrivateFile.test.tsgreenfield/scripts/development/developmentPrivateFile.tsgreenfield/scripts/development/developmentProcessGuard.tsgreenfield/scripts/development/developmentProxy.test.tsgreenfield/scripts/development/developmentProxy.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentRuntime.tsgreenfield/scripts/development/developmentStackConfig.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentState.tsgreenfield/scripts/development/developmentStateLease.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/scripts/development/developmentTailscale.tsgreenfield/scripts/development/developmentTailscaleLock.test.tsgreenfield/scripts/development/developmentTailscaleLock.tsgreenfield/scripts/developmentFrontend.tsgreenfield/scripts/developmentStack.tsgreenfield/src/app/developmentWeb.tsgreenfield/src/app/developmentWorker.tsgreenfield/src/shared/developmentProcessSupport.test.tsgreenfield/src/shared/developmentProcessSupport.tsgreenfield/src/worker/developmentTaskNotifications.test.tsgreenfield/src/worker/logs/developmentLogMaintenance.test.tsgreenfield/src/worker/logs/developmentLogMaintenance.ts
🚧 Files skipped from review as they are similar to previous changes (17)
- greenfield/scripts/development/developmentTailscaleLock.test.ts
- greenfield/src/worker/developmentTaskNotifications.test.ts
- greenfield/scripts/development/developmentEnvironment.ts
- greenfield/src/worker/logs/developmentLogMaintenance.test.ts
- greenfield/scripts/development/developmentTailscale.test.ts
- greenfield/scripts/development/developmentProcessGuard.ts
- greenfield/scripts/developmentStack.ts
- greenfield/src/worker/logs/developmentLogMaintenance.ts
- greenfield/src/app/developmentWeb.ts
- greenfield/scripts/development/developmentStateLease.ts
- greenfield/scripts/development/developmentFrontendConfig.ts
- greenfield/scripts/developmentFrontend.ts
- greenfield/scripts/development/developmentStackConfig.ts
- greenfield/scripts/development/developmentState.ts
- greenfield/scripts/development/developmentRuntime.ts
- greenfield/src/app/developmentWorker.ts
- greenfield/scripts/development/developmentTailscale.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: dashboard-checks
- GitHub Check: Analyze JavaScript and TypeScript
- GitHub Check: storybook
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-08-07T17:05:36.638Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 397
File: greenfield/src/server/domains/agents/service.test.ts:225-239
Timestamp: 2026-08-07T17:05:36.638Z
Learning: In Bun test files, write rejection assertions as `expect(promise).rejects...` without `await`. The repository's installed matcher types return `void`, and ESLint's `typescript(await-thenable)` rule rejects awaiting these matcher assertions.
Applied to files:
greenfield/src/shared/developmentProcessSupport.test.tsgreenfield/scripts/development/developmentPrivateFile.test.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentProxy.test.ts
📚 Learning: 2026-08-07T18:47:49.639Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 398
File: greenfield/src/server/domains/monitoring/catalogErrors.ts:3-3
Timestamp: 2026-08-07T18:47:49.639Z
Learning: In the greenfield TypeScript application, use the pinned Effect version 4.0.0-beta.104 API. Preserve `Schema.Literals` for readonly literal tuples and arrays, and do not replace it with variadic `Schema.Literal(...)` unless the replacement has been validated against the pinned Effect version.
Applied to files:
greenfield/src/shared/developmentProcessSupport.test.tsgreenfield/scripts/development/developmentPrivateFile.test.tsgreenfield/scripts/development/developmentPrivateFile.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentFrontend.test.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/src/shared/developmentProcessSupport.tsgreenfield/scripts/development/developmentProxy.tsgreenfield/scripts/development/developmentTailscaleLock.tsgreenfield/scripts/development/developmentProxy.test.ts
🔇 Additional comments (13)
greenfield/scripts/development/developmentPrivateFile.ts (1)
26-78: LGTM!greenfield/scripts/development/developmentPrivateFile.test.ts (1)
12-59: LGTM!Also applies to: 61-102
greenfield/scripts/development/developmentState.test.ts (1)
212-245: LGTM!greenfield/src/shared/developmentProcessSupport.ts (1)
14-29: LGTM!greenfield/src/shared/developmentProcessSupport.test.ts (1)
10-39: LGTM!greenfield/scripts/development/developmentFrontend.test.ts (1)
65-119: LGTM!Also applies to: 121-129
greenfield/scripts/development/developmentRuntime.test.ts (1)
1-6: LGTM!Also applies to: 15-56, 82-114, 126-126, 163-163, 190-233
greenfield/docs/development/local-development.md (1)
82-93: LGTM!greenfield/.bun-browser-test-timings.json (1)
3-159: LGTM!greenfield/.bun-test-timings.json (1)
3-381: LGTM!greenfield/scripts/development/developmentProxy.ts (1)
13-15: LGTM!Also applies to: 194-207, 240-277, 345-349, 437-439, 510-520
greenfield/scripts/development/developmentProxy.test.ts (1)
3-3: LGTM!Also applies to: 15-20, 43-48, 125-141, 143-212, 281-318
greenfield/scripts/development/developmentTailscaleLock.ts (1)
20-23: LGTM!Also applies to: 52-54, 112-122, 169-169
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8edcbe64d6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@greenfield/scripts/development/developmentStateAcquisitionLock.ts`:
- Around line 21-38: Update the readiness-read logic surrounding reader.read()
to accumulate decoded child-process output across fragmented chunks until the
complete expected readiness signal, such as "LOCKED\n", is available before
validation. Preserve timeout cleanup and reader.releaseLock() behavior, and add
a regression test covering readiness output split across multiple writes.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 755d0ab7-1b9f-4532-9839-75bf7a8679ea
⛔ Files ignored due to path filters (108)
greenfield/docs/generated/schemas/accountSecurity.beginTotpEnrollment.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/accountSecurity.beginTotpEnrollment.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/accountSecurity.confirmTotpEnrollment.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/accountSecurity.confirmWebAuthnEnrollment.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/accountSecurity.confirmWebAuthnEnrollment.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/accountSecurity.summary.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.getConfiguration.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.getStatus.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.listStatuses.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.listTaskHistory.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.updateMetadata.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/agents.updateMetadata.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createCredential.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createCredential.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createPrincipal.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createPrincipal.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.disablePrincipal.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.listCredentials.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.listPrincipals.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.replaceCapabilities.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.revokeCredential.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.rotateCredential.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.rotateCredential.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getEntry.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getHeartbeat.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getStatus.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.refreshEntry.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.abort.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.abort.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.companionAsk.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.companionReset.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.companionState.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.getMessage.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.getMessage.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.history.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.history.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.listModels.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.prepareAttachmentTicket.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.runtime.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.runtime.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.send.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.send.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.updateSessionSettings.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/chat.updateSessionSettings.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.getWriteStatus.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.listRoots.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.prepareContent.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.prepareReveal.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.prepareUpload.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/files.upload.accepted.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.compact.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.compact.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.delete.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.delete.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.reset.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/gatewaySessions.reset.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/jobs.cancelRun.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/jobs.getRun.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/jobs.listRuns.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/logs.listSources.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/logs.maintenanceStatus.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/monitoring.submitCompleteSnapshot.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/notifications.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/notifications.markRead.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/notifications.upsert.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/notifications.upsert.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.delete.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.delete.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.get.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.list.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.listRuns.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.listRuns.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.run.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.run.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.setEnabled.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.setEnabled.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.update.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawCron.update.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.cancel.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.cancel.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.get.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.list.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/openClawTasks.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/reports.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/reports.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/reports.upsert.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/reports.upsert.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.listRuns.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.run.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.update.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.update.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.assign.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.create.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.create.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.list.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.move.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.update.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/tasks.update.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/terminal.getRuntime.output.schema.jsonis excluded by!**/generated/**and included by**/*
📒 Files selected for processing (13)
greenfield/.bun-test-timings.jsongreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentStateAcquisitionLock.tsgreenfield/scripts/development/developmentStateLease.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/scripts/development/developmentTailscale.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/scripts/sourceBoundaries/sourceTopologyPolicy.tsgreenfield/src/app/developmentProcesses.test.tsgreenfield/src/shared/developmentProcessSupport.test.tsgreenfield/src/shared/validation.test.tsgreenfield/src/shared/validation.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- greenfield/src/shared/developmentProcessSupport.test.ts
- greenfield/.bun-test-timings.json
- greenfield/scripts/development/developmentState.test.ts
- greenfield/scripts/sourceBoundaries/sourceTopologyPolicy.ts
- greenfield/scripts/development/developmentStateLease.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
- GitHub Check: frontend-checks
- GitHub Check: dashboard-checks
- GitHub Check: storybook
- GitHub Check: Analyze JavaScript and TypeScript
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-08-07T17:05:36.638Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 397
File: greenfield/src/server/domains/agents/service.test.ts:225-239
Timestamp: 2026-08-07T17:05:36.638Z
Learning: In Bun test files, write rejection assertions as `expect(promise).rejects...` without `await`. The repository's installed matcher types return `void`, and ESLint's `typescript(await-thenable)` rule rejects awaiting these matcher assertions.
Applied to files:
greenfield/src/app/developmentProcesses.test.tsgreenfield/src/shared/validation.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/scripts/development/developmentTailscale.test.ts
📚 Learning: 2026-08-07T18:47:49.639Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 398
File: greenfield/src/server/domains/monitoring/catalogErrors.ts:3-3
Timestamp: 2026-08-07T18:47:49.639Z
Learning: In the greenfield TypeScript application, use the pinned Effect version 4.0.0-beta.104 API. Preserve `Schema.Literals` for readonly literal tuples and arrays, and do not replace it with variadic `Schema.Literal(...)` unless the replacement has been validated against the pinned Effect version.
Applied to files:
greenfield/src/app/developmentProcesses.test.tsgreenfield/src/shared/validation.tsgreenfield/src/shared/validation.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/scripts/development/developmentTailscale.test.tsgreenfield/scripts/development/developmentStateAcquisitionLock.tsgreenfield/scripts/development/developmentTailscale.ts
🔇 Additional comments (8)
greenfield/scripts/documentation/jsonSchema.test.ts (1)
562-562: LGTM!Also applies to: 574-574, 587-587
greenfield/scripts/documentation/jsonSchema.ts (1)
242-254: LGTM!greenfield/src/app/developmentProcesses.test.ts (1)
1-21: LGTM!greenfield/src/shared/validation.test.ts (1)
99-100: LGTM!greenfield/src/shared/validation.ts (1)
107-112: LGTM!greenfield/scripts/development/developmentTailscale.test.ts (1)
8-8: LGTM!Also applies to: 31-67
greenfield/scripts/development/developmentTailscale.ts (2)
53-97: LGTM!
99-156: LGTM!
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 558777623e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40e2edba21
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
greenfield/scripts/development/developmentFileRoots.ts (1)
483-559: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPreserve the failure cause in the final throw.
The
catchat line 555 discards the original error. The function then throwsinvalidDevelopmentFileRoot()with nocause. Every inner failure already carries a chainedcause, so this is the only place where the diagnostic chain is lost. Preservation costs one variable and keeps root-cause data for a security-sensitive preparation path.♻️ Proposed change to retain the cause
const files: HeldReviewedFile[] = []; - let failed = false; + let failure: unknown; + let failed = false; try { @@ await revalidateVisibleDirectory(stateRoot, userId, stateDevice); - } catch { - failed = true; + } catch (error) { + failed = true; + failure = error; } const closed = await closeHandles(resources); - if (failed || !closed) throw invalidDevelopmentFileRoot(); + if (failed || !closed) throw invalidDevelopmentFileRoot(failure); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentFileRoots.ts` around lines 483 - 559, Update the try/catch flow around the directory and file preparation operations to capture the caught error in a variable, then pass it as the cause when throwing invalidDevelopmentFileRoot(). Preserve the existing failed flag and closeHandles(resources) handling while retaining the original diagnostic chain.greenfield/scripts/development/developmentStateAcquisitionLock.test.ts (1)
5-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd negative-path coverage for the readiness parser.
This test covers the fragmented success path only. Two rejection branches in
waitForDevelopmentStateLockReadinessstay untested: a stream that closes before the full signal (chunk.done === true), and output that does not prefix-matchLOCKED\n. Both branches protect lock acquisition. Each test costs a few lines.♻️ Proposed additional tests
test("rejects output that closes before the readiness signal", async () => { const encoder = new TextEncoder(); const stream = new ReadableStream<Uint8Array>({ start(controller) { controller.enqueue(encoder.encode("LOCK")); controller.close(); }, }); expect(waitForDevelopmentStateLockReadiness(stream)).rejects.toThrow( "Development state lease acquisition lock failed" ); }); test("rejects output that does not match the readiness signal", async () => { const encoder = new TextEncoder(); const stream = new ReadableStream<Uint8Array>({ start(controller) { controller.enqueue(encoder.encode("DENIED\n")); controller.close(); }, }); expect(waitForDevelopmentStateLockReadiness(stream)).rejects.toThrow( "Development state lease acquisition lock failed" ); });Based on learnings, the rejection assertions are written as
expect(promise).rejects...withoutawait, because the repository's installed matcher types returnvoidand ESLint'stypescript(await-thenable)rule rejects awaiting these matcher assertions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentStateAcquisitionLock.test.ts` around lines 5 - 17, Add negative-path tests alongside the fragmented success test for waitForDevelopmentStateLockReadiness: verify it rejects when the stream closes before completing LOCKED\n and when the output does not prefix-match the readiness signal. Assert the expected "Development state lease acquisition lock failed" message using the repository-compatible non-awaited rejects matcher pattern.Source: Learnings
greenfield/scripts/development/developmentState.test.ts (1)
82-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winGuard against a vacuous permission assertion.
writableManifestSegmentsfalls back to[]whenwebRoot.manifestis undefined. If that happens, line 86 compares[]to[]and the loop at lines 105-113 runs zero times. The permission,nlink, and ownership checks then assert nothing, and the test still passes. Add a non-empty assertion so a manifest shape change fails the test instead of silently removing coverage.♻️ Proposed guard
const writableManifestSegments = webRoot.manifest ?.filter(({ writable }) => writable) .map(({ segments }) => [...segments]) ?? []; + expect(writableManifestSegments.length).toBeGreaterThan(0); expect( workerRoot.replacementManifest?.map(({ segments }) => [...segments]) ).toEqual(writableManifestSegments);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/scripts/development/developmentState.test.ts` around lines 82 - 113, Add a non-empty assertion for writableManifestSegments before the equality and file-permission checks in the test, ensuring the manifest-derived file validation cannot pass vacuously when the manifest is missing or contains no writable entries. Keep the existing manifest comparison and per-file ownership, permission, link-count, and type assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@greenfield/scripts/development/developmentFileRoots.ts`:
- Around line 483-559: Update the try/catch flow around the directory and file
preparation operations to capture the caught error in a variable, then pass it
as the cause when throwing invalidDevelopmentFileRoot(). Preserve the existing
failed flag and closeHandles(resources) handling while retaining the original
diagnostic chain.
In `@greenfield/scripts/development/developmentState.test.ts`:
- Around line 82-113: Add a non-empty assertion for writableManifestSegments
before the equality and file-permission checks in the test, ensuring the
manifest-derived file validation cannot pass vacuously when the manifest is
missing or contains no writable entries. Keep the existing manifest comparison
and per-file ownership, permission, link-count, and type assertions unchanged.
In `@greenfield/scripts/development/developmentStateAcquisitionLock.test.ts`:
- Around line 5-17: Add negative-path tests alongside the fragmented success
test for waitForDevelopmentStateLockReadiness: verify it rejects when the stream
closes before completing LOCKED\n and when the output does not prefix-match the
readiness signal. Assert the expected "Development state lease acquisition lock
failed" message using the repository-compatible non-awaited rejects matcher
pattern.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9688a24a-a989-4409-b9e0-57cf3fd7f3ad
📒 Files selected for processing (22)
greenfield/.bun-test-timings.jsongreenfield/docs/development/local-development.mdgreenfield/migrations/20260804022252_dashboard-foundation/migration.sqlgreenfield/migrations/20260804022252_dashboard-foundation/snapshot.jsongreenfield/package.jsongreenfield/scripts/development/developmentFileRoots.test.tsgreenfield/scripts/development/developmentFileRoots.tsgreenfield/scripts/development/developmentRemoteProxy.test.tsgreenfield/scripts/development/developmentRemoteProxy.tsgreenfield/scripts/development/developmentRuntime.test.tsgreenfield/scripts/development/developmentRuntime.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentState.tsgreenfield/scripts/development/developmentStateAcquisitionLock.test.tsgreenfield/scripts/development/developmentStateAcquisitionLock.tsgreenfield/src/app/developmentProcesses.test.tsgreenfield/src/app/developmentWeb.tsgreenfield/src/server/database/migrations/securityIdentitySchema.automation.test.tsgreenfield/src/server/database/schema/checks.tsgreenfield/src/server/database/validation/automationPrincipals.test.tsgreenfield/src/server/database/validation/securityScalars.tsgreenfield/src/shared/databaseMigrationManifest.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- greenfield/.bun-test-timings.json
- greenfield/package.json
- greenfield/scripts/development/developmentRuntime.test.ts
- greenfield/docs/development/local-development.md
- greenfield/scripts/development/developmentRemoteProxy.test.ts
- greenfield/scripts/development/developmentState.ts
- greenfield/scripts/development/developmentRuntime.ts
- greenfield/scripts/development/developmentRemoteProxy.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-08-07T17:05:36.638Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 397
File: greenfield/src/server/domains/agents/service.test.ts:225-239
Timestamp: 2026-08-07T17:05:36.638Z
Learning: In Bun test files, write rejection assertions as `expect(promise).rejects...` without `await`. The repository's installed matcher types return `void`, and ESLint's `typescript(await-thenable)` rule rejects awaiting these matcher assertions.
Applied to files:
greenfield/src/server/database/validation/automationPrincipals.test.tsgreenfield/scripts/development/developmentStateAcquisitionLock.test.tsgreenfield/src/server/database/migrations/securityIdentitySchema.automation.test.tsgreenfield/src/app/developmentProcesses.test.tsgreenfield/scripts/development/developmentFileRoots.test.tsgreenfield/scripts/development/developmentState.test.ts
📚 Learning: 2026-08-07T18:47:49.639Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 398
File: greenfield/src/server/domains/monitoring/catalogErrors.ts:3-3
Timestamp: 2026-08-07T18:47:49.639Z
Learning: In the greenfield TypeScript application, use the pinned Effect version 4.0.0-beta.104 API. Preserve `Schema.Literals` for readonly literal tuples and arrays, and do not replace it with variadic `Schema.Literal(...)` unless the replacement has been validated against the pinned Effect version.
Applied to files:
greenfield/src/server/database/validation/automationPrincipals.test.tsgreenfield/scripts/development/developmentStateAcquisitionLock.test.tsgreenfield/src/shared/databaseMigrationManifest.tsgreenfield/src/server/database/migrations/securityIdentitySchema.automation.test.tsgreenfield/src/server/database/schema/checks.tsgreenfield/src/server/database/validation/securityScalars.tsgreenfield/src/app/developmentProcesses.test.tsgreenfield/scripts/development/developmentFileRoots.test.tsgreenfield/src/app/developmentWeb.tsgreenfield/scripts/development/developmentStateAcquisitionLock.tsgreenfield/scripts/development/developmentState.test.tsgreenfield/scripts/development/developmentFileRoots.ts
🔇 Additional comments (15)
greenfield/src/app/developmentProcesses.test.ts (2)
3-72: LGTM!
74-86: 📐 Maintainability & Code QualityKeep the current rejection assertions. These tests use
await rejectionError(...), notexpect(...).rejects; no matcher change is needed.> Likely an incorrect or invalid review comment.greenfield/src/app/developmentWeb.ts (1)
21-61: LGTM!Also applies to: 80-80
greenfield/src/server/database/migrations/securityIdentitySchema.automation.test.ts (1)
8-8: LGTM!Also applies to: 23-35
greenfield/src/server/database/schema/checks.ts (1)
6-6: LGTM!Also applies to: 59-67
greenfield/src/server/database/validation/automationPrincipals.test.ts (1)
55-56: LGTM!greenfield/src/server/database/validation/securityScalars.ts (1)
9-9: LGTM!Also applies to: 26-29
greenfield/migrations/20260804022252_dashboard-foundation/migration.sql (1)
128-128: LGTM!Also applies to: 155-155, 208-218, 242-248, 292-299, 452-452, 479-479, 547-554, 589-597, 634-634, 665-665, 914-914, 932-932, 987-987, 1004-1004, 1070-1073
greenfield/migrations/20260804022252_dashboard-foundation/snapshot.json (1)
6806-7292: LGTM!Also applies to: 7334-7430, 7562-7742, 7928-8078, 8120-8348
greenfield/src/shared/databaseMigrationManifest.ts (1)
16-18: LGTM!greenfield/scripts/development/developmentFileRoots.ts (2)
7-27: LGTM!Also applies to: 29-50, 70-157
159-193: LGTM!Also applies to: 195-276, 278-361, 363-457, 459-466
greenfield/scripts/development/developmentFileRoots.test.ts (1)
26-34: LGTM!Also applies to: 36-89, 91-155
greenfield/scripts/development/developmentState.test.ts (1)
3-3: LGTM!Also applies to: 16-17, 29-31, 119-150, 152-208, 210-241, 259-261, 288-288, 590-591, 600-600
greenfield/scripts/development/developmentStateAcquisitionLock.ts (1)
5-9: LGTM!Also applies to: 11-59, 120-120
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 91ca8d8cf4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Summary
Depends on #416.
bun devstack with source-watched web and worker processes;3205/3206/3207/3445without touching the existing preview on3444;Security and operations
/_bun/hmrOrigin;Verification
dev:remotesmoke proved HTTPS HTML and an actual HMR WebSocket handshake through3445, clean Ctrl-C shutdown, route removal, lease removal, and release of ports3205/3206/3207;SIGKILLprobes removed ordinary web/worker/frontend descendants and the supervisor/sudo/root-command chain;Deployment / operations
No production deploy, restart, schema migration, or secret change is required. The established preview route on
3444is unchanged.