qfai 1.0.3 → 1.0.5

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.
Files changed (99) hide show
  1. package/README.md +53 -74
  2. package/assets/init/.qfai/README.md +17 -82
  3. package/assets/init/.qfai/assistant/README.md +9 -0
  4. package/assets/init/.qfai/assistant/agents/README.md +34 -0
  5. package/assets/init/.qfai/assistant/agents/architect.md +73 -0
  6. package/assets/init/.qfai/assistant/agents/backend-engineer.md +73 -0
  7. package/assets/init/.qfai/assistant/agents/code-reviewer.md +73 -0
  8. package/assets/init/.qfai/assistant/agents/contract-designer.md +73 -0
  9. package/assets/init/.qfai/assistant/agents/devops-ci-engineer.md +73 -0
  10. package/assets/init/.qfai/assistant/agents/facilitator.md +74 -0
  11. package/assets/init/.qfai/assistant/agents/frontend-engineer.md +73 -0
  12. package/assets/init/.qfai/assistant/agents/interviewer.md +72 -0
  13. package/assets/init/.qfai/assistant/agents/planner.md +73 -0
  14. package/assets/init/.qfai/assistant/agents/qa-engineer.md +73 -0
  15. package/assets/init/.qfai/assistant/agents/requirements-analyst.md +73 -0
  16. package/assets/init/.qfai/assistant/agents/test-engineer.md +73 -0
  17. package/assets/init/.qfai/assistant/instructions/README.md +6 -0
  18. package/assets/init/.qfai/assistant/instructions/constitution.md +131 -0
  19. package/assets/init/.qfai/assistant/instructions/workflow.md +75 -0
  20. package/assets/init/.qfai/assistant/prompts/README.md +19 -0
  21. package/assets/init/.qfai/assistant/prompts/qfai-discuss.md +173 -0
  22. package/assets/init/.qfai/assistant/prompts/qfai-implement.md +239 -0
  23. package/assets/init/.qfai/assistant/prompts/qfai-pr.md +218 -0
  24. package/assets/init/.qfai/assistant/prompts/qfai-require.md +273 -0
  25. package/assets/init/.qfai/assistant/prompts/qfai-scenario-test.md +229 -0
  26. package/assets/init/.qfai/assistant/prompts/qfai-spec.md +287 -0
  27. package/assets/init/.qfai/assistant/prompts/qfai-unit-test.md +202 -0
  28. package/assets/init/.qfai/assistant/prompts/qfai-verify.md +231 -0
  29. package/assets/init/.qfai/assistant/prompts.local/README.md +6 -0
  30. package/assets/init/.qfai/assistant/steering/README.md +33 -0
  31. package/assets/init/.qfai/assistant/steering/product.md +32 -0
  32. package/assets/init/.qfai/assistant/steering/structure.md +34 -0
  33. package/assets/init/.qfai/assistant/steering/tech.md +37 -0
  34. package/assets/init/.qfai/contracts/README.md +7 -87
  35. package/assets/init/.qfai/contracts/api/README.md +8 -0
  36. package/assets/init/.qfai/contracts/db/README.md +8 -0
  37. package/assets/init/.qfai/contracts/ui/README.md +8 -0
  38. package/assets/init/.qfai/report/README.md +13 -0
  39. package/assets/init/.qfai/require/README.md +4 -26
  40. package/assets/init/.qfai/require/require.md +74 -0
  41. package/assets/init/.qfai/specs/README.md +6 -57
  42. package/assets/init/root/.github/workflows/qfai.yml +1 -1
  43. package/assets/init/root/qfai.config.yaml +3 -4
  44. package/dist/cli/index.cjs +313 -472
  45. package/dist/cli/index.cjs.map +1 -1
  46. package/dist/cli/index.mjs +295 -454
  47. package/dist/cli/index.mjs.map +1 -1
  48. package/dist/index.cjs +37 -63
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +0 -1
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.mjs +37 -63
  53. package/dist/index.mjs.map +1 -1
  54. package/package.json +1 -1
  55. package/assets/init/.qfai/contracts/api/api-0001-sample.yaml +0 -15
  56. package/assets/init/.qfai/contracts/db/db-0001-sample.sql +0 -7
  57. package/assets/init/.qfai/contracts/ui/assets/thema-001-facebook-like/assets.yaml +0 -6
  58. package/assets/init/.qfai/contracts/ui/assets/thema-001-facebook-like/palette.png +0 -0
  59. package/assets/init/.qfai/contracts/ui/assets/ui-0001-sample/assets.yaml +0 -6
  60. package/assets/init/.qfai/contracts/ui/assets/ui-0001-sample/snapshots/login__desktop__light__default.png +0 -0
  61. package/assets/init/.qfai/contracts/ui/thema-001-facebook-like.yml +0 -13
  62. package/assets/init/.qfai/contracts/ui/ui-0001-sample.yaml +0 -17
  63. package/assets/init/.qfai/out/README.md +0 -17
  64. package/assets/init/.qfai/promptpack/commands/implement.md +0 -8
  65. package/assets/init/.qfai/promptpack/commands/plan.md +0 -11
  66. package/assets/init/.qfai/promptpack/commands/release.md +0 -6
  67. package/assets/init/.qfai/promptpack/commands/review.md +0 -7
  68. package/assets/init/.qfai/promptpack/constitution.md +0 -15
  69. package/assets/init/.qfai/promptpack/modes/change.md +0 -5
  70. package/assets/init/.qfai/promptpack/modes/compatibility.md +0 -6
  71. package/assets/init/.qfai/promptpack/roles/qa.md +0 -4
  72. package/assets/init/.qfai/promptpack/roles/spec.md +0 -4
  73. package/assets/init/.qfai/promptpack/roles/test.md +0 -4
  74. package/assets/init/.qfai/promptpack/steering/compatibility-vs-change.md +0 -42
  75. package/assets/init/.qfai/promptpack/steering/naming.md +0 -7
  76. package/assets/init/.qfai/promptpack/steering/traceability.md +0 -25
  77. package/assets/init/.qfai/prompts/README.md +0 -70
  78. package/assets/init/.qfai/prompts/analyze/README.md +0 -21
  79. package/assets/init/.qfai/prompts/analyze/scenario_test_consistency.md +0 -8
  80. package/assets/init/.qfai/prompts/analyze/scenario_to_test.md +0 -56
  81. package/assets/init/.qfai/prompts/analyze/spec_contract_consistency.md +0 -8
  82. package/assets/init/.qfai/prompts/analyze/spec_scenario_consistency.md +0 -8
  83. package/assets/init/.qfai/prompts/analyze/spec_to_contract.md +0 -54
  84. package/assets/init/.qfai/prompts/analyze/spec_to_scenario.md +0 -56
  85. package/assets/init/.qfai/prompts/makeBusinessFlow.md +0 -34
  86. package/assets/init/.qfai/prompts/makeOverview.md +0 -27
  87. package/assets/init/.qfai/prompts/qfai-classify-change.md +0 -33
  88. package/assets/init/.qfai/prompts/qfai-generate-test-globs.md +0 -29
  89. package/assets/init/.qfai/prompts/qfai-maintain-contracts.md +0 -35
  90. package/assets/init/.qfai/prompts/qfai-maintain-traceability.md +0 -36
  91. package/assets/init/.qfai/prompts/require-to-spec.md +0 -41
  92. package/assets/init/.qfai/prompts.local/README.md +0 -31
  93. package/assets/init/.qfai/rules/conventions.md +0 -27
  94. package/assets/init/.qfai/rules/pnpm.md +0 -29
  95. package/assets/init/.qfai/samples/analyze/analysis.md +0 -38
  96. package/assets/init/.qfai/samples/analyze/input_bundle.md +0 -54
  97. package/assets/init/.qfai/specs/spec-0001/delta.md +0 -30
  98. package/assets/init/.qfai/specs/spec-0001/scenario.feature +0 -11
  99. package/assets/init/.qfai/specs/spec-0001/spec.md +0 -40
