Skip to content

refactor(agent-core-v2): unify fs watching into a single xstate watch service - #3502

Merged
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:feat-143-09-03-linux-parcel-watcher
Sep 7, 2026
Merged

refactor(agent-core-v2): unify fs watching into a single xstate watch service#3502
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:feat-143-09-03-linux-parcel-watcher

Conversation

@sailist

@sailist sailist commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — internal refactor of the fs-watch stack (follow-up to EMFILE/wd investigations in large Linux workspaces).

Problem

Fs watching was scattered across four separate implementations: the os-layer HostFsWatchService (chokidar + native signal handle), WorkspaceFsWatchService (whole-tree workspace watch), FileStorageService.watch (document-store watch chain), and kap-server's FsWatchBridge plus the WS watch_fs_add/watch_fs_remove/event.fs.changed protocol surface. The whole WS watch chain has no real client (no sender of watch_fs_add anywhere), and each service re-implements watcher lifecycle, readiness, retry and filtering in its own way.

What changed

  • New single watch service at packages/agent-core-v2/src/human/utils/watch.ts: a module-level singleton whose side effects are managed by xstate — a root machine spawns one child machine per subscription, with fromCallback legs owning the chokidar FSWatcher, the native recursive fs.watch (signal mode on darwin/win32) and the backoff retry timer. Capabilities match the previous implementation: recursive/ignored (native-level pruning)/depth/signal (FSEvents / ReadDirectoryChangesW coarse invalidation, chokidar fallback on ERR_FEATURE_UNAVAILABLE_ON_PLATFORM, 1s→30s exponential retry)/ready/default .git exclusion.
  • Deleted: HostFsWatchService (interface + impl), WorkspaceFsWatchService, FileStorageService.watch and the whole document-store watch chain, kap-server FsWatchBridge, the WS watch_fs_add/watch_fs_remove/event.fs.changed protocol schemas (no consumers), and their tests (-2648/+819 lines).
  • Rewired the seven hot-reload consumers (config.toml, workspaces.json, project skills, agent profiles, AGENTS.md chain, local.toml, mcp.json) to the new service; per-consumer debounce and subtreeWatchFilter pruning are unchanged, so hot-reload behavior is identical.

No new dependencies (chokidar 4 and xstate 5 were already dependencies of agent-core-v2).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9b8468f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@9b8468f
npx https://pkg.pr.new/@moonshot-ai/kimi-code@9b8468f

commit: 9b8468f

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f29952f8bf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agent-core-v2/package.json Outdated
Comment on lines +92 to +95
"optionalDependencies": {
"@parcel/watcher-darwin-arm64": "2.5.1",
"@parcel/watcher-darwin-x64": "2.5.1",
"@parcel/watcher-linux-arm64-glibc": "2.5.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Install Parcel bindings with the published CLI

For users installing @moonshot-ai/kimi-code from npm, these optional dependencies are never installed: agent-core-v2 is private and bundled into apps/kimi-code/dist/main.mjs, while the published package contains only the app's own dependency manifest. The computed runtime require('@parcel/watcher-…') therefore fails and every recursive Linux watch falls back to chokidar, leaving the advertised single-inotify fix unavailable outside the SEA build. Declare or ship the platform bindings from the published CLI package as well.

Useful? React with 👍 / 👎.

const ignorePaths = resolveIgnorePaths(root, options?.ignorePaths);
this.subscribeOptions = {
backend: 'inotify',
...(ignorePaths.length > 0 ? { ignorePaths } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass the optional ignore path property directly

This conditional spread violates the repository rule for optional object properties. Assign ignorePaths directly, using undefined when it should be absent, rather than conditionally spreading a temporary object.

AGENTS.md reference: AGENTS.md:L52-L54

Useful? React with 👍 / 👎.

Comment thread .changeset/linux-parcel-watcher.md Outdated
"@moonshot-ai/kimi-code": patch
---

On Linux, recursive directory watching now uses the native @parcel/watcher binding — one inotify instance for the whole tree instead of one watcher per directory — so watching large workspaces no longer fails with `EMFILE: too many open files`. Heavy generated directories (`.git`, `node_modules`, `.tower`, `.worktrees`, `.jj`) are now pruned at the OS watch level. When the native binding is unavailable, watching falls back to the previous behavior.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Rewrite the changeset as one short sentence

The changeset body contains three detailed sentences, but repository policy requires exactly one short user-facing sentence stating only what changed. Condense this entry before release.

AGENTS.md reference: AGENTS.md:L85-L87

Useful? React with 👍 / 👎.

@sailist
sailist force-pushed the feat-143-09-03-linux-parcel-watcher branch 4 times, most recently from 4afae8a to ad86368 Compare September 3, 2026 13:06
@sailist sailist changed the title feat(agent-core-v2): watch linux directories with @parcel/watcher feat(agent-core-v2): add depth option to host fs watch Sep 3, 2026
@sailist
sailist force-pushed the feat-143-09-03-linux-parcel-watcher branch from ad86368 to 56fab0d Compare September 7, 2026 05:07
@sailist sailist changed the title feat(agent-core-v2): add depth option to host fs watch refactor(agent-core-v2): unify fs watching into a single xstate watch service Sep 7, 2026
@sailist

sailist commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

description: 'Start a client session and optionally subscribe to existing daemon sessions.',
},

P1 Badge Preserve the fs-watch protocol until a major release

When an external client uses the documented watch_fs_add or watch_fs_remove frames, removing both schemas from this union causes the existing protocol-v2 server to reject those requests and stops delivery of event.fs.changed, while WS_PROTOCOL_VERSION remains unchanged. The repository requires breaking changes to go through a changeset with a major bump, but this commit includes neither; retain compatibility or explicitly version and release the removal as a major change.

AGENTS.md reference: AGENTS.md:L61-L61

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sailist
sailist force-pushed the feat-143-09-03-linux-parcel-watcher branch from 56fab0d to 9c85dec Compare September 7, 2026 05:21
@sailist
sailist force-pushed the feat-143-09-03-linux-parcel-watcher branch from 9c85dec to 9b8468f Compare September 7, 2026 05:26
@sailist
sailist merged commit 3f967e1 into MoonshotAI:main Sep 7, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant