@takagaki/cortex-decisions-viewer 0.4.77 → 0.4.78

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 +57 -2
  2. package/package.json +1 -1
package/dist/render.js CHANGED
@@ -1329,6 +1329,8 @@ a.ds-name:hover { text-decoration: underline; }
1329
1329
  .rt-steps li { margin: 2px 0; }
1330
1330
  /* URLは長いので、入力欄を伸ばしてボタンを右に置く(折り返しても崩れないように wrap) */
1331
1331
  .rt-url-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
1332
+ .rt-copy { margin: 6px 0 10px; }
1333
+ .rt-copy-text { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: #f3f4f6; border: 1px solid #e5e7eb; border-radius: 6px; padding: 4px 10px; user-select: all; }
1332
1334
  .rt-url { flex: 1 1 260px; margin-bottom: 0; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px; }
1333
1335
  /* 稼働中の表示(#123)。緑は「動いている」の合図で、見出しの右に置いて先に目に入れる */
1334
1336
  .rt-live-badge {
@@ -1543,6 +1545,46 @@ ${capabilityState.toString()}
1543
1545
  footerEl.textContent = "生成: " + SITE.generatedAt +
1544
1546
  (SITE.repoBaseUrl ? " / " + SITE.repoBaseUrl.split("://").pop() + " (" + SITE.branch + ")" : "");
1545
1547
 
1548
+ /**
1549
+ * 「貼り付けて使う文字列」を、選べる形+コピーボタンで出す。
1550
+ *
1551
+ * **手で打たせない。** 「/invite @Cortex」のような短いものでも、打ち間違いは黙って失敗し、
1552
+ * 利用者には「招待したのに読まれない」としか見えない。
1553
+ * clipboard API が使えない環境(http・古いブラウザ・権限拒否)では、**選択までしてやって**
1554
+ * 次の一手を伝える(何も起きないのが一番悪い)。
1555
+ */
1556
+ function copyRow(text) {
1557
+ // **input と button を使わない。** 追加フォームの中に置くので、input を足すと
1558
+ // 「先頭がURL欄・末尾が名前欄」、button を足すと「最初のボタンが送信」という
1559
+ // フォームの並びが崩れる(実際にテストが壊れて気づいた)。
1560
+ // 表示は code、コピーは role="button" のリンクで代える。
1561
+ var field = el("code", { class: "rt-copy-text", text: text });
1562
+ var btn = el("a", { class: "ds-toggle-btn", role: "button", tabindex: "0", text: "コピー" });
1563
+ var msg = el("div", { class: "ds-toggle-msg" });
1564
+ btn.addEventListener("click", function () {
1565
+ var done = function () { msg.className = "ds-toggle-msg is-ok"; msg.textContent = "✓ コピーしました。"; };
1566
+ var fallback = function () {
1567
+ // clipboard が使えない環境では、せめて**文字列を選択状態にして**次の一手を伝える
1568
+ try {
1569
+ var r = document.createRange();
1570
+ r.selectNodeContents(field);
1571
+ var sel = window.getSelection();
1572
+ sel.removeAllRanges();
1573
+ sel.addRange(r);
1574
+ if (document.execCommand && document.execCommand("copy")) return done();
1575
+ } catch (e) { /* 下の案内へ */ }
1576
+ msg.className = "ds-toggle-msg is-error";
1577
+ msg.textContent = "⚠ 自動コピーできませんでした。選択された文字列を手でコピーしてください。";
1578
+ };
1579
+ try {
1580
+ if (navigator.clipboard && navigator.clipboard.writeText) {
1581
+ navigator.clipboard.writeText(text).then(done, fallback);
1582
+ } else fallback();
1583
+ } catch (e) { fallback(); }
1584
+ });
1585
+ return el("div", { class: "rt-copy" }, [el("div", { class: "rt-url-row" }, [field, btn]), msg]);
1586
+ }
1587
+
1546
1588
  function el(tag, props, children) {
1547
1589
  var e = document.createElement(tag);
1548
1590
  if (props) Object.keys(props).forEach(function (k) {
@@ -1947,7 +1989,9 @@ ${capabilityState.toString()}
1947
1989
  };
1948
1990
  var DS_GATE = {
1949
1991
  "ok": { text: "接続OK", cls: "ds-gate-ok" },
1950
- "not_in_channel": { text: "bot未招待", cls: "ds-gate-warn" },
1992
+ // **状態だけでなく、次にすることを書く。** bot未招待」では何をすればよいか分からない
1993
+ // (公開チャンネルでも招待が要ることは Slack の仕様で、知らない人のほうが多い)
1994
+ "not_in_channel": { text: "Slackで招待してください", cls: "ds-gate-warn" },
1951
1995
  "unreachable": { text: "アクセス不可", cls: "ds-gate-warn" },
1952
1996
  "no_token": { text: "トークン未設定", cls: "ds-gate-muted" },
1953
1997
  "unknown": { text: "不明", cls: "ds-gate-muted" },
@@ -3476,7 +3520,11 @@ ${capabilityState.toString()}
3476
3520
  // 別名を付けたいときだけ入れてもらう。
3477
3521
  namePlaceholder: "表示名(省略するとSlackから取得します)",
3478
3522
  requiredNote: "チャンネルのURLを入力してください。",
3479
- hint: "チャンネル名を右クリック →「リンクをコピー」で出るURLを貼ってください。追加しただけでは Gold 昇格には載りません(載せるには各チャンネルの「Gold昇格を始める」を押します)。cortex の Bot が入っていないチャンネルは名前を取得できません(「名前未取得」で登録され、Bot招待後にGold昇格をONにすると実名に変わります)。",
3523
+ // **招待の話を先頭に置く。** Slack の仕様で、ボットは**公開チャンネルでも**招待されるまで
3524
+ // 中身を1件も読めない(conversations.history が not_in_channel を返す・2026-08-16 実測+公式ドキュメント)。
3525
+ // 以前は「名前が取得できない」を主に書いていたが、読めない方が重い話なので順序を入れ替えた。
3526
+ hint: "先に Slack でそのチャンネルを開き、下のコマンドを貼って Cortex を招待してください。公開チャンネルでも招待が必要で、招待していないと中身を読めません。そのあと、チャンネル名を右クリック →「リンクをコピー」で出るURLを下に貼ります。追加しただけでは Gold 昇格には載りません(載せるには各チャンネルの「Gold昇格を始める」を押します)。招待前に登録すると名前は「名前未取得」になり、招待後にGold昇格をONにすると実名に変わります。",
3527
+ copyText: "/invite @Cortex",
3480
3528
  // **「Goldに載る」と書かない。** 追加だけでは載らないので嘘になる。
3481
3529
  // 確認する理由は「中央Botで読みに行く」「他案件の取り違え」。
3482
3530
  confirmLines: function (v) {
@@ -3487,6 +3535,10 @@ ${capabilityState.toString()}
3487
3535
  "",
3488
3536
  v,
3489
3537
  "",
3538
+ // Slack の仕様(公開チャンネルでも招待が要る)を、最後にもう一度置く。
3539
+ // 「追加したのに何も取り込まれない」の原因のほとんどがこれ。
3540
+ "※ Slack でこのチャンネルに Cortex を招待していないと、中身は読めません。",
3541
+ "",
3490
3542
  "追加しますか?",
3491
3543
  ];
3492
3544
  },
@@ -3758,6 +3810,9 @@ ${capabilityState.toString()}
3758
3810
  var box = el("div", opts.adder ? { class: "ds-addform", "data-adder": opts.adder } : { class: "ds-addform" }, [
3759
3811
  el("div", { class: "ds-addform-title", text: opts.title }),
3760
3812
  opts.hint ? el("p", { class: "sec-how", text: opts.hint }) : null,
3813
+ // 手順の中に「どこかへ貼る文字列」があるときは、**手で打たせない**。
3814
+ // 「/invite @Cortex」のような短い文字列でも、打ち間違えると黙って失敗する
3815
+ opts.copyText ? copyRow(opts.copyText) : null,
3761
3816
  main,
3762
3817
  name,
3763
3818
  wsSelect,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.4.77",
3
+ "version": "0.4.78",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,