feat: add VS Code IDE bridge extension#213
feat: add VS Code IDE bridge extension#213suger-m wants to merge 2 commits intoclaude-code-best:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a new VS Code extension package Changes
Sequence Diagram(s)sequenceDiagram
participant VSCode as VSCode
participant Ext as Extension
participant Service as LocalIdeBridgeService
participant WS as WebSocketServer
participant MCP as MCPServer
participant CLI as ClaudeCode CLI
participant Diff as DiffController
VSCode->>Ext: activate()
Ext->>Service: start()
Service->>WS: listen on ephemeral port
Service->>Service: write lockfile (port, auth token)
VSCode->>Ext: editor selection/change
Ext->>Service: publishActiveSelection()
Service->>MCP: notifySelectionChanged()
MCP-->>CLI: selection_changed notification
CLI->>WS: connect (X-Claude-Code-Ide-Authorization header)
WS->>Service: new connection
Service->>Service: validate auth, attach transport
Service->>MCP: attach transport -> MCP ready
CLI->>MCP: CallTool openDiff
MCP->>Diff: openDiff(args)
Diff->>VSCode: show diff tab
alt user saves file
VSCode->>Diff: file saved -> settle (FILE_SAVED)
Diff-->>MCP: tool result
else user closes tab / closeTab call
CLI->>MCP: closeTab
MCP->>Diff: closeTab -> settle (SETTLED)
Diff-->>MCP: tool result
end
VSCode->>Ext: deactivate()
Ext->>Service: dispose()
Service->>WS: close server
Service->>Service: remove lockfile
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (7)
packages/vscode-ide-bridge/tsconfig.json (1)
12-14: Use official type packages instead ofanystubs.With only
"bun"intypes, this setup loses meaningful checking for VS Code and Node APIs and encourages ambientanydeclarations. Prefer adding official typings and listing them here.💡 Proposed fix
"types": [ - "bun" + "bun", + "node", + "vscode" ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/tsconfig.json` around lines 12 - 14, The tsconfig.json "types" array only includes "bun", which causes missing type coverage for VS Code and Node APIs; update the "types" array in tsconfig.json to include the official ambient packages such as "node" and "vscode" (and keep "bun" if still needed) and ensure the corresponding packages are installed (e.g., `@types/node` or the official vscode typings) so the project uses correct official type definitions instead of ambient any stubs.packages/vscode-ide-bridge/test/selectionPublisher.test.ts (1)
13-16: Strengthen selection assertions to cover all coordinates.Current checks only validate
start.lineandend.character; regressions instart.characterorend.linewould slip through.✅ Suggested test tightening
- expect(params.selection?.start.line).toBe(10) - expect(params.selection?.end.character).toBe(17) + expect(params.selection).toEqual({ + start: { line: 10, character: 2 }, + end: { line: 10, character: 17 }, + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/test/selectionPublisher.test.ts` around lines 13 - 16, The test in selectionPublisher.test.ts only asserts params.selection?.start.line and params.selection?.end.character, leaving start.character and end.line untested; update the assertions on the params object to verify all four selection coordinates by adding checks for params.selection?.start.character and params.selection?.end.line alongside the existing expectations for start.line and end.character so the test validates start.line, start.character, end.line, and end.character.packages/vscode-ide-bridge/test/workspaceInfo.test.ts (1)
37-40: Assert the fullselectionpayload, not just one field.Only checking
snapshot.selection?.start.lineleavesstart.character,end.line, andend.characterunverified.✅ Suggested assertion update
- expect(snapshot.selection?.start.line).toBe(3) + expect(snapshot.selection).toEqual({ + start: { line: 3, character: 1 }, + end: { line: 5, character: 0 }, + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/test/workspaceInfo.test.ts` around lines 37 - 40, The test only asserts snapshot.selection?.start.line; update the assertion to verify the entire selection payload by replacing the single-field check with an equality check against an expected selection object (include start.line, start.character, end.line, end.character). Locate the snapshot variable in workspaceInfo.test.ts and use a deep equality assertion (e.g., expect(snapshot.selection).toEqual(expectedSelection)) or toMatchObject with an explicit expectedSelection you construct with the correct numeric values.packages/vscode-ide-bridge/test/bridgeServer.test.ts (1)
111-128: Guard notification wait with a timeout to avoid hung test runs.If the notification is never emitted, this Promise can hang indefinitely. Wrapping it with a bounded timeout will make failures deterministic and easier to debug.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/test/bridgeServer.test.ts` around lines 111 - 128, The test's notificationPromise (created with client.setNotificationHandler and SelectionChangedSchema) can hang forever if no notification arrives; wrap or replace it with a timeout-guarded promise (e.g., race the handler promise with a timer that rejects or fails after a short timeout) and then await that guarded promise instead of notificationPromise; ensure the timeout includes a descriptive error so bridge.notifySelectionChanged failures yield deterministic test failures.packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts (1)
21-71: Add unhappy-path transport tests for open-state and callback errors.Current tests only validate the happy path. Please add coverage for:
start()whenreadyState !== 1,send()callback errors, andclose()cleanup/listener detachment to protect regressions in transport reliability paths.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts` around lines 21 - 71, Add tests for ServerWebSocketTransport unhappy paths: 1) start() when the FakeWebSocket.readyState is not 1 (e.g., 0 or 3) should reject or throw — set socket.readyState accordingly before calling transport.start() and assert it fails; 2) send() callback errors — make FakeWebSocket.send invoke its callback with an Error and assert transport.send(...) rejects with that error; 3) close() cleanup/listener detachment — call transport.start(), transport.close(), then emit a 'message' on the FakeWebSocket and assert transport.onmessage is not invoked and socket listeners count is cleaned up. Reference ServerWebSocketTransport.start, ServerWebSocketTransport.send, ServerWebSocketTransport.close, and the FakeWebSocket test helper when adding these tests.packages/vscode-ide-bridge/src/server/localIdeBridgeService.ts (2)
71-75:restart()can resurrect a disposed service.Setting
this.disposed = falseallowsrestart()to work even afterdispose()has been called. Ifdispose()is meant to be a terminal operation (e.g., extension deactivation), this could lead to unexpected behavior where the service is resurrected.Consider either:
- Checking if previously disposed and throwing/returning early
- Documenting that
restart()intentionally re-enables a disposed service💡 Option to prevent restart after dispose
async restart(): Promise<void> { + if (this.disposed) { + throw new Error('Cannot restart a disposed service') + } await this.stop() - this.disposed = false await this.start() }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/src/server/localIdeBridgeService.ts` around lines 71 - 75, The restart() method currently clears this.disposed and restarts the service, which can resurrect a service after dispose(); update restart() to first check this.disposed and either throw an error or return early if the service was previously disposed, or explicitly document in the LocalIdeBridgeService class that restart() intentionally re-enables a disposed service; reference restart(), dispose(), and the this.disposed flag when making the change so the guard is placed before calling stop() / start().
26-54: Consider adding explicit types to improve type safety.The heavy use of
anyreduces type safety and IDE assistance:
socket: any→ could useWebSocketfrom'ws'server: any→ could useWebSocketServerfrom'ws'vscode: any→ could usetypeof import('vscode')This would catch type errors at compile time and improve maintainability.
💡 Example type improvements
+import type { WebSocket, WebSocketServer } from 'ws' +import type * as vscodeTypes from 'vscode' type ActiveConnection = { - socket: any + socket: WebSocket bridge: ReturnType<typeof createIdeBridgeServer> transport: ServerWebSocketTransport } export class LocalIdeBridgeService { private readonly diffController private readonly ideName = 'VS Code' private readonly runningInWindows = process.platform === 'win32' - private server: any | null = null + private server: WebSocketServer | null = null // ... constructor( - private readonly vscode: any, - private readonly outputChannel: any, + private readonly vscode: typeof vscodeTypes, + private readonly outputChannel: vscodeTypes.OutputChannel,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vscode-ide-bridge/src/server/localIdeBridgeService.ts` around lines 26 - 54, The code uses many anys which reduces type safety—replace them with concrete types: change ActiveConnection.socket from any to WebSocket (imported from 'ws'), change LocalIdeBridgeService.server from any to WebSocketServer | null (from 'ws'), and type the constructor parameter vscode as typeof import('vscode'); also update ActiveConnection.bridge to the concrete return type of createIdeBridgeServer if available (or a dedicated interface) and adjust any usages of socket/server/ide bridge methods accordingly so TS catches mismatches. Ensure you add the necessary imports (WebSocket, WebSocketServer) and update the related property declarations (socket, server, vscode, and ActiveConnection.bridge) throughout the class.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/superpowers/plans/2026-04-07-vscode-ide-bridge.md`:
- Line 15: The heading "### Task 1: 脚手架 VSCode 扩展包" should be promoted from H3
to H2 to fix the MD001 level-jump; replace the leading "###" with "##" for the
heading "Task 1: 脚手架 VSCode 扩展包" so task sections use H2 and restore proper
heading hierarchy.
In `@packages/vscode-ide-bridge/.vscodeignore`:
- Line 6: The .vscodeignore currently excludes the compiled runtime server files
via the pattern "dist/server/**", which prevents inclusion of runtime modules in
the VSIX and causes activation-time module-not-found errors; remove the
"dist/server/**" exclusion (or narrow it only to dev-only artifacts) so the
extension's runtime server code in dist/server is packaged, then rebuild the
VSIX and verify the extension activates without missing-module errors.
In `@packages/vscode-ide-bridge/src/server/diffController.ts`:
- Around line 297-317: The accept branch currently calls settleSession(...,
createTextResult('TAB_CLOSED'), true) which sets closeEditors=true and triggers
closeSessionEditors() that reverts dirty editors (dropping the accepted diff);
before settling on ACCEPT_LABEL, persist the right-hand diff editor instead of
immediately closing: locate the showInformationMessage handler in
diffController.ts and, when choice === ACCEPT_LABEL, ensure the matching dirty
TextEditor (the diff's right-hand buffer) is saved (e.g., call document.save()
on the editor for args.new_file_path or programmatically apply and save the
edit) and only after a successful save call settleSession(...,
createTextResult('TAB_CLOSED'), true); alternatively, if you intend a
non-committal action, change the closeEditors flag to false and use
createTextResult('DIFF_ACCEPTED') to reflect acceptance without saving.
- Around line 196-207: The current conditional in the diff-closing loop includes
a loose check using tab?.label === session.tabName which can match unrelated
files with the same basename; remove that label comparison and rely solely on
canonical identifiers (original/modified/uri strings and
tab?.input?.uri?.fsPath) to identify the session. Update the condition in the
loop inside diffController (the for-loops over vscode.window.tabGroups) to drop
the tab?.label === session.tabName clause so only original, modified,
uri.toString() or fsPath comparisons (session.leftUri, session.rightUri,
session.filePath) are used to find the matching tab.
- Around line 115-139: Replace the current visible-editors-based closure
detection in the visibilityDisposable listener with a tab-close-based listener:
remove or stop using vscode.window.onDidChangeVisibleTextEditors and instead
subscribe to vscode.window.tabGroups.onDidChangeTabs, inspect the event.tabs or
the event.change(s) to find tabs where change.kind === 'closed' (or
event.closed) and match those closed tabs to your session entries (use
session.leftUri/session.rightUri or session.tabName via the Tab input) and then
call settleSession(session.tabName, createTextResult('TAB_CLOSED'), false) for
matching sessions; keep session.hasBeenVisible logic if still needed but only
resolve sessions when a matching tab closure is detected to avoid treating mere
visibility changes as tab close.
In `@packages/vscode-ide-bridge/src/server/localIdeBridgeService.ts`:
- Around line 191-219: The handleConnection method can leave the socket open if
bridge.server.connect(transport) throws; wrap the connect call in try/catch so
that on any exception you close/cleanup the socket/transport and do not leak
resources, then rethrow or log the error. Specifically, after creating transport
= new ServerWebSocketTransport(socket) and before setting this.activeConnection,
add a try around await bridge.server.connect(transport) and in the catch/finally
ensure socket.close() (or equivalent) and any transport cleanup is performed if
connect fails; only set this.activeConnection (and call publishActiveSelection)
after a successful connect. Ensure references to handleConnection,
bridge.server.connect, transport, socket, and activeConnection are used to
locate the correct code.
- Around line 169-178: The connection handler currently calls void
this.handleConnection(socket) which discards the promise and can produce
unhandled rejections; change it to attach error handling to the returned promise
(e.g., this.handleConnection(socket).catch(err => {
this.outputChannel.appendLine(`[bridge] connection error: ${err?.message ||
err}`); try { socket.close(1011, 'internal error'); } catch (_) {} })) so any
rejection from handleConnection is logged and the socket is closed gracefully;
update the server.on('connection', ...) callback to use this pattern referencing
handleConnection, outputChannel, and socket.close.
In `@packages/vscode-ide-bridge/src/server/serverWebSocketTransport.ts`:
- Around line 60-66: The close() method currently calls cleanup() even when the
socket is in CLOSING state; change it so cleanup() is only invoked after the
socket is fully CLOSED. In practice, update close() to: if readyState ===
WS_OPEN call socket.close() and return; if readyState === WS_CLOSING simply
return (do not call cleanup or remove handlers); if readyState === WS_CLOSED
then call cleanup(). This preserves the handleClose listener so onclose runs
when the 'close' event fires (refer to close(), cleanup(),
this.socket.readyState, WS_OPEN, WS_CLOSING, handleClose and onclose).
In `@packages/vscode-ide-bridge/test/lockfile.test.ts`:
- Around line 28-30: The test in lockfile.test.ts hardcodes a Windows-style path
which breaks on CI; update the assertion to be OS-agnostic by constructing the
expected path with Node's path utilities and comparing normalized paths: build
the expected using path.join('D:', 'tmp', 'claude-config', 'ide', '4567.lock')
(or normalize the returned value with path.normalize/replace separators) and
assert equality against getLockfilePath(4567); reference getLockfilePath in the
test to locate where to change the assertion.
In `@packages/vscode-ide-bridge/test/package.test.ts`:
- Around line 1-2: Remove the node:fs and node:path imports and replace all
usages with Bun-native APIs: swap join(...) calls to Bun.path.join(...), replace
existsSync(...) with Bun.existsSync(...), and replace readFileSync(..., 'utf8')
with Bun.readFileSync(...) (or Bun.file(...) + .text() if you prefer a
File-based API); update any path construction to use Bun.path.join and ensure
encoding is passed to Bun.readFileSync when reading text. References: replace
the imports at the top and the functions join, existsSync, and readFileSync in
the test.
In `@packages/vscode-ide-bridge/test/packagePackaging.test.ts`:
- Around line 65-69: The test "keeps the packaged README free of local absolute
file links" is using a too-broad check expect(contents).not.toContain(':/')
which will flag valid URLs like https://; update the assertion to specifically
detect Markdown links with absolute POSIX or Windows file paths: remove the ':/`
check and instead assert that contents does not match a POSIX-absolute link
regex (e.g. /\]\(\/[^)]+\)/) and does not match a Windows-drive absolute link
regex (e.g. /\]\([A-Za-z]:[\\/][^)]+\)/); locate the test by its name and the
variables readmePath / contents and replace the second expect with these two
regex-based negative matches.
In `@packages/vscode-ide-bridge/test/packageWorkspaceWorkflow.test.ts`:
- Around line 1-2: Replace Node built-ins used at the top (existsSync,
readFileSync, join) with Bun-native APIs: remove imports of node:fs and
node:path, replace any existsSync(...) checks with a Bun.file(path) existence
check (e.g., try to access/read or check .size via Bun.file(path) in a
try/catch), replace readFileSync(...) with await Bun.file(path).text(), and
replace join(...) usage with simple string/path concatenation or URL-based
construction (e.g., new URL('./sub/dir', import.meta.url).pathname) consistent
with the test's runtime; update the test functions to be async where needed so
they can await Bun.file(...).text() and ensure error handling uses try/catch for
missing files instead of existsSync.
In `@packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts`:
- Around line 1-19: The test imports Node's EventEmitter and defines
FakeWebSocket; replace that with a Bun-native test double that implements only
the needed event APIs (on, off, emit) and the websocket shape used by
ServerWebSocketTransport: readyState property, send(data, callback?), close(),
sent array and closed flag; remove the import of 'node:events', implement the
lightweight FakeWebSocket class used in serverWebSocketTransport.test.ts so it
emits 'message', 'close', and 'error' correctly for tests against
ServerWebSocketTransport.
In `@packages/vscode-ide-bridge/test/vscodeWorkflow.test.ts`:
- Around line 1-2: The test imports Node built-ins readFileSync and join;
replace these by using Bun APIs and import.meta.dir: remove "readFileSync" and
"join" imports, change any readFileSync(...) calls to Bun.file(...) or
Bun.read(...)/Bun.readFile(...) as appropriate, and use import.meta.dir for path
resolution instead of join; update references in vscodeWorkflow.test.ts to call
Bun.file(path).text() or Bun.readFile(path) where the file contents are needed
and construct file paths with import.meta.dir + '/relative/path'.
---
Nitpick comments:
In `@packages/vscode-ide-bridge/src/server/localIdeBridgeService.ts`:
- Around line 71-75: The restart() method currently clears this.disposed and
restarts the service, which can resurrect a service after dispose(); update
restart() to first check this.disposed and either throw an error or return early
if the service was previously disposed, or explicitly document in the
LocalIdeBridgeService class that restart() intentionally re-enables a disposed
service; reference restart(), dispose(), and the this.disposed flag when making
the change so the guard is placed before calling stop() / start().
- Around line 26-54: The code uses many anys which reduces type safety—replace
them with concrete types: change ActiveConnection.socket from any to WebSocket
(imported from 'ws'), change LocalIdeBridgeService.server from any to
WebSocketServer | null (from 'ws'), and type the constructor parameter vscode as
typeof import('vscode'); also update ActiveConnection.bridge to the concrete
return type of createIdeBridgeServer if available (or a dedicated interface) and
adjust any usages of socket/server/ide bridge methods accordingly so TS catches
mismatches. Ensure you add the necessary imports (WebSocket, WebSocketServer)
and update the related property declarations (socket, server, vscode, and
ActiveConnection.bridge) throughout the class.
In `@packages/vscode-ide-bridge/test/bridgeServer.test.ts`:
- Around line 111-128: The test's notificationPromise (created with
client.setNotificationHandler and SelectionChangedSchema) can hang forever if no
notification arrives; wrap or replace it with a timeout-guarded promise (e.g.,
race the handler promise with a timer that rejects or fails after a short
timeout) and then await that guarded promise instead of notificationPromise;
ensure the timeout includes a descriptive error so bridge.notifySelectionChanged
failures yield deterministic test failures.
In `@packages/vscode-ide-bridge/test/selectionPublisher.test.ts`:
- Around line 13-16: The test in selectionPublisher.test.ts only asserts
params.selection?.start.line and params.selection?.end.character, leaving
start.character and end.line untested; update the assertions on the params
object to verify all four selection coordinates by adding checks for
params.selection?.start.character and params.selection?.end.line alongside the
existing expectations for start.line and end.character so the test validates
start.line, start.character, end.line, and end.character.
In `@packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts`:
- Around line 21-71: Add tests for ServerWebSocketTransport unhappy paths: 1)
start() when the FakeWebSocket.readyState is not 1 (e.g., 0 or 3) should reject
or throw — set socket.readyState accordingly before calling transport.start()
and assert it fails; 2) send() callback errors — make FakeWebSocket.send invoke
its callback with an Error and assert transport.send(...) rejects with that
error; 3) close() cleanup/listener detachment — call transport.start(),
transport.close(), then emit a 'message' on the FakeWebSocket and assert
transport.onmessage is not invoked and socket listeners count is cleaned up.
Reference ServerWebSocketTransport.start, ServerWebSocketTransport.send,
ServerWebSocketTransport.close, and the FakeWebSocket test helper when adding
these tests.
In `@packages/vscode-ide-bridge/test/workspaceInfo.test.ts`:
- Around line 37-40: The test only asserts snapshot.selection?.start.line;
update the assertion to verify the entire selection payload by replacing the
single-field check with an equality check against an expected selection object
(include start.line, start.character, end.line, end.character). Locate the
snapshot variable in workspaceInfo.test.ts and use a deep equality assertion
(e.g., expect(snapshot.selection).toEqual(expectedSelection)) or toMatchObject
with an explicit expectedSelection you construct with the correct numeric
values.
In `@packages/vscode-ide-bridge/tsconfig.json`:
- Around line 12-14: The tsconfig.json "types" array only includes "bun", which
causes missing type coverage for VS Code and Node APIs; update the "types" array
in tsconfig.json to include the official ambient packages such as "node" and
"vscode" (and keep "bun" if still needed) and ensure the corresponding packages
are installed (e.g., `@types/node` or the official vscode typings) so the project
uses correct official type definitions instead of ambient any stubs.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: e21ff602-977a-47a3-b06f-4d0205b272e4
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (35)
.vscode/launch.json.vscode/tasks.jsondocs/superpowers/plans/2026-04-07-vscode-ide-bridge.mddocs/superpowers/specs/2026-04-07-vscode-ide-bridge-design.mdpackages/vscode-ide-bridge/.vscode/launch.jsonpackages/vscode-ide-bridge/.vscode/tasks.jsonpackages/vscode-ide-bridge/.vscodeignorepackages/vscode-ide-bridge/LICENSE.txtpackages/vscode-ide-bridge/README.mdpackages/vscode-ide-bridge/package.jsonpackages/vscode-ide-bridge/src/extension.tspackages/vscode-ide-bridge/src/server/bridgeServer.tspackages/vscode-ide-bridge/src/server/diffController.tspackages/vscode-ide-bridge/src/server/localIdeBridgeService.tspackages/vscode-ide-bridge/src/server/lockfile.tspackages/vscode-ide-bridge/src/server/protocol.tspackages/vscode-ide-bridge/src/server/randomToken.tspackages/vscode-ide-bridge/src/server/selectionPublisher.tspackages/vscode-ide-bridge/src/server/serverWebSocketTransport.tspackages/vscode-ide-bridge/src/server/terminalEnvironment.tspackages/vscode-ide-bridge/src/server/workspaceInfo.tspackages/vscode-ide-bridge/src/vscode.d.tspackages/vscode-ide-bridge/src/ws.d.tspackages/vscode-ide-bridge/test/bridgeServer.test.tspackages/vscode-ide-bridge/test/diffController.test.tspackages/vscode-ide-bridge/test/lockfile.test.tspackages/vscode-ide-bridge/test/package.test.tspackages/vscode-ide-bridge/test/packagePackaging.test.tspackages/vscode-ide-bridge/test/packageWorkspaceWorkflow.test.tspackages/vscode-ide-bridge/test/selectionPublisher.test.tspackages/vscode-ide-bridge/test/serverWebSocketTransport.test.tspackages/vscode-ide-bridge/test/terminalEnvironment.test.tspackages/vscode-ide-bridge/test/vscodeWorkflow.test.tspackages/vscode-ide-bridge/test/workspaceInfo.test.tspackages/vscode-ide-bridge/tsconfig.json
|
|
||
| --- | ||
|
|
||
| ### Task 1: 脚手架 VSCode 扩展包 |
There was a problem hiding this comment.
Fix heading level jump at Line 15.
The heading hierarchy skips ## (H2) and jumps from H1 to H3, which triggers MD001. Use ## for task sections.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 15-15: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/superpowers/plans/2026-04-07-vscode-ide-bridge.md` at line 15, The
heading "### Task 1: 脚手架 VSCode 扩展包" should be promoted from H3 to H2 to fix the
MD001 level-jump; replace the leading "###" with "##" for the heading "Task 1:
脚手架 VSCode 扩展包" so task sections use H2 and restore proper heading hierarchy.
| .vscode/** | ||
| tsconfig.json | ||
| *.tsbuildinfo | ||
| dist/server/** |
There was a problem hiding this comment.
Do not exclude runtime server modules from the VSIX.
Line 6 removes dist/server/**, but extension runtime code typically imports those compiled files from dist/. This can cause activation-time module not found failures in packaged installs.
💡 Proposed fix
src/**
test/**
.vscode/**
tsconfig.json
*.tsbuildinfo
-dist/server/**🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/.vscodeignore` at line 6, The .vscodeignore
currently excludes the compiled runtime server files via the pattern
"dist/server/**", which prevents inclusion of runtime modules in the VSIX and
causes activation-time module-not-found errors; remove the "dist/server/**"
exclusion (or narrow it only to dev-only artifacts) so the extension's runtime
server code in dist/server is packaged, then rebuild the VSIX and verify the
extension activates without missing-module errors.
| const visibilityDisposable = vscode.window.onDidChangeVisibleTextEditors( | ||
| (editors: any[]) => { | ||
| const visibleUris = new Set( | ||
| editors.map(editor => editor?.document?.uri?.toString?.()), | ||
| ) | ||
|
|
||
| for (const session of sessions.values()) { | ||
| const leftVisible = visibleUris.has(session.leftUri.toString()) | ||
| const rightVisible = visibleUris.has(session.rightUri.toString()) | ||
|
|
||
| if (leftVisible || rightVisible) { | ||
| session.hasBeenVisible = true | ||
| continue | ||
| } | ||
|
|
||
| if (session.hasBeenVisible) { | ||
| void settleSession( | ||
| session.tabName, | ||
| createTextResult('TAB_CLOSED'), | ||
| false, | ||
| ) | ||
| } | ||
| } | ||
| }, | ||
| ) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
VS Code API: does window.visibleTextEditors/window.onDidChangeVisibleTextEditors include only editors currently visible on screen, or all open tabs? What event or API should be used to detect when a tab is actually closed?
💡 Result:
vscode.window.visibleTextEditorsis only the editors currently visible in the UI (i.e., the editor panes that are showing content right now), not all open tabs. The API describes it as “The currently visible editors”. [1]vscode.window.onDidChangeVisibleTextEditorsfires when that visible editors array changes (e.g., you change editor layout, switch which editor is shown in a group, open/close an editor that affects what’s visible). It’s defined as firing when the “array of visible editors has changed”. [2]
If you need “all open tabs”
Use the Tabs API: vscode.window.tabGroups.all and each group’s tabs. [3]
Detect when a tab is actually closed
Use vscode.window.tabGroups.onDidChangeTabs and look at event.closed (the event explicitly includes “The tabs that have been closed”). [4]
Why workspace.onDidCloseTextDocument isn’t a reliable “tab closed” signal
workspace.onDidCloseTextDocument is about the document being disposed (or language id change), and the docs explicitly note there’s no guarantee it fires when an editor tab is closed. [2]
Sources
[1] VS Code API docs — window.visibleTextEditors (“currently visible editors”) https://code.visualstudio.com/api/references/vscode-api
[2] VS Code API docs — window.onDidChangeVisibleTextEditors; workspace.onDidCloseTextDocument notes https://code.visualstudio.com/api/references/vscode-api
[3] VS Code API docs — window.tabGroups / TabGroup.tabs https://code.visualstudio.com/api/references/vscode-api
[4] VS Code API docs — tabGroups.onDidChangeTabs / TabChangeEvent.closed https://code.visualstudio.com/api/references/vscode-api
Replace onDidChangeVisibleTextEditors with tabGroups.onDidChangeTabs to detect actual tab closure.
The code treats "not currently visible in the editor pane" as "tab closed," but onDidChangeVisibleTextEditors only fires when the set of visible editors changes (e.g., user switches to another tab in the same group). Both diff editors disappear from visibleTextEditors without being closed, so the session incorrectly resolves as TAB_CLOSED while the diff tab is still open, dropping it from tracking and preventing later save/reject actions.
Use vscode.window.tabGroups.onDidChangeTabs instead, checking event.closed to detect when tabs are actually closed (per VS Code API documentation).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/src/server/diffController.ts` around lines 115 -
139, Replace the current visible-editors-based closure detection in the
visibilityDisposable listener with a tab-close-based listener: remove or stop
using vscode.window.onDidChangeVisibleTextEditors and instead subscribe to
vscode.window.tabGroups.onDidChangeTabs, inspect the event.tabs or the
event.change(s) to find tabs where change.kind === 'closed' (or event.closed)
and match those closed tabs to your session entries (use
session.leftUri/session.rightUri or session.tabName via the Tab input) and then
call settleSession(session.tabName, createTextResult('TAB_CLOSED'), false) for
matching sessions; keep session.hasBeenVisible logic if still needed but only
resolve sessions when a matching tab closure is detected to avoid treating mere
visibility changes as tab close.
| for (const group of vscode.window.tabGroups?.all ?? []) { | ||
| for (const tab of group.tabs ?? []) { | ||
| const original = tab?.input?.original?.toString?.() | ||
| const modified = tab?.input?.modified?.toString?.() | ||
| const uri = tab?.input?.uri?.toString?.() | ||
| if ( | ||
| original === session.leftUri.toString() || | ||
| modified === session.rightUri.toString() || | ||
| uri === session.rightUri.toString() || | ||
| tab?.input?.uri?.fsPath === session.filePath || | ||
| tab?.label === session.tabName | ||
| ) { |
There was a problem hiding this comment.
Plain tab.label matching can close the wrong editor.
tab_name looks basename-like and user-controlled. Matching on tab?.label === session.tabName means closing sample.ts here can also close an unrelated sample.ts tab from another folder. Please restrict this to the session URIs / fsPath.
🧭 Minimal fix
if (
original === session.leftUri.toString() ||
modified === session.rightUri.toString() ||
uri === session.rightUri.toString() ||
- tab?.input?.uri?.fsPath === session.filePath ||
- tab?.label === session.tabName
+ tab?.input?.uri?.fsPath === session.filePath
) {
matchedTabs.push(tab)
}📝 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.
| for (const group of vscode.window.tabGroups?.all ?? []) { | |
| for (const tab of group.tabs ?? []) { | |
| const original = tab?.input?.original?.toString?.() | |
| const modified = tab?.input?.modified?.toString?.() | |
| const uri = tab?.input?.uri?.toString?.() | |
| if ( | |
| original === session.leftUri.toString() || | |
| modified === session.rightUri.toString() || | |
| uri === session.rightUri.toString() || | |
| tab?.input?.uri?.fsPath === session.filePath || | |
| tab?.label === session.tabName | |
| ) { | |
| for (const group of vscode.window.tabGroups?.all ?? []) { | |
| for (const tab of group.tabs ?? []) { | |
| const original = tab?.input?.original?.toString?.() | |
| const modified = tab?.input?.modified?.toString?.() | |
| const uri = tab?.input?.uri?.toString?.() | |
| if ( | |
| original === session.leftUri.toString() || | |
| modified === session.rightUri.toString() || | |
| uri === session.rightUri.toString() || | |
| tab?.input?.uri?.fsPath === session.filePath | |
| ) { |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/src/server/diffController.ts` around lines 196 -
207, The current conditional in the diff-closing loop includes a loose check
using tab?.label === session.tabName which can match unrelated files with the
same basename; remove that label comparison and rely solely on canonical
identifiers (original/modified/uri strings and tab?.input?.uri?.fsPath) to
identify the session. Update the condition in the loop inside diffController
(the for-loops over vscode.window.tabGroups) to drop the tab?.label ===
session.tabName clause so only original, modified, uri.toString() or fsPath
comparisons (session.leftUri, session.rightUri, session.filePath) are used to
find the matching tab.
| void vscode.window | ||
| .showInformationMessage( | ||
| `Claude Code 提议了对 ${args.new_file_path} 的修改`, | ||
| ACCEPT_LABEL, | ||
| REJECT_LABEL, | ||
| ) | ||
| .then((choice: string | undefined) => { | ||
| if (choice === ACCEPT_LABEL) { | ||
| void settleSession( | ||
| args.tab_name, | ||
| createTextResult('TAB_CLOSED'), | ||
| true, | ||
| ) | ||
| } else if (choice === REJECT_LABEL) { | ||
| void settleSession( | ||
| args.tab_name, | ||
| createTextResult('DIFF_REJECTED'), | ||
| true, | ||
| ) | ||
| } | ||
| }) |
There was a problem hiding this comment.
“接受” currently discards unsaved diff contents.
The accept branch settles with closeEditors = true. closeSessionEditors() then reverts any dirty matching editor at Lines 179-191 before closing it, so clicking 接受 without saving drops the proposed change instead of accepting it. Either save the right-hand document first or rename this action to something non-committal.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/src/server/diffController.ts` around lines 297 -
317, The accept branch currently calls settleSession(...,
createTextResult('TAB_CLOSED'), true) which sets closeEditors=true and triggers
closeSessionEditors() that reverts dirty editors (dropping the accepted diff);
before settling on ACCEPT_LABEL, persist the right-hand diff editor instead of
immediately closing: locate the showInformationMessage handler in
diffController.ts and, when choice === ACCEPT_LABEL, ensure the matching dirty
TextEditor (the diff's right-hand buffer) is saved (e.g., call document.save()
on the editor for args.new_file_path or programmatically apply and save the
edit) and only after a successful save call settleSession(...,
createTextResult('TAB_CLOSED'), true); alternatively, if you intend a
non-committal action, change the closeEditors flag to false and use
createTextResult('DIFF_ACCEPTED') to reflect acceptance without saving.
| import { existsSync, readFileSync } from 'node:fs' | ||
| import { join } from 'node:path' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify TS/JS files under vscode-ide-bridge do not use Node built-in imports.
rg -n --type=ts --type=tsx --type=js --type=jsx "from ['\"]node:"Repository: claude-code-best/claude-code
Length of output: 99
🏁 Script executed:
#!/bin/bash
# Find the file and check its content
find . -path "*vscode-ide-bridge/test/package.test.ts" -type fRepository: claude-code-best/claude-code
Length of output: 121
🏁 Script executed:
#!/bin/bash
# Check for node: imports with correct rg options
rg -n "from ['\"]node:" --type tsRepository: claude-code-best/claude-code
Length of output: 2470
🏁 Script executed:
#!/bin/bash
# Read the actual test file to verify imports
cat -n packages/vscode-ide-bridge/test/package.test.tsRepository: claude-code-best/claude-code
Length of output: 1431
Replace Node built-ins with Bun APIs in this test file.
Lines 1-2 import node:fs and node:path, which violate the repository's Bun-only TS/JS guideline. Additionally, join() on lines 5-6, existsSync() on line 10, and readFileSync() on lines 12-13 must be replaced with Bun equivalents.
🔁 Bun-native rewrite
-import { existsSync, readFileSync } from 'node:fs'
-import { join } from 'node:path'
import { describe, expect, test } from 'bun:test'
-const packageRoot = join(import.meta.dir, '..')
-const packageJsonPath = join(packageRoot, 'package.json')
+const packageJsonPath = new URL('../package.json', import.meta.url)
describe('vscode-ide-bridge package', () => {
- test('declares a VSCode extension entry', () => {
- expect(existsSync(packageJsonPath)).toBe(true)
+ test('declares a VSCode extension entry', async () => {
+ expect(await Bun.file(packageJsonPath).exists()).toBe(true)
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {
+ const packageJson = (await Bun.file(packageJsonPath).json()) as {
main?: string
engines?: { vscode?: string }
activationEvents?: string[]
dependencies?: Record<string, string>
devDependencies?: Record<string, string>
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/test/package.test.ts` around lines 1 - 2, Remove
the node:fs and node:path imports and replace all usages with Bun-native APIs:
swap join(...) calls to Bun.path.join(...), replace existsSync(...) with
Bun.existsSync(...), and replace readFileSync(..., 'utf8') with
Bun.readFileSync(...) (or Bun.file(...) + .text() if you prefer a File-based
API); update any path construction to use Bun.path.join and ensure encoding is
passed to Bun.readFileSync when reading text. References: replace the imports at
the top and the functions join, existsSync, and readFileSync in the test.
| test('keeps the packaged README free of local absolute file links', () => { | ||
| const contents = readFileSync(readmePath, 'utf8') | ||
|
|
||
| expect(contents).not.toContain('](/') | ||
| expect(contents).not.toContain(':/') |
There was a problem hiding this comment.
Tighten README link check to avoid false failures on valid URLs.
not.toContain(':/') also matches valid https://... links, so this assertion can fail for legitimate README content.
Suggested fix
- expect(contents).not.toContain(':/')
+ // Block local absolute paths only (POSIX + Windows), allow web URLs.
+ expect(contents).not.toMatch(/\]\(\/(?!\/)/)
+ expect(contents).not.toMatch(/\b[A-Za-z]:[\\/]/)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/test/packagePackaging.test.ts` around lines 65 -
69, The test "keeps the packaged README free of local absolute file links" is
using a too-broad check expect(contents).not.toContain(':/') which will flag
valid URLs like https://; update the assertion to specifically detect Markdown
links with absolute POSIX or Windows file paths: remove the ':/` check and
instead assert that contents does not match a POSIX-absolute link regex (e.g.
/\]\(\/[^)]+\)/) and does not match a Windows-drive absolute link regex (e.g.
/\]\([A-Za-z]:[\\/][^)]+\)/); locate the test by its name and the variables
readmePath / contents and replace the second expect with these two regex-based
negative matches.
| import { existsSync, readFileSync } from 'node:fs' | ||
| import { join } from 'node:path' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files | head -20Repository: claude-code-best/claude-code
Length of output: 460
🏁 Script executed:
find . -name "packageWorkspaceWorkflow.test.ts" -o -name "vscode-ide-bridge" -type dRepository: claude-code-best/claude-code
Length of output: 167
🏁 Script executed:
fd "packageWorkspaceWorkflow" --type fRepository: claude-code-best/claude-code
Length of output: 136
🏁 Script executed:
cat -n "packages/vscode-ide-bridge/test/packageWorkspaceWorkflow.test.ts" | head -50Repository: claude-code-best/claude-code
Length of output: 1957
🏁 Script executed:
ls -la "packages/vscode-ide-bridge/"Repository: claude-code-best/claude-code
Length of output: 655
🏁 Script executed:
cat -n "CLAUDE.md" | head -100Repository: claude-code-best/claude-code
Length of output: 5768
🌐 Web query:
Bun fs path APIs built-in modules
💡 Result:
In Bun, filesystem + path work primarily through Node-compatible built-in modules, plus a couple of Bun-native file APIs:
-
node:fs/node:fs/promises: Bun’s Nodefsimplementation is “fully implemented” (and Bun recommends using it for directory ops likemkdir/readdir). [1][2]import { readdir, mkdir } from "node:fs/promises";
-
node:path(and usuallypath): Bun reportsnode:pathas “fully implemented”. [1]import path from "node:path"; // or: import * as path from "node:path";
-
Bun-native file I/O (recommended for fast reads/writes):
Bun.file(pathOrUrlOrFd)for reading (Blob-like interface)Bun.write(dest, data)for writing/copying
[2]
-
Handy module utility for paths:
import.meta.dirgives the absolute directory of the current file (useful withpath.join). [3]const here = import.meta.dir;
Sources: Bun Node.js compatibility (built-ins) [1]; Bun File I/O docs [2]; Bun import.meta.dir guide [3].
🏁 Script executed:
cat "packages/vscode-ide-bridge/package.json"Repository: claude-code-best/claude-code
Length of output: 1771
🏁 Script executed:
grep -n "vscode-ide-bridge" CLAUDE.mdRepository: claude-code-best/claude-code
Length of output: 54
Migrate this test off Node built-in module imports and use Bun-native APIs.
Lines 1-2 import node:fs and node:path; replace with Bun-native APIs:
existsSync()→ check existence viaBun.file()or try-catch on readreadFileSync()→await Bun.file().text()join()fromnode:path→ use string concatenation, URL API, or import a dedicated path utility
This aligns with the repository standard for Bun-only runtime environments.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/test/packageWorkspaceWorkflow.test.ts` around
lines 1 - 2, Replace Node built-ins used at the top (existsSync, readFileSync,
join) with Bun-native APIs: remove imports of node:fs and node:path, replace any
existsSync(...) checks with a Bun.file(path) existence check (e.g., try to
access/read or check .size via Bun.file(path) in a try/catch), replace
readFileSync(...) with await Bun.file(path).text(), and replace join(...) usage
with simple string/path concatenation or URL-based construction (e.g., new
URL('./sub/dir', import.meta.url).pathname) consistent with the test's runtime;
update the test functions to be async where needed so they can await
Bun.file(...).text() and ensure error handling uses try/catch for missing files
instead of existsSync.
| import { EventEmitter } from 'node:events' | ||
| import { describe, expect, test } from 'bun:test' | ||
| import { ServerWebSocketTransport } from '../src/server/serverWebSocketTransport.js' | ||
|
|
||
| class FakeWebSocket extends EventEmitter { | ||
| readyState = 1 | ||
| sent: string[] = [] | ||
| closed = false | ||
|
|
||
| send(data: string, callback?: (error?: Error) => void) { | ||
| this.sent.push(data) | ||
| callback?.() | ||
| } | ||
|
|
||
| close() { | ||
| this.closed = true | ||
| this.emit('close') | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and read its content
cat -n packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts | head -50Repository: claude-code-best/claude-code
Length of output: 1584
🏁 Script executed:
# Check how FakeWebSocket is used in the test file
cat -n packages/vscode-ide-bridge/test/serverWebSocketTransport.test.tsRepository: claude-code-best/claude-code
Length of output: 2203
🏁 Script executed:
# Check the ServerWebSocketTransport implementation to see what interface it expects
cat -n packages/vscode-ide-bridge/src/server/serverWebSocketTransport.ts | head -100Repository: claude-code-best/claude-code
Length of output: 3312
Replace Node EventEmitter usage with a Bun-native test double.
Line 1 imports node:events, which violates the Bun-only runtime/import rule for TS/JS files in this repo. The custom EventEmitter implementation in the suggestion correctly covers all required methods (on, off, emit) for the 'message', 'close', and 'error' events expected by ServerWebSocketTransport.
Suggested refactor
-import { EventEmitter } from 'node:events'
import { describe, expect, test } from 'bun:test'
import { ServerWebSocketTransport } from '../src/server/serverWebSocketTransport.js'
-class FakeWebSocket extends EventEmitter {
+class FakeWebSocket {
readyState = 1
sent: string[] = []
closed = false
+ private listeners: Record<string, Array<(...args: any[]) => void>> = {}
+ on(event: 'message' | 'close' | 'error', listener: (...args: any[]) => void) {
+ this.listeners[event] ??= []
+ this.listeners[event].push(listener)
+ }
+
+ off(event: 'message' | 'close' | 'error', listener: (...args: any[]) => void) {
+ this.listeners[event] = (this.listeners[event] ?? []).filter(l => l !== listener)
+ }
+
+ emit(event: 'message' | 'close' | 'error', payload?: unknown) {
+ for (const listener of this.listeners[event] ?? []) listener(payload)
+ }
send(data: string, callback?: (error?: Error) => void) {
this.sent.push(data)
callback?.()
}
close() {
this.closed = true
this.emit('close')
}📝 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.
| import { EventEmitter } from 'node:events' | |
| import { describe, expect, test } from 'bun:test' | |
| import { ServerWebSocketTransport } from '../src/server/serverWebSocketTransport.js' | |
| class FakeWebSocket extends EventEmitter { | |
| readyState = 1 | |
| sent: string[] = [] | |
| closed = false | |
| send(data: string, callback?: (error?: Error) => void) { | |
| this.sent.push(data) | |
| callback?.() | |
| } | |
| close() { | |
| this.closed = true | |
| this.emit('close') | |
| } | |
| } | |
| import { describe, expect, test } from 'bun:test' | |
| import { ServerWebSocketTransport } from '../src/server/serverWebSocketTransport.js' | |
| class FakeWebSocket { | |
| readyState = 1 | |
| sent: string[] = [] | |
| closed = false | |
| private listeners: Record<string, Array<(...args: any[]) => void>> = {} | |
| on(event: 'message' | 'close' | 'error', listener: (...args: any[]) => void) { | |
| this.listeners[event] ??= [] | |
| this.listeners[event].push(listener) | |
| } | |
| off(event: 'message' | 'close' | 'error', listener: (...args: any[]) => void) { | |
| this.listeners[event] = (this.listeners[event] ?? []).filter(l => l !== listener) | |
| } | |
| emit(event: 'message' | 'close' | 'error', payload?: unknown) { | |
| for (const listener of this.listeners[event] ?? []) listener(payload) | |
| } | |
| send(data: string, callback?: (error?: Error) => void) { | |
| this.sent.push(data) | |
| callback?.() | |
| } | |
| close() { | |
| this.closed = true | |
| this.emit('close') | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/test/serverWebSocketTransport.test.ts` around
lines 1 - 19, The test imports Node's EventEmitter and defines FakeWebSocket;
replace that with a Bun-native test double that implements only the needed event
APIs (on, off, emit) and the websocket shape used by ServerWebSocketTransport:
readyState property, send(data, callback?), close(), sent array and closed flag;
remove the import of 'node:events', implement the lightweight FakeWebSocket
class used in serverWebSocketTransport.test.ts so it emits 'message', 'close',
and 'error' correctly for tests against ServerWebSocketTransport.
| import { readFileSync } from 'node:fs' | ||
| import { join } from 'node:path' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check the file structure and see what packages/vscode-ide-bridge contains
fd -t f . packages/vscode-ide-bridge --max-results 20 | head -30Repository: claude-code-best/claude-code
Length of output: 1090
🏁 Script executed:
# Check the actual content of the test file mentioned in the review
cat -n packages/vscode-ide-bridge/test/vscodeWorkflow.test.ts | head -50Repository: claude-code-best/claude-code
Length of output: 1995
🏁 Script executed:
# Check if there's a package.json for vscode-ide-bridge that indicates its purpose
cat packages/vscode-ide-bridge/package.json 2>/dev/null || echo "Not found"Repository: claude-code-best/claude-code
Length of output: 1771
🏁 Script executed:
# Check if there's documentation about vscode-ide-bridge
cat packages/vscode-ide-bridge/README.md 2>/dev/null || echo "Not found"Repository: claude-code-best/claude-code
Length of output: 1643
🏁 Script executed:
# Look at the root package.json to understand the project structure
cat -n package.json | head -40Repository: claude-code-best/claude-code
Length of output: 1287
🏁 Script executed:
# Check how other test files in vscode-ide-bridge handle imports
rg -n "import.*from.*['\"]node:" packages/vscode-ide-bridge/test/ -A 2Repository: claude-code-best/claude-code
Length of output: 2397
🏁 Script executed:
# Check if any test files use Bun APIs for file operations
rg -n "Bun\." packages/vscode-ide-bridge/test/ | head -20Repository: claude-code-best/claude-code
Length of output: 54
🏁 Script executed:
# Check CLAUDE.md or guidelines for vscode-ide-bridge mentions
find . -name "CLAUDE.md" -o -name "*.md" -path "*/guidelines*" | xargs grep -l "vscode" 2>/dev/null || trueRepository: claude-code-best/claude-code
Length of output: 54
🏁 Script executed:
# Check CLAUDE.md for exceptions to Bun API rule
cat CLAUDE.md 2>/dev/null | head -100Repository: claude-code-best/claude-code
Length of output: 5068
🏁 Script executed:
# Check if there's any documented guidance on Node.js packages
rg "Node\.js" -A 3 -B 3 CLAUDE.md 2>/dev/null || trueRepository: claude-code-best/claude-code
Length of output: 1367
Use Bun APIs instead of Node.js built-ins in this test file.
Lines 1-2 import from node:fs and node:path. Replace with Bun equivalents: use Bun.file() or Bun.readFile() for file I/O and import.meta.dir for path resolution (already used on line 19).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-ide-bridge/test/vscodeWorkflow.test.ts` around lines 1 - 2,
The test imports Node built-ins readFileSync and join; replace these by using
Bun APIs and import.meta.dir: remove "readFileSync" and "join" imports, change
any readFileSync(...) calls to Bun.file(...) or Bun.read(...)/Bun.readFile(...)
as appropriate, and use import.meta.dir for path resolution instead of join;
update references in vscodeWorkflow.test.ts to call Bun.file(path).text() or
Bun.readFile(path) where the file contents are needed and construct file paths
with import.meta.dir + '/relative/path'.
Summary
Verification
Summary by CodeRabbit
New Features
Documentation
Tests