Skip to content

[Visible Copilot folder] - Step 2: Remove the hidden Copilot folder fallbacks - #3620

Merged
zeroliu merged 2 commits into
zeroliu/require-visible-copilot-folderfrom
zeroliu/remove-hidden-folder-fallbacks
Oct 15, 2026
Merged

zeroliu merged 2 commits into
zeroliu/require-visible-copilot-folderfrom
zeroliu/remove-hidden-folder-fallbacks

Conversation

@zeroliu

@zeroliu zeroliu commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Relates to Brevilabs/obsidian-copilot-private#712

Why

Obsidian does not index dot folders, so Copilot carried a second way to reach its own files for a hidden Copilot folder. Chat save, history, pins, titles, chat images, AGENTS.md, and projects each checked whether a file was in the vault index and, when it was not, read, wrote, listed, or deleted it through the raw file system instead. With the previous PR in this stack, the Copilot folder is always visible, so every file Copilot owns is in the index and that second path never runs.

What

No visible change for any vault. Copilot now reads and writes its chats, chat images, projects, and AGENTS.md only through Obsidian's vault APIs.

Kept on purpose Why it stays
Reading a chat's frontmatter from disk when Obsidian has not parsed it yet Copy chat link and bookmarks read a note right after its first save
Disk checks that catch chat.md vs Chat.md macOS and Windows treat them as the same file while Obsidian's index does not
Agent Mode refusing paths in dot folders That protects .obsidian and other hidden folders, not the Copilot folder

The "Cannot open source files from hidden directories" notice goes away, since a chat note can no longer be in one.

Non goal

  • Hidden agent folders such as .agents/ and .claude/ keep their disk access for skills.
  • Copilot's caches in .copilot/ keep using the raw file system.
  • No change to how a hidden root is moved; that is the previous PR in this stack.

Screenshot

Not applicable: this PR removes code paths that a visible Copilot folder never reaches, and nothing on screen changes.

Risk

Medium

Criterion Status Reason
No behavior change, or a cosmetic/copy/docs/config change visible where it renders, or deterministic tests cover the changed behavior ✅ The chat persistence, chat image, AGENTS.md, project, deep link, and frontmatter suites cover the remaining vault paths
A defect would fail CI or be obvious on first use ❌ A missed caller would surface only when that action runs, such as pinning or deleting a chat or renaming a project
A revert fully restores prior state, including persisted data ✅ No data format or location changes
No auth, permissions, secrets, or input-handling surface changes ✅ Agent Mode's path checks are unchanged
No public API, plugin API, message, or on-disk contract changes ✅ Notes and project files are written in the same format and place
No core-path concurrency, async-lifecycle, or state-machine changes ✅ Only fallback branches are removed
No hot-path behavior lacks deterministic coverage ✅ Every edited function keeps unit coverage
No new dependency ✅ Dependency manifests are unchanged
Human-only behavior stays in one feature area and surfaces quickly ❌ It spans chats, chat images, projects, and AGENTS.md

Review: read listMarkdownFiles and patchFrontmatter in src/utils/vaultAdapterUtils.ts, ensureFile in src/instructions/agentsFile.ts, and updateProject in src/projects/ProjectFileManager.ts. Then run Verification steps 1-4.

Verification

  1. With the Copilot folder set to copilot, start an Agent Chat, attach an image, and send a message. Open Recent Chats; the chat is listed, and its note in copilot/copilot-conversations/ embeds the image.
  2. Right away, open the chat's More Actions menu and select Copy chat link. The notice says the link was copied. Then pin, rename, and delete the chat from Recent Chats; each action succeeds and the note changes to match.
  3. Create a project, rename it, then delete it. Its folder under copilot/projects/ is created, renamed, and removed.
  4. In Settings → Basic, select Open AGENTS.md. The vault's AGENTS.md opens in a new tab.

@vercel

vercel Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
obsidian-copilot-docs Ignored Ignored Oct 15, 2026 3:37pm UTC

Request Review

@zeroliu

zeroliu commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T04:56:25.157961Z 0884819 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: edb2655b20

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 15 to +17
const folder = app.vault.getAbstractFileByPath(folderPath);
if (folder instanceof TFolder) {
return app.vault.getMarkdownFiles().filter((f) => f.path.startsWith(folder.path));
}

if (await app.vault.adapter.exists(folderPath)) {
const listing = await app.vault.adapter.list(folderPath);
const mdPaths = listing.files.filter((f) => f.endsWith(".md"));
const result: TFile[] = [];
for (const filePath of mdPaths) {
result.push(await createSyntheticTFile(app, filePath));
}
return result;
}

return [];
if (!(folder instanceof TFolder)) return [];
return app.vault.getMarkdownFiles().filter((f) => f.path.startsWith(folder.path));

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 Keep disk fallback until migrated files enter the vault cache

On the upgrade path from a hidden Copilot root, revealHiddenCopilotFolder() moves the directories with vault.adapter.rename() immediately before startup migrations scan projects and chats. Those adapter operations do not synchronously populate Obsidian's Vault cache, so returning [] whenever the destination folder is not yet a cached TFolder can make the just-migrated conversations disappear from Recent Chats and makes the initial project scan cache an empty project list until a reload or later filesystem event. Retain the adapter-backed listing until the migration explicitly ensures the moved tree is indexed.

AGENTS.md reference: AGENTS.md:L84-L89

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Confirmed the timing in Obsidian 1.14.4: adapter.rename() from a hidden source doesn't update the vault index, so only the file watcher indexes the moved tree. It recovers without a reload, though. I reproduced the race by holding back watcher events by 3 s on a vault with a hidden .copilot root: the project scan saw no folder, and once the files were indexed, ProjectRegister's create listener (subscribed before the scan) added both projects to the list. Recent Chats lists the moved chats because it reads files on each open instead of caching them at startup. Keeping the adapter fallback would bring back synthetic TFiles that processFrontMatter/vault.read can't use, just to cover that gap.

@zeroliu
zeroliu added this pull request to stack #3621 October 15, 2026 04:21
@zeroliu
zeroliu force-pushed the zeroliu/remove-hidden-folder-fallbacks branch from edb2655 to 0884819 Compare October 15, 2026 04:45
@zeroliu
zeroliu marked this pull request as ready for review October 15, 2026 04:51
zeroliu and others added 2 commits October 15, 2026 08:33
With the Copilot folder always visible, every Copilot file is in
Obsidian's vault index. Drop the code that read, wrote, listed, and
deleted files outside the index: synthetic TFiles, adapter listings and
writes in chat and project persistence, the hidden chat image path, the
AGENTS.md adapter paths, and the hidden-directory notice. Keep the
adapter reads that cover case-insensitive name collisions and notes
whose metadata Obsidian has not parsed yet.

Relates to Brevilabs/obsidian-copilot-private#712

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guard only routed hidden-folder notes to an adapter branch that no
longer exists; when false it marked a timestamp persisted that was
never written.

Relates to Brevilabs/obsidian-copilot-private#712

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zeroliu
zeroliu force-pushed the zeroliu/remove-hidden-folder-fallbacks branch from 0884819 to 32ab1e3 Compare October 15, 2026 15:37
@zeroliu
zeroliu merged commit 370b4d1 into master Oct 15, 2026
18 checks passed
@zeroliu
zeroliu deleted the zeroliu/remove-hidden-folder-fallbacks branch October 15, 2026 15:47
@zeroliu zeroliu mentioned this pull request Oct 15, 2026
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.

1 participant