sdtk-wiki-kit 0.1.2 → 0.1.3
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 +12 -5
- package/package.json +1 -1
- package/src/commands/lint.js +1 -0
- package/src/commands/operations.js +1 -1
- package/src/commands/wiki.js +1 -1
- package/src/lib/wiki-compile.js +427 -42
- package/src/lib/wiki-extract.js +680 -4
- package/src/lib/wiki-lint.js +223 -2
package/README.md
CHANGED
|
@@ -177,13 +177,20 @@ sdtk-wiki ingest <source-root> [--project-path <path>]
|
|
|
177
177
|
sdtk-wiki ingest --source-root <source-root> [--project-path <path>]
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
Runs semantic extraction over a local Markdown source root
|
|
180
|
+
Runs semantic extraction over a local Markdown source root plus supported JSON
|
|
181
|
+
source records and writes the latest
|
|
181
182
|
`semantic-extraction-dry-run-*.json` report under `.sdtk/wiki/reports`.
|
|
182
183
|
|
|
183
184
|
This is the beginner-friendly facade for `sdtk-wiki wiki extract --dry-run`.
|
|
184
185
|
It does not mutate source files, personal-brain pages, raw/provenance state,
|
|
185
186
|
graph outputs, web sources, Ask state, or `.sdtk/atlas`.
|
|
186
187
|
|
|
188
|
+
Supported JSON repository records may be an array or an object containing a
|
|
189
|
+
`records`, `repos`, `repositories`, `items`, or `data` array. Each record can
|
|
190
|
+
include `repo_url`, `owner`, `repo_name`, `message_text_snippet`,
|
|
191
|
+
`source_link`, `topics`, and `confidence`. JSON records are local-only evidence:
|
|
192
|
+
SDTK-WIKI does not fetch GitHub, Facebook, or web URLs.
|
|
193
|
+
|
|
187
194
|
### Lint
|
|
188
195
|
|
|
189
196
|
```powershell
|
|
@@ -235,10 +242,10 @@ boundary.
|
|
|
235
242
|
sdtk-wiki wiki extract --project-path <path> --source-root <path> --dry-run
|
|
236
243
|
```
|
|
237
244
|
|
|
238
|
-
Reads local Markdown sources and
|
|
239
|
-
`.sdtk/wiki/reports`. The report can
|
|
240
|
-
tool candidates, concept candidates,
|
|
241
|
-
source-quality findings.
|
|
245
|
+
Reads local Markdown sources and supported JSON repository records and writes a
|
|
246
|
+
semantic extraction JSON report under `.sdtk/wiki/reports`. The report can
|
|
247
|
+
identify local source records, GitHub tool candidates, concept candidates,
|
|
248
|
+
relations, comparisons, syntheses, and source-quality findings.
|
|
242
249
|
|
|
243
250
|
Safety:
|
|
244
251
|
|
package/package.json
CHANGED
package/src/commands/lint.js
CHANGED
|
@@ -21,6 +21,7 @@ Output:
|
|
|
21
21
|
Behavior:
|
|
22
22
|
Findings are written to the report and do not auto-modify wiki or source files.
|
|
23
23
|
Source-quality checks report mojibake-like text, missing source URLs, weak titles, duplicate repo/source candidates, low-confidence extraction, and raw/graph/provenance coverage mismatch.
|
|
24
|
+
Personal-brain quality metrics report frontmatter coverage, required sections, source refs, internal links, stub ratio, giant pages, density, and source evidence coverage.
|
|
24
25
|
Completed lint runs exit 0 even when findings exist.
|
|
25
26
|
Missing workspace or fatal report-write failures exit non-zero.
|
|
26
27
|
|
|
@@ -97,7 +97,7 @@ Usage:
|
|
|
97
97
|
sdtk-wiki ingest --source-root <path> [--project-path <path>]
|
|
98
98
|
|
|
99
99
|
Purpose:
|
|
100
|
-
Run local semantic extraction over
|
|
100
|
+
Run local semantic extraction over Markdown and supported JSON source records and write a report under .sdtk/wiki/reports.
|
|
101
101
|
|
|
102
102
|
Safety:
|
|
103
103
|
Local sources only.
|
package/src/commands/wiki.js
CHANGED
|
@@ -44,7 +44,7 @@ Writes:
|
|
|
44
44
|
|
|
45
45
|
Safety:
|
|
46
46
|
Dry-run report only.
|
|
47
|
-
Local Markdown source roots only; remote URLs are rejected.
|
|
47
|
+
Local Markdown and supported JSON source roots only; remote URLs are rejected.
|
|
48
48
|
No personal-brain pages, managed pages, raw sources, provenance state, atlas compatibility files, web fetch, Ask, compile/apply, prune, delete, archive, or source files are modified.`);
|
|
49
49
|
return 0;
|
|
50
50
|
}
|
package/src/lib/wiki-compile.js
CHANGED
|
@@ -106,13 +106,150 @@ function mdList(values) {
|
|
|
106
106
|
return items.length > 0 ? items.map((item) => `- ${item}`).join("\n") : "- None recorded.";
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
function mdLinkedList(values) {
|
|
110
|
+
const items = asArray(values).filter(Boolean);
|
|
111
|
+
if (items.length === 0) return "- None recorded.";
|
|
112
|
+
return items.map((item) => {
|
|
113
|
+
const text = String(item);
|
|
114
|
+
if (/^https?:\/\//i.test(text)) return `- [${text}](${text})`;
|
|
115
|
+
return `- ${text}`;
|
|
116
|
+
}).join("\n");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function quoteBlock(value) {
|
|
120
|
+
const text = String(value || "").replace(/\r?\n/g, " ").trim();
|
|
121
|
+
return text ? `> ${text}` : "> No extracted snippet recorded in the local source.";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function topicLabelList(entity) {
|
|
125
|
+
const topics = [...new Set(asArray(entity.topics).filter(Boolean).map(String))];
|
|
126
|
+
return topics.length > 0 ? topics.map((topic) => `- ${topic}`).join("\n") : "- No topic labels extracted from local sources.";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function relatedRepoList(entity) {
|
|
130
|
+
const repos = asArray(entity.related_repos);
|
|
131
|
+
if (repos.length === 0) return "- No related repositories inferred from local topic overlap.";
|
|
132
|
+
return repos.map((repo) => {
|
|
133
|
+
const label = repo.name || repo.entity_id || "related repo";
|
|
134
|
+
const suffix = asArray(repo.shared_topics).length > 0 ? ` (shared topics: ${asArray(repo.shared_topics).join(", ")})` : "";
|
|
135
|
+
return repo.github_url ? `- [${label}](${repo.github_url})${suffix}` : `- ${label}${suffix}`;
|
|
136
|
+
}).join("\n");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function relativePersonalBrainLink(targetPagePath) {
|
|
140
|
+
const text = toPosix(targetPagePath || "");
|
|
141
|
+
const marker = ".sdtk/wiki/personal-brain/";
|
|
142
|
+
const idx = text.indexOf(marker);
|
|
143
|
+
return idx >= 0 ? text.slice(idx + marker.length) : text;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function conceptAxisList(concept) {
|
|
147
|
+
const axes = asArray(concept.key_axes);
|
|
148
|
+
if (axes.length === 0) return "- No key axes were inferred from local evidence.";
|
|
149
|
+
return axes.map((axis) => `- ${axis.name}: ${axis.evidence_count || 1} local evidence reference(s).`).join("\n");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function conceptImplementationList(concept) {
|
|
153
|
+
const entities = asArray(concept.related_entity_details);
|
|
154
|
+
if (entities.length === 0) return "- No implementation examples were extracted from local sources.";
|
|
155
|
+
return entities.slice(0, 10).map((entity) => {
|
|
156
|
+
const label = entity.repo_owner && entity.repo_name ? `${entity.repo_owner}/${entity.repo_name}` : (entity.name || "tool candidate");
|
|
157
|
+
const link = entity.target_page_path ? relativePersonalBrainLink(entity.target_page_path) : "";
|
|
158
|
+
const target = link ? `[${label}](../${link})` : label;
|
|
159
|
+
const url = entity.github_url ? `; ${entity.github_url}` : "";
|
|
160
|
+
return `- ${target}: ${entity.summary || `Local candidate in ${entity.category || "uncategorized"}`}${url}`;
|
|
161
|
+
}).join("\n");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function conceptPatternList(concept) {
|
|
165
|
+
const patterns = asArray(concept.patterns);
|
|
166
|
+
if (patterns.length === 0) return "- No repeated pattern was inferred from local evidence.";
|
|
167
|
+
return patterns.map((pattern) => `- ${pattern.pattern}: ${pattern.evidence}`).join("\n");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function conceptRelatedPagesList(concept) {
|
|
171
|
+
const pages = asArray(concept.related_entity_details)
|
|
172
|
+
.map((entity) => entity.target_page_path)
|
|
173
|
+
.filter(Boolean)
|
|
174
|
+
.map((target) => `../${relativePersonalBrainLink(target)}`);
|
|
175
|
+
return mdList([...new Set(pages)].slice(0, 12));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function confidenceSummaryList(summary) {
|
|
179
|
+
if (!summary || typeof summary !== "object") return "- No source confidence summary recorded.";
|
|
180
|
+
const rows = Object.entries(summary).filter(([, count]) => Number(count) > 0);
|
|
181
|
+
return rows.length > 0 ? rows.map(([tier, count]) => `- ${tier}: ${count}`).join("\n") : "- No source confidence summary recorded.";
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function comparisonMatrix(comparison) {
|
|
185
|
+
const rows = asArray(comparison.matrix_rows);
|
|
186
|
+
if (rows.length === 0) return "| Candidate | Category | Local evidence | Strengths | Caveats | Recommendation |\n|---|---|---:|---|---|---|\n| None recorded | - | 0 | - | - | - |";
|
|
187
|
+
const table = [
|
|
188
|
+
"| Candidate | Category | Local evidence | Strengths | Caveats | Recommendation |",
|
|
189
|
+
"|---|---|---:|---|---|---|",
|
|
190
|
+
];
|
|
191
|
+
for (const row of rows) {
|
|
192
|
+
const candidate = row.github_url ? `[${row.name || row.entity_id}](${row.github_url})` : (row.name || row.entity_id || "candidate");
|
|
193
|
+
table.push(`| ${candidate} | ${row.category || "uncategorized"} | ${row.source_ref_count || 0} | ${asArray(row.strengths).slice(0, 3).join("<br>") || "-"} | ${asArray(row.caveats).slice(0, 3).join("<br>") || "-"} | ${row.local_recommendation || "review"} |`);
|
|
194
|
+
}
|
|
195
|
+
return table.join("\n");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function candidateToolList(records) {
|
|
199
|
+
const rows = asArray(records);
|
|
200
|
+
if (rows.length === 0) return "- No candidate tools recorded.";
|
|
201
|
+
return rows.slice(0, 12).map((row) => {
|
|
202
|
+
const label = row.github_url ? `[${row.name || row.entity_id}](${row.github_url})` : (row.name || row.entity_id || "candidate");
|
|
203
|
+
return `- ${label}: ${row.local_recommendation || "review"}; confidence ${row.source_confidence || row.confidence_tier || "unknown"}.`;
|
|
204
|
+
}).join("\n");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function yamlScalar(value) {
|
|
208
|
+
return `"${String(value ?? "").replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, " ").trim()}"`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function yamlInlineList(values) {
|
|
212
|
+
const items = [...new Set(asArray(values).filter(Boolean).map(String))];
|
|
213
|
+
return `[${items.map(yamlScalar).join(", ")}]`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function frontmatterBlock(fields) {
|
|
217
|
+
const lines = ["---"];
|
|
218
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
219
|
+
if (Array.isArray(value)) {
|
|
220
|
+
lines.push(`${key}: ${yamlInlineList(value)}`);
|
|
221
|
+
} else {
|
|
222
|
+
lines.push(`${key}: ${yamlScalar(value)}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
lines.push("---", "");
|
|
226
|
+
return lines.join("\n");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function withPersonalBrainFrontmatter(fields, body) {
|
|
230
|
+
return `${frontmatterBlock({
|
|
231
|
+
schema_version: "1",
|
|
232
|
+
product: "SDTK-WIKI",
|
|
233
|
+
managed_by: "sdtk-wiki",
|
|
234
|
+
status: "generated",
|
|
235
|
+
aliases: [],
|
|
236
|
+
tags: [],
|
|
237
|
+
related_pages: [],
|
|
238
|
+
source_refs: [],
|
|
239
|
+
confidence: "medium",
|
|
240
|
+
review_status: "needs_review",
|
|
241
|
+
...fields,
|
|
242
|
+
})}${String(body || "").replace(/^\s+/, "")}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
109
245
|
function recordTitle(record, fallback) {
|
|
110
246
|
return String(record.title || record.name || record.topic || record.entity_id || record.concept_id || record.source_id || fallback || "Generated page");
|
|
111
247
|
}
|
|
112
248
|
|
|
113
|
-
function renderSourcePage(source) {
|
|
114
|
-
|
|
115
|
-
|
|
249
|
+
function renderSourcePage(source, generatedAt) {
|
|
250
|
+
const title = recordTitle(source, "Source");
|
|
251
|
+
const body = [
|
|
252
|
+
`# ${title}`,
|
|
116
253
|
"",
|
|
117
254
|
"## Summary",
|
|
118
255
|
"",
|
|
@@ -136,93 +273,316 @@ function renderSourcePage(source) {
|
|
|
136
273
|
mdList(provenanceRefsFor(source)),
|
|
137
274
|
"",
|
|
138
275
|
].join("\n");
|
|
276
|
+
return withPersonalBrainFrontmatter({
|
|
277
|
+
id: source.source_id,
|
|
278
|
+
title,
|
|
279
|
+
type: "source",
|
|
280
|
+
created_at: generatedAt,
|
|
281
|
+
updated_at: generatedAt,
|
|
282
|
+
aliases: source.source_logical_path ? [source.source_logical_path] : [],
|
|
283
|
+
tags: ["source", source.source_type || "local"],
|
|
284
|
+
source_refs: sourceRefsFor(source),
|
|
285
|
+
confidence: source.source_quality && source.source_quality.low_confidence_extraction ? "low" : "medium",
|
|
286
|
+
review_status: source.source_quality && source.source_quality.low_confidence_extraction ? "needs_review" : "ready_for_review",
|
|
287
|
+
}, body);
|
|
139
288
|
}
|
|
140
289
|
|
|
141
|
-
function renderToolEntityPage(entity) {
|
|
142
|
-
|
|
143
|
-
|
|
290
|
+
function renderToolEntityPage(entity, generatedAt) {
|
|
291
|
+
const title = recordTitle(entity, "Tool entity");
|
|
292
|
+
const evidenceRecords = asArray(entity.evidence_records);
|
|
293
|
+
const firstSnippet = asArray(entity.evidence_snippets)[0] || (evidenceRecords[0] && evidenceRecords[0].snippet);
|
|
294
|
+
const discoverySources = [
|
|
295
|
+
...asArray(entity.source_links),
|
|
296
|
+
...asArray(entity.discovery_sources),
|
|
297
|
+
...evidenceRecords.map((record) => record.source_link || record.source_logical_path).filter(Boolean),
|
|
298
|
+
];
|
|
299
|
+
const sourceCount = sourceRefsFor(entity).length;
|
|
300
|
+
const whyItMatters = entity.summary
|
|
301
|
+
? `Local evidence presents ${title} as relevant to ${entity.category || "the extracted tool landscape"}. ${entity.summary}`
|
|
302
|
+
: `Local evidence links ${title} to ${entity.category || "the extracted tool landscape"} with ${sourceCount} source reference(s).`;
|
|
303
|
+
const whenToUse = asArray(entity.topics).length > 0
|
|
304
|
+
? `Review when exploring ${asArray(entity.topics).slice(0, 4).join(", ")} options from the local source set.`
|
|
305
|
+
: "Review when evaluating whether this repository should become a maintained tool note.";
|
|
306
|
+
const overlap = asArray(entity.related_repos).length > 0
|
|
307
|
+
? "Related repositories were inferred from shared local topic labels or category evidence. Treat this as a review cue, not external verification."
|
|
308
|
+
: "No overlap was inferred from local topic labels in this slice.";
|
|
309
|
+
const body = [
|
|
310
|
+
`# ${title}`,
|
|
144
311
|
"",
|
|
145
312
|
"## Summary",
|
|
146
313
|
"",
|
|
147
314
|
entity.summary || `Generated tool entity page for ${entity.name || entity.entity_id}.`,
|
|
148
315
|
"",
|
|
149
|
-
"##
|
|
316
|
+
"## Key Facts",
|
|
150
317
|
"",
|
|
151
|
-
`-
|
|
152
|
-
`-
|
|
153
|
-
`-
|
|
154
|
-
`-
|
|
318
|
+
`- Canonical URL: ${entity.github_url || "(missing)"}`,
|
|
319
|
+
`- Owner: ${entity.repo_owner || "(missing)"}`,
|
|
320
|
+
`- Repo name: ${entity.repo_name || "(missing)"}`,
|
|
321
|
+
`- Category: ${entity.category || "(unknown)"}`,
|
|
322
|
+
`- Confidence: ${entity.confidence_tier || entity.confidence || "medium"}`,
|
|
323
|
+
`- Local source refs: ${sourceCount}`,
|
|
155
324
|
"",
|
|
156
|
-
"##
|
|
325
|
+
"## Discovery Source",
|
|
326
|
+
"",
|
|
327
|
+
mdLinkedList([...new Set(discoverySources.filter(Boolean).map(String))]),
|
|
328
|
+
"",
|
|
329
|
+
"## Extracted Snippet",
|
|
330
|
+
"",
|
|
331
|
+
quoteBlock(firstSnippet),
|
|
332
|
+
"",
|
|
333
|
+
"## Topic Labels",
|
|
334
|
+
"",
|
|
335
|
+
topicLabelList(entity),
|
|
336
|
+
"",
|
|
337
|
+
"## Why It Matters",
|
|
338
|
+
"",
|
|
339
|
+
whyItMatters,
|
|
340
|
+
"",
|
|
341
|
+
"## When To Use",
|
|
342
|
+
"",
|
|
343
|
+
whenToUse,
|
|
344
|
+
"",
|
|
345
|
+
"## Related Repos",
|
|
346
|
+
"",
|
|
347
|
+
relatedRepoList(entity),
|
|
348
|
+
"",
|
|
349
|
+
"## Overlaps / Differences",
|
|
350
|
+
"",
|
|
351
|
+
overlap,
|
|
352
|
+
"",
|
|
353
|
+
"## Open Questions",
|
|
354
|
+
"",
|
|
355
|
+
"- Verify license, maintenance status, and project maturity before relying on this tool.",
|
|
356
|
+
"- Confirm whether the local topic labels match the repository's actual current scope.",
|
|
357
|
+
"- Decide whether this should remain a tool entity or be reclassified after review.",
|
|
358
|
+
"",
|
|
359
|
+
"## Local Evidence Records",
|
|
157
360
|
"",
|
|
158
|
-
|
|
361
|
+
evidenceRecords.length > 0
|
|
362
|
+
? evidenceRecords.map((record) => [
|
|
363
|
+
`- source_id: ${record.source_id || "(missing)"}`,
|
|
364
|
+
` - source: ${record.source_link || record.source_logical_path || "(missing)"}`,
|
|
365
|
+
` - topics: ${asArray(record.topics).join(", ") || "(none)"}`,
|
|
366
|
+
` - confidence: ${record.confidence_tier || record.confidence || "(unknown)"}`,
|
|
367
|
+
].join("\n")).join("\n")
|
|
368
|
+
: "- No structured evidence records recorded.",
|
|
159
369
|
"",
|
|
160
370
|
"## Provenance",
|
|
161
371
|
"",
|
|
162
372
|
mdList(provenanceRefsFor(entity)),
|
|
163
373
|
"",
|
|
164
374
|
].join("\n");
|
|
375
|
+
return withPersonalBrainFrontmatter({
|
|
376
|
+
id: entity.entity_id,
|
|
377
|
+
title,
|
|
378
|
+
type: "tool_entity",
|
|
379
|
+
created_at: generatedAt,
|
|
380
|
+
updated_at: generatedAt,
|
|
381
|
+
aliases: [entity.repo_name, entity.github_url].filter(Boolean),
|
|
382
|
+
tags: ["tool", entity.category, ...asArray(entity.topics)].filter(Boolean),
|
|
383
|
+
source_refs: sourceRefsFor(entity),
|
|
384
|
+
confidence: entity.confidence_tier || entity.confidence || "medium",
|
|
385
|
+
review_status: "ready_for_review",
|
|
386
|
+
}, body);
|
|
165
387
|
}
|
|
166
388
|
|
|
167
|
-
function renderConceptPage(concept) {
|
|
168
|
-
|
|
169
|
-
|
|
389
|
+
function renderConceptPage(concept, generatedAt) {
|
|
390
|
+
const title = recordTitle(concept, "Concept");
|
|
391
|
+
const relatedCount = asArray(concept.related_entity_details).length || asArray(concept.related_entities).length;
|
|
392
|
+
const sourceCount = sourceRefsFor(concept).length;
|
|
393
|
+
const summary = concept.definition
|
|
394
|
+
|| `Local sources contain ${relatedCount} tool candidate(s) and ${sourceCount} source reference(s) related to ${title}.`;
|
|
395
|
+
const body = [
|
|
396
|
+
`# ${title}`,
|
|
397
|
+
"",
|
|
398
|
+
"## Summary",
|
|
399
|
+
"",
|
|
400
|
+
summary,
|
|
401
|
+
"",
|
|
402
|
+
"## Key Axes",
|
|
403
|
+
"",
|
|
404
|
+
conceptAxisList(concept),
|
|
405
|
+
"",
|
|
406
|
+
"## Implementations / Examples",
|
|
170
407
|
"",
|
|
171
|
-
|
|
408
|
+
conceptImplementationList(concept),
|
|
172
409
|
"",
|
|
173
|
-
|
|
410
|
+
"## Patterns",
|
|
411
|
+
"",
|
|
412
|
+
conceptPatternList(concept),
|
|
413
|
+
"",
|
|
414
|
+
"## Recommendations / Caveats",
|
|
415
|
+
"",
|
|
416
|
+
"- Treat this concept page as local-evidence synthesis, not external verification.",
|
|
417
|
+
"- Prioritize examples with multiple source references or stronger extraction confidence.",
|
|
418
|
+
"- Review source-quality warnings before making architecture or tool adoption decisions.",
|
|
419
|
+
"",
|
|
420
|
+
"## Open Questions",
|
|
421
|
+
"",
|
|
422
|
+
"- Which extracted implementation is mature enough for real project adoption?",
|
|
423
|
+
"- Are the local topic labels accurate after human review?",
|
|
424
|
+
"- Should this concept be split, merged, or promoted after comparison/synthesis enrichment?",
|
|
174
425
|
"",
|
|
175
426
|
"## Aliases",
|
|
176
427
|
"",
|
|
177
428
|
mdList(concept.aliases),
|
|
178
429
|
"",
|
|
179
|
-
"## Related
|
|
430
|
+
"## Related Pages",
|
|
180
431
|
"",
|
|
181
|
-
|
|
432
|
+
conceptRelatedPagesList(concept),
|
|
182
433
|
"",
|
|
183
|
-
"##
|
|
434
|
+
"## Source References",
|
|
184
435
|
"",
|
|
185
436
|
mdList(sourceRefsFor(concept)),
|
|
186
437
|
"",
|
|
438
|
+
"## Provenance",
|
|
439
|
+
"",
|
|
440
|
+
mdList(provenanceRefsFor(concept)),
|
|
441
|
+
"",
|
|
187
442
|
].join("\n");
|
|
443
|
+
return withPersonalBrainFrontmatter({
|
|
444
|
+
id: concept.concept_id,
|
|
445
|
+
title,
|
|
446
|
+
type: "concept",
|
|
447
|
+
created_at: generatedAt,
|
|
448
|
+
updated_at: generatedAt,
|
|
449
|
+
aliases: concept.aliases,
|
|
450
|
+
tags: ["concept"],
|
|
451
|
+
related_pages: asArray(concept.related_entity_details).map((entity) => entity.target_page_path ? `../${relativePersonalBrainLink(entity.target_page_path)}` : null).filter(Boolean).slice(0, 12),
|
|
452
|
+
source_refs: sourceRefsFor(concept),
|
|
453
|
+
confidence: concept.confidence_tier || concept.confidence || "medium",
|
|
454
|
+
review_status: "ready_for_review",
|
|
455
|
+
}, body);
|
|
188
456
|
}
|
|
189
457
|
|
|
190
|
-
function renderComparisonPage(comparison) {
|
|
191
|
-
|
|
192
|
-
|
|
458
|
+
function renderComparisonPage(comparison, generatedAt) {
|
|
459
|
+
const title = recordTitle(comparison, "Comparison");
|
|
460
|
+
const body = [
|
|
461
|
+
`# ${title}`,
|
|
462
|
+
"",
|
|
463
|
+
"## Summary",
|
|
464
|
+
"",
|
|
465
|
+
comparison.summary || `Local comparison for ${comparison.topic || comparison.comparison_id}.`,
|
|
466
|
+
"",
|
|
467
|
+
"## Decision Axes",
|
|
468
|
+
"",
|
|
469
|
+
conceptAxisList({ key_axes: comparison.decision_axes }),
|
|
470
|
+
"",
|
|
471
|
+
"## Comparison Matrix",
|
|
472
|
+
"",
|
|
473
|
+
comparisonMatrix(comparison),
|
|
474
|
+
"",
|
|
475
|
+
"## Candidate Tools / Repos",
|
|
476
|
+
"",
|
|
477
|
+
candidateToolList(comparison.matrix_rows),
|
|
478
|
+
"",
|
|
479
|
+
"## Recommendations",
|
|
193
480
|
"",
|
|
194
|
-
|
|
481
|
+
mdList(comparison.recommendations),
|
|
195
482
|
"",
|
|
196
|
-
|
|
483
|
+
"## Caveats",
|
|
197
484
|
"",
|
|
198
|
-
|
|
485
|
+
mdList(comparison.caveats),
|
|
199
486
|
"",
|
|
200
|
-
|
|
487
|
+
"## Source Confidence",
|
|
201
488
|
"",
|
|
202
|
-
|
|
489
|
+
confidenceSummaryList(comparison.source_confidence_summary),
|
|
490
|
+
"",
|
|
491
|
+
"## Open Questions",
|
|
492
|
+
"",
|
|
493
|
+
"- Which candidate should be verified first with external source checks?",
|
|
494
|
+
"- Which criteria matter most for the target SDTK use case?",
|
|
495
|
+
"- Are any candidates duplicates, abandoned, or misclassified in the local source set?",
|
|
496
|
+
"",
|
|
497
|
+
"## Source References",
|
|
203
498
|
"",
|
|
204
499
|
mdList(sourceRefsFor(comparison)),
|
|
205
500
|
"",
|
|
501
|
+
"## Provenance",
|
|
502
|
+
"",
|
|
503
|
+
mdList(provenanceRefsFor(comparison)),
|
|
504
|
+
"",
|
|
206
505
|
].join("\n");
|
|
506
|
+
return withPersonalBrainFrontmatter({
|
|
507
|
+
id: comparison.comparison_id,
|
|
508
|
+
title,
|
|
509
|
+
type: "comparison",
|
|
510
|
+
created_at: generatedAt,
|
|
511
|
+
updated_at: generatedAt,
|
|
512
|
+
aliases: [comparison.topic].filter(Boolean),
|
|
513
|
+
tags: ["comparison"],
|
|
514
|
+
related_pages: asArray(comparison.compared_entity_details).map((entity) => entity.target_page_path ? `../${relativePersonalBrainLink(entity.target_page_path)}` : null).filter(Boolean).slice(0, 12),
|
|
515
|
+
source_refs: sourceRefsFor(comparison),
|
|
516
|
+
confidence: comparison.confidence_tier || comparison.confidence || "medium",
|
|
517
|
+
review_status: "needs_review",
|
|
518
|
+
}, body);
|
|
207
519
|
}
|
|
208
520
|
|
|
209
|
-
function renderSynthesisPage(synthesis) {
|
|
210
|
-
|
|
211
|
-
|
|
521
|
+
function renderSynthesisPage(synthesis, generatedAt) {
|
|
522
|
+
const title = recordTitle(synthesis, "Synthesis");
|
|
523
|
+
const body = [
|
|
524
|
+
`# ${title}`,
|
|
212
525
|
"",
|
|
213
526
|
"## Summary",
|
|
214
527
|
"",
|
|
215
528
|
synthesis.summary || `Generated synthesis page for ${synthesis.topic || synthesis.synthesis_id}.`,
|
|
216
529
|
"",
|
|
217
|
-
"##
|
|
530
|
+
"## Landscape Snapshot",
|
|
531
|
+
"",
|
|
532
|
+
candidateToolList(synthesis.candidate_tools),
|
|
533
|
+
"",
|
|
534
|
+
"## Key Patterns",
|
|
535
|
+
"",
|
|
536
|
+
conceptPatternList({ patterns: synthesis.patterns }),
|
|
537
|
+
"",
|
|
538
|
+
"## Decision Axes",
|
|
539
|
+
"",
|
|
540
|
+
conceptAxisList({ key_axes: synthesis.landscape_axes }),
|
|
541
|
+
"",
|
|
542
|
+
"## Recommended Review Path",
|
|
218
543
|
"",
|
|
219
544
|
mdList(synthesis.recommendations),
|
|
220
545
|
"",
|
|
221
|
-
"##
|
|
546
|
+
"## Caveats",
|
|
547
|
+
"",
|
|
548
|
+
mdList(synthesis.caveats),
|
|
549
|
+
"",
|
|
550
|
+
"## Source Confidence",
|
|
551
|
+
"",
|
|
552
|
+
confidenceSummaryList(synthesis.source_confidence_summary),
|
|
553
|
+
"",
|
|
554
|
+
"## Related Comparisons",
|
|
555
|
+
"",
|
|
556
|
+
synthesis.related_comparison_path ? mdList([`../${relativePersonalBrainLink(synthesis.related_comparison_path)}`]) : "- None recorded.",
|
|
557
|
+
"",
|
|
558
|
+
"## Open Questions",
|
|
559
|
+
"",
|
|
560
|
+
"- Which comparison criteria should become product acceptance gates?",
|
|
561
|
+
"- Which local candidates need external verification before adoption?",
|
|
562
|
+
"- Does this cluster need a dedicated deeper synthesis pass?",
|
|
563
|
+
"",
|
|
564
|
+
"## Source References",
|
|
222
565
|
"",
|
|
223
566
|
mdList(sourceRefsFor(synthesis)),
|
|
224
567
|
"",
|
|
568
|
+
"## Provenance",
|
|
569
|
+
"",
|
|
570
|
+
mdList(provenanceRefsFor(synthesis)),
|
|
571
|
+
"",
|
|
225
572
|
].join("\n");
|
|
573
|
+
return withPersonalBrainFrontmatter({
|
|
574
|
+
id: synthesis.synthesis_id,
|
|
575
|
+
title,
|
|
576
|
+
type: "synthesis",
|
|
577
|
+
created_at: generatedAt,
|
|
578
|
+
updated_at: generatedAt,
|
|
579
|
+
aliases: [synthesis.topic].filter(Boolean),
|
|
580
|
+
tags: ["synthesis"],
|
|
581
|
+
related_pages: synthesis.related_comparison_path ? [`../${relativePersonalBrainLink(synthesis.related_comparison_path)}`] : [],
|
|
582
|
+
source_refs: sourceRefsFor(synthesis),
|
|
583
|
+
confidence: synthesis.confidence_tier || synthesis.confidence || "medium",
|
|
584
|
+
review_status: "needs_review",
|
|
585
|
+
}, body);
|
|
226
586
|
}
|
|
227
587
|
|
|
228
588
|
function renderRootPage(name, payload) {
|
|
@@ -235,8 +595,9 @@ function renderRootPage(name, payload) {
|
|
|
235
595
|
graph: "Personal Brain Graph",
|
|
236
596
|
log: "Personal Brain Generation Log",
|
|
237
597
|
};
|
|
238
|
-
|
|
239
|
-
|
|
598
|
+
const title = titles[name] || "Personal Brain";
|
|
599
|
+
const body = [
|
|
600
|
+
`# ${title}`,
|
|
240
601
|
"",
|
|
241
602
|
"## Generation Context",
|
|
242
603
|
"",
|
|
@@ -257,10 +618,22 @@ function renderRootPage(name, payload) {
|
|
|
257
618
|
"- maintenance/",
|
|
258
619
|
"",
|
|
259
620
|
].join("\n");
|
|
621
|
+
return withPersonalBrainFrontmatter({
|
|
622
|
+
id: `personal_brain_${name}`,
|
|
623
|
+
title,
|
|
624
|
+
type: "root",
|
|
625
|
+
created_at: payload.generated_at || "",
|
|
626
|
+
updated_at: payload.generated_at || "",
|
|
627
|
+
aliases: [name],
|
|
628
|
+
tags: ["personal-brain", name],
|
|
629
|
+
source_refs: asArray(payload.sources).map((source) => source.source_id).filter(Boolean).slice(0, 50),
|
|
630
|
+
confidence: "medium",
|
|
631
|
+
review_status: "needs_review",
|
|
632
|
+
}, body);
|
|
260
633
|
}
|
|
261
634
|
|
|
262
635
|
function renderMaintenancePage(payload) {
|
|
263
|
-
|
|
636
|
+
const body = [
|
|
264
637
|
"# Extraction Quality Review",
|
|
265
638
|
"",
|
|
266
639
|
"## Source Quality Findings",
|
|
@@ -272,6 +645,18 @@ function renderMaintenancePage(payload) {
|
|
|
272
645
|
mdList(asArray(payload.unsupported_items).map((item) => `${item.item_id || "unsupported"}: ${item.reason || item.raw_observation_summary || "review required"}`)),
|
|
273
646
|
"",
|
|
274
647
|
].join("\n");
|
|
648
|
+
return withPersonalBrainFrontmatter({
|
|
649
|
+
id: "maintenance_extraction_quality_review",
|
|
650
|
+
title: "Extraction Quality Review",
|
|
651
|
+
type: "maintenance",
|
|
652
|
+
created_at: payload.generated_at || "",
|
|
653
|
+
updated_at: payload.generated_at || "",
|
|
654
|
+
aliases: ["source quality", "extraction quality"],
|
|
655
|
+
tags: ["maintenance", "quality"],
|
|
656
|
+
source_refs: asArray(payload.sources).map((source) => source.source_id).filter(Boolean).slice(0, 50),
|
|
657
|
+
confidence: asArray(payload.unsupported_items).length > 0 ? "low" : "medium",
|
|
658
|
+
review_status: "needs_review",
|
|
659
|
+
}, body);
|
|
275
660
|
}
|
|
276
661
|
|
|
277
662
|
function pushCreatePageOperation(operations, raw) {
|
|
@@ -308,7 +693,7 @@ function operationsFromSemanticExtraction(payload) {
|
|
|
308
693
|
source_id: source.source_id,
|
|
309
694
|
source_hash: source.source_hash,
|
|
310
695
|
target_page_path: source.target_page_path,
|
|
311
|
-
content: renderSourcePage(source),
|
|
696
|
+
content: renderSourcePage(source, payload.generated_at),
|
|
312
697
|
proposed_content_summary: `Create personal-brain source page for ${source.source_logical_path || source.source_relative_path || source.source_id}.`,
|
|
313
698
|
source_refs: sourceRefsFor(source),
|
|
314
699
|
provenance_refs: provenanceRefsFor(source),
|
|
@@ -325,7 +710,7 @@ function operationsFromSemanticExtraction(payload) {
|
|
|
325
710
|
source_id: sourceId,
|
|
326
711
|
source_hash: sourceHashFor(sourceById, sourceId),
|
|
327
712
|
target_page_path: entity.target_page_path,
|
|
328
|
-
content: renderToolEntityPage(entity),
|
|
713
|
+
content: renderToolEntityPage(entity, payload.generated_at),
|
|
329
714
|
proposed_content_summary: `Create tool entity page for ${entity.name || entity.entity_id}.`,
|
|
330
715
|
source_refs: sourceRefsFor(entity),
|
|
331
716
|
provenance_refs: provenanceRefsFor(entity),
|
|
@@ -361,7 +746,7 @@ function operationsFromSemanticExtraction(payload) {
|
|
|
361
746
|
source_id: sourceId,
|
|
362
747
|
source_hash: sourceHashFor(sourceById, sourceId),
|
|
363
748
|
target_page_path: concept.target_page_path,
|
|
364
|
-
content: renderConceptPage(concept),
|
|
749
|
+
content: renderConceptPage(concept, payload.generated_at),
|
|
365
750
|
proposed_content_summary: `Create concept page for ${concept.name || concept.concept_id}.`,
|
|
366
751
|
source_refs: sourceRefsFor(concept),
|
|
367
752
|
provenance_refs: provenanceRefsFor(concept),
|
|
@@ -378,7 +763,7 @@ function operationsFromSemanticExtraction(payload) {
|
|
|
378
763
|
source_id: sourceId,
|
|
379
764
|
source_hash: sourceHashFor(sourceById, sourceId),
|
|
380
765
|
target_page_path: comparison.target_page_path,
|
|
381
|
-
content: renderComparisonPage(comparison),
|
|
766
|
+
content: renderComparisonPage(comparison, payload.generated_at),
|
|
382
767
|
proposed_content_summary: `Create comparison page for ${comparison.topic || comparison.comparison_id}.`,
|
|
383
768
|
source_refs: sourceRefsFor(comparison),
|
|
384
769
|
provenance_refs: provenanceRefsFor(comparison),
|
|
@@ -395,7 +780,7 @@ function operationsFromSemanticExtraction(payload) {
|
|
|
395
780
|
source_id: sourceId,
|
|
396
781
|
source_hash: sourceHashFor(sourceById, sourceId),
|
|
397
782
|
target_page_path: synthesis.target_page_path,
|
|
398
|
-
content: renderSynthesisPage(synthesis),
|
|
783
|
+
content: renderSynthesisPage(synthesis, payload.generated_at),
|
|
399
784
|
proposed_content_summary: `Create synthesis page for ${synthesis.topic || synthesis.synthesis_id}.`,
|
|
400
785
|
source_refs: sourceRefsFor(synthesis),
|
|
401
786
|
provenance_refs: provenanceRefsFor(synthesis),
|