@caelo-cms/shared 0.2.2

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 (77) hide show
  1. package/dist/ai-tools.d.ts +571 -0
  2. package/dist/ai-tools.d.ts.map +1 -0
  3. package/dist/ai-tools.js +696 -0
  4. package/dist/ai-tools.js.map +1 -0
  5. package/dist/auth-forms.d.ts +24 -0
  6. package/dist/auth-forms.d.ts.map +1 -0
  7. package/dist/auth-forms.js +27 -0
  8. package/dist/auth-forms.js.map +1 -0
  9. package/dist/cap-failures.d.ts +17 -0
  10. package/dist/cap-failures.d.ts.map +1 -0
  11. package/dist/cap-failures.js +58 -0
  12. package/dist/cap-failures.js.map +1 -0
  13. package/dist/content.d.ts +111 -0
  14. package/dist/content.d.ts.map +1 -0
  15. package/dist/content.js +137 -0
  16. package/dist/content.js.map +1 -0
  17. package/dist/context.d.ts +40 -0
  18. package/dist/context.d.ts.map +1 -0
  19. package/dist/context.js +3 -0
  20. package/dist/context.js.map +1 -0
  21. package/dist/i18n.d.ts +49 -0
  22. package/dist/i18n.d.ts.map +1 -0
  23. package/dist/i18n.js +154 -0
  24. package/dist/i18n.js.map +1 -0
  25. package/dist/index.d.ts +20 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +21 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/logger.d.ts +56 -0
  30. package/dist/logger.d.ts.map +1 -0
  31. package/dist/logger.js +84 -0
  32. package/dist/logger.js.map +1 -0
  33. package/dist/media.d.ts +143 -0
  34. package/dist/media.d.ts.map +1 -0
  35. package/dist/media.js +168 -0
  36. package/dist/media.js.map +1 -0
  37. package/dist/preview-compose.d.ts +84 -0
  38. package/dist/preview-compose.d.ts.map +1 -0
  39. package/dist/preview-compose.js +385 -0
  40. package/dist/preview-compose.js.map +1 -0
  41. package/dist/preview-scanner.d.ts +44 -0
  42. package/dist/preview-scanner.d.ts.map +1 -0
  43. package/dist/preview-scanner.js +177 -0
  44. package/dist/preview-scanner.js.map +1 -0
  45. package/dist/result.d.ts +21 -0
  46. package/dist/result.d.ts.map +1 -0
  47. package/dist/result.js +14 -0
  48. package/dist/result.js.map +1 -0
  49. package/dist/seo.d.ts +128 -0
  50. package/dist/seo.d.ts.map +1 -0
  51. package/dist/seo.js +176 -0
  52. package/dist/seo.js.map +1 -0
  53. package/dist/skills.d.ts +88 -0
  54. package/dist/skills.d.ts.map +1 -0
  55. package/dist/skills.js +127 -0
  56. package/dist/skills.js.map +1 -0
  57. package/dist/snapshots.d.ts +54 -0
  58. package/dist/snapshots.d.ts.map +1 -0
  59. package/dist/snapshots.js +59 -0
  60. package/dist/snapshots.js.map +1 -0
  61. package/dist/structured-sets.d.ts +116 -0
  62. package/dist/structured-sets.d.ts.map +1 -0
  63. package/dist/structured-sets.js +154 -0
  64. package/dist/structured-sets.js.map +1 -0
  65. package/dist/subagents.d.ts +123 -0
  66. package/dist/subagents.d.ts.map +1 -0
  67. package/dist/subagents.js +202 -0
  68. package/dist/subagents.js.map +1 -0
  69. package/dist/translation.d.ts +127 -0
  70. package/dist/translation.d.ts.map +1 -0
  71. package/dist/translation.js +208 -0
  72. package/dist/translation.js.map +1 -0
  73. package/dist/version.d.ts +46 -0
  74. package/dist/version.d.ts.map +1 -0
  75. package/dist/version.js +46 -0
  76. package/dist/version.js.map +1 -0
  77. package/package.json +38 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * P10.5 — Subagent invocation shapes (Zod) + result parser.
