test: id + shell — monotonic ID ordering and shell blacklist enforcement#398
test: id + shell — monotonic ID ordering and shell blacklist enforcement#398anandgupta42 wants to merge 1 commit intomainfrom
Conversation
Identifier (14 tests): covers prefix format, ascending/descending sort order, timestamp comparison, given-ID passthrough validation, and schema(). Shell (9 tests): covers fish/nu blacklist enforcement, preferred vs acceptable semantics, lazy cache reset, and SHELL-unset fallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> https://claude.ai/code/session_01SA2444fMWSyZaR3EkdJ7bL
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review.
Tip: disable this comment in your organization's Code Review settings.
📝 WalkthroughWalkthroughTwo new Bun test suites were added: one validating Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/opencode/test/shell/shell.test.ts`:
- Around line 55-61: The test "returns fallback when SHELL is unset" calls
Shell.acceptable() and currently uses a regex requiring a leading forward slash
but also includes "cmd\.exe", which can never match Windows paths with
backslashes; update the test to either (a) limit the assertion to POSIX shells
by removing "cmd\.exe" from the regex, or (b) handle platforms explicitly by
branching on process.platform and asserting a POSIX-style regex
(/\/(bash|zsh|sh)$/) on 'linux'/'darwin' and a Windows-style regex (e.g.,
/\\(?:Windows\\)?(?:System32\\)?cmd\.exe$/ or checking for 'cmd.exe' via
/cmd\.exe$/) on 'win32'; modify the test for "returns fallback when SHELL is
unset" and reference Shell.acceptable() so it validates the correct path format
per platform.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 686f8770-5082-4133-8735-adf7639d1723
📒 Files selected for processing (2)
packages/opencode/test/id/id.test.tspackages/opencode/test/shell/shell.test.ts
| test("returns fallback when SHELL is unset", () => { | ||
| delete process.env.SHELL | ||
| const result = Shell.acceptable() | ||
| expect(result.length).toBeGreaterThan(0) | ||
| // On Linux/macOS, fallback should be a valid shell path | ||
| expect(result).toMatch(/\/(bash|zsh|sh|cmd\.exe)$/) | ||
| }) |
There was a problem hiding this comment.
Regex won't match Windows cmd.exe paths.
The comment on line 59 says "On Linux/macOS" but the regex includes cmd\.exe. Windows paths use backslashes (e.g., C:\Windows\System32\cmd.exe), so the pattern requiring a forward slash will never match cmd.exe.
Either remove cmd\.exe from the pattern to align with the comment, or adjust the regex to handle both path separators:
Option 1: Remove cmd.exe (match comment scope)
- expect(result).toMatch(/\/(bash|zsh|sh|cmd\.exe)$/)
+ expect(result).toMatch(/\/(bash|zsh|sh)$/)Option 2: Handle both separators
- expect(result).toMatch(/\/(bash|zsh|sh|cmd\.exe)$/)
+ expect(result).toMatch(/[/\\](bash|zsh|sh|cmd\.exe)$/)📝 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.
| test("returns fallback when SHELL is unset", () => { | |
| delete process.env.SHELL | |
| const result = Shell.acceptable() | |
| expect(result.length).toBeGreaterThan(0) | |
| // On Linux/macOS, fallback should be a valid shell path | |
| expect(result).toMatch(/\/(bash|zsh|sh|cmd\.exe)$/) | |
| }) | |
| test("returns fallback when SHELL is unset", () => { | |
| delete process.env.SHELL | |
| const result = Shell.acceptable() | |
| expect(result.length).toBeGreaterThan(0) | |
| // On Linux/macOS, fallback should be a valid shell path | |
| expect(result).toMatch(/[/\\](bash|zsh|sh|cmd\.exe)$/) | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/opencode/test/shell/shell.test.ts` around lines 55 - 61, The test
"returns fallback when SHELL is unset" calls Shell.acceptable() and currently
uses a regex requiring a leading forward slash but also includes "cmd\.exe",
which can never match Windows paths with backslashes; update the test to either
(a) limit the assertion to POSIX shells by removing "cmd\.exe" from the regex,
or (b) handle platforms explicitly by branching on process.platform and
asserting a POSIX-style regex (/\/(bash|zsh|sh)$/) on 'linux'/'darwin' and a
Windows-style regex (e.g., /\\(?:Windows\\)?(?:System32\\)?cmd\.exe$/ or
checking for 'cmd.exe' via /cmd\.exe$/) on 'win32'; modify the test for "returns
fallback when SHELL is unset" and reference Shell.acceptable() so it validates
the correct path format per platform.
Merges 9 test PRs (#390, #394, #395, #396, #397, #398, #399, #401, #387) into a single PR, discarding 4 duplicates (#391, #392, #393, #400). **New test coverage:** - `id.test.ts` — 14 tests: Identifier generation, monotonic ordering, timestamp extraction, Zod schema - `shell.test.ts` — 9 tests: shell blacklist enforcement for fish/nu, cache reset, fallback - `path-traversal.test.ts` — 7 tests (new): `Protected.isSensitiveWrite` for .pem/.key, .gnupg, .env variants - `ignore.test.ts` — 7 tests (new): `FileIgnore.match` directory patterns, globs, whitelist overrides - `paths-parsetext.test.ts` — 16 tests: `ConfigPaths.parseText` env/file substitution, JSONC parsing - `finops-formatting.test.ts` — 14 tests: `formatBytes`/`truncateQuery` edge cases - `finops-role-access.test.ts` — 10 tests: RBAC `formatGrants`/`formatHierarchy`/`formatUserRoles` - `tool-lookup.test.ts` — 4 tests: Zod schema introspection for tool parameters - `summary-git-path.test.ts` — 10 tests: `unquoteGitPath` decoding for non-ASCII filenames - `tracing.test.ts` — 2 tests (added): Recap loop detection boundaries - `patch.test.ts` — 9 tests (added): `maybeParseApplyPatchVerified` entry point coverage - `instruction.test.ts` — 13 tests (new): `InstructionPrompt.loaded()` dedup guards - `message-v2.test.ts` — 23 tests (new): `MessageV2.filterCompacted()` boundary detection **Bug fixes (discovered during testing):** - `finops-formatting.ts`: fix `formatBytes` crash on negative/NaN/fractional inputs - `finops-formatting.ts`: fix `truncateQuery` returning empty for whitespace-only, exceeding `maxLen` when < 4 - `training-import.test.ts`: fix pre-existing typecheck errors (missing `context`/`rule` mock keys) - `instruction.test.ts`, `message-v2.test.ts`: fix `MessageV2.Part` cast and branded ID type errors Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
What does this PR do?
Adds first-ever tests for two core infrastructure modules that had zero test coverage.
1.
Identifier—src/id/id.ts(14 new tests)This module generates all IDs in the system (sessions, messages, parts, permissions, etc.). It's used everywhere — session ordering, message sequencing, database operations, and cleanup cutoffs. Zero tests existed. New coverage includes:
toolprefix outliertimestamp()preserves relative ordering between IDs (used byTruncate.cleanup()for retention cutoffs)tool) prefixes2.
Shell.acceptableandShell.preferred—src/shell/shell.ts(9 new tests)The Shell module selects which shell to use for bash tool execution. The
acceptable()function blacklistsfishandnu(Nushell) because they have incompatible syntax. If the blacklist fails, every bash tool call silently breaks for fish/nu users. Zero tests existed. New coverage includes:acceptable()returns$SHELLfor non-blacklisted shells (bash, zsh)acceptable()rejects fish and nu, returning a valid fallback/opt/nushell/bin/bashis NOT blacklisted (only the basename matters)preferred()returns$SHELLeven for blacklisted shells (intentional — used for user's terminal, not tool execution)$SHELLis unset (CI environments, containers)lazy()cache reset between tests to prevent order-dependent flakinessType of change
Issue for this PR
N/A — proactive test coverage via
/test-discoveryHow did you verify your code works?
Checklist
https://claude.ai/code/session_01SA2444fMWSyZaR3EkdJ7bL
Summary by CodeRabbit