Conversation
Greatly expands the virtual file system (VFS) to provide a richer and more realistic console experience. Implements dynamic content generation for VFS files and directories, reflecting real-time application state (e.g., themes, achievements). Adds support for tilde (`~`) expansion in all VFS path operations, including `cd`, `ls`, `cat`, and tab completion. Enhances the console prompt to display the current working directory in a more familiar `~` format. Refactors VFS utility functions into a new module and updates all relevant console command tests.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds confetti event handling and a confetti console command. Persists and resizes the secret console UI with cwd-aware prompts. Reworks VFS resolution, dynamic content, and stats. Adds new console commands (clear, tree, uptime), binary-file guards across readers, type updates, and multiple test adjustments to the new VFS and behaviors. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Console as SecretConsole (command)
participant Window as window
participant Provider as ConfettiProvider
participant Engine as ConfettiEngine
User->>Console: confetti <type>
Console->>Window: dispatch CustomEvent("kd:trigger-confetti", { detail: { type } })
Note right of Window: Browser-only dispatch (guarded)
Window-->>Provider: kd:trigger-confetti event
Provider->>Provider: validate CustomEvent & detail.type is string
alt type in {default,corners,top,center}
Provider->>Engine: trigger[type]()
else invalid type
Provider->>Provider: console.warn("Unexpected confetti type")
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
src/utils/console/tail.ts (1)
33-37: Binary file guard is duplicated.This guard is identical to the one in
cat.ts(lines 13-17). See the refactoring suggestion in the review comment forcat.tsto extract this shared logic.src/utils/console/head.ts (1)
33-37: Binary file guard is duplicated.This guard is identical to the ones in
cat.ts(lines 13-17) andtail.ts(lines 33-37). See the refactoring suggestion in the review comment forcat.tsto extract this shared logic.src/utils/console/wc.ts (1)
13-17: Binary file guard is duplicated.This guard is identical to the ones in
cat.ts(lines 13-17),head.ts(lines 33-37), andtail.ts(lines 33-37). See the refactoring suggestion in the review comment forcat.tsto extract this shared logic.
🧹 Nitpick comments (10)
src/utils/console/__tests__/cd.test.ts (1)
28-30: Add assertions: ensure target is a file and cwd remains unchangedVerify the error case more thoroughly by asserting the target is a file and that cwd didn’t change.
it('shows error when target is not a directory', () => { const { env, output } = createMockEnv() cd.execute(['/home/kil/.bashrc'], env) expect(output).toEqual([formatCdNotDirectory('/home/kil/.bashrc')]) + // Optional: strengthen the test + expect(env.stat('/home/kil/.bashrc')?.kind).toBe('file') + expect(env.pwd()).toBe('/home/kil') })src/utils/console/uname.ts (2)
23-33: Fix architecture detection to avoid mislabeling Intel MacsUsing “mac OR arm ⇒ aarch64” labels Intel Macs as aarch64. Prefer checking for arm/aarch hints, otherwise default to x86_64.
- const machine = (() => { - if (typeof navigator === 'undefined') return '' - const nav: Navigator & { userAgentData?: { platform?: string } } = navigator - const platform = nav.userAgentData?.platform ?? nav.platform ?? '' - const p = platform.toLowerCase() - return p.includes('mac') || p.includes('arm') ? 'aarch64' : 'x86_64' - })() + const machine = (() => { + if (typeof navigator === 'undefined') return '' + const nav: Navigator & { userAgentData?: { platform?: string } } = navigator + const platform = (nav.userAgentData?.platform ?? nav.platform ?? '').toLowerCase() + const ua = (nav.userAgent ?? '').toLowerCase() + const hints = `${platform} ${ua}` + return /arm|aarch/.test(hints) || /apple\s?silicon/.test(hints) ? 'aarch64' : 'x86_64' + })()
38-38: Avoid extra spaces when some fields are missingJoin non-empty parts for -a output to prevent double spaces.
- env.appendOutput(`${sysname} ${nodename} ${release} ${version} ${machine}`) + env.appendOutput([sysname, nodename, release, version, machine].filter(Boolean).join(' '))src/utils/secret-console-vfs.ts (4)
11-15: Centralize home path for tilde expansionMinor: extract '/home/kil' into a constant to avoid scattering literals and ease future changes.
+const HOME_DIR = '/home/kil' ... - if (path === '~' || path.startsWith('~/')) { - expandedPath = path.replace(/^~/, '/home/kil') + if (path === '~' || path.startsWith('~/')) { + expandedPath = path.replace(/^~/, HOME_DIR) }
71-83: Make vfsStat size computation resilient across environmentsTextEncoder may be unavailable in some runtimes; add safe fallbacks.
- const size = new TextEncoder().encode(content).length + const size = (() => { + try { + if (typeof TextEncoder !== 'undefined') return new TextEncoder().encode(content).length + } catch {} + // Node fallback + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore Buffer may not exist in browsers + if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') { + // @ts-ignore + return Buffer.byteLength(content) + } + return content.length + })()
85-91: Use proper ELF magic byteUse 0x7F "ELF" instead of NUL prefix.
return { type: 'file', - content: '\u0000ELF\n', + content: '\x7FELF\n', meta: { binary: true, executable: true }, } as VfsNode
93-116: Guard getAvailableThemes to avoid storage-related failuresIf theme helpers touch localStorage and throw, this file’s content generation could fail. Wrap in try/catch and degrade gracefully.
export function getThemeCacheContent(): string { let activeTheme = 'system' try { if (typeof localStorage !== 'undefined') { activeTheme = localStorage.getItem(LOCAL_STORAGE_KEYS.THEME) ?? 'system' } } catch { // localStorage not available } - const availableThemes = getAvailableThemes() + let availableThemes: string[] = [] + try { + availableThemes = getAvailableThemes() + } catch { + // Fallback to empty list if theme resolution fails + availableThemes = [] + } return (src/utils/console/cat.ts (1)
13-17: Consider extracting the binary file guard to reduce duplication.This binary file check is duplicated identically in
cat.ts,head.ts,tail.ts, andwc.ts. Consider extracting it to a shared utility function.Create a shared utility in a common file (e.g.,
src/utils/console/common.ts):export function checkAndRejectBinary( target: string, env: SecretConsoleEnv, commandName: string ): boolean { const stat = env.stat(target) if (stat && stat.kind === 'file' && stat.binary) { env.appendOutput(`${commandName}: ${target}: Is a binary file`) return true } return false }Then in each command file:
- const stat = env.stat(target) - if (stat && stat.kind === 'file' && stat.binary) { - env.appendOutput(`cat: ${target}: Is a binary file`) + if (checkAndRejectBinary(target, env, 'cat')) { return }src/utils/console/completion.ts (1)
283-305: Consider extracting shared completion logic.The
completeConfettiSubcommandsfunction duplicates the logic fromcompleteAchievementSubcommands(Lines 259-281). Both follow the identical pattern of filtering subcommands and handling completion cases.Consider extracting a shared helper function to reduce duplication:
+function completeSubcommands( + token: string, + before: string, + after: string, + getSubcommands: () => string[], +): CompletionResult | null { + const subcommands = getSubcommands() + const filtered = subcommands.filter(s => s.startsWith(token)) + + if (filtered.length === 0) return { value: `${before}${token}${after}`, caret: (before + token).length } + if (filtered.length === 1) { + const completed = filtered[0]! + const nextToken = `${completed} ` + const nextValue = `${before}${nextToken}${after}` + const nextCaret = (before + nextToken).length + return { value: nextValue, caret: nextCaret } + } + if (token.length === 0) + return { value: `${before}${token}${after}`, caret: (before + token).length, suggestions: filtered } + const common = longestCommonPrefix(filtered) + if (common && common.length > token.length) { + const nextToken = common + const nextValue = `${before}${nextToken}${after}` + const nextCaret = (before + nextToken).length + return { value: nextValue, caret: nextCaret } + } + return { value: `${before}${token}${after}`, caret: (before + token).length, suggestions: filtered } +}Then replace both functions:
function completeAchievementSubcommands(token: string, before: string, after: string): CompletionResult | null { return completeSubcommands(token, before, after, getAchievementSubcommands) } function completeConfettiSubcommands(token: string, before: string, after: string): CompletionResult | null { return completeSubcommands(token, before, after, getConfettiSubcommands) }src/utils/console/confetti.ts (1)
3-8: Deduplicate confetti type literals.
ConfettiTypeandgetConfettiSubcommands()both hardcode the same string list; keeping two sources in sync is brittle. Hoisting the literals into a singleconsttuple lets the type alias and completion helper share the same source of truth.-type ConfettiType = 'default' | 'corners' | 'top' | 'center' - -// Get available confetti subcommands for completion -export function getConfettiSubcommands(): string[] { - return ['default', 'corners', 'top', 'center'] -} +const CONFETTI_TYPES = ['default', 'corners', 'top', 'center'] as const +type ConfettiType = (typeof CONFETTI_TYPES)[number] + +// Get available confetti subcommands for completion +export function getConfettiSubcommands(): string[] { + return [...CONFETTI_TYPES] +}Also applies to: 26-33
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (30)
src/components/providers/confetti-provider.tsx(1 hunks)src/components/secret-console/secret-console.tsx(8 hunks)src/lib/secret-console-files.ts(1 hunks)src/lib/storage-keys.ts(1 hunks)src/types/secret-console.d.ts(3 hunks)src/utils/console/__tests__/cat.test.ts(1 hunks)src/utils/console/__tests__/cd.test.ts(2 hunks)src/utils/console/__tests__/clear.test.ts(1 hunks)src/utils/console/__tests__/completion.test.ts(4 hunks)src/utils/console/__tests__/head.test.ts(3 hunks)src/utils/console/__tests__/ls.test.ts(1 hunks)src/utils/console/__tests__/pwd.test.ts(1 hunks)src/utils/console/__tests__/tail.test.ts(1 hunks)src/utils/console/__tests__/test-utils.ts(2 hunks)src/utils/console/__tests__/tree.test.ts(1 hunks)src/utils/console/__tests__/uname.test.ts(1 hunks)src/utils/console/__tests__/uptime.test.ts(1 hunks)src/utils/console/__tests__/wc.test.ts(1 hunks)src/utils/console/cat.ts(1 hunks)src/utils/console/clear.ts(1 hunks)src/utils/console/completion.ts(3 hunks)src/utils/console/confetti.ts(1 hunks)src/utils/console/head.ts(1 hunks)src/utils/console/index.ts(2 hunks)src/utils/console/tail.ts(1 hunks)src/utils/console/tree.ts(1 hunks)src/utils/console/uname.ts(1 hunks)src/utils/console/uptime.ts(1 hunks)src/utils/console/wc.ts(1 hunks)src/utils/secret-console-vfs.ts(4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,cjs,mjs}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
**/*.{ts,tsx,js,jsx,cjs,mjs}: Never hardcode or hallucinate the PostHog API key; always read it from the value populated in the .env file
Create new feature flag names that are clear and descriptive
Gate flag-dependent code on a check that verifies the flag’s values are valid and expected
If a custom property for a person or event is referenced in two or more files or in two or more callsites within the same file, centralize the property name in an enum (TS) or const object (JS)
Files:
src/utils/console/__tests__/tail.test.tssrc/utils/console/uptime.tssrc/utils/console/__tests__/ls.test.tssrc/utils/console/tail.tssrc/utils/console/completion.tssrc/components/providers/confetti-provider.tsxsrc/utils/console/head.tssrc/utils/console/__tests__/head.test.tssrc/utils/console/tree.tssrc/utils/console/__tests__/cat.test.tssrc/utils/console/__tests__/wc.test.tssrc/utils/console/__tests__/completion.test.tssrc/utils/console/uname.tssrc/utils/console/__tests__/clear.test.tssrc/types/secret-console.d.tssrc/utils/console/__tests__/cd.test.tssrc/lib/storage-keys.tssrc/utils/console/cat.tssrc/utils/console/__tests__/pwd.test.tssrc/utils/console/index.tssrc/utils/console/__tests__/test-utils.tssrc/utils/console/wc.tssrc/utils/console/__tests__/uptime.test.tssrc/utils/console/__tests__/tree.test.tssrc/utils/console/confetti.tssrc/utils/secret-console-vfs.tssrc/utils/console/clear.tssrc/utils/console/__tests__/uname.test.tssrc/lib/secret-console-files.tssrc/components/secret-console/secret-console.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
In TypeScript, store feature flag names in an enum with members written in UPPERCASE_WITH_UNDERSCORE and use a consistent naming convention
Files:
src/utils/console/__tests__/tail.test.tssrc/utils/console/uptime.tssrc/utils/console/__tests__/ls.test.tssrc/utils/console/tail.tssrc/utils/console/completion.tssrc/components/providers/confetti-provider.tsxsrc/utils/console/head.tssrc/utils/console/__tests__/head.test.tssrc/utils/console/tree.tssrc/utils/console/__tests__/cat.test.tssrc/utils/console/__tests__/wc.test.tssrc/utils/console/__tests__/completion.test.tssrc/utils/console/uname.tssrc/utils/console/__tests__/clear.test.tssrc/types/secret-console.d.tssrc/utils/console/__tests__/cd.test.tssrc/lib/storage-keys.tssrc/utils/console/cat.tssrc/utils/console/__tests__/pwd.test.tssrc/utils/console/index.tssrc/utils/console/__tests__/test-utils.tssrc/utils/console/wc.tssrc/utils/console/__tests__/uptime.test.tssrc/utils/console/__tests__/tree.test.tssrc/utils/console/confetti.tssrc/utils/secret-console-vfs.tssrc/utils/console/clear.tssrc/utils/console/__tests__/uname.test.tssrc/lib/secret-console-files.tssrc/components/secret-console/secret-console.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-03T00:48:27.729Z
Learnt from: kiliantyler
PR: kiliantyler/kil.dev#103
File: src/components/providers/confetti-provider.tsx:214-314
Timestamp: 2025-10-03T00:48:27.729Z
Learning: In src/components/providers/confetti-provider.tsx, the `triggerConfettiChaos` function intentionally creates an infinite confetti loop with no exit condition. This is a deliberate easter egg feature triggered after 20 clicks, and the resource usage is expected behavior. The warning toasts inform users that the only way to stop it is by reloading the page.
Applied to files:
src/components/providers/confetti-provider.tsx
🧬 Code graph analysis (22)
src/utils/console/__tests__/tail.test.ts (2)
src/utils/console/tail.ts (1)
tail(48-53)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/uptime.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/__tests__/ls.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/ls.ts (1)
ls(9-14)
src/utils/console/completion.ts (1)
src/utils/console/confetti.ts (1)
getConfettiSubcommands(6-8)
src/utils/console/__tests__/head.test.ts (2)
src/utils/console/head.ts (1)
head(47-52)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/tree.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/__tests__/cat.test.ts (1)
src/utils/console/cat.ts (1)
cat(26-31)
src/utils/console/__tests__/wc.test.ts (2)
src/utils/console/wc.ts (1)
wc(29-34)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/__tests__/completion.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/secret-console-vfs.ts (1)
normalizePath(8-29)
src/utils/console/__tests__/clear.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/clear.ts (1)
clear(7-13)
src/utils/console/__tests__/cd.test.ts (2)
src/utils/console/cd.ts (2)
cd(20-25)formatCdNotDirectory(3-5)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/__tests__/pwd.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/pwd.ts (1)
pwd(7-12)
src/utils/console/index.ts (1)
src/types/secret-console.d.ts (1)
SecretConsoleCommand(12-35)
src/utils/console/__tests__/test-utils.ts (3)
src/utils/secret-console-vfs.ts (5)
normalizePath(8-29)vfsList(49-62)vfsRead(64-69)vfsStat(71-83)vfsResolve(36-47)src/types/secret-console.d.ts (1)
SecretConsoleEnv(1-10)src/lib/secret-console-files.ts (1)
SECRET_CONSOLE_VFS(9-561)
src/utils/console/__tests__/uptime.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/uptime.ts (1)
uptime(53-58)
src/utils/console/__tests__/tree.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/tree.ts (1)
tree(146-151)
src/utils/console/confetti.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/secret-console-vfs.ts (6)
src/types/secret-console.d.ts (2)
VfsNode(48-48)VfsStat(50-55)src/lib/storage-keys.ts (1)
LOCAL_STORAGE_KEYS(7-28)src/utils/theme-runtime.ts (1)
getAvailableThemes(84-108)src/utils/achievements.ts (1)
parseUnlockedStorage(68-76)src/lib/achievements.ts (2)
ACHIEVEMENTS(6-159)AchievementId(161-161)src/lib/secret-console-commands.ts (1)
SECRET_CONSOLE_COMMANDS(3-3)
src/utils/console/clear.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/__tests__/uname.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/uname.ts (1)
uname(44-49)
src/lib/secret-console-files.ts (2)
src/types/secret-console.d.ts (1)
VfsNode(48-48)src/utils/secret-console-vfs.ts (4)
binChildren(190-192)getThemeCacheContent(93-116)getUnlockedAchievementFiles(118-143)getAchievementProgressContent(145-188)
src/components/secret-console/secret-console.tsx (4)
src/types/secret-console.d.ts (2)
VfsNode(48-48)SecretConsoleEnv(1-10)src/lib/secret-console-files.ts (1)
SECRET_CONSOLE_VFS(9-561)src/lib/storage-keys.ts (1)
SESSION_STORAGE_KEYS(31-47)src/utils/secret-console-vfs.ts (4)
vfsRead(64-69)vfsList(49-62)normalizePath(8-29)vfsStat(71-83)
🪛 GitHub Actions: CI - Lighthouse
src/components/secret-console/secret-console.tsx
[error] 141-145: ESLint: unicorn/prefer-global-this — Prefer globalThis over window (lines 141-145).
🪛 GitHub Actions: Lint
src/components/secret-console/secret-console.tsx
[error] 141-141: ESLint: unicorn/prefer-global-this. Prefer globalThis over window.
🪛 GitHub Check: lint
src/components/secret-console/secret-console.tsx
[failure] 145-145:
Prefer globalThis over window
[failure] 144-144:
Prefer globalThis over window
[failure] 142-142:
Prefer globalThis over window
[failure] 141-141:
Prefer globalThis over window
🔇 Additional comments (29)
src/utils/console/__tests__/cd.test.ts (2)
8-10: LGTM: absolute path cdGood coverage for absolute path; empty output and updated cwd assertions are correct.
32-44: LGTM: tilde expansion tests; confirm default cd semanticsThe new tests for ~ and
/… expansion look solid. One question: cd with no args currently lands on /home (per the other test). Typical shells resolve cd to the user’s home (, i.e., /home/kil here). If intentional, ignore; otherwise consider aligning cd [] with cd ~.src/types/secret-console.d.ts (1)
3-3: Type surface aligns with richer VFS and console envThe additions (clearOutput, stat, functional children, VfsStat) look consistent with usage in VFS and tests. No issues found.
Also applies to: 7-7, 19-29, 37-55
src/utils/console/__tests__/pwd.test.ts (1)
9-9: LGTM: expectations match env initial cwdUpdated assertions to /home/kil align with createMockEnv’s default.
Also applies to: 15-15
src/utils/console/__tests__/clear.test.ts (1)
5-32: LGTM! Well-structured test coverage.The test cases properly verify the clear command's core behavior: removing output and ignoring arguments. The use of
createMockEnvand assertions on output length are appropriate.src/utils/console/__tests__/uname.test.ts (1)
9-22: LGTM! Test expectations updated correctly.The test expectations now properly reflect the new VFS-backed implementation where
unamereads from/etc/os-releaseand/etc/hostnamerather than using hardcoded values.src/utils/console/index.ts (1)
5-46: LGTM! New commands properly registered.The four new commands (
clear,confetti,tree,uptime) are correctly imported and added to the command registry, maintaining consistency with existing command registration patterns.src/components/providers/confetti-provider.tsx (1)
362-409: LGTM! Robust event handling with proper validation.The event listener implementation correctly:
- Validates that the event is a CustomEvent
- Performs runtime type checking on
event.detailstructure- Logs warnings for unexpected types or invalid data
- Includes all trigger callbacks in the effect dependencies
- Properly cleans up the event listener
src/utils/console/clear.ts (1)
1-13: LGTM! Clean implementation.The clear command implementation is concise and correct. The use of
_argsprefix properly indicates the parameter is intentionally unused, and the completion configuration appropriately restricts positional arguments. Theclsalias provides good cross-platform familiarity.src/utils/console/__tests__/cat.test.ts (1)
8-11: Good refactor to presence-based validation.The shift from exact content matching to presence checks (using
toContain) makes the test more resilient to non-breaking changes in the file content while still validating the essential requirements.src/utils/console/__tests__/ls.test.ts (1)
9-25: Test improvements aligned with VFS expansion.The updated assertions using
toContainfor specific directory entries make the tests more maintainable as the VFS structure evolves, while continuing to validate the core listing behavior.src/utils/console/__tests__/tail.test.ts (1)
8-26: LGTM! Validation correctly balances specificity and flexibility.The combination of presence checks and line count validation (using
toBeLessThanOrEqualat Line 19) appropriately tests the-nflag behavior without over-constraining the output format.src/utils/console/__tests__/wc.test.ts (1)
8-21: Correct validation of wc output structure.The test correctly validates the standard wc output format (lines, words, bytes, filename) by splitting on spaces and checking for 4 parts, ensuring the command adheres to its contract.
src/utils/console/completion.ts (1)
413-413: Completion integration looks correct.The confetti-subcommands mode is properly integrated into the completion flow, maintaining consistency with the existing achievement-subcommands pattern.
src/lib/storage-keys.ts (1)
42-46: Well-documented session storage keys.The new console state keys follow the established naming convention and are appropriately scoped to sessionStorage for transient state that should reset on page reload. The inline documentation clearly explains the persistence behavior.
src/utils/console/__tests__/tree.test.ts (1)
1-92: Comprehensive test coverage for tree command.The test suite thoroughly validates the tree command functionality:
- Basic rendering and structure validation
- Flag behavior (
-Lfor depth,-dfor directories-only)- Error handling for invalid paths and non-directory targets
- Flag combinations
The depth validation approach at Line 44 (checking for absence of double indentation) is particularly clever, and the flexible regex patterns at Lines 33 and 55 handle both singular and plural forms gracefully.
src/utils/console/__tests__/completion.test.ts (2)
82-98: Test updates align with new VFS structure.The test correctly verifies relative path completion from
/home/kil/projectstowardkil.dev/. The updated assertions properly check for prefix matching and substring inclusion.
100-116: Folder completion test properly validates new home directory.The test correctly expects completion toward
/home/kil/Documents/or/home/kil/Downloads/from the prefix/home/kil/Do. The assertions appropriately verify both the prefix and caret positioning.src/utils/console/__tests__/test-utils.ts (2)
1-18: VFS integration properly implemented.The mock environment correctly integrates with SECRET_CONSOLE_VFS and implements path resolution consistent with the real environment. The
resolvePathhelper properly handles absolute, tilde, and relative paths.
24-39: Environment methods correctly updated.All VFS operations (
list,read,stat,chdir) now use the centralizedresolvePathhelper and delegate to the corresponding VFS functions. The newclearOutputmethod properly clears the output array.src/utils/console/tree.ts (3)
1-44: Argument parsing properly implemented.The
parseTreeArgsfunction correctly handles the-Lflag for depth and-dflag for directories-only mode. Flag parsing correctly increments the index and validates numeric inputs.
46-103: Tree building logic is sound.The recursive
buildTreefunction properly:
- Respects the depth limit
- Filters children based on
dirsOnlyoption- Sorts directories before files, then alphabetically
- Tracks directory and file counts
- Handles path construction for root and non-root directories (line 96)
105-151: Command execution and export are correct.The
executeTreefunction properly validates the target path, checks for directories, and formats the output with appropriate summary statistics. The completion configuration correctly specifies'paths'for tab completion support.src/components/secret-console/secret-console.tsx (6)
13-17: Entry type and prompt formatting properly implemented.The updated
Entrytype includes the optionalcwdfield, andformatPromptcorrectly replaces/home/kilwith~for a cleaner prompt display.
21-90: Session storage initialization correctly implemented.All state (entries, history, cwd, height) is properly initialized from
sessionStoragewith appropriate fallbacks and error handling. The MOTD is correctly loaded from the VFS when no saved entries exist.
111-138: Resize drag handlers are well-implemented.The drag handlers properly track mouse movement and calculate height in viewport units with appropriate bounds (30-95 vh). The implementation follows React best practices with proper event handling.
183-216: State persistence properly implemented.All effects correctly persist state to
sessionStoragewith appropriate error handling. This ensures the console maintains its state across interactions during a session.
222-248: Environment object correctly updated.The
envobject properly implements:
- The new
clearOutputmethod- Path resolution with tilde expansion support
- Integration with VFS functions for
list,read,stat- Directory change handling with proper validation
The path resolution correctly handles absolute, tilde, and relative paths by checking prefixes and using
normalizePath.
372-421: UI interactions properly implemented.The component correctly:
- Prevents input focus when interacting with the resize handle (lines 373-380)
- Includes cwd-aware prompts in entry rendering (line 392) and input display (line 399)
- Implements the resize handle with appropriate ARIA labels and visual feedback (lines 414-421)
… listeners and viewport height
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
src/utils/console/confetti.ts (1)
3-8: Consider deriving the subcommands array from the type to maintain single source of truth.The
ConfettiTypeunion andgetConfettiSubcommands()array duplicate the same four values. If you add/remove a confetti type, you must update both locations.Apply this pattern to derive the array from a const assertion:
-type ConfettiType = 'default' | 'corners' | 'top' | 'center' +const CONFETTI_TYPES = ['default', 'corners', 'top', 'center'] as const +type ConfettiType = (typeof CONFETTI_TYPES)[number] // Get available confetti subcommands for completion export function getConfettiSubcommands(): string[] { - return ['default', 'corners', 'top', 'center'] + return [...CONFETTI_TYPES] }src/utils/console/cat.ts (1)
13-17: Consider extracting the binary-file guard to reduce duplication.This guard pattern appears in
cat.ts,head.ts,tail.ts, andwc.ts. Extracting it to a helper would ensure consistency and simplify maintenance.Example helper:
function checkBinaryFile( target: string, commandName: string, env: SecretConsoleEnv ): boolean { const stat = env.stat(target) if (stat && stat.kind === 'file' && stat.binary) { env.appendOutput(`${commandName}: ${target}: Is a binary file`) return true } return false }Usage in each command:
- const stat = env.stat(target) - if (stat && stat.kind === 'file' && stat.binary) { - env.appendOutput(`cat: ${target}: Is a binary file`) + if (checkBinaryFile(target, 'cat', env)) { return - }src/utils/console/__tests__/tail.test.ts (1)
43-53: Inconsistent file path usage in error tests.Lines 43 and 53 still reference
/home/README.md, while other tests use the updated VFS paths like/home/kil/Documents/bookmarks.mdand/home/kil/.profile.For consistency with the rest of the test suite, consider updating these paths as well, even though the tests focus on flag parsing errors rather than file reading.
Apply this diff to align with updated paths:
- tail.execute(['-n', 'invalid', '/home/README.md'], env) + tail.execute(['-n', 'invalid', '/home/kil/.bashrc'], env)And:
- tail.execute(['-n', '0', '/home/README.md'], env) + tail.execute(['-n', '0', '/home/kil/.bashrc'], env)src/components/secret-console/secret-console.tsx (2)
130-138: Persist height when resizing ends.Height is saved on every mousemove while dragging, causing dozens of writes per frame. Persist only on drag end (or debounce) to avoid thrashing sessionStorage.
228-247: Repeated path resolution logic.The
path.startsWith('/') || path.startsWith('~') ? …pattern is duplicated for list/read/stat/chdir. Extract a helper (e.g.,resolvePath(path, cwd)) for clarity and fewer mistakes if this logic changes later.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (30)
src/components/providers/confetti-provider.tsx(1 hunks)src/components/secret-console/secret-console.tsx(8 hunks)src/lib/secret-console-files.ts(1 hunks)src/lib/storage-keys.ts(1 hunks)src/types/secret-console.d.ts(3 hunks)src/utils/console/__tests__/cat.test.ts(1 hunks)src/utils/console/__tests__/cd.test.ts(2 hunks)src/utils/console/__tests__/clear.test.ts(1 hunks)src/utils/console/__tests__/completion.test.ts(4 hunks)src/utils/console/__tests__/head.test.ts(3 hunks)src/utils/console/__tests__/ls.test.ts(1 hunks)src/utils/console/__tests__/pwd.test.ts(1 hunks)src/utils/console/__tests__/tail.test.ts(1 hunks)src/utils/console/__tests__/test-utils.ts(2 hunks)src/utils/console/__tests__/tree.test.ts(1 hunks)src/utils/console/__tests__/uname.test.ts(1 hunks)src/utils/console/__tests__/uptime.test.ts(1 hunks)src/utils/console/__tests__/wc.test.ts(1 hunks)src/utils/console/cat.ts(1 hunks)src/utils/console/clear.ts(1 hunks)src/utils/console/completion.ts(3 hunks)src/utils/console/confetti.ts(1 hunks)src/utils/console/head.ts(1 hunks)src/utils/console/index.ts(2 hunks)src/utils/console/tail.ts(1 hunks)src/utils/console/tree.ts(1 hunks)src/utils/console/uname.ts(1 hunks)src/utils/console/uptime.ts(1 hunks)src/utils/console/wc.ts(1 hunks)src/utils/secret-console-vfs.ts(4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,cjs,mjs}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
**/*.{ts,tsx,js,jsx,cjs,mjs}: Never hardcode or hallucinate the PostHog API key; always read it from the value populated in the .env file
Create new feature flag names that are clear and descriptive
Gate flag-dependent code on a check that verifies the flag’s values are valid and expected
If a custom property for a person or event is referenced in two or more files or in two or more callsites within the same file, centralize the property name in an enum (TS) or const object (JS)
Files:
src/utils/console/__tests__/pwd.test.tssrc/utils/console/__tests__/cat.test.tssrc/utils/console/__tests__/uname.test.tssrc/utils/console/__tests__/uptime.test.tssrc/utils/console/tree.tssrc/utils/console/index.tssrc/utils/console/tail.tssrc/lib/storage-keys.tssrc/utils/console/__tests__/completion.test.tssrc/utils/console/__tests__/head.test.tssrc/components/providers/confetti-provider.tsxsrc/utils/console/clear.tssrc/utils/console/confetti.tssrc/utils/console/__tests__/wc.test.tssrc/utils/console/__tests__/ls.test.tssrc/utils/console/uptime.tssrc/utils/console/__tests__/clear.test.tssrc/utils/console/cat.tssrc/types/secret-console.d.tssrc/utils/console/completion.tssrc/utils/console/wc.tssrc/utils/console/__tests__/tail.test.tssrc/utils/secret-console-vfs.tssrc/utils/console/head.tssrc/utils/console/__tests__/cd.test.tssrc/utils/console/__tests__/test-utils.tssrc/lib/secret-console-files.tssrc/utils/console/__tests__/tree.test.tssrc/utils/console/uname.tssrc/components/secret-console/secret-console.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
In TypeScript, store feature flag names in an enum with members written in UPPERCASE_WITH_UNDERSCORE and use a consistent naming convention
Files:
src/utils/console/__tests__/pwd.test.tssrc/utils/console/__tests__/cat.test.tssrc/utils/console/__tests__/uname.test.tssrc/utils/console/__tests__/uptime.test.tssrc/utils/console/tree.tssrc/utils/console/index.tssrc/utils/console/tail.tssrc/lib/storage-keys.tssrc/utils/console/__tests__/completion.test.tssrc/utils/console/__tests__/head.test.tssrc/components/providers/confetti-provider.tsxsrc/utils/console/clear.tssrc/utils/console/confetti.tssrc/utils/console/__tests__/wc.test.tssrc/utils/console/__tests__/ls.test.tssrc/utils/console/uptime.tssrc/utils/console/__tests__/clear.test.tssrc/utils/console/cat.tssrc/types/secret-console.d.tssrc/utils/console/completion.tssrc/utils/console/wc.tssrc/utils/console/__tests__/tail.test.tssrc/utils/secret-console-vfs.tssrc/utils/console/head.tssrc/utils/console/__tests__/cd.test.tssrc/utils/console/__tests__/test-utils.tssrc/lib/secret-console-files.tssrc/utils/console/__tests__/tree.test.tssrc/utils/console/uname.tssrc/components/secret-console/secret-console.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-03T00:48:27.729Z
Learnt from: kiliantyler
PR: kiliantyler/kil.dev#103
File: src/components/providers/confetti-provider.tsx:214-314
Timestamp: 2025-10-03T00:48:27.729Z
Learning: In src/components/providers/confetti-provider.tsx, the `triggerConfettiChaos` function intentionally creates an infinite confetti loop with no exit condition. This is a deliberate easter egg feature triggered after 20 clicks, and the resource usage is expected behavior. The warning toasts inform users that the only way to stop it is by reloading the page.
Applied to files:
src/components/providers/confetti-provider.tsx
🧬 Code graph analysis (22)
src/utils/console/__tests__/pwd.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/pwd.ts (1)
pwd(7-12)
src/utils/console/__tests__/cat.test.ts (1)
src/utils/console/cat.ts (1)
cat(26-31)
src/utils/console/__tests__/uname.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/uname.ts (1)
uname(44-49)
src/utils/console/__tests__/uptime.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/uptime.ts (1)
uptime(53-58)
src/utils/console/tree.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/index.ts (1)
src/types/secret-console.d.ts (1)
SecretConsoleCommand(12-35)
src/utils/console/__tests__/completion.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/secret-console-vfs.ts (1)
normalizePath(8-29)
src/utils/console/__tests__/head.test.ts (2)
src/utils/console/head.ts (1)
head(47-52)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/clear.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/confetti.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/__tests__/wc.test.ts (2)
src/utils/console/wc.ts (1)
wc(29-34)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/__tests__/ls.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/ls.ts (1)
ls(9-14)
src/utils/console/uptime.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/utils/console/__tests__/clear.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/clear.ts (1)
clear(7-13)
src/utils/console/completion.ts (1)
src/utils/console/confetti.ts (1)
getConfettiSubcommands(6-8)
src/utils/console/__tests__/tail.test.ts (2)
src/utils/console/tail.ts (1)
tail(48-53)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/secret-console-vfs.ts (6)
src/types/secret-console.d.ts (2)
VfsNode(48-48)VfsStat(50-55)src/lib/storage-keys.ts (1)
LOCAL_STORAGE_KEYS(7-28)src/utils/theme-runtime.ts (1)
getAvailableThemes(84-108)src/utils/achievements.ts (1)
parseUnlockedStorage(68-76)src/lib/achievements.ts (2)
ACHIEVEMENTS(6-159)AchievementId(161-161)src/lib/secret-console-commands.ts (1)
SECRET_CONSOLE_COMMANDS(3-3)
src/utils/console/__tests__/cd.test.ts (2)
src/utils/console/cd.ts (2)
cd(20-25)formatCdNotDirectory(3-5)src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)
src/utils/console/__tests__/test-utils.ts (3)
src/utils/secret-console-vfs.ts (5)
normalizePath(8-29)vfsList(49-62)vfsRead(64-69)vfsStat(71-83)vfsResolve(36-47)src/types/secret-console.d.ts (1)
SecretConsoleEnv(1-10)src/lib/secret-console-files.ts (1)
SECRET_CONSOLE_VFS(9-561)
src/lib/secret-console-files.ts (2)
src/types/secret-console.d.ts (1)
VfsNode(48-48)src/utils/secret-console-vfs.ts (4)
binChildren(190-192)getThemeCacheContent(93-116)getUnlockedAchievementFiles(118-143)getAchievementProgressContent(145-188)
src/utils/console/__tests__/tree.test.ts (2)
src/utils/console/__tests__/test-utils.ts (1)
createMockEnv(5-62)src/utils/console/tree.ts (1)
tree(146-151)
src/components/secret-console/secret-console.tsx (3)
src/types/secret-console.d.ts (2)
VfsNode(48-48)SecretConsoleEnv(1-10)src/lib/storage-keys.ts (1)
SESSION_STORAGE_KEYS(31-47)src/utils/secret-console-vfs.ts (4)
vfsRead(64-69)vfsList(49-62)normalizePath(8-29)vfsStat(71-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lighthouse
🔇 Additional comments (22)
src/utils/console/confetti.ts (3)
11-17: LGTM!The helper provides clear user guidance for available confetti types.
48-56: LGTM!The command configuration is properly structured with appropriate completion settings.
19-46: Event name consistency confirmed The dispatched'kd:trigger-confetti'CustomEvent insrc/utils/console/confetti.tsmatches the listener and removal insrc/components/providers/confetti-provider.tsx.src/utils/console/__tests__/pwd.test.ts (2)
9-9: LGTM!Test expectation correctly updated to match the new default working directory
/home/kilestablished in the test utilities.
15-15: LGTM!Consistent with the first test—correctly expects
/home/kilas the working directory.src/utils/console/__tests__/cat.test.ts (1)
8-11: LGTM!Test updated to read from the expanded VFS path
/home/kil/.bashrcand validates expected content markers. The assertion pattern is appropriate for verifying multi-line output.src/utils/console/tail.ts (1)
33-37: LGTM!The binary-file guard correctly prevents attempting to read binary content as text. The error message is clear and follows Unix conventions.
src/utils/console/head.ts (1)
33-37: LGTM!The binary-file guard is correctly implemented, matching the pattern used in
tail.tsand other file-reading commands.src/utils/console/__tests__/uname.test.ts (3)
9-9: LGTM!Test expectation correctly updated to reflect the new
unameimplementation that reads OS metadata from the VFS.
16-16: LGTM!The regex pattern correctly validates the full system info format with OS name, nodename, and version.
22-22: LGTM!Consistent with the default behavior test—correctly expects
kilOSas the system name.src/utils/console/wc.ts (1)
13-17: LGTM!The binary-file guard is correctly implemented. Note that this pattern is duplicated across
cat.ts,head.ts,tail.ts, andwc.ts—see the refactor suggestion in thecat.tsreview.src/utils/console/__tests__/uptime.test.ts (1)
1-45: LGTM! Comprehensive test coverage for the uptime command.The test suite appropriately covers:
- Display formatting verification
- Load average parsing from
/proc/loadavg- Uptime duration formatting with time units
- Graceful fallback when
/proc/loadavgis unavailableThe assertions use appropriate matchers and the tests exercise both success and error paths.
src/utils/console/__tests__/cd.test.ts (1)
8-44: LGTM! Tests updated to reflect VFS changes and tilde expansion.The test updates appropriately:
- Adapt paths to the new VFS structure (
/home/kil/Documents,/home/kil/.bashrc)- Add coverage for tilde expansion (
~→/home/kil,~/Documents→/home/kil/Documents)The tilde expansion tests are valuable additions that verify shell-like path resolution behavior.
src/utils/console/__tests__/head.test.ts (1)
6-60: LGTM! Test updates improve maintainability.The test updates appropriately:
- Switch to alternative file paths that align with the expanded VFS
- Use looser content assertions (presence checks vs exact string matches), improving maintainability against future content changes
- Maintain comprehensive coverage of flag handling, error cases, and edge conditions
The
-nflag behavior and error handling remain well-tested.src/utils/console/index.ts (1)
5-47: LGTM! Command registry expansion is correct.The new commands (
clear,confetti,tree,uptime) are properly:
- Imported from their respective modules
- Registered in the command registry
- Typed via the
Readonly<typeof registry>patternThe registry structure and initialization order are maintained correctly.
src/utils/console/__tests__/tail.test.ts (1)
8-39: LGTM! Test updates align with VFS changes.The test updates appropriately:
- Adapt to the new VFS structure with updated file paths
- Use presence-based assertions instead of exact content matching
- Maintain comprehensive coverage of default behavior, custom line counts, and error handling
src/utils/console/__tests__/clear.test.ts (1)
1-32: LGTM! Clear and focused tests for the clear command.The test suite appropriately covers:
- Basic clearing functionality (output length goes from 3 to 0)
- Argument handling (arguments are ignored as expected)
The tests are simple, readable, and verify the command's core behavior correctly.
src/lib/storage-keys.ts (1)
42-46: LGTM! Session storage keys follow established conventions.The new console state keys:
- Follow the consistent
kd_naming prefix- Are appropriately placed in
SESSION_STORAGE_KEYS(state persists during session, resets on page reload)- Are well-documented with inline comments
- Align with the console persistence requirements described in the PR objectives
src/components/providers/confetti-provider.tsx (2)
362-409: Robust event handling with thorough validation.The event listener implementation correctly:
- Adds and cleans up the listener on mount/unmount
- Validates
event.detailstructure before use (object with stringtypeproperty)- Dispatches to the appropriate trigger functions based on type
- Logs warnings for unexpected types to aid debugging
The dependencies array correctly includes all trigger functions referenced in the handler.
386-402: Console command intentionally supports only the four basic types
Theconfetticonsole command and its subcommands (default,corners,top,center) are deliberately limited to those four modes. Thecelebrationandchaostriggers are exposed only via the React context hooks for programmatic/UI use, not via the console.src/components/secret-console/secret-console.tsx (1)
183-219: Persisting after each mutation suffices.Nice touch persisting entries, history, cwd, and height in sessionStorage with safe guards around storage failures. Looks solid.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/components/secret-console/secret-console.tsx (1)
140-150: Past review comment already addressed.The code already uses
globalThis.addEventListenerandglobalThis.removeEventListeneras suggested in the previous review. The implementation is correct and follows the codebase style.
🧹 Nitpick comments (1)
src/components/secret-console/secret-console.tsx (1)
184-191: Consider capping entries array to prevent unbounded growth.History is capped at 50 entries (line 360), but the
entriesarray has no size limit. During a long session with extensive output, this could lead to large sessionStorage consumption and potential performance degradation when serializing/deserializing the array.Consider adding a cap when persisting entries, similar to history:
useEffect(() => { try { - sessionStorage.setItem(SESSION_STORAGE_KEYS.CONSOLE_ENTRIES, JSON.stringify(entries)) + const cappedEntries = entries.length > 500 ? entries.slice(-500) : entries + sessionStorage.setItem(SESSION_STORAGE_KEYS.CONSOLE_ENTRIES, JSON.stringify(cappedEntries)) } catch { // Ignore storage errors } }, [entries])Alternatively, cap when adding entries rather than when persisting.
Also applies to: 358-361
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/secret-console/secret-console.tsx(8 hunks)src/utils/console/__tests__/uptime.test.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/utils/console/tests/uptime.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,cjs,mjs}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
**/*.{ts,tsx,js,jsx,cjs,mjs}: Never hardcode or hallucinate the PostHog API key; always read it from the value populated in the .env file
Create new feature flag names that are clear and descriptive
Gate flag-dependent code on a check that verifies the flag’s values are valid and expected
If a custom property for a person or event is referenced in two or more files or in two or more callsites within the same file, centralize the property name in an enum (TS) or const object (JS)
Files:
src/components/secret-console/secret-console.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
In TypeScript, store feature flag names in an enum with members written in UPPERCASE_WITH_UNDERSCORE and use a consistent naming convention
Files:
src/components/secret-console/secret-console.tsx
🧬 Code graph analysis (1)
src/components/secret-console/secret-console.tsx (4)
src/types/secret-console.d.ts (2)
VfsNode(48-48)SecretConsoleEnv(1-10)src/lib/secret-console-files.ts (1)
SECRET_CONSOLE_VFS(9-561)src/lib/storage-keys.ts (1)
SESSION_STORAGE_KEYS(31-47)src/utils/secret-console-vfs.ts (4)
vfsRead(64-69)vfsList(49-62)normalizePath(8-29)vfsStat(71-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lighthouse
🔇 Additional comments (1)
src/components/secret-console/secret-console.tsx (1)
23-91: Excellent implementation of console persistence and resize features.The implementation demonstrates several strengths:
- SSR-safe: All browser API access is properly guarded with
globalThis.windowchecks- Error handling: Consistent try-catch blocks around sessionStorage operations with graceful fallbacks
- Path resolution: Correctly handles absolute (
/), tilde (~), and relative paths across all VFS operations- Drag mechanics: Math for vh-based height calculation is correct, with appropriate bounds [30, 95]
- React patterns: Proper use of hooks, memoization, and dependency arrays
The code is well-organized, readable, and properly integrated with the expanded VFS system.
Also applies to: 112-150, 184-219, 229-251
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
src/components/secret-console/secret-console.tsx (4)
60-75: Consider usingclearConsoleSessionStoragefor consistency.Unlike the entries initialization which calls
clearConsoleSessionStorage()on parse failure, this only removes the history key. For consistency and to prevent potential state inconsistencies, consider using the centralized clearing function here as well.Apply this diff for consistency:
} catch (error) { - // Clean up corrupted history state console.warn('Failed to parse console history from sessionStorage, clearing:', error) - sessionStorage.removeItem(SESSION_STORAGE_KEYS.CONSOLE_HISTORY) + clearConsoleSessionStorage() }
77-92: Consider usingclearConsoleSessionStoragefor consistency.Same as with history initialization, consider using the centralized clearing function to maintain consistent recovery behavior across all console state.
Apply this diff:
} catch (error) { - // Clean up corrupted cwd state console.warn('Failed to read console cwd from sessionStorage, clearing:', error) - sessionStorage.removeItem(SESSION_STORAGE_KEYS.CONSOLE_CWD) + clearConsoleSessionStorage() }
94-113: Consider usingclearConsoleSessionStoragefor consistency.While the validation logic for height bounds is good, consider using the centralized clearing function on parse failure for consistency with the entries initialization.
Apply this diff:
} catch (error) { - // Clean up corrupted height state console.warn('Failed to parse console height from sessionStorage, clearing:', error) - sessionStorage.removeItem(SESSION_STORAGE_KEYS.CONSOLE_HEIGHT) + clearConsoleSessionStorage() }
233-241: Remove unnecessary type cast.The
SESSION_STORAGE_KEYS.CONSOLE_HEIGHTis already typed as a string, so the explicit cast is unnecessary.Apply this diff:
try { - const key = SESSION_STORAGE_KEYS.CONSOLE_HEIGHT as string - sessionStorage.setItem(key, height.toString()) + sessionStorage.setItem(SESSION_STORAGE_KEYS.CONSOLE_HEIGHT, height.toString()) } catch {src/utils/console/tree.ts (2)
35-41: Multiple non-flag arguments overwrite the path.If a user passes multiple path arguments (e.g.,
tree foo bar), the last one silently overwrites previous values. Consider either:
- Rejecting multiple paths with an error message, or
- Documenting that the last path argument wins
Example fix to reject multiple paths:
// Treat as path if it doesn't start with - if (!arg.startsWith('-')) { + if (path !== '.') { + // Path already set + return { path: '', options } // Signal error to caller + } path = arg }Then in
executeTree, check for empty path and emit an error.
20-27: Consider allowing-L 0to display only the root.The Unix
treecommand accepts-L 0to display only the root directory. The current checkdepth > 0(line 22) silently ignores-L 0, keeping the default depth of 3. Consider either:
- Allowing
depth >= 0and treating 0 as "root only", or- Explicitly rejecting invalid depth values with an error message
Example to allow
-L 0:- if (!Number.isNaN(depth) && depth > 0) { + if (!Number.isNaN(depth) && depth >= 0) { options.maxDepth = depth }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/secret-console/secret-console.tsx(8 hunks)src/utils/console/tree.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,cjs,mjs}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
**/*.{ts,tsx,js,jsx,cjs,mjs}: Never hardcode or hallucinate the PostHog API key; always read it from the value populated in the .env file
Create new feature flag names that are clear and descriptive
Gate flag-dependent code on a check that verifies the flag’s values are valid and expected
If a custom property for a person or event is referenced in two or more files or in two or more callsites within the same file, centralize the property name in an enum (TS) or const object (JS)
Files:
src/utils/console/tree.tssrc/components/secret-console/secret-console.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
In TypeScript, store feature flag names in an enum with members written in UPPERCASE_WITH_UNDERSCORE and use a consistent naming convention
Files:
src/utils/console/tree.tssrc/components/secret-console/secret-console.tsx
🧬 Code graph analysis (2)
src/utils/console/tree.ts (1)
src/types/secret-console.d.ts (2)
SecretConsoleEnv(1-10)SecretConsoleCommand(12-35)
src/components/secret-console/secret-console.tsx (3)
src/lib/storage-keys.ts (1)
SESSION_STORAGE_KEYS(31-47)src/types/secret-console.d.ts (2)
VfsNode(48-48)SecretConsoleEnv(1-10)src/utils/secret-console-vfs.ts (4)
vfsRead(64-69)vfsList(49-62)normalizePath(8-29)vfsStat(71-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lighthouse
🔇 Additional comments (11)
src/components/secret-console/secret-console.tsx (8)
15-17: LGTM!The tilde substitution logic correctly uses a positive lookahead to match
/home/kilonly when followed by/or at the end of the string, preventing false matches on paths like/home/kilroy.
19-31: Good recovery mechanism for corrupted state.This helper function addresses the previous review concern about corrupted sessionStorage by providing a centralized way to clear all console-related keys when corruption is detected.
37-58: Excellent error handling for corrupted session data.This implementation addresses the previous review concern by:
- Clearing all corrupted console keys when JSON.parse fails
- Logging warnings for debugging
- Gracefully falling back to MOTD display
134-142: LGTM!The drag start handler correctly prevents default browser behavior and captures the initial state for the resize operation.
144-156: LGTM!The drag move calculation correctly converts pixel deltas to viewport height units and enforces the specified bounds [30vh, 95vh].
251-273: Excellent cwd-aware VFS integration.The environment object properly handles absolute paths (
/), tilde paths (~), and relative paths by checking prefixes and prepending cwd when needed. All operations consistently usenormalizePathand the cachedrootVfsreference.
397-405: Good UX pattern for preventing unwanted focus.The click handlers correctly prevent input focus when interacting with the resize handle, using a clean data-attribute selector for target detection.
439-446: LGTM!The resize handle includes proper accessibility labeling and clear visual affordances with hover states. The data attribute allows clean event handler logic.
src/utils/console/tree.ts (3)
1-6: LGTM! Clean structure and appropriate type definitions.The imports, type definitions, and command export are well-structured. The completion configuration correctly specifies path completion and supported flags.
Also applies to: 146-151
105-126: Path resolution and validation logic looks correct.The path resolution (line 109) properly handles the current directory, and the error handling for non-existent paths (lines 112-116) and non-directories (lines 118-121) provides clear user feedback.
73-77: Sorting logic correctly prioritizes directories.The sort implementation properly orders directories before files and uses alphabetical sorting within each group, matching expected
treecommand behavior.


Summary by CodeRabbit
New Features
Bug Fixes
Tests