qfai 0.7.0 → 0.7.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/README.md CHANGED
@@ -48,7 +48,7 @@ npx qfai report
48
48
 
49
49
  ## できること
50
50
 
51
- - `npx qfai init` によるテンプレート生成(specs/contracts に加え、`.qfai/require/README.md`、`.qfai/rules/pnpm.md`、`.qfai/prompts/require-to-spec.md`、`.qfai/prompts/qfai-generate-test-globs.md`、`.qfai/prompts/qfai-maintain-traceability.md`、`.qfai/prompts/qfai-maintain-contracts.md`、`.qfai/prompts/qfai-classify-change.md`、`.qfai/promptpack/` を含む)
51
+ - `npx qfai init` によるテンプレート生成(specs/contracts に加え、`.qfai/require/README.md`、`.qfai/rules/pnpm.md`、`.qfai/prompts/**`、`.qfai/prompts.local/README.md`、`.qfai/promptpack/` を含む)
52
52
  - `npx qfai validate` による `.qfai/` 内ドキュメントの整合性・トレーサビリティ検査
53
53
  - `npx qfai validate` による SC→Test 参照の検証(`validation.traceability.testFileGlobs` に一致するテストファイルから `QFAI:SC-xxxx` を抽出)
54
54
  - `npx qfai doctor` による設定/探索/パス/glob/validate.json の事前診断
@@ -61,6 +61,15 @@ npx qfai report
61
61
  `validate` は `--fail-on` / `--strict` によって CI ゲート化できます。`validate` は常に `.qfai/out/validate.json`(`output.validateJsonPath`)へ JSON を出力します。`--format` は画面表示(text/github)のみを制御します。`--format github` はアノテーションの上限と重複排除を行い、先頭にサマリを出します(全量は `validate.json` か `--format text` を参照)。
62
62
  `report` は `.qfai/out/validate.json` を既定入力とし、`--in` で上書きできます(優先順位: CLI > config)。`--run-validate` を指定すると validate を実行してから report を生成します。出力先は `--out` で変更できます(`--format json` の場合は `.qfai/out/report.json`)。
63
63
  `doctor` は validate/report の前段で設定/探索/パス/glob/validate.json を診断します。`--format text|json`、`--out` をサポートし、診断のみ(修復はしません)。`--fail-on warning|error` を指定すると該当 severity 以上で exit 1(未指定は常に exit 0)になります。
64
+
65
+ ### Prompts Overlay(v0.7 以降の方針)
66
+
67
+ QFAI が提供するプロンプト資産は次の 2 つに分離します。
68
+
69
+ - `.qfai/prompts/**`: QFAI 標準資産(更新や `qfai init` 再実行で上書きされ得る。利用者編集は非推奨・非サポート)
70
+ - `.qfai/prompts.local/**`: 利用者カスタム資産(QFAI はここを上書きしない)
71
+
72
+ 同じ相対パスのファイルがある場合は `.qfai/prompts.local` を優先して参照する運用とします。
64
73
  `report.json` は非契約(experimental / internal)として扱います。外部 consumer は依存しないでください。フィールドは例であり固定ではありません。短い例:
65
74
 
66
75
  ```json
@@ -80,7 +89,7 @@ doctor(text)の例:
80
89
  ```text
81
90
  qfai doctor: root=. config=qfai.config.yaml (found)
82
91
  [ok] config.search: qfai.config.yaml found
