chore: Auto-generate bundled help skill references from docs/ at build time#562
chore: Auto-generate bundled help skill references from docs/ at build time#562allenhutchison merged 9 commits intomasterfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a build-time generator that scans Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant DevCI as Dev/CI
participant Gen as Generator\nscripts/generate-help-references.mjs
participant FS as File System\n(docs/, src/)
participant Bundler as Bundler\n(tsc/esbuild)
DevCI->>Gen: run `npm run generate-refs` (pre-build)
Gen->>FS: glob `docs/guide/*.md` & `docs/reference/*.md`
Gen->>FS: read files, extract first `#` heading, detect basename/import collisions
Gen->>FS: write `src/services/generated-help-references.ts` (if changed)
DevCI->>Bundler: run `npm run build` / dev flow (includes generate-refs)
Bundler->>FS: import `src/services/generated-help-references.ts`
Bundler->>FS: bundle code (gemini-scribe-help receives injected table)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
test/scripts/generate-help-references.test.ts (1)
34-46: Cover the escaping path with a regression test.These assertions prove generation/idempotency, but they never exercise headings containing backslashes, backticks, or
${...}—the exact branchscripts/generate-help-references.mjsnow escapes. A small fixture-based case here would keep that fix from regressing silently.As per coding guidelines, "Assert observable behavior of prompts, services, and tool orchestration; add regression coverage for bugs".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/scripts/generate-help-references.test.ts` around lines 34 - 46, Add a regression test that exercises the escaping branch by creating a small fixture markdown with headings containing backslashes, backticks, and a `${...}` sequence, run the script "node scripts/generate-help-references.mjs" (use the same execSync pattern and ROOT constant), read GENERATED_FILE with fs.readFileSync, and assert the generated output contains the correctly escaped/encoded representation (and re-run to assert idempotency). Locate the new test near the existing blocks in generate-help-references.test.ts so it uses execSync and fs.readFileSync and verifies both the presence of escaped content and that running the script twice produces the same output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/generate-help-references.mjs`:
- Line 15: Remove the unsupported and unused globSync import from the top-level
import list (the "import { globSync } from 'fs';" statement) in the
generate-help-references.mjs module; simply delete the globSync import so the
file only imports supported symbols and CI on Node.js 18 no longer fails.
In `@src/services/bundled-skills.ts`:
- Line 45: The replace call building helpContent uses String.prototype.replace
with a string replacement which can interpret $ tokens; update the expression
creating helpContent so that stripFrontmatter(helpSkillMd).replace('<!--
REFERENCES_TABLE -->', helpReferencesTable) uses a replacer callback instead
(e.g., .replace('<!-- REFERENCES_TABLE -->', () => helpReferencesTable)) to
ensure helpReferencesTable is injected verbatim and prevent accidental token
expansion; locate the usage of helpContent and the symbols stripFrontmatter,
helpSkillMd, and helpReferencesTable to make this change.
---
Nitpick comments:
In `@test/scripts/generate-help-references.test.ts`:
- Around line 34-46: Add a regression test that exercises the escaping branch by
creating a small fixture markdown with headings containing backslashes,
backticks, and a `${...}` sequence, run the script "node
scripts/generate-help-references.mjs" (use the same execSync pattern and ROOT
constant), read GENERATED_FILE with fs.readFileSync, and assert the generated
output contains the correctly escaped/encoded representation (and re-run to
assert idempotency). Locate the new test near the existing blocks in
generate-help-references.test.ts so it uses execSync and fs.readFileSync and
verifies both the presence of escaped content and that running the script twice
produces the same output.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ec23e3b0-915b-4188-8d5c-0ae6bfd93f48
📒 Files selected for processing (8)
AGENTS.mdpackage.jsonprompts/bundled-skills/gemini-scribe-help/SKILL.mdscripts/generate-help-references.mjssrc/services/bundled-skills.tssrc/services/generated-help-references.tstest/scripts/generate-help-references.test.tstest/services/bundled-skills.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
AGENTS.md
📄 CodeRabbit inference engine (CLAUDE.md)
AGENTS.md: Document agent definitions and responsibilities in AGENTS.md
Maintain clear descriptions of agent responsibilities and interactions in AGENTS.mdMaintain AGENTS.md as the central documentation for all agent definitions and their usage patterns
Files:
AGENTS.md
test/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
test/**/*.test.ts: Unit tests should live in thetest/directory mirroringsrc/structure as*.test.tsfiles
Use Jest with ts-jest for TypeScript support, JSDOM environment for DOM testing, and test pattern**/?(*.)+(spec|test).[tj]s. Keep unit tests next to implementations and name them after the unit
Assert observable behavior of prompts, services, and tool orchestration; add regression coverage for bugs
Files:
test/services/bundled-skills.test.tstest/scripts/generate-help-references.test.ts
**/*.{ts,tsx,js,jsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Format code with Prettier using 2-space indent, 120-column width, semicolons, single quotes, and trailing commas
Files:
test/services/bundled-skills.test.tssrc/services/bundled-skills.tstest/scripts/generate-help-references.test.tssrc/services/generated-help-references.tspackage.json
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.ts: Plugin entry point should be insrc/main.tswith domain folders such asagent/,api/,tools/,ui/, andservices/, plus shared utilities inutils/
Use camelCase for variables and functions, PascalCase for classes and types, and kebab-case for filenames
Use Obsidian API functions when available instead of low-level operations:vault.getMarkdownFiles()instead ofvault.adapter.list(),app.fileManager.processFrontMatter()for frontmatter,vault.getAbstractFileByPath()for file operations,app.metadataCachefor metadata,app.fileManager.renameFile()for renaming, andapp.workspace.openLinkText()for clickable links
Never use nativeconsole.log()orconsole.debug()directly; use the Logger service (src/utils/logger.ts) withthis.plugin.loggerin components,context.plugin.loggerin tools, or pass logger as a parameter to utility functions. Uselogger.log()andlogger.debug()for debug information (filtered by debugMode), andlogger.error()andlogger.warn()for always-visible errors and warnings
Handle TypeScript errors properly and ensure all properties are correctly typed
Use proper async/await patterns for all asynchronous operations instead of promises and callbacks
Always use Obsidian's normalized paths and metadata cache for file operations
Always exclude system folders from file operations: the plugin state folder (settings.historyFolder) and.obsidianconfiguration folder
Group modules by domain and add barrel exports only when they simplify imports in TypeScript files
Use.editorconfigto enforce LF endings for code and CRLF handling for other files; avoid hand-editing generated bundles
Files:
src/services/bundled-skills.tssrc/services/generated-help-references.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Write concise, imperative commit subjects (e.g., 'Fix agent session cleanup', 'Improve prompt builder'), reference issues/PRs with `#123`, and commit generated artifacts alongside source changes
📚 Learning: 2025-12-06T03:43:40.257Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-06T03:43:40.257Z
Learning: Applies to AGENTS.md : Maintain AGENTS.md as the central documentation for all agent definitions and their usage patterns
Applied to files:
prompts/bundled-skills/gemini-scribe-help/SKILL.mdAGENTS.md
📚 Learning: 2025-12-06T03:43:40.257Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-06T03:43:40.257Z
Learning: Applies to **/*agent*.{ts,tsx,js,jsx} : Document agent implementations with clear purpose, capabilities, and usage examples in AGENTS.md
Applied to files:
AGENTS.mdsrc/services/generated-help-references.ts
📚 Learning: 2025-12-06T03:43:36.306Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T03:43:36.306Z
Learning: Applies to AGENTS.md : Document agent definitions and responsibilities in AGENTS.md
Applied to files:
AGENTS.md
📚 Learning: 2025-12-06T03:43:36.306Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T03:43:36.306Z
Learning: Applies to AGENTS.md : Maintain clear descriptions of agent responsibilities and interactions in AGENTS.md
Applied to files:
AGENTS.md
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Write concise, imperative commit subjects (e.g., 'Fix agent session cleanup', 'Improve prompt builder'), reference issues/PRs with `#123`, and commit generated artifacts alongside source changes
Applied to files:
AGENTS.md
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Always run `npm install` first if encountering TypeScript errors or missing module errors during build to ensure all dependencies in `node_modules` are present
Applied to files:
AGENTS.md
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to src/services/skill-manager.ts : Skills are self-contained packages stored in `[state-folder]/Skills/<skill-name>/SKILL.md` following the agentskills.io specification. Skill names must be lowercase alphanumeric with hyphens, 1-64 characters, with no consecutive/leading/trailing hyphens
Applied to files:
AGENTS.mdtest/services/bundled-skills.test.tssrc/services/bundled-skills.ts
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to src/tools/**/*.ts : YAML frontmatter must start with `---` on line 1 and end with `---`, and content placed by AI tools should go after frontmatter blocks unless explicitly instructed otherwise
Applied to files:
AGENTS.md
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to {main.js,manifest.json,styles.css} : Generate artifacts (`main.js`, `manifest.json`, `styles.css`) stay in the repo root for Obsidian and should be committed alongside source changes
Applied to files:
AGENTS.mdpackage.json
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to src/**/*.ts : Use Obsidian API functions when available instead of low-level operations: `vault.getMarkdownFiles()` instead of `vault.adapter.list()`, `app.fileManager.processFrontMatter()` for frontmatter, `vault.getAbstractFileByPath()` for file operations, `app.metadataCache` for metadata, `app.fileManager.renameFile()` for renaming, and `app.workspace.openLinkText()` for clickable links
Applied to files:
AGENTS.md
📚 Learning: 2025-12-29T00:49:29.597Z
Learnt from: allenhutchison
Repo: allenhutchison/obsidian-gemini PR: 277
File: src/services/rag-indexing.ts:459-512
Timestamp: 2025-12-29T00:49:29.597Z
Learning: Guideline: When using the Obsidian API in TypeScript code, import the standalone setTooltip from 'obsidian' and call setTooltip(element, tooltip, options?) instead of using a component method like component.setTooltip(tooltip, options). This applies to any TypeScript file (not just UI components) and helps avoid confusion between the standalone API and component-specific methods. Ensure the import is: import { setTooltip } from 'obsidian'; and use the signature setTooltip(element: HTMLElement, tooltip: string, options?: { placement?: 'top' | 'bottom' | 'left' | 'right' });
Applied to files:
test/services/bundled-skills.test.tssrc/services/bundled-skills.tstest/scripts/generate-help-references.test.tssrc/services/generated-help-references.ts
📚 Learning: 2026-03-01T22:53:18.726Z
Learnt from: allenhutchison
Repo: allenhutchison/obsidian-gemini PR: 380
File: src/main.ts:856-868
Timestamp: 2026-03-01T22:53:18.726Z
Learning: For Obsidian's SecretStorage API (v1.11.4+), setSecret(id, secret) and getSecret(id) are synchronous. Do not use await with these calls. After calling setSecret(id, secret), immediately call getSecret(id) and verify the value to confirm storage succeeded before proceeding. If getSecret returns null or a different value, handle the failure. This guideline applies to all code paths in the codebase that use this API.
Applied to files:
src/services/bundled-skills.tssrc/services/generated-help-references.ts
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to test/**/*.test.ts : Use Jest with ts-jest for TypeScript support, JSDOM environment for DOM testing, and test pattern `**/?(*.)+(spec|test).[tj]s`. Keep unit tests next to implementations and name them after the unit
Applied to files:
test/scripts/generate-help-references.test.ts
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to test/**/*.test.ts : Assert observable behavior of prompts, services, and tool orchestration; add regression coverage for bugs
Applied to files:
test/scripts/generate-help-references.test.ts
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to test/**/*.test.ts : Unit tests should live in the `test/` directory mirroring `src/` structure as `*.test.ts` files
Applied to files:
test/scripts/generate-help-references.test.ts
🪛 GitHub Actions: CI
test/scripts/generate-help-references.test.ts
[error] 10-10: Test failed: should generate the references file. Command failed: node scripts/generate-help-references.mjs (SyntaxError about missing 'fs' export 'globSync').
[error] 41-41: Test failed: should be idempotent (running twice produces same output). Command failed: node scripts/generate-help-references.mjs (SyntaxError about missing 'fs' export 'globSync').
scripts/generate-help-references.mjs
[error] 15-15: SyntaxError: The requested module 'fs' does not provide an export named 'globSync' (import { globSync } from 'fs';). Node.js v18.20.8.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
scripts/generate-help-references.mjs (1)
31-35: Add a guard for generated import variable-name collisions.
toVarName()can map different filenames to the same identifier in edge cases, which would generate duplicate imports and break TypeScript compilation. Consider validatingvarNameuniqueness alongside basename checks.Proposed fix
const imports = []; const mapEntries = []; const tableRows = []; +const seenVarNames = new Map(); @@ const varName = toVarName(basename); + if (seenVarNames.has(varName)) { + console.error( + `ERROR: Import variable collision "${varName}" between "${seenVarNames.get(varName)}" and "${relPath}". ` + + `Rename one of the files to avoid generated identifier conflicts.` + ); + process.exit(1); + } + seenVarNames.set(varName, relPath);Also applies to: 84-95
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/generate-help-references.mjs` around lines 31 - 35, toVarName() can produce duplicate identifiers for different filenames; update the generation flow to detect and prevent varName collisions by tracking used names (e.g. a Set or Map) when creating imports and, on collision, derive a unique fallback (append a numeric suffix or short hash) and return that instead; update all places that call toVarName (and the import-generation loop around the block referenced at lines 84-95) to validate uniqueness against the tracker before emitting import statements so TypeScript identifiers never collide.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/generate-help-references.mjs`:
- Around line 41-44: Headings are inserted raw into Markdown table cells which
breaks tables when they contain '|' or line breaks; create a small helper (e.g.,
escapeMarkdownCell) that replaces pipe characters with '\|' and collapses or
replaces newlines with a safe token (space or '<br>') and trim, then call that
helper from extractHeading and from the row-generation code that writes titles
into table cells (the table/row generation block currently around the other
insertion sites) so all cell content is escaped before being concatenated into
table rows.
---
Nitpick comments:
In `@scripts/generate-help-references.mjs`:
- Around line 31-35: toVarName() can produce duplicate identifiers for different
filenames; update the generation flow to detect and prevent varName collisions
by tracking used names (e.g. a Set or Map) when creating imports and, on
collision, derive a unique fallback (append a numeric suffix or short hash) and
return that instead; update all places that call toVarName (and the
import-generation loop around the block referenced at lines 84-95) to validate
uniqueness against the tracker before emitting import statements so TypeScript
identifiers never collide.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3591088a-ee94-42c4-aba0-817d073bdc81
📒 Files selected for processing (2)
scripts/generate-help-references.mjssrc/services/bundled-skills.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/services/bundled-skills.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Write concise, imperative commit subjects (e.g., 'Fix agent session cleanup', 'Improve prompt builder'), reference issues/PRs with `#123`, and commit generated artifacts alongside source changes
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to src/**/*.ts : Use Obsidian API functions when available instead of low-level operations: `vault.getMarkdownFiles()` instead of `vault.adapter.list()`, `app.fileManager.processFrontMatter()` for frontmatter, `vault.getAbstractFileByPath()` for file operations, `app.metadataCache` for metadata, `app.fileManager.renameFile()` for renaming, and `app.workspace.openLinkText()` for clickable links
Applied to files:
scripts/generate-help-references.mjs
🔇 Additional comments (1)
scripts/generate-help-references.mjs (1)
65-77: Good defensive check for reference key collisions.Failing fast on duplicate basenames in the
references/<basename>namespace prevents silent overwrites and stale/ambiguous resource lookups.
6c59264 to
2087c10
Compare
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@package.json`:
- Around line 14-16: Update the package.json "test" script to run the
generate-refs step before tests: modify the scripts.test entry so it invokes
"npm run generate-refs" (or "npm run generate-refs && <existing test command>")
so the generated file used by bundled-skills.ts (./generated-help-references)
exists prior to running tests; ensure you reference the existing "generate-refs"
script rather than duplicating logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 68fb0bce-e9c8-466f-8680-4f590bb1ba0f
📒 Files selected for processing (8)
AGENTS.mdpackage.jsonprompts/bundled-skills/gemini-scribe-help/SKILL.mdscripts/generate-help-references.mjssrc/services/bundled-skills.tssrc/services/generated-help-references.tstest/scripts/generate-help-references.test.tstest/services/bundled-skills.test.ts
✅ Files skipped from review due to trivial changes (6)
- test/services/bundled-skills.test.ts
- prompts/bundled-skills/gemini-scribe-help/SKILL.md
- src/services/generated-help-references.ts
- AGENTS.md
- src/services/bundled-skills.ts
- scripts/generate-help-references.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
- test/scripts/generate-help-references.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Format code with Prettier using 2-space indent, 120-column width, semicolons, single quotes, and trailing commas
Files:
package.json
🧠 Learnings (1)
📚 Learning: 2026-04-05T19:58:54.181Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-05T19:58:54.181Z
Learning: Applies to {main.js,manifest.json,styles.css} : Generate artifacts (`main.js`, `manifest.json`, `styles.css`) stay in the repo root for Obsidian and should be committed alongside source changes
Applied to files:
package.json
🔇 Additional comments (1)
package.json (1)
14-14: Thegenerate-refsscript integration looks good.The approach of separating the generation into its own npm script and composing it with
&&indevandbuildis clean and follows npm script best practices.One operational note: per context snippet 3, the generator silently skips missing
docs/guide/ordocs/reference/directories rather than failing. If these directories are accidentally removed or renamed, the build will succeed but produce an incomplete generated file, leading to confusing runtime errors rather than an actionable build-time message.
…d time Replace manual import/map/table maintenance in bundled-skills.ts and SKILL.md with a build-time code generation script. New or removed markdown files in docs/guide/ and docs/reference/ are automatically picked up — zero manual edits needed. - Add scripts/generate-help-references.mjs that scans docs/ and generates src/services/generated-help-references.ts - Update bundled-skills.ts to import from the generated module - Replace hardcoded references table in SKILL.md with a placeholder that gets injected at build time - Add generate-refs step to dev/build scripts in package.json - Add tests for both the generation script and table injection - Picks up 2 previously missing references: projects.md, loop-detection.md Fixes #560 https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
Address CodeQL alert about incomplete string escaping when embedding
the references table into a JS template literal. Now escapes
backslashes, backticks, and ${ sequences.
https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
The generated file must be checked in so that tsc and jest in CI can resolve the module without running the generate script first. The file is deterministic, so it only changes when docs are added or removed. https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
…nfig The generate script was producing 2-space indents for map entries, but Prettier (via .editorconfig indent_style: tab) converts to tabs. This mismatch caused the idempotency test to fail in CI since the first test run overwrote the committed (tab) file with the script's (space) output. https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
- Remove `import { globSync } from 'fs'` which is unused and only
available in Node.js v22+, breaking CI on Node.js 18
- Use a replacer callback in String.replace() to prevent $ token
expansion when injecting the references table
https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
- Detect duplicate import variable names from toVarName() and fail fast, complementing the existing basename collision check - Escape pipe characters and newlines in headings before inserting into markdown table cells to prevent malformed tables https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
Address CodeQL alert about incomplete string escaping in escapeMarkdownTableCell by escaping backslashes before pipes. https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
Ensures the generated help references file is up-to-date before running jest, protecting against stale or missing files when contributors run npm test without building first. https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
27ecd54 to
d016db2
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/generate-help-references.mjs (1)
31-35: Consider hardening identifier generation intoVarNamefor edge cases.The function currently handles kebab-case normalization but could generate invalid TypeScript identifiers for filenames with dots, spaces, or other special characters. While current docs filenames don't trigger this, adding defensive sanitization would prevent breakage if future documentation naming changes are made.
♻️ Suggested improvement
function toVarName(filename) { const base = path.basename(filename, '.md'); - const camel = base.replace(/-([a-z])/g, (_, c) => c.toUpperCase()); - return 'ref' + camel.charAt(0).toUpperCase() + camel.slice(1); + const normalized = base.replace(/[^A-Za-z0-9_$]+/g, '_'); + const safe = /^[A-Za-z_$]/.test(normalized) ? normalized : `_${normalized}`; + return `ref${safe.charAt(0).toUpperCase()}${safe.slice(1)}`; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/generate-help-references.mjs` around lines 31 - 35, toVarName currently only normalizes kebab-case and can produce invalid TypeScript identifiers for filenames with dots, spaces, or special chars; update toVarName to first strip the extension, then sanitize the base by replacing any non-alphanumeric characters (including dots, spaces, punctuation) with a separator or removing them, convert to camelCase (preserving existing kebab/camel rules), ensure the resulting identifier does not start with a digit (prefix with underscore if it does), and finally prepend the "ref" prefix and capitalize the first letter as before; reference the toVarName function and adjust its regex/logic to perform these sanitization steps defensively.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@scripts/generate-help-references.mjs`:
- Around line 31-35: toVarName currently only normalizes kebab-case and can
produce invalid TypeScript identifiers for filenames with dots, spaces, or
special chars; update toVarName to first strip the extension, then sanitize the
base by replacing any non-alphanumeric characters (including dots, spaces,
punctuation) with a separator or removing them, convert to camelCase (preserving
existing kebab/camel rules), ensure the resulting identifier does not start with
a digit (prefix with underscore if it does), and finally prepend the "ref"
prefix and capitalize the first letter as before; reference the toVarName
function and adjust its regex/logic to perform these sanitization steps
defensively.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bfe4452f-b98c-4c69-b392-b9e8f4c0eba5
📒 Files selected for processing (8)
AGENTS.mdpackage.jsonprompts/bundled-skills/gemini-scribe-help/SKILL.mdscripts/generate-help-references.mjssrc/services/bundled-skills.tssrc/services/generated-help-references.tstest/scripts/generate-help-references.test.tstest/services/bundled-skills.test.ts
✅ Files skipped from review due to trivial changes (3)
- prompts/bundled-skills/gemini-scribe-help/SKILL.md
- src/services/generated-help-references.ts
- test/scripts/generate-help-references.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- test/services/bundled-skills.test.ts
- src/services/bundled-skills.ts
- AGENTS.md
📜 Review details
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to src/services/bundled-skills.ts : Wire new documentation files in `docs/` into the `gemini-scribe-help` bundled skill by adding imports in `src/services/bundled-skills.ts`, entries in the `helpResources` Map, and rows in the references table in `prompts/bundled-skills/gemini-scribe-help/SKILL.md`
📚 Learning: 2026-04-07T03:51:10.557Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to {main.js,manifest.json,versions.json} : Commit generated artifacts (`main.js`, `manifest.json`, `versions.json`) alongside source changes using `npm run version` for releases
Applied to files:
package.json
📚 Learning: 2026-04-07T03:51:10.557Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to test-scripts/**/*.mjs : Run all Jest tests with `npm test` before each PR and execute relevant `test-scripts/*.mjs` after touching agent or tool code
Applied to files:
package.json
📚 Learning: 2026-04-07T03:51:10.557Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to src/services/bundled-skills.ts : Wire new documentation files in `docs/` into the `gemini-scribe-help` bundled skill by adding imports in `src/services/bundled-skills.ts`, entries in the `helpResources` Map, and rows in the references table in `prompts/bundled-skills/gemini-scribe-help/SKILL.md`
Applied to files:
package.jsonscripts/generate-help-references.mjs
📚 Learning: 2026-04-07T03:51:10.557Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to test/**/*.test.ts : Assert observable behavior of prompts, services, and tool orchestration in tests; add regression coverage for bugs
Applied to files:
package.json
📚 Learning: 2026-04-07T03:51:10.556Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.556Z
Learning: Applies to test/**/*.test.ts : Create unit tests in the `test/` directory mirroring `src/` structure with `*.test.ts` naming pattern using Jest and ts-jest
Applied to files:
package.json
📚 Learning: 2026-04-07T03:51:10.556Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.556Z
Learning: Applies to src/**/*.ts : Use Obsidian API functions when available instead of low-level operations (e.g., `vault.getMarkdownFiles()` over `vault.adapter.list()`, `app.fileManager.processFrontMatter()` for frontmatter manipulation, `vault.getAbstractFileByPath()` for file operations, `app.metadataCache` for file metadata)
Applied to files:
scripts/generate-help-references.mjs
📚 Learning: 2026-04-07T03:51:10.557Z
Learnt from: CR
Repo: allenhutchison/obsidian-gemini PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T03:51:10.557Z
Learning: Applies to src/**/*.ts : Use proper Obsidian file operations with normalized paths and metadata cache for all file operations
Applied to files:
scripts/generate-help-references.mjs
🔇 Additional comments (2)
scripts/generate-help-references.mjs (1)
72-84: Good guardrails and idempotent generation flow.Collision checks plus write-on-change behavior are clean and reduce stale-file churn in CI/dev workflows.
Also applies to: 98-148
package.json (1)
14-16: Nice build/test orchestration update.Running
generate-refsbefore dev/build/test is the right dependency ordering for generated skill references.Also applies to: 21-21
Replace manual import/map/table maintenance in bundled-skills.ts and
SKILL.md with a build-time code generation script. New or removed
markdown files in docs/guide/ and docs/reference/ are automatically
picked up — zero manual edits needed.
generates src/services/generated-help-references.ts
that gets injected at build time
Fixes #560
https://claude.ai/code/session_017jehiYdzcBfEigEFkJetEx
Summary by CodeRabbit
New Features
Bug Fixes / Improvements
Chores
Tests