claude-init 1.0.31 → 1.0.33
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/package.json +1 -1
- package/src/cli.js +53 -5
- package/src/prompt.js +59 -0
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
handleSelectiveFileCopy,
|
|
9
9
|
handleSingleFile
|
|
10
10
|
} from './fileManager.js';
|
|
11
|
-
import { promptYesNo } from './prompt.js';
|
|
11
|
+
import { promptYesNo, promptChoice } from './prompt.js';
|
|
12
12
|
import { getTemplatesPath, getFilesInDirectory } from './utils.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -89,15 +89,30 @@ export async function cli() {
|
|
|
89
89
|
false
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
+
// Determine which devcontainer configuration to install
|
|
93
|
+
const devcontainerVariant = await promptChoice(
|
|
94
|
+
'Which devcontainer configuration to install?',
|
|
95
|
+
[
|
|
96
|
+
{ value: 'js', label: 'JavaScript/TypeScript' },
|
|
97
|
+
{ value: 'go', label: 'Go' },
|
|
98
|
+
{ value: 'rust', label: 'Rust' },
|
|
99
|
+
{ value: 'none', label: 'Skip devcontainer installation' }
|
|
100
|
+
],
|
|
101
|
+
'js'
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Map devcontainer variant to source directory name in templates
|
|
105
|
+
const devcontainerSourceMap = {
|
|
106
|
+
'js': '.devcontainer',
|
|
107
|
+
'go': '.devcontainer-go',
|
|
108
|
+
'rust': '.devcontainer-rust'
|
|
109
|
+
};
|
|
110
|
+
|
|
92
111
|
const tasks = [
|
|
93
112
|
{
|
|
94
113
|
name: 'CLAUDE.md',
|
|
95
114
|
handler: () => handleClaudeMarkdown(targetDir)
|
|
96
115
|
},
|
|
97
|
-
{
|
|
98
|
-
name: '.devcontainer',
|
|
99
|
-
handler: () => handleDirectoryMirror(targetDir, '.devcontainer')
|
|
100
|
-
},
|
|
101
116
|
{
|
|
102
117
|
name: '.claude/settings.json',
|
|
103
118
|
handler: () => handleSingleFile(targetDir, '.claude/settings.json', { overwrite: overwriteSettings })
|
|
@@ -111,6 +126,35 @@ export async function cli() {
|
|
|
111
126
|
}
|
|
112
127
|
];
|
|
113
128
|
|
|
129
|
+
// Conditionally add devcontainer task
|
|
130
|
+
if (devcontainerVariant !== 'none') {
|
|
131
|
+
const sourceDir = devcontainerSourceMap[devcontainerVariant];
|
|
132
|
+
tasks.splice(1, 0, {
|
|
133
|
+
name: '.devcontainer',
|
|
134
|
+
handler: async () => {
|
|
135
|
+
const targetPath = path.join(targetDir, '.devcontainer');
|
|
136
|
+
const templatePath = path.join(getTemplatesPath(), sourceDir);
|
|
137
|
+
|
|
138
|
+
const exists = await fs.pathExists(targetPath);
|
|
139
|
+
|
|
140
|
+
// Remove existing .devcontainer if it exists
|
|
141
|
+
if (exists) {
|
|
142
|
+
await fs.remove(targetPath);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Copy from selected source to .devcontainer
|
|
146
|
+
await fs.copy(templatePath, targetPath);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
action: exists ? 'updated' : 'created',
|
|
150
|
+
details: exists
|
|
151
|
+
? `Overwrote .devcontainer with ${devcontainerVariant} configuration`
|
|
152
|
+
: `Created .devcontainer with ${devcontainerVariant} configuration`
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
114
158
|
// Conditionally add .claude/agents task
|
|
115
159
|
if (includeAgents) {
|
|
116
160
|
tasks.push({
|
|
@@ -160,6 +204,10 @@ export async function cli() {
|
|
|
160
204
|
console.log(chalk.cyan(` Files added: ${totalActions.filesAdded}`));
|
|
161
205
|
}
|
|
162
206
|
|
|
207
|
+
if (devcontainerVariant === 'none') {
|
|
208
|
+
console.log(chalk.gray(` - devcontainer skipped by user`));
|
|
209
|
+
}
|
|
210
|
+
|
|
163
211
|
if (!includeAgents) {
|
|
164
212
|
console.log(chalk.gray(` - .claude/agents skipped by user`));
|
|
165
213
|
}
|
package/src/prompt.js
CHANGED
|
@@ -42,3 +42,62 @@ export async function promptYesNo(question, defaultAnswer) {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Prompts the user to select from multiple choices.
|
|
48
|
+
* @param {string} question - The question to ask
|
|
49
|
+
* @param {Array<{value: string, label: string}>} choices - Array of choices with value and label
|
|
50
|
+
* @param {string} defaultValue - The default value if user presses Enter or if non-TTY
|
|
51
|
+
* @returns {Promise<string>} - The selected value
|
|
52
|
+
*/
|
|
53
|
+
export async function promptChoice(question, choices, defaultValue) {
|
|
54
|
+
// If not TTY, return default immediately
|
|
55
|
+
if (!process.stdin.isTTY) {
|
|
56
|
+
return defaultValue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const rl = readline.createInterface({
|
|
60
|
+
input: process.stdin,
|
|
61
|
+
output: process.stdout
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
// Build the prompt with choices
|
|
66
|
+
const choicesText = choices.map((choice, index) =>
|
|
67
|
+
`${index + 1}. ${choice.label}${choice.value === defaultValue ? ' (default)' : ''}`
|
|
68
|
+
).join('\n ');
|
|
69
|
+
|
|
70
|
+
const promptText = `${question}\n ${choicesText}\nSelect (1-${choices.length}): `;
|
|
71
|
+
|
|
72
|
+
rl.question(promptText, (answer) => {
|
|
73
|
+
rl.close();
|
|
74
|
+
|
|
75
|
+
const normalized = answer.trim();
|
|
76
|
+
|
|
77
|
+
// Empty answer uses default
|
|
78
|
+
if (normalized === '') {
|
|
79
|
+
resolve(defaultValue);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Try to parse as number
|
|
84
|
+
const choiceIndex = parseInt(normalized, 10) - 1;
|
|
85
|
+
|
|
86
|
+
// Check if valid number choice
|
|
87
|
+
if (!isNaN(choiceIndex) && choiceIndex >= 0 && choiceIndex < choices.length) {
|
|
88
|
+
resolve(choices[choiceIndex].value);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Try to match by value directly
|
|
93
|
+
const matchedChoice = choices.find(c => c.value.toLowerCase() === normalized.toLowerCase());
|
|
94
|
+
if (matchedChoice) {
|
|
95
|
+
resolve(matchedChoice.value);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Invalid input, use default
|
|
100
|
+
resolve(defaultValue);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|