@schoolai/shipyard-mcp 0.4.0 → 0.4.1-nightly.20260128

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/README.md CHANGED
@@ -47,7 +47,11 @@ Shipyard is just an MCP server. One command or a simple JSON config—works with
47
47
  Full experience with hooks, skills, and auto-task creation:
48
48
 
49
49
  ```bash
50
- /plugin install SchoolAI/shipyard
50
+ # Step 1: Add the marketplace
51
+ /plugin marketplace add https://github.com/SchoolAI/shipyard.git
52
+
53
+ # Step 2: Install the plugin
54
+ /plugin install shipyard@schoolai-shipyard
51
55
  ```
52
56
 
53
57
  ### Cursor
@@ -59,7 +63,7 @@ Add to `~/.cursor/mcp.json`:
59
63
  "mcpServers": {
60
64
  "shipyard": {
61
65
  "command": "npx",
62
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
66
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
63
67
  }
64
68
  }
65
69
  }
@@ -70,7 +74,7 @@ Add to `~/.cursor/mcp.json`:
70
74
  Add via CLI:
71
75
 
72
76
  ```bash
73
- codex mcp add shipyard -- npx -y @schoolai/shipyard-mcp@latest
77
+ codex mcp add shipyard -- npx -y -p @schoolai/shipyard-mcp@latest mcp-server-shipyard
74
78
  ```
75
79
 
76
80
  Or add to `~/.codex/config.toml`:
@@ -78,13 +82,13 @@ Or add to `~/.codex/config.toml`:
78
82
  ```toml
79
83
  [mcp_servers.shipyard]
80
84
  command = "npx"
81
- args = ["-y", "@schoolai/shipyard-mcp@latest"]
85
+ args = ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
82
86
  ```
83
87
 
84
88
  ### VS Code / GitHub Copilot
85
89
 
86
90
  ```bash
87
- code --add-mcp '{"name":"shipyard","command":"npx","args":["-y","@schoolai/shipyard-mcp@latest"]}'
91
+ code --add-mcp '{"name":"shipyard","command":"npx","args":["-y","-p","@schoolai/shipyard-mcp@latest","mcp-server-shipyard"]}'
88
92
  ```
89
93
 
90
94
  <details>
@@ -102,7 +106,7 @@ Add to your config file:
102
106
  "mcpServers": {
103
107
  "shipyard": {
104
108
  "command": "npx",
105
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
109
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
106
110
  }
107
111
  }
108
112
  }
@@ -117,7 +121,7 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
117
121
  "mcpServers": {
118
122
  "shipyard": {
119
123
  "command": "npx",
120
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
124
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
121
125
  }
122
126
  }
123
127
  }
@@ -139,7 +143,7 @@ Add to `~/.config/zed/settings.json`:
139
143
  "shipyard": {
140
144
  "command": {
141
145
  "path": "npx",
142
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
146
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
143
147
  }
144
148
  }
145
149
  }
@@ -154,7 +158,7 @@ Create `.continue/mcpServers/shipyard.yaml`:
154
158
  mcpServers:
155
159
  - name: Shipyard
156
160
  command: npx
