mockpit 1.3.0 → 2.0.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.
Files changed (45) hide show
  1. package/README.md +61 -45
  2. package/bin/demoData.js +3 -3
  3. package/bin/mockpit.js +327 -52
  4. package/dist/mcp/server.js +35 -0
  5. package/dist/server/apiViews.d.ts +308 -23
  6. package/dist/server/apiViews.js +60 -19
  7. package/dist/server/app.d.ts +4 -1
  8. package/dist/server/app.js +608 -119
  9. package/dist/server/codeWorker.js +2 -1
  10. package/dist/server/decisions.d.ts +5 -5
  11. package/dist/server/decisions.js +10 -9
  12. package/dist/server/designGuide.d.ts +6 -2
  13. package/dist/server/designGuide.js +77 -43
  14. package/dist/server/embeds.d.ts +1 -0
  15. package/dist/server/embeds.js +30 -4
  16. package/dist/server/feedbackBatch.d.ts +6 -6
  17. package/dist/server/feedbackBatch.js +18 -11
  18. package/dist/server/guidance.d.ts +23 -0
  19. package/dist/server/guidance.js +71 -0
  20. package/dist/server/index.js +10 -1
  21. package/dist/server/mcpHttp.d.ts +3 -0
  22. package/dist/server/mcpHttp.js +32 -0
  23. package/dist/server/mcpSpec.d.ts +2 -1
  24. package/dist/server/mcpSpec.js +74 -24
  25. package/dist/server/postSurfaces.js +3 -0
  26. package/dist/server/run.js +6 -1
  27. package/dist/server/runApi.d.ts +3 -3
  28. package/dist/server/runApi.js +16 -12
  29. package/dist/server/sqlStore.d.ts +10 -3
  30. package/dist/server/sqlStore.js +230 -16
  31. package/dist/server/types.d.ts +46 -17
  32. package/dist/server/types.js +34 -11
  33. package/extensions/mockpit.js +179 -16
  34. package/guide/packs/design-craft.md +35 -0
  35. package/guide/topics/asks.md +60 -56
  36. package/guide/topics/feedback.md +104 -74
  37. package/guide/topics/html.md +5 -11
  38. package/guide/topics/http.md +6 -3
  39. package/guide/topics/knobs.md +2 -2
  40. package/guide/topics/scripts.md +2 -2
  41. package/guide/topics/surfaces.md +28 -10
  42. package/package.json +1 -4
  43. package/skills/launch-video/SKILL.md +1 -1
  44. package/skills/mockpit/SKILL.md +18 -10
  45. package/viewer/dist/index.html +8 -7
@@ -144,6 +144,26 @@ async function ensureSession(title) {
144
144
  sessionId = session.id;
145
145
  return sessionId;
146
146
  }
147
+ // A poster may name an image file: it travels as an upload, never as bytes in
148
+ // the model's context. Anything else goes through as the asset id it is.
149
+ async function posterId(value, session) {
150
+ if (typeof value !== "string")
151
+ return value;
152
+ try {
153
+ if (!statSync(value).isFile())
154
+ return value;
155
+ }
156
+ catch {
157
+ return value;
158
+ }
159
+ const asset = await post("/api/assets", {
160
+ data: readFileSync(value, "base64"),
161
+ contentType: contentTypeForPath(value),
162
+ filename: value.split(/[\\/]/).pop(),
163
+ session,
164
+ });
165
+ return asset.id;
166
+ }
147
167
  // Every tool is a pass-through to the REST route the CLI uses, mapped the way
148
168
  // server/mcpHttp.ts maps HTTP MCP: same request, same response, so the tiers
149
169
  // cannot drift. Only the session (one per conversation), the project (this
@@ -157,6 +177,7 @@ const handlers = {
157
177
  html,
158
178
  parts: readPartFiles(args.parts),
159
179
  fills: readPartFiles(args.fills),
180
+ poster: await posterId(args.poster, session),
160
181
  session,
161
182
  agent: AGENT,
162
183
  project: resolveProject(args.project),
@@ -195,6 +216,20 @@ const handlers = {
195
216
  message: args.message,
196
217
  });
197
218
  },
