@rubytech/create-maxy-code 0.1.463 → 0.1.464
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/package.json +1 -1
- package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +397 -0
- package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +128 -0
- package/payload/platform/lib/graph-mcp/dist/index.js +5 -24
- package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/index.ts +7 -25
- package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +2 -2
- package/payload/platform/lib/mcp-spawn-tee/dist/index.js +2 -2
- package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +0 -25
- package/payload/platform/lib/mcp-spawn-tee/src/index.ts +2 -2
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/admin/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +11 -29
- package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/aeo/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/aeo/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/browser/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/browser/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/connector/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/connector/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/connector/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/contacts/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +10 -28
- package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/email/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/filesystem/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/filesystem/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/filesystem/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/graph-viewer/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/graph-viewer/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/graph-viewer/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/scripts/boot-smoke.sh +0 -1
- package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/quickbooks/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/quickbooks/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/quickbooks/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/replicate/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/replicate/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/telegram/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/url-get/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/url-get/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/voice-mirror/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/voice-mirror/mcp/dist/index.d.ts.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/voice-mirror/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/work/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +2 -2
- package/payload/platform/plugins/workflows/mcp/dist/index.js +0 -2
- package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
- package/payload/platform/scripts/__tests__/logs-rotate.test.sh +2 -2
- package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +21 -14
- package/payload/platform/scripts/logs-rotate.sh +6 -6
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +23 -2
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +27 -2
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +11 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/passive-print-surface.d.ts +10 -0
- package/payload/platform/services/claude-session-manager/dist/passive-print-surface.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/passive-print-surface.js +31 -0
- package/payload/platform/services/claude-session-manager/dist/passive-print-surface.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/print-child-launcher.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/print-child-launcher.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/print-child-launcher.js +50 -0
- package/payload/platform/services/claude-session-manager/dist/print-child-launcher.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +10 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +23 -2
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +2 -2
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/server/server.js +77 -13
- package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts +0 -69
- package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
- package/payload/platform/lib/mcp-stderr-tee/dist/index.js +0 -189
- package/payload/platform/lib/mcp-stderr-tee/dist/index.js.map +0 -1
- package/payload/platform/lib/mcp-stderr-tee/package.json +0 -7
- package/payload/platform/lib/mcp-stderr-tee/src/index.ts +0 -197
- package/payload/platform/lib/mcp-stderr-tee/tsconfig.json +0 -8
package/package.json
CHANGED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# Retire `mcp-stderr-tee` — Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Delete the `mcp-stderr-tee` module, its 21 call sites, and every doc claim that a per-conversation MCP stream log exists — leaving `mcp-spawn-tee`'s per-session raw sink as the single, honest MCP-stderr surface.
|
|
6
|
+
|
|
7
|
+
**Architecture:** This is removal work, not feature work. Each task asserts the current state (grep/build), makes the deletion, then asserts the new state. There is no new runtime behaviour to test; the invariants are grep counts and a clean build. The order is fixed: remove the importers before the module they import, or the build breaks mid-plan.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript (platform workspace at `maxy-code/platform/`), npm workspaces, Node ≥ 22.6.
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Work happens in worktree `worktree-task-1736-retire-mcp-stderr-tee`. All paths below are relative to its `maxy-code/` subdirectory unless absolute.
|
|
14
|
+
- Node ≥ 22.6: `export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH"` before any node/npm command.
|
|
15
|
+
- Deps already installed at `maxy-code/platform/` via `npm install --ignore-scripts`.
|
|
16
|
+
- **Collision guard (Task 5):** task 1737 owns `mcp-spawn-tee`'s stale marker names (`[mcp-spawn-tee-attached]`, `[mcp-spawn-tee-exit]`). Do not rename, restate, or fix them. Where a paragraph this plan edits also contains one, edit only the `initStderrTee`/`STREAM_LOG_PATH` clause and leave the stale name untouched for 1737.
|
|
17
|
+
- **Success invariants (whole plan):** after all tasks, in the live tree (excluding `.tasks/archive/` and `docs/superpowers/`): `initStderrTee` → 0 hits, `mcp-stderr-tee` → 0 hits, `STREAM_LOG_PATH` → 0 hits.
|
|
18
|
+
- Shipped-doc prose rule: the rewritten `plugins-guide.md` prose carries zero em-dashes (per repo doctrine for shipped markdown).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### Task 1: Remove the 21 `initStderrTee` call sites
|
|
23
|
+
|
|
24
|
+
**Files:**
|
|
25
|
+
- Modify: 20 plugin MCP entry files `platform/plugins/<name>/mcp/src/index.ts` for name in: admin, aeo, browser, connector, contacts, email, filesystem, graph-viewer, joblogic, memory, quickbooks, replicate, scheduling, storage-broker, telegram, url-get, voice-mirror, whatsapp, work, workflows
|
|
26
|
+
- Modify: `platform/lib/graph-mcp/src/index.ts` (import line 31, call line 63 — NOT adjacent; leave `syncEmit` for Task 3)
|
|
27
|
+
|
|
28
|
+
**Interfaces:**
|
|
29
|
+
- Consumes: nothing.
|
|
30
|
+
- Produces: nothing. This removes a call; no symbol is exported.
|
|
31
|
+
|
|
32
|
+
**Non-uniform sites to handle by hand, not by a blind 2-line delete:**
|
|
33
|
+
- `voice-mirror`: import is line 1, call is line 3. Line 2 is `import { lifelineTool } ...` — KEEP line 2.
|
|
34
|
+
- `graph-mcp`: import line 31 (`import { initStderrTee } from "../../mcp-stderr-tee/dist/index.js";`), call line 63 (`initStderrTee(SERVER_NAME);`). Two separate deletions. Keep line 30 (`StringDecoder`, used at line 1001) and `SERVER_NAME` (used by `syncEmit` at line 83).
|
|
35
|
+
- All other 19: import and call are adjacent (e.g. memory lines 1-2; whatsapp lines 8-9; admin 1-2; storage-broker 8-9; url-get 9-10; graph-viewer 7-8). Delete both lines.
|
|
36
|
+
|
|
37
|
+
- [ ] **Step 1: Assert the starting count is 21**
|
|
38
|
+
|
|
39
|
+
Run:
|
|
40
|
+
```bash
|
|
41
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
42
|
+
/usr/bin/grep -rl 'initStderrTee' platform/plugins/*/mcp/src/index.ts platform/lib/graph-mcp/src/index.ts | wc -l
|
|
43
|
+
```
|
|
44
|
+
Expected: `21`
|
|
45
|
+
|
|
46
|
+
- [ ] **Step 2: Remove the import + call from each of the 20 plugin files**
|
|
47
|
+
|
|
48
|
+
For the 19 adjacent sites, delete the `import { initStderrTee } ...` line and the `initStderrTee("<name>");` line. For `voice-mirror`, delete only the import (line 1) and the call (line 3), preserving the `lifelineTool` import. Use Edit per file with the exact two strings; do not delete by line number blindly (line numbers shift as you go).
|
|
49
|
+
|
|
50
|
+
- [ ] **Step 3: Remove the import + call from graph-mcp**
|
|
51
|
+
|
|
52
|
+
Delete `import { initStderrTee } from "../../mcp-stderr-tee/dist/index.js";` (line 31) and `initStderrTee(SERVER_NAME);` (line 63). Leave the surrounding `StringDecoder` import and `SERVER_NAME` const in place.
|
|
53
|
+
|
|
54
|
+
- [ ] **Step 4: Assert zero call sites remain**
|
|
55
|
+
|
|
56
|
+
Run:
|
|
57
|
+
```bash
|
|
58
|
+
/usr/bin/grep -rn 'initStderrTee' platform/plugins platform/lib | /usr/bin/grep -v node_modules | /usr/bin/grep -v '/dist/'
|
|
59
|
+
```
|
|
60
|
+
Expected: no output.
|
|
61
|
+
|
|
62
|
+
- [ ] **Step 5: Build the lib dependency dists (needed for plugin typecheck), then typecheck the plugins**
|
|
63
|
+
|
|
64
|
+
The plugin MCPs import sibling lib dists (`mcp-lifeline` etc.). Build libs first, EXCLUDING the soon-to-be-deleted `mcp-stderr-tee` (its dist may still exist from install; that's fine for this step — it just won't be imported anymore).
|
|
65
|
+
|
|
66
|
+
Run:
|
|
67
|
+
```bash
|
|
68
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code/platform
|
|
69
|
+
export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH"
|
|
70
|
+
npm run build:lib
|
|
71
|
+
NODE_OPTIONS='--max-old-space-size=8192' npx tsc -b plugins/*/mcp/tsconfig.json lib/graph-mcp/tsconfig.json
|
|
72
|
+
```
|
|
73
|
+
Expected: exit 0, no errors. A wall of `TS7031 implicitly any` here means the lib dists did not build — fix setup, do not touch code (per project memory).
|
|
74
|
+
|
|
75
|
+
- [ ] **Step 6: Commit**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee
|
|
79
|
+
git add -A
|
|
80
|
+
git commit -m "$(printf 'refactor: remove 21 initStderrTee call sites\n\nThe call is a no-op in production (STREAM_LOG_PATH is never set).\nmcp-spawn-tee already captures the same stderr per session.\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Task 2: Delete the module and its build entries
|
|
86
|
+
|
|
87
|
+
**Files:**
|
|
88
|
+
- Delete: `platform/lib/mcp-stderr-tee/` (whole directory)
|
|
89
|
+
- Modify: `platform/package.json` lines 9 (`build`) and 10 (`build:lib`) — remove ` && tsc -p lib/mcp-stderr-tee/tsconfig.json` from both
|
|
90
|
+
|
|
91
|
+
**Interfaces:**
|
|
92
|
+
- Consumes: nothing (Task 1 removed all importers).
|
|
93
|
+
- Produces: nothing.
|
|
94
|
+
|
|
95
|
+
- [ ] **Step 1: Assert no importer remains before deleting**
|
|
96
|
+
|
|
97
|
+
Run:
|
|
98
|
+
```bash
|
|
99
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
100
|
+
/usr/bin/grep -rl 'mcp-stderr-tee/dist' platform premium-plugins | /usr/bin/grep -v node_modules | /usr/bin/grep -v '/dist/' | /usr/bin/grep -v '.tasks/'
|
|
101
|
+
```
|
|
102
|
+
Expected: no output. (If any hit, return to Task 1 — deleting the module now would break that importer.)
|
|
103
|
+
|
|
104
|
+
- [ ] **Step 2: Delete the module directory**
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
git rm -r platform/lib/mcp-stderr-tee
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- [ ] **Step 3: Remove both tsconfig entries from package.json**
|
|
111
|
+
|
|
112
|
+
Edit `platform/package.json`: in the `build` script (line 9) and the `build:lib` script (line 10), delete the exact substring ` && tsc -p lib/mcp-stderr-tee/tsconfig.json` (it appears once per line, immediately after `lib/models/tsconfig.json`).
|
|
113
|
+
|
|
114
|
+
- [ ] **Step 4: Verify build:lib still runs clean without the entry**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code/platform
|
|
118
|
+
export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH"
|
|
119
|
+
npm run build:lib
|
|
120
|
+
```
|
|
121
|
+
Expected: exit 0. No reference to `mcp-stderr-tee`.
|
|
122
|
+
|
|
123
|
+
- [ ] **Step 5: Commit**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee
|
|
127
|
+
git add -A
|
|
128
|
+
git commit -m "$(printf 'refactor: delete mcp-stderr-tee module and its build entries\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### Task 3: Neutralize the remaining `STREAM_LOG_PATH` readers
|
|
134
|
+
|
|
135
|
+
Two readers survive Task 1: graph-mcp's `syncEmit` writes `[mcp:graph]` to `process.env.STREAM_LOG_PATH` on exit paths, and the memory boot-smoke harness sets it. Both point at the same never-produced destination. The `syncEmit` stderr fallback already reaches the `mcp-spawn-tee` sink, so removing the dead branch loses nothing.
|
|
136
|
+
|
|
137
|
+
**Files:**
|
|
138
|
+
- Modify: `platform/lib/graph-mcp/src/index.ts` — `syncEmit` (approx lines 66-92): remove the `STREAM_LOG_PATH` branch and its now-unused locals
|
|
139
|
+
- Modify: `platform/plugins/memory/mcp/scripts/boot-smoke.sh:46` — remove the `STREAM_LOG_PATH="$LOG_DIR/stream.log" \` line
|
|
140
|
+
|
|
141
|
+
**Interfaces:**
|
|
142
|
+
- Consumes: nothing.
|
|
143
|
+
- Produces: `syncEmit(line: string): void` — unchanged signature, still called at all 5 exit paths; only its body shrinks.
|
|
144
|
+
|
|
145
|
+
- [ ] **Step 1: Assert the three graph-mcp hits and one boot-smoke hit exist**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
149
|
+
/usr/bin/grep -n 'STREAM_LOG_PATH\|streamLogPath' platform/lib/graph-mcp/src/index.ts
|
|
150
|
+
/usr/bin/grep -n 'STREAM_LOG_PATH' platform/plugins/memory/mcp/scripts/boot-smoke.sh
|
|
151
|
+
```
|
|
152
|
+
Expected: 3 graph-mcp lines (80, 81, 83), 1 boot-smoke line (46).
|
|
153
|
+
|
|
154
|
+
- [ ] **Step 2: Rewrite `syncEmit` to drop the dead branch**
|
|
155
|
+
|
|
156
|
+
Replace the current body (which reads `const iso`, `const streamLogPath = process.env.STREAM_LOG_PATH`, the `if (streamLogPath) { try { appendFileSync(...) } catch {} }` block, then the stderr write) with:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
function syncEmit(line: string): void {
|
|
160
|
+
const msg = `[graph-mcp] ${line}`;
|
|
161
|
+
// The mcp-spawn-tee shim (PLUGIN.md spawns this entry under it) installs an
|
|
162
|
+
// appendFileSync-backed stderr writer, so this line reaches the raw sink
|
|
163
|
+
// synchronously and survives an immediate process.exit().
|
|
164
|
+
try {
|
|
165
|
+
process.stderr.write(`${msg}\n`);
|
|
166
|
+
} catch {
|
|
167
|
+
/* stderr closed — nothing else to do */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
This drops the `iso` local and the `appendFileSync` call. Then remove `appendFileSync` from the `node:fs` import at line 28 (it has no other use — the file uses `accessSync`, `constants`, `readFileSync`, `statSync`). Verify before removing:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
/usr/bin/grep -n 'appendFileSync' platform/lib/graph-mcp/src/index.ts
|
|
176
|
+
```
|
|
177
|
+
Expected after the syncEmit rewrite: only the line-28 import mention remains, so remove it from the import list.
|
|
178
|
+
|
|
179
|
+
- [ ] **Step 3: Remove the boot-smoke assignment**
|
|
180
|
+
|
|
181
|
+
Delete the line ` STREAM_LOG_PATH="$LOG_DIR/stream.log" \` from `platform/plugins/memory/mcp/scripts/boot-smoke.sh` (line 46, inside the `env` block). The surrounding `LOG_DIR=` and `NEO4J_URI=` lines stay.
|
|
182
|
+
|
|
183
|
+
- [ ] **Step 4: Assert zero `STREAM_LOG_PATH` hits in the live tree**
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
187
|
+
/usr/bin/grep -rn 'STREAM_LOG_PATH' platform premium-plugins packages | /usr/bin/grep -v node_modules | /usr/bin/grep -v '/dist/' | /usr/bin/grep -v '.tasks/' | /usr/bin/grep -v 'docs/superpowers/'
|
|
188
|
+
```
|
|
189
|
+
Expected: no output.
|
|
190
|
+
|
|
191
|
+
- [ ] **Step 5: Typecheck graph-mcp and confirm boot-smoke still parses**
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code/platform
|
|
195
|
+
export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH"
|
|
196
|
+
npx tsc -p lib/graph-mcp/tsconfig.json
|
|
197
|
+
bash -n plugins/memory/mcp/scripts/boot-smoke.sh
|
|
198
|
+
```
|
|
199
|
+
Expected: both exit 0.
|
|
200
|
+
|
|
201
|
+
- [ ] **Step 6: Commit**
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee
|
|
205
|
+
git add -A
|
|
206
|
+
git commit -m "$(printf 'refactor: drop the two remaining dead STREAM_LOG_PATH readers\n\ngraph-mcp syncEmit and the memory boot-smoke harness both wrote to a\nvariable no spawner sets. syncEmit keeps its stderr write, which the\nmcp-spawn-tee shim already captures to the raw sink.\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
### Task 4: Strip the three comment-only references
|
|
212
|
+
|
|
213
|
+
**Files:**
|
|
214
|
+
- Modify: `platform/services/claude-session-manager/src/rc-daemon.ts:460` — comment naming `mcp-stderr-tee`
|
|
215
|
+
- Modify: `platform/scripts/logs-rotate.sh:182` — comment naming `mcp-stderr-tee`
|
|
216
|
+
- Modify: `packages/create-maxy-code/scripts/bundle.js:563` — the lib-rewrite comment example
|
|
217
|
+
|
|
218
|
+
**Interfaces:** none — comments only.
|
|
219
|
+
|
|
220
|
+
- [ ] **Step 1: Read each comment in context**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
224
|
+
sed -n '458,462p' platform/services/claude-session-manager/src/rc-daemon.ts
|
|
225
|
+
sed -n '180,184p' platform/scripts/logs-rotate.sh
|
|
226
|
+
sed -n '561,565p' packages/create-maxy-code/scripts/bundle.js
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- [ ] **Step 2: Edit each so the sentence stays true without the dead module name**
|
|
230
|
+
|
|
231
|
+
- `rc-daemon.ts:460`: the comment says the sink is off `mcp-stderr-tee` "which no longer reads LOG_DIR". Reword to describe the current state without the retired module (the sink is `mcp-spawn-tee`'s `mcp-<name>-<SESSION_ID>.log`).
|
|
232
|
+
- `logs-rotate.sh:182`: the comment references why an earlier draft could not purge `mcp-*` because `mcp-stderr-tee` held the file open. Reword to name `mcp-spawn-tee` (the current holder) or drop the historical clause.
|
|
233
|
+
- `bundle.js:563`: change the example path in the comment from `mcp-stderr-tee` to a lib premium plugins actually import (e.g. `mcp-lifeline`). Verify the replacement is real:
|
|
234
|
+
```bash
|
|
235
|
+
/usr/bin/grep -rl 'mcp-lifeline/dist' premium-plugins | /usr/bin/grep -v node_modules | head -1
|
|
236
|
+
```
|
|
237
|
+
Expected: at least one premium plugin imports it.
|
|
238
|
+
|
|
239
|
+
- [ ] **Step 3: Assert zero `mcp-stderr-tee` hits in the live tree**
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
243
|
+
/usr/bin/grep -rn 'mcp-stderr-tee' platform premium-plugins packages | /usr/bin/grep -v node_modules | /usr/bin/grep -v '/dist/' | /usr/bin/grep -v '.tasks/' | /usr/bin/grep -v 'docs/superpowers/' | /usr/bin/grep -v 'plugins/docs/references/plugins-guide.md' | /usr/bin/grep -v 'platform-architecture/SKILL.md'
|
|
244
|
+
```
|
|
245
|
+
Expected: no output. (plugins-guide.md and SKILL.md are handled in Tasks 5-6.)
|
|
246
|
+
|
|
247
|
+
- [ ] **Step 4: Commit**
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee
|
|
251
|
+
git add -A
|
|
252
|
+
git commit -m "$(printf 'refactor: strip dead mcp-stderr-tee name from three comments\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### Task 5: Rewrite `plugins-guide.md` so it stops claiming a per-conversation stream log
|
|
258
|
+
|
|
259
|
+
**Files:**
|
|
260
|
+
- Modify: `platform/plugins/docs/references/plugins-guide.md` (the `## MCP Plugin Observability` section, ~lines 153-197)
|
|
261
|
+
|
|
262
|
+
**Interfaces:** none — documentation.
|
|
263
|
+
|
|
264
|
+
**Keep / remove / rewrite map** (verify line numbers against the file first — they shift as you edit):
|
|
265
|
+
|
|
266
|
+
| Content | Action |
|
|
267
|
+
|---|---|
|
|
268
|
+
| 155 intro ("Every `console.error` line ... teed into the per-conversation stream log") | REWRITE: `console.error` from a plugin's MCP server is captured by the `mcp-spawn-tee` shim into the per-session raw file `mcp-<name>-<SESSION_ID>.log`. |
|
|
269
|
+
| 157-161 Opt-in block (`import { initStderrTee }` + call) | REMOVE entirely — no opt-in; capture is automatic under the shim. |
|
|
270
|
+
| 163 ("After this ... `mcp-your-plugin-name-{sessionId}.log` ... That is where you grep") | KEEP — true; it names the real sink. Merge with the rewritten intro. |
|
|
271
|
+
| 166 ("`initStderrTee` is *intended* to also mirror ... no-op in production ... Tracked as 1736") | REMOVE — the whole reason to retire; do not leave a "tracked as 1736" pointer to a closed task. |
|
|
272
|
+
| 168 Premium-plugins paragraph (ships `mcp-stderr-tee/{dist,package.json}`) | REMOVE — it documents shipping the deleted module. The generic bundler behaviour is not plugin-author guidance and lives in `bundle.js`. |
|
|
273
|
+
| 170 ("How the tee decides ... platform sets `STREAM_LOG_PATH` on every spawn") | REMOVE — false claim. |
|
|
274
|
+
| 174-177 Retrieve block: `logs-read {type:"system"}` → grep stream log | REMOVE the `type:"system"` bullet (returns nothing). KEEP the `type:"mcp"` bullet (real raw feed). |
|
|
275
|
+
| 179 Tee-state markers (`[mcp-tee-attach/skip/detach]` land in stream log) | REMOVE — no such log. |
|
|
276
|
+
| 181 Main-subprocess stderr (`[subproc-stderr]`) | REMOVE — describes the retired admin server. |
|
|
277
|
+
| 185 (`initStderrTee` `createWriteStream` write-race paragraph) | REMOVE — about the deleted module. |
|
|
278
|
+
| 187-191 "Two layers" — plugin-side sync-write + `mcp-spawn-tee` wrapper | KEEP, but in the wrapper paragraph edit only clauses that name `initStderrTee` (e.g. "module-load throws before `initStderrTee` runs" → "module-load throws before any plugin logging runs"). DO NOT touch `[mcp-spawn-tee-attached]` / SIGTERM-forwarding wording — that is 1737's collision surface. |
|
|
279
|
+
|
|
280
|
+
- [ ] **Step 1: Re-read the section with current line numbers**
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
284
|
+
sed -n '153,197p' platform/plugins/docs/references/plugins-guide.md
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
- [ ] **Step 2: Apply the keep/remove/rewrite map**
|
|
288
|
+
|
|
289
|
+
Edit the section per the table. Prose carries zero em-dashes. The section should end shorter, asserting one surface: automatic capture by the shim into the per-session raw sink, retrievable via `logs-read {type:"mcp"}`, with the two-layer failure contract intact minus the `initStderrTee` clauses.
|
|
290
|
+
|
|
291
|
+
- [ ] **Step 3: Assert the false surfaces are gone and 1737's names are untouched**
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
/usr/bin/grep -n 'initStderrTee\|STREAM_LOG_PATH\|subproc-stderr\|mcp-tee-attach\|claude-agent-stream\|logs-read { type: "system"' platform/plugins/docs/references/plugins-guide.md
|
|
295
|
+
```
|
|
296
|
+
Expected: no output.
|
|
297
|
+
```bash
|
|
298
|
+
/usr/bin/grep -c 'mcp-spawn-tee-attached' platform/plugins/docs/references/plugins-guide.md
|
|
299
|
+
```
|
|
300
|
+
Expected: `1` (unchanged — still 1737's to fix, not zero).
|
|
301
|
+
|
|
302
|
+
- [ ] **Step 4: Commit**
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee
|
|
306
|
+
git add -A
|
|
307
|
+
git commit -m "$(printf 'docs: plugins-guide no longer claims a per-conversation MCP stream log\n\nThe mcp-spawn-tee per-session raw sink is the single honest surface.\nLeaves 1737 stale marker names untouched.\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### Task 6: Regenerate the architecture skill and pass the no-drift gate
|
|
313
|
+
|
|
314
|
+
**Files:**
|
|
315
|
+
- Regenerate: `platform/plugins/admin/skills/platform-architecture/SKILL.md` (and any brand twins) via the assembler
|
|
316
|
+
- Possibly regenerate: `docs/public/llms-full.*.txt` corpus via copy-docs
|
|
317
|
+
|
|
318
|
+
**Interfaces:** none — generated artefact.
|
|
319
|
+
|
|
320
|
+
- [ ] **Step 1: Refresh the doc corpus and reassemble the skill**
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
324
|
+
export PATH="$HOME/.nvm/versions/node/v22.22.0/bin:$PATH"
|
|
325
|
+
node scripts/copy-docs.mjs 2>&1 | tail -3
|
|
326
|
+
node scripts/assemble-architecture-skill.mjs 2>&1 | tail -3
|
|
327
|
+
```
|
|
328
|
+
Expected: both complete without error. (If `copy-docs.mjs` needs args or a different path, read `check-architecture-skill-no-drift.mjs` for the exact corpus path it expects and match it.)
|
|
329
|
+
|
|
330
|
+
- [ ] **Step 2: Run the no-drift gate**
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
node platform/scripts/check-architecture-skill-no-drift.mjs
|
|
334
|
+
```
|
|
335
|
+
Expected: exit 0, no "out of sync" failure.
|
|
336
|
+
|
|
337
|
+
- [ ] **Step 3: Confirm the regenerated skill dropped the false surface**
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
/usr/bin/grep -n 'initStderrTee\|STREAM_LOG_PATH\|subproc-stderr' platform/plugins/admin/skills/platform-architecture/SKILL.md
|
|
341
|
+
```
|
|
342
|
+
Expected: no output.
|
|
343
|
+
|
|
344
|
+
- [ ] **Step 4: Commit**
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
git add -A
|
|
348
|
+
git commit -m "$(printf 'chore: regenerate platform-architecture skill after plugins-guide edit\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')"
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
### Task 7: Correct the reasoning in the task file and LANES
|
|
354
|
+
|
|
355
|
+
The archive MOVE happens in the sprint's Land phase (6c). This task fixes the CONTENT — both records currently argue "retire because 287/288 dismantled the consumers," which is wrong. Do this before the archive so the archived file carries the correct reason.
|
|
356
|
+
|
|
357
|
+
**Files:**
|
|
358
|
+
- Modify: `.tasks/1736-nothing-sets-stream-log-path-so-the-per-conversation-mcp-stream-log-does-not-exist.md` (reasoning already partly corrected in an earlier session; verify it names the real reason: `mcp-spawn-tee` already serves this consumer per session)
|
|
359
|
+
- Modify: `.tasks/LANES.md` row 1736 (same correction)
|
|
360
|
+
|
|
361
|
+
**Interfaces:** none — tracker prose.
|
|
362
|
+
|
|
363
|
+
- [ ] **Step 1: Verify current task-file reasoning names the real reason**
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
cd /Users/neo/getmaxy/maxy-code/.claude/worktrees/task-1736-retire-mcp-stderr-tee/maxy-code
|
|
367
|
+
/usr/bin/grep -n 'mcp-spawn-tee already\|287\|288\|dismantled' .tasks/1736-*.md
|
|
368
|
+
```
|
|
369
|
+
The task file must state the retire reason as redundancy with `mcp-spawn-tee`, and must not present "287/288 retired the consumers" as the load-bearing argument. If the current text still leans on 287/288 as the reason, reword it. (Note: the reasoning correction may already be applied from a prior session; this step confirms rather than assumes.)
|
|
370
|
+
|
|
371
|
+
- [ ] **Step 2: Confirm LANES row 1736 matches**
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
/usr/bin/grep -n '287 retired the script_stream\|mcp-spawn-tee already writes' .tasks/LANES.md
|
|
375
|
+
```
|
|
376
|
+
Ensure the row's DECIDED block frames the reason as redundancy, with 287 named only as what it actually did (retired `script_stream`), not as the reason to retire this.
|
|
377
|
+
|
|
378
|
+
- [ ] **Step 3: Commit any corrections**
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
git add -A
|
|
382
|
+
git commit -m "$(printf 'docs: correct the retire reasoning in task 1736 and its LANES row\n\nSession: 71944c42-a91c-452a-96d2-b7bbcfe888fb')" || echo "nothing to correct — already accurate"
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Self-Review
|
|
388
|
+
|
|
389
|
+
**Spec coverage:** module deletion (T2), 21 call sites (T1), build entries (T2), boot-smoke assignment (T3), graph-mcp second reader (T3 — an addition the spec implied via "zero STREAM_LOG_PATH hits" but did not enumerate), comment refs (T4), doc rewrite (T5), skill regen (T6), reasoning correction (T7). The `logs-read {type:"system"}` open question is handled inside T5 (the doc bullet is removed) with the tool-level bug filed separately if implementation finds it reads a producerless file. All spec sections map to a task.
|
|
390
|
+
|
|
391
|
+
**Placeholder scan:** no TBD/TODO; every edit names exact files, strings, and expected grep output.
|
|
392
|
+
|
|
393
|
+
**Type consistency:** the only signature touched is `syncEmit(line: string): void` (T3), unchanged. No cross-task symbol references.
|
|
394
|
+
|
|
395
|
+
## Deviation from spec, flagged
|
|
396
|
+
|
|
397
|
+
Task 3's graph-mcp `syncEmit` edit is the one place the change rewrites live failure-path logic rather than deleting a no-op. It is in scope (it is a second reader of the same dead `STREAM_LOG_PATH`, and the spec's "zero hits" criterion requires it), and it is behaviour-preserving (the stderr write already reaches the sink). Called out here so a reviewer sees it deliberately, not buried in a bulk deletion.
|
package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Task 1736 — retire `mcp-stderr-tee`
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-17
|
|
4
|
+
**Task:** [`.tasks/1736-*.md`](../../../../.tasks/1736-nothing-sets-stream-log-path-so-the-per-conversation-mcp-stream-log-does-not-exist.md)
|
|
5
|
+
**Verdict:** retire the module, its call sites, and every doc claim that a per-conversation
|
|
6
|
+
MCP stream log exists.
|
|
7
|
+
|
|
8
|
+
## Why retire, precisely
|
|
9
|
+
|
|
10
|
+
`mcp-stderr-tee` reads `STREAM_LOG_PATH` and mirrors MCP stderr into a per-conversation
|
|
11
|
+
stream log. Nothing sets that variable, so `initStderrTee` takes its skip path on every
|
|
12
|
+
production spawn and 21 call sites wire up a no-op.
|
|
13
|
+
|
|
14
|
+
The reason to retire is **not** that the surface was deliberately retired elsewhere. It is
|
|
15
|
+
that `mcp-spawn-tee` already serves the same consumer, strictly better:
|
|
16
|
+
|
|
17
|
+
- It is a shim Claude Code runs *in place of* each server's entry, so it replaces
|
|
18
|
+
`process.stderr.write` before the real entry imports. It captures every stderr byte with
|
|
19
|
+
no cooperation from the plugin — including module-load throws that happen before
|
|
20
|
+
`initStderrTee` would ever run.
|
|
21
|
+
- It writes `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log`, keyed by session, which *is* the
|
|
22
|
+
conversation. Per-conversation correlation already exists.
|
|
23
|
+
- It handles the sessionless spawn explicitly (`mcp-<name>-nosession.log`).
|
|
24
|
+
- It uses `appendFileSync`, which survives an immediate `process.exit`. `mcp-stderr-tee`
|
|
25
|
+
used an async `createWriteStream`, which does not.
|
|
26
|
+
|
|
27
|
+
The two modules were never complements. Task 1721's docstring records that they wrote the
|
|
28
|
+
same file and "every line landed twice". 1721 removed the duplication and left the loser
|
|
29
|
+
holding a destination nothing produces.
|
|
30
|
+
|
|
31
|
+
## Correcting the record
|
|
32
|
+
|
|
33
|
+
The task file and its LANES row currently argue "retire because Tasks 287 and 288
|
|
34
|
+
dismantled the consumers." That is wrong and it is load-bearing: 287 retired the
|
|
35
|
+
`script_stream` surface — shell scripts narrating phase lines into the chat UI. It never
|
|
36
|
+
evaluated the MCP-stderr surface, whose consumer is an investigator grepping a file. That
|
|
37
|
+
consumer still exists; it is simply already served by `mcp-spawn-tee`.
|
|
38
|
+
|
|
39
|
+
Both records get the correct argument before the task archives. A wrong reason in an
|
|
40
|
+
archive licenses the next removal that the reason does not actually cover.
|
|
41
|
+
|
|
42
|
+
## What changes
|
|
43
|
+
|
|
44
|
+
**Code.**
|
|
45
|
+
|
|
46
|
+
- Delete `platform/lib/mcp-stderr-tee/`.
|
|
47
|
+
- Delete its two `tsc -p lib/mcp-stderr-tee/tsconfig.json` entries in
|
|
48
|
+
`platform/package.json` (`build` and `build:lib`).
|
|
49
|
+
- Remove 21 `initStderrTee` call sites — 20 plugin MCP entry files plus
|
|
50
|
+
`platform/lib/graph-mcp/src/index.ts`. Each loses one import line and one call line.
|
|
51
|
+
`graph-mcp` is inside the 21, not additional. Premium plugins have zero call sites.
|
|
52
|
+
- Remove the now-dead `STREAM_LOG_PATH` assignment in
|
|
53
|
+
`platform/plugins/memory/mcp/scripts/boot-smoke.sh` — the last assignment in the tree once
|
|
54
|
+
the reader is gone.
|
|
55
|
+
- Strip the dangling module name from two comment-only references
|
|
56
|
+
(`services/claude-session-manager/src/rc-daemon.ts`, `platform/scripts/logs-rotate.sh`).
|
|
57
|
+
Neither imports it.
|
|
58
|
+
- `packages/create-maxy-code/scripts/bundle.js` names `mcp-stderr-tee` as the example in its
|
|
59
|
+
lib-rewrite comment. The mechanism is generic and collects whatever premium plugins import;
|
|
60
|
+
the example just becomes stale. Point it at a lib that is actually imported.
|
|
61
|
+
|
|
62
|
+
**Docs.** `platform/plugins/docs/references/plugins-guide.md` loses every claim that a
|
|
63
|
+
per-conversation MCP stream log exists:
|
|
64
|
+
|
|
65
|
+
- the `initStderrTee` opt-in block;
|
|
66
|
+
- "How the tee decides which file to write to" (asserts the platform sets `STREAM_LOG_PATH`
|
|
67
|
+
on every spawn — it does not);
|
|
68
|
+
- the tee-state markers paragraph (`[mcp-tee-attach]` / `[mcp-tee-skip]` /
|
|
69
|
+
`[mcp-tee-detach]` "land in the stream log");
|
|
70
|
+
- the `logs-read { type: "system", sessionId }` → grep `[mcp:<name>]` retrieval instruction;
|
|
71
|
+
- the "Main-subprocess stderr" `[subproc-stderr]` paragraph, which describes the retired
|
|
72
|
+
admin server;
|
|
73
|
+
- the `initStderrTee` `createWriteStream` write-race paragraph in the failure-path contract;
|
|
74
|
+
- the premium-plugins paragraph's `mcp-stderr-tee` bundler example.
|
|
75
|
+
|
|
76
|
+
What replaces them is short: a plugin author calls `console.error`; the `mcp-spawn-tee` shim
|
|
77
|
+
captures every byte into `mcp-<name>-<SESSION_ID>.log`; that file is where you grep. No
|
|
78
|
+
import, no call, no opt-in.
|
|
79
|
+
|
|
80
|
+
`platform/plugins/admin/skills/platform-architecture/SKILL.md` is generated from that
|
|
81
|
+
reference doc. Regenerate it; never hand-edit.
|
|
82
|
+
|
|
83
|
+
## Scope boundaries
|
|
84
|
+
|
|
85
|
+
**In scope:** the `STREAM_LOG_PATH` contract — the module, its 21 call sites, its build
|
|
86
|
+
entries, and the doc claims asserting the surface works.
|
|
87
|
+
|
|
88
|
+
**Out of scope:**
|
|
89
|
+
|
|
90
|
+
- The raw sink. Task 1721 settled it and this removal does not touch it.
|
|
91
|
+
- `mcp-spawn-tee`'s stale marker names (`[mcp-spawn-tee-attached]` / `[mcp-spawn-tee-exit]`,
|
|
92
|
+
retired by Task 989 in favour of `[mcp-helper] op=spawn|boot|exit`) and its stale
|
|
93
|
+
two-process description. Owned by [`.tasks/1737-*.md`](../../../../.tasks/1737-mcp-spawn-tee-docs-promise-lifecycle-markers-and-a-child-process-that-task-989-removed.md),
|
|
94
|
+
which is designed but unimplemented on branch `worktree-task-1737-mcp-spawn-tee-docs`.
|
|
95
|
+
This sprint must not restate those names when it points authors at the sink, or it
|
|
96
|
+
re-introduces the exact bug 1737 exists to fix.
|
|
97
|
+
- Reviving `claude-agent-stream-<id>.log` or any per-conversation agent stream file. It has
|
|
98
|
+
no producer in the PTY architecture; building one is a different task with a different
|
|
99
|
+
premise.
|
|
100
|
+
- The `script_stream` surface and its banned-token gate. Tasks 287/288 settled it.
|
|
101
|
+
|
|
102
|
+
## Open question to resolve during implementation
|
|
103
|
+
|
|
104
|
+
`logs-read { type: "system", sessionId }` is documented as returning the conversation's
|
|
105
|
+
stream log for `[mcp:<name>]` grepping. The doc instruction goes either way — grepping
|
|
106
|
+
`[mcp:<name>]` on that log returns nothing, so the sentence is false regardless of what the
|
|
107
|
+
tool does internally.
|
|
108
|
+
|
|
109
|
+
What is unresolved is the *tool*. If `logs-read type:"system"` reads a file with no producer,
|
|
110
|
+
that is a live bug and not this task's doc defect. Establish which during implementation. If
|
|
111
|
+
it is a bug, file a `.tasks/NNN-*.md` for it — deleting the doc sentence while leaving a tool
|
|
112
|
+
that silently returns nothing would hide the same false-clean shape one layer down, which is
|
|
113
|
+
the exact failure this task exists to close.
|
|
114
|
+
|
|
115
|
+
## Verification
|
|
116
|
+
|
|
117
|
+
- `npm run build` at `maxy-code/platform/` is clean after the tsconfig entries are removed.
|
|
118
|
+
- The 21 affected MCP packages typecheck.
|
|
119
|
+
- `initStderrTee` and `mcp-stderr-tee` return zero hits outside `.tasks/archive/` and
|
|
120
|
+
`docs/superpowers/specs/`.
|
|
121
|
+
- The architecture-skill regeneration gate passes with the regenerated `SKILL.md` committed.
|
|
122
|
+
- `STREAM_LOG_PATH` returns zero hits in the live tree.
|
|
123
|
+
|
|
124
|
+
## Deployment
|
|
125
|
+
|
|
126
|
+
Every one of the 21 call sites ships in the bundled `create-maxy-code` payload, so this
|
|
127
|
+
requires an installer publish to reach the fleet. Per the sprint gating rule, publish awaits
|
|
128
|
+
an explicit operator command.
|
|
@@ -29,7 +29,6 @@ const node_child_process_1 = require("node:child_process");
|
|
|
29
29
|
const node_fs_1 = require("node:fs");
|
|
30
30
|
const node_path_1 = require("node:path");
|
|
31
31
|
const node_string_decoder_1 = require("node:string_decoder");
|
|
32
|
-
const index_js_1 = require("../../mcp-stderr-tee/dist/index.js");
|
|
33
32
|
const cypher_validate_js_1 = require("./cypher-validate.js");
|
|
34
33
|
const audit_js_1 = require("../../graph-write/dist/audit.js");
|
|
35
34
|
const schema_cache_js_1 = require("./schema-cache.js");
|
|
@@ -39,31 +38,13 @@ const cypher_shim_read_js_1 = require("./cypher-shim-read.js");
|
|
|
39
38
|
const node_crypto_1 = require("node:crypto");
|
|
40
39
|
const SERVER_NAME = "graph";
|
|
41
40
|
const UPSTREAM_PACKAGE = "mcp-neo4j-cypher@0.6.0";
|
|
42
|
-
(
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// survives an immediate exit. Each destination is wrapped independently — an
|
|
48
|
-
// unwritable destination must not mask the primary failure.
|
|
49
|
-
//
|
|
50
|
-
// Task 1721 removed this function's own raw-file write. The final
|
|
51
|
-
// process.stderr.write goes through the writer the mcp-spawn-tee shim installed
|
|
52
|
-
// (PLUGIN.md spawns this entry under it), and that shim's appendSafe is itself
|
|
53
|
-
// an appendFileSync to the raw sink — so exit-path lines still reach disk
|
|
54
|
-
// synchronously, via one writer instead of two.
|
|
41
|
+
// Emit a failure line on exit paths (missing password, uvx unresolvable,
|
|
42
|
+
// upstream spawn/exit error). The mcp-spawn-tee shim spawns this entry (see
|
|
43
|
+
// PLUGIN.md) and installs an appendFileSync-backed stderr writer, so this
|
|
44
|
+
// process.stderr.write reaches the raw sink synchronously and survives an
|
|
45
|
+
// immediate process.exit() — an async buffer would not flush in time.
|
|
55
46
|
function syncEmit(line) {
|
|
56
47
|
const msg = `[graph-mcp] ${line}`;
|
|
57
|
-
const iso = new Date().toISOString();
|
|
58
|
-
const streamLogPath = process.env.STREAM_LOG_PATH;
|
|
59
|
-
if (streamLogPath) {
|
|
60
|
-
try {
|
|
61
|
-
(0, node_fs_1.appendFileSync)(streamLogPath, `[${iso}] [mcp:${SERVER_NAME}] ${msg}\n`);
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
/* unwritable destination — preserve primary failure */
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
48
|
try {
|
|
68
49
|
process.stderr.write(`${msg}\n`);
|
|
69
50
|
}
|