Commit Graph

1385 Commits

Author SHA1 Message Date
Adit Karode 9fa7cb9155 feat(cli): add delete-note tool command
Surfaces the delete-note command on the CLI tool app, delegating to the mcp_delete_note tool. Supports deleting notes and directories via --is-directory.

Signed-off-by: Adit Karode <adit.karode@gmail.com>
2026-06-03 11:15:28 -04:00
Paul Hernandez fc2ee07076 feat(api): expose owning project on entity resolve
Expose project_external_id on v2 entity resolve responses so cloud callers can authorize cross-project targets without a second tenant DB lookup.
2026-06-02 18:01:17 -05:00
phernandez 61891f2e33 fix(plugins): address PR review — scope captureFolder to checkpoints, ASCII echo
Review feedback on #876:
- Codex (P2): the SessionStart "Where to write" brief said all auto-capture goes to
  captureFolder, but captureFolder is only the PreCompact checkpoint folder. Narrowed
  it — checkpoints go to captureFolder; decisions/tasks/notes follow
  placementConventions (or topic folders when none are set), so proactive captures
  aren't dumped into sessions/ alongside checkpoints.
- Claude review: replaced the em dash in the skills-source-guard echo string with a
  hyphen so the instruction's console output stays ASCII (CLAUDE.md compatibility).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 15:05:01 -05:00
phernandez 5f59ca49a2 docs(plugins): fold in setup debrief fixes — cloud-create, skills-source guard, shared-read cap
- Project mapping: document local vs cloud project creation — a cloud-workspace
  project needs a cloud-connected MCP server and a workspace selector; a purely
  local server fails to mkdir the cloud-style path. Pin cloud primaryProject to the
  external_id UUID.
