Skip to content

fix(memory): make extraPaths watch match nested directories recursively#64654

Closed
Pick-cat wants to merge 2 commits into
openclaw:mainfrom
Pick-cat:fix/issue-64549-extraPaths-watch-recursive-glob
Closed

fix(memory): make extraPaths watch match nested directories recursively#64654
Pick-cat wants to merge 2 commits into
openclaw:mainfrom
Pick-cat:fix/issue-64549-extraPaths-watch-recursive-glob

Conversation

@Pick-cat

Copy link
Copy Markdown
Contributor

Fixes #64549

The glob pattern **/*.md only matches files in immediate
subdirectory, not nested subdirectories. Change to **/**/*.md
for recursive matching through all nested directory levels in
extraPaths and workspace/memory.

This ensures that when memorySearch.sync.watch=true, newly created
markdown files in any nested subdirectory under extraPaths or
workspace/memory are automatically indexed.

Fixes openclaw#64549

The glob pattern `**/*.md` only matches files in immediate
subdirectory, not nested subdirectories. Change to `**/**/*.md`
for recursive matching through all nested directory levels in
extraPaths and workspace/memory.

This ensures that when memorySearch.sync.watch=true, newly created
markdown files in any nested subdirectory under extraPaths or
workspace/memory are automatically indexed.

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

Copy link
Copy Markdown
Contributor

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: 2aa1e26005

ℹ️ 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 on lines +175 to +176
path.join(extraDir, "**", "**", "*.[pP][nN][gG]"),
path.join(extraDir, "**", "**", "*.[wW][aA][vV]"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Restore multimodal glob expectation to match watcher output

These expected paths were changed to extraDir/**/**/*, but ensureWatcher still builds multimodal watch globs as path.join(entry, "**", buildCaseInsensitiveExtensionGlob(...)) in manager-sync-ops.ts, which produces extraDir/**/*. As written, this test now asserts a pattern the implementation never emits, so watches multimodal extensions with case-insensitive globs will fail when run.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Addressed in commit a379b98 — reverted multimodal test expectations back to single-** format to match what the implementation actually emits.

@greptile-apps

greptile-apps Bot commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR attempts to fix recursive file watching for extraPaths by replacing a non-recursive glob with a deeper pattern, and adds a new test file to verify watcher configuration. However, the implementation and test expectations are mutually inconsistent in two places, meaning both added test cases will fail as written.

  • manager-sync-ops.ts line 355: produces {extraDir}/**/**/*.md (via path.join(entry, \"**\", \"**/*.md\")), but the test asserts {extraDir}/**/*.md — the strings differ, so the markdown watch test fails.
  • manager.watcher-config.test.ts lines 175–178: the multimodal assertions expect a redundant \"**\" segment ({extraDir}/**/**/*.[ext]) that the implementation never emits, causing the multimodal watch test to also fail.

Confidence Score: 2/5

Not safe to merge — both new test cases fail due to implementation/expectation mismatches introduced in this PR.

Two P1 findings: the markdown glob pattern in the implementation (//.md) differs from what the test asserts (**/.md), and the multimodal test expects an extra ** segment that the implementation never produces. Both tests will fail.

Both changed files need attention: manager-sync-ops.ts line 355 and manager.watcher-config.test.ts lines 175–178.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/memory-core/src/memory/manager-sync-ops.ts
Line: 355

Comment:
**Glob pattern mismatch with test expectation**

`path.join(entry, "**", "**/*.md")` produces `{extraDir}/**/**/*.md`, but the corresponding test at line 143 of `manager.watcher-config.test.ts` asserts `path.join(extraDir, "**", "*.md")` = `{extraDir}/**/*.md`. These are different strings, so the test will fail. The intended fix also diverges from the already-working workspace pattern on line 345, which uses `path.join(this.workspaceDir, "memory", "**", "*.md")` — same two-component structure.

```suggestion
          watchPaths.add(path.join(entry, "**", "*.md"));
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/memory-core/src/memory/manager.watcher-config.test.ts
Line: 175-178

Comment:
**Multimodal test expectation mismatches the implementation**

The multimodal watcher in `manager-sync-ops.ts` line 360 generates `path.join(entry, "**", buildCaseInsensitiveExtensionGlob(extension))``{extraDir}/**/*.[pP][nN][gG]`. These assertions expect an extra `"**"` segment (`{extraDir}/**/**/*.[pP][nN][gG]`), which is not what the implementation emits, so this test case will also fail.

