camelmind 0.2.2 → 0.2.3

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/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import { fileURLToPath as fileURLToPath2 } from "url";
6
- import path2 from "path";
7
- import fs2 from "fs";
5
+ import { fileURLToPath as fileURLToPath3 } from "url";
6
+ import path3 from "path";
7
+ import fs3 from "fs";
8
8
 
9
9
  // src/commands/init.ts
10
10
  import path from "path";
@@ -135,11 +135,188 @@ async function init(projectName, options) {
135
135
  `);
136
136
  }
137
137
 
138
- // src/commands/version.ts
138
+ // src/commands/update.ts
139
+ import path2 from "path";
140
+ import { fileURLToPath as fileURLToPath2 } from "url";
141
+ import { execSync as execSync2 } from "child_process";
142
+ import fs2 from "fs-extra";
139
143
  import chalk2 from "chalk";
140
144
  import ora2 from "ora";
145
+ import prompts2 from "prompts";
146
+ var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
147
+ var TEMPLATE_DIR2 = path2.join(__dirname2, "../template");
148
+ var FRAMEWORK_DIRS = ["app", "components", "lib", "public", "scripts"];
149
+ var FRAMEWORK_FILES = [
150
+ "next.config.ts",
151
+ "postcss.config.mjs",
152
+ "tsconfig.json",
153
+ "eslint.config.mjs",
154
+ "proxy.ts"
155
+ ];
156
+ async function walkFiles(dir) {
157
+ if (!await fs2.pathExists(dir)) return [];
158
+ const entries = await fs2.readdir(dir, { withFileTypes: true });
159
+ const files = [];
160
+ for (const entry of entries) {
161
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === ".git") {
162
+ continue;
163
+ }
164
+ const fullPath = path2.join(dir, entry.name);
165
+ if (entry.isDirectory()) {
166
+ files.push(...await walkFiles(fullPath));
167
+ } else if (entry.isFile()) {
168
+ files.push(fullPath);
169
+ }
170
+ }
171
+ return files;
172
+ }
173
+ function mergePackageJson(current, template) {
174
+ return {
175
+ ...current,
176
+ scripts: {
177
+ ...template.scripts,
178
+ ...current.scripts
179
+ },
180
+ dependencies: {
181
+ ...current.dependencies,
182
+ ...template.dependencies
183
+ },
184
+ devDependencies: {
185
+ ...current.devDependencies,
186
+ ...template.devDependencies
187
+ },
188
+ overrides: {
189
+ ...current.overrides,
190
+ ...template.overrides
191
+ }
192
+ };
193
+ }
194
+ async function copyWithBackup(source, target, backupRoot, projectRoot) {
195
+ if (await fs2.pathExists(target)) {
196
+ await backupFile(target, backupRoot, projectRoot);
197
+ }
198
+ await fs2.ensureDir(path2.dirname(target));
199
+ await fs2.copy(source, target, { overwrite: true });
200
+ }
201
+ async function backupFile(file, backupRoot, projectRoot) {
202
+ const rel = path2.relative(projectRoot, file);
203
+ await fs2.ensureDir(path2.dirname(path2.join(backupRoot, rel)));
204
+ await fs2.copy(file, path2.join(backupRoot, rel), { overwrite: true });
205
+ }
206
+ async function updatePackageJson(projectRoot, backupRoot, dryRun) {
207
+ const projectPkgPath = path2.join(projectRoot, "package.json");
208
+ const templatePkgPath = path2.join(TEMPLATE_DIR2, "_package.json");
209
+ const current = await fs2.readJson(projectPkgPath);
210
+ const template = await fs2.readJson(templatePkgPath);
211
+ const merged = mergePackageJson(current, template);
212
+ if (dryRun) return;
213
+ await backupFile(projectPkgPath, backupRoot, projectRoot);
214
+ await fs2.writeJson(projectPkgPath, merged, { spaces: 2 });
215
+ await fs2.appendFile(projectPkgPath, "\n");
216
+ }
217
+ async function plannedTemplateFiles() {
218
+ const files = [];
219
+ for (const dir of FRAMEWORK_DIRS) {
220
+ const dirPath = path2.join(TEMPLATE_DIR2, dir);
221
+ const dirFiles = await walkFiles(dirPath);
222
+ files.push(...dirFiles.map((file) => path2.relative(TEMPLATE_DIR2, file)));
223
+ }
224
+ files.push(...FRAMEWORK_FILES);
225
+ return files.sort();
226
+ }
227
+ async function update(targetDir, options) {
228
+ const projectRoot = path2.resolve(process.cwd(), targetDir ?? ".");
229
+ const packageJsonPath = path2.join(projectRoot, "package.json");
230
+ const configPath = path2.join(projectRoot, "camelmind.config.ts");
231
+ if (!await fs2.pathExists(TEMPLATE_DIR2)) {
232
+ console.error(chalk2.red("Template directory not found in the installed CamelMind package."));
233
+ process.exit(1);
234
+ }
235
+ if (!await fs2.pathExists(packageJsonPath) || !await fs2.pathExists(configPath)) {
236
+ console.error(chalk2.red("Run this command from a CamelMind project root, or pass the project directory."));
237
+ process.exit(1);
238
+ }
239
+ const files = await plannedTemplateFiles();
240
+ const backupRoot = path2.join(
241
+ projectRoot,
242
+ ".camelmind-update-backup",
243
+ (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")
244
+ );
245
+ console.log(`
246
+ ${chalk2.hex("#D8A15B").bold("CamelMind update")}
247
+
248
+ Project: ${chalk2.cyan(projectRoot)}
249
+ Files: ${chalk2.cyan(String(files.length))} framework files + package.json
250
+ Backup: ${chalk2.cyan(path2.relative(projectRoot, backupRoot))}
251
+ `);
252
+ if (options.dryRun) {
253
+ console.log(chalk2.bold(" Dry run \u2014 files that would be refreshed:\n"));
254
+ for (const file of files) console.log(` ${file}`);
255
+ console.log(" package.json");
256
+ console.log("");
257
+ return;
258
+ }
259
+ if (!options.yes) {
260
+ const { proceed } = await prompts2(
261
+ {
262
+ type: "confirm",
263
+ name: "proceed",
264
+ message: "Refresh CamelMind framework files and merge package updates?",
265
+ initial: true
266
+ },
267
+ { onCancel: () => process.exit(0) }
268
+ );
269
+ if (!proceed) {
270
+ console.log(chalk2.gray("\n Update cancelled.\n"));
271
+ return;
272
+ }
273
+ }
274
+ const spinner = ora2("Refreshing CamelMind framework files...").start();
275
+ try {
276
+ for (const rel of files) {
277
+ await copyWithBackup(
278
+ path2.join(TEMPLATE_DIR2, rel),
279
+ path2.join(projectRoot, rel),
280
+ backupRoot,
281
+ projectRoot
282
+ );
283
+ }
284
+ await updatePackageJson(projectRoot, backupRoot, false);
285
+ spinner.succeed("CamelMind files refreshed");
286
+ } catch (err) {
287
+ spinner.fail("Update failed");
288
+ console.error(chalk2.red(`
289
+ ${String(err)}
290
+ `));
291
+ process.exit(1);
292
+ }
293
+ if (options.install) {
294
+ const installSpinner = ora2("Installing updated dependencies...").start();
295
+ try {
296
+ execSync2("npm install", {
297
+ cwd: projectRoot,
298
+ stdio: "ignore"
299
+ });
300
+ installSpinner.succeed("Dependencies installed");
301
+ } catch {
302
+ installSpinner.warn("Dependency install failed \u2014 run npm install inside your project");
303
+ }
304
+ }
305
+ console.log(`
306
+ ${chalk2.green("Done.")} Review the changes, then run:
307
+
308
+ ${chalk2.cyan("npm run lint")}
309
+ ${chalk2.cyan("npm run build")}
310
+
311
+ Backup saved in ${chalk2.cyan(path2.relative(projectRoot, backupRoot))}
312
+ `);
313
+ }
314
+
315
+ // src/commands/version.ts
316
+ import chalk3 from "chalk";
317
+ import ora3 from "ora";
141
318
  async function checkVersion(currentVersion) {
142
- const spinner = ora2("Checking latest version...").start();
319
+ const spinner = ora3("Checking latest version...").start();
143
320
  let latestVersion;
144
321
  try {
145
322
  const res = await fetch("https://registry.npmjs.org/camelmind/latest");
@@ -150,7 +327,7 @@ async function checkVersion(currentVersion) {
150
327
  } catch {
151
328
  spinner.fail("Could not reach the npm registry");
152
329
  console.log(`
153
- Installed: ${chalk2.cyan(currentVersion)}
330
+ Installed: ${chalk3.cyan(currentVersion)}
154
331
  `);
155
332
  return;
156
333
  }
@@ -158,28 +335,29 @@ async function checkVersion(currentVersion) {
158
335
  const [latMajor, latMinor, latPatch] = latestVersion.split(".").map(Number);
159
336
  const isOutdated = latMajor > curMajor || latMajor === curMajor && latMinor > curMinor || latMajor === curMajor && latMinor === curMinor && latPatch > curPatch;
160
337
  console.log(`
161
- Installed ${chalk2.cyan(currentVersion)}
162
- Latest ${isOutdated ? chalk2.yellow(latestVersion) : chalk2.green(latestVersion)}
338
+ Installed ${chalk3.cyan(currentVersion)}
339
+ Latest ${isOutdated ? chalk3.yellow(latestVersion) : chalk3.green(latestVersion)}
163
340
  `);
164
341
  if (isOutdated) {
165
342
  console.log(
166
- ` ${chalk2.yellow("\u26A0")} A new version is available. Run:
343
+ ` ${chalk3.yellow("\u26A0")} A new version is available. To update an existing site, run:
167
344
 
168
- ${chalk2.cyan("npm install -g camelmind@latest")}
345
+ ${chalk3.cyan("npx camelmind@latest update")}
169
346
  `
170
347
  );
