@byterover/claude-plugin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,44 @@
1
+ Elastic License 2.0 (ELv2)
2
+
3
+ Acceptance
4
+ By using the software, you agree to all of the terms and conditions below.
5
+
6
+ Copyright License
7
+ The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below.
8
+
9
+ Limitations
10
+ You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
11
+
12
+ You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key.
13
+
14
+ You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor's trademarks is subject to applicable law.
15
+
16
+ Patents
17
+ The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
18
+
19
+ Notices
20
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
21
+
22
+ If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
23
+
24
+ No Other Rights
25
+ These terms do not imply any licenses other than those expressly granted in these terms.
26
+
27
+ Termination
28
+ If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
29
+
30
+ No Liability
31
+ As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
32
+
33
+ Definitions
34
+ The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it.
35
+
36
+ _you_ refers to the individual or entity agreeing to these terms.
37
+
38
+ _your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
39
+
40
+ _your licenses_ are all the licenses granted to you for the software under these terms.
41
+
42
+ _use_ means anything you do with the software requiring one of your licenses.
43
+
44
+ _trademark_ means trademarks, service marks, and similar rights.
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # @byterover/claude-bridge
2
+
3
+ Native bridge between [ByteRover](https://www.byterover.dev) and [Claude Code](https://docs.anthropic.com/en/docs/claude-code). Enriches Claude's auto-memory with ByteRover's full multi-tier retrieval — BM25 search, importance scoring, performance correlation, and LLM synthesis — giving Claude persistent, cross-referenced context that improves over time.
4
+
5
+ ## Table of contents
6
+
7
+ - [What it does](#what-it-does)
8
+ - [Prerequisites](#prerequisites)
9
+ - [Quick start](#quick-start)
10
+ - [Commands](#commands)
11
+ - [How it works](#how-it-works)
12
+ - [Development](#development)
13
+ - [Project structure](#project-structure)
14
+ - [License](#license)
15
+
16
+ ## What it does
17
+
18
+ Claude Code has a built-in auto-memory system — it saves observations across sessions as flat markdown files. ByteRover has a richer context tree with multi-tier retrieval: BM25 text search, importance/recency scoring, maturity tier boosting, performance-memory correlation, and LLM-powered synthesis. This bridge connects the two:
19
+
20
+ 1. **Ingesting memories** — when Claude's extraction agent writes a memory file, a hook fires and sends the content to `brv curate`, which enriches it with tags, keywords, scoring metadata, and stores it in the context tree
21
+ 2. **Syncing context** — after each turn, a hook queries ByteRover for ranked knowledge and writes a cross-reference file that Claude's recall system can pick up
22
+ 3. **Zero workflow change** — you use `claude` exactly as before. The bridge runs in the background via Claude Code's hook system
23
+
24
+ The result: Claude's memories are indexed, scored, and searchable alongside the rest of your project knowledge in ByteRover.
25
+
26
+ ## Prerequisites
27
+
28
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed
29
+ - Node.js 20+
30
+ - [brv CLI](https://docs.byterover.dev/quickstart) installed and available on your `PATH`
31
+
32
+ ## Quick start
33
+
34
+ ### 1. Install the bridge
35
+
36
+ ```bash
37
+ npm install -g @byterover/claude-bridge
38
+ ```
39
+
40
+ ### 2. Install hooks
41
+
42
+ ```bash
43
+ brv-claude-plugin install
44
+ ```
45
+
46
+ This adds four hooks to `~/.claude/settings.json`:
47
+
48
+ - **PostToolUse(Write)** — triggers `brv-claude-plugin ingest` when Claude writes a memory file
49
+ - **PostToolUse(Edit)** — triggers `brv-claude-plugin ingest` when Claude edits a memory file
50
+ - **Stop** — triggers `brv-claude-plugin sync` after each turn to refresh cross-references
51
+ - **UserPromptSubmit** — triggers `brv-claude-plugin recall` to query ByteRover with the user's prompt and inject relevant context before the model call
52
+
53
+ Your existing settings and hooks are preserved. A backup is saved to `settings.json.brv-backup`.
54
+
55
+ ### 3. Verify
56
+
57
+ ```bash
58
+ brv-claude-plugin doctor
59
+ ```
60
+
61
+ You should see all checks passing:
62
+
63
+ ```
64
+ brv-claude-plugin doctor
65
+
66
+ ✓ brv CLI — byterover-cli/2.5.0
67
+ ✓ Context tree — /path/to/project/.brv/context-tree
68
+ ✓ Claude settings — ~/.claude/settings.json
69
+ ✓ Bridge hooks — PostToolUse + Stop + UserPromptSubmit hooks found
70
+ ✓ Bridge executable — /usr/local/bin/brv-claude-plugin
71
+ ✓ Memory directory — ~/.claude/projects/-path-to-project/memory/
72
+
73
+ All checks passed.
74
+ ```
75
+
76
+ ### 4. Use Claude normally
77
+
78
+ ```bash
79
+ claude "fix the auth bug"
80
+ ```
81
+
82
+ Memories are ingested into `.brv/context-tree/_cc/` automatically. No changes to your workflow.
83
+
84
+ ### 5. Uninstall (if needed)
85
+
86
+ ```bash
87
+ brv-claude-plugin uninstall
88
+ ```
89
+
90
+ Removes only bridge hooks. Your other hooks and settings are untouched.
91
+
92
+ ## Commands
93
+
94
+ ### `brv-claude-plugin install`
95
+
96
+ Installs hooks into Claude Code's `~/.claude/settings.json`.
97
+
98
+ | Option | Description |
99
+ | ------------------- | ------------------------------------------ |
100
+ | `--dry-run` | Show what would be written without saving |
101
+ | `--settings-path` | Override path to Claude Code settings.json |
102
+
103
+ Idempotent — safe to run multiple times. Deduplicates by checking for the `#brv-claude-plugin` marker in existing hooks.
104
+
105
+ ### `brv-claude-plugin uninstall`
106
+
107
+ Removes bridge hooks from settings. Per-hook removal — if a matcher entry contains both a bridge hook and your own hook, only the bridge hook is deleted.
108
+
109
+ | Option | Description |
110
+ | ------------------- | ------------------------------------------ |
111
+ | `--settings-path` | Override path to Claude Code settings.json |
112
+
113
+ ### `brv-claude-plugin ingest`
114
+
115
+ Called by the PostToolUse hook. Reads hook JSON from stdin, parses the memory file, and sends it to `brv curate --detach`.
116
+
117
+ - **Write tool**: reads content from `tool_input.content`
118
+ - **Edit tool**: reads the file from disk (Edit only carries `old_string`/`new_string`)
119
+ - Skips non-memory files, `MEMORY.md`, and `_brv_context.md`
120
+ - Always exits 0 — never blocks Claude
121
+
122
+ | Option | Description |
123
+ | --------- | ------------------------ |
124
+ | `--json` | Output result as JSON |
125
+
126
+ ### `brv-claude-plugin sync`
127
+
128
+ Called by the Stop hook. Copies the context tree index from `.brv/context-tree/_index.md` into `_brv_context.md` in Claude's memory directory with a single pointer in `MEMORY.md`.
129
+
130
+ - On success: writes context tree index with a guide note pointing to the full tree
131
+ - If `_index.md` unavailable but `_brv_context.md` exists: preserves existing content
132
+ - If `_index.md` unavailable and no existing file: writes a stub with "(sync pending)"
133
+ - Runs async in the background — never blocks Claude
134
+
135
+ | Option | Description |
136
+ | ---------------- | ---------------------------------------- |
137
+ | `--json` | Output result as JSON |
138
+ | `--memory-dir` | Override path to Claude memory directory |
139
+
140
+ ### `brv-claude-plugin recall`
141
+
142
+ Called by the UserPromptSubmit hook. Reads the user's prompt from stdin, queries ByteRover with it, and returns targeted context as `additionalContext` that Claude sees before generating a response.
143
+
144
+ - Runs **synchronously** — delays the model call until ByteRover responds (6s internal timeout, 8s hook timeout)
145
+ - Skips trivially short prompts (< 5 chars)
146
+ - If ByteRover query fails or times out, exits silently — prompt proceeds without context
147
+ - Wraps results in `<byterover-context>` tags
148
+
149
+ ### `brv-claude-plugin doctor`
150
+
151
+ Runs 6 diagnostic checks: brv CLI, context tree, settings file, installed hooks, bridge executable, and memory directory resolution.
152
+
153
+ ## How it works
154
+
155
+ The bridge uses Claude Code's [hook system](https://docs.anthropic.com/en/docs/claude-code/hooks) to intercept memory operations without modifying Claude Code's source.
156
+
157
+ ### Recall flow (UserPromptSubmit hook)
158
+
159
+ ```
160
+ User types: "fix the combo scoring bug"
161
+
162
+ ▼ UserPromptSubmit hook fires (before model call)
163
+ brv-claude-plugin recall
164
+ │ brv query "fix the combo scoring bug" → targeted results
165
+
166
+ Claude sees <byterover-context> as system reminder
167
+ (live, relevant to this specific prompt)
168
+ ```
169
+
170
+ ### Ingest flow (PostToolUse hook)
171
+
172
+ ```
173
+ Claude writes ~/.claude/projects/.../memory/feedback_testing.md
174
+
175
+ ▼ PostToolUse hook fires, pipes JSON to stdin
176
+ brv-claude-plugin ingest
177
+ │ Parse cc-ts frontmatter (name, description, type)
178
+ │ Map type → domain (_cc/user, _cc/feedback, _cc/project, _cc/reference)
179
+
180
+ brv curate --detach --format json -- "context string"
181
+ │ Daemon queues curation (async, non-blocking)
182
+
183
+ .brv/context-tree/_cc/feedback/testing.md
184
+ (enriched with tags, keywords, importance scoring)
185
+ ```
186
+
187
+ ### Sync flow (Stop hook)
188
+
189
+ ```
190
+ Turn ends
191
+
192
+ ▼ Stop hook fires
193
+ brv-claude-plugin sync
194
+ │ read .brv/context-tree/_index.md → copy to memory dir
195
+
196
+ ~/.claude/projects/.../memory/_brv_context.md
197
+ (context tree index + guide to full tree)
198
+ ```
199
+
200
+ ### Memory path resolution
201
+
202
+ The bridge resolves Claude's memory directory using the same logic as Claude Code:
203
+
204
+ 1. `CLAUDE_COWORK_MEMORY_PATH_OVERRIDE` env var (full override)
205
+ 2. `autoMemoryDirectory` from settings (local → user, excluding project settings for security)
206
+ 3. `~/.claude/projects/<sanitized-canonical-git-root>/memory/`
207
+
208
+ Git worktrees are resolved to their canonical root so all worktrees share one memory directory.
209
+
210
+ ### Multi-project support
211
+
212
+ The bridge naturally supports multiple projects. Claude Code scopes memory per git repository, and ByteRover scopes its context tree per `.brv/` directory. Both use the same `cwd` from the hook input as their anchor:
213
+
214
+ ```
215
+ /Users/x/project-a/ ← claude session here
216
+ ├── .git/ ← Claude memory: ~/.claude/projects/-Users-x-project-a/memory/
217
+ ├── .brv/ ← ByteRover tree: project-a/.brv/context-tree/
218
+ └── src/
219
+
220
+ /Users/x/project-b/ ← separate claude session here
221
+ ├── .git/ ← Claude memory: ~/.claude/projects/-Users-x-project-b/memory/
222
+ ├── .brv/ ← ByteRover tree: project-b/.brv/context-tree/
223
+ └── src/
224
+ ```
225
+
226
+ Each project's memories are ingested into its own context tree and synced back to its own memory directory. No cross-project leakage.
227
+
228
+ **Important: initialize `.brv/` at the git root.** Claude Code resolves memory directories from the canonical git root. ByteRover walks up from `cwd` to find `.brv/`. When both are at the same level, everything maps correctly.
229
+
230
+ If you initialize `.brv/` in a subdirectory instead of the git root, the bridge will encounter mismatches:
231
+
232
+ ```
233
+ /monorepo/ ← git root (Claude memory lives here)
234
+ ├── .git/
235
+ ├── frontend/
236
+ │ └── .brv/ ← brv initialized here, not at git root
237
+ └── backend/ ← sessions from here won't find .brv/
238
+ ```
239
+
240
+ In this layout, Claude sessions from `/monorepo/backend/` would fail to reach the `.brv/` in `frontend/`. To fix this, initialize ByteRover at the git root:
241
+
242
+ ```bash
243
+ cd /monorepo
244
+ brv init # .brv/ at git root — matches Claude's project boundary
245
+ ```
246
+
247
+ If you need separate context trees for subdirectories in a monorepo, initialize `.brv/` in each subdirectory and run `claude` from within that subdirectory (not from the monorepo root).
248
+
249
+ ### Hook identification
250
+
251
+ Every stored hook command includes a `#brv-claude-plugin` shell comment marker. This marker — not the path text — is used by `install` (dedupe), `uninstall` (removal), and `doctor` (detection). A clone in any directory will work correctly.
252
+
253
+ ## Development
254
+
255
+ ```bash
256
+ # Install dependencies
257
+ npm install
258
+
259
+ # Type check
260
+ npm run typecheck
261
+
262
+ # Build
263
+ npm run build
264
+
265
+ # Run in dev mode
266
+ npm run dev -- doctor
267
+
268
+ # Run built CLI
269
+ node dist/cli.js doctor
270
+ ```
271
+
272
+ ### Testing locally
273
+
274
+ 1. Initialize a brv project: `cd /your/project && brv init`
275
+ 2. Build the bridge: `npm run build`
276
+ 3. Install hooks (dev mode): `node dist/cli.js install`
277
+ 4. Start a Claude session and make a few changes
278
+ 5. Check `.brv/context-tree/_cc/` for ingested memories
279
+ 6. Check `~/.claude/projects/.../memory/_brv_context.md` for synced context
280
+
281
+ ## Project structure
282
+
283
+ ```
284
+ src/
285
+ cli.ts # Commander.js entry point
286
+ cc-frontmatter.ts # Claude Code memory YAML frontmatter parser
287
+ memory-path.ts # Full cc-ts memory path resolution (git root, worktrees, env vars)
288
+ stdin.ts # Read + validate JSON from stdin
289
+ bridge-command.ts # Executable resolution + #brv-claude-plugin marker
290
+ schemas/
291
+ cc-hook-input.ts # Zod schemas for PostToolUse and Stop hook input
292
+ cc-settings.ts # Raw JSON read/write for settings.json (lossless)
293
+ commands/
294
+ install.ts # Install hooks into settings.json (per-hook dedupe, backup)
295
+ uninstall.ts # Remove bridge hooks (per-hook removal)
296
+ ingest.ts # PostToolUse handler — Write/Edit split, brv curate
297
+ sync.ts # Stop handler — _index.md copy, _brv_context.md, MEMORY.md pointer
298
+ recall.ts # UserPromptSubmit handler — live brv query with user prompt
299
+ doctor.ts # 6 diagnostic checks
300
+ ```
301
+
302
+ ## License
303
+
304
+ [Elastic License 2.0 (ELv2)](./LICENSE)
@@ -0,0 +1,23 @@
1
+ export declare const BRIDGE_HOOK_MARKER = "#brv-claude-plugin";
2
+ /**
3
+ * Resolve the executable prefix for hook commands.
4
+ * Returns ONLY the executable part — callers append subcommand via buildHookCommand().
5
+ *
6
+ * Production: "/usr/local/bin/brv-claude-plugin"
7
+ * Dev: "node /abs/path/to/dist/cli.js"
8
+ */
9
+ export declare function resolveBridgeExecutable(): string;
10
+ /**
11
+ * Build the full hook command string for a subcommand.
12
+ * Appends the marker as a trailing shell comment so isBridgeHook() works
13
+ * regardless of install path or directory name.
14
+ *
15
+ * "/usr/local/bin/brv-claude-plugin ingest #brv-claude-plugin"
16
+ * "node /tmp/bridge/dist/cli.js sync #brv-claude-plugin"
17
+ */
18
+ export declare function buildHookCommand(subcommand: string): string;
19
+ /**
20
+ * Check if a hook object was installed by this bridge.
21
+ * Matches on BRIDGE_HOOK_MARKER, not path text.
22
+ */
23
+ export declare function isBridgeHook(hook: Record<string, unknown>): boolean;
@@ -0,0 +1,103 @@
1
+ import { accessSync, constants, existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ // ---------------------------------------------------------------------------
5
+ // Marker — explicit shell comment suffix for hook identification.
6
+ // Not derived from path text. Injected deliberately into every stored command.
7
+ // ---------------------------------------------------------------------------
8
+ export const BRIDGE_HOOK_MARKER = "#brv-claude-plugin";
9
+ // ---------------------------------------------------------------------------
10
+ // Executable resolution
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Resolve the executable prefix for hook commands.
14
+ * Returns ONLY the executable part — callers append subcommand via buildHookCommand().
15
+ *
16
+ * Production: "/usr/local/bin/brv-claude-plugin"
17
+ * Dev: "node /abs/path/to/dist/cli.js"
18
+ */
19
+ export function resolveBridgeExecutable() {
20
+ const pkgRoot = findPackageRoot();
21
+ // Try production bin first
22
+ const pkgJson = JSON.parse(readFileSync(join(pkgRoot, "package.json"), "utf-8"));
23
+ const bin = pkgJson.bin;
24
+ const binEntry = typeof bin === "string"
25
+ ? bin
26
+ : typeof bin === "object" && bin !== null
27
+ ? bin["brv-claude-plugin"]
28
+ : undefined;
29
+ if (binEntry) {
30
+ const resolved = resolve(pkgRoot, binEntry);
31
+ if (existsSync(resolved)) {
32
+ assertNoSpaces(resolved);
33
+ // Only return the bare path if it's actually executable (e.g. npm
34
+ // global install creates a proper shim with +x). tsc output and
35
+ // local dev builds are 0644, so we must prefix with node.
36
+ if (isExecutable(resolved)) {
37
+ return resolved;
38
+ }
39
+ return `node ${resolved}`;
40
+ }
41
+ }
42
+ // Dev fallback: dist/cli.js (never executable — always prefix with node)
43
+ const distCli = join(pkgRoot, "dist", "cli.js");
44
+ if (existsSync(distCli)) {
45
+ assertNoSpaces(distCli);
46
+ return `node ${distCli}`;
47
+ }
48
+ throw new Error(`Cannot resolve bridge executable. Run 'pnpm build' first, ` +
49
+ `or install the package globally.`);
50
+ }
51
+ /**
52
+ * Build the full hook command string for a subcommand.
53
+ * Appends the marker as a trailing shell comment so isBridgeHook() works
54
+ * regardless of install path or directory name.
55
+ *
56
+ * "/usr/local/bin/brv-claude-plugin ingest #brv-claude-plugin"
57
+ * "node /tmp/bridge/dist/cli.js sync #brv-claude-plugin"
58
+ */
59
+ export function buildHookCommand(subcommand) {
60
+ const exe = resolveBridgeExecutable();
61
+ return `${exe} ${subcommand} ${BRIDGE_HOOK_MARKER}`;
62
+ }
63
+ /**
64
+ * Check if a hook object was installed by this bridge.
65
+ * Matches on BRIDGE_HOOK_MARKER, not path text.
66
+ */
67
+ export function isBridgeHook(hook) {
68
+ return (typeof hook.command === "string" &&
69
+ hook.command.includes(BRIDGE_HOOK_MARKER));
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Helpers
73
+ // ---------------------------------------------------------------------------
74
+ function findPackageRoot() {
75
+ // Walk up from this file to find package.json
76
+ let dir = dirname(fileURLToPath(import.meta.url));
77
+ for (let i = 0; i < 10; i++) {
78
+ if (existsSync(join(dir, "package.json"))) {
79
+ return dir;
80
+ }
81
+ const parent = dirname(dir);
82
+ if (parent === dir)
83
+ break;
84
+ dir = parent;
85
+ }
86
+ throw new Error("Cannot find package.json for brv-claude-plugin");
87
+ }
88
+ function isExecutable(filePath) {
89
+ try {
90
+ accessSync(filePath, constants.X_OK);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ function assertNoSpaces(resolvedPath) {
98
+ if (/\s/.test(resolvedPath)) {
99
+ throw new Error(`Bridge install path contains spaces: "${resolvedPath}"\n` +
100
+ `Install brv-claude-plugin to a path without spaces, or use a symlink.`);
101
+ }
102
+ }
103
+ //# sourceMappingURL=bridge-command.js.map
@@ -0,0 +1,21 @@
1
+ declare const VALID_TYPES: readonly ["user", "feedback", "project", "reference"];
2
+ export type CcMemoryType = (typeof VALID_TYPES)[number];
3
+ export interface CcMemoryFrontmatter {
4
+ name: string;
5
+ description: string;
6
+ type: CcMemoryType;
7
+ }
8
+ export interface CcMemoryFile {
9
+ frontmatter: CcMemoryFrontmatter;
10
+ body: string;
11
+ }
12
+ /**
13
+ * Parse a Claude Code memory file into frontmatter + body.
14
+ * Returns null if the file is not a valid cc-ts memory file.
15
+ */
16
+ export declare function parseCcMemoryFile(content: string): CcMemoryFile | null;
17
+ /**
18
+ * Map cc-ts memory type to ByteRover context tree domain path.
19
+ */
20
+ export declare function ccTypeToDomain(type: CcMemoryType): string;
21
+ export {};
@@ -0,0 +1,51 @@
1
+ import yaml from "js-yaml";
2
+ // Match cc-ts/utils/frontmatterParser.ts line 123
3
+ const FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)---\s*\n?/;
4
+ const VALID_TYPES = ["user", "feedback", "project", "reference"];
5
+ /**
6
+ * Parse a Claude Code memory file into frontmatter + body.
7
+ * Returns null if the file is not a valid cc-ts memory file.
8
+ */
9
+ export function parseCcMemoryFile(content) {
10
+ const match = content.match(FRONTMATTER_REGEX);
11
+ if (!match)
12
+ return null;
13
+ const raw = match[1] || "";
14
+ const body = content.slice(match[0].length);
15
+ try {
16
+ const fm = yaml.load(raw);
17
+ if (!fm || typeof fm !== "object")
18
+ return null;
19
+ if (typeof fm.name !== "string")
20
+ return null;
21
+ if (typeof fm.type !== "string")
22
+ return null;
23
+ const type = fm.type;
24
+ if (!VALID_TYPES.includes(type))
25
+ return null;
26
+ return {
27
+ frontmatter: {
28
+ name: fm.name,
29
+ description: typeof fm.description === "string" ? fm.description : "",
30
+ type: type,
31
+ },
32
+ body,
33
+ };
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Map cc-ts memory type to ByteRover context tree domain path.
41
+ */
42
+ export function ccTypeToDomain(type) {
43
+ const map = {
44
+ user: "_cc/user",
45
+ feedback: "_cc/feedback",
46
+ project: "_cc/project",
47
+ reference: "_cc/reference",
48
+ };
49
+ return map[type];
50
+ }
51
+ //# sourceMappingURL=cc-frontmatter.js.map
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { program } from "commander";
3
+ import { registerInstallCommand } from "./commands/install.js";
4
+ import { registerUninstallCommand } from "./commands/uninstall.js";
5
+ import { registerIngestCommand } from "./commands/ingest.js";
6
+ import { registerSyncCommand } from "./commands/sync.js";
7
+ import { registerRecallCommand } from "./commands/recall.js";
8
+ import { registerDoctorCommand } from "./commands/doctor.js";
9
+ program
10
+ .name("brv-claude-plugin")
11
+ .description("Native bridge between ByteRover context engine and Claude Code auto-memory")
12
+ .version("0.1.0");
13
+ registerInstallCommand(program);
14
+ registerUninstallCommand(program);
15
+ registerIngestCommand(program);
16
+ registerSyncCommand(program);
17
+ registerRecallCommand(program);
18
+ registerDoctorCommand(program);
19
+ program.parse();
20
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerDoctorCommand(program: Command): void;