@takagaki/cortex-decisions-viewer 0.10.2 → 0.10.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.
package/dist/build.js CHANGED
@@ -166,6 +166,10 @@ async function readFleetSources(repoRoot) {
166
166
  goldState: s.goldState != null ? String(s.goldState) : undefined,
167
167
  notify: typeof s.notify === "boolean" ? s.notify : undefined,
168
168
  gate: s.gate != null ? String(s.gate) : undefined,
169
+ // gate が missing_scope のときに Slack が名指しした不足スコープ(段B)。
170
+ // **列挙し忘れると静かに消える**(この対応は素通しではなく明示の許可リスト)。
171
+ // 落とすと「権限が足りません」とだけ出て、何を頼めばよいか画面から分からない
172
+ needed: s.needed != null ? String(s.needed) : undefined,
169
173
  // どこから来たか(derived / explicit / both)。**削除を出してよいかの判断に要る。**
170
174
  // 自動導出されたものは登録ファイルから消しても翌日また現れるので、
171
175
  // explicit のときだけ削除ボタンを出す。
package/dist/render.js CHANGED
@@ -601,7 +601,20 @@ function sanitizeStateNow(v) {
601
601
  /**
602
602
  * ストアの「届くか」を行に重ねる。**まとめ表より新しいときだけ**——古い確認結果で
603
603
  * 新しい実測を潰さない(時刻の比較は ISO 文字列の辞書順で足りる)。
604
- * 対象はチャットの行だけ(段A。確認ボタンが書くのがチャットだけのため)。
604
+ *
605
+ * 対象はチャットと開発の行(段B。夜間チェックがこの2つを書く)。
606
+ *
607
+ * 🔴 **突き合わせの鍵は能力ごとに違う。**
608
+ * - chat … ワークスペース + チャンネルID。チャンネルIDはワークスペースの中でしか
609
+ * 一意でないので、IDだけで突き合わせると別ワークスペースの同IDを同じものと見る
610
+ * - dev … owner/repo の生文字列(devRowsToAdd と同じ)。**ワークスペースは持たない。**
611
+ * 同じリポジトリの github-issues と github-discussions は**同じ行**を指すので、
612
+ * 2つの行に同じ判定が載るのが正しい(書く側が SK で dedupe している)
613
+ *
614
+ * **needed(足りないスコープ)も載せる。** 載せないと、夜間が missing_scope を
615
+ * 書いた行だけスコープ名が消え、「権限が足りません」とだけ出て何を直せばよいか
616
+ * 分からない状態に戻る。上書きするときは空でも必ず載せる——夜間の古い needed が
617
+ * 新しい判定の横に残ると、直したはずのスコープ名がいつまでも出る
605
618
  */
606
619
  function overlayStateOnFleet(view, rows, generatedAt) {
607
620
  const v = view || {};
@@ -609,21 +622,33 @@ function overlayStateOnFleet(view, rows, generatedAt) {
609
622
  return v;
610
623
  const byKey = {};
611
624
  for (const r of rows) {
612
- if (r.cap !== "chat" || r.question !== "reachable")
625
+ if (r.question !== "reachable")
613
626
  continue;
614
- byKey[String(r.workspace || "") + "\t" + String(r.ref)] = r;
627
+ if (r.cap === "chat")
628
+ byKey["chat\t" + String(r.workspace || "") + "\t" + String(r.ref)] = r;
629
+ else if (r.cap === "dev")
630
+ byKey["dev\t" + String(r.ref)] = r;
615
631
  }
616
632
  let changed = false;
617
633
  const externals = v.externalSources.map((s) => {
618
- if (!s || s.type !== "slack" || !s.ref)
634
+ if (!s || !s.ref)
619
635
  return s;
620
- const hit = byKey[String(s.workspace || "") + "\t" + String(s.ref)];
636
+ let hit = null;
637
+ if (s.type === "slack")
638
+ hit = byKey["chat\t" + String(s.workspace || "") + "\t" + String(s.ref)];
639
+ else if (String(s.type || "").indexOf("github") === 0)
640
+ hit = byKey["dev\t" + String(s.ref)];
621
641
  if (!hit)
622
642
  return s;
623
643
  if (generatedAt && hit.at <= generatedAt)
624
644
  return s;
625
645
  changed = true;
626
- return Object.assign({}, s, { gate: hit.status, gateAt: hit.at, gateBy: hit.by });
646
+ return Object.assign({}, s, {
647
+ gate: hit.status,
648
+ gateAt: hit.at,
649
+ gateBy: hit.by,
650
+ needed: hit.needed || "",
651
+ });
627
652
  });
628
653
  return changed ? Object.assign({}, v, { externalSources: externals }) : v;
629
654
  }
@@ -5486,6 +5511,12 @@ ${nextStateDelay.toString()}
5486
5511
  // 古い「X分前に確認」を残さない(下に出るいまの結果と、時刻が2つ並ぶ)
5487
5512
  var oldAt = card.querySelector(".ds-gate-at");
5488
5513
  if (oldAt) oldAt.remove();
5514
+ // 🔴 **古いスコープ名の札も必ず消してから出し直す。** 行には夜間の判定に添えた
5515
+ // 札が出ていることがあり(段B)、置き換えた「接続OK」の横に古いスコープ名が
5516
+ // 残ると、同じ行が2つのことを言う——この節が何度も直してきた形そのもの。
5517
+ // 押し直すたびに札が増えていくのも、まとめてここで断つ
5518
+ var oldScopes = card.querySelectorAll(".ds-probe-scope");
5519
+ for (var oi = 0; oi < oldScopes.length; oi++) oldScopes[oi].remove();
5489
5520
  // 不足スコープは**状態の語のすぐ横**に出す(「権限が足りません:groups:read」)。
5490
5521
  // 本文へ落とすと、いちばん要る情報が説明文に埋もれる
5491
5522
  if (j.gate === "missing_scope") {
@@ -6939,6 +6970,17 @@ ${nextStateDelay.toString()}
6939
6970
  badges,
6940
6971
  gateEl,
6941
6972
  ]);
6973
+ // 足りないスコープは**状態の語のすぐ横**に出す(「権限が足りません:groups:read」)。
6974
+ //
6975
+ // **押した瞬間の結果と同じ見た目にする**(probeSection が同じ class を付けている)。
6976
+ // 出どころは2つあるが、読む人にとっては同じ情報:
6977
+ // - 夜間チェックが書いた needed(fleet-status.json 経由)
6978
+ // - 状態ストアの行が上書きした needed(overlayStateOnFleet 経由)
6979
+ // ここが無いと「権限が足りません」とだけ出て、**どのスコープを頼めばよいか
6980
+ // 画面から分からない**——押して確かめた人にしか分からない状態に戻る
6981
+ if (s.gate === "missing_scope" && s.needed) {
6982
+ card.appendChild(el("code", { class: "ds-probe-scope", text: String(s.needed) }));
6983
+ }
6942
6984
  if (gateAtEl) card.appendChild(gateAtEl);
6943
6985
  // チャンネルの登録解除。書き込み経路(intake Lambda)がある案件でだけ出す。
6944
6986
  // **Slack だけ。** github は登録ファイルが別(dev-sources.json)で、下のトグルと
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,