@medicine-wheel/app 0.23.0 → 0.24.1

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 (2) hide show
  1. package/dist/cli/mw.js +57 -7
  2. package/package.json +28 -28
package/dist/cli/mw.js CHANGED
@@ -80,8 +80,15 @@ function resolveMcpPath() {
80
80
  const fromModules = path.join(packageRoot, 'node_modules', '@medicine-wheel', 'mcp', 'dist', 'index.js');
81
81
  if (fs.existsSync(fromModules))
82
82
  return fromModules;
83
+ // The package itself, not a file inside it. @medicine-wheel/mcp has an
84
+ // `exports` map whose "." is ./dist/index.js (the server) and which does not
85
+ // export "./dist/index.js", so resolving that subpath throws
86
+ // ERR_PACKAGE_PATH_NOT_EXPORTED. A global install of app and mcp side by side
87
+ // (`npm i -g @medicine-wheel/app @medicine-wheel/mcp`) therefore found no
88
+ // server, and every installed `mw chart` said "MCP server path not found"
89
+ // until 0.24.1. Found by RELEASING.md step 7 on 0.24.0.
83
90
  try {
84
- return require.resolve('@medicine-wheel/mcp/dist/index.js', {
91
+ return require.resolve('@medicine-wheel/mcp', {
85
92
  paths: [packageRoot, process.cwd()],
86
93
  });
87
94
  }
@@ -180,22 +187,60 @@ async function checkApi() {
180
187
  }
181
188
  }
182
189
  // ── MCP JSON-RPC ──────────────────────────────────────────────────
190
+ // One MCP session per command, over the server's stdio. The stdio transport
191
+ // reads newline-delimited JSON-RPC messages, and a client opens the session
192
+ // with `initialize` and the `notifications/initialized` notification before
193
+ // any request.
194
+ //
195
+ // Until 0.24.0 this sent a lone request with no handshake and no trailing
196
+ // newline. The server never read a complete message, answered nothing, and
197
+ // every `mw chart` and `mw tools` command printed nothing and exited 0
198
+ // (Miadi Chronicle Episode 297, finding F1).
199
+ const MCP_PROTOCOL_VERSION = '2025-06-18';
200
+ const MCP_REQUEST_ID = 2;
183
201
  function mcpRaw(rpcMethod, params) {
184
202
  if (!MW_MCP_PATH) {
185
203
  console.error('Error: MCP server path not found. Set MW_MCP_PATH or use the HTTP server via MW_API_URL.');
186
204
  process.exit(1);
187
205
  }
188
- const req = JSON.stringify({ jsonrpc: '2.0', method: rpcMethod, params, id: 1 });
206
+ const messages = [
207
+ {
208
+ jsonrpc: '2.0',
209
+ id: 1,
210
+ method: 'initialize',
211
+ params: { protocolVersion: MCP_PROTOCOL_VERSION, capabilities: {}, clientInfo: { name: 'mw', version: '1' } },
212
+ },
213
+ { jsonrpc: '2.0', method: 'notifications/initialized' },
214
+ { jsonrpc: '2.0', id: MCP_REQUEST_ID, method: rpcMethod, params },
215
+ ];
189
216
  const result = (0, child_process_1.spawnSync)('node', [MW_MCP_PATH], {
190
- input: req,
217
+ input: messages.map((m) => JSON.stringify(m) + '\n').join(''),
191
218
  encoding: 'utf8',
192
219
  timeout: 10000,
220
+ maxBuffer: 64 * 1024 * 1024,
193
221
  });
194
222
  if (result.error) {
195
223
  console.error('MCP error:', result.error.message);
224
+ process.exitCode = 1;
196
225
  return '';
197
226
  }
198
- return result.stdout?.trim() ?? '';
227
+ // One JSON line per response; keep the one that answers the request.
228
+ for (const line of (result.stdout ?? '').split('\n')) {
229
+ const text = line.trim();
230
+ if (!text)
231
+ continue;
232
+ try {
233
+ if (JSON.parse(text)?.id === MCP_REQUEST_ID)
234
+ return text;
235
+ }
236
+ catch { /* not a JSON-RPC line */ }
237
+ }
238
+ const stderrTail = (result.stderr ?? '').trim().split('\n').slice(-5).join('\n');
239
+ console.error(`MCP error: no response to ${rpcMethod} from ${MW_MCP_PATH} (exit ${result.status ?? result.signal})`);
240
+ if (stderrTail)
241
+ console.error(stderrTail);
242
+ process.exitCode = 1;
243
+ return '';
199
244
  }
200
245
  function mcpCall(toolName, args) {
201
246
  const raw = mcpRaw('tools/call', { name: toolName, arguments: args });
@@ -284,6 +329,7 @@ ${C.bold}🌿 mw — Medicine Wheel CLI${C.reset}
284
329
  mw chart delay <chart> <step> <resolve_by> <reason> --by <who>
285
330
  [--primary <text>] [--wake-on <cue>] Choose to delay a step's resolution
286
331
  [--session <id> --cwd <dir> --resume <cmd>] ...with the session to rehydrate
332
+ [--trace <miadi-...> --rehydrate-with <miadi-...>] ...its LLMOps trace and rehydrating prompt
287
333
  mw chart delayed [--within <days>] [--all] Delays by resolve_by, owed first
288
334
  mw chart end-delay <chart> <step> <rehydrated|released> --by <who> [--note <text>]
289
335
  mw mmot <chart_id> <expected> <actual> <analysis> MMOT review
@@ -706,11 +752,13 @@ function cmdChart(positional, flags = {}) {
706
752
  case 'delay': {
707
753
  const [, chartId, stepId, resolveBy, reason] = positional;
708
754
  const by = flagText(flags, 'by');
709
- if (!chartId || !stepId || !resolveBy || !reason || !by) {
710
- chartUsage('mw chart delay <chart_id> <step_id> <resolve_by> <reason> --by <who> [--primary <text>] [--wake-on <cue>] [--session <id>] [--cwd <dir>] [--resume <command>]');
755
+ const sessionId = flagText(flags, 'session');
756
+ const trace = flagText(flags, 'trace');
757
+ const rehydrateWith = flagText(flags, 'rehydrate-with');
758
+ if (!chartId || !stepId || !resolveBy || !reason || !by || ((trace || rehydrateWith) && !sessionId)) {
759
+ chartUsage('mw chart delay <chart_id> <step_id> <resolve_by> <reason> --by <who> [--primary <text>] [--wake-on <cue>] [--session <id>] [--cwd <dir>] [--resume <command>] [--host <host>] [--trace <miadi-...>] [--rehydrate-with <miadi-...>] (--trace and --rehydrate-with need --session)');
711
760
  return;
712
761
  }
713
- const sessionId = flagText(flags, 'session');
714
762
  const wakeOn = flagText(flags, 'wake-on');
715
763
  mcpCall('delay_resolution', {
716
764
  chart_id: chartId,
@@ -727,6 +775,8 @@ function cmdChart(positional, flags = {}) {
727
775
  ...(flagText(flags, 'cwd') ? { cwd: flagText(flags, 'cwd') } : {}),
728
776
  ...(flagText(flags, 'resume') ? { resume_command: flagText(flags, 'resume') } : {}),
729
777
  ...(flagText(flags, 'host') ? { host: flagText(flags, 'host') } : {}),
778
+ ...(trace ? { trace } : {}),
779
+ ...(rehydrateWith ? { rehydrate_with: rehydrateWith } : {}),
730
780
  },
731
781
  }
732
782
  : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medicine-wheel/app",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "description": "Medicine Wheel — Interactive visual layer for Indigenous relational research with Four Directions, ceremonies, and narrative arcs",
5
5
  "bin": {
6
6
  "mw": "dist/cli/mw.js",
@@ -94,33 +94,33 @@
94
94
  "release:major": "npm run version:major && npm run publish:all && npm run release:commit"
95
95
  },
96
96
  "dependencies": {
97
- "@medicine-wheel/ceremonial-diary": "^0.23.0",
98
- "@medicine-wheel/ceremony-protocol": "^0.23.0",
99
- "@medicine-wheel/community-identity": "^0.23.0",
100
- "@medicine-wheel/community-review": "^0.23.0",
101
- "@medicine-wheel/consent-lifecycle": "^0.23.0",
102
- "@medicine-wheel/creative-orientation": "^0.23.0",
103
- "@medicine-wheel/data-store": "^0.23.0",
104
- "@medicine-wheel/data-store-postgres": "^0.23.0",
105
- "@medicine-wheel/events": "^0.23.0",
106
- "@medicine-wheel/fire-keeper": "^0.23.0",
107
- "@medicine-wheel/github-ceremony": "^0.23.0",
108
- "@medicine-wheel/graph-viz": "^0.23.0",
109
- "@medicine-wheel/honcho": "^0.23.0",
110
- "@medicine-wheel/importance-unit": "^0.23.0",
111
- "@medicine-wheel/mcp": "^4.23.0",
112
- "@medicine-wheel/memory": "^0.23.0",
113
- "@medicine-wheel/narrative-cluster": "^0.23.0",
114
- "@medicine-wheel/narrative-engine": "^0.23.0",
115
- "@medicine-wheel/ontology-core": "^0.23.0",
116
- "@medicine-wheel/perception-layer": "^0.23.0",
117
- "@medicine-wheel/prompt-decomposition": "^0.23.0",
118
- "@medicine-wheel/relational-index": "^0.23.0",
119
- "@medicine-wheel/relational-query": "^0.23.0",
120
- "@medicine-wheel/session-reader": "^0.23.0",
121
- "@medicine-wheel/storage-provider": "^0.23.0",
122
- "@medicine-wheel/transformation-tracker": "^0.23.0",
123
- "@medicine-wheel/ui-components": "^0.23.0",
97
+ "@medicine-wheel/ceremonial-diary": "^0.24.1",
98
+ "@medicine-wheel/ceremony-protocol": "^0.24.1",
99
+ "@medicine-wheel/community-identity": "^0.24.1",
100
+ "@medicine-wheel/community-review": "^0.24.1",
101
+ "@medicine-wheel/consent-lifecycle": "^0.24.1",
102
+ "@medicine-wheel/creative-orientation": "^0.24.1",
103
+ "@medicine-wheel/data-store": "^0.24.1",
104
+ "@medicine-wheel/data-store-postgres": "^0.24.1",
105
+ "@medicine-wheel/events": "^0.24.1",
106
+ "@medicine-wheel/fire-keeper": "^0.24.1",
107
+ "@medicine-wheel/github-ceremony": "^0.24.1",
108
+ "@medicine-wheel/graph-viz": "^0.24.1",
109
+ "@medicine-wheel/honcho": "^0.24.1",
110
+ "@medicine-wheel/importance-unit": "^0.24.1",
111
+ "@medicine-wheel/mcp": "^4.24.1",
112
+ "@medicine-wheel/memory": "^0.24.1",
113
+ "@medicine-wheel/narrative-cluster": "^0.24.1",
114
+ "@medicine-wheel/narrative-engine": "^0.24.1",
115
+ "@medicine-wheel/ontology-core": "^0.24.1",
116
+ "@medicine-wheel/perception-layer": "^0.24.1",
117
+ "@medicine-wheel/prompt-decomposition": "^0.24.1",
118
+ "@medicine-wheel/relational-index": "^0.24.1",
119
+ "@medicine-wheel/relational-query": "^0.24.1",
120
+ "@medicine-wheel/session-reader": "^0.24.1",
121
+ "@medicine-wheel/storage-provider": "^0.24.1",
122
+ "@medicine-wheel/transformation-tracker": "^0.24.1",
123
+ "@medicine-wheel/ui-components": "^0.24.1",
124
124
  "@miadi/episode-vessel": "^0.2.1",
125
125
  "@neondatabase/serverless": "^0.10.0",
126
126
  "@xyflow/react": "^12.3.0",