{"owner":"foambubble","repo":"foam","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Collaboration Principles\n\n**Be honest and objective**: Evaluate all suggestions, ideas, and feedback on their technical merits. Don't be overly complimentary or sycophantic. If something doesn't make sense, doesn't align with best practices, or could be improved, say so directly and constructively. Technical accuracy and project quality take precedence over being agreeable.\n\n**Prefer simple commands over complex ones**: Each compound/chained/piped command may require manual approval, so default to simple, single-purpose commands that match existing allowlist patterns. Don't staple on \"bonus\" steps the user didn't ask for, and don't wrap things in `bash -c`, `eval`, or defensive `|| true` without reason. Compound commands are fine when genuinely needed: atomic operations (`git add X && git commit`), pipelines where the pipe IS the interface (`find | xargs`, `cmd | jq`), heredocs for multi-line input, and loops over many items (one approval beats N).\n\n**Working in a different directory (worktrees, packages)**: The Bash tool's CWD is always the main checkout — not wherever you last \"cd'd\". To run commands elsewhere without a prompt for each call, match the existing allowlist patterns:\n\n- Prefer `git -C <path> <subcommand>` for git operations (matches `Bash(git -C *)`)\n- For yarn commands, prefer, in order:\n  - `yarn workspace <package> <subcommand>`\n  - `yarn --cwd <path> <command>`\n  - `cd <path> && yarn <subcommand>`\n- Use `cd <path> && npm <subcommand>` for npm\n- Do NOT constantly use `nvm use ...` (e.g. `nvm use <version> && yarn <subcommand>`)\n- Do NOT mix `git -C` with `cd &&` in the same command\n- If you're about to introduce a new pattern (e.g. `cd && python`, `cd && cargo`), pause and either use a simpler equivalent or add the pattern to `.claude/settings.local.json` first\n\nThe point is autonomy: implement runs, agents, and skills should not stop for permission prompts on the same shape of command that already works elsewhere.\n\n## Project overview\n\nFoam is a personal knowledge management and sharing system, built on Visual Studio Code and GitHub. It allows users to organize research, keep re-discoverable notes, write long-form content, and optionally publish it to the web. The main goals are to help users create relationships between thoughts and information, supporting practices like building a \"Second Brain\" or a \"Zettelkasten\". Foam is free, open-source, and extensible, giving users ownership and control over their information. The target audience includes individuals interested in personal knowledge management, note-taking, and content creation, particularly those familiar with VS Code and GitHub.\n\n## Quick Commands\n\nAll the following commands are to be executed from the `packages/foam-vscode` directory\n\n### Development\n\n- `yarn install` - Install dependencies\n- `yarn build` - Build all packages\n- `yarn watch` - Watch mode for development\n- `yarn clean` - Clean build outputs\n- `yarn reset` - Full clean, install, and build\n\n### Testing\n\n- `yarn test` - Run all tests (unit + integration)\n- `yarn test:unit` - Run unit tests (\\*.test.ts files and the .spec.ts files marked as vscode-mock friendly)\n- `yarn test:unit-without-specs` - Run only \\*.test.ts files, skipping all \\*.spec.ts files\n- `yarn test:e2e` - Run only integration tests (all \\*.spec.ts files, including `@unit-ready` ones)\n- `yarn lint` - Run linting\n- `yarn test-reset-workspace` to clean test workspace\n\nUnit tests run in Node.js environment using Vitest\nIntegration tests require VS Code extension host\nWhen running tests, do not provide additional parameters, they are ignored by the custom runner script. You cannot run just a test, you have to run the whole suite.\n\nUnit tests are named `*.test.ts` and integration tests are `*.spec.ts`. These test files live alongside the code in the `src` directory. An integration test is one that has a direct or indirect dependency on `vscode` module.\nThere is a mock `vscode` module that can be used to run most integration tests without starting VS Code. Tests that can use this mock start with the line `/* @unit-ready */`. Note that `@unit-ready` specs run in both `yarn test:unit` (with the mock) and `yarn test:e2e` (in real VS Code) — this is intentional.\n\n- If you are interested in a test inside a `*.test.ts` file, run `yarn test:unit` or inside a `*.spec.ts` file that starts with `/* @unit-ready */` run `yarn test:unit`\n- If you are interested in a test inside a `*.spec.ts` file that does not include `/* @unit-ready */` run `yarn test`\n\nWhile in development we mostly want to use `yarn test:unit`.\nWhen multiple tests are failing, look at all of them, but only focus on fixing the first one. Once that is fixed, run the test suite again and repeat the process.\n\nWhen writing tests keep mocking to a bare minimum. Code should be written in a way that is easily testable and if I/O is necessary, it should be done in appropriate temporary directories.\nNever mock anything that is inside `packages/foam-vscode/src/core/`.\n\nDo not use dynamic imports (`await import(...)` or `import(...)`) anywhere — neither in source code nor in tests. Use static top-level imports instead. If a module needs lazy initialization, refactor to make it explicit rather than reaching for a dynamic import.\n\nUse the utility functions from `test-utils.ts` and `test-utils-vscode.ts` and `test-datastore.ts`.\n\nTo improve readability of the tests, set up the test and tear it down within the test case (as opposed to use other functions like `beforeEach` unless it's much better to do it that way)\n\nNever fix a test by adjusting the expectation if the expectation is correct, test must be fixed by addressing the issue with the code.\n\n## Repository Structure\n\nThis is a monorepo using Yarn workspaces with the main VS Code extension in `packages/foam-vscode/`.\n\n### Key Directories\n\n- `packages/foam-vscode/src/core/` - Platform-agnostic business logic (NO vscode dependencies)\n- `packages/foam-vscode/src/features/` - VS Code-specific features and UI\n- `packages/foam-vscode/src/services/` - service implementations, might have VS Code dependency, but we try keep that to a minimum\n- `packages/foam-vscode/src/test/` - Test utilities and mocks\n- `packages/foam-graph/` - Graph visualization web component (`@foam/graph-view`)\n- `docs/` - Documentation and user guides\n\n### Graph Webview (`@foam/graph-view`)\n\nThe graph webview is a standalone Yarn workspace built with Lit, bundled for use inside the VS Code extension.\n\n- Source lives in `packages/foam-graph/src/`; `packages/foam-vscode/static/dataviz/` is **build output** (gitignored), not source\n- `src/protocol.ts` owns the message contract between extension host and webview — the extension imports from `@foam/graph-view/protocol`\n- The extension's `tsconfig.json` uses `paths` to resolve `@foam/graph-view/*` to TypeScript source for type checking; esbuild resolves via package exports at bundle time\n\nCommands (run from repo root or `packages/foam-vscode`):\n\n- `yarn workspace @foam/graph-view build` - Build VS Code bundle\n- `yarn workspace @foam/graph-view build:vscode` - Build VS Code bundle only\n- `yarn workspace @foam/graph-view watch` - Watch mode for webview development\n- `yarn workspace @foam/graph-view test` - Run webview tests (Vitest)\n\n### File Naming Patterns\n\nTest files follow `*.test.ts` for unit tests and `*.spec.ts` for integration tests, living alongside the code in `src`. An integration test is one that has a direct or indirect dependency on `vscode` package.\n\n### Important Constraint\n\nCode in `packages/foam-vscode/src/core/` MUST NOT depend on the `vscode` library or any files outside the core directory. This maintains platform independence.\n\n### Changesets: a `@foam/core` change must also bump `foam-vscode` and `@foam/cli`\n\n`foam-vscode` and `@foam/cli` **bundle** `@foam/core` at build time (esbuild inlines it) and declare it as a `devDependency`, not a runtime `dependency`. Because of that, Changesets' automatic internal-dependency bumping does **not** cascade a `@foam/core` bump to them.\n\nSo when a change touches `packages/foam-core`, its changeset fragment must **also** list `foam-vscode` and `@foam/cli` (usually `patch`) — otherwise their republished bundles ship updated code under a stale version number with no changelog entry. Rule of thumb: if `@foam/core` is in the fragment, `foam-vscode` and `@foam/cli` almost always belong there too. See `docs/dev/releasing-foam.md`.\n\n### URIs throughout, paths only at the edges\n\nDomain code (everything in `@foam/core` and the platform-agnostic layers of `foam-cli`, `foam-mcp`, `foam-vscode`) takes and returns `URI` objects, not path strings. This is consistent with the existing core API: `FoamWorkspace.find(uri: URI)`, `FoamGraph.getLinks(uri: URI)`, `Resource.uri: URI`.\n\n```typescript\n// ✅ Good\nfunction listOrphans(workspace, graph, rootUri: URI): NoteItem[];\n\n// ❌ Avoid\nfunction listOrphans(workspace, graph, rootDir: string): NoteItem[];\n```\n\nPath strings only appear at:\n\n1. **I/O boundaries** — `IDataStore` implementations convert URI ↔ filesystem path (`URI.file(...)`, `uri.toFsPath()`).\n2. **External wire formats** — CLI argument parsing, MCP tool inputs/outputs, JSON serialization.\n3. **Display fields in return values** — e.g. `NoteItem.path` for human-readable workspace-relative paths, alongside the `URI`.\n\nFor path manipulation inside `@foam/core`, use the POSIX-safe utilities in `packages/foam-core/src/utils/path.ts` (`relativeTo`, `joinPath`, `getBasename`, `getExtension`, `getDirectory`) — never import Node's `path` module, since `@foam/core` runs in both Node and browser contexts.\n\n## Architecture Overview\n\n### Core Abstractions\n\n**FoamWorkspace** - Central repository managing all resources (notes, attachments)\n\n- Uses reversed trie for efficient resource lookup\n- Event-driven updates (onDidAdd, onDidUpdate, onDidDelete)\n- Handles identifier resolution for short-form linking\n\n**FoamGraph** - Manages relationship graph between resources\n\n- Tracks links and backlinks between resources\n- Real-time updates when workspace changes\n- Handles placeholder resources for broken links\n\n**ResourceProvider Pattern** - Pluggable architecture for different file types\n\n- `MarkdownProvider` for .md files\n- `AttachmentProvider` for other file types\n- Extensible for future resource types\n\n**DataStore Interface** - Abstract file system operations\n\n- Platform-agnostic file access with configurable filtering\n- Supports both local and remote file systems\n\n### Feature Integration Pattern\n\nFeatures are registered as functions receiving:\n\n```typescript\n(context: ExtensionContext, foamPromise: Promise<Foam>) => void\n```\n\nThis allows features to:\n\n- Register VS Code commands, providers, and event handlers\n- Access the Foam workspace when ready\n- Extend markdown-it for preview rendering\n\n### Testing Conventions\n\n- `*.test.ts` - Unit tests using Vitest\n- `*.spec.ts` - Integration tests requiring VS Code extension host\n- Tests live alongside source code in `src/`\n- Test cases should be phrased in terms of aspects of the feature being tested (expected behaviors), as they serve both as validation of the code as well as documentation of what the expected behavior for the code is in different situations. They should include the happy paths and edge cases.\n\n## Development Workflow\n\nWe build production code together. I handle implementation details while you guide architecture and catch complexity early.\nWhen working on an issue, check if a `.agent/tasks/<issue-id>-<sanitized-title>.md` exists. If not, suggest whether we should start by doing a research on it (using the `/research-issue <issue-id>`) command.\nWhenever we work together on a task, feel free to challenge my assumptions and ideas and be critical if useful.\n\n## Core Workflow: Research → Plan → Implement → Validate\n\n**Start every feature with:** \"Let me research the codebase and create a plan before implementing.\"\n\n1. **Research** - Understand existing patterns and architecture\n2. **Plan** - Propose approach and verify with you\n3. **Implement** - Build with tests and error handling\n4. **Validate** - ALWAYS run formatters, linters, and tests after implementation\n\n- Whenever working on a feature or issue, let's always come up with a plan first, then save it to a file called `/.agent/current-plan.md`, before getting started with code changes. Update this file as the work progresses.\n- Let's use pure functions where possible to improve readability and testing.\n\n### Adding New Features\n\n1. Create feature in `src/features/` directory\n2. Register feature in `src/features/index.ts`\n3. Add tests (both unit and integration as needed)\n4. Update configuration in `package.json` if needed\n\n### Working on an issue\n\n1. Get the issue information from github\n2. Define a step by step plan for addressing the issue\n3. Create tests for the feature\n4. **IMPORTANT**: Run the tests to ensure they FAIL before implementing the fix (this validates the test is actually testing what we think it is)\n5. Implement the fix to make the test pass\n6. Run the tests again to verify the fix works\n\n### Core Logic Changes\n\n1. Modify code in `src/core/` (ensure no vscode dependencies)\n2. Add comprehensive unit tests\n3. Update integration tests in features that use the core logic\n\n## Configuration\n\nThe extension uses VS Code's configuration system with the `foam.*` namespace.\nYou can find all the settings in `/packages/foam-vscode/package.json`\n\n## Common Development Tasks\n\n### Extending Core Functionality\n\nWhen adding to `src/core/`:\n\n- Keep platform-agnostic (no vscode imports)\n- Add comprehensive unit tests\n- Consider impact on graph and workspace state\n- Update relevant providers if needed\n\n## Dependencies\n\n- **Runtime**: VS Code API, markdown parsing, file watching\n- **Development**: TypeScript, Vitest, ESLint, esbuild\n- **Key Libraries**: remark (markdown parsing), lru-cache, lodash\n- **Graph webview**: Lit (web components), force-graph, d3-force/scale/color, Vitest, happy-dom\n\nThe extension supports both Node.js and browser environments via separate build targets.\n\n## Documentation Guidelines\n\n### User Documentation (`docs/user/`)\n\nDocumentation in `docs/user/` must be written for non-technical users. The goal is to help novice users quickly start using features, not to explain technical implementation details.\n\n**Writing Guidelines:**\n\n- **Target audience**: Assume users are new to Foam and may not be technical\n- **Be concise**: Keep it short and to the point - every sentence must convey useful information\n- **Avoid repetition**: Don't repeat the same concept in different words\n- **Focus on \"how to use\"**: Show users what they can do and how to do it, not how it works internally\n- **Balance brevity with clarity**: Users won't read verbose documentation, but they need enough information to succeed\n- **Use examples**: Show practical use cases rather than abstract descriptions\n- **Start with the most common use case**: Lead with what most users will want to do first\n\n# GitHub CLI Integration\n\nTo interact with the github repo we will be using the `gh` command.\nALWAYS ask before performing a write operation on Github.\n\n## Common Commands for Claude Code Integration\n\n### Issues\n\n```bash\n# List all issues\ngh issue list\n\n# Filter issues by milestone\ngh issue list --milestone \"v1.0.0\"\n\n# Filter issues by assignee\ngh issue list --assignee @me\ngh issue list --assignee username\n\n# Filter issues by label\ngh issue list --label \"bug\"\ngh issue list --label \"enhancement,priority-high\"\n\n# Filter issues by state\ngh issue list --state open\ngh issue list --state closed\ngh issue list --state all\n\n# Combine filters\ngh issue list --milestone \"v1.0.0\" --label \"bug\" --assignee @me\n\n# View specific issue\ngh issue view 123\n\n# Create issue\ngh issue create --title \"Bug fix\" --body \"Description\"\n\n# Add comment to issue\ngh issue comment 123 --body \"Update comment\"\n```\n\n### Pull Requests\n\n```bash\n# List all PRs\ngh pr list\n\n# Filter PRs the same way as for filters (for example, here is by milestone)\ngh pr list --milestone \"v1.0.0\"\n\n# View PR details\ngh pr view 456\n\n# Create PR\ngh pr create --title \"Feature\" --body \"Description\"\n\n# Check out PR locally\ngh pr checkout 456\n\n# Add review comment\ngh pr comment 456 --body \"LGTM\"\n```\n"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Collaboration Principles\n\n**Be honest and objective**: Evaluate all suggestions, ideas, and feedback on their technical merits. Don't be overly complimentary or sycophantic. If something doesn't make sense, doesn't align with best practices, or could be improved, say so directly and constructively. Technical accuracy and project quality take precedence over being agreeable.\n\n**Prefer simple commands over complex ones**: Each compound/chained/piped command may require manual approval, so default to simple, single-purpose commands that match existing allowlist patterns. Don't staple on \"bonus\" steps the user didn't ask for, and don't wrap things in `bash -c`, `eval`, or defensive `|| true` without reason. Compound commands are fine when genuinely needed: atomic operations (`git add X && git commit`), pipelines where the pipe IS the interface (`find | xargs`, `cmd | jq`), heredocs for multi-line input, and loops over many items (one approval beats N).\n\n**Working in a different directory (worktrees, packages)**: The Bash tool's CWD is always the main checkout — not wherever you last \"cd'd\". To run commands elsewhere without a prompt for each call, match the existing allowlist patterns:\n\n- Prefer `git -C <path> <subcommand>` for git operations (matches `Bash(git -C *)`)\n- For yarn commands, prefer, in order:\n  - `yarn workspace <package> <subcommand>`\n  - `yarn --cwd <path> <command>`\n  - `cd <path> && yarn <subcommand>`\n- Use `cd <path> && npm <subcommand>` for npm\n- Do NOT constantly use `nvm use ...` (e.g. `nvm use <version> && yarn <subcommand>`)\n- Do NOT mix `git -C` with `cd &&` in the same command\n- If you're about to introduce a new pattern (e.g. `cd && python`, `cd && cargo`), pause and either use a simpler equivalent or add the pattern to `.claude/settings.local.json` first\n\nThe point is autonomy: implement runs, agents, and skills should not stop for permission prompts on the same shape of command that already works elsewhere.\n\n## Project overview\n\nFoam is a personal knowledge management and sharing system, built on Visual Studio Code and GitHub. It allows users to organize research, keep re-discoverable notes, write long-form content, and optionally publish it to the web. The main goals are to help users create relationships between thoughts and information, supporting practices like building a \"Second Brain\" or a \"Zettelkasten\". Foam is free, open-source, and extensible, giving users ownership and control over their information. The target audience includes individuals interested in personal knowledge management, note-taking, and content creation, particularly those familiar with VS Code and GitHub.\n\n## Quick Commands\n\nAll the following commands are to be executed from the `packages/foam-vscode` directory\n\n### Development\n\n- `yarn install` - Install dependencies\n- `yarn build` - Build all packages\n- `yarn watch` - Watch mode for development\n- `yarn clean` - Clean build outputs\n- `yarn reset` - Full clean, install, and build\n\n### Testing\n\n- `yarn test` - Run all tests (unit + integration)\n- `yarn test:unit` - Run unit tests (\\*.test.ts files and the .spec.ts files marked as vscode-mock friendly)\n- `yarn test:unit-without-specs` - Run only \\*.test.ts files, skipping all \\*.spec.ts files\n- `yarn test:e2e` - Run only integration tests (all \\*.spec.ts files, including `@unit-ready` ones)\n- `yarn lint` - Run linting\n- `yarn test-reset-workspace` to clean test workspace\n\nUnit tests run in Node.js environment using Vitest\nIntegration tests require VS Code extension host\nWhen running tests, do not provide additional parameters, they are ignored by the custom runner script. You cannot run just a test, you have to run the whole suite.\n\nUnit tests are named `*.test.ts` and integration tests are `*.spec.ts`. These test files live alongside the code in the `src` directory. An integration test is one that has a direct or indirect dependency on `vscode` module.\nThere is a mock `vscode` module that can be used to run most integration tests without starting VS Code. Tests that can use this mock start with the line `/* @unit-ready */`. Note that `@unit-ready` specs run in both `yarn test:unit` (with the mock) and `yarn test:e2e` (in real VS Code) — this is intentional.\n\n- If you are interested in a test inside a `*.test.ts` file, run `yarn test:unit` or inside a `*.spec.ts` file that starts with `/* @unit-ready */` run `yarn test:unit`\n- If you are interested in a test inside a `*.spec.ts` file that does not include `/* @unit-ready */` run `yarn test`\n\nWhile in development we mostly want to use `yarn test:unit`.\nWhen multiple tests are failing, look at all of them, but only focus on fixing the first one. Once that is fixed, run the test suite again and repeat the process.\n\nWhen writing tests keep mocking to a bare minimum. Code should be written in a way that is easily testable and if I/O is necessary, it should be done in appropriate temporary directories.\nNever mock anything that is inside `packages/foam-vscode/src/core/`.\n\nDo not use dynamic imports (`await import(...)` or `import(...)`) anywhere — neither in source code nor in tests. Use static top-level imports instead. If a module needs lazy initialization, refactor to make it explicit rather than reaching for a dynamic import.\n\nUse the utility functions from `test-utils.ts` and `test-utils-vscode.ts` and `test-datastore.ts`.\n\nTo improve readability of the tests, set up the test and tear it down within the test case (as opposed to use other functions like `beforeEach` unless it's much better to do it that way)\n\nNever fix a test by adjusting the expectation if the expectation is correct, test must be fixed by addressing the issue with the code.\n\n## Repository Structure\n\nThis is a monorepo using Yarn workspaces with the main VS Code extension in `packages/foam-vscode/`.\n\n### Key Directories\n\n- `packages/foam-vscode/src/core/` - Platform-agnostic business logic (NO vscode dependencies)\n- `packages/foam-vscode/src/features/` - VS Code-specific features and UI\n- `packages/foam-vscode/src/services/` - service implementations, might have VS Code dependency, but we try keep that to a minimum\n- `packages/foam-vscode/src/test/` - Test utilities and mocks\n- `packages/foam-graph/` - Graph visualization web component (`@foam/graph-view`)\n- `docs/` - Documentation and user guides\n\n### Graph Webview (`@foam/graph-view`)\n\nThe graph webview is a standalone Yarn workspace built with Lit, bundled for use inside the VS Code extension.\n\n- Source lives in `packages/foam-graph/src/`; `packages/foam-vscode/static/dataviz/` is **build output** (gitignored), not source\n- `src/protocol.ts` owns the message contract between extension host and webview — the extension imports from `@foam/graph-view/protocol`\n- The extension's `tsconfig.json` uses `paths` to resolve `@foam/graph-view/*` to TypeScript source for type checking; esbuild resolves via package exports at bundle time\n\nCommands (run from repo root or `packages/foam-vscode`):\n\n- `yarn workspace @foam/graph-view build` - Build VS Code bundle\n- `yarn workspace @foam/graph-view build:vscode` - Build VS Code bundle only\n- `yarn workspace @foam/graph-view watch` - Watch mode for webview development\n- `yarn workspace @foam/graph-view test` - Run webview tests (Vitest)\n\n### File Naming Patterns\n\nTest files follow `*.test.ts` for unit tests and `*.spec.ts` for integration tests, living alongside the code in `src`. An integration test is one that has a direct or indirect dependency on `vscode` package.\n\n### Important Constraint\n\nCode in `packages/foam-vscode/src/core/` MUST NOT depend on the `vscode` library or any files outside the core directory. This maintains platform independence.\n\n### Changesets: a `@foam/core` change must also bump `foam-vscode` and `@foam/cli`\n\n`foam-vscode` and `@foam/cli` **bundle** `@foam/core` at build time (esbuild inlines it) and declare it as a `devDependency`, not a runtime `dependency`. Because of that, Changesets' automatic internal-dependency bumping does **not** cascade a `@foam/core` bump to them.\n\nSo when a change touches `packages/foam-core`, its changeset fragment must **also** list `foam-vscode` and `@foam/cli` (usually `patch`) — otherwise their republished bundles ship updated code under a stale version number with no changelog entry. Rule of thumb: if `@foam/core` is in the fragment, `foam-vscode` and `@foam/cli` almost always belong there too. See `docs/dev/releasing-foam.md`.\n\n### URIs throughout, paths only at the edges\n\nDomain code (everything in `@foam/core` and the platform-agnostic layers of `foam-cli`, `foam-mcp`, `foam-vscode`) takes and returns `URI` objects, not path strings. This is consistent with the existing core API: `FoamWorkspace.find(uri: URI)`, `FoamGraph.getLinks(uri: URI)`, `Resource.uri: URI`.\n\n```typescript\n// ✅ Good\nfunction listOrphans(workspace, graph, rootUri: URI): NoteItem[];\n\n// ❌ Avoid\nfunction listOrphans(workspace, graph, rootDir: string): NoteItem[];\n```\n\nPath strings only appear at:\n\n1. **I/O boundaries** — `IDataStore` implementations convert URI ↔ filesystem path (`URI.file(...)`, `uri.toFsPath()`).\n2. **External wire formats** — CLI argument parsing, MCP tool inputs/outputs, JSON serialization.\n3. **Display fields in return values** — e.g. `NoteItem.path` for human-readable workspace-relative paths, alongside the `URI`.\n\nFor path manipulation inside `@foam/core`, use the POSIX-safe utilities in `packages/foam-core/src/utils/path.ts` (`relativeTo`, `joinPath`, `getBasename`, `getExtension`, `getDirectory`) — never import Node's `path` module, since `@foam/core` runs in both Node and browser contexts.\n\n## Architecture Overview\n\n### Core Abstractions\n\n**FoamWorkspace** - Central repository managing all resources (notes, attachments)\n\n- Uses reversed trie for efficient resource lookup\n- Event-driven updates (onDidAdd, onDidUpdate, onDidDelete)\n- Handles identifier resolution for short-form linking\n\n**FoamGraph** - Manages relationship graph between resources\n\n- Tracks links and backlinks between resources\n- Real-time updates when workspace changes\n- Handles placeholder resources for broken links\n\n**ResourceProvider Pattern** - Pluggable architecture for different file types\n\n- `MarkdownProvider` for .md files\n- `AttachmentProvider` for other file types\n- Extensible for future resource types\n\n**DataStore Interface** - Abstract file system operations\n\n- Platform-agnostic file access with configurable filtering\n- Supports both local and remote file systems\n\n### Feature Integration Pattern\n\nFeatures are registered as functions receiving:\n\n```typescript\n(context: ExtensionContext, foamPromise: Promise<Foam>) => void\n```\n\nThis allows features to:\n\n- Register VS Code commands, providers, and event handlers\n- Access the Foam workspace when ready\n- Extend markdown-it for preview rendering\n\n### Testing Conventions\n\n- `*.test.ts` - Unit tests using Vitest\n- `*.spec.ts` - Integration tests requiring VS Code extension host\n- Tests live alongside source code in `src/`\n- Test cases should be phrased in terms of aspects of the feature being tested (expected behaviors), as they serve both as validation of the code as well as documentation of what the expected behavior for the code is in different situations. They should include the happy paths and edge cases.\n\n## Development Workflow\n\nWe build production code together. I handle implementation details while you guide architecture and catch complexity early.\nWhen working on an issue, check if a `.agent/tasks/<issue-id>-<sanitized-title>.md` exists. If not, suggest whether we should start by doing a research on it (using the `/research-issue <issue-id>`) command.\nWhenever we work together on a task, feel free to challenge my assumptions and ideas and be critical if useful.\n\n## Core Workflow: Research → Plan → Implement → Validate\n\n**Start every feature with:** \"Let me research the codebase and create a plan before implementing.\"\n\n1. **Research** - Understand existing patterns and architecture\n2. **Plan** - Propose approach and verify with you\n3. **Implement** - Build with tests and error handling\n4. **Validate** - ALWAYS run formatters, linters, and tests after implementation\n\n- Whenever working on a feature or issue, let's always come up with a plan first, then save it to a file called `/.agent/current-plan.md`, before getting started with code changes. Update this file as the work progresses.\n- Let's use pure functions where possible to improve readability and testing.\n\n### Adding New Features\n\n1. Create feature in `src/features/` directory\n2. Register feature in `src/features/index.ts`\n3. Add tests (both unit and integration as needed)\n4. Update configuration in `package.json` if needed\n\n### Working on an issue\n\n1. Get the issue information from github\n2. Define a step by step plan for addressing the issue\n3. Create tests for the feature\n4. **IMPORTANT**: Run the tests to ensure they FAIL before implementing the fix (this validates the test is actually testing what we think it is)\n5. Implement the fix to make the test pass\n6. Run the tests again to verify the fix works\n\n### Core Logic Changes\n\n1. Modify code in `src/core/` (ensure no vscode dependencies)\n2. Add comprehensive unit tests\n3. Update integration tests in features that use the core logic\n\n## Configuration\n\nThe extension uses VS Code's configuration system with the `foam.*` namespace.\nYou can find all the settings in `/packages/foam-vscode/package.json`\n\n## Common Development Tasks\n\n### Extending Core Functionality\n\nWhen adding to `src/core/`:\n\n- Keep platform-agnostic (no vscode imports)\n- Add comprehensive unit tests\n- Consider impact on graph and workspace state\n- Update relevant providers if needed\n\n## Dependencies\n\n- **Runtime**: VS Code API, markdown parsing, file watching\n- **Development**: TypeScript, Vitest, ESLint, esbuild\n- **Key Libraries**: remark (markdown parsing), lru-cache, lodash\n- **Graph webview**: Lit (web components), force-graph, d3-force/scale/color, Vitest, happy-dom\n\nThe extension supports both Node.js and browser environments via separate build targets.\n\n## Documentation Guidelines\n\n### User Documentation (`docs/user/`)\n\nDocumentation in `docs/user/` must be written for non-technical users. The goal is to help novice users quickly start using features, not to explain technical implementation details.\n\n**Writing Guidelines:**\n\n- **Target audience**: Assume users are new to Foam and may not be technical\n- **Be concise**: Keep it short and to the point - every sentence must convey useful information\n- **Avoid repetition**: Don't repeat the same concept in different words\n- **Focus on \"how to use\"**: Show users what they can do and how to do it, not how it works internally\n- **Balance brevity with clarity**: Users won't read verbose documentation, but they need enough information to succeed\n- **Use examples**: Show practical use cases rather than abstract descriptions\n- **Start with the most common use case**: Lead with what most users will want to do first\n\n# GitHub CLI Integration\n\nTo interact with the github repo we will be using the `gh` command.\nALWAYS ask before performing a write operation on Github.\n\n## Common Commands for Claude Code Integration\n\n### Issues\n\n```bash\n# List all issues\ngh issue list\n\n# Filter issues by milestone\ngh issue list --milestone \"v1.0.0\"\n\n# Filter issues by assignee\ngh issue list --assignee @me\ngh issue list --assignee username\n\n# Filter issues by label\ngh issue list --label \"bug\"\ngh issue list --label \"enhancement,priority-high\"\n\n# Filter issues by state\ngh issue list --state open\ngh issue list --state closed\ngh issue list --state all\n\n# Combine filters\ngh issue list --milestone \"v1.0.0\" --label \"bug\" --assignee @me\n\n# View specific issue\ngh issue view 123\n\n# Create issue\ngh issue create --title \"Bug fix\" --body \"Description\"\n\n# Add comment to issue\ngh issue comment 123 --body \"Update comment\"\n```\n\n### Pull Requests\n\n```bash\n# List all PRs\ngh pr list\n\n# Filter PRs the same way as for filters (for example, here is by milestone)\ngh pr list --milestone \"v1.0.0\"\n\n# View PR details\ngh pr view 456\n\n# Create PR\ngh pr create --title \"Feature\" --body \"Description\"\n\n# Check out PR locally\ngh pr checkout 456\n\n# Add review comment\ngh pr comment 456 --body \"LGTM\"\n```\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Collaboration Principles\n\n**Be honest and objective**: Evaluate all suggestions, ideas, and feedback on their technical merits. Don't be overly complimentary or sycophantic. If something doesn't make sense, doesn't align with best practices, or could be improved, say so directly and constructively. Technical accuracy and project quality take precedence over being agreeable.\n\n**Prefer simple commands over complex ones**: Each compound/chained/piped command may require manual approval, so default to simple, single-purpose commands that match existing allowlist patterns. Don't staple on \"bonus\" steps the user didn't ask for, and don't wrap things in `bash -c`, `eval`, or defensive `|| true` without reason. Compound commands are fine when genuinely needed: atomic operations (`git add X && git commit`), pipelines where the pipe IS the interface (`find | xargs`, `cmd | jq`), heredocs for multi-line input, and loops over many items (one approval beats N).\n\n**Working in a different directory (worktrees, packages)**: The Bash tool's CWD is always the main checkout — not wherever you last \"cd'd\". To run commands elsewhere without a prompt for each call, match the existing allowlist patterns:\n\n- Prefer `git -C <path> <subcommand>` for git operations (matches `Bash(git -C *)`)\n- For yarn commands, prefer, in order:\n  - `yarn workspace <package> <subcommand>`\n  - `yarn --cwd <path> <command>`\n  - `cd <path> && yarn <subcommand>`\n- Use `cd <path> && npm <subcommand>` for npm\n- Do NOT constantly use `nvm use ...` (e.g. `nvm use <version> && yarn <subcommand>`)\n- Do NOT mix `git -C` with `cd &&` in the same command\n- If you're about to introduce a new pattern (e.g. `cd && python`, `cd && cargo`), pause and either use a simpler equivalent or add the pattern to `.claude/settings.local.json` first\n\nThe point is autonomy: implement runs, agents, and skills should not stop for permission prompts on the same shape of command that already works elsewhere.\n\n## Project overview\n\nFoam is a personal knowledge management and sharing system, built on Visual Studio Code and GitHub. It allows users to organize research, keep re-discoverable notes, write long-form content, and optionally publish it to the web. The main goals are to help users create relationships between thoughts and information, supporting practices like building a \"Second Brain\" or a \"Zettelkasten\". Foam is free, open-source, and extensible, giving users ownership and control over their information. The target audience includes individuals interested in personal knowledge management, note-taking, and content creation, particularly those familiar with VS Code and GitHub.\n\n## Quick Commands\n\nAll the following commands are to be executed from the `packages/foam-vscode` directory\n\n### Development\n\n- `yarn install` - Install dependencies\n- `yarn build` - Build all packages\n- `yarn watch` - Watch mode for development\n- `yarn clean` - Clean build outputs\n- `yarn reset` - Full clean, install, and build\n\n### Testing\n\n- `yarn test` - Run all tests (unit + integration)\n- `yarn test:unit` - Run unit tests (\\*.test.ts files and the .spec.ts files marked as vscode-mock friendly)\n- `yarn test:unit-without-specs` - Run only \\*.test.ts files, skipping all \\*.spec.ts files\n- `yarn test:e2e` - Run only integration tests (all \\*.spec.ts files, including `@unit-ready` ones)\n- `yarn lint` - Run linting\n- `yarn test-reset-workspace` to clean test workspace\n\nUnit tests run in Node.js environment using Vitest\nIntegration tests require VS Code extension host\nWhen running tests, do not provide additional parameters, they are ignored by the custom runner script. You cannot run just a test, you have to run the whole suite.\n\nUnit tests are named `*.test.ts` and integration tests are `*.spec.ts`. These test files live alongside the code in the `src` directory. An integration test is one that has a direct or indirect dependency on `vscode` module.\nThere is a mock `vscode` module that can be used to run most integration tests without starting VS Code. Tests that can use this mock start with the line `/* @unit-ready */`. Note that `@unit-ready` specs run in both `yarn test:unit` (with the mock) and `yarn test:e2e` (in real VS Code) — this is intentional.\n\n- If you are interested in a test inside a `*.test.ts` file, run `yarn test:unit` or inside a `*.spec.ts` file that starts with `/* @unit-ready */` run `yarn test:unit`\n- If you are interested in a test inside a `*.spec.ts` file that does not include `/* @unit-ready */` run `yarn test`\n\nWhile in development we mostly want to use `yarn test:unit`.\nWhen multiple tests are failing, look at all of them, but only focus on fixing the first one. Once that is fixed, run the test suite again and repeat the process.\n\nWhen writing tests keep mocking to a bare minimum. Code should be written in a way that is easily testable and if I/O is necessary, it should be done in appropriate temporary directories.\nNever mock anything that is inside `packages/foam-vscode/src/core/`.\n\nDo not use dynamic imports (`await import(...)` or `import(...)`) anywhere — neither in source code nor in tests. Use static top-level imports instead. If a module needs lazy initialization, refactor to make it explicit rather than reaching for a dynamic import.\n\nUse the utility functions from `test-utils.ts` and `test-utils-vscode.ts` and `test-datastore.ts`.\n\nTo improve readability of the tests, set up the test and tear it down within the test case (as opposed to use other functions like `beforeEach` unless it's much better to do it that way)\n\nNever fix a test by adjusting the expectation if the expectation is correct, test must be fixed by addressing the issue with the code.\n\n## Repository Structure\n\nThis is a monorepo using Yarn workspaces with the main VS Code extension in `packages/foam-vscode/`.\n\n### Key Directories\n\n- `packages/foam-vscode/src/core/` - Platform-agnostic business logic (NO vscode dependencies)\n- `packages/foam-vscode/src/features/` - VS Code-specific features and UI\n- `packages/foam-vscode/src/services/` - service implementations, might have VS Code dependency, but we try keep that to a minimum\n- `packages/foam-vscode/src/test/` - Test utilities and mocks\n- `packages/foam-graph/` - Graph visualization web component (`@foam/graph-view`)\n- `docs/` - Documentation and user guides\n\n### Graph Webview (`@foam/graph-view`)\n\nThe graph webview is a standalone Yarn workspace built with Lit, bundled for use inside the VS Code extension.\n\n- Source lives in `packages/foam-graph/src/`; `packages/foam-vscode/static/dataviz/` is **build output** (gitignored), not source\n- `src/protocol.ts` owns the message contract between extension host and webview — the extension imports from `@foam/graph-view/protocol`\n- The extension's `tsconfig.json` uses `paths` to resolve `@foam/graph-view/*` to TypeScript source for type checking; esbuild resolves via package exports at bundle time\n\nCommands (run from repo root or `packages/foam-vscode`):\n\n- `yarn workspace @foam/graph-view build` - Build VS Code bundle\n- `yarn workspace @foam/graph-view build:vscode` - Build VS Code bundle only\n- `yarn workspace @foam/graph-view watch` - Watch mode for webview development\n- `yarn workspace @foam/graph-view test` - Run webview tests (Vitest)\n\n### File Naming Patterns\n\nTest files follow `*.test.ts` for unit tests and `*.spec.ts` for integration tests, living alongside the code in `src`. An integration test is one that has a direct or indirect dependency on `vscode` package.\n\n### Important Constraint\n\nCode in `packages/foam-vscode/src/core/` MUST NOT depend on the `vscode` library or any files outside the core directory. This maintains platform independence.\n\n### Changesets: a `@foam/core` change must also bump `foam-vscode` and `@foam/cli`\n\n`foam-vscode` and `@foam/cli` **bundle** `@foam/core` at build time (esbuild inlines it) and declare it as a `devDependency`, not a runtime `dependency`. Because of that, Changesets' automatic internal-dependency bumping does **not** cascade a `@foam/core` bump to them.\n\nSo when a change touches `packages/foam-core`, its changeset fragment must **also** list `foam-vscode` and `@foam/cli` (usually `patch`) — otherwise their republished bundles ship updated code under a stale version number with no changelog entry. Rule of thumb: if `@foam/core` is in the fragment, `foam-vscode` and `@foam/cli` almost always belong there too. See `docs/dev/releasing-foam.md`.\n\n### URIs throughout, paths only at the edges\n\nDomain code (everything in `@foam/core` and the platform-agnostic layers of `foam-cli`, `foam-mcp`, `foam-vscode`) takes and returns `URI` objects, not path strings. This is consistent with the existing core API: `FoamWorkspace.find(uri: URI)`, `FoamGraph.getLinks(uri: URI)`, `Resource.uri: URI`.\n\n```typescript\n// ✅ Good\nfunction listOrphans(workspace, graph, rootUri: URI): NoteItem[];\n\n// ❌ Avoid\nfunction listOrphans(workspace, graph, rootDir: string): NoteItem[];\n```\n\nPath strings only appear at:\n\n1. **I/O boundaries** — `IDataStore` implementations convert URI ↔ filesystem path (`URI.file(...)`, `uri.toFsPath()`).\n2. **External wire formats** — CLI argument parsing, MCP tool inputs/outputs, JSON serialization.\n3. **Display fields in return values** — e.g. `NoteItem.path` for human-readable workspace-relative paths, alongside the `URI`.\n\nFor path manipulation inside `@foam/core`, use the POSIX-safe utilities in `packages/foam-core/src/utils/path.ts` (`relativeTo`, `joinPath`, `getBasename`, `getExtension`, `getDirectory`) — never import Node's `path` module, since `@foam/core` runs in both Node and browser contexts.\n\n## Architecture Overview\n\n### Core Abstractions\n\n**FoamWorkspace** - Central repository managing all resources (notes, attachments)\n\n- Uses reversed trie for efficient resource lookup\n- Event-driven updates (onDidAdd, onDidUpdate, onDidDelete)\n- Handles identifier resolution for short-form linking\n\n**FoamGraph** - Manages relationship graph between resources\n\n- Tracks links and backlinks between resources\n- Real-time updates when workspace changes\n- Handles placeholder resources for broken links\n\n**ResourceProvider Pattern** - Pluggable architecture for different file types\n\n- `MarkdownProvider` for .md files\n- `AttachmentProvider` for other file types\n- Extensible for future resource types\n\n**DataStore Interface** - Abstract file system operations\n\n- Platform-agnostic file access with configurable filtering\n- Supports both local and remote file systems\n\n### Feature Integration Pattern\n\nFeatures are registered as functions receiving:\n\n```typescript\n(context: ExtensionContext, foamPromise: Promise<Foam>) => void\n```\n\nThis allows features to:\n\n- Register VS Code commands, providers, and event handlers\n- Access the Foam workspace when ready\n- Extend markdown-it for preview rendering\n\n### Testing Conventions\n\n- `*.test.ts` - Unit tests using Vitest\n- `*.spec.ts` - Integration tests requiring VS Code extension host\n- Tests live alongside source code in `src/`\n- Test cases should be phrased in terms of aspects of the feature being tested (expected behaviors), as they serve both as validation of the code as well as documentation of what the expected behavior for the code is in different situations. They should include the happy paths and edge cases.\n\n## Development Workflow\n\nWe build production code together. I handle implementation details while you guide architecture and catch complexity early.\nWhen working on an issue, check if a `.agent/tasks/<issue-id>-<sanitized-title>.md` exists. If not, suggest whether we should start by doing a research on it (using the `/research-issue <issue-id>`) command.\nWhenever we work together on a task, feel free to challenge my assumptions and ideas and be critical if useful.\n\n## Core Workflow: Research → Plan → Implement → Validate\n\n**Start every feature with:** \"Let me research the codebase and create a plan before implementing.\"\n\n1. **Research** - Understand existing patterns and architecture\n2. **Plan** - Propose approach and verify with you\n3. **Implement** - Build with tests and error handling\n4. **Validate** - ALWAYS run formatters, linters, and tests after implementation\n\n- Whenever working on a feature or issue, let's always come up with a plan first, then save it to a file called `/.agent/current-plan.md`, before getting started with code changes. Update this file as the work progresses.\n- Let's use pure functions where possible to improve readability and testing.\n\n### Adding New Features\n\n1. Create feature in `src/features/` directory\n2. Register feature in `src/features/index.ts`\n3. Add tests (both unit and integration as needed)\n4. Update configuration in `package.json` if needed\n\n### Working on an issue\n\n1. Get the issue information from github\n2. Define a step by step plan for addressing the issue\n3. Create tests for the feature\n4. **IMPORTANT**: Run the tests to ensure they FAIL before implementing the fix (this validates the test is actually testing what we think it is)\n5. Implement the fix to make the test pass\n6. Run the tests again to verify the fix works\n\n### Core Logic Changes\n\n1. Modify code in `src/core/` (ensure no vscode dependencies)\n2. Add comprehensive unit tests\n3. Update integration tests in features that use the core logic\n\n## Configuration\n\nThe extension uses VS Code's configuration system with the `foam.*` namespace.\nYou can find all the settings in `/packages/foam-vscode/package.json`\n\n## Common Development Tasks\n\n### Extending Core Functionality\n\nWhen adding to `src/core/`:\n\n- Keep platform-agnostic (no vscode imports)\n- Add comprehensive unit tests\n- Consider impact on graph and workspace state\n- Update relevant providers if needed\n\n## Dependencies\n\n- **Runtime**: VS Code API, markdown parsing, file watching\n- **Development**: TypeScript, Vitest, ESLint, esbuild\n- **Key Libraries**: remark (markdown parsing), lru-cache, lodash\n- **Graph webview**: Lit (web components), force-graph, d3-force/scale/color, Vitest, happy-dom\n\nThe extension supports both Node.js and browser environments via separate build targets.\n\n## Documentation Guidelines\n\n### User Documentation (`docs/user/`)\n\nDocumentation in `docs/user/` must be written for non-technical users. The goal is to help novice users quickly start using features, not to explain technical implementation details.\n\n**Writing Guidelines:**\n\n- **Target audience**: Assume users are new to Foam and may not be technical\n- **Be concise**: Keep it short and to the point - every sentence must convey useful information\n- **Avoid repetition**: Don't repeat the same concept in different words\n- **Focus on \"how to use\"**: Show users what they can do and how to do it, not how it works internally\n- **Balance brevity with clarity**: Users won't read verbose documentation, but they need enough information to succeed\n- **Use examples**: Show practical use cases rather than abstract descriptions\n- **Start with the most common use case**: Lead with what most users will want to do first\n\n# GitHub CLI Integration\n\nTo interact with the github repo we will be using the `gh` command.\nALWAYS ask before performing a write operation on Github.\n\n## Common Commands for Claude Code Integration\n\n### Issues\n\n```bash\n# List all issues\ngh issue list\n\n# Filter issues by milestone\ngh issue list --milestone \"v1.0.0\"\n\n# Filter issues by assignee\ngh issue list --assignee @me\ngh issue list --assignee username\n\n# Filter issues by label\ngh issue list --label \"bug\"\ngh issue list --label \"enhancement,priority-high\"\n\n# Filter issues by state\ngh issue list --state open\ngh issue list --state closed\ngh issue list --state all\n\n# Combine filters\ngh issue list --milestone \"v1.0.0\" --label \"bug\" --assignee @me\n\n# View specific issue\ngh issue view 123\n\n# Create issue\ngh issue create --title \"Bug fix\" --body \"Description\"\n\n# Add comment to issue\ngh issue comment 123 --body \"Update comment\"\n```\n\n### Pull Requests\n\n```bash\n# List all PRs\ngh pr list\n\n# Filter PRs the same way as for filters (for example, here is by milestone)\ngh pr list --milestone \"v1.0.0\"\n\n# View PR details\ngh pr view 456\n\n# Create PR\ngh pr create --title \"Feature\" --body \"Description\"\n\n# Check out PR locally\ngh pr checkout 456\n\n# Add review comment\ngh pr comment 456 --body \"LGTM\"\n```\n","category":"root","tokens":4095}]}