@takagaki/cortex-decisions-viewer 0.12.200 → 0.12.214
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/README.md +4 -2
- package/dist/build.js +123 -85
- package/dist/canonical-evidence.js +11 -191
- package/dist/change-log.js +1 -1
- package/dist/config-flow.js +462 -0
- package/dist/config-mode.js +57 -0
- package/dist/confirmed.js +2 -2
- package/dist/engine/decision-v2-fields.js +188 -0
- package/dist/engine/ref-tokens.js +276 -0
- package/dist/engine/related-materials-field.js +148 -0
- package/dist/engine/supersedes-index.js +257 -0
- package/dist/google-confirm-page.js +14 -3
- package/dist/ledger-dir.js +1 -0
- package/dist/memory-dir.js +40 -0
- package/dist/memory-evidence.js +12 -6
- package/dist/rederivation.js +17 -8
- package/dist/render.js +909 -78
- package/dist/story.js +13 -9
- package/dist/supersedes.js +12 -110
- package/dist/view-dir.js +120 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -74,8 +74,10 @@ cortex-decisions-viewer build [dir] [options]
|
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
76
|
npm install
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
node ../scripts/ci/assemble-engine.mjs # engine の原本を viewer/engine-src/ に組み立てる(engine の場所は ENGINE_ROOT、無ければ tools の隣の ../cortex-engine)
|
|
78
|
+
# npm test は pretest が回す。build・demo を単独で回す前は手で
|
|
79
|
+
npm run build # tsc → dist/ と、engine の原本を束ねて dist/engine/(先に組み立て)
|
|
80
|
+
npm run demo # 中で build を呼ぶ(先に組み立て)。../../aidd-project-cortex の Cortex/ をビルドして .demo-site/ に出力
|
|
79
81
|
```
|
|
80
82
|
|
|
81
83
|
## 位置づけ(cortex-tools モノレポ)
|
package/dist/build.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.REFERENCES_SECTIONS = exports.RELATED_MATERIALS_SECTIONS = exports.RELATED_URL_MAX = exports.RELATED_MATERIALS_FIELD = exports.
|
|
39
|
+
exports.REFERENCES_SECTIONS = exports.RELATED_MATERIALS_SECTIONS = exports.DECISION_FIRMNESS = exports.RELATED_URL_MAX = exports.RELATED_MATERIALS_FIELD = exports.relatedMaterialsRead = exports.isRelatedUrl = exports.GRAPH_RELS = exports.GRAPH_RECORD_TYPES = exports.GUIDE_VIDEO_SOURCES = exports.PROJECT_ICON_EXTS = exports.MIRROR_RELS = void 0;
|
|
40
40
|
exports.sanitizeBody = sanitizeBody;
|
|
41
41
|
exports.copyHashedAsset = copyHashedAsset;
|
|
42
42
|
exports.buildGuideAssets = buildGuideAssets;
|
|
@@ -61,8 +61,6 @@ exports.build = build;
|
|
|
61
61
|
exports.decisionFirmnessOf = decisionFirmnessOf;
|
|
62
62
|
exports.decisionStrandOf = decisionStrandOf;
|
|
63
63
|
exports.decidedByOf = decidedByOf;
|
|
64
|
-
exports.isRelatedUrl = isRelatedUrl;
|
|
65
|
-
exports.relatedMaterialsRead = relatedMaterialsRead;
|
|
66
64
|
exports.relatedMaterialsView = relatedMaterialsView;
|
|
67
65
|
exports.attachRecordReferences = attachRecordReferences;
|
|
68
66
|
exports.attachRelatedMaterials = attachRelatedMaterials;
|
|
@@ -78,15 +76,19 @@ const evidence_names_1 = require("./evidence-names");
|
|
|
78
76
|
const change_log_1 = require("./change-log");
|
|
79
77
|
const repo_1 = require("./repo");
|
|
80
78
|
const engagement_1 = require("./engagement");
|
|
79
|
+
const memory_dir_1 = require("./memory-dir");
|
|
81
80
|
const story_1 = require("./story");
|
|
82
81
|
const ranking_1 = require("./ranking");
|
|
83
82
|
const memory_evidence_1 = require("./memory-evidence");
|
|
84
83
|
const hands_1 = require("./hands");
|
|
84
|
+
const config_mode_1 = require("./config-mode");
|
|
85
85
|
const rederivation_1 = require("./rederivation");
|
|
86
86
|
const external_id_1 = require("./external-id");
|
|
87
87
|
const member_origin_1 = require("./member-origin");
|
|
88
88
|
const home_project_1 = require("./home-project");
|
|
89
89
|
const supersedes_1 = require("./supersedes");
|
|
90
|
+
const decision_v2_fields_1 = require("./engine/decision-v2-fields");
|
|
91
|
+
const related_materials_field_1 = require("./engine/related-materials-field");
|
|
90
92
|
const minify_1 = require("./minify");
|
|
91
93
|
const google_confirm_page_1 = require("./google-confirm-page");
|
|
92
94
|
const render_1 = require("./render");
|
|
@@ -259,14 +261,20 @@ function memberSearchText(data, sectionDir, base) {
|
|
|
259
261
|
}
|
|
260
262
|
/** dir未指定時の探索候補(新構成 → 旧構成の順) */
|
|
261
263
|
const DEFAULT_DIR_CANDIDATES = ["Cortex/Decisions/records", "Cortex/Decisions", "Decisions"];
|
|
264
|
+
/** 組み直した案件(木に `Memory/Home.md`)の探索候補。**この木のときだけ先に探す**(今までの案件は上の 3 つのまま) */
|
|
265
|
+
const MEMORY_DIR_CANDIDATES = ["Memory/Decisions/records", "Memory/Decisions"];
|
|
262
266
|
/**
|
|
263
267
|
* Decisionsディレクトリを解決する。明示指定があればそれを使い、
|
|
264
268
|
* 未指定なら Cortex/Decisions/records → Cortex/Decisions → Decisions の順で存在するものを採用する。
|
|
269
|
+
* 組み直した案件(木に `Memory/Home.md`)は Memory/Decisions/records → Memory/Decisions だけ。
|
|
265
270
|
*/
|
|
266
271
|
async function resolveDecisionsDir(dir) {
|
|
267
272
|
if (dir)
|
|
268
273
|
return path.resolve(dir);
|
|
269
|
-
|
|
274
|
+
const rebuilt = (await (0, memory_dir_1.memoryDirOfTree)(process.cwd())) === "Memory";
|
|
275
|
+
// 🔴 組み直した案件は `Memory/` だけを探す(今までの置き場〈Cortex/…・Decisions〉へ倒れない・cortex-engine #1911 便 GV)
|
|
276
|
+
const candidates = rebuilt ? MEMORY_DIR_CANDIDATES : DEFAULT_DIR_CANDIDATES;
|
|
277
|
+
for (const candidate of candidates) {
|
|
270
278
|
const abs = path.resolve(candidate);
|
|
271
279
|
try {
|
|
272
280
|
const st = await node_fs_1.promises.stat(abs);
|
|
@@ -277,7 +285,53 @@ async function resolveDecisionsDir(dir) {
|
|
|
277
285
|
// 存在しない候補はスキップ
|
|
278
286
|
}
|
|
279
287
|
}
|
|
280
|
-
throw new Error(`Decisionsディレクトリが見つかりません(${
|
|
288
|
+
throw new Error(`Decisionsディレクトリが見つかりません(${candidates.join(" / ")} を確認してください)`);
|
|
289
|
+
}
|
|
290
|
+
/** 取り出した区画にファイルが 1 本も無いか(無いフォルダも空と読む・読めないフォルダは空と読まない) */
|
|
291
|
+
async function viewDirIsEmpty(viewDir) {
|
|
292
|
+
try {
|
|
293
|
+
return (await node_fs_1.promises.readdir(viewDir)).length === 0;
|
|
294
|
+
}
|
|
295
|
+
catch (e) {
|
|
296
|
+
return e?.code === "ENOENT";
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** 記憶の中身に数えない Markdown(入口・説明・雛形) */
|
|
300
|
+
const MEMORY_NON_CONTENT_MD = new Set(["home.md", "readme.md", "template.md"]);
|
|
301
|
+
/**
|
|
302
|
+
* 組み直した案件の木の記憶の中身の数(`Memory/` の下の .md。Home・README・template は数えない)。区画の名前も `records/` の有無も決め打ちしない
|
|
303
|
+
* (記録・ストーリー・区画の直下の記録を全部数える)。リンクはたどる(`stat`)。空の画面に倒してよいかの判定にだけ使う(cortex-engine #1911 便 GV)。
|
|
304
|
+
* 🔴 読めない階層・深すぎる階層は 1 と数える(空に倒れる側にしない)。`Memory/` が無い木も 1(組み直した案件の印と食い違う)
|
|
305
|
+
*/
|
|
306
|
+
async function memoryContentCount(dir, depth = 0) {
|
|
307
|
+
if (depth > 8)
|
|
308
|
+
return 1;
|
|
309
|
+
let names;
|
|
310
|
+
try {
|
|
311
|
+
names = await node_fs_1.promises.readdir(dir);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return 1;
|
|
315
|
+
}
|
|
316
|
+
let n = 0;
|
|
317
|
+
for (const name of names) {
|
|
318
|
+
const abs = path.join(dir, name);
|
|
319
|
+
let st;
|
|
320
|
+
try {
|
|
321
|
+
st = await node_fs_1.promises.stat(abs);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
n += 1;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (st.isDirectory())
|
|
328
|
+
n += await memoryContentCount(abs, depth + 1);
|
|
329
|
+
else if (name.toLowerCase().endsWith(".md") && !MEMORY_NON_CONTENT_MD.has(name.toLowerCase()))
|
|
330
|
+
n += 1;
|
|
331
|
+
if (n > 0)
|
|
332
|
+
return n;
|
|
333
|
+
}
|
|
334
|
+
return n;
|
|
281
335
|
}
|
|
282
336
|
/**
|
|
283
337
|
* DecisionsディレクトリからCortex(Gold層)ルートを推定する。
|
|
@@ -289,7 +343,7 @@ function resolveKnowledgeRoot(decisionsDirAbs) {
|
|
|
289
343
|
if (path.basename(decisionsDirAbs) === "records" && path.basename(parent) === "Decisions") {
|
|
290
344
|
return path.dirname(parent);
|
|
291
345
|
}
|
|
292
|
-
if (path.basename(decisionsDirAbs) === "Decisions" && path.basename(parent) === "Cortex") {
|
|
346
|
+
if (path.basename(decisionsDirAbs) === "Decisions" && (path.basename(parent) === "Cortex" || path.basename(parent) === "Memory")) {
|
|
293
347
|
return parent;
|
|
294
348
|
}
|
|
295
349
|
return null;
|
|
@@ -1855,7 +1909,7 @@ function buildGraph(decisions, sections, targetUrls, repoBaseUrl, book = (0, evi
|
|
|
1855
1909
|
if (ev)
|
|
1856
1910
|
return addEvidence(ev);
|
|
1857
1911
|
// 点にしない記録(Home・レポート・その他)へのパス参照は、根拠ではない。点を作らず数える
|
|
1858
|
-
if (/(^|\/)Cortex\/(Home\.md|[^/]+\/records\/)/.test(target)) {
|
|
1912
|
+
if (/(^|\/)(?:Cortex|Memory)\/(Home\.md|[^/]+\/records\/)/.test(target)) {
|
|
1859
1913
|
unresolvedTargets++;
|
|
1860
1914
|
return null;
|
|
1861
1915
|
}
|
|
@@ -2438,11 +2492,36 @@ async function buildSite(opts, views) {
|
|
|
2438
2492
|
// 解決するので、あとから作ると空の表・空の実在判定が渡り、**実在するパスまで
|
|
2439
2493
|
// 「リンクにしない」に倒れて全滅する**(以前は順序が逆だった)。
|
|
2440
2494
|
const repoRoot = knowledgeRoot ? path.dirname(knowledgeRoot) : path.dirname(dirAbs);
|
|
2441
|
-
//
|
|
2495
|
+
// 記憶の置き場の名前(知識の根の名前から。`Cortex` ならこれまでと同じ出力)
|
|
2496
|
+
const memoryDir = (0, memory_dir_1.memoryDirOfRoot)(knowledgeRoot);
|
|
2497
|
+
// 帳簿 9 本の置き場(既定は `<repoRoot>/.cortex`)。読み口はこの 1 つから読む(根拠の台帳は組み直していない案件だけ `<repoRoot>/.cortex`)
|
|
2442
2498
|
let ledgerDir = (0, ledger_dir_1.ledgerDirOf)(repoRoot, opts.ledgerDir);
|
|
2443
|
-
//
|
|
2444
|
-
|
|
2445
|
-
|
|
2499
|
+
// 設定の置き場のヒント(便 DS-8b)。組み直した案件(木に `Memory/Home.md`)だけ `table`。最初の描画(骨組みを出すか)だけに使い、応答の mode が勝つ
|
|
2500
|
+
const configMode = await (0, config_mode_1.configModeHint)(repoRoot);
|
|
2501
|
+
// 🔴 組み直した案件(v2・cortex-engine #1911 便 DC-2f・設計書 D-4)は封筒を無条件で採用し、帳簿 8 本と根拠の台帳(便 DC-2e)を `.cortex` から読まない。
|
|
2502
|
+
// 封筒が無い・確かめられない回は投げる(空の画面を緑で配らない)。下の倒れ(catch)は組み直していない案件だけ
|
|
2503
|
+
const rebuilt = configMode === "table";
|
|
2504
|
+
if (rebuilt) {
|
|
2505
|
+
if (!opts.viewDir)
|
|
2506
|
+
throw new Error("組み直した案件(Memory/Home.md)のビルドには記憶側の画面用ファイル(--view-dir)が要ります(帳簿は .cortex から組みません)");
|
|
2507
|
+
// 記憶がまだ 1 件も無い案件(組み直した直後で、記憶側がまだ画面用ファイルを 1 度も置いていない)は空の画面を組む(cortex-engine #1911 便 GV)。
|
|
2508
|
+
// 🔴 空に倒れるのは「取り出した区画にファイルが 1 本も無い」かつ「読んだ決定と木の記憶の中身(記録・ストーリー)が 0 件」のときだけ。記録があるのに目次が無い・目次が空や壊れている・
|
|
2509
|
+
// 封筒の欠けは、取り出しか公開が壊れている(今どおり赤)
|
|
2510
|
+
const viewDirAbs = path.resolve(opts.viewDir);
|
|
2511
|
+
const empty = mdFiles.length === 0 && (await viewDirIsEmpty(viewDirAbs)) && (await memoryContentCount(path.join(repoRoot, "Memory"))) === 0;
|
|
2512
|
+
// 黙って緑にしない: 警告の 1 行を出す(記憶側の最初の通常の夜が目次を置けば、次のビルドから消える)
|
|
2513
|
+
if (empty)
|
|
2514
|
+
console.warn("記憶 v2 の画面用ファイル(組み直した案件): 記憶がまだ 1 件も無く、記憶側の画面用ファイルもまだ 1 本も無いので、空の画面を組みます");
|
|
2515
|
+
const plan = empty ? (0, view_dir_1.emptyPlanV2)() : await (0, view_dir_1.planViewsV2)(viewDirAbs);
|
|
2516
|
+
const merged = await (0, view_dir_1.mergeViewsV2)(plan);
|
|
2517
|
+
views.cleanup = merged.cleanup;
|
|
2518
|
+
views.counts = plan.counts;
|
|
2519
|
+
ledgerDir = merged.dir;
|
|
2520
|
+
console.log((0, view_dir_1.viewCountsLineV2)(plan.counts));
|
|
2521
|
+
}
|
|
2522
|
+
else if (opts.viewDir) {
|
|
2523
|
+
// 記憶 v2 の画面用ファイル(cortex-engine #1094 鎖 3 V10b)。checkout の HEAD とそろう封筒だけを差し替えた合わせの置き場を読む
|
|
2524
|
+
// 合わせの置き場を作れなかった回(一時フォルダの失敗など)は今の帳簿の置き場のまま組む(取り出しの失敗で画面を止めない・数は出さない)
|
|
2446
2525
|
try {
|
|
2447
2526
|
const plan = await (0, view_dir_1.planViews)(path.resolve(opts.viewDir), (0, view_dir_1.checkoutGit)(repoRoot), ledgerDir);
|
|
2448
2527
|
const merged = await (0, view_dir_1.mergeLedgerDir)(ledgerDir, plan);
|
|
@@ -2469,7 +2548,7 @@ async function buildSite(opts, views) {
|
|
|
2469
2548
|
// 🔴 **強さ(`state` が on のときだけ中身が入る)だけの案件でも器を作る**——作らないと、活性度の帳簿を
|
|
2470
2549
|
// 持たない案件で用語集が目次(engine の `termRows`)と違う順になる。
|
|
2471
2550
|
// 確認の帳簿(`confirmation`)は並びには関係しない
|
|
2472
|
-
const ledgers = await (0, rederivation_1.readRederivationLedgers)(repoRoot, ledgerDir);
|
|
2551
|
+
const ledgers = await (0, rederivation_1.readRederivationLedgers)(repoRoot, ledgerDir, { v2: rebuilt });
|
|
2473
2552
|
const rederive = ledgers.activity.size || ledgers.strength.size
|
|
2474
2553
|
? { ledgers: ledgers, repoRoot: repoRoot }
|
|
2475
2554
|
: null;
|
|
@@ -2479,11 +2558,13 @@ async function buildSite(opts, views) {
|
|
|
2479
2558
|
// 目次と同じ順位(engine #551)。**読めないなら `null`** で、つながり画面の点は今までどおり一律
|
|
2480
2559
|
const memoryRanking = await (0, ranking_1.readMemoryRanking)(repoRoot, ledgerDir);
|
|
2481
2560
|
// 根拠の台帳(便 B3)。**読めないなら `null`** で、根拠の段は記録に書かれた references のリンクだけ
|
|
2482
|
-
|
|
2561
|
+
// 組み直していない案件は案件リポの .cortex から(--ledger-dir に従わない)。組み直した案件は封筒をほどいた置き場から(便 DC-2e・memory-evidence.ts)
|
|
2562
|
+
const memoryEvidence = await (0, memory_evidence_1.readMemoryEvidence)(repoRoot, rebuilt ? ledgerDir : null);
|
|
2483
2563
|
// 人の手の表の写し(engine #1094 q-10)。あれば記憶 v2 の案件で、確認の印とボタンを出さない。**無い案件は今と 1 バイトも同じ**(キーごと無い)
|
|
2484
2564
|
// 「記憶 v2 の案件か」は 1 本の栓 `memory_v2_writer` の値で決める(cortex-engine #1094 鎖 3 V10b)。橋の間は写しとの OR
|
|
2485
2565
|
const memoryHands = await (0, hands_1.readMemoryHands)(repoRoot, ledgerDir);
|
|
2486
|
-
|
|
2566
|
+
// 組み直した案件(便 DC-2f)は記憶 v2 の案件(v1 の確認の帳簿を読まないので、確認の印とボタンを出さない)
|
|
2567
|
+
const memoryV2 = (0, hands_1.isMemoryV2)(opts.memoryV2Writer, memoryHands !== null) || rebuilt;
|
|
2487
2568
|
// 関係者の「つながっている ID」の出どころ(cortex-engine #1911 便 B4b)。`--view-dir` の中の平文を読むだけ。無い・読めない案件は何も付かない(今と 1 バイトも同じ)
|
|
2488
2569
|
const memberOrigins = opts.viewDir ? await (0, member_origin_1.readMemberOrigins)(path.resolve(opts.viewDir)) : null;
|
|
2489
2570
|
// 記録の id → リポジトリルート相対のパス(順位のファイルの鍵と突き合わせる。`repoRoot` 起点・cwd 起点にしない)
|
|
@@ -2637,9 +2718,9 @@ async function buildSite(opts, views) {
|
|
|
2637
2718
|
// 名前のリンク(story.screen-name-links): 日の relations の関係者・用語・ルールを、画面にある記録の表示名・別名・同義語で本文に当てる
|
|
2638
2719
|
(targets) => (0, story_1.storyNameLinks)(targets, storyNameSources(sections)),
|
|
2639
2720
|
// 本文の相対リンク(決定の記録など)の飛び先: 画面に載る記録(決定・各区画)のパス → id
|
|
2640
|
-
(repoPath) => idByRepoPath.get(repoPath));
|
|
2721
|
+
(repoPath) => idByRepoPath.get(repoPath), memoryDir);
|
|
2641
2722
|
// 週・月のあらすじ(#901)。週・月のファイルが無ければ null(キーごと出さない=今までと同じ画面)
|
|
2642
|
-
const storyDigest = await (0, story_1.readStoryDigest)(repoRoot, renderGroundingSection, (p) => repo.baseUrl ? `${repo.baseUrl}/edit/${repo.branch}/${encodePath(p)}` : null, storyToday, ledgerDir);
|
|
2723
|
+
const storyDigest = await (0, story_1.readStoryDigest)(repoRoot, renderGroundingSection, (p) => repo.baseUrl ? `${repo.baseUrl}/edit/${repo.branch}/${encodePath(p)}` : null, storyToday, ledgerDir, memoryDir);
|
|
2643
2724
|
// 案件アイコン(#348)。Cortex構成でなければ undefined(旧レイアウトには置き場が無い)
|
|
2644
2725
|
const projectIcon = await findProjectIcon(knowledgeRoot);
|
|
2645
2726
|
const site = {
|
|
@@ -2655,6 +2736,9 @@ async function buildSite(opts, views) {
|
|
|
2655
2736
|
homeGrounding: homeGrounding,
|
|
2656
2737
|
homeUpdatedAt: homeUpdatedAt,
|
|
2657
2738
|
...(memoryV2 ? { memoryV2: true } : {}),
|
|
2739
|
+
// 組み直した案件(`Memory`)だけ印を出す。今までの案件はキーごと無い(出力を変えない)
|
|
2740
|
+
...(memoryDir === "Memory" ? { memoryDir } : {}),
|
|
2741
|
+
...(configMode ? { configMode } : {}),
|
|
2658
2742
|
sections,
|
|
2659
2743
|
graph,
|
|
2660
2744
|
months,
|
|
@@ -2822,89 +2906,43 @@ async function parseDecision(raw, fileName, repoRelDir, repoBaseUrl, branch, ref
|
|
|
2822
2906
|
};
|
|
2823
2907
|
}
|
|
2824
2908
|
/**
|
|
2825
|
-
* 記憶 v2 の決定の新しい欄の読み手(#1094)。
|
|
2909
|
+
* 記憶 v2 の決定の新しい欄の読み手(#1094)と、関連の資料の欄 `related_materials` の読み手(cortex-engine #1094 F8)。
|
|
2826
2910
|
*
|
|
2827
|
-
*
|
|
2828
|
-
*
|
|
2829
|
-
* `
|
|
2911
|
+
* 原本は engine を束ねて引く(viewer/engine-src → dist/engine・便 R4): `scripts/gold/decision-v2-fields.mjs` の
|
|
2912
|
+
* `decisionV2FieldsOf`・`DECISION_FIRMNESS_READ_VALUES` と、`scripts/gold/related-materials-field.mjs` の `isRelatedUrl`・
|
|
2913
|
+
* `relatedMaterialsRead`・`RELATED_URL_MAX`・`RELATED_MATERIALS_FIELD`。規則はここに書かない。
|
|
2914
|
+
* 下の 3 つは欄 1 つの値を受ける viewer の薄い入口(原本は frontmatter 全体を受け、読めないとき `null`。viewer はキーごと載せないので `undefined`)。
|
|
2915
|
+
* 題材は engine から組み立てる `test/fixtures/decision-v2-fields-contract.json`・`related-materials-contract.json`
|
|
2916
|
+
* (`test/supersedes-view.test.mjs`・`test/related-materials-view.test.mjs` の「[契約] …」が流す)
|
|
2830
2917
|
*/
|
|
2831
|
-
|
|
2832
|
-
exports
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2918
|
+
var related_materials_field_2 = require("./engine/related-materials-field");
|
|
2919
|
+
Object.defineProperty(exports, "isRelatedUrl", { enumerable: true, get: function () { return related_materials_field_2.isRelatedUrl; } });
|
|
2920
|
+
Object.defineProperty(exports, "relatedMaterialsRead", { enumerable: true, get: function () { return related_materials_field_2.relatedMaterialsRead; } });
|
|
2921
|
+
Object.defineProperty(exports, "RELATED_MATERIALS_FIELD", { enumerable: true, get: function () { return related_materials_field_2.RELATED_MATERIALS_FIELD; } });
|
|
2922
|
+
Object.defineProperty(exports, "RELATED_URL_MAX", { enumerable: true, get: function () { return related_materials_field_2.RELATED_URL_MAX; } });
|
|
2923
|
+
/** 決定の固さの語彙(受け付ける語彙・並びも原本の `DECISION_FIRMNESS_READ_VALUES`) */
|
|
2924
|
+
exports.DECISION_FIRMNESS = decision_v2_fields_1.DECISION_FIRMNESS_READ_VALUES;
|
|
2838
2925
|
/** frontmatter の `firmness` → 語彙の 1 語。語彙外・文字列でないものは undefined(綴りはそのまま比べる) */
|
|
2839
2926
|
function decisionFirmnessOf(value) {
|
|
2840
|
-
return
|
|
2927
|
+
return (0, decision_v2_fields_1.decisionV2FieldsOf)({ firmness: value }).firmness ?? undefined;
|
|
2841
2928
|
}
|
|
2842
|
-
/**
|
|
2929
|
+
/**
|
|
2930
|
+
* frontmatter の `strand` → 筋の札の名前(前後の空白を落とす)。空・文字列でないものは undefined。
|
|
2931
|
+
* 🔴 viewer は `topic` でなく `strand` を読む。原本の札の読み(`topic` の読み=文字列で空でなければ trim)に `strand` の値を渡す
|
|
2932
|
+
*/
|
|
2843
2933
|
function decisionStrandOf(value) {
|
|
2844
|
-
return
|
|
2845
|
-
}
|
|
2846
|
-
/** `decided_by` の要素 1 つ。読めなければ null(文字列・知らない鍵・member と name/url の同居・member: で始まらない・空の name・http(s) でない url) */
|
|
2847
|
-
function decidedByEntryOf(entry) {
|
|
2848
|
-
if (entry == null || typeof entry !== "object" || Array.isArray(entry))
|
|
2849
|
-
return null;
|
|
2850
|
-
const o = entry;
|
|
2851
|
-
if (Object.keys(o).some((k) => !DECIDED_BY_KEYS.includes(k)))
|
|
2852
|
-
return null;
|
|
2853
|
-
const has = (k) => Object.prototype.hasOwnProperty.call(o, k);
|
|
2854
|
-
if (has("member")) {
|
|
2855
|
-
if (has("name") || has("url"))
|
|
2856
|
-
return null;
|
|
2857
|
-
return typeof o.member === "string" && MEMBER_ID_RE.test(o.member) ? { member: o.member } : null;
|
|
2858
|
-
}
|
|
2859
|
-
if (!has("name") || !isText(o.name))
|
|
2860
|
-
return null;
|
|
2861
|
-
if (o.url == null)
|
|
2862
|
-
return { name: o.name };
|
|
2863
|
-
return typeof o.url === "string" && DECIDED_BY_URL_RE.test(o.url) ? { name: o.name, url: o.url } : null;
|
|
2934
|
+
return (0, decision_v2_fields_1.decisionV2FieldsOf)({ topic: value }).topic ?? undefined;
|
|
2864
2935
|
}
|
|
2865
2936
|
/**
|
|
2866
|
-
* frontmatter の `decided_by` →
|
|
2937
|
+
* frontmatter の `decided_by` → 決めた人の並び。形の崩れた要素は**飛ばす**(原本の読み)。
|
|
2867
2938
|
* 欄がリストでなければ undefined(無いものとして扱う)。空のリストは []
|
|
2868
2939
|
*/
|
|
2869
2940
|
function decidedByOf(value) {
|
|
2870
|
-
|
|
2871
|
-
return undefined;
|
|
2872
|
-
return value.map(decidedByEntryOf).filter((e) => e !== null);
|
|
2873
|
-
}
|
|
2874
|
-
/**
|
|
2875
|
-
* 関連の資料の欄 `related_materials` の読み手(決定・ルール・用語・cortex-engine #1094 F8)。
|
|
2876
|
-
*
|
|
2877
|
-
* 🔴 **写し。正本は cortex-engine `scripts/gold/related-materials-field.mjs` の `isRelatedUrl` と `relatedMaterialsRead`**。
|
|
2878
|
-
* 同じバイト列の表 `test/fixtures/related-materials-contract.json` を両リポに置き、`test/related-materials-view.test.mjs` の
|
|
2879
|
-
* 「[契約] …」が全ケースを流す。規則を変えるときは engine の正本・この写し・表を同じ日に直す。
|
|
2880
|
-
* 重複も上限も見ない(人が足した分を落とさない)。`decided_by` の URL の門(`DECIDED_BY_URL_RE`)とは別の、engine と同じ門
|
|
2881
|
-
*/
|
|
2882
|
-
exports.RELATED_MATERIALS_FIELD = "related_materials";
|
|
2883
|
-
exports.RELATED_URL_MAX = 2000;
|
|
2884
|
-
// eslint-disable-next-line no-control-regex
|
|
2885
|
-
const RELATED_URL_RE = /^https?:\/\/[^\s<>"\[\]〔〕\u0000-\u001f\u007f]+$/i;
|
|
2886
|
-
/** 欄に置いてよい URL か(http(s)・空白と制御文字・`<>"[]〔〕` を含まない・ホストあり・2000 字まで) */
|
|
2887
|
-
function isRelatedUrl(v) {
|
|
2888
|
-
if (typeof v !== "string" || !v || v.length > exports.RELATED_URL_MAX)
|
|
2889
|
-
return false;
|
|
2890
|
-
if (!RELATED_URL_RE.test(v))
|
|
2891
|
-
return false;
|
|
2892
|
-
try {
|
|
2893
|
-
const u = new URL(v);
|
|
2894
|
-
return (u.protocol === "http:" || u.protocol === "https:") && u.hostname !== "";
|
|
2895
|
-
}
|
|
2896
|
-
catch {
|
|
2897
|
-
return false;
|
|
2898
|
-
}
|
|
2899
|
-
}
|
|
2900
|
-
/** frontmatter → 欄の URL の並び(通るものだけ・順はそのまま)。欄が無い・リストでなければ [] */
|
|
2901
|
-
function relatedMaterialsRead(fm) {
|
|
2902
|
-
const v = fm && typeof fm === "object" ? fm[exports.RELATED_MATERIALS_FIELD] : null;
|
|
2903
|
-
return Array.isArray(v) ? v.filter(isRelatedUrl) : [];
|
|
2941
|
+
return (0, decision_v2_fields_1.decisionV2FieldsOf)({ decided_by: value }).decidedBy ?? undefined;
|
|
2904
2942
|
}
|
|
2905
2943
|
/** 画面に載せる形(名前は根拠と同じ解決=帳の題名・URL の種類の名前)。通る URL が 0 本なら undefined(キーごと載せない) */
|
|
2906
2944
|
function relatedMaterialsView(fm, refs) {
|
|
2907
|
-
const urls = relatedMaterialsRead(fm);
|
|
2945
|
+
const urls = (0, related_materials_field_1.relatedMaterialsRead)(fm);
|
|
2908
2946
|
if (!urls.length)
|
|
2909
2947
|
return undefined;
|
|
2910
2948
|
return urls.map((u) => {
|
|
@@ -1,196 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syntaxNormalizedUrl = exports.githubRefToken = exports.canonicalEvidence = void 0;
|
|
2
4
|
/**
|
|
3
|
-
* **根拠の名前の正規化**(cortex-engine #968 設計 v3 §1.4
|
|
4
|
-
*
|
|
5
|
-
* 正本は cortex-engine `scripts/gold/ref-tokens.mjs#canonicalEvidence`。ここはその TypeScript の写し
|
|
6
|
-
* (ビューアは engine のコードを import できないので、ロジックごと複製する)。
|
|
5
|
+
* **根拠の名前の正規化**(cortex-engine #968 設計 v3 §1.4)の viewer の入口。
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* 原本は engine を束ねて引く(viewer/engine-src → dist/engine・便 R4): cortex-engine `scripts/gold/ref-tokens.mjs` の
|
|
8
|
+
* `canonicalEvidence`・`syntaxNormalizedUrl`・`githubRefToken`。規則はここに書かない(ctx の Map/Record の両対応も原本が持つ)。
|
|
9
|
+
* 題材は engine から組み立てる `test/fixtures/evidence-canonical-cases.json`(`test/canonical-evidence.test.mjs` が流す)。
|
|
11
10
|
*
|
|
12
|
-
* 比べるのは `key`、画面がリンク先として使うのは `url
|
|
13
|
-
* 既存の印(`refTokens`)と同じ綴り(小文字の課題キー・`gh:o/r#N`)——ビューアの他の場所
|
|
14
|
-
* (課題キーをそのまま ID にする `classifyTarget` の旧経路)と当たり方をそろえるため。
|
|
15
|
-
*/
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.githubRefToken = void 0;
|
|
18
|
-
exports.syntaxNormalizedUrl = syntaxNormalizedUrl;
|
|
19
|
-
exports.canonicalEvidence = canonicalEvidence;
|
|
20
|
-
/** 課題キーだけの値(`PJ_CORTEX-12`)。engine の `ISSUE_KEY_RE` と同じ形の全体一致 */
|
|
21
|
-
const WHOLE_ISSUE_KEY_RE = /^([A-Z][A-Z0-9_]{1,20})-(\d+)$/;
|
|
22
|
-
/** `owner/repo#N` だけの値 */
|
|
23
|
-
const WHOLE_GH_SHORT_RE = /^([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)#(\d+)$/;
|
|
24
|
-
/** スキーム・ホスト・残り(パス・クエリ・断片) */
|
|
25
|
-
const URL_PARTS_RE = /^(https?):\/\/([^/?#\s]+)([^\s]*)$/i;
|
|
26
|
-
/** GitHub の issue / PR を指す 2 つの綴りを同じ印にする(engine `githubRefToken` と同じ) */
|
|
27
|
-
const githubRefToken = (owner, repo, num) => `gh:${String(owner).toLowerCase()}/${String(repo).toLowerCase()}#${num}`;
|
|
28
|
-
exports.githubRefToken = githubRefToken;
|
|
29
|
-
/**
|
|
30
|
-
* URL の構文の正規化(RFC 3986 §6.2.2)。スキームとホストを小文字・既定のポートを落とす・`%xx` を大文字・
|
|
31
|
-
* 末尾の句読点と末尾の `/` を落とす。日本語はエンコードしない。URL でなければ `null`。
|
|
32
|
-
*/
|
|
33
|
-
function syntaxNormalizedUrl(raw) {
|
|
34
|
-
let t = String(raw ?? "").trim();
|
|
35
|
-
for (let prev = ""; prev !== t;) {
|
|
36
|
-
prev = t;
|
|
37
|
-
t = t.replace(/[).,;:、。]+$/, "").replace(/\/+$/, "");
|
|
38
|
-
}
|
|
39
|
-
const m = t.match(URL_PARTS_RE);
|
|
40
|
-
if (!m)
|
|
41
|
-
return null;
|
|
42
|
-
const scheme = m[1].toLowerCase();
|
|
43
|
-
let host = m[2].toLowerCase();
|
|
44
|
-
if ((scheme === "http" && host.endsWith(":80")) || (scheme === "https" && host.endsWith(":443"))) {
|
|
45
|
-
host = host.replace(/:\d+$/, "");
|
|
46
|
-
}
|
|
47
|
-
const rest = m[3].replace(/%[0-9a-f]{2}/gi, (x) => x.toUpperCase()).replace(/\/+(?=$|[?#])/, "");
|
|
48
|
-
return `${scheme}://${host}${rest}`;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* 値全体が URL 1 本の形のときだけ、その URL を返す(素の URL・`[ラベル](URL)`・Slack の `<URL|ラベル>`)。
|
|
52
|
-
* パスに URL を添えた値・文の中に URL がある値は `null`。Markdown のエスケープ(`PJ\_CORTEX`)は外す
|
|
53
|
-
*/
|
|
54
|
-
function wholeUrlOf(value) {
|
|
55
|
-
const v = value.trim();
|
|
56
|
-
const m = v.match(/^(https?:\/\/\S+)$/i) ||
|
|
57
|
-
v.match(/^\[[^\]\n]*\]\((https?:\/\/[^)\s]+)\)$/i) ||
|
|
58
|
-
v.match(/^<(https?:\/\/[^|>\s]+)(?:\|[^>]*)?>$/i);
|
|
59
|
-
return m ? m[1].replace(/\\_/g, "_") : null;
|
|
60
|
-
}
|
|
61
|
-
function toMap(v) {
|
|
62
|
-
if (v instanceof Map)
|
|
63
|
-
return v;
|
|
64
|
-
return new Map(Object.entries(v ?? {}));
|
|
65
|
-
}
|
|
66
|
-
const queryOf = (rest) => {
|
|
67
|
-
const q = rest.indexOf("?");
|
|
68
|
-
if (q < 0)
|
|
69
|
-
return new URLSearchParams();
|
|
70
|
-
const h = rest.indexOf("#", q);
|
|
71
|
-
return new URLSearchParams(rest.slice(q + 1, h < 0 ? undefined : h));
|
|
72
|
-
};
|
|
73
|
-
const pathOf = (rest) => rest.replace(/[?#].*$/, "");
|
|
74
|
-
const fragmentOf = (rest) => {
|
|
75
|
-
const h = rest.indexOf("#");
|
|
76
|
-
return h < 0 ? "" : rest.slice(h + 1);
|
|
77
|
-
};
|
|
78
|
-
const GDOC_KINDS = new Set(["document", "spreadsheets", "presentation", "forms"]);
|
|
79
|
-
const BACKLOG_HOST_RE = /\.(?:backlog\.jp|backlog\.com|backlogtool\.com)$/;
|
|
80
|
-
/** 種類ごとの解き方(URL を構文正規化した後)。当たらなければ汎用の `url` 種に落ちる */
|
|
81
|
-
function canonicalOfUrl(url, ctx) {
|
|
82
|
-
const m = url.match(URL_PARTS_RE);
|
|
83
|
-
const host = m[2];
|
|
84
|
-
const rest = m[3];
|
|
85
|
-
const p = pathOf(rest);
|
|
86
|
-
const q = queryOf(rest);
|
|
87
|
-
if (host === "docs.google.com") {
|
|
88
|
-
const g = p.match(/^\/([a-z]+)\/(?:u\/\d+\/)?d\/([A-Za-z0-9_-]{10,})/);
|
|
89
|
-
if (g && GDOC_KINDS.has(g[1])) {
|
|
90
|
-
return { kind: "gdoc", key: `gfile:${g[2]}`, url: `https://docs.google.com/${g[1]}/d/${g[2]}` };
|
|
91
|
-
}
|
|
92
|
-
const fd = p.match(/^\/file\/d\/([A-Za-z0-9_-]{10,})/);
|
|
93
|
-
if (fd)
|
|
94
|
-
return { kind: "drive", key: `gfile:${fd[1]}`, url: `https://drive.google.com/file/d/${fd[1]}/view` };
|
|
95
|
-
}
|
|
96
|
-
if (host === "drive.google.com") {
|
|
97
|
-
const f = p.match(/^\/file\/(?:u\/\d+\/)?d\/([A-Za-z0-9_-]{10,})/);
|
|
98
|
-
const id = f ? f[1] : /^\/(?:open|uc)$/.test(p) && /^[A-Za-z0-9_-]{10,}$/.test(q.get("id") || "") ? q.get("id") : "";
|
|
99
|
-
if (id)
|
|
100
|
-
return { kind: "drive", key: `gfile:${id}`, url: `https://drive.google.com/file/d/${id}/view` };
|
|
101
|
-
const d = p.match(/^\/drive\/(?:u\/\d+\/)?folders\/([A-Za-z0-9_-]{10,})/);
|
|
102
|
-
if (d)
|
|
103
|
-
return { kind: "drive-folder", key: `gfolder:${d[1]}`, url: `https://drive.google.com/drive/folders/${d[1]}` };
|
|
104
|
-
}
|
|
105
|
-
if (host.endsWith(".slack.com")) {
|
|
106
|
-
const s = p.match(/^\/archives\/([A-Z0-9]+)(?:\/p(\d+))?$/);
|
|
107
|
-
if (s) {
|
|
108
|
-
const hosts = toMap(ctx.slackHosts);
|
|
109
|
-
const h = String(hosts.get(s[1]) || "").trim().toLowerCase() || host;
|
|
110
|
-
const thread = s[2] && /^\d+\.\d+$/.test(q.get("thread_ts") || "") ? q.get("thread_ts") : "";
|
|
111
|
-
const key = `slack:${s[1]}${s[2] ? `:p${s[2]}` : ""}`;
|
|
112
|
-
const tail = `${s[2] ? `/p${s[2]}` : ""}${thread ? `?thread_ts=${thread}` : ""}`;
|
|
113
|
-
return { kind: "slack", key, url: `https://${h}/archives/${s[1]}${tail}` };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (host === "chat.google.com" || host === "mail.google.com") {
|
|
117
|
-
const room = host === "chat.google.com" ? p.match(/^\/(?:u\/\d+\/)?room\/([A-Za-z0-9_-]+)/) : null;
|
|
118
|
-
const inMail = host === "mail.google.com" && /^\/chat(?:\/|$)/.test(p) ? fragmentOf(rest).match(/^chat\/space\/([A-Za-z0-9_-]+)/) : null;
|
|
119
|
-
const space = (room && room[1]) || (inMail && inMail[1]);
|
|
120
|
-
if (space)
|
|
121
|
-
return { kind: "gchat", key: `gchat:${space}`, url: `https://chat.google.com/room/${space}` };
|
|
122
|
-
}
|
|
123
|
-
if (BACKLOG_HOST_RE.test(host)) {
|
|
124
|
-
const v = p.match(/^\/view\/([A-Z][A-Z0-9_]{1,20}-\d+)$/);
|
|
125
|
-
if (v) {
|
|
126
|
-
const c = fragmentOf(rest).match(/^comment-(\d+)$/);
|
|
127
|
-
const issue = v[1].toLowerCase();
|
|
128
|
-
return {
|
|
129
|
-
kind: "backlog",
|
|
130
|
-
key: c ? `${issue}#comment-${c[1]}` : issue,
|
|
131
|
-
url: `https://${host}/view/${v[1]}${c ? `#comment-${c[1]}` : ""}`,
|
|
132
|
-
...(c ? { parentKey: issue } : {}),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
const w = p.match(/^\/alias\/wiki\/(\d+)$/);
|
|
136
|
-
if (w)
|
|
137
|
-
return { kind: "backlog", key: `backlog:${host}:wiki:${w[1]}`, url: `https://${host}/alias/wiki/${w[1]}` };
|
|
138
|
-
const d = p.match(/^\/document\/([^/]+)\/([0-9a-f]{32})$/i);
|
|
139
|
-
if (d)
|
|
140
|
-
return { kind: "backlog", key: `backlog:${host}:doc:${d[2].toLowerCase()}`, url: `https://${host}/document/${d[1]}/${d[2].toLowerCase()}` };
|
|
141
|
-
}
|
|
142
|
-
if (host === "figma.com" || host === "www.figma.com") {
|
|
143
|
-
const f = p.match(/^\/(design|file|proto|board)\/([A-Za-z0-9]{10,})(?:\/branch\/([A-Za-z0-9]{10,}))?(?:\/|$)/);
|
|
144
|
-
if (f) {
|
|
145
|
-
const fileKey = f[3] || f[2];
|
|
146
|
-
const node = String(q.get("node-id") || "").trim().replace(/%3A/gi, ":");
|
|
147
|
-
if (node && !/^\d+[-:]\d+$/.test(node))
|
|
148
|
-
return { kind: "url", key: `url:${url}`, url };
|
|
149
|
-
const n = node ? node.replace(":", "-") : "";
|
|
150
|
-
const seg = f[1] === "board" ? "board" : "design";
|
|
151
|
-
return { kind: "figma", key: `figma:${fileKey}${n ? `:${n.replace("-", ":")}` : ""}`, url: `https://www.figma.com/${seg}/${fileKey}${n ? `?node-id=${n}` : ""}` };
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (host === "github.com" || host === "www.github.com") {
|
|
155
|
-
const g = p.match(/^\/([^/]+)\/([^/]+)\/(?:issues|pull|discussions)\/(\d+)$/);
|
|
156
|
-
if (g) {
|
|
157
|
-
const [o, r] = [g[1].toLowerCase(), g[2].toLowerCase()];
|
|
158
|
-
const issue = (0, exports.githubRefToken)(o, r, g[3]);
|
|
159
|
-
const c = fragmentOf(rest).match(/^(issuecomment-\d+|discussioncomment-\d+|discussion_r\d+|pullrequestreview-\d+)$/);
|
|
160
|
-
return {
|
|
161
|
-
kind: "github",
|
|
162
|
-
key: c ? `${issue}#${c[1]}` : issue,
|
|
163
|
-
url: `https://github.com/${o}/${r}/issues/${g[3]}${c ? `#${c[1]}` : ""}`,
|
|
164
|
-
...(c ? { parentKey: issue } : {}),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return { kind: "url", key: `url:${url}`, url };
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* 根拠の名前の正規化。解けない入力(Gold の ID・`minute:`・`material:`・`design:`・リポのパス・
|
|
172
|
-
* ホストの決まらない課題キー・URL が 2 本以上の値)は `null`。engine 版と 1:1 対応。
|
|
11
|
+
* 比べるのは `key`、画面がリンク先として使うのは `url`。
|
|
173
12
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const key = raw.match(WHOLE_ISSUE_KEY_RE);
|
|
179
|
-
if (key) {
|
|
180
|
-
const domains = toMap(ctx.backlogDomains);
|
|
181
|
-
const host = String(domains.get(key[1]) || "")
|
|
182
|
-
.trim()
|
|
183
|
-
.toLowerCase()
|
|
184
|
-
.replace(/^https?:\/\//, "")
|
|
185
|
-
.replace(/\/+$/, "");
|
|
186
|
-
return host ? canonicalOfUrl(`https://${host}/view/${raw}`, ctx) : null;
|
|
187
|
-
}
|
|
188
|
-
const gh = raw.match(WHOLE_GH_SHORT_RE);
|
|
189
|
-
if (gh)
|
|
190
|
-
return canonicalOfUrl(`https://github.com/${gh[1]}/${gh[2]}/issues/${gh[3]}`, ctx);
|
|
191
|
-
const url = wholeUrlOf(raw);
|
|
192
|
-
if (!url)
|
|
193
|
-
return null;
|
|
194
|
-
const normalized = syntaxNormalizedUrl(url);
|
|
195
|
-
return normalized ? canonicalOfUrl(normalized, ctx) : null;
|
|
196
|
-
}
|
|
13
|
+
var ref_tokens_1 = require("./engine/ref-tokens");
|
|
14
|
+
Object.defineProperty(exports, "canonicalEvidence", { enumerable: true, get: function () { return ref_tokens_1.canonicalEvidence; } });
|
|
15
|
+
Object.defineProperty(exports, "githubRefToken", { enumerable: true, get: function () { return ref_tokens_1.githubRefToken; } });
|
|
16
|
+
Object.defineProperty(exports, "syntaxNormalizedUrl", { enumerable: true, get: function () { return ref_tokens_1.syntaxNormalizedUrl; } });
|
package/dist/change-log.js
CHANGED
|
@@ -46,7 +46,7 @@ exports.CHANGE_LOG_MAX_ROWS = 50;
|
|
|
46
46
|
/** `why` は 1 行 3 本まで(engine の `WHY_MAX`)。これも画面の表示の絞り(`common.delete-cap-exceptions`・元のリンクはコミットに残る) */
|
|
47
47
|
const WHY_MAX = 3;
|
|
48
48
|
/** 載る記録のパス(4 区画の記録。README・雛形・入れ子は載らない) */
|
|
49
|
-
const RECORD_PATH = /^Cortex\/(Decisions|Glossary|Members|Rules)\/records\/[^/]+\.md$/;
|
|
49
|
+
const RECORD_PATH = /^(?:Cortex|Memory)\/(Decisions|Glossary|Members|Rules)\/records\/[^/]+\.md$/;
|
|
50
50
|
const isObj = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
51
51
|
/** メールの形(URL の部分を除いて見る) */
|
|
52
52
|
// engine `change-log.mjs` の定義と同じ(緩めると、URL の後ろのメールや非 ASCII のローカル部が通る)
|