diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a824367..f1974879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 2026-08-30 + +### Changes + +- Doc Collector: a `docs collect` run streamed with `--ws` now sends the spec index it generates as a + `docs` frame — the file path and the full markdown of `docs/index.md` — so a listening UI can show + the finished documentation the same way an exploration run streams its session report. +- Doc Collector: a streamed run now closes the connection on its way out instead of exiting from + under it, so the final `result` frame arrives and anything still queued is flushed. Previously the + index frame, written moments before exit, was the one most likely to be lost. + ## 2026-08-29 ### Changes diff --git a/boat/doc-collector/src/cli.ts b/boat/doc-collector/src/cli.ts index 50e53db9..b7f6d92d 100644 --- a/boat/doc-collector/src/cli.ts +++ b/boat/doc-collector/src/cli.ts @@ -2,6 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { Command } from 'commander'; import { ConfigCommand } from '../../../src/commands/config-command.ts'; +import { remote } from '../../../src/remote.ts'; import { isVerboseMode, setPreserveConsoleLogs, setQuietMode } from '../../../src/utils/logger.ts'; import { DocBot, type DocbotOptions } from './docbot.ts'; @@ -59,9 +60,11 @@ export function createDocsCommands(name = 'docs'): Command { console.log(`Use in Explorbot: npx explorbot start ${startPath} --spec "${result.outputDir}"`); await bot.stop(); + await remote.close(0); process.exit(0); } catch (error) { console.error('Failed:', error instanceof Error ? error.message : 'Unknown error'); + await remote.close(1); process.exit(1); } }); diff --git a/boat/doc-collector/src/docbot.ts b/boat/doc-collector/src/docbot.ts index e394cc4a..f48f880e 100644 --- a/boat/doc-collector/src/docbot.ts +++ b/boat/doc-collector/src/docbot.ts @@ -465,7 +465,9 @@ class DocBot { private saveIndex(startPath: string, pages: DocumentedPage[], skipped: SkippedPage[], maxPages: number): { indexPath: string; diagramPath: string } { const outputDir = this.configParser.getOutputDir(); const indexPath = path.join(outputDir, 'index.md'); - writeFileSync(indexPath, renderSpecIndex(outputDir, startPath, pages, skipped, maxPages), 'utf8'); + const index = renderSpecIndex(outputDir, startPath, pages, skipped, maxPages); + writeFileSync(indexPath, index, 'utf8'); + tag('data').log('docs', { path: indexPath, content: index }); const diagramPath = path.join(outputDir, 'state-diagram.mmd'); writeFileSync(diagramPath, renderMermaidBody(outputDir, pages), 'utf8'); return { indexPath, diagramPath }; diff --git a/docs/reference/websocket.md b/docs/reference/websocket.md index 0473550e..66a5ad10 100644 --- a/docs/reference/websocket.md +++ b/docs/reference/websocket.md @@ -19,6 +19,7 @@ Every message is JSON with a `type` and a `ts`, plus whatever that type carries. | `screenshot` | the screenshot file just written | | `research` | the researcher's map of a page: markdown and its file | | `report` | the analyst's end-of-session report: markdown and its file | +| `docs` | the doc collector's spec index: markdown and its file | | `activity` | what the run is doing this second | | `log` | a log line and its level | | `ask` | a question for a human, carrying an `askId` |