@kira905/dsh-memory-toolkit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  本仓的版本按**语义化版本**:改结论/改契约升主版本,加能力升次版本,修错别字与文档订正不升。
4
4
  英文摘要见每节末尾的 *English* 行。
5
5
 
6
+ ## v0.1.1 — 2026-10-30
7
+
8
+ **部署面补齐 + 用语刷净**(无 API / 行为契约变化):
9
+
10
+ - `dsh-memory-local/` 部署侧支持 `.modules.yaml` profiles(主包 0.2.0-rc.x 的文件布局),新增「全新安装」分支,备份目录改为按需创建。
11
+ - 内部用语刷净:构建机的设备标记改为中性写法(`【设备:ROG】`),文档标签示例由设备名改为通用词(`工作记录`);对应单测断言同步更新,`memory-engine` 184 项全绿。
12
+ - 本版起 `npm publish` 走 `next` 标签、稳定后再挂 `latest`。
13
+
14
+ *English: deploy side now supports `.modules.yaml` profiles (host 0.2.0-rc.x) with a fresh-install branch and lazy backup-dir creation; internal build-machine wording scrubbed (no API/behaviour change).*
15
+
6
16
  ## v0.1.0 — 2026-10-19(首发)
7
17
 
8
18
  **首发范围**(从自用工作流中拆出的记忆面四件,源码级只读复制 + 脱敏 + 补齐仓骨架):
@@ -137,8 +137,13 @@ console.log(`source : ${here}`)
137
137
  console.log(`target : ${target}${isProduction ? ' ⚠ PRODUCTION HOME' : ' [non-default home]'}`)
138
138
  console.log(`entity : ${entityExists ? (alreadyFork ? `already fork (sha ${entitySha.slice(0, 16)}…)` : entityPkg?.fork ? 'fork, but different sha' : `upstream ${entityPkg?.name}@${entityPkg?.version}`) : 'absent'}`)
139
139
  console.log(`lib sha : ${srcSha}`)
