mockpit 1.2.0 → 1.3.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.
- package/README.md +13 -8
- package/bin/mockpit.js +116 -16
- package/dist/mcp/server.js +10 -7
- package/dist/server/apiViews.d.ts +118 -17
- package/dist/server/apiViews.js +66 -8
- package/dist/server/app.d.ts +2 -1
- package/dist/server/app.js +917 -144
- package/dist/server/decisions.d.ts +23 -0
- package/dist/server/decisions.js +99 -0
- package/dist/server/designGuide.js +45 -10
- package/dist/server/embeds.d.ts +25 -0
- package/dist/server/embeds.js +118 -0
- package/dist/server/eventLog.js +2 -1
- package/dist/server/feedbackBatch.d.ts +12 -1
- package/dist/server/feedbackBatch.js +20 -3
- package/dist/server/fills.d.ts +41 -0
- package/dist/server/fills.js +328 -0
- package/dist/server/index.js +15 -1
- package/dist/server/knobs.d.ts +6 -2
- package/dist/server/knobs.js +11 -1
- package/dist/server/mcpHttp.d.ts +3 -0
- package/dist/server/mcpHttp.js +3 -0
- package/dist/server/mcpSpec.d.ts +13 -13
- package/dist/server/mcpSpec.js +73 -8
- package/dist/server/postSurfaces.js +3 -12
- package/dist/server/richRender.js +3 -1
- package/dist/server/run.js +4 -0
- package/dist/server/runApi.d.ts +1 -1
- package/dist/server/runApi.js +4 -3
- package/dist/server/sqlStore.d.ts +89 -4
- package/dist/server/sqlStore.js +149 -23
- package/dist/server/surfacePage.d.ts +6 -2
- package/dist/server/surfacePage.js +142 -10
- package/dist/server/themes.d.ts +2 -0
- package/dist/server/themes.js +23 -3
- package/dist/server/types.d.ts +73 -11
- package/dist/server/types.js +42 -2
- package/dist/server/viewerRequest.d.ts +2 -0
- package/dist/server/viewerRequest.js +14 -0
- package/guide/topics/asks.md +50 -3
- package/guide/topics/feedback.md +89 -11
- package/guide/topics/html.md +5 -1
- package/guide/topics/http.md +2 -1
- package/guide/topics/knobs.md +2 -1
- package/guide/topics/surfaces.md +24 -8
- package/package.json +4 -13
- package/skills/launch-video/SKILL.md +1 -1
- package/skills/mockpit/SKILL.md +12 -4
- package/viewer/dist/index.html +8 -8
- package/dist/server/slots.d.ts +0 -14
- package/dist/server/slots.js +0 -71
package/dist/server/apiViews.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Response shapes shared by every tier (REST, both MCP transports, the CLI), so
|
|
2
2
|
// one mock reads the same however an agent asks for it.
|
|
3
|
+
import { slotKnobs, slotsInSurfaces } from "./fills.js";
|
|
3
4
|
import { mergeParts, partsInSurfaces } from "./parts.js";
|
|
4
|
-
import { isSandboxedSurfaceKind,
|
|
5
|
+
import { draftedCount, inUseVersion, isSandboxedSurfaceKind, isLive, openCount, SURFACE_CONTENT_FIELDS, } from "./types.js";
|
|
5
6
|
export const surfaceRef = (surface, index) => ({
|
|
6
7
|
id: surface.id,
|
|
7
8
|
kind: surface.kind,
|
|
@@ -48,8 +49,21 @@ export const variantView = (post, opts = {}) => ({
|
|
|
48
49
|
...(post.from === undefined ? {} : { from: post.from }),
|
|
49
50
|
...(post.prompt ? { prompt: post.prompt } : {}),
|
|
50
51
|
...(post.author === undefined ? {} : { author: post.author }),
|
|
51
|
-
|
|
52
|
-
...(post.
|
|
52
|
+
// A slot is a select knob on its part (fills.ts); declared knobs win.
|
|
53
|
+
...(slotsInSurfaces(post.surfaces).length || post.knobs
|
|
54
|
+
? { knobs: { ...slotKnobs(slotsInSurfaces(post.surfaces)), ...post.knobs } }
|
|
55
|
+
: {}),
|
|
56
|
+
...(slotsInSurfaces(post.surfaces).length ? { slots: slotsInSurfaces(post.surfaces) } : {}),
|
|
57
|
+
...(post.note ? { note: post.note } : {}),
|
|
58
|
+
// Embedded components as they render now (server/embeds.ts); `publishedWith`
|
|
59
|
+
// is what this version rendered with when it was published.
|
|
60
|
+
...(opts.embeds?.get(post.id)
|
|
61
|
+
? { embeds: opts.embeds.get(post.id).list, embedsKey: opts.embeds.get(post.id).key }
|
|
62
|
+
: {}),
|
|
63
|
+
...(post.embeds.length ? { publishedWith: post.embeds } : {}),
|
|
64
|
+
...(post.forkedFrom ? { forkedFrom: post.forkedFrom } : {}),
|
|
65
|
+
...(post.starred ? { starred: true } : {}),
|
|
66
|
+
...(post.acceptedVersion === undefined ? {} : { acceptedVersion: post.acceptedVersion }),
|
|
53
67
|
// The part names this variant's own markup marks, so the viewer can tell
|
|
54
68
|
// which looks render a part (Mix) without the html bodies.
|
|
55
69
|
parts: partsInSurfaces(post.surfaces).map((p) => p.name),
|
|
@@ -67,17 +81,23 @@ export const variantView = (post, opts = {}) => ({
|
|
|
67
81
|
...(post.author === undefined ? {} : { author: post.author }),
|
|
68
82
|
}),
|
|
69
83
|
...[...post.history].sort((a, b) => b.version - a.version).map(historyMetaView),
|
|
70
|
-
],
|
|
84
|
+
].map((row) => post.hiddenVersions?.includes(row.version) ? { ...row, hidden: true } : row),
|
|
71
85
|
}
|
|
72
86
|
: {}),
|
|
73
87
|
});
|
|
74
88
|
const stateOrder = (mock) => (mock.states.length ? mock.states : [null]);
|
|
89
|
+
// What the user put in use, per state, in the mock's order; a state with
|
|
90
|
+
// nothing accepted is absent. Export and embeds resolve to exactly these.
|
|
91
|
+
export const inUseByState = (mock, posts) => stateOrder(mock).flatMap((state) => {
|
|
92
|
+
const p = posts.find((x) => x.state === state && x.status === "accepted");
|
|
93
|
+
return p ? [{ state, variant: p.variant, version: inUseVersion(p) }] : [];
|
|
94
|
+
});
|
|
75
95
|
// The parts the agent marked, per state, across the variants still in play.
|
|
76
96
|
export function partsByState(mock, posts) {
|
|
77
97
|
return stateOrder(mock).map((state) => ({
|
|
78
98
|
state,
|
|
79
99
|
parts: mergeParts(posts
|
|
80
|
-
.filter((p) => p.state === state && p.status
|
|
100
|
+
.filter((p) => p.state === state && isLive(p.status))
|
|
81
101
|
.map((p) => partsInSurfaces(p.surfaces))),
|
|
82
102
|
}));
|
|
83
103
|
}
|
|
@@ -92,7 +112,7 @@ function thumbnail(mock, posts) {
|
|
|
92
112
|
if (!pick)
|
|
93
113
|
return null;
|
|
94
114
|
const surface = pick.surfaces.findIndex((s) => isSandboxedSurfaceKind(s.kind));
|
|
95
|
-
return { postId: pick.id, surface: Math.max(surface, 0), version: pick
|
|
115
|
+
return { postId: pick.id, surface: Math.max(surface, 0), version: inUseVersion(pick) };
|
|
96
116
|
}
|
|
97
117
|
export const mockSummaryView = (mock, posts) => {
|
|
98
118
|
const drafted = draftedCount(mock, posts);
|
|
@@ -109,6 +129,7 @@ export const mockSummaryView = (mock, posts) => {
|
|
|
109
129
|
// Only once the user has started one, so a list with no drafts costs nothing.
|
|
110
130
|
...(drafted === null ? {} : { drafted }),
|
|
111
131
|
sessionId: mock.sessionId,
|
|
132
|
+
resolvedAt: mock.resolvedAt,
|
|
112
133
|
createdAt: mock.createdAt,
|
|
113
134
|
updatedAt: mock.updatedAt,
|
|
114
135
|
thumbnail: thumbnail(mock, posts),
|
|
@@ -126,15 +147,52 @@ export const mockDetailView = (mock, posts, opts = {}) => ({
|
|
|
126
147
|
asks: mock.asks,
|
|
127
148
|
open: openCount(mock, posts),
|
|
128
149
|
knobs: mock.knobs,
|
|
150
|
+
widths: mock.widths,
|
|
129
151
|
sessionId: mock.sessionId,
|
|
152
|
+
resolvedAt: mock.resolvedAt,
|
|
130
153
|
createdAt: mock.createdAt,
|
|
131
154
|
updatedAt: mock.updatedAt,
|
|
132
155
|
variants: posts.map((p) => variantView(p, opts)),
|
|
156
|
+
inUse: inUseByState(mock, posts),
|
|
133
157
|
parts: partsByState(mock, posts),
|
|
134
|
-
//
|
|
135
|
-
|
|
158
|
+
// Every knob value the user has sent (answers' sets and tuning, later replies
|
|
159
|
+
// winning), never drafts. Later questions render on top of it.
|
|
160
|
+
settled: opts.settled ?? {},
|
|
136
161
|
});
|
|
137
162
|
export const sessionRowView = (session, postCount) => ({
|
|
138
163
|
...session,
|
|
139
164
|
postCount,
|
|
140
165
|
});
|
|
166
|
+
// One mock as a node of the project tree (GET /api/projects/:name/tree): its
|
|
167
|
+
// variants per state with status and lineage, and the mocks it embeds (`uses`);
|
|
168
|
+
// `usedIn` is filled in once every node is known.
|
|
169
|
+
export const treeNodeView = (mock, posts, extra) => ({
|
|
170
|
+
id: mock.id,
|
|
171
|
+
slug: mock.slug,
|
|
172
|
+
title: mock.title,
|
|
173
|
+
kind: mock.kind,
|
|
174
|
+
open: openCount(mock, posts),
|
|
175
|
+
states: mock.states.length ? mock.states : [null],
|
|
176
|
+
widths: mock.widths,
|
|
177
|
+
createdAt: mock.createdAt,
|
|
178
|
+
updatedAt: mock.updatedAt,
|
|
179
|
+
resolvedAt: mock.resolvedAt,
|
|
180
|
+
settled: extra.settled,
|
|
181
|
+
uses: extra.uses,
|
|
182
|
+
usedIn: [],
|
|
183
|
+
inUse: inUseByState(mock, posts),
|
|
184
|
+
variants: posts.map((p) => ({
|
|
185
|
+
postId: p.id,
|
|
186
|
+
state: p.state,
|
|
187
|
+
variant: p.variant,
|
|
188
|
+
status: p.status,
|
|
189
|
+
version: p.version,
|
|
190
|
+
updatedAt: p.updatedAt,
|
|
191
|
+
surface: p.surfaces.findIndex((x) => isSandboxedSurfaceKind(x.kind)),
|
|
192
|
+
...(p.note ? { note: p.note } : {}),
|
|
193
|
+
...(p.forkedFrom ? { forkedFrom: p.forkedFrom } : {}),
|
|
194
|
+
...(p.starred ? { starred: true } : {}),
|
|
195
|
+
...(p.acceptedVersion === undefined ? {} : { acceptedVersion: p.acceptedVersion }),
|
|
196
|
+
...(extra.embeds.get(p.id) ? { embedsKey: extra.embeds.get(p.id).key } : {}),
|
|
197
|
+
})),
|
|
198
|
+
});
|
package/dist/server/app.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface AppOptions {
|
|
|
21
21
|
screenshots?: boolean;
|
|
22
22
|
version?: string;
|
|
23
23
|
upgradeCommand?: string;
|
|
24
|
+
renderRev?: string;
|
|
24
25
|
fetchLatestRelease?: () => Promise<LatestRelease | null>;
|
|
25
26
|
onEvent?: (event: FeedEvent) => void;
|
|
26
27
|
maxHoldConnections?: number;
|
|
@@ -52,4 +53,4 @@ export interface FlowContext {
|
|
|
52
53
|
request?: Request;
|
|
53
54
|
signal?: AbortSignal;
|
|
54
55
|
}
|
|
55
|
-
export declare function createApp({ store, viewerHtml, setupText, topics, authenticate, authToken, basePath, publicRead, screenshots, version, upgradeCommand, fetchLatestRelease, onEvent, maxHoldConnections, executor, runLimits, log, }: AppOptions): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
56
|
+
export declare function createApp({ store, viewerHtml, setupText, topics, authenticate, authToken, basePath, publicRead, screenshots, version, upgradeCommand, renderRev, fetchLatestRelease, onEvent, maxHoldConnections, executor, runLimits, log, }: AppOptions): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|