Skip to content

fix(dev): make pnpm dev:app:win work on default Git for Windows installs - #5342

Open
Mustaqeem66 wants to merge 10 commits into
tinyhumansai:mainfrom
Mustaqeem66:fix/5270-dev-app-win-cmd-quoting
Open

fix(dev): make pnpm dev:app:win work on default Git for Windows installs#5342
Mustaqeem66 wants to merge 10 commits into
tinyhumansai:mainfrom
Mustaqeem66:fix/5270-dev-app-win-cmd-quoting

Conversation

@Mustaqeem66

@Mustaqeem66 Mustaqeem66 commented Aug 3, 2026

Copy link
Copy Markdown

Summary

  • pnpm dev:app:win fails on every default Git for Windows install with 'C:/Program' is not recognized as an internal or external command.
  • Route the script through a new scripts/run-dev-win.cmd wrapper so the bash.exe path is quoted in a context where quoting actually survives.
  • app/package.json now points at a relative, space-free path (..\scripts\run-dev-win.cmd) that needs no quoting of its own.
  • The wrapper is written as straight-line batch with no labels and no goto/call, so its behaviour does not depend on whether it is checked out with LF or CRLF.
  • .gitattributes now checks out *.cmd/*.bat with CRLF, matching the exception *.ps1 already had.
  • Added app/test/dev-app-win-launcher.test.ts, which models cmd.exe /d /s /c argument parsing and locks in both the quoting regression and the no-label property.
  • scripts/run-dev-win.sh is unchanged — this only fixes how it is invoked.

Problem

app/package.json declared:

"dev:app:win": "\"C:/Program Files/Git/bin/bash.exe\" ../scripts/run-dev-win.sh"

pnpm runs package.json scripts through cmd.exe /d /s /c <string>. The /S flag strips the first and last quote characters of <string> before parsing it. So cmd receives:

C:/Program Files/Git/bin/bash.exe ../scripts/run-dev-win.sh

and takes C:/Program as the program name, producing exactly the error reported in #5270. The quotes cannot protect the path at this layer — they are the first and last characters, so they are precisely what /S removes.

Because C:\Program Files\Git is the default install location, this breaks the documented Windows dev path for essentially every contributor who did not install Git somewhere without a space.

Solution

Quoting behaves normally inside a .cmd file, so the fix is to make the package.json body something cmd cannot mis-split, and do the real quoting one level down.

app/package.json (single line changed):

-"dev:app:win": "\"C:/Program Files/Git/bin/bash.exe\" ../scripts/run-dev-win.sh",
+"dev:app:win": "..\\scripts\\run-dev-win.cmd",

The new value has no spaces and no quotes, so /S stripping is a no-op on it. Backslashes are used rather than forward slashes because cmd treats a leading / as a switch prefix. pnpm runs lifecycle scripts with the package directory as cwd, so the relative path resolves from app/.

scripts/run-dev-win.cmd then locates bash.exe and invokes it with the path properly quoted:

"%BASH_EXE%" "%SCRIPT_DIR%run-dev-win.sh" %*

Lookup order:

  1. %OPENHUMAN_BASH_EXE% — escape hatch for portable/exotic Git installs.
  2. %ProgramFiles%\Git\bin, %ProgramFiles(x86)%\Git\bin, %LOCALAPPDATA%\Programs\Git\bin — the machine-scope and user-scope Git for Windows installers.
  3. %SCOOP%, %USERPROFILE%\scoop, %ProgramData%\scoopapps\git\current\bin\bash.exe — scoop only exposes shims on PATH, so it must be probed directly (see below).
  4. The Git root derived from git.exe on PATH — covers winget and chocolatey, where git.exe lives in \cmd and bash in \bin.

If none match it exits 1 with actionable guidance instead of failing obscurely.

No labels, no goto/call — deliberate

Each candidate is applied by a single-line if not defined BASH_EXE if exist "…" set "BASH_EXE=…", and the failure path is a run of single-line if not defined BASH_EXE echo …>&2 lines terminated by if not defined BASH_EXE exit /b 1. There is no call :use_if_exists helper and no goto :no_bash jump.

That is not stylistic. cmd.exe locates a label by byte offset and re-reads the script in 512-byte chunks, which makes label-based control flow the one batch construct whose behaviour depends on the file's line endings — the basis of the well-known LF-only batch corruption bug. Writing the launcher without labels removes the dependency at the source, instead of relying on every checkout on every machine having applied the right .gitattributes rule. A test pins the property so it cannot silently regress.

.gitattributes

The repo root normalises everything with * text=auto eol=lf and carves out exactly one Windows exception, *.ps1 text eol=crlf. Batch files had no rule at all, so *.cmd/*.bat text eol=crlf was added alongside it. With the label-free launcher this is defence in depth and consistency for editors and future batch files, rather than the thing correctness rests on.

Design notes / rejected alternatives

The issue suggested three options. This PR takes option 1 deliberately:

  • Option 2 — bare bash ../scripts/run-dev-win.sh was rejected as actively harmful. Git\bin is not on PATH by default (only Git\cmd, which has no bash.exe), and on machines with WSL enabled bash resolves to C:\Windows\System32\bash.exe — the WSL launcher. That would run the script inside a Linux distro with none of the Windows toolchain it configures (MSVC, CEF, cargo-tauri), producing a far more confusing failure than the current one. The wrapper therefore never falls back to a bare bash lookup, and there is a test asserting it does not.
  • Option 3 — .npmrc script-shell was rejected because it changes shell semantics repo-wide for every platform to fix one Windows script.
  • Option 1 is already the idiom here. scripts/run-dev-win.sh generates .bat shims internally (vcvars_launcher, run-vite.bat) for cargo-tauri's beforeDevCommand to dodge this exact quoting problem. This change applies the same trick one level up, at the pnpm boundary.

Impact

  • Platform: Windows dev workflow only. dev:app, dev:web, dev:wry and all CI/build/release scripts are untouched; nothing outside Windows executes a .cmd.
  • Runtime/product: none. This is a developer entry point, not shipped application code.
  • Compatibility: a hardcoded absolute path is replaced by a probe, so this widens the set of working setups (machine-scope, user-scope, winget, scoop, chocolatey, portable Git) rather than narrowing it. OPENHUMAN_BASH_EXE covers anything exotic.
  • Security: no new network dependency; no new executable is downloaded. Candidate paths are all derived from OS-provided environment variables or where git.exe.

Related

Review feedback addressed

  • CodeRabbit — CRLF line endings, round 1 (b4a710e): fixed at the attributes layer rather than by committing CRLF bytes, since text=auto normalises the blob to LF on commit regardless, so a checkout rule is the only durable form of that fix.
  • Greptile — scoop coverage (f141144): correct, and this description previously overclaimed. where git.exe under scoop returns <scoop>\shims\git.exe, so the derived <shim>\..\bin\bash.exe resolved to <scoop>\bin\bash.exe, which never exists. Now probing apps\git\current\bin\bash.exe — the real binary behind the shim, via the current junction scoop maintains across upgrades — across the user, global and %SCOOP%-relocated roots. The failure-path diagnostic and the comment above the git.exe probe were corrected to match.
  • CodeRabbit — CRLF line endings, round 2 (9d81ab4, b353a74): the bot re-flagged the blob (Blinter E018) after the .gitattributes fix, and it has a fair point that the earlier fix left the repository object LF-only — which is what anyone reading the file through the API, a raw link, or a source archive sees. Rather than argue the checkout rule again, the dependency itself is now gone: the launcher was rewritten with no labels and no goto/call, which is the only batch construct whose parsing is line-ending sensitive. The file is now correct under LF and CRLF, the .gitattributes rule stays for consistency, and app/test/dev-app-win-launcher.test.ts gained a fifth case asserting no label-based control flow so this cannot regress. Behaviour is otherwise unchanged: identical probe order, identical quoting, identical exit-code propagation.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) — app/test/dev-app-win-launcher.test.ts has 5 cases. The failure-path case reconstructs the old script body verbatim and asserts cmd /S parsing yields C:/Program, so the regression is pinned rather than merely described. The others assert the current body survives /S as one token, that it points at a file that exists, that the wrapper quotes %BASH_EXE% and contains no bare-bash lookup, and that the wrapper uses no label-based control flow.
  • Diff coverage ≥ 80%N/A, and verifiably so rather than by assertion: app/test/vitest.config.ts sets coverage.include: ["src/**/*.{ts,tsx}"]. All four changed files (app/package.json, app/test/dev-app-win-launcher.test.ts, scripts/run-dev-win.cmd, .gitattributes) fall outside app/src/**, so no changed line appears in the lcov report and diff-cover --fail-under=80 has no lines to judge. No Rust changed, so cargo-llvm-cov is unaffected. Please flag if you would rather I approach this differently.
  • Coverage matrix updated — N/A: developer tooling change. docs/TEST-COVERAGE-MATRIX.md tracks product feature rows with IDs validated against a catalog; a build-script entry point has no feature ID, and inventing one would add noise. Calling this out explicitly rather than silently skipping — happy to add a row if you disagree.
  • All affected feature IDs listed under ## RelatedN/A, none (see above).
  • No new external network dependencies introduced — none added; no test performs I/O beyond reading two files from the repo working tree.
  • Manual smoke checklist updated — N/A: does not touch release-cut surfaces. This affects the dev entry point only; release builds go through macos:build:* / build:app.
  • Linked issue closed via Closes #NNN in ## RelatedCloses #5270.

