@schoolai/shipyard-mcp 0.3.2-next.530 → 0.3.2-next.538

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
@@ -1,139 +1,173 @@
1
1
  <div align="center">
2
2
  <img src="apps/web/public/icon.svg" alt="Shipyard Logo" width="120" height="120">
3
3
  <h1>Shipyard</h1>
4
- <p><strong>Verify AI agent work with collaborative review and proof-of-work artifacts</strong></p>
4
+ <p><strong>Ship responsibly.</strong></p>
5
+ <p>Human-agent collaboration with receipts.</p>
5
6
 
6
7
  <p>
7
8
  <a href="https://github.com/SchoolAI/shipyard/actions"><img src="https://img.shields.io/github/actions/workflow/status/SchoolAI/shipyard/deploy.yml?branch=main&label=deploy" alt="Deploy Status"></a>
8
- <img src="https://img.shields.io/badge/TypeScript-5.6-3178C6?logo=typescript&logoColor=white" alt="TypeScript">
9
- <img src="https://img.shields.io/badge/pnpm-10.x-F69220?logo=pnpm&logoColor=white" alt="pnpm">
9
+ <a href="https://www.npmjs.com/package/@schoolai/shipyard-mcp"><img src="https://img.shields.io/npm/v/@schoolai/shipyard-mcp" alt="npm version"></a>
10
10
  <a href="./LICENSE.md"><img src="https://img.shields.io/badge/license-FSL--1.1-blue" alt="License"></a>
11
+ <a href="https://github.com/SchoolAI/shipyard/discussions"><img src="https://img.shields.io/github/discussions/SchoolAI/shipyard" alt="Discussions"></a>
11
12
  </p>
12
13
  </div>
13
14
 
14
15
  ---
15
16
 
16
- ## The Problem
17
-
18
- AI agents can generate implementation tasks, but there's no good way to:
19
- - **Verify** the agent actually did what it claimed
20
- - **Review** tasks collaboratively with humans in real-time
21
- - **Provide feedback** that agents can act on
17
+ <div align="center">
18
+ <img src="docs/assets/hero-inbox-split.png" alt="Shipyard Inbox with Task Detail" width="800">
19
+ <p><em>Inbox showing tasks needing review with split panel detail view</em></p>
20
+ </div>
22
21
 
23
- Shipyard solves this with P2P collaborative review and proof-of-work artifacts.
22
+ ## The Problem
24
23
 
25
- ## Features
24
+ You're managing multiple AI agents (Claude, Cursor, Devin), but there's no workspace where humans and agents collaborate together:
25
+ - **No verification** — Agent says "done" but you have no proof
26
+ - **No collaboration layer** — Humans review in GitHub, agents work in chat logs
27
+ - **No feedback loop** — You approve work, but the agent never sees it
26
28
 
27
- - **Real-time collaboration** Multiple reviewers sync via WebRTC, no server required
28
- - **Proof-of-work artifacts** — Screenshots, videos, test results stored in GitHub
29
- - **MCP integration** — Works with Claude Code, Cursor, and any MCP-compatible agent
30
- - **Zero infrastructure** — GitHub Pages + local MCP server, no paid services
31
- - **BlockNote editor** — Notion-like editing with inline comments and threads
32
- - **Offline-first** — IndexedDB persistence, works without network
29
+ Shipyard is the collaboration workspace for mixed human-agent teams. Agents create tasks with proof. Humans review in real-time. Feedback flows both ways.
33
30
 
34
- ## Platform Support
31
+ ## Why Shipyard
35
32
 