171
348
  } else {
172
- console.log(` ${chalk2.green("\u2713")} You're up to date.
349
+ console.log(` ${chalk3.green("\u2713")} You're up to date.
173
350
  `);
174
351
  }
175
352
  }
176
353
 
177
354
  // src/index.ts
178
- var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
179
- var pkgPath = path2.join(__dirname2, "../package.json");
180
- var pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
355
+ var __dirname3 = path3.dirname(fileURLToPath3(import.meta.url));
356
+ var pkgPath = path3.join(__dirname3, "../package.json");
357
+ var pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
181
358
  var program = new Command();
182
359
  program.name("camelmind").description("CamelMind CLI \u2014 scaffold and manage documentation sites").version(pkg.version);
183
360
  program.command("init [project-name]").description("Create a new CamelMind documentation site").option("--no-install", "Skip installing npm dependencies").action(init);
184
361
  program.command("version").description("Show installed version and check for updates").action(() => checkVersion(pkg.version));
362
+ program.command("update [project-dir]").description("Update an existing CamelMind site to the latest platform files").option("--no-install", "Skip installing npm dependencies").option("--dry-run", "Show what would change without writing files").option("-y, --yes", "Skip the confirmation prompt").action(update);
185
363
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camelmind",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Create and manage CamelMind documentation sites",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,6 +25,10 @@
25
25
  "rehype-slug": "^6.0.0",
26
26
  "remark-gfm": "^4.0.1"
27
27
  },
28
+ "overrides": {
29
+ "js-yaml": "^4.2.0",
30
+ "postcss": "^8.5.10"
31
+ },
28
32
  "devDependencies": {
29
33
  "@tailwindcss/postcss": "^4",
30
34
  "@types/js-yaml": "^4.0.9",