AI Authored PR Metadata (required for Codex/Linear PRs)

Disclosing this fully, since the template asks for it: the investigation and patch were drafted with AI assistance, reviewed line-by-line by me before pushing. It is not a Codex/Linear-tracked PR, so those fields are N/A.

Linear Issue

Commit & Branch

  • Branch: Mustaqeem66:fix/5270-dev-app-win-cmd-quoting
  • Commit SHA: b353a745ad541696126481825deb6bb5a040cd7f

Validation Run

Three of these could not be run in my environment. Rather than tick boxes I did not earn — or leave them unchecked and trip check-pr-checklist.mjs — they are listed as plain bullets marked NOT RUN, with full detail in Validation Blocked below. Happy to reformat if maintainers prefer a different convention here.

  • NOT RUNpnpm --filter openhuman-app format:check
  • NOT RUNpnpm typecheck
  • NOT RUN — Focused tests: pnpm --filter openhuman-app test -- dev-app-win-launcher
  • Rust fmt/check (if changed): N/A — no Rust changed.
  • Tauri fmt/check (if changed): N/A — no Tauri config or Rust changed.

Validation Blocked

I would rather state this plainly than tick boxes I did not earn:

  • command: pnpm --filter openhuman-app format:check, pnpm typecheck, pnpm test, pnpm test:coverage
  • error: pnpm: command not found — the environment I prepared this in has no Node package manager, no Rust toolchain and no network access, so dependencies cannot be installed.
  • impact: The test file has not been executed locally under vitest. To de-risk that, the pure-logic helpers were extracted and run standalone under plain node: the legacy body yields C:/Program, the new body survives /S unchanged, and the no-label assertions were run against both an LF and a CRLF copy of the launcher (both pass, which is the point of the rewrite). The remaining assertions are existsSync and substring checks against files added in this PR. CI is the real verification for typecheck/format/lint — the first run flagged a format:check failure (hand-wrapped call expressions that fit inside the repo's printWidth of 100), fixed in bb9e76a with no behavioural change to the tests.
  • impact (Windows): I have no Windows machine attached to this environment, so pnpm dev:app:win has not been run end-to-end against a real Git install. The .cmd was desk-checked for batch parsing hazards — one was found and fixed in 9df25a7 (an unescaped ) in %ProgramFiles(x86)% inside an if (...) block would have closed the block early), and the later rewrite removed every multi-line parenthesised block and every label, so that class of hazard is now structurally absent. A maintainer sanity-check on a real Windows box would be genuinely valuable before merge, and I will act on any failure immediately.