36
- | Platform | Status | Installation | Notes |
37
- |----------|--------|--------------|-------|
38
- | **Claude Code** | Full support | GitHub plugin | Complete integration with hooks + skills |
39
- | **OpenCode** | ⚠️ Experimental | npm + config | Native task mode, testing in progress |
40
- | **Cursor** | ⚠️ MCP only | npm + config | Works via MCP tools, manual workflow |
41
- | **Windsurf** | ⚠️ MCP only | npm + config | Works via MCP tools, testing needed |
42
- | **Devin** | ⚠️ MCP only | npm + config | API-only mode has limitations |
43
- | **Replit Agent** | ⚠️ MCP only | npm + config | Basic functionality |
44
- | **GitHub Copilot** | ⚠️ MCP only | npm + config | Basic functionality |
45
- | **Gemini Code Assist** | ⚠️ MCP only | npm + config | Basic functionality |
46
- | **Codex (OpenAI)** | ❓ Research needed | TBD | Feature completeness assessment in progress |
33
+ - **Human-agent collaboration** The first workspace designed for mixed teams. Humans and AI agents work together with structured feedback loops.
34
+ - **Built for mixed teams** — Not a human tool with AI bolted on, or an AI tool ignoring humans. Designed for how agents and humans actually work together.
35
+ - **Receipts, not promises** Screenshots, videos, and test results. Not just chat logs claiming work was done.
36
+ - **Zero infrastructure** Works completely locally. GitHub optional for remote artifact sharing. No paid services, no servers to maintain.
37
+ - **Real-time P2P** Multiple agents and reviewers sync via WebRTC. Works offline, no central server required.
47
38
 
48
- **Key:** Only Claude Code provides the full experience with automatic task creation and approval workflows. Other platforms work via manual MCP tool invocation.
39
+ ## Get Started
49
40
 
50
- See [Platform Compatibility Matrix](./docs/INSTALLATION.md#platform-compatibility-matrix) for detailed feature comparison.
41
+ Shipyard is just an MCP server. One command or a simple JSON config—works with all major AI coding tools.
51
42
 
52
- ## Installation
43
+ **Prerequisite:** Node.js 22+ ([download](https://nodejs.org/))
53
44
 
54
- ### For Claude Code Users
45
+ ### Claude Code (Recommended)
55
46
 
56
- Install the complete Shipyard plugin (MCP server + hooks + skills):
47
+ Full experience with hooks, skills, and auto-task creation:
57
48
 
58
49
  ```bash
59
- # Step 1: Add the marketplace
60
- /plugin marketplace add SchoolAI/shipyard
61
-
62
- # Step 2: Install the plugin
63
- /plugin install shipyard@schoolai-shipyard
50
+ /plugin install SchoolAI/shipyard
64
51
  ```
65
52
 
66
- > **Note:** Claude Code requires adding a marketplace before installing plugins from it. This is intentional design (similar to app stores).
53
+ ### Cursor
67
54
 
68
- **Enable auto-updates:** After installing, run `/plugin` → Marketplaces tab → select `schoolai-shipyard` → "Enable auto-update" to receive updates automatically.
55
+ Add to `~/.cursor/mcp.json`:
69
56
 
70
- <details>
71
- <summary>Troubleshooting: If Step 1 fails with a cache error</summary>
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "shipyard": {
61
+ "command": "npx",
62
+ "args": ["-y", "@schoolai/shipyard-mcp@latest"]
63
+ }
64
+ }
65
+ }
66
+ ```
72
67
 
73
- There's a known Claude Code bug (#14696) with case-sensitive GitHub org names. Try the full git URL instead:
68
+ ### VS Code / GitHub Copilot
74
69
 
75
70
  ```bash
76
- /plugin marketplace add https://github.com/SchoolAI/shipyard.git
71
+ code --add-mcp '{"name":"shipyard","command":"npx","args":["-y","@schoolai/shipyard-mcp@latest"]}'
77
72
  ```
78
73
 
79
- If that stalls, start a fresh Claude Code session and try again.
80
- </details>
81
-
82
- This gives you:
83
- - ✅ MCP tools for creating and managing tasks
84
- - ✅ Automatic hooks for task creation workflow
85
- - ✅ Skills for collaborative task management
74
+ <details>
75
+ <summary><strong>See all platforms (Claude Desktop, Windsurf, JetBrains, Zed, etc.)</strong></summary>
86
76
 
87
- ### For Other Platforms (Cursor, Windsurf, Replit, etc.)
77
+ ### Claude Desktop
88
78
 
89
- Install the MCP server via npm:
79
+ Add to your config file:
80
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
81
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
82
+ - Linux: `~/.config/claude/claude_desktop_config.json`
90
83
 
91
- ```bash
92
- npx -y -p @schoolai/shipyard-mcp mcp-server-shipyard
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "shipyard": {
88
+ "command": "npx",
89
+ "args": ["-y", "@schoolai/shipyard-mcp@latest"]
90
+ }
91
+ }
92
+ }
93
93
  ```
94
94
 
95
- Then configure in your platform's MCP settings:
95
+ ### Windsurf
96
+
97
+ Add to `~/.codeium/windsurf/mcp_config.json`:
96
98
 
97
- **Cursor** (`~/.cursor/mcp.json`):
98
99
  ```json
