@takagaki/cortex-decisions-viewer 0.4.62 → 0.4.63
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 +25 -1
- package/dist/render.js +115 -2
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -148,6 +148,26 @@ async function readFleetSources(repoRoot) {
|
|
|
148
148
|
origin: s.origin != null ? String(s.origin) : undefined,
|
|
149
149
|
}))
|
|
150
150
|
: undefined;
|
|
151
|
+
// セットアップの充足チェック。**missing だけを通す。**
|
|
152
|
+
// na(使わないと宣言した能力)を通すと「設定する必要が無いものに設定を促す」偽の警告になり、
|
|
153
|
+
// #101 で潰した穴が復活する。unknown は AWS/gh へ到達できなかった回に出るので、
|
|
154
|
+
// 夜間実行がこけた日に嘘が出る。
|
|
155
|
+
// score / nextActions は通さない——nextActions は checks[].action を平坦化した
|
|
156
|
+
// 同じ内容の別キーで、通すと同じ文が2箇所に出る。
|
|
157
|
+
const checks = Array.isArray(obj.checks)
|
|
158
|
+
? obj.checks
|
|
159
|
+
.filter((c) => c != null && typeof c === "object")
|
|
160
|
+
.filter((c) => String(c.status ?? "") === "missing")
|
|
161
|
+
.map((c) => ({
|
|
162
|
+
id: String(c.id ?? ""),
|
|
163
|
+
label: String(c.label ?? ""),
|
|
164
|
+
category: String(c.category ?? ""),
|
|
165
|
+
status: String(c.status ?? ""),
|
|
166
|
+
action: c.action != null ? String(c.action) : undefined,
|
|
167
|
+
detail: c.detail != null ? String(c.detail) : undefined,
|
|
168
|
+
}))
|
|
169
|
+
.filter((c) => c.id !== "")
|
|
170
|
+
: undefined;
|
|
151
171
|
const internalSources = Array.isArray(obj.internalSources)
|
|
152
172
|
? obj.internalSources
|
|
153
173
|
.filter((s) => s != null && typeof s === "object")
|
|
@@ -157,6 +177,9 @@ async function readFleetSources(repoRoot) {
|
|
|
157
177
|
label: String(s.label ?? ""),
|
|
158
178
|
url: s.url != null ? String(s.url) : undefined,
|
|
159
179
|
lastSync: s.lastSync != null ? String(s.lastSync) : undefined,
|
|
180
|
+
// 取り込み済みの件数。**「同期が走った」と「実際に入った」は別物。**
|
|
181
|
+
// これが無いと、初回全量同期をしていない案件が「接続OK」に見える
|
|
182
|
+
itemCount: typeof s.itemCount === "number" ? s.itemCount : undefined,
|
|
160
183
|
// 会議名に入れる合図。**古い fleet-status.json の matchKeys は引き継がない**
|
|
161
184
|
// (client名と廃止した meetingNamePatterns の寄せ集めで、いま照合には使われていない。
|
|
162
185
|
// 出すと「この語を会議名に入れれば拾われる」と読めてしまう)。
|
|
@@ -225,7 +248,7 @@ async function readFleetSources(repoRoot) {
|
|
|
225
248
|
const secretSources = obj.secretSources && typeof obj.secretSources === "object"
|
|
226
249
|
? obj.secretSources
|
|
227
250
|
: undefined;
|
|
228
|
-
return { externalSources, internalSources, pipelines, tools, fleetGeneratedAt, secretSources };
|
|
251
|
+
return { externalSources, internalSources, pipelines, tools, fleetGeneratedAt, secretSources, checks };
|
|
229
252
|
}
|
|
230
253
|
/** パスがディレクトリとして存在するか */
|
|
231
254
|
async function isDirectory(dirAbs) {
|
|
@@ -1101,6 +1124,7 @@ async function build(opts) {
|
|
|
1101
1124
|
internalSources: fleet.internalSources,
|
|
1102
1125
|
pipelines: fleet.pipelines,
|
|
1103
1126
|
tools: fleet.tools,
|
|
1127
|
+
checks: fleet.checks,
|
|
1104
1128
|
};
|
|
1105
1129
|
// サムネイル(デザイン画面等)をサイトに同梱し、ノードのパスをサイト内相対に書き換える
|
|
1106
1130
|
await node_fs_1.promises.mkdir(outAbs, { recursive: true });
|
package/dist/render.js
CHANGED
|
@@ -224,7 +224,13 @@ function capabilityState(cap, ctx) {
|
|
|
224
224
|
const pipeSkipped = ctx.pipes.some(function (p) {
|
|
225
225
|
return pipeRe != null && pipeRe.test(p.id) && p.applicable === false;
|
|
226
226
|
});
|
|
227
|
-
|
|
227
|
+
// **「同期が走った」と「実際にデータが入った」は別物。** 初回全量同期をしていない案件は、
|
|
228
|
+
// 毎晩の差分同期が成功し続けても0件のままになる(cortex-context の課題管理が実例で、
|
|
229
|
+
// lastSync はあるのに取り込み件数は0だった)。件数を見ないと、タイルが「接続OK」と言い、
|
|
230
|
+
// 同じ画面のセットアップ残りが「初回同期がまだです」と言う状態になる。
|
|
231
|
+
// 件数が無い(古い fleet-status.json・件数を持たない能力)ときは、いままでの判定に従う。
|
|
232
|
+
const emptyForReal = internal != null && internal.itemCount === 0;
|
|
233
|
+
const syncedForReal = internal != null && !emptyForReal && ((internal.lastSync && !pipeSkipped) || internal.url);
|
|
228
234
|
const idle = !off &&
|
|
229
235
|
(isLive
|
|
230
236
|
? liveExts.length === 0
|
|
@@ -944,6 +950,19 @@ a.ds-name:hover { text-decoration: underline; }
|
|
|
944
950
|
width: 40px; height: 40px; flex: 0 0 40px; font-size: 26px; line-height: 1;
|
|
945
951
|
}
|
|
946
952
|
.ds-tile-logo svg { width: 100%; height: 100%; }
|
|
953
|
+
/* セットアップの残り。**直し方を状態と同じ大きさで出す**——
|
|
954
|
+
何が足りないかだけ分かっても、次の一歩が分からなければ画面の意味が薄い */
|
|
955
|
+
.ds-tile-todo { color: var(--muted); }
|
|
956
|
+
.ds-checks { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
|
|
957
|
+
.ds-check-cat { font-size: 12px; font-weight: 700; color: var(--muted); margin-top: 8px; }
|
|
958
|
+
.ds-check {
|
|
959
|
+
display: flex; flex-direction: column; gap: 3px;
|
|
960
|
+
border-left: 3px solid #fcd34d; background: #fffbeb;
|
|
961
|
+
border-radius: 0 8px 8px 0; padding: 8px 12px;
|
|
962
|
+
}
|
|
963
|
+
.ds-check-label { font-size: 13px; font-weight: 700; color: var(--text); }
|
|
964
|
+
.ds-check-action { font-size: 13px; color: var(--text); line-height: 1.7; }
|
|
965
|
+
.ds-check-detail { font-size: 12px; color: var(--muted); }
|
|
947
966
|
.ds-tile-desc { font-size: 12.5px; color: var(--muted); }
|
|
948
967
|
.ds-tile-sub { font-size: 12.5px; margin-top: 2px; }
|
|
949
968
|
.ds-tile-chev { color: var(--muted); }
|
|
@@ -969,6 +988,9 @@ a.ds-name:hover { text-decoration: underline; }
|
|
|
969
988
|
.ds-gate-warn { color: #b45309; }
|
|
970
989
|
.ds-gate-muted { color: #6b7280; }
|
|
971
990
|
.ds-pipes { display: flex; flex-direction: column; gap: 8px; }
|
|
991
|
+
/* 実行状況の行に直し方を添える。同じ run の未達を別の節にも出すと画面に2回並ぶ */
|
|
992
|
+
.ds-pipe-wrap { display: flex; flex-direction: column; gap: 3px; }
|
|
993
|
+
.ds-pipe-todo { font-size: 12.5px; color: var(--muted); line-height: 1.7; padding-left: 4px; }
|
|
972
994
|
.ds-pipe {
|
|
973
995
|
display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px;
|
|
974
996
|
padding: 10px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow);
|
|
@@ -1957,6 +1979,50 @@ ${capabilityState.toString()}
|
|
|
1957
1979
|
var STATE_LABEL = { ok: "● 接続OK", idle: "⦿ 未接続", off: "未使用", warn: "⚠️" };
|
|
1958
1980
|
var SECRET_OF_CAP = { "デザイン": "figma", "課題管理": "backlog", "開発": "external-sources" };
|
|
1959
1981
|
|
|
1982
|
+
// ---- セットアップの残り(checks)----
|
|
1983
|
+
//
|
|
1984
|
+
// **能力に紐づくものはその能力のタイルへ、紐づかないものは節にまとめる。**
|
|
1985
|
+
// 独立した一覧にすると、鍵カードの「現在: 未設定」やタイルの状態と
|
|
1986
|
+
// 同じことを別の言い方で二度言うことになり、ズレたときに読み手が
|
|
1987
|
+
// どちらを信じるか決められない(#101 で判定を1箇所に集めたのと同じ理由)。
|
|
1988
|
+
//
|
|
1989
|
+
// **missing 以外は出さない。** na は「使わないと宣言した能力」で、出すと
|
|
1990
|
+
// 「設定する必要が無いものに設定を促す」偽の警告になる(#101 で潰した穴)。
|
|
1991
|
+
// ビルド時とライブの両方で絞っているが、ここでも見る——経路が増えたときに
|
|
1992
|
+
// 絞り忘れると、いちばん見せてはいけないものが出る側に倒れるため。
|
|
1993
|
+
// **夜間 run の項目は、下の「自動化パイプライン」節が同じ run を出している。**
|
|
1994
|
+
// 両方に出すと、同じ失敗が1画面に2回並ぶ。実行状況はパイプライン節に任せ、
|
|
1995
|
+
// ここでは直し方だけをその行に添える(下の renderPipelines で使う)
|
|
1996
|
+
var PIPE_CHECK = { "update-gold": "nightly_decisionlog", "sync-backlog": "nightly_backlog", "sync-designs": "figma_sync" };
|
|
1997
|
+
var CHECK_CAP = {
|
|
1998
|
+
backlog_secrets: "課題管理", backlog_synced: "課題管理",
|
|
1999
|
+
meeting_minutes: "会議",
|
|
2000
|
+
channels_json: "チャット",
|
|
2001
|
+
figma_token: "デザイン", figma_inventory: "デザイン",
|
|
2002
|
+
submodules: "開発", dev_issues_derived: "開発",
|
|
2003
|
+
};
|
|
2004
|
+
var allChecks = (fleetVal("checks") || []).filter(function (c) {
|
|
2005
|
+
return c != null && c.status === "missing";
|
|
2006
|
+
});
|
|
2007
|
+
// **タイルに出せたものを覚えておく。** 振り分け先の能力タイルが立たない案件
|
|
2008
|
+
//(tools に宣言が無い・行も無い)では出す場所が無くなり、項目が**黙って消える**。
|
|
2009
|
+
// 消えた分は下の節へ落とす——振り分けを間違えても、消えるよりは出る方がよい
|
|
2010
|
+
var shownOnTile = {};
|
|
2011
|
+
function checksFor(cap) {
|
|
2012
|
+
return allChecks.filter(function (c) { return CHECK_CAP[c.id] === cap; });
|
|
2013
|
+
}
|
|
2014
|
+
/** 残りの1件を、直し方まで含めて1行にする */
|
|
2015
|
+
function checkLine(c) {
|
|
2016
|
+
var row = el("div", { class: "ds-check" });
|
|
2017
|
+
row.appendChild(el("span", { class: "ds-check-label", text: c.label }));
|
|
2018
|
+
if (c.action) row.appendChild(el("span", { class: "ds-check-action", text: c.action }));
|
|
2019
|
+
// **detail は内部値が入ることがある**("none" / "success")。読めるものだけ出す
|
|
2020
|
+
if (c.detail && !/^(none|success|failure|skipped|unknown)$/.test(c.detail)) {
|
|
2021
|
+
row.appendChild(el("span", { class: "ds-check-detail", text: c.detail }));
|
|
2022
|
+
}
|
|
2023
|
+
return row;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
1960
2026
|
/** タイルの2行目(状態と読み取り範囲)。**件数は出せる能力だけ出す** */
|
|
1961
2027
|
function tileSub(cap, st) {
|
|
1962
2028
|
var internal = internals.filter(function (s) { return s.kind === cap; })[0];
|
|
@@ -2066,6 +2132,18 @@ ${capabilityState.toString()}
|
|
|
2066
2132
|
if (tools[cap] !== "none" && sk && (SITE.secretKinds || []).indexOf(sk) >= 0 && !((fleetVal("secretSources") || {})[sk])) {
|
|
2067
2133
|
body.appendChild(el("div", { class: "ds-tile-note", text: "⚠ トークンが未設定です" }));
|
|
2068
2134
|
}
|
|
2135
|
+
// セットアップの残りのうち、この能力のもの。**鍵の注記と同じ位置**に出して
|
|
2136
|
+
// 「何が足りないか」と「何をすればよいか」を同じ場所で読めるようにする
|
|
2137
|
+
checksFor(cap).forEach(function (c) {
|
|
2138
|
+
// **直し方が無いものはタイルに出さないが、出したことにもしない。**
|
|
2139
|
+
// shownOnTile を先に立てると節からも外れ、画面のどこにも出なくなる
|
|
2140
|
+
//(実データで mitsubishi の nightly_backlog / figma_token、verdy の
|
|
2141
|
+
// nightly_backlog が消えていた)。タイルは状態を読む場所なので
|
|
2142
|
+
//「足りない」だけの行では埋めず、節の側で拾う
|
|
2143
|
+
if (!c.action) return;
|
|
2144
|
+
shownOnTile[c.id] = true;
|
|
2145
|
+
body.appendChild(el("div", { class: "ds-tile-note ds-tile-todo", text: "→ " + c.action }));
|
|
2146
|
+
});
|
|
2069
2147
|
var tile = el("button", { class: "ds-tile", type: "button", id: "ds-" + cap }, [
|
|
2070
2148
|
ic,
|
|
2071
2149
|
body,
|
|
@@ -2124,11 +2202,46 @@ ${capabilityState.toString()}
|
|
|
2124
2202
|
}
|
|
2125
2203
|
children.push(el("span", { class: "ds-pipe-label", text: p.label || p.id || "" }));
|
|
2126
2204
|
if (t) children.push(el("span", { class: "ds-pipe-time", text: "最終成功: " + t }));
|
|
2127
|
-
|
|
2205
|
+
var row = el("div", { class: "ds-pipe" }, children);
|
|
2206
|
+
// **直し方はこの行に添える。** 同じ run の未達を「セットアップの残り」にも出すと、
|
|
2207
|
+
// 同じ失敗が1画面に2回並ぶ。実行状況はここが正本なので、直し方だけを持ってくる
|
|
2208
|
+
var pc = allChecks.filter(function (c) { return c.id === PIPE_CHECK[p.id]; })[0];
|
|
2209
|
+
if (pc && pc.action) {
|
|
2210
|
+
shownOnTile[pc.id] = true;
|
|
2211
|
+
row = el("div", { class: "ds-pipe-wrap" }, [row, el("div", { class: "ds-pipe-todo", text: "→ " + pc.action })]);
|
|
2212
|
+
}
|
|
2213
|
+
plist.appendChild(row);
|
|
2128
2214
|
});
|
|
2129
2215
|
sec.appendChild(plist);
|
|
2130
2216
|
}
|
|
2131
2217
|
|
|
2218
|
+
// ---- セットアップの残り(どこにも出せなかったもの)----
|
|
2219
|
+
//
|
|
2220
|
+
// **パイプライン節より後に計算する。** 夜間 run の直し方はその行に添えるので、
|
|
2221
|
+
// 先に計算すると shownOnTile がまだ立っておらず、同じ文が2箇所に出る
|
|
2222
|
+
//
|
|
2223
|
+
// **8/8案件で未達の scaffold_drift が、ここで初めて誰かの目に入る。**
|
|
2224
|
+
// 能力のタイルに居場所が無い項目(基盤・Cortex・シークレット)は、
|
|
2225
|
+
// ここに出さないとどこにも出ない。
|
|
2226
|
+
var loose = allChecks.filter(function (c) { return !shownOnTile[c.id]; });
|
|
2227
|
+
if (loose.length) {
|
|
2228
|
+
sec.appendChild(el("div", { class: "ds-sub", text: "セットアップの残り" }));
|
|
2229
|
+
sec.appendChild(el("p", { class: "ds-note", text: "毎晩の自動チェックで見つかった、まだ済んでいない設定です。" }));
|
|
2230
|
+
var byCat = {};
|
|
2231
|
+
var catOrder = [];
|
|
2232
|
+
loose.forEach(function (c) {
|
|
2233
|
+
var k = c.category || "その他";
|
|
2234
|
+
if (!byCat[k]) { byCat[k] = []; catOrder.push(k); }
|
|
2235
|
+
byCat[k].push(c);
|
|
2236
|
+
});
|
|
2237
|
+
var todo = el("div", { class: "ds-checks" });
|
|
2238
|
+
catOrder.forEach(function (k) {
|
|
2239
|
+
todo.appendChild(el("div", { class: "ds-check-cat", text: k }));
|
|
2240
|
+
byCat[k].forEach(function (c) { todo.appendChild(checkLine(c)); });
|
|
2241
|
+
});
|
|
2242
|
+
sec.appendChild(todo);
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2132
2245
|
return sec;
|
|
2133
2246
|
}
|
|
2134
2247
|
function renderDataSources() {
|
package/package.json
CHANGED