@intlayer/engine 9.4.0-canary.0 → 9.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cjs/build.cjs +1 -0
- package/dist/cjs/createType/createModuleAugmentation.cjs +22 -1
- package/dist/cjs/createType/createModuleAugmentation.cjs.map +1 -1
- package/dist/cjs/createType/index.cjs +1 -0
- package/dist/cjs/docReview/pipeline.cjs +21 -3
- package/dist/cjs/docReview/pipeline.cjs.map +1 -1
- package/dist/cjs/docReview/reviewReport.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs +6 -6
- package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs +11 -9
- package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs +10 -70
- package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
- package/dist/cjs/init/index.cjs +5 -3
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/installSkills/index.cjs +37 -6
- package/dist/cjs/installSkills/index.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs +21 -1
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs.map +1 -1
- package/dist/esm/build.mjs +2 -2
- package/dist/esm/createType/createModuleAugmentation.mjs +23 -3
- package/dist/esm/createType/createModuleAugmentation.mjs.map +1 -1
- package/dist/esm/createType/index.mjs +2 -2
- package/dist/esm/docReview/pipeline.mjs +21 -3
- package/dist/esm/docReview/pipeline.mjs.map +1 -1
- package/dist/esm/docReview/reviewReport.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs +7 -7
- package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs +11 -9
- package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs +11 -70
- package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
- package/dist/esm/init/index.mjs +5 -3
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/installSkills/index.mjs +37 -6
- package/dist/esm/installSkills/index.mjs.map +1 -1
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs +21 -1
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs.map +1 -1
- package/dist/types/build.d.ts +2 -2
- package/dist/types/createType/createModuleAugmentation.d.ts +16 -1
- package/dist/types/createType/createModuleAugmentation.d.ts.map +1 -1
- package/dist/types/createType/index.d.ts +2 -2
- package/dist/types/docReview/pipeline.d.ts +14 -2
- package/dist/types/docReview/pipeline.d.ts.map +1 -1
- package/dist/types/docReview/reviewReport.d.ts +6 -3
- package/dist/types/docReview/reviewReport.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts +4 -2
- package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts +8 -3
- package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts +8 -10
- package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts.map +1 -1
- package/dist/types/installSkills/index.d.ts.map +1 -1
- package/dist/types/writeConfiguration/generateConfigurationContent.d.ts +15 -0
- package/dist/types/writeConfiguration/generateConfigurationContent.d.ts.map +1 -1
- package/package.json +10 -10
|
@@ -228,22 +228,53 @@ const getLicenceContent = () => {
|
|
|
228
228
|
}
|
|
229
229
|
};
|
|
230
230
|
const ALLOWED_FETCH_HOSTS = /* @__PURE__ */ new Set(["intlayer.org"]);
|
|
231
|
+
/** Upper bound on the redirect chain a reference URL may take. */
|
|
232
|
+
const MAX_FETCH_REDIRECTS = 5;
|
|
231
233
|
/**
|
|
232
|
-
*
|
|
234
|
+
* Parses a URL and rejects it unless it is an HTTPS address on an allowed host.
|
|
235
|
+
*
|
|
236
|
+
* @param url - Absolute URL to validate.
|
|
237
|
+
* @returns The parsed URL.
|
|
238
|
+
* @throws When the protocol or host is not allowed.
|
|
233
239
|
*/
|
|
234
|
-
const
|
|
240
|
+
const parseAllowedUrl = (url) => {
|
|
235
241
|
const parsed = new URL(url);
|
|
236
242
|
if (parsed.protocol !== "https:" || !ALLOWED_FETCH_HOSTS.has(parsed.hostname)) throw new Error(`Blocked fetch to disallowed host: ${parsed.hostname}`);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
return parsed;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Fetches the content of a URL using native fetch.
|
|
247
|
+
*
|
|
248
|
+
* Redirects are followed manually so every hop is re-checked against the host
|
|
249
|
+
* allowlist — a redirect off `intlayer.org` is refused rather than silently
|
|
250
|
+
* followed. Letting `fetch` refuse them outright (`redirect: 'error'`) instead
|
|
251
|
+
* reported an unhelpful `TypeError: fetch failed` for a documentation URL that
|
|
252
|
+
* merely moved.
|
|
253
|
+
*
|
|
254
|
+
* @param url - Absolute URL to read.
|
|
255
|
+
* @returns The response body as text.
|
|
256
|
+
*/
|
|
257
|
+
const fetchUrlContent = async (url) => {
|
|
258
|
+
let target = parseAllowedUrl(url);
|
|
259
|
+
for (let hop = 0; hop <= MAX_FETCH_REDIRECTS; hop++) {
|
|
260
|
+
const response = await fetch(target, { redirect: "manual" });
|
|
261
|
+
if (response.status >= 300 && response.status < 400) {
|
|
262
|
+
const location = response.headers.get("location");
|
|
263
|
+
if (!location) throw new Error(`Failed to fetch ${url}: redirect without a location`);
|
|
264
|
+
target = parseAllowedUrl(new URL(location, target));
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (!response.ok) throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
|
|
268
|
+
return response.text();
|
|
269
|
+
}
|
|
270
|
+
throw new Error(`Failed to fetch ${url}: too many redirects`);
|
|
240
271
|
};
|
|
241
272
|
/**
|
|
242
273
|
* Installs skills using the "Agent Skills" directory standard.
|
|
243
274
|
* Standard: <PROJECT_ROOT>/<CONFIG_DIR>/skills/<SKILL_NAME>/SKILL.md
|
|
244
275
|
*/
|
|
245
276
|
const installSkills = async (projectRoot, platform, skills) => {
|
|
246
|
-
const relativeDir = PLATFORMS_METADATA[platform]
|
|
277
|
+
const relativeDir = PLATFORMS_METADATA[platform]?.dir ?? "skills";
|
|
247
278
|
const skillsBaseDir = path.join(projectRoot, relativeDir);
|
|
248
279
|
await promises.mkdir(skillsBaseDir, { recursive: true });
|
|
249
280
|
const createdSkills = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fs"],"sources":["../../../src/installSkills/index.ts"],"sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport { v } from '@intlayer/config/logger';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\n\n/**\n * Metadata for each available documentation skill.\n */\nexport const SKILLS_METADATA = {\n Config: 'Intlayer configuration documentation',\n Content: 'Reference for all Intlayer content node types (t, enu, etc.)',\n Usage: 'How to use Intlayer in your project',\n CLI: 'Intlayer CLI commands and usage',\n Compiler:\n 'Intlayer Compiler setup and usage for automatic content extraction without .content files',\n RemoteContent: 'How to use Intlayer with Remote/CMS/Server-side content',\n NextJS: 'Next.js-specific usage (Server & Client components)',\n React: 'React-specific syntax and hooks usage',\n Vue: 'Vue-specific composables and syntax',\n Svelte: 'Svelte-specific stores and syntax',\n Angular: 'Angular-specific syntax and Injectable Function usage',\n Preact: 'Preact-specific syntax and hooks usage',\n Solid:\n 'Integrates Intlayer internationalization with SolidJS components. Use when the user asks to \"setup SolidJS i18n\", use the \"useIntlayer\" hook in Solid, or manage locales in a SolidJS application.',\n Astro: 'Astro-specific usage and getIntlayer',\n} as const;\n\nexport type Skill = keyof typeof SKILLS_METADATA;\n\nexport const SKILLS = Object.keys(SKILLS_METADATA) as Skill[];\n\nexport const getInitialSkills = (\n deps: Record<string, string>\n): (keyof typeof SKILLS_METADATA)[] => {\n const skills: (keyof typeof SKILLS_METADATA)[] = [\n 'Usage',\n 'Content',\n 'Config',\n 'CLI',\n 'Compiler',\n ];\n\n if (deps.next) skills.push('NextJS');\n if (deps.react || !deps.next) skills.push('React');\n if (deps.preact) skills.push('Preact');\n if (deps['solid-js']) skills.push('Solid');\n if (deps.vue || deps.nuxt) skills.push('Vue');\n if (deps.svelte || deps['@sveltejs/kit']) skills.push('Svelte');\n if (deps.astro) skills.push('Astro');\n\n return skills;\n};\n\nexport interface PlatformMetadata {\n label: string;\n dir: string;\n check?: () => boolean;\n}\n\n/**\n * Metadata and configuration for each supported platform.\n */\nexport const PLATFORMS_METADATA: Record<string, PlatformMetadata> = {\n Cursor: {\n label: 'Cursor',\n dir: '.cursor/skills',\n check: () =>\n process.env.CURSOR === 'true' || process.env.TERM_PROGRAM === 'cursor',\n },\n Windsurf: {\n label: 'Windsurf',\n dir: '.windsurf/skills',\n check: () =>\n process.env.WINDSURF === 'true' ||\n process.env.TERM_PROGRAM === 'windsurf',\n },\n Trae: {\n label: 'Trae',\n dir: '.trae/skills',\n check: () =>\n process.env.TRAE === 'true' || process.env.TERM_PROGRAM === 'trae',\n },\n TraeCN: {\n label: 'Trae CN',\n dir: '.trae/skills',\n check: () => process.env.TRAE_CN === 'true',\n },\n VSCode: {\n label: 'VS Code',\n dir: '.vscode/skills',\n check: () =>\n process.env.VSCODE === 'true' || process.env.TERM_PROGRAM === 'vscode',\n },\n OpenCode: {\n label: 'OpenCode',\n dir: '.opencode/skills',\n check: () => process.env.OPENCODE === 'true',\n },\n Claude: {\n label: 'Claude Code',\n dir: '.claude/skills',\n check: () => process.env.CLAUDE === 'true',\n },\n GitHub: {\n label: 'GitHub Copilot Workspace',\n dir: '.github/skills',\n check: () =>\n process.env.GITHUB_ACTIONS === 'true' || !!process.env.GITHUB_WORKSPACE,\n },\n Antigravity: {\n label: 'Antigravity',\n dir: '.agent/skills',\n },\n Augment: {\n label: 'Augment',\n dir: '.augment/skills',\n },\n OpenClaw: {\n label: 'OpenClaw',\n dir: 'skills',\n },\n Cline: {\n label: 'Cline',\n dir: '.cline/skills',\n },\n CodeBuddy: {\n label: 'CodeBuddy',\n dir: '.codebuddy/skills',\n },\n CommandCode: {\n label: 'Command Code',\n dir: '.commandcode/skills',\n },\n Continue: {\n label: 'Continue',\n dir: '.continue/skills',\n },\n Crush: {\n label: 'Crush',\n dir: '.crush/skills',\n },\n Droid: {\n label: 'Droid',\n dir: '.factory/skills',\n },\n Goose: {\n label: 'Goose',\n dir: '.goose/skills',\n },\n IFlow: {\n label: 'iFlow CLI',\n dir: '.iflow/skills',\n },\n Junie: {\n label: 'Junie',\n dir: '.junie/skills',\n },\n KiloCode: {\n label: 'Kilo Code',\n dir: '.kilocode/skills',\n },\n Kiro: {\n label: 'Kiro CLI',\n dir: '.kiro/skills',\n },\n Kode: {\n label: 'Kode',\n dir: '.kode/skills',\n },\n MCPJam: {\n label: 'MCPJam',\n dir: '.mcpjam/skills',\n },\n MistralVibe: {\n label: 'Mistral Vibe',\n dir: '.vibe/skills',\n },\n Mux: {\n label: 'Mux',\n dir: '.mux/skills',\n },\n OpenHands: {\n label: 'OpenHands',\n dir: '.openhands/skills',\n },\n Pi: {\n label: 'Pi',\n dir: '.pi/skills',\n },\n Qoder: {\n label: 'Qoder',\n dir: '.qoder/skills',\n },\n Qwen: {\n label: 'Qwen Code',\n dir: '.qwen/skills',\n },\n RooCode: {\n label: 'Roo Code',\n dir: '.roo/skills',\n },\n Zencoder: {\n label: 'Zencoder',\n dir: '.zencoder/skills',\n },\n Neovate: {\n label: 'Neovate',\n dir: '.neovate/skills',\n },\n Pochi: {\n label: 'Pochi',\n dir: '.pochi/skills',\n },\n Other: {\n label: 'Other',\n dir: 'skills',\n },\n} as const;\n\nexport type Platform = keyof typeof PLATFORMS_METADATA;\n\nexport const PLATFORMS = Object.keys(PLATFORMS_METADATA) as Platform[];\n\n/**\n * Maps specific skill keys to special filenames if they differ from standard snake_case.\n */\nconst SKILL_FILENAME_MAP: Partial<Record<Skill, string>> = {};\n\n/**\n * Helper to convert CamelCase to kebab-case for directory naming\n */\nconst camelToKebabCase = (str: string) =>\n str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Reads the raw markdown content for a specific skill from the assets folder.\n */\nconst getSkillContent = (skill: Skill): string => {\n const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n const fileName = `./skills/${baseName}.md`;\n\n try {\n return readAsset(fileName);\n } catch {\n console.warn(\n `Warning: Could not read asset for skill: ${skill} at ${fileName}`\n );\n return '';\n }\n};\n\n/**\n * Reads the licence content from the assets folder.\n */\nconst getLicenceContent = (): string => {\n try {\n return readAsset('./LICENCE.md');\n } catch {\n console.warn('Warning: Could not read LICENCE.md asset');\n return '';\n }\n};\n\nconst ALLOWED_FETCH_HOSTS = new Set(['intlayer.org']);\n\n/**\n * Fetches the content of a URL using native fetch.\n */\nconst fetchUrlContent = async (url: string): Promise<string> => {\n const parsed = new URL(url);\n if (\n parsed.protocol !== 'https:' ||\n !ALLOWED_FETCH_HOSTS.has(parsed.hostname)\n ) {\n throw new Error(`Blocked fetch to disallowed host: ${parsed.hostname}`);\n }\n const response = await fetch(url, { redirect: 'error' });\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}: ${response.statusText}`);\n }\n return response.text();\n};\n\n/**\n * Installs skills using the \"Agent Skills\" directory standard.\n * Standard: <PROJECT_ROOT>/<CONFIG_DIR>/skills/<SKILL_NAME>/SKILL.md\n */\nexport const installSkills = async (\n projectRoot: string,\n platform: Platform,\n skills: Skill[]\n): Promise<string> => {\n // Determine destination directory\n const relativeDir = PLATFORMS_METADATA[platform].dir ?? 'skills';\n const skillsBaseDir = path.join(projectRoot, relativeDir);\n\n // Ensure the base directory exists\n await fs.mkdir(skillsBaseDir, { recursive: true });\n\n const createdSkills: string[] = [];\n const licenceContent = getLicenceContent();\n\n for (const skill of skills) {\n const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n const skillName = `intlayer-${baseName}`;\n const skillContent = getSkillContent(skill);\n\n if (!skillContent) continue;\n\n // Extract unique URLs\n const urls = Array.from(\n new Set(skillContent.match(/https:\\/\\/intlayer\\.org\\/[^\\s)]+\\.md/g) || [])\n );\n\n // Agent Standard: .../skills/<skill-name>/SKILL.md\n const skillDir = path.join(skillsBaseDir, skillName);\n const referenceDir = path.join(skillDir, 'references');\n\n // Ensure directories exist\n await fs.mkdir(referenceDir, { recursive: true });\n\n // Write License\n if (licenceContent) {\n await fs.writeFile(\n path.join(skillDir, 'LICENCE.md'),\n licenceContent,\n 'utf-8'\n );\n }\n\n let updatedSkillContent = skillContent;\n\n // Parallel download of references\n const downloadPromises = urls.map(async (url) => {\n try {\n const content = await fetchUrlContent(url);\n const metadata = getMarkdownMetadata<{ slugs?: string[] }>(content);\n\n let fileName = '';\n\n // Determine filename from slugs or URL path\n if (Array.isArray(metadata.slugs)) {\n fileName = metadata.slugs.filter((slug) => slug !== 'doc').join('_');\n } else {\n const urlPath = new URL(url).pathname;\n fileName = urlPath\n .split('/')\n .filter((part) => part && part !== 'doc')\n .map((part) => part.replace('.md', '')) // Clean extension for joining\n .join('_');\n }\n\n // Ensure it ends with .md\n fileName = fileName ? `${fileName}.md` : 'index.md';\n const localRefPath = `references/${fileName}`;\n\n return {\n url,\n localRefPath,\n fileName,\n content,\n success: true,\n };\n } catch (error) {\n console.warn(\n `Warning: Failed to download ref ${url} for skill ${skill}`,\n error\n );\n return { url, success: false };\n }\n });\n\n const results = await Promise.all(downloadPromises);\n\n // Process results: Write files and update content string\n for (const res of results) {\n if (res.success && res.fileName && res.content && res.localRefPath) {\n // Write the reference file\n await fs.writeFile(\n path.join(referenceDir, res.fileName),\n res.content,\n 'utf-8'\n );\n\n // Update the main content to point to local file\n updatedSkillContent = updatedSkillContent.replaceAll(\n res.url,\n res.localRefPath\n );\n }\n }\n\n // Write the main SKILL.md\n const filePath = path.join(skillDir, 'SKILL.md');\n await fs.writeFile(filePath, updatedSkillContent, 'utf-8');\n createdSkills.push(`${skillName}/SKILL.md`);\n }\n\n if (createdSkills.length === 0) {\n return `No skill files were created. Check your asset paths.`;\n }\n\n return `${v} Created ${createdSkills.length} skills in ${skillsBaseDir}`;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["fs"],"sources":["../../../src/installSkills/index.ts"],"sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport { v } from '@intlayer/config/logger';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\n\n/**\n * Metadata for each available documentation skill.\n */\nexport const SKILLS_METADATA = {\n Config: 'Intlayer configuration documentation',\n Content: 'Reference for all Intlayer content node types (t, enu, etc.)',\n Usage: 'How to use Intlayer in your project',\n CLI: 'Intlayer CLI commands and usage',\n Compiler:\n 'Intlayer Compiler setup and usage for automatic content extraction without .content files',\n RemoteContent: 'How to use Intlayer with Remote/CMS/Server-side content',\n NextJS: 'Next.js-specific usage (Server & Client components)',\n React: 'React-specific syntax and hooks usage',\n Vue: 'Vue-specific composables and syntax',\n Svelte: 'Svelte-specific stores and syntax',\n Angular: 'Angular-specific syntax and Injectable Function usage',\n Preact: 'Preact-specific syntax and hooks usage',\n Solid:\n 'Integrates Intlayer internationalization with SolidJS components. Use when the user asks to \"setup SolidJS i18n\", use the \"useIntlayer\" hook in Solid, or manage locales in a SolidJS application.',\n Astro: 'Astro-specific usage and getIntlayer',\n} as const;\n\nexport type Skill = keyof typeof SKILLS_METADATA;\n\nexport const SKILLS = Object.keys(SKILLS_METADATA) as Skill[];\n\nexport const getInitialSkills = (\n deps: Record<string, string>\n): (keyof typeof SKILLS_METADATA)[] => {\n const skills: (keyof typeof SKILLS_METADATA)[] = [\n 'Usage',\n 'Content',\n 'Config',\n 'CLI',\n 'Compiler',\n ];\n\n if (deps.next) skills.push('NextJS');\n if (deps.react || !deps.next) skills.push('React');\n if (deps.preact) skills.push('Preact');\n if (deps['solid-js']) skills.push('Solid');\n if (deps.vue || deps.nuxt) skills.push('Vue');\n if (deps.svelte || deps['@sveltejs/kit']) skills.push('Svelte');\n if (deps.astro) skills.push('Astro');\n\n return skills;\n};\n\nexport interface PlatformMetadata {\n label: string;\n dir: string;\n check?: () => boolean;\n}\n\n/**\n * Metadata and configuration for each supported platform.\n */\nexport const PLATFORMS_METADATA: Record<string, PlatformMetadata> = {\n Cursor: {\n label: 'Cursor',\n dir: '.cursor/skills',\n check: () =>\n process.env.CURSOR === 'true' || process.env.TERM_PROGRAM === 'cursor',\n },\n Windsurf: {\n label: 'Windsurf',\n dir: '.windsurf/skills',\n check: () =>\n process.env.WINDSURF === 'true' ||\n process.env.TERM_PROGRAM === 'windsurf',\n },\n Trae: {\n label: 'Trae',\n dir: '.trae/skills',\n check: () =>\n process.env.TRAE === 'true' || process.env.TERM_PROGRAM === 'trae',\n },\n TraeCN: {\n label: 'Trae CN',\n dir: '.trae/skills',\n check: () => process.env.TRAE_CN === 'true',\n },\n VSCode: {\n label: 'VS Code',\n dir: '.vscode/skills',\n check: () =>\n process.env.VSCODE === 'true' || process.env.TERM_PROGRAM === 'vscode',\n },\n OpenCode: {\n label: 'OpenCode',\n dir: '.opencode/skills',\n check: () => process.env.OPENCODE === 'true',\n },\n Claude: {\n label: 'Claude Code',\n dir: '.claude/skills',\n check: () => process.env.CLAUDE === 'true',\n },\n GitHub: {\n label: 'GitHub Copilot Workspace',\n dir: '.github/skills',\n check: () =>\n process.env.GITHUB_ACTIONS === 'true' || !!process.env.GITHUB_WORKSPACE,\n },\n Antigravity: {\n label: 'Antigravity',\n dir: '.agent/skills',\n },\n Augment: {\n label: 'Augment',\n dir: '.augment/skills',\n },\n OpenClaw: {\n label: 'OpenClaw',\n dir: 'skills',\n },\n Cline: {\n label: 'Cline',\n dir: '.cline/skills',\n },\n CodeBuddy: {\n label: 'CodeBuddy',\n dir: '.codebuddy/skills',\n },\n CommandCode: {\n label: 'Command Code',\n dir: '.commandcode/skills',\n },\n Continue: {\n label: 'Continue',\n dir: '.continue/skills',\n },\n Crush: {\n label: 'Crush',\n dir: '.crush/skills',\n },\n Droid: {\n label: 'Droid',\n dir: '.factory/skills',\n },\n Goose: {\n label: 'Goose',\n dir: '.goose/skills',\n },\n IFlow: {\n label: 'iFlow CLI',\n dir: '.iflow/skills',\n },\n Junie: {\n label: 'Junie',\n dir: '.junie/skills',\n },\n KiloCode: {\n label: 'Kilo Code',\n dir: '.kilocode/skills',\n },\n Kiro: {\n label: 'Kiro CLI',\n dir: '.kiro/skills',\n },\n Kode: {\n label: 'Kode',\n dir: '.kode/skills',\n },\n MCPJam: {\n label: 'MCPJam',\n dir: '.mcpjam/skills',\n },\n MistralVibe: {\n label: 'Mistral Vibe',\n dir: '.vibe/skills',\n },\n Mux: {\n label: 'Mux',\n dir: '.mux/skills',\n },\n OpenHands: {\n label: 'OpenHands',\n dir: '.openhands/skills',\n },\n Pi: {\n label: 'Pi',\n dir: '.pi/skills',\n },\n Qoder: {\n label: 'Qoder',\n dir: '.qoder/skills',\n },\n Qwen: {\n label: 'Qwen Code',\n dir: '.qwen/skills',\n },\n RooCode: {\n label: 'Roo Code',\n dir: '.roo/skills',\n },\n Zencoder: {\n label: 'Zencoder',\n dir: '.zencoder/skills',\n },\n Neovate: {\n label: 'Neovate',\n dir: '.neovate/skills',\n },\n Pochi: {\n label: 'Pochi',\n dir: '.pochi/skills',\n },\n Other: {\n label: 'Other',\n dir: 'skills',\n },\n} as const;\n\nexport type Platform = keyof typeof PLATFORMS_METADATA;\n\nexport const PLATFORMS = Object.keys(PLATFORMS_METADATA) as Platform[];\n\n/**\n * Maps specific skill keys to special filenames if they differ from standard snake_case.\n */\nconst SKILL_FILENAME_MAP: Partial<Record<Skill, string>> = {};\n\n/**\n * Helper to convert CamelCase to kebab-case for directory naming\n */\nconst camelToKebabCase = (str: string) =>\n str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Reads the raw markdown content for a specific skill from the assets folder.\n */\nconst getSkillContent = (skill: Skill): string => {\n const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n const fileName = `./skills/${baseName}.md`;\n\n try {\n return readAsset(fileName);\n } catch {\n console.warn(\n `Warning: Could not read asset for skill: ${skill} at ${fileName}`\n );\n return '';\n }\n};\n\n/**\n * Reads the licence content from the assets folder.\n */\nconst getLicenceContent = (): string => {\n try {\n return readAsset('./LICENCE.md');\n } catch {\n console.warn('Warning: Could not read LICENCE.md asset');\n return '';\n }\n};\n\nconst ALLOWED_FETCH_HOSTS = new Set(['intlayer.org']);\n\n/** Upper bound on the redirect chain a reference URL may take. */\nconst MAX_FETCH_REDIRECTS = 5;\n\n/**\n * Parses a URL and rejects it unless it is an HTTPS address on an allowed host.\n *\n * @param url - Absolute URL to validate.\n * @returns The parsed URL.\n * @throws When the protocol or host is not allowed.\n */\nconst parseAllowedUrl = (url: string | URL): URL => {\n const parsed = new URL(url);\n\n if (\n parsed.protocol !== 'https:' ||\n !ALLOWED_FETCH_HOSTS.has(parsed.hostname)\n ) {\n throw new Error(`Blocked fetch to disallowed host: ${parsed.hostname}`);\n }\n\n return parsed;\n};\n\n/**\n * Fetches the content of a URL using native fetch.\n *\n * Redirects are followed manually so every hop is re-checked against the host\n * allowlist — a redirect off `intlayer.org` is refused rather than silently\n * followed. Letting `fetch` refuse them outright (`redirect: 'error'`) instead\n * reported an unhelpful `TypeError: fetch failed` for a documentation URL that\n * merely moved.\n *\n * @param url - Absolute URL to read.\n * @returns The response body as text.\n */\nconst fetchUrlContent = async (url: string): Promise<string> => {\n let target = parseAllowedUrl(url);\n\n for (let hop = 0; hop <= MAX_FETCH_REDIRECTS; hop++) {\n const response = await fetch(target, { redirect: 'manual' });\n\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location');\n\n if (!location) {\n throw new Error(`Failed to fetch ${url}: redirect without a location`);\n }\n\n target = parseAllowedUrl(new URL(location, target));\n continue;\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}: ${response.statusText}`);\n }\n\n return response.text();\n }\n\n throw new Error(`Failed to fetch ${url}: too many redirects`);\n};\n\n/**\n * Installs skills using the \"Agent Skills\" directory standard.\n * Standard: <PROJECT_ROOT>/<CONFIG_DIR>/skills/<SKILL_NAME>/SKILL.md\n */\nexport const installSkills = async (\n projectRoot: string,\n platform: Platform,\n skills: Skill[]\n): Promise<string> => {\n // Determine destination directory\n const relativeDir = PLATFORMS_METADATA[platform]?.dir ?? 'skills';\n const skillsBaseDir = path.join(projectRoot, relativeDir);\n\n // Ensure the base directory exists\n await fs.mkdir(skillsBaseDir, { recursive: true });\n\n const createdSkills: string[] = [];\n const licenceContent = getLicenceContent();\n\n for (const skill of skills) {\n const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n const skillName = `intlayer-${baseName}`;\n const skillContent = getSkillContent(skill);\n\n if (!skillContent) continue;\n\n // Extract unique URLs\n const urls = Array.from(\n new Set(skillContent.match(/https:\\/\\/intlayer\\.org\\/[^\\s)]+\\.md/g) || [])\n );\n\n // Agent Standard: .../skills/<skill-name>/SKILL.md\n const skillDir = path.join(skillsBaseDir, skillName);\n const referenceDir = path.join(skillDir, 'references');\n\n // Ensure directories exist\n await fs.mkdir(referenceDir, { recursive: true });\n\n // Write License\n if (licenceContent) {\n await fs.writeFile(\n path.join(skillDir, 'LICENCE.md'),\n licenceContent,\n 'utf-8'\n );\n }\n\n let updatedSkillContent = skillContent;\n\n // Parallel download of references\n const downloadPromises = urls.map(async (url) => {\n try {\n const content = await fetchUrlContent(url);\n const metadata = getMarkdownMetadata<{ slugs?: string[] }>(content);\n\n let fileName = '';\n\n // Determine filename from slugs or URL path\n if (Array.isArray(metadata.slugs)) {\n fileName = metadata.slugs.filter((slug) => slug !== 'doc').join('_');\n } else {\n const urlPath = new URL(url).pathname;\n fileName = urlPath\n .split('/')\n .filter((part) => part && part !== 'doc')\n .map((part) => part.replace('.md', '')) // Clean extension for joining\n .join('_');\n }\n\n // Ensure it ends with .md\n fileName = fileName ? `${fileName}.md` : 'index.md';\n const localRefPath = `references/${fileName}`;\n\n return {\n url,\n localRefPath,\n fileName,\n content,\n success: true,\n };\n } catch (error) {\n console.warn(\n `Warning: Failed to download ref ${url} for skill ${skill}`,\n error\n );\n return { url, success: false };\n }\n });\n\n const results = await Promise.all(downloadPromises);\n\n // Process results: Write files and update content string\n for (const res of results) {\n if (res.success && res.fileName && res.content && res.localRefPath) {\n // Write the reference file\n await fs.writeFile(\n path.join(referenceDir, res.fileName),\n res.content,\n 'utf-8'\n );\n\n // Update the main content to point to local file\n updatedSkillContent = updatedSkillContent.replaceAll(\n res.url,\n res.localRefPath\n );\n }\n }\n\n // Write the main SKILL.md\n const filePath = path.join(skillDir, 'SKILL.md');\n await fs.writeFile(filePath, updatedSkillContent, 'utf-8');\n createdSkills.push(`${skillName}/SKILL.md`);\n }\n\n if (createdSkills.length === 0) {\n return `No skill files were created. Check your asset paths.`;\n }\n\n return `${v} Created ${createdSkills.length} skills in ${skillsBaseDir}`;\n};\n"],"mappings":"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"}
|
|
@@ -10,14 +10,34 @@ import { BUILT_CONFIG_KEYS } from "@intlayer/config/utils";
|
|
|
10
10
|
* exports consumers import — preventing `MISSING_EXPORT` errors when a new
|
|
11
11
|
* configuration section (e.g. `analytics`) is added.
|
|
12
12
|
*
|
|
13
|
+
* ## Why `editor.clientSecret` is never emitted
|
|
14
|
+
*
|
|
15
|
+
* This file is what a bundle *inlines*. Every framework integration installs the
|
|
16
|
+
* same alias for the client and the server build, so anything written here that
|
|
17
|
+
* a client module imports ends up in a public asset — and `editor` is imported
|
|
18
|
+
* by browser code (the provider, the analytics SDK, the visual editor).
|
|
19
|
+
*
|
|
20
|
+
* `clientSecret` grants full project-scoped API access, so it is stripped here
|
|
21
|
+
* rather than in each integration: a per-bundler fix only protects the bundlers
|
|
22
|
+
* we patched, while stripping it at the source protects every consumer,
|
|
23
|
+
* including ones that build their own alias.
|
|
24
|
+
*
|
|
25
|
+
* Server-side code reads the secret from `@intlayer/config/secrets`, whose
|
|
26
|
+
* `browser` export condition resolves to an empty stub in browser builds.
|
|
27
|
+
*
|
|
13
28
|
* @param configuration - The fully resolved Intlayer configuration.
|
|
14
29
|
* @param format - Module format to emit (`esm` for `.mjs`, `cjs` for `.cjs`).
|
|
15
30
|
* @returns The file content as a string.
|
|
16
31
|
*/
|
|
17
32
|
const generateConfigurationContent = (configuration, format) => {
|
|
18
33
|
let fileContent = "";
|
|
34
|
+
const { clientSecret: _clientSecret, ...editorWithoutSecret } = configuration.editor;
|
|
35
|
+
const values = {
|
|
36
|
+
...configuration,
|
|
37
|
+
editor: editorWithoutSecret
|
|
38
|
+
};
|
|
19
39
|
for (const key of BUILT_CONFIG_KEYS) {
|
|
20
|
-
const value =
|
|
40
|
+
const value = values[key];
|
|
21
41
|
fileContent += `const ${key} = ${JSON.stringify(value, null, 2)};\n`;
|
|
22
42
|
}
|
|
23
43
|
if (format === "esm") fileContent += `\nexport { ${BUILT_CONFIG_KEYS.join(", ")} };\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import { BUILT_CONFIG_KEYS } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n\n/**\n * Generates the source of the `.intlayer/config/configuration.{mjs,cjs}` file\n * that bundler integrations alias `@intlayer/config/built` to.\n *\n * The emitted named exports are derived from {@link BUILT_CONFIG_KEYS}, the same\n * canonical list `built.ts` uses, so the aliased file always exposes exactly the\n * exports consumers import — preventing `MISSING_EXPORT` errors when a new\n * configuration section (e.g. `analytics`) is added.\n *\n * @param configuration - The fully resolved Intlayer configuration.\n * @param format - Module format to emit (`esm` for `.mjs`, `cjs` for `.cjs`).\n * @returns The file content as a string.\n */\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n let fileContent = '';\n\n for (const key of BUILT_CONFIG_KEYS) {\n const value =
|
|
1
|
+
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import { BUILT_CONFIG_KEYS } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n\n/**\n * Generates the source of the `.intlayer/config/configuration.{mjs,cjs}` file\n * that bundler integrations alias `@intlayer/config/built` to.\n *\n * The emitted named exports are derived from {@link BUILT_CONFIG_KEYS}, the same\n * canonical list `built.ts` uses, so the aliased file always exposes exactly the\n * exports consumers import — preventing `MISSING_EXPORT` errors when a new\n * configuration section (e.g. `analytics`) is added.\n *\n * ## Why `editor.clientSecret` is never emitted\n *\n * This file is what a bundle *inlines*. Every framework integration installs the\n * same alias for the client and the server build, so anything written here that\n * a client module imports ends up in a public asset — and `editor` is imported\n * by browser code (the provider, the analytics SDK, the visual editor).\n *\n * `clientSecret` grants full project-scoped API access, so it is stripped here\n * rather than in each integration: a per-bundler fix only protects the bundlers\n * we patched, while stripping it at the source protects every consumer,\n * including ones that build their own alias.\n *\n * Server-side code reads the secret from `@intlayer/config/secrets`, whose\n * `browser` export condition resolves to an empty stub in browser builds.\n *\n * @param configuration - The fully resolved Intlayer configuration.\n * @param format - Module format to emit (`esm` for `.mjs`, `cjs` for `.cjs`).\n * @returns The file content as a string.\n */\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n let fileContent = '';\n\n const { clientSecret: _clientSecret, ...editorWithoutSecret } =\n configuration.editor;\n\n const values: Record<string, unknown> = {\n ...configuration,\n editor: editorWithoutSecret,\n };\n\n for (const key of BUILT_CONFIG_KEYS) {\n const value = values[key];\n fileContent += `const ${key} = ${JSON.stringify(value, null, 2)};\\n`;\n }\n\n if (format === 'esm') {\n fileContent += `\\nexport { ${BUILT_CONFIG_KEYS.join(', ')} };\\n`;\n } else {\n fileContent += '\\n';\n for (const key of BUILT_CONFIG_KEYS) {\n fileContent += `module.exports.${key} = ${key};\\n`;\n }\n }\n\n return fileContent;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,MAAa,gCACX,eACA,WACW;CACX,IAAI,cAAc;CAElB,MAAM,EAAE,cAAc,eAAe,GAAG,wBACtC,cAAc;CAEhB,MAAM,SAAkC;EACtC,GAAG;EACH,QAAQ;CACV;CAEA,KAAK,MAAM,OAAO,mBAAmB;EACnC,MAAM,QAAQ,OAAO;EACrB,eAAe,SAAS,IAAI,KAAK,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;CAClE;CAEA,IAAI,WAAW,OACb,eAAe,cAAc,kBAAkB,KAAK,IAAI,EAAE;MACrD;EACL,eAAe;EACf,KAAK,MAAM,OAAO,mBAChB,eAAe,kBAAkB,IAAI,KAAK,IAAI;CAElD;CAEA,OAAO;AACT"}
|
package/dist/types/build.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { getBuiltFetchDictionariesPath } from "./createDictionaryEntryPoint/getB
|
|
|
10
10
|
import { getBuiltRemoteDictionariesPath } from "./createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.js";
|
|
11
11
|
import { getBuiltUnmergedDictionariesPath } from "./createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.js";
|
|
12
12
|
import "./createDictionaryEntryPoint/index.js";
|
|
13
|
-
import { createModuleAugmentation, formatRewriteRules, getTypeName } from "./createType/createModuleAugmentation.js";
|
|
13
|
+
import { createModuleAugmentation, formatDomains, formatRewriteRules, getTypeName } from "./createType/createModuleAugmentation.js";
|
|
14
14
|
import { createTypes, generateTypeScriptType } from "./createType/createType.js";
|
|
15
15
|
import "./createType/index.js";
|
|
16
16
|
import { formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput } from "./formatDictionary.js";
|
|
@@ -28,4 +28,4 @@ import { transformJSFile } from "./writeContentDeclaration/transformJSFile.js";
|
|
|
28
28
|
import { writeContentDeclaration } from "./writeContentDeclaration/writeContentDeclaration.js";
|
|
29
29
|
import { writeJSFile } from "./writeContentDeclaration/writeJSFile.js";
|
|
30
30
|
import "./writeContentDeclaration/index.js";
|
|
31
|
-
export { BuildDictionariesOptions, CreateDictionaryEntryPointOptions, DictionariesStatus, DictionaryStatus, buildDictionary, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, ensureIntlayerBundle, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatLocalDictionaries, formatRewriteRules, generateDictionaryListContent, generateTypeScriptType, getBuiltDictionariesPath, getBuiltDynamicDictionariesPath, getBuiltFetchDictionariesPath, getBuiltRemoteDictionariesPath, getBuiltUnmergedDictionariesPath, getTypeName, isCachedConfigurationUpToDate, loadContentDeclaration, loadContentDeclarations, loadDictionaries, loadLocalDictionaries, loadRemoteDictionaries, prepareIntlayer, processContentDeclaration, readDictionariesFromDisk, transformJSFile, writeConfiguration, writeContentDeclaration, writeJSFile };
|
|
31
|
+
export { BuildDictionariesOptions, CreateDictionaryEntryPointOptions, DictionariesStatus, DictionaryStatus, buildDictionary, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, ensureIntlayerBundle, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatDomains, formatLocalDictionaries, formatRewriteRules, generateDictionaryListContent, generateTypeScriptType, getBuiltDictionariesPath, getBuiltDynamicDictionariesPath, getBuiltFetchDictionariesPath, getBuiltRemoteDictionariesPath, getBuiltUnmergedDictionariesPath, getTypeName, isCachedConfigurationUpToDate, loadContentDeclaration, loadContentDeclarations, loadDictionaries, loadLocalDictionaries, loadRemoteDictionaries, prepareIntlayer, processContentDeclaration, readDictionariesFromDisk, transformJSFile, writeConfiguration, writeContentDeclaration, writeJSFile };
|
|
@@ -11,8 +11,23 @@ declare const getTypeName: (key: string) => string;
|
|
|
11
11
|
* is exactly what the runtime matches against.
|
|
12
12
|
*/
|
|
13
13
|
declare const formatRewriteRules: (rewrite: RoutingConfig['rewrite']) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Serializes the `routing.domains` map as a type literal, so `getLocalizedUrl`
|
|
16
|
+
* and `getLocalizedPath` can resolve the origin of a locale — and the
|
|
17
|
+
* suppression of its path prefix — at the type level. Returns an empty string
|
|
18
|
+
* when the project maps no locale to a domain.
|
|
19
|
+
*
|
|
20
|
+
* Each entry carries the two facts the consuming types need, both computed with
|
|
21
|
+
* the very helpers the runtime uses:
|
|
22
|
+
* - `origin`: the normalized origin ({@link getDomainOrigin}), prepended to the
|
|
23
|
+
* localized path when the target locale lives on another domain.
|
|
24
|
+
* - `exclusive`: whether the locale is the only one on that hostname
|
|
25
|
+
* ({@link isLocaleExclusiveOnDomain}), in which case the domain identifies the
|
|
26
|
+
* locale and no path prefix is emitted.
|
|
27
|
+
*/
|
|
28
|
+
declare const formatDomains: (domains: RoutingConfig['domains']) => string;
|
|
14
29
|
/** Generate the index file merging all the types */
|
|
15
30
|
declare const createModuleAugmentation: (configuration: IntlayerConfig) => Promise<void>;
|
|
16
31
|
//#endregion
|
|
17
|
-
export { createModuleAugmentation, formatRewriteRules, getTypeName };
|
|
32
|
+
export { createModuleAugmentation, formatDomains, formatRewriteRules, getTypeName };
|
|
18
33
|
//# sourceMappingURL=createModuleAugmentation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createModuleAugmentation.d.ts","names":[],"sources":["../../../src/createType/createModuleAugmentation.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"createModuleAugmentation.d.ts","names":[],"sources":["../../../src/createType/createModuleAugmentation.ts"],"mappings":";;cAca,cAAW;;;;;;;;;;cAgBX,qBAAkB,SACpB;;;;;;;;;;;;;;;cAkCE,gBAAa,SAAa;;cAuM1B,2BAAwB,eACpB,mBAAc"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createModuleAugmentation, formatRewriteRules, getTypeName } from "./createModuleAugmentation.js";
|
|
1
|
+
import { createModuleAugmentation, formatDomains, formatRewriteRules, getTypeName } from "./createModuleAugmentation.js";
|
|
2
2
|
import { createTypes, generateTypeScriptType } from "./createType.js";
|
|
3
|
-
export { createModuleAugmentation, createTypes, formatRewriteRules, generateTypeScriptType, getTypeName };
|
|
3
|
+
export { createModuleAugmentation, createTypes, formatDomains, formatRewriteRules, generateTypeScriptType, getTypeName };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FingerprintedBlock } from "./types.js";
|
|
1
|
+
import { AlignmentPlan, FingerprintedBlock } from "./types.js";
|
|
2
2
|
import { SegmentToReview, mergeReviewedSegments } from "./rebuildDocument.js";
|
|
3
3
|
//#region src/docReview/pipeline.d.ts
|
|
4
4
|
type BuildAlignmentPlanInput = {
|
|
@@ -6,7 +6,13 @@ type BuildAlignmentPlanInput = {
|
|
|
6
6
|
baseText: string;
|
|
7
7
|
/** The existing target (translated) document, possibly empty. */
|
|
8
8
|
targetText: string;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* 1-based line numbers that changed in the base document.
|
|
11
|
+
*
|
|
12
|
+
* `undefined` means the changed lines are unknown (no git history available):
|
|
13
|
+
* every section is then compared block by block. An empty array means nothing
|
|
14
|
+
* changed, and every aligned block is reused.
|
|
15
|
+
*/
|
|
10
16
|
changedLines: number[] | undefined;
|
|
11
17
|
};
|
|
12
18
|
type BuildAlignmentPlanOutput = {
|
|
@@ -29,6 +35,12 @@ type BuildAlignmentPlanOutput = {
|
|
|
29
35
|
* whole section. Within a changed section a target block with no base
|
|
30
36
|
* counterpart is **kept as-is** (reused) rather than deleted, so a translation
|
|
31
37
|
* that has extra paragraphs never loses content.
|
|
38
|
+
* When `changedLines` is `undefined` the changed lines are simply unknown, so
|
|
39
|
+
* **every** section is inspected instead of none: aligned blocks are still
|
|
40
|
+
* reused (there is no way to tell which translation went stale), but blocks
|
|
41
|
+
* living on one side only are reported as `insert_new` / `delete`. This is
|
|
42
|
+
* what makes a plain "compare this document with its translation" run — one
|
|
43
|
+
* with no git history behind it — report anything at all.
|
|
32
44
|
*
|
|
33
45
|
* Section-level insertions and deletions stay whole: a brand-new section is
|
|
34
46
|
* translated as one unit, and a target section with no base counterpart is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","names":[],"sources":["../../../src/docReview/pipeline.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","names":[],"sources":["../../../src/docReview/pipeline.ts"],"mappings":";;;KAiBY;;EAEV;;EAEA;;;;;;;;EAQA;;KAGU;EACV,YAAY;EACZ,cAAc;EACd,MAAM;EACN,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4DP,uBAAkB,UAAA,YAAA,gBAI5B,4BAA0B"}
|
|
@@ -54,9 +54,12 @@ type BuildReviewReportInput = {
|
|
|
54
54
|
/** The existing target (translated) document, possibly empty. */
|
|
55
55
|
targetText: string;
|
|
56
56
|
/**
|
|
57
|
-
* 1-based line numbers that changed in the base document.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* 1-based line numbers that changed in the base document.
|
|
58
|
+
*
|
|
59
|
+
* When omitted the whole document is compared, and only inserted and deleted
|
|
60
|
+
* blocks are reported (no aligned block is flagged for review since there is
|
|
61
|
+
* no way to know which ones changed). An empty array means nothing changed,
|
|
62
|
+
* and no block at all is reported.
|
|
60
63
|
*/
|
|
61
64
|
changedLines?: number[];
|
|
62
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewReport.d.ts","names":[],"sources":["../../../src/docReview/reviewReport.ts"],"mappings":";;;;;;;;;KAYY;;KAGA;EACV;EACA;;;;;;;;;KAUU;;EAEV,QAAQ;;EAER,gBAAgB;;EAEhB,kBAAkB;;EAElB;;EAEA;;KAGU;;EAEV;;EAEA;;EAEA;;EAEA;;KAGU;;EAEV,QAAQ;;EAER,SAAS;;KAGC;;EAEV;;EAEA
|
|
1
|
+
{"version":3,"file":"reviewReport.d.ts","names":[],"sources":["../../../src/docReview/reviewReport.ts"],"mappings":";;;;;;;;;KAYY;;KAGA;EACV;EACA;;;;;;;;;KAUU;;EAEV,QAAQ;;EAER,gBAAgB;;EAEhB,kBAAkB;;EAElB;;EAEA;;KAGU;;EAEV;;EAEA;;EAEA;;EAEA;;KAGU;;EAEV,QAAQ;;EAER,SAAS;;KAGC;;EAEV;;EAEA;;;;;;;;;EASA;;;;;;;;;;;;;cAcW,sBAAiB,UAAA,YAAA,gBAI3B,2BAAyB;;;;;;;;;;;cAgJf,qBAAkB,QACrB,cAAY;EACR;EAAoB"}
|
|
@@ -2,8 +2,10 @@ import { FrameworkAdapter } from "../types.js";
|
|
|
2
2
|
//#region src/init/frameworkSetup/nextAppRouter/index.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Next.js App Router adapter. Scaffolds the locale proxy/middleware, restructures
|
|
5
|
-
* the app into a `[locale]` segment, and wraps the layout
|
|
6
|
-
*
|
|
5
|
+
* the app into a `[locale]` segment, and wraps the layout with the unified
|
|
6
|
+
* Intlayer provider — all idempotently and without overwriting recognizable
|
|
7
|
+
* user code. Pages are never wrapped: `IntlayerProvider` in the locale layout
|
|
8
|
+
* covers them.
|
|
7
9
|
*/
|
|
8
10
|
declare const nextAppRouterAdapter: FrameworkAdapter;
|
|
9
11
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/index.ts"],"mappings":";;;;;;;;;cA2Ha,sBAAsB"}
|
|
@@ -11,9 +11,14 @@ declare const MIDDLEWARE_TEMPLATE = "export { intlayerMiddleware as middleware }
|
|
|
11
11
|
/** Minimal pass-through root layout (`app/layout.tsx`), lets `[locale]/layout` own `<html>`. */
|
|
12
12
|
declare const ROOT_LAYOUT_TEMPLATE_TS = "import type { PropsWithChildren, FC } from \"react\";\n\nconst RootLayout: FC<PropsWithChildren> = ({ children }) => <>{children}</>;\n\nexport default RootLayout;\n";
|
|
13
13
|
declare const ROOT_LAYOUT_TEMPLATE_JS = "const RootLayout = ({ children }) => <>{children}</>;\n\nexport default RootLayout;\n";
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Locale layout (`app/[locale]/layout.tsx`) providing `<html>` + the unified
|
|
16
|
+
* provider. `IntlayerProvider` seeds both the server context (read by server
|
|
17
|
+
* hooks and by any page below, without per-page wrapping) and the client
|
|
18
|
+
* provider in one mount.
|
|
19
|
+
*/
|
|
20
|
+
declare const LOCALE_LAYOUT_TEMPLATE_TS = "import { type NextLayoutIntlayer } from \"next-intlayer\";\nimport { IntlayerProvider } from \"next-intlayer/server\";\nimport { getHTMLTextDir } from \"intlayer\";\n\nexport { generateStaticParams } from \"next-intlayer\";\n\nconst LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {\n const { locale } = await params;\n\n return (\n <html lang={locale} dir={getHTMLTextDir(locale)}>\n <body>\n <IntlayerProvider locale={locale}>{children}</IntlayerProvider>\n </body>\n </html>\n );\n};\n\nexport default LocaleLayout;\n";
|
|
21
|
+
declare const LOCALE_LAYOUT_TEMPLATE_JS = "import { IntlayerProvider } from \"next-intlayer/server\";\nimport { getHTMLTextDir } from \"intlayer\";\n\nexport { generateStaticParams } from \"next-intlayer\";\n\nconst LocaleLayout = async ({ children, params }) => {\n const { locale } = await params;\n\n return (\n <html lang={locale} dir={getHTMLTextDir(locale)}>\n <body>\n <IntlayerProvider locale={locale}>{children}</IntlayerProvider>\n </body>\n </html>\n );\n};\n\nexport default LocaleLayout;\n";
|
|
17
22
|
/**
|
|
18
23
|
* Locale home page (`app/[locale]/page.tsx`). Self-contained starter that does
|
|
19
24
|
* not depend on an example content declaration — add Intlayer content (a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/templates.ts"],"mappings":";;;;;;;cAOa;;cASA;;cASA;cAOA
|
|
1
|
+
{"version":3,"file":"templates.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/templates.ts"],"mappings":";;;;;;;cAOa;;cASA;;cASA;cAOA;;;;;;;cAWA;cAqBA;;;;;;cAyBA;cAgBA"}
|
|
@@ -5,19 +5,17 @@ type TransformResult = {
|
|
|
5
5
|
status: 'wrapped' | 'already' | 'skipped-client' | 'skipped';
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
* Wraps the `{children}` of a Next.js App Router **layout** with
|
|
9
|
-
* `
|
|
8
|
+
* Wraps the `{children}` of a Next.js App Router **layout** with the unified
|
|
9
|
+
* `IntlayerProvider`, deriving the locale via `getLocale()`. Safe and
|
|
10
10
|
* idempotent: bails (returns the original code) for client components, when no
|
|
11
11
|
* `{children}` placeholder is found, or when there is no default export.
|
|
12
|
+
*
|
|
13
|
+
* `IntlayerProvider` seeds both the server context and the client provider in
|
|
14
|
+
* one mount, so this is the only provider a Next.js App Router app needs —
|
|
15
|
+
* pages below the locale layout read locale/variant from it without wrapping
|
|
16
|
+
* themselves individually (see the removed `wrapPageWithProvider`).
|
|
12
17
|
*/
|
|
13
18
|
declare const wrapLayoutWithProvider: (code: string) => TransformResult;
|
|
14
|
-
/**
|
|
15
|
-
* Wraps the returned JSX of a Next.js App Router **page** with
|
|
16
|
-
* `IntlayerServerProvider`, deriving the locale via `getLocale()`. Safe and
|
|
17
|
-
* idempotent: bails for client components, when the page has no single
|
|
18
|
-
* top-level JSX return, or when there is no default export.
|
|
19
|
-
*/
|
|
20
|
-
declare const wrapPageWithProvider: (code: string) => TransformResult;
|
|
21
19
|
//#endregion
|
|
22
|
-
export { TransformResult, wrapLayoutWithProvider
|
|
20
|
+
export { TransformResult, wrapLayoutWithProvider };
|
|
23
21
|
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"mappings":";;KAWY;EACV;EACA
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"mappings":";;KAWY;EACV;EACA;;;;;;;;;;;;;cAsLW,yBAAsB,iBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/installSkills/index.ts"],"mappings":";;;;cASa;WACX;WACA;WACA;WACA;WACA;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WAEA;;KAGU,qBAAqB;cAEpB,QAAyC;cAEzC,mBAAgB,MACrB,yCACS;UAoBA;EACf;EACA;EACA;;;;;cAMW,oBAAoB,eAAe;KA6JpC,wBAAwB;cAEvB,WAA+C;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/installSkills/index.ts"],"mappings":";;;;cASa;WACX;WACA;WACA;WACA;WACA;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WAEA;;KAGU,qBAAqB;cAEpB,QAAyC;cAEzC,mBAAgB,MACrB,yCACS;UAoBA;EACf;EACA;EACA;;;;;cAMW,oBAAoB,eAAe;KA6JpC,wBAAwB;cAEvB,WAA+C;;;;;cA8G/C,gBAAa,qBACL,UACT,UAAQ,QACV,YACP"}
|
|
@@ -9,6 +9,21 @@ import { IntlayerConfig } from "@intlayer/types/config";
|
|
|
9
9
|
* exports consumers import — preventing `MISSING_EXPORT` errors when a new
|
|
10
10
|
* configuration section (e.g. `analytics`) is added.
|
|
11
11
|
*
|
|
12
|
+
* ## Why `editor.clientSecret` is never emitted
|
|
13
|
+
*
|
|
14
|
+
* This file is what a bundle *inlines*. Every framework integration installs the
|
|
15
|
+
* same alias for the client and the server build, so anything written here that
|
|
16
|
+
* a client module imports ends up in a public asset — and `editor` is imported
|
|
17
|
+
* by browser code (the provider, the analytics SDK, the visual editor).
|
|
18
|
+
*
|
|
19
|
+
* `clientSecret` grants full project-scoped API access, so it is stripped here
|
|
20
|
+
* rather than in each integration: a per-bundler fix only protects the bundlers
|
|
21
|
+
* we patched, while stripping it at the source protects every consumer,
|
|
22
|
+
* including ones that build their own alias.
|
|
23
|
+
*
|
|
24
|
+
* Server-side code reads the secret from `@intlayer/config/secrets`, whose
|
|
25
|
+
* `browser` export condition resolves to an empty stub in browser builds.
|
|
26
|
+
*
|
|
12
27
|
* @param configuration - The fully resolved Intlayer configuration.
|
|
13
28
|
* @param format - Module format to emit (`esm` for `.mjs`, `cjs` for `.cjs`).
|
|
14
29
|
* @returns The file content as a string.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateConfigurationContent.d.ts","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"generateConfigurationContent.d.ts","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+Ba,+BAA4B,eACxB,gBAAc"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/engine",
|
|
3
|
-
"version": "9.4.
|
|
3
|
+
"version": "9.4.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Scans and builds Intlayer declaration files into dictionaries based on Intlayer configuration.",
|
|
6
6
|
"keywords": [
|
|
@@ -141,13 +141,13 @@
|
|
|
141
141
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
142
142
|
},
|
|
143
143
|
"dependencies": {
|
|
144
|
-
"@intlayer/api": "9.4.
|
|
145
|
-
"@intlayer/config": "9.4.
|
|
146
|
-
"@intlayer/core": "9.4.
|
|
147
|
-
"@intlayer/dictionaries-entry": "9.4.
|
|
148
|
-
"@intlayer/remote-dictionaries-entry": "9.4.
|
|
149
|
-
"@intlayer/types": "9.4.
|
|
150
|
-
"@intlayer/unmerged-dictionaries-entry": "9.4.
|
|
144
|
+
"@intlayer/api": "9.4.1",
|
|
145
|
+
"@intlayer/config": "9.4.1",
|
|
146
|
+
"@intlayer/core": "9.4.1",
|
|
147
|
+
"@intlayer/dictionaries-entry": "9.4.1",
|
|
148
|
+
"@intlayer/remote-dictionaries-entry": "9.4.1",
|
|
149
|
+
"@intlayer/types": "9.4.1",
|
|
150
|
+
"@intlayer/unmerged-dictionaries-entry": "9.4.1",
|
|
151
151
|
"@parcel/watcher": "2.6.0",
|
|
152
152
|
"defu": "6.1.7",
|
|
153
153
|
"fast-glob": "3.3.3",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"zod-to-ts": "2.1.0"
|
|
157
157
|
},
|
|
158
158
|
"devDependencies": {
|
|
159
|
-
"@types/node": "26.
|
|
159
|
+
"@types/node": "26.3.0",
|
|
160
160
|
"@utils/ts-config": "1.0.4",
|
|
161
161
|
"@utils/ts-config-types": "1.0.4",
|
|
162
162
|
"@utils/tsdown-config": "1.0.4",
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"zod": "4.4.3"
|
|
168
168
|
},
|
|
169
169
|
"peerDependencies": {
|
|
170
|
-
"@intlayer/babel": "9.4.
|
|
170
|
+
"@intlayer/babel": "9.4.1"
|
|
171
171
|
},
|
|
172
172
|
"peerDependenciesMeta": {
|
|
173
173
|
"@intlayer/babel": {
|