package/dist/index.d.cts CHANGED
@@ -53,7 +53,6 @@ type OrphanContractsPolicy = "error" | "warning" | "allow";
53
53
  type QfaiPaths = {
54
54
  contractsDir: string;
55
55
  specsDir: string;
56
- rulesDir: string;
57
56
  outDir: string;
58
57
  promptsDir: string;
59
58
  srcDir: string;
package/dist/index.d.ts CHANGED
@@ -53,7 +53,6 @@ type OrphanContractsPolicy = "error" | "warning" | "allow";
53
53
  type QfaiPaths = {
54
54
  contractsDir: string;
55
55
  specsDir: string;
56
- rulesDir: string;
57
56
  outDir: string;
58
57
  promptsDir: string;
59
58
  srcDir: string;
package/dist/index.mjs CHANGED
@@ -6,9 +6,8 @@ var defaultConfig = {
6
6
  paths: {
7
7
  contractsDir: ".qfai/contracts",
8
8
  specsDir: ".qfai/specs",
9
- rulesDir: ".qfai/rules",
10
- outDir: ".qfai/out",
11
- promptsDir: ".qfai/prompts",
9
+ outDir: ".qfai/report",
10
+ promptsDir: ".qfai/assistant/prompts",
12
11
  srcDir: "src",
13
12
  testsDir: "tests"
14
13
  },
@@ -36,7 +35,7 @@ var defaultConfig = {
36
35
  }
37
36
  },
38
37
  output: {
39
- validateJsonPath: ".qfai/out/validate.json"
38
+ validateJsonPath: ".qfai/report/validate.json"
40
39
  }
41
40
  };
42
41
  function getConfigPath(root) {
@@ -119,13 +118,6 @@ function normalizePaths(raw, configPath, issues) {
119
118
  configPath,
120
119
  issues
121
120
  ),
122
- rulesDir: readString(
123
- raw.rulesDir,
124
- base.rulesDir,
125
- "paths.rulesDir",
126
- configPath,
127
- issues
128
- ),
129
121
  outDir: readString(
130
122
  raw.outDir,
131
123
  base.outDir,
@@ -1245,8 +1237,8 @@ import { readFile as readFile4 } from "fs/promises";
1245
1237
  import path8 from "path";
1246
1238
  import { fileURLToPath } from "url";
1247
1239
  async function resolveToolVersion() {
1248
- if ("1.0.3".length > 0) {
1249
- return "1.0.3";
1240
+ if ("1.0.5".length > 0) {
1241
+ return "1.0.5";
1250
1242
  }
1251
1243
  try {
1252
1244
  const packagePath = resolvePackageJsonPath();
@@ -1995,11 +1987,6 @@ function issue(code, message, severity, file, rule, refs, category = "compatibil
1995
1987
  // src/core/validators/delta.ts
1996
1988
  import { readFile as readFile6 } from "fs/promises";
1997
1989
  import path11 from "path";
1998
- var SECTION_RE = /^##\s+変更区分/m;
1999
- var COMPAT_LINE_RE = /^\s*-\s*\[[ xX]\]\s*Compatibility\b/m;
2000
- var CHANGE_LINE_RE = /^\s*-\s*\[[ xX]\]\s*Change\/Improvement\b/m;
2001
- var COMPAT_CHECKED_RE = /^\s*-\s*\[[xX]\]\s*Compatibility\b/m;
2002
- var CHANGE_CHECKED_RE = /^\s*-\s*\[[xX]\]\s*Change\/Improvement\b/m;
2003
1990
  async function validateDeltas(root, config) {
2004
1991
  const specsRoot = resolvePath(root, config, "specsDir");
2005
1992
  const packs = await collectSpecPackDirs(specsRoot);
@@ -2009,9 +1996,8 @@ async function validateDeltas(root, config) {
2009
1996
  const issues = [];
2010
1997
  for (const pack of packs) {
2011
1998
  const deltaPath = path11.join(pack, "delta.md");
2012
- let text;
2013
1999
  try {
2014
- text = await readFile6(deltaPath, "utf-8");
2000
+ await readFile6(deltaPath, "utf-8");
2015
2001
  } catch (error) {
2016
2002
  if (isMissingFileError2(error)) {
2017
2003
  issues.push(
@@ -2020,41 +2006,16 @@ async function validateDeltas(root, config) {
2020
2006
  "delta.md \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002",
2021
2007
  "error",
2022
2008
  deltaPath,
2023
- "delta.exists"
2009
+ "delta.exists",
2010
+ void 0,
2011
+ "change",
2012
+ "spec-xxxx/delta.md \u3092\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u30C6\u30F3\u30D7\u30EC\u306F init \u751F\u6210\u7269\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\uFF09\u3002"
2024
2013
  )
2025
2014
  );
2026
2015
  continue;
2027
2016
  }
2028
2017
  throw error;
2029
2018
  }
2030
- const hasSection = SECTION_RE.test(text);
2031
- const hasCompatibility = COMPAT_LINE_RE.test(text);
2032
- const hasChange = CHANGE_LINE_RE.test(text);
2033
- if (!hasSection || !hasCompatibility || !hasChange) {
2034
- issues.push(
2035
- issue2(
2036
- "QFAI-DELTA-002",
2037
- "delta.md \u306E\u5909\u66F4\u533A\u5206\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059\u3002`## \u5909\u66F4\u533A\u5206` \u3068\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9\uFF08Compatibility / Change/Improvement\uFF09\u3092\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
2038
- "error",
2039
- deltaPath,
2040
- "delta.section"
2041
- )
2042
- );
2043
- continue;
2044
- }
2045
- const compatibilityChecked = COMPAT_CHECKED_RE.test(text);
2046
- const changeChecked = CHANGE_CHECKED_RE.test(text);
2047
- if (compatibilityChecked === changeChecked) {
2048
- issues.push(
2049
- issue2(
2050
- "QFAI-DELTA-003",
2051
- "delta.md \u306E\u5909\u66F4\u533A\u5206\u306F\u3069\u3061\u3089\u304B1\u3064\u3060\u3051\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4E21\u65B9ON/\u4E21\u65B9OFF\u306F\u7121\u52B9\u3067\u3059\uFF09\u3002",
2052
- "error",
2053
- deltaPath,
2054
- "delta.classification"
2055
- )
2056
- );
2057
- }
2058
2019
  }
2059
2020
  return issues;
2060
2021
  }
@@ -2211,11 +2172,25 @@ function getInitAssetsDir() {
2211
2172
  }
2212
2173
 
2213
2174
  // src/core/promptsIntegrity.ts
2214
- async function diffProjectPromptsAgainstInitAssets(root) {
2215
- const promptsDir = path14.resolve(root, ".qfai", "prompts");
2175
+ var LEGACY_OK_EXTRA = /* @__PURE__ */ new Set(["qfai-classify-change.md"]);
2176
+ async function diffProjectPromptsAgainstInitAssets(root, config) {
2177
+ const promptsDirConfig = config.paths.promptsDir;
2178
+ const promptsDir = path14.isAbsolute(promptsDirConfig) ? promptsDirConfig : path14.resolve(root, promptsDirConfig);
2216
2179
  let templateDir;
2217
2180
  try {
2218
- templateDir = path14.join(getInitAssetsDir(), ".qfai", "prompts");
2181
+ const rel = path14.isAbsolute(promptsDirConfig) ? path14.relative(root, promptsDirConfig) : promptsDirConfig;
2182
+ const normalized = rel.replace(/^[\\/]+/, "");
2183
+ if (normalized.length === 0 || normalized.startsWith("..")) {
2184
+ return {
2185
+ status: "skipped_missing_assets",
2186
+ promptsDir,
2187
+ templateDir: "",
2188
+ missing: [],
2189
+ extra: [],
2190
+ changed: []
2191
+ };
2192
+ }
2193
+ templateDir = path14.join(getInitAssetsDir(), normalized);
2219
2194
  } catch {
2220
2195
  return {
2221
2196
  status: "skipped_missing_assets",
@@ -2259,6 +2234,7 @@ async function diffProjectPromptsAgainstInitAssets(root) {
2259
2234
  extra.push(rel);
2260
2235
  }
2261
2236
  }
2237
+ const filteredExtra = extra.filter((rel) => !LEGACY_OK_EXTRA.has(rel));
2262
2238
  const common = intersectKeys(templateByRel, projectByRel);
2263
2239
  for (const rel of common) {
2264
2240
  const templateAbs = templateByRel.get(rel);
@@ -2278,13 +2254,13 @@ async function diffProjectPromptsAgainstInitAssets(root) {
2278
2254
  changed.push(rel);
2279
2255
  }
2280
2256
  }
2281
- const status = missing.length > 0 || extra.length > 0 || changed.length > 0 ? "modified" : "ok";
2257
+ const status = missing.length > 0 || filteredExtra.length > 0 || changed.length > 0 ? "modified" : "ok";
2282
2258
  return {
2283
2259
  status,
2284
2260
  promptsDir,
2285
2261
  templateDir,
2286
2262
  missing: missing.sort(),
2287
- extra: extra.sort(),
2263
+ extra: filteredExtra.sort(),
2288
2264
  changed: changed.sort()
2289
2265
  };
2290
2266
  }
@@ -2306,8 +2282,8 @@ function intersectKeys(a, b) {
2306
2282
  }
2307
2283
 
2308
2284
  // src/core/validators/promptsIntegrity.ts
2309
- async function validatePromptsIntegrity(root) {
2310
- const diff = await diffProjectPromptsAgainstInitAssets(root);
2285
+ async function validatePromptsIntegrity(root, config) {
2286
+ const diff = await diffProjectPromptsAgainstInitAssets(root, config);
2311
2287
  if (diff.status !== "modified") {
2312
2288
  return [];
2313
2289
  }
@@ -2324,11 +2300,11 @@ async function validatePromptsIntegrity(root) {
2324
2300
  code: "QFAI-PROMPTS-001",
2325
2301
  severity: "error",
2326
2302
  category: "change",
2327
- message: `\u6A19\u6E96\u8CC7\u7523 '.qfai/prompts/**' \u304C\u6539\u5909\u3055\u308C\u3066\u3044\u307E\u3059\uFF08${hints || `\u5DEE\u5206=${total}`}\uFF09\u3002${sampleText}`,
2303
+ message: `\u6A19\u6E96\u8CC7\u7523 '.qfai/assistant/prompts/**' \u304C\u6539\u5909\u3055\u308C\u3066\u3044\u307E\u3059\uFF08${hints || `\u5DEE\u5206=${total}`}\uFF09\u3002${sampleText}`,
2328
2304
  suggested_action: [
2329
2305
  "prompts \u306E\u76F4\u7DE8\u96C6\u306F\u975E\u63A8\u5968\u3067\u3059\uFF08\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8/\u518D init \u3067\u4E0A\u66F8\u304D\u3055\u308C\u5F97\u307E\u3059\uFF09\u3002",
2330
2306
  "\u6B21\u306E\u3044\u305A\u308C\u304B\u3092\u5B9F\u65BD\u3057\u3066\u304F\u3060\u3055\u3044:",
2331
- "- \u5909\u66F4\u3057\u305F\u3044\u5834\u5408: \u540C\u4E00\u76F8\u5BFE\u30D1\u30B9\u3067 '.qfai/prompts.local/**' \u306B\u7F6E\u3044\u3066 overlay",
2307
+ "- \u5909\u66F4\u3057\u305F\u3044\u5834\u5408: \u540C\u4E00\u76F8\u5BFE\u30D1\u30B9\u3067 '.qfai/assistant/prompts.local/**' \u306B\u7F6E\u3044\u3066 overlay",
2332
2308
  "- \u6A19\u6E96\u72B6\u614B\u3078\u623B\u3059\u5834\u5408: 'qfai init --force' \u3092\u5B9F\u884C\uFF08prompts \u306E\u307F\u4E0A\u66F8\u304D\u3001prompts.local \u306F\u4FDD\u8B77\uFF09"
2333
2309
  ].join("\n"),
2334
2310
  rule: "prompts.integrity"
@@ -3199,7 +3175,7 @@ async function validateProject(root, configResult) {
3199
3175
  const { config, issues: configIssues } = resolved;
3200
3176
  const issues = [
3201
3177
  ...configIssues,
3202
- ...await validatePromptsIntegrity(root),
3178
+ ...await validatePromptsIntegrity(root, config),
3203
3179
  ...await validateSpecs(root, config),
3204
3180
  ...await validateDeltas(root, config),
3205
3181
  ...await validateScenarios(root, config),
@@ -3721,11 +3697,9 @@ function formatReportMarkdown(data, options = {}) {
3721
3697
  "- issue \u306F\u691C\u51FA\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u904B\u7528\u30C6\u30F3\u30D7\u30EC\u306B\u6CBF\u3063\u3066\u7D99\u7D9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
3722
3698
  );
3723
3699
  }
3700
+ lines.push("- \u5909\u66F4\u5185\u5BB9\u30FB\u53D7\u5165\u89B3\u70B9\u306F `.qfai/specs/*/delta.md` \u306B\u8A18\u9332\u3057\u307E\u3059\u3002");
3724
3701
  lines.push(
3725
- "- \u5909\u66F4\u533A\u5206\uFF08Compatibility / Change/Improvement\uFF09\u306F `.qfai/specs/*/delta.md` \u306B\u8A18\u9332\u3057\u307E\u3059\u3002"
3726
- );
3727
- lines.push(
3728
- "- \u53C2\u7167\u30EB\u30FC\u30EB\u306E\u6B63\u672C: `.qfai/promptpack/steering/traceability.md` / `.qfai/promptpack/steering/compatibility-vs-change.md`"
3702
+ "- \u53C2\u7167\u30EB\u30FC\u30EB\u306E\u6B63\u672C: `.qfai/assistant/instructions/constitution.md`"
3729
3703
  );
3730
3704
  return lines.join("\n");
3731
3705
  }