From ce6b5b3d425c48ddc967f6fbfa0bd5381df3f04c Mon Sep 17 00:00:00 2001 From: Erik van der Boom Date: Tue, 7 Apr 2026 23:26:25 +0200 Subject: [PATCH] feat: add 'read_in' skill and update related documentation --- .github/copilot-instructions.md | 32 ++---------- mcp-ts/src/aisetup.ts | 7 +-- mcp-ts/src/index.ts | 4 +- mcp-ts/src/templates.ts | 86 ++++++++++++++++++++++++++++----- mcpb/README.md | 12 +++-- vscode-ext/CLAUDE.md | 2 +- vscode-ext/README.md | 4 +- vscode-ext/package.json | 6 +-- vscode-ext/src/ai-setup.ts | 7 +-- vscode-ext/src/extension.ts | 41 ++++++++-------- 10 files changed, 122 insertions(+), 79 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 83fdf14..8e9f4a1 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -44,7 +44,7 @@ annotations: { destructiveHint: true } // writes, creates, or modifies files ``` No annotation = mcpb submission rejection. Both annotations on one tool = also wrong. -| Tool behaviour | Annotation | +| Tool behavior | Annotation | |---|---| | list, get, read, search, status checks | `readOnlyHint: true` | | write, append, overwrite, format, commit, create | `destructiveHint: true` | @@ -68,33 +68,7 @@ When adding a tool, touch **all four** of these: missing any breaks one surface. ## MCP tools reference -All tools take a `book` argument (string name from `--book` config). The VS Code surface has no `book` arg — it uses the open workspace root. - -| Tool | Annotation | Description | -|---|---|---| -| `list_books` | readOnly | List configured books | -| `identify_book` | readOnly | Match a working directory to a book | -| `health` | readOnly | Server/index/embedding status | -| `init_workspace` | destructive | Create or update .bindery/settings.json + translations.json | -| `index_build` | destructive | Build/rebuild BM25 search index | -| `index_status` | readOnly | Index chunk count and build time | -| `get_text` | readOnly | Read file by relative path, optional line range | -| `get_chapter` | readOnly | Full chapter by number + language | -| `get_overview` | readOnly | Chapter structure (acts, chapters, titles) | -| `get_notes` | readOnly | Notes/ and Details_*.md, filterable | -| `search` | readOnly | BM25 full-text search with ranked snippets | -| `retrieve_context` | readOnly | Semantic passage retrieval | -| `format` | destructive | Apply typography formatting to file/folder | -| `get_review_text` | destructive | Git diff with optional autoStage | -| `git_snapshot` | destructive | Git commit of story/notes/arc changes | -| `get_translation` | readOnly | List glossary entries for a language, or look up a specific term (forgiving) | -| `add_translation` | destructive | Add/update a cross-language glossary entry (agent reference, not auto-applied at export) | -| `get_dialect` | readOnly | List dialect substitution rules, or look up a specific word | -| `add_dialect` | destructive | Add/update a dialect substitution rule (auto-applied at export, e.g. US→UK) | -| `add_language` | destructive | Add language to settings.json and scaffold story folder with stubs | -| `memory_list` | readOnly | List Notes/Memories/ files with line counts | -| `memory_append` | destructive | Append dated session entry to a memory file | -| `memory_compact` | destructive | Overwrite memory file with summary (backs up original) | +see `mcp-ts/src/index.ts` for implementation details and input schemas and `mcpb/readme.md` for user-facing descriptions. --- @@ -137,7 +111,7 @@ All tools take a `book` argument (string name from `--book` config). The VS Code | `cursor` | `.cursor/rules` | | `agents` | `AGENTS.md` | -Skills: `review`, `brainstorm`, `memory`, `translate`, `status`, `continuity`, `read_aloud`. +Skills: `review`, `brainstorm`, `memory`, `translate`, `status`, `continuity`, `read_aloud`, `read-in`. The **memory skill** uses `memory_list` → `memory_append` → `memory_compact`. Do not fall back to `get_text` + Edit tool for memory writes. diff --git a/mcp-ts/src/aisetup.ts b/mcp-ts/src/aisetup.ts index 15a35cf..d5ab8b7 100644 --- a/mcp-ts/src/aisetup.ts +++ b/mcp-ts/src/aisetup.ts @@ -24,10 +24,11 @@ export type SkillTemplate = | 'translate' | 'status' | 'continuity' - | 'read_aloud'; + | 'read_aloud' + | 'read_in'; export const ALL_SKILLS: SkillTemplate[] = [ - 'review', 'brainstorm', 'memory', 'translate', 'status', 'continuity', 'read_aloud', + 'review', 'brainstorm', 'memory', 'translate', 'status', 'continuity', 'read_aloud', 'read_in', ]; export interface AiSetupOptions { @@ -47,7 +48,7 @@ export interface AiSetupResult { * existing users should regenerate their AI files. * Must be kept in sync with AI_SETUP_VERSION in vscode-ext/src/ai-setup.ts. */ -export const AI_SETUP_VERSION = 5; +export const AI_SETUP_VERSION = 6; // ─── Settings types ─────────────────────────────────────────────────────────── diff --git a/mcp-ts/src/index.ts b/mcp-ts/src/index.ts index 2aee1ae..9e8225b 100644 --- a/mcp-ts/src/index.ts +++ b/mcp-ts/src/index.ts @@ -379,7 +379,7 @@ server.registerTool('setup_ai_files', { inputSchema: { book: bookSchema, targets: z.array(z.string()).optional().describe('Which files to generate: claude, copilot, cursor, agents. Default: all.'), - skills: z.array(z.string()).optional().describe('Which Claude skills to generate: review, brainstorm, memory, translate, status, continuity, read_aloud. Default: all.'), + skills: z.array(z.string()).optional().describe('Which Claude skills to generate: review, brainstorm, memory, translate, status, continuity, read_aloud, read_in. Default: all.'), overwrite: z.boolean().optional().describe('Overwrite existing files? Default false (skip existing).'), }, annotations: { destructiveHint: true }, @@ -418,7 +418,7 @@ server.registerTool('memory_compact', { description: 'Overwrite a memory file with a compacted version supplied by the model. ' + 'The original is backed up to .bindery/memories/archive/ before overwriting. ' + - 'Use this when a memory file has grown too large and needs to be summarised.', + 'Use this when a memory file has grown too large and needs to be summarized.', inputSchema: { book: bookSchema, file: z.string().describe('Filename within .bindery/memories/, e.g. global.md'), diff --git a/mcp-ts/src/templates.ts b/mcp-ts/src/templates.ts index ed2af3b..e84a2a2 100644 --- a/mcp-ts/src/templates.ts +++ b/mcp-ts/src/templates.ts @@ -47,6 +47,7 @@ export function renderTemplate(name: string, ctx: TemplateContext): string { case 'status': return skillStatus(ctx); case 'continuity': return skillContinuity(ctx); case 'read_aloud': return skillReadAloud(ctx); + case 'read_in': return skillReadIn(ctx); default: return `Unknown template: ${name}`; } } @@ -79,18 +80,17 @@ function claudeMd(ctx: TemplateContext): string { lines.push( '## Start of session', - `1. Read COWORK.md (if present) for current focus and context.`, - `2. Read ${memoriesFolder}/global.md for cross-chapter decisions.`, - `3. If working on a specific chapter, read ${memoriesFolder}/chXX.md if it exists.`, + '1. Use /read-in at the start of a session to load context and get your bearings.', + '2. If the skill is not available, read at least COWORK.md (if present) for current focus and context.', '', '## Memory system', - '1. When the user ask or otherwise indicates the end of a session: use /memory to save decisions.', - `2. When switching to another chapter read ${memoriesFolder}/chXX.md if it exists. for that chapter`, + '1. When concluding a discussion, or after you give a meaningful (preserve worthy) response: use /memory to store it.', + '2. Also when the user ask or otherwise indicates the end of a session: use /memory to save decisions.', '', '## Repo layout', '```', - `${arcFolder}/ ← story arc files (Overall.md, Act_I_*.md, Act_II_*.md, Act_III_*.md)`, - `${notesFolder}/ ← story bible (characters, world)`, + `${arcFolder}/ ← story arc files`, + `${notesFolder}/ ← story notes (characters, world)`, `${storyFolder}/`, ...ctx.languages.map(l => ` ${l.folderName}/ ← ${l.code} chapters (one .md per chapter)`), '```', @@ -116,6 +116,7 @@ function claudeMd(ctx: TemplateContext): string { '| `/status` | Book progress snapshot |', '| `/continuity` | Check a chapter for consistency errors |', '| `/read-aloud` | Test how a passage reads when spoken |', + '| `/read-in` | Load context and get your bearings at the start of a session |', '', '## MCP server (bindery-mcp)', '', @@ -127,6 +128,8 @@ function claudeMd(ctx: TemplateContext): string { '| `list_books` | List all configured book names |', '| `identify_book` | Match a working directory to a book name |', '| `health` | Server status: settings, index, embedding backend |', + '| `init_workspace` | Create or update `.bindery/settings.json` and `translations.json` |', + '| `setup_ai_files` | Generate AI instruction files (CLAUDE.md, copilot-instructions.md, AGENTS.md) and skill templates |', '| `index_build` | Build or rebuild the full-text search index |', '| `index_status` | Show index chunk count and build time |', '| `get_text` | Read any file by relative path, with optional line range |', @@ -146,6 +149,8 @@ function claudeMd(ctx: TemplateContext): string { '| `memory_list` | List `Notes/Memories/` files with line counts |', '| `memory_append` | Append a dated session entry to a memory file |', '| `memory_compact` | Overwrite a memory file with a summary (backs up original) |', + '| `chapter_status_get` | Read the chapter progress tracker — entries grouped by status |', + '| `chapter_status_update` | Upsert chapter progress entries (send only changed chapters) |', ); return lines.filter(l => l !== '\n').join('\n') + '\n'; } @@ -172,7 +177,7 @@ function copilotMd(ctx: TemplateContext): string { '', '## Writing guidelines', '- HTML comments `` in chapter files are writer notes — treat as context only.', - '- Quotation marks and dashes are managed by the Bindery VS Code extension. Do not normalise them.', + '- Quotation marks and dashes are managed by the Bindery VS Code extension. Do not normalize them.', '- Check `Notes/Details_Translation_notes.md` before using or translating world-specific terms.', ); if (ctx.audience) { @@ -199,7 +204,7 @@ function cursorRules(ctx: TemplateContext): string { '', '## Rules', '- HTML comments `` in chapter files are writer notes. Treat as context, not story content.', - '- Do not normalise quotation marks or dashes — these are managed by the Bindery extension.', + '- Do not normalize quotation marks or dashes — these are managed by the Bindery extension.', '- Do not rewrite prose unless explicitly asked. Suggest edits only.', ]; if (ctx.audience) { @@ -224,9 +229,9 @@ function agentsMd(ctx: TemplateContext): string { `3. Check \`${notesFolder}/Details_Translation_notes.md\` before using or translating world-specific terms.`, '', '## Story files', - `- Chapter files are \`.md\` files in \`${storyFolder}/\`, organised in act subfolders.`, + `- Chapter files are \`.md\` files in \`${storyFolder}/\`, organized in act subfolders.`, '- HTML comments `` are writer notes — treat as context only, not prose.', - '- Quotation marks and em-dashes are managed by the Bindery extension. Do not normalise them.', + '- Quotation marks and em-dashes are managed by the Bindery extension. Do not normalize them.', '', '## Writing guidelines', '- Do not rewrite paragraphs unless explicitly asked. Suggest edits only.', @@ -396,14 +401,14 @@ Use \`memory_append\` to write to the right file: Arguments: - \`file\`: just the filename, e.g. \`global.md\` or \`ch10.md\` -- \`title\`: short topic label, e.g. \`"Daeven introduction — character decisions"\` +- \`title\`: short topic label, e.g. \`"Elder introduction — character decisions"\` - \`content\`: the decisions to record, one per line The tool stamps the current date. Do not add a date to the content. ### 4. Compact if needed If \`memory_list\` shows a file exceeding ~150 lines, offer to compact it: -- Summarise the existing content into a concise replacement +- Summarize the existing content into a concise replacement - Call \`memory_compact(file, compacted_content)\` — original is backed up automatically ### 5. Snapshot @@ -595,3 +600,58 @@ Brief overall impression (2-3 sentences) after the table. - Suggestions are gentle ("consider", not "must change") `; } + +function skillReadIn(ctx: TemplateContext): string { + const { memoriesFolder } = ctx; + return `--- +name: Read-in +description: Load project context at the start of a session — memory, progress tracker, and chapter notes. Use for /read-in, "get your bearings", "what were we doing", or at the start of any working session. +--- + +# Skill: /read-in + +Load context and get your bearings before starting work. + +## Trigger +User says \`/read-in\`, "get your bearings", "what were we working on", or at the start of a session. + +## Tools +Use these Bindery MCP tools: +- \`memory_list\` — discover which memory files exist (\`global.md\`, \`chXX.md\` files) +- \`get_text(identifier)\` — read COWORK.md and memory files +- \`chapter_status_get(book)\` — read the structured progress tracker +- \`get_overview(language)\` — list all acts and chapters (only if tracker is empty or sparse) + +## Steps + +### 1. Check for current focus +Use \`get_text("COWORK.md")\` to read the current focus file (ignore if missing). + +### 2. Load global memory +Use \`memory_list\` to discover available memory files, then \`get_text("${memoriesFolder}/global.md")\` to load cross-chapter decisions. + +### 3. Read the progress tracker +Use \`chapter_status_get\` to read current chapter progress. If it is empty or has fewer than 3 entries, also call \`get_overview\` for the full chapter listing. + +### 4. Determine working chapter +If COWORK.md names a chapter, use that. +Otherwise if the tracker has a single \`in-progress\` chapter, use that. +Otherwise — **ask the user**: "Which chapter do you want to work on?" + +### 5. Load chapter memory +Once the chapter is known (e.g. chapter 10), check \`memory_list\` output for a matching file (\`ch10.md\`). If it exists, read it with \`get_text("${memoriesFolder}/ch10.md")\`. + +### 6. Summarize +Output a short orientation (3-6 lines): +- Which chapter / scene we're in +- Status from the tracker (draft / in-progress / needs-review) +- Key open decisions from global memory relevant to this chapter +- Any chapter-specific notes from the chapter memory file +- End with a phrase like: "Ready — what would you like to work on?" + +## Rules +- Do not load *all* chapter memories — only the one being worked on +- Keep the summary brief; this is orientation, not a full status report +- Do not suggest work or ask multiple questions — one question at most (which chapter?) +`; +} diff --git a/mcpb/README.md b/mcpb/README.md index c386387..e09db16 100644 --- a/mcpb/README.md +++ b/mcpb/README.md @@ -10,7 +10,9 @@ Works with any Markdown book project structured with the Bindery VS Code extensi - **Full-text search** — BM25 ranked search across all story and notes files - **Context retrieval** — "where did X happen" queries with ranked passages - **Translation management** — list, look up, add, and update translation and dialect substitution rules -- **Session memory** — append, list, and compact persistent session notes in `Notes/Memories/` +- **Session memory** — append, list, and compact persistent cross session notes in `.bindery/Memories/` +- **Workspace setup** — create or update `.bindery/settings.json` and scaffold AI instruction files +- **Chapter status tracking** — record and query per-chapter progress (draft, in-progress, done, needs-review) - **Typography formatting** — curly quotes, em-dashes, ellipses - **Version snapshots** — git-based save points after writing sessions - **Review diffs** — structured git diff of uncommitted changes @@ -29,7 +31,7 @@ To install manually without using published Claude Connectors | Setting | Required | Description | |---------|----------|-------------| | Books | Yes | Semicolon-separated `Name=path` pairs pointing to book projects | -| Ollama URL | No | URL for local Ollama instance (enables semantic reranking) | +| Ollama URL | No | URL for Ollama instance (enables semantic reranking, see [https://docs.ollama.com/quickstart](https://docs.ollama.com/quickstart)) | **Books** example: `MyBook=C:\Users\Me\MyBook;MyNovel=D:\Writing\MyNovel` @@ -94,7 +96,7 @@ date formatting needed. > "The global memory file is getting long — please compact it" -Claude reads the current content, summarises it, then calls `memory_compact` +Claude reads the current content, summarizes it, then calls `memory_compact` with the compacted text. The original is automatically backed up to `Notes/Memories/archive/global_YYYY-MM-DD.md` before the file is overwritten. @@ -123,6 +125,8 @@ issue type, location, and the reference that contradicts it. | `list_books` | List all configured book names | | `identify_book` | Match a working directory to a book name | | `health` | Server status: settings, index, embedding backend | +| `init_workspace` | Create or update `.bindery/settings.json` and `translations.json` with smart defaults | +| `setup_ai_files` | Generate AI instruction files (CLAUDE.md, copilot-instructions.md, .cursor/rules, AGENTS.md) and Claude skill templates | | `index_build` | Build or rebuild the full-text search index | | `index_status` | Show index chunk count and build time | | `get_text` | Read any file by relative path, with optional line range | @@ -142,6 +146,8 @@ issue type, location, and the reference that contradicts it. | `memory_list` | List memory files with line counts | | `memory_append` | Append a dated session entry to a memory file | | `memory_compact` | Overwrite a memory file with a summary (backs up original) | +| `chapter_status_get` | Read the chapter progress tracker — returns entries grouped by status (done, in-progress, draft, planned, needs-review) | +| `chapter_status_update` | Upsert chapter progress entries — send only changed chapters; unmentioned entries are preserved | ## Privacy Policy diff --git a/vscode-ext/CLAUDE.md b/vscode-ext/CLAUDE.md index bcb88ef..6109eed 100644 --- a/vscode-ext/CLAUDE.md +++ b/vscode-ext/CLAUDE.md @@ -45,4 +45,4 @@ src/ ## When suggesting changes - Prefer editing the smallest surface area possible. - Check that all command IDs match the `bindery.*` namespace throughout `package.json` AND `extension.ts`. -- Test mentally: does the new behaviour respect the config priority order? +- Test mentally: does the new behavior respect the config priority order? diff --git a/vscode-ext/README.md b/vscode-ext/README.md index e4e4744..f6629bc 100644 --- a/vscode-ext/README.md +++ b/vscode-ext/README.md @@ -50,7 +50,7 @@ Supported commands: - `Bindery: Find Probable US→UK Words` - `Bindery: Add Substitution Rule` - `Bindery: Open translations.json` -- `Bindery: Initialise Workspace` +- `Bindery: Initialize Workspace` - `Bindery: Setup AI Assistant Files` - `Bindery: Register MCP Server` @@ -138,7 +138,7 @@ Add to `.bindery/settings.json` (or `bindery.languages` in VS Code settings): ## Requirements - **VS Code** 1.85+ -- **Git** (recommended) — needed for version tracking and review features (`get_review_text`, `git_snapshot`). Auto-initialised during workspace setup. [Install](https://git-scm.com) +- **Git** (recommended) — needed for version tracking and review features (`get_review_text`, `git_snapshot`). Auto-initialized during workspace setup. [Install](https://git-scm.com) - **Pandoc** (needed for DOCX/EPUB/PDF export) — [Install](https://pandoc.org/installing.html) - **LibreOffice** (needed for PDF export) — used to convert the intermediate DOCX to PDF - Linux/WSL: `sudo apt install libreoffice` diff --git a/vscode-ext/package.json b/vscode-ext/package.json index 9b1c2d2..d60b688 100644 --- a/vscode-ext/package.json +++ b/vscode-ext/package.json @@ -63,7 +63,7 @@ "bindery.storyFolder": { "type": "string", "default": "Story", - "description": "Fallback story folder name if .bindery/settings.json is not present. Run 'Bindery: Initialise Workspace' to create the settings file." + "description": "Fallback story folder name if .bindery/settings.json is not present. Run 'Bindery: Initialize Workspace' to create the settings file." }, "bindery.mergedOutputDir": { "type": "string", @@ -121,7 +121,7 @@ "commands": [ { "command": "bindery.init", - "title": "Initialise Workspace", + "title": "Initialize Workspace", "category": "Bindery" }, { @@ -414,7 +414,7 @@ "type": "object", "properties": { "targets": { "type": "array", "items": { "type": "string" }, "description": "Files to generate: claude, copilot, cursor, agents. Default: all." }, - "skills": { "type": "array", "items": { "type": "string" }, "description": "Claude skills to include: review, brainstorm, memory, translate, status, continuity, read_aloud. Default: all." }, + "skills": { "type": "array", "items": { "type": "string" }, "description": "Claude skills to include: review, brainstorm, memory, translate, status, continuity, read_aloud, read_in. Default: all." }, "overwrite": { "type": "boolean", "description": "Overwrite existing files? Default false." } } } diff --git a/vscode-ext/src/ai-setup.ts b/vscode-ext/src/ai-setup.ts index 958a86f..c06e70b 100644 --- a/vscode-ext/src/ai-setup.ts +++ b/vscode-ext/src/ai-setup.ts @@ -47,10 +47,11 @@ export type SkillTemplate = | 'translate' | 'status' | 'continuity' - | 'read_aloud'; + | 'read_aloud' + | 'read_in'; export const ALL_SKILLS: SkillTemplate[] = [ - 'review', 'brainstorm', 'memory', 'translate', 'status', 'continuity', 'read_aloud', + 'review', 'brainstorm', 'memory', 'translate', 'status', 'continuity', 'read_aloud', 'read_in', ]; /** @@ -58,7 +59,7 @@ export const ALL_SKILLS: SkillTemplate[] = [ * significantly enough that existing users should regenerate their AI files. * Written to .bindery/ai-version.json after each successful setupAiFiles() run. */ -export const AI_SETUP_VERSION = 5; +export const AI_SETUP_VERSION = 6; // ─── Entry point ────────────────────────────────────────────────────────────── diff --git a/vscode-ext/src/extension.ts b/vscode-ext/src/extension.ts index 70d7125..9f10959 100644 --- a/vscode-ext/src/extension.ts +++ b/vscode-ext/src/extension.ts @@ -98,7 +98,7 @@ function getEffectiveConfig(wsSettings: WorkspaceSettings | null): EffectiveConf /** True if filePath is inside //. */ function isInsideStoryFolder(filePath: string, root: string, storyFolder: string): boolean { - // Normalise separators so Windows paths compare correctly + // Normalize separators so Windows paths compare correctly const norm = (p: string) => p.replace(/\\/g, '/'); const story = norm(path.join(root, storyFolder)); const file = norm(filePath); @@ -231,7 +231,7 @@ async function initWorkspaceCommand() { if (fs.existsSync(settingsPath)) { const choice = await vscode.window.showQuickPick( [ - { label: 'Re-initialise', description: 'Overwrites settings.json (translations.json is kept)', value: true as const }, + { label: 'Re-initialize', description: 'Overwrites settings.json (translations.json is kept)', value: true as const }, { label: 'Cancel', value: false as const }, ], { placeHolder: '.bindery/settings.json already exists' } @@ -240,28 +240,28 @@ async function initWorkspaceCommand() { } const title = await vscode.window.showInputBox({ - title: 'Bindery: Initialise (1/4)', + title: 'Bindery: Initialize (1/4)', prompt: 'Book title', placeHolder: 'e.g. The Hollow Road', }); if (title === undefined) { return; } const author = await vscode.window.showInputBox({ - title: 'Bindery: Initialise (2/4)', + title: 'Bindery: Initialize (2/4)', prompt: 'Author name', placeHolder: 'e.g. Jane Smith', }); if (author === undefined) { return; } const storyFolder = await vscode.window.showInputBox({ - title: 'Bindery: Initialise (3/4)', + title: 'Bindery: Initialize (3/4)', prompt: 'Story folder name (relative to workspace root)', value: 'Story', }); if (!storyFolder) { return; } const audience = await vscode.window.showInputBox({ - title: 'Bindery: Initialise (4/5)', + title: 'Bindery: Initialize (4/5)', prompt: 'Target audience (used for AI review feedback)', placeHolder: 'e.g. 12+, adults, 8-10', }); @@ -272,7 +272,7 @@ async function initWorkspaceCommand() { { label: 'No', value: false as const }, { label: 'Yes', value: true as const }, ], - { title: 'Bindery: Initialise (5/5)', placeHolder: 'Auto-apply typography on save (Story folder only)?' } + { title: 'Bindery: Initialize (5/5)', placeHolder: 'Auto-apply typography on save (Story folder only)?' } ); if (!formatOption) { return; } @@ -334,7 +334,7 @@ async function initWorkspaceCommand() { execSync('git add .bindery/ .gitignore', { cwd: root, encoding: 'utf-8', stdio: 'pipe' }); execSync('git commit -m "Bindery: initial setup"', { cwd: root, encoding: 'utf-8', stdio: 'pipe' }); - gitNote = ' Git repository initialised.'; + gitNote = ' Git repository initialized.'; } catch { vscode.window.showWarningMessage( 'Git is recommended for version tracking and review features. ' + @@ -347,7 +347,7 @@ async function initWorkspaceCommand() { ? ` Detected: ${detectedLangs.map(l => l.code).join(', ')}.` : ''; const action = await vscode.window.showInformationMessage( - `Bindery workspace initialised.${langNote}${gitNote}`, + `Bindery workspace initialized.${langNote}${gitNote}`, 'Open settings.json', 'Open translations.json' ); @@ -439,7 +439,7 @@ async function addDialectCommand() { } sourceLang ??= getDefaultLanguage(wsSettings); - if (!sourceLang) { vscode.window.showErrorMessage('No language configured. Run Bindery: Initialise Workspace first.'); return; } + if (!sourceLang) { vscode.window.showErrorMessage('No language configured. Run Bindery: Initialize Workspace first.'); return; } const dialects = getDialectsForLanguage(wsSettings, sourceLang.code); if (dialects.length === 0) { @@ -515,7 +515,7 @@ async function addTranslationCommand() { l => !l.isDefault && (l.code !== sourceLang?.code) ); - if (!sourceLang) { vscode.window.showErrorMessage('No default language configured. Run Bindery: Initialise Workspace first.'); return; } + if (!sourceLang) { vscode.window.showErrorMessage('No default language configured. Run Bindery: Initialize Workspace first.'); return; } if (targetLangs.length === 0) { vscode.window.showErrorMessage('No target languages configured. Use Bindery: Add Language to add one.'); return; @@ -807,13 +807,14 @@ const AI_TARGET_ITEMS: Array<{ label: string; detail: string; value: AiTarget }> ]; const SKILL_ITEMS: Array<{ label: string; description: string; value: SkillTemplate }> = [ - { label: '/review', description: 'Chapter review — language, arc, age-appropriateness', value: 'review' }, - { label: '/brainstorm', description: 'Generate plot / character / scene ideas', value: 'brainstorm' }, - { label: '/memory', description: 'Update memory files and compact if needed', value: 'memory' }, - { label: '/translate', description: 'Assisted chapter translation', value: 'translate' }, - { label: '/status', description: 'Book progress snapshot', value: 'status' }, - { label: '/continuity', description: 'Cross-check chapter for consistency errors', value: 'continuity' }, - { label: '/read-aloud', description: 'Reading-aloud test for a chapter or passage', value: 'read_aloud' }, + { label: '/review', description: 'Chapter review — language, arc, age-appropriateness', value: 'review' }, + { label: '/brainstorm', description: 'Generate plot / character / scene ideas', value: 'brainstorm' }, + { label: '/memory', description: 'Update memory files and compact if needed', value: 'memory' }, + { label: '/translate', description: 'Assisted chapter translation', value: 'translate' }, + { label: '/status', description: 'Book progress snapshot', value: 'status' }, + { label: '/continuity', description: 'Cross-check chapter for consistency errors', value: 'continuity' }, + { label: '/read-aloud', description: 'Reading-aloud test for a chapter or passage', value: 'read_aloud' }, + { label: '/read-in', description: 'Load context and get your bearings at the start of a session', value: 'read_in' }, ]; async function setupAiCommand() { @@ -823,8 +824,8 @@ async function setupAiCommand() { const wsSettings = readWorkspaceSettings(root); if (!wsSettings) { const init = await vscode.window.showWarningMessage( - 'No .bindery/settings.json found. Run "Bindery: Initialise Workspace" first.', - 'Initialise now' + 'No .bindery/settings.json found. Run "Bindery: Initialize Workspace" first.', + 'Initialize now' ); if (init) { await initWorkspaceCommand(); } return;