create-takt-sdd 0.14.0 → 0.15.1

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/cli.js CHANGED
@@ -20,7 +20,6 @@ function parseArgs(argv) {
20
20
  version: false,
21
21
  tag: undefined,
22
22
  withoutSkills: false,
23
- refsPath: "references/takt",
24
23
  layout: "auto",
25
24
  };
26
25
  for (let i = 0; i < argv.length; i++) {
@@ -53,15 +52,6 @@ function parseArgs(argv) {
53
52
  case "--without-skills":
54
53
  args.withoutSkills = true;
55
54
  break;
56
- case "--refs-path": {
57
- const value = argv[++i];
58
- if (!value) {
59
- console.error('Error: --refs-path requires a value (e.g. "references/takt")');
60
- process.exit(1);
61
- }
62
- args.refsPath = value;
63
- break;
64
- }
65
55
  case "--layout": {
66
56
  const value = argv[++i];
67
57
  if (!value || !isLayout(value)) {
@@ -104,7 +94,6 @@ async function main() {
104
94
  dryRun: args.dryRun,
105
95
  tag: args.tag,
106
96
  withoutSkills: args.withoutSkills,
107
- refsPath: args.refsPath,
108
97
  layout: args.layout,
109
98
  cwd: process.cwd(),
110
99
  });
package/dist/i18n.js CHANGED
@@ -16,13 +16,10 @@ const en = {
16
16
  scriptsCreated: "Created package.json with npm scripts and devDependencies",
17
17
  depsAdded: (keys) => `Added devDependencies: ${keys.join(", ")}`,
18
18
  depsUpdated: (keys) => `Updated devDependencies: ${keys.join(", ")}`,
19
- installingSkills: "Installing takt skills to .agents/skills/...",
19
+ installingSkills: (source) => `Installing TAKT skills from ${source}...`,
20
+ skillInstalling: (name, source) => `Installing external skill ${name} from ${source}`,
20
21
  skillInstalled: (name) => `Installed skill: ${name}`,
21
- skillSymlinked: (name, target) => `Symlinked ${target}/${name} -> .agents/skills/${name}`,
22
- downloadingTaktRefs: (refsPath) => `Downloading takt builtins to ${refsPath}/...`,
23
- taktRefsInstalled: "Installed takt references (builtins, docs)",
24
- taktRefsSkipped: "Takt references already exist, skipping",
25
- taktRefsError: "Warning: Failed to download takt references. Skills may not find style guides.",
22
+ skillInstallFailed: (name, source) => `Warning: Failed to install ${name} from ${source}. Continuing without it.`,
26
23
  layoutDetected: (layout) => `Using ${layout} layout`,
27
24
  fileAdded: (path) => `Added: ${path}`,
28
25
  fileUpdated: (path) => `Updated: ${path}`,
@@ -35,9 +32,8 @@ Options:
35
32
  --lang <en|ja> Message language (default: en)
36
33
  --force Overwrite existing .takt/ directory (ignored if manifest exists)
37
34
  --dry-run Preview without writing files
38
- --without-skills Skip installing takt skills to .agents/skills/
35
+ --without-skills Skip installing TAKT skills via external skills add
39
36
  --layout <mode> Directory layout: auto, modern, legacy (default: auto)
40
- --refs-path <path> Path for takt references (default: references/takt)
41
37
  -h, --help Show this help
42
38
  -v, --version Show version`,
43
39
  usageExamples: `
@@ -79,13 +75,10 @@ const ja = {
79
75
  scriptsCreated: "npm scripts と devDependencies 付きの package.json を作成しました",
80
76
  depsAdded: (keys) => `devDependencies を追加しました: ${keys.join(", ")}`,
81
77
  depsUpdated: (keys) => `devDependencies を更新しました: ${keys.join(", ")}`,
82
- installingSkills: ".agents/skills/ takt スキルをインストール中...",
78
+ installingSkills: (source) => `${source} から TAKT スキルをインストール中...`,
79
+ skillInstalling: (name, source) => `${source} から外部スキルをインストール中: ${name}`,
83
80
  skillInstalled: (name) => `スキルをインストールしました: ${name}`,
84
- skillSymlinked: (name, target) => `シンボリックリンク作成: ${target}/${name} -> .agents/skills/${name}`,
85
- downloadingTaktRefs: (refsPath) => `${refsPath}/ に takt ビルトインをダウンロード中...`,
86
- taktRefsInstalled: "takt リファレンスをインストールしました(builtins, docs)",
87
- taktRefsSkipped: "takt リファレンスは既に存在するためスキップしました",
88
- taktRefsError: "警告: takt リファレンスのダウンロードに失敗しました。スキルがスタイルガイドを参照できない可能性があります。",
81
+ skillInstallFailed: (name, source) => `警告: ${source} から ${name} のインストールに失敗しました。このスキルなしで継続します。`,
89
82
  layoutDetected: (layout) => `${layout} レイアウトを使用します`,
90
83
  fileAdded: (path) => `追加: ${path}`,
91
84
  fileUpdated: (path) => `更新: ${path}`,
@@ -98,9 +91,8 @@ const ja = {
98
91
  --lang <en|ja> メッセージ言語 (デフォルト: en)
99
92
  --force 既存の .takt/ を上書き(マニフェストがある場合は無視)
100
93
  --dry-run プレビューのみ(ファイル書き込みなし)
101
- --without-skills takt スキルのインストールをスキップ
94
+ --without-skills external skills add による TAKT スキル導入をスキップ
102
95
  --layout <mode> ディレクトリレイアウト: auto, modern, legacy(デフォルト: auto)
103
- --refs-path <path> takt リファレンスのパス(デフォルト: references/takt)
104
96
  -h, --help ヘルプを表示
105
97
  -v, --version バージョンを表示`,
106
98
  usageExamples: `
package/dist/install.js CHANGED
@@ -1,14 +1,12 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import { createHash } from "node:crypto";
3
- import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, symlinkSync, statSync, writeFileSync } from "node:fs";
3
+ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import https from "node:https";
5
- import { createWriteStream } from "node:fs";
6
- import { mkdtempSync } from "node:fs";
5
+ import { createWriteStream, mkdtempSync } from "node:fs";
7
6
  import { tmpdir } from "node:os";
8
7
  import { dirname, join, relative, resolve } from "node:path";
9
8
  import { fileURLToPath } from "node:url";
10
9
  import { getMessages } from "./i18n.js";
11
- import { TAKT_REF_HASH } from "./generated/takt-ref.js";
12
10
  const __filename = fileURLToPath(import.meta.url);
13
11
  const __dirname = dirname(__filename);
14
12
  function getInstallerVersion() {
@@ -17,9 +15,7 @@ function getInstallerVersion() {
17
15
  return pkg.version;
18
16
  }
19
17
  const REPO = "j5ik2o/takt-sdd";
20
- const TAKT_REPO = "nrslib/takt";
21
18
  const TARGET_DIR = ".takt";
22
- const DEFAULT_REFS_PATH = "references/takt";
23
19
  const PIECE_DIR = "pieces";
24
20
  const FACET_TYPES = [
25
21
  "personas",
@@ -28,6 +24,15 @@ const FACET_TYPES = [
28
24
  "knowledge",
29
25
  "output-contracts",
30
26
  ];
27
+ const EXTERNAL_SKILL_SOURCE = "j5ik2o/ai-tools";
28
+ const EXTERNAL_TAKT_SKILLS = [
29
+ "takt-analyzer",
30
+ "takt-facet-builder",
31
+ "takt-optimizer",
32
+ "takt-piece-builder",
33
+ "takt-skill-updater",
34
+ "takt-task-builder",
35
+ ];
31
36
  function srcFacetPath(facetType) {
32
37
  return `facets/${facetType}`;
33
38
  }
@@ -54,7 +59,7 @@ function detectLayout() {
54
59
  function rewritePiecePathsForLegacy(piecesDir) {
55
60
  if (!existsSync(piecesDir))
56
61
  return;
57
- for (const file of readdirSync(piecesDir).filter(f => f.endsWith(".yaml"))) {
62
+ for (const file of readdirSync(piecesDir).filter((f) => f.endsWith(".yaml"))) {
58
63
  const filePath = join(piecesDir, file);
59
64
  let content = readFileSync(filePath, "utf-8");
60
65
  for (const type of FACET_TYPES) {
@@ -63,33 +68,22 @@ function rewritePiecePathsForLegacy(piecesDir) {
63
68
  writeFileSync(filePath, content, "utf-8");
64
69
  }
65
70
  }
66
- const TAKT_SKILLS = [
67
- "takt-analyze",
68
- "takt-facet",
69
- "takt-optimize",
70
- "takt-piece",
71
- "takt-task",
72
- ];
73
- const SKILL_SYMLINK_TARGETS = [
74
- ".claude/skills",
75
- ".codex/skills",
76
- ];
77
71
  const SDD_SCRIPTS = {
78
- "cc-sdd:full": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-full -t",
79
- "cc-sdd:requirements": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-requirements -t",
80
- "cc-sdd:validate-gap": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-validate-gap -t",
81
- "cc-sdd:design": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-design -t",
82
- "cc-sdd:validate-design": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-validate-design -t",
83
- "cc-sdd:tasks": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-tasks -t",
84
- "cc-sdd:impl": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-impl -t",
85
- "cc-sdd:validate-impl": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-validate-impl -t",
86
- "cc-sdd:steering": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-steering -t",
87
- "cc-sdd:steering-custom": "takt --pipeline --skip-git --create-worktree no -w cc-sdd-steering-custom -t",
88
- "opsx:full": "takt --pipeline --skip-git --create-worktree no -w opsx-full -t",
89
- "opsx:propose": "takt --pipeline --skip-git --create-worktree no -w opsx-propose -t",
90
- "opsx:apply": "takt --pipeline --skip-git --create-worktree no -w opsx-apply -t",
91
- "opsx:archive": "takt --pipeline --skip-git --create-worktree no -w opsx-archive -t",
92
- "opsx:explore": "takt --skip-git --create-worktree no -w opsx-explore",
72
+ "cc-sdd:full": "takt --pipeline --skip-git -w cc-sdd-full -t",
73
+ "cc-sdd:requirements": "takt --pipeline --skip-git -w cc-sdd-requirements -t",
74
+ "cc-sdd:validate-gap": "takt --pipeline --skip-git -w cc-sdd-validate-gap -t",
75
+ "cc-sdd:design": "takt --pipeline --skip-git -w cc-sdd-design -t",
76
+ "cc-sdd:validate-design": "takt --pipeline --skip-git -w cc-sdd-validate-design -t",
77
+ "cc-sdd:tasks": "takt --pipeline --skip-git -w cc-sdd-tasks -t",
78
+ "cc-sdd:impl": "takt --pipeline --skip-git -w cc-sdd-impl -t",
79
+ "cc-sdd:validate-impl": "takt --pipeline --skip-git -w cc-sdd-validate-impl -t",
80
+ "cc-sdd:steering": "takt --pipeline --skip-git -w cc-sdd-steering -t",
81
+ "cc-sdd:steering-custom": "takt --pipeline --skip-git -w cc-sdd-steering-custom -t",
82
+ "opsx:full": "takt --pipeline --skip-git -w opsx-full -t",
83
+ "opsx:propose": "takt --pipeline --skip-git -w opsx-propose -t",
84
+ "opsx:apply": "takt --pipeline --skip-git -w opsx-apply -t",
85
+ "opsx:archive": "takt --pipeline --skip-git -w opsx-archive -t",
86
+ "opsx:explore": "takt --skip-git -w opsx-explore",
93
87
  };
94
88
  function info(msg) {
95
89
  console.log(`\x1b[1;34m==>\x1b[0m ${msg}`);
@@ -144,7 +138,6 @@ function resolveTag(tagOption, installerVersion) {
144
138
  if (tagOption === "latest") {
145
139
  return fetchLatestTag();
146
140
  }
147
- // Accept both "v0.1.0" and "0.1.0"
148
141
  return tagOption.startsWith("v") ? tagOption : `v${tagOption}`;
149
142
  }
150
143
  function download(url, dest) {
@@ -217,7 +210,6 @@ function syncDirectory(srcDir, destDir, srcBase, destBase, manifest, msg, cwd) {
217
210
  const srcHash = computeFileHash(srcPath);
218
211
  files[manifestKey] = srcHash;
219
212
  if (!existsSync(destPath)) {
220
- // New file — copy
221
213
  mkdirSync(dirname(destPath), { recursive: true });
222
214
  cpSync(srcPath, destPath);
223
215
  info(msg.fileAdded(manifestKey));
@@ -225,48 +217,61 @@ function syncDirectory(srcDir, destDir, srcBase, destBase, manifest, msg, cwd) {
225
217
  else if (manifest !== null) {
226
218
  const recordedHash = manifest.files[manifestKey];
227
219
  if (recordedHash === undefined) {
228
- // File exists but not in manifest (pre-manifest environment)
229
220
  warn(msg.fileSkippedCustomized(manifestKey));
230
221
  }
231
222
  else {
232
223
  const currentHash = computeFileHash(destPath);
233
224
  if (currentHash === recordedHash) {
234
- // User has not modified — safe to overwrite
235
225
  cpSync(srcPath, destPath);
236
226
  info(msg.fileUpdated(manifestKey));
237
227
  }
238
228
  else {
239
- // User has customized — skip
240
229
  warn(msg.fileSkippedCustomized(manifestKey));
241
230
  }
242
231
  }
243
232
  }
244
233
  else {
245
- // No manifest, fresh install or force — overwrite
246
234
  cpSync(srcPath, destPath);
247
235
  }
248
236
  }
249
237
  return { files };
250
238
  }
239
+ function skillInstallCommand(skill) {
240
+ return `npx -y skills add ${EXTERNAL_SKILL_SOURCE} --skill ${skill}`;
241
+ }
242
+ function installExternalSkills(cwd, msg) {
243
+ info(msg.installingSkills(EXTERNAL_SKILL_SOURCE));
244
+ for (const skill of EXTERNAL_TAKT_SKILLS) {
245
+ const command = skillInstallCommand(skill);
246
+ info(msg.skillInstalling(skill, EXTERNAL_SKILL_SOURCE));
247
+ try {
248
+ execSync(command, {
249
+ cwd,
250
+ stdio: "inherit",
251
+ });
252
+ info(msg.skillInstalled(skill));
253
+ }
254
+ catch {
255
+ warn(msg.skillInstallFailed(skill, EXTERNAL_SKILL_SOURCE));
256
+ }
257
+ }
258
+ }
251
259
  export async function install(options) {
252
260
  const msg = getMessages(options.lang);
253
261
  const targetPath = join(options.cwd, TARGET_DIR);
254
262
  const manifestPath = join(targetPath, MANIFEST_FILE);
255
- // tar の存在チェック
256
263
  try {
257
264
  execSync("which tar", { stdio: "ignore" });
258
265
  }
259
266
  catch {
260
267
  errorExit(msg.tarNotFound);
261
268
  }
262
- // マニフェスト読み込み&モード判定
263
269
  const manifest = loadManifest(manifestPath);
264
270
  const isUpdate = manifest !== null;
265
271
  const piecesExist = existsSync(join(targetPath, "pieces"));
266
272
  if (!isUpdate && piecesExist && !options.force) {
267
273
  errorExit(msg.existsError("npx create-takt-sdd"));
268
274
  }
269
- // ダウンロード
270
275
  info(msg.downloading);
271
276
  const tmpDir = mkdtempSync(join(tmpdir(), "takt-sdd-"));
272
277
  const archivePath = join(tmpDir, "archive.tar.gz");
@@ -285,17 +290,14 @@ export async function install(options) {
285
290
  }
286
291
  const resolvedLayout = options.layout === "auto" ? detectLayout() : options.layout;
287
292
  info(msg.layoutDetected(resolvedLayout));
288
- // dry-run: ファイル一覧のみ表示
289
293
  if (options.dryRun) {
290
294
  info(msg.dryRunHeader);
291
- // pieces
292
295
  const piecesSrcDry = join(extractedTakt, options.lang, PIECE_DIR);
293
296
  if (existsSync(piecesSrcDry)) {
294
297
  for (const file of collectFiles(piecesSrcDry, piecesSrcDry)) {
295
298
  console.log(msg.dryRunItem(join(TARGET_DIR, PIECE_DIR, file)));
296
299
  }
297
300
  }
298
- // facets
299
301
  for (const facetType of FACET_TYPES) {
300
302
  const srcDir = join(extractedTakt, options.lang, srcFacetPath(facetType));
301
303
  if (existsSync(srcDir)) {
@@ -306,32 +308,17 @@ export async function install(options) {
306
308
  }
307
309
  }
308
310
  if (!options.withoutSkills) {
309
- for (const skill of TAKT_SKILLS) {
310
- const skillSrc = join(extractedDir, ".agents", "skills", skill);
311
- if (existsSync(skillSrc)) {
312
- for (const file of collectFiles(skillSrc, join(extractedDir, ".agents", "skills"))) {
313
- // Skip language-specific SKILL files (only SKILL.md is installed)
314
- if (file.endsWith("SKILL.ja.md") || file.endsWith("SKILL.en.md"))
315
- continue;
316
- console.log(msg.dryRunItem(join(".agents", "skills", file)));
317
- }
318
- for (const target of SKILL_SYMLINK_TARGETS) {
319
- console.log(msg.dryRunItem(`${target}/${skill} -> ../../.agents/skills/${skill}`));
320
- }
321
- }
311
+ for (const skill of EXTERNAL_TAKT_SKILLS) {
312
+ console.log(msg.dryRunItem(skillInstallCommand(skill)));
322
313
  }
323
- console.log(msg.dryRunItem(`${options.refsPath}/builtins/`));
324
- console.log(msg.dryRunItem(`${options.refsPath}/docs/`));
325
314
  }
326
315
  console.log("");
327
316
  info(msg.dryRunSkipped);
328
317
  return;
329
318
  }
330
- // インストール / アップデート
331
319
  info(isUpdate ? msg.updating : msg.installing);
332
320
  mkdirSync(targetPath, { recursive: true });
333
321
  const allFiles = {};
334
- // pieces(legacy時はsync前にソースのパスを書き換え)
335
322
  const piecesSrc = join(extractedTakt, options.lang, PIECE_DIR);
336
323
  if (existsSync(piecesSrc)) {
337
324
  const piecesDest = join(targetPath, PIECE_DIR);
@@ -348,7 +335,6 @@ export async function install(options) {
348
335
  const result = syncDirectory(effectiveSrc, piecesDest, effectiveSrc, piecesDest, isUpdate ? manifest : null, msg, options.cwd);
349
336
  Object.assign(allFiles, result.files);
350
337
  }
351
- // facets
352
338
  for (const facetType of FACET_TYPES) {
353
339
  const srcDir = join(extractedTakt, options.lang, srcFacetPath(facetType));
354
340
  if (existsSync(srcDir)) {
@@ -360,152 +346,9 @@ export async function install(options) {
360
346
  Object.assign(allFiles, result.files);
361
347
  }
362
348
  }
363
- // .gitignore は takt が初回実行時に自動配置するため、インストーラでは生成しない
364
- // takt スキルのインストール
365
- const agentSkillsDir = join(options.cwd, ".agents", "skills");
366
- const extractedSkillsDir = join(extractedDir, ".agents", "skills");
367
- if (!options.withoutSkills && existsSync(extractedSkillsDir)) {
368
- info(msg.installingSkills);
369
- mkdirSync(agentSkillsDir, { recursive: true });
370
- for (const skill of TAKT_SKILLS) {
371
- const skillSrc = join(extractedSkillsDir, skill);
372
- if (!existsSync(skillSrc))
373
- continue;
374
- // Prepare a temp copy with language selection applied
375
- const skillTmp = join(tmpDir, "skill-prep", skill);
376
- if (existsSync(skillTmp))
377
- rmSync(skillTmp, { recursive: true });
378
- cpSync(skillSrc, skillTmp, { recursive: true });
379
- // Select SKILL.md based on language
380
- const skillLangMd = join(skillTmp, `SKILL.${options.lang}.md`);
381
- const skillMdPath = join(skillTmp, "SKILL.md");
382
- if (existsSync(skillLangMd)) {
383
- cpSync(skillLangMd, skillMdPath);
384
- }
385
- // Remove language-specific SKILL files from temp
386
- for (const l of ["ja", "en"]) {
387
- const langFile = join(skillTmp, `SKILL.${l}.md`);
388
- if (existsSync(langFile)) {
389
- rmSync(langFile);
390
- }
391
- }
392
- // SKILL.md 内の references/takt パスを置換
393
- if (options.refsPath !== DEFAULT_REFS_PATH) {
394
- if (existsSync(skillMdPath)) {
395
- const content = readFileSync(skillMdPath, "utf-8");
396
- const updated = content.replaceAll(DEFAULT_REFS_PATH, options.refsPath);
397
- writeFileSync(skillMdPath, updated, "utf-8");
398
- }
399
- }
400
- const skillDest = join(agentSkillsDir, skill);
401
- if (!isUpdate && existsSync(skillDest)) {
402
- rmSync(skillDest, { recursive: true });
403
- }
404
- const result = syncDirectory(skillTmp, skillDest, skillTmp, skillDest, isUpdate ? manifest : null, msg, options.cwd);
405
- Object.assign(allFiles, result.files);
406
- info(msg.skillInstalled(skill));
407
- }
408
- // .claude/skills/ と .codex/skills/ にシンボリックリンクを作成
409
- for (const target of SKILL_SYMLINK_TARGETS) {
410
- const targetDir = join(options.cwd, target);
411
- mkdirSync(targetDir, { recursive: true });
412
- for (const skill of TAKT_SKILLS) {
413
- if (!existsSync(join(agentSkillsDir, skill)))
414
- continue;
415
- const linkPath = join(targetDir, skill);
416
- if (existsSync(linkPath)) {
417
- rmSync(linkPath, { recursive: true });
418
- }
419
- symlinkSync(`../../.agents/skills/${skill}`, linkPath);
420
- info(msg.skillSymlinked(skill, target));
421
- }
422
- }
423
- }
424
- // takt リファレンスのダウンロード(スキルが参照するbuiltins等)
425
349
  if (!options.withoutSkills) {
426
- const refsDir = join(options.cwd, options.refsPath);
427
- const needsRefDownload = isUpdate
428
- ? manifest.taktRefHash !== TAKT_REF_HASH
429
- : !existsSync(join(refsDir, "builtins"));
430
- if (needsRefDownload) {
431
- info(msg.downloadingTaktRefs(options.refsPath));
432
- const taktTmpDir = mkdtempSync(join(tmpdir(), "takt-refs-"));
433
- try {
434
- const taktArchive = join(taktTmpDir, "takt.tar.gz");
435
- const taktTarball = `https://github.com/${TAKT_REPO}/archive/${TAKT_REF_HASH}.tar.gz`;
436
- await download(taktTarball, taktArchive);
437
- execSync(`tar -xzf "${taktArchive}" -C "${taktTmpDir}"`, { stdio: "ignore" });
438
- // takt-{hash}/ ディレクトリを探す
439
- const taktExtracted = readdirSync(taktTmpDir).find((d) => d.startsWith("takt-") && statSync(join(taktTmpDir, d)).isDirectory());
440
- if (taktExtracted) {
441
- const taktRoot = join(taktTmpDir, taktExtracted);
442
- mkdirSync(refsDir, { recursive: true });
443
- // builtins/ を syncDirectory でコピー
444
- const builtinsSrc = join(taktRoot, "builtins");
445
- if (existsSync(builtinsSrc)) {
446
- const builtinsDest = join(refsDir, "builtins");
447
- const result = syncDirectory(builtinsSrc, builtinsDest, builtinsSrc, builtinsDest, isUpdate ? manifest : null, msg, options.cwd);
448
- Object.assign(allFiles, result.files);
449
- }
450
- // docs/faceted-prompting.ja.md をコピー
451
- const fpSrc = join(taktRoot, "docs", "faceted-prompting.ja.md");
452
- if (existsSync(fpSrc)) {
453
- const docsDir = join(refsDir, "docs");
454
- mkdirSync(docsDir, { recursive: true });
455
- const fpDest = join(docsDir, "faceted-prompting.ja.md");
456
- const fpKey = relative(options.cwd, fpDest).split("\\").join("/");
457
- const fpHash = computeFileHash(fpSrc);
458
- if (!existsSync(fpDest)) {
459
- cpSync(fpSrc, fpDest);
460
- info(msg.fileAdded(fpKey));
461
- }
462
- else if (isUpdate) {
463
- const recordedHash = manifest.files[fpKey];
464
- if (recordedHash === undefined) {
465
- warn(msg.fileSkippedCustomized(fpKey));
466
- }
467
- else {
468
- const currentHash = computeFileHash(fpDest);
469
- if (currentHash === recordedHash) {
470
- cpSync(fpSrc, fpDest);
471
- info(msg.fileUpdated(fpKey));
472
- }
473
- else {
474
- warn(msg.fileSkippedCustomized(fpKey));
475
- }
476
- }
477
- }
478
- else {
479
- cpSync(fpSrc, fpDest);
480
- }
481
- allFiles[fpKey] = fpHash;
482
- }
483
- info(msg.taktRefsInstalled);
484
- }
485
- else {
486
- warn(msg.taktRefsError);
487
- }
488
- }
489
- catch {
490
- warn(msg.taktRefsError);
491
- }
492
- finally {
493
- rmSync(taktTmpDir, { recursive: true, force: true });
494
- }
495
- }
496
- else {
497
- info(msg.taktRefsSkipped);
498
- // Preserve existing file hashes from manifest for refs
499
- if (isUpdate) {
500
- for (const [key, hash] of Object.entries(manifest.files)) {
501
- if (key.startsWith(options.refsPath)) {
502
- allFiles[key] = hash;
503
- }
504
- }
505
- }
506
- }
350
+ installExternalSkills(options.cwd, msg);
507
351
  }
508
- // アーカイブの package.json から devDependencies を取得
509
352
  const sddPkgPath = join(extractedDir, "package.json");
510
353
  const sddDevDependencies = {};
511
354
  if (existsSync(sddPkgPath)) {
@@ -515,7 +358,6 @@ export async function install(options) {
515
358
  sddDevDependencies[key] = value;
516
359
  }
517
360
  }
518
- // package.json に npm scripts と devDependencies を追加
519
361
  const pkgPath = join(options.cwd, "package.json");
520
362
  if (existsSync(pkgPath)) {
521
363
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
@@ -569,12 +411,10 @@ export async function install(options) {
569
411
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
570
412
  info(msg.scriptsCreated);
571
413
  }
572
- // マニフェスト書き込み
573
414
  const newManifest = {
574
415
  version: version,
575
416
  installedAt: new Date().toISOString(),
576
417
  lang: options.lang,
577
- taktRefHash: TAKT_REF_HASH,
578
418
  files: allFiles,
579
419
  };
580
420
  writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2) + "\n", "utf-8");
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "create-takt-sdd",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "Installer for takt-sdd: Spec-Driven Development workflow for takt",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "create-takt-sdd": "./dist/cli.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "node scripts/embed-takt-ref.js && tsc && node scripts/add-shebang.js",
10
+ "build": "tsc && node scripts/add-shebang.js",
11
11
  "prepare": "npm run build"
12
12
  },
13
13
  "keywords": [
@@ -1,2 +0,0 @@
1
- // Auto-generated by scripts/embed-takt-ref.js — do not edit
2
- export const TAKT_REF_HASH = "6a3c64a033be250c7a1a18eb52ed5d71f6b5eedc";