@schoolai/shipyard-mcp 0.1.3-next.460 → 0.1.3-next.466
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/apps/hook/dist/index.js +3 -3
- package/apps/server/dist/{chunk-4BEPSPPL.js → chunk-75NZRAN5.js} +3 -3
- package/apps/server/dist/{chunk-FTOVV4YW.js → chunk-MZTJGBLT.js} +1 -1
- package/apps/server/dist/{dist-FZ4WTJ2H.js → dist-HIDISXZO.js} +1 -1
- package/apps/server/dist/index.js +111 -39
- package/apps/server/dist/{input-request-manager-YMNFW4JM.js → input-request-manager-43QSOJS3.js} +2 -2
- package/package.json +1 -1
package/apps/hook/dist/index.js
CHANGED
|
@@ -28494,7 +28494,7 @@ init_cjs_shims();
|
|
|
28494
28494
|
// ../../packages/schema/dist/index.mjs
|
|
28495
28495
|
init_cjs_shims();
|
|
28496
28496
|
|
|
28497
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
28497
|
+
// ../../packages/schema/dist/yjs-helpers-CFQmkNYl.mjs
|
|
28498
28498
|
init_cjs_shims();
|
|
28499
28499
|
|
|
28500
28500
|
// ../../packages/schema/dist/plan.mjs
|
|
@@ -42665,7 +42665,7 @@ var PRReviewCommentSchema = external_exports.object({
|
|
|
42665
42665
|
resolved: external_exports.boolean().optional()
|
|
42666
42666
|
});
|
|
42667
42667
|
|
|
42668
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
42668
|
+
// ../../packages/schema/dist/yjs-helpers-CFQmkNYl.mjs
|
|
42669
42669
|
function assertNever2(value) {
|
|
42670
42670
|
throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
|
|
42671
42671
|
}
|
|
@@ -42770,7 +42770,7 @@ var InputRequestBaseSchema = external_exports.object({
|
|
|
42770
42770
|
message: external_exports.string().min(1, "Message cannot be empty"),
|
|
42771
42771
|
status: external_exports.enum(InputRequestStatusValues),
|
|
42772
42772
|
defaultValue: external_exports.string().optional(),
|
|
42773
|
-
timeout: external_exports.number().int().min(10, "Timeout must be at least 10 seconds").max(
|
|
42773
|
+
timeout: external_exports.number().int().min(10, "Timeout must be at least 10 seconds").max(14400, "Timeout cannot exceed 4 hours").optional(),
|
|
42774
42774
|
planId: external_exports.string().optional(),
|
|
42775
42775
|
response: external_exports.unknown().optional(),
|
|
42776
42776
|
answeredAt: external_exports.number().optional(),
|
|
@@ -863,7 +863,7 @@ function createHandedOffConversationVersion(params) {
|
|
|
863
863
|
return ConversationVersionSchema.parse(version);
|
|
864
864
|
}
|
|
865
865
|
|
|
866
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
866
|
+
// ../../packages/schema/dist/yjs-helpers-CFQmkNYl.mjs
|
|
867
867
|
import { z as z2 } from "zod";
|
|
868
868
|
import { nanoid as nanoid2 } from "nanoid";
|
|
869
869
|
import * as Y from "yjs";
|
|
@@ -959,7 +959,7 @@ var CreateSubscriptionRequestSchema = z2.object({
|
|
|
959
959
|
threshold: z2.number().positive().optional()
|
|
960
960
|
});
|
|
961
961
|
var CreateSubscriptionResponseSchema = z2.object({ clientId: z2.string() });
|
|
962
|
-
var DEFAULT_INPUT_REQUEST_TIMEOUT_SECONDS =
|
|
962
|
+
var DEFAULT_INPUT_REQUEST_TIMEOUT_SECONDS = 1800;
|
|
963
963
|
var InputRequestTypeValues = [
|
|
964
964
|
"text",
|
|
965
965
|
"multiline",
|
|
@@ -978,7 +978,7 @@ var InputRequestBaseSchema = z2.object({
|
|
|
978
978
|
message: z2.string().min(1, "Message cannot be empty"),
|
|
979
979
|
status: z2.enum(InputRequestStatusValues),
|
|
980
980
|
defaultValue: z2.string().optional(),
|
|
981
|
-
timeout: z2.number().int().min(10, "Timeout must be at least 10 seconds").max(
|
|
981
|
+
timeout: z2.number().int().min(10, "Timeout must be at least 10 seconds").max(14400, "Timeout cannot exceed 4 hours").optional(),
|
|
982
982
|
planId: z2.string().optional(),
|
|
983
983
|
response: z2.unknown().optional(),
|
|
984
984
|
answeredAt: z2.number().optional(),
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./chunk-EBNL5ZX7.js";
|
|
20
20
|
import {
|
|
21
21
|
InputRequestManager
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-MZTJGBLT.js";
|
|
23
23
|
import {
|
|
24
24
|
ArtifactSchema,
|
|
25
25
|
DeliverableSchema,
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
setPlanMetadata,
|
|
69
69
|
touchPlanIndexEntry,
|
|
70
70
|
transitionPlanStatus
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-75NZRAN5.js";
|
|
72
72
|
import {
|
|
73
73
|
loadEnv,
|
|
74
74
|
logger
|
|
@@ -2477,7 +2477,7 @@ import { z as z12 } from "zod";
|
|
|
2477
2477
|
|
|
2478
2478
|
// src/tools/add-artifact.ts
|
|
2479
2479
|
import { execSync } from "child_process";
|
|
2480
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
2480
|
+
import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
2481
2481
|
import { ServerBlockNoteEditor as ServerBlockNoteEditor2 } from "@blocknote/server-util";
|
|
2482
2482
|
import { nanoid as nanoid4 } from "nanoid";
|
|
2483
2483
|
import { z as z3 } from "zod";
|
|
@@ -2909,6 +2909,14 @@ Linked to deliverable: ${input.deliverableId}` : "";
|
|
|
2909
2909
|
logger.warn({ planId }, "Cannot update plan index: missing ownerId");
|
|
2910
2910
|
}
|
|
2911
2911
|
logger.info({ planId, snapshotUrl }, "Task auto-completed");
|
|
2912
|
+
const { homedir: homedir5 } = await import("os");
|
|
2913
|
+
const { join: join6 } = await import("path");
|
|
2914
|
+
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
2915
|
+
const snapshotsDir = join6(homedir5(), ".shipyard", "snapshots");
|
|
2916
|
+
await mkdir3(snapshotsDir, { recursive: true });
|
|
2917
|
+
const snapshotFile = join6(snapshotsDir, `${planId}.txt`);
|
|
2918
|
+
await writeFile4(snapshotFile, snapshotUrl, "utf-8");
|
|
2919
|
+
logger.info({ planId, snapshotFile }, "Snapshot URL written to file");
|
|
2912
2920
|
let prText = "";
|
|
2913
2921
|
if (linkedPR) {
|
|
2914
2922
|
prText = `
|
|
@@ -2934,10 +2942,11 @@ URL: ${artifactUrl}${linkedText}
|
|
|
2934
2942
|
|
|
2935
2943
|
\u{1F389} ALL DELIVERABLES COMPLETE! Task auto-completed.${prText}
|
|
2936
2944
|
|
|
2937
|
-
Snapshot URL
|
|
2945
|
+
Snapshot URL saved to: ${snapshotFile}
|
|
2946
|
+
(Note: Very long URL - recommend not reading directly. Use file path to attach to PR or access later.)`
|
|
2938
2947
|
}
|
|
2939
2948
|
],
|
|
2940
|
-
//
|
|
2949
|
+
// Keep structured data for execute_code wrapper
|
|
2941
2950
|
snapshotUrl,
|
|
2942
2951
|
allDeliverablesComplete: true
|
|
2943
2952
|
};
|
|
@@ -4140,7 +4149,9 @@ USAGE (for non-hook agents):
|
|
|
4140
4149
|
1. Call this tool to get monitoring script
|
|
4141
4150
|
2. Run script in background: bash <script> &
|
|
4142
4151
|
3. Script polls registry server for status changes
|
|
4143
|
-
4. Exits when status becomes '
|
|
4152
|
+
4. Exits when status becomes 'in_progress' (approved) or 'changes_requested' (needs work)
|
|
4153
|
+
|
|
4154
|
+
REQUIREMENTS: The script requires 'jq' for URL encoding. Install with: brew install jq (macOS) or apt install jq (Linux)`,
|
|
4144
4155
|
inputSchema: {
|
|
4145
4156
|
type: "object",
|
|
4146
4157
|
properties: {
|
|
@@ -4158,25 +4169,64 @@ USAGE (for non-hook agents):
|
|
|
4158
4169
|
const { planId, pollIntervalSeconds = 30 } = input;
|
|
4159
4170
|
const registryPort2 = registryConfig.REGISTRY_PORT[0];
|
|
4160
4171
|
const trpcUrl = `http://localhost:${registryPort2}/trpc`;
|
|
4161
|
-
const
|
|
4162
|
-
|
|
4172
|
+
const statusInProgress = PlanStatusValues.find((s) => s === "in_progress");
|
|
4173
|
+
const statusChangesRequested = PlanStatusValues.find((s) => s === "changes_requested");
|
|
4174
|
+
if (!statusInProgress || !statusChangesRequested) {
|
|
4175
|
+
throw new Error("Required status values not found in PlanStatusValues");
|
|
4176
|
+
}
|
|
4177
|
+
const script = `#!/bin/bash
|
|
4178
|
+
# Monitor plan "${planId}" for approval status changes
|
|
4179
|
+
# Polls the Shipyard registry server and exits when approved/rejected
|
|
4180
|
+
|
|
4181
|
+
# Check for required dependency
|
|
4182
|
+
if ! command -v jq &> /dev/null; then
|
|
4183
|
+
echo "Error: jq is required but not installed."
|
|
4184
|
+
echo "Install with: brew install jq (macOS) or apt install jq (Linux)"
|
|
4185
|
+
exit 1
|
|
4186
|
+
fi
|
|
4187
|
+
|
|
4188
|
+
TRPC_URL="${trpcUrl}"
|
|
4189
|
+
PLAN_ID="${planId}"
|
|
4190
|
+
POLL_INTERVAL=${pollIntervalSeconds}
|
|
4191
|
+
|
|
4192
|
+
# Subscribe to status changes via tRPC mutation
|
|
4193
|
+
echo "Subscribing to plan changes..."
|
|
4194
|
+
RESPONSE=$(curl -sf -X POST "$TRPC_URL/subscription.create" \\
|
|
4163
4195
|
-H "Content-Type: application/json" \\
|
|
4164
|
-
-d '{"planId":"$
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
echo "
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4196
|
+
-d '{"planId":"'"$PLAN_ID"'","subscribe":["status","comments"],"windowMs":5000,"threshold":1}')
|
|
4197
|
+
|
|
4198
|
+
# Extract clientId from response: {"result":{"data":{"clientId":"..."}}}
|
|
4199
|
+
CLIENT_ID=$(echo "$RESPONSE" | sed -n 's/.*"clientId":"\\([^"]*\\)".*/\\1/p')
|
|
4200
|
+
|
|
4201
|
+
if [ -z "$CLIENT_ID" ]; then
|
|
4202
|
+
echo "Failed to subscribe. Is the Shipyard registry server running?"
|
|
4203
|
+
echo "Response: $RESPONSE"
|
|
4204
|
+
exit 1
|
|
4205
|
+
fi
|
|
4206
|
+
|
|
4207
|
+
echo "Subscribed with clientId: $CLIENT_ID"
|
|
4208
|
+
echo "Polling every $POLL_INTERVAL seconds..."
|
|
4209
|
+
|
|
4210
|
+
# Poll for changes via tRPC query (GET with url-encoded input)
|
|
4211
|
+
while true; do
|
|
4212
|
+
sleep $POLL_INTERVAL
|
|
4213
|
+
|
|
4214
|
+
# URL-encode the input JSON for GET request
|
|
4215
|
+
INPUT='{"planId":"'"$PLAN_ID"'","clientId":"'"$CLIENT_ID"'"}'
|
|
4216
|
+
ENCODED_INPUT=$(printf '%s' "$INPUT" | jq -sRr @uri)
|
|
4217
|
+
|
|
4218
|
+
RESULT=$(curl -sf "$TRPC_URL/subscription.getChanges?input=$ENCODED_INPUT" 2>/dev/null)
|
|
4219
|
+
|
|
4220
|
+
# Check if changes are ready: {"result":{"data":{"ready":true,"changes":"..."}}}
|
|
4221
|
+
if echo "$RESULT" | grep -q '"ready":true'; then
|
|
4222
|
+
CHANGES=$(echo "$RESULT" | sed -n 's/.*"changes":"\\([^"]*\\)".*/\\1/p')
|
|
4223
|
+
echo "Changes detected: $CHANGES"
|
|
4224
|
+
|
|
4225
|
+
# Exit on status change to in_progress (approved) or changes_requested (needs work)
|
|
4226
|
+
if echo "$CHANGES" | grep -qE "Status:.*(${statusInProgress}|${statusChangesRequested})"; then
|
|
4227
|
+
echo "Plan status changed. Exiting."
|
|
4228
|
+
exit 0
|
|
4229
|
+
fi
|
|
4180
4230
|
fi
|
|
4181
4231
|
done`;
|
|
4182
4232
|
return {
|
|
@@ -4189,10 +4239,13 @@ done`;
|
|
|
4189
4239
|
${script}
|
|
4190
4240
|
\`\`\`
|
|
4191
4241
|
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4242
|
+
**Usage:** Save to a file and run in background: \`bash script.sh &\`
|
|
4243
|
+
|
|
4244
|
+
The script:
|
|
4245
|
+
- Subscribes to status/comment changes via tRPC
|
|
4246
|
+
- Polls every ${pollIntervalSeconds} seconds
|
|
4247
|
+
- Exits when status becomes in_progress (approved) or changes_requested (needs work)
|
|
4248
|
+
- Requires \`jq\` for URL encoding (install: brew install jq)`
|
|
4196
4249
|
}
|
|
4197
4250
|
]
|
|
4198
4251
|
};
|
|
@@ -4779,17 +4832,36 @@ Parameters:
|
|
|
4779
4832
|
- pollIntervalSeconds (number, optional): Polling interval (default: 30)
|
|
4780
4833
|
|
|
4781
4834
|
Returns:
|
|
4782
|
-
- script: Bash script that polls registry server and exits when status becomes '
|
|
4835
|
+
- script: Bash script that polls registry server and exits when status becomes 'in_progress' (approved) or 'changes_requested' (needs work)
|
|
4783
4836
|
|
|
4784
|
-
|
|
4837
|
+
**IMPORTANT:** This is ONLY for agents WITHOUT hook support (Cursor, Devin, Windsurf, etc).
|
|
4838
|
+
Claude Code users have automatic blocking via the shipyard hook - you don't need this.
|
|
4785
4839
|
|
|
4786
|
-
|
|
4840
|
+
**Complete workflow for non-hook agents (example user code):**
|
|
4787
4841
|
\`\`\`typescript
|
|
4842
|
+
// 1. Create plan and get the monitoring script in ONE code block
|
|
4843
|
+
const plan = await createPlan({
|
|
4844
|
+
title: "My Feature Implementation",
|
|
4845
|
+
content: "- [ ] Screenshot of working feature {#deliverable}"
|
|
4846
|
+
});
|
|
4847
|
+
|
|
4848
|
+
// 2. Get the polling script (returns bash script as string)
|
|
4788
4849
|
const { script } = await setupReviewNotification(plan.planId, 15);
|
|
4789
|
-
|
|
4790
|
-
|
|
4850
|
+
|
|
4851
|
+
// 3. Return both so the agent can run the script
|
|
4852
|
+
return {
|
|
4853
|
+
planId: plan.planId,
|
|
4854
|
+
sessionToken: plan.sessionToken,
|
|
4855
|
+
monitoringScript: script,
|
|
4856
|
+
instructions: "Run the monitoring script in background: bash <script> &"
|
|
4857
|
+
};
|
|
4791
4858
|
\`\`\`
|
|
4792
4859
|
|
|
4860
|
+
The agent then runs the returned bash script in the background. The script will:
|
|
4861
|
+
- Poll the registry server every N seconds
|
|
4862
|
+
- Print status changes to stdout
|
|
4863
|
+
- Exit with code 0 when the plan is approved/rejected
|
|
4864
|
+
|
|
4793
4865
|
---
|
|
4794
4866
|
|
|
4795
4867
|
### requestUserInput(opts): Promise<{ success, response?, status, reason? }>
|
|
@@ -4801,7 +4873,7 @@ Parameters:
|
|
|
4801
4873
|
- options (string[], optional): For 'choice' type - available options (required for choice)
|
|
4802
4874
|
- multiSelect (boolean, optional): For 'choice' type - allow selecting multiple options (uses checkboxes instead of radio buttons)
|
|
4803
4875
|
- defaultValue (string, optional): Pre-filled value for text/multiline inputs
|
|
4804
|
-
- timeout (number, optional): Timeout in seconds (default:
|
|
4876
|
+
- timeout (number, optional): Timeout in seconds (default: 1800, min: 10, max: 14400)
|
|
4805
4877
|
- planId (string, optional): Optional metadata to link request to plan (for activity log filtering)
|
|
4806
4878
|
|
|
4807
4879
|
Returns:
|
|
@@ -5076,7 +5148,7 @@ async function setupReviewNotification(planId, pollIntervalSeconds) {
|
|
|
5076
5148
|
return { script, fullResponse: text };
|
|
5077
5149
|
}
|
|
5078
5150
|
async function requestUserInput(opts) {
|
|
5079
|
-
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-
|
|
5151
|
+
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-43QSOJS3.js");
|
|
5080
5152
|
const ydoc = await getOrCreateDoc3(PLAN_INDEX_DOC_NAME);
|
|
5081
5153
|
const manager = new InputRequestManager2();
|
|
5082
5154
|
const params = opts.type === "choice" ? {
|
|
@@ -5120,7 +5192,7 @@ async function requestUserInput(opts) {
|
|
|
5120
5192
|
};
|
|
5121
5193
|
}
|
|
5122
5194
|
async function postActivityUpdate(opts) {
|
|
5123
|
-
const { logPlanEvent: logPlanEvent2 } = await import("./dist-
|
|
5195
|
+
const { logPlanEvent: logPlanEvent2 } = await import("./dist-HIDISXZO.js");
|
|
5124
5196
|
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-6PHKR2FY.js");
|
|
5125
5197
|
const { nanoid: nanoid7 } = await import("nanoid");
|
|
5126
5198
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
@@ -5143,7 +5215,7 @@ async function postActivityUpdate(opts) {
|
|
|
5143
5215
|
return { success: true, eventId, requestId };
|
|
5144
5216
|
}
|
|
5145
5217
|
async function resolveActivityRequest(opts) {
|
|
5146
|
-
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-
|
|
5218
|
+
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-HIDISXZO.js");
|
|
5147
5219
|
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-6PHKR2FY.js");
|
|
5148
5220
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
5149
5221
|
const actorName = await getGitHubUsername2();
|
|
@@ -5278,7 +5350,7 @@ var RequestUserInputInput = z13.object({
|
|
|
5278
5350
|
options: z13.array(z13.string()).optional().describe("For 'choice' type - available options (required for choice)"),
|
|
5279
5351
|
multiSelect: z13.boolean().optional().describe("For 'choice' type - allow selecting multiple options"),
|
|
5280
5352
|
defaultValue: z13.string().optional().describe("Pre-filled value for text/multiline inputs"),
|
|
5281
|
-
timeout: z13.number().optional().describe("Timeout in seconds (default:
|
|
5353
|
+
timeout: z13.number().optional().describe("Timeout in seconds (default: 1800, min: 10, max: 14400)"),
|
|
5282
5354
|
planId: z13.string().optional().describe("Optional metadata to link request to plan (for activity log filtering)")
|
|
5283
5355
|
});
|
|
5284
5356
|
var requestUserInputTool = {
|
|
@@ -5335,7 +5407,7 @@ NOTE: This is also available as requestUserInput() inside execute_code for multi
|
|
|
5335
5407
|
},
|
|
5336
5408
|
timeout: {
|
|
5337
5409
|
type: "number",
|
|
5338
|
-
description: "Timeout in seconds (default:
|
|
5410
|
+
description: "Timeout in seconds (default: 1800, min: 10, max: 14400)"
|
|
5339
5411
|
},
|
|
5340
5412
|
planId: {
|
|
5341
5413
|
type: "string",
|