219
+ async edit(args) {
220
+ const session = await ensureSession();
221
+ const project = resolveProject(args.project);
222
+ if (args.rename !== undefined || args.areaOrder !== undefined) {
223
+ if (args.mock !== undefined) {
224
+ throw new Error('"rename" and "areaOrder" edit the project; edit the mock without them');
225
+ }
226
+ return post(`/api/projects/${enc(project)}`, { name: args.rename, areaOrder: args.areaOrder, session }, "PATCH");
227
+ }
228
+ if (typeof args.mock !== "string" || !args.mock) {
229
+ throw new Error('provide "mock", or "rename" / "areaOrder" to edit the project');
230
+ }
231
+ return post(`/api/mocks/${enc(args.mock)}`, { ...args, project, session }, "PATCH");
232
+ },
198
233
  export: (args) => json(`/api/mocks/${enc(args.mock)}/export${query({
199
234
  project: resolveProject(args.project),
200
235
  state: args.state,
@@ -10,6 +10,7 @@ export declare const fullSurfaceView: (surface: Surface, index: number) => {
10
10
  kind: "html";
11
11
  html: string;
12
12
  kits?: string[];
13
+ poster?: string;
13
14
  id?: string;
14
15
  } | {
15
16
  index: number;
@@ -61,6 +62,7 @@ export declare const hydratedSurfaceView: (surface: Surface, index: number) => {
61
62
  kind: "html";
62
63
  html: string;
63
64
  kits?: string[];
65
+ poster?: string;
64
66
  id?: string;
65
67
  } | {
66
68
  index: number;
@@ -108,6 +110,16 @@ export declare const hydratedSurfaceView: (surface: Surface, index: number) => {
108
110
  id?: string;
109
111
  } | Record<string, unknown>;
110
112
  export declare const historyMetaView: (version: PostVersion) => {
113
+ poster: string;
114
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
115
+ author?: string | undefined;
116
+ prompt?: string | undefined;
117
+ from?: number | undefined;
118
+ version: number;
119
+ title: string;
120
+ at: string;
121
+ } | {
122
+ poster?: undefined;
111
123
  surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
112
124
  author?: string | undefined;
113
125
  prompt?: string | undefined;
@@ -130,6 +142,16 @@ export interface EmbedView {
130
142
  }
131
143
  export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
132
144
  history?: ({
145
+ poster: string;
146
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
147
+ author?: string | undefined;
148
+ prompt?: string | undefined;
149
+ from?: number | undefined;
150
+ version: number;
151
+ title: string;
152
+ at: string;
153
+ } | {
154
+ poster?: undefined;
133
155
  surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
134
156
  author?: string | undefined;
135
157
  prompt?: string | undefined;
@@ -139,6 +161,17 @@ export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
139
161
  at: string;
140
162
  } | {
141
163
  hidden: true;
164
+ poster: string;
165
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
166
+ author?: string | undefined;
167
+ prompt?: string | undefined;
168
+ from?: number | undefined;
169
+ version: number;
170
+ title: string;
171
+ at: string;
172
+ } | {
173
+ hidden: true;
174
+ poster?: undefined;
142
175
  surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
143
176
  author?: string | undefined;
144
177
  prompt?: string | undefined;
@@ -153,6 +186,7 @@ export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
153
186
  kind: "html";
154
187
  html: string;
155
188
  kits?: string[];
189
+ poster?: string;
156
190
  id?: string;
157
191
  } | {
158
192
  index: number;
@@ -199,7 +233,7 @@ export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
199
233
  lineStart?: number;
200
234
  id?: string;
201
235
  } | Record<string, unknown>)[];
202
- acceptedVersion?: number | undefined;
236
+ inUseVersion?: number | undefined;
203
237
  starred?: boolean | undefined;
204
238
  forkedFrom?: import("./types.ts").ForkRef | undefined;
205
239
  publishedWith?: Embed[] | undefined;
@@ -209,7 +243,7 @@ export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
209
243
  })[] | undefined;
210
244
  embedsKey?: string | undefined;
211
245
  note?: string | undefined;
212
- slots?: import("./fills.ts").SlotInfo[] | undefined;
246
+ fills?: import("./fills.ts").SlotInfo[] | undefined;
213
247
  knobs?: {
214
248
  [x: string]: import("./types.ts").KnobConfig;
215
249
  } | undefined;
@@ -219,7 +253,7 @@ export declare const variantView: (post: Post, opts?: VariantViewOptions) => {
219
253
  postId: string;
220
254
  state: string | null;
221
255
  variant: string;
222
- status: import("./types.ts").PostStatus;
256
+ status: import("./types.ts").VariantStatus;
223
257
  version: number;
224
258
  title: string;
225
259
  sessionId: string;
@@ -236,46 +270,227 @@ export interface StateParts {
236
270
  parts: PartInfo[];
237
271
  }
238
272
  export declare function partsByState(mock: Mock, posts: Post[]): StateParts[];
273
+ export declare const placeOf: (mock: Pick<Mock, "area" | "source">) => {
274
+ area?: string;
275
+ source?: string;
276
+ };
239
277
  export declare const mockSummaryView: (mock: Mock, posts: Post[]) => {
240
278
  sessionId: string | null;
241
- resolvedAt: string | null;
279
+ closedAt: string | null;
242
280
  createdAt: string;
243
281
  updatedAt: string;
244
282
  thumbnail: {
283
+ poster?: string | undefined;
245
284
  postId: string;
246
285
  surface: number;
247
286
  version: number;
248
287
  } | null;
249
288
  drafted?: number | undefined;
289
+ stateCount: number;
290
+ variants: number;
291
+ open: number;
292
+ situations: Record<string, string[]>;
293
+ states: string[];
294
+ area?: string;
295
+ source?: string;
250
296
  id: string;
251
297
  project: string;
252
298
  slug: string;
253
299
  title: string;
254
300
  kind: import("./types.ts").MockKind;
255
- states: string[];
301
+ } | {
302
+ sessionId: string | null;
303
+ closedAt: string | null;
304
+ createdAt: string;
305
+ updatedAt: string;
306
+ thumbnail: {
307
+ poster?: string | undefined;
308
+ postId: string;
309
+ surface: number;
310
+ version: number;
311
+ } | null;
312
+ drafted?: number | undefined;
256
313
  stateCount: number;
257
314
  variants: number;
258
315
  open: number;
316
+ situations?: undefined;
317
+ states: string[];
318
+ area?: string;
319
+ source?: string;
320
+ id: string;
321
+ project: string;
322
+ slug: string;
323
+ title: string;
324
+ kind: import("./types.ts").MockKind;
259
325
  };
260
326
  export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantViewOptions & {
261
327
  settled?: Record<string, KnobValue>;
262
328
  }) => {
329
+ asks: import("./types.ts").Ask[];
330
+ open: number;
331
+ knobs: import("./types.ts").Knobs;
332
+ widths: number[];
333
+ sessionId: string | null;
334
+ closedAt: string | null;
335
+ createdAt: string;
336
+ updatedAt: string;
337
+ variants: {
338
+ history?: ({
339
+ poster: string;
340
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
341
+ author?: string | undefined;
342
+ prompt?: string | undefined;
343
+ from?: number | undefined;
344
+ version: number;
345
+ title: string;
346
+ at: string;
347
+ } | {
348
+ poster?: undefined;
349
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
350
+ author?: string | undefined;
351
+ prompt?: string | undefined;
352
+ from?: number | undefined;
353
+ version: number;
354
+ title: string;
355
+ at: string;
356
+ } | {
357
+ hidden: true;
358
+ poster: string;
359
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
360
+ author?: string | undefined;
361
+ prompt?: string | undefined;
362
+ from?: number | undefined;
363
+ version: number;
364
+ title: string;
365
+ at: string;
366
+ } | {
367
+ hidden: true;
368
+ poster?: undefined;
369
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
370
+ author?: string | undefined;
371
+ prompt?: string | undefined;
372
+ from?: number | undefined;
373
+ version: number;
374
+ title: string;
375
+ at: string;
376
+ })[] | undefined;
377
+ parts: string[];
378
+ surfaces: ({
379
+ index: number;
380
+ kind: "html";
381
+ html: string;
382
+ kits?: string[];
383
+ poster?: string;
384
+ id?: string;
385
+ } | {
386
+ index: number;
387
+ kind: "diff";
388
+ patch?: string;
389
+ files?: import("./types.ts").DiffFile[];
390
+ layout?: "unified" | "split";
391
+ id?: string;
392
+ } | {
393
+ index: number;
394
+ kind: "image";
395
+ assetId: string;
396
+ alt?: string;
397
+ caption?: string;
398
+ id?: string;
399
+ } | {
400
+ index: number;
401
+ kind: "markdown";
402
+ markdown: string;
403
+ id?: string;
404
+ } | {
405
+ index: number;
406
+ kind: "terminal";
407
+ text: string;
408
+ cols?: number;
409
+ title?: string;
410
+ id?: string;
411
+ } | {
412
+ index: number;
413
+ kind: "mermaid";
414
+ mermaid: string;
415
+ id?: string;
416
+ } | {
417
+ index: number;
418
+ kind: "json";
419
+ data: unknown;
420
+ id?: string;
421
+ } | {
422
+ index: number;
423
+ kind: "code";
424
+ code: string;
425
+ language?: string;
426
+ title?: string;
427
+ lineStart?: number;
428
+ id?: string;
429
+ } | Record<string, unknown>)[];
430
+ inUseVersion?: number | undefined;
431
+ starred?: boolean | undefined;
432
+ forkedFrom?: import("./types.ts").ForkRef | undefined;
433
+ publishedWith?: Embed[] | undefined;
434
+ embeds?: (Embed & {
435
+ latest: number;
436
+ versions: number[];
437
+ })[] | undefined;
438
+ embedsKey?: string | undefined;
439
+ note?: string | undefined;
440
+ fills?: import("./fills.ts").SlotInfo[] | undefined;
441
+ knobs?: {
442
+ [x: string]: import("./types.ts").KnobConfig;
443
+ } | undefined;
444
+ author?: string | undefined;
445
+ prompt?: string | undefined;
446
+ from?: number | undefined;
447
+ postId: string;
448
+ state: string | null;
449
+ variant: string;
450
+ status: import("./types.ts").VariantStatus;
451
+ version: number;
452
+ title: string;
453
+ sessionId: string;
454
+ createdAt: string;
455
+ updatedAt: string;
456
+ }[];
457
+ inUse: {
458
+ state: string | null;
459
+ variant: string;
460
+ version: number;
461
+ }[];
462
+ parts: StateParts[];
463
+ settled: Record<string, KnobValue>;
464
+ situations: Record<string, string[]>;
465
+ states: string[];
466
+ area?: string;
467
+ source?: string;
263
468
  id: string;
264
469
  project: string;
265
470
  slug: string;
266
471
  title: string;
267
472
  kind: import("./types.ts").MockKind;
268
- states: string[];
473
+ } | {
269
474
  asks: import("./types.ts").Ask[];
270
475
  open: number;
271
476
  knobs: import("./types.ts").Knobs;
272
477
  widths: number[];
273
478
  sessionId: string | null;
274
- resolvedAt: string | null;
479
+ closedAt: string | null;
275
480
  createdAt: string;
276
481
  updatedAt: string;
277
482
  variants: {
278
483
  history?: ({
484
+ poster: string;
485
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
486
+ author?: string | undefined;
487
+ prompt?: string | undefined;
488
+ from?: number | undefined;
489
+ version: number;
490
+ title: string;
491
+ at: string;
492
+ } | {
493
+ poster?: undefined;
279
494
  surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
280
495
  author?: string | undefined;
281
496
  prompt?: string | undefined;
@@ -285,6 +500,17 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
285
500
  at: string;
286
501
  } | {
287
502
  hidden: true;
503
+ poster: string;
504
+ surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
505
+ author?: string | undefined;
506
+ prompt?: string | undefined;
507
+ from?: number | undefined;
508
+ version: number;
509
+ title: string;
510
+ at: string;
511
+ } | {
512
+ hidden: true;
513
+ poster?: undefined;
288
514
  surfaceKinds: ("html" | "diff" | "image" | "markdown" | "terminal" | "mermaid" | "json" | "code")[];
289
515
  author?: string | undefined;
290
516
  prompt?: string | undefined;
@@ -299,6 +525,7 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
299
525
  kind: "html";
300
526
  html: string;
301
527
  kits?: string[];
528
+ poster?: string;
302
529
  id?: string;
303
530
  } | {
304
531
  index: number;
@@ -345,7 +572,7 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
345
572
  lineStart?: number;
346
573
  id?: string;
347
574
  } | Record<string, unknown>)[];
348
- acceptedVersion?: number | undefined;
575
+ inUseVersion?: number | undefined;
349
576
  starred?: boolean | undefined;
350
577
  forkedFrom?: import("./types.ts").ForkRef | undefined;
351
578
  publishedWith?: Embed[] | undefined;
@@ -355,7 +582,7 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
355
582
  })[] | undefined;
356
583
  embedsKey?: string | undefined;
357
584
  note?: string | undefined;
358
- slots?: import("./fills.ts").SlotInfo[] | undefined;
585
+ fills?: import("./fills.ts").SlotInfo[] | undefined;
359
586
  knobs?: {
360
587
  [x: string]: import("./types.ts").KnobConfig;
361
588
  } | undefined;
@@ -365,7 +592,7 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
365
592
  postId: string;
366
593
  state: string | null;
367
594
  variant: string;
368
- status: import("./types.ts").PostStatus;
595
+ status: import("./types.ts").VariantStatus;
369
596
  version: number;
370
597
  title: string;
371
598
  sessionId: string;
@@ -379,6 +606,15 @@ export declare const mockDetailView: (mock: Mock, posts: Post[], opts?: VariantV
379
606
  }[];
380
607
  parts: StateParts[];
381
608
  settled: Record<string, KnobValue>;
609
+ situations?: undefined;
610
+ states: string[];
611
+ area?: string;
612
+ source?: string;
613
+ id: string;
614
+ project: string;
615
+ slug: string;
616
+ title: string;
617
+ kind: import("./types.ts").MockKind;
382
618
  };
383
619
  export declare const sessionRowView: (session: Session, postCount: number) => {
384
620
  postCount: number;
@@ -395,39 +631,88 @@ export declare const sessionRowView: (session: Session, postCount: number) => {
395
631
  };
396
632
  export declare const treeNodeView: (mock: Mock, posts: Post[], extra: {
397
633
  settled: Record<string, KnobValue>;
398
- uses: string[];
399
- embeds: Map<string, EmbedView>;
634
+ embeds: string[];
635
+ embedViews: Map<string, EmbedView>;
400
636
  }) => {
401
- id: string;
402
- slug: string;
403
- title: string;
404
- kind: import("./types.ts").MockKind;
405
637
  open: number;
406
638
  states: string[] | null[];
407
639
  widths: number[];
408
640
  createdAt: string;
409
641
  updatedAt: string;
410
- resolvedAt: string | null;
642
+ closedAt: string | null;
411
643
  settled: Record<string, KnobValue>;
412
- uses: string[];
413
- usedIn: string[];
644
+ embeds: string[];
645
+ embeddedIn: string[];
414
646
  inUse: {
415
647
  state: string | null;
416
648
  variant: string;
417
649
  version: number;
418
650
  }[];
419
- variants: {
651
+ variants: ({
420
652
  embedsKey?: string | undefined;
421
- acceptedVersion?: number | undefined;
653
+ inUseVersion?: number | undefined;
422
654
  starred?: boolean | undefined;
423
655
  forkedFrom?: import("./types.ts").ForkRef | undefined;
424
656
  note?: string | undefined;
657
+ inUsePoster?: undefined;
658
+ poster: string;
425
659
  postId: string;
426
660
  state: string | null;
427
661
  variant: string;
428
- status: import("./types.ts").PostStatus;
662
+ status: import("./types.ts").VariantStatus;
429
663
  version: number;
430
664
  updatedAt: string;
431
665
  surface: number;
432
- }[];
666
+ } | {
667
+ embedsKey?: string | undefined;
668
+ inUseVersion?: number | undefined;
669
+ starred?: boolean | undefined;
670
+ forkedFrom?: import("./types.ts").ForkRef | undefined;
671
+ note?: string | undefined;
672
+ inUsePoster: string;
673
+ poster: string;
674
+ postId: string;
675
+ state: string | null;
676
+ variant: string;
677
+ status: import("./types.ts").VariantStatus;
678
+ version: number;
679
+ updatedAt: string;
680
+ surface: number;
681
+ } | {
682
+ embedsKey?: string | undefined;
683
+ inUseVersion?: number | undefined;
684
+ starred?: boolean | undefined;
685
+ forkedFrom?: import("./types.ts").ForkRef | undefined;
686
+ note?: string | undefined;
687
+ inUsePoster?: undefined;
688
+ poster?: undefined;
689
+ postId: string;
690
+ state: string | null;
691
+ variant: string;
692
+ status: import("./types.ts").VariantStatus;
693
+ version: number;
694
+ updatedAt: string;
695
+ surface: number;
696
+ } | {
697
+ embedsKey?: string | undefined;
698
+ inUseVersion?: number | undefined;
699
+ starred?: boolean | undefined;
700
+ forkedFrom?: import("./types.ts").ForkRef | undefined;
701
+ note?: string | undefined;
702
+ inUsePoster: string;
703
+ poster?: undefined;
704
+ postId: string;
705
+ state: string | null;
706
+ variant: string;
707
+ status: import("./types.ts").VariantStatus;
708
+ version: number;
709
+ updatedAt: string;
710
+ surface: number;
711
+ })[];
712
+ area?: string;
713
+ source?: string;
714
+ id: string;
715
+ slug: string;
716
+ title: string;
717
+ kind: import("./types.ts").MockKind;
433
718
  };