create-takt-sdd 0.7.0 → 0.9.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/cli.js CHANGED
@@ -8,6 +8,9 @@ import { install } from "./install.js";
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = dirname(__filename);
10
10
  const packageRoot = resolve(__dirname, "..");
11
+ function isLayout(value) {
12
+ return value === "auto" || value === "modern" || value === "legacy";
13
+ }
11
14
  function parseArgs(argv) {
12
15
  const args = {
13
16
  lang: "en",
@@ -18,6 +21,7 @@ function parseArgs(argv) {
18
21
  tag: undefined,
19
22
  withoutSkills: false,
20
23
  refsPath: "references/takt",
24
+ layout: "auto",
21
25
  };
22
26
  for (let i = 0; i < argv.length; i++) {
23
27
  const arg = argv[i];
@@ -58,6 +62,15 @@ function parseArgs(argv) {
58
62
  args.refsPath = value;
59
63
  break;
60
64
  }
65
+ case "--layout": {
66
+ const value = argv[++i];
67
+ if (!value || !isLayout(value)) {
68
+ console.error(`Error: --layout requires "auto", "modern", or "legacy". Got: ${value ?? "(empty)"}`);
69
+ process.exit(1);
70
+ }
71
+ args.layout = value;
72
+ break;
73
+ }
61
74
  case "-h":
62
75
  case "--help":
63
76
  args.help = true;
@@ -92,6 +105,7 @@ async function main() {
92
105
  tag: args.tag,
93
106
  withoutSkills: args.withoutSkills,
94
107
  refsPath: args.refsPath,
108
+ layout: args.layout,
95
109
  cwd: process.cwd(),
96
110
  });
97
111
  }
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/embed-takt-ref.js — do not edit
2
- export const TAKT_REF_HASH = "a89099e819af7b6982c520e7729b17e08de8246a";
2
+ export const TAKT_REF_HASH = "d2c4acd3de2bd383f753905bc7cb7efac3c92d4c";
package/dist/i18n.js CHANGED
@@ -23,6 +23,7 @@ const en = {
23
23
  taktRefsInstalled: "Installed takt references (builtins, docs)",
24
24
  taktRefsSkipped: "Takt references already exist, skipping",
25
25
  taktRefsError: "Warning: Failed to download takt references. Skills may not find style guides.",
26
+ layoutDetected: (layout) => `Using ${layout} layout`,
26
27
  fileAdded: (path) => `Added: ${path}`,
27
28
  fileUpdated: (path) => `Updated: ${path}`,
28
29
  fileSkippedCustomized: (path) => `Skipped (customized): ${path}`,
@@ -35,6 +36,7 @@ Options:
35
36
  --force Overwrite existing .takt/ directory (ignored if manifest exists)
36
37
  --dry-run Preview without writing files
37
38
  --without-skills Skip installing takt skills to .agent/skills/
39
+ --layout <mode> Directory layout: auto, modern, legacy (default: auto)
38
40
  --refs-path <path> Path for takt references (default: references/takt)
39
41
  -h, --help Show this help
40
42
  -v, --version Show version`,
@@ -77,6 +79,7 @@ const ja = {
77
79
  taktRefsInstalled: "takt リファレンスをインストールしました(builtins, docs)",
78
80
  taktRefsSkipped: "takt リファレンスは既に存在するためスキップしました",
79
81
  taktRefsError: "警告: takt リファレンスのダウンロードに失敗しました。スキルがスタイルガイドを参照できない可能性があります。",
82
+ layoutDetected: (layout) => `${layout} レイアウトを使用します`,
80
83
  fileAdded: (path) => `追加: ${path}`,
81
84
  fileUpdated: (path) => `更新: ${path}`,
82
85
  fileSkippedCustomized: (path) => `スキップ(カスタマイズ済み): ${path}`,
@@ -89,6 +92,7 @@ const ja = {
89
92
  --force 既存の .takt/ を上書き(マニフェストがある場合は無視)
90
93
  --dry-run プレビューのみ(ファイル書き込みなし)
91
94
  --without-skills takt スキルのインストールをスキップ
95
+ --layout <mode> ディレクトリレイアウト: auto, modern, legacy(デフォルト: auto)
92
96
  --refs-path <path> takt リファレンスのパス(デフォルト: references/takt)
93
97
  -h, --help ヘルプを表示
94
98
  -v, --version バージョンを表示`,
package/dist/install.js CHANGED
@@ -20,19 +20,55 @@ const REPO = "j5ik2o/takt-sdd";
20
20
  const TAKT_REPO = "nrslib/takt";
21
21
  const TARGET_DIR = ".takt";
22
22
  const DEFAULT_REFS_PATH = "references/takt";
23
- const FACET_DIRS = [
24
- "pieces",
23
+ const PIECE_DIR = "pieces";
24
+ const FACET_TYPES = [
25
25
  "personas",
26
26
  "policies",
27
27
  "instructions",
28
28
  "knowledge",
29
29
  "output-contracts",
30
30
  ];
31
+ function srcFacetPath(facetType) {
32
+ return `facets/${facetType}`;
33
+ }
34
+ function destFacetPath(facetType, layout) {
35
+ return layout === "modern" ? `facets/${facetType}` : facetType;
36
+ }
37
+ function detectLayout() {
38
+ try {
39
+ const output = execSync("takt --version", {
40
+ encoding: "utf-8",
41
+ stdio: ["pipe", "pipe", "ignore"],
42
+ }).trim();
43
+ const match = output.match(/(\d+)\.(\d+)\.(\d+)/);
44
+ if (match) {
45
+ const [, major, minor] = match.map(Number);
46
+ if (major > 0 || (major === 0 && minor >= 22))
47
+ return "modern";
48
+ return "legacy";
49
+ }
50
+ }
51
+ catch { /* takt not installed */ }
52
+ return "modern";
53
+ }
54
+ function rewritePiecePathsForLegacy(piecesDir) {
55
+ if (!existsSync(piecesDir))
56
+ return;
57
+ for (const file of readdirSync(piecesDir).filter(f => f.endsWith(".yaml"))) {
58
+ const filePath = join(piecesDir, file);
59
+ let content = readFileSync(filePath, "utf-8");
60
+ for (const type of FACET_TYPES) {
61
+ content = content.replaceAll(`../facets/${type}/`, `../${type}/`);
62
+ }
63
+ writeFileSync(filePath, content, "utf-8");
64
+ }
65
+ }
31
66
  const TAKT_SKILLS = [
32
67
  "takt-analyze",
33
68
  "takt-facet",
34
69
  "takt-optimize",
35
70
  "takt-piece",
71
+ "takt-task",
36
72
  ];
37
73
  const SKILL_SYMLINK_TARGETS = [
38
74
  ".claude/skills",
@@ -238,14 +274,25 @@ export async function install(options) {
238
274
  if (!existsSync(extractedTakt)) {
239
275
  errorExit(msg.archiveError);
240
276
  }
277
+ const resolvedLayout = options.layout === "auto" ? detectLayout() : options.layout;
278
+ info(msg.layoutDetected(resolvedLayout));
241
279
  // dry-run: ファイル一覧のみ表示
242
280
  if (options.dryRun) {
243
281
  info(msg.dryRunHeader);
244
- for (const dir of FACET_DIRS) {
245
- const srcDir = join(extractedTakt, options.lang, dir);
282
+ // pieces
283
+ const piecesSrcDry = join(extractedTakt, options.lang, PIECE_DIR);
284
+ if (existsSync(piecesSrcDry)) {
285
+ for (const file of collectFiles(piecesSrcDry, piecesSrcDry)) {
286
+ console.log(msg.dryRunItem(join(TARGET_DIR, PIECE_DIR, file)));
287
+ }
288
+ }
289
+ // facets
290
+ for (const facetType of FACET_TYPES) {
291
+ const srcDir = join(extractedTakt, options.lang, srcFacetPath(facetType));
246
292
  if (existsSync(srcDir)) {
247
- for (const file of collectFiles(srcDir, join(extractedTakt, options.lang))) {
248
- console.log(msg.dryRunItem(join(TARGET_DIR, file)));
293
+ const destPrefix = destFacetPath(facetType, resolvedLayout);
294
+ for (const file of collectFiles(srcDir, srcDir)) {
295
+ console.log(msg.dryRunItem(join(TARGET_DIR, destPrefix, file)));
249
296
  }
250
297
  }
251
298
  }
@@ -275,14 +322,32 @@ export async function install(options) {
275
322
  info(isUpdate ? msg.updating : msg.installing);
276
323
  mkdirSync(targetPath, { recursive: true });
277
324
  const allFiles = {};
278
- for (const dir of FACET_DIRS) {
279
- const srcDir = join(extractedTakt, options.lang, dir);
325
+ // pieces(legacy時はsync前にソースのパスを書き換え)
326
+ const piecesSrc = join(extractedTakt, options.lang, PIECE_DIR);
327
+ if (existsSync(piecesSrc)) {
328
+ const piecesDest = join(targetPath, PIECE_DIR);
329
+ if (!isUpdate && existsSync(piecesDest)) {
330
+ rmSync(piecesDest, { recursive: true });
331
+ }
332
+ let effectiveSrc = piecesSrc;
333
+ if (resolvedLayout === "legacy") {
334
+ const legacyTmp = join(tmpDir, "legacy-pieces");
335
+ cpSync(piecesSrc, legacyTmp, { recursive: true });
336
+ rewritePiecePathsForLegacy(legacyTmp);
337
+ effectiveSrc = legacyTmp;
338
+ }
339
+ const result = syncDirectory(effectiveSrc, piecesDest, effectiveSrc, piecesDest, isUpdate ? manifest : null, msg, options.cwd);
340
+ Object.assign(allFiles, result.files);
341
+ }
342
+ // facets
343
+ for (const facetType of FACET_TYPES) {
344
+ const srcDir = join(extractedTakt, options.lang, srcFacetPath(facetType));
280
345
  if (existsSync(srcDir)) {
281
- const destDir = join(targetPath, dir);
346
+ const destDir = join(targetPath, destFacetPath(facetType, resolvedLayout));
282
347
  if (!isUpdate && existsSync(destDir)) {
283
348
  rmSync(destDir, { recursive: true });
284
349
  }
285
- const result = syncDirectory(srcDir, destDir, join(extractedTakt, options.lang), targetPath, isUpdate ? manifest : null, msg, options.cwd);
350
+ const result = syncDirectory(srcDir, destDir, srcDir, destDir, isUpdate ? manifest : null, msg, options.cwd);
286
351
  Object.assign(allFiles, result.files);
287
352
  }
288
353
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-takt-sdd",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Installer for takt-sdd: Spec-Driven Development workflow for takt",
5
5
  "type": "module",
6
6
  "bin": {