@sushanglewis/lincoln 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +6 -1
- package/dist/main.js.map +1 -1
- package/dist/postinstall.js +6 -1
- package/dist/postinstall.js.map +1 -1
- package/framework/.claude/agents/pm.md +3 -0
- package/framework/.claude/harnesses/command-map.yaml +5 -1
- package/framework/.claude/hooks/on-session-start.sh +15 -0
- package/framework/.claude/policies/less-is-more.md +24 -0
- package/framework/.claude/schemas/stage-definition.schema.json +2 -0
- package/framework/.claude/skills/build-product-prototype/prompts/main.md +4 -1
- package/framework/.claude/skills/clarify-requirements/prompts/main.md +36 -16
- package/framework/.claude/skills/draft-product-design/prompts/main.md +1 -1
- package/framework/.claude/skills/lc-workflow/validators/validate.py +93 -12
- package/framework/.claude/skills/plan-tdd-development/SKILL.md +1 -0
- package/framework/.claude/skills/plan-tdd-development/prompts/main.md +34 -4
- package/framework/.claude/stages/clarify.yaml +3 -0
- package/framework/.claude/stages/tdd-development-plan.yaml +6 -1
- package/framework/.claude/workflows/interview-to-knowledge.yaml +5 -0
- package/framework/.claude-plugin/marketplace.json +2 -2
- package/framework/.claude-plugin/plugin.json +1 -1
- package/framework/.version-bump.json +1 -1
- package/framework/README.en.md +16 -2
- package/framework/README.md +16 -2
- package/framework/RELEASE.md +37 -0
- package/framework/manifest.json +30 -26
- package/framework/scripts/sync-external-agents.sh +7 -1
- package/framework/scripts/validate_stage.py +96 -15
- package/framework/tools/lincoln/package-lock.json +2 -2
- package/framework/tools/lincoln/package.json +1 -1
- package/framework/tools/lincoln-installer/package.json +1 -1
- package/package.json +1 -1
package/framework/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.8.
|
|
3
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"version": "1.8.4",
|
|
3
|
+
"generatedAt": "2026-10-08T15:05:56.234Z",
|
|
4
4
|
"files": [
|
|
5
5
|
{
|
|
6
6
|
"path": ".claude-plugin/hooks.json",
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"path": ".claude-plugin/marketplace.json",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "eedc0fe820496ffa76731e694758753e81d55bcbab1b3f4700562559aeebeba8"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"path": ".claude-plugin/plugin.json",
|
|
15
|
-
"sha256": "
|
|
15
|
+
"sha256": "c18a2bb7fa9907deccc2e14556a3279d876ed08560eb092a59f341587f7fe7c9"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"path": ".claude/agents/architect.md",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"path": ".claude/agents/pm.md",
|
|
59
|
-
"sha256": "
|
|
59
|
+
"sha256": "eaf7c02ca5b268376e3df7ebe5862bee739688748b8a9472818117b74cfdd627"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"path": ".claude/agents/qa.md",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"path": ".claude/harnesses/command-map.yaml",
|
|
87
|
-
"sha256": "
|
|
87
|
+
"sha256": "8a285b529f845e02df81ccb213833f4bb34d22a01de29a9c9ffc47a736cf1b7b"
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"path": ".claude/harnesses/opencode.yaml",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"path": ".claude/hooks/on-session-start.sh",
|
|
107
|
-
"sha256": "
|
|
107
|
+
"sha256": "b830ac27606e1428d066150861ac74a23d49c2e1566bade9cfddc812bd6a5e09"
|
|
108
108
|
},
|
|
109
109
|
{
|
|
110
110
|
"path": ".claude/hooks/on-stop.sh",
|
|
@@ -126,6 +126,10 @@
|
|
|
126
126
|
"path": ".claude/policies/friction.yaml",
|
|
127
127
|
"sha256": "146af77dbfcdbe4c56aef082f770c8169d91b7574f78189326d965457403d6e8"
|
|
128
128
|
},
|
|
129
|
+
{
|
|
130
|
+
"path": ".claude/policies/less-is-more.md",
|
|
131
|
+
"sha256": "92e073f7dc2a3971e352b8ffe73e4f435b724408e1d43ba70b089bad546e25dd"
|
|
132
|
+
},
|
|
129
133
|
{
|
|
130
134
|
"path": ".claude/policies/security.yaml",
|
|
131
135
|
"sha256": "bd71fd2dd313e033d9248a0697f2b70cc5c6787b39cddb331c39c17f7fdc31cf"
|
|
@@ -148,7 +152,7 @@
|
|
|
148
152
|
},
|
|
149
153
|
{
|
|
150
154
|
"path": ".claude/schemas/stage-definition.schema.json",
|
|
151
|
-
"sha256": "
|
|
155
|
+
"sha256": "153a15c095706c259fabb313227eb183615b84596020f70326ea5e3541f9797e"
|
|
152
156
|
},
|
|
153
157
|
{
|
|
154
158
|
"path": ".claude/schemas/workflow-stage.schema.json",
|
|
@@ -168,7 +172,7 @@
|
|
|
168
172
|
},
|
|
169
173
|
{
|
|
170
174
|
"path": ".claude/skills/build-product-prototype/prompts/main.md",
|
|
171
|
-
"sha256": "
|
|
175
|
+
"sha256": "6523aa6def0f75f93cbbbcbb76e5de285ecc730bb81211add8900826f6a51d5b"
|
|
172
176
|
},
|
|
173
177
|
{
|
|
174
178
|
"path": ".claude/skills/clarify-requirements/SKILL.md",
|
|
@@ -176,7 +180,7 @@
|
|
|
176
180
|
},
|
|
177
181
|
{
|
|
178
182
|
"path": ".claude/skills/clarify-requirements/prompts/main.md",
|
|
179
|
-
"sha256": "
|
|
183
|
+
"sha256": "c96b1972e085fdea5c28c152c69fa8421d814fc9ce4a7169fa5c8f94619ef36c"
|
|
180
184
|
},
|
|
181
185
|
{
|
|
182
186
|
"path": ".claude/skills/dependencies.yaml",
|
|
@@ -188,7 +192,7 @@
|
|
|
188
192
|
},
|
|
189
193
|
{
|
|
190
194
|
"path": ".claude/skills/draft-product-design/prompts/main.md",
|
|
191
|
-
"sha256": "
|
|
195
|
+
"sha256": "77aa515515dbe87216041f064a480ddac269889e2e5f296843537ab92d794c44"
|
|
192
196
|
},
|
|
193
197
|
{
|
|
194
198
|
"path": ".claude/skills/lc-analyze-frameworks/SKILL.md",
|
|
@@ -344,15 +348,15 @@
|
|
|
344
348
|
},
|
|
345
349
|
{
|
|
346
350
|
"path": ".claude/skills/lc-workflow/validators/validate.py",
|
|
347
|
-
"sha256": "
|
|
351
|
+
"sha256": "0a6b9afab31c0e0e4b33dc7cc2e421604bafbc386cb9bd259098232f161e0e1b"
|
|
348
352
|
},
|
|
349
353
|
{
|
|
350
354
|
"path": ".claude/skills/plan-tdd-development/SKILL.md",
|
|
351
|
-
"sha256": "
|
|
355
|
+
"sha256": "71c9497cd6bb6cbf0486fd3955bdf41579c6c2691f4c060a343d4712ba485143"
|
|
352
356
|
},
|
|
353
357
|
{
|
|
354
358
|
"path": ".claude/skills/plan-tdd-development/prompts/main.md",
|
|
355
|
-
"sha256": "
|
|
359
|
+
"sha256": "9a5a3a5b84c27e52026e8f6d01f3c350d5ac478af4f349c6756a5b40e2150705"
|
|
356
360
|
},
|
|
357
361
|
{
|
|
358
362
|
"path": ".claude/skills/process-interview/SKILL.md",
|
|
@@ -400,7 +404,7 @@
|
|
|
400
404
|
},
|
|
401
405
|
{
|
|
402
406
|
"path": ".claude/stages/clarify.yaml",
|
|
403
|
-
"sha256": "
|
|
407
|
+
"sha256": "506491928f9e68fb643912046b66b565035ed9c2b397a9613d3541cd46d35327"
|
|
404
408
|
},
|
|
405
409
|
{
|
|
406
410
|
"path": ".claude/stages/explore-opensource.yaml",
|
|
@@ -492,7 +496,7 @@
|
|
|
492
496
|
},
|
|
493
497
|
{
|
|
494
498
|
"path": ".claude/stages/tdd-development-plan.yaml",
|
|
495
|
-
"sha256": "
|
|
499
|
+
"sha256": "2e684504983e2b9488ffc885a018832883395fd8b0b9beadf4cd6f30e73d06bf"
|
|
496
500
|
},
|
|
497
501
|
{
|
|
498
502
|
"path": ".claude/stages/workflow-router.yaml",
|
|
@@ -524,7 +528,7 @@
|
|
|
524
528
|
},
|
|
525
529
|
{
|
|
526
530
|
"path": ".claude/workflows/interview-to-knowledge.yaml",
|
|
527
|
-
"sha256": "
|
|
531
|
+
"sha256": "8f858613592282504701141d65c36cc44c82d4ea47c14b890db90559a30f9e9c"
|
|
528
532
|
},
|
|
529
533
|
{
|
|
530
534
|
"path": ".claude/workflows/oss-first-design.yaml",
|
|
@@ -536,7 +540,7 @@
|
|
|
536
540
|
},
|
|
537
541
|
{
|
|
538
542
|
"path": ".version-bump.json",
|
|
539
|
-
"sha256": "
|
|
543
|
+
"sha256": "19c15c1eae8c4e4a1062f0e82bdbf4201910f6fd9a42019a0627fa7e41061546"
|
|
540
544
|
},
|
|
541
545
|
{
|
|
542
546
|
"path": "CLAUDE.md",
|
|
@@ -552,15 +556,15 @@
|
|
|
552
556
|
},
|
|
553
557
|
{
|
|
554
558
|
"path": "README.en.md",
|
|
555
|
-
"sha256": "
|
|
559
|
+
"sha256": "12325801ae226d0dfa825b66cae2fb48758af0c979d890f56f7447fa1be8b89b"
|
|
556
560
|
},
|
|
557
561
|
{
|
|
558
562
|
"path": "README.md",
|
|
559
|
-
"sha256": "
|
|
563
|
+
"sha256": "8b5427ce20877fddd96a763f50841bf91706e0611e22320fd255dbc19d72e66d"
|
|
560
564
|
},
|
|
561
565
|
{
|
|
562
566
|
"path": "RELEASE.md",
|
|
563
|
-
"sha256": "
|
|
567
|
+
"sha256": "a4d72d108a6f676a48392327bab1a5b88b40eaf3c8eec581d3866705f3994942"
|
|
564
568
|
},
|
|
565
569
|
{
|
|
566
570
|
"path": "SKILL.md",
|
|
@@ -752,7 +756,7 @@
|
|
|
752
756
|
},
|
|
753
757
|
{
|
|
754
758
|
"path": "scripts/sync-external-agents.sh",
|
|
755
|
-
"sha256": "
|
|
759
|
+
"sha256": "4dc9f374e4ef7c36a75147f20f6a4986e52f258070678a892a8aeda8ba65f987"
|
|
756
760
|
},
|
|
757
761
|
{
|
|
758
762
|
"path": "scripts/sync-framework-package.mjs",
|
|
@@ -772,7 +776,7 @@
|
|
|
772
776
|
},
|
|
773
777
|
{
|
|
774
778
|
"path": "scripts/validate_stage.py",
|
|
775
|
-
"sha256": "
|
|
779
|
+
"sha256": "45259fce089fb9fc72df5b1a1c00a3c782008662e9de551aff45aff44a732019"
|
|
776
780
|
},
|
|
777
781
|
{
|
|
778
782
|
"path": "tools/lincoln-installer/.gitignore",
|
|
@@ -784,7 +788,7 @@
|
|
|
784
788
|
},
|
|
785
789
|
{
|
|
786
790
|
"path": "tools/lincoln-installer/package.json",
|
|
787
|
-
"sha256": "
|
|
791
|
+
"sha256": "8af7b6ee0dc6da02d47413495af0b8f042d90ffb0a79c46e8bce5c6dafb19671"
|
|
788
792
|
},
|
|
789
793
|
{
|
|
790
794
|
"path": "tools/lincoln-installer/src/cli.tsx",
|
|
@@ -1068,11 +1072,11 @@
|
|
|
1068
1072
|
},
|
|
1069
1073
|
{
|
|
1070
1074
|
"path": "tools/lincoln/package-lock.json",
|
|
1071
|
-
"sha256": "
|
|
1075
|
+
"sha256": "5156ad816f5a4eb0ea354943b74af393c2586878bf5b64a1ab228bb6cae98ae4"
|
|
1072
1076
|
},
|
|
1073
1077
|
{
|
|
1074
1078
|
"path": "tools/lincoln/package.json",
|
|
1075
|
-
"sha256": "
|
|
1079
|
+
"sha256": "6631b2928992358105633a0e0b4c693c40e40fbd73757f74a39dc8bd2302165e"
|
|
1076
1080
|
},
|
|
1077
1081
|
{
|
|
1078
1082
|
"path": "tools/lincoln/src/cli.tsx",
|
|
@@ -18,7 +18,13 @@ fi
|
|
|
18
18
|
AGENTS_DIR="$ROOT/.claude/agents/external"
|
|
19
19
|
mkdir -p "$AGENTS_DIR"
|
|
20
20
|
|
|
21
|
-
"$ROOT/.venv/bin/python3"
|
|
21
|
+
if [[ -x "$ROOT/.venv/bin/python3" ]]; then
|
|
22
|
+
PYTHON="$ROOT/.venv/bin/python3"
|
|
23
|
+
else
|
|
24
|
+
PYTHON="python3"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
"$PYTHON" - "$AGENTS_DIR" "$DRY_RUN" <<'PY'
|
|
22
28
|
from __future__ import annotations
|
|
23
29
|
|
|
24
30
|
import sys
|
|
@@ -324,37 +324,82 @@ def check_portal_index_fresh() -> None:
|
|
|
324
324
|
# ---------------------------------------------------------------------------
|
|
325
325
|
|
|
326
326
|
|
|
327
|
+
# 递进骨架(issue-129):版本说明 → 修订记录 → 功能列表 → 需求展开。
|
|
328
|
+
# 章节编号不参与匹配,PM 可按需求类型在骨架内增插业务章节。
|
|
327
329
|
REQUIRED_PRD_SECTIONS = [
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
"
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"
|
|
330
|
+
"版本说明",
|
|
331
|
+
"修订记录",
|
|
332
|
+
"功能列表",
|
|
333
|
+
"需求背景",
|
|
334
|
+
"用户故事",
|
|
335
|
+
"功能拆解",
|
|
336
|
+
"业务流程图",
|
|
337
|
+
"验收标准",
|
|
338
|
+
"业务规则",
|
|
339
|
+
"非功能需求",
|
|
340
|
+
"关联系统/接口",
|
|
341
|
+
"相关产物链接",
|
|
342
|
+
"风险与开放问题",
|
|
338
343
|
]
|
|
339
344
|
|
|
345
|
+
PRD_SECTION_PATTERNS = [
|
|
346
|
+
(name, re.compile(rf"^##\s*(?:\d+\s*[.、.]?\s*)?{re.escape(name)}\s*$", re.MULTILINE))
|
|
347
|
+
for name in REQUIRED_PRD_SECTIONS
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
# PRD 正文禁则:过程性疑问在对话中解决,技术内容归归档页(issue-129 第 4/6 条)。
|
|
351
|
+
PRD_FORBIDDEN_PROCESS_RE = re.compile(r"待确认|待人类|待补充|待\s*PM|TODO|FIXME", re.IGNORECASE)
|
|
352
|
+
PRD_FORBIDDEN_TECH_HEADING_RE = re.compile(
|
|
353
|
+
r"^##+\s*.*(技术调研|技术方案|可行性研究|架构设计|接口设计|数据库设计)",
|
|
354
|
+
re.MULTILINE,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
CROSS_VALIDATION_PASS_RE = re.compile(
|
|
358
|
+
r"<!--\s*cross-validation:\s*pass\s+prd-version:\s*(v\d+\.\d+)\s*-->"
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _read_prd_text(target: Path) -> str:
|
|
363
|
+
if target.suffix == ".html":
|
|
364
|
+
return extract_html_markdown(target)
|
|
365
|
+
return target.read_text(encoding="utf-8")
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def _prd_hygiene_violations(text: str) -> list[str]:
|
|
369
|
+
violations = sorted(set(PRD_FORBIDDEN_PROCESS_RE.findall(text)))
|
|
370
|
+
violations.extend(sorted(set(PRD_FORBIDDEN_TECH_HEADING_RE.findall(text))))
|
|
371
|
+
return violations
|
|
372
|
+
|
|
340
373
|
|
|
341
374
|
def check_prd_has_required_sections(path: str) -> None:
|
|
342
375
|
target = PROJECT_ROOT / path
|
|
343
376
|
if not target.exists():
|
|
344
377
|
fail(f"PRD missing: {target}")
|
|
345
378
|
|
|
346
|
-
|
|
347
|
-
text = extract_html_markdown(target)
|
|
348
|
-
else:
|
|
349
|
-
text = target.read_text(encoding="utf-8")
|
|
379
|
+
text = _read_prd_text(target)
|
|
350
380
|
|
|
351
|
-
missing = [
|
|
381
|
+
missing = [name for name, pattern in PRD_SECTION_PATTERNS if not pattern.search(text)]
|
|
352
382
|
if missing:
|
|
353
383
|
fail(f"PRD missing required sections: {', '.join(missing)}")
|
|
354
384
|
|
|
355
385
|
pass_check("PRD has all required sections")
|
|
356
386
|
|
|
357
387
|
|
|
388
|
+
def check_prd_content_hygiene(path: str) -> None:
|
|
389
|
+
target = PROJECT_ROOT / path
|
|
390
|
+
if not target.exists():
|
|
391
|
+
fail(f"PRD missing: {target}")
|
|
392
|
+
|
|
393
|
+
violations = _prd_hygiene_violations(_read_prd_text(target))
|
|
394
|
+
if violations:
|
|
395
|
+
fail(
|
|
396
|
+
"PRD contains content that belongs in conversation or archived pages, "
|
|
397
|
+
f"not the PRD: {', '.join(violations)}"
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
pass_check("PRD content hygiene OK")
|
|
401
|
+
|
|
402
|
+
|
|
358
403
|
def check_prd_snapshot_present(path: str) -> None:
|
|
359
404
|
target = PROJECT_ROOT / path
|
|
360
405
|
if not target.exists():
|
|
@@ -374,6 +419,40 @@ def check_prd_snapshot_present(path: str) -> None:
|
|
|
374
419
|
pass_check(f"PRD snapshot present: {snapshot_path}")
|
|
375
420
|
|
|
376
421
|
|
|
422
|
+
def check_prd_cross_validated(path: str) -> None:
|
|
423
|
+
target = PROJECT_ROOT / path
|
|
424
|
+
if not target.exists():
|
|
425
|
+
fail(f"Cross-validation report missing: {target}")
|
|
426
|
+
|
|
427
|
+
match = CROSS_VALIDATION_PASS_RE.search(_read_prd_text(target))
|
|
428
|
+
if not match:
|
|
429
|
+
fail(
|
|
430
|
+
"Cross-validation report has no pass marker. Every gap must be closed by a "
|
|
431
|
+
"human-PM decision (PRD fix with re-freeze, or accepted with recorded "
|
|
432
|
+
"rationale) before adding '<!-- cross-validation: pass prd-version: vX.Y -->'."
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
prd_path = target.parent / "prd.html"
|
|
436
|
+
if not prd_path.exists():
|
|
437
|
+
fail(f"PRD missing next to cross-validation report: {prd_path}")
|
|
438
|
+
|
|
439
|
+
prd_version = _extract_document_version(prd_path)
|
|
440
|
+
if prd_version != match.group(1):
|
|
441
|
+
fail(
|
|
442
|
+
f"Cross-validation pass marker is for PRD {match.group(1)}, but the PRD is now "
|
|
443
|
+
f"{prd_version or 'unversioned'}. Re-run cross-validation against the current PRD."
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
violations = _prd_hygiene_violations(_read_prd_text(prd_path))
|
|
447
|
+
if violations:
|
|
448
|
+
fail(
|
|
449
|
+
f"PRD regressed after cross-validation pass: {', '.join(violations)}. "
|
|
450
|
+
"Fix the PRD, bump its version, re-freeze, and re-run cross-validation."
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
pass_check(f"PRD cross-validation pass marker matches PRD {prd_version}")
|
|
454
|
+
|
|
455
|
+
|
|
377
456
|
# ---------------------------------------------------------------------------
|
|
378
457
|
# Registry
|
|
379
458
|
# ---------------------------------------------------------------------------
|
|
@@ -397,6 +476,8 @@ EXIT_CHECKS = {
|
|
|
397
476
|
"handoff_versions_match": check_handoff_versions_match,
|
|
398
477
|
"prd_has_required_sections": check_prd_has_required_sections,
|
|
399
478
|
"prd_snapshot_present": check_prd_snapshot_present,
|
|
479
|
+
"prd_content_hygiene": check_prd_content_hygiene,
|
|
480
|
+
"prd_cross_validated": check_prd_cross_validated,
|
|
400
481
|
"portal_index_exists": check_portal_index_exists,
|
|
401
482
|
"artifact_meta_complete": check_artifact_meta_complete,
|
|
402
483
|
"ids_valid": check_ids_valid,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sushanglewis/lincoln",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@sushanglewis/lincoln",
|
|
9
|
-
"version": "1.8.
|
|
9
|
+
"version": "1.8.4",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"ink": "^5.2.0",
|