@takagaki/cortex-decisions-viewer 0.12.49 → 0.12.51
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/render.js +234 -22
- package/package.json +1 -1
package/dist/render.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.STATE_CONFIRMING = exports.UNSETTLED_LIMITS = exports.ALREADY_REGISTERED = exports.LIVE_CONFIRM_LIMITS = exports.CLAUDE_CODE_LINK = void 0;
|
|
3
|
+
exports.STATE_CONFIRMING = exports.PROBE_WAIT_TIMEOUT_TEXT = exports.UNSETTLED_LIMITS = exports.ALREADY_REGISTERED = exports.LIVE_CONFIRM_LIMITS = exports.CLAUDE_CODE_LINK = void 0;
|
|
4
4
|
exports.renderSite = renderSite;
|
|
5
5
|
exports.renderSiteWithAssets = renderSiteWithAssets;
|
|
6
6
|
exports.viewerAssetSources = viewerAssetSources;
|
|
@@ -28,6 +28,7 @@ exports.unsettledRegisteredCount = unsettledRegisteredCount;
|
|
|
28
28
|
exports.registeredRowsToAdd = registeredRowsToAdd;
|
|
29
29
|
exports.subtractRemovedRegistered = subtractRemovedRegistered;
|
|
30
30
|
exports.mergeRegisteredFleet = mergeRegisteredFleet;
|
|
31
|
+
exports.probeWaitPhase = probeWaitPhase;
|
|
31
32
|
exports.nextStateDelay = nextStateDelay;
|
|
32
33
|
exports.sanitizeSecretsNow = sanitizeSecretsNow;
|
|
33
34
|
exports.secretStateFromNow = secretStateFromNow;
|
|
@@ -1623,6 +1624,44 @@ const UNSETTLED_POLL_MS = 60 * 1000;
|
|
|
1623
1624
|
* 書き換えられ、toString() で流し込んだ先には exports が無い)。
|
|
1624
1625
|
*/
|
|
1625
1626
|
exports.UNSETTLED_LIMITS = { ttlMs: UNSETTLED_TTL_MS, pollMs: UNSETTLED_POLL_MS };
|
|
1627
|
+
/**
|
|
1628
|
+
* 「接続を確認」(dispatch 種別)を押したあと、結果が届いたか(#523 S3・設計レビュー🔴2)。
|
|
1629
|
+
*
|
|
1630
|
+
* Backlog / Drive / Figma の確認は**その案件の同期を1回起こす**ので、答えは接続状態
|
|
1631
|
+
* ストアの行として数分〜十数分後に届く。押した瞬間には何も変わらない。
|
|
1632
|
+
*
|
|
1633
|
+
* 🔴 **壁時計で判定しない。** 「押した時刻より新しい行」で見ると、画面の時計とサーバの
|
|
1634
|
+
* 時計がずれている端末で**永久に届かない**(または、届く前に届いたことになる)。
|
|
1635
|
+
* 押す前にその行の `at` を控え、**辞書順でそれより大きい `at` の行**が来たら差し替える
|
|
1636
|
+
* ——ストアの `at` は正規化済みの ISO 8601(Z・ミリ秒)なので、辞書順=時刻順。
|
|
1637
|
+
*
|
|
1638
|
+
* 上限は `UNSETTLED_TTL_MS`(15分・仮置きと同じ)。過ぎたら**待てば出ると言い続けない**。
|
|
1639
|
+
*
|
|
1640
|
+
* @param wait { at: 押す前に控えた行の `at`(無ければ ""), startedAt: 押した時刻 }
|
|
1641
|
+
* @param row いまのその ref の**いちばん新しい行**(問いは問わない。無ければ null)
|
|
1642
|
+
* ——押して起きるのは同期そのものなので、答えが `reachable` とは限らない
|
|
1643
|
+
* @returns "arrived" | "timeout" | "waiting"(`wait` が無ければ "")
|
|
1644
|
+
*/
|
|
1645
|
+
function probeWaitPhase(wait, row, now) {
|
|
1646
|
+
if (!wait)
|
|
1647
|
+
return "";
|
|
1648
|
+
const base = String((wait && wait.at) || "");
|
|
1649
|
+
const at = String((row && row.at) || "");
|
|
1650
|
+
if (at && at > base)
|
|
1651
|
+
return "arrived";
|
|
1652
|
+
const started = Number((wait && wait.startedAt) || 0);
|
|
1653
|
+
// 端末の時計が戻った回(NTP 補正)は待ち続けない——`nextStateDelay` と同じ理由で、
|
|
1654
|
+
// 経過が負なら期限の判定に使わずに待ちを続ける
|
|
1655
|
+
const age = now - started;
|
|
1656
|
+
if (Number.isFinite(age) && age >= UNSETTLED_TTL_MS)
|
|
1657
|
+
return "timeout";
|
|
1658
|
+
return "waiting";
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* 待ちが上限に達したときの1文(#523 S3・決定8)。**「もう少しお待ちください」と言わない**
|
|
1662
|
+
* ——15分待って届かないなら、待つのではなく実行状況を見に行く番。
|
|
1663
|
+
*/
|
|
1664
|
+
exports.PROBE_WAIT_TIMEOUT_TEXT = "まだ結果が届いていません(Actions の実行状況を確認してください)。";
|
|
1626
1665
|
/**
|
|
1627
1666
|
* 次に取り直すまでの ms。もう取り直す必要が無ければ null。
|
|
1628
1667
|
*
|
|
@@ -2949,11 +2988,8 @@ function tutorialChallenge4Prompt(decisions) {
|
|
|
2949
2988
|
* 規約はプロンプトに書き写さず、規約のあるファイル(README.md・template.md)をAIに読ませ、
|
|
2950
2989
|
* 中身は利用者に聞き返させる(AI導線ボタンのプロンプトと同じ方針)。
|
|
2951
2990
|
* 規約がどこにも無い手順(外部サービスへのつなぎ方・投稿経路の判定)だけを骨子として残す。
|
|
2952
|
-
* 対応するスキルがある操作は、スキルが使える環境ではそちらを優先させる旨を冒頭に添える。
|
|
2953
2991
|
*/
|
|
2954
2992
|
const TUT_MEMBER_PROMPT = [
|
|
2955
|
-
"(update-member スキルが使える環境なら、そのスキルの手順を優先してください。)",
|
|
2956
|
-
"",
|
|
2957
2993
|
"Cortex/Members/README.md と Cortex/Members/template.md を読んで規約を把握してから、Cortex/Members/records/ にあるわたし自身のメンバーレコードの表示名(title)を変更してください。Gold層へ書き込む練習です。名簿にわたしのレコードが無ければ、新規に1件作ってかまいません。",
|
|
2958
2994
|
"わたしが誰で、何をどう変えたいかは、まずわたしに質問してください。",
|
|
2959
2995
|
"あなた(人間)が内容を確認して編集したので、status が draft なら active に上げてください。",
|
|
@@ -3915,6 +3951,9 @@ a.ds-tile:hover { text-decoration: none; }
|
|
|
3915
3951
|
(flex: 1 1 100%)——状態バッジの横に押し込むと、いちばん読ませたい一文が
|
|
3916
3952
|
カード幅に負けて省略される。状態の語より弱く、しかし読める大きさで出す */
|
|
3917
3953
|
.ds-gate-help { flex: 1 1 100%; margin: 4px 0 0; font-size: 12px; line-height: 1.7; color: #6b7280; }
|
|
3954
|
+
/* 「接続を確認」(dispatch)を押したあとの返事(#523 S3)。**必ず自分の行を占める**
|
|
3955
|
+
——行の途中に挟むと ID と「外す」が案内文の下へ落ちる(.ds-gate-help と同じ理由) */
|
|
3956
|
+
.ds-probe-wait { flex: 1 1 100%; margin: 4px 0 0; font-size: 12px; line-height: 1.7; color: #6b7280; }
|
|
3918
3957
|
/* 管理者への依頼文(#521)。手順が複数行あるので details に畳む——開いたまま出すと、
|
|
3919
3958
|
1行のはずの案内(.ds-gate-help / .ds-probe-help)が一覧を占領する */
|
|
3920
3959
|
.ds-gate-request { margin-top: 4px; }
|
|
@@ -4406,6 +4445,10 @@ var ALREADY_REGISTERED_SUFFIX = ${JSON.stringify(ALREADY_REGISTERED_SUFFIX)};
|
|
|
4406
4445
|
${isAlreadyRegistered.toString()}
|
|
4407
4446
|
var UNSETTLED_TTL_MS = ${JSON.stringify(UNSETTLED_TTL_MS)};
|
|
4408
4447
|
var UNSETTLED_POLL_MS = ${JSON.stringify(UNSETTLED_POLL_MS)};
|
|
4448
|
+
// dispatch の「接続を確認」の待ち(#523 S3)。**判定は1つの関数に閉じる**——
|
|
4449
|
+
// 画面側に書き写すと、押した行と一覧の判定が別々にずれる(🔴2 の壁時計に戻る)
|
|
4450
|
+
${probeWaitPhase.toString()}
|
|
4451
|
+
var PROBE_WAIT_TIMEOUT_TEXT = ${JSON.stringify(exports.PROBE_WAIT_TIMEOUT_TEXT)};
|
|
4409
4452
|
${sanitizeRegisteredNow.toString()}
|
|
4410
4453
|
${chatRowsToAdd.toString()}
|
|
4411
4454
|
${gchatRowsToAdd.toString()}
|
|
@@ -4994,10 +5037,6 @@ ${calendarAddUrl.toString()}
|
|
|
4994
5037
|
// レポート等スキルの無いディレクトリは対象外(ボタンを出さない)。
|
|
4995
5038
|
// プロンプトには規約を書き写さない。各区画の README.md(規約)と template.md(雛形)をAIに読ませ、
|
|
4996
5039
|
// 中身は利用者に聞き返させる(規約の二重定義を避け、READMEの更新がそのまま効くようにするため)。
|
|
4997
|
-
// スキルが使える環境(手元のCLI・デスクトップ等)ではそちらを優先させる旨を冒頭に添える。
|
|
4998
|
-
function aiHead(skill) {
|
|
4999
|
-
return "(" + skill + " スキルが使える環境なら、そのスキルの手順を優先してください。)\\n\\n";
|
|
5000
|
-
}
|
|
5001
5040
|
// 公開範囲の規律(内部限定情報を書かない等)は各区画の README.md に書いてあるので、プロンプトには重ねない。
|
|
5002
5041
|
// 顧客も押すボタンなので、内側の運用事情を文面に出さない。
|
|
5003
5042
|
var AI_COMMON = "";
|
|
@@ -5029,7 +5068,6 @@ ${calendarAddUrl.toString()}
|
|
|
5029
5068
|
].join("\\n");
|
|
5030
5069
|
var GOLD_SKILL = {
|
|
5031
5070
|
"Decisions": {
|
|
5032
|
-
skill: "update-decision",
|
|
5033
5071
|
noun: "決定",
|
|
5034
5072
|
dir: "Cortex/Decisions",
|
|
5035
5073
|
add: [
|
|
@@ -5048,7 +5086,6 @@ ${calendarAddUrl.toString()}
|
|
|
5048
5086
|
},
|
|
5049
5087
|
},
|
|
5050
5088
|
"Glossary": {
|
|
5051
|
-
skill: "update-glossary",
|
|
5052
5089
|
noun: "用語",
|
|
5053
5090
|
dir: "Cortex/Glossary",
|
|
5054
5091
|
add: [
|
|
@@ -5066,7 +5103,6 @@ ${calendarAddUrl.toString()}
|
|
|
5066
5103
|
},
|
|
5067
5104
|
},
|
|
5068
5105
|
"Members": {
|
|
5069
|
-
skill: "update-member",
|
|
5070
5106
|
noun: "メンバー",
|
|
5071
5107
|
dir: "Cortex/Members",
|
|
5072
5108
|
add: [
|
|
@@ -5084,7 +5120,6 @@ ${calendarAddUrl.toString()}
|
|
|
5084
5120
|
},
|
|
5085
5121
|
},
|
|
5086
5122
|
"Rules": {
|
|
5087
|
-
skill: "update-rule",
|
|
5088
5123
|
noun: "ルール",
|
|
5089
5124
|
dir: "Cortex/Rules",
|
|
5090
5125
|
add: [
|
|
@@ -5111,7 +5146,7 @@ ${calendarAddUrl.toString()}
|
|
|
5111
5146
|
function aiAddBar(sectionName) {
|
|
5112
5147
|
var g = goldSkill(sectionName);
|
|
5113
5148
|
if (!g) return null;
|
|
5114
|
-
var prompt =
|
|
5149
|
+
var prompt = g.add + AI_COMMON;
|
|
5115
5150
|
return el("div", { class: "ai-add-bar" }, [
|
|
5116
5151
|
aiLink("ai-add-btn", prompt, "+ AIで登録"),
|
|
5117
5152
|
]);
|
|
@@ -5124,7 +5159,7 @@ ${calendarAddUrl.toString()}
|
|
|
5124
5159
|
// target=AIに読ませるファイル(対象レコード+規約のREADME)、subject=直す対象の呼び名
|
|
5125
5160
|
var target = (pathRef ? pathRef + " と " : "") + g.dir + "/README.md";
|
|
5126
5161
|
var subject = "この" + g.noun + "「" + title + "」" + (pathRef ? "" : "(" + rec.id + ")");
|
|
5127
|
-
var prompt =
|
|
5162
|
+
var prompt = g.edit(target, subject) + AI_COMMON;
|
|
5128
5163
|
return aiLink("ai-edit-btn", prompt, "AIで編集");
|
|
5129
5164
|
}
|
|
5130
5165
|
|
|
@@ -5184,7 +5219,7 @@ ${calendarAddUrl.toString()}
|
|
|
5184
5219
|
: "この記録は確認済み(status: active)です。**適用後も status は active のままにしてください**(draft に戻さないでください)。",
|
|
5185
5220
|
);
|
|
5186
5221
|
lines.push("書き込む前に、変更内容を提示して承認を得てください。");
|
|
5187
|
-
var prompt =
|
|
5222
|
+
var prompt = lines.join("\\n") + AI_COMMON;
|
|
5188
5223
|
return aiLink("ai-apply-btn", prompt, "AIで適用");
|
|
5189
5224
|
}
|
|
5190
5225
|
|
|
@@ -8614,7 +8649,11 @@ ${calendarAddUrl.toString()}
|
|
|
8614
8649
|
function refreshStateTimer() {
|
|
8615
8650
|
var n = unsettledNow();
|
|
8616
8651
|
var cal = calendarPollWanted();
|
|
8617
|
-
|
|
8652
|
+
// 「接続を確認」(dispatch)の結果待ちも取り直しを回す理由になる(#523 S3)。
|
|
8653
|
+
// **仮置きの数(unsettledNow)には1件も入らない**——押した行は既に登録済みなので、
|
|
8654
|
+
// これを見ないと押した人は15分間なにも更新されない画面を見ることになる
|
|
8655
|
+
var probing = probeWaitsPending();
|
|
8656
|
+
if (!n && !cal && !probing) {
|
|
8618
8657
|
if (stateTimer) { clearTimeout(stateTimer); stateTimer = null; }
|
|
8619
8658
|
stateSince = null;
|
|
8620
8659
|
return;
|
|
@@ -8625,7 +8664,9 @@ ${calendarAddUrl.toString()}
|
|
|
8625
8664
|
// カレンダー待ちは**仮置きの15分の期限に載せない**(作成の約束は20分で、載せると
|
|
8626
8665
|
// 最後の5分だけ静かに止まる=文言が嘘になる時間帯ができる)。依頼の時刻から測った
|
|
8627
8666
|
// 期限は calendarPollWanted が持っているので、ここは間隔だけを決める
|
|
8628
|
-
|
|
8667
|
+
// 確認の結果待ちも**仮置きの15分の期限に載せない**(期限は待ちごとに
|
|
8668
|
+
// 「押した時刻」から測ってあり、「probeWaitsPending」 が切る)。ここは間隔だけ
|
|
8669
|
+
var delay = cal || probing ? UNSETTLED_POLL_MS : nextStateDelay(n, stateSince, Date.now());
|
|
8629
8670
|
if (delay == null) return;
|
|
8630
8671
|
stateTimer = setTimeout(stateTick, delay);
|
|
8631
8672
|
}
|
|
@@ -10858,11 +10899,165 @@ ${calendarAddUrl.toString()}
|
|
|
10858
10899
|
return row;
|
|
10859
10900
|
}
|
|
10860
10901
|
|
|
10861
|
-
|
|
10902
|
+
/* -------------------------------------------------------------------------
|
|
10903
|
+
* dispatch の「接続を確認」(#523 S3・Backlog / Drive / Figma)
|
|
10904
|
+
* -------------------------------------------------------------------------
|
|
10905
|
+
* Slack / GitHub / Google Chat の確認(「probeSection」)は中央がその場で叩いて
|
|
10906
|
+
* 答えを返すが、この3つは**中央が鍵を読まない**(#105 決定5)ので、押すと
|
|
10907
|
+
* その案件の同期が1回起きるだけ。答えは接続状態ストアの行として後から届く。
|
|
10908
|
+
*
|
|
10909
|
+
* だから画面がすることは3つ:
|
|
10910
|
+
* 1. 押す前にその行の 「at」 を控える(🔴2・壁時計を使わない)
|
|
10911
|
+
* 2. 「確認を開始しました」を出して、取り直し(op=state)を回す
|
|
10912
|
+
* 3. 控えた 「at」 より新しい行が届いたら、待ちを解いて札を描き直す
|
|
10913
|
+
* ——札そのものは 「appendReachableChip」 が描くので、ここは待ちの表示だけ
|
|
10914
|
+
* ----------------------------------------------------------------------- */
|
|
10915
|
+
|
|
10916
|
+
/**
|
|
10917
|
+
* 押した行ごとの待ち。**行の DOM ではなくここに持つ**——一覧は取り直しのたびに
|
|
10918
|
+
* 作り直されるので、行に持たせると押した直後の1回で消える。
|
|
10919
|
+
*/
|
|
10920
|
+
var PROBE_WAITS = {};
|
|
10921
|
+
|
|
10922
|
+
/** 待ちの鍵。**札の突き合わせと同じ畳み方**(「stateRefKey」)にする */
|
|
10923
|
+
function probeWaitKey(capId, ref) {
|
|
10924
|
+
return capId + "\\u0001" + (stateRefKey(capId, ref, "") || String(ref || ""));
|
|
10925
|
+
}
|
|
10926
|
+
|
|
10927
|
+
/** その行の待ち(無ければ null)。**期限切れも返す**(文言を出し分けるのは呼び手) */
|
|
10928
|
+
function probeWaitOf(capId, ref) {
|
|
10929
|
+
return PROBE_WAITS[probeWaitKey(capId, ref)] || null;
|
|
10930
|
+
}
|
|
10931
|
+
|
|
10932
|
+
/**
|
|
10933
|
+
* その接続先の**いちばん新しい行**(問いは問わない)。待ちの基準と到着の判定に使う。
|
|
10934
|
+
*
|
|
10935
|
+
* 🔴 **「届くか」の行だけを見ない。** 押すと起きるのは同期そのものなので、
|
|
10936
|
+
* 届いた答えが 「reachable」 とは限らない——Figma は当面 「ingested」 しか書かれず
|
|
10937
|
+
* (書き手は S4)、Backlog / Drive も回によっては片方しか動かない。
|
|
10938
|
+
* 「届くか」だけを見ると、**同期が終わって行が更新されているのに15分待たせる**。
|
|
10939
|
+
*/
|
|
10940
|
+
function probeLatestRow(capId, ref) {
|
|
10941
|
+
var rows = LIVE_STATE;
|
|
10942
|
+
if (!rows || !rows.length || !capId) return null;
|
|
10943
|
+
var want = stateRefKey(capId, ref, "");
|
|
10944
|
+
if (!want) return null;
|
|
10945
|
+
var best = null;
|
|
10946
|
+
for (var i = 0; i < rows.length; i++) {
|
|
10947
|
+
var r = rows[i];
|
|
10948
|
+
if (!r || r.cap !== capId) continue;
|
|
10949
|
+
if (stateRefKey(capId, r.ref, r.workspace) !== want) continue;
|
|
10950
|
+
if (!best || String(r.at || "") > String(best.at || "")) best = r;
|
|
10951
|
+
}
|
|
10952
|
+
return best;
|
|
10953
|
+
}
|
|
10954
|
+
|
|
10955
|
+
/**
|
|
10956
|
+
* その行の待ちの相。届いていれば待ちを**その場で解く**(次の描き直しで札だけが残る)。
|
|
10957
|
+
*/
|
|
10958
|
+
function probeWaitPhaseOf(capId, ref) {
|
|
10959
|
+
var key = probeWaitKey(capId, ref);
|
|
10960
|
+
var wait = PROBE_WAITS[key];
|
|
10961
|
+
if (!wait) return "";
|
|
10962
|
+
var phase = probeWaitPhase(wait, probeLatestRow(capId, ref), Date.now());
|
|
10963
|
+
if (phase === "arrived") delete PROBE_WAITS[key];
|
|
10964
|
+
return phase;
|
|
10965
|
+
}
|
|
10966
|
+
|
|
10967
|
+
/** まだ結果を待っている行があるか(取り直しを続けるかの判断・「refreshStateTimer」) */
|
|
10968
|
+
function probeWaitsPending() {
|
|
10969
|
+
var now = Date.now();
|
|
10970
|
+
for (var key in PROBE_WAITS) {
|
|
10971
|
+
if (!Object.prototype.hasOwnProperty.call(PROBE_WAITS, key)) continue;
|
|
10972
|
+
var w = PROBE_WAITS[key];
|
|
10973
|
+
// **鍵から ref を戻さない。** 待ちに控えてある能力と ref をそのまま使う
|
|
10974
|
+
if (probeWaitPhase(w, probeLatestRow(w.cap, w.ref), now) === "waiting") return true;
|
|
10975
|
+
}
|
|
10976
|
+
return false;
|
|
10977
|
+
}
|
|
10978
|
+
|
|
10979
|
+
/**
|
|
10980
|
+
* 能力 → 「op=probe」 に送る種別。**画面の能力名をそのまま送らない**
|
|
10981
|
+
* (サーバの受け口はレジストリの id で、「materials」 ではなく 「drive」)。
|
|
10982
|
+
* **空を返した能力にはボタンが出ない。**
|
|
10983
|
+
*/
|
|
10984
|
+
function dispatchProbeTypeOf(capId) {
|
|
10985
|
+
return { issues: "backlog", materials: "drive", design: "figma" }[String(capId || "")] || "";
|
|
10986
|
+
}
|
|
10987
|
+
|
|
10988
|
+
/**
|
|
10989
|
+
* 接続先1件の「接続を確認」(ボタン+待ちの1文)を行に足す。
|
|
10990
|
+
*
|
|
10991
|
+
* **ボタンは行の中**(Slack の行と同じ・2026-08-20 の「1行が2段になる」を繰り返さない)。
|
|
10992
|
+
* 待ちの1文は 「.ds-gate-help」 で行の最後に落とす(「appendReachableReason」 の項)。
|
|
10993
|
+
*/
|
|
10994
|
+
function appendDispatchProbe(row, capId, ref) {
|
|
10995
|
+
var type = dispatchProbeTypeOf(capId);
|
|
10996
|
+
// **書き込み経路が無ければ出さない**(押しても何も起きないボタンを置かない)
|
|
10997
|
+
if (!type || !SITE.intake || !ref) return row;
|
|
10998
|
+
var btn = el("button", { class: "ds-toggle-btn", type: "button", text: "接続を確認" });
|
|
10999
|
+
// 🔴 **「ds-gate-help」 を付けない。** あれは「最後に測った理由」の1段で、
|
|
11000
|
+
// 行の補足が1段であることを見張る検査(#523 S1)が数えている。待ちの1文は
|
|
11001
|
+
// 別の話(押した人へのその場の返事)なので、専用の class を持たせる
|
|
11002
|
+
var note = el("p", { class: "ds-probe-wait" });
|
|
11003
|
+
var phase = probeWaitPhaseOf(capId, ref);
|
|
11004
|
+
var wait = probeWaitOf(capId, ref);
|
|
11005
|
+
if (phase === "waiting") note.textContent = (wait && wait.message) || "";
|
|
11006
|
+
else if (phase === "timeout") note.textContent = PROBE_WAIT_TIMEOUT_TEXT;
|
|
11007
|
+
else note.hidden = true;
|
|
11008
|
+
|
|
11009
|
+
btn.addEventListener("click", async function () {
|
|
11010
|
+
var endBusy = beginBusy(btn, "確認中…");
|
|
11011
|
+
note.hidden = false;
|
|
11012
|
+
note.textContent = "確認中…";
|
|
11013
|
+
// 🔴 **押す前に、いまの行の 「at」 を控える(🔴2)。** 行が無ければ空文字
|
|
11014
|
+
//(どんな 「at」 が来ても「新しい」と読める)
|
|
11015
|
+
var before = probeLatestRow(capId, ref);
|
|
11016
|
+
var key = probeWaitKey(capId, ref);
|
|
11017
|
+
try {
|
|
11018
|
+
var res = await callIntake("probe", { type: type, ref: ref });
|
|
11019
|
+
var j = await res.json().catch(function () { return {}; });
|
|
11020
|
+
if (!res.ok || j.queued === false) {
|
|
11021
|
+
// サーバの文言をそのまま出す(回数制限・鍵未登録・ロール未登録・起動失敗)
|
|
11022
|
+
note.textContent = j.message || "確認できませんでした。";
|
|
11023
|
+
delete PROBE_WAITS[key];
|
|
11024
|
+
endBusy();
|
|
11025
|
+
return;
|
|
11026
|
+
}
|
|
11027
|
+
PROBE_WAITS[key] = {
|
|
11028
|
+
cap: capId, ref: ref,
|
|
11029
|
+
at: (before && before.at) || "",
|
|
11030
|
+
startedAt: Date.now(),
|
|
11031
|
+
message: j.message || "",
|
|
11032
|
+
};
|
|
11033
|
+
note.textContent = j.message || "";
|
|
11034
|
+
// 待っているあいだは取り直しを回す(届いた行で一覧が描き直される)
|
|
11035
|
+
refreshStateTimer();
|
|
11036
|
+
} catch (e) {
|
|
11037
|
+
note.textContent = "通信に失敗しました。";
|
|
11038
|
+
delete PROBE_WAITS[key];
|
|
11039
|
+
}
|
|
11040
|
+
endBusy();
|
|
11041
|
+
});
|
|
11042
|
+
row.appendChild(btn);
|
|
11043
|
+
row.appendChild(note);
|
|
11044
|
+
return row;
|
|
11045
|
+
}
|
|
11046
|
+
|
|
11047
|
+
/**
|
|
11048
|
+
* 一覧に出ている接続先の「届くか」をひとつの文字列にする(描き直しの要否の判定用)。
|
|
11049
|
+
*
|
|
11050
|
+
* **待ちの相も混ぜる(#523 S3)。** 混ぜないと、15分の上限に達しても一覧が
|
|
11051
|
+
* 作り直されず、「確認を開始しました」が出たまま止まる(待てば出ると言い続ける形)。
|
|
11052
|
+
*/
|
|
10862
11053
|
function reachSigOf(capId, refs) {
|
|
11054
|
+
var now = Date.now();
|
|
10863
11055
|
return (refs || []).map(function (ref) {
|
|
10864
|
-
var
|
|
10865
|
-
|
|
11056
|
+
var id = ref && ref.ref != null ? ref.ref : ref;
|
|
11057
|
+
var r = reachableStateOf(capId, id, ref && ref.workspace);
|
|
11058
|
+
var w = probeWaitOf(capId, id);
|
|
11059
|
+
// 待っている行は**いちばん新しい行**で相を決める(「probeLatestRow」 の項)
|
|
11060
|
+
return (r ? r.status + "@" + r.at : "-") + (w ? "/" + probeWaitPhase(w, probeLatestRow(capId, id), now) : "");
|
|
10866
11061
|
}).join(",");
|
|
10867
11062
|
}
|
|
10868
11063
|
|
|
@@ -10985,7 +11180,12 @@ ${calendarAddUrl.toString()}
|
|
|
10985
11180
|
// 理由の1段は**行の最後**(ボタンより後ろ)に置く(appendReachableReason の項)
|
|
10986
11181
|
var issuesRef = issuesRefOf(t.domain, t.projectKey);
|
|
10987
11182
|
appendReachableChip(row, "issues", issuesRef);
|
|
10988
|
-
|
|
11183
|
+
// 「接続を確認」(#523 S3)。**外す権限が無くても押せる**——読むだけの操作で、
|
|
11184
|
+
// 押せる人を絞らない(決定7)。ボタンの並びは Slack の行と同じ(外すボタンの後ろ)
|
|
11185
|
+
if (!editable) {
|
|
11186
|
+
appendDispatchProbe(row, "issues", issuesRef);
|
|
11187
|
+
return appendReachableReason(row, "issues", issuesRef);
|
|
11188
|
+
}
|
|
10989
11189
|
var btn = el("button", { class: "ds-toggle-btn ds-danger", type: "button", text: "この接続先を外す" });
|
|
10990
11190
|
btn.addEventListener("click", async function () {
|
|
10991
11191
|
// **最後の1件かどうかは「押した時点」で数える。** 描画時の件数で決めると、
|
|
@@ -11005,6 +11205,7 @@ ${calendarAddUrl.toString()}
|
|
|
11005
11205
|
sendConfig(payload, msg, btn, null, targetsHooks());
|
|
11006
11206
|
});
|
|
11007
11207
|
row.appendChild(btn);
|
|
11208
|
+
appendDispatchProbe(row, "issues", issuesRef);
|
|
11008
11209
|
return appendReachableReason(row, "issues", issuesRef);
|
|
11009
11210
|
}
|
|
11010
11211
|
|
|
@@ -11477,6 +11678,11 @@ ${calendarAddUrl.toString()}
|
|
|
11477
11678
|
// **クラスのハード代入をやめる**(片方だけ直し忘れる形を構造的に消す)
|
|
11478
11679
|
onDone: function () { row.classList.add("ds-removed"); },
|
|
11479
11680
|
}));
|
|
11681
|
+
// 「接続を確認」(#523 S3)。押すと資料の同期が1回起き、共有が外れていれば
|
|
11682
|
+
// 「フォルダを開けません…」が数分〜十数分後にこの行へ出る。
|
|
11683
|
+
// **並びは Slack の行と同じ**(外すボタンの後ろ)——先に置くと、行の1つ目の
|
|
11684
|
+
// ボタンが入れ替わる(既存のテストが「1つ目=外す」で掴んでいるのと同じ読み順)
|
|
11685
|
+
appendDispatchProbe(row, "materials", id);
|
|
11480
11686
|
// 理由の1段は行の最後(ID と「このフォルダを外す」の後ろ・appendReachableReason の項)
|
|
11481
11687
|
appendReachableReason(row, "materials", id);
|
|
11482
11688
|
dlist.appendChild(row);
|
|
@@ -11643,6 +11849,10 @@ ${calendarAddUrl.toString()}
|
|
|
11643
11849
|
else delete figSending[f.key];
|
|
11644
11850
|
},
|
|
11645
11851
|
}));
|
|
11852
|
+
// 「接続を確認」(#523 S3)。**行を書くのは S4(engine)** なので、いまは
|
|
11853
|
+
// 押すとデザイン同期が1回起きるだけ——札が出るのは S4 の配布後。
|
|
11854
|
+
// 並びは Slack の行と同じ(外すボタンの後ろ)
|
|
11855
|
+
appendDispatchProbe(row, "design", f.key);
|
|
11646
11856
|
appendReachableReason(row, "design", f.key);
|
|
11647
11857
|
// 描き直しのあとも「外した」ことが分かる形に戻す(figsRemoved の項に経緯)
|
|
11648
11858
|
if (figsRemoved.indexOf(f.key) >= 0) {
|
|
@@ -12738,7 +12948,9 @@ ${calendarAddUrl.toString()}
|
|
|
12738
12948
|
// 判定と文面は infra/lambda/shared/github-gate.mjs 側(画面に分岐を持たせない)。
|
|
12739
12949
|
// **Google Chat は #347(同じ理由)。** スペースにアプリを追加した人が、その場で
|
|
12740
12950
|
// 直ったことを確かめられる。判定は infra/lambda/shared/google-chat-gate.mjs 側。
|
|
12741
|
-
// Backlog / Figma / Drive
|
|
12951
|
+
// **Backlog / Figma / Drive は「接続を確認」の型が違う**(#523 S3・レジストリの
|
|
12952
|
+
// 「probe: dispatch」)。中央が叩くのではなく案件の同期を起こすので、ここではなく
|
|
12953
|
+
// それぞれの一覧の行が 「appendDispatchProbe」 で出す。
|
|
12742
12954
|
//
|
|
12743
12955
|
// **origin === "explicit" でも出す。** 確認は読むだけで、どの登録ファイル由来かに
|
|
12744
12956
|
// 関係なく効く(書き込みになる「表示名を更新する」だけが由来で出し分かれる)
|
package/package.json
CHANGED