Commit graph

36 commits

Author SHA1 Message Date
dependabot[bot]
9f2cab0122
ci: bump actions/setup-node from 6 to 7
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 09:10:21 +00:00
Aaron Bockelie
8bb580cc56 fix: .mcpignore semantics, TLS 1.3 startup, rename extension (#250, #252, #253)
Bundles the three reported bugs plus an unreported under-blocking bug found
while writing the tests for #250, and adds the coverage tooling that would
have caught all four.

#250 — .mcpignore negation was inverted
The parser stripped the leading '!' before Minimatch saw it, so .negate was
always false and the branch reading it was dead code. '!folder/*' compiled
into a positive exclusion: negation did not merely fail, it inverted.

Under-blocking (found while testing the above, not reported)
Patterns were handed to Minimatch raw, so two gitignore rules were never
implemented: a slash-less pattern matches at any depth ('*.secret' must hide
'a/b/creds.secret'), and a directory match covers its contents ('private/'
must hide 'private/notes.md'). No consumer of isExcluded() checks ancestors —
every caller passes a full file path — so nothing compensated downstream. The
plugin's own shipped .mcpignore template promises both behaviours, so a user
following it believed private files were hidden while they were being served
to the model. Patterns are now translated into the globs that implement
gitignore semantics, and negation is interpreted here rather than by Minimatch.

#252 — min TLS 1.3 crashed the server
secureProtocol mapped 1.3 to 'TLSv1_3_method', which OpenSSL never shipped, so
context creation threw "Unknown method: TLSv1_3_method". Switched to minVersion,
which also fixes a second latent bug: secureProtocol PINS one version, so
"minimum TLS 1.2" was silently refusing TLS 1.3 clients. The setting now
behaves as the floor it is labelled.

#253 — rename dropped the extension
'newName' was concatenated onto the source directory verbatim, so renaming
'note.md' to 'renamed' produced an extension-less file that drops out of
markdown views. The source extension is now carried over when newName omits
one, before the overwrite guard so it checks the right path.

Coverage + test contract
All four bugs shipped through code paths with zero coverage. Adds `make
coverage` / `coverage-map` / `coverage-gate`, a ratcheting coverageThreshold
(security boundary held to a far higher floor than global, since a hole there
leaks vault content), and tests/test-contract.test.ts enforcing that a green
run means something: no .only, no .skip, every file asserts, no tautologies.
The contract immediately caught an `expect(true).toBe(true)` placeholder in the
path-validator suite, now replaced with real assertions.

BREAKING (.mcpignore, both intended):
- The double-'!' workaround for #250 now correctly parses as a double negation
  (net exclude) and will stop working.
- A bare '*' now excludes at every depth, per gitignore, rather than top-level
  only. This is what makes the '*' + '!keep/**' whitelist idiom work.
2026-07-13 17:46:50 -05:00
Aaron Bockelie
fc47349e18 chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:

- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
  coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
  alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
  0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
  which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)

TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:

- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
  for an esbuild-bundled project with extensionless imports (node16/nodenext
  would force `.js` extensions and break every relative import)

Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.

Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-03 21:13:32 -05:00
Aaron Bockelie
9fe222e9a7 ci(release): note Claude Desktop .mcpb re-import in generated release notes
The .mcpb bridge ships inside the GitHub release bundle, and BRAT updates
only the Obsidian plugin — never the Claude Desktop connector. Users had no
signal that a plugin update doesn't deliver bridge-side fixes (#243/#247).
Add a standing "Claude Desktop (.mcpb connector)" section to the release
workflow's notes template so every release tells .mcpb users to re-import,
rather than depending on per-release notes remembering to.

Claude-Session: https://claude.ai/code/session_011yowKCMFCBp61DRBu5xQm4
2026-06-24 11:04:03 -05:00
Aaron Bockelie
b402db8e59
Merge pull request #194 from aaronsb/dependabot/github_actions/actions/attest-build-provenance-4
ci: Bump actions/attest-build-provenance from 2 to 4
2026-06-05 17:07:27 -05:00
Aaron Bockelie
6358d31fdd fix(ci): harden release.yml against shell injection in notes
The previous template inlined ${{ inputs.release_notes }} directly into
a double-quoted bash NOTES="..." assignment, so backticks (or $vars) in
the notes were evaluated by the shell as command substitution. Today's
0.11.30 release hit this — backticks in the ADR-107 release notes blew
up the heredoc and failed the workflow before tag creation.

