Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 9e91335

Browse files
committed
Working
1 parent d0e4b88 commit 9e91335

8 files changed

Lines changed: 335 additions & 40 deletions

File tree

.roo/roomotes.yml

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,5 @@ commands:
66
run: pnpm install
77
timeout: 60
88

9-
- name: Build & watch (Terminal 1)
10-
run: |
11-
# Build all workspace packages first (handles @roo-code/build and other deps)
12-
pnpm build || exit $?
13-
14-
# Enable polling for file watchers (helps with symlinks and macOS issues)
15-
export CHOKIDAR_USEPOLLING=true
16-
export WATCHPACK_POLLING=true
17-
18-
# Start watchers (same as .vscode/tasks.json "watch" task, using direct pnpm filters)
19-
pnpm --filter @roo-code/vscode-webview dev &
20-
pnpm --filter roo-cline watch:bundle &
21-
pnpm --filter roo-cline watch:tsc &
22-
23-
# Wait for all background jobs
24-
wait
25-
timeout: 0
26-
27-
- name: Start code-server (Terminal 2)
28-
run: |
29-
PORT=${PORT:-8443}
30-
31-
# Install code-server if missing
32-
if ! command -v code-server &> /dev/null; then
33-
curl -fsSL https://code-server.dev/install.sh | sh
34-
fi
35-
36-
# Symlink extension for live development
37-
EXT_DIR="$HOME/.local/share/code-server/extensions"
38-
mkdir -p "$EXT_DIR"
39-
ln -sfn "$(pwd)/src" "$EXT_DIR/roo-cline"
40-
41-
# Disable atomic writes so file watchers detect changes properly
42-
export DISABLE_ATOMICWRITES=true
43-
44-
# Launch code-server
45-
code-server --auth none --bind-addr 0.0.0.0:${PORT} .
46-
timeout: 0
9+
- name: Serve
10+
run: pnpm serve

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .",
2424
"knip": "knip --include files",
2525
"evals": "dotenvx run -f packages/evals/.env.development packages/evals/.env.local -- docker compose -f packages/evals/docker-compose.yml --profile server --profile runner up --build --scale runner=0",
26-
"npm:publish:types": "pnpm --filter @roo-code/types npm:publish"
26+
"npm:publish:types": "pnpm --filter @roo-code/types npm:publish",
27+
"serve": "bash scripts/serve.sh"
2728
},
2829
"devDependencies": {
2930
"@changesets/cli": "^2.27.10",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/serve.sh

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/bin/bash
2+
set -e
3+
4+
PORT=${PORT:-8443}
5+
6+
# Install code-server if missing
7+
if ! command -v code-server &> /dev/null; then
8+
echo "Installing code-server..."
9+
curl -fsSL https://code-server.dev/install.sh | sh
10+
fi
11+
12+
# Set up extension symlink for live development
13+
EXT_DIR="$HOME/.local/share/code-server/extensions"
14+
mkdir -p "$EXT_DIR"
15+
ln -sfn "$(pwd)/src" "$EXT_DIR/roo-cline"
16+
17+
echo "=============================================="
18+
echo "Setting up environment variables for watchers"
19+
echo "=============================================="
20+
21+
# Enable polling for file watchers (helps with symlinks and various environments)
22+
# Chokidar (used by Vite and now esbuild)
23+
export CHOKIDAR_USEPOLLING=true
24+
export CHOKIDAR_INTERVAL=1000
25+
echo "CHOKIDAR_USEPOLLING=$CHOKIDAR_USEPOLLING"
26+
echo "CHOKIDAR_INTERVAL=$CHOKIDAR_INTERVAL"
27+
28+
# Watchpack (used by webpack)
29+
export WATCHPACK_POLLING=true
30+
31+
# TypeScript watch mode - use polling instead of fs events
32+
export TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling
33+
export TSC_WATCHDIRECTORY=UseFsEventsWithFallbackDynamicPolling
34+
35+
# Disable atomic writes so file watchers detect changes properly
36+
export DISABLE_ATOMICWRITES=true
37+
38+
# Set development environment (from .vscode/launch.json)
39+
export NODE_ENV=development
40+
export VSCODE_DEBUG_MODE=true
41+
42+
# Trap to clean up all background processes on exit
43+
cleanup() {
44+
echo "Stopping all processes..."
45+
jobs -p | xargs -r kill 2>/dev/null
46+
}
47+
trap cleanup EXIT INT TERM
48+
49+
# Build all workspace packages first
50+
echo ""
51+
echo "=============================================="
52+
echo "Building workspace packages..."
53+
echo "=============================================="
54+
pnpm build
55+
56+
# Start code-server in background FIRST
57+
echo ""
58+
echo "=============================================="
59+
echo "Starting code-server on port $PORT"
60+
echo "Extension files are at: $(pwd)/src"
61+
echo "Symlinked to: $EXT_DIR/roo-cline"
62+
echo "=============================================="
63+
code-server --auth none --bind-addr 0.0.0.0:${PORT} . &
64+
CODE_SERVER_PID=$!
65+
66+
# Give code-server a moment to start
67+
sleep 2
68+
69+
# Start watchers with explicit env vars using env command
70+
echo ""
71+
echo "=============================================="
72+
echo "Starting file watchers..."
73+
echo "=============================================="
74+
75+
# Run webview watcher (custom chokidar-based script)
76+
env CHOKIDAR_USEPOLLING=true CHOKIDAR_INTERVAL=1000 pnpm --filter @roo-code/vscode-webview dev:watch &
77+
78+
# Run bundle watcher (custom chokidar-based script)
79+
env CHOKIDAR_USEPOLLING=true CHOKIDAR_INTERVAL=1000 pnpm --filter roo-cline watch:bundle &
80+
81+
# Run tsc watcher
82+
env TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling pnpm --filter roo-cline watch:tsc &
83+
84+
echo ""
85+
echo "=============================================="
86+
echo "All processes started!"
87+
echo "code-server running at http://localhost:${PORT}"
88+
echo "Watchers are running - file changes should trigger rebuilds"
89+
echo "Press Ctrl+C to stop all processes"
90+
echo "=============================================="
91+
echo ""
92+
93+
# Wait for all background processes
94+
wait

src/esbuild.mjs

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import * as path from "path"
44
import { fileURLToPath } from "url"
55
import process from "node:process"
66
import * as console from "node:console"
7+
import { setTimeout, clearTimeout } from "node:timers"
8+
import chokidar from "chokidar"
79

810
import { copyPaths, copyWasms, copyLocales, setupLocaleWatcher } from "@roo-code/build"
911

@@ -121,9 +123,122 @@ async function main() {
121123
])
122124

