@furongjun1999/dsh-memory 0.4.11 → 0.5.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/README.md +552 -465
- package/codebuddy/CODEBUDDY.md +11 -3
- package/codebuddy/README.md +92 -90
- package/codebuddy/mcp.json +27 -27
- package/docs/GBrain/345/217/257/345/200/237/351/211/264/347/202/271_/347/201/265/346/236/242/350/220/275/347/202/271/344/272/244/346/216/245_20260919.md +169 -169
- package/docs/Pi/345/217/257/345/255/246/344/271/240/344/274/230/347/202/271_/347/201/265/346/236/242/345/244/247/350/204/221/346/224/271/350/277/233/344/272/244/346/216/245_20260915.md +144 -144
- package/docs/README.md +143 -111
- package/docs/discipline/harnesses.yaml +244 -226
- package/docs/discipline/templates/full.md.tmpl +61 -61
- package/docs/discipline/templates/rules.mdc.tmpl +68 -0
- package/docs/discipline/templates/skill.md.tmpl +23 -23
- package/docs/eval/AGI/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v1.0.md +299 -299
- package/docs/eval/AGI/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v2.0.md +239 -239
- package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
- package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
- package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
- package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
- package/docs/eval//345/256/236/351/252/214/346/226/271/346/241/210_/345/255/246/344/271/240/351/227/255/347/216/257AB/344/270/216/346/250/252/350/257/204_v1.0.md +174 -174
- package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
- package/docs/eval//346/250/252/350/257/204_/345/205/255/345/256/266100/351/242/230/344/270/255/350/213/261/345/217/214/346/237/245_v1.0.md +223 -223
- package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
- package/docs/{mdcg → hive}//344/273/244/347/211/214/344/270/216/350/247/222/350/211/262/346/235/203/350/201/214/345/210/206/347/246/273_v0.1.md +165 -160
- package/docs/hive//344/273/244/347/211/214/350/257/255/344/271/211/344/277/256/346/255/243_/344/273/262/350/243/201/344/275/215_v0.1.md +76 -0
- package/docs/{mdcg → hive}//345/255/220/344/273/243/347/220/206/351/205/215/347/275/256/346/240/207/345/207/206_v0.5.md +236 -236
- package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
- package/docs/hive//346/243/200/347/264/242/346/224/266/346/225/233/345/256/236/346/265/213/344/270/216S1b/350/256/276/350/256/241_v0.1.md +43 -43
- package/docs/hive//346/243/200/347/264/242/347/256/227/346/263/225/345/217/243/345/276/204/345/257/271/347/205/247_v0.1.md +85 -0
- package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +102 -102
- package/docs/hive//350/234/202/345/267/242M6_ingest/345/256/236/346/226/275/350/256/241/345/210/222_v0.1.md +47 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +519 -503
- package/docs/hive//350/234/202/345/267/242/345/267/245/344/275/234/350/256/260/345/277/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +85 -85
- package/docs/hive//350/234/202/345/267/242/350/256/276/350/256/241_/347/220/206/350/256/272/345/257/271/351/275/220_v0.1.md +191 -0
- package/docs/hive//350/234/202/345/267/242/350/277/255/344/273/243_/345/256/217/350/247/202/344/270/216/347/276/244/344/275/223/350/260/203/345/272/246_v0.1.md +90 -0
- package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
- package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
- package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -216
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +646 -646
- package/docs/mdcg/lingshu_tutorial.html +14449 -14449
- package/docs/mdcg/release_v0.4.11.md +49 -0
- package/docs/mdcg/release_v0.4.5.md +55 -55
- package/docs/mdcg/tool_table_v0.3.0.md +117 -117
- package/docs/mdcg//345/205/250/345/272/223/344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/350/256/241/345/210/222_v0.1.md +600 -600
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
- package/docs/mdcg//345/215/225/345/205/203/350/207/252/346/210/221/351/224/232/347/202/271_/347/263/273/347/273/237/346/217/220/347/244/272/350/257/215/346/240/207/345/207/206_v0.3.md +275 -275
- package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +54 -0
- package/docs/mdcg//346/272/220/347/240/201/347/272/247/346/236/266/346/236/204/345/256/241/350/256/241_GPT/346/211/271/350/257/204/345/257/271/347/205/247_v1.0.md +130 -130
- package/docs/mdcg//347/201/265/346/236/24282/345/267/245/345/205/267_/345/212/237/350/203/275/346/225/264/347/220/206/344/270/216/350/277/201/347/247/273/346/230/240/345/260/204_v0.1.md +278 -278
- package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +172 -172
- package/docs/mdcg//347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +270 -270
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_G4-G8/347/274/272/345/217/243/350/243/201/345/256/232/345/215/225_v0.1.md +491 -491
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_/346/235/241/344/273/266/347/251/272/351/227/264/345/220/210/346/210/220/344/270/216/347/224/237/346/225/210/346/235/241/344/273/266/345/217/243/345/276/204_v0.1.md +340 -340
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_/347/264/242/345/274/225/344/270/216/345/267/245/347/250/213/350/247/204/350/214/203/345/214/226_/350/256/241/345/210/222_v0.1.md +588 -588
- package/docs/plans/GridWorld/346/234/200/345/260/217/351/227/255/347/216/257/350/247/204/346/240/274_v0.1.md +176 -176
- package/docs/plans//345/221/275/345/220/215/346/262/273/347/220/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +81 -81
- package/docs/swarm//350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +704 -704
- package/docs/swarm//350/234/202/347/276/244/345/220/214/351/224/231/346/243/200/346/265/213/345/256/236/351/252/214/345/215/217/350/256/256_v0.1.md +242 -242
- package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
- package/docs/theory//345/215/225/347/272/277/347/250/213/344/270/216/346/263/250/346/204/217/345/212/233/351/233/206/344/270/255_/346/227/240/344/272/211/350/256/256/347/220/206/350/256/272/346/226/207/346/241/243_v1.0.md +129 -129
- package/docs/theory//345/271/266/345/217/221/345/277/205/347/204/266/346/200/247/347/220/206/350/256/272_v0.2.md +134 -134
- package/docs/theory//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- package/docs/theory//346/246/202/345/277/265/345/210/206/345/261/202/345/257/271/351/275/220/350/241/250_v0.1.md +145 -145
- package/docs/theory//347/220/206/350/256/272_/346/234/272/345/210/266_/344/273/243/347/240/201_/345/256/236/351/252/214_/347/274/272/345/217/243/347/237/251/351/230/265_v0.1.md +144 -144
- package/docs/theory//347/220/206/350/256/272/344/273/223/346/213/206/345/210/206/344/270/216/347/231/275/347/256/261/347/237/245/350/257/206/345/272/223/345/206/205/350/277/201_v0.1.md +198 -198
- package/docs/theory//350/256/244/347/237/245/344/273/243/347/220/206/344/270/216/346/224/266/346/225/233/347/273/223/346/236/204_/346/235/241/344/273/266/350/256/272/351/207/215/346/236/204_v0.1.md +221 -221
- package/docs/world_model//344/270/226/347/225/214/346/250/241/345/236/213_/347/245/236/347/273/217/347/275/221/347/273/234/345/272/225/345/261/202/346/236/266/346/236/204_v1.0.md +237 -237
- package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
- package/docs//345/217/221/345/270/203/344/273/266/345/233/236/346/272/257/350/257/264/346/230/216_v0.1.md +82 -82
- package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +28 -2
- package/dsh/README.md +82 -82
- package/dsh/cordis.yml.example +139 -139
- package/dsh/update-lingshu.bat +11 -11
- package/lib/bridge.d.ts +9 -0
- package/lib/bridge.js +35 -0
- package/lib/hooks.js +36 -2
- package/lib/index.js +7 -1
- package/lib/lib/roleplay_web.js +116 -29
- package/lib/lib/token_store.d.ts +7 -1
- package/lib/lib/token_store.js +12 -3
- package/md_cg/__init__.py +7 -7
- package/md_cg/audit.py +379 -368
- package/md_cg/autonomy.py +287 -287
- package/md_cg/backfill.py +1328 -1327
- package/md_cg/backfill_bigdomain.py +34 -34
- package/md_cg/backfill_bucket_zh.py +35 -0
- package/md_cg/bench6_arms.py +410 -410
- package/md_cg/bench6_common.py +230 -230
- package/md_cg/bench6_competitors.py +212 -212
- package/md_cg/bench_axis_domain.py +257 -257
- package/md_cg/bench_blind_comp.py +308 -308
- package/md_cg/bench_e2e_judge.py +532 -0
- package/md_cg/bench_e2e_locomo_qa.py +368 -0
- package/md_cg/bench_e2e_qa.py +256 -0
- package/md_cg/bench_en_atoms_public.py +230 -230
- package/md_cg/bench_governance.py +348 -348
- package/md_cg/bench_lme_zh.py +410 -410
- package/md_cg/bench_locomo.py +121 -121
- package/md_cg/bench_locomo_zh.py +450 -450
- package/md_cg/bench_locomo_zh_public.py +147 -147
- package/md_cg/bench_longmem.py +112 -112
- package/md_cg/bench_membench.py +632 -632
- package/md_cg/bench_p0.py +149 -149
- package/md_cg/bench_progressive.py +287 -287
- package/md_cg/bench_role_views.py +238 -238
- package/md_cg/bench_task_ab.py +243 -243
- package/md_cg/bench_task_ab_llm.py +408 -408
- package/md_cg/bench_unified_en.py +204 -204
- package/md_cg/bench_zh_mad.py +601 -601
- package/md_cg/blindspot_tickets.py +123 -123
- package/md_cg/branches.py +301 -285
- package/md_cg/build_postings.py +73 -73
- package/md_cg/ccgc.py +1006 -948
- package/md_cg/census.py +132 -132
- package/md_cg/chain.py +315 -300
- package/md_cg/codeindex.py +531 -531
- package/md_cg/coldverify.py +292 -292
- package/md_cg/comment_gate.py +337 -337
- package/md_cg/cond_compose.py +190 -190
- package/md_cg/cond_facts.py +154 -154
- package/md_cg/cond_template.json +106 -106
- package/md_cg/condition_anchor.py +142 -142
- package/md_cg/conformance.py +726 -726
- package/md_cg/consistency.py +717 -717
- package/md_cg/consolidate.py +1537 -1439
- package/md_cg/corpus.py +110 -110
- package/md_cg/crosscheck.py +1098 -1097
- package/md_cg/crypto.py +3 -1
- package/md_cg/d_meta.py +310 -310
- package/md_cg/datapath.py +78 -18
- package/md_cg/docindex.py +473 -473
- package/md_cg/eval_common.py +575 -575
- package/md_cg/evidence.py +4 -2
- package/md_cg/evolution.py +477 -477
- package/md_cg/export.py +222 -220
- package/md_cg/forgetting.py +581 -581
- package/md_cg/fsutil.py +377 -329
- package/md_cg/hotcache.py +48 -7
- package/md_cg/hyperedge.py +251 -251
- package/md_cg/identity.py +390 -390
- package/md_cg/insight.py +500 -500
- package/md_cg/interop.py +338 -0
- package/md_cg/judgment_manifest.py +177 -0
- package/md_cg/lexicon/build_cedict_en_zh.py +329 -329
- package/md_cg/lexicon/build_standard_en.py +171 -171
- package/md_cg/lexicon/expand_en_zh.py +211 -211
- package/md_cg/lifecycle.py +272 -272
- package/md_cg/linkref.py +280 -280
- package/md_cg/links.py +140 -107
- package/md_cg/mcp_server.py +403 -55
- package/md_cg/md_whitebox.py +345 -345
- package/md_cg/mdcg.py +783 -233
- package/md_cg/mdcos.py +500 -70
- package/md_cg/metacognition.py +591 -591
- package/md_cg/migrate.py +119 -119
- package/md_cg/migrate_aeis.py +221 -221
- package/md_cg/migrate_roleplay.py +293 -293
- package/md_cg/migrate_wisdom_graph.py +360 -360
- package/md_cg/mreview/__init__.py +25 -25
- package/md_cg/mreview/__main__.py +110 -110
- package/md_cg/mreview/bundle.py +178 -178
- package/md_cg/mreview/candidates.py +262 -262
- package/md_cg/mreview/govern.py +694 -693
- package/md_cg/mreview/locate.py +939 -939
- package/md_cg/mreview/pipeline.py +728 -728
- package/md_cg/mreview/rules/duplication.json +21 -21
- package/md_cg/mreview/rules/field_coverage.json +54 -54
- package/md_cg/mreview/rules/source_license.json +21 -21
- package/md_cg/mreview/rules/template_flow.json +21 -21
- package/md_cg/mreview/ruleset.py +252 -252
- package/md_cg/nodefile.py +575 -575
- package/md_cg/pooling.py +484 -472
- package/md_cg/postings.py +300 -298
- package/md_cg/predict.py +1100 -1100
- package/md_cg/progressive.py +123 -123
- package/md_cg/protect.py +272 -272
- package/md_cg/protocol/md_cg_gate.proto +33 -33
- package/md_cg/protocol.py +372 -372
- package/md_cg/provenance.py +582 -582
- package/md_cg/reach.py +453 -453
- package/md_cg/readcache.py +143 -0
- package/md_cg/reconcile.py +228 -0
- package/md_cg/refindex.py +833 -833
- package/md_cg/refine.py +604 -604
- package/md_cg/review_cli.py +170 -0
- package/md_cg/roleviews.py +89 -89
- package/md_cg/routing.py +393 -365
- package/md_cg/run_tests.py +211 -0
- package/md_cg/scrub.py +13 -3
- package/md_cg/security.py +128 -18
- package/md_cg/self_state.py +1029 -1029
- package/md_cg/selfreport.py +152 -151
- package/md_cg/semantic/__init__.py +10 -10
- package/md_cg/semantic/canonical.py +122 -122
- package/md_cg/semantic/en_normalizer.py +364 -364
- package/md_cg/semantic/en_zh_map.json +28694 -0
- package/md_cg/semantic/export_en_zh_map.py +64 -0
- package/md_cg/semantic/unify.py +45 -0
- package/md_cg/semantic/zh_en_atoms.py +139 -139
- package/md_cg/signer.py +7 -4
- package/md_cg/sources.py +816 -582
- package/md_cg/statushdr.py +179 -179
- package/md_cg/stg.py +54 -37
- package/md_cg/subgraph.py +729 -729
- package/md_cg/sustain.py +35 -5
- package/md_cg/tasks.py +470 -470
- package/md_cg/test_access_hints.py +147 -0
- package/md_cg/test_action_derive.py +203 -203
- package/md_cg/test_audit_rotate.py +270 -270
- package/md_cg/test_autonomy.py +143 -143
- package/md_cg/test_bench_governance.py +102 -102
- package/md_cg/test_blindspot_tickets.py +166 -166
- package/md_cg/test_branch_discard_tombstone.py +136 -0
- package/md_cg/test_branches.py +13 -3
- package/md_cg/test_ccg_perturb.py +184 -184
- package/md_cg/test_ccgc.py +433 -433
- package/md_cg/test_census_prune.py +81 -81
- package/md_cg/test_chain_read_isolate.py +168 -0
- package/md_cg/test_cond_compose_anchors.py +76 -76
- package/md_cg/test_cond_match.py +165 -165
- package/md_cg/test_condition_anchor.py +81 -81
- package/md_cg/test_d_meta.py +412 -412
- package/md_cg/test_datapath_device_name.py +203 -0
- package/md_cg/test_datapath_root.py +199 -199
- package/md_cg/test_emit_negtail_cache.py +156 -0
- package/md_cg/test_en_pipeline.py +22 -2
- package/md_cg/test_gain_gate.py +212 -212
- package/md_cg/test_govern_directread.py +421 -0
- package/md_cg/test_health_scale.py +173 -173
- package/md_cg/test_hive_ingest.py +285 -0
- package/md_cg/test_hot_cold.py +215 -215
- package/md_cg/test_hyperedge.py +245 -245
- package/md_cg/test_i26_empty_first_write.py +116 -0
- package/md_cg/test_i27_e041_identity.py +128 -0
- package/md_cg/test_i28_hotcache_prodpath.py +122 -0
- package/md_cg/test_i32_hotcache_env_key.py +218 -0
- package/md_cg/test_identity_attribution.py +96 -15
- package/md_cg/test_index_durability.py +17 -3
- package/md_cg/test_interop.py +95 -0
- package/md_cg/test_interop_judgment.py +228 -0
- package/md_cg/test_issue39_utf8_stdio.py +273 -0
- package/md_cg/test_lifecycle.py +309 -309
- package/md_cg/test_linkref.py +306 -306
- package/md_cg/test_links_concurrent_write.py +188 -0
- package/md_cg/test_lock.py +43 -43
- package/md_cg/test_md_access_parity.py +255 -255
- package/md_cg/test_md_writepath.py +345 -345
- package/md_cg/test_mdstore_search_parity.py +160 -0
- package/md_cg/test_merge_upsert.py +168 -0
- package/md_cg/test_mr_m2.py +587 -587
- package/md_cg/test_mr_m3.py +710 -710
- package/md_cg/test_mr_m4.py +485 -485
- package/md_cg/test_n123_derive_expiry_chain.py +205 -0
- package/md_cg/test_n130_verify_falsified_protect.py +185 -0
- package/md_cg/test_n131_merge_gate.py +205 -0
- package/md_cg/test_p0.py +250 -250
- package/md_cg/test_p1.py +316 -316
- package/md_cg/test_p10_identity.py +173 -173
- package/md_cg/test_p11_consistency.py +233 -233
- package/md_cg/test_p12_metacognition.py +212 -212
- package/md_cg/test_p13_encryption.py +241 -241
- package/md_cg/test_p14_sustain.py +249 -249
- package/md_cg/test_p15_scrub.py +280 -280
- package/md_cg/test_p16_self_state.py +301 -301
- package/md_cg/test_p17_predict.py +354 -354
- package/md_cg/test_p18_whitebox.py +171 -171
- package/md_cg/test_p19_migrate_roleplay.py +149 -149
- package/md_cg/test_p1x_ref_root.py +160 -0
- package/md_cg/test_p20_evolution.py +315 -315
- package/md_cg/test_p21_tokens.py +293 -270
- package/md_cg/test_p22_theory.py +175 -175
- package/md_cg/test_p23_links.py +311 -311
- package/md_cg/test_p24_evidence.py +227 -227
- package/md_cg/test_p25_weights.py +156 -156
- package/md_cg/test_p26_refindex.py +416 -416
- package/md_cg/test_p27_docindex.py +16 -7
- package/md_cg/test_p28_refcheck.py +305 -305
- package/md_cg/test_p29_session_ingest_export.py +354 -333
- package/md_cg/test_p2_mcp.py +3 -0
- package/md_cg/test_p3.py +11 -2
- package/md_cg/test_p30_maintain.py +330 -330
- package/md_cg/test_p31_insight.py +534 -534
- package/md_cg/test_p32_backfill.py +7 -1
- package/md_cg/test_p33_ccg_wiring.py +293 -293
- package/md_cg/test_p34_crosscheck.py +331 -331
- package/md_cg/test_p35_conditioned_claim.py +252 -252
- package/md_cg/test_p36_kp_align.py +230 -230
- package/md_cg/test_p37_condition_space.py +248 -248
- package/md_cg/test_p38_concurrent_flush.py +102 -0
- package/md_cg/test_p38_contextualize.py +273 -273
- package/md_cg/test_p39_verify_flow.py +153 -0
- package/md_cg/test_p39_vision_evidence.py +369 -369
- package/md_cg/test_p40_refine_worklist.py +241 -241
- package/md_cg/test_p41_evolve_patrol.py +224 -224
- package/md_cg/test_p42_provenance.py +269 -269
- package/md_cg/test_p43_pooling.py +412 -398
- package/md_cg/test_p44_md_whitebox.py +231 -231
- package/md_cg/test_p45_session_identity.py +219 -219
- package/md_cg/test_p46_unit_scope.py +272 -272
- package/md_cg/test_p47_session_view.py +316 -0
- package/md_cg/test_p4_fuzzy.py +223 -223
- package/md_cg/test_p5_semantic.py +226 -226
- package/md_cg/test_p6_consolidate.py +440 -387
- package/md_cg/test_p7_goals_recent.py +202 -202
- package/md_cg/test_p8_subgraph_chain.py +200 -200
- package/md_cg/test_p9_forget_protect.py +231 -231
- package/md_cg/test_predict_beta.py +135 -135
- package/md_cg/test_preflight_failclosed.py +100 -100
- package/md_cg/test_progressive.py +146 -146
- package/md_cg/test_propose_tail_index.py +157 -0
- package/md_cg/test_protocol.py +243 -243
- package/md_cg/test_reach.py +378 -378
- package/md_cg/test_reach_keys.py +201 -201
- package/md_cg/test_read_clip.py +141 -141
- package/md_cg/test_read_scope_b27.py +277 -0
- package/md_cg/test_readcache_default_on.py +168 -0
- package/md_cg/test_readcache_precise_inval.py +270 -0
- package/md_cg/test_readcache_prodpath.py +203 -0
- package/md_cg/test_reconcile_v0.py +294 -0
- package/md_cg/test_retr_gates_prodpath.py +140 -0
- package/md_cg/test_retr_s1.py +344 -340
- package/md_cg/test_retr_s1b.py +276 -209
- package/md_cg/test_retr_s3.py +194 -194
- package/md_cg/test_retr_s4.py +163 -163
- package/md_cg/test_retr_s5.py +200 -200
- package/md_cg/test_retr_s6.py +157 -157
- package/md_cg/test_retr_s7.py +392 -384
- package/md_cg/test_retr_s8_time.py +369 -316
- package/md_cg/test_retr_s9_edges.py +286 -286
- package/md_cg/test_retr_s9_entity_ctx.py +9 -3
- package/md_cg/test_retr_score_once.py +208 -0
- package/md_cg/test_review_conformance.py +367 -367
- package/md_cg/test_review_onepass.py +170 -0
- package/md_cg/test_role_views.py +354 -354
- package/md_cg/test_rrf_graph_seed_cache.py +154 -0
- package/md_cg/test_security_audit.py +155 -0
- package/md_cg/test_security_audit_b26.py +161 -0
- package/md_cg/test_security_audit_v21.py +250 -0
- package/md_cg/test_sem_noise.py +242 -242
- package/md_cg/test_semantic_canonical.py +16 -2
- package/md_cg/test_session_isolation.py +168 -0
- package/md_cg/test_snapshot_autoclose.py +187 -0
- package/md_cg/test_subproc_encoding.py +192 -192
- package/md_cg/test_sustain_mutual.py +153 -153
- package/md_cg/test_tail_watermark_race.py +208 -0
- package/md_cg/test_tasks.py +409 -409
- package/md_cg/test_tenant_env_override_warn.py +139 -0
- package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
- package/md_cg/test_tool_face.py +189 -189
- package/md_cg/test_transfer.py +180 -180
- package/md_cg/test_trust.py +361 -361
- package/md_cg/test_twophase.py +286 -286
- package/md_cg/test_v14_fixes.py +38 -20
- package/md_cg/test_validity_filter.py +280 -280
- package/md_cg/test_verify_answer.py +138 -138
- package/md_cg/test_verify_dirty_reconcile.py +157 -0
- package/md_cg/test_wisdom_md_store.py +292 -292
- package/md_cg/test_writelimit.py +197 -197
- package/md_cg/test_writepipe.py +214 -214
- package/md_cg/theory.py +6 -3
- package/md_cg/tokens.py +85 -14
- package/md_cg/tool_face.py +260 -260
- package/md_cg/trust.py +986 -950
- package/md_cg/twophase.py +231 -231
- package/md_cg/units.py +668 -667
- package/md_cg/vision_evidence.py +667 -666
- package/md_cg/weights.py +624 -624
- package/md_cg/whitebox.py +527 -527
- package/md_cg/whitebox_kb/__init__.py +37 -37
- package/md_cg/whitebox_kb/aeis_core/__init__.py +42 -42
- package/md_cg/whitebox_kb/aeis_core/semantic.py +280 -280
- package/md_cg/whitebox_kb/aeis_core/textutil.py +13 -13
- package/md_cg/whitebox_kb/engine.py +310 -310
- package/md_cg/whitebox_kb/seed_knowledge//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- package/md_cg/whitebox_kb/wisdom/browser_units.py +2631 -2631
- package/md_cg/whitebox_kb/wisdom/causal_discover.py +432 -432
- package/md_cg/whitebox_kb/wisdom/chat_engine.py +1506 -1506
- package/md_cg/whitebox_kb/wisdom/compiler_code_units.py +3033 -3033
- package/md_cg/whitebox_kb/wisdom/condition_algebra.py +112 -112
- package/md_cg/whitebox_kb/wisdom/condition_frame.py +315 -315
- package/md_cg/whitebox_kb/wisdom/condition_kb.py +108 -108
- package/md_cg/whitebox_kb/wisdom/conflict_map.json +4445 -4445
- package/md_cg/whitebox_kb/wisdom/core/lexer.py +512 -512
- package/md_cg/whitebox_kb/wisdom/core/name_checker.py +1023 -1023
- package/md_cg/whitebox_kb/wisdom/cspmn.py +258 -258
- package/md_cg/whitebox_kb/wisdom/csre.py +264 -264
- package/md_cg/whitebox_kb/wisdom/danmaku_audit.py +252 -252
- package/md_cg/whitebox_kb/wisdom/distilled_condition_units.json +6417 -6417
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902b.json +1950 -1950
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902c.json +1296 -1296
- package/md_cg/whitebox_kb/wisdom/docs/whitebox_capability_graph_demo.json +59 -59
- package/md_cg/whitebox_kb/wisdom/graph_db_units.py +3089 -3089
- package/md_cg/whitebox_kb/wisdom/knowledge_points.py +318 -318
- package/md_cg/whitebox_kb/wisdom/md_access.py +470 -470
- package/md_cg/whitebox_kb/wisdom/md_store.py +276 -251
- package/md_cg/whitebox_kb/wisdom/migrate_wisdom.py +476 -476
- package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
- package/md_cg/whitebox_kb/wisdom/navigate.py +248 -248
- package/md_cg/whitebox_kb/wisdom/neural_retrieve.py +224 -224
- package/md_cg/whitebox_kb/wisdom/os_units.py +2735 -2735
- package/md_cg/whitebox_kb/wisdom/pattern_separation.py +376 -376
- package/md_cg/whitebox_kb/wisdom/prereq_map.json +364 -364
- package/md_cg/whitebox_kb/wisdom/python_code_units.py +2766 -2766
- package/md_cg/whitebox_kb/wisdom/role_solidified.json +7 -7
- package/md_cg/whitebox_kb/wisdom/route_memory.py +244 -244
- package/md_cg/whitebox_kb/wisdom/scene_reconstruction.py +148 -148
- package/md_cg/whitebox_kb/wisdom/snr_report.json +40 -40
- package/md_cg/whitebox_kb/wisdom/test_code_compose_domains.py +7541 -7541
- package/md_cg/whitebox_kb/wisdom/test_compiler_self_bootstrap.py +354 -354
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_assembly.py +158 -158
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_demos.py +193 -193
- package/md_cg/whitebox_kb/wisdom/test_graph_db.py +292 -292
- package/md_cg/whitebox_kb/wisdom/test_python_self_bootstrap.py +160 -160
- package/md_cg/whitebox_kb/wisdom/trigger_words_index.json +4366 -4366
- package/md_cg/whitebox_kb/wisdom/verifier.py +1297 -1297
- package/md_cg/writelimit.py +356 -356
- package/md_cg/writepipe.py +20 -8
- package/package.json +101 -96
- package/skills/plugin.json +54 -54
- package/skills/skills/designer-perspective/SKILL.md +158 -158
- package/skills/skills/designer-perspective/references/01-observation-position.md +66 -66
- package/skills/skills/designer-perspective/references/02-structure-recognition.md +62 -62
- package/skills/skills/designer-perspective/references/03-direction-judgment.md +55 -55
- package/skills/skills/designer-perspective/references/04-qualification-verdict.md +72 -72
- package/skills/skills/designer-perspective/references/05-condition-attribution.md +74 -74
- package/skills/skills/designer-perspective/scripts/designer.py +545 -545
- package/skills/skills/designer-perspective/tests/cases.jsonl +17 -17
- package/skills/skills/designer-perspective/tests/selftest.py +61 -61
- package/skills/skills/lingshu-browser/SKILL.md +60 -60
- package/skills/skills/lingshu-compiler/SKILL.md +56 -56
- package/skills/skills/lingshu-compiler/units/analyze-type-infer/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/check-name-real/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-assign/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-expr-tree/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-full-pipeline/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-func-def/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-if-then/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-logic-expr/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-recursive/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-scope/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-type-check/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-while/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0010c4bf/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0355bffb/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0361708a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-054a0414/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05a1691a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05eeed1e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0622a1f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-08b54217/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0a62b70c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ab24d00/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e093688/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e82b966/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ee9b9b9/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0f3787e6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1028685f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-11897630/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-16661b9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1f722303/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-25be1262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2a76ba07/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2dbea54a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2df52f16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2ec2c9d2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2f8c8f39/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-38378ac7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39457d2e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39fb5926/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-47f4fbfa/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4a8cd1f1/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4b230b6b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4cbbda95/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4d5a68ff/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-56dc9bdd/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-57e76ebe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-61ff016b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-63eae588/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-64c4224b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-66377955/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-674ab4f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6af76fd6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6d979db2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6de326c0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6f1c0eea/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-724d6c9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7690177f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7b229a7d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7f471b3a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-815cad08/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-83c61634/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8c798c81/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8dd747ac/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-90324d0a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94b8d72d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94f12231/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-95937c16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98a5625b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98b4c42f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98e3894a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9bdfe4b8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9d9b4e83/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9f7be5ad/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a6daf076/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a7995a0c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a8399248/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-aabbd099/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-afe169d8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b0678bda/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b09bd196/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b1396e23/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b9b31ce0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-c10264a7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cb1e8e4b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ccafd438/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cda9c262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ce648068/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cf5776a4/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-d974e5d3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-e3979fd3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-eb1cf2b5/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ecb30d5b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f8c8b24b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f99fedbe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fa8ff5f7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fe1b058d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-chinese-program/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-dao-de-jing/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-nine-chapters/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-arithmetic/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-array-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-create/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-compare/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-jump/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-space/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-exception/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-func-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-loop-run/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-profiling/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-refcount/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-run-loop/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-short-circuit/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-guard/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-trust-accum/SKILL.md +45 -45
- package/skills/skills/lingshu-graph/SKILL.md +63 -63
- package/skills/skills/lingshu-net/SKILL.md +48 -48
- package/skills/skills/lingshu-os/SKILL.md +64 -64
- package/skills/skills/lingshu-pylang/SKILL.md +71 -71
- package/src/bridge.ts +33 -0
- package/src/hooks.ts +38 -2
- package/src/index.ts +526 -518
- package/src/lib/datapath.ts +326 -326
- package/src/lib/mdcg_client.ts +413 -413
- package/src/lib/mutual.ts +428 -428
- package/src/lib/prompt_safety.ts +62 -62
- package/src/lib/python_path.ts +71 -71
- package/src/lib/roleplay_web.ts +116 -29
- package/src/lib/token_store.ts +13 -3
- package/src/tools.ts +212 -212
- package/zcode/AGENTS.md +11 -3
- package/zcode/README.md +41 -41
- /package/docs/{mdcg → hive}//344/270/273/344/273/243/347/220/206/345/255/220/344/273/243/347/220/206/350/256/260/345/277/206/346/236/266/346/236/204/350/256/276/350/256/241.md" +0 -0
package/src/lib/prompt_safety.ts
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* prompt_safety.ts · 注入边界文本安全(宿主严格模板的转义)
|
|
3
|
-
*
|
|
4
|
-
* ── 根因(issue #16,2026-09-16)────────────────────────────────────────
|
|
5
|
-
* dsh 宿主 `@deepseek-ai/dsh-system-prompt` 的 `interpolate()` 会对**每个
|
|
6
|
-
* section / context** 文本做严格 `{{variable}}` 插值,且**四类一律 throw**:
|
|
7
|
-
* ① `{{` 之后能找到 `}}` 但不成简单组(GROUP_AT = /^\{\{([^{}]*)\}\}/ 不匹配)
|
|
8
|
-
* ② 组成立但名不匹配 /^[a-z][a-z0-9_]*$/(如 `{{.Architecture}}`)
|
|
9
|
-
* ③ 名合法但未注册(如 `{{name}}`)
|
|
10
|
-
* ④ 已注册但值为 undefined
|
|
11
|
-
* `renderContextSections()` 逐 context 调用它,throw 直接冒泡到
|
|
12
|
-
* `system-prompt/assemble` → **该轮请求整体失败**。
|
|
13
|
-
*
|
|
14
|
-
* ── 伤害路径 ───────────────────────────────────────────────────────────
|
|
15
|
-
* 自动记忆把用户命令原样沉淀(如 `docker inspect --format '{{.Architecture}}'`)
|
|
16
|
-
* → auto-recall 把含裸 `{{` 的预览推入 `assembly.contexts`
|
|
17
|
-
* → 宿主每轮 assemble 必抛 → **会话永久不可用**(记忆永久在库,非偶发故障)。
|
|
18
|
-
*
|
|
19
|
-
* ── 处置:为何只在注入边界转义,不在写入侧 ────────────────────────────
|
|
20
|
-
* ① 记忆真源必须保真:`{{.Architecture}}` 是用户命令原文,写入侧转义会
|
|
21
|
-
* 不可逆失真,且 cg(op=read) / 工具面 / 检索都依赖原文(= 污染真源);
|
|
22
|
-
* ② 伤害面就是「注入到 prompt 的文本」,在注入边界处理即**最小充分**;
|
|
23
|
-
* ③ 与写入侧 desensitize 不冲突:脱敏是**隐私**要求(不许落盘),
|
|
24
|
-
* 转义是**渲染安全**要求(落盘保真、渲染时规避)——层次不同。
|
|
25
|
-
*
|
|
26
|
-
* ── 转义策略:确保文本中不出现连续两个 `{` ────────────────────────────
|
|
27
|
-
* 依据(宿主源码 `lib/index.js:109-116`):`interpolate` 以
|
|
28
|
-
* `text.indexOf("{{")` 为**唯一扫描锚点**;破坏 `{{` 序列后循环不进入,
|
|
29
|
-
* 文本走 `text.slice(last)` 原样返回。
|
|
30
|
-
* · `}}` 无需处理——它只在 `{{` 成组时参与解析,锚点已破即无意义;
|
|
31
|
-
* · 逐对打断(而非 `split('{{').join(...)`):后者对 `{{{a}}}` 会产出
|
|
32
|
-
* `{ {{a}}}`——新锚点仍在(相邻 `{` 重新合成),不幂等也不安全;
|
|
33
|
-
* · 跨 context 拼接安全:`joinContextSections` 以 `"\n\n"` 分隔并带固定
|
|
34
|
-
* 前缀(`lib/index.js:85-87`,前缀以 `.` 结尾),边界不会合成新 `{{`;
|
|
35
|
-
* · 为何不用零宽字符:显示上「看起来一样」但复制会带入不可见字符
|
|
36
|
-
* (终端粘贴即出错)——诚实性优先,宁可让改写可见。
|
|
37
|
-
*
|
|
38
|
-
* 幂等:结果中不存在 `{{`,重复调用结果不变。
|
|
39
|
-
* 边界:本函数只服务**注入到宿主 prompt 的文本**;记忆真源与工具返回原文
|
|
40
|
-
* 一律不动(工具结果不进 assembly 插值面)。
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
/** 宿主严格模板的扫描锚点。 */
|
|
44
|
-
const TEMPLATE_OPEN = '{{'
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 把文本中每一对相邻的 `{` 打断(插入半角空格),使其不再包含 `{{`。
|
|
48
|
-
*
|
|
49
|
-
* 不含 `{{` 的文本**原样返回**(零改写,保真)。
|
|
50
|
-
* 例:`{{.Architecture}}` → `{ {.Architecture}}`;`{{{a}}}` → `{ { {a}}}`。
|
|
51
|
-
*/
|
|
52
|
-
export function escapePromptBraces(text: string): string {
|
|
53
|
-
if (!text.includes(TEMPLATE_OPEN)) return text
|
|
54
|
-
let out = ''
|
|
55
|
-
for (let i = 0; i < text.length; i++) {
|
|
56
|
-
const ch = text.charAt(i)
|
|
57
|
-
out += ch
|
|
58
|
-
// 该 `{` 与下一个字符构成锚点 → 立即插入空格打断
|
|
59
|
-
if (ch === '{' && text.charAt(i + 1) === '{') out += ' '
|
|
60
|
-
}
|
|
61
|
-
return out
|
|
62
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* prompt_safety.ts · 注入边界文本安全(宿主严格模板的转义)
|
|
3
|
+
*
|
|
4
|
+
* ── 根因(issue #16,2026-09-16)────────────────────────────────────────
|
|
5
|
+
* dsh 宿主 `@deepseek-ai/dsh-system-prompt` 的 `interpolate()` 会对**每个
|
|
6
|
+
* section / context** 文本做严格 `{{variable}}` 插值,且**四类一律 throw**:
|
|
7
|
+
* ① `{{` 之后能找到 `}}` 但不成简单组(GROUP_AT = /^\{\{([^{}]*)\}\}/ 不匹配)
|
|
8
|
+
* ② 组成立但名不匹配 /^[a-z][a-z0-9_]*$/(如 `{{.Architecture}}`)
|
|
9
|
+
* ③ 名合法但未注册(如 `{{name}}`)
|
|
10
|
+
* ④ 已注册但值为 undefined
|
|
11
|
+
* `renderContextSections()` 逐 context 调用它,throw 直接冒泡到
|
|
12
|
+
* `system-prompt/assemble` → **该轮请求整体失败**。
|
|
13
|
+
*
|
|
14
|
+
* ── 伤害路径 ───────────────────────────────────────────────────────────
|
|
15
|
+
* 自动记忆把用户命令原样沉淀(如 `docker inspect --format '{{.Architecture}}'`)
|
|
16
|
+
* → auto-recall 把含裸 `{{` 的预览推入 `assembly.contexts`
|
|
17
|
+
* → 宿主每轮 assemble 必抛 → **会话永久不可用**(记忆永久在库,非偶发故障)。
|
|
18
|
+
*
|
|
19
|
+
* ── 处置:为何只在注入边界转义,不在写入侧 ────────────────────────────
|
|
20
|
+
* ① 记忆真源必须保真:`{{.Architecture}}` 是用户命令原文,写入侧转义会
|
|
21
|
+
* 不可逆失真,且 cg(op=read) / 工具面 / 检索都依赖原文(= 污染真源);
|
|
22
|
+
* ② 伤害面就是「注入到 prompt 的文本」,在注入边界处理即**最小充分**;
|
|
23
|
+
* ③ 与写入侧 desensitize 不冲突:脱敏是**隐私**要求(不许落盘),
|
|
24
|
+
* 转义是**渲染安全**要求(落盘保真、渲染时规避)——层次不同。
|
|
25
|
+
*
|
|
26
|
+
* ── 转义策略:确保文本中不出现连续两个 `{` ────────────────────────────
|
|
27
|
+
* 依据(宿主源码 `lib/index.js:109-116`):`interpolate` 以
|
|
28
|
+
* `text.indexOf("{{")` 为**唯一扫描锚点**;破坏 `{{` 序列后循环不进入,
|
|
29
|
+
* 文本走 `text.slice(last)` 原样返回。
|
|
30
|
+
* · `}}` 无需处理——它只在 `{{` 成组时参与解析,锚点已破即无意义;
|
|
31
|
+
* · 逐对打断(而非 `split('{{').join(...)`):后者对 `{{{a}}}` 会产出
|
|
32
|
+
* `{ {{a}}}`——新锚点仍在(相邻 `{` 重新合成),不幂等也不安全;
|
|
33
|
+
* · 跨 context 拼接安全:`joinContextSections` 以 `"\n\n"` 分隔并带固定
|
|
34
|
+
* 前缀(`lib/index.js:85-87`,前缀以 `.` 结尾),边界不会合成新 `{{`;
|
|
35
|
+
* · 为何不用零宽字符:显示上「看起来一样」但复制会带入不可见字符
|
|
36
|
+
* (终端粘贴即出错)——诚实性优先,宁可让改写可见。
|
|
37
|
+
*
|
|
38
|
+
* 幂等:结果中不存在 `{{`,重复调用结果不变。
|
|
39
|
+
* 边界:本函数只服务**注入到宿主 prompt 的文本**;记忆真源与工具返回原文
|
|
40
|
+
* 一律不动(工具结果不进 assembly 插值面)。
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/** 宿主严格模板的扫描锚点。 */
|
|
44
|
+
const TEMPLATE_OPEN = '{{'
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 把文本中每一对相邻的 `{` 打断(插入半角空格),使其不再包含 `{{`。
|
|
48
|
+
*
|
|
49
|
+
* 不含 `{{` 的文本**原样返回**(零改写,保真)。
|
|
50
|
+
* 例:`{{.Architecture}}` → `{ {.Architecture}}`;`{{{a}}}` → `{ { {a}}}`。
|
|
51
|
+
*/
|
|
52
|
+
export function escapePromptBraces(text: string): string {
|
|
53
|
+
if (!text.includes(TEMPLATE_OPEN)) return text
|
|
54
|
+
let out = ''
|
|
55
|
+
for (let i = 0; i < text.length; i++) {
|
|
56
|
+
const ch = text.charAt(i)
|
|
57
|
+
out += ch
|
|
58
|
+
// 该 `{` 与下一个字符构成锚点 → 立即插入空格打断
|
|
59
|
+
if (ch === '{' && text.charAt(i + 1) === '{') out += ' '
|
|
60
|
+
}
|
|
61
|
+
return out
|
|
62
|
+
}
|
package/src/lib/python_path.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* python_path.ts —— Python 解释器的**平台感知**解析(issue #19)
|
|
3
|
-
*
|
|
4
|
-
* 要解决的问题(首次安装即失效,且不自愈)
|
|
5
|
-
* ------------------------------------------------
|
|
6
|
-
* 解释器默认值此前是**字面量 `'python'`**。Linux/macOS 按 PEP 394 只要求提供
|
|
7
|
-
* `python3`——发行版默认状态就是这样,不是用户把环境装坏了。于是 `spawn('python')`
|
|
8
|
-
* 抛 `ENOENT`,桥重试 8 次后进入 failed 终态:插件看起来装好了,工具不注册、
|
|
9
|
-
* 记忆只读(`guest`)、必须重启 DSH 才会再试一次。同时日志被
|
|
10
|
-
* `灵枢调用超时(60000ms):initialize` 刷屏,把人引向「超时/性能」的错误方向,
|
|
11
|
-
* 而第一因是更早一行不起眼的 `spawn … ENOENT`。
|
|
12
|
-
* Windows 上 `python` 通常存在,所以该缺陷只在作者机器之外暴露。
|
|
13
|
-
*
|
|
14
|
-
* 解析顺序(高 → 低)
|
|
15
|
-
* ------------------------------------------------
|
|
16
|
-
* ① `config.python` —— 用户显式配置,**原样尊重**(本模块不介入)
|
|
17
|
-
* ② env `MDCG_PYTHON` —— 容器 / CI 固定解释器;命名风格与既有
|
|
18
|
-
* `MDCG_ROOT` / `MDCG_CHILD_CWD` 一致
|
|
19
|
-
* ③ 平台默认:`win32` → `python`(**逐字节保持既有行为**);其它 → `python3`
|
|
20
|
-
*
|
|
21
|
-
* 边界(诚实声明,勿据此扩大承诺)
|
|
22
|
-
* ------------------------------------------------
|
|
23
|
-
* - **不做** PATH 扫描式候选回退(`python3` → `python3.12` → `python` 取首个存在):
|
|
24
|
-
* 隐式行为在跨平台/多环境(conda、pyenv、WSL)下难以预测,且失败模式从
|
|
25
|
-
* 「明确 ENOENT」退化为「悄悄选了另一个解释器」。解释器名特殊时请显式配置
|
|
26
|
-
* 或设 `MDCG_PYTHON`。
|
|
27
|
-
* - md_cg 侧**不挑** Python 版本:只要存在解释器即可(issue 复现方实测 conda 的
|
|
28
|
-
* `python3.12` 亦正常握手)。
|
|
29
|
-
* - 本模块只**解析名字**,不校验可执行文件是否真的存在(校验属调用方职责,
|
|
30
|
-
* 且 `stat` 结果会被 PATH/沙箱差异推翻)。
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/** 解释器覆盖的环境变量名(与 MDCG_ROOT 等同风格,便于容器固定)。 */
|
|
34
|
-
export const PYTHON_ENV_VAR = 'MDCG_PYTHON'
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 解析默认 Python 解释器(issue #19)。
|
|
38
|
-
*
|
|
39
|
-
* 参数刻意做成**可注入**(platform / env)而非直接读全局:默认值此前写死导致的
|
|
40
|
-
* 正是「不可测 → 只在作者机器上成立」,注入后回归测试可在任意平台断言三分支。
|
|
41
|
-
*/
|
|
42
|
-
export function defaultPython(
|
|
43
|
-
platform: string = process.platform,
|
|
44
|
-
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
45
|
-
): string {
|
|
46
|
-
const explicit = (env[PYTHON_ENV_VAR] ?? '').trim()
|
|
47
|
-
if (explicit) return explicit
|
|
48
|
-
return platform === 'win32' ? 'python' : 'python3'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** 自检命令文案(按平台给出**可照抄**的写法,issue #19 影响面第 4 条)。 */
|
|
52
|
-
export function selfCheckCommand(python: string = defaultPython()): string {
|
|
53
|
-
return `${python} -m md_cg.mcp_server`
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* spawn 失败(ENOENT)时的修复指引。
|
|
58
|
-
*
|
|
59
|
-
* 为什么值得单列一条日志:该缺陷的原始日志把「解释器名不匹配」伪装成
|
|
60
|
-
* 「调用超时」,用户按超时方向排查只会浪费一轮;把成因与三条修法写在
|
|
61
|
-
* **同一行**,可诊断性直接闭环。
|
|
62
|
-
*/
|
|
63
|
-
export function explainMissingPython(python: string): string {
|
|
64
|
-
return `解释器「${python}」不可执行(ENOENT)。Linux/macOS 发行版按 PEP 394 只提供 `
|
|
65
|
-
+ 'python3(这是默认状态,不是环境损坏)。修法(任一):'
|
|
66
|
-
+ "① cordis.yml 的 config.python 设为 'python3'(优先级最高);"
|
|
67
|
-
+ '② 设环境变量 MDCG_PYTHON=python3(容器/CI 推荐);'
|
|
68
|
-
+ '③ 确认 python3 在 PATH 中(which python3)。改完需重启 DSH。'
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export default { defaultPython, selfCheckCommand, explainMissingPython, PYTHON_ENV_VAR }
|
|
1
|
+
/**
|
|
2
|
+
* python_path.ts —— Python 解释器的**平台感知**解析(issue #19)
|
|
3
|
+
*
|
|
4
|
+
* 要解决的问题(首次安装即失效,且不自愈)
|
|
5
|
+
* ------------------------------------------------
|
|
6
|
+
* 解释器默认值此前是**字面量 `'python'`**。Linux/macOS 按 PEP 394 只要求提供
|
|
7
|
+
* `python3`——发行版默认状态就是这样,不是用户把环境装坏了。于是 `spawn('python')`
|
|
8
|
+
* 抛 `ENOENT`,桥重试 8 次后进入 failed 终态:插件看起来装好了,工具不注册、
|
|
9
|
+
* 记忆只读(`guest`)、必须重启 DSH 才会再试一次。同时日志被
|
|
10
|
+
* `灵枢调用超时(60000ms):initialize` 刷屏,把人引向「超时/性能」的错误方向,
|
|
11
|
+
* 而第一因是更早一行不起眼的 `spawn … ENOENT`。
|
|
12
|
+
* Windows 上 `python` 通常存在,所以该缺陷只在作者机器之外暴露。
|
|
13
|
+
*
|
|
14
|
+
* 解析顺序(高 → 低)
|
|
15
|
+
* ------------------------------------------------
|
|
16
|
+
* ① `config.python` —— 用户显式配置,**原样尊重**(本模块不介入)
|
|
17
|
+
* ② env `MDCG_PYTHON` —— 容器 / CI 固定解释器;命名风格与既有
|
|
18
|
+
* `MDCG_ROOT` / `MDCG_CHILD_CWD` 一致
|
|
19
|
+
* ③ 平台默认:`win32` → `python`(**逐字节保持既有行为**);其它 → `python3`
|
|
20
|
+
*
|
|
21
|
+
* 边界(诚实声明,勿据此扩大承诺)
|
|
22
|
+
* ------------------------------------------------
|
|
23
|
+
* - **不做** PATH 扫描式候选回退(`python3` → `python3.12` → `python` 取首个存在):
|
|
24
|
+
* 隐式行为在跨平台/多环境(conda、pyenv、WSL)下难以预测,且失败模式从
|
|
25
|
+
* 「明确 ENOENT」退化为「悄悄选了另一个解释器」。解释器名特殊时请显式配置
|
|
26
|
+
* 或设 `MDCG_PYTHON`。
|
|
27
|
+
* - md_cg 侧**不挑** Python 版本:只要存在解释器即可(issue 复现方实测 conda 的
|
|
28
|
+
* `python3.12` 亦正常握手)。
|
|
29
|
+
* - 本模块只**解析名字**,不校验可执行文件是否真的存在(校验属调用方职责,
|
|
30
|
+
* 且 `stat` 结果会被 PATH/沙箱差异推翻)。
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** 解释器覆盖的环境变量名(与 MDCG_ROOT 等同风格,便于容器固定)。 */
|
|
34
|
+
export const PYTHON_ENV_VAR = 'MDCG_PYTHON'
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 解析默认 Python 解释器(issue #19)。
|
|
38
|
+
*
|
|
39
|
+
* 参数刻意做成**可注入**(platform / env)而非直接读全局:默认值此前写死导致的
|
|
40
|
+
* 正是「不可测 → 只在作者机器上成立」,注入后回归测试可在任意平台断言三分支。
|
|
41
|
+
*/
|
|
42
|
+
export function defaultPython(
|
|
43
|
+
platform: string = process.platform,
|
|
44
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
45
|
+
): string {
|
|
46
|
+
const explicit = (env[PYTHON_ENV_VAR] ?? '').trim()
|
|
47
|
+
if (explicit) return explicit
|
|
48
|
+
return platform === 'win32' ? 'python' : 'python3'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** 自检命令文案(按平台给出**可照抄**的写法,issue #19 影响面第 4 条)。 */
|
|
52
|
+
export function selfCheckCommand(python: string = defaultPython()): string {
|
|
53
|
+
return `${python} -m md_cg.mcp_server`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* spawn 失败(ENOENT)时的修复指引。
|
|
58
|
+
*
|
|
59
|
+
* 为什么值得单列一条日志:该缺陷的原始日志把「解释器名不匹配」伪装成
|
|
60
|
+
* 「调用超时」,用户按超时方向排查只会浪费一轮;把成因与三条修法写在
|
|
61
|
+
* **同一行**,可诊断性直接闭环。
|
|
62
|
+
*/
|
|
63
|
+
export function explainMissingPython(python: string): string {
|
|
64
|
+
return `解释器「${python}」不可执行(ENOENT)。Linux/macOS 发行版按 PEP 394 只提供 `
|
|
65
|
+
+ 'python3(这是默认状态,不是环境损坏)。修法(任一):'
|
|
66
|
+
+ "① cordis.yml 的 config.python 设为 'python3'(优先级最高);"
|
|
67
|
+
+ '② 设环境变量 MDCG_PYTHON=python3(容器/CI 推荐);'
|
|
68
|
+
+ '③ 确认 python3 在 PATH 中(which python3)。改完需重启 DSH。'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default { defaultPython, selfCheckCommand, explainMissingPython, PYTHON_ENV_VAR }
|
package/src/lib/roleplay_web.ts
CHANGED
|
@@ -101,6 +101,7 @@ footer button:disabled { opacity:.5; cursor:wait; }
|
|
|
101
101
|
<button onclick="showNewRole()">+ 新角色</button>
|
|
102
102
|
<button onclick="openRoleDetail()">⚙ 详情</button>
|
|
103
103
|
<button onclick="openTrans()">🌐 翻译</button>
|
|
104
|
+
<button onclick="setEditKey()" title="编辑密钥:服务端 ROLEPLAY_EDIT_KEY 的值(创建/保存角色与翻译需要;留空清除)">🔑</button>
|
|
104
105
|
</div>
|
|
105
106
|
</header>
|
|
106
107
|
<main id="chat"><div class="hint">选择角色,开始对话。角色回应由灵枢角色扮演引擎生成(白箱优先,LLM 续答)。</div></main>
|
|
@@ -191,9 +192,27 @@ try {
|
|
|
191
192
|
localStorage.setItem('lingshu_client_id', CLIENT_ID);
|
|
192
193
|
}
|
|
193
194
|
} catch (e) { /* localStorage 不可用(隐私模式)→ 空,服务端落 shared */ }
|
|
195
|
+
// V22 修复(缺陷 src/lib/roleplay_web.ts:338):编辑密钥携带途径——
|
|
196
|
+
// 服务端写操作 fail-closed 要求 x-edit-key 头(P1-2),但此前页面既无输入
|
|
197
|
+
// 密钥的途径、写 POST 又全用裸 headers → 全部编辑恒 403 不可用。现在
|
|
198
|
+
// 🔑 按钮(setEditKey → prompt)把密钥存 localStorage,apiHeaders 统一注入。
|
|
199
|
+
const EDIT_KEY_STORE = 'lingshu_edit_key';
|
|
200
|
+
function editKey() {
|
|
201
|
+
try { return localStorage.getItem(EDIT_KEY_STORE) || ''; } catch (e) { return ''; }
|
|
202
|
+
}
|
|
203
|
+
function setEditKey() {
|
|
204
|
+
const k = prompt('编辑密钥(服务端环境变量 ROLEPLAY_EDIT_KEY 的值;留空清除):', editKey());
|
|
205
|
+
if (k === null) return; // 取消不动
|
|
206
|
+
try {
|
|
207
|
+
if (k.trim()) localStorage.setItem(EDIT_KEY_STORE, k.trim());
|
|
208
|
+
else localStorage.removeItem(EDIT_KEY_STORE);
|
|
209
|
+
} catch (e) { /* localStorage 不可用 → 忽略 */ }
|
|
210
|
+
}
|
|
194
211
|
function apiHeaders(extra) {
|
|
195
212
|
const h = { 'Content-Type': 'application/json' };
|
|
196
213
|
if (CLIENT_ID) h['x-client-id'] = CLIENT_ID;
|
|
214
|
+
const ek = editKey();
|
|
215
|
+
if (ek) h['x-edit-key'] = ek; // V22:写操作鉴权头(无则服务端 403)
|
|
197
216
|
return Object.assign(h, extra || {});
|
|
198
217
|
}
|
|
199
218
|
// —— 内容分级:年龄门控 + NSFW 检测(法律与协议保护)——
|
|
@@ -334,11 +353,18 @@ async function saveRoleDetail() {
|
|
|
334
353
|
const scenario = $('rd_scenario').value.trim();
|
|
335
354
|
const first_mes = $('rd_first').value.trim();
|
|
336
355
|
const nsfw = $('rd_nsfw_chk').checked;
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
356
|
+
// V22 修复(缺陷 :338):此前 meta POST ①裸 headers(无 x-edit-key → 恒 403)
|
|
357
|
+
// ②响应完全不检查(fetch 对 403 不 reject)→ 无条件「已保存」= 虚假成功
|
|
358
|
+
// (服务端 403 在写盘之前 return,数据从未落盘)。现在统一走 apiHeaders()
|
|
359
|
+
// 并逐段检查 ok:任一失败 alert 服务端原因并中止,绝不报「已保存」。
|
|
360
|
+
let m;
|
|
361
|
+
try {
|
|
362
|
+
m = await fetch('/roleplay/api/roles/' + encodeURIComponent(role) + '/meta', {
|
|
363
|
+
method: 'POST', headers: apiHeaders(),
|
|
364
|
+
body: JSON.stringify({ name, scenario, first_mes, nsfw }),
|
|
365
|
+
}).then(x => x.json());
|
|
366
|
+
} catch (e) { m = { ok: false, error: '网络错误:' + e }; }
|
|
367
|
+
if (!m || !m.ok) { alert((m && m.error) || '保存失败(角色信息)'); return; }
|
|
342
368
|
// 当前页签的条目
|
|
343
369
|
const items = [];
|
|
344
370
|
document.querySelectorAll('#rd_items .rd-row').forEach(row => {
|
|
@@ -347,10 +373,14 @@ async function saveRoleDetail() {
|
|
|
347
373
|
const tags = row.querySelector('.rd-tags').value.split(/[,,]/).map(s => s.trim()).filter(Boolean);
|
|
348
374
|
if (content) items.push({ content, importance: imp, tags });
|
|
349
375
|
});
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
376
|
+
let r;
|
|
377
|
+
try {
|
|
378
|
+
r = await fetch('/roleplay/api/roles/' + encodeURIComponent(role) + '/import', {
|
|
379
|
+
method: 'POST', headers: apiHeaders(),
|
|
380
|
+
body: JSON.stringify({ kind: rdKind, items }),
|
|
381
|
+
}).then(x => x.json());
|
|
382
|
+
} catch (e) { r = { ok: false, error: '网络错误:' + e }; }
|
|
383
|
+
if (!r || !r.ok) { alert((r && r.error) || '保存失败(' + rdKind + ')'); return; }
|
|
354
384
|
addMsg('角色「' + role + '」已保存:' + name + ' · ' + rdKind + ' ' + items.length + ' 条' + (nsfw ? ' · NSFW' : ''), 'bot');
|
|
355
385
|
closeRoleDetail();
|
|
356
386
|
await refreshRoles();
|
|
@@ -395,21 +425,21 @@ async function saveTrans() {
|
|
|
395
425
|
});
|
|
396
426
|
const mode = (document.querySelector('input[name="tpmode"]:checked') || {}).value || 'input_only';
|
|
397
427
|
const r = await fetch('/roleplay/api/translate', {
|
|
398
|
-
method: 'POST', headers:
|
|
428
|
+
method: 'POST', headers: apiHeaders(),
|
|
399
429
|
body: JSON.stringify({ role_id: role, pairs, mode }),
|
|
400
430
|
}).then(x => x.json());
|
|
401
431
|
if (r.ok) {
|
|
402
432
|
transMode = r.mode;
|
|
403
433
|
closeTrans();
|
|
404
434
|
addMsg('翻译配置已保存:' + r.pairs.length + ' 组词对 · ' + (r.mode === 'bidirectional' ? '双向翻译' : '仅输入翻译'), 'bot');
|
|
405
|
-
} else alert(r.error || '保存失败');
|
|
435
|
+
} else alert((r.error || '保存失败') + (editKey() ? '' : '(可点右上角 🔑 输入编辑密钥)'));
|
|
406
436
|
}
|
|
407
437
|
async function createRole() {
|
|
408
438
|
const body = { role_id: $('nr_id').value.trim(), name: $('nr_name').value.trim(), scenario: $('nr_scenario').value.trim(), first_mes: $('nr_first').value.trim() };
|
|
409
439
|
if (!body.role_id) { alert('需要角色 ID'); return; }
|
|
410
|
-
const r = await fetch('/roleplay/api/roles', { method:'POST', headers:
|
|
440
|
+
const r = await fetch('/roleplay/api/roles', { method:'POST', headers: apiHeaders(), body: JSON.stringify(body) }).then(x => x.json());
|
|
411
441
|
if (r.ok) { closeNewRole(); await refreshRoles(); addMsg('角色「' + (body.name || body.role_id) + '」已创建,可以开始对话了', 'bot'); }
|
|
412
|
-
else alert(r.error || '创建失败');
|
|
442
|
+
else alert((r.error || '创建失败') + (editKey() ? '' : '(可点右上角 🔑 输入编辑密钥)'));
|
|
413
443
|
}
|
|
414
444
|
var input = document.getElementById('input');
|
|
415
445
|
var chat = document.getElementById('chat');
|
|
@@ -476,7 +506,9 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
476
506
|
// P1 修复(GPT 审查):
|
|
477
507
|
// ① 请求体大小限制(此前 for-await 无限累加,恶意请求可制造内存压力)
|
|
478
508
|
const readBody = async (req, maxBytes = 1_000_000) => {
|
|
479
|
-
|
|
509
|
+
// P2-12(批次 30):Buffer 收集后统一 utf-8 解码——旧写法
|
|
510
|
+
// body += chunk 在多字节字符跨 chunk 时产生替换符截断。
|
|
511
|
+
const chunks = [];
|
|
480
512
|
let size = 0;
|
|
481
513
|
for await (const chunk of req) {
|
|
482
514
|
size += chunk.length;
|
|
@@ -485,20 +517,28 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
485
517
|
err.status = 413;
|
|
486
518
|
throw err;
|
|
487
519
|
}
|
|
488
|
-
|
|
520
|
+
chunks.push(chunk);
|
|
489
521
|
}
|
|
490
|
-
return
|
|
522
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
491
523
|
};
|
|
492
|
-
// ②
|
|
493
|
-
//
|
|
494
|
-
//
|
|
524
|
+
// ② 编辑鉴权(P1-2,批次 26 外部审查报告):fail-closed——未配置
|
|
525
|
+
// ROLEPLAY_EDIT_KEY 时**拒绝全部写操作**(旧语义「未配置=开放」是
|
|
526
|
+
// 本地开发便利,但网页面板是唯一对浏览器开放的面,默认无鉴权 =
|
|
527
|
+
// 任意来源可改写角色数据)。403 文案引导配置:设 ROLEPLAY_EDIT_KEY
|
|
528
|
+
// 并在请求带 x-edit-key 头即可恢复编辑。
|
|
495
529
|
const EDIT_KEY = process.env.ROLEPLAY_EDIT_KEY || '';
|
|
496
530
|
const requireEditKey = (req) => {
|
|
497
531
|
if (!EDIT_KEY)
|
|
498
|
-
return
|
|
532
|
+
return false; // P1-2:未配置 = 拒绝(fail-closed)
|
|
499
533
|
const h = (req.headers && req.headers['x-edit-key']) || '';
|
|
500
534
|
return h === EDIT_KEY;
|
|
501
535
|
};
|
|
536
|
+
// V21-1(批次 34,外部报告):真分支此前误写自调用(无限递归 → 配了
|
|
537
|
+
// key 反而 500 且泄露内部异常文本)。两分支都是终止文案:已配置 =
|
|
538
|
+
// 「缺 x-edit-key 头」;未配置 = 「服务端需配置」引导。
|
|
539
|
+
const editKeyHint = () => EDIT_KEY
|
|
540
|
+
? '缺少编辑密钥(x-edit-key 头)'
|
|
541
|
+
: '编辑未开放:服务端需配置环境变量 ROLEPLAY_EDIT_KEY,请求需带 x-edit-key 头(P1-2 fail-closed)';
|
|
502
542
|
const roleDataDir = join(dirname(config.dbPath), 'roleplay_data');
|
|
503
543
|
try {
|
|
504
544
|
mkdirSync(join(roleDataDir, 'roleplay'), { recursive: true });
|
|
@@ -512,6 +552,7 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
512
552
|
}
|
|
513
553
|
catch { /* 忽略 */ }
|
|
514
554
|
const transcriptFile = (roleId, clientId) => join(transcriptsDir, `${roleId.replace(/[^\w.-]/g, '_')}__${clientId}.jsonl`);
|
|
555
|
+
const TRANSCRIPT_TAIL_MAX = 500; // P2-9(批次 31):返回最近 500 条
|
|
515
556
|
const readTranscript = (roleId, clientId = 'shared') => {
|
|
516
557
|
const f = transcriptFile(roleId, clientId);
|
|
517
558
|
if (!existsSync(f))
|
|
@@ -525,7 +566,9 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
525
566
|
}
|
|
526
567
|
catch { /* 跳过坏行 */ }
|
|
527
568
|
}
|
|
528
|
-
|
|
569
|
+
// P2-9:无上限返回会让响应体随会话长度线性增长——只回最近尾部。
|
|
570
|
+
return out.length > TRANSCRIPT_TAIL_MAX
|
|
571
|
+
? out.slice(out.length - TRANSCRIPT_TAIL_MAX) : out;
|
|
529
572
|
};
|
|
530
573
|
const appendTranscript = (roleId, entry, clientId = 'shared') => {
|
|
531
574
|
try {
|
|
@@ -551,16 +594,28 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
551
594
|
// 「角色字典」视角;写入保持原顶层结构(嵌套则写回 meta 内),读写一致——
|
|
552
595
|
// 此前读兼容嵌套但写永远写根,保存成功但列表读旧值。
|
|
553
596
|
const roleMetaFile = join(roleDataDir, 'roleplay', '_roles.json');
|
|
597
|
+
// P1-3(批次 26 外部审查报告):角色 id 白名单——role 从 URL 提取后
|
|
598
|
+
// 直接作 meta 对象键,`__proto__` 键会劫持 Object.prototype(污染插件
|
|
599
|
+
// 与 DSH 宿主共享的同进程对象)。白名单字符集 + 显式拒绝危险键。
|
|
600
|
+
const _BAD_ROLE_IDS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
601
|
+
const validRoleId = (role) => typeof role === 'string'
|
|
602
|
+
&& /^[A-Za-z0-9_.-]{1,64}$/.test(role)
|
|
603
|
+
&& !_BAD_ROLE_IDS.has(role);
|
|
604
|
+
// meta 字典统一 null 原型——即使存量文件已被写入危险键,
|
|
605
|
+
// meta['__proto__'] 也只是普通 own 属性,不再劫持原型链。
|
|
606
|
+
const toNullProto = (o) => (o && typeof o === 'object')
|
|
607
|
+
? Object.assign(Object.create(null), o)
|
|
608
|
+
: o;
|
|
554
609
|
const readRoleMeta = () => {
|
|
555
610
|
try {
|
|
556
611
|
const raw = JSON.parse(readFileSync(roleMetaFile, 'utf8'));
|
|
557
612
|
if (raw && typeof raw === 'object'
|
|
558
613
|
&& raw.meta && typeof raw.meta === 'object')
|
|
559
|
-
return raw.meta; // 嵌套格式 → meta 内角色字典
|
|
560
|
-
return raw;
|
|
614
|
+
return toNullProto(raw.meta); // 嵌套格式 → meta 内角色字典
|
|
615
|
+
return toNullProto(raw);
|
|
561
616
|
}
|
|
562
617
|
catch {
|
|
563
|
-
return
|
|
618
|
+
return Object.create(null);
|
|
564
619
|
}
|
|
565
620
|
};
|
|
566
621
|
const writeRoleMeta = (flat) => {
|
|
@@ -595,8 +650,12 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
595
650
|
}
|
|
596
651
|
};
|
|
597
652
|
const writeTransSettings = (s) => {
|
|
653
|
+
// P2-10(批次 31):tmp+rename 原子写(与 writeRoleMeta 同款)——
|
|
654
|
+
// 直接 writeFileSync 并发/中断会写坏 JSON,后续读静默丢配置。
|
|
598
655
|
try {
|
|
599
|
-
|
|
656
|
+
const tmp = transSettingsFile + '.tmp';
|
|
657
|
+
writeFileSync(tmp, JSON.stringify(s, null, 2), 'utf8');
|
|
658
|
+
renameSync(tmp, transSettingsFile);
|
|
600
659
|
}
|
|
601
660
|
catch { /* 忽略 */ }
|
|
602
661
|
};
|
|
@@ -606,6 +665,8 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
606
665
|
return Array.isArray(t) ? t : [];
|
|
607
666
|
};
|
|
608
667
|
const setTranslations = (roleId, pairs) => {
|
|
668
|
+
if (!validRoleId(roleId))
|
|
669
|
+
return; // P1-3:非法角色 id 拒写(防原型污染)
|
|
609
670
|
const meta = readRoleMeta();
|
|
610
671
|
if (!meta[roleId])
|
|
611
672
|
meta[roleId] = { created_at: Date.now() / 1000, name: roleId };
|
|
@@ -668,7 +729,7 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
668
729
|
// P1 修复(GPT 审查):写操作鉴权(ROLEPLAY_EDIT_KEY)+ 请求体大小限制
|
|
669
730
|
if (!requireEditKey(req)) {
|
|
670
731
|
res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
671
|
-
res.end(JSON.stringify({ ok: false, error:
|
|
732
|
+
res.end(JSON.stringify({ ok: false, error: editKeyHint() }));
|
|
672
733
|
return;
|
|
673
734
|
}
|
|
674
735
|
let body;
|
|
@@ -726,7 +787,7 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
726
787
|
// P1 修复(GPT 审查):写操作鉴权(ROLEPLAY_EDIT_KEY)+ 请求体大小限制
|
|
727
788
|
if (!requireEditKey(req)) {
|
|
728
789
|
res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
729
|
-
res.end(JSON.stringify({ ok: false, error:
|
|
790
|
+
res.end(JSON.stringify({ ok: false, error: editKeyHint() }));
|
|
730
791
|
return;
|
|
731
792
|
}
|
|
732
793
|
let body;
|
|
@@ -740,6 +801,15 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
740
801
|
}
|
|
741
802
|
const p = JSON.parse(body);
|
|
742
803
|
const role = decodeURIComponent(url.pathname.split('/')[4]);
|
|
804
|
+
if (!validRoleId(role)) {
|
|
805
|
+
// P1-3:__proto__/constructor/prototype 及越界字符拒绝
|
|
806
|
+
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
807
|
+
res.end(JSON.stringify({ ok: false, error: '非法角色 id(白名单 ^[A-Za-z0-9_.-]{1,64}$)' }));
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
// P2-11(批次 30 注记):本读改写段为同步执行(中间无
|
|
811
|
+
// await)——node 单 tick 内不会交错;若未来在此段引入
|
|
812
|
+
// await,须先加写队列/文件锁(并发丢更新防线)。
|
|
743
813
|
const meta = readRoleMeta();
|
|
744
814
|
if (!meta[role])
|
|
745
815
|
meta[role] = { created_at: Date.now() / 1000 };
|
|
@@ -769,6 +839,14 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
769
839
|
}
|
|
770
840
|
const p = JSON.parse(body);
|
|
771
841
|
const role = p.role_id || 'protocol-guide';
|
|
842
|
+
// P2-23(批次 30):chat 的 role_id 进 node_id 模板——
|
|
843
|
+
// 纵深防御:与 /meta 同款白名单(当前模板前缀使穿越
|
|
844
|
+
// 不可达,但模板改动即破——入口统一卡死)
|
|
845
|
+
if (!validRoleId(role)) {
|
|
846
|
+
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
847
|
+
res.end(JSON.stringify({ ok: false, error: '非法角色 id(白名单 ^[A-Za-z0-9_.-]{1,64}$)' }));
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
772
850
|
// P1 完善(会话隔离):按客户端实例隔离 session 与转录
|
|
773
851
|
const cid = clientIdOf(req);
|
|
774
852
|
// —— 服务端内容分级硬拦截(不依赖前端,法律与协议保护)——
|
|
@@ -823,7 +901,7 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
823
901
|
// P1 修复(GPT 审查):写操作鉴权(ROLEPLAY_EDIT_KEY)+ 请求体大小限制
|
|
824
902
|
if (!requireEditKey(req)) {
|
|
825
903
|
res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
826
|
-
res.end(JSON.stringify({ ok: false, error:
|
|
904
|
+
res.end(JSON.stringify({ ok: false, error: editKeyHint() }));
|
|
827
905
|
return;
|
|
828
906
|
}
|
|
829
907
|
let body;
|
|
@@ -837,6 +915,15 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
837
915
|
}
|
|
838
916
|
const p = JSON.parse(body);
|
|
839
917
|
const role = p.role_id || 'protocol-guide';
|
|
918
|
+
// P1-3 补卡(translate POST):与 /meta、/chat 同款白名单——
|
|
919
|
+
// 此前不校验即 setTranslations(内部白名单不匹配**静默 return**,
|
|
920
|
+
// 中文 id 词对永不落盘)+ settings[role] 直接键赋值('__proto__'
|
|
921
|
+
// 走原型 setter 连 mode 都丢),却仍回 ok:true = 虚假成功。
|
|
922
|
+
if (!validRoleId(role)) {
|
|
923
|
+
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
924
|
+
res.end(JSON.stringify({ ok: false, error: '非法角色 id(白名单 ^[A-Za-z0-9_.-]{1,64}$)' }));
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
840
927
|
const pairs = (Array.isArray(p.pairs) ? p.pairs : [])
|
|
841
928
|
.map((x) => ({ real: String(x.real || '').trim(), virtual: String(x.virtual || '').trim(), note: String(x.note || '').trim() }))
|
|
842
929
|
.filter((x) => x.real && x.virtual);
|
|
@@ -859,7 +946,7 @@ export async function installRoleplayWeb(ctx, capability, config, disposers, mdc
|
|
|
859
946
|
// P1 修复(GPT 审查):写操作鉴权(ROLEPLAY_EDIT_KEY)+ 请求体大小限制
|
|
860
947
|
if (!requireEditKey(req)) {
|
|
861
948
|
res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
862
|
-
res.end(JSON.stringify({ ok: false, error:
|
|
949
|
+
res.end(JSON.stringify({ ok: false, error: editKeyHint() }));
|
|
863
950
|
return;
|
|
864
951
|
}
|
|
865
952
|
let body;
|
package/src/lib/token_store.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
import { spawnSync } from 'node:child_process'
|
|
30
30
|
import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
31
31
|
import { homedir } from 'node:os'
|
|
32
|
-
import { dirname, join } from 'node:path'
|
|
32
|
+
import { dirname, join, resolve } from 'node:path'
|
|
33
33
|
import { pythonPathValue, runRoot } from './datapath.js'
|
|
34
34
|
|
|
35
35
|
/** 凭据来源(用于启动日志与故障定位)。 */
|
|
@@ -68,9 +68,19 @@ export interface ResolveTokenOptions {
|
|
|
68
68
|
keyringPath?: string
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
/**
|
|
71
|
+
/** 辅助存储根(密钥/令牌/信任/理论/心跳):与 md_cg 的 `datapath.aux_root()` 同口径。
|
|
72
|
+
*
|
|
73
|
+
* 默认 `~/.mdcg`(历史值,**逐字保留**——改默认会让存量密钥/令牌失联);
|
|
74
|
+
* `MDCG_AUX_ROOT` 可把它们整体搬走(沙箱/多用户/与记忆真源同处的场景)。
|
|
75
|
+
* 与 `config.mdcg.root`(记忆真源)有意分离:身份与信任不随认知图迁移。 */
|
|
76
|
+
export function auxRoot(): string {
|
|
77
|
+
const env = (process.env.MDCG_AUX_ROOT ?? '').trim()
|
|
78
|
+
return env ? resolve(env) : join(homedir(), '.mdcg')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** 默认密钥环路径:与 md_cg 的 `_tokens.json` 同目录(aux 根下,见 auxRoot())。 */
|
|
72
82
|
export function defaultKeyringPath(): string {
|
|
73
|
-
return join(
|
|
83
|
+
return join(auxRoot(), 'token')
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
/** 读取密钥环;不存在 / 不可读 / 空文件一律返回 undefined(不抛异常)。 */
|