@yolk_vat-y/dsh-project-memory 0.5.2 → 0.5.3

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
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3 (2026-09-10)
4
+
5
+ ### Changed (DSH 0.1.5-rc.1 compatibility)
6
+
7
+ - **devDependencies aligned with the 0.1.5-rc.1 host**: `@deepseek-ai/dsh-tools` and `dsh-llm` moved from `0.1.1-rc.2`, and `dsh-client-locale` / `dsh-client-store` / `dsh-client-ui-primitives` / `dsh-client-ui-slots` from `0.1.2-rc.1`, all to `0.1.5-rc.1` — type-checking and bundling now run against the same declaration surface the host ships.
8
+ - **Dropped `@deepseek-ai/dsh-client-runtime`** from `devDependencies`, `dsh.client.inject` and the client `CLIENT_EXTERNALS`: upstream deleted the package in 0.1.5 (`refactor(client): migrate consumers and remove Runtime`, npm stops at `0.1.1-rc.2`). The bundle only ever required `react`, `react/jsx-runtime` and `dsh-client-ui-primitives`, and the host skips unknown `inject` rows, so this is dead-config cleanup rather than a behaviour change — but a stale row would break any future re-bundle that treated it as an external.
9
+ - **Added `@types/react` / `@types/react-dom` (^18.3) as devDependencies**: 0.1.5's `dsh-client-ui-primitives` no longer pulls `react`/`react-dom`, so a clean install left `tsconfig.client.json`'s `types: ["react","react-dom"]` unresolved.
10
+ - **Regenerated `package-lock.json` via a clean install**: the old lock pinned an entire `0.1.1-rc.2` / `0.1.2-alpha.2` peer tree, which made `npm install` fail with ERESOLVE once the direct devDependencies moved to 0.1.5-rc.1.
11
+ - **Rebuilt `client/client.js`** (99.96 kB, 23.4 kB gzip) against the new externals; the entry contract is unchanged (`window.__ModuleLoader__.load({ id, factory })` plus `exports.name` / `exports.inject`).
12
+ - **Verified the consumed host surface is unchanged in 0.1.5-rc.1**: `defineTool`, `ctx.tools.register`, `BlockAssembler.push/message`, `createUserMessage`, `LlmRuntime.stream`, the `agent/pre-step` waterfall and its `{ kind: 'enter', messages }` decision, `fs/observed`, plugin message source `form: 'notice'`, and the client slots `shell.overlay` / `conversation.chat.commandview` with services `slots` / `sessions` / `remote` / `remote.commands` / `locale`. Suite green (219 checks).
13
+
14
+ ### Fixed (task auto-adoption)
15
+
16
+ - **Subagent sessions no longer mint project tasks**: every delegated child runs `todo_write`, so the bridge's auto-adopt path created one project task per child, titled from the child's prompt — a multi-audit turn could add several. Auto-creation (and auto-binding) is now skipped when the host session header marks a delegated child (`origin: 'subagent'` or `delegationDepth > 0`); `parentSession` is deliberately *not* used as a signal because it is fork/seed lineage, and a user-forked top-level session still needs tasks. Merging subagent work back into the parent task is left to a future design.
17
+ - **Auto-created task titles prefer the todo list**: `pickTitle` preferred `meta.firstHuman`, the first human message recorded *since the plugin started* — after a host restart that is a mid-conversation message, so an aside such as "刚刚你卡死了,注意点" could name a task whose steps belonged to something else. The first todo entry now wins and the human message (preferring the segment after the last `:` / `:`) is the fallback. `test/taskbridge.test.mjs` 11 → 15 checks.
18
+
19
+ ### Files
20
+ - package.json, package-lock.json, tsdown.config.ts, client/client.js, src/setup/taskbridge.js, test/taskbridge.test.mjs, CHANGELOG.md
21
+
3
22
  ## 0.5.2 (2026-09-09)
4
23
 
5
24
  ### Changed (file hotspot + resume info)
