@caelo-cms/shared 0.10.23 → 0.10.26
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/dist/ai-tools.d.ts +15 -70
- package/dist/ai-tools.d.ts.map +1 -1
- package/dist/ai-tools.js +14 -74
- package/dist/ai-tools.js.map +1 -1
- package/dist/base-css.d.ts +11 -0
- package/dist/base-css.d.ts.map +1 -1
- package/dist/base-css.js +13 -1
- package/dist/base-css.js.map +1 -1
- package/dist/build-page.d.ts +0 -2
- package/dist/build-page.d.ts.map +1 -1
- package/dist/build-page.js +2 -3
- package/dist/build-page.js.map +1 -1
- package/dist/content.d.ts +0 -3
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +91 -7
- package/dist/content.js.map +1 -1
- package/dist/context.d.ts +6 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/design-draft-shell.d.ts +21 -0
- package/dist/design-draft-shell.d.ts.map +1 -0
- package/dist/design-draft-shell.js +81 -0
- package/dist/design-draft-shell.js.map +1 -0
- package/dist/font-assets.d.ts +89 -0
- package/dist/font-assets.d.ts.map +1 -0
- package/dist/font-assets.js +61 -0
- package/dist/font-assets.js.map +1 -0
- package/dist/genesis.d.ts +43 -3
- package/dist/genesis.d.ts.map +1 -1
- package/dist/genesis.js +72 -5
- package/dist/genesis.js.map +1 -1
- package/dist/google-models.d.ts +35 -0
- package/dist/google-models.d.ts.map +1 -0
- package/dist/google-models.js +20 -0
- package/dist/google-models.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/media.d.ts +0 -3
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +0 -5
- package/dist/media.js.map +1 -1
- package/dist/plugin-preview.d.ts +44 -0
- package/dist/plugin-preview.d.ts.map +1 -0
- package/dist/plugin-preview.js +69 -0
- package/dist/plugin-preview.js.map +1 -0
- package/dist/preview-compose.d.ts +35 -15
- package/dist/preview-compose.d.ts.map +1 -1
- package/dist/preview-compose.js +95 -89
- package/dist/preview-compose.js.map +1 -1
- package/dist/responsive-images.d.ts +6 -5
- package/dist/responsive-images.d.ts.map +1 -1
- package/dist/responsive-images.js +6 -5
- package/dist/responsive-images.js.map +1 -1
- package/dist/seo.d.ts +11 -28
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +12 -31
- package/dist/seo.js.map +1 -1
- package/dist/structured-sets.d.ts +0 -36
- package/dist/structured-sets.d.ts.map +1 -1
- package/dist/structured-sets.js +1 -52
- package/dist/structured-sets.js.map +1 -1
- package/dist/template-engine.d.ts +18 -0
- package/dist/template-engine.d.ts.map +1 -1
- package/dist/template-engine.js +39 -2
- package/dist/template-engine.js.map +1 -1
- package/dist/theme-importers/loose.js +1 -1
- package/dist/theme-importers/loose.js.map +1 -1
- package/dist/theme-normalize.d.ts +9 -0
- package/dist/theme-normalize.d.ts.map +1 -1
- package/dist/theme-normalize.js +65 -6
- package/dist/theme-normalize.js.map +1 -1
- package/dist/theme-render.d.ts +15 -0
- package/dist/theme-render.d.ts.map +1 -1
- package/dist/theme-render.js +39 -0
- package/dist/theme-render.js.map +1 -1
- package/dist/themes.d.ts +15 -1
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +48 -1
- package/dist/themes.js.map +1 -1
- package/dist/url.d.ts +45 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +64 -0
- package/dist/url.js.map +1 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/__tests__/redos-hardening.test.ts +1 -1
- package/src/ai-tools.ts +14 -90
- package/src/base-css.ts +13 -1
- package/src/build-page.ts +3 -5
- package/src/content.test.ts +99 -17
- package/src/content.ts +95 -8
- package/src/context.ts +6 -0
- package/src/design-draft-shell.test.ts +85 -0
- package/src/design-draft-shell.ts +109 -0
- package/src/font-assets.ts +63 -0
- package/src/genesis.ts +76 -5
- package/src/google-models.ts +20 -0
- package/src/index.ts +5 -3
- package/src/media.ts +0 -6
- package/src/plugin-preview.test.ts +79 -0
- package/src/plugin-preview.ts +81 -0
- package/src/preview-compose-deferrals.test.ts +144 -0
- package/src/preview-compose.test.ts +51 -0
- package/src/preview-compose.ts +128 -93
- package/src/responsive-images.ts +6 -5
- package/src/seo.test.ts +8 -48
- package/src/seo.ts +16 -52
- package/src/structured-sets.ts +1 -67
- package/src/template-engine-data-lists.test.ts +90 -0
- package/src/template-engine.ts +72 -1
- package/src/theme-importers/loose.ts +1 -1
- package/src/theme-normalize.ts +70 -8
- package/src/theme-render.ts +36 -0
- package/src/theme-token-roles.test.ts +182 -0
- package/src/themes.ts +53 -0
- package/src/url.test.ts +40 -0
- package/src/url.ts +69 -0
- package/src/version.ts +1 -1
- package/dist/design-manifest.d.ts +0 -36
- package/dist/design-manifest.d.ts.map +0 -1
- package/dist/design-manifest.js +0 -90
- package/dist/design-manifest.js.map +0 -1
- package/dist/i18n.d.ts +0 -92
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js +0 -226
- package/dist/i18n.js.map +0 -1
- package/dist/translation.d.ts +0 -127
- package/dist/translation.d.ts.map +0 -1
- package/dist/translation.js +0 -208
- package/dist/translation.js.map +0 -1
- package/src/design-manifest.ts +0 -93
- package/src/i18n.test.ts +0 -274
- package/src/i18n.ts +0 -269
- package/src/translation.test.ts +0 -160
- package/src/translation.ts +0 -295
package/dist/translation.d.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/translation.js
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
/**
|
|
3
|
-
* P10 — translation primitives shared between the AI prompt builder,
|
|
4
|
-
* the Mode 1 / Mode 2 op handlers, and the dashboard.
|
|
5
|
-
*
|
|
6
|
-
* computeBlockDiff(source, variant) — block-level diff per
|
|
7
|
-
* CMS_REQUIREMENTS §7.6: matches modules by (block_name, position),
|
|
8
|
-
* returns typed `changed` / `added` / `removed` operations. Pure
|
|
9
|
-
* function; the AI receives this as Mode 2 prompt context.
|
|
10
|
-
*
|
|
11
|
-
* buildModeOnePrompt(...) / buildModeTwoPrompt(...) — assemble the
|
|
12
|
-
* §7.6 sample-payload shapes with glossary + style guide injected.
|
|
13
|
-
* Returns the prompt + a structured payload for unit-tests to
|
|
14
|
-
* assert against.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from "zod";
|
|
17
|
-
/**
|
|
18
|
-
* Diff a source page's modules against a variant's modules. Match by
|
|
19
|
-
* (blockName, position) — the §7.5 contract is that translations
|
|
20
|
-
* share STRUCTURE with the source (block + position alignment) and
|
|
21
|
-
* differ only in CONTENT (html / alt / caption per locale). Anything
|
|
22
|
-
* mis-aligned is `added` (source has it, variant doesn't) or
|
|
23
|
-
* `removed` (variant has it, source doesn't).
|
|
24
|
-
*
|
|
25
|
-
* `changed` rows contain BOTH before + after so the AI prompt can
|
|
26
|
-
* show the structured diff per the §7.6 sample payload.
|
|
27
|
-
*/
|
|
28
|
-
export function computeBlockDiff(source, variant) {
|
|
29
|
-
const ops = [];
|
|
30
|
-
const variantBy = new Map();
|
|
31
|
-
for (const v of variant)
|
|
32
|
-
variantBy.set(`${v.blockName}|${v.position}`, v);
|
|
33
|
-
const sourceBy = new Map();
|
|
34
|
-
for (const s of source)
|
|
35
|
-
sourceBy.set(`${s.blockName}|${s.position}`, s);
|
|
36
|
-
for (const s of source) {
|
|
37
|
-
const key = `${s.blockName}|${s.position}`;
|
|
38
|
-
const v = variantBy.get(key);
|
|
39
|
-
if (!v) {
|
|
40
|
-
ops.push({ kind: "added", blockName: s.blockName, position: s.position, module: s });
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (s.html !== v.html || s.altText !== v.altText || s.caption !== v.caption) {
|
|
44
|
-
ops.push({
|
|
45
|
-
kind: "changed",
|
|
46
|
-
blockName: s.blockName,
|
|
47
|
-
position: s.position,
|
|
48
|
-
moduleId: v.moduleId,
|
|
49
|
-
before: v,
|
|
50
|
-
after: s,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
for (const v of variant) {
|
|
55
|
-
const key = `${v.blockName}|${v.position}`;
|
|
56
|
-
if (!sourceBy.has(key)) {
|
|
57
|
-
ops.push({ kind: "removed", blockName: v.blockName, position: v.position, module: v });
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return ops;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* The AI returns this shape for both Mode 1 and Mode 2: one entry per
|
|
64
|
-
* source module slot, with the translated content fields. The handler
|
|
65
|
-
* matches entries back to the variant page's module rows by
|
|
66
|
-
* (blockName, position).
|
|
67
|
-
*
|
|
68
|
-
* Mode 1 returns one entry per source module.
|
|
69
|
-
* Mode 2 returns entries ONLY for changed blocks (preserves prior
|
|
70
|
-
* translation on unchanged ones).
|
|
71
|
-
*/
|
|
72
|
-
export const translationResultModule = z
|
|
73
|
-
.object({
|
|
74
|
-
blockName: z.string().min(1),
|
|
75
|
-
position: z.number().int().min(0),
|
|
76
|
-
/** Translated module HTML body. */
|
|
77
|
-
html: z.string(),
|
|
78
|
-
altText: z.string().nullable().optional(),
|
|
79
|
-
caption: z.string().nullable().optional(),
|
|
80
|
-
})
|
|
81
|
-
.strict();
|
|
82
|
-
export const translationResultPayload = z
|
|
83
|
-
.object({
|
|
84
|
-
modules: z.array(translationResultModule),
|
|
85
|
-
})
|
|
86
|
-
.strict();
|
|
87
|
-
function renderGlossaryBlock(glossary) {
|
|
88
|
-
if (glossary.length === 0)
|
|
89
|
-
return "";
|
|
90
|
-
const lines = glossary.map((g) => g.context
|
|
91
|
-
? `- "${g.sourceTerm}" → "${g.translation}" (${g.context})`
|
|
92
|
-
: `- "${g.sourceTerm}" → "${g.translation}"`);
|
|
93
|
-
return ["", "## Glossary (use these exact translations)", ...lines].join("\n");
|
|
94
|
-
}
|
|
95
|
-
function renderStyleGuideBlock(styleGuide) {
|
|
96
|
-
if (!styleGuide || styleGuide.trim().length === 0)
|
|
97
|
-
return "";
|
|
98
|
-
return ["", "## Style guide", styleGuide.trim()].join("\n");
|
|
99
|
-
}
|
|
100
|
-
function renderSourceModulesBlock(modules) {
|
|
101
|
-
const rendered = modules.map((m) => {
|
|
102
|
-
const parts = [
|
|
103
|
-
`### Module ${m.moduleSlug} (block=${m.blockName}, position=${m.position})`,
|
|
104
|
-
"HTML:",
|
|
105
|
-
"```html",
|
|
106
|
-
m.html,
|
|
107
|
-
"```",
|
|
108
|
-
];
|
|
109
|
-
if (m.altText !== null)
|
|
110
|
-
parts.push(`alt: ${m.altText}`);
|
|
111
|
-
if (m.caption !== null)
|
|
112
|
-
parts.push(`caption: ${m.caption}`);
|
|
113
|
-
return parts.join("\n");
|
|
114
|
-
});
|
|
115
|
-
return rendered.join("\n\n");
|
|
116
|
-
}
|
|
117
|
-
export function buildModeOnePrompt(input) {
|
|
118
|
-
const targetLabel = input.targetLocaleDisplayName ?? input.targetLocale;
|
|
119
|
-
const system = [
|
|
120
|
-
"You are translating a web page from one locale to another.",
|
|
121
|
-
`Source locale: ${input.sourceLocale}.`,
|
|
122
|
-
`Target locale: ${input.targetLocale} (${targetLabel}).`,
|
|
123
|
-
"",
|
|
124
|
-
"STRUCTURAL LOCK — the page's module layout (block names + positions) is identical across locales. You may NOT add, remove, or reorder modules. Translate ONLY the content fields (html, alt, caption) of each existing module.",
|
|
125
|
-
"",
|
|
126
|
-
"Translate every module listed below into the target locale. Preserve every HTML tag, attribute, class, id, href, and inline style verbatim — only the human-readable text inside tags + the alt/caption fields are translated. Numbers, code samples, and untranslatable proper nouns stay as-is.",
|
|
127
|
-
"",
|
|
128
|
-
'Respond with a JSON object matching: {"modules": [{"blockName": str, "position": int, "html": str, "altText": str|null, "caption": str|null}, ...]}. Return ONE entry per source module — same blockName + position.',
|
|
129
|
-
renderGlossaryBlock(input.glossary),
|
|
130
|
-
renderStyleGuideBlock(input.styleGuide),
|
|
131
|
-
]
|
|
132
|
-
.filter((s) => s.length > 0)
|
|
133
|
-
.join("\n");
|
|
134
|
-
const user = [
|
|
135
|
-
`# Source page modules (${input.sourceLocale} → ${input.targetLocale})`,
|
|
136
|
-
"",
|
|
137
|
-
renderSourceModulesBlock(input.sourceModules),
|
|
138
|
-
].join("\n");
|
|
139
|
-
return { system, user };
|
|
140
|
-
}
|
|
141
|
-
export function buildModeTwoPrompt(input) {
|
|
142
|
-
const targetLabel = input.targetLocaleDisplayName ?? input.targetLocale;
|
|
143
|
-
const changed = input.diff.filter((d) => d.kind === "changed");
|
|
144
|
-
const added = input.diff.filter((d) => d.kind === "added");
|
|
145
|
-
const removed = input.diff.filter((d) => d.kind === "removed");
|
|
146
|
-
const system = [
|
|
147
|
-
"You are updating an existing translation of a web page after the source changed.",
|
|
148
|
-
`Source locale: ${input.sourceLocale}.`,
|
|
149
|
-
`Target locale: ${input.targetLocale} (${targetLabel}).`,
|
|
150
|
-
"",
|
|
151
|
-
"STRUCTURAL LOCK — the page's module layout (block names + positions) is identical across locales. You may NOT add, remove, or reorder modules. Translate ONLY the content fields (html, alt, caption) that have CHANGED on the source. Preserve the existing translation verbatim for unchanged modules.",
|
|
152
|
-
"",
|
|
153
|
-
"Numbers, code samples, and untranslatable proper nouns stay as-is. Preserve every HTML tag/attribute/class/id/href/inline style in the source verbatim.",
|
|
154
|
-
"",
|
|
155
|
-
'Respond with a JSON object matching: {"modules": [{"blockName": str, "position": int, "html": str, "altText": str|null, "caption": str|null}, ...]}. Return ONE entry per CHANGED module — do NOT include unchanged modules in the response.',
|
|
156
|
-
renderGlossaryBlock(input.glossary),
|
|
157
|
-
renderStyleGuideBlock(input.styleGuide),
|
|
158
|
-
]
|
|
159
|
-
.filter((s) => s.length > 0)
|
|
160
|
-
.join("\n");
|
|
161
|
-
const userLines = [
|
|
162
|
-
`# Update translation: ${input.sourceLocale} → ${input.targetLocale}`,
|
|
163
|
-
"",
|
|
164
|
-
"## Current source (full, for context)",
|
|
165
|
-
"",
|
|
166
|
-
renderSourceModulesBlock(input.sourceModules),
|
|
167
|
-
"",
|
|
168
|
-
"## Existing translation (preserve unchanged modules verbatim)",
|
|
169
|
-
"",
|
|
170
|
-
renderSourceModulesBlock(input.variantModules),
|
|
171
|
-
"",
|
|
172
|
-
"## Structured diff",
|
|
173
|
-
];
|
|
174
|
-
if (changed.length === 0 && added.length === 0 && removed.length === 0) {
|
|
175
|
-
userLines.push("(no changes detected — return an empty `modules` array)");
|
|
176
|
-
}
|
|
177
|
-
for (const c of changed) {
|
|
178
|
-
if (c.kind !== "changed")
|
|
179
|
-
continue;
|
|
180
|
-
userLines.push("");
|
|
181
|
-
userLines.push(`### CHANGED — block=${c.blockName} position=${c.position} module=${c.moduleId}`);
|
|
182
|
-
userLines.push("Before (existing translation):");
|
|
183
|
-
userLines.push("```html");
|
|
184
|
-
userLines.push(c.before.html);
|
|
185
|
-
userLines.push("```");
|
|
186
|
-
userLines.push("Source after (current source HTML to re-translate):");
|
|
187
|
-
userLines.push("```html");
|
|
188
|
-
userLines.push(c.after.html);
|
|
189
|
-
userLines.push("```");
|
|
190
|
-
}
|
|
191
|
-
for (const a of added) {
|
|
192
|
-
if (a.kind !== "added")
|
|
193
|
-
continue;
|
|
194
|
-
userLines.push("");
|
|
195
|
-
userLines.push(`### ADDED in source — block=${a.blockName} position=${a.position} (must translate)`);
|
|
196
|
-
userLines.push("```html");
|
|
197
|
-
userLines.push(a.module.html);
|
|
198
|
-
userLines.push("```");
|
|
199
|
-
}
|
|
200
|
-
for (const r of removed) {
|
|
201
|
-
if (r.kind !== "removed")
|
|
202
|
-
continue;
|
|
203
|
-
userLines.push("");
|
|
204
|
-
userLines.push(`### REMOVED from source — block=${r.blockName} position=${r.position} (drop from the translation)`);
|
|
205
|
-
}
|
|
206
|
-
return { system, user: userLines.join("\n") };
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=translation.js.map
|
package/dist/translation.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"translation.js","sourceRoot":"","sources":["../src/translation.ts"],"names":[],"mappings":"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"}
|
package/src/design-manifest.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* issue #165 — the Design Manifest: a generated, versioned description
|
|
5
|
-
* of THIS site's design system (epic #149, growth-time convergence).
|
|
6
|
-
*
|
|
7
|
-
* The operator requirement is asymmetric: pages of the SAME site share
|
|
8
|
-
* one visual line, while different sites are free to look nothing
|
|
9
|
-
* alike. A global stylesheet solves the first at the cost of the
|
|
10
|
-
* second; the per-site manifest solves both — it captures what this
|
|
11
|
-
* site's tokens/patterns MEAN so the AI converges toward its own
|
|
12
|
-
* design, not a Caelo default.
|
|
13
|
-
*
|
|
14
|
-
* Written at Genesis materialisation (or curated later via chat);
|
|
15
|
-
* rendered as the `## Design system` system-prompt block.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { z } from "zod";
|
|
19
|
-
|
|
20
|
-
export const designManifestPattern = z
|
|
21
|
-
.object({
|
|
22
|
-
/** Pattern name the AI reasons in ("hero", "card grid", "cta band"). */
|
|
23
|
-
name: z.string().min(1).max(80),
|
|
24
|
-
/** Stable module `type` implementing it — reuse target (#159 place mode). */
|
|
25
|
-
moduleType: z.string().max(64).optional(),
|
|
26
|
-
/** One-line spec: what makes this pattern THIS site's version of it. */
|
|
27
|
-
spec: z.string().min(1).max(500),
|
|
28
|
-
})
|
|
29
|
-
.strict();
|
|
30
|
-
|
|
31
|
-
export const designManifestSchema = z
|
|
32
|
-
.object({
|
|
33
|
-
/** `--color-primary` → "CTAs and links only" — usage semantics per var. */
|
|
34
|
-
tokenRoles: z.record(z.string().min(3).max(64), z.string().min(1).max(300)).optional(),
|
|
35
|
-
/** Scale ratio, casing, measure rules. */
|
|
36
|
-
typography: z.string().min(1).max(1000).optional(),
|
|
37
|
-
/** Section padding, container width, grid gaps. */
|
|
38
|
-
rhythm: z.string().min(1).max(1000).optional(),
|
|
39
|
-
patterns: z.array(designManifestPattern).max(24).optional(),
|
|
40
|
-
imagery: z.string().min(1).max(500).optional(),
|
|
41
|
-
avoid: z.string().min(1).max(500).optional(),
|
|
42
|
-
})
|
|
43
|
-
.strict();
|
|
44
|
-
export type DesignManifest = z.infer<typeof designManifestSchema>;
|
|
45
|
-
|
|
46
|
-
/** Render the `## Design system` prompt block. Null when empty. */
|
|
47
|
-
export function formatDesignSystemBlock(manifest: DesignManifest | null): string | null {
|
|
48
|
-
if (manifest === null) return null;
|
|
49
|
-
const lines: string[] = [
|
|
50
|
-
"## Design system",
|
|
51
|
-
"",
|
|
52
|
-
"THIS site's own design language — derived from the chosen design. Every module you author or restyle conforms to it unless the operator explicitly asks to break the line. Reuse the pattern's module type (place mode) before minting lookalikes.",
|
|
53
|
-
"",
|
|
54
|
-
];
|
|
55
|
-
let hasContent = false;
|
|
56
|
-
const roles = manifest.tokenRoles ?? {};
|
|
57
|
-
const roleEntries = Object.entries(roles);
|
|
58
|
-
if (roleEntries.length > 0) {
|
|
59
|
-
hasContent = true;
|
|
60
|
-
lines.push("Token roles:");
|
|
61
|
-
for (const [token, role] of roleEntries.slice(0, 24)) lines.push(`- \`${token}\` — ${role}`);
|
|
62
|
-
lines.push("");
|
|
63
|
-
}
|
|
64
|
-
if (manifest.typography) {
|
|
65
|
-
hasContent = true;
|
|
66
|
-
lines.push(`Typography: ${manifest.typography}`, "");
|
|
67
|
-
}
|
|
68
|
-
if (manifest.rhythm) {
|
|
69
|
-
hasContent = true;
|
|
70
|
-
lines.push(`Rhythm: ${manifest.rhythm}`, "");
|
|
71
|
-
}
|
|
72
|
-
if (manifest.patterns && manifest.patterns.length > 0) {
|
|
73
|
-
hasContent = true;
|
|
74
|
-
lines.push("Patterns:");
|
|
75
|
-
for (const p of manifest.patterns) {
|
|
76
|
-
lines.push(
|
|
77
|
-
`- **${p.name}**${p.moduleType ? ` (module type \`${p.moduleType}\`)` : ""} — ${p.spec}`,
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
lines.push("");
|
|
81
|
-
}
|
|
82
|
-
if (manifest.imagery) {
|
|
83
|
-
hasContent = true;
|
|
84
|
-
lines.push(`Imagery: ${manifest.imagery}`, "");
|
|
85
|
-
}
|
|
86
|
-
if (manifest.avoid) {
|
|
87
|
-
hasContent = true;
|
|
88
|
-
lines.push(`Never: ${manifest.avoid}`, "");
|
|
89
|
-
}
|
|
90
|
-
if (!hasContent) return null;
|
|
91
|
-
while (lines[lines.length - 1] === "") lines.pop();
|
|
92
|
-
return lines.join("\n");
|
|
93
|
-
}
|