@takagaki/cortex-decisions-viewer 0.12.142 → 0.12.145
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 +14 -121
- package/dist/rederivation.js +1 -58
- package/dist/render.js +113 -248
- package/dist/repo.js +1 -62
- package/dist/story.js +57 -22
- package/dist/view-dir.js +2 -2
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -41,11 +41,8 @@ exports.sanitizeBody = sanitizeBody;
|
|
|
41
41
|
exports.findProjectIcon = findProjectIcon;
|
|
42
42
|
exports.readFleetSources = readFleetSources;
|
|
43
43
|
exports.orderRecordsByLedgers = orderRecordsByLedgers;
|
|
44
|
-
exports.humanTouchedOf = humanTouchedOf;
|
|
45
|
-
exports.attachHumanTouched = attachHumanTouched;
|
|
46
44
|
exports.rawFrontmatterDate = rawFrontmatterDate;
|
|
47
45
|
exports.attachSupersedes = attachSupersedes;
|
|
48
|
-
exports.attachRetractedBy = attachRetractedBy;
|
|
49
46
|
exports.readGoldProposals = readGoldProposals;
|
|
50
47
|
exports.buildHomeGrounding = buildHomeGrounding;
|
|
51
48
|
exports.collectMeetings = collectMeetings;
|
|
@@ -58,7 +55,7 @@ exports.bodyStampId = bodyStampId;
|
|
|
58
55
|
exports.bodyStampComment = bodyStampComment;
|
|
59
56
|
exports.build = build;
|
|
60
57
|
exports.decisionFirmnessOf = decisionFirmnessOf;
|
|
61
|
-
exports.
|
|
58
|
+
exports.decisionStrandOf = decisionStrandOf;
|
|
62
59
|
exports.decidedByOf = decidedByOf;
|
|
63
60
|
exports.isRelatedUrl = isRelatedUrl;
|
|
64
61
|
exports.relatedMaterialsRead = relatedMaterialsRead;
|
|
@@ -80,21 +77,8 @@ const story_1 = require("./story");
|
|
|
80
77
|
const ranking_1 = require("./ranking");
|
|
81
78
|
const hands_1 = require("./hands");
|
|
82
79
|
const rederivation_1 = require("./rederivation");
|
|
83
|
-
// 直近のGold昇格で追加されたレコードのパス集合。レコード生成の各所から参照するのでモジュールスコープに置く
|
|
84
|
-
// (引数で引き回すと呼び出し側の改修が広範囲になる)。build() の冒頭で1回だけ解決する。
|
|
85
|
-
let LATEST_PATHS = new Set();
|
|
86
|
-
/**
|
|
87
|
-
* このレコードが「直近のGold昇格で追加されたもの」か。
|
|
88
|
-
*
|
|
89
|
-
* **照合の手前で NFC に正規化する。** 集合側(git 由来)は NFC で入っているが、
|
|
90
|
-
* こちらのパスは readdir 由来なので、ファイルシステムが NFD で返す環境(macOS の
|
|
91
|
-
* 一部の経路)では**同じ日本語名でも一致しない**。正規化はこの1箇所に集める。
|
|
92
|
-
*/
|
|
93
|
-
function isLatestPath(filePath) {
|
|
94
|
-
return LATEST_PATHS.has(filePath.normalize("NFC"));
|
|
95
|
-
}
|
|
96
80
|
// AIからの更新提案(`.cortex/gold-proposals.json` 由来)を、レコードのパスで引ける形にしたもの。
|
|
97
|
-
//
|
|
81
|
+
// **レコードを組み立てるその場で、
|
|
98
82
|
// リポジトリルート相対のパスを鍵に引く」もので、引き回すと parseDecision / parseGeneric の
|
|
99
83
|
// 呼び出し側を全部触ることになる。build() の冒頭で毎回入れ替える(同一プロセスで
|
|
100
84
|
// 2回ビルドしても前回の値が残らないように)。
|
|
@@ -118,7 +102,6 @@ function takeProposals(filePath) {
|
|
|
118
102
|
const external_id_1 = require("./external-id");
|
|
119
103
|
const home_project_1 = require("./home-project");
|
|
120
104
|
const supersedes_1 = require("./supersedes");
|
|
121
|
-
const confirmed_1 = require("./confirmed");
|
|
122
105
|
const minify_1 = require("./minify");
|
|
123
106
|
const render_1 = require("./render");
|
|
124
107
|
const ledger_dir_1 = require("./ledger-dir");
|
|
@@ -730,45 +713,6 @@ function orderRecordsByLedgers(records, recordsDir, ctx, nowIso) {
|
|
|
730
713
|
const pathOf = (r) => (recordsRel ? `${recordsRel}/${r.fileName}` : r.fileName);
|
|
731
714
|
return (0, rederivation_1.orderByActivity)(records, pathOf, (r) => r.rstatus, ctx.ledgers, nowIso);
|
|
732
715
|
}
|
|
733
|
-
/**
|
|
734
|
-
* 記録に人の手があるか(cortex-engine #1094 段 4・削除の確認の文面を替える材料)。
|
|
735
|
-
*
|
|
736
|
-
* 次のどちらかで真:
|
|
737
|
-
* 1. status が人の値(口の `humanOwned`・区画の語彙。旧い記録の「確認済み」)
|
|
738
|
-
* 2. 確認の帳簿(`.cortex/gold-confirmation.json`)にその path の `confirmed` の行がある(消した行を除く)
|
|
739
|
-
*
|
|
740
|
-
* 🔴 **ビルドの git は使わない**(確定版 0 章 7)。cortex-bot の夜のコミットを人と数え、浅い clone では
|
|
741
|
-
* 全部が人になるため。engine の人の手の表がビューアに届く段 5 で差し替える。
|
|
742
|
-
* 取りこぼしの代償は「確認の一言が出ない」だけ(消せる範囲は変わらない)。
|
|
743
|
-
*
|
|
744
|
-
* 記憶 v2 の案件で人の手の表の写し(`memory-hands`)が読めたときは、2 の確認の帳簿の代わりに表の `touched` を見る
|
|
745
|
-
* (cortex-engine #1094 鎖 3 V10b・B9a。確認の帳簿は記憶 v2 では書かれなくなる)。表が読めない晩は今の確認の帳簿に倒す。
|
|
746
|
-
*
|
|
747
|
-
* @param p リポジトリルート相対の path(`Cortex/<区画>/records/…`)。帳簿の鍵は NFC なので NFC でも引く
|
|
748
|
-
* @param status その記録の `rstatus`(`String()` 済み)
|
|
749
|
-
* @param hands 人の手の表(path → touched)。渡したときは確認の帳簿を見ない
|
|
750
|
-
*/
|
|
751
|
-
function humanTouchedOf(p, status, confirmation, hands = null) {
|
|
752
|
-
if ((0, confirmed_1.humanOwned)(p, status))
|
|
753
|
-
return true;
|
|
754
|
-
if (hands)
|
|
755
|
-
return hands.get(p) === true || hands.get(p.normalize("NFC")) === true;
|
|
756
|
-
const row = confirmation.get(p) ?? confirmation.get(p.normalize("NFC"));
|
|
757
|
-
return !!row && row.deleted !== true;
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* 区画の記録に人の手の印(`humanTouched: true`)を載せる。**人の手が無い記録にはキーごと付けない**
|
|
761
|
-
* (今の SiteData の形を保つ)。path は `repoRoot` 起点で作る(帳簿の鍵はリポジトリルート相対)。
|
|
762
|
-
* 置き換えの逆引き(`attachSupersedes`)より前に呼ぶ。
|
|
763
|
-
*/
|
|
764
|
-
function attachHumanTouched(records, recordsDir, repoRoot, confirmation, hands = null) {
|
|
765
|
-
const recordsRel = path.relative(repoRoot, recordsDir).split(path.sep).join("/");
|
|
766
|
-
for (const r of records) {
|
|
767
|
-
const p = recordsRel ? `${recordsRel}/${r.fileName}` : r.fileName;
|
|
768
|
-
if (humanTouchedOf(p, r.rstatus, confirmation, hands))
|
|
769
|
-
r.humanTouched = true;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
716
|
/**
|
|
773
717
|
* 決定に置き換えの逆引き(置き換え先・置き換えた決定)を載せる(cortex-engine #699 F3・A-1')。
|
|
774
718
|
*
|
|
@@ -800,7 +744,7 @@ function rawFrontmatterDate(raw) {
|
|
|
800
744
|
function attachSupersedes(decisions, rawDateOf = (d) => d.fm.date, pathOf = () => undefined) {
|
|
801
745
|
const input = decisions.map((d) => ({
|
|
802
746
|
id: d.id,
|
|
803
|
-
//
|
|
747
|
+
// 記録の path(engine と入力の形を揃えるだけで、逆引きには使わない)
|
|
804
748
|
path: pathOf(d),
|
|
805
749
|
// 🔴 **frontmatter に書かれたままの date の文字列**(`rawFrontmatterDate`)。gray-matter は時刻・時差つきの
|
|
806
750
|
// date を Date に読み、sanitizeFm は UTC の日付にするので、`2026-07-01T01:00:00+09:00` が 6/30 にずれる。
|
|
@@ -844,35 +788,6 @@ function attachSupersedes(decisions, rawDateOf = (d) => d.fm.date, pathOf = () =
|
|
|
844
788
|
d.supersedesIds = replaced;
|
|
845
789
|
}
|
|
846
790
|
}
|
|
847
|
-
/**
|
|
848
|
-
* ルールに取り下げ(`relations[retracted_by]`・cortex-engine #1094 便 4-2d)を載せる。
|
|
849
|
-
*
|
|
850
|
-
* 取り下げ=この線が 1 本以上(決定の「置き換えられた」と同じ導出・engine の目次と同じ)。
|
|
851
|
-
* target は取り下げを決めた決定の ID。実在する決定なら記録の綴りと決定日を添える(無ければ ID のまま・日付は空)。
|
|
852
|
-
* **取り下げの無いルール・ルール以外の区画にはキーごと付けない**(今までと同じ SiteData)
|
|
853
|
-
*/
|
|
854
|
-
function attachRetractedBy(records, decisions, rawDateOf = (d) => d.date) {
|
|
855
|
-
const byKey = new Map();
|
|
856
|
-
for (const d of decisions) {
|
|
857
|
-
const k = (0, supersedes_1.decisionKeyOf)(d.id);
|
|
858
|
-
if (!byKey.has(k))
|
|
859
|
-
byKey.set(k, d);
|
|
860
|
-
}
|
|
861
|
-
for (const r of records) {
|
|
862
|
-
const out = [];
|
|
863
|
-
for (const rel of r.relations) {
|
|
864
|
-
if (rel.rel !== "retracted_by")
|
|
865
|
-
continue;
|
|
866
|
-
const k = (0, supersedes_1.decisionKeyOf)(rel.target);
|
|
867
|
-
if (!k || out.some((x) => (0, supersedes_1.decisionKeyOf)(x.id) === k))
|
|
868
|
-
continue;
|
|
869
|
-
const d = byKey.get(k);
|
|
870
|
-
out.push({ id: d ? d.id : k, date: d ? (0, supersedes_1.decisionDateOf)(rawDateOf(d), d.id) : "" });
|
|
871
|
-
}
|
|
872
|
-
if (out.length)
|
|
873
|
-
r.retractedBy = out;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
791
|
/**
|
|
877
792
|
* AIからの更新提案(`.cortex/gold-proposals.json`)を読む。
|
|
878
793
|
*
|
|
@@ -1198,7 +1113,6 @@ async function parseGeneric(raw, fileName, repoRelDir, repoBaseUrl, branch, sect
|
|
|
1198
1113
|
editUrl,
|
|
1199
1114
|
rtype: data.type != null ? String(data.type) : "",
|
|
1200
1115
|
rstatus: data.status != null ? String(data.status) : "",
|
|
1201
|
-
isLatest: isLatestPath(filePath),
|
|
1202
1116
|
proposals: takeProposals(filePath),
|
|
1203
1117
|
relations: toRelations(data.relations),
|
|
1204
1118
|
source: data.source != null ? String(data.source) : "",
|
|
@@ -2413,11 +2327,6 @@ async function buildSite(opts, views) {
|
|
|
2413
2327
|
branch: opts.branch,
|
|
2414
2328
|
cwd: dirAbs,
|
|
2415
2329
|
});
|
|
2416
|
-
// 直近のGold昇格で追加されたレコードを git から解決する(レコードの date は決定日なので生成時期が分からない)。
|
|
2417
|
-
// git が返すのはリポジトリルート相対のパス(`Cortex/...`)なので、判定も**リポジトリルート**で行う
|
|
2418
|
-
// (Decisionsディレクトリで実行すると `-- Cortex/` に一致せず常に空になる)。
|
|
2419
|
-
// 浅いclone・git無しの環境では空集合が返り、「最新」ラベルが出ないだけで他の表示は壊れない。
|
|
2420
|
-
LATEST_PATHS = (0, repo_1.latestGeneratedPaths)(process.cwd());
|
|
2421
2330
|
// Cortex構成なら、ホームと「records/ を持つディレクトリ」をすべて読み込む(旧構成では空)
|
|
2422
2331
|
// ディレクトリ名はハードコードしない: 案件が新しいレコード種別のディレクトリを足せば、そのままタブとして表示される
|
|
2423
2332
|
const knowledgeRoot = resolveKnowledgeRoot(dirAbs);
|
|
@@ -2458,7 +2367,7 @@ async function buildSite(opts, views) {
|
|
|
2458
2367
|
// 用語集の並びの帳簿(活性度・強さ #790)。**帳簿が無い案件では並び替えを作らない**。
|
|
2459
2368
|
// 🔴 **強さ(`state` が on のときだけ中身が入る)だけの案件でも器を作る**——作らないと、活性度の帳簿を
|
|
2460
2369
|
// 持たない案件で用語集が目次(engine の `termRows`)と違う順になる。
|
|
2461
|
-
// 確認の帳簿(`confirmation
|
|
2370
|
+
// 確認の帳簿(`confirmation`)は並びには関係しない
|
|
2462
2371
|
const ledgers = await (0, rederivation_1.readRederivationLedgers)(repoRoot, ledgerDir);
|
|
2463
2372
|
const rederive = ledgers.activity.size || ledgers.strength.size
|
|
2464
2373
|
? { ledgers: ledgers, repoRoot: repoRoot }
|
|
@@ -2472,9 +2381,6 @@ async function buildSite(opts, views) {
|
|
|
2472
2381
|
// 「記憶 v2 の案件か」は 1 本の栓 `memory_v2_writer` の値で決める(cortex-engine #1094 鎖 3 V10b)。橋の間は写しとの OR
|
|
2473
2382
|
const memoryHands = await (0, hands_1.readMemoryHands)(repoRoot, ledgerDir);
|
|
2474
2383
|
const memoryV2 = (0, hands_1.isMemoryV2)(opts.memoryV2Writer, memoryHands !== null);
|
|
2475
|
-
// 削除の確認の一言の材料(B9a): 記憶 v2 の案件で表が読めたときは表、ほかは今の確認の帳簿
|
|
2476
|
-
// (表が読めた案件は必ず記憶 v2 なので、表そのものを渡せばよい)
|
|
2477
|
-
const touchedBy = memoryHands;
|
|
2478
2384
|
// 記録の id → リポジトリルート相対のパス(順位のファイルの鍵と突き合わせる。`repoRoot` 起点・cwd 起点にしない)
|
|
2479
2385
|
const recordRelPaths = new Map();
|
|
2480
2386
|
const relOf = (dir, fileName) => {
|
|
@@ -2493,8 +2399,6 @@ async function buildSite(opts, views) {
|
|
|
2493
2399
|
if (rd !== undefined)
|
|
2494
2400
|
rawDates.set(rec, rd);
|
|
2495
2401
|
}
|
|
2496
|
-
// 人の手(削除の確認の文面を替える材料・cortex-engine #1094 段 4)。**置き換えより前に・repoRoot で**
|
|
2497
|
-
attachHumanTouched(decisions, dirAbs, repoRoot, ledgers.confirmation, touchedBy);
|
|
2498
2402
|
// 置き換えの逆引き(#699 F3)。**置き換えの無い案件では 1 件も付かない**
|
|
2499
2403
|
attachSupersedes(decisions, (d) => rawDates.get(d) ?? d.fm.date, (d) => relOf(dirAbs, d.fileName));
|
|
2500
2404
|
let home = null;
|
|
@@ -2535,14 +2439,13 @@ async function buildSite(opts, views) {
|
|
|
2535
2439
|
if (!e.isDirectory() || e.name === "Decisions")
|
|
2536
2440
|
continue;
|
|
2537
2441
|
const recordsDir = path.join(knowledgeRoot, e.name, "records");
|
|
2538
|
-
|
|
2539
|
-
//
|
|
2540
|
-
|
|
2442
|
+
let records = await loadGenericRecords(recordsDir, exclude, repo.baseUrl, repo.branch);
|
|
2443
|
+
// ルールは取り下げたらファイルを消す(cortex-engine #1094)。案件の旧い記録の片付けより画面が先に出ても
|
|
2444
|
+
// 旧い取り下げが普通に見えないよう、`retracted_by` を 1 本以上持つルールは一覧(と件数・つながり)から外す
|
|
2445
|
+
if (e.name === "Rules")
|
|
2446
|
+
records = records.filter((r) => !r.relations.some((x) => x.rel === "retracted_by"));
|
|
2541
2447
|
// 関連の資料(cortex-engine #1094 F8)。ルール・用語だけ・欄の無い記録には何も付かない
|
|
2542
2448
|
attachRelatedMaterials(e.name, records, refs);
|
|
2543
|
-
// ルールの取り下げ(`retracted_by`・cortex-engine #1094 便 4-2d)。ルールの区画だけ・取り下げの無い案件では何も付かない
|
|
2544
|
-
if (e.name === "Rules")
|
|
2545
|
-
attachRetractedBy(records, decisions, (d) => rawDates.get(d) ?? d.fm.date);
|
|
2546
2449
|
// 用語集の並び(活性度・強さ)。**帳簿を持たない案件では並びもそのまま**
|
|
2547
2450
|
const rederived = orderRecordsByLedgers(records, recordsDir, rederive, opts.generatedAt);
|
|
2548
2451
|
// 関係者だけ、関与の多い順(engine の目次と同じ `order`・便 14b)。用語集の並び
|
|
@@ -2742,17 +2645,13 @@ async function parseDecision(raw, fileName, repoRelDir, repoBaseUrl, branch, ref
|
|
|
2742
2645
|
const id = String(data.id ?? fileName.replace(/\.md$/i, ""));
|
|
2743
2646
|
const title = String(data.title ?? stripIdPrefix(fileName));
|
|
2744
2647
|
const date = normalizeDate(data.date);
|
|
2745
|
-
const sprint = data.sprint != null ? String(data.sprint) : "";
|
|
2746
|
-
const category = data.category != null ? String(data.category) : "";
|
|
2747
2648
|
const summary = data.description != null ? String(data.description) : data.summary != null ? String(data.summary) : ""; // description優先(旧summaryは移行期互換)
|
|
2748
|
-
const deciders = toStringArray(data.deciders);
|
|
2749
2649
|
const referencesRaw = toStringArray(data.references);
|
|
2750
2650
|
const references = referencesRaw.map((r) => refs.resolve(r));
|
|
2751
2651
|
const relations = toRelations(data.relations);
|
|
2752
|
-
const followupHuman = (0, rederivation_1.humanFollowupOf)(data.followup);
|
|
2753
2652
|
// 記憶 v2 の任意の欄(#1094)。**欄が無い・語彙外の記録ではキーごと載せない**(埋め込みの形を今と同じに保つ)
|
|
2754
2653
|
const firmness = decisionFirmnessOf(data.firmness);
|
|
2755
|
-
const
|
|
2654
|
+
const strand = decisionStrandOf(data.strand);
|
|
2756
2655
|
const decidedBy = decidedByOf(data.decided_by);
|
|
2757
2656
|
// 関連の資料(#1094 F8)。通る URL が 0 本ならキーごと載せない
|
|
2758
2657
|
const relatedMaterials = relatedMaterialsView(data, refs);
|
|
@@ -2766,9 +2665,6 @@ async function parseDecision(raw, fileName, repoRelDir, repoBaseUrl, branch, ref
|
|
|
2766
2665
|
id,
|
|
2767
2666
|
title,
|
|
2768
2667
|
date,
|
|
2769
|
-
sprint,
|
|
2770
|
-
category,
|
|
2771
|
-
deciders,
|
|
2772
2668
|
summary,
|
|
2773
2669
|
references,
|
|
2774
2670
|
relations,
|
|
@@ -2778,16 +2674,13 @@ async function parseDecision(raw, fileName, repoRelDir, repoBaseUrl, branch, ref
|
|
|
2778
2674
|
bodyId: "",
|
|
2779
2675
|
searchText: toSearchText(content),
|
|
2780
2676
|
rstatus: data.status != null ? String(data.status) : "",
|
|
2781
|
-
isLatest: isLatestPath(filePath),
|
|
2782
2677
|
proposals: takeProposals(filePath),
|
|
2783
2678
|
fileName,
|
|
2784
2679
|
editUrl,
|
|
2785
2680
|
fm: sanitizeFm(data),
|
|
2786
2681
|
fmErrors: validateFm(data),
|
|
2787
|
-
// 担当者の答え(#705)。**語彙外・形が違うものはキーごと載せない**
|
|
2788
|
-
...(followupHuman ? { followupHuman: followupHuman } : {}),
|
|
2789
2682
|
...(firmness ? { firmness } : {}),
|
|
2790
|
-
...(
|
|
2683
|
+
...(strand ? { strand } : {}),
|
|
2791
2684
|
...(decidedBy ? { decidedBy } : {}),
|
|
2792
2685
|
...(relatedMaterials ? { relatedMaterials } : {}),
|
|
2793
2686
|
};
|
|
@@ -2810,8 +2703,8 @@ const isText = (v) => typeof v === "string" && v.trim() !== "";
|
|
|
2810
2703
|
function decisionFirmnessOf(value) {
|
|
2811
2704
|
return exports.DECISION_FIRMNESS.includes(value) ? value : undefined;
|
|
2812
2705
|
}
|
|
2813
|
-
/** frontmatter の `
|
|
2814
|
-
function
|
|
2706
|
+
/** frontmatter の `strand` → 筋の札の名前(前後の空白を落とす)。空・文字列でないものは undefined(`topic` は読まない) */
|
|
2707
|
+
function decisionStrandOf(value) {
|
|
2815
2708
|
return isText(value) ? value.trim() : undefined;
|
|
2816
2709
|
}
|
|
2817
2710
|
/** `decided_by` の要素 1 つ。読めなければ null(文字列・知らない鍵・member と name/url の同居・member: で始まらない・空の name・http(s) でない url) */
|
|
@@ -2835,7 +2728,7 @@ function decidedByEntryOf(entry) {
|
|
|
2835
2728
|
}
|
|
2836
2729
|
/**
|
|
2837
2730
|
* frontmatter の `decided_by` → 決めた人の並び。🔴 形の崩れた要素は**飛ばす**。
|
|
2838
|
-
* 欄がリストでなければ undefined
|
|
2731
|
+
* 欄がリストでなければ undefined(無いものとして扱う)。空のリストは []
|
|
2839
2732
|
*/
|
|
2840
2733
|
function decidedByOf(value) {
|
|
2841
2734
|
if (!Array.isArray(value))
|
package/dist/rederivation.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.emptyLedgers = exports.TERM_STRENGTH_FILE = exports.LEDGER_VERSION = void 0;
|
|
7
7
|
exports.isConfirmedStatus = isConfirmedStatus;
|
|
8
8
|
exports.parseLedger = parseLedger;
|
|
9
9
|
exports.readRederivationLedgers = readRederivationLedgers;
|
|
@@ -14,8 +14,6 @@ exports.comparableContent = comparableContent;
|
|
|
14
14
|
exports.sameRederivedContent = sameRederivedContent;
|
|
15
15
|
exports.contentShaOf = contentShaOf;
|
|
16
16
|
exports.orderByActivity = orderByActivity;
|
|
17
|
-
exports.followupDateOf = followupDateOf;
|
|
18
|
-
exports.humanFollowupOf = humanFollowupOf;
|
|
19
17
|
/**
|
|
20
18
|
* 再導出の 3 帳簿(+用語の強さの帳簿)を読み、帯「人が確認した版から変わりました」と用語集の並びを作る(#665 便 12b)。
|
|
21
19
|
*
|
|
@@ -70,10 +68,6 @@ const MIN_ELAPSED_DAYS = 0.5;
|
|
|
70
68
|
* 🔴 **渡すのは `String()` 済みの `rstatus` だけ**(`build.ts:1048`)。生の frontmatter
|
|
71
69
|
* (`rec.fm.status`)を渡さない——YAML は真偽値も配列も返すので、札と同じ文字列にならない
|
|
72
70
|
* (口は文字列・null・undefined のほかを投げる)。
|
|
73
|
-
*
|
|
74
|
-
* ⚠️ **「人の手」は別にある。** 削除の確認の文面を替える `rec.humanTouched`(`build.ts` の
|
|
75
|
-
* `humanTouchedOf`)は口の `humanOwned`(区画の語彙)か確認の帳簿の行で、`""` の扱いがここと逆
|
|
76
|
-
* (人の手として**扱う**側は `humanOwned`、機械が触る前の**守り**は `!machineOwned` という割り当て)。
|
|
77
71
|
*/
|
|
78
72
|
function isConfirmedStatus(status, recordPath = null) {
|
|
79
73
|
return !(0, confirmed_1.machineOwned)(recordPath, status);
|
|
@@ -596,54 +590,3 @@ function breakTiesByStrength(records, pathOf, ledgers, nowIso) {
|
|
|
596
590
|
}
|
|
597
591
|
return out;
|
|
598
592
|
}
|
|
599
|
-
/* ---------------------------------------------------------------------------
|
|
600
|
-
* 決定の「その後」(人の答え)
|
|
601
|
-
* ---------------------------------------------------------------------------
|
|
602
|
-
*
|
|
603
|
-
* 画面が読むのは、人が frontmatter に書いた `followup:` の 1 行だけ(#1094 35d)。
|
|
604
|
-
* 夜間の帳簿(`.cortex/gold-decision-followup.json`)は画面に出さない・読まない
|
|
605
|
-
* (PR のマージを完了と数える差 97 を画面から外すため)。
|
|
606
|
-
*/
|
|
607
|
-
/** 人が frontmatter に書く `followup.state` の語彙(intake `FOLLOWUP_STATES` と同じ 4 語) */
|
|
608
|
-
exports.HUMAN_FOLLOWUP_STATES = ["confirmed", "done", "dropped", "ignore"];
|
|
609
|
-
/**
|
|
610
|
-
* 日付を `YYYY-MM-DD` に畳む。
|
|
611
|
-
*
|
|
612
|
-
* 🔴 **engine の `at` は日付とは限らない**(`decision-links.mjs` の `terminalStateOf` は
|
|
613
|
-
* `merged_at` / `updated_at` の **ISO 日時**をそのまま入れる)。時刻つきのものは
|
|
614
|
-
* **JST の日付**に直す——UTC の先頭 10 文字を切ると、日本の夜に閉じた課題が前日に見える。
|
|
615
|
-
* 読めないもの(null・数・壊れた文字列)は空。
|
|
616
|
-
*/
|
|
617
|
-
function followupDateOf(v) {
|
|
618
|
-
if (v instanceof Date)
|
|
619
|
-
return Number.isFinite(v.getTime()) ? v.toISOString().slice(0, 10) : "";
|
|
620
|
-
const s = typeof v === "string" ? v.trim() : "";
|
|
621
|
-
if (!s)
|
|
622
|
-
return "";
|
|
623
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(s))
|
|
624
|
-
return s;
|
|
625
|
-
if (!/^\d{4}-\d{2}-\d{2}T/.test(s))
|
|
626
|
-
return "";
|
|
627
|
-
const ms = Date.parse(s);
|
|
628
|
-
if (!Number.isFinite(ms))
|
|
629
|
-
return "";
|
|
630
|
-
return new Date(ms + 9 * 3600 * 1000).toISOString().slice(0, 10);
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* frontmatter の `followup:`(人が画面のボタンで書く 1 行)を読む。
|
|
634
|
-
*
|
|
635
|
-
* 形は `followup: { state: done, at: 2026-09-20 }`(intake `setFollowupLine` が書く)。
|
|
636
|
-
* YAML は `at` を Date に読むので日付に戻す。**語彙外・形が違うものは `null`**(載せない)。
|
|
637
|
-
*/
|
|
638
|
-
function humanFollowupOf(v) {
|
|
639
|
-
const o = asRecord(v);
|
|
640
|
-
if (!o)
|
|
641
|
-
return null;
|
|
642
|
-
const state = typeof o.state === "string" ? o.state : "";
|
|
643
|
-
if (!exports.HUMAN_FOLLOWUP_STATES.includes(state))
|
|
644
|
-
return null;
|
|
645
|
-
const at = followupDateOf(o.at);
|
|
646
|
-
if (!at)
|
|
647
|
-
return null;
|
|
648
|
-
return { state: state, at: at };
|
|
649
|
-
}
|