Behavior Changes

  • Intended behavior change: pnpm dev:app:win resolves bash.exe at runtime instead of assuming one hardcoded absolute path, and is invoked so that cmd.exe /S cannot split it.
  • User-visible effect: for developers, pnpm dev:app:win starts working on default Git for Windows installs instead of erroring immediately. No end-user or product-facing change.

Parity Contract

  • Legacy behavior preserved: yes. The command ultimately executed is still <bash.exe> <repo>/scripts/run-dev-win.sh, with run-dev-win.sh byte-identical. On the machines where the old form happened to work (Git at C:\Program Files\Git), the wrapper's first filesystem probe resolves to that same bash.exe, so behavior is identical. Arguments are forwarded via %*.
  • Guard/fallback/dispatch parity checks: the exit code is propagated with exit /b %ERRORLEVEL% so failures still surface to pnpm. The fallback chain only ever adds candidates that the old hardcoded path did not cover; it removes none, and the label-free rewrite preserved the probe order exactly. The one intentional non-fallback is a bare bash PATH lookup, excluded because of the WSL hazard described above and asserted absent by test.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • Bug Fixes

    • Fixed the Windows app development command so it launches reliably from paths containing spaces.
    • Added a Windows launcher that correctly locates Git Bash and forwards command arguments.
    • Added clear guidance when Git Bash cannot be found.
  • Chores

    • Standardized Windows command-file line endings for improved compatibility.
  • Tests

    • Added coverage for Windows command parsing, launcher discovery, argument forwarding, and error handling.

pnpm runs package.json scripts through `cmd.exe /d /s /c`, which strips
the first and last quote characters from the command string. The
`dev:app:win` body quoted an absolute bash.exe path containing a space,
so cmd parsed `C:/Program` as the program name and the script failed on
every default Git for Windows install:

    'C:/Program' is not recognized as an internal or external command

Quoting works normally inside a .cmd file, so route the entry point
through a new scripts/run-dev-win.cmd. package.json now references a
relative, space-free path that needs no quoting, and the wrapper quotes
the bash.exe path itself. This mirrors the .bat shim run-dev-win.sh
already generates internally for cargo-tauri's beforeDevCommand.

The wrapper probes the standard Git for Windows locations plus the
parent of git.exe on PATH, and honours OPENHUMAN_BASH_EXE for portable
installs. It deliberately avoids a bare `bash` lookup, which resolves to
the WSL launcher in System32 when WSL is enabled.

Closes tinyhumansai#5270
An unescaped `)` inside `%ProgramFiles(x86)%` in the diagnostic echo would
have closed the enclosing `if (...)` block early, so the guidance never
printed correctly. Jump to a label instead, where parentheses are literal.

Refs tinyhumansai#5270
@Mustaqeem66
Mustaqeem66 requested a review from a team August 3, 2026 16:38
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Windows development command now invokes a .cmd wrapper. The wrapper discovers Git Bash, avoids WSL bash, forwards arguments to run-dev-win.sh, and reports configuration errors. Tests validate command parsing, launcher existence, quoting, delegation, and launcher structure.

Changes

Windows launcher flow

Layer / File(s) Summary
Windows entrypoint contract
app/package.json, app/test/dev-app-win-launcher.test.ts, .gitattributes
dev:app:win now references the command wrapper. Tests validate single-token command parsing, launcher existence, and launcher structure. .cmd and .bat files use CRLF line endings.
Git Bash discovery
scripts/run-dev-win.cmd
The wrapper checks OPENHUMAN_BASH_EXE, standard Git paths, Scoop locations, and the Git installation root found through git.exe.
Delegation and failure handling
scripts/run-dev-win.cmd, app/test/dev-app-win-launcher.test.ts
The wrapper quotes BASH_EXE, forwards arguments to run-dev-win.sh, preserves its exit code, and reports missing Git Bash. Tests validate these behaviors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

A rabbit checks the launcher path,
Git Bash follows a safer path.
Quotes stay whole, arguments fly,
WSL stays safely by.
Windows starts the script just right.

Sequence Diagram(s)

