@takagaki/cortex-decisions-viewer 0.12.60 → 0.12.62

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 (2) hide show
  1. package/dist/render.js +52 -96
  2. package/package.json +1 -1
package/dist/render.js CHANGED
@@ -20,7 +20,6 @@ exports.chatRowsToAdd = chatRowsToAdd;
20
20
  exports.gchatRowsToAdd = gchatRowsToAdd;
21
21
  exports.overlayGchatNotify = overlayGchatNotify;
22
22
  exports.overlaySlackNotify = overlaySlackNotify;
23
- exports.overlayNotifyAuto = overlayNotifyAuto;
24
23
  exports.devRowsToAdd = devRowsToAdd;
25
24
  exports.markExcludedPendingRows = markExcludedPendingRows;
26
25
  exports.designRowsToAdd = designRowsToAdd;
@@ -889,11 +888,14 @@ const REGISTERED_CAP_NAMES = {
889
888
  * `orgUnknown` で同じ穴を1つ埋めた(0.12.1)のに、同族の3欄が残っていた。
890
889
  */
891
890
  const REGISTERED_FIELDS = {
892
- // notifyAuto(#589): 接続が確認できたので自動で通知先になった行の印。
893
- // **`notify` と対で読む**——サーバは通知先である行にしか付けない
894
- chat: ["ref", "name", "workspace", "orgUnknown", "origin", "goldState", "notify", "notifyAuto"],
891
+ // ⚠ **自動で入った行の印を足し戻さない(オーナー指示 2026-09-12・#592)。** #589 の初版は
892
+ // 札の語を出し分けるためにその欄(`notifyAuto`)を通していたが、1 日で撤回された
893
+ // ——自動で入るのが既定の動きなので、画面で人が設定した行と区別する意味が無い。
894
+ // この定数はクライアントへ `JSON.stringify` で渡る(コメントは付いて行かない)ので、
895
+ // 消した欄の名前をここに残しても画面には出ない
896
+ chat: ["ref", "name", "workspace", "orgUnknown", "origin", "goldState", "notify"],
895
897
  // notify(#572): スペースも通知先にできる。真偽値の扱いは chat の notify と同じ篩
896
- "google-chat": ["ref", "name", "notify", "notifyAuto"],
898
+ "google-chat": ["ref", "name", "notify"],
897
899
  dev: ["ref", "type"],
898
900
  // 🔴 **意図的に外した開発リポジトリ(#391)。** サーバは前から別キーで返していたが、
899
901
  // ここに無いので篩が丸ごと落としていた。**これが読めないと「読み取り停止中」の行を
@@ -978,9 +980,11 @@ function sanitizeRegisteredNow(v) {
978
980
  // **false はキーごと落とす。** 読み手は `=== true` で見る(`s.notify === true` /
979
981
  // `r.orgUnknown === true`)ので、false を載せても意味は同じ——載せないほうが
980
982
  // 「印が無い」と「印が false」の2通りを画面に持ち込まない。
981
- // 例外はこの3欄だけ(#589 で `notifyAuto` を足した)——他の欄まで真偽値を通すと、
982
- // 許可リストが篩の意味を失う
983
- if (f === "orgUnknown" || f === "notify" || f === "notifyAuto") {
983
+ // 例外はこの2欄だけ——他の欄まで真偽値を通すと、許可リストが篩の意味を失う
984
+ // (#589 で足した自動設定の印は #592 で落とした。上の許可リストの項を参照)
985
+ // この行はクライアントへ丸ごと流し込まれる。**印の欄の名前をここに書かない**
986
+ // ——画面にその語が 1 度も出ないことを notify-auto-gone.test.mjs が見張っている
987
+ if (f === "orgUnknown" || f === "notify") {
984
988
  if (fv === true)
985
989
  item[f] = true;
986
990
  continue;
@@ -1195,10 +1199,6 @@ function chatRowsToAdd(externals, rows) {
1195
1199
  // **真偽値の印は true のときだけ載せる**(読み手は `s.notify === true`。篩の項を参照)
1196
1200
  if (r.notify === true)
1197
1201
  row.notify = true;
1198
- // 自動で設定された通知先の印(#589)。**足す行にも載せる**——載せないと、追加して
1199
- // 接続を確認した直後(一番この説明が要る瞬間)だけ「自動で設定」が出ない
1200
- if (r.notify === true && r.notifyAuto === true)
1201
- row.notifyAuto = true;
1202
1202
  out.push(row);
1203
1203
  }
1204
1204
  return out;
@@ -1225,9 +1225,6 @@ function gchatRowsToAdd(externals, rows) {
1225
1225
  // 通知先の印(#572)。真偽値の印は true のときだけ載せる(chatRowsToAdd と同じ)
1226
1226
  if (r.notify === true)
1227
1227
  row.notify = true;
1228
- // 自動で設定された通知先の印(#589・chatRowsToAdd と同じ条件)
1229
- if (r.notify === true && r.notifyAuto === true)
1230
- row.notifyAuto = true;
1231
1228
  out.push(row);
1232
1229
  }
1233
1230
  return out;
@@ -1319,63 +1316,6 @@ function overlaySlackNotify(externals, rows) {
1319
1316
  });
1320
1317
  return changed ? out : list;
1321
1318
  }
1322
- /**
1323
- * 「自動で設定された通知先」の印(#589)を、まとめ表の行に重ねる。
1324
- *
1325
- * 🔴 **まとめ表(fleet-status)はこの印を持たない。** 印の置き場は案件リポの
1326
- * `チャット/notify.json` の `autoDefault` で、それを読んで行に付けるのは中央(intake)の
1327
- * `registeredNow` だけ。重ねないと、**自動で通知先になった行が「通知先」としか出ず、
1328
- * 担当者は自分が設定した覚えのない通知先を前にして、外してよいのかも分からない**
1329
- * (オーナー決定 4「外せる」が画面から読めない)。
1330
- *
1331
- * **印だけを重ねる。** `notify` そのものには触らない——通知先かどうかを live で重ねるのは
1332
- * `overlayGchatNotify`(Google Chat)と `overlaySlackNotify`(Slack)の仕事で、**この関数より
1333
- * 先に走る**。ここで二重に決めると「どちらが正か」が読めなくなる。印は `notify` が立っている
1334
- * 行にしか付けない(サーバ側も同じ条件で付けている)。
1335
- *
1336
- * live に該当の能力のキーが無ければ(読めていない)何も変えない。
1337
- *
1338
- * **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
1339
- */
1340
- function overlayNotifyAuto(externals, reg) {
1341
- const list = externals || [];
1342
- if (!reg || typeof reg !== "object")
1343
- return list;
1344
- const auto = {};
1345
- const known = {};
1346
- const scan = (rows, type, withWorkspace) => {
1347
- if (!Array.isArray(rows))
1348
- return;
1349
- for (const r of rows) {
1350
- if (!r || !r.ref)
1351
- continue;
1352
- const key = type + "\t" + (withWorkspace ? String(r.workspace || "") : "") + "\t" + String(r.ref);
1353
- known[key] = true;
1354
- auto[key] = r.notifyAuto === true && r.notify === true;
1355
- }
1356
- };
1357
- scan(reg.chat, "slack", true);
1358
- scan(reg["google-chat"], "google-chat", false);
1359
- let changed = false;
1360
- const out = list.map(function (s) {
1361
- if (!s || !s.ref || (s.type !== "slack" && s.type !== "google-chat"))
1362
- return s;
1363
- const key = s.type + "\t" + (s.type === "slack" ? String(s.workspace || "") : "") + "\t" + String(s.ref);
1364
- if (!Object.prototype.hasOwnProperty.call(known, key))
1365
- return s;
1366
- const want = auto[key] === true && s.notify === true;
1367
- if ((s.notifyAuto === true) === want)
1368
- return s;
1369
- changed = true;
1370
- const row = Object.assign({}, s);
1371
- if (want)
1372
- row.notifyAuto = true;
1373
- else
1374
- delete row.notifyAuto;
1375
- return row;
1376
- });
1377
- return changed ? out : list;
1378
- }
1379
1319
  /**
1380
1320
  * 開発の行で、まとめ表がまだ知らないもの。**鍵は `owner/repo` の生文字列。**
1381
1321
  *
@@ -1784,8 +1724,6 @@ function mergeRegisteredFleet(view, reg) {
1784
1724
  out.externalSources = overlayGchatNotify(v.externalSources, reg["google-chat"]);
1785
1725
  // Slack の行の「通知先」も live が正(#589・まとめ表は夜間の生成物で、自動設定に追いつかない)
1786
1726
  out.externalSources = overlaySlackNotify(out.externalSources, reg.chat);
1787
- // 「自動で設定」の印も live が正(#589・まとめ表は持っていない)。`notify` を重ねた後に置く
1788
- out.externalSources = overlayNotifyAuto(out.externalSources, reg);
1789
1727
  const add = registeredRowsToAdd(v, reg);
1790
1728
  if (add.externalSources.length)
1791
1729
  out.externalSources = (out.externalSources || []).concat(add.externalSources);
@@ -3728,9 +3666,10 @@ const TUT_BACKLOG_PROMPT = [
3728
3666
  "どの課題に何を書くかは、まずわたしに質問してください(課題は 課題管理/issues/ から選べます。課題キーは各ファイルの「基本情報 > 課題キー」)。",
3729
3667
  "",
3730
3668
  "投稿経路は次の優先順で判定し、Backlog上の名義とあわせて先に伝えてください。",
3731
- "1. mcp__backlog__ で始まるツール(あなた本人の名義。手元にAPIキーは不要)",
3732
- "2. 環境変数 DOMAIN / PROJECT_KEY / BACKLOG_API_KEY があれば Backlog REST API を直接呼ぶ(キーの持ち主の名義)",
3733
- "3. どちらも無ければ、つなぎ方(手元の Claude Code なら /mcp コマンドから backlog、クラウドならセッションのコネクタ設定)を案内して止まる",
3669
+ "1. mcp__backlog__ で始まるツール(あなた本人の名義)",
3670
+ "2. 1 が使えない場合は、/mcp コマンドから backlog を選んでログインするよう案内して止まる(初回だけブラウザが開き、自分の Backlog アカウントでログインします)",
3671
+ "",
3672
+ "環境変数のAPIキーで Backlog のAPIを直接呼ぶことはしないでください(キーの持ち主の名義で記録されてしまいます)。",
3734
3673
  "",
3735
3674
  "投稿する前に、課題キー・本文・経路・名義を提示して承認を得てください。投稿後は投稿先のURLを報告してください。",
3736
3675
  "今回はコメントの追加だけです。課題の削除・クローズ・属性変更はしないでください。",
@@ -5192,7 +5131,6 @@ ${chatRowsToAdd.toString()}
5192
5131
  ${gchatRowsToAdd.toString()}
5193
5132
  ${overlayGchatNotify.toString()}
5194
5133
  ${overlaySlackNotify.toString()}
5195
- ${overlayNotifyAuto.toString()}
5196
5134
  ${devRowsToAdd.toString()}
5197
5135
  ${markExcludedPendingRows.toString()}
5198
5136
  ${designRowsToAdd.toString()}
@@ -10313,6 +10251,7 @@ ${calendarAddUrl.toString()}
10313
10251
  stateSpace: space,
10314
10252
  spaceCount: spaces.length,
10315
10253
  inRow: true,
10254
+ scopeNote: BACKLOG_KEY_SCOPE_NOTE,
10316
10255
  }));
10317
10256
  });
10318
10257
  return;
@@ -11367,18 +11306,13 @@ ${calendarAddUrl.toString()}
11367
11306
  * 描画時と押した後で別々に作ると、押した行だけ見た目の違う札が並ぶ。
11368
11307
  */
11369
11308
  /**
11370
- * @param auto 接続が確認できたので**自動で**通知先になった行か(#589)。
11371
- * 語を増やしすぎない——札は「通知先(自動で設定)」の1つで、外せることと
11372
- * 「外したら戻さない」は hover の説明に置く(行に長い定型文を入れない)。
11373
- * **押して通知先にした行には付けない**(トグルが作る札は常に素の「通知先」)
11309
+ * **自動で入った行にも同じ札を出す(オーナー指示 2026-09-12・#592)。** #589 の初版は
11310
+ * 自動で入った行だけ札の語を変え、外し方を hover で説明していたが、1 日で撤回された
11311
+ * ——自動で入るのが既定の動きなので、画面で区別する意味が無い。外したい人はどちらの行でも
11312
+ * 「通知を止める」を押せばよい。**出し分けを足し戻さない**(notify-auto-gone.test.mjs が番人)
11374
11313
  */
11375
- function notifyBadge(auto) {
11376
- if (auto !== true) return el("span", { class: "badge ds-notify", text: "通知先" });
11377
- return el("span", {
11378
- class: "badge ds-notify",
11379
- text: "通知先(自動で設定)",
11380
- title: "接続が確認できたので、自動でこのチャンネルを通知先にしました。外すには「通知を止める」を押してください(外したら自動では戻しません)。",
11381
- });
11314
+ function notifyBadge() {
11315
+ return el("span", { class: "badge ds-notify", text: "通知先" });
11382
11316
  }
11383
11317
 
11384
11318
  /**
@@ -11422,13 +11356,10 @@ ${calendarAddUrl.toString()}
11422
11356
  // 行の元データも合わせる。ライブの読み直しで同じ行が描き直されるまでの間、
11423
11357
  // ここだけが「いまどちらか」を持っている
11424
11358
  s.notify = next;
11425
- // **押した時点で「自動で設定」ではなくなる(#589)。** 人が入り切りした行に
11426
- // 「自動で設定」と出したままだと、外して押し直した行が自動で戻ったように見える
11427
- s.notifyAuto = false;
11428
11359
  btn.textContent = labelOf();
11429
11360
  var badge = badges.querySelector(".ds-notify");
11430
11361
  // 並びは描画時と同じ(札の先頭)。後ろに足すと、押した行だけ順番が変わる
11431
- if (on && !badge) badges.insertBefore(notifyBadge(false), badges.firstChild);
11362
+ if (on && !badge) badges.insertBefore(notifyBadge(), badges.firstChild);
11432
11363
  if (!on && badge) badges.removeChild(badge);
11433
11364
  });
11434
11365
  });
@@ -11719,10 +11650,12 @@ ${calendarAddUrl.toString()}
11719
11650
  */
11720
11651
  function backlogSecretCards() {
11721
11652
  var spaces = backlogSpacesNow();
11722
- if (spaces.length <= 1) return [secretCard("backlog", SECRET_FORMS["backlog"], { spaceCount: spaces.length })];
11653
+ if (spaces.length <= 1) {
11654
+ return [secretCard("backlog", SECRET_FORMS["backlog"], { spaceCount: spaces.length, scopeNote: BACKLOG_KEY_SCOPE_NOTE })];
11655
+ }
11723
11656
  return spaces.map(function (space) {
11724
11657
  return secretCard("backlog", SECRET_FORMS["backlog"], {
11725
- space: space, stateSpace: space, spaceCount: spaces.length,
11658
+ space: space, stateSpace: space, spaceCount: spaces.length, scopeNote: BACKLOG_KEY_SCOPE_NOTE,
11726
11659
  });
11727
11660
  });
11728
11661
  }
@@ -12524,6 +12457,7 @@ ${calendarAddUrl.toString()}
12524
12457
  stateSpace: dom,
12525
12458
  spaceCount: domains.length,
12526
12459
  inRow: true,
12460
+ scopeNote: BACKLOG_KEY_SCOPE_NOTE,
12527
12461
  }));
12528
12462
  KEY_SLOTS.backlog[dom] = slot;
12529
12463
  added = true;
@@ -13934,7 +13868,7 @@ ${calendarAddUrl.toString()}
13934
13868
  title: "このリポジトリは読み取り対象から除外されています(開発の登録ファイル dev-sources.json の exclude)。この画面からは戻せません。",
13935
13869
  }));
