@plannotator/opencode 0.27.2 → 0.27.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/embedded.js CHANGED
@@ -44411,27 +44411,9 @@ var init_chokidar = __esm(() => {
44411
44411
  chokidar_default = { watch, FSWatcher };
44412
44412
  });
44413
44413
 
44414
- // ../../packages/server/reference-watch.ts
44415
- import { existsSync as existsSync11, statSync as statSync8, watch as watch2 } from "fs";
44416
- import { dirname as dirname5, isAbsolute as isAbsolute5, relative as relative5, resolve as resolve9 } from "path";
44417
- function serialize(event) {
44418
- return encoder.encode(`data: ${JSON.stringify(event)}
44419
-
44420
- `);
44421
- }
44422
- function isFileBrowserWatchIgnoredPath(path2, root3) {
44423
- const rel = relative5(root3, path2).replace(/\\/g, "/");
44424
- if (!rel || rel.startsWith("..") || isAbsolute5(rel))
44425
- return false;
44426
- return isFileBrowserExcludedPath(rel);
44427
- }
44428
- function isValidDirectory(dirPath) {
44429
- try {
44430
- return existsSync11(dirPath) && statSync8(dirPath).isDirectory();
44431
- } catch {
44432
- return false;
44433
- }
44434
- }
44414
+ // ../../packages/shared/file-browser-watch-core.ts
44415
+ import { watch as nodeFsWatch, statSync as statSync8 } from "fs";
44416
+ import { resolve as resolve9 } from "path";
44435
44417
  function getFileSignature(filePath) {
44436
44418
  try {
44437
44419
  const stats = statSync8(filePath, { bigint: true });
@@ -44453,59 +44435,51 @@ function createExactFileWatchListener(watchPath, exactFilePath, onChange) {
44453
44435
  } catch {}
44454
44436
  };
44455
44437
  }
