@takagaki/cortex-decisions-viewer 0.12.19 → 0.12.20

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/build.js CHANGED
@@ -55,6 +55,16 @@ const repo_1 = require("./repo");
55
55
  // 直近のGold昇格で追加されたレコードのパス集合。レコード生成の各所から参照するのでモジュールスコープに置く
56
56
  // (引数で引き回すと呼び出し側の改修が広範囲になる)。build() の冒頭で1回だけ解決する。
57
57
  let LATEST_PATHS = new Set();
58
+ /**
59
+ * このレコードが「直近のGold昇格で追加されたもの」か。
60
+ *
61
+ * **照合の手前で NFC に正規化する。** 集合側(git 由来)は NFC で入っているが、
62
+ * こちらのパスは readdir 由来なので、ファイルシステムが NFD で返す環境(macOS の
63
+ * 一部の経路)では**同じ日本語名でも一致しない**。正規化はこの1箇所に集める。
64
+ */
65
+ function isLatestPath(filePath) {
66
+ return LATEST_PATHS.has(filePath.normalize("NFC"));
67
+ }
58
68
  // AIからの更新提案(`.cortex/gold-proposals.json` 由来)を、レコードのパスで引ける形にしたもの。
59
69
  // **LATEST_PATHS と同じ置き方にしている**——どちらも「レコードを組み立てるその場で、
60
70
  // リポジトリルート相対のパスを鍵に引く」もので、引き回すと parseDecision / parseGeneric の
@@ -849,7 +859,7 @@ async function parseGeneric(raw, fileName, repoRelDir, repoBaseUrl, branch) {
849
859
  editUrl,
850
860
  rtype: data.type != null ? String(data.type) : "",
851
861
  rstatus: data.status != null ? String(data.status) : "",
852
- isLatest: LATEST_PATHS.has(filePath),
862
+ isLatest: isLatestPath(filePath),
853
863
  proposals: takeProposals(filePath),
854
864
  relations: toRelations(data.relations),
855
865
  source: data.source != null ? String(data.source) : "",
@@ -1918,7 +1928,7 @@ async function parseDecision(raw, fileName, repoRelDir, repoBaseUrl, branch, ref
1918
1928
  bodyRef: "",
1919
1929
  searchText: toSearchText(content),
1920
1930
  rstatus: data.status != null ? String(data.status) : "",
1921
- isLatest: LATEST_PATHS.has(filePath),
1931
+ isLatest: isLatestPath(filePath),
1922
1932
  proposals: takeProposals(filePath),
1923
1933
  fileName,
1924
1934
  editUrl,
package/dist/repo.js CHANGED
@@ -33,13 +33,22 @@ function resolveRepo(opts) {
33
33
  * 最新コミットと同じ「日」のパイプラインコミットまでをまとめて1回の実行として扱う。
34
34
  *
35
35
  * clone が浅い(--depth 1 等)・git が無い環境では**空集合を返す**(ラベルが出ないだけで壊れない)。
36
+ *
37
+ * 🔴 **パスは `-z`(NUL区切り)で取り、NFC に正規化してから集合に入れる。**
38
+ * - `-z` … 既定の git(`core.quotePath=true`)は非ASCIIを含むパスを
39
+ * `"Cortex/Rules/records/\345\261\245…md"` と引用符+8進エスケープで出す。レコードは
40
+ * **日本語のファイル名**なので、そのまま入れると照合側(readdir の生 UTF-8)と
41
+ * 一致せず「最新」ラベルが**1件も出なくなる**(#328 で実際に踏んだ)。
42
+ * - NFC … リポジトリのパスは NFC が正(cortex-engine PR #211
43
+ * https://github.com/classmethod-internal/cortex-engine/pull/211)。#211 以前に
44
+ * NFD で入ったコミットが履歴に残っているので、照合の手前で揃える。
36
45
  */
37
46
  function latestGeneratedPaths(cwd) {
38
47
  const empty = new Set();
39
48
  try {
40
49
  // 夜間パイプラインのコミットを新しい順に数件。--grep はコミットメッセージの規約に依存するため、
41
50
  // 変わっても「ラベルが出ない」だけで済むように例外は握る。
42
- const log = (0, node_child_process_1.execSync)('git log -n 20 --grep="自動追記" --pretty=format:"%H %cI" -- Cortex/', { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
51
+ const log = (0, node_child_process_1.execFileSync)("git", ["log", "-n", "20", "--grep=自動追記", "--pretty=format:%H %cI", "--", "Cortex/"], { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
43
52
  if (!log)
44
53
  return empty;
45
54
  const rows = log.split("\n").map((l) => {
@@ -53,11 +62,15 @@ function latestGeneratedPaths(cwd) {
53
62
  for (const r of rows) {
54
63
  if (r.day !== latestDay)
55
64
  break; // 直近の実行日ぶんだけ
56
- const files = (0, node_child_process_1.execSync)(`git show --diff-filter=A --name-only --pretty=format: ${r.sha}`, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
57
- for (const f of files.split("\n")) {
58
- const p = f.trim();
65
+ const files = (0, node_child_process_1.execFileSync)("git", ["show", "-z", "--no-color", "--diff-filter=A", "--name-only", "--pretty=format:", r.sha], { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
66
+ for (const f of files.split("\0")) {
67
+ // 空の `--pretty=format:` では先頭に改行は出ない(git 2.39 で実測)が、format が
68
+ // 非空だと `<ヘッダ>\n<最初のパス>` と改行で区切られる。将来ヘッダを足しても
69
+ // パスが壊れないよう**先頭の改行だけ**落とす(trim だと名前の前後の空白まで削り、
70
+ // その名前のレコードが照合できなくなる)
71
+ const p = f.replace(/^\n+/, "");
59
72
  if (p)
60
- out.add(p);
73
+ out.add(p.normalize("NFC"));
61
74
  }
62
75
  }
63
76
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.12.19",
3
+ "version": "0.12.20",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,