```suggestion
        expect(watchedPaths).toEqual(
          expect.arrayContaining([
            path.join(extraDir, "**", "*.[pP][nN][gG]"),
            path.join(extraDir, "**", "*.[wW][aA][vV]"),
          ]),
        );
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(memory): make extraPaths watch match..." | Re-trigger Greptile

}
if (stat.isDirectory()) {
watchPaths.add(path.join(entry, "**", "*.md"));
watchPaths.add(path.join(entry, "**", "**/*.md"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Glob pattern mismatch with test expectation

path.join(entry, "**", "**/*.md") produces {extraDir}/**/**/*.md, but the corresponding test at line 143 of manager.watcher-config.test.ts asserts path.join(extraDir, "**", "*.md") = {extraDir}/**/*.md. These are different strings, so the test will fail. The intended fix also diverges from the already-working workspace pattern on line 345, which uses path.join(this.workspaceDir, "memory", "**", "*.md") — same two-component structure.

Suggested change
watchPaths.add(path.join(entry, "**", "**/*.md"));
watchPaths.add(path.join(entry, "**", "*.md"));
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/memory-core/src/memory/manager-sync-ops.ts
Line: 355

Comment:
**Glob pattern mismatch with test expectation**

`path.join(entry, "**", "**/*.md")` produces `{extraDir}/**/**/*.md`, but the corresponding test at line 143 of `manager.watcher-config.test.ts` asserts `path.join(extraDir, "**", "*.md")` = `{extraDir}/**/*.md`. These are different strings, so the test will fail. The intended fix also diverges from the already-working workspace pattern on line 345, which uses `path.join(this.workspaceDir, "memory", "**", "*.md")` — same two-component structure.

```suggestion
          watchPaths.add(path.join(entry, "**", "*.md"));
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Addressed in commit a379b98 — changed to path.join(entry, "**", "*.md") to match the workspace memory pattern on line 345 and the test expectations.

Comment on lines 175 to 178
path.join(extraDir, "**", "**", "*.[pP][nN][gG]"),
path.join(extraDir, "**", "**", "*.[wW][aA][vV]"),
]),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Multimodal test expectation mismatches the implementation

The multimodal watcher in manager-sync-ops.ts line 360 generates path.join(entry, "**", buildCaseInsensitiveExtensionGlob(extension)){extraDir}/**/*.[pP][nN][gG]. These assertions expect an extra "**" segment ({extraDir}/**/**/*.[pP][nN][gG]), which is not what the implementation emits, so this test case will also fail.

Suggested change
path.join(extraDir, "**", "**", "*.[pP][nN][gG]"),
path.join(extraDir, "**", "**", "*.[wW][aA][vV]"),
]),
);
expect(watchedPaths).toEqual(
expect.arrayContaining([
path.join(extraDir, "**", "*.[pP][nN][gG]"),
path.join(extraDir, "**", "*.[wW][aA][vV]"),
]),
);
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/memory-core/src/memory/manager.watcher-config.test.ts
Line: 175-178

Comment:
**Multimodal test expectation mismatches the implementation**

The multimodal watcher in `manager-sync-ops.ts` line 360 generates `path.join(entry, "**", buildCaseInsensitiveExtensionGlob(extension))``{extraDir}/**/*.[pP][nN][gG]`. These assertions expect an extra `"**"` segment (`{extraDir}/**/**/*.[pP][nN][gG]`), which is not what the implementation emits, so this test case will also fail.

```suggestion
        expect(watchedPaths).toEqual(
          expect.arrayContaining([
            path.join(extraDir, "**", "*.[pP][nN][gG]"),
            path.join(extraDir, "**", "*.[wW][aA][vV]"),
          ]),
        );
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Addressed in commit a379b98 — fixed test expectations to use path.join(extraDir, "**", "*.[pP][nN][gG]") format, matching the actual output of the multimodal watcher.

Update test expectations to match the actual behavior where
extraPaths uses `**/**/*.md` for recursive matching through all
nested directory levels.
frankentini added a commit to frankentini/openclaw that referenced this pull request Apr 11, 2026
- manager-sync-ops.ts: use path.join(entry, '**', '*.md') for extraPaths
  markdown files, consistent with workspace memory pattern
- manager.watcher-config.test.ts: fix test expectations to match
  actual implementation output (single ** not double **)

Addresses review feedback on PR openclaw#64654
@Pick-cat

Copy link
Copy Markdown
Contributor Author

关闭此 PR,因为上游已经通过不同的方式修复了相同的问题。上游 PR #64711 (提交 2204753) 已经修复了 macOS chokidar glob 问题,使用直接监视 memory 目录的方式。

@Pick-cat Pick-cat closed this Apr 13, 2026
@YadingFang

Copy link
Copy Markdown

关闭此 PR,因为上游已经通过不同的方式修复了相同的问题。上游 PR #64711 (提交 2204753) 已经修复了 macOS chokidar glob 问题,使用直接监视 memory 目录的方式。

Quick follow-up after upgrading and retesting:

Environment:

  • OpenClaw 2026.4.12 (1c0672b)
  • Linux ARM64 (Oracle)
  • memorySearch.provider=local
  • node-llama-cpp rebuilt from source (--build-from-source) and indexing works manually

Retest result:

  1. Created new file under workspace/knowledge:
    • knowledge/_watch_probe_20260414_120s.md
  2. Polled ~/.openclaw/memory/main.sqlite for 120s:
    • select count(*) from chunks where path='knowledge/_watch_probe_20260414_120s.md'
    • result stayed 0 at t=0..120s
  3. Ran manual index:
    • openclaw memory index --agent main
  4. Re-checked DB:
    • count becomes 1

Conclusion:

  • Manual indexing path works.
  • Auto watch-triggered indexing path still does not work in this environment on 2026.4.12.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: memorySearch watch does not auto-index new markdown files in workspace/memory or extraPaths

3 participants