@takagaki/cortex-decisions-viewer 0.4.36 → 0.4.37

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
@@ -177,6 +177,15 @@ async function readFleetSources(repoRoot) {
177
177
  }
178
178
  return { externalSources, internalSources, pipelines, tools };
179
179
  }
180
+ /** パスがディレクトリとして存在するか */
181
+ async function isDirectory(dirAbs) {
182
+ try {
183
+ return (await node_fs_1.promises.stat(dirAbs)).isDirectory();
184
+ }
185
+ catch {
186
+ return false;
187
+ }
188
+ }
180
189
  /** ディレクトリ内の .md を汎用レコードとして読み込む(存在しなければ空配列) */
181
190
  async function loadGenericRecords(dirAbs, exclude, repoBaseUrl, branch) {
182
191
  let entries;
@@ -915,8 +924,11 @@ async function build(opts) {
915
924
  for (const e of rootEntries) {
916
925
  if (!e.isDirectory() || e.name === "Decisions")
917
926
  continue;
918
- const records = await loadGenericRecords(path.join(knowledgeRoot, e.name, "records"), exclude, repo.baseUrl, repo.branch);
919
- if (records.length)
927
+ const recordsDir = path.join(knowledgeRoot, e.name, "records");
928
+ const records = await loadGenericRecords(recordsDir, exclude, repo.baseUrl, repo.branch);
929
+ // レコード0件でもタブは出す(空状態から「+AIで登録」できる導線になる)。
930
+ // records/ 自体が無いディレクトリ(その区画が未導入の案件)はタブにしない
931
+ if (records.length || (await isDirectory(recordsDir)))
920
932
  sections.push({ name: e.name, records });
921
933
  }
922
934
  sections.sort((a, b) => a.name.localeCompare(b.name, "ja"));
package/dist/render.js CHANGED
@@ -201,8 +201,8 @@ function buildTutorialData(site, codeUrl, repoSlug) {
201
201
  const tools = site.tools ?? {};
202
202
  const internals = site.internalSources ?? [];
203
203
  const externals = site.externalSources ?? [];
204
- // メンバーの自分のレコードを直す体験(Members セクションがある案件のみ出す)
205
- if ((site.sections ?? []).some((s) => s.name === "Members" || s.name === "メンバー")) {
204
+ // メンバーの自分のレコードを直す体験(Members セクションにレコードがある案件のみ出す)
205
+ if ((site.sections ?? []).some((s) => (s.name === "Members" || s.name === "メンバー") && s.records.length)) {
206
206
  specs.push({
207
207
  title: "自分の名前を変更してみよう",
208
208
  desc: "メンバー一覧の自分のレコードをAIに直してもらう",
@@ -584,9 +584,13 @@ a:hover { text-decoration: underline; }
584
584
  .badge.cat-インフラ { background: #efe9fb; color: #6d28d9; }
585
585
  .badge.cat-ビジネス { background: #fde9ef; color: #be185d; }
586
586
  .badge.cat-デザイン { background: #fce7f3; color: #a21caf; }
587
+ .badge.draft { background: #fef3c7; color: #92400e; border: 1px solid #fcd34d; }
587
588
  .badge.error { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; }
588
- /* 未確認(status: draft = AI生成・人間未確認)の印。ほとんどのレコードが該当しうるため色もアイコンも使わない */
589
- .unverified { margin-left: 8px; font-size: 11.5px; font-weight: 400; color: var(--muted); white-space: nowrap; }
589
+ .draft-note {
590
+ display: flex; gap: 8px; align-items: flex-start;
591
+ background: #fffbeb; border: 1px solid #fcd34d; border-radius: 8px;
592
+ padding: 10px 14px; margin: 12px 0 4px; font-size: 13.5px; color: #92400e; line-height: 1.7;
593
+ }
590
594
  .adoption-note {
591
595
  display: flex; gap: 8px; align-items: flex-start;
592
596
  background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 8px;
@@ -933,9 +937,17 @@ const CLIENT_JS = `
933
937
  function catBadge(cat) {
934
938
  return el("span", { class: "badge cat-" + cat, text: cat || "未分類" });
935
939
  }
936
- // 未確認(status: draft = AI生成・人間未確認)の印。タイトル脇に小さく添えるだけで、active・status無しには何も出さない
937
- function unverifiedMark(rec) {
938
- return rec && rec.rstatus === "draft" ? el("span", { class: "unverified", text: "未確認" }) : null;
940
+ // 未確認(status: draft = AI生成・人間未確認)の印。Gold層の4型(決定事項・用語集・メンバー・ルール)共通で、active・status無しには何も出さない
941
+ function draftBadge(rec) {
942
+ return rec && rec.rstatus === "draft" ? el("span", { class: "badge draft", text: "AI生成・未確認" }) : null;
943
+ }
944
+ // 詳細ページの警告。バッジより強く「そのまま信じないでほしい」と伝える
945
+ function draftNote(rec) {
946
+ if (!rec || rec.rstatus !== "draft") return null;
947
+ return el("div", { class: "draft-note" }, [
948
+ el("span", { text: "⚠️" }),
949
+ el("span", { text: "この内容はAIが自動生成したものです(人間未確認)。必ず内容を確認し、適切な内容に直したうえで frontmatter の status を active に変更してください。" }),
950
+ ]);
939
951
  }
940
952
  // 未確認の絞り込み(フィルタのセレクトの選択肢は draft の1つだけ)
941
953
  function statusLabel(v) { return v === "draft" ? "未確認のみ" : v; }
@@ -1219,7 +1231,7 @@ const CLIENT_JS = `
1219
1231
  btnUrl: base ? base + "/actions/workflows/update-decision-log.yml" : null,
1220
1232
  },
1221
1233
  "dir:Glossary": {
1222
- text: "毎晩の自動走査が新しい用語を draft として直接追加します(update-glossary-auto)。AIが生成した定義は仮のものです。「未確認」の用語は内容を確認し、適切な定義に置き換えて status: active にしてください。",
1234
+ text: "毎晩の自動走査が新しい用語を draft として直接追加します(update-glossary-auto)。AIが生成した定義は仮のものです。「AI生成・未確認」の用語は必ず内容を確認し、適切な定義に置き換えて status: active にしてください。",
1223
1235
  btnLabel: "実行履歴を確認 →",
1224
1236
  btnUrl: base ? base + "/actions/workflows/update-glossary.yml" : null,
1225
1237
  },
@@ -1805,6 +1817,7 @@ const CLIENT_JS = `
1805
1817
 
1806
1818
  pg.slice.forEach(function (d) {
1807
1819
  var meta = el("div", { class: "card-meta" }, [
1820
+ draftBadge(d),
1808
1821
  el("span", { class: "mono", text: d.date || "----" }),
1809
1822
  catBadge(d.category),
1810
1823
  el("span", { class: "mono", text: d.id }),
@@ -1816,7 +1829,7 @@ const CLIENT_JS = `
1816
1829
  meta.appendChild(traceD);
1817
1830
  var card = el("div", { class: "card" }, [
1818
1831
  meta,
1819
- el("div", { class: "card-title", text: d.title }, [unverifiedMark(d)]),
1832
+ el("div", { class: "card-title", text: d.title }),
1820
1833
  d.summary ? el("p", { class: "card-summary", text: d.summary }) : null,
1821
1834
  ]);
1822
1835
  card.addEventListener("click", function () { go(d.id); });
@@ -1858,7 +1871,11 @@ const CLIENT_JS = `
1858
1871
  listWrap.innerHTML = "";
1859
1872
  if (!shown.length) {
1860
1873
  countEl.textContent = "0 / " + items.length + " 件";
1861
- listWrap.appendChild(el("div", { class: "empty", text: "該当するレコードはありません" }));
1874
+ // レコード0件のセクション(区画はあるがまだ書かれていない)と、絞り込みの結果0件とを言い分ける
1875
+ listWrap.appendChild(el("div", {
1876
+ class: "empty",
1877
+ text: items.length ? "該当するレコードはありません" : "まだ登録されていません",
1878
+ }));
1862
1879
  return;
1863
1880
  }
1864
1881
  var pg = paginate(shown);
@@ -1867,6 +1884,7 @@ const CLIENT_JS = `
1867
1884
  (pg.pages > 1 ? "(" + pg.page + "/" + pg.pages + "ページ)" : "");
1868
1885
  pg.slice.forEach(function (r) {
1869
1886
  var meta = el("div", { class: "card-meta" }, [
1887
+ draftBadge(r),
1870
1888
  r.date ? el("span", { class: "mono", text: r.date }) : null,
1871
1889
  el("span", { class: "mono", text: r.id }),
1872
1890
  ]);
@@ -1877,7 +1895,7 @@ const CLIENT_JS = `
1877
1895
  meta.appendChild(traceR);
1878
1896
  var card = el("div", { class: "card" }, [
1879
1897
  meta,
1880
- el("div", { class: "card-title", text: r.title }, [unverifiedMark(r)]),
1898
+ el("div", { class: "card-title", text: r.title }),
1881
1899
  r.summary ? el("p", { class: "card-summary", text: r.summary }) : null,
1882
1900
  ]);
1883
1901
  card.addEventListener("click", function () { go(r.id); });
@@ -1900,7 +1918,7 @@ const CLIENT_JS = `
1900
1918
  app.appendChild(back);
1901
1919
 
1902
1920
  var head = el("div", { class: "detail-head" });
1903
- head.appendChild(el("div", {}, [ el("h1", { class: "detail-title", text: r.title }, [unverifiedMark(r)]) ]));
1921
+ head.appendChild(el("div", {}, [ el("h1", { class: "detail-title", text: r.title }) ]));
1904
1922
  var traceBtn2 = el("a", { class: "edit-btn", href: "?tab=graph", text: "🕸 つながり" });
1905
1923
  traceBtn2.addEventListener("click", function (ev) { ev.preventDefault(); openExplorerFor(r); });
1906
1924
  head.appendChild(traceBtn2);
@@ -1912,6 +1930,7 @@ const CLIENT_JS = `
1912
1930
  app.appendChild(head);
1913
1931
 
1914
1932
  app.appendChild(el("div", { class: "detail-meta" }, [
1933
+ draftBadge(r),
1915
1934
  r.date ? el("span", { class: "mono", text: r.date }) : null,
1916
1935
  el("span", { class: "mono", text: r.id }),
1917
1936
  r.summary ? el("span", { text: r.summary }) : null,
@@ -1920,6 +1939,9 @@ const CLIENT_JS = `
1920
1939
  var en2 = fmErrorNote(r);
1921
1940
  if (en2) app.appendChild(en2);
1922
1941
 
1942
+ var dn2 = draftNote(r);
1943
+ if (dn2) app.appendChild(dn2);
1944
+
1923
1945
  var genBody = el("div", { class: "body" });
1924
1946
  app.appendChild(genBody);
1925
1947
  loadBody(r, genBody);
@@ -2548,7 +2570,7 @@ const CLIENT_JS = `
2548
2570
  app.appendChild(back);
2549
2571
 
2550
2572
  var head = el("div", { class: "detail-head" });
2551
- var headLeft = el("div", {}, [ el("h1", { class: "detail-title", text: d.title }, [unverifiedMark(d)]) ]);
2573
+ var headLeft = el("div", {}, [ el("h1", { class: "detail-title", text: d.title }) ]);
2552
2574
  head.appendChild(headLeft);
2553
2575
  var traceBtn = el("a", { class: "edit-btn", href: "?tab=graph", text: "🕸 つながり" });
2554
2576
  traceBtn.addEventListener("click", function (ev) { ev.preventDefault(); openExplorerFor(d); });
@@ -2561,6 +2583,7 @@ const CLIENT_JS = `
2561
2583
  app.appendChild(head);
2562
2584
 
2563
2585
  var meta = el("div", { class: "detail-meta" }, [
2586
+ draftBadge(d),
2564
2587
  el("span", { class: "mono", text: d.date || "----" }),
2565
2588
  catBadge(d.category),
2566
2589
  el("span", { class: "mono", text: d.id }),
@@ -2570,6 +2593,9 @@ const CLIENT_JS = `
2570
2593
  var en = fmErrorNote(d);
2571
2594
  if (en) app.appendChild(en);
2572
2595
 
2596
+ var dn = draftNote(d);
2597
+ if (dn) app.appendChild(dn);
2598
+
2573
2599
  if (d.summary) {
2574
2600
  app.appendChild(el("div", { class: "section-label", text: "要約" }));
2575
2601
  app.appendChild(el("div", { class: "summary-box", text: d.summary }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.4.36",
3
+ "version": "0.4.37",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,