lody 0.72.0 → 0.74.0

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.
@@ -1,31 +1,124 @@
1
- import { watch } from "node:fs";
2
- import { a as parseWorkspaceWatchParentMessage, n as normalizeWorkspaceWatchFilename, s as shouldIgnoreWorkspaceWatchFilename } from "./chunks/workspace-watch-protocol-CSO-IQeE.js";
3
- import "node:path";
1
+ import { watch, readdirSync } from "node:fs";
2
+ import { C as CODE_COLLAB_IGNORED_DIRECTORY_NAMES, a as parseWorkspaceWatchParentMessage, n as normalizeWorkspaceWatchFilename, s as shouldIgnoreWorkspaceWatchFilename } from "./chunks/workspace-watch-protocol-CSO-IQeE.js";
3
+ import path__default from "node:path";
4
+ function planWorkspaceWatchTargets(root, entries) {
5
+ const targets = [{ directory: root, recursive: false }];
6
+ for (const entry of entries) {
7
+ if (!entry.isDirectory || CODE_COLLAB_IGNORED_DIRECTORY_NAMES.has(entry.name)) {
8
+ continue;
9
+ }
10
+ targets.push({ directory: path__default.join(root, entry.name), recursive: true });
11
+ }
12
+ return targets;
13
+ }
14
+ function rootEventMayChangeWatchPlan(filename) {
15
+ if (filename === null) {
16
+ return true;
17
+ }
18
+ const normalized = filename.replaceAll("\\", "/");
19
+ return !normalized.includes("/");
20
+ }
21
+ const defaultReadDirectory = (directory) => readdirSync(directory, { withFileTypes: true }).map((entry) => ({
22
+ name: entry.name,
23
+ isDirectory: entry.isDirectory()
24
+ }));
4
25
  function startWorkspaceWatchWorker(options) {
5
26
  const watchers = /* @__PURE__ */ new Map();
6
27
  const watchFactory = options.watchFactory ?? watch;
28
+ const readDirectory = options.readDirectory ?? defaultReadDirectory;
7
29
  const startedAtMs = Date.now();
8
30
  let generation = 0;
9
31
  let reconfigurationCount = 0;
10
32
  let closed = false;
33
+ const closeRoot = (root) => {
34
+ for (const watcher of watchers.get(root) ?? []) watcher.close();
35
+ watchers.delete(root);
36
+ };
11
37
  const close = () => {
12
38
  if (closed) return;
13
39
  closed = true;
14
- for (const watcher of watchers.values()) watcher.close();
15
- watchers.clear();
40
+ for (const root of [...watchers.keys()]) closeRoot(root);
16
41
  clearInterval(statsTimer);
17
42
  };
43
+ const countWatchHandles = () => {
44
+ let total = 0;
45
+ for (const handles of watchers.values()) total += handles.length;
46
+ return total;
47
+ };
18
48
  const statsTimer = setInterval(() => {
19
49
  options.send({
20
50
  type: "code-collab-watch/stats",
21
51
  generation,
22
- watcherCount: watchers.size,
52
+ watcherCount: countWatchHandles(),
23
53
  rssBytes: process.memoryUsage().rss,
24
54
  reconfigurationCount,
25
55
  uptimeMs: Date.now() - startedAtMs
26
56
  });
27
57
  }, options.statsIntervalMs ?? 3e4);
28
58
  statsTimer.unref?.();
59
+ const reportRootError = (root, error) => {
60
+ options.send({
61
+ type: "code-collab-watch/error",
62
+ generation,
63
+ root,
64
+ code: error instanceof Error && "code" in error ? String(error.code) : "UNKNOWN"
65
+ });
66
+ };
67
+ const installRoot = (root) => {
68
+ let entries;
69
+ try {
70
+ entries = readDirectory(root);
71
+ } catch (error) {
72
+ reportRootError(root, error);
73
+ return;
74
+ }
75
+ const handles = [];
76
+ const failRoot = (error) => {
77
+ const current = watchers.get(root);
78
+ if (current !== void 0 && current !== handles) return;
79
+ for (const handle of handles) handle.close();
80
+ watchers.delete(root);
81
+ reportRootError(root, error);
82
+ };
83
+ for (const target of planWorkspaceWatchTargets(root, entries)) {
84
+ const isRootWatch = target.directory === root;
85
+ try {
86
+ const watcher = watchFactory(
87
+ target.directory,
88
+ { recursive: target.recursive, persistent: false },
89
+ (_, filename) => {
90
+ if (closed) return;
91
+ const normalized = filename === null ? null : normalizeWorkspaceWatchFilename(filename);
92
+ if (normalized !== null && shouldIgnoreWorkspaceWatchFilename(normalized)) return;
93
+ if (isRootWatch && rootEventMayChangeWatchPlan(normalized)) {
94
+ scheduleReplan(root);
95
+ }
96
+ options.send({ type: "code-collab-watch/dirty", generation, root });
97
+ }
98
+ );
99
+ watcher.on("error", (error) => failRoot(error));
100
+ handles.push(watcher);
101
+ } catch (error) {
102
+ if (isRootWatch) {
103
+ failRoot(error);
104
+ return;
105
+ }
106
+ }
107
+ }
108
+ watchers.set(root, handles);
109
+ };
110
+ const replanScheduled = /* @__PURE__ */ new Set();
111
+ const scheduleReplan = (root) => {
112
+ if (replanScheduled.has(root)) return;
113
+ replanScheduled.add(root);
114
+ const timer = setTimeout(() => {
115
+ replanScheduled.delete(root);
116
+ if (closed || !watchers.has(root)) return;
117
+ closeRoot(root);
118
+ installRoot(root);
119
+ }, 0);
120
+ timer.unref?.();
121
+ };
29
122
  options.onMessage((raw) => {
30
123
  const message = parseWorkspaceWatchParentMessage(raw);
31
124
  if (!message || closed) return;
@@ -39,41 +132,14 @@ function startWorkspaceWatchWorker(options) {
39
132
  generation = message.generation;
40
133
  reconfigurationCount += 1;
41
134
  const desired = new Set(message.roots);
42
- for (const [root, watcher] of watchers) {
135
+ for (const root of [...watchers.keys()]) {
43
136
  if (!desired.has(root)) {
44
- watcher.close();
45
- watchers.delete(root);
137
+ closeRoot(root);
46
138
  }
47
139
  }
48
140
  for (const root of desired) {
49
141
  if (watchers.has(root)) continue;
50
- try {
51
- const watcher = watchFactory(root, { recursive: true, persistent: false }, (_, filename) => {
52
- if (filename !== null) {
53
- const normalized = normalizeWorkspaceWatchFilename(filename);
54
- if (normalized !== null && shouldIgnoreWorkspaceWatchFilename(normalized)) return;
55
- }
56
- options.send({ type: "code-collab-watch/dirty", generation, root });
57
- });
58
- watcher.on("error", (error) => {
59
- watcher.close();
60
- watchers.delete(root);
61
- options.send({
62
- type: "code-collab-watch/error",
63
- generation,
64
- root,
65
- code: error.code ?? "UNKNOWN"
66
- });
67
- });
68
- watchers.set(root, watcher);
69
- } catch (error) {
70
- options.send({
71
- type: "code-collab-watch/error",
72
- generation,
73
- root,
74
- code: error instanceof Error && "code" in error ? String(error.code) : "UNKNOWN"
75
- });
76
- }
142
+ installRoot(root);
77
143
  }
78
144
  options.send({
79
145
  type: "code-collab-watch/ready",
package/dist/codex-acp.js CHANGED
@@ -3,5 +3,5 @@
3
3
  console.error("CODEX_PATH is required for the bundled Codex ACP adapter.");
4
4
  process.exit(1);
5
5
  }
6
- await import("./chunks/index-Cbwwpq6s.js");
6
+ await import("./chunks/index-Cuqd9gip.js");
7
7
  })();
@@ -1,7 +1,7 @@
1
1
  import { opendir } from "node:fs/promises";
2
2
  import path__default from "node:path";
3
- import { u as buildCodeCollabFileIndexState, z as scanGitDirectoryEntries, F as joinWorkspacePath, G as isInsideGitWorktree, x as computeAllChanges, H as pathSegmentComparisonKey, A as closeDirectoryQuietly } from "./chunks/directory-handle-D57OdGy1.js";
4
- import "./chunks/schemas-CDSDDVK-.js";
3
+ import { x as buildCodeCollabFileIndexState, D as scanGitDirectoryEntries, F as joinWorkspacePath, G as isInsideGitWorktree, A as computeAllChanges, H as pathSegmentComparisonKey, E as closeDirectoryQuietly } from "./chunks/directory-handle-zGmrHbmq.js";
4
+ import "./chunks/schemas-BDpQ67Nq.js";
5
5
  import "node:child_process";
6
6
  import "node:util";
7
7
  import "./chunks/diff-line-counts-BLxwWP6r.js";