tandem-editor 0.17.0 → 0.18.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/.claude-plugin/plugin.json +4 -4
- package/CHANGELOG.md +16 -2
- package/dist/cli/index.js +179 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/monitor/index.js +6 -3
- package/dist/monitor/index.js.map +1 -1
- package/dist/server/index.js +20 -10
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/tandem/SKILL.md +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tandem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Edit and iterate on documents with any MCP-capable AI. Claude is the default and best-supported client today.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Tandem"
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"mcpServers": {
|
|
12
12
|
"tandem": {
|
|
13
13
|
"command": "npx",
|
|
14
|
-
"args": ["-y", "tandem-editor@0.
|
|
14
|
+
"args": ["-y", "tandem-editor@0.18.0", "mcp-stdio"],
|
|
15
15
|
"env": {
|
|
16
16
|
"TANDEM_URL": "http://127.0.0.1:3479"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"tandem-channel": {
|
|
20
20
|
"command": "npx",
|
|
21
|
-
"args": ["-y", "tandem-editor@0.
|
|
21
|
+
"args": ["-y", "tandem-editor@0.18.0", "channel"],
|
|
22
22
|
"env": {
|
|
23
23
|
"TANDEM_URL": "http://127.0.0.1:3479"
|
|
24
24
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"monitors": [
|
|
29
29
|
{
|
|
30
30
|
"name": "tandem-events",
|
|
31
|
-
"command": "
|
|
31
|
+
"command": "npx -y tandem-editor@0.18.0 monitor",
|
|
32
32
|
"description": "Tandem real-time document events (annotations, chat, selections)"
|
|
33
33
|
}
|
|
34
34
|
]
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to Tandem will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.18.0] - 2026-07-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Real-time push now works for manually-launched Claude Code sessions, through the plugin monitor (#1201).** Until now, a Claude Code session received live document events (annotations, chat, selections) only if Tandem's own auto-launcher started it with a special flag — a session you started yourself by hand got nothing and had to poll for changes. The Tandem plugin now ships a *monitor* that Claude Code 2.1.212+ activates at launch and that pushes those events with no flag required. Install it once — `claude plugin marketplace add bloknayrb/tandem`, then `claude plugin install tandem@tandem-editor` — and every `claude` you start afterward wakes on document changes. (This is a Claude Code plugin capability; the desktop app and Cowork keep using their existing transports and are unchanged by this release.)
|
|
13
|
+
|
|
14
|
+
One caveat: if you install the plugin *and* also launch with `--dangerously-load-development-channels server:tandem-channel`, both transports deliver each event and you'll see it twice. For a hand-launched session, install the plugin and drop the flag.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **The server no longer crashes when an event subscriber's connection drops abruptly (#1202).** The `/api/events` push stream sends a periodic keepalive; if the client socket had already died, that write threw from inside a timer where nothing caught it, and the unhandled error took the whole server process down. The keepalive and event writes are now guarded and clean up the dead subscriber instead of crashing.
|
|
19
|
+
|
|
20
|
+
### Internal
|
|
21
|
+
|
|
22
|
+
- **The `tandem_checkInbox` tool description now explains why to poll steadily (#1200).** A session can't tell from the server whether real-time push is actually reaching it, so the guidance to poll at a steady cadence — plus the note that polling dedups against already-pushed items, making it cheap and safe — now lives in the tool description itself. That reaches every MCP client, not only the ones that installed the Tandem skill.
|
|
23
|
+
|
|
8
24
|
## [0.17.0] - 2026-07-17
|
|
9
25
|
|
|
10
26
|
### Changed
|
|
@@ -19,8 +35,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
35
|
|
|
20
36
|
- **Keyboard activation works again in the Cowork "admin declined" dialog (#1186).** The dialog sits inside its backdrop, whose unguarded keydown handler called `preventDefault()` on Enter/Space as they bubbled up from the dialog's own buttons and the Learn-more link — so every control in that dialog was dead to the keyboard, and pressing a key dismissed the dialog out from under you. The backdrop now only acts on events that originate on itself.
|
|
21
37
|
|
|
22
|
-
- **The text selection popup no longer paints a stray frosted-glass rectangle behind itself (#1189).** Selecting text in the desktop app drew a blurred rectangle spanning the popup's whole bounding box — including the empty space beside the narrower Annotate row, where no chrome is actually visible. The shared `.tandem-floating-pill` recipe carried a `backdrop-filter: blur(8px)` that every other pill hides behind its opaque background; the selection popup's shell is deliberately transparent (the two-capsule design), so there the blur had nothing to hide behind. The blur is now gone from the recipe, where it was invisible dead weight on every other surface anyway. The popup's capsules keep their background, border, shadow, and the gap the editor shows through — unchanged.
|
|
23
|
-
|
|
24
38
|
- **The text selection popup no longer paints a stray frosted-glass rectangle behind itself (#1189).** Selecting text in the desktop app drew a blurred rectangle spanning the popup's whole bounding box — including the empty space beside the narrower Annotate row, where no chrome is actually visible. The shared `.tandem-floating-pill` recipe carried a `backdrop-filter: blur(8px)` that every other pill hides behind its opaque background; the selection popup's shell is deliberately transparent (the two-capsule design), so there the blur had nothing to hide behind. The blur is now gone from the recipe, where it was invisible dead weight on every other surface anyway. The popup's capsules keep their background, border, shadow, and the gap the editor shows through — unchanged.
|
|
25
39
|
|
|
26
40
|
Only production builds were affected, which is why it survived since the two-capsule popup landed in #798: that redesign shipped with a `backdrop-filter: none` reset on the shell meant to cancel the recipe's blur, and the reset never survived minification. lightningcss (Vite's default CSS minifier) collapses a `backdrop-filter` + `-webkit-backdrop-filter` pair into the `-webkit-` form alone, and Chromium does not honour the prefixed form, so the reset silently evaporated in the packaged app while working fine in dev. That minifier hazard is tracked separately in #1188; a regression test now forbids both the blur on the recipe and the prefixed-pair pattern that hid it.
|
package/dist/cli/index.js
CHANGED
|
@@ -290,7 +290,7 @@ function resolveChannelDist(env = process.env, exists = existsSync) {
|
|
|
290
290
|
return resolve2(PACKAGE_ROOT, "dist/channel/index.js");
|
|
291
291
|
}
|
|
292
292
|
function resolveCliVersion() {
|
|
293
|
-
if (true) return "0.
|
|
293
|
+
if (true) return "0.18.0";
|
|
294
294
|
if (typeof __APP_VERSION__ !== "undefined") return __APP_VERSION__;
|
|
295
295
|
for (const rel of ["../../package.json", "../../../package.json"]) {
|
|
296
296
|
try {
|
|
@@ -1238,7 +1238,7 @@ function printPushStatus() {
|
|
|
1238
1238
|
|
|
1239
1239
|
` : "";
|
|
1240
1240
|
console.error(
|
|
1241
|
-
"\n\x1B[1mReal-time push notifications:\x1B[0m\n" + (channelRegistered ? " \x1B[32mEnabled\x1B[0m \u2014 the channel shim is registered; Claude Code receives events in real time.\n Relaunch any Claude Code session you started manually so it picks up the new server.\n\n" : " \x1B[33mUnavailable\x1B[0m \u2014 dist/channel/index.js not found; Claude Code will poll via tandem_checkInbox.\n Run 'npm run build' and re-run setup to enable push.\n\n") + " A Tandem plugin is also published (skill + MCP
|
|
1241
|
+
"\n\x1B[1mReal-time push notifications:\x1B[0m\n" + (channelRegistered ? " \x1B[32mEnabled\x1B[0m \u2014 the channel shim is registered; Claude Code receives events in real time.\n Relaunch any Claude Code session you started manually so it picks up the new server.\n\n" : " \x1B[33mUnavailable\x1B[0m \u2014 dist/channel/index.js not found; Claude Code will poll via tandem_checkInbox.\n Run 'npm run build' and re-run setup to enable push.\n\n") + " A Tandem plugin is also published (skill + MCP + a real-time monitor that\n activates on Claude Code 2.1.212+ and needs no --dangerously-... flag):\n\n claude plugin marketplace add bloknayrb/tandem\n claude plugin install tandem@tandem-editor\n\n" + devInstructions
|
|
1242
1242
|
);
|
|
1243
1243
|
}
|
|
1244
1244
|
var init_setup = __esm({
|
|
@@ -1822,7 +1822,7 @@ var init_types2 = __esm({
|
|
|
1822
1822
|
|
|
1823
1823
|
// src/shared/types.ts
|
|
1824
1824
|
import { z } from "zod";
|
|
1825
|
-
var AnnotationTypeSchema, AnnotationStatusSchema, HighlightColorSchema, SeveritySchema, TandemModeSchema, AuthorSchema, ReplyAuthorSchema, AnnotationActionSchema, ExportFormatSchema, DocumentFormatSchema, ToolErrorCodeSchema, ChannelErrorCodeSchema, CHANNEL_CONNECT_FAILED;
|
|
1825
|
+
var AnnotationTypeSchema, AnnotationStatusSchema, HighlightColorSchema, SeveritySchema, TandemModeSchema, AuthorSchema, ReplyAuthorSchema, AnnotationActionSchema, ExportFormatSchema, DocumentFormatSchema, ToolErrorCodeSchema, ChannelErrorCodeSchema, CHANNEL_CONNECT_FAILED, MONITOR_CONNECT_FAILED;
|
|
1826
1826
|
var init_types3 = __esm({
|
|
1827
1827
|
"src/shared/types.ts"() {
|
|
1828
1828
|
"use strict";
|
|
@@ -1852,6 +1852,7 @@ var init_types3 = __esm({
|
|
|
1852
1852
|
]);
|
|
1853
1853
|
ChannelErrorCodeSchema = z.enum(["CHANNEL_CONNECT_FAILED", "MONITOR_CONNECT_FAILED"]);
|
|
1854
1854
|
CHANNEL_CONNECT_FAILED = "CHANNEL_CONNECT_FAILED";
|
|
1855
|
+
MONITOR_CONNECT_FAILED = "MONITOR_CONNECT_FAILED";
|
|
1855
1856
|
}
|
|
1856
1857
|
});
|
|
1857
1858
|
|
|
@@ -2155,6 +2156,63 @@ function refreshMode(tandemUrl, logPrefix) {
|
|
|
2155
2156
|
cachedModeFailedAt = Date.now();
|
|
2156
2157
|
});
|
|
2157
2158
|
}
|
|
2159
|
+
async function flushFinalAwareness(tandemUrl, logPrefix = "[Tandem]") {
|
|
2160
|
+
if (shutdownTimers.awarenessTimer) clearTimeout(shutdownTimers.awarenessTimer);
|
|
2161
|
+
if (shutdownTimers.clearAwarenessTimer) clearTimeout(shutdownTimers.clearAwarenessTimer);
|
|
2162
|
+
if (outstandingAwareness.size > 0) {
|
|
2163
|
+
await Promise.allSettled(outstandingAwareness);
|
|
2164
|
+
}
|
|
2165
|
+
if (shutdownTimers.lastDocumentId === null) return true;
|
|
2166
|
+
try {
|
|
2167
|
+
const res = await fetchWithTimeout(
|
|
2168
|
+
`${tandemUrl}${API_CHANNEL_AWARENESS}`,
|
|
2169
|
+
{
|
|
2170
|
+
method: "POST",
|
|
2171
|
+
headers: { "Content-Type": "application/json" },
|
|
2172
|
+
body: JSON.stringify({
|
|
2173
|
+
documentId: shutdownTimers.lastDocumentId,
|
|
2174
|
+
status: "idle",
|
|
2175
|
+
active: false
|
|
2176
|
+
})
|
|
2177
|
+
},
|
|
2178
|
+
CHANNEL_AWARENESS_FETCH_TIMEOUT_MS
|
|
2179
|
+
);
|
|
2180
|
+
if (!res.ok) {
|
|
2181
|
+
console.error(`${logPrefix} Shutdown awareness clear returned ${res.status}`);
|
|
2182
|
+
return false;
|
|
2183
|
+
}
|
|
2184
|
+
return true;
|
|
2185
|
+
} catch (err) {
|
|
2186
|
+
console.error(
|
|
2187
|
+
`${logPrefix} Shutdown awareness clear failed:`,
|
|
2188
|
+
describeFetchError(
|
|
2189
|
+
err,
|
|
2190
|
+
`${API_CHANNEL_AWARENESS} shutdown`,
|
|
2191
|
+
CHANNEL_AWARENESS_FETCH_TIMEOUT_MS
|
|
2192
|
+
)
|
|
2193
|
+
);
|
|
2194
|
+
return false;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
function _resetSseConsumerStateForTests() {
|
|
2198
|
+
cachedMode = TANDEM_MODE_DEFAULT;
|
|
2199
|
+
cachedModeAt = 0;
|
|
2200
|
+
cachedModeFailedAt = 0;
|
|
2201
|
+
_modeRefreshInFlight = null;
|
|
2202
|
+
shutdownTimers.awarenessTimer = null;
|
|
2203
|
+
shutdownTimers.clearAwarenessTimer = null;
|
|
2204
|
+
shutdownTimers.lastDocumentId = null;
|
|
2205
|
+
outstandingAwareness.clear();
|
|
2206
|
+
}
|
|
2207
|
+
function _setLastDocumentIdForTests(id) {
|
|
2208
|
+
shutdownTimers.lastDocumentId = id;
|
|
2209
|
+
}
|
|
2210
|
+
function _getLastDocumentIdForTests() {
|
|
2211
|
+
return shutdownTimers.lastDocumentId;
|
|
2212
|
+
}
|
|
2213
|
+
function _addOutstandingAwarenessForTests(p) {
|
|
2214
|
+
trackAwareness(p);
|
|
2215
|
+
}
|
|
2158
2216
|
var AWARENESS_DEBOUNCE_MS, AWARENESS_CLEAR_MS, MODE_CACHE_TTL_MS, STABLE_CONNECTION_MS, RETRY_MAX_DELAY_MS, shutdownTimers, outstandingAwareness, cachedMode, cachedModeAt, cachedModeFailedAt, _modeRefreshInFlight;
|
|
2159
2217
|
var init_sse_consumer = __esm({
|
|
2160
2218
|
"src/shared/sse-consumer.ts"() {
|
|
@@ -2417,6 +2475,114 @@ var init_channel = __esm({
|
|
|
2417
2475
|
}
|
|
2418
2476
|
});
|
|
2419
2477
|
|
|
2478
|
+
// src/monitor/run.ts
|
|
2479
|
+
var run_exports = {};
|
|
2480
|
+
__export(run_exports, {
|
|
2481
|
+
_addOutstandingAwarenessForTests: () => _addOutstandingAwarenessForTests2,
|
|
2482
|
+
_getLastDocumentIdForTests: () => _getLastDocumentIdForTests2,
|
|
2483
|
+
_monitorTestExports: () => _monitorTestExports,
|
|
2484
|
+
_resetMonitorStateForTests: () => _resetMonitorStateForTests,
|
|
2485
|
+
_setLastDocumentIdForTests: () => _setLastDocumentIdForTests2,
|
|
2486
|
+
connectAndStream: () => connectAndStream,
|
|
2487
|
+
getCachedMode: () => getCachedMode2,
|
|
2488
|
+
getModeSync: () => getModeSync2,
|
|
2489
|
+
main: () => main,
|
|
2490
|
+
shutdownMonitor: () => shutdownMonitor
|
|
2491
|
+
});
|
|
2492
|
+
function buildOptions() {
|
|
2493
|
+
return {
|
|
2494
|
+
tandemUrl: TANDEM_URL,
|
|
2495
|
+
logPrefix: LOG_PREFIX,
|
|
2496
|
+
errorCode: MONITOR_CONNECT_FAILED,
|
|
2497
|
+
onEvent: (event) => {
|
|
2498
|
+
const content = formatEventContent(event).replace(/\n/g, " ");
|
|
2499
|
+
process.stdout.write(content + "\n");
|
|
2500
|
+
},
|
|
2501
|
+
onExhaustion: () => {
|
|
2502
|
+
process.stdout.write(
|
|
2503
|
+
"Tandem monitor disconnected \u2014 restart Tandem to restore real-time events\n"
|
|
2504
|
+
);
|
|
2505
|
+
}
|
|
2506
|
+
};
|
|
2507
|
+
}
|
|
2508
|
+
async function main() {
|
|
2509
|
+
installShutdownHandlers();
|
|
2510
|
+
installStdoutErrorHandler();
|
|
2511
|
+
console.error(`${LOG_PREFIX} Tandem monitor starting (server: ${TANDEM_URL})`);
|
|
2512
|
+
await getCachedMode2().catch(() => {
|
|
2513
|
+
});
|
|
2514
|
+
await runEventConsumer(buildOptions());
|
|
2515
|
+
}
|
|
2516
|
+
async function connectAndStream(lastEventId, onEventId, onStable = () => {
|
|
2517
|
+
}) {
|
|
2518
|
+
return connectAndStreamOnce(buildOptions(), lastEventId, { onEventId, onStable });
|
|
2519
|
+
}
|
|
2520
|
+
async function shutdownMonitor(signal) {
|
|
2521
|
+
console.error(`${LOG_PREFIX} Received ${signal}, clearing awareness and exiting`);
|
|
2522
|
+
const ok = await flushFinalAwareness(TANDEM_URL, LOG_PREFIX);
|
|
2523
|
+
process.exit(ok ? 0 : 1);
|
|
2524
|
+
}
|
|
2525
|
+
function _setLastDocumentIdForTests2(id) {
|
|
2526
|
+
_setLastDocumentIdForTests(id);
|
|
2527
|
+
}
|
|
2528
|
+
function _getLastDocumentIdForTests2() {
|
|
2529
|
+
return _getLastDocumentIdForTests();
|
|
2530
|
+
}
|
|
2531
|
+
function _addOutstandingAwarenessForTests2(p) {
|
|
2532
|
+
_addOutstandingAwarenessForTests(p);
|
|
2533
|
+
}
|
|
2534
|
+
function installShutdownHandlers() {
|
|
2535
|
+
if (IS_VITEST) return;
|
|
2536
|
+
const handler = (signal) => {
|
|
2537
|
+
shutdownMonitor(signal).catch((err) => {
|
|
2538
|
+
console.error(`${LOG_PREFIX} Shutdown handler failed:`, err);
|
|
2539
|
+
process.exit(1);
|
|
2540
|
+
});
|
|
2541
|
+
};
|
|
2542
|
+
process.on("SIGINT", () => handler("SIGINT"));
|
|
2543
|
+
process.on("SIGTERM", () => handler("SIGTERM"));
|
|
2544
|
+
}
|
|
2545
|
+
function onStdoutError(err) {
|
|
2546
|
+
console.error(`${LOG_PREFIX} stdout error (plugin-host pipe likely closed):`, err);
|
|
2547
|
+
process.exit(1);
|
|
2548
|
+
}
|
|
2549
|
+
function installStdoutErrorHandler() {
|
|
2550
|
+
if (IS_VITEST) return;
|
|
2551
|
+
process.stdout.on("error", onStdoutError);
|
|
2552
|
+
}
|
|
2553
|
+
async function getCachedMode2() {
|
|
2554
|
+
return getCachedMode(TANDEM_URL, LOG_PREFIX);
|
|
2555
|
+
}
|
|
2556
|
+
function getModeSync2() {
|
|
2557
|
+
return getModeSync();
|
|
2558
|
+
}
|
|
2559
|
+
function _resetMonitorStateForTests() {
|
|
2560
|
+
_resetSseConsumerStateForTests();
|
|
2561
|
+
process.removeAllListeners("SIGINT");
|
|
2562
|
+
process.removeAllListeners("SIGTERM");
|
|
2563
|
+
}
|
|
2564
|
+
var IS_VITEST, TANDEM_URL, LOG_PREFIX, _monitorTestExports;
|
|
2565
|
+
var init_run2 = __esm({
|
|
2566
|
+
"src/monitor/run.ts"() {
|
|
2567
|
+
"use strict";
|
|
2568
|
+
init_cli_runtime();
|
|
2569
|
+
init_types();
|
|
2570
|
+
init_sse_consumer();
|
|
2571
|
+
init_types3();
|
|
2572
|
+
IS_VITEST = process.env.VITEST === "true";
|
|
2573
|
+
if (!IS_VITEST) {
|
|
2574
|
+
console.log = console.error;
|
|
2575
|
+
console.warn = console.error;
|
|
2576
|
+
console.info = console.error;
|
|
2577
|
+
}
|
|
2578
|
+
TANDEM_URL = resolveTandemUrl();
|
|
2579
|
+
LOG_PREFIX = "[Monitor]";
|
|
2580
|
+
_monitorTestExports = {
|
|
2581
|
+
onStdoutError
|
|
2582
|
+
};
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
|
|
2420
2586
|
// src/server/annotations/lockfile.ts
|
|
2421
2587
|
function parseLockfile(raw) {
|
|
2422
2588
|
const trimmed = raw.trim();
|
|
@@ -3125,7 +3291,7 @@ function evaluateStaleGlobal(bundled, globalVersion) {
|
|
|
3125
3291
|
};
|
|
3126
3292
|
}
|
|
3127
3293
|
async function checkStaleGlobal(r) {
|
|
3128
|
-
const bundled = true ? "0.
|
|
3294
|
+
const bundled = true ? "0.18.0" : null;
|
|
3129
3295
|
if (!bundled) return;
|
|
3130
3296
|
let globalVersion;
|
|
3131
3297
|
try {
|
|
@@ -4218,7 +4384,7 @@ process.once("unhandledRejection", (reason) => {
|
|
|
4218
4384
|
`);
|
|
4219
4385
|
process.exit(1);
|
|
4220
4386
|
});
|
|
4221
|
-
var version = true ? "0.
|
|
4387
|
+
var version = true ? "0.18.0" : "0.0.0-dev";
|
|
4222
4388
|
var args = process.argv.slice(2);
|
|
4223
4389
|
if (args.includes("--help") || args.includes("-h")) {
|
|
4224
4390
|
console.log(`tandem v${version}
|
|
@@ -4246,6 +4412,10 @@ Usage:
|
|
|
4246
4412
|
tandem server running on the host)
|
|
4247
4413
|
tandem channel Run the Tandem channel shim (stdio MCP)
|
|
4248
4414
|
(used by the plugin's tandem-channel entry)
|
|
4415
|
+
tandem monitor Run the Tandem plugin monitor: stream event
|
|
4416
|
+
lines to stdout for Claude Code to surface as
|
|
4417
|
+
notifications (used by the plugin's
|
|
4418
|
+
experimental.monitors entry; needs no flag)
|
|
4249
4419
|
tandem --version
|
|
4250
4420
|
tandem --help
|
|
4251
4421
|
`);
|
|
@@ -4255,7 +4425,7 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
4255
4425
|
console.log(version);
|
|
4256
4426
|
process.exit(0);
|
|
4257
4427
|
}
|
|
4258
|
-
var isStdioMode = args[0] === "mcp-stdio" || args[0] === "channel";
|
|
4428
|
+
var isStdioMode = args[0] === "mcp-stdio" || args[0] === "channel" || args[0] === "monitor";
|
|
4259
4429
|
if (!isStdioMode) {
|
|
4260
4430
|
const { default: updateNotifier } = await import("update-notifier");
|
|
4261
4431
|
updateNotifier({ pkg: { name: "tandem-editor", version } }).notify();
|
|
@@ -4291,6 +4461,9 @@ try {
|
|
|
4291
4461
|
} else if (args[0] === "channel") {
|
|
4292
4462
|
const { runChannelCli: runChannelCli2 } = await Promise.resolve().then(() => (init_channel(), channel_exports));
|
|
4293
4463
|
await runChannelCli2();
|
|
4464
|
+
} else if (args[0] === "monitor") {
|
|
4465
|
+
const { main: main2 } = await Promise.resolve().then(() => (init_run2(), run_exports));
|
|
4466
|
+
await main2();
|
|
4294
4467
|
} else if (args[0] === "doctor") {
|
|
4295
4468
|
const { runDoctorCli: runDoctorCli2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
4296
4469
|
const exitCode = await runDoctorCli2({ json: args.includes("--json") });
|