13936
13870
  }
13937
- if (s.notify === true) badges.appendChild(notifyBadge(s.notifyAuto === true));
13871
+ if (s.notify === true) badges.appendChild(notifyBadge());
13938
13872
  // **どのワークスペースのチャンネルかを、必ず行に出す(#104・2026-08-20 に社内も)。**
13939
13873
  //
13940
13874
  // 折りたたみの見出しでまとめるのをやめた(オーナー指摘「複雑になっちゃってる」)ので、
@@ -14876,6 +14810,24 @@ ${calendarAddUrl.toString()}
14876
14810
  * ——このリポジトリが繰り返し踏んでいる形なので、枝ごと落とした。
14877
14811
  * **畳んではいけない種別を足すときに、テストと一緒に枝を戻すこと。**
14878
14812
  */
14813
+ /**
14814
+ * Backlog の鍵カードの「効く範囲」の 1 行(#610 便 2)。
14815
+ *
14816
+ * **鍵の話とログインの話は、同じ場所で 1 回だけ言う。** AI から Backlog を使う経路は
14817
+ * 鍵ではなく**各自のブラウザのログイン**になった(Cortex がホストする接続口に、
14818
+ * 自分の Backlog アカウントで入る=投稿もコメントも本人の名義になる)。鍵カードの
14819
+ * すぐ横で言わないと、「鍵を入れたのに AI から使えない」「AI から使うために鍵を配る」の
14820
+ * どちらかが起きる。**帯は症状・行は一手・繰り返さない**の規則に合わせて 2 文に収める。
14821
+ *
14822
+ * 🔴 **「もう鍵は要りません」と言い切らない。** 案件リポの設定が新しい形に差し替わるのは
14823
+ * 「接続先を登録し直したとき」か「1 回きりの整理を流したとき」で、**この画面が出た時点では
14824
+ * まだ古い形の案件がある**(#610 便 2 の決定ログ「便 2 だけでは 44 案件は 1 件も移行しない」)。
14825
+ * だから**一手**(接続先を登録し直す)を出す形にしてある(実装レビュー O6)。
14826
+ */
14827
+ var BACKLOG_KEY_SCOPE_NOTE =
14828
+ "この鍵は毎晩の取り込み用です。AI から Backlog を読み書きするときは、" +
14829
+ "接続先を登録し直すと鍵なしで繋げるようになります(初回だけブラウザでログインし、あなたの名義で記録されます)。";
14830
+
14879
14831
  var SECRET_FORMS = {
14880
14832
  "figma": {
14881
14833
  icon: "🎨",
@@ -14922,6 +14874,10 @@ ${calendarAddUrl.toString()}
14922
14874
  icon: "📋",
14923
14875
  title: "Backlog のAPIキー",
14924
14876
  how: "Backlog → 個人設定 → API で発行(この案件のプロジェクトが見えるアカウントで)",
14877
+ // ⚠ **desc は足さない。** 「毎晩同期するために使います」の 1 行は「カードが長すぎる」で
14878
+ // 外した経緯があり、secret-card-guidance.test.mjs が空の段落ごと見張っている。
14879
+ // この鍵が何のためのものかは、鍵の効く範囲の行(BACKLOG_KEY_SCOPE_NOTE)が
14880
+ // 1 行で言う(#610 便 2)
14925
14881
  // **案件の担当者が自分で繋ぐ。** 以前は艦隊共通の読み取りアカウントを1つ運用していたが、
14926
14882
  // 案件が増えるたびに「その1人がプロジェクトへ参加追加してキーを配る」ことになり、
14927
14883
  // セットアップが一箇所に詰まる。**繋ぐのは、その案件を持っている人**にする。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.12.60",
3
+ "version": "0.12.62",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,