@intra-mart/accel 0.1.0-dev-20260420

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/assets/assets.tar.gz +0 -0
  2. package/dist/asset/default-source.d.ts +1 -0
  3. package/dist/asset/default-source.js +9 -0
  4. package/dist/asset/deployer.d.ts +14 -0
  5. package/dist/asset/deployer.js +109 -0
  6. package/dist/asset/file-provider.d.ts +2 -0
  7. package/dist/asset/file-provider.js +25 -0
  8. package/dist/asset/local-provider.d.ts +2 -0
  9. package/dist/asset/local-provider.js +45 -0
  10. package/dist/asset/regex-replacement.d.ts +2 -0
  11. package/dist/asset/regex-replacement.js +12 -0
  12. package/dist/asset/types.d.ts +1 -0
  13. package/dist/asset/types.js +1 -0
  14. package/dist/asset/walker.d.ts +10 -0
  15. package/dist/asset/walker.js +165 -0
  16. package/dist/commands/attach.d.ts +64 -0
  17. package/dist/commands/attach.js +163 -0
  18. package/dist/commands/detach.d.ts +1 -0
  19. package/dist/commands/detach.js +74 -0
  20. package/dist/commands/init.d.ts +70 -0
  21. package/dist/commands/init.js +178 -0
  22. package/dist/core/condition-evaluator.d.ts +2 -0
  23. package/dist/core/condition-evaluator.js +26 -0
  24. package/dist/core/constants.d.ts +11 -0
  25. package/dist/core/constants.js +30 -0
  26. package/dist/core/module-map.d.ts +7 -0
  27. package/dist/core/module-map.js +12 -0
  28. package/dist/core/types.d.ts +100 -0
  29. package/dist/core/types.js +8 -0
  30. package/dist/core/variable-interpolator.d.ts +10 -0
  31. package/dist/core/variable-interpolator.js +37 -0
  32. package/dist/core/version-map.d.ts +7 -0
  33. package/dist/core/version-map.js +45 -0
  34. package/dist/i18n/en.d.ts +1 -0
  35. package/dist/i18n/en.js +47 -0
  36. package/dist/i18n/index.d.ts +2 -0
  37. package/dist/i18n/index.js +19 -0
  38. package/dist/i18n/ja.d.ts +1 -0
  39. package/dist/i18n/ja.js +47 -0
  40. package/dist/i18n/zh_CN.d.ts +1 -0
  41. package/dist/i18n/zh_CN.js +47 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +18 -0
  44. package/dist/interactive/agent-detect.d.ts +8 -0
  45. package/dist/interactive/agent-detect.js +31 -0
  46. package/dist/interactive/prompts.d.ts +22 -0
  47. package/dist/interactive/prompts.js +226 -0
  48. package/dist/juggling/extractor.d.ts +4 -0
  49. package/dist/juggling/extractor.js +15 -0
  50. package/dist/juggling/parser.d.ts +13 -0
  51. package/dist/juggling/parser.js +66 -0
  52. package/dist/markdown/processor.d.ts +3 -0
  53. package/dist/markdown/processor.js +16 -0
  54. package/dist/markdown/section-replacement.d.ts +2 -0
  55. package/dist/markdown/section-replacement.js +68 -0
  56. package/dist/markdown/text-replacement.d.ts +8 -0
  57. package/dist/markdown/text-replacement.js +32 -0
  58. package/dist/utils/archive.d.ts +3 -0
  59. package/dist/utils/archive.js +20 -0
  60. package/dist/utils/hash.d.ts +1 -0
  61. package/dist/utils/hash.js +6 -0
  62. package/dist/utils/locale-detect.d.ts +2 -0
  63. package/dist/utils/locale-detect.js +35 -0
  64. package/dist/utils/settings-io.d.ts +7 -0
  65. package/dist/utils/settings-io.js +54 -0
  66. package/package.json +60 -0