157
- args: ["-y", "@schoolai/shipyard-mcp@latest"]
161
+ args: ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
158
162
  ```
159
163
 
160
164
  </details>
@@ -33,9 +33,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  mod
34
34
  ));
35
35
 
36
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
36
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js
37
37
  var init_cjs_shims = __esm({
38
- "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js"() {
38
+ "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js"() {
39
39
  "use strict";
40
40
  }
41
41
  });
@@ -42366,13 +42366,32 @@ var PlanStatusValues = [
42366
42366
  "completed"
42367
42367
  ];
42368
42368
  var OriginPlatformValues = [
42369
+ "aider",
42370
+ "browser",
42369
42371
  "claude-code",
42370
- "devin",
42372
+ "cline",
42373
+ "codex",
42374
+ "continue",
42371
42375
  "cursor",
42376
+ "devin",
42377
+ "vscode",
42372
42378
  "windsurf",
42373
- "aider",
42379
+ "zed",
42374
42380
  "unknown"
42375
42381
  ];
42382
+ var AGENT_PLATFORMS = [
42383
+ "aider",
42384
+ "claude-code",
42385
+ "cline",
42386
+ "codex",
42387
+ "continue",
42388
+ "cursor",
42389
+ "devin",
42390
+ "vscode",
42391
+ "windsurf",
42392
+ "zed"
42393
+ ];
42394
+ var AGENT_PLATFORMS_SET = new Set(AGENT_PLATFORMS);
42376
42395
  var ClaudeCodeOriginMetadataSchema = external_exports.object({
42377
42396
  platform: external_exports.literal("claude-code"),
42378
42397
  sessionId: external_exports.string(),
@@ -43125,6 +43144,12 @@ var UrlKeyVersionSchema = external_exports.object({
43125
43144
  id: external_exports.string(),
43126
43145
  content: external_exports.array(external_exports.unknown())
43127
43146
  });
43147
+ var UrlDeliverableSchema = external_exports.object({
43148
+ id: external_exports.string().optional(),
43149
+ text: external_exports.string(),
43150
+ linkedArtifactId: external_exports.string().nullable().optional(),
43151
+ linkedAt: external_exports.number().optional()
43152
+ });
43128
43153
  var UrlEncodedPlanV1Schema = external_exports.object({
43129
43154
  v: external_exports.literal(1),
43130
43155
  id: external_exports.string(),
@@ -43132,9 +43157,9 @@ var UrlEncodedPlanV1Schema = external_exports.object({
43132
43157
  status: external_exports.enum(PlanStatusValues),
43133
43158
  repo: external_exports.string().optional(),
43134
43159
  pr: external_exports.number().optional(),
43135
- content: external_exports.array(external_exports.unknown()),
43160
+ content: external_exports.array(external_exports.unknown()).optional(),
43136
43161
  artifacts: external_exports.array(ArtifactSchema).optional(),
43137
- deliverables: external_exports.array(DeliverableSchema).optional(),
43162
+ deliverables: external_exports.array(UrlDeliverableSchema).optional(),
43138
43163
  comments: external_exports.array(external_exports.unknown()).optional()
43139
43164
  });
43140
43165
  var UrlEncodedPlanV2Schema = external_exports.object({
@@ -43144,9 +43169,9 @@ var UrlEncodedPlanV2Schema = external_exports.object({
43144
43169
  status: external_exports.enum(PlanStatusValues),
43145
43170
  repo: external_exports.string().optional(),
43146
43171
  pr: external_exports.number().optional(),
43147
- content: external_exports.array(external_exports.unknown()),
43172
+ content: external_exports.array(external_exports.unknown()).optional(),
43148
43173
  artifacts: external_exports.array(ArtifactSchema).optional(),
43149
- deliverables: external_exports.array(DeliverableSchema).optional(),
43174
+ deliverables: external_exports.array(UrlDeliverableSchema).optional(),
43150
43175
  comments: external_exports.array(external_exports.unknown()).optional(),
43151
43176
  versionRefs: external_exports.array(UrlSnapshotRefSchema).optional(),
43152
43177
  keyVersions: external_exports.array(UrlKeyVersionSchema).optional()
@@ -44144,6 +44169,11 @@ var EnvironmentContextSchema = external_exports.object({
44144
44169
  hostname: external_exports.string().optional(),
44145
44170
  repo: external_exports.string().optional()
44146
44171
  });
44172
+ var BrowserContextSchema = external_exports.object({
44173
+ browser: external_exports.string().optional(),
44174
+ os: external_exports.string().optional(),
44175
+ lastActive: external_exports.number().optional()
44176
+ });
44147
44177
  var GitHubPRResponseSchema = external_exports.object({
44148
44178
  number: external_exports.number(),
44149
44179
  html_url: external_exports.string().url(),
@@ -45077,12 +45107,44 @@ var DEFAULT_AGENT_TYPE = "claude-code";
45077
45107
  // src/logger.ts
45078
45108
  init_cjs_shims();
45079
45109
  var import_node_fs = require("fs");
45110
+ var import_node_path2 = require("path");
45111
+ var import_pino = __toESM(require_pino());
45112
+
45113
+ // src/config/env/registry.ts
45114
+ init_cjs_shims();
45080
45115
  var import_node_os = require("os");
45081
45116
  var import_node_path = require("path");
45082
- var import_pino = __toESM(require_pino());
45083
45117
 
45084
- // src/config/env/server.ts
45118
+ // ../../packages/shared/dist/index.mjs
45119
+ init_cjs_shims();
45120
+
45121
+ // ../../packages/shared/dist/registry-config.mjs
45085
45122
  init_cjs_shims();
45123
+ var DEFAULT_REGISTRY_PORTS = [
45124
+ 32191,
45125
+ 32192,
45126
+ 32193,
45127
+ 32194,
45128
+ 32195,
45129
+ 32196,
45130
+ 32197,
45131
+ 32198,
45132
+ 32199
45133
+ ];
45134
+
45135
+ // ../../packages/shared/dist/index.mjs
45136
+ var import_node_crypto = require("crypto");
45137
+ function computeHash(content) {
45138
+ return (0, import_node_crypto.createHash)("sha256").update(content).digest("hex").slice(0, 16);
45139
+ }
45140
+ function generateSessionToken() {
45141
+ return (0, import_node_crypto.randomBytes)(32).toString("base64url");
45142
+ }
45143
+ function hashSessionToken(token) {
45144
+ return (0, import_node_crypto.createHash)("sha256").update(token).digest("hex");
45145
+ }
45146
+ var APPROVAL_LONG_POLL_TIMEOUT_MS = 1800 * 1e3;
45147
+ var DEFAULT_TRPC_TIMEOUT_MS = 10 * 1e3;
45086
45148
 
45087
45149
  // src/config/config.ts
45088
45150
  init_cjs_shims();
@@ -45106,15 +45168,31 @@ ${errorMessages}`);
45106
45168
  }
