From 1624da6251d1b2744d8db5155022182cdf0dd8f8 Mon Sep 17 00:00:00 2001 From: Dat Pham Date: Fri, 29 May 2026 06:58:54 +0700 Subject: [PATCH 1/4] docs(skill): point users to the webui dashboard after curate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guide the in-daemon curate agent to surface the ByteRover dashboard (http://localhost:7700, Contexts page) once a topic is saved, so users can actually see what was curated. - SKILL.md: add `brv webui` to the Quick Reference and command list, noting the daemon already serves the dashboard on port 7700 - curate.md: on `data.status: "done"`, hand the user the clickable dashboard URL alongside `filePath`; add a "View What You Saved" section and a "Example Session Responses" walkthrough (kickoff → correction → completion JSON envelopes); add a Common Mistakes row for reporting a save without showing where to view it - skill-connector tests: assert SKILL.md mentions `brv webui` and curate.md mentions `localhost:7700` + the new examples section --- src/server/templates/skill/SKILL.md | 2 + src/server/templates/skill/curate.md | 69 ++++++++++++++++++- .../connectors/skill/skill-connector.test.ts | 3 + 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/server/templates/skill/SKILL.md b/src/server/templates/skill/SKILL.md index fec095264..053568d9f 100644 --- a/src/server/templates/skill/SKILL.md +++ b/src/server/templates/skill/SKILL.md @@ -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` (or open `http://localhost:7700`) | `curate.md` | | Find project paths | `brv locations` | `brv locations --help` | | Diagnose a `brv` error | `brv status` | `brv status --help` | @@ -173,6 +174,7 @@ Each detail file lives in this skill directory. Read the relevant one before inv - `brv swarm ` — cross-source memory federation. See `swarm.md`. - `brv vc ` — git-style version control of the context tree. See `vc.md`. - `brv dream ` — three-phase context-tree cleanup (link / merge / prune / synthesize). See `dream.md`. +- `brv webui [--port ]` — open the ByteRover dashboard in the browser. The **Contexts page** renders everything saved under `.brv/context-tree/`. The daemon already serves it at `http://localhost:7700` by default, so that URL is clickable without running anything. See `curate.md`. - `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. diff --git a/src/server/templates/skill/curate.md b/src/server/templates/skill/curate.md index 1e4b71065..016d95f7f 100644 --- a/src/server/templates/skill/curate.md +++ b/src/server/templates/skill/curate.md @@ -28,6 +28,7 @@ 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, view the topic in the dashboard: http://localhost:7700 (Contexts page) ``` ## Session Protocol @@ -44,12 +45,70 @@ Curate runs as request -> response -> request: brv curate --session --response "" --format json ``` 4. Branch on `data.status`: - - `done` - report `data.filePath`. + - `done` - report `data.filePath`, then give the user the clickable dashboard URL `http://localhost:7700` so they can see the saved topic in the Contexts page (the daemon is already serving it). - `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 "" --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": "" + }, + "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 ", "tag": "bv-note"} + ], + "prompt": "" + }, + "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 the dashboard URL `http://localhost:7700` so they can open the Contexts page and see it. + ## HTML Topic Contract Curate output is one bare HTML topic document rooted at ``. The first character must be `<`, the last characters must be ``, and there must be no prose wrapper and no code fences around the response. @@ -128,6 +187,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/`. To let the user actually see it, point them at the dashboard: + +- Give the user the clickable URL `http://localhost:7700` — 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. +- The dashboard is already running — the daemon serves it on port `7700` by default, so the URL works the moment a curate succeeds; nothing extra to start. (`brv webui` opens the same dashboard in the browser if the user prefers a command.) + ## Common Mistakes | Mistake | Correct behavior | @@ -136,3 +202,4 @@ Then tell the user what needs review. | Omitting `keywords` when retrieval terms are obvious | Add comma-separated `keywords` on `` | | 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 the dashboard URL (`http://localhost:7700`, Contexts page) and the `filePath` | diff --git a/test/unit/infra/connectors/skill/skill-connector.test.ts b/test/unit/infra/connectors/skill/skill-connector.test.ts index ceccd3b80..e7ee8ca55 100644 --- a/test/unit/infra/connectors/skill/skill-connector.test.ts +++ b/test/unit/infra/connectors/skill/skill-connector.test.ts @@ -157,6 +157,7 @@ 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('## When To Use') expect(content).to.include('## Quick Reference') expect(content).not.to.include('<<<<<<<') @@ -195,6 +196,8 @@ describe('SkillConnector', () => { expect(curateContent).to.include(' { From 47771b6abcd007bb3e2340ec34f9f2badd38d87c Mon Sep 17 00:00:00 2001 From: Dat Pham Date: Sun, 31 May 2026 11:12:51 +0700 Subject: [PATCH 2/4] [feat]: ENG-2697 use printed webui URL in skill guidance Update ByteRover skill docs to avoid hardcoded localhost:7700 links now that brv webui resolves the active port. - point post-curate and onboarding guidance to the URL printed by brv webui - document brv webui --port for port conflicts or custom ports - add skill connector regression coverage to reject fixed Web UI localhost URLs --- src/server/templates/skill/SKILL.md | 4 +-- src/server/templates/skill/curate.md | 13 +++++----- src/server/templates/skill/onboarding.md | 6 ++--- .../connectors/skill/skill-connector.test.ts | 26 ++++++++++++++++++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/server/templates/skill/SKILL.md b/src/server/templates/skill/SKILL.md index 053568d9f..0db8ec7b2 100644 --- a/src/server/templates/skill/SKILL.md +++ b/src/server/templates/skill/SKILL.md @@ -120,7 +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` (or open `http://localhost:7700`) | `curate.md` | +| Visually browse / view curated knowledge in a browser | `brv webui` (or `brv webui --port `) | `curate.md` | | Find project paths | `brv locations` | `brv locations --help` | | Diagnose a `brv` error | `brv status` | `brv status --help` | @@ -174,7 +174,7 @@ Each detail file lives in this skill directory. Read the relevant one before inv - `brv swarm ` — cross-source memory federation. See `swarm.md`. - `brv vc ` — git-style version control of the context tree. See `vc.md`. - `brv dream ` — three-phase context-tree cleanup (link / merge / prune / synthesize). See `dream.md`. -- `brv webui [--port ]` — open the ByteRover dashboard in the browser. The **Contexts page** renders everything saved under `.brv/context-tree/`. The daemon already serves it at `http://localhost:7700` by default, so that URL is clickable without running anything. See `curate.md`. +- `brv webui [--port ]` — open the ByteRover dashboard in the browser and print the active Web UI URL. The **Contexts page** renders everything saved under `.brv/context-tree/`. Share the printed Web UI URL with the user; if the current port is busy or they need another port, run `brv webui --port ` and share the new printed URL. See `curate.md`. - `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. diff --git a/src/server/templates/skill/curate.md b/src/server/templates/skill/curate.md index 016d95f7f..b236aeb29 100644 --- a/src/server/templates/skill/curate.md +++ b/src/server/templates/skill/curate.md @@ -28,7 +28,8 @@ 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, view the topic in the dashboard: http://localhost:7700 (Contexts page) +# After a successful curate, run brv webui and share the printed Web UI URL (Contexts page) +# If the port is busy, run brv webui --port and share that printed URL instead ``` ## Session Protocol @@ -45,7 +46,7 @@ Curate runs as request -> response -> request: brv curate --session --response "" --format json ``` 4. Branch on `data.status`: - - `done` - report `data.filePath`, then give the user the clickable dashboard URL `http://localhost:7700` so they can see the saved topic in the Contexts page (the daemon is already serving it). + - `done` - report `data.filePath`, then run `brv webui` and give the user the printed Web UI URL so they can see the saved topic in the Contexts page. If the command reports a port conflict, run `brv webui --port ` and share that printed URL instead. - `needs-llm-step` with `step: "correct-html"` - fix validation errors from `data.errors[]` and continue the same session. - `failed` - report the error messages. @@ -107,7 +108,7 @@ Every `--format json` response is wrapped in `{ "command", "data", "success", "t } ``` -→ Only now is the topic saved. Report `data.filePath` and hand the user the dashboard URL `http://localhost:7700` so they can open the Contexts page and see it. +→ Only now is the topic saved. Report `data.filePath`, run `brv webui`, and hand the user the printed Web UI URL so they can open the Contexts page and see it. If the command reports a port conflict, run `brv webui --port ` and share that printed URL instead. ## HTML Topic Contract @@ -191,8 +192,8 @@ Then tell the user what needs review. On `data.status: "done"`, the topic is written to `.brv/context-tree/`. To let the user actually see it, point them at the dashboard: -- Give the user the clickable URL `http://localhost:7700` — 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. -- The dashboard is already running — the daemon serves it on port `7700` by default, so the URL works the moment a curate succeeds; nothing extra to start. (`brv webui` opens the same dashboard in the browser if the user prefers a command.) +- Run `brv webui` and give the user the printed Web UI URL. 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 `brv webui` reports a port conflict or the user needs a different port, run `brv webui --port ` and give the user that newly printed URL instead. ## Common Mistakes @@ -202,4 +203,4 @@ On `data.status: "done"`, the topic is written to `.brv/context-tree/` | | 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 the dashboard URL (`http://localhost:7700`, Contexts page) and the `filePath` | +| Saying the topic is saved without showing the user where to see it | After `done`, give the user `data.filePath`, run `brv webui`, and share the printed Web UI URL for the Contexts page | diff --git a/src/server/templates/skill/onboarding.md b/src/server/templates/skill/onboarding.md index a145d89f2..0593e5875 100644 --- a/src/server/templates/skill/onboarding.md +++ b/src/server/templates/skill/onboarding.md @@ -100,7 +100,7 @@ Saved: Lives at .brv/context-tree/ — local-only. -See it in your browser: http://localhost:7700 +See it in your browser: Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -127,7 +127,7 @@ model, your reliability stance, and the context you just shared. You stop re-explaining. You start where you left off. Lives at .brv/context-tree/ — local-only. -See it in your browser: http://localhost:7700 +See it in your browser: Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -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. +Run `brv webui` to get the current dashboard URL, then give the user the printed Web UI URL. Do NOT hardcode a localhost port; the daemon may be using a remembered custom port. If `brv webui` reports a port conflict, run `brv webui --port ` and use that newly printed URL. 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. diff --git a/test/unit/infra/connectors/skill/skill-connector.test.ts b/test/unit/infra/connectors/skill/skill-connector.test.ts index e7ee8ca55..59887326f 100644 --- a/test/unit/infra/connectors/skill/skill-connector.test.ts +++ b/test/unit/infra/connectors/skill/skill-connector.test.ts @@ -158,6 +158,9 @@ describe('SkillConnector', () => { expect(content).to.include('brv curate') expect(content).to.include('brv curate view') expect(content).to.include('brv webui') + expect(content).to.include('printed Web UI URL') + expect(content).to.include('brv webui --port ') + expect(content).not.to.include('http://localhost:7700') expect(content).to.include('## When To Use') expect(content).to.include('## Quick Reference') expect(content).not.to.include('<<<<<<<') @@ -182,6 +185,25 @@ describe('SkillConnector', () => { expect(swarmContent).to.include('parallel') }) + it('should avoid fixed Web UI localhost ports in installed skill docs', 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('http://localhost:7700') + } + + const onboardingContent = await readFile(path.join(skillDir, 'onboarding.md'), 'utf8') + expect(onboardingContent).to.include('printed Web UI URL') + expect(onboardingContent).to.include('brv webui --port ') + }) + 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] @@ -196,8 +218,10 @@ describe('SkillConnector', () => { expect(curateContent).to.include('') + expect(curateContent).not.to.include('http://localhost:7700') }) it('should create sibling guides with When-To and Common Mistakes sections', async () => { From cc8a15a3dcd6ba8c24432cd2d92d6a0eeefbf5be Mon Sep 17 00:00:00 2001 From: Dat Pham Date: Mon, 1 Jun 2026 03:28:45 +0700 Subject: [PATCH 3/4] [feat]: ENG-2697 use printed webui URL in skill guidance Update ByteRover skill docs to avoid hardcoded localhost:7700 links now that brv webui resolves the active port. - point post-curate and onboarding guidance to the URL printed by brv webui - document brv webui --port for port conflicts or custom ports - add skill connector regression coverage to reject fixed Web UI localhost URLs --- src/server/templates/skill/SKILL.md | 4 ++-- src/server/templates/skill/curate.md | 15 ++++++------- src/server/templates/skill/onboarding.md | 6 +++--- .../connectors/skill/skill-connector.test.ts | 21 ++++++++++++------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/server/templates/skill/SKILL.md b/src/server/templates/skill/SKILL.md index 0db8ec7b2..7848c328f 100644 --- a/src/server/templates/skill/SKILL.md +++ b/src/server/templates/skill/SKILL.md @@ -120,7 +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` (or `brv webui --port `) | `curate.md` | +| Visually browse / view curated knowledge in a browser | `http://localhost:` | `curate.md` | | Find project paths | `brv locations` | `brv locations --help` | | Diagnose a `brv` error | `brv status` | `brv status --help` | @@ -174,7 +174,7 @@ Each detail file lives in this skill directory. Read the relevant one before inv - `brv swarm ` — cross-source memory federation. See `swarm.md`. - `brv vc ` — git-style version control of the context tree. See `vc.md`. - `brv dream ` — three-phase context-tree cleanup (link / merge / prune / synthesize). See `dream.md`. -- `brv webui [--port ]` — open the ByteRover dashboard in the browser and print the active Web UI URL. The **Contexts page** renders everything saved under `.brv/context-tree/`. Share the printed Web UI URL with the user; if the current port is busy or they need another port, run `brv webui --port ` and share the new printed URL. See `curate.md`. +- `brv webui [--port ]` — open or reconfigure the ByteRover dashboard when needed. For routine curate and onboarding closeouts, share the served Web UI link directly: `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. See `curate.md`. - `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. diff --git a/src/server/templates/skill/curate.md b/src/server/templates/skill/curate.md index b236aeb29..a8e2f5646 100644 --- a/src/server/templates/skill/curate.md +++ b/src/server/templates/skill/curate.md @@ -28,8 +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, run brv webui and share the printed Web UI URL (Contexts page) -# If the port is busy, run brv webui --port and share that printed URL instead +# After a successful curate, share the served Web UI link: http://localhost: +# default http://localhost:7700 unless a custom Web UI port is already serving +# If that link does not open, tell the user they can run brv webui ``` ## Session Protocol @@ -46,7 +47,7 @@ Curate runs as request -> response -> request: brv curate --session --response "" --format json ``` 4. Branch on `data.status`: - - `done` - report `data.filePath`, then run `brv webui` and give the user the printed Web UI URL so they can see the saved topic in the Contexts page. If the command reports a port conflict, run `brv webui --port ` and share that printed URL instead. + - `done` - report `data.filePath`, then give the user the served Web UI link, such as `http://localhost:`, so they can see the saved topic in the Contexts page. Use default `http://localhost:7700` unless a custom port is already serving. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --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. @@ -108,7 +109,7 @@ Every `--format json` response is wrapped in `{ "command", "data", "success", "t } ``` -→ Only now is the topic saved. Report `data.filePath`, run `brv webui`, and hand the user the printed Web UI URL so they can open the Contexts page and see it. If the command reports a port conflict, run `brv webui --port ` and share that printed URL instead. +→ Only now is the topic saved. Report `data.filePath` and hand the user the served Web UI link, such as `http://localhost:`, so they can open the Contexts page and see it. Use default `http://localhost:7700` unless a custom port is already serving. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port ` only when the user asks to open/change the dashboard port or the current port has a conflict. ## HTML Topic Contract @@ -192,8 +193,8 @@ Then tell the user what needs review. On `data.status: "done"`, the topic is written to `.brv/context-tree/`. To let the user actually see it, point them at the dashboard: -- Run `brv webui` and give the user the printed Web UI URL. 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 `brv webui` reports a port conflict or the user needs a different port, run `brv webui --port ` and give the user that newly printed URL instead. +- Give the user the served Web UI link, such as `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. ## Common Mistakes @@ -203,4 +204,4 @@ On `data.status: "done"`, the topic is written to `.brv/context-tree/` | | 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`, run `brv webui`, and share the printed Web UI URL for the Contexts page | +| Saying the topic is saved without showing the user where to see it | After `done`, give the user `data.filePath` and the served Web UI link, such as `http://localhost:` | diff --git a/src/server/templates/skill/onboarding.md b/src/server/templates/skill/onboarding.md index 0593e5875..058a4a771 100644 --- a/src/server/templates/skill/onboarding.md +++ b/src/server/templates/skill/onboarding.md @@ -100,7 +100,7 @@ Saved: Lives at .brv/context-tree/ — local-only. -See it in your browser: +See it in your browser: http://localhost: — or run brv webui if that link doesn't open. Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -127,7 +127,7 @@ model, your reliability stance, and the context you just shared. You stop re-explaining. You start where you left off. Lives at .brv/context-tree/ — local-only. -See it in your browser: +See it in your browser: http://localhost: Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -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. -Run `brv webui` to get the current dashboard URL, then give the user the printed Web UI URL. Do NOT hardcode a localhost port; the daemon may be using a remembered custom port. If `brv webui` reports a port conflict, run `brv webui --port ` and use that newly printed URL. +Use the served Web UI link, such as `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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 ` 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. diff --git a/test/unit/infra/connectors/skill/skill-connector.test.ts b/test/unit/infra/connectors/skill/skill-connector.test.ts index 59887326f..35f8bc8c0 100644 --- a/test/unit/infra/connectors/skill/skill-connector.test.ts +++ b/test/unit/infra/connectors/skill/skill-connector.test.ts @@ -158,9 +158,11 @@ describe('SkillConnector', () => { expect(content).to.include('brv curate') expect(content).to.include('brv curate view') expect(content).to.include('brv webui') - expect(content).to.include('printed Web UI URL') + expect(content).to.include('http://localhost:') + expect(content).to.include('default `http://localhost:7700`') + 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 ') - expect(content).not.to.include('http://localhost:7700') + 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('<<<<<<<') @@ -185,7 +187,7 @@ describe('SkillConnector', () => { expect(swarmContent).to.include('parallel') }) - it('should avoid fixed Web UI localhost ports in installed skill docs', async () => { + it('should guide installed skill docs to share the served Web UI link with command fallback', async () => { const agent = 'Claude Code' as const const {projectPath} = SKILL_CONNECTOR_CONFIGS[agent] await skillConnector.install(agent) @@ -196,11 +198,14 @@ describe('SkillConnector', () => { ) for (const content of contents) { - expect(content).not.to.include('http://localhost:7700') + expect(content).not.to.include('printed Web UI URL') + expect(content).not.to.include('run `brv webui` after every successful curate') } const onboardingContent = await readFile(path.join(skillDir, 'onboarding.md'), 'utf8') - expect(onboardingContent).to.include('printed Web UI URL') + expect(onboardingContent).to.include('http://localhost:') + expect(onboardingContent).to.include('default `http://localhost:7700`') + 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 ') }) @@ -219,9 +224,11 @@ describe('SkillConnector', () => { expect(curateContent).to.include('bv-rule') expect(curateContent).to.include('--overwrite') expect(curateContent).to.include('## Example Session Responses') - expect(curateContent).to.include('printed Web UI URL') + expect(curateContent).to.include('http://localhost:') + expect(curateContent).to.include('default `http://localhost:7700`') + 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 ') - expect(curateContent).not.to.include('http://localhost:7700') + expect(curateContent).not.to.include('printed Web UI URL') }) it('should create sibling guides with When-To and Common Mistakes sections', async () => { From 74e0095a2db12a464f944585d570b7cf51a473e0 Mon Sep 17 00:00:00 2001 From: Dat Pham Date: Mon, 1 Jun 2026 15:34:32 +0700 Subject: [PATCH 4/4] [feat]: ENG-2697 use printed webui URL in skill guidance Update ByteRover skill docs to avoid hardcoded localhost:7700 links now that brv webui resolves the active port. - point post-curate and onboarding guidance to the URL printed by brv webui - document brv webui --port for port conflicts or custom ports - add skill connector regression coverage to reject fixed Web UI localhost URLs --- src/server/templates/skill/SKILL.md | 4 ++-- src/server/templates/skill/curate.md | 12 ++++++------ src/server/templates/skill/onboarding.md | 6 +++--- .../connectors/skill/skill-connector.test.ts | 17 ++++++++++------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/server/templates/skill/SKILL.md b/src/server/templates/skill/SKILL.md index 7848c328f..73c809838 100644 --- a/src/server/templates/skill/SKILL.md +++ b/src/server/templates/skill/SKILL.md @@ -120,7 +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 | `http://localhost:` | `curate.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` | @@ -174,7 +174,7 @@ Each detail file lives in this skill directory. Read the relevant one before inv - `brv swarm ` — cross-source memory federation. See `swarm.md`. - `brv vc ` — git-style version control of the context tree. See `vc.md`. - `brv dream ` — three-phase context-tree cleanup (link / merge / prune / synthesize). See `dream.md`. -- `brv webui [--port ]` — open or reconfigure the ByteRover dashboard when needed. For routine curate and onboarding closeouts, share the served Web UI link directly: `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. See `curate.md`. +- `brv webui [--port ]` — 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. See `curate.md`. - `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. diff --git a/src/server/templates/skill/curate.md b/src/server/templates/skill/curate.md index a8e2f5646..c0ef577b3 100644 --- a/src/server/templates/skill/curate.md +++ b/src/server/templates/skill/curate.md @@ -28,8 +28,8 @@ 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 served Web UI link: http://localhost: -# default http://localhost:7700 unless a custom Web UI port is already serving +# 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 ``` @@ -47,7 +47,7 @@ Curate runs as request -> response -> request: brv curate --session --response "" --format json ``` 4. Branch on `data.status`: - - `done` - report `data.filePath`, then give the user the served Web UI link, such as `http://localhost:`, so they can see the saved topic in the Contexts page. Use default `http://localhost:7700` unless a custom port is already serving. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port ` only when the user asks to open/change the dashboard port or the current port has a conflict. + - `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 ` 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. @@ -109,7 +109,7 @@ Every `--format json` response is wrapped in `{ "command", "data", "success", "t } ``` -→ Only now is the topic saved. Report `data.filePath` and hand the user the served Web UI link, such as `http://localhost:`, so they can open the Contexts page and see it. Use default `http://localhost:7700` unless a custom port is already serving. If that link does not open, tell the user they can run `brv webui` to open the dashboard; use `brv webui --port ` only when the user asks to open/change the dashboard port or the current port has a conflict. +→ 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. ## HTML Topic Contract @@ -193,7 +193,7 @@ Then tell the user what needs review. On `data.status: "done"`, the topic is written to `.brv/context-tree/`. To let the user actually see it, point them at the dashboard: -- Give the user the served Web UI link, such as `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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. +- 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. ## Common Mistakes @@ -204,4 +204,4 @@ On `data.status: "done"`, the topic is written to `.brv/context-tree/` | | 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 served Web UI link, such as `http://localhost:` | +| 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` | diff --git a/src/server/templates/skill/onboarding.md b/src/server/templates/skill/onboarding.md index 058a4a771..6491e1e38 100644 --- a/src/server/templates/skill/onboarding.md +++ b/src/server/templates/skill/onboarding.md @@ -100,7 +100,7 @@ Saved: Lives at .brv/context-tree/ — local-only. -See it in your browser: http://localhost: — or run brv webui if that link doesn't open. +See it in your browser: http://localhost:7700 — or run brv webui if that link doesn't open. Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -127,7 +127,7 @@ model, your reliability stance, and the context you just shared. You stop re-explaining. You start where you left off. Lives at .brv/context-tree/ — local-only. -See it in your browser: http://localhost: +See it in your browser: http://localhost:7700 Also version-controlled, cloud-syncable, and shareable across agents — more at the end. ``` @@ -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. -Use the served Web UI link, such as `http://localhost:`; default `http://localhost:7700` unless a custom port is already serving. 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 ` only when the user asks to open/change the dashboard port or the current port has a conflict. +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 ` 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. diff --git a/test/unit/infra/connectors/skill/skill-connector.test.ts b/test/unit/infra/connectors/skill/skill-connector.test.ts index 35f8bc8c0..c052c01c6 100644 --- a/test/unit/infra/connectors/skill/skill-connector.test.ts +++ b/test/unit/infra/connectors/skill/skill-connector.test.ts @@ -158,10 +158,11 @@ describe('SkillConnector', () => { 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:') - expect(content).to.include('default `http://localhost:7700`') + 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 ') + expect(content).not.to.include('http://localhost:') expect(content).not.to.include('printed Web UI URL') expect(content).to.include('## When To Use') expect(content).to.include('## Quick Reference') @@ -187,7 +188,7 @@ describe('SkillConnector', () => { expect(swarmContent).to.include('parallel') }) - it('should guide installed skill docs to share the served Web UI link with command fallback', async () => { + 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) @@ -199,12 +200,13 @@ describe('SkillConnector', () => { for (const content of contents) { expect(content).not.to.include('printed Web UI URL') + expect(content).not.to.include('http://localhost:') expect(content).not.to.include('run `brv webui` after every successful curate') } const onboardingContent = await readFile(path.join(skillDir, 'onboarding.md'), 'utf8') - expect(onboardingContent).to.include('http://localhost:') - expect(onboardingContent).to.include('default `http://localhost:7700`') + 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 ') }) @@ -224,10 +226,11 @@ describe('SkillConnector', () => { expect(curateContent).to.include('bv-rule') expect(curateContent).to.include('--overwrite') expect(curateContent).to.include('## Example Session Responses') - expect(curateContent).to.include('http://localhost:') - expect(curateContent).to.include('default `http://localhost:7700`') + 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 ') + expect(curateContent).not.to.include('http://localhost:') expect(curateContent).not.to.include('printed Web UI URL') })