@mediagato/modelreins-channel 4.12.4 → 4.12.5

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.
@@ -6,9 +6,11 @@
6
6
  * ModelReins MCP Channel
7
7
  * ======================
8
8
  * Bridges any Claude Code session — CLI or VSCode extension — to a ModelReins
9
- * fleet. Once installed, this session becomes a named worker: it receives jobs
10
- * from the dashboard, executes them with full local access (files, git, shell,
11
- * env vars, browser), and reports results back in real time.
9
+ * fleet. Once installed, this session becomes a named worker: by default it
10
+ * receives jobs from the dashboard, executes them with full local access
11
+ * (files, git, shell, env vars, browser), and reports results back in real
12
+ * time. Set MODELREINS_RECEIVE_JOBS=false for outbound-only — dispatch/status
13
+ * stay available, nothing here ever executes a dispatched job (see below).
12
14
  *
13
15
  * How it works
14
16
  * ------------
@@ -51,6 +53,9 @@
51
53
  * -e MODELREINS_WORKER=my-laptop \
52
54
  * -- npx -y @mediagato/modelreins-channel
53
55
  *
56
+ * Outbound-only (this machine can dispatch to the fleet, the fleet can never
57
+ * dispatch to it): add -e MODELREINS_RECEIVE_JOBS=false to either option above.
58
+ *
54
59
  * ─────────────────────────────────────────────────────────────────────────────
55
60
  * QUICK START — VSCode (Claude Code extension)
56
61
  * ─────────────────────────────────────────────────────────────────────────────
@@ -121,6 +126,19 @@
121
126
  * Lower = more responsive, higher = less network.
122
127
  * Minimum recommended: 2000.
123
128
  *
129
+ * MODELREINS_RECEIVE_JOBS — Whether this session accepts dispatched jobs.
130
+ * Default: "true" (unchanged from every prior
131
+ * version — existing installs need no changes).
132
+ * Set to "false" for an outbound-only session:
133
+ * modelreins_dispatch/status/recruit/complete/
134
+ * result stay available so you can still hand
135
+ * work OUT to the fleet, but job polling never
136
+ * starts, so nothing ever arrives as a <channel>
137
+ * tag and nothing here executes unattended.
138
+ * Use this for a machine you're actively driving
139
+ * interactively that should never become a
140
+ * dispatch target itself.
141
+ *
124
142
  * ─────────────────────────────────────────────────────────────────────────────
125
143
  * AVAILABLE TOOLS (visible to Claude in every session)
126
144
  * ─────────────────────────────────────────────────────────────────────────────
@@ -222,6 +240,22 @@ const WORKER_MODEL = process.env.MODELREINS_WORKER_MODEL || 'claude-session';
222
240
  */
223
241
  const WORKER_TAGS = process.env.MODELREINS_WORKER_TAGS || 'local,interactive,full-access';
224
242
 
243
+ /**
244
+ * Whether this session accepts dispatched jobs from the dashboard at all.
245
+ * Default 'true' preserves the channel's original all-or-nothing behavior —
246
+ * every existing install keeps working exactly as before with no env changes.
247
+ * Set MODELREINS_RECEIVE_JOBS=false for an outbound-only session: the
248
+ * modelreins_dispatch/status/recruit/complete/result tools stay available (a
249
+ * session can still hand work OUT to the fleet), but pollJobs() never starts,
250
+ * so nothing ever arrives as a <channel> tag and nothing here ever executes
251
+ * unattended. Added 2026-08-30 after a real setup mistake: this channel was
252
+ * described to a second Claude Code seat as "outbound-only," which the
253
+ * channel as shipped has never actually supported — every install has always
254
+ * been fully bidirectional, receive included, with no way to opt out. This
255
+ * flag is the actual missing feature, not a workaround.
256
+ */
257
+ const RECEIVE_JOBS = (process.env.MODELREINS_RECEIVE_JOBS || 'true').toLowerCase() !== 'false';
258
+
225
259
  // ── HTTP Client ───────────────────────────────────────────────────────────────
226
260
  //
227
261
  // Thin wrapper around fetch — attaches auth, serializes body, swallows
