dsh-trivium 0.4.17 → 0.4.19
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 +10 -2
- package/README.zh-CN.md +10 -2
- package/lib/atomic.js +42 -0
- package/lib/client.js +54 -11
- package/lib/index.js +3 -1
- package/lib/settings.js +9 -5
- package/lib/sidecar.js +4 -19
- package/lib/store.js +5 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -46,8 +46,11 @@ Local source checkout:
|
|
|
46
46
|
```sh
|
|
47
47
|
npm install
|
|
48
48
|
node scripts/link-dsh.mjs
|
|
49
|
+
npm test # optional: runs every offline smoke script
|
|
49
50
|
```
|
|
50
51
|
|
|
52
|
+
`npm test` needs no DSH host and never touches your real `~/.dsh/trivium.json` (each script gets its own temp settings file). Pass a substring to narrow it: `npm test -- p8`.
|
|
53
|
+
|
|
51
54
|
Then restart `dsh web`.
|
|
52
55
|
|
|
53
56
|
## Updating
|
|
@@ -126,7 +129,7 @@ Trivium is a memory kernel, not a journal, calendar, or chat companion. It store
|
|
|
126
129
|
- **Injection via `agent.inject()`** — not the system prompt, so `persona.complete: true` cannot silently drop the map.
|
|
127
130
|
- **Recall carries paths** — every hit says which node it came from and along which edge.
|
|
128
131
|
- **Failures never block the agent** — store / embedding / extract errors are logged; the main loop continues.
|
|
129
|
-
- **UI follows the host language** — Settings and the Chips (memory whitelist) tab switch with DSH `locale/change` (`zh` / `en`).
|
|
132
|
+
- **UI follows the host language** — Settings and the Chips (memory whitelist) tab switch with DSH `locale/change` (`zh` / `en`). Any other resolved host language — and a browser that names no registered language — falls to English, the same `FALLBACK_LOCALE` the host itself uses.
|
|
130
133
|
- **First-turn map** — the short map is injected once per session. If `session-start` loses a race with the first model step, `pre-step` fills it in; it is not rewritten every step (prefix-cache friendly).
|
|
131
134
|
|
|
132
135
|
## Features
|
|
@@ -242,6 +245,10 @@ Off by default. After you turn **Chips (memory whitelist)** on in Settings, the
|
|
|
242
245
|
|
|
243
246
|
## Changelog
|
|
244
247
|
|
|
248
|
+
**0.4.19** — Fixed the plugin's own UI rendering Simplified Chinese on an English host ([issue #2](https://github.com/QWQcool/dsh-trivium/issues/2)). The `locale` service is now reached through `ctx.inject(["locale"], …)`, so **follow host** no longer depends on composition order, and the plugin fallback is `en` — the host's own `FALLBACK_LOCALE`, and the bucket every other resolved host language lands in. The Settings card and the Chips tab only ever choose between zh and en, so a browser naming no registered language no longer gets a Chinese card. Four tools / short map / find paths unchanged.
|
|
249
|
+
|
|
250
|
+
**0.4.18** — `~/.dsh/trivium.json` is now written atomically (a truncated write used to reset every switch and chip pin silently) and is owner-only on POSIX. `npm test` runs every offline smoke script with isolated settings, and `smoke-p0` pins the hybrid text-index-after-reopen invariant. Four tools / short map / find paths unchanged.
|
|
251
|
+
|
|
245
252
|
**0.4.17** — Storage bump to `triviumdb@0.8.8` (engine behavior unchanged from 0.4.16). Host adaptation for `@deepseek-ai/dsh@0.1.5-rc.1`: `session.header.seedLength` was removed, so the session-layer fork cut now reads `session.inheritedEventCount`. Four tools / short map / find paths unchanged.
|
|
246
253
|
|
|
247
254
|
**0.4.16** — Storage bump to `triviumdb@0.8.4`: the engine constructor now takes an options object (`{ dim }`) instead of numeric positional args, and TQL rows return string ids that the plugin coerces back to numbers. Four tools / short map / find paths unchanged.
|
|
@@ -283,6 +290,7 @@ Off by default. After you turn **Chips (memory whitelist)** on in Settings, the
|
|
|
283
290
|
| Symptom | What to do |
|
|
284
291
|
|---|---|
|
|
285
292
|
| Settings has no **Trivium memory** | Confirm the **web** profile, then **restart** `dsh web` and open a workspace. Reloading the browser is not enough. |
|
|
293
|
+
| Settings card / Chips tab shows Chinese on an English host | Fixed in 0.4.19 ([issue #2](https://github.com/QWQcool/dsh-trivium/issues/2)). On an older build pick **Settings → Trivium memory → Settings → Plugin language → English**; that is stored in `~/.dsh/trivium.json` and a page reload is enough (no host restart). |
|
|
286
294
|
| Title bar has no **Chips** | Turn on **Chips (memory whitelist)** in Settings (it saves as soon as you toggle). Switch back to the conversation; the tab should appear without restarting. |
|
|
287
295
|
| Injection / extract / embedding / chip tab changes have no effect | Chip / extract / recall toggles save immediately. Embedding URL still uses **Save**. Restart `dsh web` only if the settings page itself is missing. |
|
|
288
296
|
| Session layer shows only a **Next** box | Expected when the nested session layer is on. Boxes follow DSH compaction; a long session is not the same as already compacted (auto-compact is around 80% of the window). To split: `/compact` in the conversation, or **Create checkpoint** (plot only, does not compact the window). Older sessions can use **Update checkpoints** to backfill past compaction / forks. |
|
|
@@ -300,7 +308,7 @@ Local source checkout: `npm install`, then `node scripts/link-dsh.mjs`, then res
|
|
|
300
308
|
## Release info
|
|
301
309
|
|
|
302
310
|
- GitHub: https://github.com/QWQcool/dsh-trivium
|
|
303
|
-
- npm: [`dsh-trivium@0.4.
|
|
311
|
+
- npm: [`dsh-trivium@0.4.19`](https://www.npmjs.com/package/dsh-trivium)
|
|
304
312
|
- Tested host: `@deepseek-ai/dsh@0.1.5-rc.1` (also `0.1.1-rc.2` / `0.1.0-rc.8`)
|
|
305
313
|
- License: MIT (depends on [TriviumDB](https://github.com/YoKONCy/TriviumDB), Apache-2.0)
|
|
306
314
|
|
package/README.zh-CN.md
CHANGED
|
@@ -44,8 +44,11 @@ clone / `git pull` 后若 jsonl 变了会自动导回。设置里 **Git 旁路**
|
|
|
44
44
|
```sh
|
|
45
45
|
npm install
|
|
46
46
|
node scripts/link-dsh.mjs
|
|
47
|
+
npm test # 可选:跑全部离线 smoke
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
`npm test` 不需要 DSH 宿主,也不会碰你真实的 `~/.dsh/trivium.json`(每个脚本用独立的临时设置文件)。想只跑一部分就传子串:`npm test -- p8`。
|
|
51
|
+
|
|
49
52
|
然后重启 `dsh web`。
|
|
50
53
|
|
|
51
54
|
## 更新
|
|
@@ -122,7 +125,7 @@ Trivium 是记忆内核,不是日记、日历或聊天伴侣。它按**节点
|
|
|
122
125
|
- **注入走 `agent.inject()`** — 不写 system prompt,避免 `persona.complete: true` 把地图静默丢掉。
|
|
123
126
|
- **召回带路径** — 每条命中都说明从哪个节点、沿哪条边过来。
|
|
124
127
|
- **失败不挡主循环** — 存储 / embedding / 抽取出错只记日志,Agent 继续。
|
|
125
|
-
- **界面跟随宿主语言** — 设置页和「芯片」标签随 DSH `locale/change` 切换(`zh` / `en
|
|
128
|
+
- **界面跟随宿主语言** — 设置页和「芯片」标签随 DSH `locale/change` 切换(`zh` / `en`),也可在配置设置里锁定。其它已解析的宿主语言、以及浏览器未命名任何注册语言的情况,一律回落英文(与宿主自己的 `FALLBACK_LOCALE` 一致)。
|
|
126
129
|
- **首轮短地图** — 每个会话只注入一次。若 `session-start` 和第一步赛跑输了,`pre-step` 会补上;不会每步重写(前缀缓存友好)。
|
|
127
130
|
|
|
128
131
|
## 功能
|
|
@@ -238,6 +241,10 @@ Trivium 是记忆内核,不是日记、日历或聊天伴侣。它按**节点
|
|
|
238
241
|
|
|
239
242
|
## 更新说明
|
|
240
243
|
|
|
244
|
+
**0.4.19** — 修复插件自身界面在英文宿主上渲染成简体中文([issue #2](https://github.com/QWQcool/dsh-trivium/issues/2))。`locale` 服务改经 `ctx.inject(["locale"], …)` 获取,「跟随宿主」不再依赖插件组合顺序;兜底语言改为 `en`——与宿主自己的 `FALLBACK_LOCALE` 一致,也是其它已解析宿主语言的归宿。设置卡与芯片标签只在 zh / en 之间选择,浏览器未命名任何注册语言时不再给出中文卡。四工具 / 短地图 / find 路径不变。
|
|
245
|
+
|
|
246
|
+
**0.4.18** — `~/.dsh/trivium.json` 改为原子写(此前写到一半被杀会让所有开关和芯片钉选静默回默认),POSIX 下权限收紧为仅属主可读。新增 `npm test` 聚合入口(每个脚本用独立临时设置文件),`smoke-p0` 新增「重开后 hybrid 文本索引仍可用」的断言。四工具 / 短地图 / find 路径行为不变。
|
|
247
|
+
|
|
241
248
|
**0.4.17** — 存储升到 `triviumdb@0.8.8`(引擎行为相对 0.4.16 不变)。适配宿主 `@deepseek-ai/dsh@0.1.5-rc.1`:`session.header.seedLength` 被移除,会话层 fork 切点改读 `session.inheritedEventCount`。四工具 / 短地图 / find 路径不变。
|
|
242
249
|
|
|
243
250
|
**0.4.16** — 存储升到 `triviumdb@0.8.4`:引擎构造函数改为 options 对象(`{ dim }`),不再收数字位置参数;TQL 行 id 变字符串,插件内部归一为数字。四工具 / 短地图 / find 路径不变。
|
|
@@ -279,6 +286,7 @@ Trivium 是记忆内核,不是日记、日历或聊天伴侣。它按**节点
|
|
|
279
286
|
| 现象 | 处理 |
|
|
280
287
|
|---|---|
|
|
281
288
|
| 设置里没有「Trivium 记忆」 | 确认装的是 web profile,然后**重启** `dsh web`,再打开一个工作区。只刷新浏览器不够。 |
|
|
289
|
+
| 英文宿主下设置卡 / 芯片标签显示中文 | 0.4.19 已修([issue #2](https://github.com/QWQcool/dsh-trivium/issues/2))。旧版本可在 **设置 → Trivium 记忆 → 配置设置 → 插件语言 → English** 手动选一次,会写进 `~/.dsh/trivium.json`,刷新页面即可,不用重启宿主。 |
|
|
282
290
|
| 标题栏没有「芯片」 | 在设置里打开「芯片(记忆白名单)」(拨一下就会保存)。切回对话页,标签应立刻出现,不用重启。 |
|
|
283
291
|
| 改了注入 / 抽取 / embedding / 芯片开关没生效 | 芯片 / 抽取 / 注入拨一下即保存。Embedding URL 仍要点「保存设置」。只有设置页本身没出现时才重启 `dsh web`。 |
|
|
284
292
|
| 会话层只有一个「后续」方框 | 正常(在会话层已打开时)。方框跟 DSH 压缩走,会话长不等于已经压过(默认约窗口 80% 才自动压)。要分段:对话里 `/compact`,或点「生成检查点」(只切图,不压窗口)。旧会话可点「更新检查点」补已经发生过的压缩 / 分叉。 |
|
|
@@ -296,7 +304,7 @@ Trivium 是记忆内核,不是日记、日历或聊天伴侣。它按**节点
|
|
|
296
304
|
## 发布信息
|
|
297
305
|
|
|
298
306
|
- GitHub: https://github.com/QWQcool/dsh-trivium
|
|
299
|
-
- npm: [`dsh-trivium@0.4.
|
|
307
|
+
- npm: [`dsh-trivium@0.4.19`](https://www.npmjs.com/package/dsh-trivium)
|
|
300
308
|
- 测试宿主:`@deepseek-ai/dsh@0.1.5-rc.1`(兼 `0.1.1-rc.2` / `0.1.0-rc.8`)
|
|
301
309
|
- License: MIT(依赖 [TriviumDB](https://github.com/YoKONCy/TriviumDB) 为 Apache-2.0)
|
|
302
310
|
|
package/lib/atomic.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic text write: write a sibling temp file, then rename over the target.
|
|
3
|
+
*
|
|
4
|
+
* `writeFileSync(file, ...)` truncates in place, so a crash (or a kill) between
|
|
5
|
+
* truncate and write leaves a half-written file. For the settings file that
|
|
6
|
+
* means `readUiSettings()` silently returns `{}` and every switch / chip pin
|
|
7
|
+
* resets. A rename is atomic on the same volume, so readers see either the old
|
|
8
|
+
* file or the new one, never a truncated one.
|
|
9
|
+
*/
|
|
10
|
+
import { mkdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { dirname } from "node:path";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param file absolute target path
|
|
15
|
+
* @param text UTF-8 payload
|
|
16
|
+
* @param mode optional POSIX mode (ignored on Windows). Applied to the temp
|
|
17
|
+
* file, which the rename then promotes to the target.
|
|
18
|
+
* @returns the target path
|
|
19
|
+
*/
|
|
20
|
+
export function atomicWriteFile(file, text, { mode } = {}) {
|
|
21
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
22
|
+
const tmp = `${file}.tmp`;
|
|
23
|
+
// Drop a stale temp first so `mode` is actually applied on creation.
|
|
24
|
+
try {
|
|
25
|
+
unlinkSync(tmp);
|
|
26
|
+
} catch {
|
|
27
|
+
// nothing stale to remove
|
|
28
|
+
}
|
|
29
|
+
writeFileSync(tmp, text, mode === undefined ? "utf8" : { encoding: "utf8", mode });
|
|
30
|
+
try {
|
|
31
|
+
renameSync(tmp, file);
|
|
32
|
+
} catch {
|
|
33
|
+
// Windows cannot always rename over an existing file; clear and retry.
|
|
34
|
+
try {
|
|
35
|
+
unlinkSync(file);
|
|
36
|
+
} catch {
|
|
37
|
+
// destination may not exist yet
|
|
38
|
+
}
|
|
39
|
+
renameSync(tmp, file);
|
|
40
|
+
}
|
|
41
|
+
return file;
|
|
42
|
+
}
|
package/lib/client.js
CHANGED
|
@@ -324,25 +324,32 @@ window.__ModuleLoader__.load({
|
|
|
324
324
|
},
|
|
325
325
|
};
|
|
326
326
|
|
|
327
|
-
|
|
327
|
+
// Aligned with the host's own `FALLBACK_LOCALE` in
|
|
328
|
+
// `@deepseek-ai/dsh-client-locale`: English is both what DSH opens with when
|
|
329
|
+
// the browser names no registered language and the dictionary consulted after
|
|
330
|
+
// a miss, because that reader is the least likely to read Chinese. The plugin
|
|
331
|
+
// ships zh/en dictionaries only, so any other resolved host language is
|
|
332
|
+
// English here as well — never Chinese.
|
|
333
|
+
const FALLBACK_UI_LOCALE = "en";
|
|
334
|
+
|
|
335
|
+
let uiLocale = FALLBACK_UI_LOCALE;
|
|
328
336
|
let hostLocale = "";
|
|
329
337
|
let pluginLocalePref = "host";
|
|
330
338
|
const localeListeners = new Set();
|
|
331
339
|
|
|
332
340
|
function normalizeLocale(value) {
|
|
333
341
|
const s = String(value || "").toLowerCase();
|
|
334
|
-
if (s
|
|
335
|
-
|
|
336
|
-
return "";
|
|
342
|
+
if (!s) return "";
|
|
343
|
+
return s.startsWith("zh") ? "zh" : FALLBACK_UI_LOCALE;
|
|
337
344
|
}
|
|
338
345
|
|
|
339
346
|
function resolvedUiLocale() {
|
|
340
347
|
if (pluginLocalePref === "zh" || pluginLocalePref === "en") return pluginLocalePref;
|
|
341
|
-
return hostLocale ||
|
|
348
|
+
return hostLocale || FALLBACK_UI_LOCALE;
|
|
342
349
|
}
|
|
343
350
|
|
|
344
351
|
function setUiLocale(next) {
|
|
345
|
-
const loc = normalizeLocale(next) ||
|
|
352
|
+
const loc = normalizeLocale(next) || FALLBACK_UI_LOCALE;
|
|
346
353
|
if (loc === uiLocale) return;
|
|
347
354
|
uiLocale = loc;
|
|
348
355
|
localeListeners.forEach((fn) => {
|
|
@@ -3313,15 +3320,26 @@ window.__ModuleLoader__.load({
|
|
|
3313
3320
|
);
|
|
3314
3321
|
}
|
|
3315
3322
|
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
const sessions = ctx.sessions;
|
|
3323
|
+
/** Read the host locale service when it is reachable. Never throws. */
|
|
3324
|
+
function readHostLocaleFrom(hostCtx) {
|
|
3319
3325
|
try {
|
|
3320
|
-
const
|
|
3321
|
-
|
|
3326
|
+
const svc = hostCtx && hostCtx.locale;
|
|
3327
|
+
const snap = svc && typeof svc.getLocale === "function" ? svc.getLocale() : null;
|
|
3328
|
+
if (snap && snap.active) {
|
|
3329
|
+
setHostLocale(snap.active);
|
|
3330
|
+
return true;
|
|
3331
|
+
}
|
|
3332
|
+
return false;
|
|
3322
3333
|
} catch {
|
|
3323
3334
|
// host may not expose locale
|
|
3335
|
+
return false;
|
|
3324
3336
|
}
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
function apply(ctx) {
|
|
3340
|
+
workspacesList = ctx.workspaces?.list || null;
|
|
3341
|
+
const sessions = ctx.sessions;
|
|
3342
|
+
readHostLocaleFrom(ctx);
|
|
3325
3343
|
try {
|
|
3326
3344
|
ctx.on("locale/change", (snap) => {
|
|
3327
3345
|
if (snap && snap.active) setHostLocale(snap.active);
|
|
@@ -3329,6 +3347,18 @@ window.__ModuleLoader__.load({
|
|
|
3329
3347
|
} catch {
|
|
3330
3348
|
// ignore
|
|
3331
3349
|
}
|
|
3350
|
+
// The locale service is provided by its own plugin during boot, so it can
|
|
3351
|
+
// arrive after this plugin applied, and an undeclared service is not a
|
|
3352
|
+
// supported `ctx` property read. `ctx.inject` starts the callback once the
|
|
3353
|
+
// dependency exists, so "follow host" no longer depends on composition
|
|
3354
|
+
// order. Same pattern as `ctx.inject(["webServer"], …)` in lib/index.js.
|
|
3355
|
+
try {
|
|
3356
|
+
if (typeof ctx.inject === "function") {
|
|
3357
|
+
ctx.inject(["locale"], (localeCtx) => readHostLocaleFrom(localeCtx));
|
|
3358
|
+
}
|
|
3359
|
+
} catch {
|
|
3360
|
+
// host may not support injection
|
|
3361
|
+
}
|
|
3332
3362
|
ctx.slots.inject(
|
|
3333
3363
|
"settings.section",
|
|
3334
3364
|
() =>
|
|
@@ -3351,6 +3381,19 @@ window.__ModuleLoader__.load({
|
|
|
3351
3381
|
|
|
3352
3382
|
exports.apply = apply;
|
|
3353
3383
|
exports.inject = ["slots", "sessions", "workspaces"];
|
|
3384
|
+
// Test-only probe over the locale resolution above (no behaviour of its own).
|
|
3385
|
+
// The client module system resolves package-name specifiers only, so this
|
|
3386
|
+
// choice cannot live in a separate requireable file; scripts/smoke-p13.mjs
|
|
3387
|
+
// loads this bundle with a stubbed __ModuleLoader__/require and reads these.
|
|
3388
|
+
exports.__locale = {
|
|
3389
|
+
FALLBACK_UI_LOCALE,
|
|
3390
|
+
normalizeLocale,
|
|
3391
|
+
resolvedUiLocale,
|
|
3392
|
+
setHostLocale,
|
|
3393
|
+
setPluginLocalePref,
|
|
3394
|
+
readHostLocaleFrom,
|
|
3395
|
+
snapshot: () => ({ uiLocale, hostLocale, pluginLocalePref }),
|
|
3396
|
+
};
|
|
3354
3397
|
return module.exports;
|
|
3355
3398
|
},
|
|
3356
3399
|
});
|
package/lib/index.js
CHANGED
|
@@ -454,10 +454,12 @@ export function apply(ctx, config = {}) {
|
|
|
454
454
|
extra.push(
|
|
455
455
|
createUserMessage({
|
|
456
456
|
content: [{ type: "text", text: pin.text }],
|
|
457
|
+
// No `form`: "pins" was never in DSH's ContextForm union, so the
|
|
458
|
+
// client already rendered it as undeclared (opaque) context.
|
|
459
|
+
// Omitting the field is the documented default for that.
|
|
457
460
|
source: {
|
|
458
461
|
kind: "plugin",
|
|
459
462
|
plugin: "dsh-trivium",
|
|
460
|
-
form: "pins",
|
|
461
463
|
},
|
|
462
464
|
}),
|
|
463
465
|
);
|
package/lib/settings.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { homedir, tmpdir } from "node:os";
|
|
3
|
-
import {
|
|
3
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { atomicWriteFile } from "./atomic.js";
|
|
4
5
|
import { looksHttpUrl } from "./embed.js";
|
|
5
6
|
|
|
6
7
|
export const SETTINGS_FILE = join(homedir(), ".dsh", "trivium.json");
|
|
7
8
|
|
|
9
|
+
/** This file can hold an embedding API key; keep it owner-only. No-op on Windows. */
|
|
10
|
+
const SETTINGS_FILE_MODE = 0o600;
|
|
11
|
+
|
|
8
12
|
/** Tests may set DSH_TRIVIUM_SETTINGS to a temp file so we never touch the live home config. */
|
|
9
13
|
export function settingsFilePath() {
|
|
10
14
|
const override = String(process.env.DSH_TRIVIUM_SETTINGS || "").trim();
|
|
@@ -12,9 +16,9 @@ export function settingsFilePath() {
|
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
function persistSettings(next) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
// Atomic: a truncated settings file would make readUiSettings() return {}
|
|
20
|
+
// and silently reset every switch / chip pin.
|
|
21
|
+
atomicWriteFile(settingsFilePath(), JSON.stringify(next, null, 2), { mode: SETTINGS_FILE_MODE });
|
|
18
22
|
return next;
|
|
19
23
|
}
|
|
20
24
|
|
package/lib/sidecar.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** Git-friendly JSONL sidecar next to trivium.tdb. No embeddings, episodes, or chip pins. */
|
|
2
2
|
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
|
-
import { existsSync,
|
|
5
|
-
import {
|
|
4
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { atomicWriteFile } from "./atomic.js";
|
|
6
7
|
import { BUSINESS_EDGES } from "./schema.js";
|
|
7
8
|
import {
|
|
8
9
|
gitSidecarEnabledOf,
|
|
@@ -196,22 +197,6 @@ function readSidecarFile(cwd) {
|
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
function atomicWrite(file, text) {
|
|
200
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
201
|
-
const tmp = `${file}.tmp`;
|
|
202
|
-
writeFileSync(tmp, text, "utf8");
|
|
203
|
-
try {
|
|
204
|
-
renameSync(tmp, file);
|
|
205
|
-
} catch {
|
|
206
|
-
try {
|
|
207
|
-
unlinkSync(file);
|
|
208
|
-
} catch {
|
|
209
|
-
// dest may not exist
|
|
210
|
-
}
|
|
211
|
-
renameSync(tmp, file);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
200
|
function rememberHash(cwd, hash) {
|
|
216
201
|
const key = resolve(cwd);
|
|
217
202
|
memoryHash.set(key, hash);
|
|
@@ -293,7 +278,7 @@ export function writeSidecarNow(cwd, db, { force = false } = {}) {
|
|
|
293
278
|
if (!force && hash === knownHash(cwd) && existsSync(file)) {
|
|
294
279
|
return { path: file, hash, wrote: false };
|
|
295
280
|
}
|
|
296
|
-
|
|
281
|
+
atomicWriteFile(file, text);
|
|
297
282
|
rememberHash(cwd, hash);
|
|
298
283
|
return { path: file, hash, wrote: true };
|
|
299
284
|
}
|
package/lib/store.js
CHANGED
|
@@ -124,6 +124,11 @@ export async function openWorkspaceDb(cwd) {
|
|
|
124
124
|
// indexes may already exist
|
|
125
125
|
}
|
|
126
126
|
ensureWorkspaceRoot(db, cwd);
|
|
127
|
+
// Do NOT remove. triviumdb opens with `loadTextIndex: false` by default, so
|
|
128
|
+
// the persisted BM25 sidecar is not loaded and `searchHybrid`'s text channel
|
|
129
|
+
// returns nothing after a reopen until the index is rebuilt here. `searchNodes`
|
|
130
|
+
// cannot paper over the loss: its keyword fallback still scores, so a
|
|
131
|
+
// regression is silent at the tool level. scripts/smoke-p0.mjs pins this.
|
|
127
132
|
rebuildTextIndex(db);
|
|
128
133
|
dbs.set(key, db);
|
|
129
134
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-trivium",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.19",
|
|
4
4
|
"description": "In-process graph memory for DeepSeek Harness, backed by TriviumDB.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
|
+
"test": "node scripts/run-all.mjs",
|
|
34
35
|
"link-dsh": "node scripts/link-dsh.mjs",
|
|
35
36
|
"smoke-p0": "node scripts/smoke-p0.mjs",
|
|
36
37
|
"smoke-p1": "node scripts/smoke-p1.mjs",
|
|
@@ -41,9 +42,11 @@
|
|
|
41
42
|
"smoke-p6": "node scripts/smoke-p6.mjs",
|
|
42
43
|
"smoke-p7": "node scripts/smoke-p7.mjs",
|
|
43
44
|
"smoke-p8": "node scripts/smoke-p8.mjs",
|
|
45
|
+
"smoke-p9": "node scripts/smoke-p9.mjs",
|
|
44
46
|
"smoke-p10": "node scripts/smoke-p10.mjs",
|
|
45
47
|
"smoke-p11": "node scripts/smoke-p11.mjs",
|
|
46
48
|
"smoke-p12": "node scripts/smoke-p12.mjs",
|
|
49
|
+
"smoke-p13": "node scripts/smoke-p13.mjs",
|
|
47
50
|
"preuninstall": "node ./lib/purge.js",
|
|
48
51
|
"verify-live-p2": "node scripts/verify-live-p2.mjs"
|
|
49
52
|
},
|