@yolk_vat-y/dsh-project-memory 0.4.0 → 0.4.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.
@@ -59,6 +59,32 @@ export function firstTextOf(content) {
59
59
  return ''
60
60
  }
61
61
 
62
+ const TODO_STATUSES = new Set(['pending', 'in_progress', 'completed'])
63
+
64
+ /**
65
+ * 反向接管:任务成为某会话绑定后,把任务步骤推成宿主 todo/write 快照,
66
+ * 让 dsh 渲染的任务清单(UI/投影)变成我们这套任务的步骤。
67
+ * 规则:任务没有步骤时不推(避免误清模型手头正在用的宿主清单)。
68
+ * @returns {boolean} 是否实际推送
69
+ */
70
+ export function adoptStepsToSession(session, task) {
71
+ if (!session || typeof session.append !== 'function') return false
72
+ const steps = Array.isArray(task?.steps) ? task.steps : null
73
+ if (!steps || steps.length === 0) return false
74
+ const todos = steps.map((s) => {
75
+ const raw = typeof s === 'string' ? s : s?.content ?? s?.text ?? ''
76
+ const status = TODO_STATUSES.has(s?.status) ? s.status : 'pending'
77
+ return { content: String(raw), status }
78
+ })
79
+ session.append('todo/write', { todos })
80
+ return true
81
+ }
82
+
83
+ /** 是否开启“任务接管时同步宿主清单”(config.tasklist.syncHostOnAdopt 默认 true)。 */
84
+ export function shouldAdoptToHost(config) {
85
+ return config?.tasklist?.syncHostOnAdopt !== false
86
+ }
87
+
62
88
  function pickTitle(meta, todos) {
63
89
  const firstHuman = meta?.firstHuman?.trim()
64
90
  if (firstHuman) {
@@ -100,6 +126,8 @@ export function onSessionEvent(config, session, event, meta) {
100
126
  store.commit((s) => {
101
127
  let task = s.getBoundTaskId(sessionId) ? s.getTask(s.getBoundTaskId(sessionId)) : null
102
128
  if (!task || task.archived) {
129
+ // 空写 = 清空清单:不自动建档(避免"未绑定会话清空 todo"误建垃圾任务)
130
+ if (todos.length === 0) return
103
131
  const title = pickTitle(meta.get(sessionId), todos)
104
132
  task = {
105
133
  id: genTaskId(root, title),
@@ -2,7 +2,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools'
2
2
  import { memoryRootFor, resolveIndexRoot } from '../util/fs.js'
3
3
  import { ProjectMemoryStore } from '../store.js'
4
4
  import { truncate } from '../util/text.js'
5
- import { genTaskId, hash8 } from '../setup/taskbridge.js'
5
+ import { genTaskId, hash8, adoptStepsToSession, shouldAdoptToHost } from '../setup/taskbridge.js'
6
6
  import { createHash } from 'node:crypto'
7
7
 
8
8
  function sessionIdOf(exec) {
@@ -128,6 +128,11 @@ export function selectTaskTool(config) {
128
128
  if (sid) task.lastSessionId = sid
129
129
  store.save()
130
130
 
131
+ // 反向接管:绑定成功后,把任务步骤推成宿主 todo/write(dsh 清单跟随我们的任务)
132
+ if (shouldAdoptToHost(config)) {
133
+ adoptStepsToSession(exec?.agent?.session || exec?.ctx?.session, task)
134
+ }
135
+
131
136
  const card = {
132
137
  taskId: task.id,
133
138
  title: task.title,