@schoolai/shipyard-mcp 0.2.2-next.489 → 0.2.2-next.493
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 → index.cjs} +388 -37
- package/apps/server/dist/{chunk-CYHEHTLS.js → chunk-5V7HUMDU.js} +57 -0
- package/apps/server/dist/{chunk-7ISZ4RKB.js → chunk-ZD2SHV5V.js} +1 -1
- package/apps/server/dist/{dist-HCVQNHBC.js → dist-2W7US5HB.js} +13 -1
- package/apps/server/dist/index.js +252 -10
- package/apps/server/dist/{input-request-manager-YOBSG7RN.js → input-request-manager-QX7MYHH7.js} +2 -2
- package/package.json +3 -3
|
@@ -28488,6 +28488,342 @@ var require_undici = __commonJS({
|
|
|
28488
28488
|
// src/index.ts
|
|
28489
28489
|
init_cjs_shims();
|
|
28490
28490
|
|
|
28491
|
+
// ../../packages/shared/dist/instructions/index.mjs
|
|
28492
|
+
init_cjs_shims();
|
|
28493
|
+
var CRITICAL_USAGE_SECTION = `## CRITICAL: When to Use Shipyard
|
|
28494
|
+
|
|
28495
|
+
\u26A0\uFE0F **MANDATORY USAGE RULE:**
|
|
28496
|
+
|
|
28497
|
+
If Shipyard is available, you MUST use it for:
|
|
28498
|
+
- Creating implementation plans
|
|
28499
|
+
- Tracking work that needs human review
|
|
28500
|
+
- Documenting proof of work (screenshots, videos, test results)
|
|
28501
|
+
- ANY user request involving "plan", "track", "verify", or "prove"
|
|
28502
|
+
|
|
28503
|
+
**DO NOT:**
|
|
28504
|
+
- Create plans manually in chat or as markdown files
|
|
28505
|
+
- Write implementation docs yourself when Shipyard is available
|
|
28506
|
+
- Suggest alternatives to Shipyard for trackable work
|
|
28507
|
+
- Overthink whether to use it - WHEN IN DOUBT, USE SHIPYARD
|
|
28508
|
+
|
|
28509
|
+
**Decision Tree:**
|
|
28510
|
+
\`\`\`
|
|
28511
|
+
Need to create/track/verify work?
|
|
28512
|
+
\u2502
|
|
28513
|
+
\u25BC
|
|
28514
|
+
Shipyard available?
|
|
28515
|
+
\u2502 \u2502
|
|
28516
|
+
YES NO
|
|
28517
|
+
\u2502 \u2502
|
|
28518
|
+
\u25BC \u25BC
|
|
28519
|
+
USE IT Manual approach
|
|
28520
|
+
NOW (tell user why)
|
|
28521
|
+
\`\`\``;
|
|
28522
|
+
var DELIVERABLES_SECTION = `## What are Deliverables?
|
|
28523
|
+
|
|
28524
|
+
Deliverables are measurable outcomes you can **prove** with artifacts (screenshots, videos, test results).
|
|
28525
|
+
|
|
28526
|
+
**Good deliverables (provable):**
|
|
28527
|
+
\`\`\`
|
|
28528
|
+
- [ ] Screenshot of working login page {#deliverable}
|
|
28529
|
+
- [ ] Video showing drag-and-drop feature {#deliverable}
|
|
28530
|
+
- [ ] Test results showing all tests pass {#deliverable}
|
|
28531
|
+
\`\`\`
|
|
28532
|
+
|
|
28533
|
+
**Bad deliverables (not provable - these are tasks, not deliverables):**
|
|
28534
|
+
\`\`\`
|
|
28535
|
+
- [ ] Implement getUserMedia API \u2190 Implementation detail, not provable
|
|
28536
|
+
- [ ] Add error handling \u2190 Can't capture this with an artifact
|
|
28537
|
+
- [ ] Refactor authentication \u2190 Too vague, no visual proof
|
|
28538
|
+
\`\`\`
|
|
28539
|
+
|
|
28540
|
+
**Rule:** If you can't screenshot/record/export it, it's not a deliverable.`;
|
|
28541
|
+
var ARTIFACT_TYPES_SECTION = `## Artifact Types
|
|
28542
|
+
|
|
28543
|
+
| Type | Use For | File Formats |
|
|
28544
|
+
|------|---------|--------------|
|
|
28545
|
+
| \`screenshot\` | UI changes, visual proof, error states | .png, .jpg, .webp |
|
|
28546
|
+
| \`video\` | Complex flows, interactions, animations | .mp4, .webm |
|
|
28547
|
+
| \`test_results\` | Test output, coverage reports | .json, .txt, .xml |
|
|
28548
|
+
| \`diff\` | Code changes, before/after comparisons | .diff, .patch |`;
|
|
28549
|
+
var TIPS_SECTION = `## Tips for Effective Use
|
|
28550
|
+
|
|
28551
|
+
1. **Plan deliverables first** - Decide what proves success before coding
|
|
28552
|
+
2. **Capture during work** - Take screenshots as you implement, not after
|
|
28553
|
+
3. **Be specific** - "Login page with error state" beats "Screenshot"
|
|
28554
|
+
4. **Link every artifact** - Always set \`deliverableId\` for auto-completion
|
|
28555
|
+
5. **Check feedback** - Read reviewer comments and iterate`;
|
|
28556
|
+
var WHEN_NOT_TO_USE_SECTION = `## When NOT to Use Shipyard
|
|
28557
|
+
|
|
28558
|
+
Skip Shipyard for:
|
|
28559
|
+
- Quick answers or research questions (no artifacts to capture)
|
|
28560
|
+
- Internal refactoring with no visible output
|
|
28561
|
+
- Tasks where proof adds no value (trivial fixes)
|
|
28562
|
+
- Exploration or debugging sessions
|
|
28563
|
+
- Pure documentation without implementation`;
|
|
28564
|
+
var TROUBLESHOOTING_SECTION = `## Troubleshooting
|
|
28565
|
+
|
|
28566
|
+
**Browser doesn't open:** Check MCP server is running and accessible.
|
|
28567
|
+
|
|
28568
|
+
**Upload fails:** Verify file path exists. For GitHub uploads, check \`GITHUB_TOKEN\` has repo write access.
|
|
28569
|
+
|
|
28570
|
+
**No auto-complete:** Ensure every deliverable has an artifact with matching \`deliverableId\`.
|
|
28571
|
+
|
|
28572
|
+
**Plan not syncing:** Check WebSocket connection to registry server.`;
|
|
28573
|
+
var COMMON_INSTRUCTIONS = [
|
|
28574
|
+
CRITICAL_USAGE_SECTION,
|
|
28575
|
+
DELIVERABLES_SECTION,
|
|
28576
|
+
ARTIFACT_TYPES_SECTION,
|
|
28577
|
+
TIPS_SECTION,
|
|
28578
|
+
WHEN_NOT_TO_USE_SECTION,
|
|
28579
|
+
TROUBLESHOOTING_SECTION
|
|
28580
|
+
].join("\n\n");
|
|
28581
|
+
var CLAUDE_CODE_HEADER = `[SHIPYARD] Collaborative planning with human review & proof-of-work tracking.`;
|
|
28582
|
+
var PLAN_MODE_WORKFLOW = `## How to Use (Claude Code with Hooks)
|
|
28583
|
+
|
|
28584
|
+
You have the **full Shipyard experience** with automatic hooks. Use native plan mode:
|
|
28585
|
+
|
|
28586
|
+
### Workflow
|
|
28587
|
+
|
|
28588
|
+
1. **Enter plan mode** (Shift+Tab) \u2192 Browser opens with live plan automatically
|
|
28589
|
+
2. **Write your plan** with \`{#deliverable}\` markers for provable outcomes
|
|
28590
|
+
3. **Exit plan mode** \u2192 Hook **BLOCKS** until human approves or requests changes
|
|
28591
|
+
4. **On approval** \u2192 You automatically receive: planId, sessionToken, deliverable IDs
|
|
28592
|
+
5. **Do the work** \u2192 Take screenshots/videos as you implement
|
|
28593
|
+
6. **Upload artifacts** \u2192 \`add_artifact(filePath, deliverableId)\` for each deliverable
|
|
28594
|
+
7. **Auto-complete** \u2192 When all deliverables have artifacts, task completes with snapshot URL
|
|
28595
|
+
|
|
28596
|
+
### After Approval
|
|
28597
|
+
|
|
28598
|
+
You only need ONE tool: \`add_artifact\`
|
|
28599
|
+
|
|
28600
|
+
The hook automatically injects everything you need (planId, sessionToken, deliverables).
|
|
28601
|
+
Just call \`add_artifact\` with the file path and deliverable ID.
|
|
28602
|
+
|
|
28603
|
+
\`\`\`typescript
|
|
28604
|
+
// Example: After approval, you'll have these in context
|
|
28605
|
+
// planId: "abc123"
|
|
28606
|
+
// sessionToken: "xyz..."
|
|
28607
|
+
// deliverables: [{ id: "del_xxx", text: "Screenshot of login" }]
|
|
28608
|
+
|
|
28609
|
+
await addArtifact({
|
|
28610
|
+
planId,
|
|
28611
|
+
sessionToken,
|
|
28612
|
+
type: 'screenshot',
|
|
28613
|
+
filename: 'login-page.png',
|
|
28614
|
+
source: 'file',
|
|
28615
|
+
filePath: '/tmp/screenshot.png',
|
|
28616
|
+
deliverableId: deliverables[0].id
|
|
28617
|
+
});
|
|
28618
|
+
\`\`\`
|
|
28619
|
+
|
|
28620
|
+
When the last deliverable gets an artifact, the task auto-completes and returns a snapshot URL.`;
|
|
28621
|
+
var IMPORTANT_NOTES = `## Important Notes for Claude Code
|
|
28622
|
+
|
|
28623
|
+
- **DO NOT call \`createPlan()\` directly** - The hook handles plan creation when you enter plan mode
|
|
28624
|
+
- **DO NOT use the Shipyard skill** - The hook provides everything you need
|
|
28625
|
+
- **DO NOT poll for approval** - The hook blocks automatically until human decides
|
|
28626
|
+
- **DO use plan mode** for ANY work that needs tracking, verification, or human review`;
|
|
28627
|
+
var CLAUDE_CODE_INSTRUCTIONS = [
|
|
28628
|
+
CLAUDE_CODE_HEADER,
|
|
28629
|
+
"",
|
|
28630
|
+
CRITICAL_USAGE_SECTION,
|
|
28631
|
+
"",
|
|
28632
|
+
PLAN_MODE_WORKFLOW,
|
|
28633
|
+
"",
|
|
28634
|
+
DELIVERABLES_SECTION,
|
|
28635
|
+
"",
|
|
28636
|
+
ARTIFACT_TYPES_SECTION,
|
|
28637
|
+
"",
|
|
28638
|
+
IMPORTANT_NOTES,
|
|
28639
|
+
"",
|
|
28640
|
+
TIPS_SECTION,
|
|
28641
|
+
"",
|
|
28642
|
+
WHEN_NOT_TO_USE_SECTION,
|
|
28643
|
+
"",
|
|
28644
|
+
TROUBLESHOOTING_SECTION
|
|
28645
|
+
].join("\n");
|
|
28646
|
+
var MCP_DIRECT_HEADER = `# Shipyard: Verified Work Tasks
|
|
28647
|
+
|
|
28648
|
+
> **MCP Integration:** Use \`execute_code\` to call Shipyard APIs. This skill teaches the workflow.
|
|
28649
|
+
|
|
28650
|
+
Shipyard turns invisible agent work into reviewable, verifiable tasks. Instead of trusting that code was written correctly, reviewers see screenshots, videos, and test results as proof.`;
|
|
28651
|
+
var MCP_TOOLS_OVERVIEW = `## Available MCP Tools
|
|
28652
|
+
|
|
28653
|
+
| Tool | Purpose |
|
|
28654
|
+
|------|---------|
|
|
28655
|
+
| \`execute_code\` | Run TypeScript that calls Shipyard APIs (recommended) |
|
|
28656
|
+
| \`request_user_input\` | Ask user questions via browser modal |
|
|
28657
|
+
|
|
28658
|
+
**Preferred approach:** Use \`execute_code\` to chain multiple API calls in one step.`;
|
|
28659
|
+
var MCP_WORKFLOW = `## Workflow (MCP Direct)
|
|
28660
|
+
|
|
28661
|
+
### Step 1: Create Plan
|
|
28662
|
+
|
|
28663
|
+
\`\`\`typescript
|
|
28664
|
+
const plan = await createPlan({
|
|
28665
|
+
title: "Add user authentication",
|
|
28666
|
+
content: \`
|
|
28667
|
+
## Deliverables
|
|
28668
|
+
- [ ] Screenshot of login page {#deliverable}
|
|
28669
|
+
- [ ] Screenshot of error handling {#deliverable}
|
|
28670
|
+
|
|
28671
|
+
## Implementation
|
|
28672
|
+
1. Create login form component
|
|
28673
|
+
2. Add validation
|
|
28674
|
+
3. Connect to auth API
|
|
28675
|
+
\`
|
|
28676
|
+
});
|
|
28677
|
+
|
|
28678
|
+
const { planId, sessionToken, deliverables, monitoringScript } = plan;
|
|
28679
|
+
// deliverables = [{ id: "del_xxx", text: "Screenshot of login page" }, ...]
|
|
28680
|
+
\`\`\`
|
|
28681
|
+
|
|
28682
|
+
### Step 2: Wait for Approval
|
|
28683
|
+
|
|
28684
|
+
For platforms without hooks, run the monitoring script in the background:
|
|
28685
|
+
|
|
28686
|
+
\`\`\`bash
|
|
28687
|
+
# The monitoringScript polls for approval status
|
|
28688
|
+
# Run it in background while you wait
|
|
28689
|
+
bash <(echo "$monitoringScript") &
|
|
28690
|
+
\`\`\`
|
|
28691
|
+
|
|
28692
|
+
Or poll manually:
|
|
28693
|
+
|
|
28694
|
+
\`\`\`typescript
|
|
28695
|
+
const status = await readPlan(planId, sessionToken);
|
|
28696
|
+
if (status.status === "in_progress") {
|
|
28697
|
+
// Approved! Proceed with work
|
|
28698
|
+
}
|
|
28699
|
+
if (status.status === "changes_requested") {
|
|
28700
|
+
// Read feedback, make changes
|
|
28701
|
+
}
|
|
28702
|
+
\`\`\`
|
|
28703
|
+
|
|
28704
|
+
### Step 3: Do the Work
|
|
28705
|
+
|
|
28706
|
+
Implement the feature, taking screenshots/recordings as you go.
|
|
28707
|
+
|
|
28708
|
+
### Step 4: Upload Artifacts
|
|
28709
|
+
|
|
28710
|
+
\`\`\`typescript
|
|
28711
|
+
await addArtifact({
|
|
28712
|
+
planId,
|
|
28713
|
+
sessionToken,
|
|
28714
|
+
type: 'screenshot',
|
|
28715
|
+
filename: 'login-page.png',
|
|
28716
|
+
source: 'file',
|
|
28717
|
+
filePath: '/path/to/screenshot.png',
|
|
28718
|
+
deliverableId: deliverables[0].id // Links to specific deliverable
|
|
28719
|
+
});
|
|
28720
|
+
|
|
28721
|
+
const result = await addArtifact({
|
|
28722
|
+
planId,
|
|
28723
|
+
sessionToken,
|
|
28724
|
+
type: 'screenshot',
|
|
28725
|
+
filename: 'error-handling.png',
|
|
28726
|
+
source: 'file',
|
|
28727
|
+
filePath: '/path/to/error.png',
|
|
28728
|
+
deliverableId: deliverables[1].id
|
|
28729
|
+
});
|
|
28730
|
+
|
|
28731
|
+
// Auto-complete triggers when ALL deliverables have artifacts
|
|
28732
|
+
if (result.allDeliverablesComplete) {
|
|
28733
|
+
console.log('Done!', result.snapshotUrl);
|
|
28734
|
+
}
|
|
28735
|
+
\`\`\``;
|
|
28736
|
+
var API_REFERENCE = `## API Reference
|
|
28737
|
+
|
|
28738
|
+
### createPlan(options)
|
|
28739
|
+
|
|
28740
|
+
Creates a new plan and opens it in the browser.
|
|
28741
|
+
|
|
28742
|
+
**Parameters:**
|
|
28743
|
+
- \`title\` (string) - Plan title
|
|
28744
|
+
- \`content\` (string) - Markdown content with \`{#deliverable}\` markers
|
|
28745
|
+
- \`repo\` (string, optional) - GitHub repo for artifact storage
|
|
28746
|
+
- \`prNumber\` (number, optional) - PR number to link
|
|
28747
|
+
|
|
28748
|
+
**Returns:** \`{ planId, sessionToken, url, deliverables, monitoringScript }\`
|
|
28749
|
+
|
|
28750
|
+
### readPlan(planId, sessionToken, options?)
|
|
28751
|
+
|
|
28752
|
+
Reads current plan state.
|
|
28753
|
+
|
|
28754
|
+
**Parameters:**
|
|
28755
|
+
- \`planId\` (string) - Plan ID
|
|
28756
|
+
- \`sessionToken\` (string) - Session token from createPlan
|
|
28757
|
+
- \`options.includeAnnotations\` (boolean) - Include reviewer comments
|
|
28758
|
+
|
|
28759
|
+
**Returns:** \`{ content, status, title, deliverables }\`
|
|
28760
|
+
|
|
28761
|
+
### addArtifact(options)
|
|
28762
|
+
|
|
28763
|
+
Uploads proof-of-work artifact.
|
|
28764
|
+
|
|
28765
|
+
**Parameters:**
|
|
28766
|
+
- \`planId\` (string) - Plan ID
|
|
28767
|
+
- \`sessionToken\` (string) - Session token
|
|
28768
|
+
- \`type\` ('screenshot' | 'video' | 'test_results' | 'diff')
|
|
28769
|
+
- \`filename\` (string) - File name
|
|
28770
|
+
- \`source\` ('file' | 'url' | 'base64')
|
|
28771
|
+
- \`filePath\` (string) - Local file path (when source='file')
|
|
28772
|
+
- \`deliverableId\` (string, optional) - Links artifact to deliverable
|
|
28773
|
+
|
|
28774
|
+
**Returns:** \`{ artifactId, url, allDeliverablesComplete, snapshotUrl? }\`
|
|
28775
|
+
|
|
28776
|
+
### requestUserInput(options)
|
|
28777
|
+
|
|
28778
|
+
Asks user a question via browser modal.
|
|
28779
|
+
|
|
28780
|
+
**Parameters:**
|
|
28781
|
+
- \`message\` (string) - Question to ask
|
|
28782
|
+
- \`type\` ('text' | 'choice' | 'confirm' | 'multiline')
|
|
28783
|
+
- \`options\` (string[], for 'choice') - Available choices
|
|
28784
|
+
- \`timeout\` (number, optional) - Timeout in seconds
|
|
28785
|
+
|
|
28786
|
+
**Returns:** \`{ success, response?, status }\``;
|
|
28787
|
+
var HANDLING_FEEDBACK = `## Handling Reviewer Feedback
|
|
28788
|
+
|
|
28789
|
+
\`\`\`typescript
|
|
28790
|
+
const status = await readPlan(planId, sessionToken, {
|
|
28791
|
+
includeAnnotations: true
|
|
28792
|
+
});
|
|
28793
|
+
|
|
28794
|
+
if (status.status === "changes_requested") {
|
|
28795
|
+
// Read the content for inline comments
|
|
28796
|
+
console.log(status.content);
|
|
28797
|
+
|
|
28798
|
+
// Make changes based on feedback
|
|
28799
|
+
// Upload new artifacts
|
|
28800
|
+
// Plan will transition back to pending_review
|
|
28801
|
+
}
|
|
28802
|
+
\`\`\``;
|
|
28803
|
+
var MCP_DIRECT_INSTRUCTIONS = [
|
|
28804
|
+
MCP_DIRECT_HEADER,
|
|
28805
|
+
"",
|
|
28806
|
+
CRITICAL_USAGE_SECTION,
|
|
28807
|
+
"",
|
|
28808
|
+
MCP_TOOLS_OVERVIEW,
|
|
28809
|
+
"",
|
|
28810
|
+
MCP_WORKFLOW,
|
|
28811
|
+
"",
|
|
28812
|
+
DELIVERABLES_SECTION,
|
|
28813
|
+
"",
|
|
28814
|
+
ARTIFACT_TYPES_SECTION,
|
|
28815
|
+
"",
|
|
28816
|
+
API_REFERENCE,
|
|
28817
|
+
"",
|
|
28818
|
+
HANDLING_FEEDBACK,
|
|
28819
|
+
"",
|
|
28820
|
+
TIPS_SECTION,
|
|
28821
|
+
"",
|
|
28822
|
+
WHEN_NOT_TO_USE_SECTION,
|
|
28823
|
+
"",
|
|
28824
|
+
TROUBLESHOOTING_SECTION
|
|
28825
|
+
].join("\n");
|
|
28826
|
+
|
|
28491
28827
|
// src/adapters/claude-code.ts
|
|
28492
28828
|
init_cjs_shims();
|
|
28493
28829
|
|
|
@@ -43832,6 +44168,42 @@ var InviteRedemptionSchema = external_exports.object({
|
|
|
43832
44168
|
redeemedAt: external_exports.number(),
|
|
43833
44169
|
tokenId: external_exports.string()
|
|
43834
44170
|
});
|
|
44171
|
+
var GitFileStatusSchema = external_exports.enum([
|
|
44172
|
+
"added",
|
|
44173
|
+
"modified",
|
|
44174
|
+
"deleted",
|
|
44175
|
+
"renamed",
|
|
44176
|
+
"copied",
|
|
44177
|
+
"untracked"
|
|
44178
|
+
]);
|
|
44179
|
+
var LocalFileChangeSchema = external_exports.object({
|
|
44180
|
+
path: external_exports.string(),
|
|
44181
|
+
status: GitFileStatusSchema,
|
|
44182
|
+
additions: external_exports.number(),
|
|
44183
|
+
deletions: external_exports.number(),
|
|
44184
|
+
patch: external_exports.string().optional()
|
|
44185
|
+
});
|
|
44186
|
+
var LocalChangesResponseSchema = external_exports.object({
|
|
44187
|
+
available: external_exports.literal(true),
|
|
44188
|
+
branch: external_exports.string(),
|
|
44189
|
+
baseBranch: external_exports.string(),
|
|
44190
|
+
staged: external_exports.array(LocalFileChangeSchema),
|
|
44191
|
+
unstaged: external_exports.array(LocalFileChangeSchema),
|
|
44192
|
+
untracked: external_exports.array(external_exports.string()),
|
|
44193
|
+
files: external_exports.array(LocalFileChangeSchema)
|
|
44194
|
+
});
|
|
44195
|
+
var LocalChangesUnavailableReasonSchema = external_exports.enum([
|
|
44196
|
+
"no_cwd",
|
|
44197
|
+
"not_git_repo",
|
|
44198
|
+
"mcp_not_connected",
|
|
44199
|
+
"git_error"
|
|
44200
|
+
]);
|
|
44201
|
+
var LocalChangesUnavailableSchema = external_exports.object({
|
|
44202
|
+
available: external_exports.literal(false),
|
|
44203
|
+
reason: LocalChangesUnavailableReasonSchema,
|
|
44204
|
+
message: external_exports.string()
|
|
44205
|
+
});
|
|
44206
|
+
var LocalChangesResultSchema = external_exports.discriminatedUnion("available", [LocalChangesResponseSchema, LocalChangesUnavailableSchema]);
|
|
43835
44207
|
var ConversationExportStartMetaSchema = external_exports.object({
|
|
43836
44208
|
exportId: external_exports.string(),
|
|
43837
44209
|
totalChunks: external_exports.number().int().positive(),
|
|
@@ -44027,6 +44399,21 @@ var planRouter = router({
|
|
|
44027
44399
|
}),
|
|
44028
44400
|
hasConnections: publicProcedure.input(PlanIdSchema).output(HasConnectionsResponseSchema).query(async ({ input, ctx }) => {
|
|
44029
44401
|
return { hasConnections: await ctx.getPlanStore().hasActiveConnections(input.planId) };
|
|
44402
|
+
}),
|
|
44403
|
+
getLocalChanges: publicProcedure.input(PlanIdSchema).output(LocalChangesResultSchema).query(async ({ input, ctx }) => {
|
|
44404
|
+
const metadata = getPlanMetadata(await ctx.getOrCreateDoc(input.planId));
|
|
44405
|
+
if (!metadata) throw new TRPCError({
|
|
44406
|
+
code: "NOT_FOUND",
|
|
44407
|
+
message: "Plan not found"
|
|
44408
|
+
});
|
|
44409
|
+
const origin = metadata.origin;
|
|
44410
|
+
const cwd = origin?.platform === "claude-code" ? origin.cwd : void 0;
|
|
44411
|
+
if (!cwd) return {
|
|
44412
|
+
available: false,
|
|
44413
|
+
reason: "no_cwd",
|
|
44414
|
+
message: "Plan has no associated working directory. Only Claude Code plans support local changes."
|
|
44415
|
+
};
|
|
44416
|
+
return ctx.getLocalChanges(cwd);
|
|
44030
44417
|
})
|
|
44031
44418
|
});
|
|
44032
44419
|
var subscriptionRouter = router({
|
|
@@ -46094,46 +46481,10 @@ async function readStdin() {
|
|
|
46094
46481
|
return Buffer.concat(chunks).toString("utf-8");
|
|
46095
46482
|
}
|
|
46096
46483
|
function outputSessionStartContext() {
|
|
46097
|
-
const context = `[SHIPYARD] Collaborative planning with human review & proof-of-work tracking.
|
|
46098
|
-
|
|
46099
|
-
IMPORTANT: Use native plan mode (Shift+Tab) to create plans. The hook handles everything automatically.
|
|
46100
|
-
|
|
46101
|
-
## What are Deliverables?
|
|
46102
|
-
|
|
46103
|
-
Deliverables are measurable outcomes you can prove with artifacts (screenshots, videos, test results).
|
|
46104
|
-
|
|
46105
|
-
Good deliverables (provable):
|
|
46106
|
-
\`\`\`
|
|
46107
|
-
- [ ] Screenshot of working login page {#deliverable}
|
|
46108
|
-
- [ ] Video showing feature in action {#deliverable}
|
|
46109
|
-
- [ ] Test results showing all tests pass {#deliverable}
|
|
46110
|
-
\`\`\`
|
|
46111
|
-
|
|
46112
|
-
Bad deliverables (implementation details, not provable):
|
|
46113
|
-
\`\`\`
|
|
46114
|
-
- [ ] Implement getUserMedia API \u2190 This is a task, not a deliverable
|
|
46115
|
-
- [ ] Add error handling \u2190 Can't prove this with an artifact
|
|
46116
|
-
\`\`\`
|
|
46117
|
-
|
|
46118
|
-
## Workflow
|
|
46119
|
-
|
|
46120
|
-
1. Enter plan mode (Shift+Tab) \u2192 Browser opens with live plan
|
|
46121
|
-
2. Write plan with {#deliverable} markers for provable outcomes
|
|
46122
|
-
3. Exit plan mode \u2192 Hook BLOCKS until human approves
|
|
46123
|
-
4. On approval \u2192 You receive planId, sessionToken, and deliverable IDs
|
|
46124
|
-
5. Do work \u2192 Take screenshots/videos as you go
|
|
46125
|
-
6. \`add_artifact(filePath, deliverableId)\` for each deliverable
|
|
46126
|
-
7. When all deliverables fulfilled \u2192 Auto-completes with snapshot URL
|
|
46127
|
-
|
|
46128
|
-
## After Approval
|
|
46129
|
-
|
|
46130
|
-
You only need ONE tool: \`add_artifact\`
|
|
46131
|
-
|
|
46132
|
-
When the last deliverable gets an artifact, the task auto-completes and returns a snapshot URL for your PR.`;
|
|
46133
46484
|
const hookOutput = {
|
|
46134
46485
|
hookSpecificOutput: {
|
|
46135
46486
|
hookEventName: "SessionStart",
|
|
46136
|
-
additionalContext:
|
|
46487
|
+
additionalContext: CLAUDE_CODE_INSTRUCTIONS
|
|
46137
46488
|
}
|
|
46138
46489
|
};
|
|
46139
46490
|
console.log(JSON.stringify(hookOutput));
|
|
@@ -2356,6 +2356,42 @@ function getTokenTimeRemaining(expiresAt) {
|
|
|
2356
2356
|
formatted: `${minutes}m`
|
|
2357
2357
|
};
|
|
2358
2358
|
}
|
|
2359
|
+
var GitFileStatusSchema = z3.enum([
|
|
2360
|
+
"added",
|
|
2361
|
+
"modified",
|
|
2362
|
+
"deleted",
|
|
2363
|
+
"renamed",
|
|
2364
|
+
"copied",
|
|
2365
|
+
"untracked"
|
|
2366
|
+
]);
|
|
2367
|
+
var LocalFileChangeSchema = z3.object({
|
|
2368
|
+
path: z3.string(),
|
|
2369
|
+
status: GitFileStatusSchema,
|
|
2370
|
+
additions: z3.number(),
|
|
2371
|
+
deletions: z3.number(),
|
|
2372
|
+
patch: z3.string().optional()
|
|
2373
|
+
});
|
|
2374
|
+
var LocalChangesResponseSchema = z3.object({
|
|
2375
|
+
available: z3.literal(true),
|
|
2376
|
+
branch: z3.string(),
|
|
2377
|
+
baseBranch: z3.string(),
|
|
2378
|
+
staged: z3.array(LocalFileChangeSchema),
|
|
2379
|
+
unstaged: z3.array(LocalFileChangeSchema),
|
|
2380
|
+
untracked: z3.array(z3.string()),
|
|
2381
|
+
files: z3.array(LocalFileChangeSchema)
|
|
2382
|
+
});
|
|
2383
|
+
var LocalChangesUnavailableReasonSchema = z3.enum([
|
|
2384
|
+
"no_cwd",
|
|
2385
|
+
"not_git_repo",
|
|
2386
|
+
"mcp_not_connected",
|
|
2387
|
+
"git_error"
|
|
2388
|
+
]);
|
|
2389
|
+
var LocalChangesUnavailableSchema = z3.object({
|
|
2390
|
+
available: z3.literal(false),
|
|
2391
|
+
reason: LocalChangesUnavailableReasonSchema,
|
|
2392
|
+
message: z3.string()
|
|
2393
|
+
});
|
|
2394
|
+
var LocalChangesResultSchema = z3.discriminatedUnion("available", [LocalChangesResponseSchema, LocalChangesUnavailableSchema]);
|
|
2359
2395
|
var P2PMessageType = {
|
|
2360
2396
|
CONVERSATION_EXPORT_START: 240,
|
|
2361
2397
|
CONVERSATION_CHUNK: 241,
|
|
@@ -2763,6 +2799,21 @@ var planRouter = router({
|
|
|
2763
2799
|
}),
|
|
2764
2800
|
hasConnections: publicProcedure.input(PlanIdSchema).output(HasConnectionsResponseSchema).query(async ({ input, ctx }) => {
|
|
2765
2801
|
return { hasConnections: await ctx.getPlanStore().hasActiveConnections(input.planId) };
|
|
2802
|
+
}),
|
|
2803
|
+
getLocalChanges: publicProcedure.input(PlanIdSchema).output(LocalChangesResultSchema).query(async ({ input, ctx }) => {
|
|
2804
|
+
const metadata = getPlanMetadata(await ctx.getOrCreateDoc(input.planId));
|
|
2805
|
+
if (!metadata) throw new TRPCError({
|
|
2806
|
+
code: "NOT_FOUND",
|
|
2807
|
+
message: "Plan not found"
|
|
2808
|
+
});
|
|
2809
|
+
const origin = metadata.origin;
|
|
2810
|
+
const cwd = origin?.platform === "claude-code" ? origin.cwd : void 0;
|
|
2811
|
+
if (!cwd) return {
|
|
2812
|
+
available: false,
|
|
2813
|
+
reason: "no_cwd",
|
|
2814
|
+
message: "Plan has no associated working directory. Only Claude Code plans support local changes."
|
|
2815
|
+
};
|
|
2816
|
+
return ctx.getLocalChanges(cwd);
|
|
2766
2817
|
})
|
|
2767
2818
|
});
|
|
2768
2819
|
var subscriptionRouter = router({
|
|
@@ -2957,6 +3008,12 @@ export {
|
|
|
2957
3008
|
parseInviteFromUrl,
|
|
2958
3009
|
buildInviteUrl,
|
|
2959
3010
|
getTokenTimeRemaining,
|
|
3011
|
+
GitFileStatusSchema,
|
|
3012
|
+
LocalFileChangeSchema,
|
|
3013
|
+
LocalChangesResponseSchema,
|
|
3014
|
+
LocalChangesUnavailableReasonSchema,
|
|
3015
|
+
LocalChangesUnavailableSchema,
|
|
3016
|
+
LocalChangesResultSchema,
|
|
2960
3017
|
P2PMessageType,
|
|
2961
3018
|
ConversationExportStartMetaSchema,
|
|
2962
3019
|
ChunkMessageSchema,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
DeliverableSchema,
|
|
29
29
|
DevinOriginMetadataSchema,
|
|
30
30
|
GetReviewStatusResponseSchema,
|
|
31
|
+
GitFileStatusSchema,
|
|
31
32
|
GitHubPRResponseSchema,
|
|
32
33
|
HasConnectionsResponseSchema,
|
|
33
34
|
HookApiErrorSchema,
|
|
@@ -40,6 +41,11 @@ import {
|
|
|
40
41
|
InviteTokenSchema,
|
|
41
42
|
LinkedPRSchema,
|
|
42
43
|
LinkedPRStatusValues,
|
|
44
|
+
LocalChangesResponseSchema,
|
|
45
|
+
LocalChangesResultSchema,
|
|
46
|
+
LocalChangesUnavailableReasonSchema,
|
|
47
|
+
LocalChangesUnavailableSchema,
|
|
48
|
+
LocalFileChangeSchema,
|
|
43
49
|
NON_PLAN_DB_NAMES,
|
|
44
50
|
OriginMetadataSchema,
|
|
45
51
|
OriginPlatformValues,
|
|
@@ -206,7 +212,7 @@ import {
|
|
|
206
212
|
updateLinkedPRStatus,
|
|
207
213
|
updatePlanIndexViewedBy,
|
|
208
214
|
validateA2AMessages
|
|
209
|
-
} from "./chunk-
|
|
215
|
+
} from "./chunk-5V7HUMDU.js";
|
|
210
216
|
import "./chunk-JSBRDJBE.js";
|
|
211
217
|
export {
|
|
212
218
|
A2ADataPartSchema,
|
|
@@ -238,6 +244,7 @@ export {
|
|
|
238
244
|
DeliverableSchema,
|
|
239
245
|
DevinOriginMetadataSchema,
|
|
240
246
|
GetReviewStatusResponseSchema,
|
|
247
|
+
GitFileStatusSchema,
|
|
241
248
|
GitHubPRResponseSchema,
|
|
242
249
|
HasConnectionsResponseSchema,
|
|
243
250
|
HookApiErrorSchema,
|
|
@@ -250,6 +257,11 @@ export {
|
|
|
250
257
|
InviteTokenSchema,
|
|
251
258
|
LinkedPRSchema,
|
|
252
259
|
LinkedPRStatusValues,
|
|
260
|
+
LocalChangesResponseSchema,
|
|
261
|
+
LocalChangesResultSchema,
|
|
262
|
+
LocalChangesUnavailableReasonSchema,
|
|
263
|
+
LocalChangesUnavailableSchema,
|
|
264
|
+
LocalFileChangeSchema,
|
|
253
265
|
NON_PLAN_DB_NAMES,
|
|
254
266
|
OriginMetadataSchema,
|
|
255
267
|
OriginPlatformValues,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./chunk-EBNL5ZX7.js";
|
|
21
21
|
import {
|
|
22
22
|
InputRequestManager
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZD2SHV5V.js";
|
|
24
24
|
import {
|
|
25
25
|
ArtifactSchema,
|
|
26
26
|
DeliverableSchema,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
setPlanMetadata,
|
|
73
73
|
touchPlanIndexEntry,
|
|
74
74
|
transitionPlanStatus
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-5V7HUMDU.js";
|
|
76
76
|
import {
|
|
77
77
|
loadEnv,
|
|
78
78
|
logger
|
|
@@ -383,6 +383,247 @@ function attachCRDTValidation(planId, doc) {
|
|
|
383
383
|
logger.debug({ planId }, "CRDT validation observers attached");
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
// src/git-local-changes.ts
|
|
387
|
+
import { execSync } from "child_process";
|
|
388
|
+
function getLocalChanges(cwd) {
|
|
389
|
+
try {
|
|
390
|
+
try {
|
|
391
|
+
execSync("git rev-parse --is-inside-work-tree", {
|
|
392
|
+
cwd,
|
|
393
|
+
encoding: "utf-8",
|
|
394
|
+
timeout: 5e3,
|
|
395
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
396
|
+
});
|
|
397
|
+
} catch {
|
|
398
|
+
return {
|
|
399
|
+
available: false,
|
|
400
|
+
reason: "not_git_repo",
|
|
401
|
+
message: `Directory is not a git repository: ${cwd}`
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
let branch;
|
|
405
|
+
try {
|
|
406
|
+
branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
407
|
+
cwd,
|
|
408
|
+
encoding: "utf-8",
|
|
409
|
+
timeout: 5e3,
|
|
410
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
411
|
+
}).trim();
|
|
412
|
+
if (branch === "HEAD") {
|
|
413
|
+
branch = execSync("git rev-parse --short HEAD", {
|
|
414
|
+
cwd,
|
|
415
|
+
encoding: "utf-8",
|
|
416
|
+
timeout: 5e3,
|
|
417
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
418
|
+
}).trim();
|
|
419
|
+
}
|
|
420
|
+
} catch (error) {
|
|
421
|
+
logger.warn({ error, cwd }, "Could not get current branch");
|
|
422
|
+
branch = "unknown";
|
|
423
|
+
}
|
|
424
|
+
const statusOutput = execSync("git status --porcelain", {
|
|
425
|
+
cwd,
|
|
426
|
+
encoding: "utf-8",
|
|
427
|
+
timeout: 1e4,
|
|
428
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
429
|
+
});
|
|
430
|
+
const { staged, unstaged, untracked } = parseGitStatus(statusOutput);
|
|
431
|
+
let diffOutput = "";
|
|
432
|
+
try {
|
|
433
|
+
diffOutput = execSync("git diff HEAD", {
|
|
434
|
+
cwd,
|
|
435
|
+
encoding: "utf-8",
|
|
436
|
+
timeout: 3e4,
|
|
437
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
438
|
+
// 10MB
|
|
439
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
440
|
+
});
|
|
441
|
+
} catch (error) {
|
|
442
|
+
logger.debug({ error, cwd }, "git diff HEAD failed, trying alternatives");
|
|
443
|
+
try {
|
|
444
|
+
diffOutput = execSync("git diff --cached", {
|
|
445
|
+
cwd,
|
|
446
|
+
encoding: "utf-8",
|
|
447
|
+
timeout: 3e4,
|
|
448
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
449
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
450
|
+
});
|
|
451
|
+
} catch {
|
|
452
|
+
diffOutput = "";
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const files = parseDiffOutput(diffOutput);
|
|
456
|
+
const allPaths = /* @__PURE__ */ new Set([
|
|
457
|
+
...staged.map((f) => f.path),
|
|
458
|
+
...unstaged.map((f) => f.path),
|
|
459
|
+
...files.map((f) => f.path)
|
|
460
|
+
]);
|
|
461
|
+
const mergedFiles = [];
|
|
462
|
+
for (const path2 of allPaths) {
|
|
463
|
+
const diffFile = files.find((f) => f.path === path2);
|
|
464
|
+
const stagedFile = staged.find((f) => f.path === path2);
|
|
465
|
+
const unstagedFile = unstaged.find((f) => f.path === path2);
|
|
466
|
+
if (diffFile) {
|
|
467
|
+
mergedFiles.push(diffFile);
|
|
468
|
+
} else {
|
|
469
|
+
const status = stagedFile?.status ?? unstagedFile?.status ?? "modified";
|
|
470
|
+
mergedFiles.push({
|
|
471
|
+
path: path2,
|
|
472
|
+
status,
|
|
473
|
+
additions: 0,
|
|
474
|
+
deletions: 0,
|
|
475
|
+
patch: void 0
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
mergedFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
480
|
+
logger.debug(
|
|
481
|
+
{
|
|
482
|
+
cwd,
|
|
483
|
+
branch,
|
|
484
|
+
stagedCount: staged.length,
|
|
485
|
+
unstagedCount: unstaged.length,
|
|
486
|
+
untrackedCount: untracked.length,
|
|
487
|
+
filesCount: mergedFiles.length
|
|
488
|
+
},
|
|
489
|
+
"Got local changes"
|
|
490
|
+
);
|
|
491
|
+
return {
|
|
492
|
+
available: true,
|
|
493
|
+
branch,
|
|
494
|
+
baseBranch: "HEAD",
|
|
495
|
+
staged,
|
|
496
|
+
unstaged,
|
|
497
|
+
untracked,
|
|
498
|
+
files: mergedFiles
|
|
499
|
+
};
|
|
500
|
+
} catch (error) {
|
|
501
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
502
|
+
logger.error({ error, cwd }, "Failed to get local changes");
|
|
503
|
+
return {
|
|
504
|
+
available: false,
|
|
505
|
+
reason: "git_error",
|
|
506
|
+
message: `Git error: ${message}`
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function parseGitStatus(output) {
|
|
511
|
+
const staged = [];
|
|
512
|
+
const unstaged = [];
|
|
513
|
+
const untracked = [];
|
|
514
|
+
for (const line of output.split("\n")) {
|
|
515
|
+
if (!line || line.length < 3) continue;
|
|
516
|
+
const x = line[0];
|
|
517
|
+
const y = line[1];
|
|
518
|
+
let path2 = line.slice(3);
|
|
519
|
+
if (path2.includes(" -> ")) {
|
|
520
|
+
path2 = path2.split(" -> ")[1] ?? path2;
|
|
521
|
+
}
|
|
522
|
+
if (x === "?" && y === "?") {
|
|
523
|
+
untracked.push(path2);
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
if (x === "!" && y === "!") {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
if (x && x !== " " && x !== "?") {
|
|
530
|
+
staged.push({
|
|
531
|
+
path: path2,
|
|
532
|
+
status: parseStatusChar(x),
|
|
533
|
+
additions: 0,
|
|
534
|
+
// We get this from diff output
|
|
535
|
+
deletions: 0
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
if (y && y !== " " && y !== "?") {
|
|
539
|
+
unstaged.push({
|
|
540
|
+
path: path2,
|
|
541
|
+
status: parseStatusChar(y),
|
|
542
|
+
additions: 0,
|
|
543
|
+
deletions: 0
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return { staged, unstaged, untracked };
|
|
548
|
+
}
|
|
549
|
+
function parseStatusChar(char) {
|
|
550
|
+
switch (char) {
|
|
551
|
+
case "A":
|
|
552
|
+
return "added";
|
|
553
|
+
case "M":
|
|
554
|
+
return "modified";
|
|
555
|
+
case "D":
|
|
556
|
+
return "deleted";
|
|
557
|
+
case "R":
|
|
558
|
+
return "renamed";
|
|
559
|
+
case "C":
|
|
560
|
+
return "copied";
|
|
561
|
+
case "U":
|
|
562
|
+
return "modified";
|
|
563
|
+
// Unmerged, treat as modified
|
|
564
|
+
default:
|
|
565
|
+
return "modified";
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function parseDiffOutput(diff) {
|
|
569
|
+
const files = [];
|
|
570
|
+
if (!diff.trim()) {
|
|
571
|
+
return files;
|
|
572
|
+
}
|
|
573
|
+
const fileDiffs = diff.split(/(?=diff --git )/);
|
|
574
|
+
for (const fileDiff of fileDiffs) {
|
|
575
|
+
if (!fileDiff.trim()) continue;
|
|
576
|
+
const headerMatch = fileDiff.match(/^diff --git a\/(.+?) b\/(.+)/m);
|
|
577
|
+
if (!headerMatch) continue;
|
|
578
|
+
const path2 = headerMatch[2] ?? headerMatch[1];
|
|
579
|
+
if (!path2) continue;
|
|
580
|
+
if (fileDiff.includes("Binary files")) {
|
|
581
|
+
files.push({
|
|
582
|
+
path: path2,
|
|
583
|
+
status: detectStatus(fileDiff),
|
|
584
|
+
additions: 0,
|
|
585
|
+
deletions: 0,
|
|
586
|
+
patch: void 0
|
|
587
|
+
});
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
let additions = 0;
|
|
591
|
+
let deletions = 0;
|
|
592
|
+
for (const line of fileDiff.split("\n")) {
|
|
593
|
+
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
594
|
+
additions++;
|
|
595
|
+
} else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
596
|
+
deletions++;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
const patchStart = fileDiff.indexOf("@@");
|
|
600
|
+
const patch = patchStart >= 0 ? fileDiff.slice(patchStart) : void 0;
|
|
601
|
+
files.push({
|
|
602
|
+
path: path2,
|
|
603
|
+
status: detectStatus(fileDiff),
|
|
604
|
+
additions,
|
|
605
|
+
deletions,
|
|
606
|
+
patch
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
return files;
|
|
610
|
+
}
|
|
611
|
+
function detectStatus(fileDiff) {
|
|
612
|
+
if (fileDiff.includes("new file mode")) {
|
|
613
|
+
return "added";
|
|
614
|
+
}
|
|
615
|
+
if (fileDiff.includes("deleted file mode")) {
|
|
616
|
+
return "deleted";
|
|
617
|
+
}
|
|
618
|
+
if (fileDiff.includes("rename from")) {
|
|
619
|
+
return "renamed";
|
|
620
|
+
}
|
|
621
|
+
if (fileDiff.includes("copy from")) {
|
|
622
|
+
return "copied";
|
|
623
|
+
}
|
|
624
|
+
return "modified";
|
|
625
|
+
}
|
|
626
|
+
|
|
386
627
|
// src/github-artifacts.ts
|
|
387
628
|
import { Octokit } from "@octokit/rest";
|
|
388
629
|
var ARTIFACTS_BRANCH = "plan-artifacts";
|
|
@@ -2123,7 +2364,8 @@ function createContext() {
|
|
|
2123
2364
|
getPlanStore: createPlanStore,
|
|
2124
2365
|
logger,
|
|
2125
2366
|
hookHandlers: createHookHandlers(),
|
|
2126
|
-
conversationHandlers: createConversationHandlers()
|
|
2367
|
+
conversationHandlers: createConversationHandlers(),
|
|
2368
|
+
getLocalChanges
|
|
2127
2369
|
};
|
|
2128
2370
|
}
|
|
2129
2371
|
function createApp() {
|
|
@@ -2474,7 +2716,7 @@ import ffmpegInstaller from "@ffmpeg-installer/ffmpeg";
|
|
|
2474
2716
|
import { z as z13 } from "zod";
|
|
2475
2717
|
|
|
2476
2718
|
// src/tools/add-artifact.ts
|
|
2477
|
-
import { execSync } from "child_process";
|
|
2719
|
+
import { execSync as execSync2 } from "child_process";
|
|
2478
2720
|
import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
2479
2721
|
import { ServerBlockNoteEditor as ServerBlockNoteEditor2 } from "@blocknote/server-util";
|
|
2480
2722
|
import { nanoid as nanoid4 } from "nanoid";
|
|
@@ -3028,7 +3270,7 @@ ${error.message}`
|
|
|
3028
3270
|
async function tryAutoLinkPR(ydoc, repo) {
|
|
3029
3271
|
let branch;
|
|
3030
3272
|
try {
|
|
3031
|
-
branch =
|
|
3273
|
+
branch = execSync2("git branch --show-current", {
|
|
3032
3274
|
encoding: "utf-8",
|
|
3033
3275
|
timeout: 5e3,
|
|
3034
3276
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -3204,7 +3446,7 @@ The comment will appear in the Changes tab when viewing this PR.`
|
|
|
3204
3446
|
};
|
|
3205
3447
|
|
|
3206
3448
|
// src/tools/complete-task.ts
|
|
3207
|
-
import { execSync as
|
|
3449
|
+
import { execSync as execSync3 } from "child_process";
|
|
3208
3450
|
import { ServerBlockNoteEditor as ServerBlockNoteEditor3 } from "@blocknote/server-util";
|
|
3209
3451
|
import { z as z5 } from "zod";
|
|
3210
3452
|
var CompleteTaskInput = z5.object({
|
|
@@ -3404,7 +3646,7 @@ linkPR({ planId, sessionToken, prNumber: 42 })
|
|
|
3404
3646
|
async function tryAutoLinkPR2(ydoc, repo) {
|
|
3405
3647
|
let branch;
|
|
3406
3648
|
try {
|
|
3407
|
-
branch =
|
|
3649
|
+
branch = execSync3("git branch --show-current", {
|
|
3408
3650
|
encoding: "utf-8",
|
|
3409
3651
|
timeout: 5e3,
|
|
3410
3652
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -5408,7 +5650,7 @@ async function setupReviewNotification(planId, pollIntervalSeconds) {
|
|
|
5408
5650
|
return { script, fullResponse: text };
|
|
5409
5651
|
}
|
|
5410
5652
|
async function requestUserInput(opts) {
|
|
5411
|
-
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-
|
|
5653
|
+
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-QX7MYHH7.js");
|
|
5412
5654
|
const ydoc = await getOrCreateDoc3(PLAN_INDEX_DOC_NAME);
|
|
5413
5655
|
const manager = new InputRequestManager2();
|
|
5414
5656
|
const params = opts.type === "choice" ? {
|
|
@@ -5452,7 +5694,7 @@ async function requestUserInput(opts) {
|
|
|
5452
5694
|
};
|
|
5453
5695
|
}
|
|
5454
5696
|
async function postActivityUpdate(opts) {
|
|
5455
|
-
const { logPlanEvent: logPlanEvent2 } = await import("./dist-
|
|
5697
|
+
const { logPlanEvent: logPlanEvent2 } = await import("./dist-2W7US5HB.js");
|
|
5456
5698
|
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-LSZ4CZRK.js");
|
|
5457
5699
|
const { nanoid: nanoid8 } = await import("nanoid");
|
|
5458
5700
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
@@ -5475,7 +5717,7 @@ async function postActivityUpdate(opts) {
|
|
|
5475
5717
|
return { success: true, eventId, requestId };
|
|
5476
5718
|
}
|
|
5477
5719
|
async function resolveActivityRequest(opts) {
|
|
5478
|
-
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-
|
|
5720
|
+
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-2W7US5HB.js");
|
|
5479
5721
|
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-LSZ4CZRK.js");
|
|
5480
5722
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
5481
5723
|
const actorName = await getGitHubUsername2();
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schoolai/shipyard-mcp",
|
|
3
|
-
"version": "0.2.2-next.
|
|
3
|
+
"version": "0.2.2-next.493",
|
|
4
4
|
"description": "Shipyard MCP server and CLI tools for distributed planning with CRDTs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mcp-server-shipyard": "./apps/server/dist/index.js",
|
|
8
|
-
"shipyard-hook": "./apps/hook/dist/index.
|
|
8
|
+
"shipyard-hook": "./apps/hook/dist/index.cjs"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"apps/server/dist",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"import": "./apps/server/dist/index.js"
|
|
20
20
|
},
|
|
21
21
|
"./hook": {
|
|
22
|
-
"
|
|
22
|
+
"require": "./apps/hook/dist/index.cjs"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|