sequenceDiagram
  participant pnpm
  participant run-dev-win.cmd
  participant GitBash
  participant run-dev-win.sh
  pnpm->>run-dev-win.cmd: Execute dev:app:win
  run-dev-win.cmd->>run-dev-win.cmd: Discover BASH_EXE
  run-dev-win.cmd->>GitBash: Invoke run-dev-win.sh with arguments
  GitBash->>run-dev-win.sh: Execute shell launcher
  run-dev-win.sh-->>run-dev-win.cmd: Return exit status
  run-dev-win.cmd-->>pnpm: Preserve exit status
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary fix for the Windows development command.
Linked Issues check ✅ Passed The wrapper and package-script change directly fix the default Git for Windows quoting failure described in [#5270].
Out of Scope Changes check ✅ Passed The launcher, regression tests, line-ending rules, and package-script update support the linked issue objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@scripts/run-dev-win.cmd`:
- Line 1: Convert scripts/run-dev-win.cmd to CRLF line endings so cmd.exe
correctly handles CALL :use_if_exists and labels, and add an eol=crlf repository
rule if no existing rule enforces it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d8baaff7-85f9-47e8-9f62-85863ef23db1

📥 Commits

Reviewing files that changed from the base of the PR and between 20589ab and 9df25a7.

📒 Files selected for processing (3)
  • app/package.json
  • app/test/dev-app-win-launcher.test.ts
  • scripts/run-dev-win.cmd

Comment thread scripts/run-dev-win.cmd
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes pnpm dev:app:win failing on default Git for Windows installs by routing the entry point through a new scripts/run-dev-win.cmd wrapper. The root cause was cmd.exe /d /S /c stripping the outermost quote pair from the package.json script body, exposing the space in C:/Program Files/... and causing C:/Program to be taken as the executable name.

  • app/package.json now points at ..\scripts\run-dev-win.cmd — a relative, space-free path that /S stripping cannot mis-split.
  • scripts/run-dev-win.cmd probes four ordered locations for bash.exe (fixed installer paths, scoop apps\git\current\bin, and the install root derived from git.exe on PATH), then invokes it with proper quoting and propagates the exit code; the script is written without labels or goto/call so its behaviour is identical under LF and CRLF line endings.
  • .gitattributes gains *.cmd/*.bat eol=crlf rules for editor consistency, and five new vitest cases lock in the quoting regression, the parse-safety of the new script body, file existence, the no-bare-bash invariant, and the no-label-flow property.

Confidence Score: 5/5

Safe to merge — affects only the Windows developer entry point, with no changes to application code, CI, or release paths.

The batch wrapper is structurally sound: probe order is sensible, quoting is correct, exit-code propagation works, and the no-label design removes the one batch construct that is sensitive to line endings. The test suite covers the historical regression verbatim, the new script body parse-safety, and the key invariants of the wrapper. No production code, no Rust, no CI scripts are touched.

Files Needing Attention: A maintainer sanity-check of scripts/run-dev-win.cmd on a real Windows box would be the only remaining validation gap.

Important Files Changed

Filename Overview
.gitattributes Adds *.cmd and *.bat CRLF checkout rules, consistent with the existing *.ps1 exception. Correct and uncontroversial.
app/package.json Replaces the hard-coded, space-containing bash.exe path (broken by cmd.exe /S /C quote-stripping) with a relative, space-free .cmd wrapper path. Single-line change; correct.
scripts/run-dev-win.cmd New batch wrapper that locates bash.exe via four ordered probes (fixed paths, scoop, git-on-PATH), quotes it correctly, and propagates exit codes. Written without labels or jumps to be line-ending agnostic. Well-structured and safe.
app/test/dev-app-win-launcher.test.ts Five-case test suite covering the cmd.exe /S quoting regression, the new script parse-safety, file existence, no-bare-bash, and no-label-flow invariants. Minor gap: launcherCodeLines filter misses @rem comment lines.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["pnpm dev:app:win"] -->|"cmd.exe /d /S /c ..\\scripts\\run-dev-win.cmd"| B["run-dev-win.cmd"]
    B --> C{"OPENHUMAN_BASH_EXE set and exists?"}
    C -->|Yes| G["Run bash.exe with run-dev-win.sh and forward args"]
    C -->|No| D{"ProgramFiles Git bin or x86 or LOCALAPPDATA?"}
    D -->|Exists| G
    D -->|No| E{"Scoop apps/git/current/bin in user, global, or relocated root?"}
    E -->|Exists| G
    E -->|No| F{"git.exe on PATH - derive parent bin/bash.exe?"}
    F -->|Exists| G
    F -->|No| H["Print diagnostic to stderr and exit /b 1"]
    G --> I["exit /b ERRORLEVEL"]
Loading

Reviews (5): Last reviewed commit: "test: detect @-prefixed and colon-joined..." | Re-trigger Greptile

Comment thread scripts/run-dev-win.cmd Outdated
Collapse call expressions that fit within the repo's printWidth of 100 and
replace the multi-line concatenation with straight-line statements, so
`pnpm --filter openhuman-app format:check` is stable.

Refs tinyhumansai#5270
The repository normalises everything to LF via `* text=auto eol=lf`, and
`*.ps1` is the only Windows exception. cmd.exe's parser is line-ending
sensitive -- LF-only batch files can mis-parse `goto`/`call :label` because
of the 512-byte read-boundary bug -- so batch scripts need the same
treatment PowerShell already gets.

Refs tinyhumansai#5270
Deriving the Git root from `where git.exe` does not work under scoop: PATH
only ever contains the shim directory, so `<shim dir>\..\bin\bash.exe`
resolves to `scoop\bin\bash.exe`, which does not exist. The real binary
lives under `scoop\apps\git\current\bin`, so probe that directly for the
user-scope, global and relocated (`%SCOOP%`) install roots.

Refs tinyhumansai#5270
@Mustaqeem66

Copy link
Copy Markdown
Author

Both review findings were valid and are now addressed. (Replying here rather than in-thread — threaded replies are blocked for me by the org's OAuth app access restrictions.)


1. CRLF line endings on run-dev-win.cmd@coderabbitai

Fixed at the attributes layer rather than by committing CRLF bytes (b4a710e).

The root .gitattributes starts with * text=auto eol=lf and carves out exactly one Windows exception, *.ps1 text eol=crlf. There's no rule for *.cmd/*.bat. Under text=auto git normalises the blob to LF on commit regardless of what I push, so storing CRLF in the object would just get normalised away — and even if it survived, a fresh clone would still check the file out as LF for every contributor.

So the durable fix is the checkout rule:

*.ps1 text eol=crlf
*.cmd text eol=crlf
*.bat text eol=crlf

Batch scripts now get the same treatment PowerShell already had: LF in the object store, CRLF in the working tree, which is what cmd.exe actually reads. This also covers any future .cmd/.bat rather than just this one file.

The 512-byte read-boundary bug being flagged is a real risk for this file specifically, since it uses both goto :no_bash and call :use_if_exists.

2. Scoop coverage claim — @greptile-apps

Correct, and my PR description was overclaiming. Fixed in f141144.

Confirming the trace: scoop only ever exposes shims on PATH, so where git.exe returns <scoop>\shims\git.exe and %%~dpG..\bin\bash.exe resolves to <scoop>\bin\bash.exe, which doesn't exist. None of the original probes could ever match a scoop install.

I probed apps\git\current\bin\bash.exe rather than shims\bash.exe — that's the real binary behind the shim, reached through the current junction scoop maintains across upgrades, so it's present whenever the shim is and doesn't depend on scoop having shimmed bash.exe specifically:

%SCOOP%\apps\git\current\bin\bash.exe
%USERPROFILE%\scoop\apps\git\current\bin\bash.exe
%ProgramData%\scoop\apps\git\current\bin\bash.exe

%SCOOP% first for relocated installs; when it's unset the unexpanded string simply fails if exist, so it's a harmless no-op. %ProgramData% covers scoop install -g.

I also corrected the :no_bash diagnostic text and the comment above the git.exe probe, which now claims winget and chocolatey only.


Also in this push: app/test/dev-app-win-launcher.test.ts was reformatted to satisfy format:check (the repo's printWidth is 100, so several call expressions I'd wrapped by hand needed collapsing). No behavioural change to the tests.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@Mustaqeem66 Confirmed. The .gitattributes change provides the correct durable CRLF checkout behavior for batch scripts. The Scoop probe now targets the actual Git Bash binary. The test formatting-only update does not affect the review findings.

🐇 ✅


✏️ Learnings added
Learnt from: Mustaqeem66
URL: https://github.com/tinyhumansai/openhuman/pull/5342

Timestamp: 2026-08-03T16:57:01.941Z
Learning: The repository root `.gitattributes` uses `* text=auto eol=lf`. Windows batch files must have explicit `*.cmd text eol=crlf` and `*.bat text eol=crlf` rules so Git checks them out with CRLF line endings for `cmd.exe`.

Learnt from: Mustaqeem66
URL: https://github.com/tinyhumansai/openhuman/pull/5342

Timestamp: 2026-08-03T16:57:01.941Z
Learning: For Scoop Git installations on Windows, `where git.exe` resolves to a shim. Detect Git Bash by probing `%SCOOP%\apps\git\current\bin\bash.exe`, `%USERPROFILE%\scoop\apps\git\current\bin\bash.exe`, or `%ProgramData%\scoop\apps\git\current\bin\bash.exe`, not by deriving `bin\bash.exe` from the shim path.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Both fixes are well-executed. The current diff confirms the changes are in place:

CRLF fix — Adding *.cmd text eol=crlf and *.bat text eol=crlf to .gitattributes is the right approach. Storing LF in the object store and having git check out CRLF on Windows is exactly what the *.ps1 precedent in this repo already does. The 512-byte boundary risk (which affects batch files that use goto/call) is now mitigated.

Scoop fix — The trace is correct and the fix is sound. Using apps\git\current\bin\bash.exe via the current junction is more reliable than probing a shim path, since scoop doesn't necessarily shim bash.exe — only git.exe. The three-probe fallback (%SCOOP%%USERPROFILE%\scoop%ProgramData%\scoop) correctly handles user, global, and relocated installs. The %SCOOP% variable being unset silently failing if exist is the expected and safe behavior.

One minor thing to verify: when %SCOOP% is unset, the literal string %SCOOP%\apps\git\current\bin\bash.exe is passed to if exist inside :use_if_exists, which will evaluate to false since that path won't exist on disk — no false positive, correct behavior.

The PR looks good to merge. Both original concerns are fully addressed, the explanation is thorough, and the fix remains narrowly scoped to the Windows dev entry point only.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.

@Mustaqeem66

Copy link
Copy Markdown
Author

Note on the one review thread still showing as open — the CodeRabbit CRLF finding on scripts/run-dev-win.cmd. It was addressed in b4a710e, but at the .gitattributes layer rather than by committing CRLF bytes, so the byte-level linter can't see the fix. Worth explaining the choice:

The repo root sets * text=auto eol=lf. Under text=auto, git normalises the blob to LF on commit regardless of what I push — so committing CRLF bytes would not survive. The stored blob would still be LF, every fresh clone would still check the file out LF-only, and the finding would reappear for the next person who cloned.

The durable fix is the checkout rule, added alongside the *.ps1 exception that already existed for exactly this reason:

*.ps1 text eol=crlf
*.cmd text eol=crlf
*.bat text eol=crlf

scripts/run-dev-win.cmd now lands in the working tree with CRLF on every platform, which is what cmd.exe's parser needs given the file uses both goto :no_bash and call :use_if_exists — and it covers future batch files rather than just this one.

The Greptile scoop finding was also valid and is fixed in f141144 (probing apps\git\current\bin\bash.exe rather than deriving from the shim path, which resolved to a directory that never exists).

The one thing I still can't verify myself is an end-to-end pnpm dev:app:win run on a real Windows box with Git installed at the default location — noted in the Validation Blocked section. If a maintainer or anyone on Windows can sanity-check that, I'll act on any failure straight away.

CodeRabbit/Blinter E018 flagged the launcher for LF-only line endings:
cmd.exe seeks labels by byte offset and re-reads the file in 512-byte
chunks, so `goto`/`call :label` is the one batch construct whose
behaviour depends on line endings.

Rather than depend on a checkout rule being right on every machine,
remove the dependency: the script is now straight-line batch with no
labels, no `goto`/`call`, and no multi-line parenthesised blocks, so it
behaves identically under LF and CRLF. The `.gitattributes` eol=crlf
rule stays for editor/tooling consistency, but correctness no longer
rests on it.

Behaviour is unchanged: same probe order, same quoting of %BASH_EXE%,
same exit-code propagation, still no bare `bash` PATH lookup.
…l flow

Locks in the property that makes scripts/run-dev-win.cmd correct under
both LF and CRLF: no labels, no goto/call. Without this a future edit
could reintroduce the line-ending dependency that Blinter E018 flags.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 4, 2026
@coderabbitai coderabbitai Bot added the feature Net-new user-facing capability or product behavior. label Aug 4, 2026
@Mustaqeem66

Copy link
Copy Markdown
Author

Round-2 review feedback addressed in 9d81ab4 + b353a74. Posting as a top-level comment because threaded replies from my account are rejected with 403 … tinyhumansai organization has enabled OAuth App access restrictions.

@coderabbitaiscripts/run-dev-win.cmd LF line endings (Blinter E018, Major)

Valid finding, and I'll grant that my first pass only half-answered it. b4a710e added *.cmd/*.bat text eol=crlf to .gitattributes, which makes every checkout CRLF, but because root .gitattributes carries * text=auto eol=lf, git normalises the blob to LF on commit regardless — so the stored object stays LF, and that's exactly what your linter reads (and what anyone reading via the API, a raw link, or a source archive gets). Committing literal CRLF bytes would additionally require dropping the file out of git's text normalisation entirely (-text), which diverges from the *.ps1 text eol=crlf convention this repo already established.

So rather than keep arguing about bytes, I removed the reason the bytes matter.

The launcher no longer contains any label-based control flow. call :use_if_exists and goto :no_bash are gone:

  • each probe is now a single-line if not defined BASH_EXE if exist "…" set "BASH_EXE=…";
  • the git.exe fallback is a one-line if not defined BASH_EXE for /f … do if not defined BASH_EXE if exist … set …;
  • the failure path is a run of single-line if not defined BASH_EXE echo …>&2 statements ending in if not defined BASH_EXE exit /b 1;
  • there are no multi-line parenthesised blocks left either, which also retires the %ProgramFiles(x86)%-inside-if (…) hazard I'd fixed separately in 9df25a7.

cmd.exe seeks labels by byte offset and re-reads the script in 512-byte chunks — that is the mechanism behind the LF-only batch corruption bug your rule cites. With no labels and no jumps, the file executes identically under LF and CRLF, so correctness stops depending on whether a given clone applied the checkout rule. The .gitattributes rule stays: it's still right for editors, for future batch files, and as defence in depth — it's just no longer load-bearing.

To stop this regressing quietly, app/test/dev-app-win-launcher.test.ts gained a fifth case that strips rem lines and asserts no remaining line starts with : and none contains goto/call. I ran those assertions standalone under node against both an LF and a CRLF copy of the file; both pass.

Behaviour is otherwise unchanged: same probe order, same "%BASH_EXE%" quoting, same %* forwarding, same exit /b %ERRORLEVEL% propagation, still no bare-bash PATH lookup (WSL hazard).

If you'd still prefer literal CRLF in the object, say so and I'll switch *.cmd/*.bat to -text and recommit the bytes — I just didn't want to break the repo's normalisation convention unasked.

@greptile-apps — scoop coverage

Already handled in f141144 (your comment is marked outdated now) and carried through the rewrite unchanged: the four scoop-relevant probes are %SCOOP%, %USERPROFILE%\scoop and %ProgramData%\scoop, each pointing at apps\git\current\bin\bash.exe — the real binary behind the shim, via the current junction scoop maintains across upgrades — rather than the <scoop>\shims\..\bin\bash.exe path that never exists. The PR description and the failure-path diagnostic were corrected to match; thanks for catching the overclaim.

Still outstanding on my side

pnpm dev:app:win has not been executed against a real Git for Windows install — I have no Windows box attached to this environment. Everything above is desk-checked plus CI. A one-line confirmation from anyone on Windows would be the last missing piece before merge.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- changed files ---'
git diff --name-only HEAD^ HEAD || true

printf '%s\n' '--- .gitattributes ---'
cat -n .gitattributes

printf '%s\n' '--- scripts/run-dev-win.cmd ---'
cat -n scripts/run-dev-win.cmd

printf '%s\n' '--- app/package.json dev:app:win ---'
rg -n -C2 '"dev:app:win"\s*:' app/package.json

printf '%s\n' '--- app/test/dev-app-win-launcher.test.ts outline ---'
ast-grep outline app/test/dev-app-win-launcher.test.ts --items all || true

printf '%s\n' '--- launcher test source ---'
cat -n app/test/dev-app-win-launcher.test.ts

printf '%s\n' '--- executable batch control-flow tokens ---'
rg -n -i '^[[:space:]]*:|(^|[^[:alnum:]_])(goto|call)[[:space:]]+' scripts/run-dev-win.cmd || true

Length of output: 13628


@Mustaqeem66 Confirmed. scripts/run-dev-win.cmd now has no executable labels, goto, or call commands. It uses straight-line, single-line guarded commands only.

The launcher keeps quoted "%BASH_EXE%" execution, %* forwarding, and exit /b %ERRORLEVEL% propagation. It does not use a bare bash lookup.

app/test/dev-app-win-launcher.test.ts enforces the no-label-control-flow constraint. .gitattributes also keeps CRLF checkout rules for *.cmd and *.bat.

The original LF line-ending finding is no longer applicable. A real Windows execution remains useful final validation, but it is separate from this resolved control-flow concern.


✏️ Learnings added
Learnt from: Mustaqeem66
URL: https://github.com/tinyhumansai/openhuman/pull/5342

Timestamp: 2026-08-04T08:51:22.646Z
Learning: For the Windows batch launcher `scripts/run-dev-win.cmd`, avoid executable labels and label-based `goto` or `call` control flow. The launcher must use straight-line, single-line guarded commands so its correctness does not depend on LF versus CRLF line endings. `app/test/dev-app-win-launcher.test.ts` enforces this constraint after removing `rem` comments and blank lines.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown

The label-free rewrite is the right call — much cleaner than arguing about checkout bytes forever. The implementation looks solid:

  • Every probe is a self-contained if not defined … if exist … one-liner; no jumps, no labels, no multi-line parenthesised blocks
  • The %%~dpG..\bin\bash.exe derivation in the git.exe fallback is correct (%%~dpG always carries a trailing backslash, so the .. navigates up one level as expected, and if exist resolves the canonical path)
  • The %ProgramFiles(x86)%-inside-if (…) hazard from 9df25a7 is now structurally impossible — no parenthesised blocks remain
  • The test's no-label assertion (/^:/ + /(goto|call)\s/i) properly gates on the right construct without tripping on call appearing as a substring in paths or variable names

One minor nit: the where bash.exe assertion in the test guards specifically against a where bash.exe invocation, but the actual WSL hazard comes from a bare bash on PATH, not necessarily where bash.exe. A future change that added something like for /f … in ('bash --version') wouldn't trip this test. Not blocking given the current script has no such line and the comment documents the intent, but worth knowing if the test is ever extended.

The LF/CRLF concern is resolved. .gitattributes staying as defence-in-depth for editors and future batch files is the right call. This looks good to merge pending the Windows smoke test you called out.

The launcher test added in the previous commit wrote its single-parameter
arrow functions as `(line) => ...`. app/.prettierrc sets
`"arrowParens": "avoid"`, so `pnpm --filter openhuman-app format:check`
rejected them. Drop the parentheses; no behaviour change.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@app/test/dev-app-win-launcher.test.ts`:
- Around line 91-101: Move the Vitest suite containing the launcher label and
control-flow assertions from the current test location into app/src/**,
preserving its tests and imports. Alternatively, narrow the Vitest include
pattern so it only applies under app/test, but ensure the suite is located
within the required co-location path.
- Around line 91-101: Update the control-flow assertion in the test “uses no
label-based control flow, so line endings cannot change behaviour” to also
detect commands prefixed with `@`, including `@goto` and `@call :label`, while
preserving detection of the existing unprefixed forms.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 307eb427-3629-408f-a5c5-bdc8c34cb86d

📥 Commits

Reviewing files that changed from the base of the PR and between f141144 and b353a74.

📒 Files selected for processing (2)
  • app/test/dev-app-win-launcher.test.ts
  • scripts/run-dev-win.cmd
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/run-dev-win.cmd

Comment on lines +91 to +101
it('uses no label-based control flow, so line endings cannot change behaviour', () => {
const code = launcherCodeLines(readFileSync(LAUNCHER_PATH, 'utf8'));

// cmd.exe finds a label by byte offset and re-reads the script in 512-byte
// chunks, so `goto`/`call :label` is the one construct whose behaviour
// depends on whether the file is LF or CRLF. Keeping the launcher free of
// labels makes it correct either way instead of relying on a checkout rule.
expect(code.filter((line) => line.startsWith(':'))).toEqual([]);
expect(code.filter((line) => /(^|\s)(goto|call)\s/i.test(line))).toEqual([]);
expect(code.length).toBeGreaterThan(0);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists =="
git ls-files | grep -F 'app/test/dev-app-win-launcher.test.ts' || true

echo "== matching files under app/test and app/src =="
git ls-files | grep -E '^app/.*\.test\.(ts|tsx)$' | sed -n '1,120p'

echo "== launcher source candidates =="
git ls-files | grep -E 'dev-app-win-launcher' | sed -n '1,120p'

echo "== package / config hints =="
git ls-files | grep -E '(^|/)(package\.json|vitest\.config\.[^/]*|\.gitignore)$' | while read -r f; do
  echo "--- $f"
  sed -n '1,220p' "$f"
done

Repository: tinyhumansai/openhuman

Length of output: 28228


Move the Vitest suite to app/src/**.

app/test/dev-app-win-launcher.test.ts is outside the required test co-location path. Apply the existing Vitest include pattern only under app/test, or move the spec under app/src/**.

🤖 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 `@app/test/dev-app-win-launcher.test.ts` around lines 91 - 101, Move the Vitest
suite containing the launcher label and control-flow assertions from the current
test location into app/src/**, preserving its tests and imports. Alternatively,
narrow the Vitest include pattern so it only applies under app/test, but ensure
the suite is located within the required co-location path.

Source: Coding guidelines


🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Target test excerpt:"
sed -n '80,105p' app/test/dev-app-win-launcher.test.ts || true

echo
echo "Launcher path definition:"
rg -n "LAUNCHER_PATH|launcherCodeLines|dev-app-win-launcher" app/test/dev-app-win-launcher.test.ts app -g '*.ts' -g '*.tsx'

echo
echo "Focused registry of launcher/test files:"
git ls-files | rg '(^|/)dev-app-win-launcher|launcher|win|batch' || true

Repository: tinyhumansai/openhuman

Length of output: 4743


🏁 Script executed:

#!/bin/bash
set -euo pipefail

node - <<'JS'
const current = /(^|\s)(goto|call)\s/i;
const proposed = /(^|[\s&|()])@?(goto|call)\s/i;

const lines = [
  'goto :label',
  'call :label',
  '`@goto` :label',
  '`@call` :label',
  'echo go to label',
  'call "path with spaces\\label"',
  '`@call` "label"',
  'goto\t:label',
  '& goto :label',
  '& `@goto` :label',
  '( goto :label)',
  '( `@goto` :label)',
];

console.log(JSON.stringify(lines.map(line => ({
  input: line,
  current: current.test(line),
  proposed: proposed.test(line)
})), null, 2));
JS

Repository: tinyhumansai/openhuman

Length of output: 1163


Detect @goto and @call :label forms.

CMD accepts @goto :label and @call :label; the current regex only fires when goto/call follows start-of-line or whitespace, so the regression test can still pass if those forms are added.

Proposed fix
-    expect(code.filter(line => /(^|\s)(goto|call)\s/i.test(line))).toEqual([]);
+    expect(code.filter(line => /(^|[\s&|()])@?(goto|call)\s/i.test(line))).toEqual([]);
📝 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
it('uses no label-based control flow, so line endings cannot change behaviour', () => {
const code = launcherCodeLines(readFileSync(LAUNCHER_PATH, 'utf8'));
// cmd.exe finds a label by byte offset and re-reads the script in 512-byte
// chunks, so `goto`/`call :label` is the one construct whose behaviour
// depends on whether the file is LF or CRLF. Keeping the launcher free of
// labels makes it correct either way instead of relying on a checkout rule.
expect(code.filter((line) => line.startsWith(':'))).toEqual([]);
expect(code.filter((line) => /(^|\s)(goto|call)\s/i.test(line))).toEqual([]);
expect(code.length).toBeGreaterThan(0);
});
it('uses no label-based control flow, so line endings cannot change behaviour', () => {
const code = launcherCodeLines(readFileSync(LAUNCHER_PATH, 'utf8'));
// cmd.exe finds a label by byte offset and re-reads the script in 512-byte
// chunks, so `goto`/`call :label` is the one construct whose behaviour
// depends on whether the file is LF or CRLF. Keeping the launcher free of
// labels makes it correct either way instead of relying on a checkout rule.
expect(code.filter((line) => line.startsWith(':'))).toEqual([]);
expect(code.filter(line => /(^|[\s&|()])@?(goto|call)\s/i.test(line))).toEqual([]);
expect(code.length).toBeGreaterThan(0);
});
🤖 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 `@app/test/dev-app-win-launcher.test.ts` around lines 91 - 101, Update the
control-flow assertion in the test “uses no label-based control flow, so line
endings cannot change behaviour” to also detect commands prefixed with `@`,
including `@goto` and `@call :label`, while preserving detection of the existing
unprefixed forms.

@coderabbitai coderabbitai Bot removed the feature Net-new user-facing capability or product behavior. label Aug 4, 2026
The no-label guard only matched `goto`/`call` at start-of-line or after
whitespace, so `@goto :label` and `& call :label` could be added without
tripping it (CodeRabbit review on tinyhumansai#5342).

Widen the jump pattern to allow the `@` echo-suppression prefix and the
command separators cmd accepts before a command (whitespace, `&`, `|`,
parentheses), and to treat `goto:eof` — the colon-joined form, which the
suggested pattern still missed — as a jump. The label pattern likewise
tolerates a leading `@`.

Verified against the current launcher (21 executable lines, zero matches)
under both LF and CRLF, with 14 positive and 6 negative control lines.
@Mustaqeem66

Copy link
Copy Markdown
Author

Round-3 review response — one finding accepted, one respectfully declined.

(Posting top-level: threaded replies from my account return 403 … tinyhumansai organization has enabled OAuth App access restrictions.)

✅ Accepted — @goto / @call :label were not detected (7b0da28)

Correct, and thank you — the guard had a real hole. I took the suggestion and widened it slightly further, because the proposed pattern still missed the colon-joined form:

-    expect(code.filter(line => /(^|\s)(goto|call)\s/i.test(line))).toEqual([]);
+const BATCH_LABEL = /^@?:/;
+const BATCH_JUMP = /(^|[\s&|()])@?(goto|call)[\s:]/i;
  • [\s&|()] — the separators cmd accepts before a command, so & goto :x and ( @goto :x) are caught.
  • @? — the echo-suppression prefix, so @goto / @call are caught.
  • [\s:] instead of \sgoto:eof is valid cmd and is arguably the most common jump form in the wild; /…(goto|call)\s/ misses it, and so did the suggested /(^|[\s&|()])@?(goto|call)\s/.
  • BATCH_LABEL = /^@?:/ — a label line behind @ is now caught too.

A regex is only as good as its controls, so the patterns are now themselves under test (new case “recognises every batch jump form, so the guard below cannot be bypassed”): 9 positive controls (goto :label, call :label, @goto :label, @call :label, goto:eof, @goto:eof, & goto :label, ( @goto :label), if not defined BASH_EXE goto :no_bash) and 4 negative controls (echo go to label, echo recall the value, exit /b %ERRORLEVEL%, the launcher’s own invocation line). Against the current launcher: 21 executable lines, zero label matches, zero jump matches, identical under LF and CRLF.

🙏 Declined — moving the spec to app/src/**

I don't think this one holds against the repo as it stands, and moving it would make things worse rather than better:

  1. app/test/*.test.ts is a first-class, maintainer-authored include, not an accident. app/test/vitest.config.ts:
    include: [
      "src/**/*.test.{ts,tsx}",
      "test/*.test.{ts,tsx}",
    ],
    The suggestion is to "narrow the include pattern so it only applies under app/test" — that pattern is already exactly test/*.test.{ts,tsx}, and this file matches it.
  2. Eight sibling specs already live there, several of which are the same genre as mine — a test that asserts on a non-src repo file: info-plist-required-keys.test.ts, checklist-parser.test.ts, coverage-matrix-parser.test.ts, core-rpc-node.test.ts, core-rpc-playwright-helper.test.ts, plus the three OAuth*.test.tsx. app/test/ is evidently where repo-artifact tests belong; app/src/** is for co-located component/module tests.
  3. This spec has no module under test. Its subjects are app/package.json and scripts/run-dev-win.cmd. There is no app/src/** file to co-locate with; putting it under src/ would place a build-tooling test inside the shipped React source tree, and it would then be picked up by coverage.include: ["src/**/*.{ts,tsx}"] and pollute frontend coverage.