99
100
  {
100
101
  "mcpServers": {
101
102
  "shipyard": {
102
103
  "command": "npx",
103
- "args": ["-y", "-p", "@schoolai/shipyard-mcp", "mcp-server-shipyard"]
104
+ "args": ["-y", "@schoolai/shipyard-mcp@latest"]
104
105
  }
105
106
  }
106
107
  }
107
108
  ```
108
109
 
109
- **Windsurf** (`~/.windsurf/settings.json`):
110
+ ### JetBrains IDEs
111
+
112
+ 1. Settings > Tools > AI Assistant > Model Context Protocol (MCP)
113
+ 2. Click "Add"
114
+ 3. Paste JSON config above
115
+
116
+ ### Zed
117
+
118
+ Add to `~/.config/zed/settings.json`:
119
+
110
120
  ```json
111
121
  {
112
- "mcp.servers": {
122
+ "context_servers": {
113
123
  "shipyard": {
114
- "command": "npx -y -p @schoolai/shipyard-mcp mcp-server-shipyard"
124
+ "command": {
125
+ "path": "npx",
126
+ "args": ["-y", "@schoolai/shipyard-mcp@latest"]
127
+ }
115
128
  }
116
129
  }
117
130
  }
118
131
  ```
119
132
 
120
- See **[docs/INSTALLATION.md](./docs/INSTALLATION.md)** for comprehensive platform-specific guides.
133
+ ### Continue.dev
121
134
 
122
- ### For Development
123
-
124
- ```bash
125
- # Clone and install
126
- git clone https://github.com/SchoolAI/shipyard.git
127
- cd shipyard
128
- pnpm install
135
+ Create `.continue/mcpServers/shipyard.yaml`:
129
136
 
130
- # Start all services
131
- pnpm dev:all
137
+ ```yaml
138
+ mcpServers:
139
+ - name: Shipyard
140
+ command: npx
141
+ args: ["-y", "@schoolai/shipyard-mcp@latest"]
132
142
  ```
133
143
 
134
- **Important:** Do NOT install the `shipyard` plugin if you're developing this repo. The plugin is for end users only. Local hooks/skills/MCP are always used from the project directory.
144
+ </details>
145
+
146
+ **[Full installation guide with troubleshooting →](./docs/INSTALLATION.md)**
147
+
148
+ ## Platform Support
149
+
150
+ | Platform | Experience |
151
+ |----------|-----------|
152
+ | **Claude Code** | Full integration — hooks, skills, MCP tools, auto-task creation |
153
+ | **VS Code, Cursor, Windsurf** | MCP tools — manual workflow, full functionality |
154
+ | **Other MCP clients** | Basic — depends on platform capabilities |
155
+
156
+ **[See detailed compatibility matrix →](./docs/INSTALLATION.md#feature-comparison)**
157
+
158
+ <details>
159
+ <summary><strong>Using Shipyard skills on other platforms</strong></summary>
160
+
161
+ Shipyard includes a skill (`skills/shipyard/SKILL.md`) that teaches Claude Code how to use the MCP tools effectively. Other platforms can use this same instruction content through their native mechanisms:
162
+
163
+ - **VS Code / Copilot**: Copy to `.github/skills/shipyard/` (Agent Skills preview)
164
+ - **Cursor**: Create `.cursor/rules/shipyard.mdc` with skill content
165
+ - **Windsurf**: Create `.windsurf/workflows/shipyard-task.md`
166
+ - **JetBrains**: Add to `.junie/guidelines.md`
135
167
 
136
- See **[SETUP.md](./docs/SETUP.md)** for full development setup.
168
+ See [skills/shipyard/README.md](./skills/shipyard/README.md) for platform-specific instructions.
169
+
170
+ </details>
137
171
 
138
172
  ## How It Works
139
173
 
@@ -150,60 +184,101 @@ See **[SETUP.md](./docs/SETUP.md)** for full development setup.
150
184
  └─────────────────┘ └─────────────────┘
151
185
  ```
152
186
 
153
- 1. Agent creates a task via MCP tool → Browser opens automatically
154
- 2. Reviewers join via shared URL → Real-time P2P sync
155
- 3. Add comments, approve, or request changes → Agent sees feedback
156
- 4. Agent uploads artifacts (screenshots, etc.) → Stored in GitHub
187
+ 1. **Agent creates task** via MCP tool → Browser opens automatically
188
+ 2. **Reviewers join** via shared URL → Real-time P2P sync
189
+ 3. **Add comments**, approve, or request changes → Agent sees feedback
190
+ 4. **Agent uploads artifacts** (screenshots, videos) → Stored in GitHub
191
+ 5. **Task auto-completes** when all deliverables have receipts (screenshots, videos, test results)
192
+
193
+ ## Features
194
+
195
+ - **BlockNote editor** — Notion-like editing with inline comments and threads
196
+ - **Kanban board** — Drag-drop tasks between Draft, Review, In Progress, Done
197
+ - **GitHub artifacts** — Screenshots, videos, test results stored in your repo
198
+ - **Offline-first** — IndexedDB persistence, works without network
199
+ - **Multi-agent** — Multiple Claude Code/Cursor instances can work on same task
157
200
 
158
- ## Packages
201
+ <details>
202
+ <summary><strong>See more screenshots</strong></summary>
159
203
 
160
- | Package | Description |
161
- |---------|-------------|
162
- | [`@shipyard/server`](./apps/server) | MCP server with Shipyard task tools |
163
- | [`@shipyard/web`](./apps/web) | React app with BlockNote editor |
164
- | [`@shipyard/schema`](./packages/schema) | Shared types, Yjs helpers, URL encoding |
165
- | [`@shipyard/signaling`](./apps/signaling) | WebRTC signaling server (Cloudflare Worker) |
166
- | [`@shipyard/hook`](./apps/hook) | Claude Code hooks for auto-task creation |
204
+ ### Kanban Board
205
+ <img src="docs/assets/board-view.png" alt="Kanban board with drag-drop columns" width="600">
206
+
207
+ ### Full Task Detail
208
+ <img src="docs/assets/task-detail-full.png" alt="Task with deliverables and content" width="600">
209
+
210
+ </details>
211
+
212
+ ## Data & Privacy
213
+
214
+ | Data | Where It Lives | Control |
215
+ |------|---------------|---------|
216
+ | Task content | Browser (IndexedDB) + P2P sync | You own it |
217
+ | Artifacts (local) | `~/.shipyard/artifacts/` served via localhost | You own it |
218
+ | Artifacts (shared) | Optional: GitHub (your repo, orphan branch) | You own it |
219
+ | MCP server | Runs locally | Never leaves your machine |
220
+ | URLs | Encoded snapshots | Shareable, regenerable |
221
+
222
+ **No telemetry. No cloud storage. GitHub optional.**
223
+
224
+ Works completely locally. Add GitHub only if you need remote reviewers to access artifacts.
167
225
 
168
226
  ## Documentation
169
227
 
170
228
  | Doc | Description |
171
229
  |-----|-------------|
172
- | [SETUP.md](./docs/SETUP.md) | Installation, configuration, troubleshooting |
173
- | [BRIEF.md](./docs/BRIEF.md) | 30-second project context |
174
- | [architecture.md](./docs/architecture.md) | Data model, sync topology, tech choices |
175
- | [milestones/](./docs/milestones/) | Implementation phases and progress |
230
+ | **[Installation](./docs/INSTALLATION.md)** | Platform-specific setup guides |
231
+ | **[Setup](./docs/SETUP.md)** | Development setup, troubleshooting |
232
+ | **[Architecture](./docs/architecture.md)** | Data model, sync topology, tech choices |
233
+ | **[Brief](./docs/BRIEF.md)** | 30-second project context |
176
234
 
177
- ## Why "Shipyard"?
235
+ ## Architecture
178
236
 
179
- The name captures two ideas:
180
- 1. **Workspace metaphor** — A shipyard is where work is built
181
- 2. **Dev culture** — "Shipping" is how developers talk about delivering value
237
+ Shipyard is a monorepo with multiple components:
182
238
 
183
- The Penrose triangle logo represents the "impossible triangle" of AI development: **quality**, **speed**, and **low effort**. Traditionally you sacrifice one. Shipyard enables all three through collaborative verification loops.
239
+ | Component | Description |
240
+ |-----------|-------------|
241
+ | [**MCP Server**](./apps/server) | 12 tools for task creation, artifacts, feedback |
242
+ | [**Web App**](./apps/web) | React + BlockNote editor with Kanban board |
243
+ | [**Schema**](./packages/schema) | Shared Yjs CRDT types and URL encoding |
244
+ | [**WebRTC Signaling**](./apps/signaling) | P2P discovery (Cloudflare Worker) |
245
+ | [**Hooks**](./apps/hook) | Claude Code integration |
184
246
 
185
- > *See [ADR-0005](./docs/decisions/0005-rebrand-peer-plan-to-shipyard.md) for the full naming rationale.*
247
+ **Published package:** [`@schoolai/shipyard-mcp`](https://www.npmjs.com/package/@schoolai/shipyard-mcp) - Includes MCP server + hook
186
248
 
187
- ## Claude Cowork Integration
249
+ ## Community
188
250
 
189
- Use Shipyard with Claude Cowork via the included skill:
251
+ - **[GitHub Discussions](https://github.com/SchoolAI/shipyard/discussions)** Questions, ideas, show & tell
252
+ - **[GitHub Issues](https://github.com/SchoolAI/shipyard/issues)** — Bug reports, feature requests
190
253
 
191
- ```
192
- skills/shipyard/
193
- ├── SKILL.md # Instructions for Claude
194
- ├── README.md # Setup guide
195
- └── examples/ # Usage examples
196
- ```
254
+ ## Contributing
197
255
 
198
- See [skills/shipyard/README.md](./skills/shipyard/README.md) for setup.
256
+ We value **ideas over implementations**. Please start with discussion:
199
257
 
200
- ## Contributing
258
+ ### How to Contribute
259
+
260
+ 1. **Bug reports** — [Open an issue](https://github.com/SchoolAI/shipyard/issues/new)
261
+ 2. **Feature ideas** — [Start a discussion](https://github.com/SchoolAI/shipyard/discussions/new)
262
+ 3. **Questions** — [Ask in discussions](https://github.com/SchoolAI/shipyard/discussions)
201
263
 
202
- We welcome contributions! Please read the codebase first:
264
+ ### Before Submitting Code
203
265
 
204
- 1. [BRIEF.md](./docs/BRIEF.md) Understand the project
205
- 2. [engineering-standards.md](./docs/engineering-standards.md) Code quality expectations
206
- 3. [architecture.md](./docs/architecture.md) How it all fits together
266
+ Open an issue describing what you want to change and get maintainer approval first. This helps us:
267
+ - Ensure changes align with project direction
268
+ - Avoid duplicate efforts
269
+ - Provide design guidance upfront
270
+
271
+ PRs without a linked, approved issue may be closed.
272
+
273
+ ### AI Assistance
274
+
275
+ AI-assisted contributions are welcome. We use AI ourselves. What matters is that **you** understand what you're submitting and can answer questions about it.
276
+
277
+ ### Learn the Codebase
278
+
279
+ 1. **[Brief](./docs/BRIEF.md)** — 30-second project context
280
+ 2. **[Engineering Standards](./docs/engineering-standards.md)** — Code quality expectations
281
+ 3. **[Architecture](./docs/architecture.md)** — How it all fits together
207
282
 
208
283
  ## License
209
284
 
@@ -212,10 +287,4 @@ We welcome contributions! Please read the codebase first:
212
287
  - **Free** for all non-competing use
213
288
  - **Converts to Apache 2.0** automatically in 2 years
214
289
 
215
- We chose this to ensure that all core improvements help grow this main repository while keeping it free for developers.
216
-
217
290
  ---
218
-
219
- <div align="center">
220
- <sub>Built with Yjs, BlockNote, and the MCP protocol</sub>
221
- </div>
@@ -28491,7 +28491,7 @@ init_cjs_shims();
28491
28491
  // ../../packages/schema/dist/index.mjs
28492
28492
  init_cjs_shims();
28493
28493
 
28494
- // ../../packages/schema/dist/yjs-helpers-DzEyLz-f.mjs
28494
+ // ../../packages/schema/dist/yjs-helpers-Dr9oWyS2.mjs
28495
28495
  init_cjs_shims();
28496
28496
 
28497
28497
  // ../../packages/schema/dist/plan.mjs
@@ -42723,10 +42723,33 @@ var LocalArtifactParseSchema = external_exports.object({
42723
42723
  localArtifactId: external_exports.string()
42724
42724
  });
42725
42725
 
42726
- // ../../packages/schema/dist/yjs-helpers-DzEyLz-f.mjs
42726
+ // ../../packages/schema/dist/yjs-helpers-Dr9oWyS2.mjs
42727
42727
  function assertNever2(value) {
42728
42728
  throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
42729
42729
  }
42730
+ var SyncedFileChangeSchema = external_exports.object({
42731
+ path: external_exports.string(),
42732
+ status: external_exports.enum([
42733
+ "added",
42734
+ "modified",
42735
+ "deleted",
42736
+ "renamed"
42737
+ ]),
42738
+ patch: external_exports.string(),
42739
+ staged: external_exports.boolean()
42740
+ });
42741
+ var ChangeSnapshotSchema = external_exports.object({
42742
+ machineId: external_exports.string(),
42743
+ machineName: external_exports.string(),
42744
+ ownerId: external_exports.string(),
42745
+ headSha: external_exports.string(),
42746
+ branch: external_exports.string(),
42747
+ isLive: external_exports.boolean(),
42748
+ updatedAt: external_exports.number(),
42749
+ files: external_exports.array(SyncedFileChangeSchema),
42750
+ totalAdditions: external_exports.number(),
42751
+ totalDeletions: external_exports.number()
42752
+ });
42730
42753
  var AgentPresenceSchema = external_exports.object({
42731
42754
  agentType: external_exports.string(),
42732
42755
  sessionId: external_exports.string(),
@@ -43044,7 +43067,8 @@ var YDOC_KEYS = {
43044
43067
  EVENTS: "events",
43045
43068
  SNAPSHOTS: "snapshots",
43046
43069
  INPUT_REQUESTS: "inputRequests",
43047
- LOCAL_DIFF_COMMENTS: "localDiffComments"
43070
+ LOCAL_DIFF_COMMENTS: "localDiffComments",
43071
+ CHANGE_SNAPSHOTS: "changeSnapshots"
43048
43072
  };
43049
43073
  var validKeys = new Set(Object.values(YDOC_KEYS));
43050
43074
  var CommentBodySchema = external_exports.union([external_exports.string(), external_exports.array(external_exports.unknown())]);
@@ -44353,6 +44377,11 @@ var ImportConversationResponseSchema = external_exports.discriminatedUnion("succ
44353
44377
  success: external_exports.literal(false),
44354
44378
  error: external_exports.string()
44355
44379
  })]);
44380
+ var MachineInfoResponseSchema = external_exports.object({
44381
+ machineId: external_exports.string(),
44382
+ machineName: external_exports.string(),
44383
+ ownerId: external_exports.string()
44384
+ });
44356
44385
  var t = initTRPC.context().create({ allowOutsideOfServer: true });
44357
44386
  var router = t.router;
44358
44387
  var publicProcedure = t.procedure;
@@ -44459,6 +44488,9 @@ var planRouter = router({
44459
44488
  error: "No working directory available"
44460
44489
  };
44461
44490
  return ctx.getFileContent(cwd, input.filePath);
44491
+ }),
44492
+ getMachineInfo: publicProcedure.input(PlanIdSchema).output(MachineInfoResponseSchema).query(async ({ ctx }) => {
44493
+ return ctx.getMachineInfo();
44462
44494
  })
44463
44495
  });
44464
44496
  var subscriptionRouter = router({
@@ -864,13 +864,36 @@ function createInitialConversationVersion(params) {
864
864
  return ConversationVersionSchema.parse(version);
865
865
  }
866
866
 
867
- // ../../packages/schema/dist/yjs-helpers-DzEyLz-f.mjs
867
+ // ../../packages/schema/dist/yjs-helpers-Dr9oWyS2.mjs
868
868
  import { z as z2 } from "zod";
869
869
  import { nanoid as nanoid2 } from "nanoid";
870
870
  import * as Y from "yjs";
871
871
  function assertNever2(value) {
872
872
  throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
873
873
  }
874
+ var SyncedFileChangeSchema = z2.object({
875
+ path: z2.string(),
876
+ status: z2.enum([
877
+ "added",
878
+ "modified",
879
+ "deleted",
880
+ "renamed"
881
+ ]),
882
+ patch: z2.string(),
883
+ staged: z2.boolean()
884
+ });
885
+ var ChangeSnapshotSchema = z2.object({
886
+ machineId: z2.string(),
887
+ machineName: z2.string(),
888
+ ownerId: z2.string(),
889
+ headSha: z2.string(),
890
+ branch: z2.string(),
891
+ isLive: z2.boolean(),
892
+ updatedAt: z2.number(),
893
+ files: z2.array(SyncedFileChangeSchema),
894
+ totalAdditions: z2.number(),
895
+ totalDeletions: z2.number()
896
+ });
874
897
  var AgentPresenceSchema = z2.object({
875
898
  agentType: z2.string(),
876
899
  sessionId: z2.string(),
@@ -1283,7 +1306,8 @@ var YDOC_KEYS = {
1283
1306
  EVENTS: "events",
1284
1307
  SNAPSHOTS: "snapshots",
1285
1308
  INPUT_REQUESTS: "inputRequests",
1286
- LOCAL_DIFF_COMMENTS: "localDiffComments"
1309
+ LOCAL_DIFF_COMMENTS: "localDiffComments",
1310
+ CHANGE_SNAPSHOTS: "changeSnapshots"
1287
1311
  };
1288
1312
  var validKeys = new Set(Object.values(YDOC_KEYS));
1289
1313
  var CommentBodySchema = z2.union([z2.string(), z2.array(z2.unknown())]);
@@ -2501,6 +2525,11 @@ var ImportConversationResponseSchema = z4.discriminatedUnion("success", [z4.obje
2501
2525
  success: z4.literal(false),
2502
2526
  error: z4.string()
2503
2527
  })]);
2528
+ var MachineInfoResponseSchema = z4.object({
2529
+ machineId: z4.string(),
2530
+ machineName: z4.string(),
2531
+ ownerId: z4.string()
2532
+ });
2504
2533
  var t = initTRPC.context().create({ allowOutsideOfServer: true });
2505
2534
  var router = t.router;
2506
2535
  var publicProcedure = t.procedure;
@@ -2607,6 +2636,9 @@ var planRouter = router({
2607
2636
  error: "No working directory available"
2608
2637
  };
2609
2638
  return ctx.getFileContent(cwd, input.filePath);
2639
+ }),
2640
+ getMachineInfo: publicProcedure.input(PlanIdSchema).output(MachineInfoResponseSchema).query(async ({ ctx }) => {
2641
+ return ctx.getMachineInfo();
2610
2642
  })
2611
2643
  });
2612
2644
  var subscriptionRouter = router({
@@ -3457,6 +3489,7 @@ import { WebrtcProvider } from "y-webrtc";
3457
3489
 
3458
3490
  // src/server-identity.ts
3459
3491
  import { execSync as execSync3 } from "child_process";
3492
+ import crypto2 from "crypto";
3460
3493
  import os from "os";
3461
3494
  import { basename } from "path";
3462
3495
  import { z as z8 } from "zod";
@@ -3624,6 +3657,41 @@ function getEnvironmentContext() {
3624
3657
  repo: getRepositoryFullName() || void 0
3625
3658
  };
3626
3659
  }
3660
+ var cachedMachineId = null;
3661
+ function getMachineId() {
3662
+ if (cachedMachineId) {
3663
+ return cachedMachineId;
3664
+ }
3665
+ const hostname = os.hostname();
3666
+ const user = process.env.USER || process.env.USERNAME;
3667
+ const cwd = process.cwd();
3668
+ if (!hostname) {
3669
+ throw new Error("Could not determine hostname for machine ID");
3670
+ }
3671
+ if (!user) {
3672
+ throw new Error("Could not determine username for machine ID (set USER or USERNAME env var)");
3673
+ }
3674
+ const hash = crypto2.createHash("sha256");
3675
+ hash.update(`${hostname}:${user}:${cwd}`);
3676
+ cachedMachineId = hash.digest("hex").slice(0, 16);
3677
+ logger.info({ machineId: cachedMachineId, hostname, user, cwd }, "Generated machine ID");
3678
+ return cachedMachineId;
3679
+ }
3680
+ function getMachineName() {
3681
+ const hostname = os.hostname();
3682
+ if (hostname.endsWith(".local")) {
3683
+ return hostname.slice(0, -6);
3684
+ }
3685
+ if (hostname.includes("-")) {
3686
+ const parts = hostname.split("-");
3687
+ if (parts.length >= 2) {
3688
+ const possessivePart = parts[0];
3689
+ const typePart = parts.slice(1).join(" ");
3690
+ return `${possessivePart}'s ${typePart}`;
3691
+ }
3692
+ }
3693
+ return hostname;
3694
+ }
3627
3695
 
