openwriter 0.40.0 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/client/assets/{index-vmEPerKn.js → index-Dxbv2n2m.js} +1 -1
  2. package/dist/client/index.html +1 -1
  3. package/package.json +1 -1
  4. package/dist/plugins/authors-voice/dist/index.d.ts +0 -48
  5. package/dist/plugins/authors-voice/dist/index.js +0 -235
  6. package/dist/plugins/authors-voice/package.json +0 -24
  7. package/dist/plugins/authors-voice/skill/LICENSE +0 -21
  8. package/dist/plugins/authors-voice/skill/README.md +0 -126
  9. package/dist/plugins/authors-voice/skill/SKILL.md +0 -151
  10. package/dist/plugins/authors-voice/skill/catalog/ai-tells.md +0 -144
  11. package/dist/plugins/authors-voice/skill/catalog/anchor-prompt.md +0 -189
  12. package/dist/plugins/authors-voice/skill/catalog/author-hints.md +0 -119
  13. package/dist/plugins/authors-voice/skill/catalog/fingerprints.md +0 -175
  14. package/dist/plugins/authors-voice/skill/catalog/hurdle.md +0 -76
  15. package/dist/plugins/authors-voice/skill/catalog/post-write-audit.md +0 -105
  16. package/dist/plugins/authors-voice/skill/docs/analysis.md +0 -31
  17. package/dist/plugins/authors-voice/skill/docs/anchor-iteration.md +0 -176
  18. package/dist/plugins/authors-voice/skill/docs/api/import.md +0 -78
  19. package/dist/plugins/authors-voice/skill/docs/api/protocol.md +0 -140
  20. package/dist/plugins/authors-voice/skill/docs/api/setup.md +0 -37
  21. package/dist/plugins/authors-voice/skill/docs/api/tools.md +0 -102
  22. package/dist/plugins/authors-voice/skill/docs/api/troubleshooting.md +0 -7
  23. package/dist/plugins/authors-voice/skill/docs/apply-protocol-deep.md +0 -191
  24. package/dist/plugins/authors-voice/skill/docs/context-hygiene.md +0 -33
  25. package/dist/plugins/authors-voice/skill/docs/setup.md +0 -74
  26. package/dist/plugins/authors-voice/skill/docs/tiers.md +0 -13
  27. package/dist/plugins/authors-voice/skill/package.json +0 -35
  28. package/dist/plugins/authors-voice/skill/prompts/skeleton.md +0 -29
  29. package/dist/plugins/authors-voice/skill/voice/README.md +0 -51
  30. package/dist/plugins/authors-voice/skill/voice/corpus/.gitkeep +0 -0
  31. package/dist/plugins/github/dist/blog-tools.d.ts +0 -65
  32. package/dist/plugins/github/dist/blog-tools.js +0 -1189
  33. package/dist/plugins/github/dist/git-sync.d.ts +0 -46
  34. package/dist/plugins/github/dist/git-sync.js +0 -335
  35. package/dist/plugins/github/dist/helpers.d.ts +0 -127
  36. package/dist/plugins/github/dist/helpers.js +0 -67
  37. package/dist/plugins/github/dist/index.d.ts +0 -12
  38. package/dist/plugins/github/dist/index.js +0 -112
  39. package/dist/plugins/github/package.json +0 -24
  40. package/dist/plugins/image-gen/dist/index.d.ts +0 -35
  41. package/dist/plugins/image-gen/dist/index.js +0 -149
  42. package/dist/plugins/image-gen/package.json +0 -26
  43. package/dist/plugins/publish/dist/helpers.d.ts +0 -66
  44. package/dist/plugins/publish/dist/helpers.js +0 -199
  45. package/dist/plugins/publish/dist/index.d.ts +0 -3
  46. package/dist/plugins/publish/dist/index.js +0 -1156
  47. package/dist/plugins/publish/dist/newsletter-tools.d.ts +0 -2
  48. package/dist/plugins/publish/dist/newsletter-tools.js +0 -394
  49. package/dist/plugins/publish/package.json +0 -31
  50. package/dist/plugins/x-api/dist/index.d.ts +0 -27
  51. package/dist/plugins/x-api/dist/index.js +0 -368
  52. package/dist/plugins/x-api/dist/server-bridge.d.ts +0 -22
  53. package/dist/plugins/x-api/dist/server-bridge.js +0 -43
  54. package/dist/plugins/x-api/package.json +0 -27
  55. package/dist/server/blog-routes.js +0 -160
  56. package/dist/server/git-sync.js +0 -273
  57. package/dist/server/marks.js +0 -182
  58. package/dist/server/sync-routes.js +0 -75
  59. package/skill/docs/enrichment.md +0 -180
  60. package/skill/docs/footnotes.md +0 -178
  61. package/skill/docs/setup.md +0 -62
  62. package/skill/docs/welcome.md +0 -21