44456
- function broadcast(entry, reason) {
44457
- for (const [subscriber, clientDirPath] of entry.subscribers) {
44458
- const payload = serialize({
44459
- type: "changed",
44460
- dirPath: clientDirPath,
44461
- reason,
44462
- timestamp: Date.now()
44463
- });
44464
- try {
44465
- subscriber.enqueue(payload);
44466
- } catch {
44467
- entry.subscribers.delete(subscriber);
44438
+ function nativeRecursiveSupported() {
44439
+ return process.platform === "darwin" || process.platform === "win32";
44440
+ }
44441
+ function createFileBrowserWatchRegistry(initialOptions) {
44442
+ const options = { ...initialOptions };
44443
+ const watchers = new Map;
44444
+ let contentWatcherStarts = 0;
44445
+ const teardownGraceMs = () => options.teardownGraceMs ?? DEFAULT_TEARDOWN_GRACE_MS;
44446
+ const debounceMs = () => options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
44447
+ function broadcast(entry, reason) {
44448
+ const hadSubscribers = entry.subscribers.size > 0;
44449
+ for (const [subscriber, clientDirPath] of entry.subscribers) {
44450
+ const event = {
44451
+ type: "changed",
44452
+ dirPath: clientDirPath,
44453
+ reason,
44454
+ timestamp: Date.now()
44455
+ };
44456
+ let delivered = false;
44457
+ try {
44458
+ delivered = options.send(subscriber, event);
44459
+ } catch {
44460
+ delivered = false;
44461
+ }
44462
+ if (!delivered)
44463
+ entry.subscribers.delete(subscriber);
44468
44464
  }
44465
+ if (hadSubscribers && entry.subscribers.size === 0)
44466
+ scheduleTeardown(entry);
44469
44467
  }
44470
- }
44471
- function scheduleBroadcast(entry, reason) {
44472
- if (entry.debounceTimer)
44473
- clearTimeout(entry.debounceTimer);
44474
- entry.debounceTimer = setTimeout(() => {
44475
- entry.debounceTimer = null;
44476
- broadcast(entry, reason);
44477
- }, DEBOUNCE_MS);
44478
- }
44479
- function closeWatcher(entry) {
44480
- if (entry.debounceTimer)
44481
- clearTimeout(entry.debounceTimer);
44482
- entry.contentWatcher?.close();
44483
- entry.gitWatcher?.close();
44484
- if (watchers.get(entry.key) === entry) {
44485
- watchers.delete(entry.key);
44486
- }
44487
- }
44488
- function releaseSubscriber(entry, controller) {
44489
- entry.subscribers.delete(controller);
44490
- if (entry.subscribers.size === 0)
44491
- closeWatcher(entry);
44492
- }
44493
- function ensureWatcher(target) {
44494
- const existing = watchers.get(target.key);
44495
- if (existing)
44496
- return existing;
44497
- const entry = {
44498
- key: target.key,
44499
- subscribers: new Map,
44500
- contentWatcher: null,
44501
- gitWatcher: null,
44502
- debounceTimer: null
44503
- };
44504
- if (target.exactFilePath) {
44505
- entry.contentWatcher = watch2(target.watchPath, { persistent: true }, createExactFileWatchListener(target.watchPath, target.exactFilePath, () => scheduleBroadcast(entry, "files")));
44506
- entry.contentWatcher.on("error", () => scheduleBroadcast(entry, "files"));
44507
- } else {
44508
- entry.contentWatcher = chokidar_default.watch(target.watchPath, {
44468
+ function scheduleBroadcast(entry, reason) {
44469
+ if (entry.closed)
44470
+ return;
44471
+ if (entry.debounceTimer)
44472
+ clearTimeout(entry.debounceTimer);
44473
+ entry.debounceTimer = setTimeout(() => {
44474
+ entry.debounceTimer = null;
44475
+ broadcast(entry, reason);
44476
+ }, debounceMs());
44477
+ }
44478
+ function isCurrent(entry) {
44479
+ return !entry.closed && watchers.get(entry.key) === entry;
44480
+ }
44481
+ function startChokidarContentWatcher(entry, target) {
44482
+ const watcher = chokidar_default.watch(target.watchPath, {
44509
44483
  ignoreInitial: true,
44510
44484
  persistent: true,
44511
44485
  ignored: target.ignored,
@@ -44514,34 +44488,201 @@ function ensureWatcher(target) {
44514
44488
  pollInterval: 30
44515
44489
  }
44516
44490
  });
44517
- entry.contentWatcher.on("all", () => {
44518
- scheduleBroadcast(entry, "files");
44519
- });
44520
- entry.contentWatcher.on("error", () => scheduleBroadcast(entry, "files"));
44491
+ watcher.on("all", () => scheduleBroadcast(entry, "files"));
44492
+ watcher.on("error", () => scheduleBroadcast(entry, "files"));
44493
+ return watcher;
44494
+ }
44495
+ function startContentWatcher(entry, target) {
44496
+ contentWatcherStarts += 1;
44497
+ if (target.exactFilePath) {
44498
+ const exactFilePath = target.exactFilePath;
44499
+ const watcher = (options.nativeWatch ?? nodeFsWatch)(target.watchPath, { persistent: true }, createExactFileWatchListener(target.watchPath, exactFilePath, () => scheduleBroadcast(entry, "files")));
44500
+ watcher.on("error", () => scheduleBroadcast(entry, "files"));
44501
+ entry.contentWatcher = watcher;
44502
+ return;
44503
+ }
44504
+ const backend = options.contentWatchBackend ?? "auto";
44505
+ if (backend === "native" || backend === "auto" && nativeRecursiveSupported()) {
44506
+ try {
44507
+ const nativeWatch = options.nativeWatch ?? nodeFsWatch;
44508
+ const watcher = nativeWatch(target.watchPath, { recursive: true, persistent: true }, (_event, filename) => {
44509
+ try {
44510
+ if (filename != null) {
44511
+ const abs = resolve9(target.watchPath, filename.toString());
44512
+ if (target.ignored?.(abs))
44513
+ return;
44514
+ }
44515
+ scheduleBroadcast(entry, "files");
44516
+ } catch {}
44517
+ });
44518
+ watcher.on("error", (error) => {
44519
+ try {
44520
+ watcher.close();
44521
+ } catch {}
44522
+ if (isCurrent(entry) && entry.contentWatcher === watcher) {
44523
+ console.error(`[plannotator] Native file watching failed for ${target.watchPath}; switching to the fallback watcher:`, error);
44524
+ contentWatcherStarts += 1;
44525
+ entry.contentWatcher = startChokidarContentWatcher(entry, target);
44526
+ scheduleBroadcast(entry, "files");
44527
+ }
44528
+ });
44529
+ entry.contentWatcher = watcher;
44530
+ return;
44531
+ } catch (error) {
44532
+ console.error(`[plannotator] Native file watching unavailable for ${target.watchPath}; using the fallback watcher:`, error);
44533
+ }
44534
+ }
44535
+ entry.contentWatcher = startChokidarContentWatcher(entry, target);
44521
44536
  }
44522
- const gitWatchPaths = target.watchGit ? getGitMetadataWatchPaths(target.watchPath) : [];
44523
- if (gitWatchPaths.length > 0) {
44524
- entry.gitWatcher = chokidar_default.watch(gitWatchPaths, {
44525
- ignoreInitial: true,
44526
- persistent: true,
44527
- depth: 0,
44528
- awaitWriteFinish: {
44529
- stabilityThreshold: 80,
44530
- pollInterval: 30
44537
+ function buildWatchers(entry, target) {
44538
+ if (!isCurrent(entry))
44539
+ return;
44540
+ try {
44541
+ startContentWatcher(entry, target);
44542
+ } catch (error) {
44543
+ console.error(`[plannotator] File watcher failed to start for ${target.watchPath}:`, error);
44544
+ }
44545
+ try {
44546
+ const gitWatchPaths = target.watchGit ? options.getGitMetadataWatchPaths(target.watchPath) : [];
44547
+ if (gitWatchPaths.length > 0) {
44548
+ entry.gitWatcher = chokidar_default.watch(gitWatchPaths, {
44549
+ ignoreInitial: true,
44550
+ persistent: true,
44551
+ depth: 0,
44552
+ awaitWriteFinish: {
44553
+ stabilityThreshold: 80,
44554
+ pollInterval: 30
44555
+ }
44556
+ });
44557
+ entry.gitWatcher.on("all", () => scheduleBroadcast(entry, "git"));
44558
+ entry.gitWatcher.on("error", () => scheduleBroadcast(entry, "git"));
44531
44559
  }
44532
- });
44533
- entry.gitWatcher.on("all", () => scheduleBroadcast(entry, "git"));
44534
- entry.gitWatcher.on("error", () => scheduleBroadcast(entry, "git"));
44560
+ } catch (error) {
44561
+ console.error(`[plannotator] Git metadata watcher failed to start for ${target.watchPath}:`, error);
44562
+ }
44563
+ }
44564
+ function closeEntry(entry) {
44565
+ entry.closed = true;
44566
+ if (entry.debounceTimer)
44567
+ clearTimeout(entry.debounceTimer);
44568
+ if (entry.warmupTimer)
44569
+ clearTimeout(entry.warmupTimer);
44570
+ if (entry.teardownTimer)
44571
+ clearTimeout(entry.teardownTimer);
44572
+ entry.debounceTimer = null;
44573
+ entry.warmupTimer = null;
44574
+ entry.teardownTimer = null;
44575
+ try {
44576
+ entry.contentWatcher?.close();
44577
+ } catch {}
44578
+ try {
44579
+ entry.gitWatcher?.close();
44580
+ } catch {}
44581
+ if (watchers.get(entry.key) === entry) {
44582
+ watchers.delete(entry.key);
44583
+ }
44584
+ }
44585
+ function scheduleTeardown(entry) {
44586
+ if (entry.closed)
44587
+ return;
44588
+ if (entry.teardownTimer)
44589
+ clearTimeout(entry.teardownTimer);
44590
+ const timer = setTimeout(() => {
44591
+ entry.teardownTimer = null;
44592
+ if (entry.subscribers.size === 0)
44593
+ closeEntry(entry);
44594
+ }, teardownGraceMs());
44595
+ timer.unref?.();
44596
+ entry.teardownTimer = timer;
44597
+ }
44598
+ return {
44599
+ ensure(target) {
44600
+ const existing = watchers.get(target.key);
44601
+ if (existing) {
44602
+ if (existing.teardownTimer) {
44603
+ clearTimeout(existing.teardownTimer);
44604
+ existing.teardownTimer = null;
44605
+ }
44606
+ return existing;
44607
+ }
44608
+ const entry = {
44609
+ key: target.key,
44610
+ subscribers: new Map,
44611
+ contentWatcher: null,
44612
+ gitWatcher: null,
44613
+ debounceTimer: null,
44614
+ warmupTimer: null,
44615
+ teardownTimer: null,
44616
+ closed: false
44617
+ };
44618
+ entry.warmupTimer = setTimeout(() => {
44619
+ entry.warmupTimer = null;
44620
+ buildWatchers(entry, target);
44621
+ }, 0);
44622
+ watchers.set(target.key, entry);
44623
+ return entry;
44624
+ },
44625
+ attach(handle2, subscriber, clientDirPath) {
44626
+ const entry = watchers.get(handle2.key);
44627
+ if (!entry || entry.closed)
44628
+ return;
44629
+ entry.subscribers.set(subscriber, clientDirPath);
44630
+ },
44631
+ release(handle2, subscriber) {
44632
+ const entry = watchers.get(handle2.key);
44633
+ if (!entry)
44634
+ return;
44635
+ entry.subscribers.delete(subscriber);
44636
+ if (entry.subscribers.size === 0)
44637
+ scheduleTeardown(entry);
44638
+ },
44639
+ closeAll() {
44640
+ for (const entry of [...watchers.values()])
44641
+ closeEntry(entry);
44642
+ },
44643
+ diagnostics() {
44644
+ return { entries: watchers.size, contentWatcherStarts };
44645
+ },
44646
+ configureForTests(overrides) {
44647
+ Object.assign(options, overrides);
44648
+ }
44649
+ };
44650
+ }
44651
+ var DEFAULT_TEARDOWN_GRACE_MS = 30000, DEFAULT_DEBOUNCE_MS = 180;
44652
+ var init_file_browser_watch_core = __esm(() => {
44653
+ init_chokidar();
44654
+ });
44655
+
44656
+ // ../../packages/server/reference-watch.ts
44657
+ import { existsSync as existsSync11, statSync as statSync9 } from "fs";
44658
+ import { dirname as dirname5, isAbsolute as isAbsolute5, relative as relative5 } from "path";
44659
+ function serialize(event) {
44660
+ return encoder.encode(`data: ${JSON.stringify(event)}
44661
+
44662
+ `);
44663
+ }
44664
+ function closeAllFileBrowserWatchers() {
44665
+ registry.closeAll();
44666
+ }
44667
+ function isFileBrowserWatchIgnoredPath(path2, root3) {
44668
+ const rel = relative5(root3, path2).replace(/\\/g, "/");
44669
+ if (!rel || rel.startsWith("..") || isAbsolute5(rel))
44670
+ return false;
44671
+ return isFileBrowserExcludedPath(rel);
44672
+ }
44673
+ function isValidDirectory(dirPath) {
44674
+ try {
44675
+ return existsSync11(dirPath) && statSync9(dirPath).isDirectory();
44676
+ } catch {
44677
+ return false;
44535
44678
  }
44536
- watchers.set(target.key, entry);
44537
- return entry;
44538
44679
  }
44539
44680
  function isValidFileTarget(filePath) {
44540
44681
  if (!filePath)
44541
44682
  return false;
44542
44683
  try {
44543
44684
  if (existsSync11(filePath))
44544
- return !statSync8(filePath).isDirectory();
44685
+ return !statSync9(filePath).isDirectory();
44545
44686
  return isValidDirectory(dirname5(filePath));
44546
44687
  } catch {
44547
44688
  return false;
@@ -44593,7 +44734,7 @@ function handleFileBrowserFilesStream(req, options) {
44593
44734
  }
44594
44735
  options?.disableIdleTimeout?.();
44595
44736
  const subscriptions = [...targets.values()].map((target) => ({
44596
- entry: ensureWatcher(target),
44737
+ handle: registry.ensure(target),
44597
44738
  clientDirPath: target.clientDirPath
44598
44739
  }));
44599
44740
  let controllerRef = null;
@@ -44601,8 +44742,8 @@ function handleFileBrowserFilesStream(req, options) {
44601
44742
  const stream = new ReadableStream({
44602
44743
  start(controller) {
44603
44744
  controllerRef = controller;
44604
- for (const { entry, clientDirPath } of subscriptions) {
44605
- entry.subscribers.set(controller, clientDirPath);
44745
+ for (const { handle: handle2, clientDirPath } of subscriptions) {
44746
+ registry.attach(handle2, controller, clientDirPath);
44606
44747
  controller.enqueue(serialize({
44607
44748
  type: "ready",
44608
44749
  dirPath: clientDirPath,
@@ -44616,8 +44757,8 @@ function handleFileBrowserFilesStream(req, options) {
44616
44757
 
44617
44758
  `));
44618
44759
  } catch {
44619
- for (const { entry } of subscriptions)
44620
- releaseSubscriber(entry, controller);
44760
+ for (const { handle: handle2 } of subscriptions)
44761
+ registry.release(handle2, controller);
44621
44762
  if (heartbeatTimer)
44622
44763
  clearInterval(heartbeatTimer);
44623
44764
  }
@@ -44627,8 +44768,8 @@ function handleFileBrowserFilesStream(req, options) {
44627
44768
  if (heartbeatTimer)
44628
44769
  clearInterval(heartbeatTimer);
44629
44770
  if (controllerRef) {
44630
- for (const { entry } of subscriptions)
44631
- releaseSubscriber(entry, controllerRef);
44771
+ for (const { handle: handle2 } of subscriptions)
44772
+ registry.release(handle2, controllerRef);
44632
44773
  }
44633
44774
  }
44634
44775
  });
@@ -44640,14 +44781,24 @@ function handleFileBrowserFilesStream(req, options) {
44640
44781
  }
44641
44782
  });
44642
44783
  }
44643
- var HEARTBEAT_MS = 30000, DEBOUNCE_MS = 180, watchers, encoder;
44784
+ var HEARTBEAT_MS = 30000, encoder, registry;
44644
44785
  var init_reference_watch = __esm(() => {
44645
- init_chokidar();
44786
+ init_file_browser_watch_core();
44646
44787
  init_reference_common();
44647
44788
  init_resolve_file();
44648
44789
  init_workspace_status();
44649
- watchers = new Map;
44650
44790
  encoder = new TextEncoder;
44791
+ registry = createFileBrowserWatchRegistry({
44792
+ send: (subscriber, event) => {
44793
+ try {
44794
+ subscriber.enqueue(serialize(event));
44795
+ return true;
44796
+ } catch {
44797
+ return false;
44798
+ }
44799
+ },
44800
+ getGitMetadataWatchPaths
44801
+ });
44651
44802
  });
44652
44803
 
44653
44804
  // ../../packages/server/editor-annotations.ts
@@ -45512,7 +45663,7 @@ function clampPositiveNumber(value, max) {
45512
45663
  }
45513
45664
  function createAIEndpoints(deps) {
45514
45665
  const {
45515
- registry,
45666
+ registry: registry2,
45516
45667
  sessionManager,
45517
45668
  getCwd,
45518
45669
  beforeCapabilities,
@@ -45522,12 +45673,12 @@ function createAIEndpoints(deps) {
45522
45673
  "/api/ai/capabilities": async (req) => {
45523
45674
  await beforeCapabilities?.();
45524
45675
  const activateId = new URL(req.url).searchParams.get("activate");
45525
- if (activateId && registry.get(activateId)) {
45676
+ if (activateId && registry2.get(activateId)) {
45526
45677
  await beforeProviderSession?.(activateId);
45527
45678
  }
45528
- const defaultEntry = registry.getDefault();
45529
- const providerDetails = registry.list().map((id) => {
45530
- const p2 = registry.get(id);
45679
+ const defaultEntry = registry2.getDefault();
45680
+ const providerDetails = registry2.list().map((id) => {
45681
+ const p2 = registry2.get(id);
45531
45682
  return {
45532
45683
  id,
45533
45684
  name: p2.name,
@@ -45550,7 +45701,7 @@ function createAIEndpoints(deps) {
45550
45701
  if (!context?.mode) {
45551
45702
  return Response.json({ error: "Missing context.mode" }, { status: 400 });
45552
45703
  }
45553
- const providerEntry = providerId ? { id: providerId, provider: registry.get(providerId) } : registry.getDefault();
45704
+ const providerEntry = providerId ? { id: providerId, provider: registry2.get(providerId) } : registry2.getDefault();
45554
45705
  const provider = providerEntry?.provider;
45555
45706
  if (!provider) {
45556
45707
  return Response.json({ error: providerId ? `Provider "${providerId}" not found` : "No AI provider available" }, { status: 503 });
@@ -76815,7 +76966,7 @@ var init_opencode_sdk = __esm(() => {
76815
76966
  // ../../packages/server/ai-runtime.ts
76816
76967
  async function createAIRuntime(options = {}) {
76817
76968
  const cwd = options.cwd ?? process.cwd();
76818
- const registry = new ProviderRegistry;
76969
+ const registry2 = new ProviderRegistry;
76819
76970
  const sessionManager = new SessionManager;
76820
76971
  const modelDiscovery = [];
76821
76972
  const providerInitializers = new Map;
@@ -76827,7 +76978,7 @@ async function createAIRuntime(options = {}) {
76827
76978
  cwd,
76828
76979
  ...claudePath && { claudeExecutablePath: claudePath }
76829
76980
  });
76830
- registry.register(provider);
76981
+ registry2.register(provider);
76831
76982
  } catch {}
76832
76983
  try {
76833
76984
  await Promise.resolve().then(() => (init_codex_app_server(), exports_codex_app_server));
@@ -76838,7 +76989,7 @@ async function createAIRuntime(options = {}) {
76838
76989
  cwd,
76839
76990
  ...codexPath ? { codexExecutablePath: codexPath } : {}
76840
76991
  });
76841
- const providerId = registry.register(provider);
76992
+ const providerId = registry2.register(provider);
76842
76993
  if ("fetchModels" in provider) {
76843
76994
  providerInitializers.set(providerId, createBestEffortOnce(() => provider.fetchModels()));
76844
76995
  }
@@ -76857,7 +77008,7 @@ async function createAIRuntime(options = {}) {
76857
77008
  if (provider instanceof PiSDKProvider2) {
76858
77009
  modelDiscovery.push(provider.fetchModels().catch(() => {}));
76859
77010
  }
76860
- registry.register(provider);
77011
+ registry2.register(provider);
76861
77012
  }
76862
77013
  } catch {}
76863
77014
  try {
@@ -76871,11 +77022,11 @@ async function createAIRuntime(options = {}) {
76871
77022
  if (provider instanceof OpenCodeProvider2) {
76872
77023
  modelDiscovery.push(provider.fetchModels().catch(() => {}));
76873
77024
  }
76874
- registry.register(provider);
77025
+ registry2.register(provider);
76875
77026
  }
76876
77027
  } catch {}
76877
77028
  const endpoints = createAIEndpoints({
76878
- registry,
77029
+ registry: registry2,
76879
77030
  sessionManager,
76880
77031
  getCwd: options.getCwd,
76881
77032
  beforeCapabilities: async () => {
@@ -76889,7 +77040,7 @@ async function createAIRuntime(options = {}) {
76889
77040
  endpoints,
76890
77041
  dispose: () => {
76891
77042
  sessionManager.disposeAll();
76892
- registry.disposeAll();
77043
+ registry2.disposeAll();
76893
77044
  }
76894
77045
  };
76895
77046
  }
@@ -77306,6 +77457,7 @@ async function startPlannotatorServer(options) {
77306
77457
  const stop2 = () => {
77307
77458
  stopPromise ??= (async () => {
77308
77459
  try {
77460
+ closeAllFileBrowserWatchers();
77309
77461
  aiRuntime?.dispose();
77310
77462
  } finally {
77311
77463
  await server2.stop(true);
@@ -82872,7 +83024,7 @@ import {
82872
83024
  openSync as openSync3,
82873
83025
  readFileSync as readFileSync10,
82874
83026
  rmSync as rmSync2,
82875
- statSync as statSync10,
83027
+ statSync as statSync11,
82876
83028
  writeFileSync as writeFileSync6
82877
83029
  } from "fs";
82878
83030
  import { dirname as dirname6, join as join17 } from "path";
@@ -82908,7 +83060,7 @@ async function withCallFlowInstallLock(work, options = {}) {
82908
83060
  if (!hasErrorCode(error, "EEXIST"))
82909
83061
  throw error;
82910
83062
  try {
82911
- if (now() - statSync10(lockPath).mtimeMs > staleAfterMs) {
83063
+ if (now() - statSync11(lockPath).mtimeMs > staleAfterMs) {
82912
83064
  rmSync2(lockPath);
82913
83065
  continue;
82914
83066
  }
@@ -83213,7 +83365,7 @@ var init_call_flow_types = __esm(() => {
83213
83365
 
83214
83366
  // ../../packages/shared/call-flow.ts
83215
83367
  import { createHash as createHash4 } from "crypto";
83216
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync11, readdirSync as readdirSync5, renameSync as renameSync4, rmSync as rmSync3, statSync as statSync11, writeFileSync as writeFileSync7 } from "fs";
83368
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync11, readdirSync as readdirSync5, renameSync as renameSync4, rmSync as rmSync3, statSync as statSync12, writeFileSync as writeFileSync7 } from "fs";
83217
83369
  import { mkdtemp } from "fs/promises";
83218
83370
  import { tmpdir as tmpdir3 } from "os";
83219
83371
  import { basename as basename7, dirname as dirname7, isAbsolute as isAbsolute7, join as join18 } from "path";
@@ -83698,7 +83850,7 @@ async function preserveValidatedLanguagePacks(nodePath, currentRuntimeDir, candi
83698
83850
  function measureCallFlowDirectoryBytes(path2) {
83699
83851
  if (!existsSync15(path2))
83700
83852
  return 0;
83701
- const stat5 = statSync11(path2);
83853
+ const stat5 = statSync12(path2);
83702
83854
  if (!stat5.isDirectory())
83703
83855
  return stat5.size;
83704
83856
  return readdirSync5(path2).reduce((total, entry) => total + measureCallFlowDirectoryBytes(join18(path2, entry)), 0);
@@ -86284,7 +86436,7 @@ function createAgentJobHandler(options) {
86284
86436
  }));
86285
86437
  return { mode, providers, available: providers.some((p2) => p2.available) };
86286
86438
  }
86287
- function broadcast2(event) {
86439
+ function broadcast(event) {
86288
86440
  version++;
86289
86441
  const data = encoder2.encode(serializeAgentSSEEvent(event));
86290
86442
  for (const controller of subscribers) {
@@ -86351,7 +86503,7 @@ function createAgentJobHandler(options) {
86351
86503
  jobOutputPaths.set(`${id}:cwd`, spawnOptions.cwd);
86352
86504
  if (spawnOptions?.changedFilesSnapshot)
86353
86505
  jobChangedFilesSnapshots.set(id, spawnOptions.changedFilesSnapshot);
86354
- broadcast2({ type: "job:started", job: { ...info } });
86506
+ broadcast({ type: "job:started", job: { ...info } });
86355
86507
  let stderrBuf = "";
86356
86508
  let logPending = "";
86357
86509
  let logFlushTimer = null;
@@ -86366,7 +86518,7 @@ function createAgentJobHandler(options) {
86366
86518
  if (!logFlushTimer) {
86367
86519
  logFlushTimer = setTimeout(() => {
86368
86520
  if (logPending) {
86369
- broadcast2({ type: "job:log", jobId: id, delta: logPending });
86521
+ broadcast({ type: "job:log", jobId: id, delta: logPending });
86370
86522
  logPending = "";
86371
86523
  }
86372
86524
  logFlushTimer = null;
@@ -86378,7 +86530,7 @@ function createAgentJobHandler(options) {
86378
86530
  logFlushTimer = null;
86379
86531
  }
86380
86532
  if (logPending) {
86381
- broadcast2({ type: "job:log", jobId: id, delta: logPending });
86533
+ broadcast({ type: "job:log", jobId: id, delta: logPending });
86382
86534
  logPending = "";
86383
86535
  }
86384
86536
  } catch {}
@@ -86392,7 +86544,7 @@ function createAgentJobHandler(options) {
86392
86544
  if (provider === "claude" || spawnOptions?.engine === "claude") {
86393
86545
  const formatted = formatClaudeLogEvent(line);
86394
86546
  if (formatted !== null)
86395
- broadcast2({ type: "job:log", jobId: id, delta: formatted + `
86547
+ broadcast({ type: "job:log", jobId: id, delta: formatted + `
86396
86548
  ` });
86397
86549
  return;
86398
86550
  }
@@ -86400,7 +86552,7 @@ function createAgentJobHandler(options) {
86400
86552
  if (markerEngine) {
86401
86553
  const formatted = formatMarkerLogEvent(line, markerEngine);
86402
86554
  if (formatted !== null)
86403
- broadcast2({ type: "job:log", jobId: id, delta: formatted + `
86555
+ broadcast({ type: "job:log", jobId: id, delta: formatted + `
86404
86556
  ` });
86405
86557
  return;
86406
86558
  }
@@ -86409,7 +86561,7 @@ function createAgentJobHandler(options) {
86409
86561
  if (event.type === "result")
86410
86562
  return;
86411
86563
  } catch {}
86412
- broadcast2({ type: "job:log", jobId: id, delta: line + `
86564
+ broadcast({ type: "job:log", jobId: id, delta: line + `
86413
86565
  ` });
86414
86566
  };
86415
86567
  try {
@@ -86463,15 +86615,15 @@ function createAgentJobHandler(options) {
86463
86615
  jobOutputPaths.delete(id);
86464
86616
  jobOutputPaths.delete(`${id}:cwd`);
86465
86617
  jobChangedFilesSnapshots.delete(id);
86466
- broadcast2({ type: "job:completed", job: { ...entry.info } });
86618
+ broadcast({ type: "job:completed", job: { ...entry.info } });
86467
86619
  }).catch(() => {});
86468
86620
  } catch (err) {
86469
86621
  jobs.set(id, { info, proc: null });
86470
- broadcast2({ type: "job:started", job: { ...info } });
86622
+ broadcast({ type: "job:started", job: { ...info } });
86471
86623
  info.status = "failed";
86472
86624
  info.endedAt = Date.now();
86473
86625
  info.error = err instanceof Error ? err.message : String(err);
86474
- broadcast2({ type: "job:completed", job: { ...info } });
86626
+ broadcast({ type: "job:completed", job: { ...info } });
86475
86627
  }
86476
86628
  return { ...info };
86477
86629
  }
@@ -86489,7 +86641,7 @@ function createAgentJobHandler(options) {
86489
86641
  jobOutputPaths.delete(id);
86490
86642
  jobOutputPaths.delete(`${id}:cwd`);
86491
86643
  jobChangedFilesSnapshots.delete(id);
86492
- broadcast2({ type: "job:completed", job: { ...entry.info } });
86644
+ broadcast({ type: "job:completed", job: { ...entry.info } });
86493
86645
  return true;
86494
86646
  }
86495
86647
  function killAll() {
@@ -86519,7 +86671,7 @@ function createAgentJobHandler(options) {
86519
86671
  entry.info.error = undefined;
86520
86672
  entry.info.summary = summary;
86521
86673
  entry.info.exitCode = 0;
86522
- broadcast2({ type: "job:completed", job: { ...entry.info } });
86674
+ broadcast({ type: "job:completed", job: { ...entry.info } });
86523
86675
  return true;
86524
86676
  }
86525
86677
  return {
@@ -99035,7 +99187,7 @@ var init_html_assets = __esm(() => {
99035
99187
  });
99036
99188
 
99037
99189
  // ../../packages/shared/html-assets-node.ts
99038
- import { existsSync as existsSync18, readFileSync as readFileSync14, realpathSync as realpathSync5, statSync as statSync12 } from "fs";
99190
+ import { existsSync as existsSync18, readFileSync as readFileSync14, realpathSync as realpathSync5, statSync as statSync13 } from "fs";
99039
99191
  import { dirname as dirname9, isAbsolute as isAbsolute8, relative as relative8, resolve as resolvePath2, posix as pathPosix2 } from "path";
99040
99192
  function inlineHtmlLocalAssets(html5, htmlFilePath) {
99041
99193
  if (/^https?:\/\//i.test(htmlFilePath))
@@ -99053,7 +99205,7 @@ function inlineHtmlLocalAssets(html5, htmlFilePath) {
99053
99205
  return null;
99054
99206
  if (!existsSync18(resolved))
99055
99207
  return null;
99056
- const stat5 = statSync12(resolved);
99208
+ const stat5 = statSync13(resolved);
99057
99209
  if (!stat5.isFile() || stat5.size > MAX_HTML_ASSET_BYTES)
99058
99210
  return null;
99059
99211
  let bytes = readFileSync14(resolved);
@@ -104284,11 +104436,15 @@ async function startAnnotateServer(options) {
104284
104436
  const serverUrl = buildAdvertisedUrl(port);
104285
104437
  warmFileListCache(process.cwd(), "code");
104286
104438
  const stop2 = () => {
104287
- clientLease.cancel();
104288
- clientLease.closeSessions();
104289
- aiRuntime?.dispose();
104290
- agentTerminal.dispose();
104291
- server2.stop();
104439
+ try {
104440
+ closeAllFileBrowserWatchers();
104441
+ clientLease.cancel();
104442
+ clientLease.closeSessions();
104443
+ aiRuntime?.dispose();
104444
+ agentTerminal.dispose();
104445
+ } finally {
104446
+ server2.stop();
104447
+ }
104292
104448
  };
104293
104449
  if (onReady) {
104294
104450
  try {
@@ -104401,7 +104557,7 @@ var init_annotate_args = __esm(() => {
104401
104557
  });
104402
104558
 
104403
104559
  // ../../packages/shared/annotate-target.ts
104404
- import { existsSync as existsSync22, statSync as statSync13 } from "fs";
104560
+ import { existsSync as existsSync22, statSync as statSync14 } from "fs";
104405
104561
  function probeAnnotateToken(token2, projectRoot, options) {
104406
104562
  if (!token2)
104407
104563
  return null;
@@ -104412,7 +104568,7 @@ function probeAnnotateToken(token2, projectRoot, options) {
104412
104568
  if (allowBareDirectory || /[\\/]/.test(token2)) {
104413
104569
  const folder = resolveAtReference(token2, (candidate) => {
104414
104570
  try {
104415
- return statSync13(resolveUserPath(candidate, projectRoot)).isDirectory();
104571
+ return statSync14(resolveUserPath(candidate, projectRoot)).isDirectory();
104416
104572
  } catch {
104417
104573
  return false;
104418
104574
  }
@@ -104436,7 +104592,7 @@ function probeAnnotateToken(token2, projectRoot, options) {
104436
104592
  return unwrapped;
104437
104593
  const literal = resolveAtReference(token2, (candidate) => {
104438
104594
  try {
104439
- return statSync13(resolveUserPath(candidate, projectRoot)).isFile();
104595
+ return statSync14(resolveUserPath(candidate, projectRoot)).isFile();
104440
104596
  } catch {
104441
104597
  return false;
104442
104598
  }
@@ -104815,7 +104971,7 @@ var init_url_to_markdown = __esm(() => {
104815
104971
  });
104816
104972
 
104817
104973
  // ../../packages/shared/review-workspace-node.ts
104818
- import { existsSync as existsSync23, readdirSync as readdirSync7, realpathSync as realpathSync7, statSync as statSync14 } from "fs";
104974
+ import { existsSync as existsSync23, readdirSync as readdirSync7, realpathSync as realpathSync7, statSync as statSync15 } from "fs";
104819
104975
  import { basename as basename10, relative as relative9, resolve as resolve13 } from "path";
104820
104976
  function normalizeWorkspacePath(path3) {
104821
104977
  return path3.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -104923,7 +105079,7 @@ function hasVcsMarker(dirPath) {
104923
105079
  }
104924
105080
  function resolveDirectoryRealPath(path3) {
104925
105081
  try {
104926
- if (!statSync14(path3).isDirectory())
105082
+ if (!statSync15(path3).isDirectory())
104927
105083
  return null;
104928
105084
  return realpathSync7(path3);
104929
105085
  } catch {
@@ -105415,7 +105571,7 @@ __export(exports_commands, {
105415
105571
  handleAnnotateLastCommand: () => handleAnnotateLastCommand,
105416
105572
  handleAnnotateCommand: () => handleAnnotateCommand
105417
105573
  });
105418
- import { statSync as statSync15 } from "fs";
105574
+ import { statSync as statSync16 } from "fs";
105419
105575
  import path3 from "path";
105420
105576
  async function handleReviewCommand(event, deps) {
105421
105577
  const { client: client3, reviewHtmlContent, getSharingEnabled, getShareBaseUrl, directory } = deps;
@@ -105597,7 +105753,7 @@ async function handleAnnotateCommand(event, deps) {
105597
105753
  const projectRoot = agentCwd;
105598
105754
  const resolvedArg = resolveUserPath(filePath, projectRoot);
105599
105755
  try {
105600
- isFolder = statSync15(resolvedArg).isDirectory();
105756
+ isFolder = statSync16(resolvedArg).isDirectory();
105601
105757
  } catch {}
105602
105758
  if (isFolder) {
105603
105759
  if (!hasMarkdownFiles(resolvedArg, FILE_BROWSER_EXCLUDED, getAnnotatableDocRegex())) {
@@ -105611,7 +105767,7 @@ async function handleAnnotateCommand(event, deps) {
105611
105767
  client3.app.log({ level: "info", message: `Opening annotation UI for folder ${resolvedArg}...` });
105612
105768
  } else if (/\.html?$/i.test(resolvedArg)) {
105613
105769
  try {
105614
- statSync15(resolvedArg);
105770
+ statSync16(resolvedArg);
105615
105771
  } catch {
105616
105772
  client3.app.log({ level: "error", message: `File not found: ${filePath}` });
105617
105773
  return;