openwriter 0.8.7 → 0.9.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.
package/skill/SKILL.md CHANGED
@@ -119,7 +119,7 @@ Every document has an immutable **docId** (8-char hex, e.g. `a1b2c3d4`) in its Y
119
119
  |------|-----------|-------------|
120
120
  | `list_documents` | — | List all documents with title, docId, word count, active status |
121
121
  | `switch_document` | `docId` | Switch to a different document by docId |
122
- | `create_document` | `title?`, ... | Create a new empty document response includes docId |
122
+ | `create_document` | `content_type`, `title?`, ... | Create a new document. `content_type` is required: "document", "tweet", "reply", "quote", "article", "linkedin", "newsletter", or "blog" |
123
123
  | `open_file` | `path` | Open an existing .md file from any location on disk |
124
124
  | `delete_document` | `docId` | Delete a document file (moves to OS trash, recoverable) |
125
125
  | `archive_document` | `docId` | Archive a document (hides from sidebar, keeps on disk) |
@@ -213,8 +213,8 @@ For making changes to existing documents — rewrites, insertions, deletions:
213
213
  **Always use the two-step flow** when creating new content:
214
214
 
215
215
  ```
216
- 1. create_document({ title: "My Doc" }) no content, fires instantly, shows spinner
217
- 2. populate_document({ content: "..." }) ← delivers content, clears spinner
216
+ 1. create_document({ title: "My Doc", content_type: "document" }) ← fires instantly, shows spinner
217
+ 2. populate_document({ content: "..." }) ← delivers content, clears spinner
218
218
  ```
219
219
 
220
220
  **Why two steps?** MCP tool calls are atomic — the server doesn't receive the call until ALL parameters are fully generated. For a document with hundreds or thousands of words, the user would wait 30+ seconds with zero feedback while you generate content tokens. The two-step flow shows a sidebar spinner immediately (step 1 has no content to generate), then the spinner persists while you generate and deliver the content (step 2).
@@ -232,6 +232,7 @@ For making changes to existing documents — rewrites, insertions, deletions:
232
232
  ```
233
233
  create_document({
234
234
  title: "Opening Chapter",
235
+ content_type: "document", ← REQUIRED: "document" for plain, or "tweet"/"article"/etc.
235
236
  workspace: "The Immortal", ← creates workspace if it doesn't exist
236
237
  container: "Chapters" ← creates container if it doesn't exist
237
238
  })
@@ -269,7 +270,7 @@ This eliminates the need for separate `create_workspace`, `create_container`, an
269
270
  ### Creating new content (two-step)
270
271
 
271
272
  ```
272
- 1. create_document({ title: "My Doc", workspace: "Project", container: "Chapters" })
273
+ 1. create_document({ title: "My Doc", content_type: "document", workspace: "Project", container: "Chapters" })
273
274
  → returns docId "a1b2c3d4", spinner appears
274
275
  2. populate_document({ docId: "a1b2c3d4", content: "# ..." })
275
276
  → content delivered, spinner clears
@@ -280,13 +281,13 @@ This eliminates the need for separate `create_workspace`, `create_container`, an
280
281
  ### Building a workspace (multiple docs)
281
282
 
282
283
  ```
283
- 1. create_document({ title: "Ch 1", workspace: "My Book", container: "Chapters" })
284
+ 1. create_document({ title: "Ch 1", content_type: "document", workspace: "My Book", container: "Chapters" })
284
285
  → returns docId "ch1docid"
285
286
  2. populate_document({ docId: "ch1docid", content: "..." })
286
- 3. create_document({ title: "Ch 2", workspace: "My Book", container: "Chapters" })
287
+ 3. create_document({ title: "Ch 2", content_type: "document", workspace: "My Book", container: "Chapters" })
287
288
  → returns docId "ch2docid"
288
289
  4. populate_document({ docId: "ch2docid", content: "..." })
289
- 5. create_document({ title: "Character Bible", workspace: "My Book", container: "References" })
290
+ 5. create_document({ title: "Character Bible", content_type: "document", workspace: "My Book", container: "References" })
290
291
  6. populate_document({ docId: "<from step 5>", content: "..." })
291
292
  7. tag_doc + update_workspace_context → organize and add context
292
293
  ```
@@ -325,9 +326,7 @@ OpenWriter doubles as a tweet compose surface. When `tweetContext` is set in a d
325
326
  ### Setting up a tweet document
326
327
 
327
328
  ```
328
- 1. create_document({ title: "Reply to @username" })
329
- 2. populate_document({ content: " " }) ← empty content, compose area
330
- 3. set_metadata({ tweetContext: { url: "https://x.com/user/status/123", mode: "reply" } })
329
+ 1. create_document({ title: "Reply to @username", content_type: "reply", url: "https://x.com/user/status/123", empty: true })
331
330
  ```
332
331
 
333
332
  - **`url`** — the tweet URL to reply to or quote
@@ -370,31 +369,15 @@ The compose view fetches and renders the parent tweet (text, author, avatar, med
370
369
 
371
370
  ### Template Documents
372
371
 
373
- Users can also create tweet and article templates directly from the browser UI using the **Templates** dropdown in the titlebar. For agent-initiated template creation, use the standard two-step flow:
372
+ Users can also create tweet and article templates directly from the browser UI using the **Templates** dropdown in the titlebar. For agent-initiated creation, `content_type` handles all metadata automatically:
374
373
 
375
- **Tweet template:**
376
- ```
377
- 1. create_document({ empty: true })
378
- 2. set_metadata({ tweetContext: { mode: "tweet" }, title: "Tweet" })
379
- ```
374
+ **Tweet:** `create_document({ title: "Tweet", content_type: "tweet", empty: true })`
380
375
 
381
- **Reply template (with parent URL):**
382
- ```
383
- 1. create_document({ empty: true })
384
- 2. set_metadata({ tweetContext: { url: "https://x.com/user/status/123", mode: "reply" }, title: "Reply" })
385
- ```
376
+ **Reply:** `create_document({ title: "Reply", content_type: "reply", url: "https://x.com/user/status/123", empty: true })`
386
377
 
387
- **Quote tweet template:**
388
- ```
389
- 1. create_document({ empty: true })
390
- 2. set_metadata({ tweetContext: { url: "https://x.com/user/status/123", mode: "quote" }, title: "Quote Tweet" })
391
- ```
378
+ **Quote tweet:** `create_document({ title: "Quote Tweet", content_type: "quote", url: "https://x.com/user/status/123", empty: true })`
392
379
 
393
- **Article template:**
394
- ```
395
- 1. create_document({ empty: true })
396
- 2. set_metadata({ articleContext: { active: true }, title: "Article" })
397
- ```
380
+ **Article:** `create_document({ title: "Article", content_type: "article", empty: true })`
398
381
 
399
382
  ### Removing tweet mode
400
383