Happy to move it if a maintainer prefers — just say the word and I'll relocate it in a follow-up commit.

Status

  • CRLF / Blinter E018 — resolved structurally in 9d81ab4 (no labels, no jumps ⇒ line endings cannot change behaviour), and the thread is now marked addressed. Thanks for re-checking it.
  • Scoop coverage (@greptile-apps) — fixed earlier; Greptile Review is green on the current head.
  • format:check163fac01 fixes the arrowParens: "avoid" violation my previous commit introduced.

Still outstanding and honestly disclosed: pnpm dev:app:win has not been executed on a real Windows machine from this branch. Everything above is static/unit verification. I'll add the manual-run confirmation as soon as I'm at a Windows box.

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown

Both points are well-handled.

Regex improvements — looks great. The widened BATCH_JUMP is correct:

  • [\s&|()] — covers every cmd command separator
  • @? — covers echo-suppressed variants
  • [\s:] — the goto:eof catch is the right call; it's the most common idiom in real batch and the original \s would have missed it silently

Wrapping the patterns themselves in positive/negative controls is exactly the right move. Without those, a future reader tightening the regex could hollow out the protection without any test failure. The 9/4 control split gives real confidence.

File location — point taken. I missed that vitest.config.ts already has test/*.test.{ts,tsx} as an explicit include alongside src/**. The 8 existing sibling specs (especially info-plist-required-keys.test.ts and coverage-matrix-parser.test.ts) confirm that app/test/ is the established home for repo-artifact tests, and moving the file to src/ would pollute coverage.include with a build-tooling test that has no counterpart module there. The reasoning is sound — withdrawing that suggestion.

No remaining concerns from my side. The outstanding item is the live Windows smoke test you've already flagged; that's outside review scope. LGTM.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dev:app:win always fails on standard Git for Windows install (cmd.exe strips nested quotes)

1 participant