@composer-app/mcp 0.0.1-beta.7 → 0.0.3

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.
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: suggesting
3
+ description: Use when you're about to call `composer_add_suggestion` — proposing a text replacement in a Composer doc. Covers span scoping (don't replace more than asked), cross-span responses, ripple coverage (so accepting leaves the doc correct), the auto-suggest-on-confirm pattern, and anchor mechanics (`textToFind` / `occurrence` / whitespace / formatting).
4
+ ---
5
+
6
+ # Composer suggestions
7
+
8
+ A suggestion proposes a text replacement: `textToFind` is the literal
9
+ span that gets cut out when the user accepts; `replacementText` is what
10
+ gets inserted in its place. Pending suggestions render as Replace/With
11
+ cards in the doc's sidebar. There's no "just edit" — every text change
12
+ goes through the user's accept click.
13
+
14
+ This skill is the full guide for `composer_add_suggestion`. Load it any
15
+ time you're about to call the tool, even on familiar territory — the
16
+ failure modes are precise.
17
+
18
+ ## Match the span to the request
19
+
20
+ Before calling `composer_add_suggestion`, decide what span the user is
21
+ actually asking you to change. Three patterns:
22
+
23
+ ### 1. Request scoped to their selection (the common case)
24
+
25
+ "Rewrite this", "make this clearer", "fix the grammar" — no new span
26
+ mentioned. Pass `fromThreadId: <threadId>`. The suggestion inherits the
27
+ source thread's exact anchor — the span the user selected,
28
+ character-for-character.
29
+
30
+ ```
31
+ composer_add_suggestion({
32
+ roomId, fromThreadId: event.threadId, replacementText: "…"
33
+ })
34
+ ```
35
+
36
+ ### 2. Request targets a different span
37
+
38
+ "Rewrite this whole paragraph", "replace the entire list", "change the
39
+ heading". Supply `anchor` (`headingId` + `textToFind`) for the span the
40
+ user actually named. Do **not** pass `fromThreadId` — you're no longer
41
+ inheriting the thread's span.
42
+
43
+ ### 3. Proactive suggestion with no source thread
44
+
45
+ Supply `anchor`. Keep `textToFind` tight — do not widen beyond what
46
+ you're actually replacing.
47
+
48
+ **Picking a broader `textToFind` than the user asked for is the main
49
+ failure mode.** When in doubt, default to path 1.
50
+
51
+ ## Cross-span: respond anywhere in the doc
52
+
53
+ A thread is anchored to one span, but your response isn't confined to
54
+ it. When the user's question (or your own judgment) points elsewhere:
55
+
56
+ - **Suggest on a different span** — call `composer_add_suggestion` with
57
+ an explicit `anchor`. You can post multiple suggestions in one turn.
58
+ E.g. user says *"the flour amount is off and so is the bake time"* →
59
+ two suggestions, each anchored to its own span.
60
+ - **Open a new thread elsewhere** — `composer_add_comment` with its own
61
+ anchor. Useful for cross-references ("see also the conclusion") or
62
+ raising something the user didn't ask about but should see.
63
+ - **Still reply on the original thread too** if the user's question
64
+ deserves a direct answer — but only when the reply says something the
65
+ suggestion/new-comment doesn't already convey. Don't post "see my
66
+ suggestion"; the card IS the answer.
67
+
68
+ Order of operations for a multi-span response: post the
69
+ suggestion(s) / new comment(s) first, then (optionally) a reply on the
70
+ originating thread pointing out the bigger picture.
71
+
72
+ ## Suggest completely — accepting must leave the doc correct
73
+
74
+ The user clicks Accept and is done. They should never have to hunt down
75
+ downstream edits you forgot.
76
+
77
+ **Load enough context before you suggest.** The mention event gives you
78
+ `sectionMarkdown` for the containing section — usually enough for
79
+ wording changes. For anything that might appear elsewhere in the doc
80
+ (numbers, names, product/feature references, versions, dates,
81
+ terminology, heading text), call `composer_get_full_doc` first. One
82
+ extra read is much cheaper than shipping a broken doc.
83
+
84
+ **Scan for ripples before posting.** Common ones:
85
+
86
+ - **Counts and enumerations.** "The three examples below" / "three
87
+ things to remember" — adding or removing an item ripples to the count
88
+ and ordinal words ("first", "finally").
89
+ - **Cross-references.** "As in section 2", "see the conclusion", "per
90
+ step 3 above". If your edit moves or renames the target, update the
91
+ reference too.
92
+ - **Restated facts.** Recipes mention an ingredient twice; release notes
93
+ cite a version in both intro and body; specs quote a number in a
94
+ heading and a paragraph. One fact, multiple spans — cover all of them.
95
+ - **Subject/verb and pronoun agreement.** "X and Y are" → trim to just X
96
+ → "X is".
97
+ - **Neighboring flow.** Rewriting sentence 2 can break sentence 3 ("This
98
+ is why..."). Fix the continuation.
99
+ - **Heading changes.** If you change heading text, prose that says "see
100
+ the Intro section" may need updating.
101
+
102
+ **Post every ripple as its own suggestion, in the same turn.** The tool
103
+ accepts one anchor per call — call it multiple times. Each suggestion
104
+ stays tight to its own span (this is NOT oversuggesting — it's covering
105
+ the actual surface of the change).
106
+
107
+ If a ripple is too structural for a clean suggestion (reorder a list,
108
+ split a paragraph), post the ones you can AND a short reply flagging
109
+ what's still open. The user shouldn't be surprised.
110
+
111
+ When in doubt about the scope of a ripple, fetch the full doc. Don't
112
+ guess.
113
+
114
+ ## Auto-suggest when the user confirms a concrete proposal
115
+
116
+ Two turns, not three. When a user flags something qualitative (*"this
117
+ is too much flour"*, *"this sentence is clunky"*, *"this number feels
118
+ off"*):
119
+
120
+ 1. **Turn 1 — propose.** Reply on the thread with one specific
121
+ alternative phrased as a check: *"Does 200g seem right?"*, *"How
122
+ about 'gently fold' instead of 'stir'?"*, *"Would 45 minutes read
123
+ better than 90?"*. Pick a real number or phrase — not *"would you
124
+ like me to suggest a different amount?"* (that's a question about
125
+ your behavior, not a proposal).
126
+ 2. **Turn 2 — commit on confirmation.** When the user replies with any
127
+ variant of yes ("yes", "sure", "go for it", "perfect", a thumbs-up
128
+ emoji), call `composer_add_suggestion` with `fromThreadId:
129
+ event.threadId` and the concrete replacement. Do **not** also post a
130
+ comment reply — the suggestion card IS your reply.
131
+
132
+ If the user says no / picks a different value / redirects, follow their
133
+ lead — don't post the original proposal anyway.
134
+
135
+ If you can't name a concrete alternative (the thread is too abstract to
136
+ guess a number), ask a clarifying question instead. Don't propose
137
+ something generic just to fill the slot — *"Would you like me to
138
+ shorten this?"* is worthless without a target length.
139
+
140
+ ## Anchor mechanics
141
+
142
+ Write tools take:
143
+
144
+ ```
145
+ { headingId: "intro-0", textToFind: "the exact words to anchor on", occurrence?: 1 }
146
+ ```
147
+
148
+ `textToFind` is literally cut out on accept. Pick the right span:
149
+
150
+ - **Anchor the whole unit you're changing.** Replacing a sentence →
151
+ include the terminal punctuation (`.`, `?`, `!`). Replacing a bullet
152
+ item → anchor the item's text (not the `- ` marker; that's block
153
+ structure). Replacing a paragraph → anchor the whole paragraph.
154
+ - **Include any trailing punctuation you're changing.** Converting a
155
+ statement to a question? End the anchor at the `.`, end the
156
+ replacement with `?`. Don't anchor "the statement" alone and replace
157
+ with "the question?" — you'll end up with `the question?.`.
158
+ - **Match `replacementText`'s shape to the anchor's shape.** Inline
159
+ replacement inside a paragraph → replacement is inline (no leading
160
+ `- `, `#`, or blank line). Replacing a full list → replacement is a
161
+ full markdown list.
162
+ - **Formatting is part of your replacement, not the anchor.** If the
163
+ original had `**bold**` or a link, the anchor's formatting is gone on
164
+ accept — your replacement must include the markdown for any
165
+ formatting you want preserved.
166
+ - **Anchor at token boundaries, not mid-word.** `textToFind: "istrat"`
167
+ to hit the middle of "administration" is fragile. Use whole words or
168
+ sentence boundaries. Use `occurrence` when the same phrase appears
169
+ multiple times.
170
+ - **Whitespace.** Default: no leading or trailing whitespace in the
171
+ anchor, end `replacementText` at the same boundary. If you include a
172
+ trailing space in the anchor, include one in the replacement; otherwise
173
+ words smash together.
174
+
175
+ If you get `text_not_found`, the error message includes the current
176
+ section text. Re-plan against the fresh text and retry. Never retry
177
+ with stale content.
@@ -1,8 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "mcp__composer-mcp__composer_create_room",
5
- "mcp__composer-mcp__composer_join_room"
6
- ]
7
- }
8
- }