@schoolai/shipyard 3.2.0 → 3.2.1

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.
@@ -44,11 +44,23 @@ var PrAttributedEventSchema = EventBase.extend({
44
44
  prNumber: external_exports.number().int().positive(),
45
45
  repo: external_exports.string().min(1)
46
46
  });
47
+ var MergeMethodSchema = external_exports.enum(["github_native", "graphite_queue"]);
48
+ var PrMergedEventSchema = EventBase.extend({
49
+ kind: external_exports.literal("pr_merged"),
50
+ prUrl: external_exports.string().url(),
51
+ prNumber: external_exports.number().int().positive(),
52
+ repo: external_exports.string().min(1),
53
+ /** Null for Graphite merge queue — Graphite closes PRs as 'closed' rather than 'merged' and the mergeCommitSha is not exposed by the GitHub API for those. Null still means "this task's work landed in trunk", discoverable via the Shipyard-Task-Id trailer grep. */
54
+ mergeCommitSha: external_exports.string().nullable(),
55
+ mergeMethod: MergeMethodSchema,
56
+ mergedAt: external_exports.number().int().positive()
57
+ });
47
58
  var RoiEventSchema = external_exports.discriminatedUnion("kind", [
48
59
  TaskStartedEventSchema,
49
60
  TaskEndedEventSchema,
50
61
  CommitAttributedEventSchema,
51
- PrAttributedEventSchema
62
+ PrAttributedEventSchema,
63
+ PrMergedEventSchema
52
64
  ]);
