@modusensus/dsh-mneme 0.14.0-beta.1 → 0.14.0-beta.2
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/LICENSE +21 -21
- package/README.md +830 -830
- package/assets/icon.svg +3 -3
- package/bin/cli.mjs +964 -964
- package/bin/dsh-mneme-choro.mjs +262 -262
- package/bin/dsh-mneme-mcp.mjs +510 -510
- package/bin/dsh-mneme-serve.mjs +151 -151
- package/cordis.patch.yml +21 -21
- package/docs/CONFIGURATION.md +407 -404
- package/docs/CONTINUITY.md +139 -139
- package/docs/DAEMON.md +57 -57
- package/docs/DIRECTORIES.md +114 -114
- package/docs/DISTILL.md +397 -371
- package/docs/DSH-GO.md +97 -97
- package/docs/ENTITIES.md +247 -247
- package/docs/FORGET.md +77 -77
- package/docs/KB.md +110 -110
- package/docs/LOCAL_MODEL.md +222 -222
- package/docs/SEMANTIC.md +256 -256
- package/docs/SHARE.md +552 -552
- package/docs/SLEEP.md +202 -202
- package/docs/STORAGE.md +122 -122
- package/docs/WORKFLOWS.md +366 -366
- package/lib/api-standalone.js +1007 -1007
- package/lib/api.js +3600 -3600
- package/lib/attachment-text.js +122 -122
- package/lib/bootstrap-http.js +105 -105
- package/lib/bootstrap.js +215 -215
- package/lib/candidates.js +454 -454
- package/lib/capabilities.js +819 -819
- package/lib/choro-command.js +111 -111
- package/lib/client.js +14420 -14322
- package/lib/commands.js +95 -95
- package/lib/config-keys.js +144 -144
- package/lib/config.js +1361 -1344
- package/lib/content-hash.js +54 -54
- package/lib/continuity.js +258 -258
- package/lib/date-hint.js +32 -0
- package/lib/diary/auto.js +190 -190
- package/lib/diary/compose.js +440 -440
- package/lib/diary/dir.js +59 -59
- package/lib/diary/export.js +97 -97
- package/lib/diary/index.js +26 -26
- package/lib/diary/library.js +189 -189
- package/lib/diary/qq-inbox.js +142 -142
- package/lib/diary/rollover.js +61 -61
- package/lib/diary/session-provider.js +122 -122
- package/lib/document-index.js +94 -94
- package/lib/document.js +322 -322
- package/lib/dream/clustering.js +123 -123
- package/lib/dream/decisions.js +945 -945
- package/lib/dream/narratives.js +44 -44
- package/lib/dream/sleep.js +2027 -2027
- package/lib/dream/triage.js +139 -139
- package/lib/dream.js +1879 -1879
- package/lib/dsh-go/host.js +162 -162
- package/lib/dsh-go/panel.js +2091 -2091
- package/lib/dsh-go/text.js +342 -342
- package/lib/dsh-go/views/common.js +68 -68
- package/lib/dsh-go/views/entity.js +48 -48
- package/lib/dsh-go/views/memory.js +198 -198
- package/lib/dsh-go/views/root.js +30 -30
- package/lib/dsh-go/views/settings.js +398 -398
- package/lib/dsh-go/views/status.js +51 -51
- package/lib/embedding.js +342 -342
- package/lib/entities/extractor.js +285 -285
- package/lib/fence.js +24 -24
- package/lib/graph/anchoring.js +184 -184
- package/lib/guide.js +74 -74
- package/lib/heat.js +144 -144
- package/lib/hot-memory.js +119 -119
- package/lib/image-describe.js +158 -0
- package/lib/index.js +852 -852
- package/lib/inject.js +656 -651
- package/lib/kb/index.js +309 -309
- package/lib/kb/routes.js +219 -219
- package/lib/kb/tools.js +148 -148
- package/lib/lang.js +607 -595
- package/lib/local-embedder.js +358 -358
- package/lib/maintenance.js +162 -162
- package/lib/memory-source.js +9 -9
- package/lib/mirror.js +330 -330
- package/lib/organize.js +456 -456
- package/lib/peak-hours.js +172 -172
- package/lib/pipeline-activities.js +178 -178
- package/lib/pipeline-attribution.js +165 -165
- package/lib/pipeline-command.js +279 -279
- package/lib/pipeline-confirm.js +142 -142
- package/lib/pipeline-exec.js +174 -174
- package/lib/pipeline-nudge-auto.js +129 -129
- package/lib/pipeline-nudge.js +1623 -1623
- package/lib/pipeline-observations.js +181 -181
- package/lib/pipeline-observe.js +133 -133
- package/lib/pipeline-runner.js +361 -361
- package/lib/pipeline-runs.js +442 -442
- package/lib/pipeline.js +716 -716
- package/lib/placement.js +13 -13
- package/lib/pre-inject-gate.js +354 -354
- package/lib/profile-extract.js +164 -164
- package/lib/profile-facts.js +356 -356
- package/lib/provenance-http.js +251 -251
- package/lib/quality-filter.js +162 -162
- package/lib/recall-stats.js +190 -190
- package/lib/reclaim-http.js +150 -150
- package/lib/reranker.js +269 -269
- package/lib/runtime/adopt.js +176 -176
- package/lib/runtime/closure.js +172 -172
- package/lib/runtime/download.js +247 -247
- package/lib/runtime/layout.js +265 -265
- package/lib/runtime/loader.js +252 -252
- package/lib/runtime/model-fetch.js +361 -361
- package/lib/runtime/provision.js +237 -237
- package/lib/runtime/tarball.js +130 -130
- package/lib/runtime/verify.js +223 -223
- package/lib/safe-slice.js +18 -18
- package/lib/scope-state.js +277 -277
- package/lib/scope.js +187 -187
- package/lib/search/adaptive.js +60 -60
- package/lib/search/bm25.js +96 -96
- package/lib/semantic.js +572 -572
- package/lib/sensitive-scan.js +209 -209
- package/lib/serve.js +228 -228
- package/lib/service.js +3268 -3268
- package/lib/session-gate.js +91 -91
- package/lib/session-usage.js +350 -350
- package/lib/settings.js +827 -817
- package/lib/share-http.js +281 -281
- package/lib/share-import.js +234 -234
- package/lib/share.js +335 -335
- package/lib/store.js +5895 -5895
- package/lib/summarize.js +1388 -1343
- package/lib/tools.js +1370 -1356
- package/lib/user-settings.js +230 -230
- package/lib/vector-index.js +180 -180
- package/lib/version-check.js +122 -122
- package/lib/wiki/claims.js +267 -267
- package/lib/wiki/cli-hint.js +90 -90
- package/lib/wiki/inject.js +164 -164
- package/lib/wiki/partition.js +200 -200
- package/lib/wiki/plan.js +214 -214
- package/lib/wiki/queries.js +640 -640
- package/lib/wiki/render.js +261 -261
- package/lib/wiki/scan.js +371 -371
- package/lib/wiki/t0.js +500 -500
- package/lib/wiki/t1-jobs.js +232 -232
- package/lib/wiki/t1.js +609 -609
- package/lib/write-admission.js +404 -404
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/package.json +1 -1
- package/runtime-manifest.json +526 -526
- package/scripts/benchmark-embed.js +201 -201
- package/scripts/benchmark-recall.js +249 -249
- package/scripts/benchmark-rerank.js +166 -166
- package/scripts/build-runtime-manifest.mjs +224 -224
- package/scripts/changelog-prep.mjs +91 -91
- package/scripts/check-sync.js +44 -44
- package/scripts/e2e-dsh.js +220 -220
- package/scripts/mneme-runtime.mjs +277 -277
- package/scripts/publish-gate.mjs +197 -197
- package/scripts/release-docs.mjs +210 -210
- package/scripts/release-notes.mjs +164 -164
- package/scripts/stress-dsh.js +255 -255
- package/scripts/sync-lib.js +47 -47
- package/scripts/sync-test-badge.mjs +69 -69
- package/scripts/test-count-sync.mjs +48 -48
- package/src/api-standalone.js +1007 -1007
- package/src/api.js +3600 -3600
- package/src/attachment-text.js +122 -122
- package/src/bootstrap-http.js +105 -105
- package/src/bootstrap.js +215 -215
- package/src/candidates.js +454 -454
- package/src/capabilities.js +819 -819
- package/src/choro-command.js +111 -111
- package/src/commands.js +95 -95
- package/src/config-keys.js +144 -144
- package/src/config.js +1361 -1344
- package/src/content-hash.js +54 -54
- package/src/continuity.js +258 -258
- package/src/date-hint.js +32 -0
- package/src/diary/auto.js +190 -190
- package/src/diary/compose.js +440 -440
- package/src/diary/dir.js +59 -59
- package/src/diary/export.js +97 -97
- package/src/diary/index.js +26 -26
- package/src/diary/library.js +189 -189
- package/src/diary/qq-inbox.js +142 -142
- package/src/diary/rollover.js +61 -61
- package/src/diary/session-provider.js +122 -122
- package/src/document-index.js +94 -94
- package/src/document.js +322 -322
- package/src/dream/clustering.js +123 -123
- package/src/dream/decisions.js +945 -945
- package/src/dream/narratives.js +44 -44
- package/src/dream/sleep.js +2027 -2027
- package/src/dream/triage.js +139 -139
- package/src/dream.js +1879 -1879
- package/src/dsh-go/host.js +162 -162
- package/src/dsh-go/panel.js +2091 -2091
- package/src/dsh-go/text.js +342 -342
- package/src/dsh-go/views/common.js +68 -68
- package/src/dsh-go/views/entity.js +48 -48
- package/src/dsh-go/views/memory.js +198 -198
- package/src/dsh-go/views/root.js +30 -30
- package/src/dsh-go/views/settings.js +398 -398
- package/src/dsh-go/views/status.js +51 -51
- package/src/embedding.js +342 -342
- package/src/entities/extractor.js +285 -285
- package/src/fence.js +24 -24
- package/src/graph/anchoring.js +184 -184
- package/src/guide.js +74 -74
- package/src/heat.js +144 -144
- package/src/hot-memory.js +119 -119
- package/src/image-describe.js +158 -0
- package/src/index.js +852 -852
- package/src/inject.js +656 -651
- package/src/kb/index.js +309 -309
- package/src/kb/routes.js +219 -219
- package/src/kb/tools.js +148 -148
- package/src/lang.js +607 -595
- package/src/local-embedder.js +358 -358
- package/src/maintenance.js +162 -162
- package/src/memory-source.js +9 -9
- package/src/mirror.js +330 -330
- package/src/organize.js +456 -456
- package/src/peak-hours.js +172 -172
- package/src/pipeline-activities.js +178 -178
- package/src/pipeline-attribution.js +165 -165
- package/src/pipeline-command.js +279 -279
- package/src/pipeline-confirm.js +142 -142
- package/src/pipeline-exec.js +174 -174
- package/src/pipeline-nudge-auto.js +129 -129
- package/src/pipeline-nudge.js +1623 -1623
- package/src/pipeline-observations.js +181 -181
- package/src/pipeline-observe.js +133 -133
- package/src/pipeline-runner.js +361 -361
- package/src/pipeline-runs.js +442 -442
- package/src/pipeline.js +716 -716
- package/src/placement.js +13 -13
- package/src/pre-inject-gate.js +354 -354
- package/src/profile-extract.js +164 -164
- package/src/profile-facts.js +356 -356
- package/src/provenance-http.js +251 -251
- package/src/quality-filter.js +162 -162
- package/src/recall-stats.js +190 -190
- package/src/reclaim-http.js +150 -150
- package/src/reranker.js +269 -269
- package/src/runtime/adopt.js +176 -176
- package/src/runtime/closure.js +172 -172
- package/src/runtime/download.js +247 -247
- package/src/runtime/layout.js +265 -265
- package/src/runtime/loader.js +252 -252
- package/src/runtime/model-fetch.js +361 -361
- package/src/runtime/provision.js +237 -237
- package/src/runtime/tarball.js +130 -130
- package/src/runtime/verify.js +223 -223
- package/src/safe-slice.js +18 -18
- package/src/scope-state.js +277 -277
- package/src/scope.js +187 -187
- package/src/search/adaptive.js +60 -60
- package/src/search/bm25.js +96 -96
- package/src/semantic.js +572 -572
- package/src/sensitive-scan.js +209 -209
- package/src/serve.js +228 -228
- package/src/service.js +3268 -3268
- package/src/session-gate.js +91 -91
- package/src/session-usage.js +350 -350
- package/src/settings.js +827 -817
- package/src/share-http.js +281 -281
- package/src/share-import.js +234 -234
- package/src/share.js +335 -335
- package/src/store.js +5895 -5895
- package/src/summarize.js +1388 -1343
- package/src/tools.js +1370 -1356
- package/src/user-settings.js +230 -230
- package/src/vector-index.js +180 -180
- package/src/version-check.js +122 -122
- package/src/wiki/claims.js +267 -267
- package/src/wiki/cli-hint.js +90 -90
- package/src/wiki/inject.js +164 -164
- package/src/wiki/partition.js +200 -200
- package/src/wiki/plan.js +214 -214
- package/src/wiki/queries.js +640 -640
- package/src/wiki/render.js +261 -261
- package/src/wiki/scan.js +371 -371
- package/src/wiki/t0.js +500 -500
- package/src/wiki/t1-jobs.js +232 -232
- package/src/wiki/t1.js +609 -609
- package/src/write-admission.js +404 -404
- package/test/adaptive-inject-budget.test.js +85 -85
- package/test/api-hardening.test.js +173 -173
- package/test/api-nudge-route.test.js +259 -259
- package/test/api-routes-gaps.test.js +1092 -1092
- package/test/api.test.js +3007 -2998
- package/test/attachment-text.test.js +139 -139
- package/test/audit.test.js +448 -448
- package/test/baseline-persist.test.js +248 -248
- package/test/benchmark.test.js +94 -94
- package/test/bm25-corpus-cache.test.js +145 -145
- package/test/bootstrap.test.js +228 -228
- package/test/candidates.test.js +345 -345
- package/test/capabilities.test.js +577 -577
- package/test/capacity-warning.test.js +262 -262
- package/test/changelog-prep.test.js +125 -125
- package/test/choro-command.test.js +218 -218
- package/test/cli-enums.test.js +37 -37
- package/test/cli-flag-value.test.js +86 -86
- package/test/cli-receive.test.js +390 -390
- package/test/cli-share.test.js +437 -437
- package/test/client-share.test.js +225 -225
- package/test/client.test.js +4595 -4425
- package/test/clustering.test.js +100 -100
- package/test/commands.test.js +106 -106
- package/test/config-keys-routes.test.js +233 -233
- package/test/config.test.js +153 -153
- package/test/conflict-freeze.test.js +344 -344
- package/test/conflict-ledger-enforce.test.js +452 -452
- package/test/conflict-ledger.test.js +242 -242
- package/test/conflict-reviewed.test.js +79 -79
- package/test/content-hash.test.js +204 -204
- package/test/continuity.test.js +452 -452
- package/test/contrast.test.js +432 -432
- package/test/date-hint.test.js +156 -0
- package/test/dedupe-candidate-window.test.js +180 -180
- package/test/dependency-overrides.test.js +78 -78
- package/test/diary-library.test.js +187 -187
- package/test/diary.test.js +576 -576
- package/test/differentiate-feedback.test.js +248 -248
- package/test/distill-tx-embed-gap.test.js +110 -110
- package/test/docs-config-keys.test.js +65 -65
- package/test/document-dir.test.js +233 -233
- package/test/document.test.js +703 -703
- package/test/dream-archive-guardrail.test.js +116 -116
- package/test/dream-baseline-clamp.test.js +174 -174
- package/test/dream-candidate-hybrid.test.js +281 -281
- package/test/dream-coverage-degrade.test.js +86 -86
- package/test/dream-decision-evidence.test.js +314 -314
- package/test/dream-failure-backoff.test.js +173 -173
- package/test/dream-fence.test.js +207 -207
- package/test/dream-maxtokens-fallback.test.js +132 -132
- package/test/dream-merge-guardrail.test.js +219 -219
- package/test/dream-peak-hours.test.js +194 -194
- package/test/dream.test.js +1528 -1528
- package/test/dsh-go-host.test.js +134 -134
- package/test/dsh-go-panel-actions.test.js +854 -854
- package/test/dsh-go-panel.test.js +251 -251
- package/test/embed-ready-poll.test.js +94 -94
- package/test/embed-text-reasons.test.js +112 -112
- package/test/embedding-cache-f32.test.js +276 -276
- package/test/embedding-ready.test.js +226 -226
- package/test/entities.test.js +711 -711
- package/test/entity-recall.test.js +179 -179
- package/test/epistemic.test.js +325 -325
- package/test/failure-query.test.js +147 -147
- package/test/failure-retention.test.js +105 -105
- package/test/fnew-0112.test.js +311 -311
- package/test/fnew-03.test.js +422 -422
- package/test/forget-corrections.test.js +70 -70
- package/test/graph-anchoring.test.js +184 -184
- package/test/graph-api.test.js +333 -333
- package/test/graph-boosted-relations.test.js +189 -189
- package/test/graph-inject-budget.test.js +103 -103
- package/test/graph-multipath.test.js +269 -269
- package/test/graph-passive-confirm.test.js +91 -91
- package/test/graph-weight-evolution.test.js +104 -104
- package/test/heat.test.js +175 -175
- package/test/helpers/dream-mock.js +86 -86
- package/test/helpers/peer-worker.mjs +25 -25
- package/test/helpers/runtime-source.js +60 -60
- package/test/helpers/tar-builder.js +80 -80
- package/test/helpers/write-admission-samples.js +312 -312
- package/test/hot-memory.test.js +259 -259
- package/test/image-description.test.js +271 -0
- package/test/image-memory.test.js +170 -170
- package/test/inject-content-cap.test.js +91 -91
- package/test/inject-first-round-bm25.test.js +89 -89
- package/test/inject-heat.test.js +77 -77
- package/test/inject-parent-gate.test.js +134 -109
- package/test/inject-pin-explicit.test.js +300 -300
- package/test/inject-pin-vector-crowd.test.js +225 -225
- package/test/inject-pools.test.js +195 -195
- package/test/inject-recall.test.js +172 -172
- package/test/inject-rotation.test.js +161 -161
- package/test/inject.test.js +553 -553
- package/test/issue-617-step1-query-and-fusion.test.js +361 -361
- package/test/kb-api-wiring.test.js +128 -128
- package/test/kb-collections.test.js +272 -272
- package/test/kb-routes.test.js +379 -379
- package/test/lang.test.js +98 -98
- package/test/lastrunat-persist.test.js +101 -101
- package/test/lib-smoke.test.js +116 -116
- package/test/llm-audit.test.js +815 -815
- package/test/llm-message-source.test.js +207 -207
- package/test/local-embedder.test.js +292 -292
- package/test/maintenance.test.js +501 -501
- package/test/mcp-stdio.test.js +385 -385
- package/test/mint-source.test.js +311 -311
- package/test/mirror-dirty.test.js +424 -424
- package/test/mirror-edit-digest.test.js +187 -187
- package/test/mirror-generation.test.js +499 -499
- package/test/mirror-types.test.js +208 -208
- package/test/mirror.test.js +249 -249
- package/test/narrative-bars.test.js +162 -162
- package/test/organize-tool.test.js +232 -232
- package/test/organize.test.js +418 -418
- package/test/panel-chart-scale.test.js +90 -90
- package/test/panel-tokens.test.js +245 -245
- package/test/peak-hours-observability.test.js +70 -70
- package/test/peer-blockers.test.js +193 -193
- package/test/persona-addressing.test.js +83 -83
- package/test/persona-api.test.js +172 -172
- package/test/persona-by-session.test.js +568 -568
- package/test/persona-flag.test.js +36 -36
- package/test/persona-inject.test.js +145 -145
- package/test/persona-settings.test.js +198 -198
- package/test/pipeline-activities.test.js +155 -155
- package/test/pipeline-attribution.test.js +175 -175
- package/test/pipeline-command.test.js +243 -243
- package/test/pipeline-confirm.test.js +148 -148
- package/test/pipeline-exec.test.js +172 -172
- package/test/pipeline-nudge-auto.test.js +248 -248
- package/test/pipeline-nudge.test.js +1278 -1278
- package/test/pipeline-observations.test.js +157 -157
- package/test/pipeline-observe.test.js +127 -127
- package/test/pipeline-r1r2.test.js +278 -278
- package/test/pipeline-runner.test.js +468 -468
- package/test/pipeline-runs.test.js +767 -767
- package/test/pipeline.test.js +636 -636
- package/test/placement.test.js +36 -36
- package/test/policy-epoch.test.js +259 -259
- package/test/pre-inject-gate.test.js +444 -444
- package/test/profile-extract.test.js +269 -269
- package/test/profile-facts.test.js +492 -492
- package/test/prompt-stance.test.js +128 -128
- package/test/provenance-http.test.js +367 -367
- package/test/publish-gate.test.js +272 -272
- package/test/quality-backfill.test.js +290 -290
- package/test/quality-filter.test.js +295 -295
- package/test/readme-claims.test.js +113 -113
- package/test/reasoning-effort.test.js +752 -752
- package/test/recall-anti-update.test.js +82 -82
- package/test/recall-evals.test.js +253 -253
- package/test/recall-layer.test.js +326 -326
- package/test/recall-retention.test.js +128 -128
- package/test/recall-stats.test.js +274 -274
- package/test/receipt-chain.test.js +451 -451
- package/test/reclaim-http.test.js +209 -209
- package/test/reflection-update-gate.test.js +129 -129
- package/test/reflection.test.js +226 -226
- package/test/reindex-backfill.test.js +475 -475
- package/test/reindex-scheduler.test.js +369 -369
- package/test/release-docs.test.js +156 -156
- package/test/release-notes.test.js +265 -265
- package/test/release-workflow.test.js +93 -93
- package/test/reranker-single-logit.test.js +73 -73
- package/test/reranker.test.js +197 -197
- package/test/resident-status.test.js +83 -83
- package/test/route-policy.test.js +113 -113
- package/test/runtime-adopt.test.js +206 -206
- package/test/runtime-cli.test.js +89 -89
- package/test/runtime-closure.test.js +193 -193
- package/test/runtime-download.test.js +302 -302
- package/test/runtime-layout.test.js +163 -163
- package/test/runtime-loader.test.js +255 -255
- package/test/runtime-manifest.test.js +159 -159
- package/test/runtime-model-fetch.test.js +348 -348
- package/test/runtime-provision.test.js +101 -101
- package/test/runtime-tarball.test.js +81 -81
- package/test/runtime-verify.test.js +319 -319
- package/test/scope-candidates.test.js +491 -491
- package/test/scope-distill-stamp.test.js +134 -134
- package/test/scope-explicit.test.js +452 -452
- package/test/scope-inject-soft.test.js +106 -106
- package/test/scope-optional-service.test.js +110 -110
- package/test/scope-retrieval.test.js +197 -197
- package/test/scope-state.test.js +610 -610
- package/test/scope-storage.test.js +255 -255
- package/test/scope-strict.test.js +367 -367
- package/test/search-fusion.test.js +90 -90
- package/test/security-doc.test.js +188 -188
- package/test/semantic.test.js +124 -124
- package/test/sensitive-scan.test.js +251 -251
- package/test/serve-bin.test.js +121 -121
- package/test/serve.test.js +258 -258
- package/test/service-search.test.js +174 -174
- package/test/service.test.js +410 -410
- package/test/session-gate.test.js +264 -264
- package/test/session-usage.test.js +317 -317
- package/test/settings.test.js +273 -273
- package/test/share-foreign-rows.test.js +144 -144
- package/test/share-http.test.js +144 -144
- package/test/share-import.test.js +577 -577
- package/test/share-imported-guard.test.js +311 -311
- package/test/share-imported-identity.test.js +111 -111
- package/test/share-pack.test.js +511 -511
- package/test/share-receive-http.test.js +756 -756
- package/test/share-routes.test.js +337 -337
- package/test/share-store.test.js +133 -133
- package/test/share-validate.test.js +101 -101
- package/test/skip-invalid-restore.test.js +262 -262
- package/test/sleep-action-set.test.js +441 -441
- package/test/sleep-catchup.test.js +315 -315
- package/test/sleep-failure-backoff.test.js +156 -156
- package/test/sleep-heat.test.js +174 -174
- package/test/sleep-scheduler-rearm.test.js +89 -89
- package/test/sleep.test.js +1455 -1455
- package/test/standalone-api.test.js +1344 -1344
- package/test/store-vector-cache.test.js +98 -98
- package/test/store-write-path-columns.test.js +191 -191
- package/test/store.test.js +744 -744
- package/test/stress.test.js +209 -209
- package/test/summarize-occurred-at.test.js +127 -127
- package/test/summarize-parse-diagnostics.test.js +75 -75
- package/test/summarize-reasoning-effort.test.js +189 -189
- package/test/summarize.test.js +2251 -2251
- package/test/supersede-state-tracking.test.js +394 -394
- package/test/test-count-sync.test.js +71 -71
- package/test/tool-state-ignore.test.js +65 -65
- package/test/tools-dto-schema-matrix.test.js +398 -398
- package/test/tools-memory-get-schema.test.js +65 -65
- package/test/tools.test.js +585 -585
- package/test/updated-at-semantics.test.js +113 -113
- package/test/user-settings-preview.test.js +127 -127
- package/test/user-settings-segments.test.js +527 -527
- package/test/vector-index.test.js +334 -334
- package/test/version-check.test.js +152 -152
- package/test/webServer-optional.test.js +82 -82
- package/test/wiki-api.test.js +734 -734
- package/test/wiki-claims.test.js +194 -194
- package/test/wiki-cli-hint.test.js +118 -118
- package/test/wiki-inject.test.js +265 -265
- package/test/wiki-partition.test.js +112 -112
- package/test/wiki-plan.test.js +80 -80
- package/test/wiki-provenance.test.js +202 -202
- package/test/wiki-queries.test.js +398 -398
- package/test/wiki-scan.test.js +208 -208
- package/test/wiki-store.test.js +190 -190
- package/test/wiki-t0.test.js +456 -456
- package/test/wiki-t1-jobs.test.js +125 -125
- package/test/wiki-t1.test.js +460 -460
- package/test/wiki-tools.test.js +176 -176
- package/test/workflow-guards.test.js +155 -155
- package/test/write-admission.test.js +668 -668
package/src/wiki/cli-hint.js
CHANGED
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
// dsh-mneme/src/wiki/cli-hint.js
|
|
2
|
-
// issue #607:面板空态让用户「在仓库目录里跑 `dsh-mneme-choro <仓库路径> --apply`」,
|
|
3
|
-
// 但插件是装在 profile 依赖里的,npm 只为**全局**安装把 shim 放进 PATH。profile 的
|
|
4
|
-
// shim 落在 `<profile>/node_modules/.bin`,那里不在 PATH 上 —— 用户照着抄必然
|
|
5
|
-
// command not found。issue 作者实测后的原话是「完全就是 AI 自己编的」。
|
|
6
|
-
//
|
|
7
|
-
// 所以提示里的命令必须**能直接粘贴就跑**:给绝对路径的入口,而不是一个只对全局
|
|
8
|
-
// 安装成立的光名字。入口从插件自身位置推导(不信 PATH、不信 cwd)。
|
|
9
|
-
//
|
|
10
|
-
// 做法是逐级向上找「同时存在 bin/dsh-mneme-choro.mjs 与 package.json」的目录,
|
|
11
|
-
// 而不是固定 dirname 几次:本仓库的 src 与 lib 是同一层,但 wiki/ 是第二层,
|
|
12
|
-
// bin/ 里的脚本又在第一层 —— 写死层数的推导只要有一处调用方挪个位置就悄悄算错,
|
|
13
|
-
// 而算错的表现正是「又给出一条跑不起来的命令」,与这条 issue 的病因同源。
|
|
14
|
-
//
|
|
15
|
-
// 这条对 hoisted 与 pnpm isolated 两种 linker 都成立:后者的真实路径在
|
|
16
|
-
// `.pnpm/<pkg>/node_modules/@modusensus/dsh-mneme/`,包根照样是它的父目录。
|
|
17
|
-
//
|
|
18
|
-
// 刻意**只给 `node <entry>` 这一种形态**:`.bin` 的 shim 在 hoisted 布局下位于
|
|
19
|
-
// 包根的 `../../../node_modules/.bin`,isolated 布局下却在 profile 根 —— 猜错就是
|
|
20
|
-
// 再给一条跑不起来的命令。宁可只给一条一定对的,也不并列两条一条错的。
|
|
21
|
-
//
|
|
22
|
-
// 找不到入口就返回 null(源码树被裁剪、或调用方在包外),调用方退回通用说法,
|
|
23
|
-
// 不硬编一个假路径。
|
|
24
|
-
import { existsSync } from "node:fs";
|
|
25
|
-
import { dirname, join } from "node:path";
|
|
26
|
-
import { fileURLToPath } from "node:url";
|
|
27
|
-
|
|
28
|
-
const ENTRY_BASENAME = "dsh-mneme-choro.mjs";
|
|
29
|
-
// 从 `src/wiki/` 到包根是 2 层,从 `bin/` 是 1 层;留到 6 层是为了 pnpm 的
|
|
30
|
-
// `.pnpm/<pkg>/node_modules/@modusensus/<name>/` 这种深路径,同时不至于一路走到盘符。
|
|
31
|
-
const MAX_LEVELS = 6;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* choro CLI 入口的绝对路径;找不到(源码树被裁剪、调用方在包外)返回 null。
|
|
35
|
-
*
|
|
36
|
-
* @param {string} fromModuleUrl - 调用方自己的 `import.meta.url`。
|
|
37
|
-
* @returns {string|null}
|
|
38
|
-
*/
|
|
39
|
-
export function choroCliEntry(fromModuleUrl) {
|
|
40
|
-
let dir;
|
|
41
|
-
try {
|
|
42
|
-
dir = dirname(fileURLToPath(fromModuleUrl));
|
|
43
|
-
} catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
for (let level = 0; level <= MAX_LEVELS; level += 1) {
|
|
47
|
-
const entry = join(dir, "bin", ENTRY_BASENAME);
|
|
48
|
-
// 两个条件都要:只有 bin/ 没有 package.json 的目录可能是别人的同名 bin;
|
|
49
|
-
// 只有 package.json 没有 bin/ 的是源码树被裁剪(`files` 少了 bin)。
|
|
50
|
-
if (existsSync(entry) && existsSync(join(dir, "package.json"))) return entry;
|
|
51
|
-
const up = dirname(dir);
|
|
52
|
-
if (up === dir) break;
|
|
53
|
-
dir = up;
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 给一句可直接粘贴的命令。只负责引号与形态,仓库路径由调用方给(面板给
|
|
60
|
-
* `<仓库路径>` 占位符,工具报错给 `<repo>`)。
|
|
61
|
-
*
|
|
62
|
-
* 引号按平台分:Windows 的 cmd / PowerShell 用双引号;POSIX 用单引号并把内嵌
|
|
63
|
-
* 单引号转成 `'\''` —— 安装路径里带空格是常态(`C:\Program Files\`),不带引号的
|
|
64
|
-
* 示例等于又给人一条跑不起来的命令。
|
|
65
|
-
*
|
|
66
|
-
* @param {string|null} entry - `choroCliEntry()` 的产物。
|
|
67
|
-
* @param {string} repoPlaceholder - 仓库路径占位符的展示形态。
|
|
68
|
-
* @param {string} [platform] - 覆盖 `process.platform`(测试用)。
|
|
69
|
-
* @returns {string|null}
|
|
70
|
-
*/
|
|
71
|
-
export function choroCliCommand(entry, repoPlaceholder, platform = process.platform) {
|
|
72
|
-
if (!entry) return null;
|
|
73
|
-
const quoted = platform === "win32"
|
|
74
|
-
? `"${entry}"`
|
|
75
|
-
: `'${entry.replace(/'/g, "'\\''")}'`;
|
|
76
|
-
return `node ${quoted} ${repoPlaceholder} --apply`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 一站式的便捷口:从调用方的 `import.meta.url` 直接拿到命令串。
|
|
81
|
-
* 找不到入口返回 null,调用方据此选通用说法。
|
|
82
|
-
*
|
|
83
|
-
* @param {string} fromModuleUrl
|
|
84
|
-
* @param {string} repoPlaceholder
|
|
85
|
-
* @param {string} [platform]
|
|
86
|
-
* @returns {string|null}
|
|
87
|
-
*/
|
|
88
|
-
export function choroCliCommandFrom(fromModuleUrl, repoPlaceholder, platform = process.platform) {
|
|
89
|
-
return choroCliCommand(choroCliEntry(fromModuleUrl), repoPlaceholder, platform);
|
|
90
|
-
}
|
|
1
|
+
// dsh-mneme/src/wiki/cli-hint.js
|
|
2
|
+
// issue #607:面板空态让用户「在仓库目录里跑 `dsh-mneme-choro <仓库路径> --apply`」,
|
|
3
|
+
// 但插件是装在 profile 依赖里的,npm 只为**全局**安装把 shim 放进 PATH。profile 的
|
|
4
|
+
// shim 落在 `<profile>/node_modules/.bin`,那里不在 PATH 上 —— 用户照着抄必然
|
|
5
|
+
// command not found。issue 作者实测后的原话是「完全就是 AI 自己编的」。
|
|
6
|
+
//
|
|
7
|
+
// 所以提示里的命令必须**能直接粘贴就跑**:给绝对路径的入口,而不是一个只对全局
|
|
8
|
+
// 安装成立的光名字。入口从插件自身位置推导(不信 PATH、不信 cwd)。
|
|
9
|
+
//
|
|
10
|
+
// 做法是逐级向上找「同时存在 bin/dsh-mneme-choro.mjs 与 package.json」的目录,
|
|
11
|
+
// 而不是固定 dirname 几次:本仓库的 src 与 lib 是同一层,但 wiki/ 是第二层,
|
|
12
|
+
// bin/ 里的脚本又在第一层 —— 写死层数的推导只要有一处调用方挪个位置就悄悄算错,
|
|
13
|
+
// 而算错的表现正是「又给出一条跑不起来的命令」,与这条 issue 的病因同源。
|
|
14
|
+
//
|
|
15
|
+
// 这条对 hoisted 与 pnpm isolated 两种 linker 都成立:后者的真实路径在
|
|
16
|
+
// `.pnpm/<pkg>/node_modules/@modusensus/dsh-mneme/`,包根照样是它的父目录。
|
|
17
|
+
//
|
|
18
|
+
// 刻意**只给 `node <entry>` 这一种形态**:`.bin` 的 shim 在 hoisted 布局下位于
|
|
19
|
+
// 包根的 `../../../node_modules/.bin`,isolated 布局下却在 profile 根 —— 猜错就是
|
|
20
|
+
// 再给一条跑不起来的命令。宁可只给一条一定对的,也不并列两条一条错的。
|
|
21
|
+
//
|
|
22
|
+
// 找不到入口就返回 null(源码树被裁剪、或调用方在包外),调用方退回通用说法,
|
|
23
|
+
// 不硬编一个假路径。
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { dirname, join } from "node:path";
|
|
26
|
+
import { fileURLToPath } from "node:url";
|
|
27
|
+
|
|
28
|
+
const ENTRY_BASENAME = "dsh-mneme-choro.mjs";
|
|
29
|
+
// 从 `src/wiki/` 到包根是 2 层,从 `bin/` 是 1 层;留到 6 层是为了 pnpm 的
|
|
30
|
+
// `.pnpm/<pkg>/node_modules/@modusensus/<name>/` 这种深路径,同时不至于一路走到盘符。
|
|
31
|
+
const MAX_LEVELS = 6;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* choro CLI 入口的绝对路径;找不到(源码树被裁剪、调用方在包外)返回 null。
|
|
35
|
+
*
|
|
36
|
+
* @param {string} fromModuleUrl - 调用方自己的 `import.meta.url`。
|
|
37
|
+
* @returns {string|null}
|
|
38
|
+
*/
|
|
39
|
+
export function choroCliEntry(fromModuleUrl) {
|
|
40
|
+
let dir;
|
|
41
|
+
try {
|
|
42
|
+
dir = dirname(fileURLToPath(fromModuleUrl));
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
for (let level = 0; level <= MAX_LEVELS; level += 1) {
|
|
47
|
+
const entry = join(dir, "bin", ENTRY_BASENAME);
|
|
48
|
+
// 两个条件都要:只有 bin/ 没有 package.json 的目录可能是别人的同名 bin;
|
|
49
|
+
// 只有 package.json 没有 bin/ 的是源码树被裁剪(`files` 少了 bin)。
|
|
50
|
+
if (existsSync(entry) && existsSync(join(dir, "package.json"))) return entry;
|
|
51
|
+
const up = dirname(dir);
|
|
52
|
+
if (up === dir) break;
|
|
53
|
+
dir = up;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 给一句可直接粘贴的命令。只负责引号与形态,仓库路径由调用方给(面板给
|
|
60
|
+
* `<仓库路径>` 占位符,工具报错给 `<repo>`)。
|
|
61
|
+
*
|
|
62
|
+
* 引号按平台分:Windows 的 cmd / PowerShell 用双引号;POSIX 用单引号并把内嵌
|
|
63
|
+
* 单引号转成 `'\''` —— 安装路径里带空格是常态(`C:\Program Files\`),不带引号的
|
|
64
|
+
* 示例等于又给人一条跑不起来的命令。
|
|
65
|
+
*
|
|
66
|
+
* @param {string|null} entry - `choroCliEntry()` 的产物。
|
|
67
|
+
* @param {string} repoPlaceholder - 仓库路径占位符的展示形态。
|
|
68
|
+
* @param {string} [platform] - 覆盖 `process.platform`(测试用)。
|
|
69
|
+
* @returns {string|null}
|
|
70
|
+
*/
|
|
71
|
+
export function choroCliCommand(entry, repoPlaceholder, platform = process.platform) {
|
|
72
|
+
if (!entry) return null;
|
|
73
|
+
const quoted = platform === "win32"
|
|
74
|
+
? `"${entry}"`
|
|
75
|
+
: `'${entry.replace(/'/g, "'\\''")}'`;
|
|
76
|
+
return `node ${quoted} ${repoPlaceholder} --apply`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 一站式的便捷口:从调用方的 `import.meta.url` 直接拿到命令串。
|
|
81
|
+
* 找不到入口返回 null,调用方据此选通用说法。
|
|
82
|
+
*
|
|
83
|
+
* @param {string} fromModuleUrl
|
|
84
|
+
* @param {string} repoPlaceholder
|
|
85
|
+
* @param {string} [platform]
|
|
86
|
+
* @returns {string|null}
|
|
87
|
+
*/
|
|
88
|
+
export function choroCliCommandFrom(fromModuleUrl, repoPlaceholder, platform = process.platform) {
|
|
89
|
+
return choroCliCommand(choroCliEntry(fromModuleUrl), repoPlaceholder, platform);
|
|
90
|
+
}
|
package/src/wiki/inject.js
CHANGED
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
// dsh-mneme/src/wiki/inject.js
|
|
2
|
-
// chorography 的注入面(M3):会话开局往 systemPrompt 里塞一小块「仓库地志提纲」。
|
|
3
|
-
//
|
|
4
|
-
// 三条边界(spec §7 / P24–P33):
|
|
5
|
-
// 1. **只注标题级**——模块名 + 文件数 + 页状态 + 页相对路径,不读页正文。正文要
|
|
6
|
-
// 模型自己用 choro_read_page 取,那不是「开局就该付的成本」。
|
|
7
|
-
// 2. **不上热路径的硬活**——不 fork git、不 stat 磁盘、不解析 markdown。这里只吃
|
|
8
|
-
// DB 里已有的行;过期判定留给 /choro(人主动触发,付得起一次 git rev-parse)。
|
|
9
|
-
// 3. **绝不抛**——本块折在既有的 memory context 里,一个附属信息块把整轮
|
|
10
|
-
// systemPrompt 搞崩是不成比例的失败。任何异常都退化成空串(= 本帧不注入,
|
|
11
|
-
// 宿主契约里空文本会被过滤,不占位)。
|
|
12
|
-
import { escapePromptVars } from "../user-settings.js";
|
|
13
|
-
import { STR } from "../lang.js";
|
|
14
|
-
|
|
15
|
-
/** 档位枚举(与 config.js 的 chorographyInject 同一份取值,配置闸门在 settings.js)。 */
|
|
16
|
-
export const INJECT_TIERS = Object.freeze(["off", "light", "full"]);
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* light 档最多列几个模块。
|
|
20
|
-
*
|
|
21
|
-
* 定 6 是照着 spec §7 的「≤8 行」倒推的:块头 1 行 + 模块行 6 行 + 「还有 N 个」
|
|
22
|
-
* 1 行 = 8 行。多给两行要挤掉「还有 N 个」那句,读者就不知道清单被截断了——
|
|
23
|
-
* 静默截断比明说「还有 30 个」更坏。
|
|
24
|
-
*/
|
|
25
|
-
export const LIGHT_MODULE_LIMIT = 6;
|
|
26
|
-
|
|
27
|
-
/** 各档字符硬上限。宿主侧没有任何体积预算(V3 实测),所以上限只能自己兜。 */
|
|
28
|
-
export const MAX_BLOCK_CHARS = Object.freeze({ light: 900, full: 6000 });
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 配置 → 档位。纯函数,无副作用,供注入侧与 /choro 共用同一份判据。
|
|
32
|
-
*
|
|
33
|
-
* 轻量档(lightMode)在这里被压成 off 而不是进 LIGHT_MODE_OFF:那张表对平铺键
|
|
34
|
-
* 一律赋 false,枚举键塞进去会得到与 schema 不符的 false,而 false !== "off"
|
|
35
|
-
* 时注入照样渲染——比不关更糟(P26)。
|
|
36
|
-
*/
|
|
37
|
-
export function resolveInjectTier(config) {
|
|
38
|
-
if (!config || config.chorographyEnabled !== true) return "off";
|
|
39
|
-
if (config.lightMode === true) return "off";
|
|
40
|
-
const raw = config.chorographyInject;
|
|
41
|
-
return INJECT_TIERS.includes(raw) ? raw : "light";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** 页状态 → 标签。skeleton 不出标签(那是默认态,全标一遍等于没标)。 */
|
|
45
|
-
function statusLabel(status, language) {
|
|
46
|
-
if (status === "enriched") return STR.choroStatusEnriched[language];
|
|
47
|
-
if (status === "failed") return STR.choroStatusFailed[language];
|
|
48
|
-
if (status === "stale") return STR.choroStatusStale[language];
|
|
49
|
-
return "";
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* light 档取哪些模块。
|
|
54
|
-
*
|
|
55
|
-
* 按文件数降序、同数按 slug 升序——**不是**取字母序前 6 个:字母序会永远只显示
|
|
56
|
-
* 同一批(通常还是 src 这种大而空的目录页),而大模块是「被问到的概率」最高的
|
|
57
|
-
* 那批。排序里带 slug 是为了同一份库每次渲染字节一致(缓存与测试都靠它)。
|
|
58
|
-
*/
|
|
59
|
-
function pickModules(modules, tier) {
|
|
60
|
-
// 两档用同一份排序:light 与 full 若各按各的排,同一份地志在两个档位下会给出
|
|
61
|
-
// 不同次序,读起来像「刚才那份被重扫过了」。大模块在前对两档都成立——
|
|
62
|
-
// 被问到的概率最高的那批,本来就该排前面。
|
|
63
|
-
const ordered = [...modules].sort((a, b) => {
|
|
64
|
-
const d = (b.fileCount ?? 0) - (a.fileCount ?? 0);
|
|
65
|
-
if (d !== 0) return d;
|
|
66
|
-
return a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0;
|
|
67
|
-
});
|
|
68
|
-
if (tier === "full") return { shown: ordered, rest: 0 };
|
|
69
|
-
return { shown: ordered.slice(0, LIGHT_MODULE_LIMIT), rest: Math.max(0, ordered.length - LIGHT_MODULE_LIMIT) };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** 生成时间只留日期部分:注入块里精确到毫秒没有信息量,只挤体积。 */
|
|
73
|
-
function dateOnly(iso) {
|
|
74
|
-
const match = /^(\d{4}-\d{2}-\d{2})/.exec(String(iso ?? ""));
|
|
75
|
-
return match ? match[1] : String(iso ?? "");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 渲染地志提纲块。纯函数(入参进、字符串出),注入侧与 /choro 的「看提纲」
|
|
80
|
-
* 共用这一份——两张皮在这里只剩档位与语言两个参数之差。
|
|
81
|
-
*
|
|
82
|
-
* @param {object|null} outline createChoroQueries().outline() 的产物
|
|
83
|
-
* @param {"light"|"full"} tier 已解析的档位(off 不该调到这里)
|
|
84
|
-
* @param {"zh"|"en"} language
|
|
85
|
-
* @returns {string} 空串 = 不注入
|
|
86
|
-
*/
|
|
87
|
-
export function renderChoroBlock(outline, tier, language = "zh") {
|
|
88
|
-
if (!outline || !Array.isArray(outline.modules) || outline.modules.length === 0) return "";
|
|
89
|
-
const lang = language === "en" ? "en" : "zh";
|
|
90
|
-
const cap = MAX_BLOCK_CHARS[tier] ?? MAX_BLOCK_CHARS.light;
|
|
91
|
-
const picked = pickModules(outline.modules, tier);
|
|
92
|
-
|
|
93
|
-
const lines = [
|
|
94
|
-
STR.choroBlockHeader[lang](outline.repo.name, outline.modules.length, dateOnly(outline.generatedAt))
|
|
95
|
-
];
|
|
96
|
-
for (const mod of picked.shown) {
|
|
97
|
-
lines.push(STR.choroBlockLine[lang](mod.title, mod.fileCount ?? 0, statusLabel(mod.status, lang), mod.relPath ?? ""));
|
|
98
|
-
}
|
|
99
|
-
if (picked.rest > 0) lines.push(STR.choroBlockMore[lang](picked.rest));
|
|
100
|
-
|
|
101
|
-
// 逐行累加而不是拼完再切:切在行中间会让最后一条模块行变成半句话,
|
|
102
|
-
// 模型读到的「路径」就可能是断的——宁可少一行,不可半行。
|
|
103
|
-
const kept = [];
|
|
104
|
-
let used = 0;
|
|
105
|
-
for (const line of lines) {
|
|
106
|
-
if (used + line.length + 1 > cap) break;
|
|
107
|
-
kept.push(line);
|
|
108
|
-
used += line.length + 1;
|
|
109
|
-
}
|
|
110
|
-
if (kept.length <= 1) return "";
|
|
111
|
-
return kept.join("\n");
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* 注入器(给 src/inject.js 用)。
|
|
116
|
-
*
|
|
117
|
-
* 缓存键用 **outline.generatedAt**(页级生成时间的最大值),不是 choro_repos.
|
|
118
|
-
* updated_at:T1 富化只推 choro_pages.generated_at,不动仓库行——若按仓库行做键,
|
|
119
|
-
* 用户刚在终端跑完 `--t1 --apply`,注入块还写着「骨架」,而 /choro(无缓存)已经
|
|
120
|
-
* 报「已富化」。两个面说同一件事却给出不同答案,比慢一点糟得多。
|
|
121
|
-
* 每轮仍查一次库取提纲(一次索引查询,几十微秒,不 fork git、不 stat 磁盘),
|
|
122
|
-
* 只是**渲染**走缓存——省的是拼字符串,不是正确性。
|
|
123
|
-
*
|
|
124
|
-
* @param {object} opts.choro createChoroQueries() 的产物(注入侧只读它)
|
|
125
|
-
* @param {object} opts.config 合并后的配置
|
|
126
|
-
* @param {object} [opts.logger]
|
|
127
|
-
* @param {() => string} [opts.language] 语言取值器(跟随配置,不在创建时定死)
|
|
128
|
-
* @returns {{ text: (cwd: string|null|undefined) => string, tier: string, dispose: () => void }}
|
|
129
|
-
*/
|
|
130
|
-
export function createChoroInject({ choro, config, logger = null, language = null } = {}) {
|
|
131
|
-
const langOf = typeof language === "function" ? language : () => "zh";
|
|
132
|
-
const tier = resolveInjectTier(config);
|
|
133
|
-
let cache = null; // { key, text }
|
|
134
|
-
|
|
135
|
-
function text(cwd) {
|
|
136
|
-
if (tier === "off" || !choro) return "";
|
|
137
|
-
try {
|
|
138
|
-
const repo = typeof choro.repoByCwd === "function" ? choro.repoByCwd(cwd) : null;
|
|
139
|
-
if (!repo) return "";
|
|
140
|
-
const lang = langOf() === "en" ? "en" : "zh";
|
|
141
|
-
const outline = typeof choro.outline === "function" ? choro.outline(repo.id) : null;
|
|
142
|
-
// 键取页级生成时间:T0 重算与 T1 富化都会推进它,两种「地志变了」都命中。
|
|
143
|
-
const key = tier + "|" + lang + "|" + repo.id + "|" + (outline?.generatedAt ?? repo.updated_at ?? "");
|
|
144
|
-
if (cache && cache.key === key) return cache.text;
|
|
145
|
-
// 转义只在这一层做:/choro 的 UI 回执也调 renderChoroBlock,但它不进宿主模板,
|
|
146
|
-
// 转义了反而会显示成一串反斜杠。这里的 config 与 inject.js 同一份开关。
|
|
147
|
-
const rendered = escapePromptVars(config, renderChoroBlock(outline, tier, lang));
|
|
148
|
-
cache = { key, text: rendered };
|
|
149
|
-
return rendered;
|
|
150
|
-
} catch (error) {
|
|
151
|
-
// P31:注入永远不抛。日志留一次线索,但本帧就当没有地志。
|
|
152
|
-
logger?.warn?.("[dsh-mneme] chorography 注入块渲染失败,本帧跳过:" + String(error?.message ?? error));
|
|
153
|
-
return "";
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
text,
|
|
159
|
-
tier,
|
|
160
|
-
dispose() {
|
|
161
|
-
cache = null;
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
}
|
|
1
|
+
// dsh-mneme/src/wiki/inject.js
|
|
2
|
+
// chorography 的注入面(M3):会话开局往 systemPrompt 里塞一小块「仓库地志提纲」。
|
|
3
|
+
//
|
|
4
|
+
// 三条边界(spec §7 / P24–P33):
|
|
5
|
+
// 1. **只注标题级**——模块名 + 文件数 + 页状态 + 页相对路径,不读页正文。正文要
|
|
6
|
+
// 模型自己用 choro_read_page 取,那不是「开局就该付的成本」。
|
|
7
|
+
// 2. **不上热路径的硬活**——不 fork git、不 stat 磁盘、不解析 markdown。这里只吃
|
|
8
|
+
// DB 里已有的行;过期判定留给 /choro(人主动触发,付得起一次 git rev-parse)。
|
|
9
|
+
// 3. **绝不抛**——本块折在既有的 memory context 里,一个附属信息块把整轮
|
|
10
|
+
// systemPrompt 搞崩是不成比例的失败。任何异常都退化成空串(= 本帧不注入,
|
|
11
|
+
// 宿主契约里空文本会被过滤,不占位)。
|
|
12
|
+
import { escapePromptVars } from "../user-settings.js";
|
|
13
|
+
import { STR } from "../lang.js";
|
|
14
|
+
|
|
15
|
+
/** 档位枚举(与 config.js 的 chorographyInject 同一份取值,配置闸门在 settings.js)。 */
|
|
16
|
+
export const INJECT_TIERS = Object.freeze(["off", "light", "full"]);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* light 档最多列几个模块。
|
|
20
|
+
*
|
|
21
|
+
* 定 6 是照着 spec §7 的「≤8 行」倒推的:块头 1 行 + 模块行 6 行 + 「还有 N 个」
|
|
22
|
+
* 1 行 = 8 行。多给两行要挤掉「还有 N 个」那句,读者就不知道清单被截断了——
|
|
23
|
+
* 静默截断比明说「还有 30 个」更坏。
|
|
24
|
+
*/
|
|
25
|
+
export const LIGHT_MODULE_LIMIT = 6;
|
|
26
|
+
|
|
27
|
+
/** 各档字符硬上限。宿主侧没有任何体积预算(V3 实测),所以上限只能自己兜。 */
|
|
28
|
+
export const MAX_BLOCK_CHARS = Object.freeze({ light: 900, full: 6000 });
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 配置 → 档位。纯函数,无副作用,供注入侧与 /choro 共用同一份判据。
|
|
32
|
+
*
|
|
33
|
+
* 轻量档(lightMode)在这里被压成 off 而不是进 LIGHT_MODE_OFF:那张表对平铺键
|
|
34
|
+
* 一律赋 false,枚举键塞进去会得到与 schema 不符的 false,而 false !== "off"
|
|
35
|
+
* 时注入照样渲染——比不关更糟(P26)。
|
|
36
|
+
*/
|
|
37
|
+
export function resolveInjectTier(config) {
|
|
38
|
+
if (!config || config.chorographyEnabled !== true) return "off";
|
|
39
|
+
if (config.lightMode === true) return "off";
|
|
40
|
+
const raw = config.chorographyInject;
|
|
41
|
+
return INJECT_TIERS.includes(raw) ? raw : "light";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 页状态 → 标签。skeleton 不出标签(那是默认态,全标一遍等于没标)。 */
|
|
45
|
+
function statusLabel(status, language) {
|
|
46
|
+
if (status === "enriched") return STR.choroStatusEnriched[language];
|
|
47
|
+
if (status === "failed") return STR.choroStatusFailed[language];
|
|
48
|
+
if (status === "stale") return STR.choroStatusStale[language];
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* light 档取哪些模块。
|
|
54
|
+
*
|
|
55
|
+
* 按文件数降序、同数按 slug 升序——**不是**取字母序前 6 个:字母序会永远只显示
|
|
56
|
+
* 同一批(通常还是 src 这种大而空的目录页),而大模块是「被问到的概率」最高的
|
|
57
|
+
* 那批。排序里带 slug 是为了同一份库每次渲染字节一致(缓存与测试都靠它)。
|
|
58
|
+
*/
|
|
59
|
+
function pickModules(modules, tier) {
|
|
60
|
+
// 两档用同一份排序:light 与 full 若各按各的排,同一份地志在两个档位下会给出
|
|
61
|
+
// 不同次序,读起来像「刚才那份被重扫过了」。大模块在前对两档都成立——
|
|
62
|
+
// 被问到的概率最高的那批,本来就该排前面。
|
|
63
|
+
const ordered = [...modules].sort((a, b) => {
|
|
64
|
+
const d = (b.fileCount ?? 0) - (a.fileCount ?? 0);
|
|
65
|
+
if (d !== 0) return d;
|
|
66
|
+
return a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0;
|
|
67
|
+
});
|
|
68
|
+
if (tier === "full") return { shown: ordered, rest: 0 };
|
|
69
|
+
return { shown: ordered.slice(0, LIGHT_MODULE_LIMIT), rest: Math.max(0, ordered.length - LIGHT_MODULE_LIMIT) };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 生成时间只留日期部分:注入块里精确到毫秒没有信息量,只挤体积。 */
|
|
73
|
+
function dateOnly(iso) {
|
|
74
|
+
const match = /^(\d{4}-\d{2}-\d{2})/.exec(String(iso ?? ""));
|
|
75
|
+
return match ? match[1] : String(iso ?? "");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 渲染地志提纲块。纯函数(入参进、字符串出),注入侧与 /choro 的「看提纲」
|
|
80
|
+
* 共用这一份——两张皮在这里只剩档位与语言两个参数之差。
|
|
81
|
+
*
|
|
82
|
+
* @param {object|null} outline createChoroQueries().outline() 的产物
|
|
83
|
+
* @param {"light"|"full"} tier 已解析的档位(off 不该调到这里)
|
|
84
|
+
* @param {"zh"|"en"} language
|
|
85
|
+
* @returns {string} 空串 = 不注入
|
|
86
|
+
*/
|
|
87
|
+
export function renderChoroBlock(outline, tier, language = "zh") {
|
|
88
|
+
if (!outline || !Array.isArray(outline.modules) || outline.modules.length === 0) return "";
|
|
89
|
+
const lang = language === "en" ? "en" : "zh";
|
|
90
|
+
const cap = MAX_BLOCK_CHARS[tier] ?? MAX_BLOCK_CHARS.light;
|
|
91
|
+
const picked = pickModules(outline.modules, tier);
|
|
92
|
+
|
|
93
|
+
const lines = [
|
|
94
|
+
STR.choroBlockHeader[lang](outline.repo.name, outline.modules.length, dateOnly(outline.generatedAt))
|
|
95
|
+
];
|
|
96
|
+
for (const mod of picked.shown) {
|
|
97
|
+
lines.push(STR.choroBlockLine[lang](mod.title, mod.fileCount ?? 0, statusLabel(mod.status, lang), mod.relPath ?? ""));
|
|
98
|
+
}
|
|
99
|
+
if (picked.rest > 0) lines.push(STR.choroBlockMore[lang](picked.rest));
|
|
100
|
+
|
|
101
|
+
// 逐行累加而不是拼完再切:切在行中间会让最后一条模块行变成半句话,
|
|
102
|
+
// 模型读到的「路径」就可能是断的——宁可少一行,不可半行。
|
|
103
|
+
const kept = [];
|
|
104
|
+
let used = 0;
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
if (used + line.length + 1 > cap) break;
|
|
107
|
+
kept.push(line);
|
|
108
|
+
used += line.length + 1;
|
|
109
|
+
}
|
|
110
|
+
if (kept.length <= 1) return "";
|
|
111
|
+
return kept.join("\n");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 注入器(给 src/inject.js 用)。
|
|
116
|
+
*
|
|
117
|
+
* 缓存键用 **outline.generatedAt**(页级生成时间的最大值),不是 choro_repos.
|
|
118
|
+
* updated_at:T1 富化只推 choro_pages.generated_at,不动仓库行——若按仓库行做键,
|
|
119
|
+
* 用户刚在终端跑完 `--t1 --apply`,注入块还写着「骨架」,而 /choro(无缓存)已经
|
|
120
|
+
* 报「已富化」。两个面说同一件事却给出不同答案,比慢一点糟得多。
|
|
121
|
+
* 每轮仍查一次库取提纲(一次索引查询,几十微秒,不 fork git、不 stat 磁盘),
|
|
122
|
+
* 只是**渲染**走缓存——省的是拼字符串,不是正确性。
|
|
123
|
+
*
|
|
124
|
+
* @param {object} opts.choro createChoroQueries() 的产物(注入侧只读它)
|
|
125
|
+
* @param {object} opts.config 合并后的配置
|
|
126
|
+
* @param {object} [opts.logger]
|
|
127
|
+
* @param {() => string} [opts.language] 语言取值器(跟随配置,不在创建时定死)
|
|
128
|
+
* @returns {{ text: (cwd: string|null|undefined) => string, tier: string, dispose: () => void }}
|
|
129
|
+
*/
|
|
130
|
+
export function createChoroInject({ choro, config, logger = null, language = null } = {}) {
|
|
131
|
+
const langOf = typeof language === "function" ? language : () => "zh";
|
|
132
|
+
const tier = resolveInjectTier(config);
|
|
133
|
+
let cache = null; // { key, text }
|
|
134
|
+
|
|
135
|
+
function text(cwd) {
|
|
136
|
+
if (tier === "off" || !choro) return "";
|
|
137
|
+
try {
|
|
138
|
+
const repo = typeof choro.repoByCwd === "function" ? choro.repoByCwd(cwd) : null;
|
|
139
|
+
if (!repo) return "";
|
|
140
|
+
const lang = langOf() === "en" ? "en" : "zh";
|
|
141
|
+
const outline = typeof choro.outline === "function" ? choro.outline(repo.id) : null;
|
|
142
|
+
// 键取页级生成时间:T0 重算与 T1 富化都会推进它,两种「地志变了」都命中。
|
|
143
|
+
const key = tier + "|" + lang + "|" + repo.id + "|" + (outline?.generatedAt ?? repo.updated_at ?? "");
|
|
144
|
+
if (cache && cache.key === key) return cache.text;
|
|
145
|
+
// 转义只在这一层做:/choro 的 UI 回执也调 renderChoroBlock,但它不进宿主模板,
|
|
146
|
+
// 转义了反而会显示成一串反斜杠。这里的 config 与 inject.js 同一份开关。
|
|
147
|
+
const rendered = escapePromptVars(config, renderChoroBlock(outline, tier, lang));
|
|
148
|
+
cache = { key, text: rendered };
|
|
149
|
+
return rendered;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
// P31:注入永远不抛。日志留一次线索,但本帧就当没有地志。
|
|
152
|
+
logger?.warn?.("[dsh-mneme] chorography 注入块渲染失败,本帧跳过:" + String(error?.message ?? error));
|
|
153
|
+
return "";
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
text,
|
|
159
|
+
tier,
|
|
160
|
+
dispose() {
|
|
161
|
+
cache = null;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|