@takagaki/cortex-decisions-viewer 0.4.47 → 0.4.48

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
@@ -182,7 +182,10 @@ async function readFleetSources(repoRoot) {
182
182
  tools = undefined;
183
183
  }
184
184
  const fleetGeneratedAt = typeof obj.generatedAt === "string" ? obj.generatedAt : undefined;
185
- return { externalSources, internalSources, pipelines, tools, fleetGeneratedAt };
185
+ const secretSources = obj.secretSources && typeof obj.secretSources === "object"
186
+ ? obj.secretSources
187
+ : undefined;
188
+ return { externalSources, internalSources, pipelines, tools, fleetGeneratedAt, secretSources };
186
189
  }
187
190
  /** パスがディレクトリとして存在するか */
188
191
  async function isDirectory(dirAbs) {
@@ -982,8 +985,13 @@ async function build(opts) {
982
985
  projectKey: opts.projectKey,
983
986
  }
984
987
  : undefined,
988
+ secretKinds: (opts.secretKinds ?? "")
989
+ .split(",")
990
+ .map((s) => s.trim())
991
+ .filter(Boolean),
985
992
  externalSources: fleet.externalSources,
986
993
  fleetGeneratedAt: fleet.fleetGeneratedAt,
994
+ secretSources: fleet.secretSources,
987
995
  internalSources: fleet.internalSources,
988
996
  pipelines: fleet.pipelines,
989
997
  tools: fleet.tools,
package/dist/cli.js CHANGED
@@ -19,6 +19,7 @@ program
19
19
  .option("--intake-url <url>", "投入フォームのLambda URL(環境変数 INTAKE_URL でも可)")
20
20
  .option("--intake-token <token>", "投入フォームの共有秘密トークン(環境変数 INTAKE_TOKEN でも可)")
21
21
  .option("--project-key <key>", "案件キー(投入フォームのルーティングキー)")
22
+ .option("--secret-kinds <kinds>", "鍵の入力欄を出す連携(カンマ区切り。例: figma,external-sources,backlog)")
22
23
  .action(async (dir, opts) => {
23
24
  try {
24
25
  const result = await (0, build_1.build)({
@@ -32,6 +33,7 @@ program
32
33
  intakeUrl: opts.intakeUrl ?? process.env.INTAKE_URL,
33
34
  intakeToken: opts.intakeToken ?? process.env.INTAKE_TOKEN,
34
35
  projectKey: opts.projectKey,
36
+ secretKinds: opts.secretKinds,
35
37
  });
36
38
  console.log(`✓ ${result.count} 件のレコードを ${result.outDir} にビルドしました`);
37
39
  }
package/dist/render.js CHANGED
@@ -767,6 +767,12 @@ a.ds-name:hover { text-decoration: underline; }
767
767
  /* ---- 操作タブ ---- */
768
768
  .ops-intro { color: var(--muted); font-size: 14px; line-height: 1.8; margin: 4px 0 8px; }
769
769
  .ops-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
770
+ .sec-state { font-size: 12.5px; font-weight: 600; margin: 0 0 8px; color: var(--muted); }
771
+ .sec-state.is-managed { color: #1a7f37; }
772
+ .sec-state.is-none { color: var(--muted); font-weight: 400; }
773
+ .sec-how { color: var(--muted); font-size: 12px; line-height: 1.7; margin: 0 0 10px; }
774
+ .sec-input { width: 100%; box-sizing: border-box; font-size: 13px; padding: 7px 10px; margin-bottom: 8px; border: 1px solid var(--border); border-radius: 6px; background: #fff; color: var(--text); }
775
+ .sec-input:focus { outline: none; border-color: var(--accent); }
770
776
  .ops-card {
771
777
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
772
778
  padding: 18px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 10px;
@@ -1656,9 +1662,116 @@ const CLIENT_JS = `
1656
1662
  grid.appendChild(opsCard("🗒️", "会議の文字起こしを追加", "顧客主催の会議など、自動取り込みできない会議の文字起こしファイル(.txt / .docx 等)から議事録を生成します。", "transcript", "文字起こしを追加"));
1657
1663
  grid.appendChild(opsCard("📎", "共有資料を追加", "提案書・仕様書・議事メモなどの資料を Markdown 化して 共有資料 に取り込みます。", "material", "資料を追加"));
1658
1664
  app.appendChild(grid);
1665
+ renderSecrets();
1659
1666
  }
1660
1667
  }
1661
1668
 
1669
+ /** 鍵の入力欄に出す説明。kind は Lambda 側(resolveSecretTarget)と綴りを合わせること */
1670
+ var SECRET_FORMS = {
1671
+ "figma": {
1672
+ icon: "🎨",
1673
+ title: "Figma のトークン",
1674
+ desc: "デザインの画面インベントリを毎晩同期するために使います。",
1675
+ how: "Figma → Settings → Security → Personal access tokens で発行(file_content:read があれば足ります)",
1676
+ },
1677
+ "backlog": {
1678
+ icon: "📋",
1679
+ title: "Backlog のAPIキー",
1680
+ desc: "課題・Wiki・ドキュメントを毎晩同期するために使います。",
1681
+ how: "Backlog → 個人設定 → API で発行",
1682
+ },
1683
+ "external-sources": {
1684
+ icon: "🐙",
1685
+ title: "GitHub の読み取りトークン",
1686
+ desc: "開発リポジトリの Issues / Discussions を読み、Gold の原料にするために使います。",
1687
+ how: "GitHub → Settings → Developer settings → Personal access tokens で、対象リポジトリに Contents / Issues の Read-only を付けて発行",
1688
+ },
1689
+ };
1690
+
1691
+ /**
1692
+ * 連携の鍵(トークン)の投入。
1693
+ *
1694
+ * **入れた値は読み出せない。** 表示・確認の経路は作っていないので、間違えたら入れ直す。
1695
+ * 保存先は案件ごとに分かれており、他の案件には影響しない。
1696
+ * 反映は次回のワークフロー実行から(接続状況の表示が変わるのは翌朝の自己チェック後)。
1697
+ */
1698
+ function renderSecrets() {
1699
+ var kinds = (SITE.secretKinds || []).filter(function (k) { return SECRET_FORMS[k]; });
1700
+ if (!kinds.length) return;
1701
+
1702
+ app.appendChild(el("div", { class: "section-label", text: "連携の鍵" }));
1703
+ app.appendChild(el("p", { class: "ops-intro", text: "各ツールを読むためのトークンです。入れた値はここには表示されません(保存だけできます)。保存先は案件ごとに分かれているので、他の案件には影響しません。" }));
1704
+ var grid = el("div", { class: "ops-grid" });
1705
+ kinds.forEach(function (k) { grid.appendChild(secretCard(k, SECRET_FORMS[k])); });
1706
+ app.appendChild(grid);
1707
+ }
1708
+
1709
+ function secretCard(kind, meta) {
1710
+ // **いま何で動いているか**を先に出す。入れ直したのに反映されていない状態が
1711
+ // 画面で分かるようにする(接続状況は夜間バッチのスナップショットなので、
1712
+ // 保存の直後は前日の値のまま。時刻は上の節に出している)。
1713
+ var src = (SITE.secretSources || {})[kind] || "";
1714
+ var state = src
1715
+ ? el("p", { class: "sec-state" + (src === "Secrets Manager" ? " is-managed" : ""),
1716
+ text: "現在: " + src + " から取得中" })
1717
+ : el("p", { class: "sec-state is-none", text: "現在: 未設定" });
1718
+
1719
+ var input = el("input", { class: "sec-input", type: "password", placeholder: "トークンを貼り付け", autocomplete: "off" });
1720
+ var who = el("input", { class: "sec-input", type: "text", placeholder: "変更者のお名前(履歴に残ります)", autocomplete: "off" });
1721
+ var btn = el("button", { class: "ds-toggle-btn", type: "button", text: "保存" });
1722
+ var msg = el("div", { class: "ds-toggle-msg" });
1723
+
1724
+ btn.addEventListener("click", async function () {
1725
+ var value = input.value;
1726
+ var editor = who.value;
1727
+ if (!value.trim()) { msg.className = "ds-toggle-msg is-error"; msg.textContent = "⚠ トークンを入力してください。"; return; }
1728
+ if (!editor.trim()) { msg.className = "ds-toggle-msg is-error"; msg.textContent = "⚠ お名前を入力してください。"; return; }
1729
+
1730
+ btn.disabled = true;
1731
+ msg.className = "ds-toggle-msg";
1732
+ msg.textContent = "保存中…";
1733
+ var intake = SITE.intake;
1734
+ var pfx = intake.url + (intake.url.indexOf("?") === -1 ? "?" : "&");
1735
+ try {
1736
+ var res = await fetch(pfx + "op=secret&t=" + encodeURIComponent(intake.token), {
1737
+ method: "POST",
1738
+ headers: { "content-type": "application/json" },
1739
+ // **シークレット名は送らない。** どの連携かだけを送り、書き込み先はサーバが案件から決める。
1740
+ body: JSON.stringify({ projectKey: intake.projectKey, kind: kind, value: value, editor: editor }),
1741
+ });
1742
+ var j = await res.json().catch(function () { return {}; });
1743
+ if (!res.ok) {
1744
+ msg.className = "ds-toggle-msg is-error";
1745
+ msg.textContent = "✗ " + (j.message || "保存できませんでした。");
1746
+ btn.disabled = false;
1747
+ return;
1748
+ }
1749
+ msg.className = "ds-toggle-msg is-ok";
1750
+ msg.textContent = "✓ " + (j.message || "保存しました。");
1751
+ // 入れた値は画面に残さない(肩越しに見えるのを防ぐ)。お名前は続けて直せるよう残す。
1752
+ input.value = "";
1753
+ btn.disabled = false;
1754
+ } catch (e) {
1755
+ msg.className = "ds-toggle-msg is-error";
1756
+ msg.textContent = "✗ 通信に失敗しました。";
1757
+ btn.disabled = false;
1758
+ }
1759
+ });
1760
+
1761
+ return el("div", { class: "ops-card" }, [
1762
+ el("div", { class: "ops-card-head" }, [
1763
+ el("span", { class: "ops-card-icon", text: meta.icon }),
1764
+ el("h3", { class: "ops-card-title", text: meta.title }),
1765
+ ]),
1766
+ el("p", { class: "ops-card-desc", text: meta.desc }),
1767
+ state,
1768
+ el("p", { class: "sec-how", text: meta.how }),
1769
+ input,
1770
+ who,
1771
+ el("div", { class: "ds-toggle" }, [btn, msg]),
1772
+ ]);
1773
+ }
1774
+
1662
1775
  // ---------- 接続マップ(ビルド時生成のSVGを<template>から取り出して表示) ----------
1663
1776
  function renderConnMap() {
1664
1777
  var tpl = document.getElementById("conn-map");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.4.47",
3
+ "version": "0.4.48",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,