83
- summary: ok=10 warning=2 error=0
92
+ summary: ok=10 info=1 warning=2 error=0
84
93
  ```
85
94
 
86
95
  doctor の JSON も非契約(内部形式。将来予告なく変更あり)です。フィールドは例であり固定ではありません。短い例:
@@ -221,6 +230,8 @@ qfai.config.yaml
221
230
  qfai-maintain-traceability.md
222
231
  qfai-maintain-contracts.md
223
232
  qfai-classify-change.md
233
+ prompts.local/
234
+ README.md
224
235
  contracts/
225
236
  README.md
226
237
  api/
@@ -24,7 +24,8 @@ npx qfai report
24
24
  - `contracts/` : UI / API / DB 契約を置く場所
25
25
  - `require/` : 既存要件の集約(validate 対象外)
26
26
  - `rules/` : 規約・運用ルール
27
- - `prompts/` : 生成プロンプト資産(自動読取はしない)
27
+ - `prompts/` : QFAI 標準のプロンプト資産(自動読取はしない。更新や再 init で上書きされ得る)
28
+ - `prompts.local/` : 利用者カスタムのプロンプト資産(存在する場合は overlay でこちらを優先して読む運用)
28
29
  - `promptpack/` : PromptPack(SSOT、運用ルール/観点の正本)
29
30
  - `out/` : `validate` / `report` の出力先(gitignore 推奨)
30
31
 
@@ -36,6 +37,7 @@ npx qfai report
36
37
  - `rules/conventions.md`
37
38
  - `rules/pnpm.md`
38
39
  - `prompts/README.md`
40
+ - `prompts.local/README.md`
39
41
  - `prompts/require-to-spec.md`
40
42
  - `prompts/qfai-generate-test-globs.md`
41
43
  - `prompts/qfai-maintain-traceability.md`
@@ -54,6 +56,12 @@ npx qfai report
54
56
 
55
57
  `prompts/` は **人間が手動で使う資産**です。現時点では自動読取は行いません(将来のバージョンで CLI 連携を検討します)。
56
58
 
59
+ v0.7 以降、プロンプト資産のカスタマイズは `.qfai/prompts.local/**` に集約します(overlay 運用)。
60
+
61
+ - `.qfai/prompts/**` は QFAI 標準資産であり、更新や `qfai init` 再実行で上書きされ得ます
62
+ - 利用者が `.qfai/prompts/**` を直接編集することは非推奨・非サポートです
63
+ - 変更したい場合は同一相対パスで `.qfai/prompts.local/**` に置いて上書きしてください
64
+
57
65
  例:
58
66
 
59
67
  - Copilot: `.github/copilot-instructions.md` に要旨を転記
@@ -2,12 +2,22 @@
2
2
 
3
3
  このディレクトリのプロンプトは **手動で使う資産**です。現時点では自動読取は行いません(将来のバージョンで CLI 連携を検討します)。
4
4
 
5
+ 重要: `.qfai/prompts/**` は **QFAI 標準資産**です。QFAI のアップデートや `qfai init` の再実行により **上書きされ得ます**。
6
+ 利用者が直接編集することは **非推奨・非サポート(ほぼ禁止)**です。変更したい場合は `.qfai/prompts.local/**` に同一相対パスで置いて overlay してください。
7
+
5
8
  ## 目的
6
9
 
7
10
  - Spec から overview / Business Flow を生成するための素材
8
11
  - トレーサビリティ/契約/変更区分の運用支援(CIで止めない領域)
9
12
  - 将来(v0.9)の adapter/emit 実装に備えた配布物
10
13
 
14
+ ## Overlay(prompts.local)
15
+
16
+ カスタムしたい場合は、次の優先順位で参照する運用とします。
17
+
18
+ 1. `.qfai/prompts.local/<relativePath>`
19
+ 2. `.qfai/prompts/<relativePath>`
20
+
11
21
  ## プロンプト一覧
12
22
 
13
23
  - `makeOverview.md`: Spec 一覧(overview)生成
@@ -0,0 +1,25 @@
1
+ # Prompts Local(利用者カスタム / Overlay)
2
+
3
+ このディレクトリは **利用者が自由に編集・追加できるプロンプト資産**の置き場です。
4
+
5
+ QFAI v0.7 以降は、プロンプト資産のカスタマイズ手段を **overlay(prompts.local 優先)**に一本化します。
6
+
7
+ ## Overlay ルール(重要)
8
+
9
+ 同じ相対パスのファイルが存在する場合、次の優先順位で参照する運用とします。
10
+
11
+ 1. `.qfai/prompts.local/<relativePath>`(存在すればこちらを優先)
12
+ 2. `.qfai/prompts/<relativePath>`(無ければ base を参照)
13
+
14
+ 例:
15
+
16
+ - base: `.qfai/prompts/require-to-spec.md`
17
+ - local override: `.qfai/prompts.local/require-to-spec.md`
18
+
19
+ → `prompts.local` に同じ相対パスで置けば、以降は local を読む運用にできます。
20
+
21
+ ## 重要な注意(サポート境界)
22
+
23
+ - `.qfai/prompts/**` は **QFAI 標準資産**です(更新や `qfai init` の再実行で上書きされ得ます)。
24
+ - 利用者が `.qfai/prompts/**` を直接編集することは **非推奨・非サポート(ほぼ禁止)**です。
25
+ - 変更したい場合は、対象ファイルを `prompts.local` にコピーして上書きしてください。
@@ -889,8 +889,8 @@ var import_promises6 = require("fs/promises");
889
889
  var import_node_path6 = __toESM(require("path"), 1);
890
890
  var import_node_url = require("url");
891
891
  async function resolveToolVersion() {
892
- if ("0.7.0".length > 0) {
893
- return "0.7.0";
892
+ if ("0.7.1".length > 0) {
893
+ return "0.7.1";
894
894
  }
895
895
  try {
896
896
  const packagePath = resolvePackageJsonPath();
@@ -921,7 +921,7 @@ function addCheck(checks, check) {
921
921
  checks.push(check);
922
922
  }
923
923
  function summarize(checks) {
924
- const summary = { ok: 0, warning: 0, error: 0 };
924
+ const summary = { ok: 0, info: 0, warning: 0, error: 0 };
925
925
  for (const check of checks) {
926
926
  summary[check.severity] += 1;
927
927
  }
@@ -993,6 +993,20 @@ async function createDoctorData(options) {
993
993
  message: ok ? `${key} exists` : `${key} is missing (did you run 'qfai init'?)`,
994
994
  details: { path: toRelativePath(root, resolved) }
995
995
  });
996
+ if (key === "promptsDir") {
997
+ const promptsLocalDir = import_node_path7.default.join(
998
+ import_node_path7.default.dirname(resolved),
999
+ `${import_node_path7.default.basename(resolved)}.local`
1000
+ );
1001
+ const found = await exists4(promptsLocalDir);
1002
+ addCheck(checks, {
1003
+ id: "paths.promptsLocalDir",
1004
+ severity: "info",
1005
+ title: "Prompts overlay (prompts.local)",
1006
+ message: found ? "prompts.local exists (overlay can be used)" : "prompts.local is optional (create it to override prompts)",
1007
+ details: { path: toRelativePath(root, promptsLocalDir) }
1008
+ });
1009
+ }
996
1010
  }
997
1011
  const specsRoot = resolvePath(root, config, "specsDir");
998
1012
  const entries = await collectSpecEntries(specsRoot);
@@ -1191,7 +1205,7 @@ function formatDoctorText(data) {
1191
1205
  lines.push(`[${check.severity}] ${check.id}: ${check.message}`);
1192
1206
  }
1193
1207
  lines.push(
1194
- `summary: ok=${data.summary.ok} warning=${data.summary.warning} error=${data.summary.error}`
1208
+ `summary: ok=${data.summary.ok} info=${data.summary.info} warning=${data.summary.warning} error=${data.summary.error}`
1195
1209
  );
1196
1210
  return lines.join("\n");
1197
1211
  }
@@ -1240,9 +1254,22 @@ async function copyFiles(files, sourceRoot, destRoot, options) {
1240
1254
  const copied = [];
1241
1255
  const skipped = [];
1242
1256
  const conflicts = [];
1257
+ const protectPrefixes = (options.protect ?? []).map((p) => p.replace(/^[\\/]+/, "").replace(/[\\/]+$/, "")).filter((p) => p.length > 0).map((p) => p + import_node_path9.default.sep);
1258
+ const isProtectedRelative = (relative) => {
1259
+ if (protectPrefixes.length === 0) {
1260
+ return false;
1261
+ }
1262
+ const normalized = relative.replace(/[\\/]+/g, import_node_path9.default.sep);
1263
+ return protectPrefixes.some(
1264
+ (prefix) => normalized === prefix.slice(0, -1) || normalized.startsWith(prefix)
1265
+ );
1266
+ };
1243
1267
  if (!options.force) {
1244
1268
  for (const file of files) {
1245
1269
  const relative = import_node_path9.default.relative(sourceRoot, file);
1270
+ if (isProtectedRelative(relative)) {
1271
+ continue;
1272
+ }
1246
1273
  const dest = import_node_path9.default.join(destRoot, relative);
1247
1274
  if (!await shouldWrite(dest, options.force)) {
1248
1275
  conflicts.push(dest);
@@ -1255,7 +1282,8 @@ async function copyFiles(files, sourceRoot, destRoot, options) {
1255
1282
  for (const file of files) {
1256
1283
  const relative = import_node_path9.default.relative(sourceRoot, file);
1257
1284
  const dest = import_node_path9.default.join(destRoot, relative);
1258
- if (!await shouldWrite(dest, options.force)) {
1285
+ const forceForThisFile = isProtectedRelative(relative) ? false : options.force;
1286
+ if (!await shouldWrite(dest, forceForThisFile)) {
1259
1287
  skipped.push(dest);
1260
1288
  continue;
1261
1289
  }
@@ -1350,7 +1378,8 @@ async function runInit(options) {
1350
1378
  });
1351
1379
  const qfaiResult = await copyTemplateTree(qfaiAssets, destQfai, {
1352
1380
  force: options.force,
1353
- dryRun: options.dryRun
1381
+ dryRun: options.dryRun,
1382
+ protect: ["prompts.local"]
1354
1383
  });
1355
1384
  report(
1356
1385
  [...rootResult.copied, ...qfaiResult.copied],
@@ -3664,235 +3693,9 @@ async function writeValidationResult(root, outputPath, result) {
3664
3693
  `, "utf-8");
3665
3694
  }
3666
3695
 
3667
- // src/core/sync.ts
3696
+ // src/cli/commands/validate.ts
3668
3697
  var import_promises19 = require("fs/promises");
3669
3698
  var import_node_path19 = __toESM(require("path"), 1);
3670
- var import_node_crypto2 = require("crypto");
3671
- var import_node_url3 = require("url");
3672
- async function exists6(target) {
3673
- try {
3674
- await (0, import_promises19.access)(target);
3675
- return true;
3676
- } catch {
3677
- return false;
3678
- }
3679
- }
3680
- async function computeFileHash(filePath) {
3681
- const content = await (0, import_promises19.readFile)(filePath);
3682
- return (0, import_node_crypto2.createHash)("sha256").update(content).digest("hex");
3683
- }
3684
- async function collectFilesRecursive(dir, base) {
3685
- const result = [];
3686
- if (!await exists6(dir)) {
3687
- return result;
3688
- }
3689
- const entries = await (0, import_promises19.readdir)(dir, { withFileTypes: true });
3690
- for (const entry of entries) {
3691
- const fullPath = import_node_path19.default.join(dir, entry.name);
3692
- if (entry.isDirectory()) {
3693
- const nested = await collectFilesRecursive(fullPath, base);
3694
- result.push(...nested);
3695
- } else if (entry.isFile()) {
3696
- const relative = import_node_path19.default.relative(base, fullPath);
3697
- result.push(relative);
3698
- }
3699
- }
3700
- return result;
3701
- }
3702
- function resolveAssetsPath() {
3703
- const base = __filename;
3704
- const basePath = base.startsWith("file:") ? (0, import_node_url3.fileURLToPath)(base) : base;
3705
- return import_node_path19.default.resolve(
3706
- import_node_path19.default.dirname(basePath),
3707
- "../../assets/init/.qfai/promptpack"
3708
- );
3709
- }
3710
- async function copyDirRecursive(srcDir, destDir) {
3711
- await (0, import_promises19.mkdir)(destDir, { recursive: true });
3712
- const entries = await (0, import_promises19.readdir)(srcDir, { withFileTypes: true });
3713
- for (const entry of entries) {
3714
- const srcPath = import_node_path19.default.join(srcDir, entry.name);
3715
- const destPath = import_node_path19.default.join(destDir, entry.name);
3716
- if (entry.isDirectory()) {
3717
- await copyDirRecursive(srcPath, destPath);
3718
- } else if (entry.isFile()) {
3719
- await (0, import_promises19.copyFile)(srcPath, destPath);
3720
- }
3721
- }
3722
- }
3723
- async function createSyncData(options) {
3724
- const root = import_node_path19.default.resolve(options.root);
3725
- const version = await resolveToolVersion();
3726
- const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
3727
- const scope = "promptpack";
3728
- const assetsPromptPackPath = resolveAssetsPath();
3729
- const projectPromptPackPath = import_node_path19.default.join(root, ".qfai", "promptpack");
3730
- const diffs = [];
3731
- const assetsFiles = await collectFilesRecursive(
3732
- assetsPromptPackPath,
3733
- assetsPromptPackPath
3734
- );
3735
- const projectFiles = await collectFilesRecursive(
3736
- projectPromptPackPath,
3737
- projectPromptPackPath
3738
- );
3739
- const assetsSet = new Set(assetsFiles);
3740
- const projectSet = new Set(projectFiles);
3741
- for (const relativePath of assetsFiles) {
3742
- const assetsFilePath = import_node_path19.default.join(assetsPromptPackPath, relativePath);
3743
- const projectFilePath = import_node_path19.default.join(projectPromptPackPath, relativePath);
3744
- if (!projectSet.has(relativePath)) {
3745
- diffs.push({
3746
- filePath: relativePath,
3747
- status: "added",
3748
- reason: "File exists in assets but not in project"
3749
- });
3750
- } else {
3751
- const assetsHash = await computeFileHash(assetsFilePath);
3752
- const projectHash = await computeFileHash(projectFilePath);
3753
- if (assetsHash !== projectHash) {
3754
- diffs.push({
3755
- filePath: relativePath,
3756
- status: "changed",
3757
- reason: "Content differs between assets and project"
3758
- });
3759
- } else {
3760
- diffs.push({
3761
- filePath: relativePath,
3762
- status: "unchanged"
3763
- });
3764
- }
3765
- }
3766
- }
3767
- for (const relativePath of projectFiles) {
3768
- if (!assetsSet.has(relativePath)) {
3769
- diffs.push({
3770
- filePath: relativePath,
3771
- status: "removed",
3772
- reason: "File exists in project but not in assets (local extension)"
3773
- });
3774
- }
3775
- }
3776
- diffs.sort((a, b) => a.filePath.localeCompare(b.filePath));
3777
- const summary = {
3778
- added: diffs.filter((d) => d.status === "added").length,
3779
- removed: diffs.filter((d) => d.status === "removed").length,
3780
- changed: diffs.filter((d) => d.status === "changed").length,
3781
- unchanged: diffs.filter((d) => d.status === "unchanged").length
3782
- };
3783
- let exportPath;
3784
- if (options.mode === "export") {
3785
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
3786
- const baseTimestamp = `${timestamp}-${Date.now()}`;
3787
- const defaultOutDir = import_node_path19.default.join(root, ".qfai", ".sync");
3788
- const outBase = options.outPath ? import_node_path19.default.isAbsolute(options.outPath) ? options.outPath : import_node_path19.default.resolve(root, options.outPath) : defaultOutDir;
3789
- let exportDir;
3790
- for (let attempt = 0; attempt < 100; attempt += 1) {
3791
- const uniqueTimestamp = attempt === 0 ? baseTimestamp : `${baseTimestamp}-${attempt}`;
3792
- const exportParent = import_node_path19.default.join(outBase, uniqueTimestamp);
3793
- const candidate = import_node_path19.default.join(exportParent, "promptpack");
3794
- await (0, import_promises19.mkdir)(exportParent, { recursive: true });
3795
- try {
3796
- await (0, import_promises19.mkdir)(candidate);
3797
- exportDir = candidate;
3798
- break;
3799
- } catch (err) {
3800
- const code = err?.code;
3801
- if (code === "EEXIST") {
3802
- continue;
3803
- }
3804
- throw err;
3805
- }
3806
- }
3807
- if (!exportDir) {
3808
- throw new Error("Failed to allocate unique export directory");
3809
- }
3810
- await copyDirRecursive(assetsPromptPackPath, exportDir);
3811
- exportPath = toRelativePath(root, exportDir);
3812
- }
3813
- return {
3814
- tool: "qfai",
3815
- version,
3816
- generatedAt,
3817
- root: toRelativePath(process.cwd(), root),
3818
- mode: options.mode,
3819
- scope,
3820
- summary,
3821
- diffs,
3822
- ...exportPath ? { exportPath } : {}
3823
- };
3824
- }
3825
- function computeExitCode(data) {
3826
- const hasDiff = data.summary.added > 0 || data.summary.removed > 0 || data.summary.changed > 0;
3827
- return hasDiff ? 1 : 0;
3828
- }
3829
-
3830
- // src/cli/commands/sync.ts
3831
- var import_node_path20 = __toESM(require("path"), 1);
3832
- function formatSyncText(data) {
3833
- const lines = [];
3834
- lines.push(
3835
- `qfai sync: root=${data.root} mode=${data.mode} scope=${data.scope}`
3836
- );
3837
- lines.push("");
3838
- const diffs = data.diffs.filter((d) => d.status !== "unchanged");
3839
- if (diffs.length === 0) {
3840
- lines.push(
3841
- "No differences found. Project promptpack is in sync with assets."
3842
- );
3843
- } else {
3844
- lines.push("Differences:");
3845
- for (const diff of diffs) {
3846
- const statusMark = diff.status === "added" ? "[+]" : diff.status === "removed" ? "[-]" : "[~]";
3847
- lines.push(` ${statusMark} ${diff.filePath}`);
3848
- }
3849
- }
3850
- lines.push("");
3851
- lines.push(
3852
- `summary: added=${data.summary.added} removed=${data.summary.removed} changed=${data.summary.changed} unchanged=${data.summary.unchanged}`
3853
- );
3854
- if (data.exportPath) {
3855
- lines.push("");
3856
- lines.push(`exported to: ${data.exportPath}`);
3857
- lines.push("");
3858
- lines.push("Next steps:");
3859
- const absRoot = import_node_path20.default.resolve(process.cwd(), data.root);
3860
- const absExportPath = import_node_path20.default.resolve(absRoot, data.exportPath);
3861
- lines.push(
3862
- ` git diff --no-index ${import_node_path20.default.join(absRoot, ".qfai", "promptpack")} ${absExportPath}`
3863
- );
3864
- } else if (data.summary.added + data.summary.changed > 0) {
3865
- lines.push("");
3866
- lines.push("To export sync candidates:");
3867
- lines.push(" qfai sync --mode export");
3868
- }
3869
- return lines.join("\n");
3870
- }
3871
- function formatSyncJson(data) {
3872
- return JSON.stringify(data, null, 2);
3873
- }
3874
- async function runSync(options) {
3875
- try {
3876
- const data = await createSyncData({
3877
- root: options.root,
3878
- mode: options.mode,
3879
- ...options.outPath !== void 0 ? { outPath: options.outPath } : {}
3880
- });
3881
- const output = options.format === "json" ? formatSyncJson(data) : formatSyncText(data);
3882
- info(output);
3883
- if (options.mode === "export") {
3884
- return 0;
3885
- }
3886
- return computeExitCode(data);
3887
- } catch (err) {
3888
- error(`sync failed: ${err instanceof Error ? err.message : String(err)}`);
3889
- return 2;
3890
- }
3891
- }
3892
-
3893
- // src/cli/commands/validate.ts
3894
- var import_promises20 = require("fs/promises");
3895
- var import_node_path21 = __toESM(require("path"), 1);
3896
3699
 
3897
3700
  // src/cli/lib/failOn.ts
3898
3701
  function shouldFail(result, failOn) {
@@ -3907,7 +3710,7 @@ function shouldFail(result, failOn) {
3907
3710
 
3908
3711
  // src/cli/commands/validate.ts
3909
3712
  async function runValidate(options) {
3910
- const root = import_node_path21.default.resolve(options.root);
3713
+ const root = import_node_path19.default.resolve(options.root);
3911
3714
  const configResult = await loadConfig(root);
3912
3715
  const result = await validateProject(root, configResult);
3913
3716
  const normalized = normalizeValidationResult(root, result);
@@ -4024,12 +3827,12 @@ function issueKey(issue7) {
4024
3827
  }
4025
3828
  async function emitJson(result, root, jsonPath) {
4026
3829
  const abs = resolveJsonPath(root, jsonPath);
4027
- await (0, import_promises20.mkdir)(import_node_path21.default.dirname(abs), { recursive: true });
4028
- await (0, import_promises20.writeFile)(abs, `${JSON.stringify(result, null, 2)}
3830
+ await (0, import_promises19.mkdir)(import_node_path19.default.dirname(abs), { recursive: true });
3831
+ await (0, import_promises19.writeFile)(abs, `${JSON.stringify(result, null, 2)}
4029
3832
  `, "utf-8");
4030
3833
  }
4031
3834
  function resolveJsonPath(root, jsonPath) {
4032
- return import_node_path21.default.isAbsolute(jsonPath) ? jsonPath : import_node_path21.default.resolve(root, jsonPath);
3835
+ return import_node_path19.default.isAbsolute(jsonPath) ? jsonPath : import_node_path19.default.resolve(root, jsonPath);
4033
3836
  }
4034
3837
  var GITHUB_ANNOTATION_LIMIT = 100;
4035
3838
 
@@ -4046,8 +3849,6 @@ function parseArgs(argv, cwd) {
4046
3849
  reportRunValidate: false,
4047
3850
  doctorFormat: "text",
4048
3851
  validateFormat: "text",
4049
- syncFormat: "text",
4050
- syncMode: "check",
4051
3852
  strict: false,
4052
3853
  help: false
4053
3854
  };
@@ -4101,8 +3902,6 @@ function parseArgs(argv, cwd) {
4101
3902
  if (next) {
4102
3903
  if (command === "doctor") {
4103
3904
  options.doctorOut = next;
4104
- } else if (command === "sync") {
4105
- options.syncOut = next;
4106
3905
  } else {
4107
3906
  options.reportOut = next;
4108
3907
  }
@@ -4110,28 +3909,6 @@ function parseArgs(argv, cwd) {
4110
3909
  }
4111
3910
  i += 1;
4112
3911
  break;
4113
- case "--mode":
4114
- {
4115
- const next = args[i + 1];
4116
- if (!next) {
4117
- throw new Error(
4118
- '--mode option requires a value of "check" or "export"'
4119
- );
4120
- }
4121
- if (command !== "sync") {
4122
- throw new Error(
4123
- '--mode option is only supported for the "sync" command'
4124
- );
4125
- }
4126
- if (next !== "check" && next !== "export") {
4127
- throw new Error(
4128
- `Invalid value for --mode: "${next}". Expected "check" or "export".`
4129
- );
4130
- }
4131
- options.syncMode = next;
4132
- }
4133
- i += 1;
4134
- break;
4135
3912
  case "--in":
4136
3913
  {
4137
3914
  const next = args[i + 1];
@@ -4176,12 +3953,6 @@ function applyFormatOption(command, value, options) {
4176
3953
  }
4177
3954
  return;
4178
3955
  }
4179
- if (command === "sync") {
4180
- if (value === "text" || value === "json") {
4181
- options.syncFormat = value;
4182
- }
4183
- return;
4184
- }
4185
3956
  if (value === "md" || value === "json") {
4186
3957
  options.reportFormat = value;
4187
3958
  }
@@ -4241,18 +4012,6 @@ async function run(argv, cwd) {
4241
4012
  process.exitCode = exitCode;
4242
4013
  }
4243
4014
  return;
4244
- case "sync":
4245
- {
4246
- const resolvedRoot = await resolveRoot(options);
4247
- const exitCode = await runSync({
4248
- root: resolvedRoot,
4249
- mode: options.syncMode,
4250
- format: options.syncFormat,
4251
- ...options.syncOut !== void 0 ? { outPath: options.syncOut } : {}
4252
- });
4253
- process.exitCode = exitCode;
4254
- }
4255
- return;
4256
4015
  default:
4257
4016
  error(`Unknown command: ${command}`);
4258
4017
  info(usage());
@@ -4267,7 +4026,6 @@ Commands:
4267
4026
  validate \u4ED5\u69D8/\u5951\u7D04/\u53C2\u7167\u306E\u691C\u67FB
4268
4027
  report \u691C\u8A3C\u7D50\u679C\u3068\u96C6\u8A08\u3092\u51FA\u529B
4269
4028
  doctor \u8A2D\u5B9A/\u30D1\u30B9/\u51FA\u529B\u524D\u63D0\u306E\u8A3A\u65AD
4270
- sync PromptPack \u306E\u5DEE\u5206\u691C\u77E5\u30FB\u540C\u671F\u5019\u88DC\u66F8\u304D\u51FA\u3057
4271
4029
 
4272
4030
  Options:
4273
4031
  --root <path> \u5BFE\u8C61\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
@@ -4277,13 +4035,11 @@ Options:
4277
4035
  --dry-run \u5909\u66F4\u3092\u884C\u308F\u305A\u8868\u793A\u306E\u307F
4278
4036
  --format <text|github> validate \u306E\u51FA\u529B\u5F62\u5F0F
4279
4037
  --format <md|json> report \u306E\u51FA\u529B\u5F62\u5F0F
4280
- --format <text|json> doctor/sync \u306E\u51FA\u529B\u5F62\u5F0F
4038
+ --format <text|json> doctor \u306E\u51FA\u529B\u5F62\u5F0F
4281
4039
  --strict validate: warning \u4EE5\u4E0A\u3067 exit 1
4282
4040
  --fail-on <error|warning|never> validate: \u5931\u6557\u6761\u4EF6
4283
4041
  --fail-on <error|warning> doctor: \u5931\u6557\u6761\u4EF6
4284
- --mode <check|export> sync: \u52D5\u4F5C\u30E2\u30FC\u30C9\uFF08default: check\uFF09
4285
4042
  --out <path> report/doctor: \u51FA\u529B\u5148
4286
- --out <dir> sync: export \u306E\u51FA\u529B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\uFF08\u76F8\u5BFE/\u7D76\u5BFE\u3001export \u306E\u307F\uFF09
4287
4043
  --in <path> report: validate.json \u306E\u5165\u529B\u5148\uFF08config\u3088\u308A\u512A\u5148\uFF09
4288
4044
  --run-validate report: validate \u3092\u5B9F\u884C\u3057\u3066\u304B\u3089 report \u3092\u751F\u6210
4289
4045
  -h, --help \u30D8\u30EB\u30D7\u8868\u793A