@dbx-tools/shared-generator 0.0.0-stage → 0.9.136

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.
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Browser-safe contracts and client for AppKit brand generation.
3
+ *
4
+ * @module
5
+ */
6
+ import { BrandContextSchema } from "@dbx-tools/shared-core/brand-utils";
7
+ import { z } from "zod";
8
+ const nonBlankString = z.string().trim().min(1);
9
+ /** Registered AppKit generator plugin name. */
10
+ export const GENERATOR_PLUGIN_NAME = "generator";
11
+ /** Default route prefix published by the generator plugin. */
12
+ export const GENERATOR_BASE_PATH = `/api/${GENERATOR_PLUGIN_NAME}`;
13
+ /** Mount-relative route segments owned by the generator plugin. */
14
+ export const GENERATOR_ROUTES = {
15
+ generateBrand: "/brand/generate",
16
+ };
17
+ /** Input accepted by brand generation. */
18
+ export const BrandGenerationRequestSchema = z
19
+ .object({
20
+ name: nonBlankString
21
+ .max(200)
22
+ .optional()
23
+ .describe("Known brand, organization, or product name."),
24
+ prompt: nonBlankString
25
+ .max(2_000)
26
+ .optional()
27
+ .describe("Open-ended brand brief used for research and generation."),
28
+ website: z
29
+ .string()
30
+ .url()
31
+ .refine((value) => new URL(value).protocol === "https:", "Expected an HTTPS website URL.")
32
+ .optional()
33
+ .describe("Known official website used to disambiguate the brand."),
34
+ })
35
+ .strict()
36
+ .refine((value) => value.name !== undefined || value.prompt !== undefined, {
37
+ message: "Brand generation requires a name or prompt.",
38
+ })
39
+ .describe("Request to research one brand and generate its portable branding package.");
40
+ /** A cited source and whether its page content was available to synthesis. */
41
+ export const BrandPackageSourceSchema = z
42
+ .object({
43
+ url: z.string().url().describe("Source URL used during brand research."),
44
+ title: nonBlankString.optional().describe("Source page title, when available."),
45
+ snippet: nonBlankString.optional().describe("Search-result excerpt, when available."),
46
+ fetched: z
47
+ .boolean()
48
+ .describe("True when web_fetch returned page content used during synthesis."),
49
+ })
50
+ .strict()
51
+ .describe("Web source used to research the generated brand.");
52
+ /** One fetched mobile-app image used as visual brand research. */
53
+ export const BrandVisualImageSchema = z
54
+ .object({
55
+ url: z.string().url().describe("Original mobile-store image URL."),
56
+ contentType: z.string().optional().describe("Fetched image media type."),
57
+ localPath: z
58
+ .string()
59
+ .optional()
60
+ .describe("Package-relative exported image path, when written by a CLI."),
61
+ })
62
+ .strict()
63
+ .describe("Mobile-store image reference used for brand inspiration.");
64
+ /** App Store or Play Store page and its visual references. */
65
+ export const BrandVisualReferenceSchema = z
66
+ .object({
67
+ platform: z.enum(["ios", "android"]).describe("Mobile application platform."),
68
+ appName: nonBlankString.describe("Application name read from the store page."),
69
+ pageUrl: z.string().url().describe("Official application-store page."),
70
+ images: z.array(BrandVisualImageSchema).describe("Fetched app icon or screenshots."),
71
+ })
72
+ .strict()
73
+ .describe("Mobile application visuals consulted during brand research.");
74
+ /** Portable generated brand context with research provenance. */
75
+ export const BrandPackageSchema = z
76
+ .object({
77
+ brand: BrandContextSchema.describe("Portable brand context ready for @dbx-tools UI and email consumers."),
78
+ sources: z
79
+ .array(BrandPackageSourceSchema)
80
+ .describe("Deduplicated web sources used to generate this package."),
81
+ visualReferences: z
82
+ .array(BrandVisualReferenceSchema)
83
+ .default([])
84
+ .describe("iOS and Android application visuals used for inspiration."),
85
+ })
86
+ .strict()
87
+ .describe("Generated branding package and its web research provenance.");
88
+ /** Observable stages in one brand-generation workflow. */
89
+ export const BrandGenerationStageSchema = z.enum([
90
+ "search",
91
+ "fetch",
92
+ "visuals",
93
+ "assets",
94
+ "synthesize",
95
+ ]);
96
+ /** Progress emitted while the backend researches and synthesizes a brand. */
97
+ export const BrandGenerationProgressEventSchema = z
98
+ .object({
99
+ type: z.literal("progress"),
100
+ stage: BrandGenerationStageSchema.describe("Current workflow stage."),
101
+ message: nonBlankString.describe("Short user-facing progress message."),
102
+ current: z.number().int().nonnegative().optional().describe("Completed items in this stage."),
103
+ total: z.number().int().positive().optional().describe("Total items in this stage."),
104
+ })
105
+ .strict()
106
+ .describe("Progress update from a running brand generation.");
107
+ /** Final successful brand-generation event. */
108
+ export const BrandGenerationResultEventSchema = z
109
+ .object({
110
+ type: z.literal("result"),
111
+ package: BrandPackageSchema.describe("Completed portable branding package."),
112
+ })
113
+ .strict()
114
+ .describe("Successful completion of brand generation.");
115
+ /** Final error event from a started brand-generation stream. */
116
+ export const BrandGenerationErrorEventSchema = z
117
+ .object({
118
+ type: z.literal("error"),
119
+ message: nonBlankString.describe("Actionable generation failure message."),
120
+ })
121
+ .strict()
122
+ .describe("Failure emitted after a brand-generation stream started.");
123
+ /** Every server-sent event emitted by brand generation. */
124
+ export const BrandGenerationEventSchema = z.discriminatedUnion("type", [
125
+ BrandGenerationProgressEventSchema,
126
+ BrandGenerationResultEventSchema,
127
+ BrandGenerationErrorEventSchema,
128
+ ]);
129
+ /** Browser-safe route configuration published by the AppKit generator plugin. */
130
+ export const GeneratorClientConfigSchema = z
131
+ .object({
132
+ basePath: nonBlankString.describe("Mounted API route prefix for the generator plugin."),
133
+ })
134
+ .strict()
135
+ .describe("Browser configuration published by the AppKit generator plugin.");
136
+ /** Build the brand endpoint from the generator plugin's published base path. */
137
+ export function brandGenerateUrl(basePath = GENERATOR_BASE_PATH) {
138
+ return `${basePath.replace(/\/+$/, "")}${GENERATOR_ROUTES.generateBrand}`;
139
+ }
140
+ /** Parse one complete SSE frame into its validated brand event. */
141
+ function parseEventFrame(frame) {
142
+ const data = frame
143
+ .split("\n")
144
+ .filter((line) => line.startsWith("data:"))
145
+ .map((line) => line.slice(5).trimStart())
146
+ .join("\n");
147
+ if (!data)
148
+ return undefined;
149
+ const value = JSON.parse(data);
150
+ return BrandGenerationEventSchema.parse(value);
151
+ }
152
+ /** Read a failed HTTP response without trusting its payload shape. */
153
+ async function responseError(response) {
154
+ const value = await response
155
+ .clone()
156
+ .json()
157
+ .catch(() => undefined);
158
+ if (typeof value === "object" && value !== null && "error" in value) {
159
+ const message = value.error;
160
+ if (typeof message === "string" && message.trim())
161
+ return message.trim();
162
+ }
163
+ const text = await response.text().catch(() => "");
164
+ return text.trim() || `Brand generation failed (${response.status}).`;
165
+ }
166
+ /** Browser client for the generator plugin's streamed routes. */
167
+ export class GeneratorPluginClient {
168
+ config;
169
+ /** Create a client from the plugin's published `clientConfig()` payload. */
170
+ constructor(config) {
171
+ this.config = GeneratorClientConfigSchema.parse(config);
172
+ }
173
+ /** Generate a brand while yielding validated progress and terminal events. */
174
+ async *generate(input, options = {}) {
175
+ const request = BrandGenerationRequestSchema.parse(input);
176
+ const fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);
177
+ const response = await fetcher(brandGenerateUrl(this.config.basePath), {
178
+ method: "POST",
179
+ headers: {
180
+ Accept: "text/event-stream",
181
+ "Content-Type": "application/json",
182
+ },
183
+ body: JSON.stringify(request),
184
+ ...(options.signal ? { signal: options.signal } : {}),
185
+ });
186
+ if (!response.ok)
187
+ throw new Error(await responseError(response));
188
+ if (!response.body)
189
+ throw new Error("Brand generation returned no event stream.");
190
+ const reader = response.body.getReader();
191
+ const decoder = new TextDecoder();
192
+ let buffer = "";
193
+ for (;;) {
194
+ const { done, value } = await reader.read();
195
+ buffer += decoder.decode(value, { stream: !done }).replaceAll("\r\n", "\n");
196
+ let boundary = buffer.indexOf("\n\n");
197
+ while (boundary >= 0) {
198
+ const event = parseEventFrame(buffer.slice(0, boundary));
199
+ if (event)
200
+ yield event;
201
+ buffer = buffer.slice(boundary + 2);
202
+ boundary = buffer.indexOf("\n\n");
203
+ }
204
+ if (done)
205
+ break;
206
+ }
207
+ const event = parseEventFrame(buffer.trim());
208
+ if (event)
209
+ yield event;
210
+ }
211
+ }
212
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJhbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnJhbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFFeEIsTUFBTSxjQUFjLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVoRCwrQ0FBK0M7QUFDL0MsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsV0FBVyxDQUFDO0FBRWpELDhEQUE4RDtBQUM5RCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxRQUFRLHFCQUFxQixFQUFFLENBQUM7QUFFbkUsbUVBQW1FO0FBQ25FLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHO0lBQzlCLGFBQWEsRUFBRSxpQkFBaUI7Q0FDeEIsQ0FBQztBQUVYLDBDQUEwQztBQUMxQyxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRyxDQUFDO0tBQzFDLE1BQU0sQ0FBQztJQUNOLElBQUksRUFBRSxjQUFjO1NBQ2pCLEdBQUcsQ0FBQyxHQUFHLENBQUM7U0FDUixRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsNkNBQTZDLENBQUM7SUFDMUQsTUFBTSxFQUFFLGNBQWM7U0FDbkIsR0FBRyxDQUFDLEtBQUssQ0FBQztTQUNWLFFBQVEsRUFBRTtTQUNWLFFBQVEsQ0FBQywwREFBMEQsQ0FBQztJQUN2RSxPQUFPLEVBQUUsQ0FBQztTQUNQLE1BQU0sRUFBRTtTQUNSLEdBQUcsRUFBRTtTQUNMLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxnQ0FBZ0MsQ0FBQztTQUN6RixRQUFRLEVB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LENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM1RSxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RDLE9BQU8sUUFBUSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNyQixNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDekQsSUFBSSxLQUFLO29CQUFFLE1BQU0sS0FBSyxDQUFDO2dCQUN2QixNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLENBQUM7WUFDRCxJQUFJLElBQUk7Z0JBQUUsTUFBTTtRQUNsQixDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLElBQUksS0FBSztZQUFFLE1BQU0sS0FBSyxDQUFDO0lBQ3pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnJvd3Nlci1zYWZlIGNvbnRyYWN0cyBhbmQgY2xpZW50IGZvciBBcHBLaXQgYnJhbmQgZ2VuZXJhdGlvbi5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgQnJhbmRDb250ZXh0U2NoZW1hIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvYnJhbmQtdXRpbHNcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmNvbnN0IG5vbkJsYW5rU3RyaW5nID0gei5zdHJpbmcoKS50cmltKCkubWluKDEpO1xuXG4vKiogUmVnaXN0ZXJlZCBBcHBLaXQgZ2VuZXJhdG9yIHBsdWdpbiBuYW1lLiAqL1xuZXhwb3J0IGNvbnN0IEdFTkVSQVRPUl9QTFVHSU5fTkFNRSA9IFwiZ2VuZXJhdG9yXCI7XG5cbi8qKiBEZWZhdWx0IHJvdXRlIHByZWZpeCBwdWJsaXNoZWQgYnkgdGhlIGdlbmVyYXRvciBwbHVnaW4uICovXG5leHBvcnQgY29uc3QgR0VORVJBVE9SX0JBU0VfUEFUSCA9IGAvYXBpLyR7R0VORVJBVE9SX1BMVUdJTl9OQU1FfWA7XG5cbi8qKiBNb3VudC1yZWxhdGl2ZSByb3V0ZSBzZWdtZW50cyBvd25lZCBieSB0aGUgZ2VuZXJhdG9yIHBsdWdpbi4gKi9cbmV4cG9ydCBjb25zdCBHRU5FUkFUT1JfUk9VVEVTID0ge1xuICBnZW5lcmF0ZUJyYW5kOiBcIi9icmFuZC9nZW5lcmF0ZVwiLFxufSBhcyBjb25zdDtcblxuLyoqIElucHV0IGFjY2VwdGVkIGJ5IGJyYW5kIGdlbmVyYXRpb24uICovXG5leHBvcnQgY29uc3QgQnJhbmRHZW5lcmF0aW9uUmVxdWVzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgbmFtZTogbm9uQmxhbmtTdHJpbmdcbiAgICAgIC5tYXgoMjAwKVxuICAgICAgLm9wdGlvbmFsKClcbiAgICAgIC5kZXNjcmliZShcIktub3duIGJyYW5kLCBvcmdhbml6YXRpb24sIG9yIHByb2R1Y3QgbmFtZS5cIiksXG4gICAgcHJvbXB0OiBub25CbGFua1N0cmluZ1xuICAgICAgLm1heCgyXzAwMClcbiAgICAgIC5vcHRpb25hbCgpXG4gICAgICAuZGVzY3JpYmUoXCJPcGVuLWVuZGVkIGJyYW5kIGJyaWVmIHVzZWQgZm9yIHJlc2VhcmNoIGFuZCBnZW5lcmF0aW9uLlwiKSxcbiAgICB3ZWJzaXRlOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC51cmwoKVxuICAgICAgLnJlZmluZSgodmFsdWUpID0+IG5ldyBVUkwodmFsdWUpLnByb3RvY29sID09PSBcImh0dHBzOlwiLCBcIkV4cGVjdGVkIGFuIEhUVFBTIHdlYnNpdGUgVVJMLlwiKVxuICAgICAgLm9wdGlvbmFsKClcbiAgICAgIC5kZXNjcmliZShcIktub3duIG9mZmljaWFsIHdlYnNpdGUgdXNlZCB0byBkaXNhbWJpZ3VhdGUgdGhlIGJyYW5kLlwiKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5yZWZpbmUoKHZhbHVlKSA9PiB2YWx1ZS5uYW1lICE9PSB1bmRlZmluZWQgfHwgdmFsdWUucHJvbXB0ICE9PSB1bmRlZmluZWQsIHtcbiAgICBtZXNzYWdlOiBcIkJyYW5kIGdlbmVyYXRpb24gcmVxdWlyZXMgYSBuYW1lIG9yIHByb21wdC5cIixcbiAgfSlcbiAgLmRlc2NyaWJlKFwiUmVxdWVzdCB0byByZXNlYXJjaCBvbmUgYnJhbmQgYW5kIGdlbmVyYXRlIGl0cyBwb3J0YWJsZSBicmFuZGluZyBwYWNrYWdlLlwiKTtcblxuLyoqIFZhbGlkYXRlZCBicmFuZC1nZW5lcmF0aW9uIHJlcXVlc3QuICovXG5leHBvcnQgdHlwZSBCcmFuZEdlbmVyYXRpb25SZXF1ZXN0ID0gei5pbmZlcjx0eXBlb2YgQnJhbmRHZW5lcmF0aW9uUmVxdWVzdFNjaGVtYT47XG5cbi8qKiBBIGNpdGVkIHNvdXJjZSBhbmQgd2hldGhlciBpdHMgcGFnZSBjb250ZW50IHdhcyBhdmFpbGFibGUgdG8gc3ludGhlc2lzLiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kUGFja2FnZVNvdXJjZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgdXJsOiB6LnN0cmluZygpLnVybCgpLmRlc2NyaWJlKFwiU291cmNlIFVSTCB1c2VkIGR1cmluZyBicmFuZCByZXNlYXJjaC5cIiksXG4gICAgdGl0bGU6IG5vbkJsYW5rU3RyaW5nLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJTb3VyY2UgcGFnZSB0aXRsZSwgd2hlbiBhdmFpbGFibGUuXCIpLFxuICAgIHNuaXBwZXQ6IG5vbkJsYW5rU3RyaW5nLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJTZWFyY2gtcmVzdWx0IGV4Y2VycHQsIHdoZW4gYXZhaWxhYmxlLlwiKSxcbiAgICBmZXRjaGVkOiB6XG4gICAgICAuYm9vbGVhbigpXG4gICAgICAuZGVzY3JpYmUoXCJUcnVlIHdoZW4gd2ViX2ZldGNoIHJldHVybmVkIHBhZ2UgY29udGVudCB1c2VkIGR1cmluZyBzeW50aGVzaXMuXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiV2ViIHNvdXJjZSB1c2VkIHRvIHJlc2VhcmNoIHRoZSBnZW5lcmF0ZWQgYnJhbmQuXCIpO1xuXG4vKiogU291cmNlIHByb3ZlbmFuY2UgaW5jbHVkZWQgaW4gYSBnZW5lcmF0ZWQgYnJhbmRpbmcgcGFja2FnZS4gKi9cbmV4cG9ydCB0eXBlIEJyYW5kUGFja2FnZVNvdXJjZSA9IHouaW5mZXI8dHlwZW9mIEJyYW5kUGFja2FnZVNvdXJjZVNjaGVtYT47XG5cbi8qKiBPbmUgZmV0Y2hlZCBtb2JpbGUtYXBwIGltYWdlIHVzZWQgYXMgdmlzdWFsIGJyYW5kIHJlc2VhcmNoLiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kVmlzdWFsSW1hZ2VTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHVybDogei5zdHJpbmcoKS51cmwoKS5kZXNjcmliZShcIk9yaWdpbmFsIG1vYmlsZS1zdG9yZSBpbWFnZSBVUkwuXCIpLFxuICAgIGNvbnRlbnRUeXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJGZXRjaGVkIGltYWdlIG1lZGlhIHR5cGUuXCIpLFxuICAgIGxvY2FsUGF0aDogelxuICAgICAgLnN0cmluZygpXG4gICAgICAub3B0aW9uYWwoKVxuICAgICAgLmRlc2NyaWJlKFwiUGFja2FnZS1yZWxhdGl2ZSBleHBvcnRlZCBpbWFnZSBwYXRoLCB3aGVuIHdyaXR0ZW4gYnkgYSBDTEkuXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiTW9iaWxlLXN0b3JlIGltYWdlIHJlZmVyZW5jZSB1c2VkIGZvciBicmFuZCBpbnNwaXJhdGlvbi5cIik7XG5cbi8qKiBNb2JpbGUtc3RvcmUgaW1hZ2UgdXNlZCBhcyB2aXN1YWwgYnJhbmQgcmVzZWFyY2guICovXG5leHBvcnQgdHlwZSBCcmFuZFZpc3VhbEltYWdlID0gei5pbmZlcjx0eXBlb2YgQnJhbmRWaXN1YWxJbWFnZVNjaGVtYT47XG5cbi8qKiBBcHAgU3RvcmUgb3IgUGxheSBTdG9yZSBwYWdlIGFuZCBpdHMgdmlzdWFsIHJlZmVyZW5jZXMuICovXG5leHBvcnQgY29uc3QgQnJhbmRWaXN1YWxSZWZlcmVuY2VTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHBsYXRmb3JtOiB6LmVudW0oW1wiaW9zXCIsIFwiYW5kcm9pZFwiXSkuZGVzY3JpYmUoXCJNb2JpbGUgYXBwbGljYXRpb24gcGxhdGZvcm0uXCIpLFxuICAgIGFwcE5hbWU6IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQXBwbGljYXRpb24gbmFtZSByZWFkIGZyb20gdGhlIHN0b3JlIHBhZ2UuXCIpLFxuICAgIHBhZ2VVcmw6IHouc3RyaW5nKCkudXJsKCkuZGVzY3JpYmUoXCJPZmZpY2lhbCBhcHBsaWNhdGlvbi1zdG9yZSBwYWdlLlwiKSxcbiAgICBpbWFnZXM6IHouYXJyYXkoQnJhbmRWaXN1YWxJbWFnZVNjaGVtYSkuZGVzY3JpYmUoXCJGZXRjaGVkIGFwcCBpY29uIG9yIHNjcmVlbnNob3RzLlwiKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcIk1vYmlsZSBhcHBsaWNhdGlvbiB2aXN1YWxzIGNvbnN1bHRlZCBkdXJpbmcgYnJhbmQgcmVzZWFyY2guXCIpO1xuXG4vKiogTW9iaWxlLXN0b3JlIGJyYW5kIHJlc2VhcmNoIHJlZmVyZW5jZS4gKi9cbmV4cG9ydCB0eXBlIEJyYW5kVmlzdWFsUmVmZXJlbmNlID0gei5pbmZlcjx0eXBlb2YgQnJhbmRWaXN1YWxSZWZlcmVuY2VTY2hlbWE+O1xuXG4vKiogUG9ydGFibGUgZ2VuZXJhdGVkIGJyYW5kIGNvbnRleHQgd2l0aCByZXNlYXJjaCBwcm92ZW5hbmNlLiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kUGFja2FnZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgYnJhbmQ6IEJyYW5kQ29udGV4dFNjaGVtYS5kZXNjcmliZShcbiAgICAgIFwiUG9ydGFibGUgYnJhbmQgY29udGV4dCByZWFkeSBmb3IgQGRieC10b29scyBVSSBhbmQgZW1haWwgY29uc3VtZXJzLlwiLFxuICAgICksXG4gICAgc291cmNlczogelxuICAgICAgLmFycmF5KEJyYW5kUGFja2FnZVNvdXJjZVNjaGVtYSlcbiAgICAgIC5kZXNjcmliZShcIkRlZHVwbGljYXRlZCB3ZWIgc291cmNlcyB1c2VkIHRvIGdlbmVyYXRlIHRoaXMgcGFja2FnZS5cIiksXG4gICAgdmlzdWFsUmVmZXJlbmNlczogelxuICAgICAgLmFycmF5KEJyYW5kVmlzdWFsUmVmZXJlbmNlU2NoZW1hKVxuICAgICAgLmRlZmF1bHQoW10pXG4gICAgICAuZGVzY3JpYmUoXCJpT1MgYW5kIEFuZHJvaWQgYXBwbGljYXRpb24gdmlzdWFscyB1c2VkIGZvciBpbnNwaXJhdGlvbi5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJHZW5lcmF0ZWQgYnJhbmRpbmcgcGFja2FnZSBhbmQgaXRzIHdlYiByZXNlYXJjaCBwcm92ZW5hbmNlLlwiKTtcblxuLyoqIEdlbmVyYXRlZCBicmFuZGluZyBwYWNrYWdlLiAqL1xuZXhwb3J0IHR5cGUgQnJhbmRQYWNrYWdlID0gei5pbmZlcjx0eXBlb2YgQnJhbmRQYWNrYWdlU2NoZW1hPjtcblxuLyoqIE9ic2VydmFibGUgc3RhZ2VzIGluIG9uZSBicmFuZC1nZW5lcmF0aW9uIHdvcmtmbG93LiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kR2VuZXJhdGlvblN0YWdlU2NoZW1hID0gei5lbnVtKFtcbiAgXCJzZWFyY2hcIixcbiAgXCJmZXRjaFwiLFxuICBcInZpc3VhbHNcIixcbiAgXCJhc3NldHNcIixcbiAgXCJzeW50aGVzaXplXCIsXG5dKTtcblxuLyoqIE9ic2VydmFibGUgYnJhbmQtZ2VuZXJhdGlvbiBzdGFnZS4gKi9cbmV4cG9ydCB0eXBlIEJyYW5kR2VuZXJhdGlvblN0YWdlID0gei5pbmZlcjx0eXBlb2YgQnJhbmRHZW5lcmF0aW9uU3RhZ2VTY2hlbWE+O1xuXG4vKiogUHJvZ3Jlc3MgZW1pdHRlZCB3aGlsZSB0aGUgYmFja2VuZCByZXNlYXJjaGVzIGFuZCBzeW50aGVzaXplcyBhIGJyYW5kLiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kR2VuZXJhdGlvblByb2dyZXNzRXZlbnRTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbChcInByb2dyZXNzXCIpLFxuICAgIHN0YWdlOiBCcmFuZEdlbmVyYXRpb25TdGFnZVNjaGVtYS5kZXNjcmliZShcIkN1cnJlbnQgd29ya2Zsb3cgc3RhZ2UuXCIpLFxuICAgIG1lc3NhZ2U6IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiU2hvcnQgdXNlci1mYWNpbmcgcHJvZ3Jlc3MgbWVzc2FnZS5cIiksXG4gICAgY3VycmVudDogei5udW1iZXIoKS5pbnQoKS5ub25uZWdhdGl2ZSgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJDb21wbGV0ZWQgaXRlbXMgaW4gdGhpcyBzdGFnZS5cIiksXG4gICAgdG90YWw6IHoubnVtYmVyKCkuaW50KCkucG9zaXRpdmUoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiVG90YWwgaXRlbXMgaW4gdGhpcyBzdGFnZS5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJQcm9ncmVzcyB1cGRhdGUgZnJvbSBhIHJ1bm5pbmcgYnJhbmQgZ2VuZXJhdGlvbi5cIik7XG5cbi8qKiBQcm9ncmVzcyBldmVudCBlbWl0dGVkIGR1cmluZyBicmFuZCBnZW5lcmF0aW9uLiAqL1xuZXhwb3J0IHR5cGUgQnJhbmRHZW5lcmF0aW9uUHJvZ3Jlc3NFdmVudCA9IHouaW5mZXI8dHlwZW9mIEJyYW5kR2VuZXJhdGlvblByb2dyZXNzRXZlbnRTY2hlbWE+O1xuXG4vKiogRmluYWwgc3VjY2Vzc2Z1bCBicmFuZC1nZW5lcmF0aW9uIGV2ZW50LiAqL1xuZXhwb3J0IGNvbnN0IEJyYW5kR2VuZXJhdGlvblJlc3VsdEV2ZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoXCJyZXN1bHRcIiksXG4gICAgcGFja2FnZTogQnJhbmRQYWNrYWdlU2NoZW1hLmRlc2NyaWJlKFwiQ29tcGxldGVkIHBvcnRhYmxlIGJyYW5kaW5nIHBhY2thZ2UuXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiU3VjY2Vzc2Z1bCBjb21wbGV0aW9uIG9mIGJyYW5kIGdlbmVyYXRpb24uXCIpO1xuXG4vKiogRmluYWwgc3VjY2Vzc2Z1bCBicmFuZC1nZW5lcmF0aW9uIGV2ZW50LiAqL1xuZXhwb3J0IHR5cGUgQnJhbmRHZW5lcmF0aW9uUmVzdWx0RXZlbnQgPSB6LmluZmVyPHR5cGVvZiBCcmFuZEdlbmVyYXRpb25SZXN1bHRFdmVudFNjaGVtYT47XG5cbi8qKiBGaW5hbCBlcnJvciBldmVudCBmcm9tIGEgc3RhcnRlZCBicmFuZC1nZW5lcmF0aW9uIHN0cmVhbS4gKi9cbmV4cG9ydCBjb25zdCBCcmFuZEdlbmVyYXRpb25FcnJvckV2ZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoXCJlcnJvclwiKSxcbiAgICBtZXNzYWdlOiBub25CbGFua1N0cmluZy5kZXNjcmliZShcIkFjdGlvbmFibGUgZ2VuZXJhdGlvbiBmYWlsdXJlIG1lc3NhZ2UuXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiRmFpbHVyZSBlbWl0dGVkIGFmdGVyIGEgYnJhbmQtZ2VuZXJhdGlvbiBzdHJlYW0gc3RhcnRlZC5cIik7XG5cbi8qKiBGaW5hbCBlcnJvciBldmVudCBmcm9tIGEgc3RhcnRlZCBicmFuZC1nZW5lcmF0aW9uIHN0cmVhbS4gKi9cbmV4cG9ydCB0eXBlIEJyYW5kR2VuZXJhdGlvbkVycm9yRXZlbnQgPSB6LmluZmVyPHR5cGVvZiBCcmFuZEdlbmVyYXRpb25FcnJvckV2ZW50U2NoZW1hPjtcblxuLyoqIEV2ZXJ5IHNlcnZlci1zZW50IGV2ZW50IGVtaXR0ZWQgYnkgYnJhbmQgZ2VuZXJhdGlvbi4gKi9cbmV4cG9ydCBjb25zdCBCcmFuZEdlbmVyYXRpb25FdmVudFNjaGVtYSA9IHouZGlzY3JpbWluYXRlZFVuaW9uKFwidHlwZVwiLCBbXG4gIEJyYW5kR2VuZXJhdGlvblByb2dyZXNzRXZlbnRTY2hlbWEsXG4gIEJyYW5kR2VuZXJhdGlvblJlc3VsdEV2ZW50U2NoZW1hLFxuICBCcmFuZEdlbmVyYXRpb25FcnJvckV2ZW50U2NoZW1hLFxuXSk7XG5cbi8qKiBTZXJ2ZXItc2VudCBldmVudCBlbWl0dGVkIGJ5IGJyYW5kIGdlbmVyYXRpb24uICovXG5leHBvcnQgdHlwZSBCcmFuZEdlbmVyYXRpb25FdmVudCA9IHouaW5mZXI8dHlwZW9mIEJyYW5kR2VuZXJhdGlvbkV2ZW50U2NoZW1hPjtcblxuLyoqIEJyb3dzZXItc2FmZSByb3V0ZSBjb25maWd1cmF0aW9uIHB1Ymxpc2hlZCBieSB0aGUgQXBwS2l0IGdlbmVyYXRvciBwbHVnaW4uICovXG5leHBvcnQgY29uc3QgR2VuZXJhdG9yQ2xpZW50Q29uZmlnU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBiYXNlUGF0aDogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJNb3VudGVkIEFQSSByb3V0ZSBwcmVmaXggZm9yIHRoZSBnZW5lcmF0b3IgcGx1Z2luLlwiKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcIkJyb3dzZXIgY29uZmlndXJhdGlvbiBwdWJsaXNoZWQgYnkgdGhlIEFwcEtpdCBnZW5lcmF0b3IgcGx1Z2luLlwiKTtcblxuLyoqIEJyb3dzZXItc2FmZSBnZW5lcmF0b3IgcGx1Z2luIHJvdXRlIGNvbmZpZ3VyYXRpb24uICovXG5leHBvcnQgdHlwZSBHZW5lcmF0b3JDbGllbnRDb25maWcgPSB6LmluZmVyPHR5cGVvZiBHZW5lcmF0b3JDbGllbnRDb25maWdTY2hlbWE+O1xuXG4vKiogT3B0aW9ucyBmb3Igb25lIGJyb3dzZXIgYnJhbmQtZ2VuZXJhdGlvbiBzdHJlYW0uICovXG5leHBvcnQgaW50ZXJmYWNlIEJyYW5kR2VuZXJhdGlvblN0cmVhbU9wdGlvbnMge1xuICAvKiogQ2FuY2VscyB0aGUgcmVxdWVzdCBhbmQgcmVzcG9uc2Ugc3RyZWFtLiAqL1xuICBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgLyoqIEZldGNoIGltcGxlbWVudGF0aW9uLiBEZWZhdWx0cyB0byB0aGUgYnJvd3NlciBnbG9iYWwuICovXG4gIGZldGNoPzogdHlwZW9mIGdsb2JhbFRoaXMuZmV0Y2g7XG59XG5cbi8qKiBCdWlsZCB0aGUgYnJhbmQgZW5kcG9pbnQgZnJvbSB0aGUgZ2VuZXJhdG9yIHBsdWdpbidzIHB1Ymxpc2hlZCBiYXNlIHBhdGguICovXG5leHBvcnQgZnVuY3Rpb24gYnJhbmRHZW5lcmF0ZVVybChiYXNlUGF0aDogc3RyaW5nID0gR0VORVJBVE9SX0JBU0VfUEFUSCk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtiYXNlUGF0aC5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpfSR7R0VORVJBVE9SX1JPVVRFUy5nZW5lcmF0ZUJyYW5kfWA7XG59XG5cbi8qKiBQYXJzZSBvbmUgY29tcGxldGUgU1NFIGZyYW1lIGludG8gaXRzIHZhbGlkYXRlZCBicmFuZCBldmVudC4gKi9cbmZ1bmN0aW9uIHBhcnNlRXZlbnRGcmFtZShmcmFtZTogc3RyaW5nKTogQnJhbmRHZW5lcmF0aW9uRXZlbnQgfCB1bmRlZmluZWQge1xuICBjb25zdCBkYXRhID0gZnJhbWVcbiAgICAuc3BsaXQoXCJcXG5cIilcbiAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lLnN0YXJ0c1dpdGgoXCJkYXRhOlwiKSlcbiAgICAubWFwKChsaW5lKSA9PiBsaW5lLnNsaWNlKDUpLnRyaW1TdGFydCgpKVxuICAgIC5qb2luKFwiXFxuXCIpO1xuICBpZiAoIWRhdGEpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHZhbHVlOiB1bmtub3duID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgcmV0dXJuIEJyYW5kR2VuZXJhdGlvbkV2ZW50U2NoZW1hLnBhcnNlKHZhbHVlKTtcbn1cblxuLyoqIFJlYWQgYSBmYWlsZWQgSFRUUCByZXNwb25zZSB3aXRob3V0IHRydXN0aW5nIGl0cyBwYXlsb2FkIHNoYXBlLiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzcG9uc2VFcnJvcihyZXNwb25zZTogUmVzcG9uc2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB2YWx1ZTogdW5rbm93biA9IGF3YWl0IHJlc3BvbnNlXG4gICAgLmNsb25lKClcbiAgICAuanNvbigpXG4gICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgXCJlcnJvclwiIGluIHZhbHVlKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IHZhbHVlLmVycm9yO1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiAmJiBtZXNzYWdlLnRyaW0oKSkgcmV0dXJuIG1lc3NhZ2UudHJpbSgpO1xuICB9XG4gIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCkuY2F0Y2goKCkgPT4gXCJcIik7XG4gIHJldHVybiB0ZXh0LnRyaW0oKSB8fCBgQnJhbmQgZ2VuZXJhdGlvbiBmYWlsZWQgKCR7cmVzcG9uc2Uuc3RhdHVzfSkuYDtcbn1cblxuLyoqIEJyb3dzZXIgY2xpZW50IGZvciB0aGUgZ2VuZXJhdG9yIHBsdWdpbidzIHN0cmVhbWVkIHJvdXRlcy4gKi9cbmV4cG9ydCBjbGFzcyBHZW5lcmF0b3JQbHVnaW5DbGllbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogR2VuZXJhdG9yQ2xpZW50Q29uZmlnO1xuXG4gIC8qKiBDcmVhdGUgYSBjbGllbnQgZnJvbSB0aGUgcGx1Z2luJ3MgcHVibGlzaGVkIGBjbGllbnRDb25maWcoKWAgcGF5bG9hZC4gKi9cbiAgY29uc3RydWN0b3IoY29uZmlnOiBHZW5lcmF0b3JDbGllbnRDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IEdlbmVyYXRvckNsaWVudENvbmZpZ1NjaGVtYS5wYXJzZShjb25maWcpO1xuICB9XG5cbiAgLyoqIEdlbmVyYXRlIGEgYnJhbmQgd2hpbGUgeWllbGRpbmcgdmFsaWRhdGVkIHByb2dyZXNzIGFuZCB0ZXJtaW5hbCBldmVudHMuICovXG4gIGFzeW5jICpnZW5lcmF0ZShcbiAgICBpbnB1dDogQnJhbmRHZW5lcmF0aW9uUmVxdWVzdCxcbiAgICBvcHRpb25zOiBCcmFuZEdlbmVyYXRpb25TdHJlYW1PcHRpb25zID0ge30sXG4gICk6IEFzeW5jR2VuZXJhdG9yPEJyYW5kR2VuZXJhdGlvbkV2ZW50PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IEJyYW5kR2VuZXJhdGlvblJlcXVlc3RTY2hlbWEucGFyc2UoaW5wdXQpO1xuICAgIGNvbnN0IGZldGNoZXIgPSBvcHRpb25zLmZldGNoID8/IGdsb2JhbFRoaXMuZmV0Y2guYmluZChnbG9iYWxUaGlzKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoZXIoYnJhbmRHZW5lcmF0ZVVybCh0aGlzLmNvbmZpZy5iYXNlUGF0aCksIHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEFjY2VwdDogXCJ0ZXh0L2V2ZW50LXN0cmVhbVwiLFxuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSxcbiAgICAgIC4uLihvcHRpb25zLnNpZ25hbCA/IHsgc2lnbmFsOiBvcHRpb25zLnNpZ25hbCB9IDoge30pLFxuICAgIH0pO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHRocm93IG5ldyBFcnJvcihhd2FpdCByZXNwb25zZUVycm9yKHJlc3BvbnNlKSk7XG4gICAgaWYgKCFyZXNwb25zZS5ib2R5KSB0aHJvdyBuZXcgRXJyb3IoXCJCcmFuZCBnZW5lcmF0aW9uIHJldHVybmVkIG5vIGV2ZW50IHN0cmVhbS5cIik7XG5cbiAgICBjb25zdCByZWFkZXIgPSByZXNwb25zZS5ib2R5LmdldFJlYWRlcigpO1xuICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICBsZXQgYnVmZmVyID0gXCJcIjtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgYnVmZmVyICs9IGRlY29kZXIuZGVjb2RlKHZhbHVlLCB7IHN0cmVhbTogIWRvbmUgfSkucmVwbGFjZUFsbChcIlxcclxcblwiLCBcIlxcblwiKTtcbiAgICAgIGxldCBib3VuZGFyeSA9IGJ1ZmZlci5pbmRleE9mKFwiXFxuXFxuXCIpO1xuICAgICAgd2hpbGUgKGJvdW5kYXJ5ID49IDApIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBwYXJzZUV2ZW50RnJhbWUoYnVmZmVyLnNsaWNlKDAsIGJvdW5kYXJ5KSk7XG4gICAgICAgIGlmIChldmVudCkgeWllbGQgZXZlbnQ7XG4gICAgICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShib3VuZGFyeSArIDIpO1xuICAgICAgICBib3VuZGFyeSA9IGJ1ZmZlci5pbmRleE9mKFwiXFxuXFxuXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGRvbmUpIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBldmVudCA9IHBhcnNlRXZlbnRGcmFtZShidWZmZXIudHJpbSgpKTtcbiAgICBpZiAoZXZlbnQpIHlpZWxkIGV2ZW50O1xuICB9XG59XG4iXX0=
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Browser-safe KPI research contracts.
3
+ *
4
+ * @module
5
+ */
6
+ import { z } from "zod";
7
+ /** One evidence-backed KPI used to shape generated data and presentation. */
8
+ export declare const ResearchedKpiSchema: z.ZodObject<{
9
+ name: z.ZodString;
10
+ label: z.ZodString;
11
+ definition: z.ZodString;
12
+ unit: z.ZodEnum<{
13
+ number: "number";
14
+ currency: "currency";
15
+ percent: "percent";
16
+ duration: "duration";
17
+ }>;
18
+ targetDirection: z.ZodEnum<{
19
+ higher: "higher";
20
+ lower: "lower";
21
+ neutral: "neutral";
22
+ }>;
23
+ sourceUrls: z.ZodArray<z.ZodString>;
24
+ }, z.core.$strict>;
25
+ /** Evidence-backed KPI. */
26
+ export type ResearchedKpi = z.infer<typeof ResearchedKpiSchema>;
27
+ /** KPI research request independent of any mutation workflow. */
28
+ export declare const KpiResearchRequestSchema: z.ZodObject<{
29
+ company: z.ZodString;
30
+ purpose: z.ZodString;
31
+ queries: z.ZodArray<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ /** KPI research request. */
34
+ export type KpiResearchRequest = z.infer<typeof KpiResearchRequestSchema>;
35
+ /** KPI research result and its source provenance. */
36
+ export declare const KpiResearchResultSchema: z.ZodObject<{
37
+ kpis: z.ZodArray<z.ZodObject<{
38
+ name: z.ZodString;
39
+ label: z.ZodString;
40
+ definition: z.ZodString;
41
+ unit: z.ZodEnum<{
42
+ number: "number";
43
+ currency: "currency";
44
+ percent: "percent";
45
+ duration: "duration";
46
+ }>;
47
+ targetDirection: z.ZodEnum<{
48
+ higher: "higher";
49
+ lower: "lower";
50
+ neutral: "neutral";
51
+ }>;
52
+ sourceUrls: z.ZodArray<z.ZodString>;
53
+ }, z.core.$strict>>;
54
+ sources: z.ZodArray<z.ZodObject<{
55
+ url: z.ZodString;
56
+ title: z.ZodOptional<z.ZodString>;
57
+ fetched: z.ZodBoolean;
58
+ }, z.core.$strict>>;
59
+ }, z.core.$strict>;
60
+ /** KPI research result. */
61
+ export type KpiResearchResult = z.infer<typeof KpiResearchResultSchema>;
package/lib/src/kpi.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Browser-safe KPI research contracts.
3
+ *
4
+ * @module
5
+ */
6
+ import { z } from "zod";
7
+ const nonBlankString = z.string().trim().min(1);
8
+ const identifier = z.string().regex(/^[a-z][a-z0-9_]*$/);
9
+ /** One evidence-backed KPI used to shape generated data and presentation. */
10
+ export const ResearchedKpiSchema = z
11
+ .object({
12
+ name: identifier.describe("Stable snake_case KPI identifier."),
13
+ label: nonBlankString.describe("Human-readable KPI label."),
14
+ definition: nonBlankString.describe("Business definition supported by cited research."),
15
+ unit: z
16
+ .enum(["number", "currency", "percent", "duration"])
17
+ .describe("Display unit and formatting family."),
18
+ targetDirection: z
19
+ .enum(["higher", "lower", "neutral"])
20
+ .describe("Whether higher or lower values represent improvement."),
21
+ sourceUrls: z
22
+ .array(z.string().url())
23
+ .describe("Research sources supporting the KPI definition."),
24
+ })
25
+ .strict()
26
+ .describe("Evidence-backed KPI selected for generated demo data.");
27
+ /** KPI research request independent of any mutation workflow. */
28
+ export const KpiResearchRequestSchema = z
29
+ .object({
30
+ company: nonBlankString.max(200).describe("Company or brand being modeled."),
31
+ purpose: nonBlankString.max(200).describe("Purpose of the generated demonstration."),
32
+ queries: z
33
+ .array(nonBlankString.max(500))
34
+ .min(1)
35
+ .max(10)
36
+ .describe("Natural-language questions the generated data should answer."),
37
+ })
38
+ .strict()
39
+ .describe("Request for web-researched KPIs that shape generated demo data.");
40
+ /** KPI research result and its source provenance. */
41
+ export const KpiResearchResultSchema = z
42
+ .object({
43
+ kpis: z.array(ResearchedKpiSchema).min(1).max(8).describe("Selected KPI definitions."),
44
+ sources: z
45
+ .array(z
46
+ .object({
47
+ url: z.string().url().describe("Research source URL."),
48
+ title: nonBlankString.optional().describe("Source title, when available."),
49
+ fetched: z.boolean().describe("Whether page content was read."),
50
+ })
51
+ .strict())
52
+ .describe("Deduplicated KPI research sources."),
53
+ })
54
+ .strict()
55
+ .describe("Evidence-backed KPI research output.");
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3BpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2twaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QixNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hELE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUV6RCw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQztLQUNqQyxNQUFNLENBQUM7SUFDTixJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxtQ0FBbUMsQ0FBQztJQUM5RCxLQUFLLEVBQUUsY0FBYyxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQztJQUMzRCxVQUFVLEVBQUUsY0FBYyxDQUFDLFFBQVEsQ0FBQyxrREFBa0QsQ0FBQztJQUN2RixJQUFJLEVBQUUsQ0FBQztTQUNKLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ25ELFFBQVEsQ0FBQyxxQ0FBcUMsQ0FBQztJQUNsRCxlQUFlLEVBQUUsQ0FBQztTQUNmLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7U0FDcEMsUUFBUSxDQUFDLHVEQUF1RCxDQUFDO0lBQ3BFLFVBQVUsRUFBRSxDQUFDO1NBQ1YsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUN2QixRQUFRLENBQUMsaURBQWlELENBQUM7Q0FDL0QsQ0FBQztLQUNELE1BQU0sRUFBRTtLQUNSLFFBQVEsQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO0FBS3JFLGlFQUFpRTtBQUNqRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDO0tBQ3RDLE1BQU0sQ0FBQztJQUNOLE9BQU8sRUFBRSxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxpQ0FBaUMsQ0FBQztJQUM1RSxPQUFPLEVBQUUsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMseUNBQXlDLENBQUM7SUFDcEYsT0FBTyxFQUFFLENBQUM7U0FDUCxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUM5QixHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQ04sR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUNQLFFBQVEsQ0FBQyw4REFBOEQsQ0FBQztDQUM1RSxDQUFDO0tBQ0QsTUFBTSxFQUFFO0tBQ1IsUUFBUSxDQUFDLGlFQUFpRSxDQUFDLENBQUM7QUFLL0UscURBQXFEO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUM7S0FDckMsTUFBTSxDQUFDO0lBQ04sSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQztJQUN0RixPQUFPLEVBQUUsQ0FBQztTQUNQLEtBQUssQ0FDSixDQUFDO1NBQ0UsTUFBTSxDQUFDO1FBQ04sR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUM7UUFDdEQsS0FBSyxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsK0JBQStCLENBQUM7UUFDMUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUM7S0FDaEUsQ0FBQztTQUNELE1BQU0sRUFBRSxDQUNaO1NBQ0EsUUFBUSxDQUFDLG9DQUFvQyxDQUFDO0NBQ2xELENBQUM7S0FDRCxNQUFNLEVBQUU7S0FDUixRQUFRLENBQUMsc0NBQXNDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnJvd3Nlci1zYWZlIEtQSSByZXNlYXJjaCBjb250cmFjdHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmNvbnN0IG5vbkJsYW5rU3RyaW5nID0gei5zdHJpbmcoKS50cmltKCkubWluKDEpO1xuY29uc3QgaWRlbnRpZmllciA9IHouc3RyaW5nKCkucmVnZXgoL15bYS16XVthLXowLTlfXSokLyk7XG5cbi8qKiBPbmUgZXZpZGVuY2UtYmFja2VkIEtQSSB1c2VkIHRvIHNoYXBlIGdlbmVyYXRlZCBkYXRhIGFuZCBwcmVzZW50YXRpb24uICovXG5leHBvcnQgY29uc3QgUmVzZWFyY2hlZEtwaVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgbmFtZTogaWRlbnRpZmllci5kZXNjcmliZShcIlN0YWJsZSBzbmFrZV9jYXNlIEtQSSBpZGVudGlmaWVyLlwiKSxcbiAgICBsYWJlbDogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJIdW1hbi1yZWFkYWJsZSBLUEkgbGFiZWwuXCIpLFxuICAgIGRlZmluaXRpb246IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQnVzaW5lc3MgZGVmaW5pdGlvbiBzdXBwb3J0ZWQgYnkgY2l0ZWQgcmVzZWFyY2guXCIpLFxuICAgIHVuaXQ6IHpcbiAgICAgIC5lbnVtKFtcIm51bWJlclwiLCBcImN1cnJlbmN5XCIsIFwicGVyY2VudFwiLCBcImR1cmF0aW9uXCJdKVxuICAgICAgLmRlc2NyaWJlKFwiRGlzcGxheSB1bml0IGFuZCBmb3JtYXR0aW5nIGZhbWlseS5cIiksXG4gICAgdGFyZ2V0RGlyZWN0aW9uOiB6XG4gICAgICAuZW51bShbXCJoaWdoZXJcIiwgXCJsb3dlclwiLCBcIm5ldXRyYWxcIl0pXG4gICAgICAuZGVzY3JpYmUoXCJXaGV0aGVyIGhpZ2hlciBvciBsb3dlciB2YWx1ZXMgcmVwcmVzZW50IGltcHJvdmVtZW50LlwiKSxcbiAgICBzb3VyY2VVcmxzOiB6XG4gICAgICAuYXJyYXkoei5zdHJpbmcoKS51cmwoKSlcbiAgICAgIC5kZXNjcmliZShcIlJlc2VhcmNoIHNvdXJjZXMgc3VwcG9ydGluZyB0aGUgS1BJIGRlZmluaXRpb24uXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiRXZpZGVuY2UtYmFja2VkIEtQSSBzZWxlY3RlZCBmb3IgZ2VuZXJhdGVkIGRlbW8gZGF0YS5cIik7XG5cbi8qKiBFdmlkZW5jZS1iYWNrZWQgS1BJLiAqL1xuZXhwb3J0IHR5cGUgUmVzZWFyY2hlZEtwaSA9IHouaW5mZXI8dHlwZW9mIFJlc2VhcmNoZWRLcGlTY2hlbWE+O1xuXG4vKiogS1BJIHJlc2VhcmNoIHJlcXVlc3QgaW5kZXBlbmRlbnQgb2YgYW55IG11dGF0aW9uIHdvcmtmbG93LiAqL1xuZXhwb3J0IGNvbnN0IEtwaVJlc2VhcmNoUmVxdWVzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgY29tcGFueTogbm9uQmxhbmtTdHJpbmcubWF4KDIwMCkuZGVzY3JpYmUoXCJDb21wYW55IG9yIGJyYW5kIGJlaW5nIG1vZGVsZWQuXCIpLFxuICAgIHB1cnBvc2U6IG5vbkJsYW5rU3RyaW5nLm1heCgyMDApLmRlc2NyaWJlKFwiUHVycG9zZSBvZiB0aGUgZ2VuZXJhdGVkIGRlbW9uc3RyYXRpb24uXCIpLFxuICAgIHF1ZXJpZXM6IHpcbiAgICAgIC5hcnJheShub25CbGFua1N0cmluZy5tYXgoNTAwKSlcbiAgICAgIC5taW4oMSlcbiAgICAgIC5tYXgoMTApXG4gICAgICAuZGVzY3JpYmUoXCJOYXR1cmFsLWxhbmd1YWdlIHF1ZXN0aW9ucyB0aGUgZ2VuZXJhdGVkIGRhdGEgc2hvdWxkIGFuc3dlci5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJSZXF1ZXN0IGZvciB3ZWItcmVzZWFyY2hlZCBLUElzIHRoYXQgc2hhcGUgZ2VuZXJhdGVkIGRlbW8gZGF0YS5cIik7XG5cbi8qKiBLUEkgcmVzZWFyY2ggcmVxdWVzdC4gKi9cbmV4cG9ydCB0eXBlIEtwaVJlc2VhcmNoUmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIEtwaVJlc2VhcmNoUmVxdWVzdFNjaGVtYT47XG5cbi8qKiBLUEkgcmVzZWFyY2ggcmVzdWx0IGFuZCBpdHMgc291cmNlIHByb3ZlbmFuY2UuICovXG5leHBvcnQgY29uc3QgS3BpUmVzZWFyY2hSZXN1bHRTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGtwaXM6IHouYXJyYXkoUmVzZWFyY2hlZEtwaVNjaGVtYSkubWluKDEpLm1heCg4KS5kZXNjcmliZShcIlNlbGVjdGVkIEtQSSBkZWZpbml0aW9ucy5cIiksXG4gICAgc291cmNlczogelxuICAgICAgLmFycmF5KFxuICAgICAgICB6XG4gICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICB1cmw6IHouc3RyaW5nKCkudXJsKCkuZGVzY3JpYmUoXCJSZXNlYXJjaCBzb3VyY2UgVVJMLlwiKSxcbiAgICAgICAgICAgIHRpdGxlOiBub25CbGFua1N0cmluZy5vcHRpb25hbCgpLmRlc2NyaWJlKFwiU291cmNlIHRpdGxlLCB3aGVuIGF2YWlsYWJsZS5cIiksXG4gICAgICAgICAgICBmZXRjaGVkOiB6LmJvb2xlYW4oKS5kZXNjcmliZShcIldoZXRoZXIgcGFnZSBjb250ZW50IHdhcyByZWFkLlwiKSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zdHJpY3QoKSxcbiAgICAgIClcbiAgICAgIC5kZXNjcmliZShcIkRlZHVwbGljYXRlZCBLUEkgcmVzZWFyY2ggc291cmNlcy5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJFdmlkZW5jZS1iYWNrZWQgS1BJIHJlc2VhcmNoIG91dHB1dC5cIik7XG5cbi8qKiBLUEkgcmVzZWFyY2ggcmVzdWx0LiAqL1xuZXhwb3J0IHR5cGUgS3BpUmVzZWFyY2hSZXN1bHQgPSB6LmluZmVyPHR5cGVvZiBLcGlSZXNlYXJjaFJlc3VsdFNjaGVtYT47XG4iXX0=