@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/choro-command.js
CHANGED
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
// dsh-mneme/src/choro-command.js
|
|
2
|
-
// /choro:仓库地志的只读回执(M3,spec §10)。
|
|
3
|
-
//
|
|
4
|
-
// 与 pipeline-command.js 的区别:那边持有状态(开窗 / 结账),这边**什么都不写**。
|
|
5
|
-
// spec §2 D6 定的是「只手动触发,过期只提示」——重建、富化、切档位全都不在这条
|
|
6
|
-
// 命令里,它只回答三个问题:当前仓库登记过地志吗?基线还一致吗?提纲长什么样?
|
|
7
|
-
import { gitHead } from "./wiki/t0.js";
|
|
8
|
-
import { renderChoroBlock } from "./wiki/inject.js";
|
|
9
|
-
import { STR } from "./lang.js";
|
|
10
|
-
// #607:提示里的 CLI 命令必须给绝对路径入口(profile 装的插件没有全局 shim),
|
|
11
|
-
// 光写 `dsh-mneme-choro` 让用户照抄只会 command not found。推导不出入口时
|
|
12
|
-
// 返回 null,文案退回通用说法——宁可少说,也不给一条跑不起来的命令。
|
|
13
|
-
import { choroCliCommandFrom } from "./wiki/cli-hint.js";
|
|
14
|
-
|
|
15
|
-
export const CHORO_COMMAND = "choro";
|
|
16
|
-
|
|
17
|
-
/** 短 sha:回执里只用于人眼比对,给全 40 位纯属噪音。 */
|
|
18
|
-
function shortSha(sha) {
|
|
19
|
-
const text = String(sha ?? "").trim();
|
|
20
|
-
return text.length > 7 ? text.slice(0, 7) : text;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** 生成时间只留日期(与注入块同口径:分钟级精度在这块文本里没有信息量)。 */
|
|
24
|
-
function dateOnly(iso) {
|
|
25
|
-
const m = /^(\d{4}-\d{2}-\d{2})/.exec(String(iso ?? ""));
|
|
26
|
-
return m ? m[1] : String(iso ?? "");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 过期判定:地志落库时的 git 基线 vs 当前 HEAD。
|
|
31
|
-
*
|
|
32
|
-
* **只在这里做**——注入块是每轮都要渲染的热路径,fork 一次 git 在 Windows 上
|
|
33
|
-
* 几十毫秒起步(P29)。这里是用户主动敲的,付得起一次 rev-parse。
|
|
34
|
-
* 三种结局分开报:一致 / 不一致 / 读不到 git——不能把「读不到」说成「没过期」。
|
|
35
|
-
*/
|
|
36
|
-
function staleness(repo) {
|
|
37
|
-
const baseline = String(repo.git_baseline ?? "").trim();
|
|
38
|
-
const head = gitHead(repo.root_path);
|
|
39
|
-
if (!head) return { state: "no-git", baseline, head: null };
|
|
40
|
-
if (baseline && baseline === head) return { state: "fresh", baseline, head };
|
|
41
|
-
return { state: "stale", baseline, head };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 处理函数。返回 CommandResult 形状 { kind, text }——**只作 UI 回执,不进模型
|
|
46
|
-
* 上下文**(同 pipeline-command.js 的契约注释);要模型看提纲,走开局注入那条路。
|
|
47
|
-
*
|
|
48
|
-
* @param {object} opts.choro createChoroQueries() 的产物
|
|
49
|
-
* @param {object} opts.config 合并后的配置
|
|
50
|
-
* @param {() => string} [opts.language]
|
|
51
|
-
*/
|
|
52
|
-
export function createChoroHandler({ choro, config, language = () => "zh" } = {}) {
|
|
53
|
-
// 本文件在 `src/` 与 `lib/` 的同一层(bin/ 的父级),推导一次就够,不必每次
|
|
54
|
-
// 报错都去碰文件系统。
|
|
55
|
-
const cli = choroCliCommandFrom(import.meta.url, language() === "en" ? "<repo path>" : "<仓库路径>");
|
|
56
|
-
return (invocation) => {
|
|
57
|
-
const lang = language() === "en" ? "en" : "zh";
|
|
58
|
-
const S = STR.choroCommandUsage[lang];
|
|
59
|
-
try {
|
|
60
|
-
// 闸只认 chorographyEnabled,不认注入档位:resolveInjectTier 在轻量档下也返回
|
|
61
|
-
// "off",用它当闸会让 lightMode 的用户敲 /choro 时听到「没开,去设置里打开」
|
|
62
|
-
// ——而设置里明明是开着的(档位只管注入,不管这条命令能不能看提纲)。
|
|
63
|
-
if (!config || config.chorographyEnabled !== true) return { kind: "error", text: S.off };
|
|
64
|
-
const raw = invocation?.agent?.session?.header?.cwd ?? null;
|
|
65
|
-
const cwd = typeof raw === "string" ? raw.trim() : "";
|
|
66
|
-
if (!cwd) return { kind: "error", text: S.noCwd };
|
|
67
|
-
const repo = choro ? choro.repoByCwd(cwd) : null;
|
|
68
|
-
if (!repo) return { kind: "error", text: S.noRepo(cwd, cli) };
|
|
69
|
-
const outline = choro.outline(repo.id);
|
|
70
|
-
if (!outline || outline.modules.length === 0) {
|
|
71
|
-
return { kind: "success", text: S.title(repo.name, 0, dateOnly(repo.updated_at)) + "\n" + S.empty };
|
|
72
|
-
}
|
|
73
|
-
const lines = [S.title(repo.name, outline.modules.length, dateOnly(outline.generatedAt))];
|
|
74
|
-
// 命令里的清单不设 light 的 6 行上限:人主动敲了命令就是要看全表。
|
|
75
|
-
// 但 full 档的字符上限仍由 renderChoroBlock 自己兜——回执是 UI 里一个文本框,
|
|
76
|
-
// 贴爆它同样是失败(上限不在这里判,两处各判一次迟早对不上)。
|
|
77
|
-
const block = renderChoroBlock(outline, "full", lang);
|
|
78
|
-
if (block) lines.push(block.split("\n").slice(1).join("\n"));
|
|
79
|
-
// 截断语要说「还剩几个」,不是「总共几个」:总表格行数减去真列出来的行数才是
|
|
80
|
-
// 读者没看到的量。传总数会让人以为「另有 38 个」而实际只漏了 3 个。
|
|
81
|
-
const listed = block ? block.split("\n").filter((line) => line.startsWith("- ")).length : 0;
|
|
82
|
-
const rest = Math.max(0, outline.modules.length - listed);
|
|
83
|
-
if (rest > 0) lines.push(S.truncated(rest));
|
|
84
|
-
const head = staleness(repo);
|
|
85
|
-
if (head.state === "fresh") lines.push(S.fresh(shortSha(head.head)));
|
|
86
|
-
else if (head.state === "stale") lines.push(S.stale(shortSha(head.baseline), shortSha(head.head), cli));
|
|
87
|
-
else lines.push(S.noGit);
|
|
88
|
-
lines.push(S.hint);
|
|
89
|
-
return { kind: "success", text: lines.filter(Boolean).join("\n") };
|
|
90
|
-
} catch (error) {
|
|
91
|
-
// 回执层永不抛进宿主(同 pipeline-command.js):把原因写进文本就够了。
|
|
92
|
-
return { kind: "error", text: String(error?.message ?? error) };
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 注册。返回 disposer 或 null(宿主没有命令注册表时静默返回 null,不抛)。
|
|
99
|
-
* 形状与 registerMoRunCommand 一致——两条内置命令只有「做什么」不同。
|
|
100
|
-
*/
|
|
101
|
-
export function registerChoroCommand({ ctx, choro, config, enabled, language = () => "zh" }) {
|
|
102
|
-
if (enabled !== true) return null;
|
|
103
|
-
if (typeof ctx?.commands?.register !== "function") return null;
|
|
104
|
-
const lang = language() === "en" ? "en" : "zh";
|
|
105
|
-
return ctx.commands.register({
|
|
106
|
-
name: CHORO_COMMAND,
|
|
107
|
-
description: STR.choroCommandDescription[lang],
|
|
108
|
-
input: { hint: STR.choroCommandInputHint[lang] },
|
|
109
|
-
handler: createChoroHandler({ choro, config, language })
|
|
110
|
-
});
|
|
111
|
-
}
|
|
1
|
+
// dsh-mneme/src/choro-command.js
|
|
2
|
+
// /choro:仓库地志的只读回执(M3,spec §10)。
|
|
3
|
+
//
|
|
4
|
+
// 与 pipeline-command.js 的区别:那边持有状态(开窗 / 结账),这边**什么都不写**。
|
|
5
|
+
// spec §2 D6 定的是「只手动触发,过期只提示」——重建、富化、切档位全都不在这条
|
|
6
|
+
// 命令里,它只回答三个问题:当前仓库登记过地志吗?基线还一致吗?提纲长什么样?
|
|
7
|
+
import { gitHead } from "./wiki/t0.js";
|
|
8
|
+
import { renderChoroBlock } from "./wiki/inject.js";
|
|
9
|
+
import { STR } from "./lang.js";
|
|
10
|
+
// #607:提示里的 CLI 命令必须给绝对路径入口(profile 装的插件没有全局 shim),
|
|
11
|
+
// 光写 `dsh-mneme-choro` 让用户照抄只会 command not found。推导不出入口时
|
|
12
|
+
// 返回 null,文案退回通用说法——宁可少说,也不给一条跑不起来的命令。
|
|
13
|
+
import { choroCliCommandFrom } from "./wiki/cli-hint.js";
|
|
14
|
+
|
|
15
|
+
export const CHORO_COMMAND = "choro";
|
|
16
|
+
|
|
17
|
+
/** 短 sha:回执里只用于人眼比对,给全 40 位纯属噪音。 */
|
|
18
|
+
function shortSha(sha) {
|
|
19
|
+
const text = String(sha ?? "").trim();
|
|
20
|
+
return text.length > 7 ? text.slice(0, 7) : text;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 生成时间只留日期(与注入块同口径:分钟级精度在这块文本里没有信息量)。 */
|
|
24
|
+
function dateOnly(iso) {
|
|
25
|
+
const m = /^(\d{4}-\d{2}-\d{2})/.exec(String(iso ?? ""));
|
|
26
|
+
return m ? m[1] : String(iso ?? "");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 过期判定:地志落库时的 git 基线 vs 当前 HEAD。
|
|
31
|
+
*
|
|
32
|
+
* **只在这里做**——注入块是每轮都要渲染的热路径,fork 一次 git 在 Windows 上
|
|
33
|
+
* 几十毫秒起步(P29)。这里是用户主动敲的,付得起一次 rev-parse。
|
|
34
|
+
* 三种结局分开报:一致 / 不一致 / 读不到 git——不能把「读不到」说成「没过期」。
|
|
35
|
+
*/
|
|
36
|
+
function staleness(repo) {
|
|
37
|
+
const baseline = String(repo.git_baseline ?? "").trim();
|
|
38
|
+
const head = gitHead(repo.root_path);
|
|
39
|
+
if (!head) return { state: "no-git", baseline, head: null };
|
|
40
|
+
if (baseline && baseline === head) return { state: "fresh", baseline, head };
|
|
41
|
+
return { state: "stale", baseline, head };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 处理函数。返回 CommandResult 形状 { kind, text }——**只作 UI 回执,不进模型
|
|
46
|
+
* 上下文**(同 pipeline-command.js 的契约注释);要模型看提纲,走开局注入那条路。
|
|
47
|
+
*
|
|
48
|
+
* @param {object} opts.choro createChoroQueries() 的产物
|
|
49
|
+
* @param {object} opts.config 合并后的配置
|
|
50
|
+
* @param {() => string} [opts.language]
|
|
51
|
+
*/
|
|
52
|
+
export function createChoroHandler({ choro, config, language = () => "zh" } = {}) {
|
|
53
|
+
// 本文件在 `src/` 与 `lib/` 的同一层(bin/ 的父级),推导一次就够,不必每次
|
|
54
|
+
// 报错都去碰文件系统。
|
|
55
|
+
const cli = choroCliCommandFrom(import.meta.url, language() === "en" ? "<repo path>" : "<仓库路径>");
|
|
56
|
+
return (invocation) => {
|
|
57
|
+
const lang = language() === "en" ? "en" : "zh";
|
|
58
|
+
const S = STR.choroCommandUsage[lang];
|
|
59
|
+
try {
|
|
60
|
+
// 闸只认 chorographyEnabled,不认注入档位:resolveInjectTier 在轻量档下也返回
|
|
61
|
+
// "off",用它当闸会让 lightMode 的用户敲 /choro 时听到「没开,去设置里打开」
|
|
62
|
+
// ——而设置里明明是开着的(档位只管注入,不管这条命令能不能看提纲)。
|
|
63
|
+
if (!config || config.chorographyEnabled !== true) return { kind: "error", text: S.off };
|
|
64
|
+
const raw = invocation?.agent?.session?.header?.cwd ?? null;
|
|
65
|
+
const cwd = typeof raw === "string" ? raw.trim() : "";
|
|
66
|
+
if (!cwd) return { kind: "error", text: S.noCwd };
|
|
67
|
+
const repo = choro ? choro.repoByCwd(cwd) : null;
|
|
68
|
+
if (!repo) return { kind: "error", text: S.noRepo(cwd, cli) };
|
|
69
|
+
const outline = choro.outline(repo.id);
|
|
70
|
+
if (!outline || outline.modules.length === 0) {
|
|
71
|
+
return { kind: "success", text: S.title(repo.name, 0, dateOnly(repo.updated_at)) + "\n" + S.empty };
|
|
72
|
+
}
|
|
73
|
+
const lines = [S.title(repo.name, outline.modules.length, dateOnly(outline.generatedAt))];
|
|
74
|
+
// 命令里的清单不设 light 的 6 行上限:人主动敲了命令就是要看全表。
|
|
75
|
+
// 但 full 档的字符上限仍由 renderChoroBlock 自己兜——回执是 UI 里一个文本框,
|
|
76
|
+
// 贴爆它同样是失败(上限不在这里判,两处各判一次迟早对不上)。
|
|
77
|
+
const block = renderChoroBlock(outline, "full", lang);
|
|
78
|
+
if (block) lines.push(block.split("\n").slice(1).join("\n"));
|
|
79
|
+
// 截断语要说「还剩几个」,不是「总共几个」:总表格行数减去真列出来的行数才是
|
|
80
|
+
// 读者没看到的量。传总数会让人以为「另有 38 个」而实际只漏了 3 个。
|
|
81
|
+
const listed = block ? block.split("\n").filter((line) => line.startsWith("- ")).length : 0;
|
|
82
|
+
const rest = Math.max(0, outline.modules.length - listed);
|
|
83
|
+
if (rest > 0) lines.push(S.truncated(rest));
|
|
84
|
+
const head = staleness(repo);
|
|
85
|
+
if (head.state === "fresh") lines.push(S.fresh(shortSha(head.head)));
|
|
86
|
+
else if (head.state === "stale") lines.push(S.stale(shortSha(head.baseline), shortSha(head.head), cli));
|
|
87
|
+
else lines.push(S.noGit);
|
|
88
|
+
lines.push(S.hint);
|
|
89
|
+
return { kind: "success", text: lines.filter(Boolean).join("\n") };
|
|
90
|
+
} catch (error) {
|
|
91
|
+
// 回执层永不抛进宿主(同 pipeline-command.js):把原因写进文本就够了。
|
|
92
|
+
return { kind: "error", text: String(error?.message ?? error) };
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 注册。返回 disposer 或 null(宿主没有命令注册表时静默返回 null,不抛)。
|
|
99
|
+
* 形状与 registerMoRunCommand 一致——两条内置命令只有「做什么」不同。
|
|
100
|
+
*/
|
|
101
|
+
export function registerChoroCommand({ ctx, choro, config, enabled, language = () => "zh" }) {
|
|
102
|
+
if (enabled !== true) return null;
|
|
103
|
+
if (typeof ctx?.commands?.register !== "function") return null;
|
|
104
|
+
const lang = language() === "en" ? "en" : "zh";
|
|
105
|
+
return ctx.commands.register({
|
|
106
|
+
name: CHORO_COMMAND,
|
|
107
|
+
description: STR.choroCommandDescription[lang],
|
|
108
|
+
input: { hint: STR.choroCommandInputHint[lang] },
|
|
109
|
+
handler: createChoroHandler({ choro, config, language })
|
|
110
|
+
});
|
|
111
|
+
}
|
package/src/commands.js
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
|
-
import { STR } from "./lang.js";
|
|
3
|
-
|
|
4
|
-
// Custom slash-command manager: keeps the DSH command registry in sync with
|
|
5
|
-
// user-defined commands persisted in SQLite. Commands are registered on boot
|
|
6
|
-
// and (re)registered on add/remove through the API.
|
|
7
|
-
//
|
|
8
|
-
// Per the DSH command contract, a handler's CommandResult text is only a UI
|
|
9
|
-
// settlement notice and never reaches the model. To actually drive the agent,
|
|
10
|
-
// the handler submits the user-authored instruction itself as a user followup
|
|
11
|
-
// message on the receiving agent (same pattern as the official /goal command).
|
|
12
|
-
// The notice just acknowledges the submission; an optional rawInput suffix
|
|
13
|
-
// typed after the command is appended for the model.
|
|
14
|
-
|
|
15
|
-
export function createCommandManager({ ctx, settings, logger, language = "zh" }) {
|
|
16
|
-
const registered = new Map(); // name -> disposer
|
|
17
|
-
|
|
18
|
-
function registerOne(command) {
|
|
19
|
-
if (registered.has(command.name)) return;
|
|
20
|
-
let dispose;
|
|
21
|
-
try {
|
|
22
|
-
dispose = ctx.commands.register({
|
|
23
|
-
name: command.name,
|
|
24
|
-
// 缺省描述随实例语言(命令描述进命令注册表,对 LLM 可见)。
|
|
25
|
-
description: command.description || STR.commandFallbackDesc[language](command.name),
|
|
26
|
-
input: { hint: STR.commandInputHint[language] },
|
|
27
|
-
handler: (invocation) => submit(command, invocation)
|
|
28
|
-
});
|
|
29
|
-
} catch (error) {
|
|
30
|
-
logger?.warn?.(`dsh-mneme: failed to register command /${command.name}: ${String(error)}`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
registered.set(command.name, dispose);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Submit the instruction (plus optional rawInput suffix) to the receiving agent. */
|
|
37
|
-
function submit(command, invocation) {
|
|
38
|
-
const suffix = typeof invocation?.rawInput === "string" ? invocation.rawInput.trim() : "";
|
|
39
|
-
const text = suffix ? `${command.instruction}\n\n${suffix}` : command.instruction;
|
|
40
|
-
const agent = invocation?.agent;
|
|
41
|
-
if (typeof agent?.followup !== "function") {
|
|
42
|
-
// 兜底:宿主未提供接收 agent 时退回旧行为,至少把指令展示在 notice 里。
|
|
43
|
-
return { kind: "success", text };
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
agent.followup(createUserMessage({
|
|
47
|
-
content: [{ type: "text", text }],
|
|
48
|
-
source: { kind: "user" }
|
|
49
|
-
}));
|
|
50
|
-
} catch (error) {
|
|
51
|
-
logger?.warn?.(`dsh-mneme: failed to submit /${command.name} to agent: ${String(error)}`);
|
|
52
|
-
return { kind: "error", text: STR.commandSubmitFailed[language](command.name) };
|
|
53
|
-
}
|
|
54
|
-
return { kind: "success", text: STR.commandSubmitted[language](command.name) };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function unregisterOne(name) {
|
|
58
|
-
const dispose = registered.get(name);
|
|
59
|
-
if (dispose) {
|
|
60
|
-
try {
|
|
61
|
-
dispose();
|
|
62
|
-
} catch {
|
|
63
|
-
/* ignore double-dispose */
|
|
64
|
-
}
|
|
65
|
-
registered.delete(name);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Register every stored command (boot-time sync). */
|
|
70
|
-
function sync() {
|
|
71
|
-
for (const command of settings.listCommands()) registerOne(command);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Add (or replace) a command and register it live. */
|
|
75
|
-
function add({ name, description, instruction }) {
|
|
76
|
-
const command = settings.addCommand({ name, description, instruction });
|
|
77
|
-
registerOne(command);
|
|
78
|
-
return command;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Remove a command by id and unregister it live. */
|
|
82
|
-
function remove(id) {
|
|
83
|
-
const existing = settings.listCommands().find((c) => c.id === id);
|
|
84
|
-
if (!existing) return false;
|
|
85
|
-
if (!settings.removeCommand(id)) return false;
|
|
86
|
-
unregisterOne(existing.name);
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function dispose() {
|
|
91
|
-
for (const name of [...registered.keys()]) unregisterOne(name);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return { sync, add, remove, list: () => settings.listCommands(), dispose };
|
|
95
|
-
}
|
|
1
|
+
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
|
+
import { STR } from "./lang.js";
|
|
3
|
+
|
|
4
|
+
// Custom slash-command manager: keeps the DSH command registry in sync with
|
|
5
|
+
// user-defined commands persisted in SQLite. Commands are registered on boot
|
|
6
|
+
// and (re)registered on add/remove through the API.
|
|
7
|
+
//
|
|
8
|
+
// Per the DSH command contract, a handler's CommandResult text is only a UI
|
|
9
|
+
// settlement notice and never reaches the model. To actually drive the agent,
|
|
10
|
+
// the handler submits the user-authored instruction itself as a user followup
|
|
11
|
+
// message on the receiving agent (same pattern as the official /goal command).
|
|
12
|
+
// The notice just acknowledges the submission; an optional rawInput suffix
|
|
13
|
+
// typed after the command is appended for the model.
|
|
14
|
+
|
|
15
|
+
export function createCommandManager({ ctx, settings, logger, language = "zh" }) {
|
|
16
|
+
const registered = new Map(); // name -> disposer
|
|
17
|
+
|
|
18
|
+
function registerOne(command) {
|
|
19
|
+
if (registered.has(command.name)) return;
|
|
20
|
+
let dispose;
|
|
21
|
+
try {
|
|
22
|
+
dispose = ctx.commands.register({
|
|
23
|
+
name: command.name,
|
|
24
|
+
// 缺省描述随实例语言(命令描述进命令注册表,对 LLM 可见)。
|
|
25
|
+
description: command.description || STR.commandFallbackDesc[language](command.name),
|
|
26
|
+
input: { hint: STR.commandInputHint[language] },
|
|
27
|
+
handler: (invocation) => submit(command, invocation)
|
|
28
|
+
});
|
|
29
|
+
} catch (error) {
|
|
30
|
+
logger?.warn?.(`dsh-mneme: failed to register command /${command.name}: ${String(error)}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
registered.set(command.name, dispose);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Submit the instruction (plus optional rawInput suffix) to the receiving agent. */
|
|
37
|
+
function submit(command, invocation) {
|
|
38
|
+
const suffix = typeof invocation?.rawInput === "string" ? invocation.rawInput.trim() : "";
|
|
39
|
+
const text = suffix ? `${command.instruction}\n\n${suffix}` : command.instruction;
|
|
40
|
+
const agent = invocation?.agent;
|
|
41
|
+
if (typeof agent?.followup !== "function") {
|
|
42
|
+
// 兜底:宿主未提供接收 agent 时退回旧行为,至少把指令展示在 notice 里。
|
|
43
|
+
return { kind: "success", text };
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
agent.followup(createUserMessage({
|
|
47
|
+
content: [{ type: "text", text }],
|
|
48
|
+
source: { kind: "user" }
|
|
49
|
+
}));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger?.warn?.(`dsh-mneme: failed to submit /${command.name} to agent: ${String(error)}`);
|
|
52
|
+
return { kind: "error", text: STR.commandSubmitFailed[language](command.name) };
|
|
53
|
+
}
|
|
54
|
+
return { kind: "success", text: STR.commandSubmitted[language](command.name) };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function unregisterOne(name) {
|
|
58
|
+
const dispose = registered.get(name);
|
|
59
|
+
if (dispose) {
|
|
60
|
+
try {
|
|
61
|
+
dispose();
|
|
62
|
+
} catch {
|
|
63
|
+
/* ignore double-dispose */
|
|
64
|
+
}
|
|
65
|
+
registered.delete(name);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Register every stored command (boot-time sync). */
|
|
70
|
+
function sync() {
|
|
71
|
+
for (const command of settings.listCommands()) registerOne(command);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Add (or replace) a command and register it live. */
|
|
75
|
+
function add({ name, description, instruction }) {
|
|
76
|
+
const command = settings.addCommand({ name, description, instruction });
|
|
77
|
+
registerOne(command);
|
|
78
|
+
return command;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Remove a command by id and unregister it live. */
|
|
82
|
+
function remove(id) {
|
|
83
|
+
const existing = settings.listCommands().find((c) => c.id === id);
|
|
84
|
+
if (!existing) return false;
|
|
85
|
+
if (!settings.removeCommand(id)) return false;
|
|
86
|
+
unregisterOne(existing.name);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function dispose() {
|
|
91
|
+
for (const name of [...registered.keys()]) unregisterOne(name);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { sync, add, remove, list: () => settings.listCommands(), dispose };
|
|
95
|
+
}
|