@schoolai/shipyard 3.8.0 → 3.9.1-nightly.20260607.0

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.
@@ -18,8 +18,8 @@ function getDaemonVersion() {
18
18
  return cached;
19
19
  }
20
20
  function readDaemonVersion() {
21
- if ("3.8.0".length > 0) {
22
- return "3.8.0";
21
+ if ("3.9.1".length > 0) {
22
+ return "3.9.1";
23
23
  }
24
24
  try {
25
25
  const here = dirname(fileURLToPath(import.meta.url));
@@ -48,4 +48,4 @@ function readDaemonVersion() {
48
48
  export {
49
49
  getDaemonVersion
50
50
  };
51
- //# sourceMappingURL=chunk-RMN36UD3.js.map
51
+ //# sourceMappingURL=chunk-K3QG7S6V.js.map
@@ -257,7 +257,7 @@ var RoiReportSchema = external_exports.object({
257
257
 
258
258
  // ../../packages/roi-aggregator/src/schemas/trailers.ts
259
259
  var TRAILER_SCHEMA_VERSION = 2;
260
- var SHIPYARD_COAUTHOR = "Shipyard <bot@shipyard.dev>";
260
+ var SHIPYARD_COAUTHOR = "Shipyard <bot@shipyard.computer>";
261
261
  var GitTrailerV2Schema = external_exports.object({
262
262
  version: external_exports.literal(TRAILER_SCHEMA_VERSION),
263
263
  taskId: external_exports.string().min(1),
@@ -327,4 +327,4 @@ export {
327
327
  hasShipyardTrailer,
328
328
  appendTrailerToMessage
329
329
  };
330
- //# sourceMappingURL=chunk-2CNIEBKO.js.map
330
+ //# sourceMappingURL=chunk-WN5Q6WBU.js.map
@@ -1 +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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: string;\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 runtimeId: input.runtimeId,\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 runtimeId?: 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 ...(input.runtimeId !== undefined ? { runtimeId: input.runtimeId } : {}),\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 runtimeId?: string;\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 ...(input.runtimeId !== undefined ? { runtimeId: input.runtimeId } : {}),\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 runtimeId: string;\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 runtimeId: input.runtimeId,\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 runtimeId: 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 runtimeId: input.runtimeId,\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":[]}
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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: z.string().min(1).default('claude-code'),\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 runtimeId: string;\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 runtimeId: input.runtimeId,\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 runtimeId?: 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 ...(input.runtimeId !== undefined ? { runtimeId: input.runtimeId } : {}),\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 runtimeId?: string;\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 ...(input.runtimeId !== undefined ? { runtimeId: input.runtimeId } : {}),\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 runtimeId: string;\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 runtimeId: input.runtimeId,\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 runtimeId: 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 runtimeId: input.runtimeId,\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.computer>' 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":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getDaemonVersion
4
- } from "./chunk-RMN36UD3.js";
4
+ } from "./chunk-K3QG7S6V.js";
5
5
  import {
6
6
  installWasmPanicBuffer
7
7
  } from "./chunk-7H34LI75.js";
@@ -66,7 +66,7 @@ async function main() {
66
66
  await loadAuthFromConfig(env);
67
67
  crumb("post-auth-load");
68
68
  crumb("pre-serve-import");
69
- const { serve } = await import("./serve-Y5GM5DOM.js");
69
+ const { serve } = await import("./serve-76X367VD.js");
70
70
  crumb("post-serve-import");
71
71
  const portQueue = [];
72
72
  let acceptor = null;
package/dist/index.js CHANGED
@@ -112,12 +112,12 @@ async function handleSubcommand() {
112
112
  return true;
113
113
  }
114
114
  if (subcommand === "start") {
115
- const { startCommand } = await import("./start-6CHD7LNT.js");
115
+ const { startCommand } = await import("./start-QOGAKRUP.js");
116
116
  await startCommand();
117
117
  return true;
118
118
  }
119
119
  if (subcommand === "roi") {
120
- const { roiCommand } = await import("./roi-QLXN7AIX.js");
120
+ const { roiCommand } = await import("./roi-Q3BQLIO7.js");
121
121
  await roiCommand();
122
122
  return true;
123
123
  }
@@ -129,7 +129,7 @@ async function main() {
129
129
  const args = parseCliArgs();
130
130
  if (args.serve) {
131
131
  await loadAuthFromConfig(env);
132
- const { serve } = await import("./serve-Y5GM5DOM.js");
132
+ const { serve } = await import("./serve-76X367VD.js");
133
133
  return serve({ isDev: env.SHIPYARD_DEV });
134
134
  }
135
135
  logger.error("Use `shipyard start` to run the daemon. Use --help for usage.");
@@ -4,7 +4,7 @@ import {
4
4
  ROI_EVENT_TYPE,
5
5
  RoiEventSchema,
6
6
  assertNeverEvent
7
- } from "./chunk-2CNIEBKO.js";
7
+ } from "./chunk-WN5Q6WBU.js";
8
8
  import "./chunk-EHQITHQX.js";
9
9
  import {
10
10
  logger
@@ -681,4 +681,4 @@ function renderReport(report, format) {
681
681
  export {
682
682
  roiCommand
683
683
  };
684
- //# sourceMappingURL=roi-QLXN7AIX.js.map
684
+ //# sourceMappingURL=roi-Q3BQLIO7.js.map
@@ -22,13 +22,13 @@ import {
22
22
  emitTaskEnded,
23
23
  emitTaskStarted,
24
24
  hasShipyardTrailer
25
- } from "./chunk-2CNIEBKO.js";
25
+ } from "./chunk-WN5Q6WBU.js";
26
26
  import {
27
27
  loadAuthToken
28
28
  } from "./chunk-CVMNGYPR.js";
29
29
  import {
30
30
  getDaemonVersion
31
- } from "./chunk-RMN36UD3.js";
31
+ } from "./chunk-K3QG7S6V.js";
32
32
  import {
33
33
  getRecentWasmPanicMessages
34
34
  } from "./chunk-7H34LI75.js";
@@ -9319,7 +9319,7 @@ var SignalingClient = class {
9319
9319
  /**
9320
9320
  * Creates a new SignalingClient instance.
9321
9321
  *
9322
- * @param baseUrl - Base URL of the signaling server (e.g., 'https://signaling.shipyard.dev')
9322
+ * @param baseUrl - Base URL of the signaling server (e.g., 'https://shipyard-session-server.jacob-191.workers.dev')
9323
9323
  * @param options - Optional configuration
9324
9324
  */
9325
9325
  constructor(baseUrl, options = {}) {
@@ -12936,7 +12936,7 @@ function nanoid(size2 = 21) {
12936
12936
  }
12937
12937
 
12938
12938
  // src/services/bootstrap/signaling.ts
12939
- var DAEMON_NPM_VERSION = true ? "3.8.0" : "unknown";
12939
+ var DAEMON_NPM_VERSION = true ? "3.9.1" : "unknown";
12940
12940
  function createDaemonSignaling(config) {
12941
12941
  const agentId = config.agentId ?? nanoid();
12942
12942
  function send(msg) {
@@ -124839,4 +124839,4 @@ export {
124839
124839
  decideWorkspaceScope,
124840
124840
  serve
124841
124841
  };
124842
- //# sourceMappingURL=serve-Y5GM5DOM.js.map
124842
+ //# sourceMappingURL=serve-76X367VD.js.map