123125
if (watch) {
124-
await Promise.all([extensionCtx.watch(), workerCtx.watch()])
126+
// Use chokidar for file watching with polling support
127+
// This is more reliable than esbuild's native watcher in environments like code-server
128+
const usePolling = process.env.CHOKIDAR_USEPOLLING === "true"
129+
const pollInterval = parseInt(process.env.CHOKIDAR_INTERVAL || "1000", 10)
130+
131+
console.log(`[${name}] ========================================`)
132+
console.log(`[${name}] Starting watch mode`)
133+
console.log(`[${name}] CHOKIDAR_USEPOLLING: ${process.env.CHOKIDAR_USEPOLLING}`)
134+
console.log(`[${name}] Polling enabled: ${usePolling}`)
135+
console.log(`[${name}] Poll interval: ${pollInterval}ms`)
136+
console.log(`[${name}] Watching directory: ${srcDir}`)
137+
console.log(`[${name}] CWD: ${process.cwd()}`)
138+
console.log(`[${name}] ========================================`)
139+
140+
// Initial build
141+
await Promise.all([extensionCtx.rebuild(), workerCtx.rebuild()])
125142
copyLocales(srcDir, distDir)
126143
setupLocaleWatcher(srcDir, distDir)
144+
145+
// Set up chokidar watcher - watch the srcDir directly
146+
console.log(`[${name}] Setting up chokidar watcher...`)
147+
console.log(`[${name}] srcDir:`, srcDir)
148+
149+
// List files to verify they exist
150+
const extensionTs = path.join(srcDir, "extension.ts")
151+
console.log(`[${name}] extension.ts exists:`, fs.existsSync(extensionTs))
152+
153+
const watcher = chokidar.watch(srcDir, {
154+
ignored: (filePath) => {
155+
// Ignore node_modules, dist, and test files
156+
const relativePath = path.relative(srcDir, filePath)
157+
return relativePath.includes("node_modules") ||
158+
relativePath.includes("dist") ||
159+
relativePath.endsWith(".spec.ts") ||
160+
relativePath.endsWith(".test.ts")
161+
},
162+
persistent: true,
163+
usePolling,
164+
interval: pollInterval,
165+
ignoreInitial: false, // Count files during initial scan
166+
depth: 10,
167+
})
168+
169+
console.log(`[${name}] Watcher created, waiting for ready event...`)
170+
171+
let rebuildTimeout = null
172+
let fileCount = 0
173+
let isReady = false
174+
175+
const triggerRebuild = (eventType, filePath) => {
176+
if (!isReady) return
177+
178+
// Ignore directories that are written to during build
179+
const ignoredPaths = [
180+
"/dist/", "\\dist\\", "/dist", "\\dist",
181+
"/node_modules/", "\\node_modules\\",
182+
"/assets/", "\\assets\\",
183+
"/webview-ui/", "\\webview-ui\\",
184+
]
185+
for (const ignored of ignoredPaths) {
186+
if (filePath.includes(ignored)) {
187+
return
188+
}
189+
}
190+
191+
// Only rebuild for .ts, .tsx source files (not .json since those can be copied)
192+
const shouldRebuild = (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) &&
193+
!filePath.endsWith(".d.ts") && !filePath.endsWith(".spec.ts") && !filePath.endsWith(".test.ts")
194+
if (!shouldRebuild) {
195+
return
196+
}
197+
198+
// Debounce rebuilds
199+
if (rebuildTimeout) {
200+
clearTimeout(rebuildTimeout)
201+
}
202+
rebuildTimeout = setTimeout(async () => {
203+
console.log(`[${name}] File ${eventType}: ${path.relative(srcDir, filePath)}`)
204+
console.log(`[esbuild-problem-matcher#onStart]`)
205+
try {
206+
await Promise.all([extensionCtx.rebuild(), workerCtx.rebuild()])
207+
console.log(`[esbuild-problem-matcher#onEnd]`)
208+
} catch (err) {
209+
console.error(`[${name}] Rebuild failed:`, err.message)
210+
console.log(`[esbuild-problem-matcher#onEnd]`)
211+
}
212+
}, 200)
213+
}
214+
215+
watcher.on("change", (p) => triggerRebuild("changed", p))
216+
watcher.on("add", (p) => {
217+
if (!isReady && (p.endsWith(".ts") || p.endsWith(".tsx") || p.endsWith(".json"))) {
218+
fileCount++
219+
}
220+
triggerRebuild("added", p)
221+
})
222+
watcher.on("unlink", (p) => triggerRebuild("deleted", p))
223+
watcher.on("error", (err) => console.error(`[${name}] Watcher error:`, err))
224+
watcher.on("ready", () => {
225+
isReady = true
226+
console.log(`[${name}] ========================================`)
227+
console.log(`[${name}] Watcher ready!`)
228+
console.log(`[${name}] Watching ${fileCount} files`)
229+
console.log(`[${name}] Listening for changes...`)
230+
console.log(`[${name}] ========================================`)
231+
})
232+
233+
// Also add a raw event listener to see ALL events
234+
watcher.on("raw", (event, rawPath, details) => {
235+
if (process.env.DEBUG_WATCHER === "true") {
236+
console.log(`[${name}] Raw event:`, event, rawPath)
237+
}
238+
})
239+
240+
// Keep the process running
241+
await new Promise(() => {})
127242
} else {
128243
await Promise.all([extensionCtx.rebuild(), workerCtx.rebuild()])
129244
await Promise.all([extensionCtx.dispose(), workerCtx.dispose()])

src/extension.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ export async function activate(context: vscode.ExtensionContext) {
347347
// Watch the core files and automatically reload the extension host.
348348
if (process.env.NODE_ENV === "development") {
349349
const watchPaths = [
350+
// Watch compiled output - triggers reload when esbuild finishes a rebuild
351+
{ path: path.join(context.extensionPath, "dist"), pattern: "extension.js" },
352+
// Also watch webview build output
353+
{ path: path.join(context.extensionPath, "webview-ui/build"), pattern: "**/*" },
354+
// Watch source files for changes that might not trigger a rebuild
350355
{ path: context.extensionPath, pattern: "**/*.ts" },
351356
{ path: path.join(context.extensionPath, "../packages/types"), pattern: "**/*.ts" },
352357
{ path: path.join(context.extensionPath, "../packages/telemetry"), pattern: "**/*.ts" },

webview-ui/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"test": "vitest run",
1010
"format": "prettier --write src",
1111
"dev": "vite",
12+
"dev:watch": "node watch.mjs",
1213
"build": "tsc -b && vite build",
1314
"build:nightly": "tsc -b && vite build --mode nightly",
1415
"preview": "vite preview",
@@ -86,6 +87,7 @@
8687
"devDependencies": {
8788
"@roo-code/config-eslint": "workspace:^",
8889
"@roo-code/config-typescript": "workspace:^",
90+
"chokidar": "^4.0.1",
8991
"@testing-library/jest-dom": "^6.6.3",
9092
"@testing-library/react": "^16.2.0",
9193
"@testing-library/user-event": "^14.6.1",

0 commit comments

Comments
 (0)