45107
45169
  }
45108
45170
 
45109
- // src/config/env/server.ts
45171
+ // src/config/env/registry.ts
45110
45172
  var schema = external_exports.object({
45173
+ REGISTRY_PORT: external_exports.string().optional().transform((val) => {
45174
+ if (!val) return DEFAULT_REGISTRY_PORTS;
45175
+ const port = Number.parseInt(val, 10);
45176
+ if (Number.isNaN(port)) {
45177
+ throw new Error(`REGISTRY_PORT must be a valid number, got: ${val}`);
45178
+ }
45179
+ return [port];
45180
+ }),
45181
+ SHIPYARD_STATE_DIR: external_exports.string().optional().transform((val) => val || void 0).default(() => (0, import_node_path.join)((0, import_node_os.homedir)(), ".shipyard"))
45182
+ });
45183
+ var registryConfig = loadEnv(schema);
45184
+
45185
+ // src/config/env/server.ts
45186
+ init_cjs_shims();
45187
+ var schema2 = external_exports.object({
45111
45188
  LOG_LEVEL: external_exports.enum(["debug", "info", "warn", "error"]).default("info")
45112
45189
  });
45113
- var serverConfig = loadEnv(schema);
45190
+ var serverConfig = loadEnv(schema2);
45114
45191
 
45115
45192
  // src/logger.ts
45116
- var LOG_DIR = (0, import_node_path.join)((0, import_node_os.homedir)(), ".shipyard");
45117
- var LOG_FILE = (0, import_node_path.join)(LOG_DIR, "hook-debug.log");
45193
+ var LOG_DIR = registryConfig.SHIPYARD_STATE_DIR;
45194
+ var LOG_FILE = (0, import_node_path2.join)(LOG_DIR, "hook-debug.log");
45195
+ var HOOK_LOG_FILE = LOG_FILE;
45118
45196
  var isTest = process.env.NODE_ENV === "test" || process.env.VITEST;