- Install shared skills: guard against clobbering a source checkout — if ./skills is
  git-tracked and holds memory-* dirs (the skills' own source repo), skip the npx
  install instead of overwriting the working copy with published versions.
- Cloud/teams: warn that the SessionStart brief reads only the first 6 shared
  projects per session, so order the most relevant first when more are configured.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 15:05:01 -05:00
phernandez 2ba1ca8722 feat(plugins): make setup focus load-bearing, seed schemas via metadata, add smoke test
- Focus question is now load-bearing: it drives an adaptive light folder-structure
  suggestion and is stored. The placement step branches learn (existing project
  with notes) vs suggest (new/empty project) instead of only learning.
- Seed schema notes via the write_note `metadata` param instead of content
  frontmatter. The cloud write path silently coerces nested YAML to the string
  '[object Object]', corrupting schema/settings (basic-memory-cloud#1000); the
  metadata param round-trips correctly on both local and cloud.
- Surface placementConventions + captureFolder in the SessionStart brief so the
  output style's "follow stored placement conventions" reflex has something to
  follow — previously written by setup but never shown to Claude (dead config).
- Add a post-settings smoke test (run the hook's recall query, confirm routing)
  and a restart prompt gated on outputStyle in the close.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 15:05:01 -05:00
phernandez 4b6de80faa fix(plugins): hooks fall back to uvx/uv when no CLI binary is on PATH
Codex flagged (review 4397232451) that the hooks locate the CLI via
`command -v basic-memory || command -v bm`, but our own README recommends
connecting the MCP server as `claude mcp add basic-memory -- uvx basic-memory mcp`
— an ephemeral uv run that leaves NO binary on PATH. In that (recommended) setup
both hooks exited before doing anything, so the bridge silently did nothing even
though the MCP server worked.

Both hooks now resolve the CLI invocation as: prefer a `basic-memory`/`bm` binary
(fast), else fall back to `uvx basic-memory`, else `uv tool run basic-memory`, else
silent no-op. The launcher may be multi-token, so the embedded Python splits it with
shlex and prepends it to each command list. The uv cache is already warm from
running the MCP server, so the fallback is cheap.

Verified: with no binary on PATH but uvx present, SessionStart now produces a brief
(previously a silent no-op). Updated the README requirement to note uvx-only works.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 1eb4cd154f fix(plugins): route UUID project refs consistently across all skills
Codex flagged /basic-memory:remember passing a UUID primaryProject as `project`
(review 4397206729) — the same routing bug already fixed in the hooks and the
share skill. Rather than fix only the flagged spot, audited every project-ref
site and made them all consistent:

- remember: route primaryProject as project_id when it's a UUID (was the flag)
- status: same for the primaryProject-scoped search_notes queries
- setup: same for the schema-seed write to primaryProject

share/SKILL.md and both hooks (session-start, pre-compact) already handle it.
That's now every place the plugin routes to a project ref — a project ref may be
a workspace-qualified name (-> project) or an external_id UUID (-> project_id),
and all six sites detect and route accordingly. Plugin validates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez bfee8958ad docs(integrations): document the defensive getattr in the Hermes provider
Addresses the remaining review finding (deferred while #859 was open; now merged,
so the hermes module is on main and the comment lands cleanly here). The two
getattr sites read MCP SDK result/tool fields; `mcp` is an unpinned dependency
(plugin.yaml), and its CallToolResult / ListToolsResult / Tool shapes have varied
across SDK versions — so the defensive getattr is intentional, not the speculative
kind CLAUDE.md warns against. Added constraint comments at both sites explaining why.

No behavior change. `just package-check-hermes` passes (244 passed, 12 integration
tests skipped without BM_INTEGRATION).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 63f5c62dfd fix(plugins): address review findings (UUID routing, outputStyle location, line length)
Resolves the in-scope findings from the github-actions review (its prepared commit
1283a46 couldn't push — 403) and the Codex P2 (review 4397168884):

- pre-compact.sh: route a UUID primaryProject via --project-id, not --project.
  This mirrors session-start.sh; without it a UUID-configured project gets correct
  session briefs but SILENT checkpoint failures at every compaction. The substantive
  correctness fix. Verified end-to-end (checkpoint now lands in a UUID-keyed project).
- skills/share/SKILL.md: same UUID routing for /basic-memory:share team targets —
  pass external_id UUIDs as project_id, qualified names as project. (Codex P2.)
- skills/status/SKILL.md: read outputStyle from the ROOT settings object, not the
  basicMemory block — otherwise /basic-memory:status reports capture reflexes as off
  for a correctly-configured user.
- docs/getting-started.md: move outputStyle out of the basicMemory block to root in
  the team example (matches settings.example.json; it's a top-level Claude Code key).
- session-start.sh: split the >100-char project-routing line.

Out of scope here: the hermes/__init__.py getattr-rationale comments the bot
prepared live in the #859 consolidation code (not in this PR's diff) — flagged for
that PR. Plugin validates; hooks smoke-tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 451f27cfd9 docs: cross-link MCP-server prereq with the Claude Code plugin install
The MCP server is a hard prerequisite for the plugin (its hooks and skills call
it), but the two were in separate README sections with no link between them.

- The "Claude Code plugin" install section now points to "Connect your AI client"
  and states the MCP server must be connected first.
- The "Connect your AI client → Claude Code" section now points to the plugin for
  the full memory bridge.
- /basic-memory:setup's prerequisite check is now concrete: verify the MCP server
  via list_memory_projects, and if absent, walk the user through installing and
  `claude mcp add basic-memory -- uvx basic-memory mcp` before starting the interview.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez df5f0f4c04 docs: fix stale Claude Code plugin description in root README
The umbrella install section still described the plugin as bundling "skills,
hooks, and an agent" — the agent was removed in the v0.4 redesign. Updated to the
current surface: hooks (briefings + checkpoints), the opt-in output style, and the
/basic-memory:* skills.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 731e7baac1 fix(plugins): address Codex review P2s on PR #865
1. SessionStart worker pool was sized 8 but submits up to 9 searches (3 primary
   + MAX_SHARED=6 shared) — the 9th queued behind a possibly-10s call and could
   push the hook past Claude Code's 20s SessionStart timeout before the brief
   printed. Size the pool to 3 + MAX_SHARED so nothing queues. (Introduced in
   Phase 4 when the third primary query was added.)

2. captureChattyness was dead config — written by setup but read by no hook, and
   its "heavy" level advertised "checkpoint without compaction," which no hook
   implements. The real proactivity knob is `outputStyle`. Removed
   captureChattyness entirely and folded the "how active should I be?" question
   into the output-style step (the single, actually-wired toggle); the always-on
   hooks run regardless. Updated setup skill, settings.example.json, and DESIGN.

Both flagged by Codex (review 4395911984); same class as the recallTimeframe
dead-config fix from the earlier self-review. Plugin validates; hook smoke-tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 877e52fd73 feat(skills): port useful retired plugin skills into the shared memory-* set
Following the evaluation on #866, the genuinely-useful behavior from the deleted
Claude Code plugin skills is preserved as framework-agnostic shared skills (usable
by any MCP agent — Claude Desktop, OpenClaw, etc.), instead of being lost in the
v0.4 clean-break. The Claude Code plugin itself is unchanged — it deliberately
relies on hooks + the output style for capture/recall and pulls these shared skills
via /basic-memory:setup.

New shared skills (ported from the deleted set, CC-specific glue stripped):
- memory-curate (from knowledge-organize) — the real coverage gap: knowledge-GRAPH
  curation (orphan notes, relation suggestion, duplicate merge, tag/folder audit,
  hub notes, sparse-note enrichment). Distinct from memory-defrag, which is
  agent-memory-FILE hygiene.
- memory-continue (from continue-conversation) — resume prior work by rebuilding
  context from the graph (build_context / recent_activity / search), timeframe table,
  resume playbooks.
- memory-capture (from knowledge-capture) — synthesize a thread's current state into
  one note, rewriting in place via a thread_id key. The Claude-Code-specific session
  UUID is generalized to "any stable thread id your host exposes."

Also completed memory-notes' edit reference (added prepend / replace_section to the
two existing operations). Updated skills/README.md and skills/CLAUDE.md.

`just package-check-skills` validates 13 skills. NOTE: skills/skills-lock.json is a
generated artifact of the `npx skills` CLI (not used by Claude Code or OpenClaw) and
should be regenerated once the set is final — not hand-edited here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez fc8ac86fa1 feat(plugins): setup installs the shared memory-* skills (no repo dup)
Addresses the consolidation direction from issue #866: the Claude Code plugin
should consume the canonical skills/ set, not reinvent a parallel one. Rather
than vendoring copies into the plugin, /basic-memory:setup now offers to install
the shared memory-* skills via `npx skills add basicmachines-co/basic-memory
--path skills` (the existing SPEC-58 distribution path, same source OpenClaw
bundles). The plugin stays "hooks + Claude-Code-specific skills" and pulls the
shared toolkit on demand — skills/ remains the single source of truth, no
duplication in the repo.

Updated the setup interview + apply steps, README, getting-started, and CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez df3eb3208c fix(plugins): address v0.4 plugin code-review findings (PR #865)
Resolves the 8 self-review findings on PR #865:

session-start.sh:
- Wire recallTimeframe into a new "Recent sessions" query (--after_date) — it was
  parsed but unused after the Phase 4 rewrite. The brief now surfaces recent
  session checkpoints (the resume cursor), which is the one query the recency
  window legitimately applies to. (#1)
- Guard secondaryProjects/teamProjects JSON types — a string value was iterated
  character-by-character into bogus per-char queries. (#3)
- A configured-but-unreachable/misnamed primaryProject now emits a one-line
  "couldn't read" signal instead of a silent blank brief. (#7)

pre-compact.sh:
- Filter transcript turns by the `isMeta` and `toolUseResult` flags instead of a
  `text.startswith("<")` heuristic. This stops dropping legitimate user messages
  that start with "<" (#4) and stops capturing tool-result/meta frames as human
  turns (#8) — verified against a real transcript (25 human turns cleanly
  separated from 8 meta + 288 tool-result frames).
- Title now uses second precision so rapid same-minute compactions don't collide
  and silently drop/overwrite a checkpoint; removed the unused stamp/slug. (#2)
- Empty-checkpoint guard now requires at least one real user turn, not just any
  turn, so an assistant-only transcript can't produce a dangling-title note. (#5)

validate_skills.py:
- parse_frontmatter now skips indented lines, capturing only top-level keys, so a
  schema note's nested schema:/settings: children can't overwrite a top-level
  type/entity via last-write-wins. Documented its single-line-only limitation. (#6)

All verified end-to-end; `just package-check-claude-code` and
`package-check-skills` pass; ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 2886ab64e1 docs(plugins): add architecture, why, and getting-started docs (v0.4 Phase 5)
Adds user- and contributor-facing documentation under plugins/claude-code/docs/:

- why-combine-memory.md — the value proposition: two-memories/two-jobs, the
  1+1=3 framing, the three personas (thinker / builder / operator) with concrete
  use cases, and the official "use both" stance. The "why would I want this" doc.
- getting-started.md — a ~5-minute guided walkthrough: prerequisites, install,
  /basic-memory:setup, a capture→checkpoint→brief loop to see it work, the team
  workspace path, tuning knobs, and troubleshooting.
- architecture.md — how it works flow by flow, with mermaid diagrams: the bridge
  (working memory <-> durable graph), the four surfaces, SessionStart and
  PreCompact sequence flows, capture reflexes, team read/share, component map.

Linked all three from the README's new Documentation section. Marked Phase 5
docs done in DESIGN. Migration guide intentionally skipped — v0.4 is a clean
break (uninstall old, install new), noted in the CHANGELOG. Dogfood remains the
open human step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 36c245f0d2 feat(plugins): team workspace support + /basic-memory:share (v0.4 Phase 4)
Implements DESIGN.md Phase 4, grounded in a real two-workspace BM Cloud account.

Recall reads across the team:
- hooks/session-start.sh rewritten to read the primary project (active tasks +
  open decisions) AND each configured shared/team project (open decisions) in
  parallel via ThreadPoolExecutor. Routes by workspace-qualified name or
  external_id UUID (project names collide across workspaces, so bare names won't
  route); per-call timeout, capped at 6 shared projects, graceful on any failure.
  Adds a "From shared projects (read-only)" section + the share-vs-capture note.
  Verified against the real my-team-2 workspace (OAuth routing) and local fixtures.

Deliberate team writes:
- skills/share/SKILL.md → /basic-memory:share <note>: copies a note from the
  primary project into a configured teamProjects target's promoteFolder, with
  shared_from attribution and a confirmation step. Preserves the note's type so
  shared decisions stay findable in the team's structured recall. Pulled forward
  from future-work since team usage needs a safe write path.

Safe by default: capture (PreCompact checkpoints, /remember) NEVER writes to a
shared project. The proposed teamProjects.autoWrite flag is deliberately not
shipped — documented as future rather than ship an unenforced flag.

Config: secondaryProjects (read sources) + teamProjects (share targets with
promoteFolder), both requiring qualified names/UUIDs. setup interview step 3 now
configures them via list_workspaces; status reports team read-sources + share
targets; settings.example.json documents the shape. REQUIRED_SKILLS adds share.

Discovery verified: Skills (4): remember, setup, share, status. Passes
`just package-check-claude-code` incl. `claude plugin validate . --strict`.
Updated README (Teams section), CHANGELOG, and DESIGN §6 + Phase 4 status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 2bd52676d9 feat(plugins): add /basic-memory:setup bootstrap interview (v0.4 Phase 3)
Adds the bootstrap interview from DESIGN.md Phase 3 as a prose skill, plus the
first-run nudge that points users to it.

- skills/setup/SKILL.md → /basic-memory:setup: an adaptive ~2-min interview that
  maps the Claude Code project to a Basic Memory project (pick existing or create),
  seeds the session/decision/task schemas into it, optionally learns the project's
  placement conventions (list_directory + sampling, stored in placementConventions),
  writes the basicMemory settings block, and enables the capture output style.
- hooks/session-start.sh: nudges toward /basic-memory:setup on first run (when no
  basicMemory config block exists). The nudge now survives a failed/empty task
  query, so a brand-new user with no project yet still sees it; it stops once setup
  writes the config (config presence is the sentinel — no separate file).
- validate_claude_plugin.py: REQUIRED_SKILLS now includes setup.

Corrects the Phase 1 schema-seeding finding: writing a schema file's content via
write_note (CLI or MCP) indexes it as type: schema AND resolves via schema_validate
— the earlier "must use note_type/metadata" conclusion was confounded by the enum
YAML bug (since fixed). Verified end-to-end: all three schemas seed, index, and
resolve (entity=Session/Decision/Task); nudge verified across all config states;
discovery shows Skills (3): setup, remember, status.

Updated README, CHANGELOG, and DESIGN Phase 3 status. Passes
`just package-check-claude-code` incl. `claude plugin validate . --strict`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 215a2d9f99 feat(plugins): add /basic-memory:remember and :status skills (v0.4 Phase 2)
Adds the two deliberate-gesture skills from DESIGN.md Phase 2, both as prose
skills (skills are prompts) — robust to arbitrary user text and any MCP server
tool-name prefix, no bundled-script path placeholders.

- skills/remember/SKILL.md → /basic-memory:remember <text>: quick capture to the
  rememberFolder (default bm-remember) with a first-line title and manual-capture
  tag, via write_note. Model-invocable so "remember that…" triggers it.
- skills/status/SKILL.md → /basic-memory:status: user-only diagnostic
  (disable-model-invocation) reporting active project, capture/remember folders,
  output-style state, recent session checkpoints, and active-task count.

validate_claude_plugin.py now requires the shipped skill set (REQUIRED_SKILLS)
and validates each skill's name/description frontmatter. Passes
`just package-check-claude-code` incl. `claude plugin validate . --strict`.

Discovery verified end-to-end: installed from a local marketplace and confirmed
via `claude plugin details` — Skills (2): remember, status; Hooks (2):
SessionStart, PreCompact; Agents (0) — namespaced as /basic-memory:<name>.

Updated README (Commands table), CHANGELOG, and DESIGN Phase 2 status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez f485c1ef3f chore(plugins): add scoped version recipes for plugin/agent artifacts
Adds a --scope {all,core,packages} option to scripts/update_versions.py so the
version bump can target just the host-native agent artifacts (Claude Code plugin
+ root/local marketplaces, Hermes, OpenClaw) separately from the Python package
core (__init__.py, server.json). Default scope is "all" — fully backward
compatible.

New justfile recipes:
- set-version <v> [scope]            — write version (all|core|packages)
- set-version-dry-run <v> [scope]    — preview
- set-packages-version <v>           — plugin/agent artifacts only
- set-packages-version-dry-run <v>   — preview

The release / beta / release-dry-run recipes now route through set-version
instead of calling the script inline, so version-setting has one source of
truth and is reusable by the /release skill. Updated the /release command doc
to describe the consolidated version update and the new recipes.

Tests cover the new scope filtering (packages leaves core untouched and vice
versa; invalid scope errors). Existing lockstep behavior unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 3ff40d51fc feat(plugins): rebuild Claude Code plugin as the memory bridge (v0.4 Phase 1)
Reframes the Claude Code plugin as the bridge between Claude's working
memory and Basic Memory's durable graph, per plugins/claude-code/DESIGN.md.
This is the minimal-first vertical slice with a clean break from v0.3.x.

Added:
- hooks/session-start.sh — SessionStart brief: one structured `type: task`
  query against the configured (or default) project + always-on recall
  prompt. Plain stdout, silent if BM is absent.
- hooks/pre-compact.sh — PreCompact checkpoint: writes a `type: session`
  note before compaction (extractive). Only writes when primaryProject is
  set, so it never touches an un-opted-in graph.
- output-styles/basic-memory.md — capture reflexes (search-first, typed
  decision notes, cite permalinks); keep-coding-instructions: true.
- schemas/{session,decision,task}.md — picoschema seeds (validation: warn)
  so plugin-written notes are findable via metadata_filters. task mirrors
  the memory-tasks skill.
- settings.example.json — copyable config with sensible defaults.

Removed (clean break):
- the six bundled skills, the basic-memory-manager agent, the
  PreToolUse/PostToolUse write_note hooks, the basic-memory config-note
  convention, and PLUGIN.md. Equivalent workflows live in top-level skills/.

Other:
- Rewrote scripts/validate_claude_plugin.py for the new layout (hooks +
  output-style + schemas; agent dropped; skills optional). Passes
  `just package-check-claude-code` incl. `claude plugin validate --strict`.
- Rewrote README around the bridge story; updated CHANGELOG, marketplace
  descriptions, and the AGENTS.md package-check note.
- Hooks tested end-to-end against throwaway projects (brief surfaces tasks;
  checkpoint writes a queryable session note; both degrade silently).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 82f6d15946 docs(plugins): add Claude Code plugin v0.4 redesign DESIGN.md
WIP design doc for modernizing the Claude Code plugin around the
"bridge between Claude auto-memory and Basic Memory" positioning.

- Reframes the plugin as connective tissue between Claude's working
  memory and BM's durable graph (per docs/vs-built-in-memory).
- Defines the four core surfaces: SessionStart brief, PreCompact
  checkpoint, output-style reflexes, deliberate skills.
- Leans on BM schemas + structured metadata search for deterministic
  recall (ships session/decision/task picoschemas).
- Maps Claude Code projects to BM projects; team-workspace safety
  (read-across, write-by-gesture); bootstrap interview.
- Records verified findings for 8 open questions (CC v2.1.153 /
  basic-memory 0.21.5) from an investigate→adversarial-verify pass:
  PreCompact 600s budget enables LLM summaries; metadata_filters
  confirmed; path-scoped rules cut (don't load yet); commands are
  plugin-namespaced; bootstrap via SessionStart sentinel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-31 12:31:08 -05:00
phernandez 4e7a217fa7 fix(skills): correct invalid picoschema enum YAML in memory skills
The Task schema in memory-tasks/SKILL.md and the enum examples in
memory-schema/SKILL.md used a bare YAML flow sequence followed by a
trailing description:

    status?(enum): [active, blocked, done, abandoned], current state

A flow sequence ([...]) cannot be followed by ', current state' —
python-frontmatter/PyYAML raises a ParserError. In schema_router.py,
_schema_frontmatter_from_file catches that error and silently falls
back to DB metadata, so the schema's enum constraints never load.

Per the picoschema parser docstring, enum descriptions belong inside
the parens:

    status?(enum, current state): [active, blocked, done, abandoned]

Fixes 4 lines (1 in memory-tasks, 3 in memory-schema). The
memory-literary-analysis schemas use the quoted-string form
("role(enum)": "[...], desc"), which is valid YAML handled by
_parse_enum_string, so they were left unchanged.

Verified: all yaml schema blocks now parse via parse_schema_note,
and just package-check-skills passes (10 skills validated).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 15:07:00 -05:00
phernandez 354e1642b2 delete ui dir
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 15:07:00 -05:00
Drew Cain b1bd6d57e8 Update MONKEYPATCH.md with upstream issue link
Add tracking link for upstream issue regarding slash commands.

Signed-off-by: Drew Cain <groksrc@users.noreply.github.com>
2026-05-30 14:16:04 -05:00
phernandez 5365f971ef chore(integrations): consolidate agent packages
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:16:04 -05:00
phernandez 4ea03d2bf1 chore: qualify Phase 2 verdicts schema path with $SKILL_DIR
Follow-up PR review: Phase 2 prose used a CWD-relative
`--output-schema schemas/verdicts.schema.json`, while Phase 1 uses
`"$SKILL_DIR/schemas/..."`. Following Phase 2 from the repo root would
resolve the wrong path and break the Codex refutation call. Now matches the
$SKILL_DIR-qualified pattern used everywhere else; swept the file to confirm
all command/flag path positions are qualified.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez f652a09664 chore: build DIFF as argv array so scoped pathspecs survive (unix-friendly paths)
Addresses Codex PR review (P2): storing the diff in a scalar and running
`$DIFF` unquoted let the shell word-split/glob $SCOPE, so a pathspec with
spaces or glob chars ('docs/notes with spaces') broke or reviewed the wrong
files.

DIFF is now an argv array (`DIFF=(git diff "$BASE...HEAD")`, append
`-- "$SCOPE"` when set). Run via `"${DIFF[@]}"`; embed in subprocess prompts
via a shell-quoted `DIFF_STR=$(printf '%q ' "${DIFF[@]}")`. Verified the
pathspec stays a single intact argument in both bash and zsh.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez d8901efb46 chore: make claude json parsing robust to both output shapes
Follow-up PR review claimed `claude --output-format json` emits a single
object and the array form is stream-json only. Verified empirically against
the installed CLI: `claude -p --output-format json` returns a JSON ARRAY of
event objects (system, rate_limit_event, assistant, result), not a single
object — so the reviewer's suggested fix would have broken parsing here.

The portability concern is still valid (older CLIs emit a single object), so
the parsing note now handles BOTH shapes: if array, take the type=='result'
element; else use the object as-is; then read .result and strip the fence.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez c717d9997e chore: implement path scoping in adversarial-review (was broken-as-advertised)
Addresses follow-up PR review: the Inputs section advertised a path-scope
arg, but BASE=${ARG:-main} treated it only as a ref, so passing a path
produced `git diff <path>...HEAD` → fatal: ambiguous argument.

Root-causes both review findings (this one and the prior $BASE issue): the
diff command was spelled inline in many places and drifted. Now BASE (ref)
and SCOPE (pathspec) are separate inputs, combined once into a canonical
$DIFF command in preflight and reused everywhere — single source of truth.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez f865d39d3d chore: make adversarial-review prompts base-agnostic
Addresses PR review: the prompt bodies hardcoded `git diff main...HEAD`,
which contradicted the orchestrator's parameterized `git diff $BASE...HEAD`
when run against a non-main base. The prompts now defer to the exact diff
command the orchestrator appends, and Phase 2 passes that command alongside
the findings so the refuter judges against the correct base.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez 6a667dd3f8 chore: add cross-vendor adversarial-review skill
Adds an agent skill that runs adversarial code review across two model
families (Claude + Codex/GPT). Whichever runtime invokes it reviews the
branch diff natively and shells out to the other vendor for an independent
pass; each model then tries to refute the other's findings, and survivors
are reported by cross-model confidence. Report-only — never auto-applies
fixes.

- Canonical skill in .agents/skills/, symlinked from .claude/skills/
  (matches the existing instrumentation skill layout); discoverable by
  both Claude Code and Codex.
- Symmetric orchestration: run from Claude -> calls codex exec; run from
  Codex -> calls claude -p. The skill auto-detects which side it is on.
- Deterministic gate layer (ruff + grep) for negation-style house rules,
  since models underweight "never do X" constraints.
- Structured findings/verdicts via JSON schemas (codex --output-schema).

Deliberately omits the loop-until-converged state machine and auto-fix
behavior found in similar tools — convergence between models is not
correctness, so it surfaces a ranked list for a human gate instead.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:14:35 -05:00
phernandez 8d21a38588 fix(cli): handle non-subscription errors in cloud login
`bm cloud login` only caught SubscriptionRequiredError after the
post-login `/proxy/health` subscription check. OAuth succeeds and tokens
are saved, but if that check returns anything else — a 5xx while the
tenant instance is still provisioning, a 403/401 whose body doesn't match
the subscription_required shape, or a transport error — make_api_request
raises a generic CloudAPIError that escaped uncaught, dumping a raw
httpx.raise_for_status traceback. Users read this as "login failed" even
though authentication actually worked.

Add a CloudAPIError handler that prints a clean, actionable message and
exits non-zero. make_api_request wraps every httpx error (status and
transport) in CloudAPIError, so the single handler covers them all.

Fixes #863.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:13:32 -05:00
Paul Hernandez 597b12fcd1 Update README.md
update all pricing

Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
2026-05-29 08:19:52 -05:00
Paul Hernandez c86f4402f6 Update README.md
add teams info. update pricing

Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
2026-05-29 08:18:01 -05:00
Drew Cain f07643d3a8 feat(cli): expose project sync support metadata
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-28 15:00:05 -05:00
Drew Cain 8bf7bdbc0d fix(cli): limit team workspace guard to bisync
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-28 14:59:48 -05:00
Drew Cain d0ae373f45 docs(cli): clarify team mirror sync guard
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-28 14:59:48 -05:00
Drew Cain 1acec0a69d test(cli): cover workspace sync guard branches
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-28 14:59:48 -05:00
Drew Cain a2276a8a04 fix(cli): block team workspace rclone sync
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-28 14:59:48 -05:00
Drew Cain ff5d872a8c chore: update version to 0.21.5 for v0.21.5 release v0.21.5 2026-05-26 10:58:09 -05:00
Drew Cain 96ee4eafd2 docs: add v0.21.5 changelog entry
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-26 10:57:55 -05:00
Drew Cain b109b7337f fix(mcp): attach local state to one workspace project row (#854)
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-26 10:54:44 -05:00
Drew Cain 36b51b676e fix(mcp): return workspace-qualified write permalinks (#853)
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-26 00:33:21 -05:00
Drew Cain 9af320187c fix(core): load sqlite-vec before vector table cleanup (#852)
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-26 00:27:47 -05:00
Paul Hernandez 5a34a420c9 fix(mcp): preinitialize local ASGI database (#838)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-25 15:57:00 -05:00
Drew Cain a7e2368f9e chore: update version to 0.21.4 for v0.21.4 release v0.21.4 2026-05-23 14:55:49 -05:00
Sean Campbell c755127317 fix(cli): ignore CancelledError in background task done callback (#839) (#842)
Signed-off-by: rudi193-cmd <rudi193@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 14:27:59 -05:00
Sean Campbell 94c04ee456 fix(mcp): restore write_note overwrite schema for external clients (#818) (#841)
Signed-off-by: rudi193-cmd <rudi193@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 14:19:43 -05:00
Drew Cain d4ed02ba74 docs(core): move release process from CONTRIBUTING.md to AGENTS.md (#846)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 14:00:01 -05:00