3
+ *
4
+ * A subagent is just a chat-runner turn. The `spawn_subagent` AI tool
5
+ * lets the parent kick off another chat-runner turn with a constrained
6
+ * tool set + a seed task message; the matcher inside that turn engages
7
+ * whichever skill the task wording matches. Same chat-runner code path,
8
+ * different inputs.
9
+ *
10
+ * This file holds:
11
+ * - subagentSpec — single-spawn input shape.
12
+ * - spawnSubagentToolInput — wraps one spec.
13
+ * - spawnSubagentsToolInput — wraps an array (parallel batch).
14
+ * - Return-shape variants the AI can request:
15
+ * verdict ({pass, issues[], suggestions[]})
16
+ * tree ({tree: [...], rationale})
17
+ * freeform ({text})
18
+ * - parseSubagentResult — pulls JSON out of the subagent's final
19
+ * assistant message (handles ```json fences) and validates against
20
+ * the requested shape.
21
+ */
22
+ import { z } from "zod";
23
+ declare const expectedReturnShape: z.ZodEnum<{
24
+ verdict: "verdict";
25
+ tree: "tree";
26
+ freeform: "freeform";
27
+ }>;
28
+ export type ExpectedReturnShape = z.infer<typeof expectedReturnShape>;
29
+ /**
30
+ * One subagent spec. The parent supplies role + task + optional
31
+ * narrowing. The handler creates the ephemeral chat session, appends
32
+ * the task as the seed user message, calls runChatTurn directly with
33
+ * `excludedToolNames=spawn_subagent,spawn_subagents` (depth cap) +
34
+ * `allowedToolNames` from the spec.
35
+ */
36
+ export declare const subagentSpec: z.ZodObject<{
37
+ role: z.ZodString;
38
+ task: z.ZodString;
39
+ allowedToolNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
40
+ expectedReturnShape: z.ZodDefault<z.ZodEnum<{
41
+ verdict: "verdict";
42
+ tree: "tree";
43
+ freeform: "freeform";
44
+ }>>;
45
+ maxCostMicrocents: z.ZodDefault<z.ZodNumber>;
46
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
47
+ activePageId: z.ZodOptional<z.ZodString>;
48
+ }, z.core.$strict>;
49
+ export type SubagentSpec = z.infer<typeof subagentSpec>;
50
+ export declare const spawnSubagentToolInput: z.ZodObject<{
51
+ role: z.ZodString;
52
+ task: z.ZodString;
53
+ allowedToolNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
54
+ expectedReturnShape: z.ZodDefault<z.ZodEnum<{
55
+ verdict: "verdict";
56
+ tree: "tree";
57
+ freeform: "freeform";
58
+ }>>;
59
+ maxCostMicrocents: z.ZodDefault<z.ZodNumber>;
60
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
61
+ activePageId: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>;
63
+ export type SpawnSubagentToolInput = SubagentSpec;
64
+ export declare const spawnSubagentsToolInput: z.ZodObject<{
65
+ subagents: z.ZodArray<z.ZodObject<{
66
+ role: z.ZodString;
67
+ task: z.ZodString;
68
+ allowedToolNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ expectedReturnShape: z.ZodDefault<z.ZodEnum<{
70
+ verdict: "verdict";
71
+ tree: "tree";
72
+ freeform: "freeform";
73
+ }>>;
74
+ maxCostMicrocents: z.ZodDefault<z.ZodNumber>;
75
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
76
+ activePageId: z.ZodOptional<z.ZodString>;
77
+ }, z.core.$strict>>;
78
+ }, z.core.$strict>;
79
+ export type SpawnSubagentsToolInput = z.infer<typeof spawnSubagentsToolInput>;
80
+ export declare const verdictReturnShape: z.ZodObject<{
81
+ pass: z.ZodBoolean;
82
+ issues: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
83
+ suggestions: z.ZodDefault<z.ZodArray<z.ZodString>>;
84
+ }, z.core.$strict>;
85
+ export type VerdictReturn = z.infer<typeof verdictReturnShape>;
86
+ export declare const treeReturnShape: z.ZodObject<{
87
+ tree: z.ZodArray<z.ZodUnknown>;
88
+ rationale: z.ZodDefault<z.ZodString>;
89
+ }, z.core.$strict>;
90
+ export type TreeReturn = z.infer<typeof treeReturnShape>;
91
+ export declare const freeformReturnShape: z.ZodObject<{
92
+ text: z.ZodString;
93
+ }, z.core.$strict>;
94
+ export type FreeformReturn = z.infer<typeof freeformReturnShape>;
95
+ export type ParseSuccess = {
96
+ ok: true;
97
+ shape: "verdict";
98
+ value: VerdictReturn;
99
+ } | {
100
+ ok: true;
101
+ shape: "tree";
102
+ value: TreeReturn;
103
+ } | {
104
+ ok: true;
105
+ shape: "freeform";
106
+ value: FreeformReturn;
107
+ };
108
+ export type ParseResult = ParseSuccess | {
109
+ ok: false;
110
+ error: string;
111
+ };
112
+ /**
113
+ * Pull JSON out of the subagent's final assistant text and validate
114
+ * against the requested shape. On schema mismatch, returns
115
+ * `{ok: false, error}` so the caller can decide whether to retry.
116
+ *
117
+ * For `freeform`, accepts EITHER `{text: "..."}` JSON or raw text;
118
+ * raw text is wrapped as `{text: rawText}` so the caller always gets
119
+ * the same shape.
120
+ */
121
+ export declare function parseSubagentResult(text: string, shape: ExpectedReturnShape): ParseResult;
122
+ export {};
123
+ //# sourceMappingURL=subagents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../src/subagents.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,mBAAmB;;;;EAA0C,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;kBA4Bd,CAAC;AACZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;kBAAe,CAAC;AACnD,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAElD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;kBAIzB,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAM9E,eAAO,MAAM,kBAAkB;;;;kBAQpB,CAAC;AACZ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE/D,eAAO,MAAM,eAAe;;;kBAKjB,CAAC;AACZ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAEzD,eAAO,MAAM,mBAAmB;;kBAIrB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAiDjE,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACpD;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC9C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,WAAW,CAkDzF"}
@@ -0,0 +1,202 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * P10.5 — Subagent invocation shapes (Zod) + result parser.
4
+ *
5
+ * A subagent is just a chat-runner turn. The `spawn_subagent` AI tool
6
+ * lets the parent kick off another chat-runner turn with a constrained
7
+ * tool set + a seed task message; the matcher inside that turn engages
8
+ * whichever skill the task wording matches. Same chat-runner code path,
9
+ * different inputs.
10
+ *
11
+ * This file holds:
12
+ * - subagentSpec — single-spawn input shape.
13
+ * - spawnSubagentToolInput — wraps one spec.
14
+ * - spawnSubagentsToolInput — wraps an array (parallel batch).
15
+ * - Return-shape variants the AI can request:
16
+ * verdict ({pass, issues[], suggestions[]})
17
+ * tree ({tree: [...], rationale})
18
+ * freeform ({text})
19
+ * - parseSubagentResult — pulls JSON out of the subagent's final
20
+ * assistant message (handles ```json fences) and validates against
21
+ * the requested shape.
22
+ */
23
+ import { z } from "zod";
24
+ const expectedReturnShape = z.enum(["verdict", "tree", "freeform"]);
25
+ /**
26
+ * One subagent spec. The parent supplies role + task + optional
27
+ * narrowing. The handler creates the ephemeral chat session, appends
28
+ * the task as the seed user message, calls runChatTurn directly with
29
+ * `excludedToolNames=spawn_subagent,spawn_subagents` (depth cap) +
30
+ * `allowedToolNames` from the spec.
31
+ */
32
+ export const subagentSpec = z
33
+ .object({
34
+ /** Owner-readable role label for the verdicts UI + the subagent_runs row. */
35
+ role: z.string().min(1).max(120),
36
+ /** The seed user message. The matcher engages skills based on this text. */
37
+ task: z.string().min(1).max(8000),
38
+ /**
39
+ * Optional tool-catalogue narrowing. When omitted, the subagent
40
+ * gets the default registry MINUS the spawn tools. When set, the
41
+ * subagent gets the INTERSECTION of (default minus spawn) and
42
+ * `allowedToolNames` — typically read-only ops for safety.
43
+ */
44
+ allowedToolNames: z.array(z.string().min(1).max(120)).optional(),
45
+ /** Zod-validated return shape. Defaults to `verdict`. */
46
+ expectedReturnShape: expectedReturnShape.default("verdict"),
47
+ /** Per-spawn cost cap; default 50_000_000 microcents = $0.50. */
48
+ maxCostMicrocents: z.number().int().nonnegative().default(50_000_000),
49
+ /** Per-spawn timeout; default 60s. */
50
+ timeoutMs: z.number().int().min(1000).max(600_000).default(60_000),
51
+ /**
52
+ * Optional active page id. When passed, the spawn handler routes
53
+ * it through to the runChatTurn invocation as `activePageId`,
54
+ * giving the subagent the same Current-page volatile chunk a
55
+ * normal /edit chat would see. The subagent still has to call
56
+ * `pages.get_with_modules` to pull module HTML.
57
+ */
58
+ activePageId: z.string().uuid().optional(),
59
+ })
60
+ .strict();
61
+ export const spawnSubagentToolInput = subagentSpec;
62
+ export const spawnSubagentsToolInput = z
63
+ .object({
64
+ subagents: z.array(subagentSpec).min(1).max(8),
65
+ })
66
+ .strict();
67
+ // ---------------------------------------------------------------------
68
+ // Return-shape variants the parent asks the subagent to emit
69
+ // ---------------------------------------------------------------------
70
+ export const verdictReturnShape = z
71
+ .object({
72
+ pass: z.boolean(),
73
+ issues: z
74
+ .array(z.union([z.string().min(1).max(2000), z.record(z.string(), z.unknown())]))
75
+ .max(50),
76
+ suggestions: z.array(z.string().min(1).max(2000)).max(50).default([]),
77
+ })
78
+ .strict();
79
+ export const treeReturnShape = z
80
+ .object({
81
+ tree: z.array(z.unknown()).max(500),
82
+ rationale: z.string().max(4000).default(""),
83
+ })
84
+ .strict();
85
+ export const freeformReturnShape = z
86
+ .object({
87
+ text: z.string().min(1).max(40_000),
88
+ })
89
+ .strict();
90
+ // ---------------------------------------------------------------------
91
+ // Result parser — handles `````json {…} ````` fences + raw JSON.
92
+ // ---------------------------------------------------------------------
93
+ function stripFences(text) {
94
+ const trimmed = text.trim();
95
+ if (trimmed.startsWith("```")) {
96
+ const firstNl = trimmed.indexOf("\n");
97
+ const last = trimmed.lastIndexOf("```");
98
+ if (firstNl !== -1 && last > firstNl) {
99
+ return trimmed.slice(firstNl + 1, last).trim();
100
+ }
101
+ }
102
+ // Common case: raw JSON wrapped in prose. Pull out the first {...}
103
+ // block by brace-balancing. If no braces, return as-is.
104
+ const firstBrace = trimmed.indexOf("{");
105
+ if (firstBrace === -1)
106
+ return trimmed;
107
+ let depth = 0;
108
+ let inStr = false;
109
+ let escaped = false;
110
+ for (let i = firstBrace; i < trimmed.length; i++) {
111
+ const ch = trimmed[i];
112
+ if (escaped) {
113
+ escaped = false;
114
+ continue;
115
+ }
116
+ if (inStr) {
117
+ if (ch === "\\") {
118
+ escaped = true;
119
+ continue;
120
+ }
121
+ if (ch === '"')
122
+ inStr = false;
123
+ continue;
124
+ }
125
+ if (ch === '"') {
126
+ inStr = true;
127
+ continue;
128
+ }
129
+ if (ch === "{")
130
+ depth += 1;
131
+ else if (ch === "}") {
132
+ depth -= 1;
133
+ if (depth === 0)
134
+ return trimmed.slice(firstBrace, i + 1);
135
+ }
136
+ }
137
+ return trimmed;
138
+ }
139
+ /**
140
+ * Pull JSON out of the subagent's final assistant text and validate
141
+ * against the requested shape. On schema mismatch, returns
142
+ * `{ok: false, error}` so the caller can decide whether to retry.
143
+ *
144
+ * For `freeform`, accepts EITHER `{text: "..."}` JSON or raw text;
145
+ * raw text is wrapped as `{text: rawText}` so the caller always gets
146
+ * the same shape.
147
+ */
148
+ export function parseSubagentResult(text, shape) {
149
+ if (shape === "freeform") {
150
+ // Try JSON first; on failure treat the whole thing as freeform text.
151
+ try {
152
+ const stripped = stripFences(text);
153
+ const parsed = JSON.parse(stripped);
154
+ const validated = freeformReturnShape.safeParse(parsed);
155
+ if (validated.success)
156
+ return { ok: true, shape: "freeform", value: validated.data };
157
+ }
158
+ catch {
159
+ /* fall through */
160
+ }
161
+ if (text.trim().length === 0)
162
+ return { ok: false, error: "subagent returned empty text" };
163
+ return { ok: true, shape: "freeform", value: { text: text.trim() } };
164
+ }
165
+ const stripped = stripFences(text);
166
+ let parsed;
167
+ try {
168
+ parsed = JSON.parse(stripped);
169
+ }
170
+ catch (e) {
171
+ return {
172
+ ok: false,
173
+ error: `subagent response is not valid JSON: ${e.message}; first 200 chars: ${stripped.slice(0, 200)}`,
174
+ };
175
+ }
176
+ if (shape === "verdict") {
177
+ const validated = verdictReturnShape.safeParse(parsed);
178
+ if (!validated.success) {
179
+ return {
180
+ ok: false,
181
+ error: `verdict shape mismatch: ${validated.error.issues
182
+ .slice(0, 3)
183
+ .map((i) => `${i.path.join(".")}: ${i.message}`)
184
+ .join("; ")}`,
185
+ };
186
+ }
187
+ return { ok: true, shape: "verdict", value: validated.data };
188
+ }
189
+ // tree
190
+ const validated = treeReturnShape.safeParse(parsed);
191
+ if (!validated.success) {
192
+ return {
193
+ ok: false,
194
+ error: `tree shape mismatch: ${validated.error.issues
195
+ .slice(0, 3)
196
+ .map((i) => `${i.path.join(".")}: ${i.message}`)
197
+ .join("; ")}`,
198
+ };
199
+ }
200
+ return { ok: true, shape: "tree", value: validated.data };
201
+ }
202
+ //# sourceMappingURL=subagents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagents.js","sourceRoot":"","sources":["../src/subagents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * P10 — translation primitives shared between the AI prompt builder,
3
+ * the Mode 1 / Mode 2 op handlers, and the dashboard.
4
+ *
5
+ * computeBlockDiff(source, variant) — block-level diff per
6
+ * CMS_REQUIREMENTS §7.6: matches modules by (block_name, position),
7
+ * returns typed `changed` / `added` / `removed` operations. Pure
8
+ * function; the AI receives this as Mode 2 prompt context.
9
+ *
10
+ * buildModeOnePrompt(...) / buildModeTwoPrompt(...) — assemble the
11
+ * §7.6 sample-payload shapes with glossary + style guide injected.
12
+ * Returns the prompt + a structured payload for unit-tests to
13
+ * assert against.
14
+ */
15
+ import { z } from "zod";
16
+ export interface ModuleBlockSlot {
17
+ /** The block (e.g. "content", "header") this module sits in. */
18
+ blockName: string;
19
+ /** Position within the block. Blocks are ordered + 0-based. */
20
+ position: number;
21
+ /** Module id — locked across locales (translations share refs). */
22
+ moduleId: string;
23
+ /** Display name shown to the AI for context. */
24
+ moduleSlug: string;
25
+ /** The translatable fields of the module. P10 supports HTML body
26
+ * and three SEO-style metadata fields. Extend as new typed fields
27
+ * land (e.g. structured-content blocks in P12A). */
28
+ html: string;
29
+ altText: string | null;
30
+ caption: string | null;
31
+ }
32
+ export type BlockDiffOp = {
33
+ kind: "changed";
34
+ blockName: string;
35
+ position: number;
36
+ moduleId: string;
37
+ before: ModuleBlockSlot;
38
+ after: ModuleBlockSlot;
39
+ } | {
40
+ kind: "added";
41
+ blockName: string;
42
+ position: number;
43
+ module: ModuleBlockSlot;
44
+ } | {
45
+ kind: "removed";
46
+ blockName: string;
47
+ position: number;
48
+ module: ModuleBlockSlot;
49
+ };
50
+ /**
51
+ * Diff a source page's modules against a variant's modules. Match by
52
+ * (blockName, position) — the §7.5 contract is that translations
53
+ * share STRUCTURE with the source (block + position alignment) and
54
+ * differ only in CONTENT (html / alt / caption per locale). Anything
55
+ * mis-aligned is `added` (source has it, variant doesn't) or
56
+ * `removed` (variant has it, source doesn't).
57
+ *
58
+ * `changed` rows contain BOTH before + after so the AI prompt can
59
+ * show the structured diff per the §7.6 sample payload.
60
+ */
61
+ export declare function computeBlockDiff(source: readonly ModuleBlockSlot[], variant: readonly ModuleBlockSlot[]): BlockDiffOp[];
62
+ export interface GlossaryEntry {
63
+ sourceTerm: string;
64
+ translation: string;
65
+ context: string | null;
66
+ }
67
+ export interface ModeOnePromptInput {
68
+ /** Source-locale code (e.g. 'en'). */
69
+ sourceLocale: string;
70
+ /** Target locale code (e.g. 'de-AT'). */
71
+ targetLocale: string;
72
+ /** Optional locale displayName for context (e.g. "German (Austria)"). */
73
+ targetLocaleDisplayName?: string;
74
+ /** Source-page modules. The AI translates each per (blockName, position). */
75
+ sourceModules: readonly ModuleBlockSlot[];
76
+ glossary: readonly GlossaryEntry[];
77
+ styleGuide: string | null;
78
+ }
79
+ export interface ModeTwoPromptInput {
80
+ sourceLocale: string;
81
+ targetLocale: string;
82
+ targetLocaleDisplayName?: string;
83
+ sourceModules: readonly ModuleBlockSlot[];
84
+ /** The CURRENT variant — passed in full so the AI keeps the prior
85
+ * translation quality on unchanged blocks. */
86
+ variantModules: readonly ModuleBlockSlot[];
87
+ /** Pre-computed diff (call computeBlockDiff first). */
88
+ diff: readonly BlockDiffOp[];
89
+ glossary: readonly GlossaryEntry[];
90
+ styleGuide: string | null;
91
+ }
92
+ /**
93
+ * The AI returns this shape for both Mode 1 and Mode 2: one entry per
94
+ * source module slot, with the translated content fields. The handler
95
+ * matches entries back to the variant page's module rows by
96
+ * (blockName, position).
97
+ *
98
+ * Mode 1 returns one entry per source module.
99
+ * Mode 2 returns entries ONLY for changed blocks (preserves prior
100
+ * translation on unchanged ones).
101
+ */
102
+ export declare const translationResultModule: z.ZodObject<{
103
+ blockName: z.ZodString;
104
+ position: z.ZodNumber;
105
+ html: z.ZodString;
106
+ altText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
107
+ caption: z.ZodOptional<z.ZodNullable<z.ZodString>>;
108
+ }, z.core.$strict>;
109
+ export declare const translationResultPayload: z.ZodObject<{
110
+ modules: z.ZodArray<z.ZodObject<{
111
+ blockName: z.ZodString;
112
+ position: z.ZodNumber;
113
+ html: z.ZodString;
114
+ altText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
+ caption: z.ZodOptional<z.ZodNullable<z.ZodString>>;
116
+ }, z.core.$strict>>;
117
+ }, z.core.$strict>;
118
+ export type TranslationResultPayload = z.infer<typeof translationResultPayload>;
119
+ export declare function buildModeOnePrompt(input: ModeOnePromptInput): {
120
+ system: string;
121
+ user: string;
122
+ };
123
+ export declare function buildModeTwoPrompt(input: ModeTwoPromptInput): {
124
+ system: string;
125
+ user: string;
126
+ };
127
+ //# sourceMappingURL=translation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translation.d.ts","sourceRoot":"","sources":["../src/translation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB;;wDAEoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,MAAM,WAAW,GACnB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;CACxB,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAEtF;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,OAAO,EAAE,SAAS,eAAe,EAAE,GAClC,WAAW,EAAE,CAgCf;AAMD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,6EAA6E;IAC7E,aAAa,EAAE,SAAS,eAAe,EAAE,CAAC;IAC1C,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,EAAE,SAAS,eAAe,EAAE,CAAC;IAC1C;kDAC8C;IAC9C,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;IAC3C,uDAAuD;IACvD,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IAC7B,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB;;;;;;kBASzB,CAAC;AAEZ,eAAO,MAAM,wBAAwB;;;;;;;;kBAI1B,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAiChF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAuBA;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAuEA"}