140
- if (!fs.existsSync(packageMapFile)) {
141
- console.error(`[deploy] 找不到 ${packageMapFile} —— 这不是一个可加载的 DSH profile`)
140
+ // gate0b:profile 可加载性 —— 0.1.x 世代用 node_modules/.package-map.json,
141
+ // 0.2.0-rc.x 起该文件已废弃(2026-10-28 实测:已装 @deepseek-ai 包 6,273 个 .js
142
+ // 里 `package-map` / `packageMap` / `modules.yaml` 零引用),现世代以 pnpm 的
143
+ // node_modules/.modules.yaml 为准 ⇒ 二者任一存在即视为可加载。
144
+ const modulesYamlFile = path.join(profile, 'node_modules', '.modules.yaml')
145
+ if (!fs.existsSync(packageMapFile) && !fs.existsSync(modulesYamlFile)) {
146
+ console.error(`[deploy] 找不到 ${packageMapFile} 或 ${modulesYamlFile} —— 这不是一个可加载的 DSH profile`)
142
147
  process.exit(EXIT.USAGE)
143
148
  }
144
149
 
@@ -170,6 +175,12 @@ if (isUpstream) {
170
175
  const existing = findMatchingSnapshot(target)
171
176
  if (existing) { backupDir = existing; reusedSnapshot = true }
172
177
  else backupDir = path.join(archiveRoot, `g24-s2a-memory-deploy-${stamp()}`)
178
+ } else if (!entityExists) {
179
+ // 目标 profile 里**根本没有** dsh-memory 实体 = 全新安装(2026-10-28 为小汐生活实例
180
+ // `--profile life` 补的分支):没有「上游原物」可归档,restore.mjs 也用不到还原源
181
+ // ⇒ 只建一个记录目录,DEPLOY-INFO 落这里。
182
+ backupDir = path.join(archiveRoot, `g24-s2a-memory-deploy-${stamp()}`)
183
+ console.log('[deploy] 目标 profile 无 dsh-memory 实体 = 全新安装,无需归档上游原物')
173
184
  } else {
174
185
  // 已在 fork 态:沿用最近一个「含上游原物」的备份目录(restore 的唯一还原源)
175
186
  const candidates = fs.existsSync(archiveRoot)
@@ -288,6 +299,7 @@ const info = {
288
299
  rollback: `node ${path.join(here, 'restore.mjs')} --target ${home}${isProduction ? ' --allow-production' : ''}`,
289
300
  }
290
301
  const infoFile = path.join(backupDir, `DEPLOY-INFO-${stamp()}.json`)
302
+ fs.mkdirSync(backupDir, { recursive: true })
291
303
  fs.writeFileSync(infoFile, `${JSON.stringify(info, null, 2)}\n`, 'utf8')
292
304
  console.log(`\n[deploy] complete — 记录:${infoFile}`)
293
305
  console.log('[deploy] 未重启任何 DSH(本脚本不做重启)。隔离实例请用测试环境冒烟脚本启动:')
@@ -50,7 +50,7 @@
50
50
  // 唯一源 = 本文件;派生副本 = `tools/sync-host-adapter.mjs` 幂等生成到各包 `lib/host-adapter.mjs`(含源 sha 头);
51
51
  // 守门 = `tools/check-decoupling.mjs` R5 校验副本 sha == 唯一源。
52
52
  //
53
- // 【设备:工作ROG】|P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
53
+ // 【设备:ROG】|P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
54
54
  // | 2026-09-28 档 B 切(`UNKNOWN_FAMILY_POLICY`: 'unknown' → 'open',主人单独批准)
55
55
  // | 2026-10-10 空会话误判治本(`classifyTail` 加「整段零回合内事件 ⇒ closed」前置判定;
56
56
  // 修「新建空会话静止 10 分钟被判卡死」;真源 `docs\交付报告-卡死自愈空会话误判治本-20261010.md`)
@@ -50,7 +50,7 @@
50
50
  // 唯一源 = 本文件;派生副本 = `tools/sync-host-adapter.mjs` 幂等生成到各包 `lib/host-adapter.mjs`(含源 sha 头);
51
51
  // 守门 = `tools/check-decoupling.mjs` R5 校验副本 sha == 唯一源。
52
52
  //
53
- // 【设备:工作ROG】|P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
53
+ // 【设备:ROG】|P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
54
54
  // | 2026-09-28 档 B 切(`UNKNOWN_FAMILY_POLICY`: 'unknown' → 'open',主人单独批准)
55
55
  // | 2026-10-10 空会话误判治本(`classifyTail` 加「整段零回合内事件 ⇒ closed」前置判定;
56
56
  // 修「新建空会话静止 10 分钟被判卡死」;真源 `docs\交付报告-卡死自愈空会话误判治本-20261010.md`)
@@ -298,7 +298,7 @@ export function selfTest() {
298
298
  const inFile = path.join(tmp, "memories.json");
299
299
  const outDir = path.join(tmp, "out");
300
300
  try {
301
- const base = "【设备:工作ROG】重复内容判定用长文本片段甲乙丙丁戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥";
301
+ const base = "【设备:ROG】重复内容判定用长文本片段甲乙丙丁戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥";
302
302
  const DRV = path.parse(process.cwd()).root;
303
303
  const mems = [
304
304
  { id: 1, text: base, pinned: true, tags: "", created_at: 1, updated_at: 1 },
@@ -166,11 +166,11 @@ export function selfTest() {
166
166
  try {
167
167
  const mems = [
168
168
  { id: 1, text: "普通条目", pinned: false, tags: "", created_at: 1, updated_at: 1 },
169
- { id: 2, text: "【设备:工作ROG】正常条目", pinned: true, tags: "", created_at: 1, updated_at: 1 },
169
+ { id: 2, text: "【设备:ROG】正常条目", pinned: true, tags: "", created_at: 1, updated_at: 1 },
170
170
  { id: 3, text: "【设备:某个奇怪的东西】异常设备标", pinned: false, tags: "", created_at: 1, updated_at: 1 },
171
171
  {
172
172
  id: 4,
173
- text: "【设备:工作ROG】\n【设备:TUF】双标条目" + "x".repeat(300),
173
+ text: "【设备:ROG】\n【设备:TUF】双标条目" + "x".repeat(300),
174
174
  pinned: false,
175
175
  tags: "",
176
176
  created_at: 1,
@@ -81,7 +81,7 @@ export function tokensOf(tags) {
81
81
  return String(tags ?? '').split(/\s+/).map((t) => t.trim()).filter(Boolean);
82
82
  }
83
83
 
84
- /** 该条 already 有哪些域标签(token 级精确比较,**不用 includes**:`工作rog` 不等于 `工作`)。 */
84
+ /** 该条 already 有哪些域标签(token 级精确比较,**不用 includes**:`工作记录` 不等于 `工作`)。 */
85
85
  export function domainTokensIn(tags) {
86
86
  const set = new Set(tokensOf(tags));
87
87
  return DOMAIN_TOKENS.filter((t) => set.has(t));
@@ -42,17 +42,17 @@ test('appendDomainTags:追加不覆盖原标签', () => {
42
42
  assertEq(r.added, ['技术', 'dsh生态'], 'added 记录实际新增');
43
43
  });
44
44
  test('appendDomainTags:同输入跑两次 ⇒ 第二次零新增(写前逐标签判重)', () => {
45
- const once = D.appendDomainTags('项目 工作rog', ['工作']);
45
+ const once = D.appendDomainTags('项目 工作记录', ['工作']);
46
46
  const twice = D.appendDomainTags(once.tags, ['工作']);
47
- assertEq(once.tags, '项目 工作rog 工作', '第一次追加');
47
+ assertEq(once.tags, '项目 工作记录 工作', '第一次追加');
48
48
  assertEq(twice.added, [], '第二次零新增');
49
49
  assertEq(twice.tags, once.tags, '第二次不改内容');
50
50
  const tokens = D.tokensOf(twice.tags);
51
51
  assertEq(tokens.length, new Set(tokens).size, '无重复 token');
52
52
  });
53
- test('appendDomainTags:**token 级**判重(`工作rog` ≠ `工作`)', () => {
54
- const r = D.appendDomainTags('工作rog', ['工作']);
55
- assertEq(r.added, ['工作'], '`工作rog` 不算已含 `工作`');
53
+ test('appendDomainTags:**token 级**判重(`工作记录` ≠ `工作`)', () => {
54
+ const r = D.appendDomainTags('工作记录', ['工作']);
55
+ assertEq(r.added, ['工作'], '`工作记录` 不算已含 `工作`');
56
56
  assert(r.tags.split(/\s+/).includes('工作'), '新 token 独立存在');
57
57
  });
58
58
  test('appendDomainTags:集合外的标签被丢弃(模型自创词不落库)', () => {
@@ -66,7 +66,7 @@ test('appendDomainTags:标签集为空 ⇒ 一个字都不动', () => {
66
66
  assertEq(r.added, [], '零新增');
67
67
  });
68
68
  test('domainTokensIn:只认域标签 token', () => {
69
- assertEq(D.domainTokensIn('技术 dsh生态 工作rog'), ['技术', 'dsh生态'], 'token 级识别');
69
+ assertEq(D.domainTokensIn('技术 dsh生态 工作记录'), ['技术', 'dsh生态'], 'token 级识别');
70
70
  assertEq(D.domainTokensIn(''), [], '空 tags');
71
71
  });
72
72
  test('tagSetHash:与顺序无关、与重复无关、不同集不同哈希', () => {
@@ -124,7 +124,7 @@ test('distilledTagOf / srcKeyInTags:标签形态可往返解析', () => {
124
124
  assert(tags.includes('srcids=3,9'), '带源 id 清单(升序)');
125
125
  assert(/\sdate=\d{8}$/.test(tags), '带日期');
126
126
  assertEq(D.srcKeyInTags(tags), 'd0123456789abcdef', '能解析回来');
127
- assertEq(D.srcKeyInTags('技术 工作rog'), null, '普通标签解析为 null');
127
+ assertEq(D.srcKeyInTags('技术 工作记录'), null, '普通标签解析为 null');
128
128
  });
129
129
 
130
130
  // ── 02 输入挑选:窗口 ∪ 台账 + 不自我指涉 + D2 从严 ─────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kira905/dsh-memory-toolkit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"