53
65
  function assertNeverEvent(event) {
54
66
  throw new Error(`unhandled ROI event kind: ${JSON.stringify(event)}`);
@@ -93,6 +105,26 @@ function emitPrAttributed(collector, input) {
93
105
  collector.capture(ROI_EVENT_TYPE, parsed.data);
94
106
  }
95
107
 
108
+ // ../../packages/roi-aggregator/src/emit/pr-merged.ts
109
+ function emitPrMerged(collector, input) {
110
+ const candidate = {
111
+ version: ROI_EVENT_SCHEMA_VERSION,
112
+ kind: "pr_merged",
113
+ taskId: input.taskId,
114
+ userId: input.userId,
115
+ timestamp: input.timestamp ?? Date.now(),
116
+ prUrl: input.prUrl,
117
+ prNumber: input.prNumber,
118
+ repo: input.repo,
119
+ mergeCommitSha: input.mergeCommitSha,
120
+ mergeMethod: input.mergeMethod,
121
+ mergedAt: input.mergedAt
122
+ };
123
+ const parsed = PrMergedEventSchema.safeParse(candidate);
124
+ if (!parsed.success) return;
125
+ collector.capture(ROI_EVENT_TYPE, parsed.data);
126
+ }
127
+
96
128
  // ../../packages/roi-aggregator/src/emit/task-ended.ts
97
129
  function emitTaskEnded(collector, input) {
98
130
  const candidate = {
@@ -277,6 +309,7 @@ export {
277
309
  assertNeverEvent,
278
310
  emitCommitAttributed,
279
311
  emitPrAttributed,
312
+ emitPrMerged,
280
313
  emitTaskEnded,
281
314
  emitTaskStarted,
282
315
  REPORT_SCHEMA_VERSION,
@@ -284,4 +317,4 @@ export {
284
317
  hasShipyardTrailer,
285
318
  appendTrailerToMessage
286
319
  };
287
- //# sourceMappingURL=chunk-FD2QK7IN.js.map
320
+ //# sourceMappingURL=chunk-DKMDBOFU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/roi-aggregator/src/schemas/events.ts","../../../packages/roi-aggregator/src/emit/commit-attributed.ts","../../../packages/roi-aggregator/src/emit/pr-attributed.ts","../../../packages/roi-aggregator/src/emit/pr-merged.ts","../../../packages/roi-aggregator/src/emit/task-ended.ts","../../../packages/roi-aggregator/src/emit/task-started.ts","../../../packages/roi-aggregator/src/schemas/report.ts","../../../packages/roi-aggregator/src/schemas/trailers.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const ROI_EVENT_TYPE = 'shipyard.roi' as const;\n\nexport const ROI_EVENT_SCHEMA_VERSION = 2 as const;\n\nconst EventBase = z.object({\n version: z.literal(ROI_EVENT_SCHEMA_VERSION),\n taskId: z.string().min(1),\n userId: z.string().min(1),\n timestamp: z.number().int().positive(),\n});\n\nexport const TaskStartedEventSchema = EventBase.extend({\n kind: z.literal('task_started'),\n activeTaskCount: z.number().int().nonnegative(),\n taskType: z.string().max(50).optional(),\n mode: z.string().max(50),\n});\nexport type TaskStartedEvent = z.infer<typeof TaskStartedEventSchema>;\n\nexport const TaskEndedEventSchema = EventBase.extend({\n kind: z.literal('task_ended'),\n finalStatus: z.enum(['completed', 'canceled', 'input_required']),\n totalCostUsd: z.number().nonnegative(),\n totalOutputTokens: z.number().int().nonnegative(),\n turnCount: z.number().int().nonnegative(),\n durationMs: z.number().int().nonnegative(),\n});\nexport type TaskEndedEvent = z.infer<typeof TaskEndedEventSchema>;\n\nexport const AttributionTypeSchema = z.enum(['originated', 'amended', 'extended']);\nexport type AttributionType = z.infer<typeof AttributionTypeSchema>;\n\nexport const CommitAttributedEventSchema = EventBase.extend({\n kind: z.literal('commit_attributed'),\n commitSha: z.string().regex(/^[0-9a-f]{7,40}$/, 'expected hex SHA'),\n repo: z.string().min(1),\n branch: z.string().min(1),\n model: z.string().min(1),\n tokens: z.number().int().nonnegative(),\n costUsd: z.number().nonnegative(),\n turnCount: z.number().int().nonnegative(),\n attributionType: AttributionTypeSchema,\n});\nexport type CommitAttributedEvent = z.infer<typeof CommitAttributedEventSchema>;\n\nexport const PrAttributedEventSchema = EventBase.extend({\n kind: z.literal('pr_attributed'),\n prUrl: z.string().url(),\n prNumber: z.number().int().positive(),\n repo: z.string().min(1),\n});\nexport type PrAttributedEvent = z.infer<typeof PrAttributedEventSchema>;\n\nexport const MergeMethodSchema = z.enum(['github_native', 'graphite_queue']);\nexport type MergeMethod = z.infer<typeof MergeMethodSchema>;\n\nexport const PrMergedEventSchema = EventBase.extend({\n kind: z.literal('pr_merged'),\n prUrl: z.string().url(),\n prNumber: z.number().int().positive(),\n repo: z.string().min(1),\n /** Null for Graphite merge queue — Graphite closes PRs as 'closed' rather than 'merged' and the mergeCommitSha is not exposed by the GitHub API for those. Null still means \"this task's work landed in trunk\", discoverable via the Shipyard-Task-Id trailer grep. */\n mergeCommitSha: z.string().nullable(),\n mergeMethod: MergeMethodSchema,\n mergedAt: z.number().int().positive(),\n});\nexport type PrMergedEvent = z.infer<typeof PrMergedEventSchema>;\n\nexport const RoiEventSchema = z.discriminatedUnion('kind', [\n TaskStartedEventSchema,\n TaskEndedEventSchema,\n CommitAttributedEventSchema,\n PrAttributedEventSchema,\n PrMergedEventSchema,\n]);\nexport type RoiEvent = z.infer<typeof RoiEventSchema>;\n\nexport type RoiEventKind = RoiEvent['kind'];\n\nexport function isRoiEvent(value: unknown): value is RoiEvent {\n return RoiEventSchema.safeParse(value).success;\n}\n\nexport function assertNeverEvent(event: never): never {\n throw new Error(`unhandled ROI event kind: ${JSON.stringify(event)}`);\n}\n","import type { AttributionType } from '../schemas/events';\nimport {\n CommitAttributedEventSchema,\n ROI_EVENT_SCHEMA_VERSION,\n ROI_EVENT_TYPE,\n} from '../schemas/events';\nimport type { MetricsCapture } from './types';\n\nexport interface CommitAttributedInput {\n taskId: string;\n userId: string;\n commitSha: string;\n repo: string;\n branch: string;\n model: string;\n tokens: number;\n costUsd: number;\n turnCount: number;\n attributionType: AttributionType;\n timestamp?: number;\n}\n\nexport function emitCommitAttributed(\n collector: MetricsCapture,\n input: CommitAttributedInput\n): void {\n const candidate = {\n version: ROI_EVENT_SCHEMA_VERSION,\n kind: 'commit_attributed' as const,\n taskId: input.taskId,\n userId: input.userId,\n timestamp: input.timestamp ?? Date.now(),\n commitSha: input.commitSha,\n repo: input.repo,\n branch: input.branch,\n model: input.model,\n tokens: input.tokens,\n costUsd: input.costUsd,\n turnCount: input.turnCount,\n attributionType: input.attributionType,\n };\n const parsed = CommitAttributedEventSchema.safeParse(candidate);\n if (!parsed.success) return;\n collector.capture(ROI_EVENT_TYPE, parsed.data);\n}\n","import {\n PrAttributedEventSchema,\n ROI_EVENT_SCHEMA_VERSION,\n ROI_EVENT_TYPE,\n} from '../schemas/events';\nimport type { MetricsCapture } from './types';\n\nexport interface PrAttributedInput {\n taskId: string;\n userId: string;\n prUrl: string;\n prNumber: number;\n repo: string;\n timestamp?: number;\n}\n\nexport function emitPrAttributed(collector: MetricsCapture, input: PrAttributedInput): void {\n const candidate = {\n version: ROI_EVENT_SCHEMA_VERSION,\n kind: 'pr_attributed' as const,\n taskId: input.taskId,\n userId: input.userId,\n timestamp: input.timestamp ?? Date.now(),\n prUrl: input.prUrl,\n prNumber: input.prNumber,\n repo: input.repo,\n };\n const parsed = PrAttributedEventSchema.safeParse(candidate);\n if (!parsed.success) return;\n collector.capture(ROI_EVENT_TYPE, parsed.data);\n}\n","import {\n type MergeMethod,\n PrMergedEventSchema,\n ROI_EVENT_SCHEMA_VERSION,\n ROI_EVENT_TYPE,\n} from '../schemas/events';\nimport type { MetricsCapture } from './types';\n\nexport interface PrMergedInput {\n taskId: string;\n userId: string;\n prUrl: string;\n prNumber: number;\n repo: string;\n mergeCommitSha: string | null;\n mergeMethod: MergeMethod;\n mergedAt: number;\n timestamp?: number;\n}\n\nexport function emitPrMerged(collector: MetricsCapture, input: PrMergedInput): void {\n const candidate = {\n version: ROI_EVENT_SCHEMA_VERSION,\n kind: 'pr_merged' as const,\n taskId: input.taskId,\n userId: input.userId,\n timestamp: input.timestamp ?? Date.now(),\n prUrl: input.prUrl,\n prNumber: input.prNumber,\n repo: input.repo,\n mergeCommitSha: input.mergeCommitSha,\n mergeMethod: input.mergeMethod,\n mergedAt: input.mergedAt,\n };\n const parsed = PrMergedEventSchema.safeParse(candidate);\n if (!parsed.success) return;\n collector.capture(ROI_EVENT_TYPE, parsed.data);\n}\n","import { ROI_EVENT_SCHEMA_VERSION, ROI_EVENT_TYPE, TaskEndedEventSchema } from '../schemas/events';\nimport type { MetricsCapture } from './types';\n\nexport interface TaskEndedInput {\n taskId: string;\n userId: string;\n finalStatus: 'completed' | 'canceled' | 'input_required';\n totalCostUsd: number;\n totalOutputTokens: number;\n turnCount: number;\n durationMs: number;\n timestamp?: number;\n}\n\nexport function emitTaskEnded(collector: MetricsCapture, input: TaskEndedInput): void {\n const candidate = {\n version: ROI_EVENT_SCHEMA_VERSION,\n kind: 'task_ended' as const,\n taskId: input.taskId,\n userId: input.userId,\n timestamp: input.timestamp ?? Date.now(),\n finalStatus: input.finalStatus,\n totalCostUsd: input.totalCostUsd,\n totalOutputTokens: input.totalOutputTokens,\n turnCount: input.turnCount,\n durationMs: input.durationMs,\n };\n const parsed = TaskEndedEventSchema.safeParse(candidate);\n if (!parsed.success) return;\n collector.capture(ROI_EVENT_TYPE, parsed.data);\n}\n","import {\n ROI_EVENT_SCHEMA_VERSION,\n ROI_EVENT_TYPE,\n TaskStartedEventSchema,\n} from '../schemas/events';\nimport type { MetricsCapture } from './types';\n\nexport interface TaskStartedInput {\n taskId: string;\n userId: string;\n activeTaskCount: number;\n mode: string;\n taskType?: string;\n timestamp?: number;\n}\n\nexport function emitTaskStarted(collector: MetricsCapture, input: TaskStartedInput): void {\n const candidate = {\n version: ROI_EVENT_SCHEMA_VERSION,\n kind: 'task_started' as const,\n taskId: input.taskId,\n userId: input.userId,\n timestamp: input.timestamp ?? Date.now(),\n activeTaskCount: input.activeTaskCount,\n mode: input.mode,\n taskType: input.taskType,\n };\n const parsed = TaskStartedEventSchema.safeParse(candidate);\n if (!parsed.success) return;\n collector.capture(ROI_EVENT_TYPE, parsed.data);\n}\n","import { z } from 'zod';\n\nexport const REPORT_SCHEMA_VERSION = 1 as const;\n\nexport const TimeWindowSchema = z.object({\n since: z.string(),\n until: z.string(),\n});\nexport type TimeWindow = z.infer<typeof TimeWindowSchema>;\n\nexport const TimeSeriesPointSchema = z.object({\n bucket: z.string(),\n value: z.number(),\n denominator: z.number().int().nonnegative().optional(),\n});\nexport type TimeSeriesPoint = z.infer<typeof TimeSeriesPointSchema>;\n\nexport const TimeSeriesMetricSchema = z.object({\n metric: z.string(),\n unit: z.string(),\n bucketSize: z.enum(['day', 'week', 'month']),\n series: z.array(TimeSeriesPointSchema),\n});\nexport type TimeSeriesMetric = z.infer<typeof TimeSeriesMetricSchema>;\n\nexport const TaskOutcomeFunnelSchema = z.object({\n tasksStarted: z.number().int().nonnegative(),\n producedCommits: z.number().int().nonnegative(),\n openedPr: z.number().int().nonnegative(),\n merged: z.number().int().nonnegative(),\n abandoned: z.number().int().nonnegative(),\n revertedWithin30d: z.number().int().nonnegative(),\n});\nexport type TaskOutcomeFunnel = z.infer<typeof TaskOutcomeFunnelSchema>;\n\nexport const EngineerScorecardRowSchema = z.object({\n userId: z.string(),\n prsPerWeekDelta: z.number().optional(),\n cycleTimeDelta: z.number().optional(),\n peakParallel: z.number().nonnegative(),\n costPerPrUsd: z.number().nonnegative(),\n revertRate: z.number().min(0).max(1),\n sampleSize: z.number().int().nonnegative(),\n signal: z.enum(['strong', 'modest', 'low-adoption', 'outlier-high', 'insufficient-data']),\n});\nexport type EngineerScorecardRow = z.infer<typeof EngineerScorecardRowSchema>;\n\nexport const FacetBreakdownSchema = z.object({\n facet: z.string(),\n rows: z.array(\n z.object({\n key: z.string(),\n count: z.number().int().nonnegative(),\n costUsd: z.number().nonnegative(),\n mergedPct: z.number().min(0).max(1).optional(),\n abandonedPct: z.number().min(0).max(1).optional(),\n revertedPct: z.number().min(0).max(1).optional(),\n })\n ),\n});\nexport type FacetBreakdown = z.infer<typeof FacetBreakdownSchema>;\n\nexport const RoiTotalsSchema = z.object({\n tasksStarted: z.number().int().nonnegative(),\n tasksAbandoned: z.number().int().nonnegative(),\n tasksShipped: z.number().int().nonnegative(),\n costUsd: z.number().nonnegative(),\n tokens: z.number().int().nonnegative(),\n engineersActive: z.number().int().nonnegative(),\n});\nexport type RoiTotals = z.infer<typeof RoiTotalsSchema>;\n\nexport const RoiKpisSchema = z.object({\n costPerMergedPr: z.number().nonnegative(),\n peakLeverageAvg: z.number().nonnegative(),\n peakLeverageHumanBaseline: z.number().nonnegative().default(1.0),\n revertRateShipyard: z.number().min(0).max(1),\n revertRateManualBaseline: z.number().min(0).max(1).optional(),\n});\nexport type RoiKpis = z.infer<typeof RoiKpisSchema>;\n\nexport const RoiWarningSchema = z.object({\n code: z.string(),\n message: z.string(),\n context: z.record(z.unknown()).default({}),\n});\nexport type RoiWarning = z.infer<typeof RoiWarningSchema>;\n\nexport const RoiReportSchema = z.object({\n schemaVersion: z.literal(REPORT_SCHEMA_VERSION),\n generatedAt: z.string(),\n window: TimeWindowSchema,\n totals: RoiTotalsSchema,\n kpis: RoiKpisSchema,\n series: z.object({\n tokensPerPrWeekly: TimeSeriesMetricSchema,\n concurrentTasksWeekly: TimeSeriesMetricSchema,\n }),\n funnel: TaskOutcomeFunnelSchema,\n byEngineer: z.array(EngineerScorecardRowSchema),\n facets: z.array(FacetBreakdownSchema),\n warnings: z.array(RoiWarningSchema),\n});\nexport type RoiReport = z.infer<typeof RoiReportSchema>;\n","import { z } from 'zod';\nimport { type AttributionType, AttributionTypeSchema } from './events';\n\nexport const TRAILER_SCHEMA_VERSION = 2 as const;\n\nexport const SHIPYARD_COAUTHOR = 'Shipyard <bot@shipyard.dev>' as const;\n\nexport const GitTrailerV2Schema = z.object({\n version: z.literal(TRAILER_SCHEMA_VERSION),\n taskId: z.string().min(1),\n sessionId: z.string().min(1),\n model: z.string().min(1),\n tokens: z.number().int().nonnegative(),\n costUsd: z.number().nonnegative(),\n turnCount: z.number().int().nonnegative(),\n attributionType: AttributionTypeSchema,\n clientVersion: z.string().min(1),\n});\nexport type GitTrailerV2 = z.infer<typeof GitTrailerV2Schema>;\n\nconst HEADERS: Record<keyof GitTrailerV2, string> = {\n version: 'Shipyard-Version',\n taskId: 'Shipyard-Task-Id',\n sessionId: 'Shipyard-Session-Id',\n model: 'Shipyard-Model',\n tokens: 'Shipyard-Tokens',\n costUsd: 'Shipyard-Cost-Usd',\n turnCount: 'Shipyard-Turn-Count',\n attributionType: 'Shipyard-Attribution-Type',\n clientVersion: 'Shipyard-Client-Version',\n};\n\nexport function formatTrailer(trailer: GitTrailerV2): string {\n const lines = [\n `${HEADERS.version}: ${trailer.version}`,\n `${HEADERS.taskId}: ${trailer.taskId}`,\n `${HEADERS.sessionId}: ${trailer.sessionId}`,\n `${HEADERS.model}: ${trailer.model}`,\n `${HEADERS.tokens}: ${trailer.tokens}`,\n `${HEADERS.costUsd}: ${trailer.costUsd.toFixed(4)}`,\n `${HEADERS.turnCount}: ${trailer.turnCount}`,\n `${HEADERS.attributionType}: ${trailer.attributionType}`,\n `${HEADERS.clientVersion}: ${trailer.clientVersion}`,\n '',\n `Co-Authored-By: ${SHIPYARD_COAUTHOR}`,\n ];\n return lines.join('\\n');\n}\n\nexport type ParseTrailerResult =\n | { success: true; trailer: GitTrailerV2 }\n | { success: false; error: string };\n\nconst NUMERIC_FIELDS: Record<string, 'int' | 'float'> = {\n [HEADERS.version]: 'int',\n [HEADERS.tokens]: 'int',\n [HEADERS.costUsd]: 'float',\n [HEADERS.turnCount]: 'int',\n};\n\ntype ExtractFieldResult =\n | { ok: true; key: string; value: string | number }\n | { ok: false; error: string }\n | { ok: 'skip' };\n\nfunction extractField(rawLine: string): ExtractFieldResult {\n const line = rawLine.trimEnd();\n if (!line.startsWith('Shipyard-')) return { ok: 'skip' };\n const colonIdx = line.indexOf(':');\n if (colonIdx === -1) return { ok: 'skip' };\n\n const header = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n const numericKind = NUMERIC_FIELDS[header];\n\n if (numericKind === undefined) {\n return { ok: true, key: header, value };\n }\n const n = numericKind === 'int' ? Number.parseInt(value, 10) : Number.parseFloat(value);\n if (Number.isNaN(n)) {\n return { ok: false, error: `non-numeric ${header}: ${value}` };\n }\n return { ok: true, key: header, value: n };\n}\n\nexport function parseTrailer(commitMessage: string): ParseTrailerResult {\n const fields: Record<string, string | number> = {};\n for (const rawLine of commitMessage.split(/\\r?\\n/)) {\n const result = extractField(rawLine);\n if (result.ok === false) return { success: false, error: result.error };\n if (result.ok === 'skip') continue;\n fields[result.key] = result.value;\n }\n\n const candidate = {\n version: fields[HEADERS.version],\n taskId: fields[HEADERS.taskId],\n sessionId: fields[HEADERS.sessionId],\n model: fields[HEADERS.model],\n tokens: fields[HEADERS.tokens],\n costUsd: fields[HEADERS.costUsd],\n turnCount: fields[HEADERS.turnCount],\n attributionType: fields[HEADERS.attributionType],\n clientVersion: fields[HEADERS.clientVersion],\n };\n\n const parsed = GitTrailerV2Schema.safeParse(candidate);\n if (!parsed.success) {\n return { success: false, error: parsed.error.issues.map((i) => i.message).join('; ') };\n }\n return { success: true, trailer: parsed.data };\n}\n\nexport function hasShipyardTrailer(commitMessage: string): boolean {\n return commitMessage.includes(`${HEADERS.taskId}:`);\n}\n\nexport function appendTrailerToMessage(originalMessage: string, trailer: GitTrailerV2): string {\n const body = originalMessage.trimEnd();\n return `${body}\\n\\n${formatTrailer(trailer)}\\n`;\n}\n\nexport { AttributionTypeSchema };\nexport type { AttributionType };\n"],"mappings":"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","names":[]}
@@ -1008,7 +1008,7 @@ var PersonalRoomConnection = class {
1008
1008
  };
1009
1009
 
1010
1010
  // ../../packages/session/src/protocol-version.ts
1011
- var PROTOCOL_VERSION = 23;
1011
+ var PROTOCOL_VERSION = 24;
1012
1012
 
1013
1013
  export {
1014
1014
  TESTED_CLAUDE_CODE_VERSION,
@@ -1049,4 +1049,4 @@ export {
1049
1049
  PROTOCOL_VERSION,
1050
1050
  ROUTES
1051
1051
  };
1052
- //# sourceMappingURL=chunk-5SJBSLGT.js.map
1052
+ //# sourceMappingURL=chunk-FMMRZTOF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../packages/session/src/schemas.ts","../../../packages/session/src/routes.ts","../../../packages/session/src/claude-code-compat.ts","../../../packages/session/src/collab-room-connection.ts","../../../packages/session/src/personal-room-connection.ts","../../../packages/session/src/protocol-version.ts"],"sourcesContent":["/**\n * Zod schemas for all signaling server request/response bodies and WebSocket messages.\n *\n * This module provides:\n * - Validation schemas for all HTTP endpoints\n * - WebSocket message schemas for personal and collab rooms\n * - Inferred TypeScript types for type-safe API usage\n * - Error response schemas for consistent error handling\n *\n * This is the single source of truth for all API schemas.\n * The client directory is designed to be self-contained and hoistable\n * to packages/shared without depending on server code.\n *\n * @module client/schemas\n */\n\nimport { z } from 'zod';\n\n/**\n * Pattern for valid git branch names.\n * Shared between daemon validation and web form validation.\n */\nexport const BRANCH_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9/_.-]*$/;\n\n/**\n * Pattern for browser/agent machineId query params on personal-room and\n * collab-room WebSocket upgrades. Used by the server to validate before\n * composing participantIds. Clients below MIN_PROTOCOL_VERSION that omit\n * it will be rejected elsewhere, but the server falls back gracefully.\n */\nexport const MACHINE_ID_PATTERN = /^[\\w-]+$/;\nexport const MACHINE_ID_MAX_LENGTH = 128;\n\n/**\n * Standard error response schema used across all endpoints.\n */\nexport const ErrorResponseSchema = z.object({\n error: z.string(),\n message: z.string(),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n/**\n * Validation error response with field-level details.\n */\nexport const ValidationErrorResponseSchema = ErrorResponseSchema.extend({\n details: z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string(),\n code: z.string().optional(),\n })\n )\n .optional(),\n});\n\nexport type ValidationErrorResponse = z.infer<typeof ValidationErrorResponseSchema>;\n\n/**\n * Not found error response with available endpoints.\n */\nexport const NotFoundResponseSchema = ErrorResponseSchema.extend({\n endpoints: z.array(z.string()),\n});\n\nexport type NotFoundResponse = z.infer<typeof NotFoundResponseSchema>;\n\n/**\n * GET /health response schema.\n *\n * Returns service health status and environment info.\n */\nexport const HealthResponseSchema = z.object({\n status: z.literal('ok'),\n service: z.literal('shipyard-signaling'),\n environment: z.enum(['development', 'production']),\n});\n\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n\n/**\n * POST /auth/github/callback request body schema.\n *\n * Used to exchange a GitHub OAuth code for a Shipyard JWT.\n */\nexport const AuthGitHubCallbackRequestSchema = z.object({\n /** GitHub OAuth authorization code */\n code: z.string().min(1, 'code is required'),\n /** OAuth redirect URI that was used in the authorize request */\n redirect_uri: z.string().url('redirect_uri must be a valid URL'),\n});\n\nexport type AuthGitHubCallbackRequest = z.infer<typeof AuthGitHubCallbackRequestSchema>;\n\n/**\n * User info returned from successful OAuth.\n */\nexport const OAuthUserSchema = z.object({\n /** Shipyard user ID (\"usr_abc123\") */\n id: z.string(),\n /** Display name */\n displayName: z.string(),\n /** GitHub avatar URL */\n avatarUrl: z.string().nullable(),\n /** Linked providers */\n providers: z.array(z.string()),\n});\n\nexport type OAuthUser = z.infer<typeof OAuthUserSchema>;\n\n/**\n * POST /auth/github/callback response schema.\n *\n * Returns a Shipyard JWT and user info on successful OAuth.\n */\nexport const AuthGitHubCallbackResponseSchema = z.object({\n /** Shipyard JWT for authentication */\n token: z.string(),\n /** User info from GitHub */\n user: OAuthUserSchema,\n /** GitHub access token for API calls (~8h expiry for GitHub App tokens) */\n githubAccessToken: z.string().optional(),\n /** GitHub refresh token for obtaining new access tokens (~6 month expiry) */\n githubRefreshToken: z.string().optional(),\n /** Present and true if request came from a mobile device */\n is_mobile: z.boolean().optional(),\n});\n\nexport type AuthGitHubCallbackResponse = z.infer<typeof AuthGitHubCallbackResponseSchema>;\n\n/**\n * POST /auth/github/refresh request body schema.\n *\n * Exchange a GitHub refresh token for a new access token.\n */\nexport const AuthGitHubRefreshRequestSchema = z.object({\n /** GitHub refresh token from the original OAuth flow */\n refreshToken: z.string().min(1, 'refreshToken is required'),\n});\n\nexport type AuthGitHubRefreshRequest = z.infer<typeof AuthGitHubRefreshRequestSchema>;\n\n/**\n * POST /auth/github/refresh response schema.\n */\nexport const AuthGitHubRefreshResponseSchema = z.object({\n /** New GitHub access token */\n githubAccessToken: z.string(),\n /** New GitHub refresh token (GitHub rotates these on each use) */\n githubRefreshToken: z.string(),\n});\n\nexport type AuthGitHubRefreshResponse = z.infer<typeof AuthGitHubRefreshResponseSchema>;\n\n/**\n * GET /auth/verify response schema.\n *\n * Validates a JWT against the database and returns user info or failure reason.\n */\nexport const AuthVerifyResponseSchema = z.discriminatedUnion('valid', [\n z.object({ valid: z.literal(true), user: OAuthUserSchema }),\n z.object({\n valid: z.literal(false),\n reason: z.enum(['invalid_token', 'user_not_found']),\n }),\n]);\n\nexport type AuthVerifyResponse = z.infer<typeof AuthVerifyResponseSchema>;\n\n/**\n * All valid participant roles in a collab room.\n * Owner is the task creator; collaborator roles come from the invite link.\n */\nexport const ParticipantRoleSchema = z.enum([\n 'owner',\n 'collaborator-full',\n 'collaborator-review',\n 'viewer',\n]);\nexport type ParticipantRole = z.infer<typeof ParticipantRoleSchema>;\n\n/**\n * Collaborator-only roles (subset of ParticipantRole, excludes 'owner').\n * Used for invite link creation where the owner role is never assignable.\n */\nexport const CollaboratorRoleSchema = ParticipantRoleSchema.extract([\n 'collaborator-full',\n 'collaborator-review',\n 'viewer',\n]);\nexport type CollaboratorRole = z.infer<typeof CollaboratorRoleSchema>;\n\n/**\n * POST /collab/create request body schema.\n *\n * Used to create a new collaboration room with a pre-signed URL.\n */\nexport const CollabCreateRequestSchema = z.object({\n /** ID of the task to collaborate on */\n taskId: z.string().min(1, 'taskId is required'),\n /** How long the collaboration link should be valid (1-10080 minutes / 7 days max, default 60) */\n expiresInMinutes: z.number().min(1).max(10080).default(60),\n /** Permission level for the invitee (defaults to 'collaborator-full') */\n role: CollaboratorRoleSchema.optional(),\n});\n\nexport type CollabCreateRequest = z.infer<typeof CollabCreateRequestSchema>;\n\n/**\n * POST /collab/create response schema.\n *\n * Returns the pre-signed WebSocket URL for joining the collaboration room.\n */\nexport const CollabCreateResponseSchema = z.object({\n /** Pre-signed WebSocket URL for joining the room */\n url: z.string().url(),\n /** Unique room identifier */\n roomId: z.string(),\n /** Unix timestamp when the collaboration link expires */\n expiresAt: z.number(),\n});\n\nexport type CollabCreateResponse = z.infer<typeof CollabCreateResponseSchema>;\n\n/**\n * GET /personal/:userId error responses.\n *\n * WebSocket messages are defined below.\n *\n * The actual WebSocket is handled by the Durable Object.\n * These are HTTP error responses before upgrade.\n */\nexport const WsPersonalErrorSchema = z.discriminatedUnion('error', [\n ErrorResponseSchema.extend({\n error: z.literal('upgrade_required'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('missing_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('invalid_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('forbidden'),\n }),\n]);\n\nexport type WsPersonalError = z.infer<typeof WsPersonalErrorSchema>;\n\n/**\n * GET /collab/:roomId error responses.\n *\n * WebSocket messages are defined below.\n *\n * The actual WebSocket is handled by the Durable Object.\n * These are HTTP error responses before upgrade.\n */\nexport const WsCollabErrorSchema = z.discriminatedUnion('error', [\n ErrorResponseSchema.extend({\n error: z.literal('upgrade_required'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('missing_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('invalid_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('forbidden'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('expired'),\n }),\n]);\n\nexport type WsCollabError = z.infer<typeof WsCollabErrorSchema>;\n\n/**\n * Shipyard JWT claims schema.\n *\n * This is the payload embedded in the JWT returned by /auth/github/callback.\n */\nexport const ShipyardJWTClaimsSchema = z.object({\n /** Shipyard user ID: \"usr_abc123\" */\n sub: z.string(),\n /** Display name from primary provider */\n displayName: z.string(),\n /** Linked OAuth providers */\n providers: z.array(z.string()),\n iat: z.number(),\n exp: z.number(),\n /** Optional: Scope for agent tokens (e.g., 'task:abc123') */\n scope: z.string().optional(),\n /** Optional: Machine ID for daemon tokens */\n machineId: z.string().optional(),\n});\n\nexport type ShipyardJWTClaims = z.infer<typeof ShipyardJWTClaimsSchema>;\n\n/**\n * Pre-signed URL payload schema.\n *\n * Embedded in the token query parameter for /collab/:roomId.\n */\nexport const PresignedUrlPayloadSchema = z.object({\n /** Room ID this token is valid for */\n roomId: z.string(),\n /** Task ID being collaborated on */\n taskId: z.string(),\n /** User ID of the person who created the invite */\n inviterId: z.string(),\n /** Expiration timestamp (Unix ms) */\n exp: z.number(),\n /** Permission level for the invitee (defaults to 'collaborator-full') */\n role: CollaboratorRoleSchema.optional(),\n /** Generation counter for link revocation — tokens with a generation older than the room's current generation are rejected */\n generation: z.number().optional(),\n});\n\nexport type PresignedUrlPayload = z.infer<typeof PresignedUrlPayloadSchema>;\n\n/**\n * Reasoning capability schema for models that support configurable reasoning effort.\n */\n/*\n * Keep in sync with ReasoningEffortSchema in packages/loro-schema/src/shared-enums.ts.\n * Inlined here because packages/session has no dependency on @shipyard/loro-schema.\n */\nexport const ReasoningCapabilitySchema = z\n .object({\n efforts: z.array(z.enum(['low', 'medium', 'high', 'xhigh', 'max', 'auto'])).min(1),\n defaultEffort: z.enum(['low', 'medium', 'high', 'xhigh', 'max', 'auto']),\n })\n .refine((data) => data.efforts.includes(data.defaultEffort), {\n message: 'defaultEffort must be one of the supported efforts',\n });\n\nexport type ReasoningCapability = z.infer<typeof ReasoningCapabilitySchema>;\n\n/**\n * Model info schema for machine capabilities.\n */\nexport const ModelInfoSchema = z.object({\n id: z.string(),\n name: z.string(),\n provider: z.string(),\n description: z.string().optional(),\n reasoning: ReasoningCapabilitySchema.optional(),\n supportsFastMode: z.boolean().optional(),\n});\n\nexport type ModelInfo = z.infer<typeof ModelInfoSchema>;\n\n/**\n * Git repo info schema for machine capabilities.\n */\nexport const GitRepoInfoSchema = z.object({\n path: z.string(),\n name: z.string(),\n branch: z.string(),\n remote: z.string().optional(),\n});\n\nexport type GitRepoInfo = z.infer<typeof GitRepoInfoSchema>;\n\n/**\n * Permission mode schema for machine capabilities.\n */\nexport const PermissionModeSchema = z.enum(['default', 'accept-edits', 'plan', 'bypass', 'auto']);\n\nexport type PermissionMode = z.infer<typeof PermissionModeSchema>;\n\n/**\n * Anthropic auth status — detected from env vars, Claude Code OAuth, or cloud providers.\n */\nconst AnthropicAuthMethodEnum = z.enum([\n 'claude-ai',\n 'console',\n 'api-key',\n 'sso',\n 'gateway',\n 'bedrock',\n 'vertex',\n 'foundry',\n 'none',\n]);\n\nexport const AnthropicAuthStatusSchema = z.object({\n status: z.enum(['authenticated', 'unauthenticated', 'unknown']),\n method: AnthropicAuthMethodEnum,\n email: z.string().optional(),\n orgName: z.string().optional(),\n subscriptionType: z.string().nullable().optional(),\n apiProvider: z.string().optional(),\n authMismatch: z\n .object({\n selected: AnthropicAuthMethodEnum,\n envMethod: AnthropicAuthMethodEnum,\n envVar: z.string(),\n })\n .optional(),\n});\n\nexport type AnthropicAuthStatus = z.infer<typeof AnthropicAuthStatusSchema>;\n\nexport const MCPServerAuthStatusSchema = z.enum(['authenticated', 'unauthenticated', 'unknown']);\nexport type MCPServerAuthStatus = z.infer<typeof MCPServerAuthStatusSchema>;\n\nexport const MCPServerSourceSchema = z.enum([\n 'project',\n 'user',\n 'local',\n 'mcp-json',\n 'plugin',\n 'claudeai',\n]);\nexport type MCPServerSource = z.infer<typeof MCPServerSourceSchema>;\n\nconst MCP_SERVER_TYPES = ['stdio', 'http', 'sse'] as const;\nexport const MCPServerTypeSchema = z.enum(MCP_SERVER_TYPES);\nexport type MCPServerType = z.infer<typeof MCPServerTypeSchema>;\n\nexport const MCPOAuthConfigSchema = z.object({\n clientId: z.string().optional(),\n callbackPort: z.number().optional(),\n});\n\nexport const MCPServerInfoSchema = z.object({\n name: z.string(),\n type: MCPServerTypeSchema.default('stdio'),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n url: z.string().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n oauth: MCPOAuthConfigSchema.optional(),\n enabled: z.boolean(),\n source: MCPServerSourceSchema,\n authStatus: MCPServerAuthStatusSchema,\n});\nexport type MCPServerInfo = z.infer<typeof MCPServerInfoSchema>;\n\nexport const SkillInfoSchema = z.object({\n name: z.string(),\n description: z.string(),\n});\nexport type SkillInfo = z.infer<typeof SkillInfoSchema>;\n\n/**\n * Machine capabilities schema — advertised by daemons at registration time.\n */\nexport const MarketplacePluginInfoSchema = z.object({\n name: z.string(),\n description: z.string(),\n author: z.string(),\n marketplace: z.string(),\n installCount: z.number().optional(),\n installed: z.boolean(),\n enabled: z.boolean(),\n version: z.string().optional(),\n isExternal: z.boolean(),\n});\nexport type MarketplacePluginInfo = z.infer<typeof MarketplacePluginInfoSchema>;\n\nexport const ClaudeCodeAgentSchema = z.object({\n id: z.literal('claude-code'),\n name: z.literal('Claude Code'),\n version: z.string().optional(),\n});\n\nexport const InstalledAgentSchema = z.discriminatedUnion('id', [ClaudeCodeAgentSchema]);\nexport type InstalledAgent = z.infer<typeof InstalledAgentSchema>;\n\nexport const MachineCapabilitiesSchema = z.object({\n models: z.array(ModelInfoSchema),\n environments: z.array(GitRepoInfoSchema),\n permissionModes: z.array(PermissionModeSchema),\n homeDir: z.string(),\n anthropicAuth: AnthropicAuthStatusSchema.optional(),\n mcpServers: z.array(MCPServerInfoSchema),\n skills: z.array(SkillInfoSchema),\n marketplacePlugins: z.array(MarketplacePluginInfoSchema),\n autoModeEnabled: z.boolean().optional(),\n installedAgents: z.array(InstalledAgentSchema),\n});\n\nexport type MachineCapabilities = z.infer<typeof MachineCapabilitiesSchema>;\n\n/**\n * Register agent message schema for personal room WebSocket.\n * Capabilities are no longer sent via signaling -- they flow through\n * Loro ephemeral on the room document instead.\n */\nexport const RegisterAgentSchema = z.object({\n type: z.literal('register-agent'),\n agentId: z.string(),\n machineId: z.string(),\n machineName: z.string(),\n agentType: z.string(),\n protocolVersion: z.number().optional(),\n npmVersion: z.string().optional(),\n});\n\n/**\n * Unregister agent message schema for personal room WebSocket.\n */\nexport const UnregisterAgentSchema = z.object({\n type: z.literal('unregister-agent'),\n agentId: z.string(),\n});\n\n/**\n * Agent status update message schema for personal room WebSocket.\n */\nexport const AgentStatusSchema = z.object({\n type: z.literal('agent-status'),\n agentId: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n});\n\n/**\n * WebRTC offer message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCOfferSchema = z.object({\n type: z.literal('webrtc-offer'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n offer: z.unknown(),\n requestId: z.string().optional(),\n});\n\n/**\n * WebRTC answer message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCAnswerSchema = z.object({\n type: z.literal('webrtc-answer'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n answer: z.unknown(),\n requestId: z.string().optional(),\n});\n\n/**\n * WebRTC ICE candidate message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCIceSchema = z.object({\n type: z.literal('webrtc-ice'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n candidate: z.unknown(),\n});\n\n/**\n * ICE server entry schema (matches RTCIceServer).\n */\nexport const IceServerSchema = z.object({\n urls: z.union([z.string(), z.array(z.string())]),\n username: z.string().optional(),\n credential: z.string().optional(),\n});\n\nexport type IceServer = z.infer<typeof IceServerSchema>;\n\n/**\n * Default ICE servers used when the server has not provided TURN credentials.\n * Centralized here so all consumers (browser, daemon, session-server) share\n * one source of truth for the fallback STUN URL.\n */\nexport const DEFAULT_ICE_SERVERS: IceServer[] = [{ urls: 'stun:stun.cloudflare.com:3478' }];\n\n/**\n * Server→client message delivering ICE server configuration (STUN + TURN).\n * Sent after authentication so clients have TURN credentials before any\n * peer connections are created.\n */\nexport const IceServersSchema = z.object({\n type: z.literal('ice-servers'),\n iceServers: z.array(IceServerSchema),\n});\n\n/**\n * Error message schema for WebSocket connections.\n */\nexport const ErrorMessageSchema = z.object({\n type: z.literal('error'),\n code: z.string(),\n message: z.string(),\n requestId: z.string().optional(),\n});\n\n/**\n * User settings schema — stored in CRDT, synced across daemons.\n */\nexport const UserSettingsSchema = z.object({\n worktreeSetupScript: z.string().nullable(),\n});\n\nexport type UserSettings = z.infer<typeof UserSettingsSchema>;\n\n/**\n * Browser requests daemon self-update via signaling relay.\n * Follows the WebRTC relay pattern: browser sends with targetMachineId,\n * server relays to daemon with fromMachineId added.\n */\nexport const RequestDaemonUpdateSchema = z.object({\n type: z.literal('request-daemon-update'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n installCommand: z.string(),\n});\n\nexport type RequestDaemonUpdate = z.infer<typeof RequestDaemonUpdateSchema>;\n\n/**\n * Daemon reports self-update progress via signaling relay.\n * Sent by daemon, server broadcasts to all browser connections.\n *\n * Status lifecycle — daemon-as-stager model:\n * downloading → downloaded → handoff → (daemon exits) → installing →\n * verifying → restarting → (new daemon boots) → succeeded|rolled-back|failed\n * The succeeded transition is reported by the NEW daemon on first authenticated\n * browser connection (see readAndClearUpdateStatus).\n */\nexport const DaemonUpdateStatusSchema = z.object({\n type: z.literal('daemon-update-status'),\n fromMachineId: z.string().optional(),\n status: z.enum([\n 'downloading',\n 'downloaded',\n 'handoff',\n 'installing',\n 'verifying',\n 'restarting',\n 'succeeded',\n 'rolled-back',\n 'failed',\n ]),\n error: z.string().optional(),\n targetVersion: z.string().optional(),\n previousVersion: z.string().optional(),\n});\n\nexport type DaemonUpdateStatus = z.infer<typeof DaemonUpdateStatusSchema>;\n\n/**\n * Union of all client-to-server messages for personal room WebSocket.\n */\nexport const PersonalRoomClientMessageSchema = z.discriminatedUnion('type', [\n RegisterAgentSchema,\n UnregisterAgentSchema,\n AgentStatusSchema,\n WebRTCOfferSchema,\n WebRTCAnswerSchema,\n WebRTCIceSchema,\n ErrorMessageSchema,\n RequestDaemonUpdateSchema,\n DaemonUpdateStatusSchema,\n]);\n\nexport type PersonalRoomClientMessage = z.infer<typeof PersonalRoomClientMessageSchema>;\n\n/**\n * Authentication success message schema for personal room WebSocket.\n */\nexport const AuthenticatedSchema = z.object({\n type: z.literal('authenticated'),\n userId: z.string(),\n username: z.string(),\n});\n\n/**\n * Agent info schema for personal room WebSocket.\n * Capabilities are no longer included -- they flow through Loro ephemeral.\n */\nexport const AgentInfoSchema = z.object({\n agentId: z.string(),\n machineId: z.string(),\n machineName: z.string(),\n agentType: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n protocolVersion: z.number().optional(),\n npmVersion: z.string().optional(),\n});\n\nexport type AgentInfo = z.infer<typeof AgentInfoSchema>;\n\n/**\n * Agents list message schema for personal room WebSocket.\n */\nexport const AgentsListSchema = z.object({\n type: z.literal('agents-list'),\n agents: z.array(AgentInfoSchema),\n hasDaemonRegistered: z.boolean().optional(),\n});\n\n/**\n * Agent joined notification message schema for personal room WebSocket.\n */\nexport const AgentJoinedSchema = z.object({\n type: z.literal('agent-joined'),\n agent: AgentInfoSchema,\n});\n\n/**\n * Agent left notification message schema for personal room WebSocket.\n */\nexport const AgentLeftSchema = z.object({\n type: z.literal('agent-left'),\n agentId: z.string(),\n});\n\n/**\n * Agent status changed notification message schema for personal room WebSocket.\n */\nexport const AgentStatusChangedSchema = z.object({\n type: z.literal('agent-status-changed'),\n agentId: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n});\n\n/**\n * Webhook event schema for events ingested from external services (e.g. Linear)\n * and forwarded to connected daemons via the PersonalRoom WebSocket.\n */\nexport const WebhookEventSchema = z.object({\n type: z.literal('webhook-event'),\n source: z.string(),\n event: z.string(),\n payload: z.record(z.string(), z.unknown()),\n timestamp: z.number(),\n});\n\nexport type WebhookEvent = z.infer<typeof WebhookEventSchema>;\n\n/**\n * Union of all server-to-client messages for personal room WebSocket.\n */\nexport const PersonalRoomServerMessageSchema = z.discriminatedUnion('type', [\n AuthenticatedSchema,\n AgentsListSchema,\n AgentJoinedSchema,\n AgentLeftSchema,\n AgentStatusChangedSchema,\n ErrorMessageSchema,\n WebRTCOfferSchema,\n WebRTCAnswerSchema,\n WebRTCIceSchema,\n IceServersSchema,\n WebhookEventSchema,\n RequestDaemonUpdateSchema,\n DaemonUpdateStatusSchema,\n]);\n\nexport type PersonalRoomServerMessage = z.infer<typeof PersonalRoomServerMessageSchema>;\n\n/**\n * WebRTC offer message schema for collab room WebSocket.\n */\nexport const CollabWebRTCOfferSchema = z.object({\n type: z.literal('webrtc-offer'),\n targetUserId: z.string(),\n offer: z.unknown(),\n});\n\n/**\n * WebRTC answer message schema for collab room WebSocket.\n */\nexport const CollabWebRTCAnswerSchema = z.object({\n type: z.literal('webrtc-answer'),\n targetUserId: z.string(),\n answer: z.unknown(),\n});\n\n/**\n * WebRTC ICE candidate message schema for collab room WebSocket.\n */\nexport const CollabWebRTCIceSchema = z.object({\n type: z.literal('webrtc-ice'),\n targetUserId: z.string(),\n candidate: z.unknown(),\n});\n\n/**\n * Union of all client-to-server messages for collab room WebSocket.\n */\nexport const CollabRoomClientMessageSchema = z.discriminatedUnion('type', [\n CollabWebRTCOfferSchema,\n CollabWebRTCAnswerSchema,\n CollabWebRTCIceSchema,\n]);\n\nexport type CollabRoomClientMessage = z.infer<typeof CollabRoomClientMessageSchema>;\n\n/**\n * Participant info schema for collab room WebSocket.\n */\nexport const ParticipantSchema = z.object({\n userId: z.string(),\n username: z.string(),\n avatarUrl: z.string().nullable().optional(),\n role: ParticipantRoleSchema,\n});\n\nexport type Participant = z.infer<typeof ParticipantSchema>;\n\n/**\n * Authentication success message schema for collab room WebSocket.\n */\nexport const CollabAuthenticatedSchema = z.object({\n type: z.literal('authenticated'),\n userId: z.string(),\n username: z.string(),\n taskId: z.string(),\n});\n\n/**\n * Participants list message schema for collab room WebSocket.\n */\nexport const ParticipantsListSchema = z.object({\n type: z.literal('participants-list'),\n participants: z.array(ParticipantSchema),\n});\n\n/**\n * Participant joined notification message schema for collab room WebSocket.\n */\nexport const ParticipantJoinedSchema = z.object({\n type: z.literal('participant-joined'),\n participant: ParticipantSchema,\n});\n\n/**\n * Participant left notification message schema for collab room WebSocket.\n */\nexport const ParticipantLeftSchema = z.object({\n type: z.literal('participant-left'),\n userId: z.string(),\n});\n\n/**\n * Union of all server-to-client messages for collab room WebSocket.\n */\nexport const CollabRoomServerMessageSchema = z.discriminatedUnion('type', [\n CollabAuthenticatedSchema,\n ParticipantsListSchema,\n ParticipantJoinedSchema,\n ParticipantLeftSchema,\n ErrorMessageSchema,\n CollabWebRTCOfferSchema,\n CollabWebRTCAnswerSchema,\n CollabWebRTCIceSchema,\n IceServersSchema,\n]);\n\nexport type CollabRoomServerMessage = z.infer<typeof CollabRoomServerMessageSchema>;\n\n/**\n * GitHub issue type for feedback categorization.\n */\nexport const GitHubIssueTypeSchema = z.enum(['bug', 'feature', 'question', 'praise']);\nexport type GitHubIssueType = z.infer<typeof GitHubIssueTypeSchema>;\n\n/**\n * POST /feedback/issue request body schema.\n */\nexport const GitHubIssueCreateRequestSchema = z.object({\n type: GitHubIssueTypeSchema,\n title: z.string().min(1, 'title is required').max(256, 'title must be 256 chars or fewer'),\n description: z.string().max(10000).optional(),\n logs: z.string().max(50000).optional(),\n context: z\n .object({\n url: z.string().optional(),\n taskId: z.string().optional(),\n userAgent: z.string().optional(),\n timestamp: z.string().optional(),\n })\n .optional(),\n});\n\nexport type GitHubIssueCreateRequest = z.infer<typeof GitHubIssueCreateRequestSchema>;\n\n/**\n * POST /feedback/issue response schema.\n */\nexport const GitHubIssueCreateResponseSchema = z.object({\n issueUrl: z.string(),\n issueNumber: z.number(),\n});\n\nexport type GitHubIssueCreateResponse = z.infer<typeof GitHubIssueCreateResponseSchema>;\n\n/**\n * POST /auth/linear/callback request body schema.\n *\n * Used to exchange a Linear OAuth code for Linear access tokens.\n * Requires an authenticated Shipyard JWT.\n */\nexport const AuthLinearCallbackRequestSchema = z.object({\n /** Linear OAuth authorization code */\n code: z.string().min(1, 'code is required'),\n /** OAuth redirect URI that was used in the authorize request */\n redirect_uri: z.string().url('redirect_uri must be a valid URL'),\n});\n\nexport type AuthLinearCallbackRequest = z.infer<typeof AuthLinearCallbackRequestSchema>;\n\n/**\n * POST /auth/linear/callback response schema.\n *\n * Returns Linear OAuth tokens and user info on successful OAuth.\n */\nexport const AuthLinearCallbackResponseSchema = z.object({\n /** Linear access token */\n linearAccessToken: z.string(),\n /** Seconds until the access token expires (from Linear's token response) */\n expiresIn: z.number().optional(),\n /** Linear user info */\n linearUser: z.object({\n id: z.string(),\n name: z.string().nullable(),\n email: z.string().nullable(),\n avatarUrl: z.string().nullable(),\n }),\n});\n\nexport type AuthLinearCallbackResponse = z.infer<typeof AuthLinearCallbackResponseSchema>;\n\n/** POST /auth/device/start — no request body needed */\nexport const DeviceStartResponseSchema = z.object({\n deviceCode: z.string(),\n userCode: z.string(),\n verificationUri: z.string().url(),\n expiresIn: z.number(),\n interval: z.number(),\n});\nexport type DeviceStartResponse = z.infer<typeof DeviceStartResponseSchema>;\n\n/** POST /auth/device/poll request */\nexport const DevicePollRequestSchema = z.object({\n deviceCode: z.string().min(1, 'deviceCode is required'),\n});\nexport type DevicePollRequest = z.infer<typeof DevicePollRequestSchema>;\n\n/** POST /auth/device/poll response (success) */\nexport const DevicePollResponseSchema = z.object({\n token: z.string(),\n user: OAuthUserSchema,\n});\nexport type DevicePollResponse = z.infer<typeof DevicePollResponseSchema>;\n\n/** POST /auth/device/poll response (pending/errors) */\nexport const DevicePollPendingSchema = z.object({\n error: z.enum(['authorization_pending', 'slow_down', 'expired_token']),\n});\nexport type DevicePollPending = z.infer<typeof DevicePollPendingSchema>;\n\n/** POST /auth/device/authorize — browser authorizes a device using its own JWT */\nexport const DeviceAuthorizeRequestSchema = z.object({\n userCode: z.string().min(1, 'userCode is required'),\n});\nexport type DeviceAuthorizeRequest = z.infer<typeof DeviceAuthorizeRequestSchema>;\n\nexport const DeviceAuthorizeResponseSchema = z.object({\n authorized: z.boolean(),\n});\nexport type DeviceAuthorizeResponse = z.infer<typeof DeviceAuthorizeResponseSchema>;\n\n/** POST /auth/device/exchange-code — daemon exchanges userCode for deviceCode */\nexport const DeviceExchangeCodeRequestSchema = z.object({\n userCode: z.string().min(1, 'userCode is required'),\n});\nexport type DeviceExchangeCodeRequest = z.infer<typeof DeviceExchangeCodeRequestSchema>;\n\nexport const DeviceExchangeCodeResponseSchema = z.object({\n deviceCode: z.string(),\n});\nexport type DeviceExchangeCodeResponse = z.infer<typeof DeviceExchangeCodeResponseSchema>;\n\n/** POST /auth/browser-code — daemon requests a one-time code for browser auth */\nexport const BrowserCodeResponseSchema = z.object({\n code: z.string(),\n expiresIn: z.number(),\n});\nexport type BrowserCodeResponse = z.infer<typeof BrowserCodeResponseSchema>;\n\n/** POST /auth/browser-code/exchange — browser exchanges code for JWT */\nexport const BrowserCodeExchangeRequestSchema = z.object({\n code: z.string().min(1, 'code is required'),\n});\nexport type BrowserCodeExchangeRequest = z.infer<typeof BrowserCodeExchangeRequestSchema>;\n\nexport const BrowserCodeExchangeResponseSchema = z.object({\n token: z.string(),\n user: OAuthUserSchema,\n});\nexport type BrowserCodeExchangeResponse = z.infer<typeof BrowserCodeExchangeResponseSchema>;\n\n/** GET /vault/key response */\nexport const VaultKeyGetResponseSchema = z.object({\n encryptedKey: z.string(),\n createdAt: z.number(),\n});\nexport type VaultKeyGetResponse = z.infer<typeof VaultKeyGetResponseSchema>;\n\n/** PUT /vault/key request */\nexport const VaultKeyPutRequestSchema = z.object({\n encryptedKey: z.string().min(1, 'encryptedKey is required').max(4096),\n});\nexport type VaultKeyPutRequest = z.infer<typeof VaultKeyPutRequestSchema>;\n\n/** PUT /vault/key response (created) */\nexport const VaultKeyPutResponseSchema = z.object({\n created: z.boolean(),\n});\nexport type VaultKeyPutResponse = z.infer<typeof VaultKeyPutResponseSchema>;\n\n/** Metrics ingestion */\n\nexport const MetricsEventSchema = z.object({\n eventType: z.string().min(1).max(100),\n taskId: z.string().max(200).optional(),\n payload: z.record(z.unknown()).default({}),\n clientTimestamp: z.number().int().positive(),\n});\nexport type MetricsEvent = z.infer<typeof MetricsEventSchema>;\n\nexport const MetricsIngestRequestSchema = z.object({\n events: z.array(MetricsEventSchema).min(1).max(100),\n});\nexport type MetricsIngestRequest = z.infer<typeof MetricsIngestRequestSchema>;\n\nexport const MetricsIngestResponseSchema = z.object({\n accepted: z.number(),\n});\nexport type MetricsIngestResponse = z.infer<typeof MetricsIngestResponseSchema>;\n","/**\n * Shared route constants for the signaling server.\n *\n * Used by both server (route registration) and client (request URLs).\n * Single source of truth prevents drift between implementations.\n *\n * @module client/routes\n */\nexport const ROUTES = {\n HEALTH: '/health',\n AUTH_GITHUB_CALLBACK: '/auth/github/callback',\n AUTH_GITHUB_REFRESH: '/auth/github/refresh',\n AUTH_DEVICE_START: '/auth/device/start',\n AUTH_DEVICE_VERIFY: '/auth/device/verify',\n AUTH_DEVICE_POLL: '/auth/device/poll',\n AUTH_DEVICE_AUTHORIZE: '/auth/device/authorize',\n AUTH_DEVICE_EXCHANGE_CODE: '/auth/device/exchange-code',\n AUTH_BROWSER_CODE: '/auth/browser-code',\n AUTH_BROWSER_CODE_EXCHANGE: '/auth/browser-code/exchange',\n AUTH_VERIFY: '/auth/verify',\n COLLAB_CREATE: '/collab/create',\n COLLAB_REVOKE: '/collab/:roomId',\n GITHUB_ISSUE_CREATE: '/feedback/issue',\n VAULT_KEY: '/vault/key',\n AUTH_LINEAR: '/auth/linear',\n AUTH_LINEAR_CALLBACK: '/auth/linear/callback',\n WEBHOOK_INGEST: '/webhooks/:userId/:source',\n WS_PERSONAL: '/personal/:userId',\n WS_COLLAB: '/collab/:roomId',\n METRICS_INGEST: '/ingest',\n METRICS_QUERY_EVENTS: '/query/events',\n} as const;\n\n/**\n * Human-readable endpoint descriptions for documentation and error messages.\n */\nexport const ROUTE_DESCRIPTIONS = [\n `GET ${ROUTES.HEALTH}`,\n `POST ${ROUTES.AUTH_GITHUB_CALLBACK}`,\n `POST ${ROUTES.AUTH_GITHUB_REFRESH}`,\n `POST ${ROUTES.AUTH_DEVICE_START}`,\n `GET ${ROUTES.AUTH_DEVICE_VERIFY}`,\n `POST ${ROUTES.AUTH_DEVICE_POLL}`,\n `POST ${ROUTES.AUTH_DEVICE_AUTHORIZE}`,\n `POST ${ROUTES.AUTH_DEVICE_EXCHANGE_CODE}`,\n `POST ${ROUTES.AUTH_BROWSER_CODE}`,\n `POST ${ROUTES.AUTH_BROWSER_CODE_EXCHANGE}`,\n `GET ${ROUTES.AUTH_VERIFY}`,\n `POST ${ROUTES.COLLAB_CREATE}`,\n `DELETE ${ROUTES.COLLAB_REVOKE}`,\n `POST ${ROUTES.GITHUB_ISSUE_CREATE}`,\n `GET ${ROUTES.VAULT_KEY}`,\n `PUT ${ROUTES.VAULT_KEY}`,\n `GET ${ROUTES.AUTH_LINEAR}`,\n `GET ${ROUTES.AUTH_LINEAR_CALLBACK}`,\n `POST ${ROUTES.WEBHOOK_INGEST}`,\n `WS ${ROUTES.WS_PERSONAL}`,\n `WS ${ROUTES.WS_COLLAB}`,\n `POST ${ROUTES.METRICS_INGEST}`,\n `GET ${ROUTES.METRICS_QUERY_EVENTS}`,\n] as const;\n","/**\n * Claude Code version compatibility for the Shipyard daemon.\n *\n * The SDK bundles its own `cli.js` — the user's global `claude` binary\n * is NOT what Shipyard spawns. Pinning the SDK version effectively pins\n * Claude Code. This module provides observability: when the init message\n * reports a runtime version, we compare it against what we tested.\n */\n\n/** The Claude Code version bundled with the currently pinned SDK (0.2.111). */\nexport const TESTED_CLAUDE_CODE_VERSION = '2.1.111';\n\nexport type ClaudeCodeCompatResult =\n | { status: 'compatible' }\n | { status: 'untested'; detected: string; tested: string }\n | { status: 'unknown' };\n\n/**\n * Compare a detected Claude Code runtime version against the tested version.\n *\n * - `compatible`: major.minor matches the tested version\n * - `untested`: version detected but major.minor differs\n * - `unknown`: version could not be determined\n */\nexport function classifyClaudeCodeCompatibility(\n detected: string | undefined,\n tested: string = TESTED_CLAUDE_CODE_VERSION\n): ClaudeCodeCompatResult {\n if (!detected) return { status: 'unknown' };\n\n const detectedParts = detected.split('.');\n const testedParts = tested.split('.');\n\n if (detectedParts[0] === testedParts[0] && detectedParts[1] === testedParts[1]) {\n return { status: 'compatible' };\n }\n\n return { status: 'untested', detected, tested };\n}\n","import type { ConnectionState } from './personal-room-connection';\nimport type { CollabRoomClientMessage, CollabRoomServerMessage } from './schemas';\nimport { CollabRoomServerMessageSchema } from './schemas';\n\ninterface MinimalWebSocket {\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: string }) => void) | null;\n send(data: string): void;\n close(): void;\n}\n\nexport interface CollabRoomConnectionConfig {\n url: string;\n WebSocketImpl?: new (url: string) => MinimalWebSocket;\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /** Called when the server closes the connection with code 1000 (\"Room expired\"). Do not reconnect. */\n onRoomExpired?: () => void;\n}\n\nexport class CollabRoomConnection {\n private state: ConnectionState = 'disconnected';\n private ws: MinimalWebSocket | null = null;\n private readonly messageHandlers = new Set<(msg: CollabRoomServerMessage) => void>();\n private readonly stateChangeHandlers = new Set<(state: ConnectionState) => void>();\n private readonly config: CollabRoomConnectionConfig;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private pingTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect = false;\n\n constructor(config: CollabRoomConnectionConfig) {\n this.config = config;\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n connect(): void {\n this.intentionalDisconnect = false;\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n if (this.ws) {\n this.stopPingTimer();\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n\n const Impl = this.config.WebSocketImpl ?? (WebSocket as never);\n try {\n this.ws = new Impl(this.config.url);\n } catch {\n this.setState('error');\n this.reconnectWithBackoff();\n return;\n }\n this.setState('connecting');\n\n this.ws.onopen = () => {\n this.setState('connected');\n this.startPingTimer();\n };\n\n this.ws.onclose = (ev: unknown) => {\n this.stopPingTimer();\n if (this.state !== 'error' && this.state !== 'reconnecting') {\n this.setState('disconnected');\n }\n const code = extractCloseCode(ev);\n /** NOTE: 1000 = \"Room expired\" — the Durable Object TTL has elapsed. Stop reconnecting and notify the caller. */\n if (code === 1000) {\n this.config.onRoomExpired?.();\n return;\n }\n /** NOTE: 4001 = \"Replaced by new connection\" — a newer WebSocket for the same userId was accepted by the server. Do not reconnect; the replacement is already active. */\n if (!this.intentionalDisconnect && code !== 4001) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onerror = () => {\n this.stopPingTimer();\n this.setState('error');\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onmessage = (event: { data: string }) => {\n this.startPingTimer();\n\n if (event.data === 'pong') return;\n\n let raw: unknown;\n try {\n raw = JSON.parse(event.data);\n } catch {\n return;\n }\n\n const result = CollabRoomServerMessageSchema.safeParse(raw);\n if (!result.success) {\n // biome-ignore lint/suspicious/noConsole: intentional debug visibility for silent Zod drops that hid a critical share-link bug\n console.warn(\n '[CollabRoom] Dropped unrecognized server message:',\n JSON.stringify(raw),\n result.error.issues\n );\n return;\n }\n\n for (const handler of [...this.messageHandlers]) {\n handler(result.data);\n }\n };\n }\n\n send(msg: CollabRoomClientMessage): void {\n try {\n this.ws?.send(JSON.stringify(msg));\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n }\n\n onMessage(handler: (msg: CollabRoomServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => {\n this.stateChangeHandlers.delete(handler);\n };\n }\n\n reconnect(): void {\n this.intentionalDisconnect = false;\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.retryCount = 0;\n this.connect();\n }\n\n disconnect(): void {\n this.intentionalDisconnect = true;\n this.stopPingTimer();\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n this.retryCount = 0;\n\n if (this.ws) {\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n this.setState('disconnected');\n }\n\n private startPingTimer(): void {\n this.stopPingTimer();\n this.schedulePing();\n }\n\n private stopPingTimer(): void {\n if (this.pingTimer !== null) {\n clearTimeout(this.pingTimer);\n this.pingTimer = null;\n }\n }\n\n private schedulePing(): void {\n const jitter = Math.floor(Math.random() * 25_000);\n const delay = 30_000 + jitter;\n this.pingTimer = setTimeout(() => {\n this.pingTimer = null;\n try {\n this.ws?.send('ping');\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n this.schedulePing();\n }, delay);\n }\n\n private reconnectWithBackoff(): void {\n if (this.retryTimer !== null) return;\n\n const maxRetries = this.config.maxRetries;\n if (maxRetries === undefined || maxRetries === 0) {\n return;\n }\n\n if (maxRetries !== -1 && this.retryCount >= maxRetries) {\n return;\n }\n\n this.setState('reconnecting');\n\n if (this.intentionalDisconnect) return;\n\n const initialDelay = this.config.initialDelayMs ?? 1000;\n const maxDelay = this.config.maxDelayMs ?? 30000;\n const multiplier = this.config.backoffMultiplier ?? 2;\n const delay = Math.min(initialDelay * multiplier ** this.retryCount, maxDelay);\n\n this.retryCount++;\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.connect();\n }, delay);\n }\n\n private setState(newState: ConnectionState): void {\n this.state = newState;\n if (newState === 'connected') {\n this.retryCount = 0;\n }\n for (const handler of [...this.stateChangeHandlers]) {\n handler(newState);\n }\n }\n}\n\nfunction extractCloseCode(ev: unknown): number | undefined {\n if (typeof ev !== 'object' || ev === null || !('code' in ev)) return undefined;\n const code: unknown = ev.code;\n return typeof code === 'number' ? code : undefined;\n}\n","import type { PersonalRoomClientMessage, PersonalRoomServerMessage } from './schemas';\nimport { PersonalRoomServerMessageSchema } from './schemas';\n\nexport type ConnectionState =\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'error';\n\ninterface MinimalWebSocket {\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: string }) => void) | null;\n send(data: string): void;\n close(): void;\n}\n\nexport interface PersonalRoomConnectionConfig {\n url: string;\n WebSocketImpl?: new (url: string) => MinimalWebSocket;\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n}\n\nexport class PersonalRoomConnection {\n private state: ConnectionState = 'disconnected';\n private ws: MinimalWebSocket | null = null;\n private readonly messageHandlers = new Set<(msg: PersonalRoomServerMessage) => void>();\n private readonly stateChangeHandlers = new Set<(state: ConnectionState) => void>();\n private readonly config: PersonalRoomConnectionConfig;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private pingTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect = false;\n\n constructor(config: PersonalRoomConnectionConfig) {\n this.config = config;\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n connect(): void {\n this.intentionalDisconnect = false;\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n if (this.ws) {\n this.stopPingTimer();\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n\n const Impl = this.config.WebSocketImpl ?? (WebSocket as never);\n try {\n this.ws = new Impl(this.config.url);\n } catch {\n this.setState('error');\n this.reconnectWithBackoff();\n return;\n }\n this.setState('connecting');\n\n this.ws.onopen = () => {\n this.setState('connected');\n this.startPingTimer();\n };\n\n this.ws.onclose = () => {\n this.stopPingTimer();\n if (this.state !== 'error' && this.state !== 'reconnecting') {\n this.setState('disconnected');\n }\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onerror = () => {\n this.stopPingTimer();\n this.setState('error');\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onmessage = (event: { data: string }) => {\n this.startPingTimer();\n\n if (event.data === 'pong') return;\n\n let raw: unknown;\n try {\n raw = JSON.parse(event.data);\n } catch {\n return;\n }\n\n const result = PersonalRoomServerMessageSchema.safeParse(raw);\n if (!result.success) {\n if (this.state === 'connected') {\n // biome-ignore lint/suspicious/noConsole: intentional debug visibility for silent Zod drops that hid a critical share-link bug\n console.warn(\n '[PersonalRoom] Dropped unrecognized server message:',\n JSON.stringify(raw),\n result.error.issues\n );\n }\n return;\n }\n\n for (const handler of [...this.messageHandlers]) {\n handler(result.data);\n }\n };\n }\n\n send(msg: PersonalRoomClientMessage): void {\n try {\n this.ws?.send(JSON.stringify(msg));\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n }\n\n onMessage(handler: (msg: PersonalRoomServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => {\n this.stateChangeHandlers.delete(handler);\n };\n }\n\n reconnect(): void {\n this.intentionalDisconnect = false;\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.retryCount = 0;\n this.connect();\n }\n\n disconnect(): void {\n this.intentionalDisconnect = true;\n this.stopPingTimer();\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n this.retryCount = 0;\n\n if (this.ws) {\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n this.setState('disconnected');\n }\n\n private startPingTimer(): void {\n this.stopPingTimer();\n this.schedulePing();\n }\n\n private stopPingTimer(): void {\n if (this.pingTimer !== null) {\n clearTimeout(this.pingTimer);\n this.pingTimer = null;\n }\n }\n\n private schedulePing(): void {\n const jitter = Math.floor(Math.random() * 25_000);\n const delay = 30_000 + jitter;\n this.pingTimer = setTimeout(() => {\n this.pingTimer = null;\n try {\n this.ws?.send('ping');\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n this.schedulePing();\n }, delay);\n }\n\n private reconnectWithBackoff(): void {\n if (this.retryTimer !== null) return;\n\n const maxRetries = this.config.maxRetries;\n if (maxRetries === undefined || maxRetries === 0) {\n return;\n }\n\n if (maxRetries !== -1 && this.retryCount >= maxRetries) {\n return;\n }\n\n this.setState('reconnecting');\n\n if (this.intentionalDisconnect) return;\n\n const initialDelay = this.config.initialDelayMs ?? 1000;\n const maxDelay = this.config.maxDelayMs ?? 30000;\n const multiplier = this.config.backoffMultiplier ?? 2;\n const delay = Math.min(initialDelay * multiplier ** this.retryCount, maxDelay);\n\n this.retryCount++;\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.connect();\n }, delay);\n }\n\n private setState(newState: ConnectionState): void {\n this.state = newState;\n if (newState === 'connected') {\n this.retryCount = 0;\n }\n for (const handler of [...this.stateChangeHandlers]) {\n handler(newState);\n }\n }\n}\n","/**\n * Monotonic protocol version for daemon↔browser compatibility.\n *\n * Bump ONLY on breaking changes to the communication protocol between\n * the daemon and browser (new/removed message types, changed ephemeral\n * schemas, etc.). Feature releases that don't break the protocol do\n * NOT bump this number.\n *\n * The browser hardcodes a minimum acceptable version. When a daemon\n * connects with a lower version, the browser shows a blocking update\n * modal.\n */\nexport const PROTOCOL_VERSION = 23;\n\n/**\n * Minimum protocol version the browser requires from daemons.\n * Daemons reporting a version below this (or no version at all)\n * trigger the \"update your daemon\" modal.\n */\nexport const MIN_PROTOCOL_VERSION = 20;\n\nexport type CompatResult =\n | { compatible: true }\n | { compatible: false; reason: 'protocol' | 'prerelease-mismatch'; installCommand: string };\n\nfunction isPrerelease(version: string): boolean {\n return /-(nightly|rc)\\./.test(version);\n}\n\nexport function getInstallCommand(version?: string, channel?: 'latest' | 'next'): string {\n if (channel) {\n return `npm install -g @schoolai/shipyard@${channel}`;\n }\n const tag = version && isPrerelease(version) ? '@next' : '@latest';\n return `npm install -g @schoolai/shipyard${tag}`;\n}\n\nexport function classifyDaemonCompatibility(\n daemon: { protocolVersion?: number; npmVersion?: string },\n browser: {\n minProtocolVersion: number;\n expectedDaemonVersion?: string;\n channel?: 'latest' | 'next';\n }\n): CompatResult {\n const installCommand = getInstallCommand(\n browser.expectedDaemonVersion ?? daemon.npmVersion,\n browser.channel\n );\n\n if (\n daemon.npmVersion &&\n browser.expectedDaemonVersion &&\n isPrerelease(daemon.npmVersion) &&\n isPrerelease(browser.expectedDaemonVersion) &&\n daemon.npmVersion !== browser.expectedDaemonVersion\n ) {\n return {\n compatible: false,\n reason: 'prerelease-mismatch',\n installCommand,\n };\n }\n\n if ((daemon.protocolVersion ?? 0) < browser.minProtocolVersion) {\n return {\n compatible: false,\n reason: 'protocol',\n installCommand,\n };\n }\n\n return { compatible: true };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../packages/session/src/schemas.ts","../../../packages/session/src/routes.ts","../../../packages/session/src/claude-code-compat.ts","../../../packages/session/src/collab-room-connection.ts","../../../packages/session/src/personal-room-connection.ts","../../../packages/session/src/protocol-version.ts"],"sourcesContent":["/**\n * Zod schemas for all signaling server request/response bodies and WebSocket messages.\n *\n * This module provides:\n * - Validation schemas for all HTTP endpoints\n * - WebSocket message schemas for personal and collab rooms\n * - Inferred TypeScript types for type-safe API usage\n * - Error response schemas for consistent error handling\n *\n * This is the single source of truth for all API schemas.\n * The client directory is designed to be self-contained and hoistable\n * to packages/shared without depending on server code.\n *\n * @module client/schemas\n */\n\nimport { z } from 'zod';\n\n/**\n * Pattern for valid git branch names.\n * Shared between daemon validation and web form validation.\n */\nexport const BRANCH_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9/_.-]*$/;\n\n/**\n * Pattern for browser/agent machineId query params on personal-room and\n * collab-room WebSocket upgrades. Used by the server to validate before\n * composing participantIds. Clients below MIN_PROTOCOL_VERSION that omit\n * it will be rejected elsewhere, but the server falls back gracefully.\n */\nexport const MACHINE_ID_PATTERN = /^[\\w-]+$/;\nexport const MACHINE_ID_MAX_LENGTH = 128;\n\n/**\n * Standard error response schema used across all endpoints.\n */\nexport const ErrorResponseSchema = z.object({\n error: z.string(),\n message: z.string(),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n/**\n * Validation error response with field-level details.\n */\nexport const ValidationErrorResponseSchema = ErrorResponseSchema.extend({\n details: z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string(),\n code: z.string().optional(),\n })\n )\n .optional(),\n});\n\nexport type ValidationErrorResponse = z.infer<typeof ValidationErrorResponseSchema>;\n\n/**\n * Not found error response with available endpoints.\n */\nexport const NotFoundResponseSchema = ErrorResponseSchema.extend({\n endpoints: z.array(z.string()),\n});\n\nexport type NotFoundResponse = z.infer<typeof NotFoundResponseSchema>;\n\n/**\n * GET /health response schema.\n *\n * Returns service health status and environment info.\n */\nexport const HealthResponseSchema = z.object({\n status: z.literal('ok'),\n service: z.literal('shipyard-signaling'),\n environment: z.enum(['development', 'production']),\n});\n\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n\n/**\n * POST /auth/github/callback request body schema.\n *\n * Used to exchange a GitHub OAuth code for a Shipyard JWT.\n */\nexport const AuthGitHubCallbackRequestSchema = z.object({\n /** GitHub OAuth authorization code */\n code: z.string().min(1, 'code is required'),\n /** OAuth redirect URI that was used in the authorize request */\n redirect_uri: z.string().url('redirect_uri must be a valid URL'),\n});\n\nexport type AuthGitHubCallbackRequest = z.infer<typeof AuthGitHubCallbackRequestSchema>;\n\n/**\n * User info returned from successful OAuth.\n */\nexport const OAuthUserSchema = z.object({\n /** Shipyard user ID (\"usr_abc123\") */\n id: z.string(),\n /** Display name */\n displayName: z.string(),\n /** GitHub avatar URL */\n avatarUrl: z.string().nullable(),\n /** Linked providers */\n providers: z.array(z.string()),\n});\n\nexport type OAuthUser = z.infer<typeof OAuthUserSchema>;\n\n/**\n * POST /auth/github/callback response schema.\n *\n * Returns a Shipyard JWT and user info on successful OAuth.\n */\nexport const AuthGitHubCallbackResponseSchema = z.object({\n /** Shipyard JWT for authentication */\n token: z.string(),\n /** User info from GitHub */\n user: OAuthUserSchema,\n /** GitHub access token for API calls (~8h expiry for GitHub App tokens) */\n githubAccessToken: z.string().optional(),\n /** GitHub refresh token for obtaining new access tokens (~6 month expiry) */\n githubRefreshToken: z.string().optional(),\n /** Present and true if request came from a mobile device */\n is_mobile: z.boolean().optional(),\n});\n\nexport type AuthGitHubCallbackResponse = z.infer<typeof AuthGitHubCallbackResponseSchema>;\n\n/**\n * POST /auth/github/refresh request body schema.\n *\n * Exchange a GitHub refresh token for a new access token.\n */\nexport const AuthGitHubRefreshRequestSchema = z.object({\n /** GitHub refresh token from the original OAuth flow */\n refreshToken: z.string().min(1, 'refreshToken is required'),\n});\n\nexport type AuthGitHubRefreshRequest = z.infer<typeof AuthGitHubRefreshRequestSchema>;\n\n/**\n * POST /auth/github/refresh response schema.\n */\nexport const AuthGitHubRefreshResponseSchema = z.object({\n /** New GitHub access token */\n githubAccessToken: z.string(),\n /** New GitHub refresh token (GitHub rotates these on each use) */\n githubRefreshToken: z.string(),\n});\n\nexport type AuthGitHubRefreshResponse = z.infer<typeof AuthGitHubRefreshResponseSchema>;\n\n/**\n * GET /auth/verify response schema.\n *\n * Validates a JWT against the database and returns user info or failure reason.\n */\nexport const AuthVerifyResponseSchema = z.discriminatedUnion('valid', [\n z.object({ valid: z.literal(true), user: OAuthUserSchema }),\n z.object({\n valid: z.literal(false),\n reason: z.enum(['invalid_token', 'user_not_found']),\n }),\n]);\n\nexport type AuthVerifyResponse = z.infer<typeof AuthVerifyResponseSchema>;\n\n/**\n * All valid participant roles in a collab room.\n * Owner is the task creator; collaborator roles come from the invite link.\n */\nexport const ParticipantRoleSchema = z.enum([\n 'owner',\n 'collaborator-full',\n 'collaborator-review',\n 'viewer',\n]);\nexport type ParticipantRole = z.infer<typeof ParticipantRoleSchema>;\n\n/**\n * Collaborator-only roles (subset of ParticipantRole, excludes 'owner').\n * Used for invite link creation where the owner role is never assignable.\n */\nexport const CollaboratorRoleSchema = ParticipantRoleSchema.extract([\n 'collaborator-full',\n 'collaborator-review',\n 'viewer',\n]);\nexport type CollaboratorRole = z.infer<typeof CollaboratorRoleSchema>;\n\n/**\n * POST /collab/create request body schema.\n *\n * Used to create a new collaboration room with a pre-signed URL.\n */\nexport const CollabCreateRequestSchema = z.object({\n /** ID of the task to collaborate on */\n taskId: z.string().min(1, 'taskId is required'),\n /** How long the collaboration link should be valid (1-10080 minutes / 7 days max, default 60) */\n expiresInMinutes: z.number().min(1).max(10080).default(60),\n /** Permission level for the invitee (defaults to 'collaborator-full') */\n role: CollaboratorRoleSchema.optional(),\n});\n\nexport type CollabCreateRequest = z.infer<typeof CollabCreateRequestSchema>;\n\n/**\n * POST /collab/create response schema.\n *\n * Returns the pre-signed WebSocket URL for joining the collaboration room.\n */\nexport const CollabCreateResponseSchema = z.object({\n /** Pre-signed WebSocket URL for joining the room */\n url: z.string().url(),\n /** Unique room identifier */\n roomId: z.string(),\n /** Unix timestamp when the collaboration link expires */\n expiresAt: z.number(),\n});\n\nexport type CollabCreateResponse = z.infer<typeof CollabCreateResponseSchema>;\n\n/**\n * GET /personal/:userId error responses.\n *\n * WebSocket messages are defined below.\n *\n * The actual WebSocket is handled by the Durable Object.\n * These are HTTP error responses before upgrade.\n */\nexport const WsPersonalErrorSchema = z.discriminatedUnion('error', [\n ErrorResponseSchema.extend({\n error: z.literal('upgrade_required'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('missing_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('invalid_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('forbidden'),\n }),\n]);\n\nexport type WsPersonalError = z.infer<typeof WsPersonalErrorSchema>;\n\n/**\n * GET /collab/:roomId error responses.\n *\n * WebSocket messages are defined below.\n *\n * The actual WebSocket is handled by the Durable Object.\n * These are HTTP error responses before upgrade.\n */\nexport const WsCollabErrorSchema = z.discriminatedUnion('error', [\n ErrorResponseSchema.extend({\n error: z.literal('upgrade_required'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('missing_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('invalid_token'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('forbidden'),\n }),\n ErrorResponseSchema.extend({\n error: z.literal('expired'),\n }),\n]);\n\nexport type WsCollabError = z.infer<typeof WsCollabErrorSchema>;\n\n/**\n * Shipyard JWT claims schema.\n *\n * This is the payload embedded in the JWT returned by /auth/github/callback.\n */\nexport const ShipyardJWTClaimsSchema = z.object({\n /** Shipyard user ID: \"usr_abc123\" */\n sub: z.string(),\n /** Display name from primary provider */\n displayName: z.string(),\n /** Linked OAuth providers */\n providers: z.array(z.string()),\n iat: z.number(),\n exp: z.number(),\n /** Optional: Scope for agent tokens (e.g., 'task:abc123') */\n scope: z.string().optional(),\n /** Optional: Machine ID for daemon tokens */\n machineId: z.string().optional(),\n});\n\nexport type ShipyardJWTClaims = z.infer<typeof ShipyardJWTClaimsSchema>;\n\n/**\n * Pre-signed URL payload schema.\n *\n * Embedded in the token query parameter for /collab/:roomId.\n */\nexport const PresignedUrlPayloadSchema = z.object({\n /** Room ID this token is valid for */\n roomId: z.string(),\n /** Task ID being collaborated on */\n taskId: z.string(),\n /** User ID of the person who created the invite */\n inviterId: z.string(),\n /** Expiration timestamp (Unix ms) */\n exp: z.number(),\n /** Permission level for the invitee (defaults to 'collaborator-full') */\n role: CollaboratorRoleSchema.optional(),\n /** Generation counter for link revocation — tokens with a generation older than the room's current generation are rejected */\n generation: z.number().optional(),\n});\n\nexport type PresignedUrlPayload = z.infer<typeof PresignedUrlPayloadSchema>;\n\n/**\n * Reasoning capability schema for models that support configurable reasoning effort.\n */\n/*\n * Keep in sync with ReasoningEffortSchema in packages/loro-schema/src/shared-enums.ts.\n * Inlined here because packages/session has no dependency on @shipyard/loro-schema.\n */\nexport const ReasoningCapabilitySchema = z\n .object({\n efforts: z.array(z.enum(['low', 'medium', 'high', 'xhigh', 'max', 'auto'])).min(1),\n defaultEffort: z.enum(['low', 'medium', 'high', 'xhigh', 'max', 'auto']),\n })\n .refine((data) => data.efforts.includes(data.defaultEffort), {\n message: 'defaultEffort must be one of the supported efforts',\n });\n\nexport type ReasoningCapability = z.infer<typeof ReasoningCapabilitySchema>;\n\n/**\n * Model info schema for machine capabilities.\n */\nexport const ModelInfoSchema = z.object({\n id: z.string(),\n name: z.string(),\n provider: z.string(),\n description: z.string().optional(),\n reasoning: ReasoningCapabilitySchema.optional(),\n supportsFastMode: z.boolean().optional(),\n});\n\nexport type ModelInfo = z.infer<typeof ModelInfoSchema>;\n\n/**\n * Git repo info schema for machine capabilities.\n */\nexport const GitRepoInfoSchema = z.object({\n path: z.string(),\n name: z.string(),\n branch: z.string(),\n remote: z.string().optional(),\n});\n\nexport type GitRepoInfo = z.infer<typeof GitRepoInfoSchema>;\n\n/**\n * Permission mode schema for machine capabilities.\n */\nexport const PermissionModeSchema = z.enum(['default', 'accept-edits', 'plan', 'bypass', 'auto']);\n\nexport type PermissionMode = z.infer<typeof PermissionModeSchema>;\n\n/**\n * Anthropic auth status — detected from env vars, Claude Code OAuth, or cloud providers.\n */\nconst AnthropicAuthMethodEnum = z.enum([\n 'claude-ai',\n 'console',\n 'api-key',\n 'sso',\n 'gateway',\n 'bedrock',\n 'vertex',\n 'foundry',\n 'none',\n]);\n\nexport const AnthropicAuthStatusSchema = z.object({\n status: z.enum(['authenticated', 'unauthenticated', 'unknown']),\n method: AnthropicAuthMethodEnum,\n email: z.string().optional(),\n orgName: z.string().optional(),\n subscriptionType: z.string().nullable().optional(),\n apiProvider: z.string().optional(),\n authMismatch: z\n .object({\n selected: AnthropicAuthMethodEnum,\n envMethod: AnthropicAuthMethodEnum,\n envVar: z.string(),\n })\n .optional(),\n});\n\nexport type AnthropicAuthStatus = z.infer<typeof AnthropicAuthStatusSchema>;\n\nexport const MCPServerAuthStatusSchema = z.enum(['authenticated', 'unauthenticated', 'unknown']);\nexport type MCPServerAuthStatus = z.infer<typeof MCPServerAuthStatusSchema>;\n\nexport const MCPServerSourceSchema = z.enum([\n 'project',\n 'user',\n 'local',\n 'mcp-json',\n 'plugin',\n 'claudeai',\n]);\nexport type MCPServerSource = z.infer<typeof MCPServerSourceSchema>;\n\nconst MCP_SERVER_TYPES = ['stdio', 'http', 'sse'] as const;\nexport const MCPServerTypeSchema = z.enum(MCP_SERVER_TYPES);\nexport type MCPServerType = z.infer<typeof MCPServerTypeSchema>;\n\nexport const MCPOAuthConfigSchema = z.object({\n clientId: z.string().optional(),\n callbackPort: z.number().optional(),\n});\n\nexport const MCPServerInfoSchema = z.object({\n name: z.string(),\n type: MCPServerTypeSchema.default('stdio'),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n url: z.string().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n oauth: MCPOAuthConfigSchema.optional(),\n enabled: z.boolean(),\n source: MCPServerSourceSchema,\n authStatus: MCPServerAuthStatusSchema,\n});\nexport type MCPServerInfo = z.infer<typeof MCPServerInfoSchema>;\n\nexport const SkillInfoSchema = z.object({\n name: z.string(),\n description: z.string(),\n});\nexport type SkillInfo = z.infer<typeof SkillInfoSchema>;\n\n/**\n * Machine capabilities schema — advertised by daemons at registration time.\n */\nexport const MarketplacePluginInfoSchema = z.object({\n name: z.string(),\n description: z.string(),\n author: z.string(),\n marketplace: z.string(),\n installCount: z.number().optional(),\n installed: z.boolean(),\n enabled: z.boolean(),\n version: z.string().optional(),\n isExternal: z.boolean(),\n});\nexport type MarketplacePluginInfo = z.infer<typeof MarketplacePluginInfoSchema>;\n\nexport const ClaudeCodeAgentSchema = z.object({\n id: z.literal('claude-code'),\n name: z.literal('Claude Code'),\n version: z.string().optional(),\n});\n\nexport const InstalledAgentSchema = z.discriminatedUnion('id', [ClaudeCodeAgentSchema]);\nexport type InstalledAgent = z.infer<typeof InstalledAgentSchema>;\n\nexport const MachineCapabilitiesSchema = z.object({\n models: z.array(ModelInfoSchema),\n environments: z.array(GitRepoInfoSchema),\n permissionModes: z.array(PermissionModeSchema),\n homeDir: z.string(),\n anthropicAuth: AnthropicAuthStatusSchema.optional(),\n mcpServers: z.array(MCPServerInfoSchema),\n skills: z.array(SkillInfoSchema),\n marketplacePlugins: z.array(MarketplacePluginInfoSchema),\n autoModeEnabled: z.boolean().optional(),\n installedAgents: z.array(InstalledAgentSchema),\n});\n\nexport type MachineCapabilities = z.infer<typeof MachineCapabilitiesSchema>;\n\n/**\n * Register agent message schema for personal room WebSocket.\n * Capabilities are no longer sent via signaling -- they flow through\n * Loro ephemeral on the room document instead.\n */\nexport const RegisterAgentSchema = z.object({\n type: z.literal('register-agent'),\n agentId: z.string(),\n machineId: z.string(),\n machineName: z.string(),\n agentType: z.string(),\n protocolVersion: z.number().optional(),\n npmVersion: z.string().optional(),\n});\n\n/**\n * Unregister agent message schema for personal room WebSocket.\n */\nexport const UnregisterAgentSchema = z.object({\n type: z.literal('unregister-agent'),\n agentId: z.string(),\n});\n\n/**\n * Agent status update message schema for personal room WebSocket.\n */\nexport const AgentStatusSchema = z.object({\n type: z.literal('agent-status'),\n agentId: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n});\n\n/**\n * WebRTC offer message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCOfferSchema = z.object({\n type: z.literal('webrtc-offer'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n offer: z.unknown(),\n requestId: z.string().optional(),\n});\n\n/**\n * WebRTC answer message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCAnswerSchema = z.object({\n type: z.literal('webrtc-answer'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n answer: z.unknown(),\n requestId: z.string().optional(),\n});\n\n/**\n * WebRTC ICE candidate message schema for personal room WebSocket.\n *\n * When sent by a client: `targetMachineId` is the intended recipient.\n * When relayed by the server: `fromMachineId` is added to identify the sender.\n */\nexport const WebRTCIceSchema = z.object({\n type: z.literal('webrtc-ice'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n candidate: z.unknown(),\n});\n\n/**\n * ICE server entry schema (matches RTCIceServer).\n */\nexport const IceServerSchema = z.object({\n urls: z.union([z.string(), z.array(z.string())]),\n username: z.string().optional(),\n credential: z.string().optional(),\n});\n\nexport type IceServer = z.infer<typeof IceServerSchema>;\n\n/**\n * Default ICE servers used when the server has not provided TURN credentials.\n * Centralized here so all consumers (browser, daemon, session-server) share\n * one source of truth for the fallback STUN URL.\n */\nexport const DEFAULT_ICE_SERVERS: IceServer[] = [{ urls: 'stun:stun.cloudflare.com:3478' }];\n\n/**\n * Server→client message delivering ICE server configuration (STUN + TURN).\n * Sent after authentication so clients have TURN credentials before any\n * peer connections are created.\n */\nexport const IceServersSchema = z.object({\n type: z.literal('ice-servers'),\n iceServers: z.array(IceServerSchema),\n});\n\n/**\n * Error message schema for WebSocket connections.\n */\nexport const ErrorMessageSchema = z.object({\n type: z.literal('error'),\n code: z.string(),\n message: z.string(),\n requestId: z.string().optional(),\n});\n\n/**\n * User settings schema — stored in CRDT, synced across daemons.\n */\nexport const UserSettingsSchema = z.object({\n worktreeSetupScript: z.string().nullable(),\n});\n\nexport type UserSettings = z.infer<typeof UserSettingsSchema>;\n\n/**\n * Browser requests daemon self-update via signaling relay.\n * Follows the WebRTC relay pattern: browser sends with targetMachineId,\n * server relays to daemon with fromMachineId added.\n */\nexport const RequestDaemonUpdateSchema = z.object({\n type: z.literal('request-daemon-update'),\n targetMachineId: z.string(),\n fromMachineId: z.string().optional(),\n installCommand: z.string(),\n});\n\nexport type RequestDaemonUpdate = z.infer<typeof RequestDaemonUpdateSchema>;\n\n/**\n * Daemon reports self-update progress via signaling relay.\n * Sent by daemon, server broadcasts to all browser connections.\n *\n * Status lifecycle — daemon-as-stager model:\n * downloading → downloaded → handoff → (daemon exits) → installing →\n * verifying → restarting → (new daemon boots) → succeeded|rolled-back|failed\n * The succeeded transition is reported by the NEW daemon on first authenticated\n * browser connection (see readAndClearUpdateStatus).\n */\nexport const DaemonUpdateStatusSchema = z.object({\n type: z.literal('daemon-update-status'),\n fromMachineId: z.string().optional(),\n status: z.enum([\n 'downloading',\n 'downloaded',\n 'handoff',\n 'installing',\n 'verifying',\n 'restarting',\n 'succeeded',\n 'rolled-back',\n 'failed',\n ]),\n error: z.string().optional(),\n targetVersion: z.string().optional(),\n previousVersion: z.string().optional(),\n});\n\nexport type DaemonUpdateStatus = z.infer<typeof DaemonUpdateStatusSchema>;\n\n/**\n * Union of all client-to-server messages for personal room WebSocket.\n */\nexport const PersonalRoomClientMessageSchema = z.discriminatedUnion('type', [\n RegisterAgentSchema,\n UnregisterAgentSchema,\n AgentStatusSchema,\n WebRTCOfferSchema,\n WebRTCAnswerSchema,\n WebRTCIceSchema,\n ErrorMessageSchema,\n RequestDaemonUpdateSchema,\n DaemonUpdateStatusSchema,\n]);\n\nexport type PersonalRoomClientMessage = z.infer<typeof PersonalRoomClientMessageSchema>;\n\n/**\n * Authentication success message schema for personal room WebSocket.\n */\nexport const AuthenticatedSchema = z.object({\n type: z.literal('authenticated'),\n userId: z.string(),\n username: z.string(),\n});\n\n/**\n * Agent info schema for personal room WebSocket.\n * Capabilities are no longer included -- they flow through Loro ephemeral.\n */\nexport const AgentInfoSchema = z.object({\n agentId: z.string(),\n machineId: z.string(),\n machineName: z.string(),\n agentType: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n protocolVersion: z.number().optional(),\n npmVersion: z.string().optional(),\n});\n\nexport type AgentInfo = z.infer<typeof AgentInfoSchema>;\n\n/**\n * Agents list message schema for personal room WebSocket.\n */\nexport const AgentsListSchema = z.object({\n type: z.literal('agents-list'),\n agents: z.array(AgentInfoSchema),\n hasDaemonRegistered: z.boolean().optional(),\n});\n\n/**\n * Agent joined notification message schema for personal room WebSocket.\n */\nexport const AgentJoinedSchema = z.object({\n type: z.literal('agent-joined'),\n agent: AgentInfoSchema,\n});\n\n/**\n * Agent left notification message schema for personal room WebSocket.\n */\nexport const AgentLeftSchema = z.object({\n type: z.literal('agent-left'),\n agentId: z.string(),\n});\n\n/**\n * Agent status changed notification message schema for personal room WebSocket.\n */\nexport const AgentStatusChangedSchema = z.object({\n type: z.literal('agent-status-changed'),\n agentId: z.string(),\n status: z.enum(['idle', 'running', 'error']),\n activeTaskId: z.string().optional(),\n});\n\n/**\n * Webhook event schema for events ingested from external services (e.g. Linear)\n * and forwarded to connected daemons via the PersonalRoom WebSocket.\n */\nexport const WebhookEventSchema = z.object({\n type: z.literal('webhook-event'),\n source: z.string(),\n event: z.string(),\n payload: z.record(z.string(), z.unknown()),\n timestamp: z.number(),\n});\n\nexport type WebhookEvent = z.infer<typeof WebhookEventSchema>;\n\n/**\n * Union of all server-to-client messages for personal room WebSocket.\n */\nexport const PersonalRoomServerMessageSchema = z.discriminatedUnion('type', [\n AuthenticatedSchema,\n AgentsListSchema,\n AgentJoinedSchema,\n AgentLeftSchema,\n AgentStatusChangedSchema,\n ErrorMessageSchema,\n WebRTCOfferSchema,\n WebRTCAnswerSchema,\n WebRTCIceSchema,\n IceServersSchema,\n WebhookEventSchema,\n RequestDaemonUpdateSchema,\n DaemonUpdateStatusSchema,\n]);\n\nexport type PersonalRoomServerMessage = z.infer<typeof PersonalRoomServerMessageSchema>;\n\n/**\n * WebRTC offer message schema for collab room WebSocket.\n */\nexport const CollabWebRTCOfferSchema = z.object({\n type: z.literal('webrtc-offer'),\n targetUserId: z.string(),\n offer: z.unknown(),\n});\n\n/**\n * WebRTC answer message schema for collab room WebSocket.\n */\nexport const CollabWebRTCAnswerSchema = z.object({\n type: z.literal('webrtc-answer'),\n targetUserId: z.string(),\n answer: z.unknown(),\n});\n\n/**\n * WebRTC ICE candidate message schema for collab room WebSocket.\n */\nexport const CollabWebRTCIceSchema = z.object({\n type: z.literal('webrtc-ice'),\n targetUserId: z.string(),\n candidate: z.unknown(),\n});\n\n/**\n * Union of all client-to-server messages for collab room WebSocket.\n */\nexport const CollabRoomClientMessageSchema = z.discriminatedUnion('type', [\n CollabWebRTCOfferSchema,\n CollabWebRTCAnswerSchema,\n CollabWebRTCIceSchema,\n]);\n\nexport type CollabRoomClientMessage = z.infer<typeof CollabRoomClientMessageSchema>;\n\n/**\n * Participant info schema for collab room WebSocket.\n */\nexport const ParticipantSchema = z.object({\n userId: z.string(),\n username: z.string(),\n avatarUrl: z.string().nullable().optional(),\n role: ParticipantRoleSchema,\n});\n\nexport type Participant = z.infer<typeof ParticipantSchema>;\n\n/**\n * Authentication success message schema for collab room WebSocket.\n */\nexport const CollabAuthenticatedSchema = z.object({\n type: z.literal('authenticated'),\n userId: z.string(),\n username: z.string(),\n taskId: z.string(),\n});\n\n/**\n * Participants list message schema for collab room WebSocket.\n */\nexport const ParticipantsListSchema = z.object({\n type: z.literal('participants-list'),\n participants: z.array(ParticipantSchema),\n});\n\n/**\n * Participant joined notification message schema for collab room WebSocket.\n */\nexport const ParticipantJoinedSchema = z.object({\n type: z.literal('participant-joined'),\n participant: ParticipantSchema,\n});\n\n/**\n * Participant left notification message schema for collab room WebSocket.\n */\nexport const ParticipantLeftSchema = z.object({\n type: z.literal('participant-left'),\n userId: z.string(),\n});\n\n/**\n * Union of all server-to-client messages for collab room WebSocket.\n */\nexport const CollabRoomServerMessageSchema = z.discriminatedUnion('type', [\n CollabAuthenticatedSchema,\n ParticipantsListSchema,\n ParticipantJoinedSchema,\n ParticipantLeftSchema,\n ErrorMessageSchema,\n CollabWebRTCOfferSchema,\n CollabWebRTCAnswerSchema,\n CollabWebRTCIceSchema,\n IceServersSchema,\n]);\n\nexport type CollabRoomServerMessage = z.infer<typeof CollabRoomServerMessageSchema>;\n\n/**\n * GitHub issue type for feedback categorization.\n */\nexport const GitHubIssueTypeSchema = z.enum(['bug', 'feature', 'question', 'praise']);\nexport type GitHubIssueType = z.infer<typeof GitHubIssueTypeSchema>;\n\n/**\n * POST /feedback/issue request body schema.\n */\nexport const GitHubIssueCreateRequestSchema = z.object({\n type: GitHubIssueTypeSchema,\n title: z.string().min(1, 'title is required').max(256, 'title must be 256 chars or fewer'),\n description: z.string().max(10000).optional(),\n logs: z.string().max(50000).optional(),\n context: z\n .object({\n url: z.string().optional(),\n taskId: z.string().optional(),\n userAgent: z.string().optional(),\n timestamp: z.string().optional(),\n })\n .optional(),\n});\n\nexport type GitHubIssueCreateRequest = z.infer<typeof GitHubIssueCreateRequestSchema>;\n\n/**\n * POST /feedback/issue response schema.\n */\nexport const GitHubIssueCreateResponseSchema = z.object({\n issueUrl: z.string(),\n issueNumber: z.number(),\n});\n\nexport type GitHubIssueCreateResponse = z.infer<typeof GitHubIssueCreateResponseSchema>;\n\n/**\n * POST /auth/linear/callback request body schema.\n *\n * Used to exchange a Linear OAuth code for Linear access tokens.\n * Requires an authenticated Shipyard JWT.\n */\nexport const AuthLinearCallbackRequestSchema = z.object({\n /** Linear OAuth authorization code */\n code: z.string().min(1, 'code is required'),\n /** OAuth redirect URI that was used in the authorize request */\n redirect_uri: z.string().url('redirect_uri must be a valid URL'),\n});\n\nexport type AuthLinearCallbackRequest = z.infer<typeof AuthLinearCallbackRequestSchema>;\n\n/**\n * POST /auth/linear/callback response schema.\n *\n * Returns Linear OAuth tokens and user info on successful OAuth.\n */\nexport const AuthLinearCallbackResponseSchema = z.object({\n /** Linear access token */\n linearAccessToken: z.string(),\n /** Seconds until the access token expires (from Linear's token response) */\n expiresIn: z.number().optional(),\n /** Linear user info */\n linearUser: z.object({\n id: z.string(),\n name: z.string().nullable(),\n email: z.string().nullable(),\n avatarUrl: z.string().nullable(),\n }),\n});\n\nexport type AuthLinearCallbackResponse = z.infer<typeof AuthLinearCallbackResponseSchema>;\n\n/** POST /auth/device/start — no request body needed */\nexport const DeviceStartResponseSchema = z.object({\n deviceCode: z.string(),\n userCode: z.string(),\n verificationUri: z.string().url(),\n expiresIn: z.number(),\n interval: z.number(),\n});\nexport type DeviceStartResponse = z.infer<typeof DeviceStartResponseSchema>;\n\n/** POST /auth/device/poll request */\nexport const DevicePollRequestSchema = z.object({\n deviceCode: z.string().min(1, 'deviceCode is required'),\n});\nexport type DevicePollRequest = z.infer<typeof DevicePollRequestSchema>;\n\n/** POST /auth/device/poll response (success) */\nexport const DevicePollResponseSchema = z.object({\n token: z.string(),\n user: OAuthUserSchema,\n});\nexport type DevicePollResponse = z.infer<typeof DevicePollResponseSchema>;\n\n/** POST /auth/device/poll response (pending/errors) */\nexport const DevicePollPendingSchema = z.object({\n error: z.enum(['authorization_pending', 'slow_down', 'expired_token']),\n});\nexport type DevicePollPending = z.infer<typeof DevicePollPendingSchema>;\n\n/** POST /auth/device/authorize — browser authorizes a device using its own JWT */\nexport const DeviceAuthorizeRequestSchema = z.object({\n userCode: z.string().min(1, 'userCode is required'),\n});\nexport type DeviceAuthorizeRequest = z.infer<typeof DeviceAuthorizeRequestSchema>;\n\nexport const DeviceAuthorizeResponseSchema = z.object({\n authorized: z.boolean(),\n});\nexport type DeviceAuthorizeResponse = z.infer<typeof DeviceAuthorizeResponseSchema>;\n\n/** POST /auth/device/exchange-code — daemon exchanges userCode for deviceCode */\nexport const DeviceExchangeCodeRequestSchema = z.object({\n userCode: z.string().min(1, 'userCode is required'),\n});\nexport type DeviceExchangeCodeRequest = z.infer<typeof DeviceExchangeCodeRequestSchema>;\n\nexport const DeviceExchangeCodeResponseSchema = z.object({\n deviceCode: z.string(),\n});\nexport type DeviceExchangeCodeResponse = z.infer<typeof DeviceExchangeCodeResponseSchema>;\n\n/** POST /auth/browser-code — daemon requests a one-time code for browser auth */\nexport const BrowserCodeResponseSchema = z.object({\n code: z.string(),\n expiresIn: z.number(),\n});\nexport type BrowserCodeResponse = z.infer<typeof BrowserCodeResponseSchema>;\n\n/** POST /auth/browser-code/exchange — browser exchanges code for JWT */\nexport const BrowserCodeExchangeRequestSchema = z.object({\n code: z.string().min(1, 'code is required'),\n});\nexport type BrowserCodeExchangeRequest = z.infer<typeof BrowserCodeExchangeRequestSchema>;\n\nexport const BrowserCodeExchangeResponseSchema = z.object({\n token: z.string(),\n user: OAuthUserSchema,\n});\nexport type BrowserCodeExchangeResponse = z.infer<typeof BrowserCodeExchangeResponseSchema>;\n\n/** GET /vault/key response */\nexport const VaultKeyGetResponseSchema = z.object({\n encryptedKey: z.string(),\n createdAt: z.number(),\n});\nexport type VaultKeyGetResponse = z.infer<typeof VaultKeyGetResponseSchema>;\n\n/** PUT /vault/key request */\nexport const VaultKeyPutRequestSchema = z.object({\n encryptedKey: z.string().min(1, 'encryptedKey is required').max(4096),\n});\nexport type VaultKeyPutRequest = z.infer<typeof VaultKeyPutRequestSchema>;\n\n/** PUT /vault/key response (created) */\nexport const VaultKeyPutResponseSchema = z.object({\n created: z.boolean(),\n});\nexport type VaultKeyPutResponse = z.infer<typeof VaultKeyPutResponseSchema>;\n\n/** Metrics ingestion */\n\nexport const MetricsEventSchema = z.object({\n eventType: z.string().min(1).max(100),\n taskId: z.string().max(200).optional(),\n payload: z.record(z.unknown()).default({}),\n clientTimestamp: z.number().int().positive(),\n});\nexport type MetricsEvent = z.infer<typeof MetricsEventSchema>;\n\nexport const MetricsIngestRequestSchema = z.object({\n events: z.array(MetricsEventSchema).min(1).max(100),\n});\nexport type MetricsIngestRequest = z.infer<typeof MetricsIngestRequestSchema>;\n\nexport const MetricsIngestResponseSchema = z.object({\n accepted: z.number(),\n});\nexport type MetricsIngestResponse = z.infer<typeof MetricsIngestResponseSchema>;\n","/**\n * Shared route constants for the signaling server.\n *\n * Used by both server (route registration) and client (request URLs).\n * Single source of truth prevents drift between implementations.\n *\n * @module client/routes\n */\nexport const ROUTES = {\n HEALTH: '/health',\n AUTH_GITHUB_CALLBACK: '/auth/github/callback',\n AUTH_GITHUB_REFRESH: '/auth/github/refresh',\n AUTH_DEVICE_START: '/auth/device/start',\n AUTH_DEVICE_VERIFY: '/auth/device/verify',\n AUTH_DEVICE_POLL: '/auth/device/poll',\n AUTH_DEVICE_AUTHORIZE: '/auth/device/authorize',\n AUTH_DEVICE_EXCHANGE_CODE: '/auth/device/exchange-code',\n AUTH_BROWSER_CODE: '/auth/browser-code',\n AUTH_BROWSER_CODE_EXCHANGE: '/auth/browser-code/exchange',\n AUTH_VERIFY: '/auth/verify',\n COLLAB_CREATE: '/collab/create',\n COLLAB_REVOKE: '/collab/:roomId',\n GITHUB_ISSUE_CREATE: '/feedback/issue',\n VAULT_KEY: '/vault/key',\n AUTH_LINEAR: '/auth/linear',\n AUTH_LINEAR_CALLBACK: '/auth/linear/callback',\n WEBHOOK_INGEST: '/webhooks/:userId/:source',\n WS_PERSONAL: '/personal/:userId',\n WS_COLLAB: '/collab/:roomId',\n METRICS_INGEST: '/ingest',\n METRICS_QUERY_EVENTS: '/query/events',\n} as const;\n\n/**\n * Human-readable endpoint descriptions for documentation and error messages.\n */\nexport const ROUTE_DESCRIPTIONS = [\n `GET ${ROUTES.HEALTH}`,\n `POST ${ROUTES.AUTH_GITHUB_CALLBACK}`,\n `POST ${ROUTES.AUTH_GITHUB_REFRESH}`,\n `POST ${ROUTES.AUTH_DEVICE_START}`,\n `GET ${ROUTES.AUTH_DEVICE_VERIFY}`,\n `POST ${ROUTES.AUTH_DEVICE_POLL}`,\n `POST ${ROUTES.AUTH_DEVICE_AUTHORIZE}`,\n `POST ${ROUTES.AUTH_DEVICE_EXCHANGE_CODE}`,\n `POST ${ROUTES.AUTH_BROWSER_CODE}`,\n `POST ${ROUTES.AUTH_BROWSER_CODE_EXCHANGE}`,\n `GET ${ROUTES.AUTH_VERIFY}`,\n `POST ${ROUTES.COLLAB_CREATE}`,\n `DELETE ${ROUTES.COLLAB_REVOKE}`,\n `POST ${ROUTES.GITHUB_ISSUE_CREATE}`,\n `GET ${ROUTES.VAULT_KEY}`,\n `PUT ${ROUTES.VAULT_KEY}`,\n `GET ${ROUTES.AUTH_LINEAR}`,\n `GET ${ROUTES.AUTH_LINEAR_CALLBACK}`,\n `POST ${ROUTES.WEBHOOK_INGEST}`,\n `WS ${ROUTES.WS_PERSONAL}`,\n `WS ${ROUTES.WS_COLLAB}`,\n `POST ${ROUTES.METRICS_INGEST}`,\n `GET ${ROUTES.METRICS_QUERY_EVENTS}`,\n] as const;\n","/**\n * Claude Code version compatibility for the Shipyard daemon.\n *\n * The SDK bundles its own `cli.js` — the user's global `claude` binary\n * is NOT what Shipyard spawns. Pinning the SDK version effectively pins\n * Claude Code. This module provides observability: when the init message\n * reports a runtime version, we compare it against what we tested.\n */\n\n/** The Claude Code version bundled with the currently pinned SDK (0.2.111). */\nexport const TESTED_CLAUDE_CODE_VERSION = '2.1.111';\n\nexport type ClaudeCodeCompatResult =\n | { status: 'compatible' }\n | { status: 'untested'; detected: string; tested: string }\n | { status: 'unknown' };\n\n/**\n * Compare a detected Claude Code runtime version against the tested version.\n *\n * - `compatible`: major.minor matches the tested version\n * - `untested`: version detected but major.minor differs\n * - `unknown`: version could not be determined\n */\nexport function classifyClaudeCodeCompatibility(\n detected: string | undefined,\n tested: string = TESTED_CLAUDE_CODE_VERSION\n): ClaudeCodeCompatResult {\n if (!detected) return { status: 'unknown' };\n\n const detectedParts = detected.split('.');\n const testedParts = tested.split('.');\n\n if (detectedParts[0] === testedParts[0] && detectedParts[1] === testedParts[1]) {\n return { status: 'compatible' };\n }\n\n return { status: 'untested', detected, tested };\n}\n","import type { ConnectionState } from './personal-room-connection';\nimport type { CollabRoomClientMessage, CollabRoomServerMessage } from './schemas';\nimport { CollabRoomServerMessageSchema } from './schemas';\n\ninterface MinimalWebSocket {\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: string }) => void) | null;\n send(data: string): void;\n close(): void;\n}\n\nexport interface CollabRoomConnectionConfig {\n url: string;\n WebSocketImpl?: new (url: string) => MinimalWebSocket;\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n /** Called when the server closes the connection with code 1000 (\"Room expired\"). Do not reconnect. */\n onRoomExpired?: () => void;\n}\n\nexport class CollabRoomConnection {\n private state: ConnectionState = 'disconnected';\n private ws: MinimalWebSocket | null = null;\n private readonly messageHandlers = new Set<(msg: CollabRoomServerMessage) => void>();\n private readonly stateChangeHandlers = new Set<(state: ConnectionState) => void>();\n private readonly config: CollabRoomConnectionConfig;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private pingTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect = false;\n\n constructor(config: CollabRoomConnectionConfig) {\n this.config = config;\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n connect(): void {\n this.intentionalDisconnect = false;\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n if (this.ws) {\n this.stopPingTimer();\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n\n const Impl = this.config.WebSocketImpl ?? (WebSocket as never);\n try {\n this.ws = new Impl(this.config.url);\n } catch {\n this.setState('error');\n this.reconnectWithBackoff();\n return;\n }\n this.setState('connecting');\n\n this.ws.onopen = () => {\n this.setState('connected');\n this.startPingTimer();\n };\n\n this.ws.onclose = (ev: unknown) => {\n this.stopPingTimer();\n if (this.state !== 'error' && this.state !== 'reconnecting') {\n this.setState('disconnected');\n }\n const code = extractCloseCode(ev);\n /** NOTE: 1000 = \"Room expired\" — the Durable Object TTL has elapsed. Stop reconnecting and notify the caller. */\n if (code === 1000) {\n this.config.onRoomExpired?.();\n return;\n }\n /** NOTE: 4001 = \"Replaced by new connection\" — a newer WebSocket for the same userId was accepted by the server. Do not reconnect; the replacement is already active. */\n if (!this.intentionalDisconnect && code !== 4001) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onerror = () => {\n this.stopPingTimer();\n this.setState('error');\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onmessage = (event: { data: string }) => {\n this.startPingTimer();\n\n if (event.data === 'pong') return;\n\n let raw: unknown;\n try {\n raw = JSON.parse(event.data);\n } catch {\n return;\n }\n\n const result = CollabRoomServerMessageSchema.safeParse(raw);\n if (!result.success) {\n // biome-ignore lint/suspicious/noConsole: intentional debug visibility for silent Zod drops that hid a critical share-link bug\n console.warn(\n '[CollabRoom] Dropped unrecognized server message:',\n JSON.stringify(raw),\n result.error.issues\n );\n return;\n }\n\n for (const handler of [...this.messageHandlers]) {\n handler(result.data);\n }\n };\n }\n\n send(msg: CollabRoomClientMessage): void {\n try {\n this.ws?.send(JSON.stringify(msg));\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n }\n\n onMessage(handler: (msg: CollabRoomServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => {\n this.stateChangeHandlers.delete(handler);\n };\n }\n\n reconnect(): void {\n this.intentionalDisconnect = false;\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.retryCount = 0;\n this.connect();\n }\n\n disconnect(): void {\n this.intentionalDisconnect = true;\n this.stopPingTimer();\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n this.retryCount = 0;\n\n if (this.ws) {\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n this.setState('disconnected');\n }\n\n private startPingTimer(): void {\n this.stopPingTimer();\n this.schedulePing();\n }\n\n private stopPingTimer(): void {\n if (this.pingTimer !== null) {\n clearTimeout(this.pingTimer);\n this.pingTimer = null;\n }\n }\n\n private schedulePing(): void {\n const jitter = Math.floor(Math.random() * 25_000);\n const delay = 30_000 + jitter;\n this.pingTimer = setTimeout(() => {\n this.pingTimer = null;\n try {\n this.ws?.send('ping');\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n this.schedulePing();\n }, delay);\n }\n\n private reconnectWithBackoff(): void {\n if (this.retryTimer !== null) return;\n\n const maxRetries = this.config.maxRetries;\n if (maxRetries === undefined || maxRetries === 0) {\n return;\n }\n\n if (maxRetries !== -1 && this.retryCount >= maxRetries) {\n return;\n }\n\n this.setState('reconnecting');\n\n if (this.intentionalDisconnect) return;\n\n const initialDelay = this.config.initialDelayMs ?? 1000;\n const maxDelay = this.config.maxDelayMs ?? 30000;\n const multiplier = this.config.backoffMultiplier ?? 2;\n const delay = Math.min(initialDelay * multiplier ** this.retryCount, maxDelay);\n\n this.retryCount++;\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.connect();\n }, delay);\n }\n\n private setState(newState: ConnectionState): void {\n this.state = newState;\n if (newState === 'connected') {\n this.retryCount = 0;\n }\n for (const handler of [...this.stateChangeHandlers]) {\n handler(newState);\n }\n }\n}\n\nfunction extractCloseCode(ev: unknown): number | undefined {\n if (typeof ev !== 'object' || ev === null || !('code' in ev)) return undefined;\n const code: unknown = ev.code;\n return typeof code === 'number' ? code : undefined;\n}\n","import type { PersonalRoomClientMessage, PersonalRoomServerMessage } from './schemas';\nimport { PersonalRoomServerMessageSchema } from './schemas';\n\nexport type ConnectionState =\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'error';\n\ninterface MinimalWebSocket {\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: string }) => void) | null;\n send(data: string): void;\n close(): void;\n}\n\nexport interface PersonalRoomConnectionConfig {\n url: string;\n WebSocketImpl?: new (url: string) => MinimalWebSocket;\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n}\n\nexport class PersonalRoomConnection {\n private state: ConnectionState = 'disconnected';\n private ws: MinimalWebSocket | null = null;\n private readonly messageHandlers = new Set<(msg: PersonalRoomServerMessage) => void>();\n private readonly stateChangeHandlers = new Set<(state: ConnectionState) => void>();\n private readonly config: PersonalRoomConnectionConfig;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private pingTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect = false;\n\n constructor(config: PersonalRoomConnectionConfig) {\n this.config = config;\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n connect(): void {\n this.intentionalDisconnect = false;\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n if (this.ws) {\n this.stopPingTimer();\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n\n const Impl = this.config.WebSocketImpl ?? (WebSocket as never);\n try {\n this.ws = new Impl(this.config.url);\n } catch {\n this.setState('error');\n this.reconnectWithBackoff();\n return;\n }\n this.setState('connecting');\n\n this.ws.onopen = () => {\n this.setState('connected');\n this.startPingTimer();\n };\n\n this.ws.onclose = () => {\n this.stopPingTimer();\n if (this.state !== 'error' && this.state !== 'reconnecting') {\n this.setState('disconnected');\n }\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onerror = () => {\n this.stopPingTimer();\n this.setState('error');\n if (!this.intentionalDisconnect) {\n this.reconnectWithBackoff();\n }\n };\n\n this.ws.onmessage = (event: { data: string }) => {\n this.startPingTimer();\n\n if (event.data === 'pong') return;\n\n let raw: unknown;\n try {\n raw = JSON.parse(event.data);\n } catch {\n return;\n }\n\n const result = PersonalRoomServerMessageSchema.safeParse(raw);\n if (!result.success) {\n if (this.state === 'connected') {\n // biome-ignore lint/suspicious/noConsole: intentional debug visibility for silent Zod drops that hid a critical share-link bug\n console.warn(\n '[PersonalRoom] Dropped unrecognized server message:',\n JSON.stringify(raw),\n result.error.issues\n );\n }\n return;\n }\n\n for (const handler of [...this.messageHandlers]) {\n handler(result.data);\n }\n };\n }\n\n send(msg: PersonalRoomClientMessage): void {\n try {\n this.ws?.send(JSON.stringify(msg));\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n }\n\n onMessage(handler: (msg: PersonalRoomServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => {\n this.stateChangeHandlers.delete(handler);\n };\n }\n\n reconnect(): void {\n this.intentionalDisconnect = false;\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n this.retryCount = 0;\n this.connect();\n }\n\n disconnect(): void {\n this.intentionalDisconnect = true;\n this.stopPingTimer();\n\n if (this.retryTimer !== null) {\n clearTimeout(this.retryTimer);\n this.retryTimer = null;\n }\n\n this.retryCount = 0;\n\n if (this.ws) {\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n this.setState('disconnected');\n }\n\n private startPingTimer(): void {\n this.stopPingTimer();\n this.schedulePing();\n }\n\n private stopPingTimer(): void {\n if (this.pingTimer !== null) {\n clearTimeout(this.pingTimer);\n this.pingTimer = null;\n }\n }\n\n private schedulePing(): void {\n const jitter = Math.floor(Math.random() * 25_000);\n const delay = 30_000 + jitter;\n this.pingTimer = setTimeout(() => {\n this.pingTimer = null;\n try {\n this.ws?.send('ping');\n } catch {\n /** WebSocket may be in CLOSING/CLOSED state */\n }\n this.schedulePing();\n }, delay);\n }\n\n private reconnectWithBackoff(): void {\n if (this.retryTimer !== null) return;\n\n const maxRetries = this.config.maxRetries;\n if (maxRetries === undefined || maxRetries === 0) {\n return;\n }\n\n if (maxRetries !== -1 && this.retryCount >= maxRetries) {\n return;\n }\n\n this.setState('reconnecting');\n\n if (this.intentionalDisconnect) return;\n\n const initialDelay = this.config.initialDelayMs ?? 1000;\n const maxDelay = this.config.maxDelayMs ?? 30000;\n const multiplier = this.config.backoffMultiplier ?? 2;\n const delay = Math.min(initialDelay * multiplier ** this.retryCount, maxDelay);\n\n this.retryCount++;\n\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.connect();\n }, delay);\n }\n\n private setState(newState: ConnectionState): void {\n this.state = newState;\n if (newState === 'connected') {\n this.retryCount = 0;\n }\n for (const handler of [...this.stateChangeHandlers]) {\n handler(newState);\n }\n }\n}\n","/**\n * Monotonic protocol version for daemon↔browser compatibility.\n *\n * Bump ONLY on breaking changes to the communication protocol between\n * the daemon and browser (new/removed message types, changed ephemeral\n * schemas, etc.). Feature releases that don't break the protocol do\n * NOT bump this number.\n *\n * The browser hardcodes a minimum acceptable version. When a daemon\n * connects with a lower version, the browser shows a blocking update\n * modal.\n */\nexport const PROTOCOL_VERSION = 24;\n\n/**\n * Minimum protocol version the browser requires from daemons.\n * Daemons reporting a version below this (or no version at all)\n * trigger the \"update your daemon\" modal.\n */\nexport const MIN_PROTOCOL_VERSION = 24;\n\nexport type CompatResult =\n | { compatible: true }\n | { compatible: false; reason: 'protocol' | 'prerelease-mismatch'; installCommand: string };\n\nfunction isPrerelease(version: string): boolean {\n return /-(nightly|rc)\\./.test(version);\n}\n\nexport function getInstallCommand(version?: string, channel?: 'latest' | 'next'): string {\n if (channel) {\n return `npm install -g @schoolai/shipyard@${channel}`;\n }\n const tag = version && isPrerelease(version) ? '@next' : '@latest';\n return `npm install -g @schoolai/shipyard${tag}`;\n}\n\nexport function classifyDaemonCompatibility(\n daemon: { protocolVersion?: number; npmVersion?: string },\n browser: {\n minProtocolVersion: number;\n expectedDaemonVersion?: string;\n channel?: 'latest' | 'next';\n }\n): CompatResult {\n const installCommand = getInstallCommand(\n browser.expectedDaemonVersion ?? daemon.npmVersion,\n browser.channel\n );\n\n if (\n daemon.npmVersion &&\n browser.expectedDaemonVersion &&\n isPrerelease(daemon.npmVersion) &&\n isPrerelease(browser.expectedDaemonVersion) &&\n daemon.npmVersion !== browser.expectedDaemonVersion\n ) {\n return {\n compatible: false,\n reason: 'prerelease-mismatch',\n installCommand,\n };\n }\n\n if ((daemon.protocolVersion ?? 0) < browser.minProtocolVersion) {\n return {\n compatible: false,\n reason: 'protocol',\n installCommand,\n };\n }\n\n return { compatible: true };\n}\n"],"mappings":"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","names":[]}
@@ -9,7 +9,7 @@ import {
9
9
  DevicePollResponseSchema,
10
10
  DeviceStartResponseSchema,
11
11
  ROUTES
12
- } from "./chunk-5SJBSLGT.js";
12
+ } from "./chunk-FMMRZTOF.js";
13
13
  import {
14
14
  getConfigPath,
15
15
  loadAuthToken,
@@ -217,4 +217,4 @@ export {
217
217
  ensureAuthenticated,
218
218
  loginCommand
219
219
  };
220
- //# sourceMappingURL=chunk-CANDZLMB.js.map
220
+ //# sourceMappingURL=chunk-JSUYB74F.js.map
package/dist/index.js CHANGED
@@ -95,7 +95,7 @@ async function loadAuthFromConfig(env) {
95
95
  async function handleSubcommand() {
96
96
  const subcommand = process.argv[2];
97
97
  if (subcommand === "login") {
98
- const { loginCommand } = await import("./login-GRM7QIPC.js");
98
+ const { loginCommand } = await import("./login-KSI4GTLM.js");
99
99
  const hasCheck = process.argv.includes("--check");
100
100
  await loginCommand({ check: hasCheck });
101
101
  return true;
@@ -106,12 +106,12 @@ async function handleSubcommand() {
106
106
  return true;
107
107
  }
108
108
  if (subcommand === "start") {
109
- const { startCommand } = await import("./start-24JXLIQJ.js");
109
+ const { startCommand } = await import("./start-2K7HFXHV.js");
110
110
  await startCommand();
111
111
  return true;
112
112
  }
113
113
  if (subcommand === "roi") {
114
- const { roiCommand } = await import("./roi-3Y7MWLSW.js");
114
+ const { roiCommand } = await import("./roi-YQ6OLVHX.js");
115
115
  await roiCommand();
116
116
  return true;
117
117
  }
@@ -123,7 +123,7 @@ async function main() {
123
123
  const args = parseCliArgs();
124
124
  if (args.serve) {
125
125
  await loadAuthFromConfig(env);
126
- const { serve } = await import("./serve-3EFFP3PN.js");
126
+ const { serve } = await import("./serve-P5WC5JIT.js");
127
127
  return serve({ isDev: env.SHIPYARD_DEV });
128
128
  }
129
129
  logger.error("Use `shipyard start` to run the daemon. Use --help for usage.");
@@ -3,9 +3,9 @@ import {
3
3
  ensureAuthenticated,
4
4
  getSignalingUrl,
5
5
  loginCommand
6
- } from "./chunk-CANDZLMB.js";
6
+ } from "./chunk-JSUYB74F.js";
7
7
  import "./chunk-YOMKRHVO.js";
8
- import "./chunk-5SJBSLGT.js";
8
+ import "./chunk-FMMRZTOF.js";
9
9
  import "./chunk-EHQITHQX.js";
10
10
  import "./chunk-IHSXN66C.js";
11
11
  import "./chunk-3UYLOJ6E.js";
@@ -16,4 +16,4 @@ export {
16
16
  getSignalingUrl,
17
17
  loginCommand
18
18
  };
19
- //# sourceMappingURL=login-GRM7QIPC.js.map
19
+ //# sourceMappingURL=login-KSI4GTLM.js.map