@@ -1,180 +0,0 @@
1
- # Enrichment Dispatch — Detailed Procedure
2
-
3
- OpenWriter's frontmatter enrichment is dispatched via the
4
- `openwriter-enrichment-minion` custom subagent. SKILL.md firm rule 5
5
- covers the common case (single minion, small/medium batch). This doc
6
- handles the **large-corpus case** where one minion isn't enough — and
7
- the parallel-dispatch pattern that scales it.
8
-
9
- ## When to chunk
10
-
11
- | Dirty docs (N) | Dispatch shape | Wall time |
12
- |---|---|---|
13
- | 1–30 | Single minion. Default prompt. | ~10–45 seconds |
14
- | 31+ | Chunked parallel minions. | ~30 seconds (regardless of N) |
15
-
16
- The minion's turn budget (`maxTurns: 500` in its frontmatter) can handle
17
- ~50 docs serially, but at that size the wall-clock cost (3+ minutes)
18
- becomes visible to the user. Parallel dispatch keeps total wall time
19
- under ~30 seconds for any corpus size up to a few hundred docs.
20
-
21
- ## Step-by-step (large corpus)
22
-
23
- ### 1. Inventory the work
24
-
25
- ```
26
- mcp__openwriter__list_dirty_docs()
27
- ```
28
-
29
- Returns every dirty doc across all workspaces with `docId`, `title`,
30
- `workspaceFile`, `reason`. If `total ≤ 30`, stop — single minion path
31
- (firm rule 5) is correct. If `total > 30`, continue.
32
-
33
- ### 2. Chunk the work
34
-
35
- v0.19.0 simplified the minion to logline-only — workspace vocab is no
36
- longer relevant (the `domain` field that used it was dropped). You can
37
- group chunks however you want; workspace-grouping is no longer required.
38
- Practical defaults:
39
-
40
- **Target: 12–15 docs per chunk.**
41
-
42
- - **Very large dirty list (>100 docs):** split into chunks of ~15.
43
- - **Workspace-grouped is still fine** if it makes the dispatch prompts
44
- easier to read, but it's no longer a performance concern.
45
-
46
- You'll typically land on 4–10 chunks. Don't exceed ~10 parallel —
47
- Anthropic per-account rate limits kick in beyond that and you get
48
- serialized anyway.
49
-
50
- ### 3. Dispatch all chunks in one message
51
-
52
- Send **every chunk in a single assistant message** with multiple `Agent`
53
- tool uses. This is the only way they actually run in parallel —
54
- sequential `Agent` calls block each other.
55
-
56
- Use `run_in_background: true` so you can keep talking to the user while
57
- the minions work. You'll receive a `<task-notification>` per chunk as
58
- each one finishes.
59
-
60
- ### 4. Prompt format (explicit-list mode)
61
-
62
- The minion's agent file (`~/.claude/agents/openwriter-enrichment-minion.md`)
63
- supports an explicit-list mode — pass docIds in the prompt and the minion
64
- skips `list_dirty_docs` and uses your list directly.
65
-
66
- Example prompt for one chunk (v0.19.0 — logline-only):
67
-
68
- ```
69
- Enrich these specific openwriter docs:
70
-
71
- - a1b2c3d4 — Onboarding Email Sequence
72
- - e5f6a7b8 — Why We Sleep — Ch 2 Notes
73
- - 9z8y7x6w — Product Launch Checklist
74
- - 1q2w3e4r — Ch 3 — Beats
75
- - 5t6y7u8i — Ch 4 — Draft
76
-
77
- For each: read_pad to get the body, write a logline ≤150 chars, then
78
- bulk mark_enriched at the end with { docId, logline } per entry.
79
- ```
80
-
81
- Keep prompts short. The minion already knows the procedure from its
82
- agent file — you're just handing it the work list. The minion's tool
83
- allowlist (v0.19.0) is `list_dirty_docs`, `read_pad`, `mark_enriched`
84
- — `get_workspace_structure` is no longer needed because there's no
85
- workspace-vocab dependency.
86
-
87
- ### 5. Surface to the user (large-batch phrasing)
88
-
89
- Before dispatching, tell the user what's happening. Firm rule 5's
90
- "large batch" tier (N > 20) requires a heads-up. Example:
91
-
92
- > OpenWriter detected 73 docs that haven't been summarized yet —
93
- > first-time setup. Refreshing them in 6 parallel batches in the
94
- > background; this'll take ~30 seconds and a few cents of Haiku usage.
95
-
96
- Then dispatch. Stay silent as notifications come in unless one fails.
97
- When all are done, report once:
98
-
99
- > Enrichment complete: 73 docs across 8 workspaces. Cost: ~$0.15.
100
-
101
- ### 6. Verify completion
102
-
103
- After every chunk has notified, call `list_dirty_docs` once more. If
104
- `total > 0`, some docs slipped — usually because a minion errored on a
105
- specific doc or a doc was modified mid-enrichment. Re-dispatch a single
106
- minion for the stragglers; don't redo the whole batch.
107
-
108
- ## Why this shape
109
-
110
- **Why parallel, not serial single-minion at maxTurns: 500?**
111
- A single minion processing 100 docs takes 3+ minutes wall time. The
112
- user sits in silence. Six parallel minions of ~15 docs each finish in
113
- ~30 seconds. Same total token cost — much better UX.
114
-
115
- **Why explicit docId list instead of letting each minion call `list_dirty_docs`?**
116
- Race conditions. If you spawn 6 minions and they all call
117
- `list_dirty_docs`, they all see the same 100 dirty docs and try to
118
- enrich the same docs in parallel. Most enrichments succeed (last write
119
- wins on the frontmatter), but it's wasteful and the per-doc baselines
120
- get computed multiple times. Explicit lists partition the work cleanly.
121
-
122
- **Why 12–15 docs per chunk and not 50?**
123
- Two reasons: (1) turn budget — each doc costs ~1 turn (one `read_pad`
124
- call); ~15 docs leaves headroom inside the 500-turn ceiling even with
125
- retries. (2) failure isolation — if one minion's batch errors, you lose
126
- 15 docs of work, not 50.
127
-
128
- **Why dispatch in one message, not sequential Agent calls?**
129
- Sequential `Agent` calls block each other. Only multiple `Agent` tool
130
- uses in the **same assistant message** run truly in parallel.
131
-
132
- ## Cost ballpark
133
-
134
- Haiku token cost per doc: ~1.5K–3K in v0.19.0 (one read_pad + one
135
- logline synthesis + share of mark_enriched). Roughly half what it cost
136
- under v0.16's five-field schema.
137
-
138
- | Corpus size | Approx cost (v0.19.0) |
139
- |---|---|
140
- | 30 docs | ~$0.02 |
141
- | 100 docs | ~$0.08 |
142
- | 500 docs | ~$0.40 |
143
-
144
- Compare to ~$5.00 per doc if you used the general-purpose subagent with
145
- full MCP tool registry (~50K token overhead per spawn). The custom
146
- minion's tool allowlist (3 tools in v0.19.0: `list_dirty_docs`,
147
- `read_pad`, `mark_enriched`) is what makes the math work.
148
-
149
- ## Failure modes
150
-
151
- - **Minion returns with no `mark_enriched` call** — almost always means
152
- it hit the turn ceiling. Confirm its agent file has `maxTurns: 500`
153
- in the frontmatter, then reduce chunk size to ~10 docs and re-dispatch
154
- that chunk.
155
- - **Minion reports "No enrichment work pending"** — its assigned docs
156
- got enriched by a sibling minion first (race condition from
157
- `list_dirty_docs` mode, not explicit-list mode). Benign; the other
158
- minion's work landed correctly.
159
- - **`<task-notification>` reports an error** — re-dispatch just that
160
- one chunk. Don't restart the whole batch.
161
- - **Logline cap violations** — the minion's agent file enforces a
162
- 150-char hard cap. If you spot longer loglines on disk after the
163
- fact, it's a minion regression — flag for agent-file revision rather
164
- than re-enriching.
165
-
166
- ## When NOT to chunk
167
-
168
- If `list_dirty_docs` returns ≤30 docs, dispatch a single minion with
169
- the default prompt:
170
-
171
- ```
172
- Agent({
173
- subagent_type: "openwriter-enrichment-minion",
174
- description: "Enrich stale openwriter docs",
175
- prompt: "Enrich all currently stale openwriter docs."
176
- })
177
- ```
178
-
179
- The minion calls `list_dirty_docs` itself, processes everything in one
180
- pass, and reports back. Chunking ≤30 docs is overhead, not gain.
@@ -1,178 +0,0 @@
1
- # Footnotes — Author Guide for Agents
2
-
3
- OpenWriter supports CommonMark / Pandoc footnote syntax for citation-heavy
4
- long-form writing. The editor renders inline references as superscript
5
- chips and corrals definitions into an end-of-doc "Footnotes" section.
6
-
7
- This doc explains how to write footnotes via MCP tools and what to expect
8
- on disk and in the editor.
9
-
10
- ## The syntax (Pandoc / CommonMark)
11
-
12
- Two parts:
13
-
14
- - **Reference** (inline): `text[^N]` — appears in the prose
15
- - **Definition** (block): `[^N]: footnote text` — appears at end of doc
16
-
17
- Labels can be numeric or mnemonic:
18
-
19
- ```markdown
20
- The body repairs itself during deep sleep[^1] too.
21
-
22
- Per Sapolsky[^sapolsky2017], stress responses follow a pattern.
23
-
24
- [^1]: Eibl-Eibesfeldt 1973, replicated and extended by Galati et al. 2003.
25
-
26
- [^sapolsky2017]: Sapolsky, R. (2017). *Behave*. Penguin Press.
27
- ```
28
-
29
- The author label (`1` or `sapolsky2017`) is what pairs reference to
30
- definition. **Display numbering is automatic** — the editor's CSS counter
31
- shows sequential `[1] [2] [3]` regardless of label. Mnemonic labels stay
32
- on disk for human-readable file diffs.
33
-
34
- ## How to write footnotes from MCP
35
-
36
- Just include the syntax in your markdown content — no special tool needed.
37
-
38
- ### populate_document (initial draft)
39
-
40
- ```ts
41
- populate_document({
42
- docId: "abc12345",
43
- content: `# Chapter 1
44
-
45
- Theory of mind develops late[^1] in non-human primates.
46
-
47
- [^1]: Premack & Woodruff (1978), Behavioral and Brain Sciences 1: 515–526.
48
- `
49
- })
50
- ```
51
-
52
- The parser handles `[^1]` references and `[^1]: ...` definitions. The
53
- editor renders the reference as a superscript chip and the definition
54
- inside an end-of-doc "Footnotes" section.
55
-
56
- ### write_to_pad (adding to existing doc)
57
-
58
- To add a new footnote to existing prose, you have two paths.
59
-
60
- **Append a new reference + definition together** (recommended):
61
-
62
- ```ts
63
- // Step 1: rewrite the paragraph to add the reference
64
- write_to_pad({
65
- docId: "abc12345",
66
- changes: [
67
- {
68
- operation: "rewrite",
69
- nodeId: "para_id",
70
- content: "The same sentence now with a new claim[^2]."
71
- }
72
- ]
73
- })
74
-
75
- // Step 2: append the definition. If the doc already has a footnoteSection,
76
- // you can insert the definition inside it via afterNodeId pointing at the
77
- // last definition. If the doc has no footnotes yet, the parser auto-creates
78
- // the section when it sees `[^N]: ...` at the end of the markdown body.
79
- ```
80
-
81
- **Simpler: just include both the reference and the definition in one
82
- write_to_pad call**:
83
-
84
- ```ts
85
- write_to_pad({
86
- docId: "abc12345",
87
- changes: [
88
- {
89
- operation: "rewrite",
90
- nodeId: "para_id",
91
- content: "Sentence with new claim[^2]."
92
- },
93
- {
94
- operation: "insert",
95
- afterNodeId: "end",
96
- content: "[^2]: Smith et al. (2020), Nature 580: 142–148."
97
- }
98
- ]
99
- })
100
- ```
101
-
102
- The serializer normalizes definitions to the end-of-doc `footnoteSection`
103
- regardless of where they're inserted in the tree.
104
-
105
- ## What you see in `read_pad`
106
-
107
- ```
108
- title: My Chapter
109
- id: abc12345
110
- words: 423
111
- pending: 0
112
- ---
113
- [h1:aa0001] Chapter 1
114
- [p:bb0002] Theory of mind develops late[^1] in non-human primates.
115
- [fnsec:cc0003]
116
- [fndef:dd0004] [^1]: Premack & Woodruff (1978), Behavioral and Brain Sciences 1: 515–526.
117
- ```
118
-
119
- The `[^N]` in the body is the inline reference. `[fnsec:...]` is the
120
- end-of-doc section. `[fndef:...]` is each definition.
121
-
122
- ## Per-doc scope — important
123
-
124
- **Footnote labels are local to each doc.** Chapter 3's `[^1]` does not
125
- refer to Chapter 4's `[^1]`. Each chapter is its own `.md` file with its
126
- own numbering. Cross-chapter references are not supported at the editor
127
- level (a future book-export pipeline will handle global numbering at
128
- typeset time).
129
-
130
- If the author writes "see Ch 1 note 4" they're writing prose, not a
131
- cross-doc footnote link.
132
-
133
- ## Multi-paragraph definitions
134
-
135
- Pandoc allows multi-paragraph footnotes via 4-space-indented continuation:
136
-
137
- ```markdown
138
- [^1]: First paragraph of the definition.
139
-
140
- Continuation paragraph, indented 4 spaces.
141
-
142
- Another continuation.
143
- ```
144
-
145
- The editor preserves the multi-paragraph structure inside the definition.
146
- Use this for footnotes that need substantial explanation (lengthy
147
- methodology notes, multi-source citations, etc.).
148
-
149
- ## What's NOT supported (yet)
150
-
151
- - **Cross-doc footnote references.** Each doc has its own numbering.
152
- - **Bibliography auto-generation.** Authors manage citation text inline.
153
- Zotero / Mendeley / BibTeX integration is a future enhancement.
154
- - **DOI auto-resolution.** Footnote text is plain — paste a DOI manually.
155
- - **Per-page footnotes (Phase 3).** The editor uses end-of-doc placement;
156
- per-page placement is a print-layout concern handled at book-export
157
- time, not in the editor.
158
-
159
- ## When to use footnotes vs inline parentheticals
160
-
161
- Use footnotes when:
162
- - The citation count exceeds ~3 per ~500 words (inline parentheticals
163
- start visibly disrupting the prose at that density)
164
- - The audience expects an academic register (popular nonfiction in the
165
- Sapolsky / Wrangham / Pinker lineage)
166
- - The work targets book-class output (cumulative citation load at book
167
- scale destroys readability under inline parentheticals)
168
-
169
- Use inline parentheticals when:
170
- - Citations are sparse (<1 per 500 words) and short
171
- - The author prefers a journalistic register
172
- - The work is short-form (tweet thread, blog post) where there's no
173
- end-of-doc section to defer to
174
-
175
- ## Reference docs (for the editor maintainers, not agents)
176
-
177
- - `docs/footnotes.md` (in the openwriter repo): full architecture
178
- - `adr/footnote-system.md`: load-bearing invariants + decision log
@@ -1,62 +0,0 @@
1
- # OpenWriter Setup
2
-
3
- ## Quick install
4
-
5
- ```bash
6
- npx openwriter setup
7
- ```
8
-
9
- This installs openwriter globally, configures the MCP server for Claude Code, and copies this skill — all in one step. After it finishes, the user just needs to restart their Claude Code session.
10
-
11
- ## Claude Code
12
-
13
- **Fallback (if the command above fails):** Do it manually:
14
-
15
- ```bash
16
- npm install -g openwriter
17
- claude mcp add -s user openwriter -- openwriter --no-open
18
- ```
19
-
20
- If `claude mcp add` can't run (e.g. nested session error), edit `~/.claude.json` directly. Add `openwriter` as the **first entry** in `mcpServers`:
21
-
22
- ```json
23
- {
24
- "mcpServers": {
25
- "openwriter": {
26
- "command": "openwriter",
27
- "args": ["--no-open"]
28
- }
29
- }
30
- }
31
- ```
32
-
33
- ## OpenCode
34
-
35
- Same binary, different config format. Add to `opencode.json` at the project root:
36
-
37
- ```json
38
- {
39
- "$schema": "https://opencode.ai/config.json",
40
- "mcp": {
41
- "openwriter": {
42
- "type": "local",
43
- "command": ["openwriter", "--no-open"],
44
- "enabled": true
45
- }
46
- }
47
- }
48
- ```
49
-
50
- OpenCode auto-discovers the skill at `~/.claude/skills/openwriter/SKILL.md` — no copy needed.
51
-
52
- The enrichment minion is NOT auto-discovered. Place it at one of:
53
-
54
- - `~/.config/opencode/agents/openwriter-enrichment-minion.md` (global, all projects)
55
- - `.opencode/agents/openwriter-enrichment-minion.md` (this project only, repo root)
56
-
57
- Source file lives at `~/.claude/skills/openwriter/agents/openwriter-enrichment-minion.md` after `npx openwriter setup`. Copy it to one of the paths above and restart OpenCode. The filename becomes the agent name OpenCode resolves when the parent dispatches it.
58
-
59
- ## After setup
60
-
61
- 1. Restart your Claude Code or OpenCode session (MCP servers load on startup)
62
- 2. Open http://localhost:5050 in your browser
@@ -1,21 +0,0 @@
1
- # Welcome to OpenWriter
2
-
3
- What you're looking at right now is how we collaborate. These green highlights are my proposed changes — I write, you review. Use the review panel on the right to navigate (j/k), accept (a), or reject (r) each change. Try it now.
4
-
5
- ## Create Documents
6
-
7
- Hit the **+** button in the sidebar to create different document types: blog posts, newsletters, tweets, LinkedIn posts, and articles. Each type has its own compose view tailored to that format. Or just ask me to write something and I'll create the right doc type for you.
8
-
9
- ## Workspaces
10
-
11
- Organize your documents into workspaces with containers and tags. This is especially powerful for book writing — each chapter is a document, grouped into sections as containers. I can see your full workspace structure and work across multiple docs.
12
-
13
- ## Plugins
14
-
15
- **Author's Voice** — Feed me your writing samples and I'll write in your voice. Not an approximation — I pull your actual patterns, cadence, and word choices from your corpus.
16
-
17
- **Publish** — Send newsletters to your subscriber list, post to X/Twitter, publish blog posts to GitHub, and schedule content. All from inside the editor, no copy-pasting to other platforms.
18
-
19
- ## What's Next
20
-
21
- Ask me to write something. A blog post, a tweet thread, a newsletter — whatever you're working on. I'll create a doc for it and we'll iterate together.