@vibes.diy/api-svc 14.3.83 → 14.3.85

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 (131) hide show
  1. package/analytics.d.ts +1 -0
  2. package/analytics.js +1 -0
  3. package/analytics.js.map +1 -1
  4. package/index.d.ts +1 -0
  5. package/index.js +1 -0
  6. package/index.js.map +1 -1
  7. package/intern/account-vibe-activity.js +2 -1
  8. package/intern/account-vibe-activity.js.map +1 -1
  9. package/intern/agent-account-tools.js +2 -1
  10. package/intern/agent-account-tools.js.map +1 -1
  11. package/intern/agent-assembly.d.ts +5 -0
  12. package/intern/agent-assembly.js +21 -3
  13. package/intern/agent-assembly.js.map +1 -1
  14. package/intern/agent-belt.d.ts +5 -1
  15. package/intern/agent-belt.js +29 -14
  16. package/intern/agent-belt.js.map +1 -1
  17. package/intern/agent-build-tools.d.ts +3 -0
  18. package/intern/agent-build-tools.js +0 -17
  19. package/intern/agent-build-tools.js.map +1 -1
  20. package/intern/agent-discussions.js +2 -1
  21. package/intern/agent-discussions.js.map +1 -1
  22. package/intern/agent-evidence.js +5 -4
  23. package/intern/agent-evidence.js.map +1 -1
  24. package/intern/agent-file-tools.js +5 -4
  25. package/intern/agent-file-tools.js.map +1 -1
  26. package/intern/agent-options-tool.js +46 -46
  27. package/intern/agent-options-tool.js.map +1 -1
  28. package/intern/agent-read-tools.js +43 -25
  29. package/intern/agent-read-tools.js.map +1 -1
  30. package/intern/agent-request-frame.d.ts +2 -0
  31. package/intern/agent-request-frame.js +2 -2
  32. package/intern/agent-request-frame.js.map +1 -1
  33. package/intern/agent-session-instruction.d.ts +6 -2
  34. package/intern/agent-session-instruction.js +7 -3
  35. package/intern/agent-session-instruction.js.map +1 -1
  36. package/intern/agent-session-runtime.js +2 -1
  37. package/intern/agent-session-runtime.js.map +1 -1
  38. package/intern/agent-session.js +8 -7
  39. package/intern/agent-session.js.map +1 -1
  40. package/intern/agent-wake.d.ts +1 -1
  41. package/intern/agent-wake.js +1 -1
  42. package/intern/agent-wake.js.map +1 -1
  43. package/intern/agent-with-vibe.d.ts +1 -0
  44. package/intern/agent-with-vibe.js +19 -18
  45. package/intern/agent-with-vibe.js.map +1 -1
  46. package/intern/autumn-recent-usage.js +11 -10
  47. package/intern/autumn-recent-usage.js.map +1 -1
  48. package/intern/backend-db-callback.js +3 -2
  49. package/intern/backend-db-callback.js.map +1 -1
  50. package/intern/draft-chat-store.js +3 -2
  51. package/intern/draft-chat-store.js.map +1 -1
  52. package/intern/first-brief.d.ts +58 -0
  53. package/intern/first-brief.js +169 -0
  54. package/intern/first-brief.js.map +1 -0
  55. package/intern/first-build-classifier.d.ts +88 -0
  56. package/intern/first-build-classifier.js +242 -0
  57. package/intern/first-build-classifier.js.map +1 -0
  58. package/intern/guest-credit-meter.js +3 -2
  59. package/intern/guest-credit-meter.js.map +1 -1
  60. package/intern/image-survey.js +6 -5
  61. package/intern/image-survey.js.map +1 -1
  62. package/intern/instruction-variant.d.ts +31 -1
  63. package/intern/instruction-variant.js +137 -1
  64. package/intern/instruction-variant.js.map +1 -1
  65. package/intern/llm-tool-loop.d.ts +1 -0
  66. package/intern/llm-tool-loop.js +13 -0
  67. package/intern/llm-tool-loop.js.map +1 -1
  68. package/intern/manifest-assets-line.d.ts +2 -0
  69. package/intern/manifest-assets-line.js +14 -1
  70. package/intern/manifest-assets-line.js.map +1 -1
  71. package/intern/mercury-first-build-seam.d.ts +42 -0
  72. package/intern/mercury-first-build-seam.js +129 -0
  73. package/intern/mercury-first-build-seam.js.map +1 -0
  74. package/intern/mercury-first-build.d.ts +121 -0
  75. package/intern/mercury-first-build.js +808 -0
  76. package/intern/mercury-first-build.js.map +1 -0
  77. package/intern/pinned-app-slug.js +2 -1
  78. package/intern/pinned-app-slug.js.map +1 -1
  79. package/intern/prompt-step.d.ts +1 -1
  80. package/intern/prompt-step.js.map +1 -1
  81. package/intern/prompt-usage.js +5 -4
  82. package/intern/prompt-usage.js.map +1 -1
  83. package/intern/save-repair-io.js +3 -2
  84. package/intern/save-repair-io.js.map +1 -1
  85. package/intern/server-first-build.d.ts +25 -0
  86. package/intern/server-first-build.js +46 -0
  87. package/intern/server-first-build.js.map +1 -0
  88. package/intern/swr-wrapper-html-cache.js +1 -0
  89. package/intern/swr-wrapper-html-cache.js.map +1 -1
  90. package/intern/turn-latency.d.ts +3 -0
  91. package/intern/turn-latency.js +11 -0
  92. package/intern/turn-latency.js.map +1 -1
  93. package/intern/url-research.js +3 -2
  94. package/intern/url-research.js.map +1 -1
  95. package/intern/work-tools.js +8 -5
  96. package/intern/work-tools.js.map +1 -1
  97. package/not-implemented-message.js +2 -1
  98. package/not-implemented-message.js.map +1 -1
  99. package/package.json +13 -13
  100. package/public/access-output-decoder.js +4 -3
  101. package/public/access-output-decoder.js.map +1 -1
  102. package/public/agent-turn-action.d.ts +3 -2
  103. package/public/agent-turn-action.js +210 -36
  104. package/public/agent-turn-action.js.map +1 -1
  105. package/public/agent-turn-assembly.d.ts +3 -1
  106. package/public/agent-turn-assembly.js +18 -3
  107. package/public/agent-turn-assembly.js.map +1 -1
  108. package/public/draft-runtime.js +9 -5
  109. package/public/draft-runtime.js.map +1 -1
  110. package/public/list-memberships.js +3 -2
  111. package/public/list-memberships.js.map +1 -1
  112. package/public/list-notifications.js +2 -1
  113. package/public/list-notifications.js.map +1 -1
  114. package/public/list-recent-vibes.js +4 -3
  115. package/public/list-recent-vibes.js.map +1 -1
  116. package/public/prompt-chat-section.js +11 -1
  117. package/public/prompt-chat-section.js.map +1 -1
  118. package/public/prompt-section-actions.d.ts +2 -1
  119. package/public/prompt-section-actions.js +1 -0
  120. package/public/prompt-section-actions.js.map +1 -1
  121. package/public/prompt-turn-settled.js +3 -1
  122. package/public/prompt-turn-settled.js.map +1 -1
  123. package/public/prompt-turn-types.d.ts +2 -0
  124. package/public/provider-errors.js +3 -2
  125. package/public/provider-errors.js.map +1 -1
  126. package/public/report-cache.js +2 -1
  127. package/public/report-cache.js.map +1 -1
  128. package/public/serv-entry-point.js +2 -1
  129. package/public/serv-entry-point.js.map +1 -1
  130. package/types.js +7 -6
  131. package/types.js.map +1 -1
