ziku 0.21.1 → 0.21.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.
@@ -0,0 +1,3 @@
1
+ import { c as hashContent, l as hashFiles } from "./index.mjs";
2
+
3
+ export { hashFiles };
package/dist/index.mjs CHANGED
@@ -17,13 +17,14 @@ import { match } from "ts-pattern";
17
17
  import { execFileSync } from "node:child_process";
18
18
  import { Octokit } from "@octokit/rest";
19
19
  import { createHash } from "node:crypto";
20
+ import { z as z$1 } from "zod/v4";
20
21
 
21
22
  //#region rolldown:runtime
22
23
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
23
24
 
24
25
  //#endregion
25
26
  //#region package.json
26
- var version$2 = "0.21.1";
27
+ var version$2 = "0.21.3";
27
28
 
28
29
  //#endregion
29
30
  //#region src/modules/schemas.ts
@@ -869,7 +870,7 @@ function getEffectivePatterns(_moduleId, modulePatterns, config) {
869
870
  *
870
871
  * 削除条件: ziku が別の UI フレームワーク(ink 等)に移行する場合。
871
872
  */
872
- const version$1 = "0.21.1";
873
+ const version$1 = "0.21.3";
873
874
  /** CLI の開始表示 */
874
875
  function intro(command) {
875
876
  const title = command ? `ziku ${command}` : "ziku";
@@ -2037,7 +2038,7 @@ async function hashFiles(dir, patterns) {
2037
2038
 
2038
2039
  //#endregion
2039
2040
  //#region src/commands/init.ts
2040
- const version = "0.21.1";
2041
+ const version = "0.21.3";
2041
2042
  const initCommand = defineCommand({
2042
2043
  meta: {
2043
2044
  name: "ziku",
@@ -2309,6 +2310,30 @@ async function saveConfig(targetDir, config) {
2309
2310
  //#endregion
2310
2311
  //#region src/utils/merge.ts
2311
2312
  /**
2313
+ * 3-way マージにおけるベース(共通祖先)のファイル内容。
2314
+ *
2315
+ * 背景: threeWayMerge の引数は全て string だが、base/local/template を
2316
+ * 入れ違えるとサイレントに誤った結果を返す(#148 で発生)。
2317
+ * Zod brand で型レベルで区別し、取り違えをコンパイルエラーにする。
2318
+ */
2319
+ const BaseContent = z$1.string().brand("BaseContent");
2320
+ /** ローカル側(ユーザー)のファイル内容。コンフリクト時に優先される側。 */
2321
+ const LocalContent = z$1.string().brand("LocalContent");
2322
+ /** テンプレート側のファイル内容。ローカルに適用される変更の源。 */
2323
+ const TemplateContent = z$1.string().brand("TemplateContent");
2324
+ /** string を BaseContent にブランドする */
2325
+ function asBaseContent(s) {
2326
+ return BaseContent.parse(s);
2327
+ }
2328
+ /** string を LocalContent にブランドする */
2329
+ function asLocalContent(s) {
2330
+ return LocalContent.parse(s);
2331
+ }
2332
+ /** string を TemplateContent にブランドする */
2333
+ function asTemplateContent(s) {
2334
+ return TemplateContent.parse(s);
2335
+ }
2336
+ /**
2312
2337
  * base/local/template のハッシュを比較し、各ファイルを分類する。
2313
2338
  *
2314
2339
  * 背景: pull/push 時にファイルごとの処理方法(自動上書き・マージ・スキップ等)を
@@ -2358,10 +2383,11 @@ function classifyFiles(opts) {
2358
2383
  * ファイル構造を壊さずにマージできる。テキストファイルは fuzz factor や
2359
2384
  * hunk 単位のマーカーで精度を上げる。
2360
2385
  *
2361
- * @param filePath ファイルパス(拡張子でマージ戦略を選択)
2386
+ * result の内容は local をベースにし、template 側の変更を適用したもの。
2387
+ * コンフリクト時は local 側の値が保持される。
2362
2388
  */
2363
- function threeWayMerge(base, local, template, filePath) {
2364
- if (local === template) return {
2389
+ function threeWayMerge({ base, local, template, filePath }) {
2390
+ if (String(local) === String(template)) return {
2365
2391
  content: local,
2366
2392
  hasConflicts: false,
2367
2393
  conflictDetails: []
@@ -2605,12 +2631,6 @@ function tryApplyHunk(localLines, hunk) {
2605
2631
  return newLines;
2606
2632
  }
2607
2633
  /**
2608
- * base/local/template の3つの内容から 3-way マージを実行する。
2609
- * (後方互換性のためのラッパー)
2610
- *
2611
- * @deprecated filePath を渡す新しい threeWayMerge を使用してください
2612
- */
2613
- /**
2614
2634
  * ファイル内容にコンフリクトマーカーが含まれるかを検出する。
2615
2635
  *
2616
2636
  * 背景: マージ後のファイルにユーザーが手動解決すべきコンフリクトが
@@ -2734,7 +2754,12 @@ const pullCommand = defineCommand({
2734
2754
  const templateContent = await readFile(join(templateDir, file), "utf-8");
2735
2755
  let baseContent = "";
2736
2756
  if (baseTemplateDir && existsSync(join(baseTemplateDir, file))) baseContent = await readFile(join(baseTemplateDir, file), "utf-8");
2737
- const result = threeWayMerge(baseContent, localContent, templateContent, file);
2757
+ const result = threeWayMerge({
2758
+ base: asBaseContent(baseContent),
2759
+ local: asLocalContent(localContent),
2760
+ template: asTemplateContent(templateContent),
2761
+ filePath: file
2762
+ });
2738
2763
  await writeFile(join(targetDir, file), result.content, "utf-8");
2739
2764
  if (result.hasConflicts) {
2740
2765
  unresolvedConflicts.push(file);
@@ -3337,11 +3362,12 @@ const pushCommand = defineCommand({
3337
3362
  if (localAdditions.newModuleIds.length > 0) log.info(`Detected ${localAdditions.newModuleIds.length} new module(s) from local: ${localAdditions.newModuleIds.join(", ")}`);
3338
3363
  }
3339
3364
  const mergedContents = /* @__PURE__ */ new Map();
3340
- if (config.baseHashes) {
3341
- const { hashFiles: hashFiles$1 } = await import("./hash-DonjAgHQ.mjs");
3342
- const { classifyFiles: classifyFiles$1 } = await import("./merge-DFEjeYIq.mjs");
3343
- const { getModuleById: getModuleById$1 } = await import("./modules-DkQe-r1d.mjs");
3344
- const { getEffectivePatterns: getEffectivePatterns$1 } = await import("./patterns-C3oCRYgX.mjs");
3365
+ let pushableFilePaths = /* @__PURE__ */ new Set();
3366
+ {
3367
+ const { hashFiles: hashFiles$1 } = await import("./hash-CjblHutQ.mjs");
3368
+ const { classifyFiles: classifyFiles$1 } = await import("./merge-CPx9nRrL.mjs");
3369
+ const { getModuleById: getModuleById$1 } = await import("./modules-DlNMFNLz.mjs");
3370
+ const { getEffectivePatterns: getEffectivePatterns$1 } = await import("./patterns-CxgZLnrY.mjs");
3345
3371
  const allPatterns = [];
3346
3372
  for (const moduleId of effectiveModuleIds) {
3347
3373
  const mod = getModuleById$1(moduleId, moduleList);
@@ -3353,19 +3379,25 @@ const pushCommand = defineCommand({
3353
3379
  const templateHashes = await hashFiles$1(templateDir, allPatterns);
3354
3380
  const localHashes = await hashFiles$1(targetDir, allPatterns);
3355
3381
  const classification = classifyFiles$1({
3356
- baseHashes: config.baseHashes,
3382
+ baseHashes: config.baseHashes ?? {},
3357
3383
  localHashes,
3358
3384
  templateHashes
3359
3385
  });
3386
+ for (const file of classification.localOnly) pushableFilePaths.add(file);
3387
+ for (const file of classification.conflicts) pushableFilePaths.add(file);
3388
+ if (classification.autoUpdate.length > 0) {
3389
+ log.info(`Skipping ${classification.autoUpdate.length} file(s) only changed in template (use \`ziku pull\` to sync):`);
3390
+ for (const file of classification.autoUpdate) log.message(` ${pc$1.dim("↓")} ${pc$1.dim(file)}`);
3391
+ }
3360
3392
  if (classification.conflicts.length > 0) {
3361
- const { threeWayMerge: threeWayMerge$1 } = await import("./merge-DFEjeYIq.mjs");
3393
+ const { threeWayMerge: threeWayMerge$1, asBaseContent: asBaseContent$1, asLocalContent: asLocalContent$1, asTemplateContent: asTemplateContent$1 } = await import("./merge-CPx9nRrL.mjs");
3362
3394
  const baseInfo = config.baseRef ? `since ${pc$1.bold(config.baseRef.slice(0, 7))} (your last sync)` : "since your last pull/init";
3363
3395
  log.warn(`Template updated ${baseInfo} — ${classification.conflicts.length} conflict(s) detected, attempting auto-merge...`);
3364
3396
  let baseTemplateDir;
3365
3397
  let baseCleanup;
3366
3398
  if (config.baseRef) try {
3367
3399
  log.info(`Downloading base version (${config.baseRef.slice(0, 7)}...) for merge...`);
3368
- const { downloadTemplateToTemp: downloadBase } = await import("./template-BLwXZEZq.mjs");
3400
+ const { downloadTemplateToTemp: downloadBase } = await import("./template-CPgSJ67F.mjs");
3369
3401
  const baseResult = await downloadBase(targetDir, `gh:${config.source.owner}/${config.source.repo}#${config.baseRef}`);
3370
3402
  baseTemplateDir = baseResult.templateDir;
3371
3403
  baseCleanup = baseResult.cleanup;
@@ -3381,7 +3413,12 @@ const pushCommand = defineCommand({
3381
3413
  let baseContent;
3382
3414
  if (baseTemplateDir && existsSync(join(baseTemplateDir, file))) baseContent = await readFile(join(baseTemplateDir, file), "utf-8");
3383
3415
  if (baseContent) {
3384
- const result$1 = threeWayMerge$1(baseContent, templateContent, localContent, file);
3416
+ const result$1 = threeWayMerge$1({
3417
+ base: asBaseContent$1(baseContent),
3418
+ local: asLocalContent$1(localContent),
3419
+ template: asTemplateContent$1(templateContent),
3420
+ filePath: file
3421
+ });
3385
3422
  if (!result$1.hasConflicts) {
3386
3423
  mergedContents.set(file, result$1.content);
3387
3424
  autoMerged.push(file);
@@ -3430,7 +3467,7 @@ const pushCommand = defineCommand({
3430
3467
  config,
3431
3468
  moduleList
3432
3469
  }));
3433
- let pushableFiles = getPushableFiles(diff);
3470
+ let pushableFiles = diff.files.filter((f) => (f.type === "added" || f.type === "modified") && pushableFilePaths.has(f.path));
3434
3471
  if (pushableFiles.length === 0 && !updatedModulesContent) {
3435
3472
  log.info("No changes to push");
3436
3473
  log.step("Current status:");
@@ -3785,4 +3822,4 @@ async function run() {
3785
3822
  run();
3786
3823
 
3787
3824
  //#endregion
3788
- export { modulesFileExists as C, loadModulesFile as S, getModuleById as _, hashContent as a, addPatternToModulesFileWithCreate as b, buildTemplateSource as c, fetchTemplates as d, writeFileWithStrategy as f, defaultModules as g, resolvePatterns as h, threeWayMerge as i, copyFile as l, matchesPatterns as m, hasConflictMarkers as n, hashFiles as o, getEffectivePatterns as p, mergeJsonContent as r, TEMPLATE_SOURCE as s, classifyFiles as t, downloadTemplateToTemp as u, getPatternsByModuleIds as v, saveModulesFile as w, getModulesFilePath as x, addPatternToModulesFile as y };
3825
+ export { addPatternToModulesFileWithCreate as C, saveModulesFile as D, modulesFileExists as E, addPatternToModulesFile as S, loadModulesFile as T, matchesPatterns as _, hasConflictMarkers as a, getModuleById as b, hashContent as c, buildTemplateSource as d, copyFile as f, getEffectivePatterns as g, writeFileWithStrategy as h, classifyFiles as i, hashFiles as l, fetchTemplates as m, asLocalContent as n, mergeJsonContent as o, downloadTemplateToTemp as p, asTemplateContent as r, threeWayMerge as s, asBaseContent as t, TEMPLATE_SOURCE as u, resolvePatterns as v, getModulesFilePath as w, getPatternsByModuleIds as x, defaultModules as y };
@@ -0,0 +1,3 @@
1
+ import { a as hasConflictMarkers, i as classifyFiles, n as asLocalContent, o as mergeJsonContent, r as asTemplateContent, s as threeWayMerge, t as asBaseContent } from "./index.mjs";
2
+
3
+ export { asBaseContent, asLocalContent, asTemplateContent, classifyFiles, threeWayMerge };
@@ -0,0 +1,3 @@
1
+ import { C as addPatternToModulesFileWithCreate, D as saveModulesFile, E as modulesFileExists, S as addPatternToModulesFile, T as loadModulesFile, b as getModuleById, w as getModulesFilePath, x as getPatternsByModuleIds, y as defaultModules } from "./index.mjs";
2
+
3
+ export { getModuleById };
@@ -0,0 +1,3 @@
1
+ import { _ as matchesPatterns, g as getEffectivePatterns, v as resolvePatterns } from "./index.mjs";
2
+
3
+ export { getEffectivePatterns };
@@ -0,0 +1,3 @@
1
+ import { d as buildTemplateSource, f as copyFile, h as writeFileWithStrategy, m as fetchTemplates, p as downloadTemplateToTemp, u as TEMPLATE_SOURCE } from "./index.mjs";
2
+
3
+ export { downloadTemplateToTemp };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziku",
3
- "version": "0.21.1",
3
+ "version": "0.21.3",
4
4
  "description": "Interactive CLI to scaffold development environment templates",
5
5
  "repository": {
6
6
  "type": "git",
@@ -60,7 +60,7 @@
60
60
  "test": "vitest",
61
61
  "test:run": "vitest run",
62
62
  "test:coverage": "vitest run --coverage",
63
- "check": "npm run format:check && npm run lint && npm run build && npm run test:run && npm run docs:check",
63
+ "check": "npm run format:check && npm run lint && npm run typecheck && npm run build && npm run test:run && npm run docs:check",
64
64
  "docs": "npx tsx scripts/generate-readme.ts",
65
65
  "docs:check": "npx tsx scripts/generate-readme.ts --check"
66
66
  }
@@ -1,3 +0,0 @@
1
- import { a as hashContent, o as hashFiles } from "./index.mjs";
2
-
3
- export { hashFiles };
@@ -1,3 +0,0 @@
1
- import { i as threeWayMerge, n as hasConflictMarkers, r as mergeJsonContent, t as classifyFiles } from "./index.mjs";
2
-
3
- export { classifyFiles, threeWayMerge };
@@ -1,3 +0,0 @@
1
- import { C as modulesFileExists, S as loadModulesFile, _ as getModuleById, b as addPatternToModulesFileWithCreate, g as defaultModules, v as getPatternsByModuleIds, w as saveModulesFile, x as getModulesFilePath, y as addPatternToModulesFile } from "./index.mjs";
2
-
3
- export { getModuleById };
@@ -1,3 +0,0 @@
1
- import { h as resolvePatterns, m as matchesPatterns, p as getEffectivePatterns } from "./index.mjs";
2
-
3
- export { getEffectivePatterns };
@@ -1,3 +0,0 @@
1
- import { c as buildTemplateSource, d as fetchTemplates, f as writeFileWithStrategy, l as copyFile, s as TEMPLATE_SOURCE, u as downloadTemplateToTemp } from "./index.mjs";
2
-
3
- export { downloadTemplateToTemp };