@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
Binary file
@@ -0,0 +1 @@
1
+ export declare const defaultAssetSourcePath: () => string;
@@ -0,0 +1,9 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { dirname, join } from "node:path";
3
+ // Layout assumption (both dev and published package):
4
+ // <root>/dist/asset/default-source.js (or <root>/src/asset/default-source.ts in dev)
5
+ // <root>/assets/assets.tar.gz
6
+ export const defaultAssetSourcePath = () => {
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ return join(here, "..", "..", "assets", "assets.tar.gz");
9
+ };
@@ -0,0 +1,14 @@
1
+ import type { AssetProvider, AccelSettings, HashsumEntry } from "../core/types.js";
2
+ export type DeployOptions = {
3
+ projectDir: string;
4
+ settings: AccelSettings;
5
+ provider: AssetProvider;
6
+ noInstall: boolean;
7
+ skipExistingFiles?: boolean;
8
+ };
9
+ export type DeployResult = {
10
+ deployedFiles: string[];
11
+ hashEntries: HashsumEntry[];
12
+ skippedFiles: string[];
13
+ };
14
+ export declare const deployAssets: (options: DeployOptions) => Promise<DeployResult>;
@@ -0,0 +1,109 @@
1
+ import { readFile, writeFile, mkdir, stat } from "node:fs/promises";
2
+ import { join, dirname } from "node:path";
3
+ import { labelToSemver } from "../core/version-map.js";
4
+ import { walkAssetRepo } from "./walker.js";
5
+ import { processMarkdown } from "../markdown/processor.js";
6
+ import { applyRegexReplacements } from "./regex-replacement.js";
7
+ import { computeSha1 } from "../utils/hash.js";
8
+ import { writeSettings, writeHashsum } from "../utils/settings-io.js";
9
+ import { execSync } from "node:child_process";
10
+ const fileExists = async (path) => {
11
+ try {
12
+ await stat(path);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ };
19
+ const collectReplacements = (entry) => {
20
+ if (!entry.meta?.replacements)
21
+ return [];
22
+ return entry.meta.replacements;
23
+ };
24
+ export const deployAssets = async (options) => {
25
+ const { projectDir, settings, provider, noInstall, skipExistingFiles } = options;
26
+ try {
27
+ // 1. Fetch assets
28
+ const repoDir = await provider.fetch();
29
+ // 2. Build eval context
30
+ const semver = labelToSemver(settings.accelplatformVersion);
31
+ const context = {
32
+ version: semver,
33
+ modules: settings.modules,
34
+ locale: settings.locale,
35
+ agents: settings.agents,
36
+ name: settings.name,
37
+ group: settings.group,
38
+ description: settings.description,
39
+ accelplatformVersion: settings.accelplatformVersion,
40
+ database: settings.database,
41
+ projectVersion: settings.projectVersion,
42
+ };
43
+ // 3. Walk and filter
44
+ const entries = await walkAssetRepo(repoDir, semver, context);
45
+ // 4. Deploy files
46
+ const deployedFiles = [];
47
+ const hashEntries = [];
48
+ const deployedAssets = {};
49
+ const skippedFiles = [];
50
+ for (const entry of entries) {
51
+ const targetPath = entry.relativePath;
52
+ const destPath = join(projectDir, targetPath);
53
+ if (skipExistingFiles && (await fileExists(destPath))) {
54
+ skippedFiles.push(targetPath);
55
+ continue;
56
+ }
57
+ // Read source file
58
+ let content = await readFile(entry.sourcePath, "utf-8");
59
+ // Apply replacements
60
+ const replacements = collectReplacements(entry);
61
+ if (replacements.length > 0) {
62
+ if (targetPath.endsWith(".md")) {
63
+ // Markdown: process with remark AST
64
+ content = processMarkdown(content, replacements, context);
65
+ }
66
+ else {
67
+ // Non-markdown: apply regex replacements only
68
+ const regexReplacements = replacements.filter((r) => r.type === "regex");
69
+ if (regexReplacements.length > 0) {
70
+ content = applyRegexReplacements(content, regexReplacements, context);
71
+ }
72
+ }
73
+ }
74
+ // Write to project directory
75
+ await mkdir(dirname(destPath), { recursive: true });
76
+ await writeFile(destPath, content, "utf-8");
77
+ // Record hash
78
+ const sha1 = computeSha1(content);
79
+ const version = entry.meta?.version ?? "0.0.0";
80
+ hashEntries.push({ filePath: targetPath, version, sha1 });
81
+ deployedAssets[targetPath] = version;
82
+ deployedFiles.push(targetPath);
83
+ }
84
+ // 5. Write settings and hashsum
85
+ const updatedSettings = {
86
+ ...settings,
87
+ deployedAssets,
88
+ };
89
+ await writeSettings(projectDir, updatedSettings);
90
+ await writeHashsum(projectDir, hashEntries);
91
+ // 6. Run install commands at project root
92
+ if (!noInstall) {
93
+ const installCmds = ["bun install", "bun run build"];
94
+ for (const cmd of installCmds) {
95
+ try {
96
+ execSync(cmd, { cwd: projectDir, stdio: "pipe" });
97
+ }
98
+ catch {
99
+ console.warn(`Warning: install command failed: ${cmd} in ${projectDir}`);
100
+ }
101
+ }
102
+ }
103
+ return { deployedFiles, hashEntries, skippedFiles };
104
+ }
105
+ finally {
106
+ // 7. Cleanup (delegated to provider)
107
+ await provider.cleanup().catch(() => { });
108
+ }
109
+ };
@@ -0,0 +1,2 @@
1
+ import type { AssetProvider } from "../core/types.js";
2
+ export declare const createFileAssetProvider: (sourcePath: string) => AssetProvider;
@@ -0,0 +1,25 @@
1
+ import { stat, mkdir, rm } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { extractTarGz, createTempDir } from "../utils/archive.js";
4
+ export const createFileAssetProvider = (sourcePath) => {
5
+ let tmpDir = null;
6
+ return {
7
+ fetch: async () => {
8
+ const st = await stat(sourcePath);
9
+ if (st.isDirectory()) {
10
+ return sourcePath;
11
+ }
12
+ tmpDir = await createTempDir("accel-assets-");
13
+ const extractDir = join(tmpDir, "repo");
14
+ await mkdir(extractDir, { recursive: true });
15
+ await extractTarGz(sourcePath, extractDir);
16
+ return extractDir;
17
+ },
18
+ cleanup: async () => {
19
+ if (tmpDir) {
20
+ await rm(tmpDir, { recursive: true, force: true }).catch(() => { });
21
+ tmpDir = null;
22
+ }
23
+ },
24
+ };
25
+ };
@@ -0,0 +1,2 @@
1
+ import type { AssetProvider } from "../core/types.js";
2
+ export declare const createLocalAssetProvider: (serverUrl: string) => AssetProvider;
@@ -0,0 +1,45 @@
1
+ import { get } from "node:http";
2
+ import { createWriteStream } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { mkdir, rm } from "node:fs/promises";
5
+ import { extractTarGz, createTempDir } from "../utils/archive.js";
6
+ const downloadFile = (url, destPath) => {
7
+ return new Promise((resolve, reject) => {
8
+ const file = createWriteStream(destPath);
9
+ get(url, (response) => {
10
+ if (response.statusCode !== 200) {
11
+ file.close();
12
+ reject(new Error(`HTTP ${response.statusCode} when downloading from ${url}`));
13
+ return;
14
+ }
15
+ response.pipe(file);
16
+ file.on("finish", () => {
17
+ file.close();
18
+ resolve();
19
+ });
20
+ }).on("error", (err) => {
21
+ file.close();
22
+ reject(err);
23
+ });
24
+ });
25
+ };
26
+ export const createLocalAssetProvider = (serverUrl) => {
27
+ let tmpDir = null;
28
+ return {
29
+ fetch: async () => {
30
+ tmpDir = await createTempDir("accel-assets-");
31
+ const archivePath = join(tmpDir, "assets.tar.gz");
32
+ const extractDir = join(tmpDir, "repo");
33
+ await mkdir(extractDir, { recursive: true });
34
+ await downloadFile(`${serverUrl}/archive`, archivePath);
35
+ await extractTarGz(archivePath, extractDir);
36
+ return extractDir;
37
+ },
38
+ cleanup: async () => {
39
+ if (tmpDir) {
40
+ await rm(tmpDir, { recursive: true, force: true }).catch(() => { });
41
+ tmpDir = null;
42
+ }
43
+ },
44
+ };
45
+ };
@@ -0,0 +1,2 @@
1
+ import type { RegexReplacement, EvalContext } from "../core/types.js";
2
+ export declare const applyRegexReplacements: (content: string, replacements: RegexReplacement[], context: EvalContext) => string;
@@ -0,0 +1,12 @@
1
+ import { evaluateCondition } from "../core/condition-evaluator.js";
2
+ import { interpolateVariables } from "../core/variable-interpolator.js";
3
+ export const applyRegexReplacements = (content, replacements, context) => {
4
+ let result = content;
5
+ for (const rep of replacements) {
6
+ if (evaluateCondition(rep.condition, context)) {
7
+ const interpolated = interpolateVariables(rep.replacement, context);
8
+ result = result.replace(new RegExp(rep.pattern, "g"), interpolated);
9
+ }
10
+ }
11
+ return result;
12
+ };
@@ -0,0 +1 @@
1
+ export type { AssetProvider } from "../core/types.js";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { MetaJson, EvalContext } from "../core/types.js";
2
+ export type AssetEntry = {
3
+ /** Absolute path in the extracted repo */
4
+ sourcePath: string;
5
+ /** Relative path for deployment (e.g., ".claude/CLAUDE.md") */
6
+ relativePath: string;
7
+ /** MetaJson from the directory's _meta.json (or parent's) */
8
+ meta: MetaJson | null;
9
+ };
10
+ export declare const walkAssetRepo: (repoDir: string, targetSemver: string, context: EvalContext) => Promise<AssetEntry[]>;
@@ -0,0 +1,165 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join, relative, dirname } from "node:path";
3
+ import { evaluateCondition } from "../core/condition-evaluator.js";
4
+ const META_FILE = "_meta.json";
5
+ const readMetaJson = async (dir) => {
6
+ try {
7
+ const content = await readFile(join(dir, META_FILE), "utf-8");
8
+ const parsed = JSON.parse(content);
9
+ // Default type to "directory" for backward compatibility
10
+ if (!parsed.type) {
11
+ parsed.type = "directory";
12
+ }
13
+ return parsed;
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ };
19
+ /**
20
+ * Resolve rename rule: evaluate conditions and find the first matching rule.
21
+ * Returns the source file path and target name, or null if no rule matches.
22
+ */
23
+ const resolveRenameRule = (rules, context, dir) => {
24
+ if (!rules || rules.length === 0)
25
+ return null;
26
+ for (const rule of rules) {
27
+ if (evaluateCondition(rule.condition, context)) {
28
+ return {
29
+ sourcePath: join(dir, rule.from),
30
+ targetName: rule.to,
31
+ };
32
+ }
33
+ }
34
+ return null;
35
+ };
36
+ const findMatchingVersionDirs = async (repoDir, targetSemver) => {
37
+ const entries = await readdir(repoDir, { withFileTypes: true });
38
+ const matched = [];
39
+ for (const entry of entries) {
40
+ if (!entry.isDirectory())
41
+ continue;
42
+ const dirPath = join(repoDir, entry.name);
43
+ const meta = await readMetaJson(dirPath);
44
+ if (!meta) {
45
+ // No _meta.json — skip version directory without meta
46
+ continue;
47
+ }
48
+ if (meta.conditions) {
49
+ // Evaluate only the version condition at root level
50
+ const context = {
51
+ version: targetSemver,
52
+ modules: [],
53
+ locale: "",
54
+ agents: [],
55
+ name: "",
56
+ group: "",
57
+ description: "",
58
+ accelplatformVersion: "",
59
+ database: "",
60
+ projectVersion: "",
61
+ };
62
+ if (evaluateCondition(meta.conditions, context)) {
63
+ matched.push(dirPath);
64
+ }
65
+ }
66
+ }
67
+ return matched;
68
+ };
69
+ const walkDirectory = async (dir, baseDir, parentMeta, context) => {
70
+ const entries = [];
71
+ const dirEntries = await readdir(dir, { withFileTypes: true });
72
+ // Check if this directory has its own _meta.json
73
+ const ownMeta = await readMetaJson(dir);
74
+ const effectiveMeta = ownMeta ?? parentMeta;
75
+ // If this directory has conditions and they don't match, skip entirely
76
+ if (ownMeta?.conditions) {
77
+ if (!evaluateCondition(ownMeta.conditions, context)) {
78
+ return [];
79
+ }
80
+ }
81
+ // Handle type: "file" — no recursion into subdirectories
82
+ if (ownMeta?.type === "file") {
83
+ const parentRelative = relative(baseDir, dirname(dir));
84
+ if (ownMeta.rename && ownMeta.rename.length > 0) {
85
+ // With rename: select one source file via first-match-wins, deploy with `to` name
86
+ const resolved = resolveRenameRule(ownMeta.rename, context, dir);
87
+ if (!resolved)
88
+ return [];
89
+ const targetPath = parentRelative
90
+ ? join(parentRelative, resolved.targetName)
91
+ : resolved.targetName;
92
+ entries.push({
93
+ sourcePath: resolved.sourcePath,
94
+ relativePath: targetPath,
95
+ meta: effectiveMeta,
96
+ });
97
+ }
98
+ else {
99
+ // Without rename: deploy all files (except _meta.json) with original names
100
+ for (const entry of dirEntries) {
101
+ if (entry.name === META_FILE)
102
+ continue;
103
+ if (!entry.isFile())
104
+ continue;
105
+ const fullPath = join(dir, entry.name);
106
+ const targetPath = parentRelative
107
+ ? join(parentRelative, entry.name)
108
+ : entry.name;
109
+ entries.push({
110
+ sourcePath: fullPath,
111
+ relativePath: targetPath,
112
+ meta: effectiveMeta,
113
+ });
114
+ }
115
+ }
116
+ return entries;
117
+ }
118
+ // type: "directory" — walk recursively (existing behavior)
119
+ for (const entry of dirEntries) {
120
+ const fullPath = join(dir, entry.name);
121
+ if (entry.name === META_FILE) {
122
+ // Skip _meta.json itself
123
+ continue;
124
+ }
125
+ if (entry.isDirectory()) {
126
+ const children = await walkDirectory(fullPath, baseDir, effectiveMeta, context);
127
+ entries.push(...children);
128
+ }
129
+ else if (entry.isFile()) {
130
+ entries.push({
131
+ sourcePath: fullPath,
132
+ relativePath: relative(baseDir, fullPath),
133
+ meta: effectiveMeta,
134
+ });
135
+ }
136
+ }
137
+ return entries;
138
+ };
139
+ const deduplicateByPath = (entries) => {
140
+ const byPath = new Map();
141
+ for (const entry of entries) {
142
+ const existing = byPath.get(entry.relativePath);
143
+ if (!existing) {
144
+ byPath.set(entry.relativePath, entry);
145
+ continue;
146
+ }
147
+ // Same relative path collision: prefer entries from a type: "file" directory.
148
+ const existingIsFileType = existing.meta?.type === "file";
149
+ const currentIsFileType = entry.meta?.type === "file";
150
+ if (currentIsFileType && !existingIsFileType) {
151
+ byPath.set(entry.relativePath, entry);
152
+ }
153
+ }
154
+ return [...byPath.values()];
155
+ };
156
+ export const walkAssetRepo = async (repoDir, targetSemver, context) => {
157
+ const versionDirs = await findMatchingVersionDirs(repoDir, targetSemver);
158
+ const allEntries = [];
159
+ for (const versionDir of versionDirs) {
160
+ const meta = await readMetaJson(versionDir);
161
+ const entries = await walkDirectory(versionDir, versionDir, meta, context);
162
+ allEntries.push(...entries);
163
+ }
164
+ return deduplicateByPath(allEntries);
165
+ };
@@ -0,0 +1,64 @@
1
+ export declare const attachCommand: import("citty").CommandDef<{
2
+ "juggling-project": {
3
+ type: "string";
4
+ description: string;
5
+ };
6
+ "accelplatform-version": {
7
+ type: "string";
8
+ description: string;
9
+ };
10
+ module: {
11
+ type: "string";
12
+ description: string;
13
+ };
14
+ name: {
15
+ type: "string";
16
+ description: string;
17
+ };
18
+ group: {
19
+ type: "string";
20
+ description: string;
21
+ };
22
+ "project-version": {
23
+ type: "string";
24
+ description: string;
25
+ };
26
+ description: {
27
+ type: "string";
28
+ description: string;
29
+ };
30
+ database: {
31
+ type: "string";
32
+ description: string;
33
+ };
34
+ javascript: {
35
+ type: "boolean";
36
+ description: string;
37
+ };
38
+ agent: {
39
+ type: "string";
40
+ description: string;
41
+ };
42
+ locale: {
43
+ type: "string";
44
+ description: string;
45
+ };
46
+ "skip-install": {
47
+ type: "boolean";
48
+ description: string;
49
+ default: false;
50
+ };
51
+ "non-interactive": {
52
+ type: "boolean";
53
+ description: string;
54
+ default: false;
55
+ };
56
+ "asset-source": {
57
+ type: "string";
58
+ description: string;
59
+ };
60
+ "asset-server-url": {
61
+ type: "string";
62
+ description: string;
63
+ };
64
+ }>;
@@ -0,0 +1,163 @@
1
+ import { defineCommand } from "citty";
2
+ import * as p from "@clack/prompts";
3
+ import { stat } from "node:fs/promises";
4
+ import { basename, join } from "node:path";
5
+ import { CLI_VERSION } from "../core/constants.js";
6
+ import { runPrompts } from "../interactive/prompts.js";
7
+ import { deployAssets } from "../asset/deployer.js";
8
+ import { createLocalAssetProvider } from "../asset/local-provider.js";
9
+ import { createFileAssetProvider } from "../asset/file-provider.js";
10
+ import { defaultAssetSourcePath } from "../asset/default-source.js";
11
+ import { getMessage } from "../i18n/index.js";
12
+ import { detectLocale } from "../utils/locale-detect.js";
13
+ export const attachCommand = defineCommand({
14
+ meta: {
15
+ name: "attach",
16
+ description: "Attach Accel CLI to an existing project",
17
+ },
18
+ args: {
19
+ "juggling-project": {
20
+ type: "string",
21
+ description: "Path to IM-Juggling project",
22
+ },
23
+ "accelplatform-version": {
24
+ type: "string",
25
+ description: "iAP version (e.g., 2026-Spring)",
26
+ },
27
+ module: {
28
+ type: "string",
29
+ description: "Modules to use (comma-separated)",
30
+ },
31
+ name: {
32
+ type: "string",
33
+ description: "Project name",
34
+ },
35
+ group: {
36
+ type: "string",
37
+ description: "Group name",
38
+ },
39
+ "project-version": {
40
+ type: "string",
41
+ description: "Project version",
42
+ },
43
+ description: {
44
+ type: "string",
45
+ description: "Project description",
46
+ },
47
+ database: {
48
+ type: "string",
49
+ description: "Database type",
50
+ },
51
+ javascript: {
52
+ type: "boolean",
53
+ description: "Use JavaScript",
54
+ },
55
+ agent: {
56
+ type: "string",
57
+ description: "Agent type",
58
+ },
59
+ locale: {
60
+ type: "string",
61
+ description: "Locale (ja, en, zh_CN)",
62
+ },
63
+ "skip-install": {
64
+ type: "boolean",
65
+ description: "Skip dependency installation",
66
+ default: false,
67
+ },
68
+ "non-interactive": {
69
+ type: "boolean",
70
+ description: "Non-interactive mode",
71
+ default: false,
72
+ },
73
+ "asset-source": {
74
+ type: "string",
75
+ description: "Local asset source path (tar archive or extracted directory). Defaults to the bundled assets/assets.tar.gz.",
76
+ },
77
+ "asset-server-url": {
78
+ type: "string",
79
+ description: "Asset server URL (takes precedence over --asset-source when explicitly set)",
80
+ },
81
+ },
82
+ run: async ({ args }) => {
83
+ const locale = args.locale ?? detectLocale();
84
+ const projectDir = process.cwd();
85
+ // Check .accel doesn't exist
86
+ try {
87
+ await stat(join(projectDir, ".accel"));
88
+ p.log.error(getMessage("error.accelExists", locale));
89
+ process.exit(1);
90
+ }
91
+ catch {
92
+ // .accel doesn't exist — good
93
+ }
94
+ const moduleArg = args.module;
95
+ const modules = moduleArg
96
+ ? moduleArg.split(",").map((m) => m.trim())
97
+ : undefined;
98
+ const agentArg = args.agent;
99
+ const promptOpts = {
100
+ name: args.name ?? basename(projectDir),
101
+ jugglingProject: args["juggling-project"],
102
+ accelplatformVersion: args["accelplatform-version"],
103
+ module: modules,
104
+ group: args.group,
105
+ projectVersion: args["project-version"],
106
+ description: args.description,
107
+ database: args.database,
108
+ javascript: args.javascript,
109
+ agent: agentArg
110
+ ? agentArg.split(",").map((a) => a.trim())
111
+ : undefined,
112
+ locale,
113
+ noInteraction: args["non-interactive"],
114
+ isInit: false,
115
+ };
116
+ let resolved;
117
+ try {
118
+ resolved = await runPrompts(promptOpts);
119
+ }
120
+ catch (err) {
121
+ p.log.error(err instanceof Error ? err.message : String(err));
122
+ process.exit(1);
123
+ }
124
+ const settings = {
125
+ cliVersion: CLI_VERSION,
126
+ createdAt: new Date().toISOString(),
127
+ name: resolved.name,
128
+ group: resolved.group,
129
+ projectVersion: resolved.projectVersion,
130
+ description: resolved.description,
131
+ accelplatformVersion: resolved.accelplatformVersion,
132
+ modules: resolved.modules,
133
+ database: resolved.database,
134
+ agents: resolved.agents,
135
+ javascript: resolved.javascript,
136
+ locale: resolved.locale,
137
+ jugglingProject: resolved.jugglingProject,
138
+ deployedAssets: {},
139
+ };
140
+ const serverUrl = args["asset-server-url"];
141
+ const assetSource = args["asset-source"] ?? defaultAssetSourcePath();
142
+ const provider = serverUrl
143
+ ? createLocalAssetProvider(serverUrl)
144
+ : createFileAssetProvider(assetSource);
145
+ p.log.info(getMessage("progress.deploying", locale));
146
+ const result = await deployAssets({
147
+ projectDir,
148
+ settings,
149
+ provider,
150
+ noInstall: args["skip-install"],
151
+ skipExistingFiles: true,
152
+ });
153
+ for (const path of result.skippedFiles) {
154
+ p.log.warn(getMessage("warning.fileExists", locale, { path }));
155
+ }
156
+ if (result.skippedFiles.length > 0) {
157
+ p.log.info(getMessage("attach.skipSummary", locale, {
158
+ count: String(result.skippedFiles.length),
159
+ }));
160
+ }
161
+ p.log.success(getMessage("progress.complete", locale));
162
+ },
163
+ });
@@ -0,0 +1 @@
1
+ export declare const detachCommand: import("citty").CommandDef<{}>;