@ran-sh/dsh-crew 0.3.5 → 0.3.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ran-sh/dsh-crew",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "type": "module",
5
5
  "main": "./src/hub/entry.mjs",
6
6
  "bin": {
@@ -125,7 +125,10 @@ function writeCurrentPointer({ home, name, version, path }) {
125
125
 
126
126
  function listPackageEdges(manifest) {
127
127
  // Returns [{name, optional}] covering dependencies and
128
- // optionalDependencies; platform-specific optional bits stay non-fatal.
128
+ // required peerDependencies. Packages in the DSH cohort use peers for
129
+ // shared protocol/runtime modules, but a persisted Crew payload has no host
130
+ // node_modules to supply them, so their transitive peers are runtime edges.
131
+ // Platform-specific optional bits and optional peers stay non-fatal.
129
132
  const edges = [];
130
133
  for (const [name] of Object.entries(manifest?.dependencies ?? {})) {
131
134
  edges.push({ name, optional: false });
@@ -133,6 +136,10 @@ function listPackageEdges(manifest) {
133
136
  for (const [name] of Object.entries(manifest?.optionalDependencies ?? {})) {
134
137
  if (!edges.some((edge) => edge.name === name)) edges.push({ name, optional: true });
135
138
  }
139
+ for (const [name] of Object.entries(manifest?.peerDependencies ?? {})) {
140
+ if (edges.some((edge) => edge.name === name)) continue;
141
+ edges.push({ name, optional: manifest?.peerDependenciesMeta?.[name]?.optional === true });
142
+ }
136
143
  return edges.filter((edge) => typeof edge.name === 'string' && edge.name.trim());
137
144
  }
138
145
 
@@ -329,12 +336,41 @@ export function stageCandidatePayload({
329
336
  * start and answer --help from inside the staged tree alone.
330
337
  */
331
338
  export function defaultPayloadSmoke(dir, { nodePath = process.execPath, runner = spawnSync } = {}) {
332
- const result = runner(nodePath, [join(dir, 'bin', 'dsh-crew.mjs'), '--help'], {
339
+ const cli = runner(nodePath, [join(dir, 'bin', 'dsh-crew.mjs'), '--help'], {
340
+ encoding: 'utf8', timeout: 120_000, windowsHide: true,
341
+ env: { ...process.env },
342
+ });
343
+ if (cli.status !== 0) {
344
+ return { ok: false, detail: `bin --help exited ${cli.status}: ${(cli.stderr || cli.stdout || '').trim().slice(-300)}` };
345
+ }
346
+
347
+ const initialize = {
348
+ jsonrpc: '2.0',
349
+ id: 1,
350
+ method: 'initialize',
351
+ params: {
352
+ protocolVersion: '2024-11-05',
353
+ capabilities: {},
354
+ clientInfo: { name: 'dsh-crew-payload-smoke', version: '1.0.0' },
355
+ },
356
+ };
357
+ const mcp = runner(nodePath, [join(dir, 'src', 'server.mjs')], {
333
358
  encoding: 'utf8', timeout: 120_000, windowsHide: true,
359
+ input: JSON.stringify(initialize) + '\n',
334
360
  env: { ...process.env },
335
361
  });
336
- if (result.status === 0) return { ok: true };
337
- return { ok: false, detail: `bin --help exited ${result.status}: ${(result.stderr || result.stdout || '').trim().slice(-300)}` };
362
+ if (mcp.status !== 0) {
363
+ return { ok: false, detail: `MCP initialize exited ${mcp.status}: ${(mcp.stderr || mcp.stdout || '').trim().slice(-300)}` };
364
+ }
365
+ let response;
366
+ try {
367
+ response = String(mcp.stdout ?? '').split(/\r?\n/).filter(Boolean)
368
+ .map((line) => JSON.parse(line)).find((entry) => entry?.id === initialize.id);
369
+ } catch { /* handled by the fail-closed response check below */ }
370
+ if (response?.result?.serverInfo?.name !== 'dsh-crew') {
371
+ return { ok: false, detail: `MCP initialize returned no valid dsh-crew response: ${String(mcp.stdout ?? '').trim().slice(-300)}` };
372
+ }
373
+ return { ok: true };
338
374
  }
339
375
 
340
376
  // Keyword boundaries reject identifiers containing the keywords
@@ -8,7 +8,7 @@
8
8
  // Keep this module pure and dependency-free so Hub, MCP and tests all use the
9
9
  // exact same compatibility rules.
10
10
 
11
- export const RUNTIME_VERSION = '0.3.5';
11
+ export const RUNTIME_VERSION = '0.3.6';
12
12
  export const HUB_PROTOCOL_VERSION = 1;
13
13
 
14
14
  export const HUB_CAPABILITIES = Object.freeze([