tandem-editor 0.8.0 → 0.9.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.
- package/CHANGELOG.md +48 -0
- package/README.md +4 -12
- package/dist/channel/index.js +18 -4
- package/dist/channel/index.js.map +1 -1
- package/dist/cli/index.js +19 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/client/assets/{CoworkSettings-CXODT6KV.js → CoworkSettings-C9Dd4D9z.js} +1 -1
- package/dist/client/assets/{index-C6rbXHNq.css → index-Bz3WFCWw.css} +1 -1
- package/dist/client/assets/index-CN_6DqdC.js +228 -0
- package/dist/client/index.html +2 -2
- package/dist/monitor/index.js +1 -1
- package/dist/monitor/index.js.map +1 -1
- package/dist/server/index.js +260 -181
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/tandem/SKILL.md +8 -8
- package/dist/client/assets/index-q_8NVSM3.js +0 -228
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## \[Unreleased]
|
|
9
9
|
|
|
10
|
+
## \[0.9.0] - 2026-04-28
|
|
11
|
+
|
|
12
|
+
### Breaking Changes (MCP)
|
|
13
|
+
|
|
14
|
+
This is the last breaking-change window before semver lock. MCP tool count: 31 → 28.
|
|
15
|
+
|
|
16
|
+
- **`tandem_suggest` deprecated (#259)** — returns a structured error stub pointing to `tandem_comment` with `suggestedText`. Hard-remove in v0.10.0.
|
|
17
|
+
- **`tandem_getContent` removed (#259)** — superseded by `tandem_getTextContent`.
|
|
18
|
+
- **`tandem_getSelections` removed (#259)** — superseded by `tandem_checkInbox`.
|
|
19
|
+
- **`tandem_setStatus` merged into `tandem_status` (#259)** — `tandem_status` now accepts optional write params (`text`, `focusParagraph`, `focusOffset`). When params are present it writes to awareness; when absent it reads.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`/api/info` endpoint (#441)** — returns app version, MCP SDK version, tool count, data directory, and platform. Serves the Settings panel About footer.
|
|
24
|
+
- **Tabbed-left layout variant (#445)** — new `"tabbed-left"` layout mode places the side panel on the left and editor on the right. Three layout modes total: `tabbed`, `tabbed-left`, `three-panel`.
|
|
25
|
+
- **App version in Settings (#435)** — `useAppInfo` hook fetches `/api/info` and displays version + MCP SDK version in the Settings popover footer.
|
|
26
|
+
- **View Changelog button (#437)** — Settings panel button opens `CHANGELOG.md` as a read-only document tab via `POST /api/open` with `readOnly: true`.
|
|
27
|
+
- **Authorship `data-tandem-author` attributes (#443)** — authorship decorations switched from CSS classes (`.tandem-authorship--user`) to data attributes (`[data-tandem-author="user"]`), per ADR-026. Enables future attribute-based styling without class proliferation.
|
|
28
|
+
- **Schema foundations (#440, #442, #444, #450)** — `heldInSolo` field on `AnnotationBase`; 7 new `TandemSettings` fields (`accentHue`, `editorFont`, `density`, `defaultMode`, `highContrast`, `annotationPatterns`, `selectionToolbar`); `showAuthorship` default flipped to `true`; editor width minimum lowered from 50% to 40%.
|
|
29
|
+
- **Highlight palette migration (#450)** — palette switched from 5 colors to 4 (yellow/green/blue/pink). `LEGACY_COLOR_MAP` migrates `red` → `yellow`, `purple` → `blue` on annotation load.
|
|
30
|
+
- **CI stdio smoke test (#341)** — GitHub Actions step validates the Cowork stdio bridge (`scripts/ci/stdio-smoke.mjs`) on every push.
|
|
31
|
+
- **`__MCP_SDK_VERSION__` build-time injection** — tsup reads the real SDK version from the package root (not the CJS type marker) and injects it at build time.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **Cross-element edit merging (#456)** — canonical Y.js length + delta-walking merge for edits spanning multiple inline elements.
|
|
36
|
+
- **Annotation decoration initial-sync race** — Y.Map observers firing before y-prosemirror sync no longer produce empty decoration sets.
|
|
37
|
+
- **Channel checkpoint timing** — checkpoint advances after MCP notification delivery, not before, preventing event loss on reconnect.
|
|
38
|
+
- **Auto-save spurious tab switches** — auto-save no longer triggers `document:switched` events that confuse tab state.
|
|
39
|
+
- **Annotation recovery guard hardening** — narrowed guard scope for edge cases in session restore.
|
|
40
|
+
- **Event-bridge error handling** — uncaught errors in SSE delivery no longer crash the event loop.
|
|
41
|
+
- **MCP SDK version resolution** — `require("@modelcontextprotocol/sdk/package.json")` resolves to `dist/cjs/package.json` (a CJS type marker without `version`); build now walks back past `dist/` to find the real version.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **Redesign gap audit resolved (#439)** — 7 product decisions documented in ADR-026. Design response prompt at `docs/claude-design-response-prompt.md`.
|
|
46
|
+
- **Distribution items deferred** — #316 (macOS/Linux Cowork auto-setup), #317 (cross-platform firewall scoping), #322 (network-type detection) moved to v0.13.0. Requires macOS/Linux validation hardware.
|
|
47
|
+
|
|
48
|
+
### Internal
|
|
49
|
+
|
|
50
|
+
- Annotation schema Zod validation with `LEGACY_COLOR_MAP` migration path.
|
|
51
|
+
- `ResizeHandle` and `TabbedPanelContainer` shared components extracted for layout code reuse.
|
|
52
|
+
- `useAppInfo` hook with exponential backoff retry for `/api/info` fetch.
|
|
53
|
+
- `file-opener` read-only mode support for changelog viewing.
|
|
54
|
+
- 900+ lines of new test coverage: authorship decorations, annotation decorations, panel layout, app info hook, settings fields, schema migration, info route, document edit edge cases.
|
|
55
|
+
|
|
10
56
|
## \[0.8.0] - 2026-04-26
|
|
11
57
|
|
|
12
58
|
### Added
|
|
13
59
|
|
|
60
|
+
- **NSIS pre-install sidecar kill (#434)** — the NSIS installer now kills the running `node-sidecar.exe` process before file replacement, preventing "Error opening file for writing" failures during upgrade installs. Uses `nsis_tauri_utils::KillProcessCurrentUser` for user-scoped process termination. Tauri's built-in `CheckIfAppIsRunning` already handles the main binary.
|
|
61
|
+
|
|
14
62
|
- **Semantic token lint enforcement (#356)** — `npm run check:tokens` scans `src/client/` for raw hex and non-neutral `rgba()` violations. Runs on pre-commit via lint-staged, blocking merges that introduce unsanctioned color literals.
|
|
15
63
|
- **`--tandem-suggestion-*` token family (#340)** — violet semantic tokens for replacement/suggestion annotations (`--tandem-suggestion`, `-fg-strong`, `-bg`, `-border`), visually distinct from the indigo accent family.
|
|
16
64
|
- **Annotation drop count surfacing (#351)** — `normalizeAnnotation` now returns drop counts in snapshot metadata so callers can detect lossy session migrations.
|
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@ Have you ever been working on a piece of writing with an LLM and caught yourself
|
|
|
6
6
|
|
|
7
7
|
And because Tandem hooks into Claude as an MCP server, you're not stuck in some stripped-down document-editing silo. It's the full Claude — with all its knowledge, your conversation context, and every tool it has access to — just now it can also see and edit your document.
|
|
8
8
|
|
|
9
|
-

|
|
10
|
-
|
|
11
9
|
## Why Tandem?
|
|
12
10
|
|
|
13
11
|
- **No more copy-paste ping-pong.** Select text in the editor, and Claude reads your selection directly. Ask "what do you think of this?" or "make this more concise" — Claude knows exactly which text you mean.
|
|
@@ -154,20 +152,14 @@ Everything in Tandem is built around one idea: you work in the document, Claude
|
|
|
154
152
|
|
|
155
153
|
### Chat
|
|
156
154
|
|
|
157
|
-

|
|
158
|
-
|
|
159
155
|
Send messages to Claude alongside your document. Select text before sending to attach it as context — Claude sees exactly what you mean. Clicking an anchored selection later scrolls back to that passage.
|
|
160
156
|
|
|
161
157
|
### Annotations
|
|
162
158
|
|
|
163
|
-

|
|
164
|
-
|
|
165
159
|
This is how Claude's feedback shows up in the document. Claude adds highlights, comments, suggestions, and flags directly on the text. Suggestion cards show a visual diff — original text in red strikethrough, replacement in green. The side panel lists all annotations with filtering by type, author, and status. Accept, dismiss, or edit each one individually — or use bulk actions to process them in batches.
|
|
166
160
|
|
|
167
161
|
### Review Mode
|
|
168
162
|
|
|
169
|
-

|
|
170
|
-
|
|
171
163
|
Press **Ctrl+Shift+R** to enter keyboard review mode. Navigate with **Tab**, accept with **Y**, dismiss with **N**, examine with **E**. A 10-second undo window with a visual countdown lets you reverse accidental accepts. Shortcut hints appear below the Review button.
|
|
172
164
|
|
|
173
165
|
### More
|
|
@@ -193,7 +185,7 @@ Press **Ctrl+Shift+R** to enter keyboard review mode. Navigate with **Tab**, acc
|
|
|
193
185
|
|
|
194
186
|
## Where Tandem is headed
|
|
195
187
|
|
|
196
|
-
Since the v0.4.0 desktop app launch, Tandem has added auth tokens for LAN exposure (v0.7.0), a Claude Code plugin bridge for Cowork and Claude Desktop (v0.6.0+), durable annotation persistence, settings with Light/Dark/System theming,
|
|
188
|
+
Since the v0.4.0 desktop app launch, Tandem has added auth tokens for LAN exposure (v0.7.0), a Claude Code plugin bridge for Cowork and Claude Desktop (v0.6.0+), durable annotation persistence, settings with Light/Dark/System theming, authorship text coloring, and coordinate system correctness fixes with semantic token enforcement (v0.8.0). A few directions on the radar for later releases:
|
|
197
189
|
|
|
198
190
|
- **High-fidelity .docx round-trip** — current `.docx` support is review-only; production export is planned so you can stay in Tandem through the final draft.
|
|
199
191
|
- **Exportable annotated documents** — PDF (and eventually `.docx`) with annotations baked in, so you can share reviewed drafts outside Tandem.
|
|
@@ -205,12 +197,12 @@ See the full [Roadmap](docs/roadmap.md) and [Known Limitations](docs/roadmap.md#
|
|
|
205
197
|
## Documentation
|
|
206
198
|
|
|
207
199
|
- **[User Guide](docs/user-guide.md)** — How to use Tandem: editor UI, annotations, chat, review mode, keyboard shortcuts
|
|
208
|
-
- [MCP Tool Reference](docs/mcp-tools.md) —
|
|
200
|
+
- [MCP Tool Reference](docs/mcp-tools.md) — 28 MCP tools + channel API endpoints
|
|
209
201
|
- [Architecture](docs/architecture.md) — System design, data flows, coordinate systems, channel push
|
|
210
202
|
- [Workflows](docs/workflows.md) — Claude Code usage patterns: text iteration, cross-referencing, multi-model
|
|
211
203
|
- [Roadmap](docs/roadmap.md) — Phase 2+ roadmap, known issues, future extensions
|
|
212
204
|
- [Design Decisions](docs/decisions.md) — ADR-001 through ADR-024
|
|
213
|
-
- [Lessons Learned](docs/lessons-learned.md) —
|
|
205
|
+
- [Lessons Learned](docs/lessons-learned.md) — 48 implementation lessons
|
|
214
206
|
|
|
215
207
|
## CLI Commands
|
|
216
208
|
|
|
@@ -228,7 +220,7 @@ See the full [Roadmap](docs/roadmap.md) and [Known Limitations](docs/roadmap.md#
|
|
|
228
220
|
|
|
229
221
|
## MCP Configuration
|
|
230
222
|
|
|
231
|
-
Tandem registers two MCP connections: **HTTP** for document tools (
|
|
223
|
+
Tandem registers two MCP connections: **HTTP** for document tools (28 tools including annotation editing — always on), and a **channel shim** for real-time push notifications. The channel shim is what enables the live-collaborator experience described in [Connect Claude Code](#connect-claude-code) and is recommended; it activates when you start Claude Code with `--dangerously-load-development-channels server:tandem-channel`. If you'd rather not pass that experimental flag, the entry sits idle and everything still works through polling on the HTTP connection — you just lose spontaneous reactions.
|
|
232
224
|
|
|
233
225
|
**Global install** (`tandem setup`): Automatically writes both entries to `~/.claude/mcp_settings.json` (Claude Code) and/or `claude_desktop_config.json` (Claude Desktop) with absolute paths. No manual configuration needed.
|
|
234
226
|
|
package/dist/channel/index.js
CHANGED
|
@@ -18105,7 +18105,11 @@ async function connectAndStream(mcp, tandemUrl, lastEventId, onEventId) {
|
|
|
18105
18105
|
status: "idle",
|
|
18106
18106
|
active: false
|
|
18107
18107
|
})
|
|
18108
|
-
}).catch(() => {
|
|
18108
|
+
}).catch((err) => {
|
|
18109
|
+
console.error(
|
|
18110
|
+
"[Channel] clearAwareness failed (non-fatal):",
|
|
18111
|
+
err instanceof Error ? err.message : err
|
|
18112
|
+
);
|
|
18109
18113
|
});
|
|
18110
18114
|
}
|
|
18111
18115
|
function flushAwareness() {
|
|
@@ -18151,11 +18155,21 @@ async function connectAndStream(mcp, tandemUrl, lastEventId, onEventId) {
|
|
|
18151
18155
|
try {
|
|
18152
18156
|
event = parseTandemEvent(JSON.parse(data));
|
|
18153
18157
|
} catch {
|
|
18154
|
-
console.error(
|
|
18158
|
+
console.error(
|
|
18159
|
+
"[Channel] Malformed SSE event data (skipping), eventId=%s:",
|
|
18160
|
+
eventId,
|
|
18161
|
+
data.slice(0, 200)
|
|
18162
|
+
);
|
|
18163
|
+
if (eventId) onEventId(eventId);
|
|
18155
18164
|
continue;
|
|
18156
18165
|
}
|
|
18157
18166
|
if (!event) {
|
|
18158
|
-
console.error(
|
|
18167
|
+
console.error(
|
|
18168
|
+
"[Channel] Invalid SSE event structure (skipping), eventId=%s:",
|
|
18169
|
+
eventId,
|
|
18170
|
+
data.slice(0, 200)
|
|
18171
|
+
);
|
|
18172
|
+
if (eventId) onEventId(eventId);
|
|
18159
18173
|
continue;
|
|
18160
18174
|
}
|
|
18161
18175
|
if (event.type !== "chat:message") {
|
|
@@ -18166,7 +18180,6 @@ async function connectAndStream(mcp, tandemUrl, lastEventId, onEventId) {
|
|
|
18166
18180
|
continue;
|
|
18167
18181
|
}
|
|
18168
18182
|
}
|
|
18169
|
-
if (eventId) onEventId(eventId);
|
|
18170
18183
|
try {
|
|
18171
18184
|
await mcp.notification({
|
|
18172
18185
|
method: "notifications/claude/channel",
|
|
@@ -18179,6 +18192,7 @@ async function connectAndStream(mcp, tandemUrl, lastEventId, onEventId) {
|
|
|
18179
18192
|
console.error("[Channel] MCP notification failed (transport broken?):", err);
|
|
18180
18193
|
throw err;
|
|
18181
18194
|
}
|
|
18195
|
+
if (eventId) onEventId(eventId);
|
|
18182
18196
|
scheduleAwareness(event);
|
|
18183
18197
|
}
|
|
18184
18198
|
}
|