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 +6 -4
- package/lib/copy.js +7 -5
- package/package.json +1 -1
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: '
|
|
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: ${
|
|
63
|
+
message: `File exists: ${displayPath}`,
|
|
62
64
|
choices: [
|
|
63
65
|
{ title: 'Keep existing', value: 'keep' },
|
|
64
66
|
{ title: 'Overwrite with template', value: 'overwrite' },
|