@@ -294,24 +328,34 @@ const mcp = new Server(
294
328
 
295
329
  // System-level instructions Claude receives when the channel is connected.
296
330
  // These prime Claude to handle incoming jobs correctly without the user
297
- // having to explain the setup in every session.
331
+ // having to explain the setup in every session. Built conditionally on
332
+ // RECEIVE_JOBS so the session is told the truth about what it actually
333
+ // does — an outbound-only session should never be primed to expect
334
+ // <channel> tags that pollJobs() (gated below) will never produce.
298
335
  instructions: [
299
336
  `You are connected to ModelReins (${BASE_URL}) as worker "${WORKER_NAME}".`,
300
337
  `Your capability tags: ${WORKER_TAGS}`,
301
338
  '',
302
- 'RECEIVING JOBS:',
303
- 'Jobs from the ModelReins dashboard arrive as <channel source="modelreins" job_id="..." priority="..."> tags.',
304
- 'When a job arrives, read the prompt inside the tag and execute it using your full local capabilities.',
305
- 'Treat dispatched jobs with the same care as user requests — use your tools, check your work.',
306
- '',
307
- 'COMPLETING JOBS:',
308
- 'Always call modelreins_complete when you finish, whether the task succeeded or failed.',
309
- 'Never leave a job in "running" state — it blocks the queue and confuses the dashboard.',
310
- 'A good summary is 1-3 sentences: what you did, what changed, any caveats.',
311
- '',
312
- 'BETWEEN JOBS:',
313
- 'You remain a fully normal Claude Code session. The user can still talk to you, open files,',
314
- 'run commands, etc. The ModelReins channel is invisible until work arrives.',
339
+ ...(RECEIVE_JOBS ? [
340
+ 'RECEIVING JOBS:',
341
+ 'Jobs from the ModelReins dashboard arrive as <channel source="modelreins" job_id="..." priority="..."> tags.',
342
+ 'When a job arrives, read the prompt inside the tag and execute it using your full local capabilities.',
343
+ 'Treat dispatched jobs with the same care as user requests — use your tools, check your work.',
344
+ '',
345
+ 'COMPLETING JOBS:',
346
+ 'Always call modelreins_complete when you finish, whether the task succeeded or failed.',
347
+ 'Never leave a job in "running" state — it blocks the queue and confuses the dashboard.',
348
+ 'A good summary is 1-3 sentences: what you did, what changed, any caveats.',
349
+ '',
350
+ 'BETWEEN JOBS:',
351
+ 'You remain a fully normal Claude Code session. The user can still talk to you, open files,',
352
+ 'run commands, etc. The ModelReins channel is invisible until work arrives.',
353
+ ] : [
354
+ 'OUTBOUND-ONLY MODE (MODELREINS_RECEIVE_JOBS=false):',
355
+ 'This session does NOT receive dispatched jobs. No polling ever runs, no <channel> tag will',
356
+ 'ever appear here, and nothing on the ModelReins dashboard can execute anything on this',
357
+ 'machine. You can dispatch work OUT to the fleet (below) but nothing dispatches IN.',
358
+ ]),
315
359
  '',
316
360
  'DISPATCHING TO OTHER WORKERS:',
317
361
  'Use modelreins_dispatch to hand off subtasks. This is powerful: you can split a large job,',
@@ -1354,9 +1398,15 @@ async function stuckJobWatchdog() {
1354
1398
  }
1355
1399
  }
1356
1400
 
1357
- // Kick off the background loops.
1401
+ // Kick off the background loops. Heartbeat always runs (presence/status display
1402
+ // on the dashboard); pollJobs is what actually claims and executes dispatched
1403
+ // work, so it's the one RECEIVE_JOBS gates.
1358
1404
  setInterval(heartbeat, 30_000);
1359
- setInterval(pollJobs, POLL_MS);
1405
+ if (RECEIVE_JOBS) {
1406
+ setInterval(pollJobs, POLL_MS);
1407
+ } else {
1408
+ console.error('[channel] MODELREINS_RECEIVE_JOBS=false — outbound-only, job polling disabled');
1409
+ }
1360
1410
  setInterval(stuckJobWatchdog, 60_000);
1361
1411
 
1362
1412
  // Initial heartbeat fires immediately so the worker shows as online right away.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediagato/modelreins-channel",
3
- "version": "4.12.4",
3
+ "version": "4.12.5",
4
4
  "description": "ModelReins MCP Channel — turn any Claude Code session into a ModelReins worker",
5
5
  "type": "module",
6
6
  "main": "modelreins-channel.mjs",