@kood/claude-code 0.5.9 → 0.6.0
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 +127 -135
- package/package.json +1 -1
- package/templates/.claude/agents/build-fixer.md +371 -0
- package/templates/.claude/agents/critic.md +223 -0
- package/templates/.claude/agents/deep-executor.md +320 -0
- package/templates/.claude/agents/dependency-manager.md +0 -1
- package/templates/.claude/agents/deployment-validator.md +0 -1
- package/templates/.claude/agents/designer.md +0 -1
- package/templates/.claude/agents/document-writer.md +0 -1
- package/templates/.claude/agents/git-operator.md +15 -0
- package/templates/.claude/agents/implementation-executor.md +0 -1
- package/templates/.claude/agents/ko-to-en-translator.md +0 -1
- package/templates/.claude/agents/lint-fixer.md +0 -1
- package/templates/.claude/agents/planner.md +11 -7
- package/templates/.claude/agents/qa-tester.md +488 -0
- package/templates/.claude/agents/researcher.md +189 -0
- package/templates/.claude/agents/scientist.md +544 -0
- package/templates/.claude/agents/security-reviewer.md +549 -0
- package/templates/.claude/agents/tdd-guide.md +413 -0
- package/templates/.claude/agents/vision.md +165 -0
- package/templates/.claude/commands/pre-deploy.md +79 -2
- package/templates/.claude/instructions/agent-patterns/model-routing.md +2 -2
- package/templates/.claude/skills/brainstorm/SKILL.md +889 -0
- package/templates/.claude/skills/bug-fix/SKILL.md +69 -0
- package/templates/.claude/skills/crawler/SKILL.md +156 -0
- package/templates/.claude/skills/crawler/references/anti-bot-checklist.md +162 -0
- package/templates/.claude/skills/crawler/references/code-templates.md +119 -0
- package/templates/.claude/skills/crawler/references/crawling-patterns.md +167 -0
- package/templates/.claude/skills/crawler/references/document-templates.md +147 -0
- package/templates/.claude/skills/crawler/references/network-crawling.md +141 -0
- package/templates/.claude/skills/crawler/references/playwriter-commands.md +172 -0
- package/templates/.claude/skills/crawler/references/pre-crawl-checklist.md +221 -0
- package/templates/.claude/skills/crawler/references/selector-strategies.md +140 -0
- package/templates/.claude/skills/execute/SKILL.md +5 -0
- package/templates/.claude/skills/feedback/SKILL.md +570 -0
- package/templates/.claude/skills/figma-to-code/SKILL.md +1 -0
- package/templates/.claude/skills/global-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/korea-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +1 -0
- package/templates/.claude/skills/plan/SKILL.md +44 -0
- package/templates/.claude/skills/ralph/SKILL.md +16 -18
- package/templates/.claude/skills/refactor/SKILL.md +19 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +1 -0
- package/templates/.claude/skills/stitch-design/README.md +0 -34
- package/templates/.claude/skills/stitch-design/SKILL.md +0 -213
- package/templates/.claude/skills/stitch-design/examples/DESIGN.md +0 -154
- package/templates/.claude/skills/stitch-loop/README.md +0 -54
- package/templates/.claude/skills/stitch-loop/SKILL.md +0 -316
- package/templates/.claude/skills/stitch-loop/examples/SITE.md +0 -73
- package/templates/.claude/skills/stitch-loop/examples/next-prompt.md +0 -25
- package/templates/.claude/skills/stitch-loop/resources/baton-schema.md +0 -61
- package/templates/.claude/skills/stitch-loop/resources/site-template.md +0 -104
- package/templates/.claude/skills/stitch-react/README.md +0 -36
- package/templates/.claude/skills/stitch-react/SKILL.md +0 -323
- package/templates/.claude/skills/stitch-react/examples/gold-standard-card.tsx +0 -88
- package/templates/.claude/skills/stitch-react/package-lock.json +0 -231
- package/templates/.claude/skills/stitch-react/package.json +0 -16
- package/templates/.claude/skills/stitch-react/resources/architecture-checklist.md +0 -15
- package/templates/.claude/skills/stitch-react/resources/component-template.tsx +0 -37
- package/templates/.claude/skills/stitch-react/resources/stitch-api-reference.md +0 -14
- package/templates/.claude/skills/stitch-react/resources/style-guide.json +0 -24
- package/templates/.claude/skills/stitch-react/scripts/fetch-stitch.sh +0 -30
- package/templates/.claude/skills/stitch-react/scripts/validate.js +0 -77
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var banner = () => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
// src/commands/init.ts
|
|
25
|
-
import
|
|
25
|
+
import fs8 from "fs-extra";
|
|
26
26
|
|
|
27
27
|
// src/features/templates/template-path-resolver.ts
|
|
28
28
|
import path2 from "path";
|
|
@@ -232,37 +232,85 @@ var checkExistingFiles = async (targetDir) => {
|
|
|
232
232
|
};
|
|
233
233
|
|
|
234
234
|
// src/features/extras/extras-copier.ts
|
|
235
|
-
import
|
|
236
|
-
import
|
|
235
|
+
import fs5 from "fs-extra";
|
|
236
|
+
import path7 from "path";
|
|
237
237
|
|
|
238
238
|
// src/shared/constants.ts
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
239
|
+
var NON_UI_TEMPLATES = ["hono", "npx"];
|
|
240
|
+
|
|
241
|
+
// src/features/extras/skill-metadata.ts
|
|
242
|
+
import fs4 from "fs-extra";
|
|
243
|
+
import path6 from "path";
|
|
244
|
+
var parseSkillMetadata = async (skillPath) => {
|
|
245
|
+
const skillMdPath = path6.join(skillPath, "SKILL.md");
|
|
246
|
+
if (!await fs4.pathExists(skillMdPath)) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
const content = await fs4.readFile(skillMdPath, "utf-8");
|
|
250
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
251
|
+
if (!frontmatterMatch) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
const frontmatter = frontmatterMatch[1];
|
|
255
|
+
const metadata = {
|
|
256
|
+
name: "",
|
|
257
|
+
description: ""
|
|
258
|
+
};
|
|
259
|
+
const lines = frontmatter.split("\n");
|
|
260
|
+
for (const line of lines) {
|
|
261
|
+
const colonIndex = line.indexOf(":");
|
|
262
|
+
if (colonIndex === -1) continue;
|
|
263
|
+
const key = line.slice(0, colonIndex).trim();
|
|
264
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
265
|
+
switch (key) {
|
|
266
|
+
case "name":
|
|
267
|
+
metadata.name = value;
|
|
268
|
+
break;
|
|
269
|
+
case "description":
|
|
270
|
+
metadata.description = value;
|
|
271
|
+
break;
|
|
272
|
+
case "user-invocable":
|
|
273
|
+
metadata.userInvocable = value === "true";
|
|
274
|
+
break;
|
|
275
|
+
case "ui-only":
|
|
276
|
+
metadata.uiOnly = value === "true";
|
|
277
|
+
break;
|
|
278
|
+
case "framework":
|
|
279
|
+
metadata.framework = value;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return metadata;
|
|
284
|
+
};
|
|
285
|
+
var loadAllSkillMetadata = async (skillsSrc) => {
|
|
286
|
+
const metadataMap = /* @__PURE__ */ new Map();
|
|
287
|
+
if (!await fs4.pathExists(skillsSrc)) {
|
|
288
|
+
return metadataMap;
|
|
289
|
+
}
|
|
290
|
+
const entries = await fs4.readdir(skillsSrc, { withFileTypes: true });
|
|
291
|
+
for (const entry of entries) {
|
|
292
|
+
if (entry.isDirectory()) {
|
|
293
|
+
const skillPath = path6.join(skillsSrc, entry.name);
|
|
294
|
+
const metadata = await parseSkillMetadata(skillPath);
|
|
295
|
+
if (metadata) {
|
|
296
|
+
if (!metadata.name) {
|
|
297
|
+
metadata.name = entry.name;
|
|
298
|
+
}
|
|
299
|
+
metadataMap.set(entry.name, metadata);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return metadataMap;
|
|
247
304
|
};
|
|
248
|
-
var COMMON_SKILLS = [
|
|
249
|
-
"global-uiux-design",
|
|
250
|
-
"docs-creator",
|
|
251
|
-
"docs-refactor",
|
|
252
|
-
"plan",
|
|
253
|
-
"prd",
|
|
254
|
-
"ralph",
|
|
255
|
-
"execute"
|
|
256
|
-
];
|
|
257
305
|
|
|
258
306
|
// src/features/extras/extras-copier.ts
|
|
259
307
|
var createExtrasCopier = (extrasType) => {
|
|
260
308
|
return async (_templates, targetDir) => {
|
|
261
309
|
const counter = { files: 0, directories: 0 };
|
|
262
|
-
const targetExtrasDir =
|
|
263
|
-
const extrasSrc =
|
|
264
|
-
if (await
|
|
265
|
-
await
|
|
310
|
+
const targetExtrasDir = path7.join(targetDir, ".claude", extrasType);
|
|
311
|
+
const extrasSrc = path7.join(getTemplatesDir(), ".claude", extrasType);
|
|
312
|
+
if (await fs5.pathExists(extrasSrc)) {
|
|
313
|
+
await fs5.ensureDir(targetExtrasDir);
|
|
266
314
|
await copyRecursive(extrasSrc, targetExtrasDir, counter);
|
|
267
315
|
}
|
|
268
316
|
return counter;
|
|
@@ -271,85 +319,71 @@ var createExtrasCopier = (extrasType) => {
|
|
|
271
319
|
var copyCommands = createExtrasCopier("commands");
|
|
272
320
|
var copyAgents = createExtrasCopier("agents");
|
|
273
321
|
var copyInstructions = createExtrasCopier("instructions");
|
|
322
|
+
var getSkillsToInstall = async (skillsSrc, templates) => {
|
|
323
|
+
const metadataMap = await loadAllSkillMetadata(skillsSrc);
|
|
324
|
+
const isNonUITemplate = templates.some((t) => NON_UI_TEMPLATES.includes(t));
|
|
325
|
+
const skillsToInstall = [];
|
|
326
|
+
for (const [skillName, metadata] of metadataMap) {
|
|
327
|
+
if (isNonUITemplate && metadata.uiOnly) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (metadata.framework && !templates.includes(metadata.framework)) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
skillsToInstall.push(skillName);
|
|
334
|
+
}
|
|
335
|
+
return skillsToInstall;
|
|
336
|
+
};
|
|
274
337
|
var copySkills = async (templates, targetDir) => {
|
|
275
338
|
const counter = { files: 0, directories: 0 };
|
|
276
|
-
const targetSkillsDir =
|
|
277
|
-
const skillsSrc =
|
|
278
|
-
if (!await
|
|
339
|
+
const targetSkillsDir = path7.join(targetDir, ".claude", "skills");
|
|
340
|
+
const skillsSrc = path7.join(getTemplatesDir(), ".claude", "skills");
|
|
341
|
+
if (!await fs5.pathExists(skillsSrc)) {
|
|
279
342
|
return counter;
|
|
280
343
|
}
|
|
281
|
-
await
|
|
282
|
-
const
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
skillsToCopy.add(skill);
|
|
289
|
-
if (!skillTemplateMap.has(skill)) {
|
|
290
|
-
skillTemplateMap.set(skill, /* @__PURE__ */ new Set());
|
|
291
|
-
}
|
|
292
|
-
skillTemplateMap.get(skill).add(template);
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
for (const skill of skillsToCopy) {
|
|
296
|
-
const skillSrc = path6.join(skillsSrc, skill);
|
|
297
|
-
const skillDest = path6.join(targetSkillsDir, skill);
|
|
298
|
-
if (await fs4.pathExists(skillSrc)) {
|
|
299
|
-
if (await fs4.pathExists(skillDest)) {
|
|
300
|
-
await fs4.remove(skillDest);
|
|
301
|
-
}
|
|
302
|
-
await copyRecursive(skillSrc, skillDest, counter);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
const duplicateSkills = [];
|
|
306
|
-
for (const [skill, templateSet] of skillTemplateMap.entries()) {
|
|
307
|
-
if (templateSet.size > 1) {
|
|
308
|
-
duplicateSkills.push({
|
|
309
|
-
skill,
|
|
310
|
-
templates: Array.from(templateSet).sort()
|
|
311
|
-
});
|
|
344
|
+
await fs5.ensureDir(targetSkillsDir);
|
|
345
|
+
const skillsToInstall = await getSkillsToInstall(skillsSrc, templates);
|
|
346
|
+
for (const skill of skillsToInstall) {
|
|
347
|
+
const skillSrc = path7.join(skillsSrc, skill);
|
|
348
|
+
const skillDest = path7.join(targetSkillsDir, skill);
|
|
349
|
+
if (await fs5.pathExists(skillDest)) {
|
|
350
|
+
await fs5.remove(skillDest);
|
|
312
351
|
}
|
|
352
|
+
await copyRecursive(skillSrc, skillDest, counter);
|
|
313
353
|
}
|
|
314
|
-
return
|
|
315
|
-
...counter,
|
|
316
|
-
...duplicateSkills.length > 0 && { duplicateSkills }
|
|
317
|
-
};
|
|
354
|
+
return counter;
|
|
318
355
|
};
|
|
319
356
|
|
|
320
357
|
// src/features/extras/extras-checker.ts
|
|
321
|
-
import
|
|
322
|
-
import
|
|
358
|
+
import fs6 from "fs-extra";
|
|
359
|
+
import path8 from "path";
|
|
323
360
|
var checkExistingClaudeFiles = async (targetDir) => {
|
|
324
361
|
const existingFiles = [];
|
|
325
|
-
const skillsDir =
|
|
326
|
-
const commandsDir =
|
|
327
|
-
const agentsDir =
|
|
328
|
-
const instructionsDir =
|
|
329
|
-
if (await
|
|
362
|
+
const skillsDir = path8.join(targetDir, ".claude", "skills");
|
|
363
|
+
const commandsDir = path8.join(targetDir, ".claude", "commands");
|
|
364
|
+
const agentsDir = path8.join(targetDir, ".claude", "agents");
|
|
365
|
+
const instructionsDir = path8.join(targetDir, ".claude", "instructions");
|
|
366
|
+
if (await fs6.pathExists(skillsDir)) {
|
|
330
367
|
existingFiles.push(".claude/skills/");
|
|
331
368
|
}
|
|
332
|
-
if (await
|
|
369
|
+
if (await fs6.pathExists(commandsDir)) {
|
|
333
370
|
existingFiles.push(".claude/commands/");
|
|
334
371
|
}
|
|
335
|
-
if (await
|
|
372
|
+
if (await fs6.pathExists(agentsDir)) {
|
|
336
373
|
existingFiles.push(".claude/agents/");
|
|
337
374
|
}
|
|
338
|
-
if (await
|
|
375
|
+
if (await fs6.pathExists(instructionsDir)) {
|
|
339
376
|
existingFiles.push(".claude/instructions/");
|
|
340
377
|
}
|
|
341
378
|
return existingFiles;
|
|
342
379
|
};
|
|
343
|
-
var checkAllExtrasExist = async (
|
|
344
|
-
const claudeDir =
|
|
345
|
-
const
|
|
346
|
-
const
|
|
347
|
-
const
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
return skills && skills.length > 0;
|
|
351
|
-
});
|
|
352
|
-
const hasSkills = COMMON_SKILLS.length > 0 || hasFrameworkSkills;
|
|
380
|
+
var checkAllExtrasExist = async (_templates) => {
|
|
381
|
+
const claudeDir = path8.join(getTemplatesDir(), ".claude");
|
|
382
|
+
const skillsSrc = path8.join(claudeDir, "skills");
|
|
383
|
+
const commandsSrc = path8.join(claudeDir, "commands");
|
|
384
|
+
const agentsSrc = path8.join(claudeDir, "agents");
|
|
385
|
+
const instructionsSrc = path8.join(claudeDir, "instructions");
|
|
386
|
+
const hasSkills = await hasFiles(skillsSrc);
|
|
353
387
|
const hasCommands = await hasFiles(commandsSrc);
|
|
354
388
|
const hasAgents = await hasFiles(agentsSrc);
|
|
355
389
|
const hasInstructions = await hasFiles(instructionsSrc);
|
|
@@ -367,15 +401,6 @@ async function promptConfirm(message, initial = false) {
|
|
|
367
401
|
});
|
|
368
402
|
return { confirmed: response.confirmed ?? false };
|
|
369
403
|
}
|
|
370
|
-
async function promptSelect(message, choices) {
|
|
371
|
-
const response = await prompts({
|
|
372
|
-
type: "select",
|
|
373
|
-
name: "value",
|
|
374
|
-
message,
|
|
375
|
-
choices
|
|
376
|
-
});
|
|
377
|
-
return { value: response.value };
|
|
378
|
-
}
|
|
379
404
|
async function promptMultiselect(message, choices, options) {
|
|
380
405
|
const response = await prompts({
|
|
381
406
|
type: "multiselect",
|
|
@@ -447,8 +472,8 @@ async function promptExtrasSelection(options) {
|
|
|
447
472
|
} = options;
|
|
448
473
|
let installSkills = skills ?? false;
|
|
449
474
|
let installCommands = commands ?? false;
|
|
450
|
-
|
|
451
|
-
|
|
475
|
+
const installAgents = agents ?? hasAgents;
|
|
476
|
+
const installInstructions = instructions ?? hasInstructions;
|
|
452
477
|
const noOptionsProvided = skills === void 0 && commands === void 0 && agents === void 0 && instructions === void 0;
|
|
453
478
|
if (noOptionsProvided && (hasSkills || hasCommands || hasAgents || hasInstructions)) {
|
|
454
479
|
logger.blank();
|
|
@@ -489,32 +514,6 @@ async function handleDuplicateFiles(existingClaudeFiles, force) {
|
|
|
489
514
|
);
|
|
490
515
|
return response.confirmed;
|
|
491
516
|
}
|
|
492
|
-
async function handleDuplicateSkills(duplicateSkills, templates, targetDir) {
|
|
493
|
-
logger.blank();
|
|
494
|
-
logger.warn("The following skills are included in multiple templates:");
|
|
495
|
-
duplicateSkills.forEach(({ skill, templates: skillTemplates }) => {
|
|
496
|
-
logger.step(`${skill} (${skillTemplates.join(", ")})`);
|
|
497
|
-
});
|
|
498
|
-
logger.blank();
|
|
499
|
-
const response = await promptSelect(
|
|
500
|
-
"Which template's version should be used?",
|
|
501
|
-
templates.map((t) => ({
|
|
502
|
-
title: t,
|
|
503
|
-
value: t
|
|
504
|
-
}))
|
|
505
|
-
);
|
|
506
|
-
if (response.value) {
|
|
507
|
-
logger.info(`Reinstalling skills with ${response.value} template...`);
|
|
508
|
-
const reinstallResult = await copySkills([response.value], targetDir);
|
|
509
|
-
logger.success(
|
|
510
|
-
`Skills: ${reinstallResult.files} files, ${reinstallResult.directories} directories`
|
|
511
|
-
);
|
|
512
|
-
return reinstallResult;
|
|
513
|
-
} else {
|
|
514
|
-
logger.warn("No template selected. Using all templates.");
|
|
515
|
-
return { files: 0, directories: 0 };
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
517
|
async function installSkillsIfNeeded(templates, targetDir, shouldInstall, hasSkills) {
|
|
519
518
|
if (!shouldInstall) {
|
|
520
519
|
return { files: 0, directories: 0 };
|
|
@@ -526,13 +525,6 @@ async function installSkillsIfNeeded(templates, targetDir, shouldInstall, hasSki
|
|
|
526
525
|
logger.blank();
|
|
527
526
|
logger.info("Installing skills...");
|
|
528
527
|
const skillsResult = await copySkills(templates, targetDir);
|
|
529
|
-
if (skillsResult.duplicateSkills && skillsResult.duplicateSkills.length > 0) {
|
|
530
|
-
return await handleDuplicateSkills(
|
|
531
|
-
skillsResult.duplicateSkills,
|
|
532
|
-
templates,
|
|
533
|
-
targetDir
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
528
|
logger.success(
|
|
537
529
|
`Skills: ${skillsResult.files} files, ${skillsResult.directories} directories`
|
|
538
530
|
);
|
|
@@ -627,8 +619,8 @@ async function installExtras(templates, targetDir, flags, availability, force) {
|
|
|
627
619
|
}
|
|
628
620
|
|
|
629
621
|
// src/shared/gitignore-manager.ts
|
|
630
|
-
import
|
|
631
|
-
import
|
|
622
|
+
import fs7 from "fs-extra";
|
|
623
|
+
import path9 from "path";
|
|
632
624
|
var CLAUDE_GENERATED_FOLDERS = [
|
|
633
625
|
".claude/plan/",
|
|
634
626
|
".claude/ralph/",
|
|
@@ -636,14 +628,14 @@ var CLAUDE_GENERATED_FOLDERS = [
|
|
|
636
628
|
".claude/prd/"
|
|
637
629
|
];
|
|
638
630
|
async function updateGitignore(targetDir) {
|
|
639
|
-
const gitignorePath =
|
|
631
|
+
const gitignorePath = path9.join(targetDir, ".gitignore");
|
|
640
632
|
const sectionComment = "# Claude Code generated files";
|
|
641
633
|
let content = "";
|
|
642
634
|
let hasGitignore = false;
|
|
643
635
|
try {
|
|
644
|
-
content = await
|
|
636
|
+
content = await fs7.readFile(gitignorePath, "utf-8");
|
|
645
637
|
hasGitignore = true;
|
|
646
|
-
} catch
|
|
638
|
+
} catch {
|
|
647
639
|
content = "";
|
|
648
640
|
}
|
|
649
641
|
const linesToAdd = [];
|
|
@@ -684,7 +676,7 @@ async function updateGitignore(targetDir) {
|
|
|
684
676
|
newContent += linesToAdd.join("\n") + "\n";
|
|
685
677
|
}
|
|
686
678
|
}
|
|
687
|
-
await
|
|
679
|
+
await fs7.writeFile(gitignorePath, newContent, "utf-8");
|
|
688
680
|
if (hasGitignore) {
|
|
689
681
|
logger.success(`.gitignore updated with ${linesToAdd.length} patterns`);
|
|
690
682
|
} else {
|
|
@@ -700,7 +692,7 @@ var TEMPLATE_DESCRIPTIONS = {
|
|
|
700
692
|
};
|
|
701
693
|
async function validateTargetDirectory(targetDir) {
|
|
702
694
|
try {
|
|
703
|
-
const stat = await
|
|
695
|
+
const stat = await fs8.stat(targetDir);
|
|
704
696
|
if (!stat.isDirectory()) {
|
|
705
697
|
logger.error(`Target is not a directory: ${targetDir}`);
|
|
706
698
|
process.exit(1);
|
|
@@ -714,7 +706,7 @@ async function validateTargetDirectory(targetDir) {
|
|
|
714
706
|
process.exit(1);
|
|
715
707
|
}
|
|
716
708
|
try {
|
|
717
|
-
await
|
|
709
|
+
await fs8.access(targetDir, fs8.constants.W_OK);
|
|
718
710
|
} catch {
|
|
719
711
|
logger.error(`No write permission for: ${targetDir}`);
|
|
720
712
|
process.exit(1);
|
|
@@ -854,7 +846,7 @@ var init = async (options) => {
|
|
|
854
846
|
|
|
855
847
|
// src/index.ts
|
|
856
848
|
var program = new Command();
|
|
857
|
-
program.name("claude-code").description("Claude Code documentation installer for projects").version("0.
|
|
849
|
+
program.name("claude-code").description("Claude Code documentation installer for projects").version("0.6.0");
|
|
858
850
|
program.option(
|
|
859
851
|
"-t, --template <names>",
|
|
860
852
|
"template names (comma-separated: tanstack-start,hono)"
|