mockpit 2.0.0 → 3.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 (73) hide show
  1. package/README.md +60 -212
  2. package/bin/demoData.js +2 -2
  3. package/bin/initDesign.js +6 -6
  4. package/bin/mockpit.js +407 -187
  5. package/bin/poster.js +377 -0
  6. package/dist/mcp/server.js +80 -24
  7. package/dist/server/answerAdditions.d.ts +7 -0
  8. package/dist/server/answerAdditions.js +76 -0
  9. package/dist/server/apiViews.d.ts +289 -52
  10. package/dist/server/apiViews.js +189 -81
  11. package/dist/server/app.d.ts +7 -2
  12. package/dist/server/app.js +2845 -832
  13. package/dist/server/appIcon.js +15 -5
  14. package/dist/server/appIconPng.js +3 -3
  15. package/dist/server/askNudges.js +1 -1
  16. package/dist/server/cdnInline.d.ts +8 -0
  17. package/dist/server/cdnInline.js +638 -0
  18. package/dist/server/codeWorker.js +1 -1
  19. package/dist/server/decisionList.d.ts +45 -0
  20. package/dist/server/decisionList.js +302 -0
  21. package/dist/server/decisions.d.ts +4 -4
  22. package/dist/server/decisions.js +9 -9
  23. package/dist/server/designGuide.d.ts +5 -5
  24. package/dist/server/designGuide.js +128 -67
  25. package/dist/server/embeds.d.ts +3 -1
  26. package/dist/server/embeds.js +31 -6
  27. package/dist/server/eventLog.d.ts +2 -2
  28. package/dist/server/eventLog.js +11 -11
  29. package/dist/server/events.d.ts +9 -6
  30. package/dist/server/feedbackBatch.d.ts +35 -13
  31. package/dist/server/feedbackBatch.js +111 -47
  32. package/dist/server/fills.d.ts +4 -0
  33. package/dist/server/fills.js +55 -1
  34. package/dist/server/handoff.d.ts +4 -1
  35. package/dist/server/handoff.js +8 -2
  36. package/dist/server/icons.js +1 -1
  37. package/dist/server/index.js +39 -10
  38. package/dist/server/jump.d.ts +21 -0
  39. package/dist/server/jump.js +175 -0
  40. package/dist/server/knobs.d.ts +3 -3
  41. package/dist/server/knobs.js +6 -6
  42. package/dist/server/mcpHttp.d.ts +5 -1
  43. package/dist/server/mcpHttp.js +16 -11
  44. package/dist/server/mcpSpec.js +118 -46
  45. package/dist/server/parts.js +9 -1
  46. package/dist/server/run.d.ts +1 -1
  47. package/dist/server/run.js +25 -16
  48. package/dist/server/runApi.d.ts +3 -3
  49. package/dist/server/runApi.js +25 -19
  50. package/dist/server/sqlStore.d.ts +112 -96
  51. package/dist/server/sqlStore.js +906 -172
  52. package/dist/server/standings.d.ts +25 -0
  53. package/dist/server/standings.js +113 -0
  54. package/dist/server/surfacePage.d.ts +6 -9
  55. package/dist/server/surfacePage.js +361 -86
  56. package/dist/server/types.d.ts +226 -72
  57. package/dist/server/types.js +73 -78
  58. package/extensions/mockpit.js +89 -72
  59. package/guide/AGENT_SETUP.md +13 -1
  60. package/guide/packs/design-craft.md +2 -3
  61. package/guide/topics/asks.md +106 -62
  62. package/guide/topics/feedback.md +126 -119
  63. package/guide/topics/html.md +17 -24
  64. package/guide/topics/http.md +41 -41
  65. package/guide/topics/knobs.md +7 -10
  66. package/guide/topics/scripts.md +22 -33
  67. package/guide/topics/surfaces.md +39 -48
  68. package/opencode/mockpit.js +120 -0
  69. package/opencode/package.json +8 -0
  70. package/package.json +4 -3
  71. package/skills/launch-video/SKILL.md +11 -11
  72. package/skills/mockpit/SKILL.md +26 -22
  73. package/viewer/dist/index.html +9 -9