@@ -0,0 +1,129 @@
1
+ import { isSseLine } from "@vibes.diy/call-ai-v2";
2
+ import { runCreateVibeTool } from "./agent-build-tools.js";
3
+ import { claimAgentAppContext } from "./agent-request-frame.js";
4
+ import { SERVER_FIRST_BUILD_EVIDENCE_NAME } from "./server-first-build.js";
5
+ export const MERCURY_SEAM_SOURCE = "mercury";
6
+ export async function runMercurySeam(vctx, o) {
7
+ const record = async (body) => {
8
+ const written = await o.evidence({
9
+ kind: "receipt",
10
+ name: SERVER_FIRST_BUILD_EVIDENCE_NAME,
11
+ text: JSON.stringify({ ...body, source: MERCURY_SEAM_SOURCE }),
12
+ });
13
+ if (written.isErr())
14
+ vctx.logger.Warn().Err(written).Str("chatId", o.firstTurn.chatId).Msg("mercury-seam-evidence-failed");
15
+ };
16
+ const rMercury = await o.pending;
17
+ if (rMercury.isErr()) {
18
+ vctx.logger
19
+ .Warn()
20
+ .Any("event", { chatId: o.firstTurn.chatId, error: rMercury.Err().message })
21
+ .Msg("mercury-first-build-fallback");
22
+ await record({ dispatched: false, reason: "mercury-failed", error: rMercury.Err().message });
23
+ return { dispatched: false, reason: "mercury-failed" };
24
+ }
25
+ const mercury = rMercury.Ok();
26
+ const summary = {
27
+ elapsedMs: mercury.elapsedMs,
28
+ archetype: mercury.shape.archetype,
29
+ coreAction: mercury.shape.coreAction,
30
+ skills: mercury.input.skills ?? [],
31
+ };
32
+ const createArgs = {
33
+ actor: o.actor,
34
+ input: mercury.input,
35
+ dispatcher: o.dispatcher,
36
+ firstTurn: o.firstTurn,
37
+ ...(o.presetColorway === undefined ? {} : { presetColorway: o.presetColorway }),
38
+ };
39
+ const first = await runCreateVibeTool(vctx, { ...createArgs, offerAddressRetry: true });
40
+ const addressRetried = first.isErr() && first.Err().refusal.reason === "address-taken";
41
+ const r = addressRetried ? await runCreateVibeTool(vctx, createArgs) : first;
42
+ if (r.isErr()) {
43
+ vctx.logger
44
+ .Warn()
45
+ .Any("event", { chatId: o.firstTurn.chatId, refusal: r.Err().refusal })
46
+ .Msg("mercury-first-build-create-refused");
47
+ await record({
48
+ dispatched: false,
49
+ reason: "create-refused",
50
+ refusal: r.Err().refusal,
51
+ mercury: summary,
52
+ ...(addressRetried ? { addressRetried: true } : {}),
53
+ });
54
+ return { dispatched: false, reason: "create-refused" };
55
+ }
56
+ await record({
57
+ dispatched: true,
58
+ appSlug: r.Ok().appSlug,
59
+ receipt: r.Ok(),
60
+ mercury: summary,
61
+ ...(addressRetried ? { addressRetried: true } : {}),
62
+ });
63
+ vctx.logger
64
+ .Info()
65
+ .Any("event", { chatId: r.Ok().chatId, appSlug: r.Ok().appSlug, mercuryMs: mercury.elapsedMs, addressRetried })
66
+ .Msg("mercury-first-build-dispatched");
67
+ return {
68
+ dispatched: true,
69
+ chatId: r.Ok().chatId,
70
+ appSlug: r.Ok().appSlug,
71
+ preamble: mercury.preamble,
72
+ ...(addressRetried ? { addressRetried: true } : {}),
73
+ };
74
+ }
75
+ export function mercuryFirstBuildContextLine(preamble) {
76
+ return ("its first build is running now, started by the platform from the person's own words as this turn began. " +
77
+ `Your reply this turn already opens with these words, on the person's screen as you start: "${preamble}" ` +
78
+ "Carry on from them in a sentence at most, and answer from the [build result] when it arrives; " +
79
+ "its files, versions and settings are readable once it lands.");
80
+ }
81
+ export function mercuryFirstBuildAppContext(messages, o) {
82
+ return claimAgentAppContext(messages, { ownerHandle: o.ownerHandle, appSlug: o.appSlug }, { firstBuildLine: mercuryFirstBuildContextLine(o.preamble) });
83
+ }
84
+ export function withPreambleFirst(stream, preamble) {
85
+ let sent = false;
86
+ return stream.pipeThrough(new TransformStream({
87
+ transform(msg, controller) {
88
+ if (sent === false && isSseLine(msg)) {
89
+ sent = true;
90
+ controller.enqueue({
91
+ ...msg,
92
+ chunk: {
93
+ id: msg.chunk.id,
94
+ provider: msg.chunk.provider,
95
+ model: msg.chunk.model,
96
+ object: msg.chunk.object,
97
+ created: msg.chunk.created,
98
+ choices: [
99
+ {
100
+ index: 0,
101
+ delta: { role: "assistant", content: `${preamble}\n\n` },
102
+ finish_reason: null,
103
+ native_finish_reason: null,
104
+ },
105
+ ],
106
+ },
107
+ });
108
+ }
109
+ controller.enqueue(msg);
110
+ },
111
+ }));
112
+ }
113
+ export const MERCURY_DERIVE_FROM_ASK_OVERLAY = `<derive-from-ask>
114
+ The <app-workflow> brief for this app is deliberately thin on records and screens. It fixes what is settled: the person's own words, the ownership archetype and the access shape, which capabilities are loaded, the core action in the person's words, the record names, the seed cast, the look and the title. It leaves the mechanics to you, because you can read the person's message and work out what the app must actually do.
115
+
116
+ Derive the rest from the verbatim ask before you write code: the fields each named record needs so the screens can show what the person described; the first screen, built around the core action as its biggest control in as few taps as the words allow; every other screen the ask implies and nothing it does not; the calculations, states and transitions the words commit you to — a tally that increments on one tap, a split that shows who owes whom, a feed that refreshes from its source, a timer that fills the screen. Each asked feature is a direct control of its own.
117
+
118
+ Keep the ownership and access shape exactly as the brief gives it: who owns the object, who is let in, what a visitor sees. Keep the record names and the seed cast; give the seed records exactly the fields your Add writes. A specified ask gets on screen only what it names plus what that needs; a vague ask gets one or two alive defaults. The hints in the brief are hints: where your reading of the ask disagrees with one, the ask wins.
119
+ </derive-from-ask>`;
120
+ export function mercuryBuilderOverlayApplies(o) {
121
+ return o.instructionVariant === "mercury-recut-first-build" && o.agentDispatched && o.initialTurn;
122
+ }
123
+ export function withMercuryBuilderOverlay(messages) {
124
+ const at = messages.findIndex((m) => m.role === "system");
125
+ if (at < 0)
126
+ return [...messages];
127
+ return messages.map((m, i) => i === at ? { ...m, content: [...m.content, { type: "text", text: MERCURY_DERIVE_FROM_ASK_OVERLAY }] } : m);
128
+ }
129
+ //# sourceMappingURL=mercury-first-build-seam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mercury-first-build-seam.js","sourceRoot":"","sources":["../../jsr/intern/mercury-first-build-seam.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import { Result } from "@adviser/cement";
2
+ import type { CreateVibeToolInput, AppNature } from "@vibes.diy/api-types";
3
+ import type { LLMMessage } from "@vibes.diy/call-ai-v2";
4
+ import type { VibesApiSQLCtx } from "../types.js";
5
+ export declare const MERCURY_FIRST_BUILD_MODEL = "inception/mercury-2.5";
6
+ export declare const MERCURY_FIRST_BUILD_REASONING: {
7
+ readonly effort: "none";
8
+ };
9
+ export declare const MERCURY_CALL_DEADLINE_MS = 8000;
10
+ export declare const MERCURY_CALL_ATTEMPTS = 2;
11
+ export declare const MERCURY_TRANSIENT_RETRIES = 3;
12
+ export declare const MERCURY_TRANSIENT_BACKOFF_MS = 400;
13
+ export declare const MERCURY_ARCHETYPES: readonly ["personal", "group", "publish", "intake", "open", "toy"];
14
+ export type MercuryArchetype = (typeof MERCURY_ARCHETYPES)[number];
15
+ export declare const MERCURY_FLAGS: readonly ["ai", "composer", "imageGen", "backend", "calendar", "audio", "threeD", "charts", "boardGame", "sensitive"];
16
+ export type MercuryFlag = (typeof MERCURY_FLAGS)[number];
17
+ export interface MercuryShape {
18
+ readonly archetype: MercuryArchetype;
19
+ readonly coreAction: string;
20
+ readonly kind: string;
21
+ readonly who: string;
22
+ readonly recordNames: readonly string[];
23
+ readonly flags: Readonly<Record<MercuryFlag, boolean>>;
24
+ }
25
+ export interface MercuryBriefFields {
26
+ readonly opening: string;
27
+ readonly access: string;
28
+ readonly seed: string;
29
+ readonly look: string;
30
+ readonly pairs: readonly {
31
+ readonly title: string;
32
+ readonly slug: string;
33
+ }[];
34
+ readonly icon: string;
35
+ }
36
+ export type MercuryBriefField = keyof MercuryBriefFields;
37
+ export declare const MERCURY_BRIEF_FIELDS: readonly MercuryBriefField[];
38
+ export declare const MERCURY_SHAPE_SYSTEM = "You classify a person's one-message request for a small web app before a build brief is written. Return only JSON.\n\narchetype, exactly one:\n- personal: one person's own tool (\"for me\", \"my\", \"private\", a tracker, a log, a list, a journal) with no other people named.\n- group: the person names other people who use it with them (we, our, friends, family, team, club, kids, housemates, partner, members, a foursome).\n- publish: the person writes and other people only read (a blog, menu, gallery, portfolio, schedule, zine, \"everyone can read\").\n- intake: strangers or customers submit something without signing up and the person sees the submissions (orders, bookings, requests, sign-ups, replies, reports from the public).\n- open: anyone with the link joins in and adds their own bit (a shared wall, canvas, feed, leaderboard game, community board, swap board, \"anyone can post\").\n- toy: a game, simulator, visual, sound or generator that keeps little or nothing (scores at most).\nTie-breaks: group means other people open the app on their own devices; a calculator, splitter or tool used on one phone \"with friends\" at the table is personal. toy is for games, simulators and visual or sound toys; a tool that analyzes, estimates, designs, counts, tracks or logs stores records and is personal. A \"feed of information\" pulled from the internet is personal with backend true. A test or nonsense phrase is still a request: make the most playful literal app of it (a \"squash bloom soothsayer\" is a fortune teller about squash) and classify that.\n\ncoreAction: the one thing the person does most in this app, as a short verb phrase in their own words (\"tap once per glass\", \"paste the group chat\", \"lasso cows\"). It becomes the biggest control on the first screen.\nkind: 2-6 word noun phrase for the app in the person's own nouns. who: who it is for, 2-8 words.\nrecordNames: 1-5 short singular record type names the app stores (toys may have just \"score\" or none).\nflags, each true only when the request itself needs it:\n- ai: the app must read, write or judge free text or photos with a language model (extract facts from pasted words, answer questions, generate text, chat, analyze a picture, suggest recipes).\n- composer: ai is true AND the person types or pastes their own words or photos as the way records get in.\n- imageGen: the app generates pictures.\n- backend: server work the page cannot do: scheduled reminders or digests, a live feed pulled from outside, secret dealing, email.\n- calendar: dates on a calendar, bookings by slot, recurring events, paystub periods.\n- audio: sound or music playback or synthesis.\n- threeD: 3D graphics, a simulator, a world you move through.\n- charts: heatmaps, graphs, statistics views.\n- boardGame: a turn-based card or board game.\n- sensitive: health, money of real people, kids, or the word private.";
39
+ export declare function mercuryShapeSchema(): Record<string, unknown>;
40
+ export declare function mercuryNonce(): string;
41
+ export declare function mercuryShapeMessages(o: {
42
+ readonly personWords: string;
43
+ readonly nonce: string;
44
+ }): LLMMessage[];
45
+ export declare function parseMercuryShape(raw: unknown): Result<MercuryShape>;
46
+ export declare function fixMercuryShape(shape: MercuryShape, personWords: string): MercuryShape;
47
+ export declare const MERCURY_EXEMPLAR_FIELD = "## How to read this field\n\nEvery brief has the same parts, in this order. Below, each part is shown as a SPREAD of alternatives, side by side. Each row is tagged with the ownership archetype it fits:\n\n- [personal] one person's own tool: private, records keyed to their own object so a friend could be let in later.\n- [group] a named set of people (friends, family, team, club, housemates): the owner invites them by handle, members read and write; the invite screen is part of this first build.\n- [publish] the owner writes, everyone reads: a blog, menu, gallery, zine, schedule.\n- [intake] strangers submit without signing in (orders, bookings, requests, RSVPs); the owner sees and manages what came in.\n- [open] anyone with the link joins and writes their own bit: a shared wall, a canvas, a leaderboard game. Each person edits what they made.\n- [toy] a game or visual that keeps little or nothing: scores or a save slot at most.\n\nPick the rows that match the archetype you were given. Take every noun from the person's own words.\n\n## 1. Opening \u2014 one sentence: what it is and who it is for\n\n- [personal] A glaze test notebook for a home potter.\n- [personal] A sourdough starter log for one baker's kitchen.\n- [group] A tool library for one neighbourhood block, shared by the households on it.\n- [group] A setlist planner for a four-piece cover band.\n- [publish] A taco truck menu board the owner updates from their phone and customers read.\n- [publish] A micro-poetry zine where one editor posts and everyone reads.\n- [intake] An appointment book for a dog grooming salon: clients book without signing up, the groomer sees every slot.\n- [intake] A repair drop-off form for a bike shop, with the owner's queue on the other side.\n- [open] A lost-and-found board for a music festival that anyone with the link can post to.\n- [open] A wedding photo wall where every guest drops pictures from their phone.\n- [toy] A hex-grid pong game with a slow-motion ball and a local best score.\n- [toy] A kaleidoscope you steer with the mouse, with nothing saved.\n\n## 2. Ownership and access \u2014 who owns what, who gets in, who sees what\n\n- [personal] Each signed-in person has their own notebook object (keyed on their handle, named for the app, renameable in settings); glazes and tiles carry the notebook id so a studio mate could be let in later. The creator reads and writes it alone.\n- [personal] The person's own starter log is ready on arrival. Feedings belong to that log; rules key on its creator, so the entries stay theirs, shaped so a housemate could be admitted later.\n- [group] Each signed-in person starts with their own block library object. Households are let in with the platform's HandleInput invite screen, which writes a membership into the library; members read every tool and write their own loans. The library list shows shared ones with ViewerTag.\n- [group] The owner's band object holds memberships for the other three players, written by the HandleInput invite screen. Any member adds songs and reorders the set; the creator manages members and deletes songs.\n- [publish] The owner's menu object is keyed on their handle. Menu items are written by the owner and readable by everyone, signed in or not. Shaped so a co-owner could be let in later.\n- [publish] One editor owns the zine; poem records are creator-writable and world-readable. Readers see the issues.\n- [intake] Two sides. Clients book anonymously: anyone, signed in or not, can create a booking record on the salon object and reads back the confirmation they just made. The groomer, signed in as the salon's owner, reads and updates every booking.\n- [intake] Drop-off requests are created by visitors without accounts; each request is readable by the shop owner (and staff let in later by membership). The public form page shows the visitor their own request.\n- [open] The owner creates the board and names it for the app. Any visitor with the link reads the whole board and writes their own posts; each poster edits or removes what they wrote, keyed on the record's creator. The board creator can remove anything.\n- [open] Anyone with the link uploads photos to the wall; everyone reads; a photo is deletable by whoever posted it or the couple who own the wall.\n- [toy] Each signed-in player keeps a best score record keyed on their handle; a shared Top Scores list shows everyone's best with ViewerTag.\n- [toy] The toy keeps its state in memory: it opens instantly, with no sign-in and no records.\n\n## 3. Seed cast \u2014 seed.json demo with a named cast, counts and dates near today\n\n- [personal] seed.json demo: the owner's notebook plus 5 glazes (Tenmoku, Shino, Celadon, Chun blue, Ash) and 9 tiles fired between 2026-09-20 and 2026-10-05, two rated 5.\n- [personal] seed.json demo: one starter \"Gus\" born 2026-03-02 with 10 feedings over the last two weeks, rise heights between 3 and 7 cm.\n- [group] seed.json demo: the owner's library \"Maple Street Tools\" with the owner's own membership plus @priya and @tomas, 8 tools (a ladder, a tile saw, a pressure washer...), two loans out due this week and one returned.\n- [group] seed.json demo: the band \"Low Tide\" with the owner's membership and three members (@dee, @marco, @sun), 14 songs with keys and bpm, one setlist for a gig dated 2026-10-18.\n- [publish] seed.json demo: the owner's menu with 6 items across tacos, sides and drinks, one marked sold out, and a note of the day dated 2026-10-07.\n- [intake] seed.json demo: the owner's salon with 7 bookings spread over 2026-10-07 to 2026-10-11 in mixed statuses, dog names like Biscuit and Juno.\n- [open] seed.json demo: the festival board with 9 posts from five handles, five lost and four found, two already resolved, dated across the last three days.\n- [toy] seed.json demo: 6 score records from a small cast including the owner so the Top Scores list opens filled.\n\n## 4. Look note \u2014 one short line: background, accent, card shape, mood\n\n- [personal] Earthy studio: oatmeal background, iron-red accents, chunky rounded tile cards.\n- [personal] Flour-dusted kitchen: warm white, rye brown, a tall rising bar as the hero number.\n- [group] Workshop pegboard: plywood tones, safety-orange accents, square tool cards with big status chips.\n- [group] Backstage: near-black, amber stage light accents, setlist rows like gaffer-tape strips.\n- [publish] Street-food bright: chalkboard dark with chalk-white type and chili-red price tags.\n- [intake] Clean salon: pale mint, charcoal type, generous slot buttons easy to tap one-handed.\n- [open] Festival poster: cream paper, bold two-colour print, pinned-note cards with torn edges.\n- [toy] Neon arcade: deep navy, electric cyan ball, glowing hex outlines.\n\n## 5. Titles, addresses and icon\n\n- pairs: Glaze Ledger / glaze-ledger, Tile Book / tile-book, Kiln Notes / kiln-notes \u2014 icon: a glazed test tile beside a small kiln\n- pairs: Block Tools / block-tools, Maple Street Shelf / maple-street-shelf, Borrow Board / borrow-board \u2014 icon: a hand drill inside a house outline\n- pairs: Truck Board / truck-board, Taco Today / taco-today, Menu Chalk / menu-chalk \u2014 icon: a chalkboard with a taco drawn on it\n- pairs: Groom Book / groom-book, Salon Slots / salon-slots, Paws Diary / paws-diary \u2014 icon: a dog brush beside a clock face\n- pairs: Festival Finds / festival-finds, Lost Tent / lost-tent, Found It / found-it \u2014 icon: a tent peg tied with a ribbon\n- pairs: Hex Pong / hex-pong, Slow Rally / slow-rally, Honey Paddle / honey-paddle \u2014 icon: a hexagonal paddle and a glowing ball";
48
+ export declare const MERCURY_BRIEF_RULES = "You write the settled parts of a build brief for a small web app (React, a local-first database, access rules). The brief is read by a builder, who works out the records, screens and mechanics from the person's own words. Write plain, concrete prose in the app's own nouns, as unformatted text in each JSON string.\n\nThe decisions already made are given in the user message; follow them (archetype, record names, capabilities). The access part matches the archetype: who owns the object, who else is let in, what visitors see. The seed part starts with \"seed.json demo:\" and gives a named cast, counts and dates near today, using the given record names. Take from the field the SHAPE of a part (its length and how a cast, a look or a title is named); every noun comes from the person's words. Each pair is a Title Case title of two or three words and a kebab-case address made from it.";
49
+ export declare function mercuryBriefSchema(fields: readonly MercuryBriefField[]): Record<string, unknown>;
50
+ export declare function mercuryBriefMessages(o: {
51
+ readonly personWords: string;
52
+ readonly shape: MercuryShape;
53
+ readonly fields: readonly MercuryBriefField[];
54
+ readonly words: readonly string[];
55
+ readonly today: string;
56
+ readonly nonce: string;
57
+ }): LLMMessage[];
58
+ export declare function cleanMercuryText(text: string): string;
59
+ export declare function gateMercuryPairs(raw: unknown): Result<{
60
+ readonly title: string;
61
+ readonly slug: string;
62
+ }[]>;
63
+ export declare function gateMercuryField(o: {
64
+ readonly field: Exclude<MercuryBriefField, "pairs">;
65
+ readonly value: string;
66
+ readonly shape: MercuryShape;
67
+ }): string[];
68
+ export declare const MERCURY_ACCESS_TAIL: Readonly<Record<MercuryArchetype, string>>;
69
+ export declare function mercuryAccessLine(shape: MercuryShape, access: string): string;
70
+ export declare function mercurySkills(shape: MercuryShape): string[];
71
+ export declare function mercuryNature(shape: MercuryShape): AppNature;
72
+ export declare function mercuryWorkflowLine(shape: MercuryShape): string;
73
+ export declare function assembleMercuryCreateVibe(o: {
74
+ readonly personWords: string;
75
+ readonly shape: MercuryShape;
76
+ readonly fields: MercuryBriefFields;
77
+ }): CreateVibeToolInput;
78
+ export declare const MERCURY_PREAMBLE_SYSTEM = "You speak to the person who asked for an app, just before it is built. Write two or three plain sentences in their own words: what you are making for them, its core action, and the big control on its first screen that does it. That is the whole promise \u2014 the builder works out everything else after you speak. Start with \"I'm making\" or \"I'm building\", and write it as plain sentences to the person.";
79
+ export declare function mercuryPreambleMessages(o: {
80
+ readonly personWords: string;
81
+ readonly shape: MercuryShape;
82
+ readonly enrichedPrompt: string;
83
+ readonly nonce: string;
84
+ }): LLMMessage[];
85
+ export declare function mercuryPreambleSchema(): Record<string, unknown>;
86
+ export declare function gateMercuryPreamble(o: {
87
+ readonly text: string;
88
+ readonly enrichedPrompt: string;
89
+ }): string[];
90
+ export interface MercuryUsage {
91
+ readonly prompt_tokens: number;
92
+ readonly completion_tokens: number;
93
+ readonly total_tokens: number;
94
+ readonly cost?: number;
95
+ }
96
+ export type MercuryCallName = "shape" | "brief" | "preamble";
97
+ export interface MercuryCallRecord {
98
+ readonly call: MercuryCallName;
99
+ readonly ok: boolean;
100
+ readonly attempts: number;
101
+ readonly elapsedMs: number;
102
+ readonly servedModel?: string;
103
+ readonly usage: readonly MercuryUsage[];
104
+ readonly error?: string;
105
+ }
106
+ export interface MercuryFirstBuild {
107
+ readonly input: CreateVibeToolInput;
108
+ readonly preamble: string;
109
+ readonly shape: MercuryShape;
110
+ readonly elapsedMs: number;
111
+ }
112
+ export interface RunMercuryFirstBuildArgs {
113
+ readonly chatId: string;
114
+ readonly userId: string;
115
+ readonly personWords: string;
116
+ readonly words: readonly string[];
117
+ readonly deadlineMs?: number;
118
+ readonly nonce?: () => string;
119
+ readonly today?: string;
120
+ }
121
+ export declare function runMercuryFirstBuild(vctx: VibesApiSQLCtx, args: RunMercuryFirstBuildArgs): Promise<Result<MercuryFirstBuild>>;