Switch the templated values to env-var bindings (RELEASE_NAME,
RELEASE_VERSION, RELEASE_NOTES_INPUT) and assemble the markdown via
printf so the notes are treated as data, not code.
2026-05-24 17:11:06 -05:00
Aaron Bockelie
535dfd1c53 fix(mcp): stop debug route shadowing the GET /mcp SSE stream + two-row Levenshtein
Reimplemented from PR #126 (djsplice, who also reported #125), reduced to
the parts that are verified-clean. The worker-offload half of #126 is split
out to a tracking issue (inert as wired + correctness divergences — see PR
discussion / the follow-up issue).

SSE route deconfliction
  In @modelcontextprotocol/sdk@1.29.0 (the pinned version), `GET /mcp` is
  the standalone server->client SSE stream for server-initiated messages —
  verified in webStandardStreamableHttp.js:handleGetRequest (opens
  `_GET_stream`, Content-Type text/event-stream, gated on
  Accept: text/event-stream + session + protocol version). A debug route
  returning application/json on `GET /mcp` shadowed it, so any client that
  opens the standalone stream (mcp-remote-class bridges — #128's logs show
  one in use here) received JSON instead of an SSE stream and treated it as
  failed. Moved debug to `GET /mcp-info`; `GET /mcp` and `POST /mcp` both
  reach handleMCPRequest. Unlike #126's `app.all('/mcp')`, GET/POST are
  registered individually so the existing explicit `app.delete('/mcp')`
  session-close handler is preserved.

  Scope note: this restores the server-initiated-notification channel (a
  real latent defect on its own). It is NOT claimed to fix #128 — per the
  #190 investigation that is a separate SDK-1.29 compat-init problem — and
  #125's "SSE reconnection loop" is the reporter's un-reproduced diagnosis.

Two-row Levenshtein
  fuzzy-match.ts rewritten from a full (m+1)x(n+1) matrix to a two-row
  formulation (O(n) memory, no per-line array-of-arrays allocation) plus
  length heuristics and a 0.95 early-exit. Pure CPU/memory win on the
  main-thread edit.window path; behaviour-preserving. Adds the first
  fuzzy-match tests (classic Levenshtein distances, symmetry,
  heuristic-preservation).

build.yml: PR-status-comment step set continue-on-error so it cannot red an
otherwise-green build on fork/limited-token PRs.

