Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/server/templates/skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ digraph brv_flow {
| Inspect past curates/queries | `brv curate view` / `brv query-log view` | `history.md` |
| Track context-tree changes (git-style) | `brv vc` | `vc.md` |
| Consolidate / dedupe / prune the context tree | `brv dream` | `dream.md` |
| Visually browse / view curated knowledge in a browser | `brv webui` | `curate.md` |
| Find project paths | `brv locations` | `brv locations --help` |
| Diagnose a `brv` error | `brv status` | `brv status --help` |

Expand Down Expand Up @@ -173,6 +174,7 @@ Each detail file lives in this skill directory. Read the relevant one before inv
- `brv swarm <query|curate|status>` — cross-source memory federation. See `swarm.md`.
- `brv vc <init|status|add|commit|...>` — git-style version control of the context tree. See `vc.md`.
- `brv dream <scan|finalize|undo>` — three-phase context-tree cleanup (link / merge / prune / synthesize). See `dream.md`.
- `brv webui [--port <n>]` — open or reconfigure the ByteRover dashboard when needed. For routine curate and onboarding closeouts, share `http://localhost:7700`; if a known custom Web UI port is already serving, share that localhost URL instead. The **Contexts page** renders everything saved under `.brv/context-tree/`. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port <port>` only when the user asks to open/change the dashboard port or the current port has a conflict. See `curate.md`.
Comment thread
DatPham-6996 marked this conversation as resolved.
Comment thread
DatPham-6996 marked this conversation as resolved.
- `brv curate view` / `brv query-log view|summary` — inspect history. See `history.md`.
- `brv locations` — list registered projects and their context tree paths. Use `-f json` for machine-readable output. Run `brv locations --help` for flags.
- `brv status` — diagnose any `brv` error (auth + project state). Run first when a command misbehaves.
Expand Down
71 changes: 70 additions & 1 deletion src/server/templates/skill/curate.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ brv curate "Authentication middleware validates JWTs in src/middleware/auth.ts a
brv curate "Retry helper in src/retry.ts treats HTTP 429 as retryable with exponential backoff."
brv curate view --detail
brv review pending --format json
# After a successful curate, share the Web UI link: http://localhost:7700
# If a known custom Web UI port is already serving, share that localhost URL instead
# If that link does not open, tell the user they can run brv webui
Comment thread
DatPham-6996 marked this conversation as resolved.
```

## Session Protocol
Expand All @@ -51,12 +54,70 @@ Curate runs as request -> response -> request:
brv curate --session <data.sessionId> --response-file envelope.json --delete-response-file --format json
```
4. Branch on `data.status`:
- `done` - report `data.filePath`.
- `done` - report `data.filePath`, then give the user `http://localhost:7700` so they can see the saved topic in the Contexts page. If a known custom Web UI port is already serving, share that localhost URL instead. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port <port>` only when the user asks to open/change the dashboard port or the current port has a conflict.
- `needs-llm-step` with `step: "correct-html"` - fix validation errors from `data.errors[]` and continue the same session.
- `failed` - report the error messages.

If `data.errors[]` includes `kind: "path-exists"`, prefer merging the existing topic with the new facts and continue with `--overwrite`. Choose a different path only when the collision is accidental. Replace existing content only when the user explicitly asked for replacement.

## Example Session Responses

Every `--format json` response is wrapped in `{ "command", "data", "success", "timestamp" }`. Branch on `data.status`. The three envelopes below show a full session: kickoff, one correction turn, then completion.

1. Kickoff (`brv curate "<intent>" --format json`) returns a live session asking you to author HTML:

```json
{
"command": "curate",
"data": {
"ok": true,
"status": "needs-llm-step",
"step": "generate-html",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"prompt": "<instructions describing the bv-topic HTML to author>"
},
"success": true,
"timestamp": "2026-05-29T14:30:45.123Z"
}
```

2. If your HTML fails validation, the same session stays open with `step: "correct-html"` and the errors to fix:

```json
{
"command": "curate",
"data": {
"ok": false,
"status": "needs-llm-step",
"step": "correct-html",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"errors": [
{"kind": "unknown-bv-element", "message": "Unknown element <bv-note>", "tag": "bv-note"}
],
"prompt": "<correction instructions, with the prior errors inlined>"
},
"success": false,
"timestamp": "2026-05-29T14:30:50.456Z"
}
```

3. On success, `data.status` is `done` and `data.filePath` is the topic path under `.brv/context-tree/`:

```json
{
"command": "curate",
"data": {
"ok": true,
"status": "done",
"filePath": "security/auth.html"
},
"success": true,
"timestamp": "2026-05-29T14:30:55.789Z"
}
```

→ Only now is the topic saved. Report `data.filePath` and hand the user `http://localhost:7700`, so they can open the Contexts page and see it. If a known custom Web UI port is already serving, share that localhost URL instead. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port <port>` only when the user asks to open/change the dashboard port or the current port has a conflict.

## HTML Topic Contract

Curate output is one bare HTML topic document rooted at `<bv-topic>`. The first character must be `<`, the last characters must be `</bv-topic>`, and there must be no prose wrapper and no code fences around the response.
Expand Down Expand Up @@ -135,6 +196,13 @@ brv review pending --format json

Then tell the user what needs review.

## View What You Saved

On `data.status: "done"`, the topic is written to `.brv/context-tree/<data.filePath>`. To let the user actually see it, point them at the dashboard:

- Give the user `http://localhost:7700`; if a known custom Web UI port is already serving, share that localhost URL instead. It opens the **Contexts page**, which renders the whole `.brv/context-tree/`. The path you just saved (e.g. `security/auth`) shows up as a node in the tree with its rendered content, edit controls, change history, and last-updated metadata.
- If that link does not open, tell the user they can run `brv webui` to open the dashboard. Use `brv webui --port <port>` only when the user asks to open/change the dashboard port or the current port has a conflict.
Comment thread
DatPham-6996 marked this conversation as resolved.

## Common Mistakes

| Mistake | Correct behavior |
Expand All @@ -143,3 +211,4 @@ Then tell the user what needs review.
| Omitting `keywords` when retrieval terms are obvious | Add comma-separated `keywords` on `<bv-topic>` |
| Reporting completion before a session reaches `data.status: "done"` | Wait for `done` before telling the user the topic is saved |
| Overwriting an existing path without preserving prior facts | Merge existing content unless the user explicitly wants replacement |
| Saying the topic is saved without showing the user where to see it | After `done`, give the user `data.filePath` and the Web UI link, usually `http://localhost:7700` |
4 changes: 2 additions & 2 deletions src/server/templates/skill/onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Saved:
<pain-naming + commitment paragraph — 2 short sentences>

Lives at .brv/context-tree/ — local-only.
See it in your browser: http://localhost:7700
See it in your browser: http://localhost:7700 — or run brv webui if that link doesn't open.
Comment thread
DatPham-6996 marked this conversation as resolved.
Also version-controlled, cloud-syncable, and shareable across agents — more at the end.
Comment thread
DatPham-6996 marked this conversation as resolved.
```

Expand Down Expand Up @@ -135,7 +135,7 @@ Also version-controlled, cloud-syncable, and shareable across agents — more at

The browser URL is the **verifiable** trust proof — the user can click it in 2 seconds and see their memory in a real local dashboard. Stronger than any worded assurance.

Do NOT tell the user to "run `brv webui`" — the daemon auto-starts the web server on the persisted port (default 7700). The URL works as soon as the daemon is alive, which it already is.
Use `http://localhost:7700` for the Web UI link unless a known custom Web UI port is already serving, in which case use that localhost URL. Do NOT run `brv webui` as part of every tour closeout just to produce this link. If that link does not open, tell the user they can run `brv webui` to open the dashboard. Use `brv webui --port <port>` only when the user asks to open/change the dashboard port or the current port has a conflict.

Do NOT ask "is this right?" — that turns the artifact into a form. Users who want to correct it will; users who don't, won't be slowed down.

Expand Down
37 changes: 37 additions & 0 deletions test/unit/infra/connectors/skill/skill-connector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ describe('SkillConnector', () => {
expect(content).to.include('brv query')
expect(content).to.include('brv curate')
expect(content).to.include('brv curate view')
expect(content).to.include('brv webui')
expect(content).to.include('http://localhost:7700')
expect(content).to.include('known custom Web UI port is already serving')
expect(content).to.include('If that link does not open, tell the user they can run `brv webui`')
expect(content).to.include('brv webui --port <port>')
expect(content).not.to.include('http://localhost:<served-port>')
expect(content).not.to.include('printed Web UI URL')
expect(content).to.include('## When To Use')
expect(content).to.include('## Quick Reference')
expect(content).not.to.include('<<<<<<<')
Expand All @@ -181,6 +188,29 @@ describe('SkillConnector', () => {
expect(swarmContent).to.include('parallel')
})

it('should guide installed skill docs to share the default Web UI link with command fallback', async () => {
const agent = 'Claude Code' as const
const {projectPath} = SKILL_CONNECTOR_CONFIGS[agent]
await skillConnector.install(agent)

const skillDir = path.join(testDir, projectPath, BRV_SKILL_NAME)
const contents = await Promise.all(
SKILL_FILE_NAMES.map((fileName) => readFile(path.join(skillDir, fileName), 'utf8')),
)

for (const content of contents) {
expect(content).not.to.include('printed Web UI URL')
expect(content).not.to.include('http://localhost:<served-port>')
expect(content).not.to.include('run `brv webui` after every successful curate')
}
Comment thread
DatPham-6996 marked this conversation as resolved.

const onboardingContent = await readFile(path.join(skillDir, 'onboarding.md'), 'utf8')
expect(onboardingContent).to.include('http://localhost:7700')
expect(onboardingContent).to.include('known custom Web UI port is already serving')
expect(onboardingContent).to.include('If that link does not open, tell the user they can run `brv webui`')
expect(onboardingContent).to.include('brv webui --port <port>')
})
Comment thread
DatPham-6996 marked this conversation as resolved.
Comment thread
DatPham-6996 marked this conversation as resolved.

it('should create curate.md documenting the session protocol and bv-topic contract', async () => {
const agent = 'Claude Code' as const
const {projectPath} = SKILL_CONNECTOR_CONFIGS[agent]
Expand All @@ -195,6 +225,13 @@ describe('SkillConnector', () => {
expect(curateContent).to.include('<bv-topic')
expect(curateContent).to.include('bv-rule')
expect(curateContent).to.include('--overwrite')
expect(curateContent).to.include('## Example Session Responses')
expect(curateContent).to.include('http://localhost:7700')
expect(curateContent).to.include('known custom Web UI port is already serving')
expect(curateContent).to.include('If that link does not open, tell the user they can run `brv webui`')
expect(curateContent).to.include('brv webui --port <port>')
expect(curateContent).not.to.include('http://localhost:<served-port>')
expect(curateContent).not.to.include('printed Web UI URL')
})

it('should create sibling guides with When-To and Common Mistakes sections', async () => {
Expand Down
Loading