@erdemtuna/doc-review 0.12.0 → 0.14.0

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 (49) hide show
  1. package/README.md +23 -25
  2. package/lib/SKILL.md +65 -202
  3. package/lib/agent-handoff.js +24 -0
  4. package/lib/agent-output.js +287 -0
  5. package/lib/anchor-text.js +31 -19
  6. package/lib/chrome-api.js +23 -4
  7. package/lib/chrome.html +0 -25
  8. package/lib/cli.js +282 -104
  9. package/lib/comment-target.js +4 -0
  10. package/lib/contracts/agent.js +122 -0
  11. package/lib/contracts/feedback.js +369 -1
  12. package/lib/contracts/frame.js +81 -0
  13. package/lib/contracts/history.js +189 -1
  14. package/lib/contracts/index.js +7 -2
  15. package/lib/contracts/page-boundary.js +187 -0
  16. package/lib/contracts/validation.js +200 -0
  17. package/lib/conversation-anchor-controller.js +84 -0
  18. package/lib/conversation-capture.js +81 -0
  19. package/lib/conversation-controller.js +798 -0
  20. package/lib/conversation-save.js +175 -0
  21. package/lib/conversation-server.js +184 -0
  22. package/lib/conversation-shell.js +1013 -0
  23. package/lib/conversation-store.js +809 -0
  24. package/lib/frame-controller.js +8 -8
  25. package/lib/frame-policy.js +1 -0
  26. package/lib/history-policy.js +4 -15
  27. package/lib/history-server.js +42 -326
  28. package/lib/html-transform.js +19 -4
  29. package/lib/icons.js +323 -0
  30. package/lib/new-message-target.js +27 -0
  31. package/lib/paths.js +2 -2
  32. package/lib/poll-transport.js +109 -26
  33. package/lib/positioning.js +51 -0
  34. package/lib/references/context-and-recovery.md +130 -0
  35. package/lib/references/response-contract.md +108 -0
  36. package/lib/references/source-edits.md +47 -0
  37. package/lib/revision-store.js +1 -1
  38. package/lib/save-controller.js +28 -14
  39. package/lib/sdk.js +357 -35
  40. package/lib/server.js +73 -595
  41. package/lib/setup.js +17 -48
  42. package/lib/state.js +21 -7
  43. package/lib/thread-anchor-controller.js +56 -0
  44. package/lib/toolbar-controller.js +3 -3
  45. package/lib/ui/THIRD_PARTY_NOTICES.md +127 -8
  46. package/lib/ui/chrome.css +1118 -2787
  47. package/lib/ui/chrome.js +81 -17
  48. package/package.json +2 -2
  49. package/lib/chrome-client.js +0 -1706
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Doc Review
2
2
 
3
- **Review your coding agent's work in the browser, not in a wall of chat.**
3
+ **Review and refine documents with your agent.**
4
4
 
5
- Open an HTML file, a Markdown document, or a localhost page. Point to what needs
6
- changing, edit the small things yourself, and send your feedback to the agent
7
- in one batch.
5
+ Open an HTML file, a Markdown document, or a localhost page. Ask questions,
6
+ request changes, and edit the small things yourself. Keep the conversation
7
+ beside the document as you iterate with your agent.
8
8
 
