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/mcpSpec.js
CHANGED
|
@@ -28,7 +28,12 @@ const field = {
|
|
|
28
28
|
knobs: 'Global knobs (tunekit usePane shape) keyed by path: [default,min,max,step], boolean, {type:"select",options}, "#hex"',
|
|
29
29
|
variantKnobs: "Knobs this variant alone has",
|
|
30
30
|
from: "Branch from this version",
|
|
31
|
+
fork: 'Start this new variant from a sibling: "variant" or "variant@N"; alone it copies it, with parts/fills it edits the copy',
|
|
31
32
|
prompt: "What prompted this version; usually omit",
|
|
33
|
+
note: "What this variant is; shown beside it, never in the html",
|
|
34
|
+
widths: "Widths it ships at, side by side: [390,1280]",
|
|
35
|
+
flow: "Flow this screen is a step of; alone, only places it",
|
|
36
|
+
step: "1-based place; 0 removes",
|
|
32
37
|
kits: `Opt-in bundles: ${KIT_IDS.join("|")}`,
|
|
33
38
|
};
|
|
34
39
|
const diffFileSchema = z.object({
|
|
@@ -75,10 +80,15 @@ const askSchema = z.object({
|
|
|
75
80
|
state: z.string().optional(),
|
|
76
81
|
part: z.string().optional().describe("data-part name, for scope part"),
|
|
77
82
|
multi: z.boolean().optional(),
|
|
83
|
+
after: z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("Id of an earlier ask this depends on; it opens once that one is answered"),
|
|
78
87
|
options: z.array(z.object({
|
|
79
88
|
id: z.string().optional(),
|
|
80
89
|
label: z.string(),
|
|
81
90
|
variant: z.string().optional().describe("Bind to a published variant"),
|
|
91
|
+
version: z.number().int().optional().describe("And one version of it"),
|
|
82
92
|
set: z.record(z.string(), z.unknown()).optional().describe("Or to knob values {path: value}"),
|
|
83
93
|
})),
|
|
84
94
|
});
|
|
@@ -100,6 +110,9 @@ function zodParam(p) {
|
|
|
100
110
|
case "integer":
|
|
101
111
|
s = z.number().int();
|
|
102
112
|
break;
|
|
113
|
+
case "integers":
|
|
114
|
+
s = z.array(z.number().int());
|
|
115
|
+
break;
|
|
103
116
|
default:
|
|
104
117
|
s = p.t === "string" ? z.string() : p.t === "number" ? z.number() : z.boolean();
|
|
105
118
|
}
|
|
@@ -118,7 +131,7 @@ const VARIANT_REF = { mock: P.mock, state: P.state, variant: P.variant, project:
|
|
|
118
131
|
export const MCP_TOOL_DEFS = [
|
|
119
132
|
{
|
|
120
133
|
name: "publish",
|
|
121
|
-
description: "Create or version one variant of one state of a mock. One of html, surfaces (the full ordered list) or
|
|
134
|
+
description: "Create or version one variant of one state of a mock. One of html, surfaces (the full ordered list), parts or fills (splice the latest version). Returns parts per state, nudges, feedback.",
|
|
122
135
|
params: {
|
|
123
136
|
...VARIANT_REF,
|
|
124
137
|
title: { t: "string", d: field.title },
|
|
@@ -129,10 +142,19 @@ export const MCP_TOOL_DEFS = [
|
|
|
129
142
|
d: "Full ordered list: {id} keeps a surface, a missing id removes it",
|
|
130
143
|
},
|
|
131
144
|
parts: { t: "object", d: '{"name"|"name#key": outer html}; splices marked parts' },
|
|
145
|
+
fills: {
|
|
146
|
+
t: "object",
|
|
147
|
+
d: '{"part#fill": outer html}; replaces that fill of a slot, or adds it after the others',
|
|
148
|
+
},
|
|
132
149
|
knobs: { t: "object", d: field.knobs },
|
|
133
150
|
variantKnobs: { t: "object", d: field.variantKnobs },
|
|
134
151
|
from: { t: "integer", d: field.from },
|
|
152
|
+
fork: { t: "string", d: field.fork },
|
|
135
153
|
prompt: { t: "string", d: field.prompt },
|
|
154
|
+
note: { t: "string", d: field.note },
|
|
155
|
+
widths: { t: "integers", d: field.widths },
|
|
156
|
+
flow: { t: "string", d: field.flow },
|
|
157
|
+
step: { t: "integer", d: field.step },
|
|
136
158
|
session: P.session,
|
|
137
159
|
sessionTitle: { t: "string", d: field.sessionTitle },
|
|
138
160
|
agent: { t: "string", d: field.agent },
|
|
@@ -152,17 +174,21 @@ export const MCP_TOOL_DEFS = [
|
|
|
152
174
|
},
|
|
153
175
|
{
|
|
154
176
|
name: "read",
|
|
155
|
-
description: "Without mock: every mock (slug, states, variants, open asks) plus pending. With mock: its states, variants, asks with answers, parts, knobs and
|
|
177
|
+
description: "Without mock: every mock (slug, states, variants, open asks), flows, plus pending. With mock: its states, variants, asks with answers, parts, knobs and settled values (every answer's set and tuning sent so far), plus pending. Never consumes feedback.",
|
|
156
178
|
params: {
|
|
157
179
|
mock: { t: "string", d: field.mock },
|
|
158
180
|
project: P.project,
|
|
159
181
|
body: { t: "boolean", d: "Include each variant's surfaces" },
|
|
160
182
|
history: { t: "boolean", d: "Include version rows" },
|
|
183
|
+
tree: {
|
|
184
|
+
t: "boolean",
|
|
185
|
+
d: "Without mock: the project as a tree (each mock's variants with status and forkedFrom, the mocks it uses and is used in)",
|
|
186
|
+
},
|
|
161
187
|
},
|
|
162
188
|
},
|
|
163
189
|
{
|
|
164
190
|
name: "feedback",
|
|
165
|
-
description: "Returns at once: what the user sent since you last heard (one batch per mock: reply answers, mix, tuned knobs, part comments, comments, accepted/archived), delivered once, plus pending (viewer open, draft progress).",
|
|
191
|
+
description: "Returns at once: what the user sent since you last heard (one batch per mock: reply answers, mix, tuned knobs, part comments, comments, accepted/archived/dropped, or resolved with the asks it dismissed), delivered once, plus pending (viewer open, draft progress).",
|
|
166
192
|
params: {
|
|
167
193
|
project: P.project,
|
|
168
194
|
session: { t: "string", d: "Session id returned by publish", req: true },
|
|
@@ -181,7 +207,7 @@ export const MCP_TOOL_DEFS = [
|
|
|
181
207
|
},
|
|
182
208
|
{
|
|
183
209
|
name: "export",
|
|
184
|
-
description: "The
|
|
210
|
+
description: "The html in use (else current) per state, version history, screenshot URL, knobs, the settled values and the last reply.",
|
|
185
211
|
params: VARIANT_REF,
|
|
186
212
|
},
|
|
187
213
|
{
|
|
@@ -235,7 +261,9 @@ const nullStr = z.string().nullable();
|
|
|
235
261
|
const strs = z.array(z.string());
|
|
236
262
|
const bag = z.record(z.string(), z.unknown());
|
|
237
263
|
const variantRef = o({ state: nullStr, variant: str });
|
|
264
|
+
const inUseRef = o({ state: nullStr, variant: str, version: num });
|
|
238
265
|
const partsByState = z.array(o({ state: nullStr, parts: z.array(o({ name: str })) }));
|
|
266
|
+
const flowSchema = o({ name: str, steps: z.array(o({ mock: str, state: nullStr })) });
|
|
239
267
|
const feedbackSchema = o({
|
|
240
268
|
mock: nullStr,
|
|
241
269
|
reply: o({
|
|
@@ -252,14 +280,24 @@ const feedbackSchema = o({
|
|
|
252
280
|
.nullable()
|
|
253
281
|
.describe("The user's Send; null if only comments"),
|
|
254
282
|
comments: z.array(o({ seq: num, text: str })),
|
|
255
|
-
accepted: z.array(
|
|
283
|
+
accepted: z.array(inUseRef).describe("Accepted, each at the version put in use"),
|
|
256
284
|
archived: z.array(variantRef),
|
|
285
|
+
dropped: z.array(variantRef),
|
|
286
|
+
resolved: z
|
|
287
|
+
.literal(true)
|
|
288
|
+
.optional()
|
|
289
|
+
.describe("The user resolved the mock: its open asks were closed unanswered"),
|
|
290
|
+
dismissed: z
|
|
291
|
+
.array(o({ ask: str, text: str }))
|
|
292
|
+
.optional()
|
|
293
|
+
.describe("The asks the resolution closed; don't ask them again"),
|
|
257
294
|
}).meta({ id: "Feedback" });
|
|
258
295
|
// Typed once, on feedback: repeating it on every write would cost more than
|
|
259
296
|
// the rest of the write's output schema.
|
|
260
297
|
const feedbackRide = z.array(bag).describe("Feedback batches as the feedback tool returns");
|
|
261
298
|
const pendingSchema = o({
|
|
262
299
|
mock: str,
|
|
300
|
+
resolved: z.literal(true).optional(),
|
|
263
301
|
viewerOpen: z.boolean(),
|
|
264
302
|
draft: o({ answered: num, of: num, comments: num, touchedAt: str }).nullable(),
|
|
265
303
|
}).meta({ id: "Pending" });
|
|
@@ -271,6 +309,7 @@ const writeOutput = {
|
|
|
271
309
|
partChanges: o({ vanished: strs, renamed: z.array(o({ from: str, to: str })) }).optional(),
|
|
272
310
|
nudges: strs.optional(),
|
|
273
311
|
suggestedAsk: bag.optional().describe("Send with ask when a nudge names it"),
|
|
312
|
+
flow: flowSchema.optional(),
|
|
274
313
|
feedback: feedbackRide,
|
|
275
314
|
};
|
|
276
315
|
const OUTPUT_SCHEMAS = {
|
|
@@ -307,13 +346,39 @@ const OUTPUT_SCHEMAS = {
|
|
|
307
346
|
mocks: z.array(o({ slug: str, states: strs, variants: num, open: num })).optional(),
|
|
308
347
|
states: strs.optional(),
|
|
309
348
|
asks: z.array(o({ id: str, text: str })).optional(),
|
|
310
|
-
variants: z
|
|
349
|
+
variants: z
|
|
350
|
+
.array(o({
|
|
351
|
+
state: nullStr,
|
|
352
|
+
variant: str,
|
|
353
|
+
status: str,
|
|
354
|
+
version: num,
|
|
355
|
+
acceptedVersion: num.optional().describe("Set when accepted: the version in use"),
|
|
356
|
+
history: z
|
|
357
|
+
.array(o({ version: num, hidden: z.boolean().optional() }))
|
|
358
|
+
.optional()
|
|
359
|
+
.describe("With history: version rows; hidden ones the user put away are flagged"),
|
|
360
|
+
}))
|
|
361
|
+
.optional(),
|
|
362
|
+
inUse: z
|
|
363
|
+
.array(inUseRef)
|
|
364
|
+
.optional()
|
|
365
|
+
.describe("Per state, the version the user put in use; export and embeds resolve to it"),
|
|
311
366
|
knobs: bag.optional(),
|
|
312
|
-
|
|
367
|
+
settled: bag.optional().describe("Every knob value the user has sent, later replies winning"),
|
|
368
|
+
tree: z.array(bag).optional(),
|
|
369
|
+
flows: z.array(flowSchema).optional(),
|
|
313
370
|
pending: z.union([z.array(pendingSchema), pendingSchema]),
|
|
314
371
|
},
|
|
315
372
|
export: {
|
|
316
|
-
states: z.array(o({
|
|
373
|
+
states: z.array(o({
|
|
374
|
+
state: nullStr,
|
|
375
|
+
variant: str,
|
|
376
|
+
version: num,
|
|
377
|
+
latest: num.optional().describe("Your newer version, not in use yet"),
|
|
378
|
+
html: str,
|
|
379
|
+
markdown: str,
|
|
380
|
+
})),
|
|
381
|
+
settled: bag,
|
|
317
382
|
reply: bag.nullable(),
|
|
318
383
|
},
|
|
319
384
|
};
|
|
@@ -6,23 +6,14 @@ const MERMAID_PARSE_NEXT_STEPS = [
|
|
|
6
6
|
'Keep the diagram declaration on the first non-comment line (for example, "flowchart TD").',
|
|
7
7
|
"Reduce the diagram to a minimal valid form, then add statements back until the failing line is isolated.",
|
|
8
8
|
];
|
|
9
|
-
const requiredString = (name) => z.string({
|
|
10
|
-
required_error: `requires string "${name}"`,
|
|
11
|
-
invalid_type_error: `requires string "${name}"`,
|
|
12
|
-
});
|
|
9
|
+
const requiredString = (name) => z.string({ error: `requires string "${name}"` });
|
|
13
10
|
const optionalLooseString = z.preprocess((v) => (typeof v === "string" ? v : undefined), z.string().optional());
|
|
14
11
|
const looseLayout = z.preprocess((v) => (v === "unified" || v === "split" ? v : undefined), z.enum(["unified", "split"]).optional());
|
|
15
12
|
const optionalLooseNumber = z.preprocess((v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined), z.number().optional());
|
|
16
13
|
const strictDiffFile = z.object({
|
|
17
14
|
filename: requiredString("filename"),
|
|
18
|
-
before: z.string({
|
|
19
|
-
|
|
20
|
-
invalid_type_error: 'requires string "before" and "after"',
|
|
21
|
-
}),
|
|
22
|
-
after: z.string({
|
|
23
|
-
required_error: 'requires string "before" and "after"',
|
|
24
|
-
invalid_type_error: 'requires string "before" and "after"',
|
|
25
|
-
}),
|
|
15
|
+
before: z.string({ error: 'requires string "before" and "after"' }),
|
|
16
|
+
after: z.string({ error: 'requires string "before" and "after"' }),
|
|
26
17
|
language: z.string().optional(),
|
|
27
18
|
});
|
|
28
19
|
const looseDiffFile = z
|
|
@@ -139,7 +139,9 @@ blockquote {
|
|
|
139
139
|
color: var(--muted);
|
|
140
140
|
}
|
|
141
141
|
table { border-collapse: collapse; font-size: 13px; }
|
|
142
|
-
|
|
142
|
+
/* break-word, not the body's anywhere: anywhere lets a column shrink to one
|
|
143
|
+
letter, so a long cell beside it squeezes "Topic" into "Top/ic". */
|
|
144
|
+
th, td { border: 0.5px solid var(--border); padding: 4px 8px; text-align: left; overflow-wrap: break-word; }
|
|
143
145
|
th { background: var(--hover); }
|
|
144
146
|
img { max-width: 100%; height: auto; border-radius: 6px; }
|
|
145
147
|
hr { border: none; border-top: 0.5px solid var(--border); margin: 1em 0; }
|
package/dist/server/run.js
CHANGED
|
@@ -153,6 +153,10 @@ export function createRunFlow(deps) {
|
|
|
153
153
|
return [await deps.guide("", topic), String(topic)];
|
|
154
154
|
},
|
|
155
155
|
async read([mock, opts]) {
|
|
156
|
+
if ((mock === undefined || mock === null) && plain(opts).tree === true) {
|
|
157
|
+
const value = await take(flows.tree({ project: await projectOf() }));
|
|
158
|
+
return [value, `${value.tree.length} mocks`];
|
|
159
|
+
}
|
|
156
160
|
if (mock === undefined || mock === null) {
|
|
157
161
|
const value = await take(flows.list({ project: await projectOf() }));
|
|
158
162
|
return [value, `${value.mocks.length} mocks`];
|
package/dist/server/runApi.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const RUN_API = "// The body of an async function, in plain JavaScript (no TypeScript syntax).\n// `await mockpit.*`, `return` a JSON value, print() adds an output line.\n// No network, timers, imports or process. Session, project and agent are fixed\n// for the run; pass the returned session to the next run.\ntype Ref = { mock: string; state?: string; variant?: string };\ntype Knobs = Record<string, unknown>; // path \u2192 [default,min,max,step] | boolean | {type:\"select\",options} | \"#hex\"\ntype Surface =\n | { kind: \"html\"; html: string; kits?: string[] }\n | { kind: \"markdown\"; markdown: string }\n | { kind: \"diff\"; patch?: string; files?: { filename: string; before: string; after: string }[]; layout?: \"unified\" | \"split\" }\n | { kind: \"image\"; assetId: string; alt?: string; caption?: string }\n | { kind: \"terminal\"; text: string; cols?: number; title?: string }\n | { kind: \"mermaid\"; mermaid: string }\n | { kind: \"json\"; data: unknown; title?: string }\n | { kind: \"code\"; code: string; language?: string; lineStart?: number };\ntype Ask = {\n id?: string; text: string; scope?: \"mock\" | \"state\" | \"part\"; state?: string; part?: string; multi?: boolean;\n options: { id?: string; label: string; variant?: string; set?: Knobs }[];\n};\ntype Written = {\n post: { state: string | null; variant: string; version: number }; url: string;\n parts: { state: string | null; parts: { name: string }[] }[];\n partChanges?: { vanished: string[]; renamed: { from: string; to: string }[] };\n nudges?: string[]; suggestedAsk?: Ask; // send it with ask when nudged\n};\ntype Feedback = {\n mock: string | null;\n reply: null | { asks: { ask: string; chosen: { id: string; label: string; other?: true }[]; note?: string }[]; mix: Knobs; tuned: Knobs; comments: { part: string | null; text: string }[] };\n comments: { text: string; state: string | null; variant: string | null }[];\n accepted: { state: string | null; variant: string }[]; archived: { state: string | null; variant: string }[];\n};\ntype Pending = { mock: string; viewerOpen: boolean; draft: null | { answered: number; of: number; comments: number; touchedAt: string } };\ndeclare const mockpit: {\n guide(topic?: \"knobs\" | \"asks\" | \"surfaces\" | \"html\" | \"feedback\" | \"http\" | \"scripts\"): Promise<string>;\n /** No mock: every mock plus pending. With one: its states, variants, asks, parts, knobs. */\n read(mock?: string, opts?: { body?: boolean; history?: boolean }): Promise<unknown>;\n /** Creates or versions (mock, state, variant). One of: html; surfaces, the full ordered list\n * ({id} alone keeps that surface, a missing id is removed); parts {\"name\"|\"name#key\": outer html}. */\n publish(v: Ref & { title?: string; kind?: \"component\" | \"page\"; html?: string; surfaces?: (Surface | { id: string })[]; parts?: Record<string, string>; knobs?: Knobs; variantKnobs?: Knobs; from?: number }): Promise<Written>;\n ask(mock: string, asks: Ask[]): Promise<{ asks: { id: string; text: string }[]; url: string; nudges?: string[] }>;\n /** Never waits: what the user sent since you last heard, and what they are doing now. */\n feedback(): Promise<{ feedback: Feedback[]; pending: Pending[] }>;\n say(v: Ref, message: string): Promise<void>;\n export(v: Ref): Promise<{ states: { state: string | null; variant: string; version: number; html: string }[]; reply: unknown }>;\n /** data: base64 bytes. Use id as an image surface's assetId. */\n upload(data: string, opts: { contentType: string; filename?: string; kind?: \"image\" | \"file\" }): Promise<{ id: string; url: string }>;\n};\ndeclare function print(...values: unknown[]): void;";
|
|
1
|
+
export declare const RUN_API = "// The body of an async function, in plain JavaScript (no TypeScript syntax).\n// `await mockpit.*`, `return` a JSON value, print() adds an output line.\n// No network, timers, imports or process. Session, project and agent are fixed\n// for the run; pass the returned session to the next run.\ntype Ref = { mock: string; state?: string; variant?: string };\ntype Knobs = Record<string, unknown>; // path \u2192 [default,min,max,step] | boolean | {type:\"select\",options} | \"#hex\"\ntype Surface =\n | { kind: \"html\"; html: string; kits?: string[] }\n | { kind: \"markdown\"; markdown: string }\n | { kind: \"diff\"; patch?: string; files?: { filename: string; before: string; after: string }[]; layout?: \"unified\" | \"split\" }\n | { kind: \"image\"; assetId: string; alt?: string; caption?: string }\n | { kind: \"terminal\"; text: string; cols?: number; title?: string }\n | { kind: \"mermaid\"; mermaid: string }\n | { kind: \"json\"; data: unknown; title?: string }\n | { kind: \"code\"; code: string; language?: string; lineStart?: number };\ntype Ask = {\n id?: string; text: string; scope?: \"mock\" | \"state\" | \"part\"; state?: string; part?: string; multi?: boolean;\n options: { id?: string; label: string; variant?: string; set?: Knobs }[];\n};\ntype Written = {\n post: { state: string | null; variant: string; version: number }; url: string;\n parts: { state: string | null; parts: { name: string }[] }[];\n partChanges?: { vanished: string[]; renamed: { from: string; to: string }[] };\n nudges?: string[]; suggestedAsk?: Ask; // send it with ask when nudged\n};\ntype Feedback = {\n mock: string | null;\n reply: null | { asks: { ask: string; chosen: { id: string; label: string; other?: true }[]; note?: string }[]; mix: Knobs; tuned: Knobs; comments: { part: string | null; text: string }[] };\n comments: { text: string; state: string | null; variant: string | null }[];\n accepted: { state: string | null; variant: string }[]; archived: { state: string | null; variant: string }[];\n};\ntype Pending = { mock: string; viewerOpen: boolean; draft: null | { answered: number; of: number; comments: number; touchedAt: string } };\ndeclare const mockpit: {\n guide(topic?: \"knobs\" | \"asks\" | \"surfaces\" | \"html\" | \"feedback\" | \"http\" | \"scripts\"): Promise<string>;\n /** No mock: every mock, the flows, plus pending. With one: its states, variants, asks, parts, knobs. */\n read(mock?: string, opts?: { body?: boolean; history?: boolean }): Promise<unknown>;\n /** Creates or versions (mock, state, variant). One of: html; surfaces, the full ordered list\n * ({id} alone keeps that surface, a missing id is removed); parts {\"name\"|\"name#key\": outer html};\n * fills {\"part#fill\": outer html}, replacing or adding one alternative of a slot. */\n publish(v: Ref & { title?: string; kind?: \"component\" | \"page\"; html?: string; surfaces?: (Surface | { id: string })[]; parts?: Record<string, string>; fills?: Record<string, string>; knobs?: Knobs; variantKnobs?: Knobs; from?: number; prompt?: string; note?: string; widths?: number[]; flow?: string; step?: number }): Promise<Written>;\n ask(mock: string, asks: Ask[]): Promise<{ asks: { id: string; text: string }[]; url: string; nudges?: string[] }>;\n /** Never waits: what the user sent since you last heard, and what they are doing now. */\n feedback(): Promise<{ feedback: Feedback[]; pending: Pending[] }>;\n say(v: Ref, message: string): Promise<void>;\n export(v: Ref): Promise<{ states: { state: string | null; variant: string; version: number; html: string }[]; reply: unknown }>;\n /** data: base64 bytes. Use id as an image surface's assetId. */\n upload(data: string, opts: { contentType: string; filename?: string; kind?: \"image\" | \"file\" }): Promise<{ id: string; url: string }>;\n};\ndeclare function print(...values: unknown[]): void;";
|
|
2
2
|
export declare const RUN_FUNCTIONS: readonly ["guide", "read", "publish", "ask", "feedback", "say", "export", "upload"];
|
|
3
3
|
export type RunFunction = (typeof RUN_FUNCTIONS)[number];
|
|
4
4
|
export declare const RUN_EXAMPLE = "const html = (tone) => `<section data-part=\"hero\" class=\"${tone}\"><h1>Writer</h1></section>`;\nawait mockpit.publish({ mock: \"writer\", variant: \"calm\", html: html(\"calm\") });\nawait mockpit.publish({ mock: \"writer\", variant: \"bold\", html: html(\"bold\") });\nconst { url } = await mockpit.ask(\"writer\", [{ id: \"look\", text: \"Which look?\",\n options: [{ label: \"Calm\", variant: \"calm\" }, { label: \"Bold\", variant: \"bold\" }] }]);\n// Tell the user where to look and end the turn; a later run reads mockpit.feedback().\nreturn url;";
|
package/dist/server/runApi.js
CHANGED
|
@@ -38,11 +38,12 @@ type Feedback = {
|
|
|
38
38
|
type Pending = { mock: string; viewerOpen: boolean; draft: null | { answered: number; of: number; comments: number; touchedAt: string } };
|
|
39
39
|
declare const mockpit: {
|
|
40
40
|
guide(topic?: "knobs" | "asks" | "surfaces" | "html" | "feedback" | "http" | "scripts"): Promise<string>;
|
|
41
|
-
/** No mock: every mock plus pending. With one: its states, variants, asks, parts, knobs. */
|
|
41
|
+
/** No mock: every mock, the flows, plus pending. With one: its states, variants, asks, parts, knobs. */
|
|
42
42
|
read(mock?: string, opts?: { body?: boolean; history?: boolean }): Promise<unknown>;
|
|
43
43
|
/** Creates or versions (mock, state, variant). One of: html; surfaces, the full ordered list
|
|
44
|
-
* ({id} alone keeps that surface, a missing id is removed); parts {"name"|"name#key": outer html}
|
|
45
|
-
|
|
44
|
+
* ({id} alone keeps that surface, a missing id is removed); parts {"name"|"name#key": outer html};
|
|
45
|
+
* fills {"part#fill": outer html}, replacing or adding one alternative of a slot. */
|
|
46
|
+
publish(v: Ref & { title?: string; kind?: "component" | "page"; html?: string; surfaces?: (Surface | { id: string })[]; parts?: Record<string, string>; fills?: Record<string, string>; knobs?: Knobs; variantKnobs?: Knobs; from?: number; prompt?: string; note?: string; widths?: number[]; flow?: string; step?: number }): Promise<Written>;
|
|
46
47
|
ask(mock: string, asks: Ask[]): Promise<{ asks: { id: string; text: string }[]; url: string; nudges?: string[] }>;
|
|
47
48
|
/** Never waits: what the user sent since you last heard, and what they are doing now. */
|
|
48
49
|
feedback(): Promise<{ feedback: Feedback[]; pending: Pending[] }>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Ask, type Asset, type Comment, type CommentQuery, type CommitReplyInput, type CreateAssetInput, type CreateCommentInput, type CreateMockInput, type CreatePostInput, type CreateSessionInput, type Draft, type Knobs, type Mock, type MockKind, type Post, type PostQuery, type PostStatus, type PostVersion, type Session, type
|
|
1
|
+
import { type Ask, type Asset, type Comment, type CommentQuery, type CommitReplyInput, type CreateAssetInput, type CreateCommentInput, type CreateMockInput, type CreatePostInput, type CreateSessionInput, type Draft, type Knobs, type Mock, type MockKind, type Post, type PostQuery, type PostStatus, type PostVersion, type Session, type Embed, type Flow, type FlowStep, type ForkRef, type SqlStorage, type Store, type Surface, type UpdateMockInput, type UpdatePostInput } from "./types.ts";
|
|
2
2
|
export declare class SqlStore implements Store {
|
|
3
3
|
private sql;
|
|
4
4
|
private assetRefCache;
|
|
@@ -45,6 +45,10 @@ export declare class SqlStore implements Store {
|
|
|
45
45
|
createMock(input: CreateMockInput): Promise<Mock>;
|
|
46
46
|
updateMock(id: string, patch: UpdateMockInput): Promise<Mock | null>;
|
|
47
47
|
removeMock(id: string): Promise<boolean>;
|
|
48
|
+
private flowsOf;
|
|
49
|
+
private writeFlow;
|
|
50
|
+
listFlows(project: string): Promise<Flow[]>;
|
|
51
|
+
placeFlowStep(project: string, name: string, screen: FlowStep, step: number): Promise<Flow | null>;
|
|
48
52
|
putDraft(mockId: string, draft: Draft | null): Promise<{
|
|
49
53
|
draft: Draft | null;
|
|
50
54
|
id: string;
|
|
@@ -55,7 +59,9 @@ export declare class SqlStore implements Store {
|
|
|
55
59
|
states: string[];
|
|
56
60
|
asks: Ask[];
|
|
57
61
|
knobs: Knobs;
|
|
62
|
+
widths: number[];
|
|
58
63
|
sessionId: string | null;
|
|
64
|
+
resolvedAt: string | null;
|
|
59
65
|
createdAt: string;
|
|
60
66
|
updatedAt: string;
|
|
61
67
|
} | null>;
|
|
@@ -67,13 +73,14 @@ export declare class SqlStore implements Store {
|
|
|
67
73
|
createPost(input: CreatePostInput): Promise<Post | null>;
|
|
68
74
|
updatePost(id: string, patch: UpdatePostInput): Promise<{
|
|
69
75
|
author?: string | undefined;
|
|
70
|
-
|
|
76
|
+
embeds: Embed[];
|
|
71
77
|
state: string | null;
|
|
72
78
|
version: number;
|
|
73
79
|
updatedAt: string;
|
|
74
80
|
history: PostVersion[];
|
|
75
81
|
from: number;
|
|
76
82
|
prompt: string;
|
|
83
|
+
note?: string | undefined;
|
|
77
84
|
knobs?: Knobs | undefined;
|
|
78
85
|
title: string;
|
|
79
86
|
surfaces: Surface[];
|
|
@@ -83,9 +90,13 @@ export declare class SqlStore implements Store {
|
|
|
83
90
|
variant: string;
|
|
84
91
|
status: PostStatus;
|
|
85
92
|
createdAt: string;
|
|
93
|
+
forkedFrom?: ForkRef;
|
|
94
|
+
starred?: true;
|
|
95
|
+
acceptedVersion?: number;
|
|
96
|
+
hiddenVersions?: number[];
|
|
86
97
|
} | null>;
|
|
87
98
|
removePost(id: string): Promise<boolean>;
|
|
88
|
-
setPostStatus(id: string, status: PostStatus): Promise<{
|
|
99
|
+
setPostStatus(id: string, status: PostStatus, acceptedVersion?: number): Promise<{
|
|
89
100
|
status: PostStatus;
|
|
90
101
|
id: string;
|
|
91
102
|
sessionId: string;
|
|
@@ -99,11 +110,85 @@ export declare class SqlStore implements Store {
|
|
|
99
110
|
version: number;
|
|
100
111
|
history: PostVersion[];
|
|
101
112
|
knobs?: Knobs;
|
|
102
|
-
|
|
113
|
+
note?: string;
|
|
114
|
+
embeds: Embed[];
|
|
115
|
+
forkedFrom?: ForkRef;
|
|
116
|
+
starred?: true;
|
|
117
|
+
hiddenVersions?: number[];
|
|
118
|
+
from?: number;
|
|
119
|
+
prompt?: string;
|
|
120
|
+
author?: string;
|
|
121
|
+
} | {
|
|
122
|
+
status: PostStatus;
|
|
123
|
+
acceptedVersion: number;
|
|
124
|
+
id: string;
|
|
125
|
+
sessionId: string;
|
|
126
|
+
mock: string;
|
|
127
|
+
state: string | null;
|
|
128
|
+
variant: string;
|
|
129
|
+
title: string;
|
|
130
|
+
surfaces: Surface[];
|
|
131
|
+
createdAt: string;
|
|
132
|
+
updatedAt: string;
|
|
133
|
+
version: number;
|
|
134
|
+
history: PostVersion[];
|
|
135
|
+
knobs?: Knobs;
|
|
136
|
+
note?: string;
|
|
137
|
+
embeds: Embed[];
|
|
138
|
+
forkedFrom?: ForkRef;
|
|
139
|
+
starred?: true;
|
|
140
|
+
hiddenVersions?: number[];
|
|
141
|
+
from?: number;
|
|
142
|
+
prompt?: string;
|
|
143
|
+
author?: string;
|
|
144
|
+
} | null>;
|
|
145
|
+
setPostStarred(id: string, starred: boolean): Promise<{
|
|
146
|
+
id: string;
|
|
147
|
+
sessionId: string;
|
|
148
|
+
mock: string;
|
|
149
|
+
state: string | null;
|
|
150
|
+
variant: string;
|
|
151
|
+
status: PostStatus;
|
|
152
|
+
title: string;
|
|
153
|
+
surfaces: Surface[];
|
|
154
|
+
createdAt: string;
|
|
155
|
+
updatedAt: string;
|
|
156
|
+
version: number;
|
|
157
|
+
history: PostVersion[];
|
|
158
|
+
knobs?: Knobs;
|
|
159
|
+
note?: string;
|
|
160
|
+
embeds: Embed[];
|
|
161
|
+
forkedFrom?: ForkRef;
|
|
162
|
+
acceptedVersion?: number;
|
|
163
|
+
hiddenVersions?: number[];
|
|
164
|
+
from?: number;
|
|
165
|
+
prompt?: string;
|
|
166
|
+
author?: string;
|
|
167
|
+
} | {
|
|
168
|
+
starred: true;
|
|
169
|
+
id: string;
|
|
170
|
+
sessionId: string;
|
|
171
|
+
mock: string;
|
|
172
|
+
state: string | null;
|
|
173
|
+
variant: string;
|
|
174
|
+
status: PostStatus;
|
|
175
|
+
title: string;
|
|
176
|
+
surfaces: Surface[];
|
|
177
|
+
createdAt: string;
|
|
178
|
+
updatedAt: string;
|
|
179
|
+
version: number;
|
|
180
|
+
history: PostVersion[];
|
|
181
|
+
knobs?: Knobs;
|
|
182
|
+
note?: string;
|
|
183
|
+
embeds: Embed[];
|
|
184
|
+
forkedFrom?: ForkRef;
|
|
185
|
+
acceptedVersion?: number;
|
|
186
|
+
hiddenVersions?: number[];
|
|
103
187
|
from?: number;
|
|
104
188
|
prompt?: string;
|
|
105
189
|
author?: string;
|
|
106
190
|
} | null>;
|
|
191
|
+
setVersionHidden(id: string, version: number, hidden: boolean): Promise<Post | null>;
|
|
107
192
|
listComments(query: CommentQuery): Promise<Comment[]>;
|
|
108
193
|
private insertComment;
|
|
109
194
|
createComment(input: CreateCommentInput): Promise<Comment | null>;
|