@@ -0,0 +1,47 @@
1
+ export const messages = {
2
+ // init/attach prompts
3
+ "prompt.name": "Enter project name",
4
+ "prompt.jugglingProject": "Enter IM-Juggling project path (optional)",
5
+ "prompt.accelplatformVersion": "Select iAP version",
6
+ "prompt.modules": "Select modules to use",
7
+ "prompt.group": "Enter group name",
8
+ "prompt.projectVersion": "Enter project version",
9
+ "prompt.description": "Enter project description",
10
+ "prompt.database": "Select database",
11
+ "prompt.javascript": "Use JavaScript?",
12
+ "prompt.agent": "Select agent",
13
+ "prompt.withGit": "Initialize Git repository?",
14
+ // juggling
15
+ "juggling.detected.version": "Detected version from juggling.im: {version}",
16
+ "juggling.detected.modules": "Detected modules from juggling.im: {modules}",
17
+ "juggling.notFound": "juggling.im not found at specified path: {path}",
18
+ // warnings
19
+ "warning.versionMismatch": "Specified iAP version ({option}) differs from juggling.im ({juggling}). Using specified value.",
20
+ "warning.moduleMismatch": "Specified modules differ from juggling.im. Using specified values.",
21
+ "warning.gitNotFound": "git command not found. Skipping Git initialization.",
22
+ "warning.fileExists": "File already exists, skipping: {path}",
23
+ // attach
24
+ "attach.skipSummary": "{count} file(s) were skipped because they already exist.",
25
+ // detach
26
+ "detach.confirm": "Detach Accel CLI from this project. Are you sure?",
27
+ "detach.deleted": "Deleted: {path}",
28
+ "detach.skipped": "Skipped: {path} (modifications detected)",
29
+ "detach.complete": "Detach complete. {skipped} file(s) were skipped due to user modifications.",
30
+ "detach.completeAll": "Detach complete. All assets removed.",
31
+ "detach.cancelled": "Detach cancelled.",
32
+ // errors
33
+ "error.directoryExists": "Directory already exists: {path}",
34
+ "error.accelExists": ".accel directory already exists",
35
+ "error.accelNotFound": ".accel directory not found",
36
+ "error.missingRequiredOptions": "The following required options are missing: {options}",
37
+ "error.invalidVersion": "Invalid iAP version: {version}",
38
+ "error.invalidModule": "Invalid module: {module}",
39
+ "error.invalidDatabase": "Invalid database: {database}",
40
+ "error.invalidAgent": "Invalid agent: {agent}",
41
+ // progress
42
+ "progress.downloading": "Downloading assets...",
43
+ "progress.deploying": "Deploying assets...",
44
+ "progress.installing": "Installing dependencies...",
45
+ "progress.gitInit": "Initializing Git repository...",
46
+ "progress.complete": "Project creation complete.",
47
+ };
@@ -0,0 +1,2 @@
1
+ export declare const getMessage: (key: string, locale: string, params?: Record<string, string>) => string;
2
+ export declare const getSupportedLocales: () => string[];
@@ -0,0 +1,19 @@
1
+ import { messages as ja } from "./ja.js";
2
+ import { messages as en } from "./en.js";
3
+ import { messages as zhCN } from "./zh_CN.js";
4
+ const catalogs = {
5
+ ja,
6
+ en,
7
+ "zh_CN": zhCN,
8
+ };
9
+ export const getMessage = (key, locale, params) => {
10
+ const catalog = catalogs[locale] ?? catalogs["en"];
11
+ let message = catalog[key] ?? catalogs["en"][key] ?? key;
12
+ if (params) {
13
+ for (const [paramKey, paramValue] of Object.entries(params)) {
14
+ message = message.replaceAll(`{${paramKey}}`, paramValue);
15
+ }
16
+ }
17
+ return message;
18
+ };
19
+ export const getSupportedLocales = () => Object.keys(catalogs);
@@ -0,0 +1 @@
1
+ export declare const messages: Record<string, string>;
@@ -0,0 +1,47 @@
1
+ export const messages = {
2
+ // init/attach prompts
3
+ "prompt.name": "プロジェクト名を入力してください",
4
+ "prompt.jugglingProject": "IM-Jugglingプロジェクトのパスを入力してください(省略可)",
5
+ "prompt.accelplatformVersion": "iAPバージョンを選択してください",
6
+ "prompt.modules": "利用するモジュールを選択してください",
7
+ "prompt.group": "グループ名を入力してください",
8
+ "prompt.projectVersion": "プロジェクトバージョンを入力してください",
9
+ "prompt.description": "プロジェクトの説明を入力してください",
10
+ "prompt.database": "データベースを選択してください",
11
+ "prompt.javascript": "JavaScriptを利用しますか?",
12
+ "prompt.agent": "エージェントを選択してください",
13
+ "prompt.withGit": "Gitリポジトリを初期化しますか?",
14
+ // juggling
15
+ "juggling.detected.version": "juggling.imからバージョンを検出: {version}",
16
+ "juggling.detected.modules": "juggling.imからモジュールを検出: {modules}",
17
+ "juggling.notFound": "指定されたパスにjuggling.imが見つかりません: {path}",
18
+ // warnings
19
+ "warning.versionMismatch": "指定されたiAPバージョン ({option}) とjuggling.imのバージョン ({juggling}) が異なります。指定値を優先します。",
20
+ "warning.moduleMismatch": "指定されたモジュールとjuggling.imのモジュールが異なります。指定値を優先します。",
21
+ "warning.gitNotFound": "gitコマンドが見つかりません。Git初期化をスキップします。",
22
+ "warning.fileExists": "既存ファイルのためスキップ: {path}",
23
+ // attach
24
+ "attach.skipSummary": "{count}件のファイルは既に存在したためスキップしました。",
25
+ // detach
26
+ "detach.confirm": "このプロジェクトからAccel CLIを解除します。よろしいですか?",
27
+ "detach.deleted": "削除: {path}",
28
+ "detach.skipped": "スキップ: {path} (変更が検出されました)",
29
+ "detach.complete": "detachが完了しました。{skipped}件のファイルはユーザーによる変更が検出されたためスキップしました。",
30
+ "detach.completeAll": "detachが完了しました。すべての資材を削除しました。",
31
+ "detach.cancelled": "detachをキャンセルしました。",
32
+ // errors
33
+ "error.directoryExists": "ディレクトリが既に存在します: {path}",
34
+ "error.accelExists": ".accelディレクトリが既に存在します",
35
+ "error.accelNotFound": ".accelディレクトリが見つかりません",
36
+ "error.missingRequiredOptions": "以下の必須オプションが指定されていません: {options}",
37
+ "error.invalidVersion": "無効なiAPバージョンです: {version}",
38
+ "error.invalidModule": "無効なモジュールです: {module}",
39
+ "error.invalidDatabase": "無効なデータベースです: {database}",
40
+ "error.invalidAgent": "無効なエージェントです: {agent}",
41
+ // progress
42
+ "progress.downloading": "資材をダウンロードしています...",
43
+ "progress.deploying": "資材を配備しています...",
44
+ "progress.installing": "依存関係をインストールしています...",
45
+ "progress.gitInit": "Gitリポジトリを初期化しています...",
46
+ "progress.complete": "プロジェクトの作成が完了しました。",
47
+ };
@@ -0,0 +1 @@
1
+ export declare const messages: Record<string, string>;
@@ -0,0 +1,47 @@
1
+ export const messages = {
2
+ // init/attach prompts
3
+ "prompt.name": "请输入项目名称",
4
+ "prompt.jugglingProject": "请输入IM-Juggling项目路径(可选)",
5
+ "prompt.accelplatformVersion": "请选择iAP版本",
6
+ "prompt.modules": "请选择要使用的模块",
7
+ "prompt.group": "请输入组名",
8
+ "prompt.projectVersion": "请输入项目版本",
9
+ "prompt.description": "请输入项目描述",
10
+ "prompt.database": "请选择数据库",
11
+ "prompt.javascript": "是否使用JavaScript?",
12
+ "prompt.agent": "请选择代理",
13
+ "prompt.withGit": "是否初始化Git仓库?",
14
+ // juggling
15
+ "juggling.detected.version": "从juggling.im检测到版本: {version}",
16
+ "juggling.detected.modules": "从juggling.im检测到模块: {modules}",
17
+ "juggling.notFound": "在指定路径未找到juggling.im: {path}",
18
+ // warnings
19
+ "warning.versionMismatch": "指定的iAP版本 ({option}) 与juggling.im ({juggling}) 不同。将使用指定值。",
20
+ "warning.moduleMismatch": "指定的模块与juggling.im不同。将使用指定值。",
21
+ "warning.gitNotFound": "未找到git命令。跳过Git初始化。",
22
+ "warning.fileExists": "文件已存在,跳过: {path}",
23
+ // attach
24
+ "attach.skipSummary": "{count}个文件已存在,已跳过。",
25
+ // detach
26
+ "detach.confirm": "从此项目解除Accel CLI。确定吗?",
27
+ "detach.deleted": "已删除: {path}",
28
+ "detach.skipped": "已跳过: {path} (检测到修改)",
29
+ "detach.complete": "解除完成。{skipped}个文件因用户修改而被跳过。",
30
+ "detach.completeAll": "解除完成。所有资源已删除。",
31
+ "detach.cancelled": "解除已取消。",
32
+ // errors
33
+ "error.directoryExists": "目录已存在: {path}",
34
+ "error.accelExists": ".accel目录已存在",
35
+ "error.accelNotFound": "未找到.accel目录",
36
+ "error.missingRequiredOptions": "以下必需选项未指定: {options}",
37
+ "error.invalidVersion": "无效的iAP版本: {version}",
38
+ "error.invalidModule": "无效的模块: {module}",
39
+ "error.invalidDatabase": "无效的数据库: {database}",
40
+ "error.invalidAgent": "无效的代理: {agent}",
41
+ // progress
42
+ "progress.downloading": "正在下载资源...",
43
+ "progress.deploying": "正在部署资源...",
44
+ "progress.installing": "正在安装依赖...",
45
+ "progress.gitInit": "正在初始化Git仓库...",
46
+ "progress.complete": "项目创建完成。",
47
+ };
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { defineCommand, runMain } from "citty";
3
+ import { initCommand } from "./commands/init.js";
4
+ import { attachCommand } from "./commands/attach.js";
5
+ import { detachCommand } from "./commands/detach.js";
6
+ const main = defineCommand({
7
+ meta: {
8
+ name: "accel",
9
+ version: "0.1.0",
10
+ description: "CLI tool for intra-mart Accel Platform development",
11
+ },
12
+ subCommands: {
13
+ init: initCommand,
14
+ attach: attachCommand,
15
+ detach: detachCommand,
16
+ },
17
+ });
18
+ runMain(main);
@@ -0,0 +1,8 @@
1
+ type DetectedAgent = {
2
+ name: string;
3
+ command: string;
4
+ };
5
+ export declare const detectAgents: () => DetectedAgent[];
6
+ export declare const detectDefaultAgent: () => string;
7
+ export declare const detectDefaultAgents: () => string[];
8
+ export {};
@@ -0,0 +1,31 @@
1
+ import { execSync } from "node:child_process";
2
+ const AGENT_COMMANDS = [
3
+ { name: "claude-code", command: "claude" },
4
+ { name: "github-copilot", command: "gh" },
5
+ ];
6
+ const commandExists = (cmd) => {
7
+ try {
8
+ const whichCmd = process.platform === "win32" ? "where" : "which";
9
+ execSync(`${whichCmd} ${cmd}`, { stdio: "pipe" });
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ };
16
+ export const detectAgents = () => {
17
+ return AGENT_COMMANDS.filter((a) => commandExists(a.command));
18
+ };
19
+ export const detectDefaultAgent = () => {
20
+ const detected = detectAgents();
21
+ if (detected.length === 0)
22
+ return "github-copilot";
23
+ return detected[0].name;
24
+ };
25
+ export const detectDefaultAgents = () => {
26
+ const detected = detectAgents();
27
+ if (detected.length === 0) {
28
+ return [...AGENT_COMMANDS.map((a) => a.name)];
29
+ }
30
+ return detected.map((a) => a.name);
31
+ };
@@ -0,0 +1,22 @@
1
+ import type { AccelSettings } from "../core/types.js";
2
+ export type PromptOptions = {
3
+ name?: string;
4
+ jugglingProject?: string;
5
+ accelplatformVersion?: string;
6
+ module?: string[];
7
+ group?: string;
8
+ projectVersion?: string;
9
+ description?: string;
10
+ database?: string;
11
+ javascript?: boolean;
12
+ agent?: string[];
13
+ locale: string;
14
+ withGit?: boolean;
15
+ noInteraction?: boolean;
16
+ isInit: boolean;
17
+ };
18
+ export type ResolvedOptions = Omit<AccelSettings, "cliVersion" | "createdAt" | "deployedAssets"> & {
19
+ withGit: boolean;
20
+ };
21
+ export declare const validateNonInteractive: (opts: PromptOptions) => string[];
22
+ export declare const runPrompts: (opts: PromptOptions) => Promise<ResolvedOptions>;
@@ -0,0 +1,226 @@
1
+ import * as p from "@clack/prompts";
2
+ import { SELECTABLE_VERSIONS, } from "../core/version-map.js";
3
+ import { MODULE_OPTIONS, DATABASE_OPTIONS, AGENT_OPTIONS, DEFAULT_SETTINGS, } from "../core/constants.js";
4
+ import { getMessage } from "../i18n/index.js";
5
+ import { detectAgents, detectDefaultAgents } from "./agent-detect.js";
6
+ import { parseJugglingFile } from "../juggling/parser.js";
7
+ import { extractVersionLabel, extractModules, } from "../juggling/extractor.js";
8
+ import { stat } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ const resolveJuggling = async (jugglingPath, locale) => {
11
+ const imPath = join(jugglingPath, "juggling.im");
12
+ try {
13
+ await stat(imPath);
14
+ }
15
+ catch {
16
+ throw new Error(getMessage("juggling.notFound", locale, { path: imPath }));
17
+ }
18
+ const data = await parseJugglingFile(imPath);
19
+ const version = extractVersionLabel(data);
20
+ const modules = extractModules(data);
21
+ return { version, modules };
22
+ };
23
+ export const validateNonInteractive = (opts) => {
24
+ const missing = [];
25
+ if (!opts.name)
26
+ missing.push("--name");
27
+ if (!opts.jugglingProject) {
28
+ if (!opts.accelplatformVersion)
29
+ missing.push("--accelplatform-version");
30
+ if (!opts.module || opts.module.length === 0)
31
+ missing.push("--module");
32
+ }
33
+ return missing;
34
+ };
35
+ export const runPrompts = async (opts) => {
36
+ const locale = opts.locale;
37
+ // Non-interactive mode
38
+ if (opts.noInteraction) {
39
+ const missing = validateNonInteractive(opts);
40
+ if (missing.length > 0) {
41
+ throw new Error(getMessage("error.missingRequiredOptions", locale, {
42
+ options: missing.join(", "),
43
+ }));
44
+ }
45
+ let jugglingVersion = null;
46
+ let jugglingModules = [];
47
+ if (opts.jugglingProject) {
48
+ const resolved = await resolveJuggling(opts.jugglingProject, locale);
49
+ jugglingVersion = resolved.version;
50
+ jugglingModules = resolved.modules;
51
+ }
52
+ return {
53
+ name: opts.name ?? DEFAULT_SETTINGS.name,
54
+ group: opts.group ?? DEFAULT_SETTINGS.group,
55
+ projectVersion: opts.projectVersion ?? DEFAULT_SETTINGS.projectVersion,
56
+ description: opts.description ?? DEFAULT_SETTINGS.description,
57
+ accelplatformVersion: opts.accelplatformVersion ??
58
+ jugglingVersion ??
59
+ DEFAULT_SETTINGS.accelplatformVersion,
60
+ modules: opts.module && opts.module.length > 0
61
+ ? opts.module
62
+ : jugglingModules.length > 0
63
+ ? jugglingModules
64
+ : [],
65
+ database: (opts.database ?? DEFAULT_SETTINGS.database),
66
+ agents: opts.agent ?? detectDefaultAgents(),
67
+ javascript: opts.javascript ?? DEFAULT_SETTINGS.javascript,
68
+ locale,
69
+ jugglingProject: opts.jugglingProject ?? null,
70
+ withGit: opts.withGit ?? true,
71
+ };
72
+ }
73
+ // Interactive mode
74
+ p.intro("Accel CLI");
75
+ // 1. Project name
76
+ const name = (await p.text({
77
+ message: getMessage("prompt.name", locale),
78
+ defaultValue: opts.name ?? DEFAULT_SETTINGS.name,
79
+ initialValue: opts.name ?? DEFAULT_SETTINGS.name,
80
+ }));
81
+ if (p.isCancel(name))
82
+ process.exit(0);
83
+ // 2. Juggling project (optional)
84
+ const jugglingInput = (await p.text({
85
+ message: getMessage("prompt.jugglingProject", locale),
86
+ defaultValue: opts.jugglingProject ?? "",
87
+ initialValue: opts.jugglingProject ?? "",
88
+ }));
89
+ if (p.isCancel(jugglingInput))
90
+ process.exit(0);
91
+ let jugglingVersion = null;
92
+ let jugglingModules = [];
93
+ const jugglingProject = jugglingInput || null;
94
+ if (jugglingProject) {
95
+ try {
96
+ const resolved = await resolveJuggling(jugglingProject, locale);
97
+ jugglingVersion = resolved.version;
98
+ jugglingModules = resolved.modules;
99
+ p.note(getMessage("juggling.detected.version", locale, {
100
+ version: jugglingVersion ?? "unknown",
101
+ }));
102
+ }
103
+ catch (err) {
104
+ p.log.warning(err instanceof Error ? err.message : String(err));
105
+ }
106
+ }
107
+ // 3. iAP version
108
+ const versionDefault = opts.accelplatformVersion ?? jugglingVersion ?? DEFAULT_SETTINGS.accelplatformVersion;
109
+ // Warn if option and juggling version differ
110
+ if (opts.accelplatformVersion && jugglingVersion && opts.accelplatformVersion !== jugglingVersion) {
111
+ p.log.warning(getMessage("warning.versionMismatch", locale, {
112
+ option: opts.accelplatformVersion,
113
+ juggling: jugglingVersion,
114
+ }));
115
+ }
116
+ const accelplatformVersion = (await p.select({
117
+ message: getMessage("prompt.accelplatformVersion", locale),
118
+ options: SELECTABLE_VERSIONS.map((v) => ({
119
+ value: v.label,
120
+ label: `${v.label} (${v.codename})`,
121
+ })),
122
+ initialValue: versionDefault,
123
+ }));
124
+ if (p.isCancel(accelplatformVersion))
125
+ process.exit(0);
126
+ // 4. Modules
127
+ const moduleDefault = opts.module && opts.module.length > 0
128
+ ? opts.module
129
+ : jugglingModules.length > 0
130
+ ? jugglingModules
131
+ : [];
132
+ if (opts.module && opts.module.length > 0 && jugglingModules.length > 0) {
133
+ const diff = opts.module.some((m) => !jugglingModules.includes(m)) ||
134
+ jugglingModules.some((m) => !opts.module.includes(m));
135
+ if (diff) {
136
+ p.log.warning(getMessage("warning.moduleMismatch", locale));
137
+ }
138
+ }
139
+ const modules = (await p.multiselect({
140
+ message: getMessage("prompt.modules", locale),
141
+ options: MODULE_OPTIONS.map((m) => ({
142
+ value: m,
143
+ label: m,
144
+ })),
145
+ initialValues: moduleDefault,
146
+ }));
147
+ if (p.isCancel(modules))
148
+ process.exit(0);
149
+ // 5. Group
150
+ const group = (await p.text({
151
+ message: getMessage("prompt.group", locale),
152
+ defaultValue: opts.group ?? DEFAULT_SETTINGS.group,
153
+ initialValue: opts.group ?? DEFAULT_SETTINGS.group,
154
+ }));
155
+ if (p.isCancel(group))
156
+ process.exit(0);
157
+ // 6. Project version
158
+ const projectVersion = (await p.text({
159
+ message: getMessage("prompt.projectVersion", locale),
160
+ defaultValue: opts.projectVersion ?? DEFAULT_SETTINGS.projectVersion,
161
+ initialValue: opts.projectVersion ?? DEFAULT_SETTINGS.projectVersion,
162
+ }));
163
+ if (p.isCancel(projectVersion))
164
+ process.exit(0);
165
+ // 7. Description
166
+ const description = (await p.text({
167
+ message: getMessage("prompt.description", locale),
168
+ defaultValue: opts.description ?? DEFAULT_SETTINGS.description,
169
+ initialValue: opts.description ?? DEFAULT_SETTINGS.description,
170
+ }));
171
+ if (p.isCancel(description))
172
+ process.exit(0);
173
+ // 8. Database
174
+ const database = (await p.select({
175
+ message: getMessage("prompt.database", locale),
176
+ options: DATABASE_OPTIONS.map((d) => ({ value: d, label: d })),
177
+ initialValue: opts.database ?? DEFAULT_SETTINGS.database,
178
+ }));
179
+ if (p.isCancel(database))
180
+ process.exit(0);
181
+ // 9. JavaScript
182
+ const javascript = (await p.confirm({
183
+ message: getMessage("prompt.javascript", locale),
184
+ initialValue: opts.javascript ?? DEFAULT_SETTINGS.javascript,
185
+ }));
186
+ if (p.isCancel(javascript))
187
+ process.exit(0);
188
+ // 10. Agent (multi-select)
189
+ const detected = detectAgents();
190
+ const agentOptions = AGENT_OPTIONS.map((a) => ({ value: a, label: a }));
191
+ const defaultAgents = opts.agent ??
192
+ (detected.length > 0
193
+ ? detected.map((a) => a.name)
194
+ : [...AGENT_OPTIONS]);
195
+ const agents = (await p.multiselect({
196
+ message: getMessage("prompt.agent", locale),
197
+ options: agentOptions,
198
+ initialValues: defaultAgents,
199
+ }));
200
+ if (p.isCancel(agents))
201
+ process.exit(0);
202
+ // 11. Git init (init only)
203
+ let withGit = opts.withGit ?? true;
204
+ if (opts.isInit) {
205
+ withGit = (await p.confirm({
206
+ message: getMessage("prompt.withGit", locale),
207
+ initialValue: opts.withGit ?? true,
208
+ }));
209
+ if (p.isCancel(withGit))
210
+ process.exit(0);
211
+ }
212
+ return {
213
+ name,
214
+ group,
215
+ projectVersion,
216
+ description,
217
+ accelplatformVersion,
218
+ modules,
219
+ database,
220
+ agents,
221
+ javascript,
222
+ locale,
223
+ jugglingProject,
224
+ withGit,
225
+ };
226
+ };
@@ -0,0 +1,4 @@
1
+ import type { JugglingData } from "./parser.js";
2
+ export declare const extractVersion: (data: JugglingData) => string;
3
+ export declare const extractVersionLabel: (data: JugglingData) => string;
4
+ export declare const extractModules: (data: JugglingData) => string[];
@@ -0,0 +1,15 @@
1
+ import { xmlIdToModuleName } from "../core/module-map.js";
2
+ import { semverToLabel } from "../core/version-map.js";
3
+ export const extractVersion = (data) => data.baseVersion;
4
+ export const extractVersionLabel = (data) => semverToLabel(data.baseVersion);
5
+ export const extractModules = (data) => {
6
+ const selectedModules = data.modules.filter((m) => m.selected);
7
+ const result = [];
8
+ for (const mod of selectedModules) {
9
+ const name = xmlIdToModuleName(mod.id);
10
+ if (name) {
11
+ result.push(name);
12
+ }
13
+ }
14
+ return [...new Set(result)].sort();
15
+ };
@@ -0,0 +1,13 @@
1
+ export type JugglingModule = {
2
+ id: string;
3
+ version: string;
4
+ selected: boolean;
5
+ name: string;
6
+ type: "module" | "module-pack";
7
+ };
8
+ export type JugglingData = {
9
+ modules: JugglingModule[];
10
+ baseVersion: string;
11
+ };
12
+ export declare const parseJugglingFile: (filePath: string) => Promise<JugglingData>;
13
+ export declare const parseJugglingXml: (xmlContent: string) => JugglingData;
@@ -0,0 +1,66 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { gunzipSync } from "node:zlib";
3
+ import { XMLParser } from "fast-xml-parser";
4
+ const parseXmlModules = (modulesObj) => {
5
+ const modules = [];
6
+ const processEntries = (entries, type) => {
7
+ const arr = Array.isArray(entries) ? entries : entries ? [entries] : [];
8
+ for (const entry of arr) {
9
+ if (typeof entry !== "object" || entry === null)
10
+ continue;
11
+ const attrs = entry;
12
+ modules.push({
13
+ id: String(attrs["@_id"] ?? ""),
14
+ version: String(attrs["@_version"] ?? ""),
15
+ selected: attrs["@_selected"] === "true",
16
+ name: String(attrs["ns2:name"] ?? ""),
17
+ type,
18
+ });
19
+ }
20
+ };
21
+ processEntries(modulesObj["ns2:module"], "module");
22
+ processEntries(modulesObj["ns2:module-pack"], "module-pack");
23
+ return modules;
24
+ };
25
+ export const parseJugglingFile = async (filePath) => {
26
+ const compressed = await readFile(filePath);
27
+ const xmlBuffer = gunzipSync(compressed);
28
+ const xmlContent = xmlBuffer.toString("utf-8");
29
+ return parseJugglingXml(xmlContent);
30
+ };
31
+ export const parseJugglingXml = (xmlContent) => {
32
+ const parser = new XMLParser({
33
+ ignoreAttributes: false,
34
+ attributeNamePrefix: "@_",
35
+ isArray: (_name, jpath) => {
36
+ if (typeof jpath !== "string")
37
+ return false;
38
+ return (jpath.endsWith("ns2:module") ||
39
+ jpath.endsWith("ns2:module-pack") ||
40
+ jpath.endsWith("ns2:structure"));
41
+ },
42
+ });
43
+ const parsed = parser.parse(xmlContent);
44
+ const structures = parsed?.["ns2:juggling"]?.["ns2:structures"]?.["ns2:structure"];
45
+ if (!Array.isArray(structures) || structures.length === 0) {
46
+ return { modules: [], baseVersion: "" };
47
+ }
48
+ // Search from the end for the first structure with valid="true"
49
+ let validStructure;
50
+ for (let i = structures.length - 1; i >= 0; i--) {
51
+ if (structures[i]["@_valid"] === "true") {
52
+ validStructure = structures[i];
53
+ break;
54
+ }
55
+ }
56
+ if (!validStructure) {
57
+ return { modules: [], baseVersion: "" };
58
+ }
59
+ // Extract baseVersion from ns2:base version attribute
60
+ const base = validStructure["ns2:base"];
61
+ const baseVersion = String(base?.["@_version"] ?? "");
62
+ // Extract modules
63
+ const modulesObj = validStructure["ns2:modules"];
64
+ const modules = modulesObj ? parseXmlModules(modulesObj) : [];
65
+ return { modules, baseVersion };
66
+ };
@@ -0,0 +1,3 @@
1
+ import type { Replacement, EvalContext } from "../core/types.js";
2
+ import { type PlaceholderMatcher } from "./text-replacement.js";
3
+ export declare const processMarkdown: (content: string, replacements: Replacement[], context: EvalContext, placeholderMatcher?: PlaceholderMatcher) => string;
@@ -0,0 +1,16 @@
1
+ import { applyTextReplacements } from "./text-replacement.js";
2
+ import { applySectionReplacements } from "./section-replacement.js";
3
+ export const processMarkdown = (content, replacements, context, placeholderMatcher) => {
4
+ const textReplacements = replacements.filter((r) => r.type === "text");
5
+ const sectionReplacements = replacements.filter((r) => r.type === "section");
6
+ // Apply text replacements first (plain string, before remark touches content)
7
+ let result = content;
8
+ if (textReplacements.length > 0) {
9
+ result = applyTextReplacements(result, textReplacements, context, placeholderMatcher);
10
+ }
11
+ // Then apply section replacements (remark AST parse + stringify)
12
+ if (sectionReplacements.length > 0) {
13
+ result = applySectionReplacements(result, sectionReplacements, context);
14
+ }
15
+ return result;
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { SectionReplacement, EvalContext } from "../core/types.js";
2
+ export declare const applySectionReplacements: (content: string, replacements: SectionReplacement[], context: EvalContext) => string;