lumina-wiki 1.6.2 → 1.7.1
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/CHANGELOG.md +51 -0
- package/README.md +2 -1
- package/README.vi.md +2 -1
- package/README.zh.md +2 -1
- package/package.json +3 -1
- package/src/installer/commands.js +6 -1
- package/src/scripts/schemas.mjs +7 -0
- package/src/scripts/wiki.mjs +25 -20
- package/src/skills/core/ask/SKILL.md +13 -2
- package/src/skills/core/check/SKILL.md +11 -7
- package/src/skills/core/check/references/lint-checks.md +21 -5
- package/src/skills/core/edit/SKILL.md +5 -1
- package/src/skills/core/ingest/SKILL.md +1 -1
- package/src/skills/core/ingest/references/step-01-draft.md +16 -1
- package/src/skills/core/ingest/references/step-04-finalize.md +1 -1
- package/src/skills/core/init/SKILL.md +7 -0
- package/src/skills/core/migrate-legacy/SKILL.md +24 -9
- package/src/skills/core/reset/SKILL.md +58 -25
- package/src/skills/core/verify/SKILL.md +1 -0
- package/src/skills/packs/learning/reflect/SKILL.md +1 -1
- package/src/skills/packs/reading/chapter-ingest/SKILL.md +2 -2
- package/src/skills/packs/reading/character-track/SKILL.md +2 -2
- package/src/skills/packs/reading/theme-map/SKILL.md +2 -2
- package/src/skills/packs/research/prefill/SKILL.md +6 -2
- package/src/skills/packs/research/rank/SKILL.md +170 -0
- package/src/skills/packs/research/rank/references/4c-rubric.md +62 -0
- package/src/skills/packs/research/rank/references/three-pass.md +40 -0
- package/src/skills/packs/research/survey/SKILL.md +125 -15
- package/src/skills/packs/research/topic/SKILL.md +20 -17
- package/src/skills/packs/research/watch-run/SKILL.md +18 -11
- package/src/skills/packs/research/watchlist/SKILL.md +11 -8
- package/src/templates/.env.example +8 -0
- package/src/templates/README.md +2 -1
- package/src/templates/README.vi.md +2 -1
- package/src/templates/README.zh.md +2 -1
- package/src/templates/_lumina/schema/lumi-help.csv +1 -0
- package/src/templates/_lumina/schema/page-templates.md +23 -0
- package/src/tools/fetch_altmetric.py +229 -0
- package/src/tools/fetch_scite.py +236 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,57 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [1.7.1] - 2026-07-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `wiki.mjs init --pack learning` now creates `wiki/reflections/`, matching the
|
|
13
|
+
learning pack's entity schema. Valid `--pack` values are derived from the
|
|
14
|
+
schema instead of hardcoded, so future packs stay in sync automatically.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- `/lumi-research-topic` previously failed every `add-edge` call with "Unknown
|
|
19
|
+
edge type" because the topic-organization edges it relies on
|
|
20
|
+
(`includes_source`/`included_in_topic`, `covers_concept`/`covered_by_topic`)
|
|
21
|
+
were missing from the schema. Added all four to `EDGE_TYPES`.
|
|
22
|
+
- Corrected skill-prompt and documentation drift: the reset skill's dry-run
|
|
23
|
+
output format, the internal lint-check reference table (was missing
|
|
24
|
+
L10-L12), and the documented behavior of ingest phase checkpoints (keyed
|
|
25
|
+
by file basename, not slug, since the checkpoint exists before slug
|
|
26
|
+
generation; the checkpoint JSON's `slug` field, written once the slug
|
|
27
|
+
phase completes, is now documented as the way other skills match a
|
|
28
|
+
checkpoint to its wiki entry).
|
|
29
|
+
|
|
30
|
+
## [1.7.0] - 2026-06-16
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **Advanced paper ranking** via the new research-pack skill
|
|
35
|
+
`/lumi-research-rank`. It scores an already-ingested paper and records the
|
|
36
|
+
results on its source page, both as a machine-readable `ranking:` frontmatter
|
|
37
|
+
block and a human-readable `## Ranking` scorecard. Re-running refreshes the
|
|
38
|
+
ranking and preserves any notes inside `<!-- user-edited -->` markers.
|
|
39
|
+
- **Citation influence signal**: surfaces Semantic Scholar's influential-citation
|
|
40
|
+
count alongside the raw citation count (reuses the existing `fetch_s2.py`; no
|
|
41
|
+
new key required).
|
|
42
|
+
- **4C qualitative rubric** (Correctness, Clarity, Contribution, Context, each
|
|
43
|
+
scored 1-5) produced with a three-pass reading method to keep the assessment
|
|
44
|
+
efficient. Scores are explicitly recorded as LLM-assessed with a timestamp.
|
|
45
|
+
- **Venue prestige** recorded from the agent's own knowledge and explicitly
|
|
46
|
+
flagged as an estimate (`venue_source: llm-estimated`) — no live API or
|
|
47
|
+
bundled dataset.
|
|
48
|
+
- **Optional, key-gated influence fetchers** `fetch_scite.py` (Scite.ai Smart
|
|
49
|
+
Citation tallies) and `fetch_altmetric.py` (Altmetric attention score). Both
|
|
50
|
+
degrade gracefully: with no key set they exit with a clear message and the
|
|
51
|
+
skill simply skips that signal. New `.env` keys `SCITE_API_KEY` and
|
|
52
|
+
`ALTMETRIC_API_KEY`.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Source page schema gains an optional `ranking` frontmatter object (no change
|
|
57
|
+
required for existing un-ranked pages).
|
|
58
|
+
|
|
8
59
|
## [1.6.2] - 2026-06-15
|
|
9
60
|
|
|
10
61
|
### Fixed
|
package/README.md
CHANGED
|
@@ -185,6 +185,7 @@ These are the commands you can use when chatting with your AI agent.
|
|
|
185
185
|
| | `/lumi-research-survey` | Create a survey or summary from existing knowledge. |
|
|
186
186
|
| | `/lumi-research-prefill` | Seed foundational concepts to avoid duplicates. |
|
|
187
187
|
| | `/lumi-research-topic` | Create a topic page at `wiki/topics/<slug>.md` by gathering related concepts and sources already in your wiki. The AI proposes what to include and you confirm before anything is written. Use this after several `/lumi-ingest` runs when you want to give a theme its own page. |
|
|
188
|
+
| | `/lumi-research-rank` | Score a paper you have already ingested so you know what to read first. It looks up how influential the paper is (citation signals), estimates how respected its venue is, and rates its quality on four points — Correctness, Clarity, Contribution, and Context — then adds a clear scorecard to the paper's page. Measured numbers and the AI's own estimates are always kept separate. |
|
|
188
189
|
| | `/lumi-research-setup` | Help configure API keys for research tools. |
|
|
189
190
|
| | `/lumi-research-watch-run` | Run one scheduled-discovery pass over your watchlist (topics + RSS / Atom feeds). Polls only when you ask. |
|
|
190
191
|
| **Reading** | `/lumi-reading-chapter-ingest` | Ingest a book chapter by chapter. |
|
|
@@ -209,7 +210,7 @@ Lumina-Wiki is evolving rapidly. Here is our user-facing roadmap:
|
|
|
209
210
|
- [x] **Improved CI/CD:** Native support for Bun and Node 22 environments. *(shipped in v1.2)*
|
|
210
211
|
- [x] **Global Source Expansion:** Direct integration with OpenAlex, CORE, and Unpaywall for reliable DOI-to-PDF resolution. *(shipped in v1.6)*
|
|
211
212
|
- [x] **RSS & Blog Monitoring:** Automatically surface new papers from your favorite lab blogs and journals via `type: feed` watchlist items. *(shipped in v1.6)*
|
|
212
|
-
- [
|
|
213
|
+
- [x] **Advanced Paper Ranking:** See influence scores and quality signals for your research papers via `/lumi-research-rank`. *(shipped in v1.7)*
|
|
213
214
|
|
|
214
215
|
**Long-term (Deep Research & Integration)**
|
|
215
216
|
- [ ] **Image OCR & Scanned PDFs:** Ingest screenshots and scanned PDFs into your wiki.
|
package/README.vi.md
CHANGED
|
@@ -185,6 +185,7 @@ Xem [Hướng dẫn Nâng cao](docs/user-guide/advanced-qmd.vi.md) để biết
|
|
|
185
185
|
| | `/lumi-research-survey` | Tạo một bài tổng quan/khảo sát từ kiến thức hiện có. |
|
|
186
186
|
| | `/lumi-research-prefill` | Tạo trước các khái niệm nền tảng để tránh trùng lặp. |
|
|
187
187
|
| | `/lumi-research-topic` | Gom các khái niệm và nguồn liên quan trong wiki thành một trang chủ đề tại `wiki/topics/<slug>.md`. AI đề xuất danh sách để bạn xem và xác nhận trước khi trang được tạo. Dùng sau khi đã nạp nhiều tài liệu và muốn tổng hợp một nhóm ý tưởng thành trang riêng. |
|
|
188
|
+
| | `/lumi-research-rank` | Chấm điểm một bài báo bạn đã nạp để biết nên đọc gì trước. Nó tra mức độ ảnh hưởng của bài (tín hiệu trích dẫn), ước lượng uy tín nơi công bố, và đánh giá chất lượng theo bốn tiêu chí — Tính đúng đắn, Sự rõ ràng, Đóng góp, và Bối cảnh — rồi thêm một bảng điểm rõ ràng vào trang của bài báo. Các con số đo được và ước lượng của AI luôn được tách bạch. |
|
|
188
189
|
| | `/lumi-research-setup` | Giúp cấu hình API key cho các công cụ nghiên cứu. |
|
|
189
190
|
| | `/lumi-research-watch-run` | Chạy một lượt khám phá theo lịch dựa trên watchlist (chủ đề + nguồn RSS / Atom). Chỉ chạy khi bạn yêu cầu. |
|
|
190
191
|
| **Reading** | `/lumi-reading-chapter-ingest`| Nạp kiến thức sách theo từng chương. |
|
|
@@ -209,7 +210,7 @@ Lumina-Wiki đang phát triển nhanh chóng. Dưới đây là lộ trình hư
|
|
|
209
210
|
- [x] **Cải thiện CI/CD:** Hỗ trợ chính thức cho môi trường Bun và Node 22. *(đã phát hành trong v1.2)*
|
|
210
211
|
- [x] **Mở rộng nguồn dữ liệu toàn cầu:** Tích hợp trực tiếp với OpenAlex, CORE và Unpaywall để tra cứu DOI-to-PDF đáng tin cậy. *(ra mắt trong v1.6)*
|
|
211
212
|
- [x] **Theo dõi RSS & Blog:** Tự động phát hiện bài báo mới từ các blog phòng thí nghiệm và tạp chí yêu thích qua các mục `type: feed` trong watchlist. *(ra mắt trong v1.6)*
|
|
212
|
-
- [
|
|
213
|
+
- [x] **Xếp hạng bài báo nâng cao:** Xem điểm số ảnh hưởng và tín hiệu chất lượng cho các nghiên cứu của bạn qua `/lumi-research-rank`. *(ra mắt ở v1.7)*
|
|
213
214
|
|
|
214
215
|
**Dài hạn (Nghiên cứu sâu & Tích hợp)**
|
|
215
216
|
- [ ] **OCR ảnh & PDF scan:** Nạp ảnh chụp màn hình và PDF dạng scan vào wiki.
|
package/README.zh.md
CHANGED
|
@@ -186,6 +186,7 @@ npx skills add https://github.com/tobi/qmd --skill qmd
|
|
|
186
186
|
| | `/lumi-research-survey` | 从现有知识创建综述/调研。 |
|
|
187
187
|
| | `/lumi-research-prefill` | 预先生成基础概念,避免重复。 |
|
|
188
188
|
| | `/lumi-research-topic` | 把 wiki 中已有的相关概念和来源汇聚成一个主题页,保存在 `wiki/topics/<slug>.md`。AI 会提议收录哪些内容,由你确认后再生成页面。多次 `/lumi-ingest` 之后,用它把一组相关想法整理成独立的主题页。 |
|
|
189
|
+
| | `/lumi-research-rank` | 给已经纳入的论文打分,帮你决定先读哪一篇。它会查询论文的影响力(引用信号)、估计发表场所的声望,并从四个方面评估质量——正确性、清晰度、贡献、背景——然后在论文页面上加上一份清晰的评分卡。实测数据与 AI 的估计始终分开标注。 |
|
|
189
190
|
| | `/lumi-research-setup` | 帮助配置研究工具的 API key。 |
|
|
190
191
|
| | `/lumi-research-watch-run` | 基于 watchlist 运行一次计划式发现(主题 + RSS / Atom 源)。仅在你要求时才运行。 |
|
|
191
192
|
| **Reading** | `/lumi-reading-chapter-ingest`| 按章节导入书籍知识。 |
|
|
@@ -210,7 +211,7 @@ Lumina-Wiki 正在快速演进。这是我们的用户路线图:
|
|
|
210
211
|
- [x] **改进的 CI/CD:** 正式支持 Bun 和 Node 22 环境。*(v1.2 已发布)*
|
|
211
212
|
- [x] **全球数据源扩展:** 直接集成 OpenAlex、CORE 和 Unpaywall,实现可靠的 DOI-to-PDF 解析。*(在 v1.6 中发布)*
|
|
212
213
|
- [x] **RSS 与博客监控:** 通过 watchlist 中的 `type: feed` 项,自动从您喜爱的实验室博客和期刊中发现新论文。*(在 v1.6 中发布)*
|
|
213
|
-
- [
|
|
214
|
+
- [x] **高级论文排名:** 通过 `/lumi-research-rank` 查看研究论文的影响力评分和质量信号。*(在 v1.7 中发布)*
|
|
214
215
|
|
|
215
216
|
**长期计划(深度研究与集成)**
|
|
216
217
|
- [ ] **图片 OCR 与扫描 PDF:** 将截图与扫描版 PDF 导入维基。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "lumina-wiki",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.1",
|
|
5
5
|
"description": "Domain-agnostic, multi-IDE wiki scaffolder — Karpathy's LLM-Wiki vision, cross-platform and pack-based.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"llm-wiki",
|
|
@@ -69,6 +69,8 @@
|
|
|
69
69
|
"src/tools/fetch_core.py",
|
|
70
70
|
"src/tools/resolve_pdf.py",
|
|
71
71
|
"src/tools/fetch_rss.py",
|
|
72
|
+
"src/tools/fetch_scite.py",
|
|
73
|
+
"src/tools/fetch_altmetric.py",
|
|
72
74
|
"src/tools/id_utils.py",
|
|
73
75
|
"src/tools/requirements.txt",
|
|
74
76
|
"CHANGELOG.md",
|
|
@@ -131,7 +131,7 @@ const RESEARCH_TOOL_FILES = [
|
|
|
131
131
|
'_env.py', '_cache.py', 'discover.py', 'init_discovery.py', 'prepare_source.py',
|
|
132
132
|
'fetch_arxiv.py', 'fetch_wikipedia.py', 'fetch_s2.py', 'fetch_deepxiv.py',
|
|
133
133
|
'fetch_openalex.py', 'fetch_unpaywall.py', 'fetch_core.py', 'resolve_pdf.py',
|
|
134
|
-
'fetch_rss.py',
|
|
134
|
+
'fetch_rss.py', 'fetch_scite.py', 'fetch_altmetric.py',
|
|
135
135
|
];
|
|
136
136
|
|
|
137
137
|
async function findEnclosingWorkspace(startDir) {
|
|
@@ -1234,6 +1234,7 @@ function getSkillDefs(packs) {
|
|
|
1234
1234
|
{ name: 'prefill', canonicalId: 'lumi-research-prefill', displayName: '/lumi-research-prefill' },
|
|
1235
1235
|
{ name: 'setup', canonicalId: 'lumi-research-setup', displayName: '/lumi-research-setup' },
|
|
1236
1236
|
{ name: 'topic', canonicalId: 'lumi-research-topic', displayName: '/lumi-research-topic' },
|
|
1237
|
+
{ name: 'rank', canonicalId: 'lumi-research-rank', displayName: '/lumi-research-rank' },
|
|
1237
1238
|
{ name: 'watchlist', canonicalId: 'lumi-research-watchlist', displayName: '/lumi-research-watchlist' },
|
|
1238
1239
|
{ name: 'watch-run', canonicalId: 'lumi-research-watch-run', displayName: '/lumi-research-watch-run' },
|
|
1239
1240
|
];
|
|
@@ -1322,6 +1323,10 @@ async function renderEnvExample(projectRoot) {
|
|
|
1322
1323
|
`OPENALEX_API_KEY=\n\n` +
|
|
1323
1324
|
`# DeepXiv token (optional; enables full-text PDF access)\n` +
|
|
1324
1325
|
`DEEPXIV_TOKEN=\n\n` +
|
|
1326
|
+
`# Scite.ai API key (optional; enables Smart Citation tallies in /lumi-research-rank)\n` +
|
|
1327
|
+
`SCITE_API_KEY=\n\n` +
|
|
1328
|
+
`# Altmetric API key (optional; enables attention scores in /lumi-research-rank)\n` +
|
|
1329
|
+
`ALTMETRIC_API_KEY=\n\n` +
|
|
1325
1330
|
`# arXiv does not require an API key in v0.1\n`;
|
|
1326
1331
|
}
|
|
1327
1332
|
await atomicWrite(destPath, content);
|
package/src/scripts/schemas.mjs
CHANGED
|
@@ -215,6 +215,12 @@ export const EDGE_TYPES = [
|
|
|
215
215
|
{ name: 'part_of', from: 'concepts', to: 'concepts', reverse: 'has_part', symmetric: false, pack: 'core' },
|
|
216
216
|
{ name: 'has_part', from: 'concepts', to: 'concepts', reverse: 'part_of', symmetric: false, pack: 'core' },
|
|
217
217
|
|
|
218
|
+
// --- research pack: topic organization edges -----------------------------
|
|
219
|
+
{ name: 'includes_source', from: 'topics', to: 'sources', reverse: 'included_in_topic', symmetric: false, pack: 'research' },
|
|
220
|
+
{ name: 'included_in_topic', from: 'sources', to: 'topics', reverse: 'includes_source', symmetric: false, pack: 'research' },
|
|
221
|
+
{ name: 'covers_concept', from: 'topics', to: 'concepts', reverse: 'covered_by_topic', symmetric: false, pack: 'research' },
|
|
222
|
+
{ name: 'covered_by_topic', from: 'concepts', to: 'topics', reverse: 'covers_concept', symmetric: false, pack: 'research' },
|
|
223
|
+
|
|
218
224
|
// --- terminal edges (no reverse) — exempt-only rule applies -------------
|
|
219
225
|
// Any entity -> foundations/** (research pack)
|
|
220
226
|
{ name: 'grounded_in', from: '*', to: 'foundations', reverse: null, terminal: true, pack: 'research' },
|
|
@@ -283,6 +289,7 @@ export const REQUIRED_FRONTMATTER = {
|
|
|
283
289
|
{ key: 'findings', type: 'array', required: false },
|
|
284
290
|
{ key: 'external_ids', type: 'object', required: false },
|
|
285
291
|
{ key: 'sources', type: 'array', required: false },
|
|
292
|
+
{ key: 'ranking', type: 'object', required: false },
|
|
286
293
|
],
|
|
287
294
|
|
|
288
295
|
// Concept page
|
package/src/scripts/wiki.mjs
CHANGED
|
@@ -1179,26 +1179,33 @@ const CORE_WIKI_DIRS = [
|
|
|
1179
1179
|
'wiki/graph',
|
|
1180
1180
|
];
|
|
1181
1181
|
|
|
1182
|
-
/**
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
]
|
|
1182
|
+
/**
|
|
1183
|
+
* Installable (non-core) pack names, derived from ENTITY_DIRS so a new pack
|
|
1184
|
+
* added to schemas.mjs becomes selectable via `init --pack` without touching
|
|
1185
|
+
* this file.
|
|
1186
|
+
* @type {string[]}
|
|
1187
|
+
*/
|
|
1188
|
+
const INSTALLABLE_PACKS = [...new Set(Object.values(ENTITY_DIRS).map(e => e.pack))]
|
|
1189
|
+
.filter(pack => pack !== 'core');
|
|
1187
1190
|
|
|
1188
|
-
/**
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1191
|
+
/**
|
|
1192
|
+
* Additional wiki dirs owned by a given pack, derived from ENTITY_DIRS.
|
|
1193
|
+
* Preserves ENTITY_DIRS declaration order.
|
|
1194
|
+
* @param {string} pack
|
|
1195
|
+
* @returns {string[]}
|
|
1196
|
+
*/
|
|
1197
|
+
function wikiDirsForPack(pack) {
|
|
1198
|
+
return Object.values(ENTITY_DIRS)
|
|
1199
|
+
.filter(e => e.pack === pack)
|
|
1200
|
+
.map(e => `wiki/${e.dir}`.replace(/\/$/, ''));
|
|
1201
|
+
}
|
|
1195
1202
|
|
|
1196
1203
|
/**
|
|
1197
1204
|
* Initialize a workspace skeleton.
|
|
1198
1205
|
* Idempotent: re-running on an existing workspace is a no-op.
|
|
1199
1206
|
* @param {string} projectRoot
|
|
1200
1207
|
* @param {object} [opts]
|
|
1201
|
-
* @param {string} [opts.pack] -
|
|
1208
|
+
* @param {string} [opts.pack] - one of INSTALLABLE_PACKS | undefined
|
|
1202
1209
|
* @returns {Promise<{created: string[], skipped: string[]}>}
|
|
1203
1210
|
*/
|
|
1204
1211
|
async function initWorkspace(projectRoot, opts = {}) {
|
|
@@ -1206,10 +1213,8 @@ async function initWorkspace(projectRoot, opts = {}) {
|
|
|
1206
1213
|
const skipped = [];
|
|
1207
1214
|
|
|
1208
1215
|
let dirs = [...CORE_WIKI_DIRS];
|
|
1209
|
-
if (opts.pack
|
|
1210
|
-
dirs = [...dirs, ...
|
|
1211
|
-
} else if (opts.pack === 'reading') {
|
|
1212
|
-
dirs = [...dirs, ...READING_WIKI_DIRS];
|
|
1216
|
+
if (opts.pack && INSTALLABLE_PACKS.includes(opts.pack)) {
|
|
1217
|
+
dirs = [...dirs, ...wikiDirsForPack(opts.pack)];
|
|
1213
1218
|
}
|
|
1214
1219
|
|
|
1215
1220
|
// Add _lumina/_state dir
|
|
@@ -1506,7 +1511,7 @@ async function main(argv) {
|
|
|
1506
1511
|
'Usage: node wiki.mjs <subcommand> [flags]',
|
|
1507
1512
|
'',
|
|
1508
1513
|
'Subcommands:',
|
|
1509
|
-
|
|
1514
|
+
` init [--pack ${INSTALLABLE_PACKS.join('|')}] Create workspace skeleton`,
|
|
1510
1515
|
' slug <title> Emit kebab-case slug',
|
|
1511
1516
|
' log <skill> <details...> Append to wiki/log.md',
|
|
1512
1517
|
' read-meta <slug> Read entity frontmatter as JSON',
|
|
@@ -1539,8 +1544,8 @@ async function main(argv) {
|
|
|
1539
1544
|
// init does not require an existing workspace; it creates one
|
|
1540
1545
|
const projectRoot = process.cwd();
|
|
1541
1546
|
const pack = flags.pack && typeof flags.pack === 'string' ? flags.pack : undefined;
|
|
1542
|
-
if (pack && pack
|
|
1543
|
-
emitError(`Invalid --pack value: ${pack}. Must be
|
|
1547
|
+
if (pack && !INSTALLABLE_PACKS.includes(pack)) {
|
|
1548
|
+
emitError(`Invalid --pack value: ${pack}. Must be one of: ${INSTALLABLE_PACKS.join(', ')}.`, 2);
|
|
1544
1549
|
process.exit(2);
|
|
1545
1550
|
}
|
|
1546
1551
|
const result = await initWorkspace(projectRoot, { pack });
|
|
@@ -127,6 +127,16 @@ Do not ingest the file yourself. The user decides whether to proceed.
|
|
|
127
127
|
|
|
128
128
|
If the user asks to save the answer:
|
|
129
129
|
|
|
130
|
+
First check whether the target page already exists:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
node _lumina/scripts/wiki.mjs read-meta outputs/<slug>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Exit 0 means the page exists. If it does, ask the user whether to overwrite
|
|
137
|
+
it or pick a new slug — do not silently overwrite. Exit 2 ("Entity not
|
|
138
|
+
found") means the slug is free; proceed.
|
|
139
|
+
|
|
130
140
|
Ask for confirmation before writing. Then write
|
|
131
141
|
`wiki/outputs/<slug>.md` or `wiki/summary/<slug>.md` with:
|
|
132
142
|
```yaml
|
|
@@ -232,5 +242,6 @@ Before reporting done, verify:
|
|
|
232
242
|
|
|
233
243
|
(a) Every cited page in the answer exists in `wiki/` (readable)
|
|
234
244
|
(b) If a page was filed: `wiki/log.md` has a new `## [YYYY-MM-DD] ask | ...` entry
|
|
235
|
-
(c) If a page was filed:
|
|
236
|
-
|
|
245
|
+
(c) If a page was filed: the Step 6 existence check (`read-meta outputs/<slug>`)
|
|
246
|
+
ran before writing, so running `/lumi-ask` again with the same question
|
|
247
|
+
does not silently create or overwrite a second output page
|
|
@@ -99,7 +99,9 @@ node _lumina/scripts/lint.mjs --fix --json
|
|
|
99
99
|
|
|
100
100
|
The `--fix` pass:
|
|
101
101
|
- Applies the supported auto-fixes listed in `references/lint-checks.md`
|
|
102
|
-
|
|
102
|
+
(L01, L03, L06, L07, L09)
|
|
103
|
+
- Leaves every other check (L02, L04, L05, L08, L10, L11, L12, L13, L14, L16)
|
|
104
|
+
for manual correction
|
|
103
105
|
|
|
104
106
|
### Step 4 — Self-check re-run
|
|
105
107
|
|
|
@@ -117,8 +119,10 @@ If errors remain, do not report done. Address each remaining error specifically:
|
|
|
117
119
|
```bash
|
|
118
120
|
node _lumina/scripts/wiki.mjs set-meta <slug> <key> "<value>"
|
|
119
121
|
```
|
|
120
|
-
- If L02, L05, or
|
|
121
|
-
need manual correction.
|
|
122
|
+
- If L02, L05, L08, or L10 remain, report the exact fields, wikilinks, edges,
|
|
123
|
+
or alias conflicts that need manual correction.
|
|
124
|
+
- If L13 or L16 persist, suggest `/lumi-migrate-legacy --backfill-ids` — these
|
|
125
|
+
are not fixed by `lint.mjs --fix`.
|
|
122
126
|
|
|
123
127
|
Repeat until `summary.errors === 0`. Do not loop more than 3 times — if errors
|
|
124
128
|
persist, surface them to the user as needing manual attention.
|
|
@@ -137,12 +141,12 @@ Present findings in a structured list. Group errors first, then warnings.
|
|
|
137
141
|
Lint check: <scanned_files> files scanned
|
|
138
142
|
|
|
139
143
|
Errors (N):
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
concepts/positional-encoding.md:18 — a return link is missing, pointing back to sources/attention-revisited (L06)
|
|
145
|
+
summary/transformers-overview.md:42 — a link points to a page that does not exist: [[flash-decoding]] (L05)
|
|
142
146
|
|
|
143
147
|
Warnings (M, advisory):
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
concepts/rotary-embeddings.md — this page has no inbound or outbound links yet (L04)
|
|
149
|
+
wiki/index.md — the page catalog is out of date (L09)
|
|
146
150
|
|
|
147
151
|
Fixes available: L06, L09 (N total). Apply? [yes/no]
|
|
148
152
|
```
|
|
@@ -14,8 +14,16 @@ output in `/lumi-check`.
|
|
|
14
14
|
| L05 | Broken wikilink | error | No — user must correct or create target |
|
|
15
15
|
| L06 | Missing reverse edge | error | Yes — writes the reverse edge |
|
|
16
16
|
| L07 | Duplicate symmetric edge | warning | Yes — deduplicates |
|
|
17
|
-
| L08 | Missing required confidence field | error | No — user must add confidence |
|
|
17
|
+
| L08 | Missing required confidence field on an edge | error | No — user must add confidence |
|
|
18
18
|
| L09 | Index out of sync | warning | Yes — rebuilds the index catalog |
|
|
19
|
+
| L10 | Foundation alias conflict | error | No — user must rename or merge the colliding title/alias |
|
|
20
|
+
| L11 | Missing `confidence` field on a source/concept page | warning | No — user must set a value |
|
|
21
|
+
| L12 | `raw_paths` entry missing, unsafe, or parked in `raw/tmp/` | warning | No — user must move or fix the file, then update `raw_paths` |
|
|
22
|
+
| L13 | `external_ids` missing a namespace derivable from `urls[]` | warning | No — run `/lumi-migrate-legacy --backfill-ids` |
|
|
23
|
+
| L14 | `external_ids` value fails validation for its namespace | error | No — user must correct or remove the value |
|
|
24
|
+
| L16 | `external_ids` value disagrees with the value derived from `urls[]` | warning | No — run `/lumi-migrate-legacy --backfill-ids` to reconcile |
|
|
25
|
+
|
|
26
|
+
(L15 is intentionally unassigned — reserved for a future collision check.)
|
|
19
27
|
|
|
20
28
|
## Classification
|
|
21
29
|
|
|
@@ -26,13 +34,19 @@ Errors that must be resolved before done:
|
|
|
26
34
|
- L03: non-kebab slugs
|
|
27
35
|
- L05: broken wikilinks
|
|
28
36
|
- L06: missing reverse edges
|
|
29
|
-
- L08: missing required confidence
|
|
37
|
+
- L08: missing required confidence field on an edge
|
|
38
|
+
- L10: foundation alias conflicts
|
|
39
|
+
- L14: invalid `external_ids` values
|
|
30
40
|
|
|
31
41
|
Advisories to surface to the user:
|
|
32
42
|
|
|
33
43
|
- L04: orphan pages
|
|
34
44
|
- L07: duplicate symmetric edges
|
|
35
45
|
- L09: index out of sync
|
|
46
|
+
- L11: missing `confidence` on a source/concept page
|
|
47
|
+
- L12: `raw_paths` missing, unsafe, or transient
|
|
48
|
+
- L13: `external_ids` missing a derivable namespace
|
|
49
|
+
- L16: `external_ids` disagrees with `urls[]`
|
|
36
50
|
|
|
37
51
|
## Fix Behavior
|
|
38
52
|
|
|
@@ -44,9 +58,11 @@ Advisories to surface to the user:
|
|
|
44
58
|
- L07 deduplicates symmetric edges.
|
|
45
59
|
- L09 regenerates the `<!-- lumina:index --> ... <!-- /lumina:index -->` block.
|
|
46
60
|
|
|
47
|
-
L02, L05,
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
L02, L04, L05, L08, L10, L11, L12, L13, L14, and L16 require manual
|
|
62
|
+
correction — none of them are touched by `--fix`. If L06 remains after
|
|
63
|
+
`--fix`, the target page may not exist; identify it and suggest
|
|
64
|
+
`/lumi-ingest` or `/lumi-edit`. For L13 and L16, the fix path is
|
|
65
|
+
`/lumi-migrate-legacy --backfill-ids`, not `lint.mjs --fix`.
|
|
50
66
|
|
|
51
67
|
The linter reads `_lumina/config/lumina.config.yaml` for exemption globs.
|
|
52
68
|
`foundations/**`, `outputs/**`, and external URL targets are exempt from L06.
|
|
@@ -123,6 +123,10 @@ manual follow-up.
|
|
|
123
123
|
node _lumina/scripts/wiki.mjs log edit "Updated <slug>: <brief description>"
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
After logging, suggest the user run `/lumi-check` in a fresh session or via a
|
|
127
|
+
sub-agent. Blank context catches bias from the reasoning chain that just made
|
|
128
|
+
this edit.
|
|
129
|
+
|
|
126
130
|
## Output Format
|
|
127
131
|
|
|
128
132
|
Report to the user:
|
|
@@ -135,7 +139,7 @@ Example:
|
|
|
135
139
|
Edited concepts/softmax-temperature.md:
|
|
136
140
|
- Added definition paragraph in ## Overview
|
|
137
141
|
- Linked back to sources/attention-revisited (used_in edge added)
|
|
138
|
-
|
|
142
|
+
Links check out — one advisory note: this page has no inbound links yet (L04)
|
|
139
143
|
```
|
|
140
144
|
|
|
141
145
|
## Examples
|
|
@@ -58,7 +58,7 @@ This is the only logic in this body — everything else lives in step files. The
|
|
|
58
58
|
| `drafted` | → `./references/step-02-lint.md` |
|
|
59
59
|
| `linted` | → `./references/step-03-verify.md` |
|
|
60
60
|
| `verified` | → `./references/step-04-finalize.md` |
|
|
61
|
-
| `finalized` | HALT, ask "this entry is already finalized; restart from scratch?" On `[Q]` (decline): exit cleanly, exit 0 — declining is not an error. On confirm, do these in order before re-entering step-01: (1) `set-meta sources/<slug> ingest_status drafted` (so a session crash mid-restart leaves the entry in a coherent stage, not a stale-finalized one), (2) delete the phase checkpoint at `_lumina/_state/ingest-<file-basename>.json
|
|
61
|
+
| `finalized` | HALT, ask "this entry is already finalized; restart from scratch?" On `[Q]` (decline): exit cleanly, exit 0 — declining is not an error. On confirm, do these in order before re-entering step-01: (1) `set-meta sources/<slug> ingest_status drafted` (so a session crash mid-restart leaves the entry in a coherent stage, not a stale-finalized one), (2) delete the phase checkpoint at `_lumina/_state/ingest-<file-basename>.json` — at this point you may only know the slug, not the file basename, so derive it first: read `raw_paths[0]` via `read-meta sources/<slug>` and take its basename; if `raw_paths` is empty or unavailable, list `_lumina/_state/ingest-*.json` and read each one to find the checkpoint whose `slug` field equals `sources/<slug>`; if no checkpoint matches either way, there is nothing to delete — simply proceed, (3) → `./references/step-01-draft.md`. |
|
|
62
62
|
|
|
63
63
|
## Examples
|
|
64
64
|
|
|
@@ -88,7 +88,22 @@ node _lumina/scripts/wiki.mjs slug "<Title>"
|
|
|
88
88
|
|
|
89
89
|
If `wiki/sources/<slug>.md` already exists: re-ingest — confirm with user before overwriting.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
The phase checkpoint is keyed by file basename (`ingest-<file-basename>.json`)
|
|
92
|
+
because it is written before the slug exists. Now that the slug is known,
|
|
93
|
+
merge it into the checkpoint so later skills (e.g. `/lumi-migrate-legacy`) can
|
|
94
|
+
match a checkpoint to a wiki entry by reading its content instead of guessing
|
|
95
|
+
the filename:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 1) Read current state
|
|
99
|
+
node _lumina/scripts/wiki.mjs checkpoint-read ingest <file-basename>
|
|
100
|
+
# 2) Merge {"phase":"slug","slug":"sources/<slug>","source_basename":"<file-basename>"}
|
|
101
|
+
# into the JSON above (preserve all other fields).
|
|
102
|
+
# 3) Write back via stdin:
|
|
103
|
+
echo '<merged-json>' | node _lumina/scripts/wiki.mjs checkpoint-write ingest <file-basename>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Write checkpoint: `phase: "slug"` (already included in the merge above).
|
|
92
107
|
|
|
93
108
|
### Phase 3 — Write source page
|
|
94
109
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- All frontmatter writes go through `wiki.mjs set-meta`.
|
|
6
6
|
- `wiki/log.md` is append-only. Use `wiki.mjs log` — never edit the file directly.
|
|
7
|
-
- The phase-level checkpoint at `_lumina/_state/ingest-<
|
|
7
|
+
- The phase-level checkpoint at `_lumina/_state/ingest-<file-basename>.json` ends here; mark it `phase: "done"`.
|
|
8
8
|
|
|
9
9
|
## Why this step exists
|
|
10
10
|
|
|
@@ -69,6 +69,11 @@ For reading pack (if installed):
|
|
|
69
69
|
node _lumina/scripts/wiki.mjs init --pack reading
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
For learning pack (if installed):
|
|
73
|
+
```bash
|
|
74
|
+
node _lumina/scripts/wiki.mjs init --pack learning
|
|
75
|
+
```
|
|
76
|
+
|
|
72
77
|
Each call returns `{ ok: true, created: [...], skipped: [...] }`. Report which
|
|
73
78
|
directories were newly created and which already existed.
|
|
74
79
|
|
|
@@ -168,6 +173,8 @@ node _lumina/scripts/lint.mjs --json
|
|
|
168
173
|
node _lumina/scripts/wiki.mjs log init "Wiki initialized. Packs: core, research. Created: 8 dirs."
|
|
169
174
|
```
|
|
170
175
|
Additional dirs created: `wiki/foundations/`, `wiki/topics/`, `raw/discovered/`
|
|
176
|
+
(research pack). The learning pack (`init --pack learning`) additionally
|
|
177
|
+
creates `wiki/reflections/`.
|
|
171
178
|
</example>
|
|
172
179
|
|
|
173
180
|
<example>
|
|
@@ -178,11 +178,22 @@ Use the following inference order. Stop at the first tier that yields a result.
|
|
|
178
178
|
|
|
179
179
|
**Tier 1 (authoritative): read the ingest checkpoint.**
|
|
180
180
|
|
|
181
|
+
Ingest checkpoints are keyed by the source file's basename
|
|
182
|
+
(`_lumina/_state/ingest-<file-basename>.json`), not by slug — there is no
|
|
183
|
+
direct `<slug>` lookup. List every ingest checkpoint and match by content:
|
|
184
|
+
|
|
181
185
|
```bash
|
|
182
|
-
|
|
186
|
+
ls _lumina/_state/ingest-*.json 2>/dev/null
|
|
183
187
|
```
|
|
184
188
|
|
|
185
|
-
|
|
189
|
+
Read each match with the Read tool and check its `slug` field. Newer ingests
|
|
190
|
+
(post-checkpoint-slug-merge) store `"slug": "sources/<slug>"` directly in the
|
|
191
|
+
checkpoint — match the checkpoint whose `slug` equals the entry being
|
|
192
|
+
migrated. Older checkpoints predate this field and won't have it; if no
|
|
193
|
+
checkpoint's `slug` matches (including the case where none carry the field at
|
|
194
|
+
all), fall through to Tier 2.
|
|
195
|
+
|
|
196
|
+
If a matching checkpoint is found and has a `source_path` field:
|
|
186
197
|
- If `source_path` is under `raw/tmp/*`: do NOT write `raw_paths`. Tell the user:
|
|
187
198
|
"`<slug>` was ingested from a transient location (`<source_path>`). Move the
|
|
188
199
|
file to `raw/sources/` or `raw/download/<resource>/` and re-run
|
|
@@ -308,13 +319,14 @@ URL=$(node _lumina/scripts/wiki.mjs read-meta sources/<slug> | node -e "process.
|
|
|
308
319
|
|
|
309
320
|
# Step 2 — write urls array
|
|
310
321
|
node _lumina/scripts/wiki.mjs set-meta sources/<slug> urls "[\"$URL\"]" --json-value
|
|
311
|
-
|
|
312
|
-
# Step 3 — remove legacy url key (set-meta with empty string removes the key)
|
|
313
|
-
node _lumina/scripts/wiki.mjs set-meta sources/<slug> url --remove
|
|
314
322
|
```
|
|
315
323
|
|
|
316
|
-
|
|
317
|
-
|
|
324
|
+
`set-meta` cannot remove a frontmatter key today — there is no `--remove`
|
|
325
|
+
flag. After confirming `urls:` was written successfully, remove the legacy
|
|
326
|
+
`url:` line with the `Edit` tool directly. This is the one sanctioned
|
|
327
|
+
exception to "never hand-edit wiki frontmatter" in this skill, and it is
|
|
328
|
+
limited strictly to deleting the obsolete `url:` key — do not use `Edit` for
|
|
329
|
+
any other frontmatter change.
|
|
318
330
|
|
|
319
331
|
After backfilling all entries, proceed immediately to Phase 4.
|
|
320
332
|
|
|
@@ -402,7 +414,7 @@ Report to the user:
|
|
|
402
414
|
2. Entries updated — count and slugs grouped by field.
|
|
403
415
|
3. Inferred values — the inference table from Phase 2 (so the user can review).
|
|
404
416
|
4. Lint result after backfill — must show 0 errors.
|
|
405
|
-
5. Whether
|
|
417
|
+
5. Whether the upgrade cleanup is finished.
|
|
406
418
|
|
|
407
419
|
## Examples
|
|
408
420
|
|
|
@@ -464,7 +476,10 @@ Re-running this skill on a clean wiki produces zero file changes.
|
|
|
464
476
|
- Never modify files in `raw/`. Read-only.
|
|
465
477
|
- Never hand-edit `wiki/graph/edges.jsonl` or `wiki/graph/citations.jsonl`.
|
|
466
478
|
- `set-meta` is the only permitted write path for frontmatter changes in this
|
|
467
|
-
skill
|
|
479
|
+
skill, with one sanctioned exception: deleting the obsolete `url:` key
|
|
480
|
+
during the `url` → `urls` schema-shape upgrade (Phase 3), since `set-meta`
|
|
481
|
+
has no key-removal flag. Do not use Edit or Write on wiki pages for
|
|
482
|
+
anything else.
|
|
468
483
|
- Do not clear `legacyMigrationNeeded` until lint confirms 0 errors.
|
|
469
484
|
- If the CHANGELOG has no `### Migration` section for the detected version gap,
|
|
470
485
|
rely entirely on the L01/L11 finding messages to identify which fields need
|