@@ -1,8 +1,9 @@
1
1
  // Response shapes shared by every tier (REST, both MCP transports, the CLI), so
2
- // one mock reads the same however an agent asks for it.
2
+ // one design reads the same however an agent asks for it.
3
3
  import { slotKnobs, slotsInSurfaces } from "./fills.js";
4
4
  import { mergeParts, partsInSurfaces } from "./parts.js";
5
- import { draftedCount, inUseVersion, isSandboxedSurfaceKind, isLive, momentsOf, openCount, SURFACE_CONTENT_FIELDS, variantStatus, } from "./types.js";
5
+ import { isKeptVariant, keptVariants } from "./standings.js";
6
+ import { changedTo, currentVersion, draftedCount, inUseVersion, isPlanned, isSandboxedSurfaceKind, isLive, openCount, recommendedVariant, SURFACE_CONTENT_FIELDS, variantStatus, } from "./types.js";
6
7
  export const surfaceRef = (surface, index) => ({
7
8
  id: surface.id,
8
9
  kind: surface.kind,
@@ -25,11 +26,34 @@ export const hydratedSurfaceView = (surface, index) => {
25
26
  delete view[field];
26
27
  return view;
27
28
  };
28
- // The still overviews show for a version: its html page's poster.
29
- const pagePoster = (surfaces) => {
30
- const page = surfaces.find((s) => s.kind === "html");
31
- return page?.kind === "html" ? page.poster : undefined;
29
+ // A still mockpit took shows the page in the mode it was taken in. In the other mode it
30
+ // would be the one picture in the wrong colours among live pages, so it is left out and the
31
+ // page runs as it did before posters. Applied to posts before any view reads them, so every
32
+ // view agrees. Posts come from the store's cache: copied where changed, never written to.
33
+ const otherMode = (s, mode) => {
34
+ const taken = s.posterMode;
35
+ return s.kind === "html" && taken !== undefined && taken !== mode;
32
36
  };
37
+ const surfacesFor = (surfaces, mode) => surfaces.some((s) => otherMode(s, mode))
38
+ ? surfaces.map((s) => {
39
+ if (!otherMode(s, mode))
40
+ return s;
41
+ const { poster: _poster, posterMode: _mode, ...rest } = s;
42
+ return rest;
43
+ })
44
+ : surfaces;
45
+ export const postersFor = (posts, mode) => posts.map((p) => {
46
+ const surfaces = surfacesFor(p.surfaces, mode);
47
+ const history = p.history.map((h) => {
48
+ const own = surfacesFor(h.surfaces, mode);
49
+ return own === h.surfaces ? h : { ...h, surfaces: own };
50
+ });
51
+ return surfaces === p.surfaces && history.every((h, i) => h === p.history[i])
52
+ ? p
53
+ : { ...p, surfaces, history };
54
+ });
55
+ // The still overviews show for a version: its html page's poster.
56
+ const pagePoster = (surfaces) => surfaces.find((s) => s.kind === "html")?.poster;
33
57
  const posterOf = (surfaces) => {
34
58
  const poster = pagePoster(surfaces);
35
59
  return poster ? { poster } : {};
@@ -46,6 +70,28 @@ const inUsePoster = (p) => {
46
70
  const poster = posterAt(p, p.acceptedVersion);
47
71
  return poster ? { inUsePoster: poster } : {};
48
72
  };
73
+ // The version Home shows when nothing is in use and the newest was hidden.
74
+ const coverVersion = (p) => {
75
+ const at = currentVersion(p);
76
+ if (p.status === "accepted" || at === p.version)
77
+ return {};
78
+ const poster = posterAt(p, at);
79
+ return { coverVersion: at, ...(poster ? { coverPoster: poster } : {}) };
80
+ };
81
+ // A page that draws on a canvas may hold a WebGL context, of which a browser
82
+ // keeps about 16 and drops the oldest past that, so overviews ration these
83
+ // frames and no others. Three.js and the like make their canvas from script.
84
+ // Asked once per version: a read lists every version, with bodies up to 1 MB.
85
+ const CANVAS_PAGE = /<canvas[\s>]|webgl|three(?:\.module|\.min|\.js|@)|['"]three['"]|pixi|babylon/i;
86
+ const canvasPages = new WeakMap();
87
+ const drawsOnCanvas = (surfaces) => {
88
+ let hit = canvasPages.get(surfaces);
89
+ if (hit === undefined) {
90
+ hit = surfaces.some((s) => s.kind === "html" && CANVAS_PAGE.test(s.html));
91
+ canvasPages.set(surfaces, hit);
92
+ }
93
+ return hit;
94
+ };
49
95
  // One past version without its bodies: enough to list versions or pick one to
50
96
  // fetch, at a bounded cost.
51
97
  export const historyMetaView = (version) => ({
@@ -55,8 +101,10 @@ export const historyMetaView = (version) => ({
55
101
  ...(version.from === undefined ? {} : { from: version.from }),
56
102
  ...(version.prompt ? { prompt: version.prompt } : {}),
57
103
  ...(version.author === undefined ? {} : { author: version.author }),
104
+ ...(version.amendedAt ? { amendedAt: version.amendedAt } : {}),
58
105
  surfaceKinds: version.surfaces.map((s) => s.kind),
59
106
  ...posterOf(version.surfaces),
107
+ ...(drawsOnCanvas(version.surfaces) ? { canvas: true } : {}),
60
108
  });
61
109
  export const variantView = (post, opts = {}) => ({
62
110
  postId: post.id,
@@ -71,12 +119,15 @@ export const variantView = (post, opts = {}) => ({
71
119
  ...(post.from === undefined ? {} : { from: post.from }),
72
120
  ...(post.prompt ? { prompt: post.prompt } : {}),
73
121
  ...(post.author === undefined ? {} : { author: post.author }),
122
+ ...(post.amendedAt ? { amendedAt: post.amendedAt } : {}),
123
+ // Frame URLs carry it (`w`): an amended version keeps its number.
124
+ ...(post.rewrites ? { rewrites: post.rewrites } : {}),
74
125
  // A part with fills is a select knob on its part (fills.ts); declared knobs win.
75
126
  ...(slotsInSurfaces(post.surfaces).length || post.knobs
76
127
  ? { knobs: { ...slotKnobs(slotsInSurfaces(post.surfaces)), ...post.knobs } }
77
128
  : {}),
78
129
  ...(slotsInSurfaces(post.surfaces).length ? { fills: slotsInSurfaces(post.surfaces) } : {}),
79
- ...(post.note ? { note: post.note } : {}),
130
+ ...(post.description ? { description: post.description } : {}),
80
131
  // Embedded components as they render now (server/embeds.ts); `publishedWith`
81
132
  // is what this version rendered with when it was published.
82
133
  ...(opts.embeds?.get(post.id)
@@ -84,8 +135,11 @@ export const variantView = (post, opts = {}) => ({
84
135
  : {}),
85
136
  ...(post.embeds.length ? { publishedWith: post.embeds } : {}),
86
137
  ...(post.forkedFrom ? { forkedFrom: post.forkedFrom } : {}),
87
- ...(post.starred ? { starred: true } : {}),
138
+ ...(post.copiedFrom ? { copiedFrom: post.copiedFrom } : {}),
139
+ ...(opts.kept && isKeptVariant(opts.kept, post) ? { kept: true } : {}),
88
140
  ...(post.acceptedVersion === undefined ? {} : { inUseVersion: post.acceptedVersion }),
141
+ ...(changedTo(post) === undefined ? {} : { changedTo: changedTo(post) }),
142
+ ...(post.archiveReason ? { archiveReason: post.archiveReason } : {}),
89
143
  // The part names this variant's own markup marks, so the viewer can tell
90
144
  // which variants render a part (Borrow) without the html bodies.
91
145
  parts: partsInSurfaces(post.surfaces).map((p) => p.name),
@@ -101,97 +155,124 @@ export const variantView = (post, opts = {}) => ({
101
155
  ...(post.from === undefined ? {} : { from: post.from }),
102
156
  ...(post.prompt === undefined ? {} : { prompt: post.prompt }),
103
157
  ...(post.author === undefined ? {} : { author: post.author }),
158
+ ...(post.amendedAt ? { amendedAt: post.amendedAt } : {}),
104
159
  }),
105
160
  ...[...post.history].sort((a, b) => b.version - a.version).map(historyMetaView),
106
161
  ].map((row) => post.hiddenVersions?.includes(row.version) ? { ...row, hidden: true } : row),
107
162
  }
108
163
  : {}),
109
164
  });
110
- const stateOrder = (mock) => (mock.states.length ? mock.states : [null]);
111
- // What the user put in use, per state, in the mock's order; a state with
165
+ const stateOrder = (design) => (design.states.length ? design.states : [null]);
166
+ // What the user put in use, per state, in the design's order; a state with
112
167
  // nothing accepted is absent. Export and embeds resolve to exactly these.
113
- export const inUseByState = (mock, posts) => stateOrder(mock).flatMap((state) => {
168
+ export const inUseByState = (design, posts) => stateOrder(design).flatMap((state) => {
114
169
  const p = posts.find((x) => x.state === state && x.status === "accepted");
115
170
  return p ? [{ state, variant: p.variant, version: inUseVersion(p) }] : [];
116
171
  });
117
172
  // The parts the agent marked, per state, across the variants still in play.
118
- export function partsByState(mock, posts) {
119
- return stateOrder(mock).map((state) => ({
173
+ export function partsByState(design, posts) {
174
+ return stateOrder(design).map((state) => ({
120
175
  state,
121
176
  parts: mergeParts(posts
122
177
  .filter((p) => p.state === state && isLive(p.status))
123
178
  .map((p) => partsInSurfaces(p.surfaces))),
124
179
  }));
125
180
  }
126
- // Where a mock sits in the product and the code that implements it, only once
181
+ // Where a design sits in the product and the code that implements it, only once
127
182
  // declared, so the views of a project that names neither cost nothing.
128
- export const placeOf = (mock) => ({
129
- ...(mock.area ? { area: mock.area } : {}),
130
- ...(mock.source ? { source: mock.source } : {}),
183
+ export const placeOf = (design) => ({
184
+ ...(design.area ? { area: design.area } : {}),
185
+ ...(design.source ? { source: design.source } : {}),
131
186
  });
132
- // What Home shows for a mock: the first state's chosen (else first) variant.
133
- function thumbnail(mock, posts) {
134
- const first = stateOrder(mock)[0];
187
+ // What a design's first state looks like in a list: what's in use, else what the agent
188
+ // recommends, else its first. Same rule as viewer/src/logic.ts screenPicture.
189
+ function thumbnail(design, posts) {
190
+ const first = stateOrder(design)[0];
135
191
  const inState = posts.filter((p) => p.state === first);
192
+ const recommended = recommendedVariant(design.asks, first);
136
193
  const pick = inState.find((p) => p.status === "accepted") ??
194
+ inState.find((p) => p.variant === recommended && isLive(p.status)) ??
137
195
  inState.find((p) => p.status === "open") ??
138
196
  inState[0] ??
139
197
  posts[0];
140
198
  if (!pick)
141
199
  return null;
142
200
  const surface = pick.surfaces.findIndex((s) => isSandboxedSurfaceKind(s.kind));
143
- const version = inUseVersion(pick);
201
+ const version = currentVersion(pick);
144
202
  const poster = posterAt(pick, version);
145
- return { postId: pick.id, surface: Math.max(surface, 0), version, ...(poster ? { poster } : {}) };
203
+ return {
204
+ postId: pick.id,
205
+ surface: Math.max(surface, 0),
206
+ version,
207
+ ...(poster ? { poster } : {}),
208
+ ...(pick.rewrites ? { rewrites: pick.rewrites } : {}),
209
+ };
146
210
  }
147
- // A mock's situations, only once it has any, so the views of mocks without
148
- // them are unchanged.
149
- const situationsOf = (mock) => Object.keys(mock.situations).length ? { situations: mock.situations } : {};
150
- export const mockSummaryView = (mock, posts) => {
151
- const drafted = draftedCount(mock, posts);
211
+ // Only a plan says so, so the views of everything drawn are unchanged.
212
+ const plannedOf = (design, variants) => isPlanned(design, variants) ? { planned: true } : {};
213
+ // Anything the user has yet to send. A stored draft can be an emptied one, which
214
+ // waits on nobody.
215
+ export const draftHolds = (draft) => !!draft &&
216
+ (draft.comments.length > 0 ||
217
+ Object.values(draft.answers).some((a) => !Array.isArray(a) || a.length > 0) ||
218
+ [draft.borrowed, draft.tuned, draft.others ?? {}, draft.askComments ?? {}].some((rec) => Object.keys(rec).length > 0));
219
+ export const designSummaryView = (design, posts) => {
220
+ const drafted = draftedCount(design);
152
221
  return {
153
- id: mock.id,
154
- project: mock.project,
155
- slug: mock.slug,
156
- title: mock.title,
157
- kind: mock.kind,
158
- ...placeOf(mock),
159
- states: mock.states,
160
- ...situationsOf(mock),
161
- stateCount: Math.max(momentsOf(mock.states, mock.situations).length, 1),
222
+ id: design.id,
223
+ project: design.project,
224
+ slug: design.slug,
225
+ title: design.title,
226
+ kind: design.kind,
227
+ ...placeOf(design),
228
+ ...plannedOf(design, posts.length),
229
+ // Text comes with a read of the design; a list only says there is some to read.
230
+ ...(design.notes ? { hasNotes: true } : {}),
231
+ states: design.states,
232
+ stateCount: Math.max(design.states.length, 1),
162
233
  variants: posts.length,
163
- open: openCount(mock, posts),
234
+ open: openCount(design),
164
235
  // Only once the user has started one, so a list with no drafts costs nothing.
165
236
  ...(drafted === null ? {} : { drafted }),
166
- sessionId: mock.sessionId,
167
- closedAt: mock.closedAt,
168
- createdAt: mock.createdAt,
169
- updatedAt: mock.updatedAt,
170
- thumbnail: thumbnail(mock, posts),
237
+ sessionId: design.sessionId,
238
+ archivedAt: design.archivedAt,
239
+ createdAt: design.createdAt,
240
+ updatedAt: design.updatedAt,
241
+ thumbnail: thumbnail(design, posts),
171
242
  };
172
243
  };
173
- // One mock as anyone outside the viewer's own draft sees it: the draft is the
244
+ // One design as anyone outside the viewer's own draft sees it: the draft is the
174
245
  // user's unsent work and never leaves through this view.
175
- export const mockDetailView = (mock, posts, opts = {}) => ({
176
- id: mock.id,
177
- project: mock.project,
178
- slug: mock.slug,
179
- title: mock.title,
180
- kind: mock.kind,
181
- ...placeOf(mock),
182
- states: mock.states,
183
- ...situationsOf(mock),
184
- asks: mock.asks,
185
- open: openCount(mock, posts),
186
- knobs: mock.knobs,
187
- widths: mock.widths,
188
- sessionId: mock.sessionId,
189
- closedAt: mock.closedAt,
190
- createdAt: mock.createdAt,
191
- updatedAt: mock.updatedAt,
192
- variants: posts.map((p) => variantView(p, opts)),
193
- inUse: inUseByState(mock, posts),
194
- parts: partsByState(mock, posts),
246
+ export const designDetailView = (design, posts, opts = {}) => ({
247
+ id: design.id,
248
+ project: design.project,
249
+ slug: design.slug,
250
+ title: design.title,
251
+ kind: design.kind,
252
+ ...placeOf(design),
253
+ ...(design.shortlist ? { shortlist: true } : {}),
254
+ // No agent has written to this shortlist yet: who its replies reach for now.
255
+ ...(opts.repliesGoTo ? { repliesGoTo: opts.repliesGoTo } : {}),
256
+ ...plannedOf(design, posts.length),
257
+ states: design.states,
258
+ ...(design.notes ? { notes: design.notes } : {}),
259
+ ...(Object.keys(design.stateOutlines).length ? { stateOutlines: design.stateOutlines } : {}),
260
+ ...(design.answerAdditions.length ? { answerAdditions: design.answerAdditions } : {}),
261
+ asks: design.asks,
262
+ // By question id: the answers the user kept for later and hid, with why.
263
+ ...(Object.keys(design.standings).length ? { standings: design.standings } : {}),
264
+ ...(design.sets.length ? { sets: design.sets } : {}),
265
+ open: openCount(design),
266
+ knobs: design.knobs,
267
+ widths: design.widths,
268
+ sessionId: design.sessionId,
269
+ archivedAt: design.archivedAt,
270
+ ...(design.archiveReason ? { archiveReason: design.archiveReason } : {}),
271
+ createdAt: design.createdAt,
272
+ updatedAt: design.updatedAt,
273
+ variants: ((kept) => posts.map((p) => variantView(p, { ...opts, kept })))(keptVariants(design, posts)),
274
+ inUse: inUseByState(design, posts),
275
+ parts: partsByState(design, posts),
195
276
  // Every knob value the user has sent (answers' sets and tuning, later replies
196
277
  // winning), never drafts. Later questions render on top of it.
197
278
  settled: opts.settled ?? {},
@@ -200,26 +281,50 @@ export const sessionRowView = (session, postCount) => ({
200
281
  ...session,
201
282
  postCount,
202
283
  });
203
- // One mock as a node of the project tree (GET /api/projects/:name/tree): its
204
- // variants per state with status and lineage, and the mocks it embeds (`embeds`);
284
+ // One design as a node of the project tree (GET /api/projects/:name/tree): its
285
+ // variants per state with status and lineage, and the designs it embeds (`embeds`);
205
286
  // `embeddedIn` is filled in once every node is known.
206
- export const treeNodeView = (mock, posts, extra) => ({
207
- id: mock.id,
208
- slug: mock.slug,
209
- title: mock.title,
210
- kind: mock.kind,
211
- ...placeOf(mock),
212
- open: openCount(mock, posts),
213
- // Home shows a mock's states, never their situations.
214
- states: mock.states.length ? momentsOf(mock.states, mock.situations) : [null],
215
- widths: mock.widths,
216
- createdAt: mock.createdAt,
217
- updatedAt: mock.updatedAt,
218
- closedAt: mock.closedAt,
287
+ // When it left the shelf: archived by hand, or with the last of its variants archived.
288
+ // Designs archived before the date was kept fall back on the design's last change.
289
+ function leftOf(design, posts) {
290
+ if (design.archivedAt)
291
+ return { leftAt: design.archivedAt };
292
+ if (!posts.length || posts.some((p) => isLive(p.status)))
293
+ return {};
294
+ const last = posts.reduce((t, p) => (p.archivedAt && p.archivedAt > t ? p.archivedAt : t), "");
295
+ return { leftAt: last || design.updatedAt };
296
+ }
297
+ export const treeNodeView = (design, posts, extra) => ({
298
+ id: design.id,
299
+ slug: design.slug,
300
+ title: design.title,
301
+ kind: design.kind,
302
+ ...placeOf(design),
303
+ ...(design.shortlist ? { shortlist: true } : {}),
304
+ ...plannedOf(design, posts.length),
305
+ open: openCount(design),
306
+ // Any question ever asked, answered or not: it tells an idea from a document.
307
+ ...(design.asks.length ? { asked: design.asks.length } : {}),
308
+ // Later than every variant: the user has spoken and it is the agent's turn.
309
+ ...(extra.lastReplyAt ? { lastReplyAt: extra.lastReplyAt } : {}),
310
+ ...(extra.lastSend ? { lastSend: extra.lastSend } : {}),
311
+ ...(extra.drafting ? { drafting: true } : {}),
312
+ states: stateOrder(design),
313
+ widths: design.widths,
314
+ createdAt: design.createdAt,
315
+ updatedAt: design.updatedAt,
316
+ archivedAt: design.archivedAt,
317
+ ...leftOf(design, posts),
318
+ ...(design.archiveReason ? { archiveReason: design.archiveReason } : {}),
219
319
  settled: extra.settled,
220
320
  embeds: extra.embeds,
221
321
  embeddedIn: [],
222
- inUse: inUseByState(mock, posts),
322
+ inUse: inUseByState(design, posts),
323
+ // What the agent recommends where nothing is in use: a cover shows it.
324
+ recommended: stateOrder(design).flatMap((state) => {
325
+ const variant = recommendedVariant(design.asks, state);
326
+ return variant ? [{ state, variant }] : [];
327
+ }),
223
328
  variants: posts.map((p) => ({
224
329
  postId: p.id,
225
330
  state: p.state,
@@ -227,13 +332,16 @@ export const treeNodeView = (mock, posts, extra) => ({
227
332
  status: variantStatus(p.status),
228
333
  version: p.version,
229
334
  updatedAt: p.updatedAt,
335
+ ...(p.rewrites ? { rewrites: p.rewrites } : {}),
230
336
  surface: p.surfaces.findIndex((x) => isSandboxedSurfaceKind(x.kind)),
231
337
  ...posterOf(p.surfaces),
232
338
  ...inUsePoster(p),
233
- ...(p.note ? { note: p.note } : {}),
339
+ ...coverVersion(p),
340
+ ...(p.description && !extra.noDescriptions ? { description: p.description } : {}),
234
341
  ...(p.forkedFrom ? { forkedFrom: p.forkedFrom } : {}),
235
- ...(p.starred ? { starred: true } : {}),
236
342
  ...(p.acceptedVersion === undefined ? {} : { inUseVersion: p.acceptedVersion }),
343
+ ...(changedTo(p) === undefined ? {} : { changedTo: changedTo(p) }),
344
+ ...(p.archiveReason ? { archiveReason: p.archiveReason } : {}),
237
345
  ...(extra.embedViews.get(p.id) ? { embedsKey: extra.embedViews.get(p.id).key } : {}),
238
346
  })),
239
347
  });
@@ -30,6 +30,10 @@ export interface AppOptions {
30
30
  maxHoldConnections?: number;
31
31
  executor?: Executor;
32
32
  runLimits?: Partial<RunLimits>;
33
+ networkHosts?: () => {
34
+ localOnly: boolean;
35
+ hosts: string[];
36
+ };
33
37
  log?: LogSink;
34
38
  }
35
39
  export interface LatestRelease {
@@ -38,12 +42,13 @@ export interface LatestRelease {
38
42
  }
39
43
  export interface CommentWait {
40
44
  sessionId?: string;
41
- mockId?: string;
45
+ designId?: string;
42
46
  postId?: string;
43
47
  author?: string;
44
48
  afterSeq?: number;
45
49
  waitSeconds: number;
46
50
  agent?: boolean;
51
+ peek?: boolean;
47
52
  }
48
53
  export interface FlowResult {
49
54
  status: number;
@@ -56,4 +61,4 @@ export interface FlowContext {
56
61
  request?: Request;
57
62
  signal?: AbortSignal;
58
63
  }
59
- export declare function createApp({ store, viewerHtml, setupText, topics, packs, userRules, authenticate, authToken, basePath, publicRead, screenshots, version, upgradeCommand, renderRev, fetchLatestRelease, onEvent, maxHoldConnections, executor, runLimits, log, }: AppOptions): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
64
+ export declare function createApp({ store, viewerHtml, setupText, topics, packs, userRules, authenticate, authToken, basePath, publicRead, screenshots, version, upgradeCommand, renderRev, fetchLatestRelease, onEvent, maxHoldConnections, executor, runLimits, networkHosts, log, }: AppOptions): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;