45119
45197
  if (!isTest && !(0, import_node_fs.existsSync)(LOG_DIR)) {
45120
45198
  try {
@@ -45299,47 +45377,9 @@ ${feedbackText}`;
45299
45377
  // src/core/plan-manager.ts
45300
45378
  init_cjs_shims();
45301
45379
 
45302
- // ../../packages/shared/dist/index.mjs
45303
- init_cjs_shims();
45304
-
45305
- // ../../packages/shared/dist/registry-config.mjs
45306
- init_cjs_shims();
45307
- var DEFAULT_REGISTRY_PORTS = [32191, 32192];
45308
-
45309
- // ../../packages/shared/dist/index.mjs
45310
- var import_node_crypto = require("crypto");
45311
- function computeHash(content) {
45312
- return (0, import_node_crypto.createHash)("sha256").update(content).digest("hex").slice(0, 16);
45313
- }
45314
- function generateSessionToken() {
45315
- return (0, import_node_crypto.randomBytes)(32).toString("base64url");
45316
- }
45317
- function hashSessionToken(token) {
45318
- return (0, import_node_crypto.createHash)("sha256").update(token).digest("hex");
45319
- }
45320
- var APPROVAL_LONG_POLL_TIMEOUT_MS = 1800 * 1e3;
45321
- var DEFAULT_TRPC_TIMEOUT_MS = 10 * 1e3;
45322
-
45323
45380
  // src/http-client.ts
45324
45381
  init_cjs_shims();
45325
45382
 
45326
- // src/config/env/registry.ts
45327
- init_cjs_shims();
45328
- var import_node_os2 = require("os");
45329
- var import_node_path2 = require("path");
45330
- var schema2 = external_exports.object({
45331
- REGISTRY_PORT: external_exports.string().optional().transform((val) => {
45332
- if (!val) return DEFAULT_REGISTRY_PORTS;
45333
- const port = Number.parseInt(val, 10);
45334
- if (Number.isNaN(port)) {
45335
- throw new Error(`REGISTRY_PORT must be a valid number, got: ${val}`);
45336
- }
45337
- return [port];
45338
- }),
45339
- SHIPYARD_STATE_DIR: external_exports.string().optional().default(() => (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".shipyard"))
45340
- });
45341
- var registryConfig = loadEnv(schema2);
45342
-
45343
45383
  // src/trpc-client.ts
45344
45384
  init_cjs_shims();
45345
45385
 
@@ -46716,7 +46756,10 @@ init_cjs_shims();
46716
46756
  // src/config/env/web.ts
46717
46757
  init_cjs_shims();
46718
46758
  var schema3 = external_exports.object({
46719
- SHIPYARD_WEB_URL: external_exports.string().url().default("https://schoolai.github.io/shipyard")
46759
+ SHIPYARD_WEB_URL: external_exports.string().url().default(() => {
46760
+ const nodeEnv = process.env.NODE_ENV || "development";
46761
+ return nodeEnv === "production" ? "https://schoolai.github.io/shipyard" : "http://localhost:5173";
46762
+ })
46720
46763
  });
46721
46764
  var webConfig = loadEnv(schema3);
46722
46765
 
@@ -46896,7 +46939,7 @@ async function checkReviewStatus(sessionId, planContent, originMetadata) {
46896
46939
  );
46897
46940
  return {
46898
46941
  allow: false,
46899
- message: "Internal error: Plan content found but session state missing. Check ~/.shipyard/hook-debug.log and report this issue."
46942
+ message: `Internal error: Plan content found but session state missing. Check ${HOOK_LOG_FILE} and report this issue.`
46900
46943
  };
46901
46944
  }
46902
46945
  if (!state.planId) {
@@ -46915,7 +46958,7 @@ async function checkReviewStatus(sessionId, planContent, originMetadata) {
46915
46958
  logger.warn({ err, planId }, "Failed to get review status, blocking exit");
46916
46959
  return {
46917
46960
  allow: false,
46918
- message: "Cannot verify plan approval status. Ensure the Shipyard MCP server is running. Check ~/.shipyard/server-debug.log for details.",
46961
+ message: "Cannot verify plan approval status. Ensure the Shipyard MCP server is running. Check server-debug.log in your Shipyard state directory for details.",
46919
46962
  planId
46920
46963
  };
46921
46964
  }
@@ -46982,7 +47025,7 @@ async function handlePlanExit(event) {
46982
47025
  const errorCode = err instanceof Error && "code" in err && typeof err.code === "string" ? err.code : void 0;
46983
47026
  logger.error({ err, message: errorMessage, code: errorCode }, "Failed to check review status");
46984
47027
  const isConnectionError = errorCode === "ECONNREFUSED" || errorCode === "ECONNRESET" || errorCode === "ETIMEDOUT" || errorCode === "ENOTFOUND" || errorMessage?.includes("connect") || errorMessage?.includes("timeout") || errorMessage?.includes("WebSocket") || errorMessage?.includes("not available");
46985
- const message = isConnectionError ? "Cannot connect to Shipyard server. Ensure the Shipyard MCP server is running. Check ~/.shipyard/hook-debug.log for details." : `Review system error: ${errorMessage}. Check ~/.shipyard/hook-debug.log for details.`;
47028
+ const message = isConnectionError ? `Cannot connect to Shipyard server. Ensure the Shipyard MCP server is running. Check ${HOOK_LOG_FILE} for details.` : `Review system error: ${errorMessage}. Check ${HOOK_LOG_FILE} for details.`;
46986
47029
  return {
46987
47030
  allow: false,
46988
47031
  message
@@ -47097,7 +47140,7 @@ async function main() {
47097
47140
  hookEventName: "PermissionRequest",
47098
47141
  decision: {
47099
47142
  behavior: "deny",
47100
- message: `Hook error: ${errorMessage}. Check ~/.shipyard/hook-debug.log for details.`
47143
+ message: `Hook error: ${errorMessage}. Check ${HOOK_LOG_FILE} for details.`
47101
47144
  }
47102
47145
  }
47103
47146
  })
@@ -26,21 +26,37 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
 
27
27
  // src/logger.ts
28
28
  import { mkdirSync } from "fs";
29
- import { homedir } from "os";
30
- import { dirname, join } from "path";
29
+ import { dirname, join as join2 } from "path";
31
30
  import pino from "pino";
32
31
 
33
- // src/config/env/server.ts
32
+ // src/config/env/registry.ts
33
+ import { homedir } from "os";
34
+ import { join } from "path";
35
+
36
+ // ../../packages/shared/dist/registry-config.mjs
37
+ var DEFAULT_REGISTRY_PORTS = [
38
+ 32191,
39
+ 32192,
40
+ 32193,
41
+ 32194,
42
+ 32195,
43
+ 32196,
44
+ 32197,
45
+ 32198,
46
+ 32199
47
+ ];
48
+
49
+ // src/config/env/registry.ts
34
50
  import { z as z2 } from "zod";
35
51
 
36
52
  // src/config/config.ts
37
53
  import { z } from "zod";
38
- function loadEnv(schema2) {
54
+ function loadEnv(schema3) {
39
55
  try {
40
- return schema2.parse(process.env);
56
+ return schema3.parse(process.env);
41
57
  } catch (error) {
42
58
  if (error instanceof z.ZodError) {
43
- const testResult = schema2.safeParse(void 0);
59
+ const testResult = schema3.safeParse(void 0);
44
60
  if (testResult.success) {
45
61
  return testResult.data;
46
62
  }
@@ -55,15 +71,30 @@ ${errorMessages}`);
55
71
  }
