Commit Graph
6 Commits
Author SHA1 Message Date
4e34d03e14 feat(hooks): user-scope agent sync hooks, one-command setup, --only scoping (#71)
* feat(hooks): register agent sync hooks per machine, not per project

Agent platforms read hook config only from the directory a session starts
in — never a parent, never a subfolder. Project-level hooks therefore fired
only for sessions that happened to start at the mount, and, living inside a
synced folder, they replicated one machine's agent config to the whole team
(a second writer of a file bdrive already owns). Claude Code additionally
ignores project hooks until the folder is trusted, so in practice they were
often inert without any visible sign.

Hooks now go to each platform's user config, once per machine, covering
every session in every folder; the existing shell guard keeps them a no-op
outside BearDrive projects. Install migrates away blocks older versions
wrote into projects, and `bdrive hooks uninstall` removes ours while leaving
foreign hooks untouched.

Setup is also one command now. init absorbs the skill install, prints the
hub link, and takes --server, so connecting to a named hub no longer needs a
separate login; the runbook forbids preflight and command chaining, since
each distinct command costs the user a permission prompt. For plugin users a
PreToolUse hook auto-approves bdrive's own setup subcommands — narrowly: any
shell operator in the command disqualifies it.

Also drops --shared in favor of `init . --only wiki,docs`, which writes a
managed block of .bdriveignore rules instead of a second scope mechanism.
Because those rules sync, `sync --prune` now refuses on a scoped project
rather than stripping everything outside the scope from the hub for everyone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016aYntCWwdUhpzUfEk3ddyJ

* docs: fix stale claims an audit found against the new CLI

An audit of every doc surface against the code turned up claims that the
user-scope hook move and the one-command init made false: project-level
hooks "riding the repo", the Claude trust prompt, Codex's //hooks project
layer, `--no-hooks` skipping the skill (it does not), prune reconciling
against a per-device scope (it now refuses on a scoped project), and
`--scan-interval`/`--remote-interval` documented as init flags when they
only exist on `bdrive daemon run`.

Also documents the surface added today — `--server`, `bdrive hooks
uninstall`, and the plugin's PreToolUse auto-approval — refreshes the two
sample `init` transcripts to the real output, and corrects hook matchers
that had drifted from agenthooks.go.

`bdrive scope` told users to narrow an existing mount with `bdrive init .
--only <dirs>`, which resume then ignored — a dead end. Init now applies
--only on resume, writing the scope block, so the advice works.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016aYntCWwdUhpzUfEk3ddyJ

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 10:08:45 +09:00
Snow LeeandClaude Fable 5 644caff70e feat(hooks): every mentioned file path gets a gated hub link — formula injected each turn
Field report follow-up: an agent with a stale skill copy couldn't find
the gated URL after creating a file. Instructions rot; hook output is
computed fresh from the binary every turn. Claude Code's turn-start
pull hook now runs 'bdrive sync --hook claude-code', which:

- pulls as before, and stamps the session note from the event JSON
  (replacing the sh/sed pipeline for the pull leg)
- emits the project's gated-link formula as UserPromptSubmit
  additionalContext: whenever the agent mentions a synced file path in
  prose, it appends the hub link on an emoji — `<path>` [🔗](<url>) —
  path plain (it's the local path), hyperlink on the emoji only; code
  blocks stay plain; bdrive share stays explicit-opt-in-public

Blind-tested: an agent given only the injected context decorated every
path mention correctly, kept the code-block command plain, and checked
files were synced before linking.

- hooks install now CONVERGES marker-identified groups to the current
  shape (command/matcher/flags), so improvements reach existing
  projects on reinstall instead of being frozen by the idempotency
  marker; hermes same
- plugin: UserPromptSubmit → beardrive-pull.sh (stdout passes through);
  version 0.3.0
- SKILL 'Share what you make' generalized to 'Link what you mention'
  (URL formula documented for non-Claude platforms); install.md pointer
  template updated

Never fails the turn: every error path in --hook mode is a silent
successful exit; offline still emits (links serve online teammates).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5cxPQdSGJnjXCYY9GeWXt
2026-07-16 10:25:07 -07:00
Snow LeeandClaude Fable 5 476113ebdc fix(hooks): read heat captures grep matches and shell-command reads, not just Read
Field report: an agent session read a dozen-plus files via Bash
(grep/cat/tail/find) and Grep, but read heat showed almost nothing —
the read-log hook only matched the native Read tool.

- matchers broadened per platform: claude Read|Grep|Bash, codex
  read_file|shell, gemini +search_file_content|run_shell_command,
  hermes read_file|grep|bash; plugin hooks.json matches Read|Grep|Bash
- read-log is now tool-aware: shell events mine the command line for
  existing files it names (redirect targets and flags excluded), grep
  events mine the response for the files the matches came from
  (content lines and filename lists), and listing tools (Glob, ls) are
  deliberately ignored — seeing a file's name is not reading it
- hooks install upgrades a registered hook's stale matcher in place, so
  re-running it after a binary upgrade rolls coverage out to existing
  projects instead of being skipped by the idempotency marker
- docs: SKILL.md platform table + read-heat wording, install/init
  commands, README command table

Note from the same report, verified not a bug: read-log resolves the
mount via the folder's own .bdrive/config.json (config.ResolveMount),
so a stale duplicate registry entry cannot swallow reads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5cxPQdSGJnjXCYY9GeWXt
2026-07-13 15:05:05 -07:00
Snow LeeandClaude Fable 5 e3ca821dc4 feat(web): Insights quadrant + read-heat docs (phase 2)
Admin/org-owner Insights view (⋯ menu): dependency-free SVG scatter of
every file by 30-day reads × days since last change, log scales, with the
hot-but-stale danger quadrant shaded and a ranked fix-these-first list;
lens toggle for all/human/agent reads. The Claude Code plugin gains a
PostToolUse(Read) hook so plugin users feed agent-read telemetry without
project-level hook registration. Docs synced: README, SKILL.md,
plugin install/init commands, CLAUDE.md, design doc marked implemented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5cxPQdSGJnjXCYY9GeWXt
2026-07-11 14:54:32 -07:00
Snow LeeandClaude Fable 5 1ac128db2c rename: sfs -> BearDrive everywhere; CLI becomes bdrive
Product and project are BearDrive; the CLI binary is bdrive (bdrive mnt,
bdrive sync, ...), the web viewer is bdrive-web. All conventions follow
the full name: .beardrive settings file, .beardriveignore, ~/.beardrive
home, BEARDRIVE_HOME, .beardrive-conflict-* / .beardrive-tmp-* files.
Plugin/skill/marketplace renamed to beardrive (/beardrive:mount).

Module path is now github.com/runbear-io/beardrive — merge only after
renaming the GitHub repo, or go install breaks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHEUaYfFHhmDvqLYw74Ehz
2026-07-07 15:02:40 -07:00
Snow LeeandClaude Fable 5 2d29ff8aac feat: web viewer, project-local config, selective sync, Claude Code plugin
- sfs-web (cmd/sfs-web, internal/webapp): read-only Obsidian-style web UI
  serving a local folder (default) or an sfs remote; markdown rendering
  with [[wikilinks]], task lists and tables, file downloads with ETags,
  per-file provenance from the journals; added to goreleaser builds
- .sfs project file (internal/config): per-folder volume/remote/include
  settings that travel with the folder, win over the global registry, and
  never sync; daemon picks up edits live
- .sfsignore + include lists (internal/syncer): gitignore-style selective
  sync with ! re-includes, applied symmetrically in scan and materialize;
  newly ignored files stop syncing without being deleted anywhere
- Claude Code plugin (plugin/, .claude-plugin/): sfs skill, /sfs:mount and
  /sfs:status commands, turn-boundary sync hooks (blocking pull on prompt,
  async push on stop); installable via the repo's marketplace manifest
- CLAUDE.md and .claude project settings for Claude Code development

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHEUaYfFHhmDvqLYw74Ehz
2026-07-07 14:05:36 -07:00