package/client/client.js CHANGED
@@ -571,91 +571,91 @@ window.__ModuleLoader__.load({
571
571
  document.head.appendChild(tag);
572
572
  }
573
573
  var TaskPanel_module_css_default = {
574
- "stepToggle": "vZSZnG_stepToggle",
575
- "stepDone": "vZSZnG_stepDone",
574
+ "muted": "vZSZnG_muted",
575
+ "memMeta": "vZSZnG_memMeta",
576
+ "updated": "vZSZnG_updated",
577
+ "dragGhostContent": "vZSZnG_dragGhostContent",
578
+ "cardTitle": "vZSZnG_cardTitle",
579
+ "headerLeft": "vZSZnG_headerLeft",
576
580
  "miniIcon": "vZSZnG_miniIcon",
581
+ "stepToggle": "vZSZnG_stepToggle",
577
582
  "headerIconBtn": "vZSZnG_headerIconBtn",
578
- "cardBody": "vZSZnG_cardBody",
579
- "sectionCount": "vZSZnG_sectionCount",
580
- "progressText": "vZSZnG_progressText",
581
- "cardBound": "vZSZnG_cardBound",
582
- "chevron": "vZSZnG_chevron",
583
- "memList": "vZSZnG_memList",
584
- "kindBadge": "vZSZnG_kindBadge",
583
+ "memActs": "vZSZnG_memActs",
584
+ "handleGrip": "vZSZnG_handleGrip",
585
+ "headerRight": "vZSZnG_headerRight",
585
586
  "cardFooter": "vZSZnG_cardFooter",
586
- "trackFill": "vZSZnG_trackFill",
587
- "cardTitle": "vZSZnG_cardTitle",
588
- "stepEditable": "vZSZnG_stepEditable",
587
+ "memRowMain": "vZSZnG_memRowMain",
588
+ "kindBadge": "vZSZnG_kindBadge",
589
589
  "counts": "vZSZnG_counts",
590
590
  "section": "vZSZnG_section",
591
- "stepInput": "vZSZnG_stepInput",
592
- "handleGrip": "vZSZnG_handleGrip",
593
- "cardTitleEditable": "vZSZnG_cardTitleEditable",
594
- "dragGhostContent": "vZSZnG_dragGhostContent",
595
- "dragGhostClose": "vZSZnG_dragGhostClose",
596
- "dropTargetBefore": "vZSZnG_dropTargetBefore",
597
- "stepDragging": "vZSZnG_stepDragging",
598
- "cardMeta": "vZSZnG_cardMeta",
599
- "panel": "vZSZnG_panel",
600
- "dragGhost": "vZSZnG_dragGhost",
591
+ "miniChevron": "vZSZnG_miniChevron",
592
+ "trackFill": "vZSZnG_trackFill",
593
+ "memNewRow": "vZSZnG_memNewRow",
594
+ "memLabel": "vZSZnG_memLabel",
595
+ "emptyDesc": "vZSZnG_emptyDesc",
596
+ "stepRow": "vZSZnG_stepRow",
597
+ "dragHandle": "vZSZnG_dragHandle",
598
+ "cardBody": "vZSZnG_cardBody",
599
+ "stepDone": "vZSZnG_stepDone",
600
+ "boundaryFallback": "vZSZnG_boundaryFallback",
601
+ "memToolbar": "vZSZnG_memToolbar",
602
+ "dragGhostCard": "vZSZnG_dragGhostCard",
601
603
  "dropTargetAfter": "vZSZnG_dropTargetAfter",
604
+ "headerTitle": "vZSZnG_headerTitle",
605
+ "stepRun": "vZSZnG_stepRun",
606
+ "cardTitleRow": "vZSZnG_cardTitleRow",
602
607
  "stepPending": "vZSZnG_stepPending",
608
+ "stepContentDone": "vZSZnG_stepContentDone",
609
+ "memToolbarActs": "vZSZnG_memToolbarActs",
610
+ "cardTitleEditable": "vZSZnG_cardTitleEditable",
611
+ "memRowArchived": "vZSZnG_memRowArchived",
612
+ "memList": "vZSZnG_memList",
613
+ "stepInput": "vZSZnG_stepInput",
614
+ "stepEditable": "vZSZnG_stepEditable",
615
+ "progressText": "vZSZnG_progressText",
616
+ "badgeArchived": "vZSZnG_badgeArchived",
617
+ "editorArea": "vZSZnG_editorArea",
618
+ "cardMeta": "vZSZnG_cardMeta",
603
619
  "fileDot": "vZSZnG_fileDot",
604
- "memTitle": "vZSZnG_memTitle",
605
- "badge": "vZSZnG_badge",
606
- "emptyTitle": "vZSZnG_emptyTitle",
607
- "stepContentRun": "vZSZnG_stepContentRun",
608
- "stepRun": "vZSZnG_stepRun",
609
620
  "fileLine": "vZSZnG_fileLine",
610
- "dropPulse": "vZSZnG_dropPulse",
611
- "memRow": "vZSZnG_memRow",
612
- "filesList": "vZSZnG_filesList",
621
+ "stepsList": "vZSZnG_stepsList",
622
+ "memCount": "vZSZnG_memCount",
613
623
  "sectionLabel": "vZSZnG_sectionLabel",
614
- "cardHead": "vZSZnG_cardHead",
615
- "fileRow": "vZSZnG_fileRow",
624
+ "filePath": "vZSZnG_filePath",
625
+ "badgeDraft": "vZSZnG_badgeDraft",
626
+ "stepDragging": "vZSZnG_stepDragging",
627
+ "miniText": "vZSZnG_miniText",
616
628
  "notice": "vZSZnG_notice",
617
- "emptyDesc": "vZSZnG_emptyDesc",
629
+ "dragGhostClose": "vZSZnG_dragGhostClose",
630
+ "memRow": "vZSZnG_memRow",
631
+ "track": "vZSZnG_track",
632
+ "emptyState": "vZSZnG_emptyState",
633
+ "taskList": "vZSZnG_taskList",
618
634
  "panelIn": "vZSZnG_panelIn",
619
- "headerLeft": "vZSZnG_headerLeft",
635
+ "dropPulse": "vZSZnG_dropPulse",
636
+ "memBody": "vZSZnG_memBody",
620
637
  "headerIcon": "vZSZnG_headerIcon",
638
+ "badge": "vZSZnG_badge",
621
639
  "memNew": "vZSZnG_memNew",
622
- "memToolbar": "vZSZnG_memToolbar",
623
- "memActs": "vZSZnG_memActs",
624
- "badgeDraft": "vZSZnG_badgeDraft",
625
- "headerRight": "vZSZnG_headerRight",
640
+ "dropTargetBefore": "vZSZnG_dropTargetBefore",
641
+ "sectionCount": "vZSZnG_sectionCount",
626
642
  "card": "vZSZnG_card",
627
- "syncHint": "vZSZnG_syncHint",
628
- "updated": "vZSZnG_updated",
629
- "memBody": "vZSZnG_memBody",
630
- "memLabel": "vZSZnG_memLabel",
631
- "dragHandle": "vZSZnG_dragHandle",
632
- "track": "vZSZnG_track",
633
- "memoryPane": "vZSZnG_memoryPane",
634
- "badgeArchived": "vZSZnG_badgeArchived",
635
- "muted": "vZSZnG_muted",
636
- "editorArea": "vZSZnG_editorArea",
637
- "memMeta": "vZSZnG_memMeta",
643
+ "stepContent": "vZSZnG_stepContent",
644
+ "chevron": "vZSZnG_chevron",
638
645
  "boundBadge": "vZSZnG_boundBadge",
639
- "stepRow": "vZSZnG_stepRow",
646
+ "fileRow": "vZSZnG_fileRow",
647
+ "cardHead": "vZSZnG_cardHead",
640
648
  "miniBar": "vZSZnG_miniBar",
641
- "stepContent": "vZSZnG_stepContent",
642
- "filePath": "vZSZnG_filePath",
643
- "memNewRow": "vZSZnG_memNewRow",
644
- "emptyState": "vZSZnG_emptyState",
645
- "memCount": "vZSZnG_memCount",
646
- "memToolbarActs": "vZSZnG_memToolbarActs",
647
- "headerTitle": "vZSZnG_headerTitle",
648
- "memRowMain": "vZSZnG_memRowMain",
649
- "stepContentDone": "vZSZnG_stepContentDone",
650
- "miniChevron": "vZSZnG_miniChevron",
651
- "taskList": "vZSZnG_taskList",
652
- "boundaryFallback": "vZSZnG_boundaryFallback",
653
- "dragGhostCard": "vZSZnG_dragGhostCard",
654
649
  "header": "vZSZnG_header",
655
- "cardTitleRow": "vZSZnG_cardTitleRow",
656
- "memRowArchived": "vZSZnG_memRowArchived",
657
- "miniText": "vZSZnG_miniText",
658
- "stepsList": "vZSZnG_stepsList"
650
+ "syncHint": "vZSZnG_syncHint",
651
+ "panel": "vZSZnG_panel",
652
+ "filesList": "vZSZnG_filesList",
653
+ "memoryPane": "vZSZnG_memoryPane",
654
+ "cardBound": "vZSZnG_cardBound",
655
+ "memTitle": "vZSZnG_memTitle",
656
+ "emptyTitle": "vZSZnG_emptyTitle",
657
+ "dragGhost": "vZSZnG_dragGhost",
658
+ "stepContentRun": "vZSZnG_stepContentRun"
659
659
  };
660
660
  //#endregion
661
661
  //#region src/client/TaskComponents.tsx
@@ -2016,8 +2016,8 @@ window.__ModuleLoader__.load({
2016
2016
  document.head.appendChild(tag);
2017
2017
  }
2018
2018
  var TaskCommandNode_module_css_default = {
2019
- "icon": "TPe-xa_icon",
2020
- "row": "TPe-xa_row"
2019
+ "row": "TPe-xa_row",
2020
+ "icon": "TPe-xa_icon"
2021
2021
  };
2022
2022
  //#endregion
2023
2023
  //#region src/client/TaskCommandNode.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk_vat-y/dsh-project-memory",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Persistent project memory for dsh agents: index docs (PDF/Markdown/text) and code symbols into a searchable per-workspace store, recall them with cited sources, and keep experience entries (problems -> solutions) searchable on demand.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -43,15 +43,16 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@deepseek-ai/cordis": "^4.0.2",
46
- "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
47
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
48
- "@deepseek-ai/dsh-client-store": "0.1.2-rc.1",
49
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
50
- "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
51
- "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
52
- "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
46
+ "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
47
+ "@deepseek-ai/dsh-client-store": "0.1.5-rc.1",
48
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
49
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
50
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
51
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
53
52
  "@deepseek-ai/schemastery": "^3.18.2",
54
53
  "@tsdown/css": "0.22.14",
54
+ "@types/react": "^18.3.31",
55
+ "@types/react-dom": "^18.3.7",
55
56
  "lightningcss": "^1.33.0",
56
57
  "tsdown": "^0.22.14",
57
58
  "typescript": "^5.6.3"
@@ -86,7 +87,6 @@
86
87
  },
87
88
  "client": {
88
89
  "inject": [
89
- "@deepseek-ai/dsh-client-runtime",
90
90
  "@deepseek-ai/dsh-client-locale",
91
91
  "@deepseek-ai/dsh-client-ui-primitives",
92
92
  "@deepseek-ai/dsh-client-ui-slots",
@@ -87,7 +87,26 @@ export function shouldAdoptToHost(config) {
87
87
  return config?.tasklist?.syncHostOnAdopt !== false
88
88
  }
89
89
 
90
+ /**
91
+ * 子代理会话判定:宿主 SessionHeader 对 in-process 子代理恒定写入
92
+ * `origin: 'subagent'` 与 `delegationDepth`(parent depth + 1)。
93
+ * 刻意不看 parentSession —— 那是 fork/seed 血缘,用户 fork 出来的顶层会话同样带它。
94
+ */
95
+ export function isSubagentSession(session) {
96
+ const header = session?.header
97
+ if (!header) return false
98
+ if (header.origin === 'subagent') return true
99
+ return typeof header.delegationDepth === 'number' && header.delegationDepth > 0
100
+ }
101
+
102
+ /**
103
+ * 标题优先级:清单首条 > 首条真人消息 > 'Untitled Task'(0.5.3 反转前两者)。
104
+ * 真人消息只在清单没有可用文本时兜底:重启后 meta.firstHuman 是重启后的第一条消息
105
+ * (常常只是半途闲聊,如"刚刚你卡死了,注意点"),拿它命名会把任务带偏。
106
+ */
90
107
  function pickTitle(meta, todos) {
108
+ const firstTodo = todos?.[0]?.content
109
+ if (typeof firstTodo === 'string' && firstTodo.trim()) return firstTodo.trim().slice(0, 48)
91
110
  const firstHuman = meta?.firstHuman?.trim()
92
111
  if (firstHuman) {
93
112
  // 用户消息常带指令前缀("用 todo_write 规划:…"),优先取最后一个":"后的任务段
@@ -96,8 +115,6 @@ function pickTitle(meta, todos) {
96
115
  if (seg.length >= 2 && seg.length <= 48) return seg
97
116
  return firstHuman.slice(0, 48)
98
117
  }
99
- const firstTodo = todos?.[0]?.content
100
- if (firstTodo && firstTodo.trim()) return firstTodo.trim().slice(0, 48)
101
118
  return 'Untitled Task'
102
119
  }
103
120
 
@@ -138,8 +155,8 @@ export function touchTaskFile(task, rel, kind, now) {
138
155
 
139
156
  /**
140
157
  * 单条会话事件处理(导出便于测试):user/message 记首条真人文本并刷新 lastHumanAt;
141
- * todo/write → 已绑定则覆盖 steps,未绑定则自动新建任务并绑定;
142
- * tool/call(fs 工具)→ 绑定任务 files 并集。
158
+ * todo/write → 已绑定则覆盖 steps,未绑定则自动新建任务并绑定(子代理会话除外,
159
+ * 由 isSubagentSession 判定);tool/call(fs 工具)→ 绑定任务 files 并集。
143
160
  */
144
161
  export function onSessionEvent(config, session, event, meta) {
145
162
  const sessionId = session?.id
@@ -183,6 +200,8 @@ export function onSessionEvent(config, session, event, meta) {
183
200
  if (!task || task.archived) {
184
201
  // 空写 = 清空清单:不自动建档(避免"未绑定会话清空 todo"误建垃圾任务)
185
202
  if (todos.length === 0) return
203
+ // 子代理会话不建档:否则每个子代理都铸一条项目任务(子代理任务融合另行设计)
204
+ if (isSubagentSession(session)) return
186
205
  const title = pickTitle(meta.get(sessionId), todos)
187
206
  task = {
188
207
  id: genTaskId(root, title),