@intlayer/cli 9.5.11 → 9.6.0
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/cjs/_virtual/_utils_asset.cjs +1 -1
- package/dist/cjs/build.cjs +2 -2
- package/dist/cjs/build.cjs.map +1 -1
- package/dist/cjs/ci.cjs +1 -1
- package/dist/cjs/cli.cjs +51 -12
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/extract.cjs +1 -1
- package/dist/cjs/fill/fill.cjs +25 -9
- package/dist/cjs/fill/fill.cjs.map +1 -1
- package/dist/cjs/getTargetDictionary.cjs +1 -1
- package/dist/cjs/index.cjs +15 -1
- package/dist/cjs/init.cjs +98 -27
- package/dist/cjs/init.cjs.map +1 -1
- package/dist/cjs/initChromeExtension.cjs +26 -3
- package/dist/cjs/initChromeExtension.cjs.map +1 -1
- package/dist/cjs/initInfra.cjs +6 -0
- package/dist/cjs/initInfra.cjs.map +1 -1
- package/dist/cjs/initMCP.cjs +18 -7
- package/dist/cjs/initMCP.cjs.map +1 -1
- package/dist/cjs/initSkills.cjs +37 -34
- package/dist/cjs/initSkills.cjs.map +1 -1
- package/dist/cjs/listContentDeclaration.cjs +1 -1
- package/dist/cjs/listProjects.cjs +1 -1
- package/dist/cjs/pull.cjs +1 -1
- package/dist/cjs/push/push.cjs +1 -1
- package/dist/cjs/reviewDoc/reviewDoc.cjs +1 -1
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -1
- package/dist/cjs/scan.cjs +1 -1
- package/dist/cjs/scan.cjs.map +1 -1
- package/dist/cjs/translateDoc/translateDoc.cjs +1 -1
- package/dist/cjs/upgrade.cjs +1 -1
- package/dist/cjs/utils/getParentPackageJSON.cjs +1 -1
- package/dist/cjs/utils/isInteractiveTerminal.cjs +12 -0
- package/dist/cjs/utils/isInteractiveTerminal.cjs.map +1 -0
- package/dist/cjs/utils/parseChoice.cjs +21 -0
- package/dist/cjs/utils/parseChoice.cjs.map +1 -0
- package/dist/esm/_virtual/_utils_asset.mjs +1 -1
- package/dist/esm/build.mjs +1 -1
- package/dist/esm/build.mjs.map +1 -1
- package/dist/esm/ci.mjs +1 -1
- package/dist/esm/cli.mjs +51 -12
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/extract.mjs +1 -1
- package/dist/esm/fill/fill.mjs +25 -9
- package/dist/esm/fill/fill.mjs.map +1 -1
- package/dist/esm/getTargetDictionary.mjs +1 -1
- package/dist/esm/index.mjs +5 -4
- package/dist/esm/init.mjs +93 -28
- package/dist/esm/init.mjs.map +1 -1
- package/dist/esm/initChromeExtension.mjs +24 -4
- package/dist/esm/initChromeExtension.mjs.map +1 -1
- package/dist/esm/initInfra.mjs +6 -0
- package/dist/esm/initInfra.mjs.map +1 -1
- package/dist/esm/initMCP.mjs +21 -11
- package/dist/esm/initMCP.mjs.map +1 -1
- package/dist/esm/initSkills.mjs +37 -36
- package/dist/esm/initSkills.mjs.map +1 -1
- package/dist/esm/listContentDeclaration.mjs +1 -1
- package/dist/esm/listProjects.mjs +1 -1
- package/dist/esm/pull.mjs +1 -1
- package/dist/esm/push/push.mjs +1 -1
- package/dist/esm/reviewDoc/reviewDoc.mjs +1 -1
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -1
- package/dist/esm/scan.mjs +1 -1
- package/dist/esm/scan.mjs.map +1 -1
- package/dist/esm/translateDoc/translateDoc.mjs +1 -1
- package/dist/esm/upgrade.mjs +1 -1
- package/dist/esm/utils/getParentPackageJSON.mjs +1 -1
- package/dist/esm/utils/isInteractiveTerminal.mjs +11 -0
- package/dist/esm/utils/isInteractiveTerminal.mjs.map +1 -0
- package/dist/esm/utils/parseChoice.mjs +20 -0
- package/dist/esm/utils/parseChoice.mjs.map +1 -0
- package/dist/types/fill/fill.d.ts +22 -1
- package/dist/types/fill/fill.d.ts.map +1 -1
- package/dist/types/fill/index.d.ts +2 -2
- package/dist/types/index.d.ts +6 -5
- package/dist/types/init.d.ts +36 -0
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/initChromeExtension.d.ts +19 -1
- package/dist/types/initChromeExtension.d.ts.map +1 -1
- package/dist/types/initInfra.d.ts.map +1 -1
- package/dist/types/initMCP.d.ts +16 -2
- package/dist/types/initMCP.d.ts.map +1 -1
- package/dist/types/initSkills.d.ts +23 -6
- package/dist/types/initSkills.d.ts.map +1 -1
- package/dist/types/utils/isInteractiveTerminal.d.ts +9 -0
- package/dist/types/utils/isInteractiveTerminal.d.ts.map +1 -0
- package/dist/types/utils/parseChoice.d.ts +13 -0
- package/dist/types/utils/parseChoice.d.ts.map +1 -0
- package/package.json +18 -13
package/dist/cjs/initSkills.cjs
CHANGED
|
@@ -1,43 +1,25 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
3
|
const require_loadPrompts = require('./loadPrompts.cjs');
|
|
4
|
+
const require_utils_isInteractiveTerminal = require('./utils/isInteractiveTerminal.cjs');
|
|
5
|
+
const require_utils_parseChoice = require('./utils/parseChoice.cjs');
|
|
4
6
|
const require_init = require('./init.cjs');
|
|
5
|
-
let node_path = require("node:path");
|
|
6
7
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
7
|
-
let node_fs = require("node:fs");
|
|
8
8
|
let enquirer = require("enquirer");
|
|
9
9
|
enquirer = require_runtime.__toESM(enquirer);
|
|
10
10
|
|
|
11
11
|
//#region src/initSkills.ts
|
|
12
|
-
const PLATFORM_CHECKS = _intlayer_engine_cli.PLATFORMS.filter((platform) => _intlayer_engine_cli.PLATFORMS_METADATA[platform]?.check).map((platform) => ({
|
|
13
|
-
check: _intlayer_engine_cli.PLATFORMS_METADATA[platform]?.check ?? (() => false),
|
|
14
|
-
platform
|
|
15
|
-
}));
|
|
16
12
|
const PLATFORM_OPTIONS = _intlayer_engine_cli.PLATFORMS.map((platform) => ({
|
|
17
13
|
value: platform,
|
|
18
14
|
label: _intlayer_engine_cli.PLATFORMS_METADATA[platform]?.label ?? "",
|
|
19
15
|
hint: `(${_intlayer_engine_cli.PLATFORMS_METADATA[platform]?.dir})`
|
|
20
16
|
}));
|
|
21
|
-
const getDetectedPlatform = () => PLATFORM_CHECKS.find(({ check }) => check())?.platform;
|
|
22
|
-
const getDependencies = (root) => {
|
|
23
|
-
try {
|
|
24
|
-
const packageJsonPath = (0, node_path.join)(root, "package.json");
|
|
25
|
-
if (!(0, node_fs.existsSync)(packageJsonPath)) return {};
|
|
26
|
-
const { dependencies = {}, devDependencies = {} } = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8"));
|
|
27
|
-
return {
|
|
28
|
-
...dependencies,
|
|
29
|
-
...devDependencies
|
|
30
|
-
};
|
|
31
|
-
} catch {
|
|
32
|
-
return {};
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
17
|
/**
|
|
36
18
|
* Asks which AI platform the user is using, preselecting the detected one.
|
|
37
19
|
* Resolves to `undefined` when the prompt is cancelled.
|
|
38
20
|
*/
|
|
39
|
-
const promptPlatform = async () => {
|
|
40
|
-
const detectedPlatform =
|
|
21
|
+
const promptPlatform = async (projectRoot) => {
|
|
22
|
+
const detectedPlatform = (0, _intlayer_engine_cli.detectPlatform)(projectRoot);
|
|
41
23
|
try {
|
|
42
24
|
return (await enquirer.default.prompt({
|
|
43
25
|
type: "autocomplete",
|
|
@@ -55,32 +37,50 @@ const promptPlatform = async () => {
|
|
|
55
37
|
return;
|
|
56
38
|
}
|
|
57
39
|
};
|
|
40
|
+
/** Validates a `--platform` value, ignoring case. */
|
|
41
|
+
const parsePlatform = (value) => require_utils_parseChoice.parseChoice(value, _intlayer_engine_cli.PLATFORMS, "--platform");
|
|
42
|
+
/** Validates the `--skills` values, ignoring case. */
|
|
43
|
+
const parseSkills = (values) => values.flatMap((value) => value.split(",")).filter((value) => value.trim() !== "").map((value) => require_utils_parseChoice.parseChoice(value, _intlayer_engine_cli.SKILLS, "--skills"));
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the platform without prompting: the given one, else the detected
|
|
46
|
+
* one. Logs how to pass it and sets a failing exit code when neither exists.
|
|
47
|
+
*/
|
|
48
|
+
const resolvePlatformWithoutPrompt = async (projectRoot, platform, command) => {
|
|
49
|
+
const resolvedPlatform = platform ?? (0, _intlayer_engine_cli.detectPlatform)(projectRoot);
|
|
50
|
+
if (!resolvedPlatform) {
|
|
51
|
+
(await require_loadPrompts.loadPrompts()).log.error(`No AI platform detected. Pass it explicitly: ${command} --platform <platform>\nPlatforms: ${_intlayer_engine_cli.PLATFORMS.join(", ")}`);
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
}
|
|
54
|
+
return resolvedPlatform;
|
|
55
|
+
};
|
|
58
56
|
/**
|
|
59
57
|
* Installs the Intlayer documentation skills. The skills are picked first, then
|
|
60
|
-
* the platform
|
|
61
|
-
*
|
|
58
|
+
* the platform. Without a terminal (AI agents, CI), nothing is prompted: the
|
|
59
|
+
* skills default to the project stack and the platform to the detected one.
|
|
60
|
+
* Resolves to the platform used, so a following step (e.g. MCP) can reuse it
|
|
61
|
+
* without asking again.
|
|
62
62
|
*/
|
|
63
|
-
const initSkills = async (projectRoot,
|
|
63
|
+
const initSkills = async (projectRoot, options = {}) => {
|
|
64
64
|
const p = await require_loadPrompts.loadPrompts();
|
|
65
|
-
const root = require_init.
|
|
65
|
+
const root = require_init.resolveProjectRoot(projectRoot);
|
|
66
|
+
const isInteractive = require_utils_isInteractiveTerminal.isInteractiveTerminal();
|
|
66
67
|
p.intro("Initializing Intlayer skills");
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
const selectedSkills = await p.multiselect({
|
|
68
|
+
const initialSkills = (0, _intlayer_engine_cli.getInitialSkills)(require_init.getProjectDependencies(root));
|
|
69
|
+
const selectedSkills = options.skills ?? (isInteractive ? await p.multiselect({
|
|
70
70
|
message: "Select the documentation skills to provide to your AI:",
|
|
71
|
-
initialValues,
|
|
71
|
+
initialValues: initialSkills,
|
|
72
72
|
options: _intlayer_engine_cli.SKILLS.map((skill) => ({
|
|
73
73
|
value: skill,
|
|
74
74
|
label: skill,
|
|
75
75
|
hint: _intlayer_engine_cli.SKILLS_METADATA[skill]
|
|
76
76
|
})),
|
|
77
77
|
required: false
|
|
78
|
-
});
|
|
79
|
-
if (p.isCancel(selectedSkills) ||
|
|
78
|
+
}) : initialSkills);
|
|
79
|
+
if (p.isCancel(selectedSkills) || selectedSkills.length === 0) {
|
|
80
80
|
p.cancel("Operation cancelled. No skills selected.");
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
|
-
const platform =
|
|
83
|
+
const platform = isInteractive ? options.platform ?? await promptPlatform(root) : await resolvePlatformWithoutPrompt(root, options.platform, "intlayer init skills");
|
|
84
84
|
if (!platform) {
|
|
85
85
|
p.cancel("Operation cancelled. No platform selected.");
|
|
86
86
|
return;
|
|
@@ -94,6 +94,7 @@ const initSkills = async (projectRoot, preselectedPlatform) => {
|
|
|
94
94
|
} catch (error) {
|
|
95
95
|
s.stop("Failed to install skills");
|
|
96
96
|
p.log.error(error instanceof Error ? error.message : String(error));
|
|
97
|
+
process.exitCode = 1;
|
|
97
98
|
}
|
|
98
99
|
p.outro("Intlayer skills initialization complete");
|
|
99
100
|
return platform;
|
|
@@ -101,7 +102,9 @@ const initSkills = async (projectRoot, preselectedPlatform) => {
|
|
|
101
102
|
|
|
102
103
|
//#endregion
|
|
103
104
|
exports.PLATFORM_OPTIONS = PLATFORM_OPTIONS;
|
|
104
|
-
exports.getDetectedPlatform = getDetectedPlatform;
|
|
105
105
|
exports.initSkills = initSkills;
|
|
106
|
+
exports.parsePlatform = parsePlatform;
|
|
107
|
+
exports.parseSkills = parseSkills;
|
|
106
108
|
exports.promptPlatform = promptPlatform;
|
|
109
|
+
exports.resolvePlatformWithoutPrompt = resolvePlatformWithoutPrompt;
|
|
107
110
|
//# sourceMappingURL=initSkills.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","
|
|
1
|
+
{"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","detectPlatform","parseChoice","SKILLS","loadPrompts","resolveProjectRoot","isInteractiveTerminal","getInitialSkills","getProjectDependencies","SKILLS_METADATA","installSkills"],"sources":["../../src/initSkills.ts"],"sourcesContent":["import {\n detectPlatform,\n getInitialSkills,\n installSkills,\n PLATFORMS,\n PLATFORMS_METADATA,\n type Platform,\n SKILLS,\n SKILLS_METADATA,\n type Skill,\n} from '@intlayer/engine/cli';\nimport enquirer from 'enquirer';\nimport { getProjectDependencies, resolveProjectRoot } from './init';\nimport { loadPrompts } from './loadPrompts';\nimport { isInteractiveTerminal } from './utils/isInteractiveTerminal';\nimport { parseChoice } from './utils/parseChoice';\n\nexport const PLATFORM_OPTIONS: Array<{\n value: Platform;\n label: string;\n hint: string;\n}> = PLATFORMS.map((platform) => ({\n value: platform,\n label: PLATFORMS_METADATA[platform]?.label ?? '',\n hint: `(${PLATFORMS_METADATA[platform]?.dir})`,\n}));\n\n/**\n * Asks which AI platform the user is using, preselecting the detected one.\n * Resolves to `undefined` when the prompt is cancelled.\n */\nexport const promptPlatform = async (\n projectRoot: string\n): Promise<Platform | undefined> => {\n const detectedPlatform = detectPlatform(projectRoot);\n\n try {\n const response = await enquirer.prompt<{ platform: Platform }>({\n type: 'autocomplete',\n name: 'platform',\n message: 'Which platform are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((option) => ({\n name: option.value,\n message: option.label,\n hint: option.hint,\n })),\n });\n\n return response.platform;\n } catch {\n return undefined;\n }\n};\n\n/** Options of {@link initSkills}; anything omitted is prompted for. */\nexport type InitSkillsOptions = {\n /** AI platform to install the skills for. */\n platform?: Platform;\n /** Skills to install. Defaults to the ones matching the project stack. */\n skills?: Skill[];\n};\n\n/** Validates a `--platform` value, ignoring case. */\nexport const parsePlatform = (value: string): Platform =>\n parseChoice(value, PLATFORMS, '--platform');\n\n/** Validates the `--skills` values, ignoring case. */\nexport const parseSkills = (values: string[]): Skill[] =>\n values\n .flatMap((value) => value.split(','))\n .filter((value) => value.trim() !== '')\n .map((value) => parseChoice(value, SKILLS, '--skills'));\n\n/**\n * Resolves the platform without prompting: the given one, else the detected\n * one. Logs how to pass it and sets a failing exit code when neither exists.\n */\nexport const resolvePlatformWithoutPrompt = async (\n projectRoot: string,\n platform: Platform | undefined,\n command: string\n): Promise<Platform | undefined> => {\n const resolvedPlatform = platform ?? detectPlatform(projectRoot);\n\n if (!resolvedPlatform) {\n const p = await loadPrompts();\n\n p.log.error(\n `No AI platform detected. Pass it explicitly: ${command} --platform <platform>\\nPlatforms: ${PLATFORMS.join(', ')}`\n );\n process.exitCode = 1;\n }\n\n return resolvedPlatform;\n};\n\n/**\n * Installs the Intlayer documentation skills. The skills are picked first, then\n * the platform. Without a terminal (AI agents, CI), nothing is prompted: the\n * skills default to the project stack and the platform to the detected one.\n * Resolves to the platform used, so a following step (e.g. MCP) can reuse it\n * without asking again.\n */\nexport const initSkills = async (\n projectRoot?: string,\n options: InitSkillsOptions = {}\n): Promise<Platform | undefined> => {\n const p = await loadPrompts();\n\n const root = resolveProjectRoot(projectRoot);\n const isInteractive = isInteractiveTerminal();\n\n p.intro('Initializing Intlayer skills');\n\n const initialSkills = getInitialSkills(getProjectDependencies(root));\n\n const selectedSkills =\n options.skills ??\n (isInteractive\n ? await p.multiselect({\n message: 'Select the documentation skills to provide to your AI:',\n initialValues: initialSkills,\n options: SKILLS.map((skill) => ({\n value: skill,\n label: skill,\n hint: SKILLS_METADATA[skill],\n })),\n required: false,\n })\n : initialSkills);\n\n if (p.isCancel(selectedSkills) || selectedSkills.length === 0) {\n p.cancel('Operation cancelled. No skills selected.');\n return;\n }\n\n const platform = isInteractive\n ? (options.platform ?? (await promptPlatform(root)))\n : await resolvePlatformWithoutPrompt(\n root,\n options.platform,\n 'intlayer init skills'\n );\n\n if (!platform) {\n p.cancel('Operation cancelled. No platform selected.');\n return;\n }\n\n const s = p.spinner();\n s.start('Installing skills...');\n\n try {\n const result = await installSkills(root, platform, selectedSkills);\n\n s.stop('Skills installed successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to install skills');\n p.log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n\n p.outro('Intlayer skills initialization complete');\n\n return platform;\n};\n"],"mappings":";;;;;;;;;;;AAiBA,MAAa,mBAIRA,+BAAU,KAAK,cAAc;CAChC,OAAO;CACP,OAAOC,wCAAmB,SAAS,EAAE,SAAS;CAC9C,MAAM,IAAIA,wCAAmB,SAAS,EAAE,IAAI;AAC9C,EAAE;;;;;AAMF,MAAa,iBAAiB,OAC5B,gBACkC;CAClC,MAAM,uBAAmBC,qCAAe,WAAW;CAEnD,IAAI;EAgBF,QAAO,MAfgB,iBAAS,OAA+B;GAC7D,MAAM;GACN,MAAM;GACN,SAAS;GACT,UAAU;GACV,SAAS,mBACLF,+BAAU,QAAQ,gBAAgB,IAClC;GACJ,SAAS,iBAAiB,KAAK,YAAY;IACzC,MAAM,OAAO;IACb,SAAS,OAAO;IAChB,MAAM,OAAO;GACf,EAAE;EACJ,CAAC,EAEc,CAAC;CAClB,QAAQ;EACN;CACF;AACF;;AAWA,MAAa,iBAAiB,UAC5BG,sCAAY,OAAOH,gCAAW,YAAY;;AAG5C,MAAa,eAAe,WAC1B,OACG,SAAS,UAAU,MAAM,MAAM,GAAG,CAAC,CAAC,CACpC,QAAQ,UAAU,MAAM,KAAK,MAAM,EAAE,CAAC,CACtC,KAAK,UAAUG,sCAAY,OAAOC,6BAAQ,UAAU,CAAC;;;;;AAM1D,MAAa,+BAA+B,OAC1C,aACA,UACA,YACkC;CAClC,MAAM,mBAAmB,gBAAYF,qCAAe,WAAW;CAE/D,IAAI,CAAC,kBAAkB;EAGrB,OAFgBG,gCAAY,EAE3B,CAAC,IAAI,MACJ,gDAAgD,QAAQ,qCAAqCL,+BAAU,KAAK,IAAI,GAClH;EACA,QAAQ,WAAW;CACrB;CAEA,OAAO;AACT;;;;;;;;AASA,MAAa,aAAa,OACxB,aACA,UAA6B,CAAC,MACI;CAClC,MAAM,IAAI,MAAMK,gCAAY;CAE5B,MAAM,OAAOC,gCAAmB,WAAW;CAC3C,MAAM,gBAAgBC,0DAAsB;CAE5C,EAAE,MAAM,8BAA8B;CAEtC,MAAM,oBAAgBC,uCAAiBC,oCAAuB,IAAI,CAAC;CAEnE,MAAM,iBACJ,QAAQ,WACP,gBACG,MAAM,EAAE,YAAY;EAClB,SAAS;EACT,eAAe;EACf,SAASL,4BAAO,KAAK,WAAW;GAC9B,OAAO;GACP,OAAO;GACP,MAAMM,qCAAgB;EACxB,EAAE;EACF,UAAU;CACZ,CAAC,IACD;CAEN,IAAI,EAAE,SAAS,cAAc,KAAK,eAAe,WAAW,GAAG;EAC7D,EAAE,OAAO,0CAA0C;EACnD;CACF;CAEA,MAAM,WAAW,gBACZ,QAAQ,YAAa,MAAM,eAAe,IAAI,IAC/C,MAAM,6BACJ,MACA,QAAQ,UACR,sBACF;CAEJ,IAAI,CAAC,UAAU;EACb,EAAE,OAAO,4CAA4C;EACrD;CACF;CAEA,MAAM,IAAI,EAAE,QAAQ;CACpB,EAAE,MAAM,sBAAsB;CAE9B,IAAI;EACF,MAAM,SAAS,UAAMC,oCAAc,MAAM,UAAU,cAAc;EAEjE,EAAE,KAAK,+BAA+B;EAEtC,EAAE,KAAK,QAAQ,SAAS;CAC1B,SAAS,OAAO;EACd,EAAE,KAAK,0BAA0B;EACjC,EAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EAClE,QAAQ,WAAW;CACrB;CAEA,EAAE,MAAM,yCAAyC;CAEjD,OAAO;AACT"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
let node_path = require("node:path");
|
|
3
2
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
4
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
5
5
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
6
6
|
let _intlayer_engine_utils = require("@intlayer/engine/utils");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
let node_path = require("node:path");
|
|
3
2
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
4
|
|
|
5
5
|
//#region src/listProjects.ts
|
|
6
6
|
const listProjectsCommand = async (options) => {
|
package/dist/cjs/pull.cjs
CHANGED
|
@@ -3,9 +3,9 @@ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
|
3
3
|
const require_utils_checkAccess = require('./utils/checkAccess.cjs');
|
|
4
4
|
const require_push_pullLog = require('./push/pullLog.cjs');
|
|
5
5
|
const require_utils_selectCmsEnvironment = require('./utils/selectCmsEnvironment.cjs');
|
|
6
|
-
let node_path = require("node:path");
|
|
7
6
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
8
7
|
let node_fs = require("node:fs");
|
|
8
|
+
let node_path = require("node:path");
|
|
9
9
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
10
10
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
11
11
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
package/dist/cjs/push/push.cjs
CHANGED
|
@@ -4,8 +4,8 @@ const require_loadPrompts = require('../loadPrompts.cjs');
|
|
|
4
4
|
const require_utils_checkAccess = require('../utils/checkAccess.cjs');
|
|
5
5
|
const require_utils_selectCmsEnvironment = require('../utils/selectCmsEnvironment.cjs');
|
|
6
6
|
const require_pushLog = require('../pushLog.cjs');
|
|
7
|
-
let node_path = require("node:path");
|
|
8
7
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
8
|
+
let node_path = require("node:path");
|
|
9
9
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
10
10
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
11
11
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
@@ -8,9 +8,9 @@ const require_reviewDoc_reviewDocBlockAware = require('./reviewDocBlockAware.cjs
|
|
|
8
8
|
const require_reviewDoc_reviewDocLog = require('./reviewDocLog.cjs');
|
|
9
9
|
const require_reviewDoc_reviewDocProgress = require('./reviewDocProgress.cjs');
|
|
10
10
|
const require_reviewDoc_reviewDocSynthesis = require('./reviewDocSynthesis.cjs');
|
|
11
|
-
let node_path = require("node:path");
|
|
12
11
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
13
12
|
let node_fs = require("node:fs");
|
|
13
|
+
let node_path = require("node:path");
|
|
14
14
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
15
15
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
16
16
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
@@ -4,8 +4,8 @@ const require__utils_asset = require('../_virtual/_utils_asset.cjs');
|
|
|
4
4
|
const require_translateDoc_validation = require('../translateDoc/validation.cjs');
|
|
5
5
|
const require_utils_chunkInference = require('../utils/chunkInference.cjs');
|
|
6
6
|
const require_utils_fixChunkStartEndChars = require('../utils/fixChunkStartEndChars.cjs');
|
|
7
|
-
let node_path = require("node:path");
|
|
8
7
|
let node_fs = require("node:fs");
|
|
8
|
+
let node_path = require("node:path");
|
|
9
9
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
10
10
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
11
11
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
package/dist/cjs/scan.cjs
CHANGED
|
@@ -95,7 +95,7 @@ const scan = async (url, options = {}) => {
|
|
|
95
95
|
appLogger(`Routing: ${(0, _intlayer_config_logger.colorize)(routingLabels[routing.strategy], _intlayer_config_colors.BLUE)} ${(0, _intlayer_config_logger.colorize)(`(${routing.evidence}${routing.defaultLocale ? `, default locale: ${routing.defaultLocale}` : ""})`, _intlayer_config_colors.GREY)}`);
|
|
96
96
|
if (result.technologies.length > 0) {
|
|
97
97
|
appLogger("\nStack:");
|
|
98
|
-
for (const technology of result.technologies) appLogger(` ${(0, _intlayer_config_logger.colorize)(categoryLabels[technology.category], _intlayer_config_colors.GREY)} ${technology.name}${technology.version ? ` ${technology.version}` : ""}
|
|
98
|
+
for (const technology of result.technologies) appLogger(` ${(0, _intlayer_config_logger.colorize)(categoryLabels[technology.category], _intlayer_config_colors.GREY)} ${technology.name}${technology.version ? ` ${technology.version}` : ""}`);
|
|
99
99
|
}
|
|
100
100
|
appLogger("\nChecks:");
|
|
101
101
|
for (const event of result.events) logCheck(appLogger, event);
|
package/dist/cjs/scan.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.cjs","names":["colorize","ANSIColors","getCheckDetailLines","getConfiguration","getAppLogger","scanWebsite","formatSize"],"sources":["../../src/scan.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport {\n type DetectedTechnology,\n formatSize,\n getCheckDetailLines,\n type ScanEvent,\n type ScanResult,\n scanWebsite,\n} from '@intlayer/engine/scan';\nimport type { ConfigurationOptions } from './cli';\n\n/** Options accepted by the {@link scan} command. */\nexport type ScanCommandOptions = {\n /** Disable the deeper puppeteer-based render scan. */\n deep?: boolean;\n /** Output the raw {@link ScanResult} as JSON instead of formatted text. */\n json?: boolean;\n configOptions?: ConfigurationOptions;\n};\n\n/** Human-readable labels for each scorable check type. */\nconst checkLabels: Record<string, string> = {\n robots_robotsPresent: 'robots.txt present',\n robots_noLocalizedUrlsForgotten: 'robots.txt keeps localized URLs crawlable',\n sitemap_sitemapPresent: 'sitemap present',\n sitemap_noLocalizedUrlsForgotten: 'sitemap lists every locale',\n sitemap_hasAlternates: 'sitemap has alternate links',\n sitemap_hasXDefault: 'sitemap has x-default',\n url_htmlLang: 'html lang attribute',\n url_htmlDir: 'html dir attribute',\n url_currentLocale: 'locale signals consistent (lang, URL, hreflang)',\n url_ogLocale: 'og:locale meta tag',\n url_hasCanonical: 'canonical link',\n url_hreflang: 'hreflang tags',\n url_hreflangReciprocal: 'hreflang alternates link back',\n url_hasXDefault: 'x-default hreflang',\n url_hasLocalizedLinks: 'localized internal links',\n url_allAnchorsLocalized: 'all internal links keep the locale',\n url_hasLangSelector: 'crawlable language switcher',\n url_unusedBundleContent: 'unused bundle locale content',\n};\n\n/** Human-readable labels of the routing strategies. */\nconst routingLabels: Record<ScanResult['routing']['strategy'], string> = {\n 'prefix-all': 'locale prefix on every URL (/en/…, /fr/…)',\n 'prefix-no-default': 'locale prefix except for the default locale',\n 'search-params': 'locale in a query parameter',\n subdomain: 'locale subdomain (fr.example.com)',\n domain: 'one domain per locale',\n 'no-prefix': 'no locale in the URL (cookie / header based)',\n unknown: 'unknown',\n};\n\n/** Human-readable labels of the technology categories. */\nconst categoryLabels: Record<DetectedTechnology['category'], string> = {\n framework: 'Framework',\n 'i18n-library': 'i18n library',\n tms: 'TMS',\n 'translation-proxy': 'Translation proxy',\n cms: 'CMS',\n};\n\n/** Maximum number of detail lines printed under a failing check. */\nconst MAX_DETAIL_LINES = 3;\n\nconst statusIcon = (status: ScanEvent['status']): string => {\n if (status === 'success') return colorize('✓', ANSIColors.GREEN);\n if (status === 'warning') return colorize('⚠', ANSIColors.YELLOW);\n return colorize('✗', ANSIColors.RED);\n};\n\nconst scoreColor = (score: number) => {\n if (score >= 80) return ANSIColors.GREEN;\n if (score >= 50) return ANSIColors.YELLOW;\n return ANSIColors.RED;\n};\n\n/** Print a check with, when it fails, a short explanation. */\nconst logCheck = (\n appLogger: ReturnType<typeof getAppLogger>,\n event: ScanEvent\n): void => {\n const type = event.type.split('\\\\')[0];\n if (!type) return;\n\n appLogger(` ${statusIcon(event.status)} ${checkLabels[type] ?? type}`);\n\n if (event.status === 'success') return;\n\n const detailLines = getCheckDetailLines(event.details?.[event.status]);\n detailLines.slice(0, MAX_DETAIL_LINES).forEach((line, index) => {\n appLogger(\n colorize(`${index === 0 ? ' ' : ' '}${line}`, ANSIColors.GREY)\n );\n });\n if (detailLines.length > MAX_DETAIL_LINES) {\n appLogger(\n colorize(\n ` … ${detailLines.length - MAX_DETAIL_LINES} more (use --json)`,\n ANSIColors.GREY\n )\n );\n }\n};\n\n/**\n * Scan a website for i18n/SEO health and bundle weight, printing a formatted\n * report (or JSON with `--json`).\n *\n * @example\n * ```sh\n * npx intlayer scan https://intlayer.org\n * ```\n */\nexport const scan = async (\n url: string,\n options: ScanCommandOptions = {}\n): Promise<void> => {\n const configuration = getConfiguration(options.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const result = await scanWebsite(url, { deep: options.deep });\n\n if (options.json) {\n appLogger(JSON.stringify(result, null, 2));\n return;\n }\n\n appLogger(\n `\\n🔍 Scanned ${colorize(result.url, ANSIColors.GREY_LIGHT)} ${colorize(\n `(${result.mode} mode)`,\n ANSIColors.GREY\n )}\\n`\n );\n\n appLogger(\n `Score: ${colorize(`${result.score}/100`, scoreColor(result.score))}`\n );\n appLogger(\n `Page size: ${colorize(formatSize(result.totalPageSize), ANSIColors.BLUE)} ${colorize(\n `(HTML ${formatSize(result.htmlSize)})`,\n ANSIColors.GREY\n )}`\n );\n if (result.locales.length > 0) {\n appLogger(\n `Locales: ${colorize(result.locales.join(', '), ANSIColors.GREEN)}`\n );\n }\n\n const { routing } = result;\n appLogger(\n `Routing: ${colorize(routingLabels[routing.strategy], ANSIColors.BLUE)} ${colorize(\n `(${routing.evidence}${routing.defaultLocale ? `, default locale: ${routing.defaultLocale}` : ''})`,\n ANSIColors.GREY\n )}`\n );\n\n if (result.technologies.length > 0) {\n appLogger('\\nStack:');\n for (const technology of result.technologies) {\n appLogger(\n ` ${colorize(categoryLabels[technology.category], ANSIColors.GREY)} ${technology.name}${\n technology.version ? ` ${technology.version}` : ''\n }
|
|
1
|
+
{"version":3,"file":"scan.cjs","names":["colorize","ANSIColors","getCheckDetailLines","getConfiguration","getAppLogger","scanWebsite","formatSize"],"sources":["../../src/scan.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport {\n type DetectedTechnology,\n formatSize,\n getCheckDetailLines,\n type ScanEvent,\n type ScanResult,\n scanWebsite,\n} from '@intlayer/engine/scan';\nimport type { ConfigurationOptions } from './cli';\n\n/** Options accepted by the {@link scan} command. */\nexport type ScanCommandOptions = {\n /** Disable the deeper puppeteer-based render scan. */\n deep?: boolean;\n /** Output the raw {@link ScanResult} as JSON instead of formatted text. */\n json?: boolean;\n configOptions?: ConfigurationOptions;\n};\n\n/** Human-readable labels for each scorable check type. */\nconst checkLabels: Record<string, string> = {\n robots_robotsPresent: 'robots.txt present',\n robots_noLocalizedUrlsForgotten: 'robots.txt keeps localized URLs crawlable',\n sitemap_sitemapPresent: 'sitemap present',\n sitemap_noLocalizedUrlsForgotten: 'sitemap lists every locale',\n sitemap_hasAlternates: 'sitemap has alternate links',\n sitemap_hasXDefault: 'sitemap has x-default',\n url_htmlLang: 'html lang attribute',\n url_htmlDir: 'html dir attribute',\n url_currentLocale: 'locale signals consistent (lang, URL, hreflang)',\n url_ogLocale: 'og:locale meta tag',\n url_hasCanonical: 'canonical link',\n url_hreflang: 'hreflang tags',\n url_hreflangReciprocal: 'hreflang alternates link back',\n url_hasXDefault: 'x-default hreflang',\n url_hasLocalizedLinks: 'localized internal links',\n url_allAnchorsLocalized: 'all internal links keep the locale',\n url_hasLangSelector: 'crawlable language switcher',\n url_unusedBundleContent: 'unused bundle locale content',\n};\n\n/** Human-readable labels of the routing strategies. */\nconst routingLabels: Record<ScanResult['routing']['strategy'], string> = {\n 'prefix-all': 'locale prefix on every URL (/en/…, /fr/…)',\n 'prefix-no-default': 'locale prefix except for the default locale',\n 'search-params': 'locale in a query parameter',\n subdomain: 'locale subdomain (fr.example.com)',\n domain: 'one domain per locale',\n 'no-prefix': 'no locale in the URL (cookie / header based)',\n unknown: 'unknown',\n};\n\n/** Human-readable labels of the technology categories. */\nconst categoryLabels: Record<DetectedTechnology['category'], string> = {\n framework: 'Framework',\n 'i18n-library': 'i18n library',\n tms: 'TMS',\n 'translation-proxy': 'Translation proxy',\n cms: 'CMS',\n};\n\n/** Maximum number of detail lines printed under a failing check. */\nconst MAX_DETAIL_LINES = 3;\n\nconst statusIcon = (status: ScanEvent['status']): string => {\n if (status === 'success') return colorize('✓', ANSIColors.GREEN);\n if (status === 'warning') return colorize('⚠', ANSIColors.YELLOW);\n return colorize('✗', ANSIColors.RED);\n};\n\nconst scoreColor = (score: number) => {\n if (score >= 80) return ANSIColors.GREEN;\n if (score >= 50) return ANSIColors.YELLOW;\n return ANSIColors.RED;\n};\n\n/** Print a check with, when it fails, a short explanation. */\nconst logCheck = (\n appLogger: ReturnType<typeof getAppLogger>,\n event: ScanEvent\n): void => {\n const type = event.type.split('\\\\')[0];\n if (!type) return;\n\n appLogger(` ${statusIcon(event.status)} ${checkLabels[type] ?? type}`);\n\n if (event.status === 'success') return;\n\n const detailLines = getCheckDetailLines(event.details?.[event.status]);\n detailLines.slice(0, MAX_DETAIL_LINES).forEach((line, index) => {\n appLogger(\n colorize(`${index === 0 ? ' ' : ' '}${line}`, ANSIColors.GREY)\n );\n });\n if (detailLines.length > MAX_DETAIL_LINES) {\n appLogger(\n colorize(\n ` … ${detailLines.length - MAX_DETAIL_LINES} more (use --json)`,\n ANSIColors.GREY\n )\n );\n }\n};\n\n/**\n * Scan a website for i18n/SEO health and bundle weight, printing a formatted\n * report (or JSON with `--json`).\n *\n * @example\n * ```sh\n * npx intlayer scan https://intlayer.org\n * ```\n */\nexport const scan = async (\n url: string,\n options: ScanCommandOptions = {}\n): Promise<void> => {\n const configuration = getConfiguration(options.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const result = await scanWebsite(url, { deep: options.deep });\n\n if (options.json) {\n appLogger(JSON.stringify(result, null, 2));\n return;\n }\n\n appLogger(\n `\\n🔍 Scanned ${colorize(result.url, ANSIColors.GREY_LIGHT)} ${colorize(\n `(${result.mode} mode)`,\n ANSIColors.GREY\n )}\\n`\n );\n\n appLogger(\n `Score: ${colorize(`${result.score}/100`, scoreColor(result.score))}`\n );\n appLogger(\n `Page size: ${colorize(formatSize(result.totalPageSize), ANSIColors.BLUE)} ${colorize(\n `(HTML ${formatSize(result.htmlSize)})`,\n ANSIColors.GREY\n )}`\n );\n if (result.locales.length > 0) {\n appLogger(\n `Locales: ${colorize(result.locales.join(', '), ANSIColors.GREEN)}`\n );\n }\n\n const { routing } = result;\n appLogger(\n `Routing: ${colorize(routingLabels[routing.strategy], ANSIColors.BLUE)} ${colorize(\n `(${routing.evidence}${routing.defaultLocale ? `, default locale: ${routing.defaultLocale}` : ''})`,\n ANSIColors.GREY\n )}`\n );\n\n if (result.technologies.length > 0) {\n appLogger('\\nStack:');\n for (const technology of result.technologies) {\n appLogger(\n ` ${colorize(categoryLabels[technology.category], ANSIColors.GREY)} ${technology.name}${\n technology.version ? ` ${technology.version}` : ''\n }`\n );\n }\n }\n\n appLogger('\\nChecks:');\n for (const event of result.events) {\n logCheck(appLogger, event);\n }\n\n if (result.bundle && result.bundle.totalLocaleSize > 0) {\n const { bundle } = result;\n appLogger('\\nBundle locale weight:');\n appLogger(\n ` Translations shipped: ${colorize(formatSize(bundle.totalLocaleSize), ANSIColors.BLUE)}`\n );\n appLogger(\n ` Unused (other locales): ${colorize(\n `${formatSize(bundle.totalUnusedLocaleSize)} (${bundle.unusedPercentOfLocale}%)`,\n bundle.unusedPercentOfLocale > 30\n ? ANSIColors.RED\n : bundle.unusedPercentOfLocale > 0\n ? ANSIColors.YELLOW\n : ANSIColors.GREEN\n )}`\n );\n }\n};\n"],"mappings":";;;;;;;;;;AAuBA,MAAM,cAAsC;CAC1C,sBAAsB;CACtB,iCAAiC;CACjC,wBAAwB;CACxB,kCAAkC;CAClC,uBAAuB;CACvB,qBAAqB;CACrB,cAAc;CACd,aAAa;CACb,mBAAmB;CACnB,cAAc;CACd,kBAAkB;CAClB,cAAc;CACd,wBAAwB;CACxB,iBAAiB;CACjB,uBAAuB;CACvB,yBAAyB;CACzB,qBAAqB;CACrB,yBAAyB;AAC3B;;AAGA,MAAM,gBAAmE;CACvE,cAAc;CACd,qBAAqB;CACrB,iBAAiB;CACjB,WAAW;CACX,QAAQ;CACR,aAAa;CACb,SAAS;AACX;;AAGA,MAAM,iBAAiE;CACrE,WAAW;CACX,gBAAgB;CAChB,KAAK;CACL,qBAAqB;CACrB,KAAK;AACP;;AAGA,MAAM,mBAAmB;AAEzB,MAAM,cAAc,WAAwC;CAC1D,IAAI,WAAW,WAAW,WAAOA,kCAAS,KAAKC,wBAAW,KAAK;CAC/D,IAAI,WAAW,WAAW,WAAOD,kCAAS,KAAKC,wBAAW,MAAM;CAChE,WAAOD,kCAAS,KAAKC,wBAAW,GAAG;AACrC;AAEA,MAAM,cAAc,UAAkB;CACpC,IAAI,SAAS,IAAI,OAAOA,wBAAW;CACnC,IAAI,SAAS,IAAI,OAAOA,wBAAW;CACnC,OAAOA,wBAAW;AACpB;;AAGA,MAAM,YACJ,WACA,UACS;CACT,MAAM,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC;CACpC,IAAI,CAAC,MAAM;CAEX,UAAU,KAAK,WAAW,MAAM,MAAM,EAAE,GAAG,YAAY,SAAS,MAAM;CAEtE,IAAI,MAAM,WAAW,WAAW;CAEhC,MAAM,kBAAcC,2CAAoB,MAAM,UAAU,MAAM,OAAO;CACrE,YAAY,MAAM,GAAG,gBAAgB,CAAC,CAAC,SAAS,MAAM,UAAU;EAC9D,cACEF,kCAAS,GAAG,UAAU,IAAI,WAAW,aAAa,QAAQC,wBAAW,IAAI,CAC3E;CACF,CAAC;CACD,IAAI,YAAY,SAAS,kBACvB,cACED,kCACE,WAAW,YAAY,SAAS,iBAAiB,qBACjDC,wBAAW,IACb,CACF;AAEJ;;;;;;;;;;AAWA,MAAa,OAAO,OAClB,KACA,UAA8B,CAAC,MACb;CAClB,MAAM,oBAAgBE,wCAAiB,QAAQ,aAAa;CAC5D,MAAM,gBAAYC,sCAAa,aAAa;CAE5C,MAAM,SAAS,UAAMC,mCAAY,KAAK,EAAE,MAAM,QAAQ,KAAK,CAAC;CAE5D,IAAI,QAAQ,MAAM;EAChB,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;EACzC;CACF;CAEA,UACE,oBAAgBL,kCAAS,OAAO,KAAKC,wBAAW,UAAU,EAAE,OAAGD,kCAC7D,IAAI,OAAO,KAAK,SAChBC,wBAAW,IACb,EAAE,GACJ;CAEA,UACE,cAAUD,kCAAS,GAAG,OAAO,MAAM,OAAO,WAAW,OAAO,KAAK,CAAC,GACpE;CACA,UACE,kBAAcA,sCAASM,kCAAW,OAAO,aAAa,GAAGL,wBAAW,IAAI,EAAE,OAAGD,kCAC3E,aAASM,kCAAW,OAAO,QAAQ,EAAE,IACrCL,wBAAW,IACb,GACF;CACA,IAAI,OAAO,QAAQ,SAAS,GAC1B,UACE,gBAAYD,kCAAS,OAAO,QAAQ,KAAK,IAAI,GAAGC,wBAAW,KAAK,GAClE;CAGF,MAAM,EAAE,YAAY;CACpB,UACE,gBAAYD,kCAAS,cAAc,QAAQ,WAAWC,wBAAW,IAAI,EAAE,OAAGD,kCACxE,IAAI,QAAQ,WAAW,QAAQ,gBAAgB,qBAAqB,QAAQ,kBAAkB,GAAG,IACjGC,wBAAW,IACb,GACF;CAEA,IAAI,OAAO,aAAa,SAAS,GAAG;EAClC,UAAU,UAAU;EACpB,KAAK,MAAM,cAAc,OAAO,cAC9B,UACE,SAAKD,kCAAS,eAAe,WAAW,WAAWC,wBAAW,IAAI,EAAE,GAAG,WAAW,OAChF,WAAW,UAAU,IAAI,WAAW,YAAY,IAEpD;CAEJ;CAEA,UAAU,WAAW;CACrB,KAAK,MAAM,SAAS,OAAO,QACzB,SAAS,WAAW,KAAK;CAG3B,IAAI,OAAO,UAAU,OAAO,OAAO,kBAAkB,GAAG;EACtD,MAAM,EAAE,WAAW;EACnB,UAAU,yBAAyB;EACnC,UACE,+BAA2BD,sCAASM,kCAAW,OAAO,eAAe,GAAGL,wBAAW,IAAI,GACzF;EACA,UACE,iCAA6BD,kCAC3B,OAAGM,kCAAW,OAAO,qBAAqB,EAAE,IAAI,OAAO,sBAAsB,KAC7E,OAAO,wBAAwB,KAC3BL,wBAAW,MACX,OAAO,wBAAwB,IAC7BA,wBAAW,SACXA,wBAAW,KACnB,GACF;CACF;AACF"}
|
|
@@ -4,9 +4,9 @@ const require_utils_setupAI = require('../utils/setupAI.cjs');
|
|
|
4
4
|
const require_utils_getOutputFilePath = require('../utils/getOutputFilePath.cjs');
|
|
5
5
|
const require_utils_checkFileModifiedRange = require('../utils/checkFileModifiedRange.cjs');
|
|
6
6
|
const require_translateDoc_translateFile = require('./translateFile.cjs');
|
|
7
|
-
let node_path = require("node:path");
|
|
8
7
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
9
8
|
let node_fs = require("node:fs");
|
|
9
|
+
let node_path = require("node:path");
|
|
10
10
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
11
11
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
12
12
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
package/dist/cjs/upgrade.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_init = require('./init.cjs');
|
|
3
|
-
let node_path = require("node:path");
|
|
4
3
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
5
|
|
|
6
6
|
//#region src/upgrade.ts
|
|
7
7
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
let node_path = require("node:path");
|
|
3
2
|
let node_fs = require("node:fs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
4
|
|
|
5
5
|
//#region src/utils/getParentPackageJSON.ts
|
|
6
6
|
const getParentPackageJSON = (startDir) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region src/utils/isInteractiveTerminal.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether the process can prompt: both stdin and stdout are attached to a
|
|
5
|
+
* terminal. False for AI agents, CI and piped runs, where a prompt would print
|
|
6
|
+
* and exit without an answer.
|
|
7
|
+
*/
|
|
8
|
+
const isInteractiveTerminal = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.isInteractiveTerminal = isInteractiveTerminal;
|
|
12
|
+
//# sourceMappingURL=isInteractiveTerminal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isInteractiveTerminal.cjs","names":[],"sources":["../../../src/utils/isInteractiveTerminal.ts"],"sourcesContent":["/**\n * Whether the process can prompt: both stdin and stdout are attached to a\n * terminal. False for AI agents, CI and piped runs, where a prompt would print\n * and exit without an answer.\n */\nexport const isInteractiveTerminal = (): boolean =>\n Boolean(process.stdin.isTTY && process.stdout.isTTY);\n"],"mappings":";;;;;;;AAKA,MAAa,8BACX,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,KAAK"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region src/utils/parseChoice.ts
|
|
3
|
+
/**
|
|
4
|
+
* Resolves a command-line value against its allowed choices, ignoring case.
|
|
5
|
+
*
|
|
6
|
+
* @param value - Raw value passed on the command line.
|
|
7
|
+
* @param choices - Accepted values, in their canonical spelling.
|
|
8
|
+
* @param optionName - Option name used in the error message (e.g. `--platform`).
|
|
9
|
+
* @returns The matching choice, in its canonical spelling.
|
|
10
|
+
* @throws When the value matches none of the choices.
|
|
11
|
+
*/
|
|
12
|
+
const parseChoice = (value, choices, optionName) => {
|
|
13
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
14
|
+
const choice = choices.find((candidate) => candidate.toLowerCase() === normalizedValue);
|
|
15
|
+
if (!choice) throw new Error(`Invalid ${optionName} value "${value}". Expected one of: ${choices.join(", ")}.`);
|
|
16
|
+
return choice;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
exports.parseChoice = parseChoice;
|
|
21
|
+
//# sourceMappingURL=parseChoice.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseChoice.cjs","names":[],"sources":["../../../src/utils/parseChoice.ts"],"sourcesContent":["/**\n * Resolves a command-line value against its allowed choices, ignoring case.\n *\n * @param value - Raw value passed on the command line.\n * @param choices - Accepted values, in their canonical spelling.\n * @param optionName - Option name used in the error message (e.g. `--platform`).\n * @returns The matching choice, in its canonical spelling.\n * @throws When the value matches none of the choices.\n */\nexport const parseChoice = <Choice extends string>(\n value: string,\n choices: readonly Choice[],\n optionName: string\n): Choice => {\n const normalizedValue = value.trim().toLowerCase();\n const choice = choices.find(\n (candidate) => candidate.toLowerCase() === normalizedValue\n );\n\n if (!choice) {\n throw new Error(\n `Invalid ${optionName} value \"${value}\". Expected one of: ${choices.join(', ')}.`\n );\n }\n\n return choice;\n};\n"],"mappings":";;;;;;;;;;;AASA,MAAa,eACX,OACA,SACA,eACW;CACX,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,YAAY;CACjD,MAAM,SAAS,QAAQ,MACpB,cAAc,UAAU,YAAY,MAAM,eAC7C;CAEA,IAAI,CAAC,QACH,MAAM,IAAI,MACR,WAAW,WAAW,UAAU,MAAM,sBAAsB,QAAQ,KAAK,IAAI,EAAE,EACjF;CAGF,OAAO;AACT"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
2
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
|
|
5
5
|
//#region \0utils:asset
|
package/dist/esm/build.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { logConfigDetails } from "@intlayer/engine/cli";
|
|
2
1
|
import { getConfiguration } from "@intlayer/config/node";
|
|
3
2
|
import { claimCliContentWatcher, reportRedundantContentWatcher, runParallel } from "@intlayer/engine/utils";
|
|
4
3
|
import { buildAndWatchIntlayer } from "@intlayer/engine/watcher";
|
|
4
|
+
import { logConfigDetails } from "@intlayer/engine/logConfigDetails";
|
|
5
5
|
|
|
6
6
|
//#region src/build.ts
|
|
7
7
|
/**
|
package/dist/esm/build.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.mjs","names":[],"sources":["../../src/build.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/
|
|
1
|
+
{"version":3,"file":"build.mjs","names":[],"sources":["../../src/build.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/logConfigDetails';\nimport {\n claimCliContentWatcher,\n type ParallelHandle,\n reportRedundantContentWatcher,\n runParallel,\n} from '@intlayer/engine/utils';\nimport { buildAndWatchIntlayer } from '@intlayer/engine/watcher';\n\ntype BuildOptions = {\n watch?: boolean;\n skipPrepare?: boolean;\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\n/**\n * Get locales dictionaries .content.{json|ts|tsx|js|jsx|mjs|cjs} and build the JSON dictionaries in the .intlayer directory.\n * Watch mode available to get the change in the .content.{json|ts|tsx|js|jsx|mjs|cjs}\n */\nexport const build = async (options?: BuildOptions) => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n let parallelProcess: ParallelHandle | null = null;\n\n // Only watch mode keeps a watcher alive; a one-off build has nothing to\n // deduplicate. Claimed before the child is spawned so the bundler plugin\n // inside it stands down instead of racing this command.\n if (options?.watch) {\n const bundlerAlreadyWatching = await claimCliContentWatcher(\n config,\n 'intlayer build --watch'\n );\n\n if (bundlerAlreadyWatching) {\n reportRedundantContentWatcher(config, {\n cliLabel: 'intlayer build --watch',\n bundlerLabel: bundlerAlreadyWatching.label,\n });\n }\n }\n\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n await buildAndWatchIntlayer({\n persistent: options?.watch ?? false,\n skipPrepare: options?.skipPrepare ?? false,\n configuration: config,\n });\n\n if (!options?.watch && parallelProcess) {\n parallelProcess.kill();\n }\n};\n"],"mappings":";;;;;;;;;;AAwBA,MAAa,QAAQ,OAAO,YAA2B;CACrD,MAAM,SAAS,iBAAiB,SAAS,aAAa;CACtD,iBAAiB,SAAS,aAAa;CAEvC,IAAI,kBAAyC;CAK7C,IAAI,SAAS,OAAO;EAClB,MAAM,yBAAyB,MAAM,uBACnC,QACA,wBACF;EAEA,IAAI,wBACF,8BAA8B,QAAQ;GACpC,UAAU;GACV,cAAc,uBAAuB;EACvC,CAAC;CAEL;CAEA,IAAI,SAAS,MAAM;EACjB,kBAAkB,YAAY,QAAQ,IAAI;EAE1C,gBAAgB,OAAO,YAAY,CAEnC,CAAC;CACH;CAEA,MAAM,sBAAsB;EAC1B,YAAY,SAAS,SAAS;EAC9B,aAAa,SAAS,eAAe;EACrC,eAAe;CACjB,CAAC;CAED,IAAI,CAAC,SAAS,SAAS,iBACrB,gBAAgB,KAAK;AAEzB"}
|
package/dist/esm/ci.mjs
CHANGED
package/dist/esm/cli.mjs
CHANGED
|
@@ -153,7 +153,7 @@ const setAPI = () => {
|
|
|
153
153
|
/**
|
|
154
154
|
* INIT
|
|
155
155
|
*/
|
|
156
|
-
const initCmd = program.command("init").description("
|
|
156
|
+
const initCmd = program.command("init").enablePositionalOptions().description("Install the Intlayer packages and set up the framework. Use --interactive, or the init subcommands, for the other setup steps (CI, skills, MCP, VS Code, LSP, lint, CMS, …)").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--no-github-actions", "With --interactive: do not scaffold the GitHub Actions workflows, even if selected").option("--no-framework-setup", "Do not set up the project (Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page)").option("-i, --interactive", "Interactively choose what to set up (packages, skills, MCP, VS Code extension, LSP, …). Needs a terminal").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").action(async (options) => {
|
|
157
157
|
const { init, parseLocaleRoutingChoice, getRoutingInitOptions } = await import("./init.mjs");
|
|
158
158
|
return init(options.projectRoot, {
|
|
159
159
|
noGitignore: options.gitignore === false,
|
|
@@ -163,21 +163,59 @@ const setAPI = () => {
|
|
|
163
163
|
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {}
|
|
164
164
|
}, options.interactive === true);
|
|
165
165
|
});
|
|
166
|
-
initCmd.command("
|
|
167
|
-
const {
|
|
168
|
-
|
|
166
|
+
initCmd.command("packages").description("Install the missing Intlayer packages and upgrade the outdated ones").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
167
|
+
const { initSteps } = await import("./init.mjs");
|
|
168
|
+
return initSteps(options.projectRoot, ["packages"], { upgradeToVersion: packageJson.version });
|
|
169
169
|
});
|
|
170
|
-
initCmd.command("
|
|
171
|
-
const {
|
|
172
|
-
return
|
|
170
|
+
initCmd.command("project").alias("framework").description("Set up the project: Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page and .gitignore").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").action(async (options) => {
|
|
171
|
+
const { initSteps, parseLocaleRoutingChoice, getRoutingInitOptions } = await import("./init.mjs");
|
|
172
|
+
return initSteps(options.projectRoot, ["projectSetup"], {
|
|
173
|
+
noGitignore: options.gitignore === false,
|
|
174
|
+
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {}
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
initCmd.command("github-actions").alias("ci").description("Scaffold the fill and test GitHub Actions workflows that run on every pull request").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
178
|
+
const { initSteps } = await import("./init.mjs");
|
|
179
|
+
return initSteps(options.projectRoot, ["githubActions"]);
|
|
180
|
+
});
|
|
181
|
+
initCmd.command("vscode-extension").alias("vscode").description("Recommend the Intlayer VS Code extension in .vscode/extensions.json").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
182
|
+
const { initSteps } = await import("./init.mjs");
|
|
183
|
+
return initSteps(options.projectRoot, ["vscodeExtension"]);
|
|
184
|
+
});
|
|
185
|
+
initCmd.command("lsp").description("Configure the Intlayer language server in .vscode/settings.json").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
186
|
+
const { initSteps } = await import("./init.mjs");
|
|
187
|
+
return initSteps(options.projectRoot, ["lsp"]);
|
|
188
|
+
});
|
|
189
|
+
initCmd.command("eslint").alias("lint").description("Enable the Intlayer lint rules (ESLint / oxlint), when the project already lints").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
190
|
+
const { initSteps } = await import("./init.mjs");
|
|
191
|
+
return initSteps(options.projectRoot, ["eslint"], { upgradeToVersion: packageJson.version });
|
|
192
|
+
});
|
|
193
|
+
initCmd.command("skills").description("Initialize Intlayer skills in the project").option("--project-root [projectRoot]", "Project root directory").option("-p, --platform <platform>", "AI platform (e.g. Claude, Cursor, VSCode). Detected when omitted").option("-s, --skills <skills...>", "Skills to install (e.g. Usage Content React). Defaults to the project stack without a terminal").action(async (options) => {
|
|
194
|
+
const { initSkills, parsePlatform, parseSkills } = await import("./initSkills.mjs");
|
|
195
|
+
await initSkills(options.projectRoot, {
|
|
196
|
+
platform: options.platform ? parsePlatform(options.platform) : void 0,
|
|
197
|
+
skills: options.skills ? parseSkills(options.skills) : void 0
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
initCmd.command("mcp").description("Initialize Intlayer MCP server in the project").option("--project-root [projectRoot]", "Project root directory").option("-p, --platform <platform>", "AI platform (e.g. Claude, Cursor, VSCode). Detected when omitted").option("-t, --transport <transport>", "stdio (local server, default without a terminal) | sse (hosted)").action(async (options) => {
|
|
201
|
+
const { initMCP, parseMCPTransport } = await import("./initMCP.mjs");
|
|
202
|
+
const { parsePlatform } = await import("./initSkills.mjs");
|
|
203
|
+
return initMCP(options.projectRoot, {
|
|
204
|
+
platform: options.platform ? parsePlatform(options.platform) : void 0,
|
|
205
|
+
transport: options.transport ? parseMCPTransport(options.transport) : void 0
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
initCmd.command("cms").description("Log in to the Intlayer CMS through your browser, then store the credentials in your .env").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
209
|
+
const { initCms } = await import("./init.mjs");
|
|
210
|
+
return initCms(options.projectRoot);
|
|
173
211
|
});
|
|
174
|
-
initCmd.command("infra").description("Set up the Intlayer infrastructure: desktop app, all-in-one Docker container or Docker Compose stack (runs https://intlayer.org/install.sh, or install.ps1 on Windows)").option("-m, --mode <mode>", "Skip the menu: desktop | docker | compose").action(async (options) => {
|
|
212
|
+
initCmd.command("infra").description("Set up the Intlayer infrastructure: desktop app, all-in-one Docker container or Docker Compose stack (runs https://intlayer.org/install.sh, or install.ps1 on Windows)").option("-m, --mode <mode>", "Skip the menu: desktop | docker | compose (required without a terminal)").action(async (options) => {
|
|
175
213
|
const { initInfra, parseInfraMode } = await import("./initInfra.mjs");
|
|
176
214
|
return initInfra({ mode: options.mode ? parseInfraMode(options.mode) : void 0 });
|
|
177
215
|
});
|
|
178
|
-
initCmd.command("extension").alias("chrome-extension").description("Install the Intlayer Chrome extension or Firefox add-on in your browser").action(async () => {
|
|
179
|
-
const { initChromeExtension } = await import("./initChromeExtension.mjs");
|
|
180
|
-
return initChromeExtension();
|
|
216
|
+
initCmd.command("extension").alias("chrome-extension").description("Install the Intlayer Chrome extension or Firefox add-on in your browser").option("-b, --browser <browsers...>", "Browsers to open the store page for: chrome | firefox. Without a terminal, the links are only printed").action(async (options) => {
|
|
217
|
+
const { initChromeExtension, parseExtensionBrowsers } = await import("./initChromeExtension.mjs");
|
|
218
|
+
return initChromeExtension({ browsers: options.browser ? parseExtensionBrowsers(options.browser) : void 0 });
|
|
181
219
|
});
|
|
182
220
|
/**
|
|
183
221
|
* UPGRADE
|
|
@@ -403,7 +441,7 @@ const setAPI = () => {
|
|
|
403
441
|
const keys = [...options.keys ?? [], ...options.key ?? []];
|
|
404
442
|
const excludedKeys = [...options.excludedKeys ?? [], ...options.excludedKey ?? []];
|
|
405
443
|
const dictionaries = [...options.dictionaries ?? [], ...options.dictionary ?? []];
|
|
406
|
-
|
|
444
|
+
await fill({
|
|
407
445
|
...options,
|
|
408
446
|
keys: keys.length > 0 ? keys : void 0,
|
|
409
447
|
excludedKeys: excludedKeys.length > 0 ? excludedKeys : void 0,
|
|
@@ -572,6 +610,7 @@ const setAPI = () => {
|
|
|
572
610
|
const { runCI } = await import("./ci.mjs");
|
|
573
611
|
process.exit(await runCI(args));
|
|
574
612
|
});
|
|
613
|
+
program.enablePositionalOptions();
|
|
575
614
|
program.parse(process.argv);
|
|
576
615
|
return program;
|
|
577
616
|
};
|