mirror of
https://github.com/evdboom/Bindery.git
synced 2026-07-22 06:49:36 +00:00
- Updated manifest.json to clarify translation and dialect commands. - Modified CLAUDE.md to reflect new dialect and translation functionalities. - Expanded package.json to include new commands for adding dialects and languages. - Implemented addDialect and addTranslation commands in extension.ts for better user experience. - Refactored merge.ts to support dialect exports and cleanup of temporary folders. - Introduced new workspace functions for managing dialects and glossary entries. - Enhanced MCP tools to handle dialect and language additions. - Updated workspace settings to accommodate new language and dialect structures.
557 lines
23 KiB
JSON
557 lines
23 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.85.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. Machine-specific — set in user settings, not workspace settings. Install from https://pandoc.org"
|
|
},
|
|
"bindery.libreOfficePath": {
|
|
"type": "string",
|
|
"default": "libreoffice",
|
|
"description": "Path to the LibreOffice executable for PDF export. Machine-specific — set in user settings. On Windows use the full path to soffice.exe, e.g. C:\\Program Files\\LibreOffice\\program\\soffice.exe"
|
|
},
|
|
"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: Initialise 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": "Initialise Workspace",
|
|
"category": "Bindery"
|
|
},
|
|
{
|
|
"command": "bindery.setupAI",
|
|
"title": "Setup AI Assistant Files",
|
|
"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.registerMcp",
|
|
"title": "Register MCP Server",
|
|
"category": "Bindery"
|
|
}
|
|
],
|
|
"languageModelTools": [
|
|
{
|
|
"name": "bindery_health",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Health",
|
|
"modelDescription": "Check Bindery workspace status: settings, index, embedding backend.",
|
|
"inputSchema": { "type": "object", "properties": {} }
|
|
},
|
|
{
|
|
"name": "bindery_index_build",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Build Index",
|
|
"modelDescription": "Build or rebuild the full-text search index for the book workspace.",
|
|
"inputSchema": { "type": "object", "properties": {} }
|
|
},
|
|
{
|
|
"name": "bindery_index_status",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Index Status",
|
|
"modelDescription": "Show current index metadata: chunk count and build time.",
|
|
"inputSchema": { "type": "object", "properties": {} }
|
|
},
|
|
{
|
|
"name": "bindery_get_text",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Get Text",
|
|
"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",
|
|
"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_overview",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Get Overview",
|
|
"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",
|
|
"modelDescription": "Read from Notes/ and Details_*.md, optionally filtered by category or character name.",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"category": { "type": "string" },
|
|
"name": { "type": "string" }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "bindery_search",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Search",
|
|
"modelDescription": "Full-text BM25 search across all story and notes files. Returns ranked snippets with file path and line numbers.",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": { "type": "string" },
|
|
"language": { "type": "string" },
|
|
"maxResults": { "type": "number" }
|
|
},
|
|
"required": ["query"]
|
|
}
|
|
},
|
|
{
|
|
"name": "bindery_retrieve_context",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Retrieve Context",
|
|
"modelDescription": "Retrieve the most relevant passages for a query. Best for 'where did X happen' or 'what did character Y say about Z'.",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": { "type": "string" },
|
|
"language": { "type": "string" },
|
|
"topK": { "type": "number" }
|
|
},
|
|
"required": ["query"]
|
|
}
|
|
},
|
|
{
|
|
"name": "bindery_format",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Format",
|
|
"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",
|
|
"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_git_snapshot",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Git Snapshot",
|
|
"modelDescription": "Save a snapshot (git commit) of all changes in story, notes, and arc folders. Use after writing sessions or successful reviews.",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": { "type": "string", "description": "Snapshot message (default: timestamp)" }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "bindery_add_translation",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Add Translation",
|
|
"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",
|
|
"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",
|
|
"modelDescription": "Generate AI assistant instruction files (CLAUDE.md, copilot-instructions.md, .cursor/rules, AGENTS.md) and Claude skill templates 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, status, continuity, read_aloud. Default: all." },
|
|
"overwrite": { "type": "boolean", "description": "Overwrite existing files? Default false." }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "bindery_init_workspace",
|
|
"tags": ["bindery"],
|
|
"displayName": "Bindery: Init Workspace",
|
|
"modelDescription": "Create or update .bindery/settings.json and translations.json. 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",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"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"]
|
|
}
|
|
}
|
|
],
|
|
"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": [
|
|
{
|
|
"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.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:mcp && npm run compile",
|
|
"compile": "tsc -p ./",
|
|
"watch": "tsc -watch -p ./",
|
|
"lint": "eslint src --ext ts",
|
|
"build:mcp": "cd ../mcp-ts && npm ci && npm run compile"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^20.0.0",
|
|
"@types/vscode": "^1.85.0",
|
|
"typescript": "^5.3.0"
|
|
}
|
|
}
|