evdboom_Bindery/vscode-ext/package.json
copilot-swe-agent[bot] fd84376a1f
Fix security vulnerabilities in mcp-ts and vscode-ext lockfiles
- mcp-ts: Update vite 8.0.9→8.1.4 (fixes server.fs.deny bypass CVE)
- mcp-ts: Update hono 4.12.14→4.12.30 (fixes CORS origin reflection CVE)
- vscode-ext: Update vite 8.0.10→8.1.4 (fixes server.fs.deny bypass CVE)
- vscode-ext: Update esbuild 0.28.0→0.28.1 (fixes withdrawn RCE advisory)
- Add overrides in mcp-ts/package.json to enforce hono>=4.12.25, vite>=8.0.16
- Add overrides in vscode-ext/package.json to enforce vite>=8.0.16
- Regenerate both standalone lockfiles with secure package versions
2026-07-16 04:34:22 +00:00

1642 lines
54 KiB
JSON

{
"name": "bindery",
"displayName": "Bindery",
"description": "Markdown book authoring tools: typography formatting (curly quotes, em-dashes, ellipses), multi-language chapter export (DOCX, EPUB, PDF), and dialect conversion.",
"version": "0.0.0",
"publisher": "option-a",
"repository": {
"type": "git",
"url": "https://github.com/evdboom/bindery"
},
"engines": {
"vscode": "^1.116.0"
},
"categories": [
"Formatters",
"Other"
],
"keywords": [
"markdown",
"book",
"writing",
"author",
"typography",
"epub",
"docx",
"merge",
"export",
"dialect"
],
"activationEvents": [
"onStartupFinished",
"onLanguage:markdown"
],
"main": "./out/extension.js",
"icon": "icon.png",
"contributes": {
"configuration": {
"title": "Bindery",
"properties": {
"bindery.pandocPath": {
"type": "string",
"default": "pandoc",
"description": "Path to the pandoc executable. Leave as 'pandoc' to auto-detect (PATH + well-known install locations, including %LOCALAPPDATA%\\Pandoc\\pandoc.exe and %ProgramFiles%\\Pandoc\\pandoc.exe on Windows). Override only if you have a non-standard install. Install from https://pandoc.org"
},
"bindery.libreOfficePath": {
"type": "string",
"default": "libreoffice",
"description": "Path to the LibreOffice executable for PDF export. Leave as 'libreoffice' to auto-detect (PATH + well-known install locations, including %ProgramFiles%\\LibreOffice\\program\\soffice.exe on Windows and /Applications/LibreOffice.app/Contents/MacOS/soffice on macOS). Override only if you have a non-standard install."
},
"bindery.generalSubstitutions": {
"type": "array",
"default": [],
"description": "Dialect substitution rules applied across all projects (e.g. US→UK spelling). Applied after the built-in rules but before project-specific rules in .bindery/translations.json. Store in user settings so they follow you to every workspace.",
"items": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"from": {
"type": "string",
"description": "Source word (e.g. US English)"
},
"to": {
"type": "string",
"description": "Target word (e.g. UK English)"
}
}
}
},
"bindery.storyFolder": {
"type": "string",
"default": "Story",
"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",
"default": "Merged",
"description": "Fallback output directory for merged files (relative to workspace root). Prefer .bindery/settings.json."
},
"bindery.mergeFilePrefix": {
"type": "string",
"default": "Book",
"description": "Fallback prefix for merged output filenames, e.g. 'Book' → Book_EN_Merged.md. Prefer .bindery/settings.json."
},
"bindery.author": {
"type": "string",
"default": "",
"description": "Fallback author name for EPUB/DOCX metadata. Prefer .bindery/settings.json."
},
"bindery.bookTitle": {
"type": "string",
"default": "",
"description": "Fallback book title for EPUB/DOCX metadata. Prefer .bindery/settings.json, which also supports per-language titles."
},
"bindery.formatOnSave": {
"type": "boolean",
"default": false,
"description": "Fallback: auto-apply typography formatting when saving markdown files inside the story folder. Prefer .bindery/settings.json."
},
"bindery.languages": {
"type": "array",
"default": [
{
"code": "EN",
"folderName": "EN",
"chapterWord": "Chapter",
"actPrefix": "Act",
"prologueLabel": "Prologue",
"epilogueLabel": "Epilogue"
}
],
"description": "Fallback language configurations for merge/export. Prefer .bindery/settings.json.",
"items": {
"type": "object",
"required": [
"code",
"folderName",
"chapterWord",
"actPrefix",
"prologueLabel",
"epilogueLabel"
],
"properties": {
"code": {
"type": "string"
},
"folderName": {
"type": "string"
},
"chapterWord": {
"type": "string"
},
"actPrefix": {
"type": "string"
},
"prologueLabel": {
"type": "string"
},
"epilogueLabel": {
"type": "string"
}
}
}
}
}
},
"commands": [
{
"command": "bindery.init",
"title": "Initialize Workspace",
"category": "Bindery"
},
{
"command": "bindery.setupAI",
"title": "Setup AI Assistant Files",
"category": "Bindery"
},
{
"command": "bindery.quickActions",
"title": "Quick Actions",
"category": "Bindery"
},
{
"command": "bindery.formatDocument",
"title": "Format Typography",
"category": "Bindery"
},
{
"command": "bindery.formatFolder",
"title": "Format All Markdown in Folder",
"category": "Bindery"
},
{
"command": "bindery.mergeMarkdown",
"title": "Merge Chapters → Markdown",
"category": "Bindery"
},
{
"command": "bindery.mergeDocx",
"title": "Merge Chapters → DOCX",
"category": "Bindery"
},
{
"command": "bindery.mergeEpub",
"title": "Merge Chapters → EPUB",
"category": "Bindery"
},
{
"command": "bindery.mergePdf",
"title": "Merge Chapters → PDF",
"category": "Bindery"
},
{
"command": "bindery.mergeAll",
"title": "Merge Chapters → All Formats",
"category": "Bindery"
},
{
"command": "bindery.findProbableUsToUkWords",
"title": "Find Probable US→UK Words",
"category": "Bindery"
},
{
"command": "bindery.addDialect",
"title": "Add Dialect Rule",
"category": "Bindery"
},
{
"command": "bindery.addTranslation",
"title": "Add Translation (Glossary)",
"category": "Bindery"
},
{
"command": "bindery.addLanguage",
"title": "Add Language",
"category": "Bindery"
},
{
"command": "bindery.addUkReplacement",
"title": "Add Dialect Rule (UK alias)",
"category": "Bindery"
},
{
"command": "bindery.openTranslations",
"title": "Open translations.json",
"category": "Bindery"
},
{
"command": "bindery.startReviewMarker",
"title": "Insert Review Start Marker (or wrap selection)",
"category": "Bindery"
},
{
"command": "bindery.stopReviewMarker",
"title": "Insert Review Stop Marker",
"category": "Bindery"
},
{
"command": "bindery.noteList",
"title": "List Notes",
"category": "Bindery"
},
{
"command": "bindery.noteGet",
"title": "Open Note Tool Output",
"category": "Bindery"
},
{
"command": "bindery.noteCreate",
"title": "Create Note",
"category": "Bindery"
},
{
"command": "bindery.noteAppend",
"title": "Append to Note",
"category": "Bindery"
},
{
"command": "bindery.characterList",
"title": "List Characters",
"category": "Bindery"
},
{
"command": "bindery.characterGet",
"title": "Open Character Tool Output",
"category": "Bindery"
},
{
"command": "bindery.characterCreate",
"title": "Create Character Profile",
"category": "Bindery"
},
{
"command": "bindery.characterUpdate",
"title": "Update Character Profile",
"category": "Bindery"
},
{
"command": "bindery.arcList",
"title": "List Arcs",
"category": "Bindery"
},
{
"command": "bindery.arcGet",
"title": "Open Arc Tool Output",
"category": "Bindery"
},
{
"command": "bindery.arcCreate",
"title": "Create Arc File",
"category": "Bindery"
},
{
"command": "bindery.arcUpdate",
"title": "Update Arc File",
"category": "Bindery"
},
{
"command": "bindery.memoryList",
"title": "List Memories",
"category": "Bindery"
},
{
"command": "bindery.memoryAppend",
"title": "Append Memory",
"category": "Bindery"
},
{
"command": "bindery.memoryCompact",
"title": "Compact Memory",
"category": "Bindery"
},
{
"command": "bindery.chapterStatusGet",
"title": "Show Chapter Status",
"category": "Bindery"
},
{
"command": "bindery.chapterStatusUpdate",
"title": "Update Chapter Status",
"category": "Bindery"
},
{
"command": "bindery.sessionFocusShow",
"title": "Show Session Focus",
"category": "Bindery"
},
{
"command": "bindery.sessionFocusUpdate",
"title": "Update Session Focus",
"category": "Bindery"
},
{
"command": "bindery.sessionFocusAppendHandoff",
"title": "Append Handoff Note",
"category": "Bindery"
},
{
"command": "bindery.inboxProcess",
"title": "Process Inbox",
"category": "Bindery"
},
{
"command": "bindery.inboxResolve",
"title": "Resolve Inbox Items",
"category": "Bindery"
},
{
"command": "bindery.registerMcp",
"title": "Register MCP Server",
"category": "Bindery"
}
],
"keybindings": [
{
"command": "bindery.formatDocument",
"key": "ctrl+k ctrl+b",
"mac": "cmd+k cmd+b",
"when": "editorTextFocus && resourceLangId == markdown"
},
{
"command": "bindery.startReviewMarker",
"key": "ctrl+k ctrl+,",
"mac": "cmd+k cmd+,",
"when": "editorTextFocus && resourceLangId == markdown"
},
{
"command": "bindery.stopReviewMarker",
"key": "ctrl+k ctrl+.",
"mac": "cmd+k cmd+.",
"when": "editorTextFocus && resourceLangId == markdown"
}
],
"languageModelTools": [
{
"name": "bindery_health",
"tags": [
"bindery"
],
"displayName": "Bindery: Health",
"toolReferenceName": "binderyHealth",
"canBeReferencedInPrompt": true,
"modelDescription": "Check Bindery workspace status: settings, index, embedding backend.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_index_build",
"tags": [
"bindery"
],
"displayName": "Bindery: Build Index",
"toolReferenceName": "binderyIndexBuild",
"canBeReferencedInPrompt": true,
"modelDescription": "Build or rebuild the lexical search index and, when enabled, the semantic embedding index for the book workspace.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_index_status",
"tags": [
"bindery"
],
"displayName": "Bindery: Index Status",
"toolReferenceName": "binderyIndexStatus",
"canBeReferencedInPrompt": true,
"modelDescription": "Show lexical and semantic index metadata, including stale-status hints.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_get_text",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Text",
"toolReferenceName": "binderyGetText",
"canBeReferencedInPrompt": true,
"modelDescription": "Read a source file by relative path, optionally restricted to a line range.",
"inputSchema": {
"type": "object",
"properties": {
"identifier": {
"type": "string",
"description": "Relative path from workspace root"
},
"startLine": {
"type": "number"
},
"endLine": {
"type": "number"
}
},
"required": [
"identifier"
]
}
},
{
"name": "bindery_get_chapter",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Chapter",
"toolReferenceName": "binderyGetChapter",
"canBeReferencedInPrompt": true,
"modelDescription": "Fetch the full content of a chapter by number and language code (e.g. EN or NL).",
"inputSchema": {
"type": "object",
"properties": {
"chapterNumber": {
"type": "number"
},
"language": {
"type": "string"
}
},
"required": [
"chapterNumber",
"language"
]
}
},
{
"name": "bindery_get_book_until",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Book Until",
"toolReferenceName": "binderyGetBookUntil",
"canBeReferencedInPrompt": true,
"modelDescription": "Fetch chapters from a start chapter through a target chapter (inclusive), concatenated in reading order.",
"inputSchema": {
"type": "object",
"properties": {
"chapterNumber": {
"type": "number",
"description": "Final chapter number (inclusive, 1-based)"
},
"language": {
"type": "string",
"description": "Language code, e.g. EN or NL"
},
"startChapter": {
"type": "number",
"description": "Starting chapter number (default 1)"
}
},
"required": [
"chapterNumber",
"language"
]
}
},
{
"name": "bindery_get_overview",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Overview",
"toolReferenceName": "binderyGetOverview",
"canBeReferencedInPrompt": true,
"modelDescription": "List the chapter structure (acts, chapters, titles) for one or all languages.",
"inputSchema": {
"type": "object",
"properties": {
"language": {
"type": "string",
"description": "Language code or ALL"
},
"act": {
"type": "number",
"description": "Act number 1, 2 or 3"
}
}
}
},
{
"name": "bindery_get_notes",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Notes",
"toolReferenceName": "binderyGetNotes",
"canBeReferencedInPrompt": true,
"modelDescription": "Read from Notes/, optionally filtered by category or character name.",
"inputSchema": {
"type": "object",
"properties": {
"category": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
},
{
"name": "bindery_note_list",
"tags": [
"bindery"
],
"displayName": "Bindery: Note List",
"toolReferenceName": "binderyNoteList",
"canBeReferencedInPrompt": true,
"modelDescription": "List markdown note files under the configured notes folder, optionally filtered to a category folder.",
"inputSchema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "Optional category/folder under Notes, e.g. Characters, World, Scenes, Research"
}
}
}
},
{
"name": "bindery_note_get",
"tags": [
"bindery"
],
"displayName": "Bindery: Note Get",
"toolReferenceName": "binderyNoteGet",
"canBeReferencedInPrompt": true,
"modelDescription": "Read a single markdown note by path relative to the configured notes folder.",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Note path relative to the notes folder, e.g. Inbox.md or Characters/index.md"
}
},
"required": ["path"]
}
},
{
"name": "bindery_note_create",
"tags": [
"bindery"
],
"displayName": "Bindery: Note Create",
"toolReferenceName": "binderyNoteCreate",
"canBeReferencedInPrompt": true,
"modelDescription": "Create a markdown note under the configured notes folder. Refuses to overwrite unless overwrite is true.",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Note path relative to the notes folder, e.g. World/Rules.md"
},
"title": {
"type": "string",
"description": "Optional H1 title. Defaults to a title derived from the filename."
},
"content": {
"type": "string",
"description": "Optional markdown body to write below the H1 title."
},
"overwrite": {
"type": "boolean",
"description": "Replace an existing note if true. Default false."
}
},
"required": ["path"]
}
},
{
"name": "bindery_note_append",
"tags": [
"bindery"
],
"displayName": "Bindery: Note Append",
"toolReferenceName": "binderyNoteAppend",
"canBeReferencedInPrompt": true,
"modelDescription": "Append markdown content to a note under the configured notes folder, creating the file if needed.",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Note path relative to the notes folder, e.g. Inbox.md or World/Rules.md"
},
"content": {
"type": "string",
"description": "Markdown content to append."
},
"heading": {
"type": "string",
"description": "Optional H2 heading to insert before the appended content."
}
},
"required": ["path", "content"]
}
},
{
"name": "bindery_character_list",
"tags": [
"bindery"
],
"displayName": "Bindery: Character List",
"toolReferenceName": "binderyCharacterList",
"canBeReferencedInPrompt": true,
"modelDescription": "List structured character profile files under the configured characters folder.",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Optional character-name filter."
}
}
}
},
{
"name": "bindery_character_get",
"tags": [
"bindery"
],
"displayName": "Bindery: Character Get",
"toolReferenceName": "binderyCharacterGet",
"canBeReferencedInPrompt": true,
"modelDescription": "Read a structured character profile by character name.",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Character name. The tool resolves the matching slugged profile file."
}
},
"required": ["name"]
}
},
{
"name": "bindery_character_create",
"tags": [
"bindery"
],
"displayName": "Bindery: Character Create",
"toolReferenceName": "binderyCharacterCreate",
"canBeReferencedInPrompt": true,
"modelDescription": "Create a structured character profile and update Notes/Characters/index.md.",
"inputSchema": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Character name. Used for the profile H1 and slugged filename." },
"role": { "type": "string" },
"age": { "type": "string" },
"origin": { "type": "string" },
"skills": { "type": "string" },
"strengths": { "type": "string" },
"weaknesses": { "type": "string" },
"personality": { "type": "string" },
"background": { "type": "string" },
"narrativeArc": { "type": "string" },
"appearanceNotes": { "type": "string" },
"relationships": { "type": "string" },
"firstAppearance": { "type": "string" },
"openQuestions": { "type": "string" },
"continuityNotes": { "type": "string" },
"indexNotes": { "type": "string" },
"overwrite": { "type": "boolean", "description": "Replace an existing profile if true. Default false." }
},
"required": ["name"]
}
},
{
"name": "bindery_character_update",
"tags": [
"bindery"
],
"displayName": "Bindery: Character Update",
"toolReferenceName": "binderyCharacterUpdate",
"canBeReferencedInPrompt": true,
"modelDescription": "Update known fields in a structured character profile and refresh the character index row.",
"inputSchema": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Character name. The tool resolves the matching slugged profile file." },
"role": { "type": "string" },
"age": { "type": "string" },
"origin": { "type": "string" },
"skills": { "type": "string" },
"strengths": { "type": "string" },
"weaknesses": { "type": "string" },
"personality": { "type": "string" },
"background": { "type": "string" },
"narrativeArc": { "type": "string" },
"appearanceNotes": { "type": "string" },
"relationships": { "type": "string" },
"firstAppearance": { "type": "string" },
"openQuestions": { "type": "string" },
"continuityNotes": { "type": "string" },
"indexNotes": { "type": "string" }
},
"required": ["name"]
}
},
{
"name": "bindery_arc_list",
"tags": [
"bindery"
],
"displayName": "Bindery: Arc List",
"toolReferenceName": "binderyArcList",
"canBeReferencedInPrompt": true,
"modelDescription": "List structured arc files under the configured arc folder.",
"inputSchema": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"description": "Optional kind filter, e.g. overall, act, chapter, thread, custom."
}
}
}
},
{
"name": "bindery_arc_get",
"tags": [
"bindery"
],
"displayName": "Bindery: Arc Get",
"toolReferenceName": "binderyArcGet",
"canBeReferencedInPrompt": true,
"modelDescription": "Read a structured arc file by path relative to the configured arc folder.",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Arc path relative to the arc folder, e.g. Overall.md or Acts/act-i.md."
}
},
"required": ["path"]
}
},
{
"name": "bindery_arc_create",
"tags": [
"bindery"
],
"displayName": "Bindery: Arc Create",
"toolReferenceName": "binderyArcCreate",
"canBeReferencedInPrompt": true,
"modelDescription": "Create a structured arc file under the configured arc folder and update Arc/index.md.",
"inputSchema": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "Arc path relative to the arc folder, e.g. Acts/act-i.md." },
"title": { "type": "string" },
"kind": { "type": "string" },
"purpose": { "type": "string" },
"majorBeats": { "type": "string" },
"characterMovement": { "type": "string" },
"worldImplications": { "type": "string" },
"unresolvedQuestions": { "type": "string" },
"continuityRisks": { "type": "string" },
"linkedChapters": { "type": "string" },
"overwrite": { "type": "boolean", "description": "Replace an existing arc file if true. Default false." }
},
"required": ["path"]
}
},
{
"name": "bindery_arc_update",
"tags": [
"bindery"
],
"displayName": "Bindery: Arc Update",
"toolReferenceName": "binderyArcUpdate",
"canBeReferencedInPrompt": true,
"modelDescription": "Update known fields in a structured arc file and refresh Arc/index.md.",
"inputSchema": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "Arc path relative to the arc folder, e.g. Acts/act-i.md." },
"title": { "type": "string" },
"kind": { "type": "string" },
"purpose": { "type": "string" },
"majorBeats": { "type": "string" },
"characterMovement": { "type": "string" },
"worldImplications": { "type": "string" },
"unresolvedQuestions": { "type": "string" },
"continuityRisks": { "type": "string" },
"linkedChapters": { "type": "string" }
},
"required": ["path"]
}
},
{
"name": "bindery_search",
"tags": [
"bindery"
],
"displayName": "Bindery: Search",
"toolReferenceName": "binderySearch",
"canBeReferencedInPrompt": true,
"modelDescription": "Search in lexical, semantic-rerank, or full-semantic mode. Semantic modes fall back to lexical results with warnings if prerequisites are unavailable.",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string"
},
"language": {
"type": "string"
},
"maxResults": {
"type": "number"
},
"mode": {
"type": "string",
"enum": [
"lexical",
"semantic_rerank",
"full_semantic"
]
}
},
"required": [
"query"
]
}
},
{
"name": "bindery_format",
"tags": [
"bindery"
],
"displayName": "Bindery: Format",
"toolReferenceName": "binderyFormat",
"canBeReferencedInPrompt": true,
"modelDescription": "Apply typography formatting (curly quotes, em-dashes, ellipses) to a file or folder.",
"inputSchema": {
"type": "object",
"properties": {
"filePath": {
"type": "string"
},
"dryRun": {
"type": "boolean"
},
"noRecurse": {
"type": "boolean"
}
}
}
},
{
"name": "bindery_get_review_text",
"tags": [
"bindery"
],
"displayName": "Bindery: Review Text",
"toolReferenceName": "binderyGetReviewText",
"canBeReferencedInPrompt": true,
"modelDescription": "Structured git diff of uncommitted changes with context lines. Filter by language (EN, NL, ALL). Set autoStage to true to stage reviewed files so the next call only shows new changes.",
"inputSchema": {
"type": "object",
"properties": {
"language": {
"type": "string",
"description": "Language filter: EN, NL, or ALL (default ALL)"
},
"contextLines": {
"type": "number",
"description": "Context lines around each change (default 3)"
},
"autoStage": {
"type": "boolean",
"description": "Stage reviewed files after producing diff (default false)"
}
}
}
},
{
"name": "bindery_update_workspace",
"tags": [
"bindery"
],
"displayName": "Bindery: Update Workspace",
"toolReferenceName": "binderyUpdateWorkspace",
"canBeReferencedInPrompt": true,
"modelDescription": "Fetch and pull the current git branch, report the current branch versus the remote default branch, and optionally switch branches before pulling.",
"inputSchema": {
"type": "object",
"properties": {
"remote": {
"type": "string",
"description": "Preferred remote name to fetch from and pull against (default: origin or first remote)"
},
"branch": {
"type": "string",
"description": "Optional branch name to switch to before pulling"
},
"switchBranch": {
"type": "boolean",
"description": "Allow the tool to switch to the requested branch before pulling (default false)"
},
"autoStash": {
"type": "boolean",
"description": "Temporarily stash local changes before pull when needed (default true)"
}
}
}
},
{
"name": "bindery_git_snapshot",
"tags": [
"bindery"
],
"displayName": "Bindery: Git Snapshot",
"toolReferenceName": "binderyGitSnapshot",
"canBeReferencedInPrompt": true,
"modelDescription": "Save a snapshot (git commit) of all changes in the bindery workspace, with optional push and saved push defaults.",
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Snapshot message (default: timestamp)"
},
"push": {
"type": "boolean",
"description": "Push the new commit after saving the snapshot (default: use stored setting or false)"
},
"remote": {
"type": "string",
"description": "Remote name to push to (default: stored setting, origin, or first remote)"
},
"branch": {
"type": "string",
"description": "Branch to push (default: stored setting or current branch)"
},
"rememberPushDefaults": {
"type": "boolean",
"description": "Persist the push preference, remote, and branch under .bindery/settings.json"
}
}
}
},
{
"name": "bindery_add_translation",
"tags": [
"bindery"
],
"displayName": "Bindery: Add Translation",
"toolReferenceName": "binderyAddTranslation",
"canBeReferencedInPrompt": true,
"modelDescription": "Add or update a substitution rule in .bindery/translations.json. Used for dialect conversion (e.g. US→UK spelling).",
"inputSchema": {
"type": "object",
"properties": {
"langKey": {
"type": "string",
"description": "Language key in translations.json, e.g. 'en-gb' or 'nl'"
},
"from": {
"type": "string",
"description": "Source word or phrase"
},
"to": {
"type": "string",
"description": "Target word or phrase"
}
},
"required": [
"langKey",
"from",
"to"
]
}
},
{
"name": "bindery_get_translation",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Translation",
"toolReferenceName": "binderyGetTranslation",
"canBeReferencedInPrompt": true,
"modelDescription": "Look up translation/substitution rules in .bindery/translations.json. Without a word, lists all rules for the language. With a word, does a forgiving case-insensitive lookup including plural and inflected forms.",
"inputSchema": {
"type": "object",
"properties": {
"language": {
"type": "string",
"description": "Language key, label, or code (e.g. 'nl', 'en-gb', 'British English')"
},
"word": {
"type": "string",
"description": "Word or term to look up (omit to list all rules for the language)"
}
},
"required": [
"language"
]
}
},
{
"name": "bindery_setup_ai_files",
"tags": [
"bindery"
],
"displayName": "Bindery: Setup AI Files",
"toolReferenceName": "binderySetupAiFiles",
"canBeReferencedInPrompt": true,
"modelDescription": "Generate AI assistant instruction files (CLAUDE.md, copilot-instructions.md, .cursor/rules, AGENTS.md), Claude skill templates, and the generated .bindery/README.md capability reference from .bindery/settings.json. Run init_workspace first. Skips existing files unless overwrite is true.",
"inputSchema": {
"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, translation-review, status, continuity, read-aloud, read-in, proof-read, plan-beats, character-setup. Default: all."
},
"overwrite": {
"type": "boolean",
"description": "Overwrite existing files? Default false."
}
}
}
},
{
"name": "bindery_settings_update",
"tags": [
"bindery"
],
"displayName": "Bindery: Settings Update",
"toolReferenceName": "binderySettingsUpdate",
"canBeReferencedInPrompt": true,
"modelDescription": "Merge a partial patch into .bindery/settings.json without replacing unrelated keys.",
"inputSchema": {
"type": "object",
"properties": {
"patch": {
"type": "object",
"description": "Partial settings object to deep-merge into .bindery/settings.json"
}
},
"required": [
"patch"
]
}
},
{
"name": "bindery_init_workspace",
"tags": [
"bindery"
],
"displayName": "Bindery: Init Workspace",
"toolReferenceName": "binderyInitWorkspace",
"canBeReferencedInPrompt": true,
"modelDescription": "Create or update .bindery/settings.json, translations.json, .bindery/README.md, and the opinionated Arc, Notes, Characters, SESSION, PREFERENCES, memory, and chapter-status scaffold. All arguments optional — smart defaults used for any omitted values. Detects language folders automatically. Safe to run on an existing workspace.",
"inputSchema": {
"type": "object",
"properties": {
"bookTitle": {
"type": "string",
"description": "Book title (defaults to folder name)"
},
"author": {
"type": "string"
},
"storyFolder": {
"type": "string",
"description": "Story folder name relative to root (default: Story)"
},
"genre": {
"type": "string"
},
"description": {
"type": "string",
"description": "One-line description for AI instruction files"
},
"targetAudience": {
"type": "string",
"description": "Target audience, e.g. 12+ or adults"
}
}
}
},
{
"name": "bindery_add_dialect",
"tags": [
"bindery"
],
"displayName": "Bindery: Add Dialect Rule",
"toolReferenceName": "binderyAddDialect",
"canBeReferencedInPrompt": true,
"modelDescription": "Add or update a dialect substitution rule in .bindery/translations.json (e.g. EN→en-gb spelling). Source is auto-detected from the active file's language folder.",
"inputSchema": {
"type": "object",
"properties": {
"dialectCode": {
"type": "string",
"description": "Dialect key in translations.json, e.g. 'en-gb'"
},
"from": {
"type": "string",
"description": "Source word (e.g. 'airplane')"
},
"to": {
"type": "string",
"description": "Dialect form (e.g. 'aeroplane')"
}
},
"required": [
"dialectCode",
"from",
"to"
]
}
},
{
"name": "bindery_get_dialect",
"tags": [
"bindery"
],
"displayName": "Bindery: Get Dialect Rules",
"toolReferenceName": "binderyGetDialect",
"canBeReferencedInPrompt": true,
"modelDescription": "List or look up dialect substitution rules from .bindery/translations.json. Without a word, lists all rules for the dialect. With a word, does a forgiving case-insensitive lookup including inflected forms.",
"inputSchema": {
"type": "object",
"properties": {
"dialectCode": {
"type": "string",
"description": "Dialect key, e.g. 'en-gb'"
},
"word": {
"type": "string",
"description": "Word to look up (optional)"
}
},
"required": [
"dialectCode"
]
}
},
{
"name": "bindery_add_language",
"tags": [
"bindery"
],
"displayName": "Bindery: Add Language",
"toolReferenceName": "binderyAddLanguage",
"canBeReferencedInPrompt": true,
"modelDescription": "Add a new main language to settings.json and create its folder structure under Story/ with stub .md files mirroring the default language. Use for manually translated editions (e.g. French, Spanish).",
"inputSchema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Language code (e.g. FR, DE, NL)"
},
"folderName": {
"type": "string",
"description": "Folder name under Story/ (default: same as code)"
},
"chapterWord": {
"type": "string",
"description": "Word for 'Chapter' in target language"
},
"actPrefix": {
"type": "string",
"description": "Word for 'Act' in target language"
},
"prologueLabel": {
"type": "string",
"description": "Word for 'Prologue'"
},
"epilogueLabel": {
"type": "string",
"description": "Word for 'Epilogue'"
},
"createStubs": {
"type": "boolean",
"description": "Create stub .md files mirroring source (default true)"
}
},
"required": [
"code"
]
}
},
{
"name": "bindery_memory_list",
"tags": [
"bindery"
],
"displayName": "Bindery: Memory List",
"toolReferenceName": "binderyMemoryList",
"canBeReferencedInPrompt": true,
"modelDescription": "List all session memory files in .bindery/memories/ with their line counts.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_memory_append",
"tags": [
"bindery"
],
"displayName": "Bindery: Memory Append",
"toolReferenceName": "binderyMemoryAppend",
"canBeReferencedInPrompt": true,
"modelDescription": "Append a dated session entry to a memory file in .bindery/memories/. The tool stamps the date; supply a short title and content.",
"inputSchema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "Filename within .bindery/memories/, e.g. global.md or ch10.md"
},
"title": {
"type": "string",
"description": "Short session title describing the topic"
},
"content": {
"type": "string",
"description": "Text to record under this session entry"
}
},
"required": [
"file",
"title",
"content"
]
}
},
{
"name": "bindery_memory_compact",
"tags": [
"bindery"
],
"displayName": "Bindery: Memory Compact",
"toolReferenceName": "binderyMemoryCompact",
"canBeReferencedInPrompt": true,
"modelDescription": "Overwrite a memory file with a compacted summary. The original is backed up to .bindery/memories/archive/ first.",
"inputSchema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "Filename within .bindery/memories/, e.g. global.md"
},
"compacted_content": {
"type": "string",
"description": "Full replacement content (model-supplied summary)"
}
},
"required": [
"file",
"compacted_content"
]
}
},
{
"name": "bindery_chapter_status_get",
"tags": [
"bindery"
],
"displayName": "Bindery: Chapter Status",
"toolReferenceName": "binderyChapterStatusGet",
"canBeReferencedInPrompt": true,
"modelDescription": "Read the current chapter progress tracker from .bindery/chapter-status.json. Returns a grouped summary (done, in-progress, draft, planned, needs-review). Returns a clear empty-state message if no status has been recorded yet.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_chapter_status_update",
"tags": [
"bindery"
],
"displayName": "Bindery: Chapter Status Update",
"toolReferenceName": "binderyChapterStatusUpdate",
"canBeReferencedInPrompt": true,
"modelDescription": "Upsert chapter progress entries in .bindery/chapter-status.json. Send only the chapters that changed — existing entries are preserved. status must be one of: done, in-progress, draft, planned, needs-review.",
"inputSchema": {
"type": "object",
"properties": {
"chapters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "number",
"description": "Chapter number"
},
"title": {
"type": "string",
"description": "Chapter title"
},
"language": {
"type": "string",
"description": "Language code, e.g. EN or NL"
},
"status": {
"type": "string",
"enum": [
"done",
"in-progress",
"draft",
"planned",
"needs-review"
]
},
"wordCount": {
"type": "number",
"description": "Approximate word count"
},
"notes": {
"type": "string",
"description": "Short agent note about this chapter"
}
},
"required": [
"number",
"title",
"language",
"status"
]
}
}
},
"required": [
"chapters"
]
}
},
{
"name": "bindery_session_focus_get",
"tags": [
"bindery"
],
"displayName": "Bindery: Session Focus",
"toolReferenceName": "binderySessionFocusGet",
"canBeReferencedInPrompt": true,
"modelDescription": "Read the ephemeral session file (default SESSION.md) holding current working state. Optionally pass a section name (Current Focus, Next Actions, Open Questions, Handoff Notes) to read just that section. Durable preferences live in PREFERENCES.md and durable decisions in .bindery/memories/. Returns a clear empty-state message if the session file does not exist yet.",
"inputSchema": {
"type": "object",
"properties": {
"section": {
"type": "string",
"description": "Optional section name to read, e.g. \"Current Focus\" or \"Handoff Notes\""
}
}
}
},
{
"name": "bindery_session_focus_update",
"tags": [
"bindery"
],
"displayName": "Bindery: Session Focus Update",
"toolReferenceName": "binderySessionFocusUpdate",
"canBeReferencedInPrompt": true,
"modelDescription": "Update neutral sections of the ephemeral session file (default SESSION.md): Current Focus, Next Actions, Open Questions, Handoff Notes. Only the sections you pass change; other content and the user-owned PREFERENCES.md are preserved. mode 'replace' (default) overwrites a section body; 'append' adds beneath existing content. Creates the file from the standard scaffold if missing. Use for current working state, not durable preferences or memory.",
"inputSchema": {
"type": "object",
"properties": {
"currentFocus": {
"type": "string",
"description": "New content for the Current Focus section"
},
"nextActions": {
"type": "string",
"description": "New content for the Next Actions section"
},
"openQuestions": {
"type": "string",
"description": "New content for the Open Questions section"
},
"handoffNotes": {
"type": "string",
"description": "New content for the Handoff Notes section"
},
"mode": {
"type": "string",
"enum": [
"replace",
"append"
],
"description": "replace (default) or append section body"
}
}
}
},
{
"name": "bindery_inbox_process",
"tags": [
"bindery"
],
"displayName": "Bindery: Process Inbox",
"toolReferenceName": "binderyInboxProcess",
"canBeReferencedInPrompt": true,
"modelDescription": "Read the notes Inbox (Notes/Inbox.md) and return a structured triage proposal: each loose item enumerated with a stable number, plus the destination tools to route them (note_*, character_*, arc_*, memory_*, chapter_status_*, session_focus_*). Read-only — never moves, deletes, or categorizes. After the user confirms and items are routed, call inbox_resolve with the item numbers to clear them.",
"inputSchema": {
"type": "object",
"properties": {}
}
},
{
"name": "bindery_inbox_resolve",
"tags": [
"bindery"
],
"displayName": "Bindery: Resolve Inbox Items",
"toolReferenceName": "binderyInboxResolve",
"canBeReferencedInPrompt": true,
"modelDescription": "Remove already-routed items from the notes Inbox (Notes/Inbox.md) by their item numbers, as enumerated by inbox_process. Use only after the items have been routed and the user has confirmed. Item numbers are stable between inbox_process and inbox_resolve; other items and the inbox heading/intro are preserved.",
"inputSchema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "number"
},
"description": "Item numbers to remove, as shown by inbox_process (1-based)"
}
},
"required": [
"items"
]
}
}
],
"menus": {
"editor/context": [
{
"submenu": "bindery.contextMenu",
"when": "resourceLangId == markdown",
"group": "1_modification@10"
}
],
"explorer/context": [
{
"submenu": "bindery.contextMenu",
"when": "resourceLangId == markdown || explorerResourceIsFolder",
"group": "7_modification@10"
}
],
"editor/title": [
{
"command": "bindery.quickActions",
"when": "resourceLangId == markdown",
"group": "navigation@95"
},
{
"submenu": "bindery.exportMenu",
"when": "resourceLangId == markdown",
"group": "navigation@100"
}
],
"bindery.contextMenu": [
{
"command": "bindery.formatDocument",
"when": "resourceLangId == markdown",
"group": "1_format@1"
},
{
"command": "bindery.formatFolder",
"when": "explorerResourceIsFolder",
"group": "1_format@2"
},
{
"command": "bindery.findProbableUsToUkWords",
"when": "resourceLangId == markdown",
"group": "2_dialect@1"
},
{
"command": "bindery.addDialect",
"when": "resourceLangId == markdown",
"group": "2_dialect@2"
},
{
"command": "bindery.addTranslation",
"when": "resourceLangId == markdown",
"group": "2_dialect@3"
},
{
"command": "bindery.startReviewMarker",
"when": "resourceLangId == markdown",
"group": "2_review@1"
},
{
"command": "bindery.stopReviewMarker",
"when": "resourceLangId == markdown",
"group": "2_review@2"
},
{
"command": "bindery.mergeMarkdown",
"group": "3_export@1"
},
{
"command": "bindery.mergeDocx",
"group": "3_export@2"
},
{
"command": "bindery.mergeEpub",
"group": "3_export@3"
},
{
"command": "bindery.mergePdf",
"group": "3_export@4"
},
{
"command": "bindery.mergeAll",
"group": "3_export@5"
}
],
"bindery.exportMenu": [
{
"command": "bindery.mergeMarkdown",
"group": "1_merge@1"
},
{
"command": "bindery.mergeDocx",
"group": "1_merge@2"
},
{
"command": "bindery.mergeEpub",
"group": "1_merge@3"
},
{
"command": "bindery.mergePdf",
"group": "1_merge@4"
},
{
"command": "bindery.mergeAll",
"group": "2_all@1"
}
]
},
"submenus": [
{
"id": "bindery.contextMenu",
"label": "Bindery",
"icon": "$(book)"
},
{
"id": "bindery.exportMenu",
"label": "Bindery Export",
"icon": "$(book)"
}
]
},
"scripts": {
"vscode:prepublish": "npm run build:core && npm run build:mcp && npm run typecheck && npm run bundle",
"compile": "tsc -p ./",
"typecheck": "tsc --noEmit -p ./",
"bundle": "node ./esbuild.mjs",
"watch": "tsc -watch -p ./",
"lint": "eslint src --ext ts",
"build:core": "cd ../bindery-core && npm run build",
"build:mcp": "cd ../mcp-ts && npm run compile",
"test": "vitest run",
"test:watch": "vitest",
"test:ci": "vitest run --reporter=verbose --reporter=json --outputFile=test-results.json",
"test:coverage": "vitest run --coverage"
},
"devDependencies": {
"@bindery/core": "*",
"@bindery/merge": "*",
"@types/node": "^25.6.0",
"@types/vscode": "1.116.0",
"@vitest/coverage-v8": "^4.1.5",
"esbuild": "^0.28.1",
"typescript": "6.0.3",
"vitest": "^4.1.5"
},
"overrides": {
"vite": ">=8.0.16"
}
}