Co-authored-by: djsplice <barrows.jeff@gmail.com>
2026-05-18 21:05:22 -05:00
dependabot[bot]
a7702c3b9e
ci: Bump actions/attest-build-provenance from 2 to 4
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2 to 4.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 16:29:12 +00:00
Aaron Bockelie
f1cc9d63ba feat(scorecard): scheduled regression gate vs committed baseline (#165)
Standalone weekly watch (+ workflow_dispatch) that FAILS only on a real
portal regression vs scripts/scorecard-baseline.json:
- Health/Review score-ratio downgrade
- automated issue count increase
- a new behaviour/permission ("**Title**:") finding

Never inspects advisory wording — structured deltas only. Scraper drift
→ exit 3, reported distinctly (fix scorecard.mjs, not a regression).
Portal unreachable → exit 0 (inconclusive, never a false fail). Gates
nothing in the release path; no PR/release triggers; no dependency
install (Node builtins only).

`make scorecard-gate` runs it; `make scorecard-baseline` re-snapshots
deliberately (refuses on drift) — a named act, since an accidental
re-baseline silently disarms the gate. Baseline captured for 0.11.25
(Health Excellent 4/4, Review Satisfactory 3/4, 5 issues, 12 findings)
— still shows Dynamic Code Execution; it clears (an improvement, not a
fail) when a post-ADR-201 release is scanned.

Validated: happy path exit 0, simulated regression exit 1 (all 3
classes), drift refusal, idempotent re-baseline.

Closes #165
2026-05-16 23:42:05 -05:00
Aaron Bockelie
43d83ed061 fix(ci): attest styles.css and manifest.json, not just main.js
Follow-up to #164. Obsidian's portal flags every installable release asset
lacking a build-provenance attestation. #164 attested main.js + the .mcpb
bundles but missed styles.css and manifest.json, leaving a standing
'styles.css release asset does not have a GitHub artifact attestation'
recommendation. Attest the full installable set.
2026-05-16 12:25:13 -05:00
Aaron Bockelie
64827f7baa ci(release): attest build provenance for main.js + mcpb bundles
Closes #164. Adds actions/attest-build-provenance@v2 (gated like Create
Release) plus id-token/attestations write permissions, attesting main.js and
both .mcpb bundles. Clears the scorecard 'release assets missing a GitHub
artifact attestation' finding without changing what ships.
2026-05-16 11:59:51 -05:00
dependabot[bot]
b7217977eb
ci: Bump actions/github-script from 8 to 9
Bumps [actions/github-script](https://github.com/actions/github-script) from 8 to 9.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v8...v9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-15 18:03:09 +00:00
Aaron Bockelie
4d46014b8a fix(build): Use stable latest-release URL for MCPB download
The Settings UI was building a versioned releases/download/<version>/
URL that would 404 for any plugin version not yet associated with a
GitHub release — the exact case for users on a fresh BRAT install
running ahead of the release pipeline.

build-mcpb.mjs now emits both the versioned filename (for archival)
and an unversioned obsidian-mcp.mcpb alias. release.yml uploads both.
The Settings UI links to releases/latest/download/obsidian-mcp.mcpb,
which GitHub resolves to the most recent release's asset by name —
stable regardless of plugin version.

Makefile clean target updated to remove the new artifact.

Refs PR #155 review.
2026-05-15 11:46:06 -05:00
Aaron Bockelie
7ca31c4685 build: Add make mcpb target and attach .mcpb to release assets
scripts/build-mcpb.mjs is a zero-dep pure-Node zip builder
(stored-only container, manual CRC32) that packs mcpb/manifest.json
and mcpb/server.js into obsidian-mcp-<version>.mcpb. Works on any
Node ≥18, doesn't require system zip/7z, runs identically on dev
machines and in CI.

Makefile gains a "mcpb" target so the local workflow is "make mcpb"
when iterating. clean now also removes built .mcpb files.

release.yml builds the bundle as part of the release job and attaches
it to the GitHub release alongside main.js/manifest.json/styles.css,
so BRAT users and the future plugin Settings "download" affordance
both resolve to the canonical release asset.

Refs ADR-102.
2026-05-15 11:30:50 -05:00
dependabot[bot]
b6956cf29f
ci: Bump actions/upload-artifact from 5 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 09:37:59 +00:00
Aaron Bockelie
36e494ff63 chore: Change release workflow to manual dispatch
Instead of auto-releasing on every push to main, releases are now
triggered manually via workflow_dispatch. This reduces noise from
incremental commits during development.

To create a release:
1. Go to Actions → Create Release
2. Click "Run workflow"
3. Optionally add release notes
4. Run
2025-12-14 23:15:58 -06:00
dependabot[bot]
fe26bbb961
ci: Bump github/codeql-action from 3 to 4 (#49)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 22:45:54 -06:00
dependabot[bot]
1240d3e677
ci: Bump actions/checkout from 3 to 6 (#48)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 22:45:52 -06:00
dependabot[bot]
7d761a7780
ci: Bump actions/github-script from 7 to 8 (#47)
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 22:45:50 -06:00
dependabot[bot]
97d4652d7e
ci: Bump actions/upload-artifact from 4 to 5 (#46)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 22:45:47 -06:00
dependabot[bot]
e2451a1808
ci: Bump actions/setup-node from 3 to 6 (#45)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 22:45:34 -06:00
Aaron Bockelie
a49e4df1ec ci: Enable Dependabot for automated dependency updates
Configure Dependabot to:
- Check npm dependencies weekly (Mondays at 9am)
- Group patch/minor updates by dependency type
- Check GitHub Actions versions weekly
- Auto-label PRs with 'dependencies' and 'automated'

Also enabled vulnerability alerts and security updates via GitHub API.
2025-12-03 12:43:00 -06:00
Aaron Bockelie
09c3511789 chore: Remove automated stats tracking
Remove the community engagement and release download statistics from README and delete the automated stats update workflow. This simplifies the repository and removes unnecessary automation.
2025-12-03 12:40:26 -06:00
Aaron Bockelie
71ac7b8be7 fix: Emergency fix for stats update workflow and README
Critical bug fix:
- The awk script in update-stats.yml had a logic error that caused
  repeated appending of <!-- STATS:END --> markers on each run
- This resulted in the README growing from 192 lines to 4.2M lines
  over 22 workflow runs

Changes:
1. Restored README.md to clean state from commit 37a640c (192 lines)
2. Rewrote awk logic to properly replace content between markers:
   - Now tracks in_stats state correctly
   - Skips all content between START and END markers
   - Inserts new stats content only once
   - Prevents duplication on subsequent runs

Tested:
- First run: correctly inserts stats (192 → 208 lines)
- Second run: correctly replaces stats (stays at 208 lines)
- Only 1 STATS:END marker after multiple runs
2025-10-27 00:29:41 -05:00
Aaron Bockelie
37a640c8fa feat: Add automated repository statistics tracking
- Created GitHub Action to update stats daily at 2 AM UTC
- Added dynamic badges to README for stars, forks, downloads, version
- Added placeholder section for detailed statistics
- Workflow also supports manual trigger via workflow_dispatch
2025-09-24 23:17:15 -05:00
Aaron Bockelie
08a314a139
feat: Add GitHub Sponsors integration
- Add .github/FUNDING.yml for GitHub Sponsors button
- Add sponsorship section to README with badge
- Manifest already has fundingUrl configured

This enables the GitHub Sponsors button on the repository and
provides clear sponsorship information for users who want to
support the plugin's development.
2025-08-13 07:12:15 -05:00
Aaron Bockelie
f19ec0881a
feat: Add recursive directory copy functionality
- Implement recursive directory copying with security layer compliance
- Add automatic file vs directory detection using Obsidian API
- Support nested directory structures with proper error handling
- Include comprehensive test suite for recursive copy operations
- Maintain backward compatibility with existing file copy operations
- Handle overwrite protection and skip binary/image files appropriately

Resolves directory copying limitations in vault operations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 08:43:32 -05:00
Aaron Bockelie
98d72c6670 chore: Remove Node.js 18.x from test matrix - Obsidian uses Node 20.x 2025-07-15 18:16:06 -05:00
Aaron Bockelie
e4861e4615 fix: Update CodeQL action to v3 and add security permissions 2025-07-15 18:13:39 -05:00
Aaron Bockelie
36301118a9 docs: Add comprehensive project documentation and security audit
- Add CONTRIBUTING.md with development guidelines
- Add SECURITY.md with vulnerability reporting policy
- Create GitHub issue templates for bugs and features
- Add PR template with checklist
- Set up GitHub Actions for testing and security scanning
- Document all security findings from code audit
- Create detailed GitHub issues for all vulnerabilities
- Update CHANGELOG with security audit results
- Add project structure documentation

This establishes proper open-source project structure and documents
all critical security issues that need to be addressed.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-12 00:14:45 -05:00
Aaron Bockelie
c5d921e33a fix: Remove 'v' prefix from release tags to match Obsidian requirements
- Change tag format from 'v0.5.3' to '0.5.3'
- Update release title and notes formatting
- Aligns with Obsidian community plugin standards

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-04 16:49:42 -05:00
Aaron Bockelie
73a2ddc318 fix: Add permissions for GitHub Actions to comment on PRs
- Add explicit permissions for pull-requests and issues write access
- Fixes "Resource not accessible by integration" error
- Allows workflow to post build status comments on PRs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-04 16:31:23 -05:00
Aaron Bockelie
b327af5bf5 ci: Add build workflow for feature branches
- Create separate build.yml for all branches (main, feat/**, feature/**, fix/**, hotfix/**)
- Keep release.yml focused on main branch releases only
- Add feature-release.yml for manual pre-releases from feature branches
- Upload build artifacts for all builds
- Add PR commenting for build status
2025-06-30 07:09:35 -05:00
Aaron Bockelie
31d89fdcce fix: Add contents write permission to GitHub Action
- Fix HTTP 403 error when creating releases
- Restore lint and test steps (they were passing)
- GitHub token now has proper permissions for release creation
2025-06-27 11:23:46 -05:00
Aaron Bockelie
f19fecdb0f feat: Add linting, testing, and development documentation
- Add ESLint configuration with TypeScript support
- Set up Jest testing framework with Obsidian mocks
- Add basic MCP server tests
- Create DEVELOPMENT.md with Claude Code integration guide
- Update GitHub Action to include lint and test steps
- Use modern GitHub CLI for releases instead of deprecated actions

Testing and linting now part of CI/CD pipeline for quality assurance.
2025-06-27 11:18:36 -05:00
Aaron Bockelie
a1972134d7 ci: Add GitHub Action for automatic releases
- Triggers on main branch pushes (excluding doc changes)
- Builds plugin and creates release with required assets
- Only creates release if version tag doesn't exist
- Marks releases as prerelease for beta testing
- Includes BRAT installation instructions in release notes
2025-06-27 11:04:47 -05:00