create-claude-rails 0.3.1 → 0.3.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/lib/cli.js CHANGED
@@ -186,11 +186,12 @@ async function run() {
186
186
  if (dirState === 'existing-install') {
187
187
  const existing = readMetadata(projectDir);
188
188
  console.log(` Found existing installation (v${existing.version}, installed ${existing.installedAt.split('T')[0]})`);
189
+ console.log(' Will add new files only. Use /cor-upgrade in Claude Code to update existing files.');
189
190
  if (!flags.yes && !flags.lean) {
190
191
  const { proceed } = await prompts({
191
192
  type: 'confirm',
192
193
  name: 'proceed',
193
- message: 'Update existing installation?',
194
+ message: 'Add new files from latest version?',
194
195
  initial: true,
195
196
  });
196
197
  if (!proceed) {
@@ -397,8 +398,9 @@ async function run() {
397
398
  const isSkill = tmpl.startsWith('skills/') && !alwaysCopyPhases.some(p => tmpl.startsWith(p));
398
399
  const results = await copyTemplates(srcPath, destPath, {
399
400
  dryRun: flags.dryRun,
400
- skipConflicts: flags.yes,
401
+ skipConflicts: flags.yes || dirState === 'existing-install',
401
402
  skipPhases: isSkill,
403
+ projectRoot: projectDir,
402
404
  });
403
405
  totalCopied += results.copied.length;
404
406
  totalSkipped += results.skipped.length;
@@ -426,8 +428,8 @@ async function run() {
426
428
  continue;
427
429
  }
428
430
 
429
- if (flags.yes) {
430
- // --yes: keep existing files (safe default)
431
+ if (flags.yes || dirState === 'existing-install') {
432
+ // --yes or existing install: keep existing files (safe default)
431
433
  totalSkipped++;
432
434
  allManifest[mPath] = incomingHash;
433
435
  } else {
package/lib/copy.js CHANGED
@@ -11,19 +11,21 @@ function hashContent(content) {
11
11
  * Recursively copy files from src to dest, surfacing conflicts.
12
12
  * Returns { copied: string[], skipped: string[], overwritten: string[] }
13
13
  */
14
- async function copyTemplates(src, dest, { dryRun = false, skipConflicts = false, skipPhases = false } = {}) {
14
+ async function copyTemplates(src, dest, { dryRun = false, skipConflicts = false, skipPhases = false, projectRoot = null } = {}) {
15
15
  const results = { copied: [], skipped: [], overwritten: [], manifest: {} };
16
- await walkAndCopy(src, dest, src, results, dryRun, skipConflicts, skipPhases);
16
+ await walkAndCopy(src, dest, src, results, dryRun, skipConflicts, skipPhases, projectRoot);
17
17
  return results;
18
18
  }
19
19
 
20
- async function walkAndCopy(srcRoot, destRoot, currentSrc, results, dryRun, skipConflicts, skipPhases) {
20
+ async function walkAndCopy(srcRoot, destRoot, currentSrc, results, dryRun, skipConflicts, skipPhases, projectRoot) {
21
21
  const entries = fs.readdirSync(currentSrc, { withFileTypes: true });
22
22
 
23
23
  for (const entry of entries) {
24
24
  const srcPath = path.join(currentSrc, entry.name);
25
25
  const relPath = path.relative(srcRoot, srcPath);
26
26
  const destPath = path.join(destRoot, relPath);
27
+ // Display path relative to project root for clearer conflict prompts
28
+ const displayPath = projectRoot ? path.relative(projectRoot, destPath) : relPath;
27
29
 
28
30
  if (entry.isDirectory()) {
29
31
  // Skip phases/ directories — absent phase files use skeleton defaults,
@@ -35,7 +37,7 @@ async function walkAndCopy(srcRoot, destRoot, currentSrc, results, dryRun, skipC
35
37
  if (!dryRun && !fs.existsSync(destPath)) {
36
38
  fs.mkdirSync(destPath, { recursive: true });
37
39
  }
38
- await walkAndCopy(srcRoot, destRoot, srcPath, results, dryRun, skipConflicts, skipPhases);
40
+ await walkAndCopy(srcRoot, destRoot, srcPath, results, dryRun, skipConflicts, skipPhases, projectRoot);
39
41
  } else {
40
42
  const incoming = fs.readFileSync(srcPath, 'utf8');
41
43
  const incomingHash = hashContent(incoming);
@@ -58,7 +60,7 @@ async function walkAndCopy(srcRoot, destRoot, currentSrc, results, dryRun, skipC
58
60
  const response = await prompts({
59
61
  type: 'select',
60
62
  name: 'action',
61
- message: `File exists: ${relPath}`,
63
+ message: `File exists: ${displayPath}`,
62
64
  choices: [
63
65
  { title: 'Keep existing', value: 'keep' },
64
66
  { title: 'Overwrite with template', value: 'overwrite' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-rails",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Claude on Rails — opinionated process scaffolding for Claude Code projects",
5
5
  "bin": {
6
6
  "create-claude-rails": "bin/create-claude-rails.js"