diff --git a/novel/.opencode/command/init.md b/novel/.opencode/command/init.md index bd182c5..5987554 100644 --- a/novel/.opencode/command/init.md +++ b/novel/.opencode/command/init.md @@ -6,15 +6,18 @@ description: "Initialize a new novel project — interactive scaffolding wizard" Initializes a new novel/series project with the OpenNovelWriter structure. -## Concept: workspace = book +## Concept: one vault, one folder per book -One book (or series) = one **workspace** = one vault folder. The user first -creates and names a vault (e.g. "Die Kessler Zwillinge") in Obsidian, then opens -that folder as a workspace in opencode, and runs `/init` THERE. +All books live as folders inside one container vault (e.g. "Novels"). A book folder +**is** the workspace: the author creates the folder, opens it as the opencode +workspace, and runs `/init` THERE. `/init` scaffolds **into the current directory** — it does NOT create a nested -subfolder. The vault's own name is the project name. The "series title" question -below is for metadata (and may differ from the folder name), not for creating a folder. +subfolder. The folder's name is the project name; the "series title" question below +is metadata (and may differ from the folder name). + +The agent pack (`.opencode/`) is **shared and inherited** from the vault root. +Never create a copy inside a book folder. ## Workflow @@ -27,6 +30,11 @@ The current directory IS the book's workspace. Confirm the folder name with the author (it is the project/series name). Do NOT create a subfolder — scaffold directly into the current directory. +Then confirm the **shared pack is reachable**: an `.opencode/` directory must exist +in an ancestor directory (the container vault root). opencode finds it by walking +up. If there is none, STOP and tell the author to set up the shared pack — never +seed a local `.opencode/` in the book folder. + ### Step 1: Ask the writing language (always first) > "Which language will you write in? (e.g. Deutsch, English, Português)" @@ -61,11 +69,8 @@ Scaffold **into the current directory** (the workspace/vault the author already created and named): ``` -. (the workspace/vault, named by the author) -├── .opencode/ -│ ├── agent/ (OpenNovelAgent + subagents, copied from the tool) -│ ├── command/ (init, chapter, translate) -│ └── opencode.json +. (the book folder inside the container vault) +├── AGENTS.md (this book's metadata; from the template) ├── 01/ (one per book, numbered; title optional, renamed later) │ ├── DE/ (one folder per publication language, ISO code) │ ├── EN/ @@ -78,10 +83,11 @@ created and named): │ ├── timeline.yaml.md │ ├── glossary.yaml.md │ └── style.md -├── AGENTS.md -└── README.md +├── README.md ``` +`.opencode/` is deliberately **absent** here — the pack is shared at the vault root. + - **Book folders:** numbers only (`01`, `02`). Titles are added later by renaming. - **Language folders:** ISO codes only (`DE`, `EN`, `PT`). - **Images:** each book gets `images/prompts/` and `images/generated/`. @@ -165,5 +171,6 @@ as chapters are written. - Book/language folders ALWAYS as number resp. ISO code — never force a title. - YAML keys English, values in the canonical language (see SCHEMA §4). - No chapter files during init — they are created when writing. -- Copy the agent/command files from the tool repo (`.opencode/`) so the new - project runs standalone. +- NEVER copy the agent/command files into the book folder. The pack is shared and + inherited from the vault root; a local `.opencode/` forks the agents and drifts + out of date. diff --git a/novel/PACK-NOTES.md b/novel/PACK-NOTES.md index bc4a3df..0447cb9 100644 --- a/novel/PACK-NOTES.md +++ b/novel/PACK-NOTES.md @@ -56,6 +56,36 @@ The three vaults are not redundant copies of one thing — they have distinct ro - `AGENTS.md` in the Scruffy vault is a *filled-in instance* (real series title/author/genre), not the template — the placeholder version is committed as `templates/AGENTS.md`; instances stay in their vault. - `opencode.json` is committed pristine (`$schema` + `default_agent`). The permission block added to the Kessler vault (external_directory allow for `/Users/Shared/Novels/**`) is machine-local and deliberately **not** in the pack. +## Layout this pack is built for + +One container vault, one folder per book, **one** `.opencode` shared at the vault root: + +``` +/Users/Shared/Vaults/Novels/ # the vault (human interface: Obsidian) +├── .opencode -> /Users/Shared/NovelPack/.opencode # this pack, symlinked +├── docs -> /Users/Shared/NovelPack/docs # this SCHEMA +├── AGENTS.md # house rules +├── Scruffy/ # a book = a workspace +└── Kessler/ # another book +``` + +opencode walks up from the book folder to find `.opencode`, so books carry no copies. +(`/Users/Shared/NovelPack` exists because opencode writes `node_modules/` and a +`package.json` next to the agents it loads — pointing that at a plain pack directory +keeps both the vault and this repo clean.) + +## Headless operation + +The pack runs headless: `bash` is allowed by default in `OpenNovelAgent` and +`Importer` (it was `"ask"`, which opencode cannot prompt for in `opencode run`, so +every tool call was auto-rejected). Safety now comes from **explicit denies** of +irreversible commands — `rm -rf *`, `rm -rf /*`, `sudo *`, `mkfs*`, `diskutil *`, +`shutdown *`, `reboot*` — plus the existing `.env`/`.key`/`.secret`/`.git` edit denies. +`--dangerously-skip-permissions` is therefore no longer needed. + +The other eight agents keep `bash: "deny"` on purpose: they are note-editing +subagents that use opencode's file tools and never need a shell. + ## Sync direction The repo is the source of truth **for the pack**. Vaults pull pack-managed files from here: diff --git a/novel/docs/SCHEMA.md b/novel/docs/SCHEMA.md index 488a49a..62178ab 100644 --- a/novel/docs/SCHEMA.md +++ b/novel/docs/SCHEMA.md @@ -8,48 +8,47 @@ ## 1. Project Structure -**Concept: workspace = book.** One book (or series) = one folder = one workspace -= one Obsidian vault. The author creates and names the vault first (e.g. -"Die Kessler Zwillinge"), then runs `/init` *inside* it. The vault's own name is -the project name; `/init` scaffolds into it directly (no nested subfolder). - -The project directory is organized like a Git repository: +**Concept: one container vault, one folder per book.** A single Obsidian vault +(e.g. "Novels") holds every book. Each book is a subfolder and *is* the workspace +you open opencode in. The agent pack lives **once**, at the vault root, and is +inherited by every book — a book never carries its own `.opencode/`. The canonical +`docs/SCHEMA.md` likewise exists once, at the vault root. ``` -[Series Title]/ # the workspace/vault (named by the author) -├── .opencode/ # agent configuration (local, via /init) -│ ├── agent/ -│ ├── command/ -│ └── opencode.json -├── 01/ # Book 1 (folder = number, title optional) -│ ├── DE/ # language folder (ISO-639-1 code) -│ │ ├── Kapitel 001.md -│ │ ├── Kapitel 002.md -│ │ └── ... -│ ├── EN/ -│ │ ├── Chapter 001.md -│ │ └── ... -│ └── images/ # illustrations for this book -│ ├── prompts/ # image prompts (Markdown, one per image) -│ └── generated/ # generated image files -├── 02/ # Book 2 -├── DATA/ -│ ├── wiki.yaml.md # world wiki (canonical) -│ ├── timeline.yaml.md # timeline (lore history + plot) -│ ├── glossary.yaml.md # translation glossary -│ └── style.md # the author's writing style -├── AGENTS.md # project rules (read by the agent) -└── README.md # human overview +Novels/ # the container vault (Obsidian) +├── .opencode -> /Users/Shared/NovelPack/.opencode # ONE shared agent pack +├── docs/ -> /Users/Shared/NovelPack/docs # canonical SCHEMA.md +├── AGENTS.md # house rules that apply to every book +├── Scruffy/ # a BOOK = a workspace +│ ├── AGENTS.md # this book's metadata and rules +│ ├── DATA/ # this book's world +│ │ ├── wiki.yaml.md # world wiki (canonical) +│ │ ├── timeline.yaml.md # timeline (lore history + plot) +│ │ ├── glossary.yaml.md # translation glossary +│ │ └── style.md # the author's writing style +│ ├── 01/ # Book 1 (folder = number, title optional) +│ │ ├── DE/ # language folder (ISO-639-1 code) +│ │ │ ├── Kapitel 001.md +│ │ │ └── ... +│ │ ├── EN/ +│ │ │ ├── Chapter 001.md +│ │ │ └── ... +│ │ └── images/ # illustrations for this book +│ │ ├── prompts/ # image prompts (Markdown, one per image) +│ │ └── generated/ # generated image files +│ └── 02/ # Book 2 of the same series +└── Kessler/ # another book — same shape, own AGENTS.md + DATA/ ``` ### Multiple books in parallel -Each book is a **separate workspace** (separate folder, separate opencode -workspace). The `OpenNovelAgent` is the same everywhere — what makes a workspace -"the Scruffy book" vs. "the Kessler book" is its own `AGENTS.md` + `DATA/`. -Switch workspaces to switch books; do not try to fit multiple books in one folder. - ---- +Each book is a **separate folder inside the one vault**. opencode is always started +*inside* the book folder; it finds the shared pack by walking up to the vault root, +so books never duplicate the agents. The `OpenNovelAgent` is identical everywhere — +what makes a workspace "the Scruffy book" vs. "the Kessler book" is its own +`AGENTS.md` + `DATA/`. Switch books by switching folders; never put two books in one +folder. (If several books live in one vault and a book needs to be verifiable on its +own, make the *book folder* a git repository — not the vault.) ## 2. Naming Conventions