3628
3696
  // src/webrtc-provider.ts
3629
3697
  var SIGNALING_SERVER = process.env.SIGNALING_URL || "wss://shipyard-signaling.jacob-191.workers.dev";
@@ -5425,7 +5493,12 @@ function createContext() {
5425
5493
  hookHandlers: createHookHandlers(),
5426
5494
  conversationHandlers: createConversationHandlers(),
5427
5495
  getLocalChanges,
5428
- getFileContent
5496
+ getFileContent,
5497
+ getMachineInfo: async () => ({
5498
+ machineId: getMachineId(),
5499
+ machineName: getMachineName(),
5500
+ ownerId: await getGitHubUsername()
5501
+ })
5429
5502
  };
5430
5503
  }
5431
5504
  function createApp() {
@@ -59,7 +59,7 @@ import {
59
59
  tryAcquireHubLock,
60
60
  uploadArtifact,
61
61
  webConfig
62
- } from "./chunk-QDYV6R7L.js";
62
+ } from "./chunk-FLGKCBXM.js";
63
63
  import {
64
64
  logger
65
65
  } from "./chunk-HFZCBGQ3.js";
@@ -3269,7 +3269,7 @@ async function setupReviewNotification(taskId, pollIntervalSeconds) {
3269
3269
  return { script, fullResponse: text };
3270
3270
  }
3271
3271
  async function requestUserInput(opts) {
3272
- const { InputRequestManager } = await import("./input-request-manager-QKHCEJUU.js");
3272
+ const { InputRequestManager } = await import("./input-request-manager-3L5EHE23.js");
3273
3273
  const ydoc = await getOrCreateDoc(PLAN_INDEX_DOC_NAME);
3274
3274
  const manager = new InputRequestManager();
3275
3275
  if ("questions" in opts && opts.questions) {
@@ -5,7 +5,7 @@ import {
5
5
  createMultiQuestionInputRequest,
6
6
  getOrCreateDoc,
7
7
  logPlanEvent
8
- } from "./chunk-QDYV6R7L.js";
8
+ } from "./chunk-FLGKCBXM.js";
9
9
  import {
10
10
  logger
11
11
  } from "./chunk-HFZCBGQ3.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schoolai/shipyard-mcp",
3
- "version": "0.3.2-next.530",
3
+ "version": "0.3.2-next.538",
4
4
  "description": "Shipyard MCP server and CLI tools for distributed planning with CRDTs",
5
5
  "type": "module",
6
6
  "bin": {