9
9
  ![The Field Notes landing page in Review, with highlighted copy and an anchored comment asking for a concrete benefit](https://raw.githubusercontent.com/erdemtuna/doc-review/main/assets/doc-review.png)
10
10
 
11
- *Feedback stays beside the work. Your agent gets the comments, edits, and overall note together.*
11
+ *Keep questions and feedback beside the document as you refine it together.*
12
12
 
13
13
  ## Get started
14
14
 
@@ -32,32 +32,27 @@ The same command works with Markdown or a running local app:
32
32
  /doc-review http://localhost:3000
33
33
  ```
34
34
 
35
- Reviews start only when you request them. Your agent uses the installed skill
36
- to open the page, wait for feedback, and apply the changes.
35
+ Your agent handles the commands using the installed skill.
37
36
 
38
- ## From feedback to the next version
37
+ ## How it works
39
38
 
40
- 1. **Open and explore.** Reviews start in **View**, so you can read and use page
41
- controls without accidentally editing.
42
- 2. **Point out what matters.** Select text or choose an element to leave a
43
- comment. Switch to **Edit** for direct changes to wording, formatting, images,
44
- or layout. Commenting works in either mode.
45
- 3. **Send one batch.** Open **Feedback**, inspect Comments and Edits, add an overall note if needed, and
46
- choose **Send to agent**. No need to describe where every sentence lives.
47
- 4. **Check the result.** Use **Changes** to compare a review round's captured
48
- before and after content, then continue reviewing. Comparisons show observed
49
- changes, not a guarantee that every request was resolved.
39
+ 1. **Open your document.** Read and explore it normally. Reviews start in **View**
40
+ so you will not accidentally edit anything.
41
+ 2. **Start a conversation.** Highlight a passage to ask a question or request a
42
+ change. Switch to **Edit** to make small changes yourself.
43
+ 3. **Review and iterate.** Choose **Send to agent**, read the replies, and compare
44
+ what changed. Keep the conversation going until you are happy with the result.
50
45
 
51
- You can review a plan, refine a landing page, or walk through a local app without
52
- moving your feedback into a separate document.
46
+ Asking a question does not authorize edits. Check **Request a change** when you
47
+ want the agent to change the document.
53
48
 
54
- ![The Feedback panel with separate Comments and Edits sections, an overall note, and End review beside Send to agent](https://raw.githubusercontent.com/erdemtuna/doc-review/main/assets/doc-review-feedback.png)
49
+ ![Feedback with independent open-conversation and edit counts, a saved headline edit, and the optional Note to agent collapsed](https://raw.githubusercontent.com/erdemtuna/doc-review/main/assets/doc-review-feedback.png)
55
50
 
56
- *One batch, with the context attached: comments, your edits, and the overall direction.*
51
+ *Review your comments and edits before sending. Add a note only if you need one.*
57
52
 
58
- ![The completed Field Notes review round in Changes, comparing the revised description and call to action with their originals](https://raw.githubusercontent.com/erdemtuna/doc-review/main/assets/doc-review-changes.png)
53
+ ![The completed Field Notes submission in Changes, comparing the revised description and call to action with their originals](https://raw.githubusercontent.com/erdemtuna/doc-review/main/assets/doc-review-changes.png)
59
54
 
60
- *Check the result beside the original. Move between changes or switch to Source for the saved file text.*
55
+ *See what changed, then continue the conversation.*
61
56
 
62
57
  ## What happens to your edits?
63
58
 
@@ -79,11 +74,14 @@ services.
79
74
  [Usage guide](https://github.com/erdemtuna/doc-review/blob/main/docs/usage.md):
80
75
  setup options, comments, comparisons, limitations, and upgrades.
81
76
 
77
+ [Agent reference](https://github.com/erdemtuna/doc-review/blob/main/docs/usage.md#sending-feedback):
78
+ commands, response formats, and recovery for integrations.
79
+
82
80
  [Development](https://github.com/erdemtuna/doc-review/blob/main/docs/development.md):
83
81
  build, test, architecture, and package checks.
84
82
 
85
83
  [Prepared review example](docs/migration-review.md):
86
- disposable HTML/Markdown sessions with saved comparison rounds and a shell review checklist.
84
+ an isolated durable shell preview and a reproducible installed-package lifecycle.
87
85
 
88
86
  [Releasing](https://github.com/erdemtuna/doc-review/blob/main/RELEASING.md):
89
87
  the maintainers' release process.
package/lib/SKILL.md CHANGED
@@ -5,213 +5,76 @@ description: Open an HTML file, Markdown file, or localhost page for View-first
5
5
 
6
6
  # doc-review
7
7
 
8
- ## Activation
9
-
10
- Start only when the user explicitly invokes `/doc-review` or asks to open an
11
- interactive browser review. A generic request to review, proofread, analyze, write,
12
- or update content is not permission to open this workflow. Another skill's
13
- automatic review step is not user permission.
14
-
15
- Without that request, respond normally without opening a review or polling for
16
- feedback. Once the user starts a review, continue its feedback loop until they
17
- end it; stop if they cancel or switch to a different task.
18
-
19
- ## Review behavior
20
-
21
- The user reviews your HTML, Markdown, or localhost page in a real browser. It starts in View.
22
- Native page controls work; supported self-contained HTML scripts run automatically.
23
- They can switch to Edit, comment explicitly in either mode,
24
- and send the whole batch at once.
25
-
26
- Plain HTML retains direct autosave. Scripted HTML edits are feedback-only:
27
- apply them to the original source, never serialize the script-modified runtime
28
- page over the file. Source changes do not require renewed approval.
29
- Reload without scripts is a temporary recovery option, not permission to write
30
- a scripted preview over its source. Reloads can wait for unresolved editing work.
31
- Applications requiring external script dependencies should use localhost review;
32
- automatic inline execution does not add support for application imports or workers.
33
-
34
- Markdown files open rendered. Their quotes and edits reference the rendered text,
35
- and the file itself is never touched — apply every change to the Markdown source,
36
- keeping its formatting syntax.
37
-
38
- Comments open from a contextual icon after a text selection or an element hover/focus.
39
- The keyboard shortcut is Ctrl+Alt+M, or Cmd+Option+M on macOS. Enter submits the
40
- comment and Shift+Enter adds a new line. On desktop the composer stays attached
41
- to its target or pins to the effective top or bottom clipping edge; Back to
42
- selection reveals an offscreen target without changing the draft.
43
-
44
- Feedback is the single toolbar entry point for Comments, Edits, and the overall
45
- note. Comments and Edits collapse independently; their choices last until the
46
- tab reloads. An active comment edit keeps Comments expanded until Save or Cancel.
47
- The inventory scrolls independently while the overall note and bottom actions
48
- remain reachable. End review is on the left and Send to agent on the right.
49
- Submitting creates the normal target mark and count but leaves the card closed
50
- until the user explicitly activates the mark or chooses Jump to. Focus returns
51
- to the reviewed element or selection. Aligned cards expose Edit, Close, and
52
- More; drawer cards expose Jump to, Edit, and More. Delete is available only
53
- through More and an inline confirmation. Long quote hints preserve both ends.
54
-
55
- Existing-comment editing uses explicit Save and Cancel controls and never saves
56
- on blur. Enter saves, Shift+Enter inserts a line, and Escape cancels. The draft,
57
- focus, and caret follow the comment between aligned and drawer cards and survive
58
- target movement. Closing an aligned card only hides its active presentation.
59
- Acknowledging the exact delivered batch removes only the comments that batch
60
- carried; newer comments and corrections survive.
61
-
62
- ## The loop
63
-
64
- 1. After the explicit review request, use the requested file or localhost route.
65
- Create or update content, or start a local page, only as needed for that request.
66
- 2. Open it for the user:
67
-
68
- ```sh
69
- npx -y @erdemtuna/doc-review path/to/file.html
70
- ```
71
-
72
- For a page served by a local development server, open the real route instead
73
- of recreating it as a separate HTML file:
74
-
75
- ```sh
76
- npx -y @erdemtuna/doc-review http://localhost:3000/wiki
77
- ```
78
-
79
- 3. Wait for feedback. This blocks until they hit Send, or the timeout passes:
80
-
81
- ```sh
82
- npx -y @erdemtuna/doc-review poll path/to/file.html --timeout 600
83
- ```
84
-
85
- Without `--timeout`, the CLI stops after 12 hours. An explicit timeout covers
86
- the entire operation, including server discovery, reconnects, and backoff.
87
- Recoverable connection drops retry within that deadline; terminal errors
88
- require action rather than another automatic poll. The 600-second command
89
- above deliberately uses a shorter deadline.
90
-
91
- Keep this command in the foreground. Do not end your turn while it is waiting.
92
- If your shell returns a process or session handle, keep waiting on that handle
93
- until the command exits. If it prints `{"status":"timeout"}`, no feedback has
94
- arrived yet — run the same poll command again to keep waiting. Feedback is
95
- saved even if a poll dies, so nothing is ever lost.
96
-
97
- If it prints `{"status":"closed"}`, the user ended the review from the
98
- browser — stop polling and do not run the poll command again. Unsent
99
- feedback is kept and ships the next time this target is reviewed.
100
-
101
- 4. Apply what comes back, then wait again. Copy `batch_id` from the response;
102
- only that exact receipt can clear the batch you handled:
103
-
104
- ```sh
105
- npx -y @erdemtuna/doc-review poll path/to/file.html --ack b_0123456789abcdef --timeout 600
106
- ```
107
-
108
- The response's `next_step` contains the complete acknowledgement command.
109
- Never acknowledge a different or guessed ID.
110
-
111
- Acknowledgement means that you handled the feedback; it is separate from
112
- browser result-capture readiness. Do not wait for history capture before
113
- acknowledging completed work, and do not acknowledge merely because a page
114
- looks stable. The browser captures round results automatically when possible.
115
- Missing comparison data does not prevent the user from sending feedback.
116
- Captured differences are observations, not proof that you alone authored them.
117
- Content results may wait for the same identifiable tab as the baseline.
118
- The user sees a return-to-tab prompt; do not automate tab clicking to force
119
- capture. Source comparison remains independent. Unknown view identity is
120
- labelled unverified, not asserted as a whole-application comparison.
121
-
122
- Repeat 3–4 until the user says they are done.
123
-
124
- Not sure whether feedback is already waiting — say, at the start of a new turn?
125
- This answers instantly without blocking:
8
+ Only an explicit user request permits opening a review or polling; another
9
+ skill's automatic review step does not.
10
+
11
+ Open the requested file or real localhost route:
126
12
 
127
13
  ```sh
128
- npx -y @erdemtuna/doc-review status path/to/file.html
14
+ npx -y @erdemtuna/doc-review path/to/file.html
129
15
  ```
130
16
 
131
- It prints `{"status": "feedback-waiting"}` when a batch is ready for a poll,
132
- plus counts of unsent comments and edits still in the browser.
133
-
134
- ## What you get
135
-
136
- One batch covers every page the user visited, grouped by file or localhost URL.
137
-
138
- ```json
139
- {
140
- "batch_id": "b_0123456789abcdef",
141
- "status": "feedback",
142
- "pages": [
143
- {
144
- "file": "/abs/path/to/page.html",
145
- "comments": [
146
- { "id": "c_1", "kind": "selection", "quote": "the exact text they selected",
147
- "anchor": { "prefix": "...", "quote": "...", "suffix": "..." },
148
- "feedback": "what they want changed" }
149
- ],
150
- "edits": [
151
- { "label": "Problem body", "kind": "edited",
152
- "before": "the original wording",
153
- "after": "their exact new wording",
154
- "after_html": "their exact new wording with <strong>formatting</strong>" }
155
- ]
156
- }
157
- ],
158
- "overall_note": "feedback not tied to any one page",
159
- "next_step": "Apply this feedback, then run: npx -y @erdemtuna/doc-review poll ... --ack b_0123456789abcdef --timeout 600"
160
- }
17
+ Retain `review.reviewId`, `review.entryKey`, receipt and URL. Copy generated
18
+ commands, not placeholders. Opening after End creates a different review;
19
+ never switch an existing handler to it.
20
+
21
+ ## Read, handle, respond, wait
22
+
23
+ ```sh
24
+ npx -y @erdemtuna/doc-review poll --review <reviewId> --entry <entryKey> --timeout 600
161
25
  ```
162
26
 
163
- ## Rules
164
-
165
- - Edits marked **`truncated`** contain incomplete fields listed in
166
- `truncated_fields`. Each text/HTML field is limited to 200,000 Unicode code
167
- points. Never apply a truncated field as a complete replacement or guess the
168
- missing content. Obtain the complete edit from an authoritative source, or ask
169
- the user for it. Do not acknowledge the batch until all feedback is handled.
170
- - **`edits` are changes the user already made.** `after` is their exact wording —
171
- unless marked truncated, carry it across verbatim and never revert it. If the HTML was generated from
172
- something else (MDX, Markdown, a template), apply `after` to the **source** too,
173
- or their fix disappears on the next build.
174
- - When `before_html`/`after_html` are present, the user changed formatting, not
175
- just words — bold, italic, underline, links. Use the HTML version to carry the
176
- formatting into the source, translated to its syntax (e.g. `<strong>` → `**`
177
- in Markdown/MDX).
178
- - A page with `kind: "url"` was edited directly in the review UI. Its `file`
179
- and `url` fields name the localhost route, not a writable file. Find the
180
- matching project source (such as MDX, TSX, or a template), apply every edit
181
- and deletion there, then acknowledge so the route reloads. Never write the
182
- rendered HTTP response back into the app.
183
- - When an edit's `after_html` contains `<img src="assets/...">`, the user pasted
184
- an image: the file already exists in an `assets/` folder next to the reviewed
185
- file. Keep that relative path — in Markdown, reference it as
186
- `![](assets/...)`. Never regenerate or inline the image.
187
- - On a localhost page, a pasted image arrives under `staged_assets`. Copy its
188
- local `path` into the app's appropriate asset folder, replace the temporary
189
- preview URL in `after_html`, and preserve the image at the user's insertion
190
- point. Never leave the temporary preview URL in source.
191
- - An edit with `kind: "moved"` means the user relocated that whole block.
192
- Reposition it in the source without rewriting its content: it now sits right
193
- after the block whose text starts with `moved_after`, and right before the
194
- block whose text starts with `moved_before`. An empty `moved_after` means it
195
- is now the first block in its container.
196
- - Find each comment by its `quote`; that exact string is in the file.
197
- - `kind: "element"` points at a whole block, so `quote` is its label, not body text.
198
- - Fix every page in `pages`, not just the first.
199
- - **Do not write a reply.** There is no chat. The user sees the updated page and
200
- can choose Changes for a fixed Send-to-result comparison. Reload may wait
201
- for the user to handle unsaved review work. Live result capture may require
202
- a contextual retry; never describe unavailable history as no changes.
203
- - Review history uses local content/source snapshots, not screenshots or Git
204
- commits. Do not create commits or alter repository state to populate history.
205
-
206
- ## Better edit labels (optional)
207
-
208
- Name the sections you author and the user's edit list uses your names instead of
209
- guessing from the DOM:
210
-
211
- ```html
212
- <p data-block="Problem body">…</p>
213
- <div data-container="Metrics callout">…</div>
27
+ Keep this foreground wait active. If the shell returns a handle, wait on that
28
+ handle. The default timeout is 12 hours; explicit timeout includes discovery and
29
+ reconnect. On `timeout`, repeat the same poll. On `ended`, stop. On `work`, retain
30
+ the submission identity/version and handle only that work.
31
+
32
+ `submission.inventory` contains pages, messages, edits and any result outcomes.
33
+ Follow `nextCursor` until `complete`; counts cover the full obligation.
34
+ `inline` is complete; retrieve `reference` content as needed. Read necessary
35
+ evidence and authoritative source before editing; exporting is not reading.
36
+ Delivery references/previews are NOT capture truncation.
37
+
38
+ Read relevant references:
39
+
40
+ - Before responding, read [response-contract](references/response-contract.md).
41
+ Use `handoff.templateCommand` to create the complete inventory in a new file.
42
+ Its blank outcomes/prose intentionally fail validation. Fill them truthfully.
43
+ - Before any source work, read [source-edits](references/source-edits.md).
44
+ - For reviewer UI, follow-ups, large content, paging, compaction or recovery, read
45
+ [context-and-recovery](references/context-and-recovery.md). Start with the
46
+ closest relevant previous exchange or `handoff.historyCommand` (`--limit 1`).
47
+ Do not load all history eagerly. Agent context excludes current,
48
+ later and saved-unsent messages; browser drafts are not agent instructions.
49
+
50
+ ## Non-negotiable boundaries
51
+
52
+ Discuss means answer without source edits. Each request-change permits only that
53
+ specific change, not blanket editing. The overall note has independent intent;
54
+ historical intent never renews permission. Clarify or defer unsafe/ambiguous work.
55
+
56
+ Preserve exact human text, formatting, moves, deletions and assets in true source.
57
+ Never reapply an edit with saved evidence. Never apply capture-truncated content
58
+ as complete or invent missing text. Missing targets require identification or
59
+ clarification, not guessed replacements.
60
+
61
+ Respond exactly once per submitted message and exact edit version, plus one
62
+ independent `resultNote`. A note requires scalar `overallOutcome`; its prose goes
63
+ in `resultNote`. Do not invent success.
64
+
65
+ Fill `summary` with 1-2 orientation sentences; `resultNote` is the full answer.
66
+ Lead replies with the answer or exact clarification question. Aim for 1-2
67
+ sentences and up to 3 useful bullets (40-90 words, not a limit). Use Markdown;
68
+ avoid boilerplate, IDs/hashes and evidence dumps unless needed.
69
+ Never auto-resend deferred/abandoned edits; they remain visible for follow-up.
70
+
71
+ ```sh
72
+ npx -y @erdemtuna/doc-review respond --review <reviewId> --entry <entryKey> --response-file response.json --timeout 600
214
73
  ```
215
74
 
216
- `data-block` names a region for the edit list. `data-container` also gives the block a
217
- stable label for its hover/focus comment affordance.
75
+ After acceptance, poll the same review. Retry an uncertain response using the
76
+ identical file/requestId; never repeat source edits because transport failed.
77
+ End freezes reviewer content but does not cancel accepted work. Abandoned work
78
+ cannot complete and does not imply the external handler stopped. Delivery is not
79
+ agent liveness. One cooperating handler is assumed; receipts do not give worker
80
+ leases or filesystem exactly-once guarantees. Stop if the user cancels.
@@ -0,0 +1,24 @@
1
+ import { agentHandoffSchema, agentReferenceSchema } from "./contracts/agent.js";
2
+ import { invocation, shellQuote } from "./setup.js";
3
+ import { createHash } from "node:crypto";
4
+ export const AGENT_INSTRUCTIONS = "Read the installed doc-review skill. Discuss is not edit permission; each request-change is scoped. " +
5
+ "Read complete required evidence and every inventory page. Never reapply saved edits or apply capture-truncated edits. " +
6
+ "Fill the complete template; retry the same response file/request, not source edits. Historical intent is not permission.";
7
+ export function agentHandoff(reference, submissionId = null, command = invocation()) {
8
+ const { reviewId, entryKey } = agentReferenceSchema.parse(reference);
9
+ const scope = `--review ${shellQuote(reviewId)} --entry ${shellQuote(entryKey)}`;
10
+ const responseFile = submissionId
11
+ ? `response-${createHash("sha256").update(JSON.stringify([reviewId, entryKey, submissionId])).digest("hex").slice(0, 32)}.json`
12
+ : "response.json";
13
+ return agentHandoffSchema.parse({
14
+ pollCommand: `${command} poll ${scope} --timeout 600`,
15
+ statusCommand: `${command} status ${scope}`,
16
+ responseCommand: `${command} respond ${scope} --response-file ${responseFile} --timeout 600`,
17
+ historyCommand: `${command} history ${scope}${submissionId ? ` --before ${shellQuote(submissionId)}` : ""} --limit 1`,
18
+ ...(submissionId ? {
19
+ submissionCommand: `${command} submission ${scope} --submission ${shellQuote(submissionId)}`,
20
+ templateCommand: `${command} response-template ${scope} --submission ${shellQuote(submissionId)} --output-file ${responseFile}`,
21
+ } : {}),
22
+ instructions: submissionId ? AGENT_INSTRUCTIONS : "Read the installed doc-review skill. Status/delivery is evidence, not agent liveness.",
23
+ });
24
+ }