56
72
  }
57
73
 
58
- // src/config/env/server.ts
74
+ // src/config/env/registry.ts
59
75
  var schema = z2.object({
60
- NODE_ENV: z2.enum(["development", "test", "production"]).default("development"),
61
- LOG_LEVEL: z2.enum(["debug", "info", "warn", "error"]).default("info")
76
+ REGISTRY_PORT: z2.string().optional().transform((val) => {
77
+ if (!val) return DEFAULT_REGISTRY_PORTS;
78
+ const port = Number.parseInt(val, 10);
79
+ if (Number.isNaN(port)) {
80
+ throw new Error(`REGISTRY_PORT must be a valid number, got: ${val}`);
81
+ }
82
+ return [port];
83
+ }),
84
+ SHIPYARD_STATE_DIR: z2.string().optional().transform((val) => val || void 0).default(() => join(homedir(), ".shipyard"))
85
+ });
86
+ var registryConfig = loadEnv(schema);
87
+
88
+ // src/config/env/server.ts
89
+ import { z as z3 } from "zod";
90
+ var schema2 = z3.object({
91
+ NODE_ENV: z3.enum(["development", "test", "production"]).default("development"),
92
+ LOG_LEVEL: z3.enum(["debug", "info", "warn", "error"]).default("info")
62
93
  });
63
- var serverConfig = loadEnv(schema);
94
+ var serverConfig = loadEnv(schema2);
64
95
 
65
96
  // src/logger.ts
66
- var LOG_FILE = join(homedir(), ".shipyard", "server-debug.log");
97
+ var LOG_FILE = join2(registryConfig.SHIPYARD_STATE_DIR, "server-debug.log");
67
98
  try {
68
99
  mkdirSync(dirname(LOG_FILE), { recursive: true });
69
100
  } catch {
@@ -181,6 +212,7 @@ export {
181
212
  __commonJS,
182
213
  __toESM,
183
214
  loadEnv,
215
+ registryConfig,
184
216
  logger,
185
217
  isSessionStateCreated,
186
218
  isSessionStateSynced,