@yolk_vat-y/dsh-project-memory 0.5.13 → 0.5.14
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 +126 -0
- package/README.md +5 -5
- package/README.zh-CN.md +5 -5
- package/client/client.js +120 -52
- package/client/client.js.map +1 -1
- package/package.json +8 -8
- package/src/audit.js +52 -3
- package/src/auto-inject.js +64 -16
- package/src/client/ShowTaskPanelNode.tsx +51 -0
- package/src/client/TaskPanel.tsx +8 -8
- package/src/client/client.ts +10 -31
- package/src/client/slash.ts +33 -17
- package/src/client/task-ui-store.ts +43 -0
- package/src/index.js +8 -3
- package/src/insight-store.js +2 -17
- package/src/readiness.js +26 -1
- package/src/store.js +8 -22
- package/src/tools/forget.js +1 -1
- package/src/tools/lesson-tools.js +1 -0
- package/src/tools/remember.js +5 -3
- package/src/tools/task-tools.js +8 -7
- package/src/tools/watch-repo.js +1 -1
- package/src/util/fs.js +33 -1
package/client/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["primitives","createElement","useSyncExternalStore","useSyncExternalStore","useState","useRef","useCallback","css","useRef","useState","Button","useState","useCallback","useRef","css","Button","useState","Component","css","useRef","Button","useRef","css","createElement"],"sources":["../src/client/icons.ts","../src/client/locales.ts","../src/client/task-data-store.ts","../src/client/task-ui-store.ts","../src/client/task-hooks.ts","../src/client/TaskComponents.tsx","../src/client/MemoryView.tsx","../src/client/session-id.js","../src/client/TaskPanel.tsx","../src/client/TaskCommandNode.tsx","../src/client/slash.ts","../src/client/client.ts"],"sourcesContent":["/**\n * 宿主图标兼容层(dsh 0.1.5 ↔ 0.1.7+)。\n *\n * 命名契约变过一次:\n * - dsh 0.1.5(含 0.1.5-rc.x):尺寸写进名字,如 `IconFolderOpenOutline16`;\n * - dsh 0.1.7+:去掉尺寸后缀、改为字重后缀,如 `IconFolderOpenOutlineRegular` /\n * `IconFolderOpenOutlineMedium`,尺寸改由 `size` prop 传入。\n * ui-primitives 是 web shell 的冻结 seed 模块(不是插件行),插件无法固定它,\n * 同一份产物会拿到宿主那一版的导出;直接按某一版的名字解构会在另一版上得到\n * `undefined`,React 渲染时抛 \"Element type is invalid\" 把面板整个打崩。\n *\n * 因此这里按旧名导出同名组件,运行时在两个名字里取存在的那个,并把旧名里的\n * 尺寸作为默认 `size`(两版的图标都接受 `size` prop,0.1.5 的默认值正是旧名后缀)。\n * 两版都没有该名字时降级为空组件并告警,而不是让面板崩溃。\n */\nimport { createElement, type ComponentType } from 'react'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\n\ntype IconProps = { size?: number; className?: string }\ntype IconComponent = ComponentType<IconProps>\n\nconst table = primitives as unknown as Record<string, unknown>\n\nfunction resolveIcon(names: readonly string[]): IconComponent | null {\n for (const name of names) {\n const candidate = table[name]\n if (typeof candidate === 'function' || (typeof candidate === 'object' && candidate !== null)) {\n return candidate as IconComponent\n }\n }\n return null\n}\n\nfunction icon(legacyName: string, currentName: string, defaultSize: number): IconComponent {\n const impl = resolveIcon([legacyName, currentName])\n if (impl === null) {\n console.warn(\n `[dsh-project-memory] host ui-primitives exports neither ${legacyName} nor ${currentName}; that icon renders nothing`,\n )\n return function MissingIcon() {\n return null\n }\n }\n function CompatIcon({ size = defaultSize, ...rest }: IconProps) {\n return createElement(impl as IconComponent, { size, ...rest })\n }\n CompatIcon.displayName = legacyName\n return CompatIcon\n}\n\nexport const IconChevronDownOutline14 = icon('IconChevronDownOutline14', 'IconChevronDownOutlineRegular', 14)\nexport const IconChevronUpOutline14 = icon('IconChevronUpOutline14', 'IconChevronUpOutlineRegular', 14)\nexport const IconQuestionOutline14 = icon('IconQuestionOutline14', 'IconQuestionOutlineRegular', 14)\nexport const IconCloseOutline16 = icon('IconCloseOutline16', 'IconCloseOutlineRegular', 16)\nexport const IconFolderOpenOutline16 = icon('IconFolderOpenOutline16', 'IconFolderOpenOutlineRegular', 16)\nexport const IconCheckOutline16 = icon('IconCheckOutline16', 'IconCheckOutlineRegular', 16)\nexport const IconPlayOutline16 = icon('IconPlayOutline16', 'IconPlayOutlineRegular', 16)\n\n// `/` 菜单行图标。旧名的尺寸后缀两版并不一致(有的是 14 有的是 16),\n// 所以这里的默认 size 只影响\"宿主两版都没有该名字\"的降级路径——正常路径由宿主自己决定。\nexport const IconChecklistOutline16 = icon('IconChecklistOutline14', 'IconChecklistOutlineRegular', 14)\nexport const IconLightOutline16 = icon('IconLightOutline16', 'IconLightOutlineRegular', 16)\nexport const IconGlobeOutline16 = icon('IconGlobeOutline14', 'IconGlobeOutlineRegular', 14)\n","/**\n * Locale dictionaries for Task Panel\n */\nexport const zh = {\n 'panel.title': '工作流任务',\n 'panel.active': '进行中',\n 'panel.total': '总计',\n 'panel.minimize': '收起为顶部迷你条',\n 'panel.close': '关闭面板(隐藏,/task 可唤起)',\n 'panel.refresh': '同步最新任务',\n 'panel.style': '切换面板风格',\n 'style.native': '原生',\n 'style.glass': '玻璃',\n 'style.brutal': '粗野',\n 'style.mono': '终端',\n 'panel.syncing': '同步中…',\n 'panel.sync-failed': '同步失败',\n 'panel.hints-on': '显示提示信息',\n 'panel.hints-off': '隐藏提示信息',\n 'drag.cancel': '取消拖拽',\n 'panel.empty': '暂无任务',\n 'panel.empty-desc': '让模型开始工作并维护 todo 清单后会自动建档',\n 'panel.no-session': '还没有会话',\n 'task.progress': '进度',\n 'task.steps': '步骤',\n 'task.files': '文件',\n 'task.current': '当前',\n 'task.title-edit': '双击修改标题',\n 'task.switch': '切换到此任务',\n 'task.unbind': '取消当前任务',\n 'task.archive': '归档',\n 'task.drag': '拖拽移动',\n 'step.completed': '已完成',\n 'step.in-progress': '进行中',\n 'step.pending': '待办',\n 'step.edit-hint': '双击编辑步骤文案;点击图标循环 待办/进行中/已完成',\n 'file.copy': '复制路径',\n 'file.copied': '已复制路径',\n 'minibar.current': '当前任务',\n 'minibar.click-expand': '点击展开并同步',\n 'minibar.tasks': '个任务',\n 'minibar.no-task': '暂无任务 · 点击查看',\n 'view.cycle': '切换视图:任务 / 项目记忆 / 全局记忆',\n 'view.task': '任务',\n 'view.project': '项目记忆',\n 'view.global': '全局记忆',\n 'mem.scope.task': '本任务草稿',\n 'mem.scope.project': '项目记忆',\n 'mem.scope.global': '全局记忆',\n 'mem.empty': '暂无记忆条目(反思或 save_lesson 后出现)',\n 'mem.confirm': '审核',\n 'mem.promote': '提升',\n 'mem.demote': '降级',\n 'mem.archive': '归档',\n 'mem.restore': '恢复',\n 'mem.delete': '删除',\n 'mem.draft': '草稿',\n 'mem.archived': '已归档',\n 'mem.loading': '加载中…',\n 'mem.error': '同步失败',\n 'mem.kind.lesson': '坑',\n 'mem.kind.decision': '权衡',\n 'mem.kind.procedure': '指南',\n 'mem.kind.experience': '经验',\n 'mem.needs-bound': '需绑定任务后可降级',\n 'mem.new': '新建',\n 'mem.save': '保存',\n 'mem.cancel': '取消',\n 'mem.f.title': '标题(教训模式/主题/指南名)',\n 'mem.f.kind': '类型',\n 'mem.f.body': '做法 / 理由 / 解法',\n 'mem.f.steps': '步骤(每行一步)',\n 'mem.f.trigger': '作为 Skill:触发关键词(逗号分隔)',\n 'mem.saved': '已保存',\n 'mem.edit': '编辑',\n 'mem.section-label': '任务记忆',\n // `/` 菜单:自建 slash 源的行文案。分组标题走候选的 section(见 slash.ts),\n // 不走 slash.menu 词典——那个 namespace 由宿主的 ui-input-trigger 独占,重复注册会抛错。\n // 三个行标题直接复用上面面板的 view.* 文案,保证菜单与面板叫同一个名字。\n 'slash.group': '工作流',\n 'slash.tasks-desc': '任务清单:步骤进度、涉及文件、当前会话绑定',\n 'slash.project-desc': '项目记忆:本项目的教训 / 决策 / 流程',\n 'slash.global-desc': '全局记忆:跨项目的经验条目',\n}\n\nexport const en = {\n 'panel.title': 'Task Flow',\n 'panel.active': 'Active',\n 'panel.total': 'Total',\n 'panel.minimize': 'Collapse to mini bar',\n 'panel.close': 'Close panel (hidden; /task reopens)',\n 'panel.refresh': 'Sync latest tasks',\n 'panel.style': 'Panel style',\n 'style.native': 'Native',\n 'style.glass': 'Glass',\n 'style.brutal': 'Brutal',\n 'style.mono': 'Mono',\n 'panel.syncing': 'Syncing…',\n 'panel.sync-failed': 'Sync failed',\n 'panel.hints-on': 'Show hints',\n 'panel.hints-off': 'Hide hints',\n 'drag.cancel': 'Cancel drag',\n 'panel.empty': 'No Tasks',\n 'panel.empty-desc': 'Tasks are created automatically when the model maintains a todo list',\n 'panel.no-session': 'No session yet',\n 'task.progress': 'Progress',\n 'task.steps': 'Steps',\n 'task.files': 'Files',\n 'task.current': 'Current',\n 'task.title-edit': 'Double-click to rename',\n 'task.switch': 'Switch to this task',\n 'task.unbind': 'Unbind current task',\n 'task.archive': 'Archive',\n 'task.drag': 'Drag to move',\n 'step.completed': 'Completed',\n 'step.in-progress': 'In Progress',\n 'step.pending': 'Pending',\n 'step.edit-hint': 'Double-click to edit; click the icon to cycle status',\n 'file.copy': 'Copy path',\n 'file.copied': 'Path copied',\n 'minibar.current': 'Current task',\n 'minibar.click-expand': 'Click to expand & sync',\n 'minibar.tasks': 'tasks',\n 'minibar.no-task': 'No tasks · click to view',\n 'view.cycle': 'Switch view: tasks / project memory / global memory',\n 'view.task': 'Tasks',\n 'view.project': 'Project Memory',\n 'view.global': 'Global Memory',\n 'mem.scope.task': 'Task drafts',\n 'mem.scope.project': 'Project memory',\n 'mem.scope.global': 'Global memory',\n 'mem.empty': 'No memory entries yet (created by reflection or save_lesson)',\n 'mem.confirm': 'Approve',\n 'mem.promote': 'Promote',\n 'mem.demote': 'Demote',\n 'mem.archive': 'Archive',\n 'mem.restore': 'Restore',\n 'mem.delete': 'Delete',\n 'mem.draft': 'draft',\n 'mem.archived': 'archived',\n 'mem.loading': 'Loading…',\n 'mem.error': 'Sync failed',\n 'mem.kind.lesson': 'lesson',\n 'mem.kind.decision': 'decision',\n 'mem.kind.procedure': 'procedure',\n 'mem.kind.experience': 'experience',\n 'mem.needs-bound': 'Bind a task to demote',\n 'mem.new': 'New',\n 'mem.save': 'Save',\n 'mem.cancel': 'Cancel',\n 'mem.f.title': 'Title (pattern / topic / procedure name)',\n 'mem.f.kind': 'Kind',\n 'mem.f.body': 'Fix / reason / solution',\n 'mem.f.steps': 'Steps (one per line)',\n 'mem.f.trigger': 'As Skill: trigger keywords (comma separated)',\n 'mem.saved': 'Saved',\n 'mem.edit': 'Edit',\n 'mem.section-label': 'Task memory',\n 'slash.group': 'Workflow',\n 'slash.tasks-desc': 'Task list: progress, involved files, current session binding',\n 'slash.project-desc': 'Project memory: this project’s lessons / decisions / procedures',\n 'slash.global-desc': 'Global memory: experience entries shared across projects',\n}\n\nexport type LocaleDict = typeof zh\n\nexport function createTranslate(dict: LocaleDict) {\n return (key: keyof LocaleDict, params?: Record<string, string | number>) => {\n let text = dict[key] ?? key\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n text = text.replace(new RegExp(`\\\\{${k}\\\\}`, 'g'), String(v))\n }\n }\n return text\n }\n}\n","/**\n * Task Data Store — 仅管服务端同步的数据(tasks、boundTaskId、archivedCount)\n * - 单向数据流:命令执行结果 → setTasks → 广播给其他标签页\n * - 无 UI 状态,无 localStorage,纯内存 + BroadcastChannel 同步\n */\nimport { useSyncExternalStore } from 'react'\n\nexport interface TaskStep {\n content: string\n status: 'pending' | 'in_progress' | 'completed'\n}\n\nexport interface TaskFile {\n path: string\n line?: number\n}\n\nexport interface TaskInsight {\n id: string\n kind: string\n title: string\n draft?: boolean\n}\n\nexport interface Task {\n id: string\n title: string\n steps: TaskStep[]\n files: TaskFile[]\n lastActiveAt: string\n updatedAt: string\n archived?: boolean\n insights?: TaskInsight[]\n}\n\nexport interface TaskPayload {\n tasks: Task[]\n boundId: string | null\n archived: number\n}\n\nexport function parseTaskPayloadText(text?: string | null): TaskPayload | null {\n if (!text) return null\n let jsonBlock: string | null = null\n const fenced = text.match(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/)\n if (fenced) jsonBlock = fenced[1]\n else {\n const lastBrace = text.lastIndexOf('{')\n if (lastBrace !== -1) jsonBlock = text.slice(lastBrace)\n }\n if (!jsonBlock) return null\n try {\n const data = JSON.parse(jsonBlock)\n if (!Array.isArray(data.tasks)) return null\n return { tasks: data.tasks, boundId: data.boundId ?? null, archived: data.archived ?? 0 }\n } catch {\n return null\n }\n}\n\ninterface TaskDataState {\n tasks: Task[]\n boundTaskId: string | null\n archivedCount: number\n lastUpdate: number\n}\n\nconst SYNC_CHANNEL = typeof window !== 'undefined' ? new BroadcastChannel('dsh-pm-tasks-data') : null\n\nlet dataState: TaskDataState = {\n tasks: [],\n boundTaskId: null,\n archivedCount: 0,\n lastUpdate: 0,\n}\n\nconst dataListeners = new Set<() => void>()\n\nfunction setDataState(next: TaskDataState | ((prev: TaskDataState) => TaskDataState)): void {\n // 兼容对象与函数式 updater(BroadcastChannel 曾误把 updater 当对象写入,\n // 导致 dataState 变成函数、tasks 丢失 → 面板崩溃)。写入一律归一化为完整 shape。\n const patch = typeof next === 'function' ? next(dataState) : next\n dataState = {\n tasks: Array.isArray(patch?.tasks) ? patch.tasks : [],\n boundTaskId: patch?.boundTaskId ?? null,\n archivedCount: typeof patch?.archivedCount === 'number' ? patch.archivedCount : 0,\n lastUpdate: typeof patch?.lastUpdate === 'number' ? patch.lastUpdate : 0,\n }\n for (const listener of dataListeners) listener()\n}\n\nfunction broadcastDataUpdate(tasks: Task[], archivedCount: number): void {\n if (!SYNC_CHANNEL) return\n SYNC_CHANNEL.postMessage({\n type: 'PROJECT_TASKS_UPDATED',\n payload: { tasks: Array.isArray(tasks) ? tasks : [], archivedCount },\n })\n}\n\nif (SYNC_CHANNEL) {\n SYNC_CHANNEL.onmessage = (event) => {\n const msg = event.data\n if (msg?.type === 'PROJECT_TASKS_UPDATED' && msg.payload) {\n const { tasks, archivedCount } = msg.payload\n setDataState(prev => ({\n ...prev,\n tasks: Array.isArray(tasks) ? tasks : [],\n archivedCount: typeof archivedCount === 'number' ? archivedCount : prev.archivedCount,\n lastUpdate: Date.now(),\n }))\n }\n }\n}\n\nexport const taskDataStore = {\n subscribe(listener: () => void): () => void {\n dataListeners.add(listener)\n return () => { dataListeners.delete(listener) }\n },\n getSnapshot(): TaskDataState {\n return dataState\n },\n actions: {\n setTasks(payload: { tasks: Task[]; boundTaskId: string | null; archivedCount: number }): void {\n const nextTasks = payload.tasks || []\n const nextArchived = payload.archivedCount ?? 0\n setDataState({\n tasks: nextTasks,\n boundTaskId: payload.boundTaskId ?? null,\n archivedCount: nextArchived,\n lastUpdate: Date.now(),\n })\n broadcastDataUpdate(nextTasks, nextArchived)\n },\n reset(): void {\n setDataState({\n tasks: [],\n boundTaskId: null,\n archivedCount: 0,\n lastUpdate: 0,\n })\n },\n },\n}\n\nexport function useTaskData(): TaskDataState {\n return useSyncExternalStore(taskDataStore.subscribe, taskDataStore.getSnapshot, taskDataStore.getSnapshot)\n}\n\nexport function useTaskDataActions() {\n return taskDataStore.actions\n}","/**\n * Task UI Store — 仅管本地 UI 状态(closed、minimized、position、expandedIds、theme、showHints)\n * - 持久化到 localStorage(key: dsh-pm-task-panel-ui)\n * - 不跨标签页同步(每个标签页独立)\n * - 启动/刷新强制 closed: true,面板默认不显示\n */\nimport { useSyncExternalStore } from 'react'\n\nconst STORAGE_KEY = 'dsh-pm-task-panel-ui'\n\ninterface TaskUIState {\n expandedTaskIds: string[]\n panelPosition: { x: number; y: number }\n minimized: boolean\n closed: boolean\n theme: string\n /** 是否显示悬停提示信息(title 气泡);false 时面板内所有功能提示都不弹出。 */\n showHints: boolean\n}\n\nfunction defaultPosition(): { x: number; y: number } {\n if (typeof window !== 'undefined') {\n return { x: Math.max(16, window.innerWidth - 408), y: 72 }\n }\n return { x: 0, y: 0 }\n}\n\n/**\n * 启动时的初始状态:\n * - closed 恒为 true(不读取 localStorage 的 closed),刷新后面板隐藏;\n * - 其余(展开项/位置/主题)可恢复上次会话偏好,minimized 默认折叠成迷你条。\n */\nfunction getDefaultUIState(): TaskUIState {\n if (typeof window !== 'undefined') {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return {\n expandedTaskIds: Array.isArray(parsed.expandedTaskIds) ? parsed.expandedTaskIds : [],\n panelPosition: parsed.panelPosition ?? defaultPosition(),\n minimized: parsed.minimized !== false,\n closed: true,\n theme: typeof parsed.theme === 'string' ? parsed.theme : 'native',\n showHints: parsed.showHints !== false,\n }\n }\n } catch { /* corrupt state — fall through to defaults */ }\n }\n return {\n expandedTaskIds: [],\n panelPosition: defaultPosition(),\n minimized: true,\n closed: true,\n theme: 'native',\n showHints: true,\n }\n}\n\nfunction persistUI(state: TaskUIState): void {\n if (typeof window === 'undefined') return\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(state))\n } catch { /* storage full/unavailable — non-fatal */ }\n}\n\nlet uiState: TaskUIState = getDefaultUIState()\nconst uiListeners = new Set<() => void>()\n\nfunction setUIState(next: TaskUIState): void {\n uiState = next\n persistUI(next)\n for (const listener of uiListeners) listener()\n}\n\nexport const taskUIStore = {\n subscribe(listener: () => void): () => void {\n uiListeners.add(listener)\n return () => { uiListeners.delete(listener) }\n },\n getSnapshot(): TaskUIState {\n return uiState\n },\n actions: {\n toggleTaskExpanded(taskId: string): void {\n const prev = uiState\n const ids = prev.expandedTaskIds.includes(taskId)\n ? prev.expandedTaskIds.filter((id) => id !== taskId)\n : [...prev.expandedTaskIds, taskId]\n setUIState({ ...prev, expandedTaskIds: ids })\n },\n expandAll(taskIds: string[]): void {\n setUIState({ ...uiState, expandedTaskIds: taskIds })\n },\n setPanelPosition(pos: { x: number; y: number }): void {\n setUIState({ ...uiState, panelPosition: pos })\n },\n open(): void {\n setUIState({ ...uiState, minimized: false, closed: false })\n },\n minimize(): void {\n setUIState({ ...uiState, minimized: true, closed: false })\n },\n close(): void {\n setUIState({ ...uiState, minimized: true, closed: true })\n },\n setTheme(theme: string): void {\n setUIState({ ...uiState, theme })\n },\n toggleHints(): void {\n setUIState({ ...uiState, showHints: !uiState.showHints })\n },\n setShowHints(showHints: boolean): void {\n setUIState({ ...uiState, showHints })\n },\n reset(): void {\n setUIState(getDefaultUIState())\n },\n },\n}\n\nexport function useTaskUI(): TaskUIState {\n return useSyncExternalStore(taskUIStore.subscribe, taskUIStore.getSnapshot, taskUIStore.getSnapshot)\n}\n\nexport function useTaskUIActions() {\n return taskUIStore.actions\n}\n","/**\n * Task Panel Hooks — 步骤拖拽交互逻辑(useTaskDrag)。\n * 只依赖 react + task-data-store 类型,不碰数据/UI store。\n */\nimport { useEffect, useRef, useState, useCallback } from 'react'\nimport { TaskStep } from './task-data-store.ts'\n\ninterface DragState {\n fromIndex: number\n stepContent: string\n clientX: number\n clientY: number\n dragging: boolean\n}\n\n/**\n * useTaskDrag — 步骤拖拽重排(绑定任务内,同一任务卡的步骤行间移动)。\n *\n * 交互模型(拖动全程按住鼠标):\n * - 步骤行上按下(左键、非按钮/输入区域)→ 进入预览;\n * - 按住 350ms 不松,或按住后移动超过 6px → 唤起跟随鼠标的浮动幽灵卡片;\n * - 幽灵悬停到本任务卡内的步骤行时显示蓝色插入线(上半=插到该行前,下半=插到该行后);\n * - 松手(mouseup):落在有效位置 → onReorder 落子;落在卡外/别的任务卡/原行\n * (插入自身前后)/按钮输入等控件上 → 取消;\n * - 350ms 内原地松手 = 普通点击,不产生幽灵;Esc → 取消。\n */\nexport function useTaskDrag(\n taskId: string,\n steps: TaskStep[],\n isBound: boolean,\n onReorder: (fromIndex: number, toIndex: number) => void\n) {\n const [dragState, setDragState] = useState<DragState | null>(null)\n const [dropTargetIndex, setDropTargetIndex] = useState<number | null>(null)\n\n // 最新值镜像:拖拽期间 window 监听只在“会话开始/结束”时挂载/卸载,\n // 避免每次 mousemove 更新状态导致监听器重挂、连 350ms 定时器都被清掉。\n const dragRef = useRef(dragState)\n dragRef.current = dragState\n const longPressTimer = useRef<number | undefined>(undefined)\n const dragOrigin = useRef<{ x: number; y: number } | null>(null)\n\n const clearTimer = useCallback(() => {\n if (longPressTimer.current !== undefined) {\n window.clearTimeout(longPressTimer.current)\n longPressTimer.current = undefined\n }\n }, [])\n\n const cancelDrag = useCallback(() => {\n clearTimer()\n dragOrigin.current = null\n document.body.style.userSelect = ''\n setDropTargetIndex(null)\n setDragState(null)\n }, [clearTimer])\n\n const startDrag = useCallback((\n fromIndex: number,\n stepContent: string,\n e: React.MouseEvent\n ) => {\n if (!isBound || e.button !== 0) return\n if (dragRef.current) return // 已有预览/拖拽会话\n e.preventDefault()\n e.stopPropagation()\n document.body.style.userSelect = 'none'\n dragOrigin.current = { x: e.clientX, y: e.clientY }\n setDropTargetIndex(null)\n setDragState({ fromIndex, stepContent, clientX: e.clientX, clientY: e.clientY, dragging: false })\n clearTimer()\n longPressTimer.current = window.setTimeout(() => {\n longPressTimer.current = undefined\n // 350ms 长按 → 唤起幽灵卡片\n setDragState(prev => (prev ? { ...prev, dragging: true } : null))\n }, 350)\n }, [isBound, clearTimer])\n\n /** 计算某行上 y 坐标对应的插入位(行数下标:上半=该行前,下半=该行后);非本任务卡返回 null */\n const dropIndexAt = useCallback((row: Element, clientY: number): number | null => {\n const parentOl = row.closest('ol')\n if (!parentOl || !parentOl.closest(`article[data-task-id=\"${taskId}\"]`)) return null\n const index = Array.from(parentOl.children).indexOf(row)\n const rect = row.getBoundingClientRect()\n return clientY < rect.top + rect.height / 2 ? index : index + 1\n }, [taskId])\n\n /** 在 (x,y) 处结算:命中有效落点则重排,否则取消;并结束本次拖拽 */\n const commitDrop = useCallback((x: number, y: number) => {\n const cur = dragRef.current\n if (!cur || !cur.dragging) return\n const el = document.elementFromPoint(x, y) as HTMLElement | null\n // 松手点在按钮/输入等交互控件上:不落子,直接取消\n if (el && !el.closest('button, input, textarea, a')) {\n const row = el.closest('[data-step-row]')\n if (row) {\n const drop = dropIndexAt(row, y)\n if (drop !== null) {\n // 行下标形式的落点:插到目标行前/后;落在自身原位视为取消(不产生空推送)\n const effective = drop > cur.fromIndex ? drop - 1 : drop\n if (effective !== cur.fromIndex) onReorder(cur.fromIndex, drop)\n }\n }\n }\n cancelDrag()\n }, [dropIndexAt, onReorder, cancelDrag])\n\n const active = dragState !== null\n\n useEffect(() => {\n if (!active) return\n\n const onMouseMove = (e: MouseEvent) => {\n const cur = dragRef.current\n if (!cur) return\n if (!cur.dragging) {\n // 未到 350ms:移动超过阈值视为拖拽开始(不必死等长按)\n const origin = dragOrigin.current\n if (!origin) return\n if (Math.hypot(e.clientX - origin.x, e.clientY - origin.y) < 6) return\n clearTimer()\n setDragState(prev => (prev ? { ...prev, dragging: true, clientX: e.clientX, clientY: e.clientY } : null))\n } else {\n setDragState(prev => (prev ? { ...prev, clientX: e.clientX, clientY: e.clientY } : null))\n }\n const row = document.elementFromPoint(e.clientX, e.clientY)?.closest('[data-step-row]')\n setDropTargetIndex(row ? dropIndexAt(row, e.clientY) : null)\n }\n\n const onMouseUp = (e: MouseEvent) => {\n const cur = dragRef.current\n if (!cur) return\n if (cur.dragging) {\n // 拖拽中松手 = 落子/取消\n commitDrop(e.clientX, e.clientY)\n } else {\n // 350ms 内原地松手 = 普通点击\n cancelDrag()\n }\n }\n\n const onClick = (e: MouseEvent) => {\n // 兜底:mouseup 发生在窗口外等情况时,下一次点击直接结算\n const cur = dragRef.current\n if (!cur || !cur.dragging) return\n commitDrop(e.clientX, e.clientY)\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') cancelDrag()\n }\n\n window.addEventListener('mousemove', onMouseMove)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('click', onClick, true)\n window.addEventListener('keydown', onKeyDown)\n return () => {\n window.removeEventListener('mousemove', onMouseMove)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('click', onClick, true)\n window.removeEventListener('keydown', onKeyDown)\n document.body.style.userSelect = ''\n }\n }, [active, taskId, dropIndexAt, onReorder, cancelDrag, commitDrop])\n\n useEffect(() => () => clearTimer(), [clearTimer])\n\n return { dragState, dropTargetIndex, startDrag, cancelDrag }\n}\n","/**\n * Task Panel Presentational 组件 — MiniBar(折叠迷你条)与 TaskCard(任务卡)。\n * 纯渲染 + 卡片局部行内编辑/拖拽状态,动作经 props 回调交给容器(TaskPanel.tsx)。\n */\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\n// 图标走兼容层:0.1.5 用 IconXxx14/16,0.1.7+ 改成 IconXxxRegular + size prop\nimport {\n IconChevronDownOutline14,\n IconChevronUpOutline14,\n IconCheckOutline16,\n IconPlayOutline16,\n IconFolderOpenOutline16,\n} from './icons.ts'\nimport { createTranslate } from './locales.ts'\nimport { useTaskDrag } from './task-hooks.ts'\nimport { type Task, type TaskInsight, type TaskStep } from './task-data-store.ts'\nimport css from './TaskPanel.module.css'\n\nfunction insightKindLabel(kind: string, t: ReturnType<typeof createTranslate>): string {\n const map: Record<string, string> = {\n lesson: t('mem.kind.lesson'),\n decision: t('mem.kind.decision'),\n procedure: t('mem.kind.procedure'),\n experience: t('mem.kind.experience'),\n }\n return map[kind] ?? kind\n}\n\ntype InsightAction = 'confirm' | 'promote' | 'delete'\n\nfunction timeAgo(iso?: string) {\n if (!iso) return ''\n const diff = Date.now() - new Date(iso).getTime()\n const m = Math.floor(diff / 60000)\n if (m < 1) return '刚刚'\n if (m < 60) return `${m}分钟前`\n const h = Math.floor(m / 60)\n if (h < 24) return `${h}小时前`\n return `${Math.floor(h / 24)}天前`\n}\n\nfunction StepIcon({ status }: { status: TaskStep['status'] }) {\n if (status === 'completed') return <IconCheckOutline16 className={css.stepDone} />\n if (status === 'in_progress') return <IconPlayOutline16 className={css.stepRun} />\n return <span className={css.stepPending} />\n}\n\n/**\n * 双击判定窗口(ms)。\n * 单击(如卡片展开/收起)会延迟该时长执行:若期间收到第二次点击则按“双击”处理并取消单击,\n * 从而避免“第一下先展开/收起、布局位移后第二下点不到目标”的问题。\n * 数值是可感知与可靠性的折中:太小慢速双击会失效,太大单击会显“肉”。\n */\nconst CLICK_SINGLE_DELAY_MS = 250\n\n/**\n * 行内自适应高度文本编辑器(textarea)。\n * 编辑体验与单行输入一致(Enter 提交 / Shift+Enter 换行 / Esc 取消 / 失焦提交),\n * 但高度随内容自动增长(按实际渲染行高测量),最多 maxRows 行后内部滚动,\n * 解决长步骤/长任务名只能挤在一行里横向滚动编辑的问题。\n */\ninterface InlineEditorProps {\n value: string\n className?: string\n maxRows?: number\n onValueChange: (value: string) => void\n onCommit: () => void\n onCancel: () => void\n}\n\nfunction InlineEditor({ value, className, maxRows = 8, onValueChange, onCommit, onCancel }: InlineEditorProps) {\n const ref = useRef<HTMLTextAreaElement>(null)\n\n // 在绘制前按真实内容测量并写死高度:内容 <= maxRows 行时刚好包住,超出后内部滚动。\n useLayoutEffect(() => {\n const el = ref.current\n if (!el) return\n el.style.height = 'auto'\n const cs = getComputedStyle(el)\n const lineHeight = parseFloat(cs.lineHeight) || 20\n const padV = (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0)\n const borderV = (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0)\n const cap = maxRows * lineHeight + padV + borderV\n const height = Math.min(el.scrollHeight, cap)\n el.style.height = `${height}px`\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden'\n }, [value, maxRows])\n\n return (\n <textarea\n ref={ref}\n className={className}\n rows={1}\n value={value}\n autoFocus\n spellCheck={false}\n onChange={(e) => onValueChange(e.target.value)}\n onFocus={(e) => {\n // 光标放到末尾,便于直接在原文后继续输入\n const len = e.target.value.length\n e.target.setSelectionRange(len, len)\n }}\n onBlur={onCommit}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onCommit()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n onCancel()\n }\n }}\n />\n )\n}\n\ninterface MiniBarProps {\n label: string\n hint: string\n showHints: boolean\n position: { x: number; y: number }\n theme: string\n onMove: (pos: { x: number; y: number }) => void\n open: () => void\n}\n\nexport function MiniBar({ label, hint, showHints, position, theme, onMove, open }: MiniBarProps) {\n const barRef = useRef<HTMLDivElement>(null)\n const down = useRef<{ dx: number; dy: number; sx: number; sy: number; moved: boolean } | null>(null)\n\n const onMouseDown = (e: React.MouseEvent) => {\n if (e.button !== 0) return\n const rect = barRef.current?.getBoundingClientRect()\n if (!rect) return\n down.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top, sx: e.clientX, sy: e.clientY, moved: false }\n const onMoveEv = (ev: MouseEvent) => {\n const d = down.current\n if (!d) return\n if (!d.moved && Math.abs(ev.clientX - d.sx) + Math.abs(ev.clientY - d.sy) > 4) d.moved = true\n if (d.moved) {\n const w = barRef.current?.offsetWidth ?? 260\n const h = barRef.current?.offsetHeight ?? 34\n const x = Math.max(8, Math.min(window.innerWidth - w - 8, ev.clientX - d.dx))\n const y = Math.max(8, Math.min(window.innerHeight - h - 8, ev.clientY - d.dy))\n onMove({ x, y })\n }\n }\n const onUpEv = () => {\n const d = down.current\n down.current = null\n window.removeEventListener('mousemove', onMoveEv)\n window.removeEventListener('mouseup', onUpEv)\n if (d && !d.moved) open()\n }\n window.addEventListener('mousemove', onMoveEv)\n window.addEventListener('mouseup', onUpEv)\n }\n\n return (\n <div\n ref={barRef}\n className={css.miniBar}\n style={{ left: position.x, top: position.y }}\n data-theme={theme === 'native' ? undefined : theme}\n onMouseDown={onMouseDown}\n role=\"button\"\n title={showHints ? hint : undefined}\n aria-label={hint}\n >\n <IconFolderOpenOutline16 className={css.miniIcon} />\n <span className={css.miniText}>{label}</span>\n <IconChevronUpOutline14 className={css.miniChevron} />\n </div>\n )\n}\n\ninterface TaskCardProps {\n task: Task\n isBound: boolean\n expanded: boolean\n onToggleExpand: () => void\n onSwitch: () => void\n onUnbind: () => void\n onArchive: () => void\n onRename: (value: string) => void\n onEditStep: (index: number, value: string) => void\n onCycleStatus: (index: number) => void\n onReorderSteps: (fromIndex: number, toIndex: number) => void\n onInsightAction?: (action: InsightAction, id: string) => void\n showHints: boolean\n syncing: boolean\n t: ReturnType<typeof createTranslate>\n}\n\nexport function TaskCard({\n task,\n isBound,\n expanded,\n onToggleExpand,\n onSwitch,\n onUnbind,\n onArchive,\n onRename,\n onEditStep,\n onCycleStatus,\n onReorderSteps,\n onInsightAction,\n showHints,\n syncing,\n t,\n}: TaskCardProps) {\n const steps = task.steps || []\n const { dragState, dropTargetIndex, startDrag, cancelDrag } = useTaskDrag(task.id, steps, isBound, onReorderSteps)\n\n // 行内编辑状态(本卡片局部):双击进入,Enter/失焦提交,Esc 取消。\n const [stepEdit, setStepEdit] = useState<{ index: number; value: string } | null>(null)\n const [titleEdit, setTitleEdit] = useState<{ value: string } | null>(null)\n\n const done = steps.filter((s) => s.status === 'completed').length\n const pct = steps.length > 0 ? Math.round((done / steps.length) * 100) : 0\n\n const commitStepEdit = (index: number) => {\n if (!stepEdit || stepEdit.index !== index) return\n const value = stepEdit.value\n setStepEdit(null)\n onEditStep(index, value)\n }\n\n const commitTitleEdit = () => {\n if (titleEdit === null) return\n const value = titleEdit.value\n setTitleEdit(null)\n onRename(value)\n }\n\n // —— 卡片头单击(展开/收起)与双击(编辑任务名)的时序判定 ——\n // 单击动作延迟 CLICK_SINGLE_DELAY_MS 执行;若在窗口内收到第二次点击,取消单击、\n // 命中任务名则直接进入编辑,避免“第一下已展开/收起、布局位移、第二下点不到任务名”。\n const headClickTimer = useRef<number | null>(null)\n // 编辑状态下,点卡片头任意处会先触发失焦提交;该次点击不应再当作“切换展开”的单击。\n const suppressHeadClick = useRef(false)\n useEffect(() => () => {\n if (headClickTimer.current !== null) window.clearTimeout(headClickTimer.current)\n }, [])\n\n const handleHeadClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (suppressHeadClick.current) {\n // 上一次 mousedown 落在标题编辑框内(失焦提交产生),吞掉这次点击,不切换展开\n suppressHeadClick.current = false\n return\n }\n if (titleEdit !== null) return\n const target = e.target as HTMLElement\n const onTitle = isBound && target.closest('[data-card-title]') !== null\n if (headClickTimer.current !== null) {\n // 第二次点击 → 双击:取消待执行的单击动作\n window.clearTimeout(headClickTimer.current)\n headClickTimer.current = null\n if (onTitle) setTitleEdit({ value: String(task.title ?? '') })\n else onToggleExpand()\n return\n }\n headClickTimer.current = window.setTimeout(() => {\n headClickTimer.current = null\n onToggleExpand()\n }, CLICK_SINGLE_DELAY_MS)\n }\n\n return (\n <article data-task-id={task.id} className={`${css.card}${isBound ? ` ${css.cardBound}` : ''}`}>\n <button\n className={css.cardHead}\n onClick={handleHeadClick}\n onMouseDownCapture={() => {\n // 标题编辑中,点击卡片头任意处都会先失焦提交;标记该次点击以在 onClick 中吞掉,\n // 避免“改名提交一下、卡片又收起/展开一下”的误切换。\n if (titleEdit !== null) suppressHeadClick.current = true\n }}\n onDoubleClick={(e) => e.preventDefault()}\n aria-expanded={expanded}\n >\n <div className={css.cardTitleRow}>\n {isBound && <span className={css.boundBadge}>{t('task.current')}</span>}\n {isBound && titleEdit !== null ? (\n <InlineEditor\n className={css.editorArea}\n value={titleEdit.value}\n maxRows={4}\n onValueChange={(value) => setTitleEdit({ value })}\n onCommit={commitTitleEdit}\n onCancel={() => setTitleEdit(null)}\n />\n ) : (\n <span\n data-card-title\n className={`${css.cardTitle}${isBound ? ` ${css.cardTitleEditable}` : ''}`}\n title={isBound && showHints ? t('task.title-edit') : undefined}\n onDoubleClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n if (isBound) setTitleEdit({ value: String(task.title ?? '') })\n }}\n >\n {task.title}\n </span>\n )}\n </div>\n <div className={css.cardMeta}>\n {steps.length > 0 && <span className={css.progressText}>{done}/{steps.length}</span>}\n <span className={css.updated}>{timeAgo(task.updatedAt || task.lastActiveAt)}</span>\n <span className={css.chevron}>{expanded ? <IconChevronUpOutline14 /> : <IconChevronDownOutline14 />}</span>\n </div>\n </button>\n {steps.length > 0 && (\n <div className={css.track}>\n <div className={css.trackFill} style={{ width: `${pct}%` }} />\n </div>\n )}\n {expanded && (\n <div className={css.cardBody}>\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('task.steps')}\n {steps.length > 0 && <span className={css.sectionCount}>{steps.length}</span>}\n </div>\n {steps.length > 0 ? (\n <>\n <ol className={css.stepsList}>\n {steps.map((step, i) => {\n const stepIsEditing = stepEdit !== null && stepEdit.index === i\n const stepIsDragging = dragState?.dragging && dragState.fromIndex === i\n const isDropTarget = dropTargetIndex === i\n const isDropTargetAfter = dropTargetIndex === i + 1\n return (\n <li\n key={i}\n data-step-row\n className={`${css.stepRow}${stepIsDragging ? ` ${css.stepDragging}` : ''}${isDropTarget ? ` ${css.dropTargetBefore}` : ''}${isDropTargetAfter ? ` ${css.dropTargetAfter}` : ''}`}\n onMouseDown={(e) => {\n if (e.button !== 0) return\n if (!isBound || syncing) return\n // 交互控件(状态图标、编辑输入框等)上不进入拖拽\n const el = e.target as HTMLElement\n if (el.closest('button, input, textarea, a')) return\n startDrag(i, step.content, e)\n }}\n >\n {isBound ? (\n <button\n type=\"button\"\n className={css.stepToggle}\n disabled={syncing}\n onClick={(e) => { e.stopPropagation(); onCycleStatus(i) }}\n title={showHints ? `${t('step.completed')}/${t('step.in-progress')}/${t('step.pending')}` : undefined}\n >\n <StepIcon status={step.status} />\n </button>\n ) : (\n <StepIcon status={step.status} />\n )}\n {stepIsEditing ? (\n <InlineEditor\n className={css.editorArea}\n value={stepEdit!.value}\n maxRows={10}\n onValueChange={(value) => setStepEdit({ index: i, value })}\n onCommit={() => commitStepEdit(i)}\n onCancel={() => setStepEdit(null)}\n />\n ) : (\n <span\n className={`${css.stepContent}${step.status === 'completed' ? ` ${css.stepContentDone}` : ''}${step.status === 'in_progress' ? ` ${css.stepContentRun}` : ''}${isBound ? ` ${css.stepEditable}` : ''}`}\n title={isBound && showHints ? t('step.edit-hint') : undefined}\n onDoubleClick={(e) => {\n e.stopPropagation()\n if (isBound) setStepEdit({ index: i, value: String(step.content ?? '') })\n }}\n >\n {step.content}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n {dragState && dragState.dragging && (\n <div\n className={css.dragGhost}\n style={{\n left: dragState.clientX + 12,\n top: dragState.clientY - 20,\n }}\n >\n <div className={css.dragGhostCard}>\n <span className={css.dragGhostContent}>{dragState.stepContent}</span>\n <button\n type=\"button\"\n className={css.dragGhostClose}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => { e.stopPropagation(); cancelDrag() }}\n title={showHints ? t('drag.cancel') : undefined}\n aria-label={t('drag.cancel')}\n >\n ×\n </button>\n </div>\n </div>\n )}\n </>\n ) : (\n <div className={css.muted}>{t('panel.empty-desc')}</div>\n )}\n </div>\n\n {(task.files?.length ?? 0) > 0 && (\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('task.files')}\n <span className={css.sectionCount}>{task.files.length}</span>\n </div>\n <ul className={css.filesList}>\n {task.files.slice(0, 12).map((file, i) => (\n <li key={i}>\n <button\n className={css.fileRow}\n onClick={() => navigator.clipboard?.writeText(file.path)}\n title={showHints ? `${t('file.copy')}: ${file.path}${file.line ? `:${file.line}` : ''}` : undefined}\n >\n <span className={css.fileDot} />\n <span className={css.filePath}>{file.path}</span>\n {file.line && <span className={css.fileLine}>:{file.line}</span>}\n </button>\n </li>\n ))}\n {(task.files?.length ?? 0) > 12 && (\n <li className={css.muted}>… 共 {task.files.length} 个</li>\n )}\n </ul>\n </div>\n )}\n\n {onInsightAction && Array.isArray(task.insights) && task.insights.length > 0 && (\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('mem.section-label')}\n <span className={css.sectionCount}>{task.insights.length}</span>\n </div>\n <ul className={css.memList}>\n {(task.insights as TaskInsight[]).map((ins) => (\n <li key={ins.id} className={css.memRow}>\n <div className={css.memTitle}>\n <span className={css.kindBadge}>{insightKindLabel(ins.kind, t)}</span>\n <span>{ins.title || ins.id}</span>\n {ins.draft && <span className={`${css.badge} ${css.badgeDraft}`}>{t('mem.draft')}</span>}\n </div>\n <div className={css.memActs}>\n {ins.draft && (\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('confirm', ins.id)}>\n {t('mem.confirm')}\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('promote', ins.id)}>\n {t('mem.promote')}\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('delete', ins.id)}>\n {t('mem.delete')}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n <div className={css.cardFooter}>\n <Button variant=\"outline\" size=\"sm\" disabled={isBound || syncing} onClick={onSwitch}>\n {t('task.switch')}\n </Button>\n {isBound && (\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={onUnbind} title={showHints ? t('task.unbind') : undefined}>\n {t('task.unbind')}\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={onArchive}>\n {t('task.archive')}\n </Button>\n </div>\n </div>\n )}\n </article>\n )\n}\n","/**\n * Memory View — 记忆三作用域列表(Task 草稿 / Project / Global)\n * 数据通道与任务面板一致:remote.commands.execute 执行 /insight 命令,取 JSON 载荷。\n * 动作:confirm(草稿审核) / promote(向上提升) / demote(向下降级,需绑定任务) / archive / restore / delete\n */\nimport { useEffect, useCallback, useRef, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './TaskPanel.module.css'\n\nexport type InsightScope = 'task' | 'project' | 'global'\n\nexport interface InsightRow {\n id: string\n kind: string\n scope: InsightScope\n title: string\n body?: string\n fix?: string\n solution?: string\n reason?: string\n pattern?: string\n problem?: string\n choice?: string\n draft?: boolean\n archived?: boolean\n confidence?: number | null\n hitCount?: number\n members?: number\n files?: number\n symbols?: number\n trigger?: { keywords: string[]; scope: string[] } | null\n steps?: string[]\n taskId?: string\n taskTitle?: string\n updatedAt?: string\n}\n\ninterface ListPayload {\n scope: InsightScope\n count: number\n items: InsightRow[]\n}\n\nexport function parseInsightPayloadText(text?: string | null): ListPayload | null {\n if (!text) return null\n let jsonBlock: string | null = null\n const fenced = text.match(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/)\n if (fenced) jsonBlock = fenced[1]\n else {\n const lastBrace = text.lastIndexOf('{')\n if (lastBrace !== -1) jsonBlock = text.slice(lastBrace)\n }\n if (!jsonBlock) return null\n try {\n const data = JSON.parse(jsonBlock)\n if (!Array.isArray(data.items)) return null\n return { scope: data.scope ?? 'project', count: data.count ?? data.items.length, items: data.items }\n } catch {\n return null\n }\n}\n\nfunction kindText(kind: string, t: any): string {\n const map: Record<string, string> = {\n lesson: t('mem.kind.lesson'),\n decision: t('mem.kind.decision'),\n procedure: t('mem.kind.procedure'),\n experience: t('mem.kind.experience'),\n }\n return map[kind] ?? kind\n}\n\nexport function MemoryView({\n ctx,\n sessionId,\n scope,\n boundTaskId,\n showHints,\n t,\n}: {\n ctx: any\n sessionId: string | null\n scope: InsightScope\n boundTaskId: string | null\n showHints: boolean\n t: any\n}) {\n const [payload, setPayload] = useState<ListPayload | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(false)\n const [busy, setBusy] = useState(false)\n const [showNew, setShowNew] = useState(false)\n const [editingId, setEditingId] = useState<string | null>(null)\n const [form, setForm] = useState({ title: '', kind: 'lesson', body: '', steps: '', trigger: '' })\n const [savedTip, setSavedTip] = useState<string | null>(null)\n\n const runLine = useCallback(\n async (line: string): Promise<{ ok: boolean; text: string }> => {\n const commands = ctx?.remote?.commands\n if (!sessionId || !commands || typeof commands.execute !== 'function') {\n return { ok: false, text: 'no session / commands service' }\n }\n try {\n const response = await commands.execute(sessionId, line, [])\n const envelope = response as { ok?: boolean; value?: any } | null | undefined\n const execution = envelope && typeof envelope === 'object' && 'value' in envelope ? envelope.value : envelope\n const result = execution?.result ?? execution\n if (result?.kind === 'error') return { ok: false, text: result.text ?? 'command error' }\n return { ok: true, text: result?.text ?? '' }\n } catch (err) {\n return { ok: false, text: String((err as Error)?.message ?? err) }\n }\n },\n [ctx, sessionId],\n )\n\n // 用 ref 做并发/频控守卫:loading 状态不能进 refresh 的依赖数组,\n // 否则 loading 每次翻转都会重建 refresh → effect 重跑 → 无限循环刷 /insight 命令。\n const inflightRef = useRef(false)\n const lastRunRef = useRef(0)\n\n const refresh = useCallback(async (force = false): Promise<void> => {\n // 没有活跃会话时不发命令、也不报错:面板顶部已经显示「还没有会话」,\n // 再报一次\"同步失败\"会让人以为记忆库坏了(0.1.7 上会话快照结构变化时就是这个表象)。\n if (!sessionId) {\n setPayload(null)\n setError(null)\n setLoading(false)\n return\n }\n if (inflightRef.current) return\n const now = Date.now()\n if (!force && now - lastRunRef.current < 800) return\n inflightRef.current = true\n lastRunRef.current = now\n setLoading(true)\n setError(null)\n try {\n const res = await runLine(`/tasks insight list ${scope}`)\n if (!res.ok) {\n setError(res.text)\n setPayload(null)\n return\n }\n const parsed = parseInsightPayloadText(res.text)\n setPayload(parsed)\n if (!parsed) setError('unparsable payload')\n } finally {\n inflightRef.current = false\n setLoading(false)\n }\n }, [runLine, scope])\n\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n const act = async (action: string, id: string): Promise<void> => {\n if (busy) return\n setBusy(true)\n setError(null)\n try {\n const line = `/tasks insight ${action} ${scope} ${id}${action === 'demote' && scope === 'project' && boundTaskId ? ` ${boundTaskId}` : ''}`\n const res = await runLine(line)\n if (!res.ok) setError(res.text)\n else void refresh(true)\n } finally {\n setBusy(false)\n }\n }\n\n const rowToForm = (row: InsightRow) => {\n // 正文按 kind 取专属字段(fix/solution/reason),避免把与标题相同的 pattern/problem 当正文\n const main =\n row.kind === 'lesson' ? row.fix\n : row.kind === 'experience' ? row.solution\n : row.kind === 'decision' ? row.reason\n : row.body\n const body = main && main !== row.title ? main : ''\n return {\n title: row.title || '',\n kind: row.kind || 'lesson',\n body,\n steps: Array.isArray((row as InsightRow & { steps?: string[] }).steps) ? ((row as InsightRow & { steps?: string[] }).steps as string[]).join('\\n') : '',\n trigger: (row.trigger?.keywords || []).join(','),\n }\n }\n\n const startEdit = (row: InsightRow) => {\n setEditingId(row.id)\n setForm(rowToForm(row))\n setShowNew(true)\n setError(null)\n }\n\n const closeForm = () => {\n setShowNew(false)\n setEditingId(null)\n setForm({ title: '', kind: 'lesson', body: '', steps: '', trigger: '' })\n }\n\n // 切换类型时把当前输入迁移到目标类型的主内容区,避免换类型后“刚写的东西消失”\n const changeKind = (next: string) => {\n setForm(prev => {\n if (prev.kind === next) return prev\n const fromProc = prev.kind === 'procedure'\n const toProc = next === 'procedure'\n let body = prev.body\n let steps = prev.steps\n if (fromProc && !toProc && !body && steps.trim()) body = steps.trim() // procedure → 正文\n if (toProc && !fromProc && !steps.trim() && body.trim()) steps = body.trim() // 正文 → 步骤\n return { ...prev, kind: next, body, steps }\n })\n }\n\n const submitNew = async (): Promise<void> => {\n if (scope === 'task' && !editingId) return\n if (busy) return\n const title = form.title.trim()\n if (!title) return\n setBusy(true)\n setError(null)\n try {\n const fields: Record<string, unknown> = { title, kind: form.kind }\n if (form.kind === 'lesson') fields.pattern = title\n if (form.kind === 'decision') fields.choice = title\n if (form.kind === 'experience') fields.problem = title\n if (form.body.trim()) {\n if (form.kind === 'lesson') fields.fix = form.body.trim()\n else if (form.kind === 'decision') fields.reason = form.body.trim()\n else if (form.kind === 'experience') fields.solution = form.body.trim()\n else fields.body = form.body.trim()\n }\n if (form.kind === 'procedure' && form.steps.trim()) {\n fields.steps = form.steps.split('\\n').map((s) => s.trim()).filter(Boolean)\n }\n if (form.kind === 'procedure' && form.trigger.trim()) {\n fields.trigger = { keywords: form.trigger.split(/[,,]/).map((s) => s.trim()).filter(Boolean) }\n }\n const line = editingId\n ? `/tasks insight edit ${scope} ${editingId} ${JSON.stringify(fields)}`\n : `/tasks insight save ${scope} ${JSON.stringify(fields)}`\n const res = await runLine(line)\n if (!res.ok) {\n setError(res.text)\n } else {\n setSavedTip(t('mem.saved'))\n closeForm()\n window.setTimeout(() => setSavedTip(null), 2500)\n void refresh(true)\n }\n } finally {\n setBusy(false)\n }\n }\n\n const items = payload?.items ?? []\n\n return (\n <div className={css.memoryPane}>\n <div className={css.memToolbar}>\n <span className={css.memCount}>\n {scope === 'task' ? t('mem.scope.task') : scope === 'global' ? t('mem.scope.global') : t('mem.scope.project')}\n {payload ? ` · ${payload.count}` : ''}\n </span>\n <span className={css.memToolbarActs}>\n {savedTip && <span className={css.badge}>{savedTip}</span>}\n {scope !== 'task' && !showNew && (\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => { setShowNew(true); setEditingId(null); setError(null) }}>{t('mem.new')}</Button>\n )}\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refresh(true)} disabled={loading} title={showHints ? t('panel.refresh') : undefined} aria-label={t('panel.refresh')}>\n ↻\n </Button>\n </span>\n </div>\n {showNew && scope !== 'task' && (\n <div className={css.memNew}>\n <input className={css.stepInput} placeholder={t('mem.f.title')} value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })} autoFocus />\n <div className={css.memNewRow}>\n <label className={css.memLabel}>{t('mem.f.kind')}\n <select className={css.stepInput} value={form.kind} onChange={(e) => changeKind(e.target.value)}>\n <option value=\"lesson\">lesson</option>\n <option value=\"decision\">decision</option>\n <option value=\"procedure\">procedure</option>\n <option value=\"experience\">experience</option>\n </select>\n </label>\n </div>\n {form.kind !== 'procedure' && (\n <textarea className={css.stepInput} placeholder={t('mem.f.body')} rows={2} value={form.body}\n onChange={(e) => setForm({ ...form, body: e.target.value })} />\n )}\n {form.kind === 'procedure' && (\n <>\n <textarea className={css.stepInput} placeholder={t('mem.f.steps')} rows={3} value={form.steps}\n onChange={(e) => setForm({ ...form, steps: e.target.value })} />\n <input className={css.stepInput} placeholder={t('mem.f.trigger')} value={form.trigger}\n onChange={(e) => setForm({ ...form, trigger: e.target.value })} />\n </>\n )}\n <div className={css.memActs}>\n <Button variant=\"outline\" size=\"sm\" disabled={busy || !form.title.trim()} onClick={() => void submitNew()}>{t('mem.save')}</Button>\n <Button variant=\"outline\" size=\"sm\" onClick={closeForm}>{t('mem.cancel')}</Button>\n </div>\n </div>\n )}\n {error && <div className={css.notice}>{t('mem.error')}: {error}</div>}\n {loading && !items.length && <div className={css.muted}>{t('mem.loading')}</div>}\n {!loading && !error && items.length === 0 && <div className={css.muted}>{t('mem.empty')}</div>}\n <div className={css.memList}>\n {items.map((row) => {\n const canDemoteToTask = scope === 'project' && !!boundTaskId\n return (\n <div key={row.id} className={`${css.memRow}${row.archived ? ` ${css.memRowArchived}` : ''}`}>\n <div className={css.memRowMain}>\n <span className={css.memTitle}>\n <span className={css.kindBadge}>{kindText(row.kind, t)}</span>\n {row.title || row.body}\n </span>\n <span className={css.memMeta}>\n {row.draft && <span className={`${css.badge} ${css.badgeDraft}`}>{t('mem.draft')}</span>}\n {row.archived && <span className={`${css.badge} ${css.badgeArchived}`}>{t('mem.archived')}</span>}\n {row.taskTitle && <span className={css.badge}>@{row.taskTitle}</span>}\n {row.members !== undefined && row.members > 0 && <span className={css.badge}>×{row.members}</span>}\n {row.confidence != null && <span className={css.badge}>{Math.round(row.confidence * 100)}%</span>}\n {row.trigger && row.trigger.keywords.length > 0 && <span className={css.badge}>⚡{row.trigger.keywords.slice(0, 2).join(',')}</span>}\n </span>\n </div>\n {row.body && row.body !== row.title && <div className={css.memBody}>{String(row.body).slice(0, 160)}</div>}\n <div className={css.memActs}>\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => startEdit(row)}>{t('mem.edit')}</Button>\n {scope === 'task' && !row.archived && (\n <>\n {row.draft && <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('confirm', row.id)}>{t('mem.confirm')}</Button>}\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('promote', row.id)}>{t('mem.promote')}</Button>\n </>\n )}\n {scope === 'project' && (\n <>\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('promote', row.id)}>{t('mem.promote')}</Button>\n <Button variant=\"outline\" size=\"sm\" disabled={busy || !canDemoteToTask} title={showHints && !canDemoteToTask ? t('mem.needs-bound') : undefined} onClick={() => void act('demote', row.id)}>{t('mem.demote')}</Button>\n </>\n )}\n {scope === 'global' && (\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('demote', row.id)}>{t('mem.demote')}</Button>\n )}\n {row.archived\n ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('restore', row.id)}>{t('mem.restore')}</Button>\n : <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('archive', row.id)}>{t('mem.archive')}</Button>}\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('delete', row.id)}>{t('mem.delete')}</Button>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n","/**\n * 会话列表快照 → 当前会话 id(宿主版本兼容层)。\n *\n * 快照结构被宿主改过一次,旧写法只认第一种:\n * - dsh ≤0.1.6:`{ current?: id, items: [{ sessionId, blank }] }`\n * - dsh 0.1.7+:`{ ids: id[], byId: Record<id, SessionSummary>, phase, projectionsBySession }`\n * —— `current` 与 `items` **都不存在了**。\n *\n * 后果一(永远 null):0.1.7 上 `snap.current` 和 `snap.items` 都是 undefined → 旧代码永远\n * 返回 null → 面板显示「还没有会话」、记忆视图报 `同步失败: no session / commands service`。\n * 而**任务视图渲染的是 task-data-store 里的缓存快照**,看起来还正常,所以这个故障很容易被\n * 误读成\"数据格式/旧版本兼容\"问题。\n *\n * 后果二(不跟随切换):光\"取一个非 null 的 id\"不够 —— 兜底取的是宿主列表里第一个非 blank 的\n * 会话,它**不随用户切换对话而变化**,面板会一直停在同一个会话(从而显示错项目的任务)。\n * 0.1.7 判断\"当前会话\"的正式依据是 `SessionSummary.retainedBy.mainView > 0`:\n * 主视图正在 retain 的那个就是用户正在看的那个(第一方同款判据,见 ui-layout/DocumentTitle.tsx\n * 与 ui-session)。它就在**列表快照的 byId 行上**,而 retain 计数变化会 `list.set(...)` 重新发布\n * 快照(session-controller/.../sessions/service.ts 的 publishRetention),所以订阅\n * `ctx.sessions.list` 的组件会在切换会话时自动重渲染 —— 这条必须走快照内字段,不能另开\n * `retainInfo()` 订阅,否则切换不会触发重渲染。\n *\n * 实测形状见 `packages/api/session-controller/src/client/sessions/service.ts` 的\n * `SessionListState` / `SessionSummary`。\n */\n\n/** 正数才算持有(retain 计数缺失/0/负数一律当没有)。 */\nfunction heldCount(value) {\n return typeof value === 'number' && value > 0 ? value : 0\n}\n\n/** 从一行 summary 抽出本模块关心的三个事实。 */\nfunction rowFacts(row) {\n return {\n blank: row?.blank === true,\n /** 主视图对这条会话的 retain 计数;> 0 即\"用户正在看它\"。 */\n mainView: heldCount(row?.retainedBy?.mainView),\n }\n}\n\n/**\n * 把两种快照形状统一成 `{ id, blank, mainView }` 列表,顺序保持宿主给的顺序。\n * @param {object|undefined|null} snap - `ctx.sessions.list.getSnapshot()`\n * @returns {Array<{id: string, blank: boolean, mainView: number}>} 认不出的形状返回空数组\n */\nexport function sessionRows(snap) {\n if (!snap || typeof snap !== 'object') return []\n // 旧形状:items 里每行自带 sessionId / blank / retainedBy\n if (Array.isArray(snap.items)) {\n return snap.items\n .map((row) => ({ id: row?.sessionId, ...rowFacts(row) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n const byId = snap.byId && typeof snap.byId === 'object' ? snap.byId : null\n // 0.1.7 形状:ids 表达宿主列表成员(顺序权威),行数据在 byId 里\n if (Array.isArray(snap.ids)) {\n return snap.ids\n .map((id) => ({ id, ...rowFacts(byId?.[id]) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n // 只有 byId 的半成品形状:仍然可用,只是丢了宿主顺序\n if (byId) {\n return Object.keys(byId)\n .map((id) => ({ id, ...rowFacts(byId[id]) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n return []\n}\n\n/**\n * 选出一个可用于执行命令的会话 id(即\"用户正在看的那个\")。\n *\n * 优先级:\n * 1. 旧形状的显式 `current`(≤0.1.6 的权威字段,保持原语义);\n * 2. `retainedBy.mainView > 0` 的会话(0.1.7 的权威判据,**跟随会话切换**);\n * 3. 第一个非 blank → 第一个(对两种形状都适用的兜底)。\n * @param {object|undefined|null} snap - `ctx.sessions.list.getSnapshot()`\n * @returns {string|null} 会话 id;拿不到返回 null(调用方据此显示「还没有会话」)\n */\nexport function pickSessionId(snap) {\n if (!snap || typeof snap !== 'object') return null\n if (typeof snap.current === 'string' && snap.current !== '') return snap.current\n const rows = sessionRows(snap)\n const live = rows.find((row) => row.mainView > 0)\n if (live) return live.id\n const chosen = rows.find((row) => !row.blank) ?? rows[0]\n return chosen ? chosen.id : null\n}\n","/**\n * Task Panel — dsh web `shell.overlay` 浮动任务面板。\n * Container 组件:负责数据获取、命令桥接、状态协调\n * Presentational 组件在 TaskComponents.tsx\n */\nimport { Component, useEffect, useRef, useState, type ReactNode } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\n// 图标走兼容层:0.1.5 用 IconXxx14/16,0.1.7+ 改成 IconXxxRegular + size prop\nimport {\n IconChevronDownOutline14,\n IconCloseOutline16,\n IconFolderOpenOutline16,\n IconQuestionOutline14,\n} from './icons.ts'\nimport { createTranslate, zh, en } from './locales.ts'\nimport { useTaskData, useTaskDataActions, taskDataStore, parseTaskPayloadText, type TaskStep } from './task-data-store.ts'\nimport { useTaskUI, useTaskUIActions } from './task-ui-store.ts'\nimport { MiniBar, TaskCard } from './TaskComponents.tsx'\nimport { MemoryView, type InsightScope } from './MemoryView.tsx'\nimport { pickSessionId } from './session-id.js'\nimport css from './TaskPanel.module.css'\n\nconst NS = 'dsh-project-memory'\n\nconst STATUS_CYCLE = ['pending', 'in_progress', 'completed'] as const\nconst VIEW_CYCLE = ['task', 'project', 'global'] as const\ntype PanelView = (typeof VIEW_CYCLE)[number]\n\nfunction getT(ctx: any) {\n const locale = ctx?.locale?.getSnapshot?.()?.active === 'zh' ? zh : en\n return createTranslate(locale)\n}\n\nfunction useSessionId(ctx: any): string | null {\n const [, force] = useState(0)\n useEffect(() => {\n const list = ctx?.sessions?.list\n if (!list || typeof list.subscribe !== 'function') return\n return list.subscribe(() => force((n) => n + 1))\n }, [ctx])\n // 快照结构在 dsh 0.1.7 变过(current/items → ids/byId):解析与兼容都在 session-id.js,\n // 那里有单测;这里只负责订阅与取值。\n return pickSessionId(ctx?.sessions?.list?.getSnapshot?.())\n}\n\nclass PanelErrorBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false }\n static getDerivedStateFromError() { return { failed: true } }\n componentDidCatch(error: unknown) {\n console.warn('[dsh-project-memory] task panel render crashed:', error)\n }\n render() {\n if (!this.state.failed) return this.props.children\n return (\n <button className={css.boundaryFallback} onClick={() => this.setState({ failed: false })} title=\"重新渲染任务面板\">\n 任务面板(点击重试)\n </button>\n )\n }\n}\n\nexport function TaskPanelEntry({ ctx }: { ctx: any }) {\n return (\n <PanelErrorBoundary>\n <TaskPanelView ctx={ctx} />\n </PanelErrorBoundary>\n )\n}\n\nfunction TaskPanelView({ ctx }: { ctx: any }) {\n const t = getT(ctx)\n const data = useTaskData()\n const ui = useTaskUI()\n const sessionId = useSessionId(ctx)\n const [syncing, setSyncing] = useState(false)\n const [syncedAt, setSyncedAt] = useState(0)\n const [syncError, setSyncError] = useState<string | null>(null)\n // 提示信息开关落在 UI store(持久化):关掉后面板内所有悬停 title 气泡都不再弹出。\n const showHints = ui.showHints\n const [view, setView] = useState<PanelView>('task')\n const cycleView = () => {\n const i = VIEW_CYCLE.indexOf(view)\n setView(VIEW_CYCLE[(i + 1) % VIEW_CYCLE.length])\n }\n const viewTitle =\n view === 'task' ? t('panel.title')\n : view === 'global' ? t('view.global')\n : t('view.project')\n\n const dataActions = useTaskDataActions()\n const uiActions = useTaskUIActions()\n\n const tasks = Array.isArray(data.tasks) ? data.tasks : []\n const activeTasks = tasks.filter((task) => !task.archived)\n const boundTask = data.boundTaskId ? tasks.find((task) => task.id === data.boundTaskId) ?? null : null\n\n const applyPayload = (text?: string): boolean => {\n const parsed = parseTaskPayloadText(text)\n if (!parsed) return false\n dataActions.setTasks({ tasks: parsed.tasks, boundTaskId: parsed.boundId, archivedCount: parsed.archived })\n setSyncedAt(Date.now())\n setSyncError(null)\n return true\n }\n\n const runLine = async (line: string): Promise<boolean> => {\n const commands = ctx?.remote?.commands\n if (!sessionId || !commands || typeof commands.execute !== 'function') {\n setSyncError('no session / commands service')\n return false\n }\n let response: any\n try {\n response = await commands.execute(sessionId, line, [])\n } catch (err) {\n setSyncError(String((err as { message?: unknown } | null | undefined)?.message ?? err))\n return false\n }\n const envelope = response as { ok?: boolean; value?: any } | null | undefined\n const execution = envelope && typeof envelope === 'object' && 'value' in envelope ? envelope.value : envelope\n const result = execution?.result ?? execution\n if (result?.kind === 'error') {\n setSyncError(result.text ?? 'command error')\n return false\n }\n return applyPayload(result?.text)\n }\n\n const refresh = async (): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n const prevBoundId = data.boundTaskId\n await runLine('/tasks')\n const newBoundId = taskDataStore.getSnapshot().boundTaskId\n if (newBoundId && newBoundId !== prevBoundId) {\n await runLine(`/tasks switch ${newBoundId}`)\n }\n } finally {\n setSyncing(false)\n }\n }\n\n const handleAction = async (verb: 'switch' | 'archive', taskId: string): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n await runLine(`/tasks ${verb} ${taskId}`)\n } finally {\n setSyncing(false)\n }\n }\n\n // v0.5:任务卡内联记忆动作(confirm/promote/delete 于 /insight task 层),随后刷新任务数据\n const handleInsightTask = async (action: 'confirm' | 'promote' | 'delete', id: string): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n await runLine(`/tasks insight ${action} task ${id}`)\n await refresh()\n } finally {\n setSyncing(false)\n }\n }\n\n const pushSteps = (taskId: string, steps: TaskStep[]): void => {\n void runLine(`/tasks todos ${JSON.stringify(steps.map((s) => ({ content: s.content, status: s.status })))}`)\n }\n\n const cycleStatus = (taskId: string, index: number) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n if (!task) return\n const steps = task.steps || []\n const next = steps.map((s, i) => {\n if (i !== index) return s\n const cur = STATUS_CYCLE.indexOf(s.status)\n return { ...s, status: STATUS_CYCLE[(cur + 1) % STATUS_CYCLE.length] }\n })\n pushSteps(taskId, next)\n }\n\n const commitStepText = (taskId: string, index: number, value: string) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n const trimmed = value.trim()\n if (!task) return\n const same = (task.steps || [])[index]?.content === trimmed\n if (same || !trimmed) return\n const next = (task.steps || []).map((s, i) => (i === index ? { ...s, content: trimmed } : s))\n pushSteps(taskId, next)\n }\n\n const reorderSteps = (taskId: string, fromIndex: number, toIndex: number) => {\n if (fromIndex === toIndex) return\n const task = data.tasks.find((tt) => tt.id === taskId)\n if (!task) return\n const steps = [...(task.steps || [])]\n const [moved] = steps.splice(fromIndex, 1)\n const targetIndex = toIndex > fromIndex ? toIndex - 1 : toIndex\n steps.splice(targetIndex, 0, moved)\n pushSteps(taskId, steps)\n }\n\n const commitTitle = (taskId: string, value: string) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n const trimmed = value.trim()\n if (!task) return\n const same = task.title === trimmed\n if (same || !trimmed) return\n void runLine(`/tasks rename ${taskId} ${JSON.stringify(trimmed)}`)\n }\n\n const expand = () => {\n uiActions.open()\n if (Date.now() - Math.max(data.lastUpdate, syncedAt) > 30_000) {\n void refresh()\n }\n }\n\n const THEMES = ['native', 'glass', 'brutal', 'mono'] as const\n const style = (THEMES as readonly string[]).includes(ui.theme) ? ui.theme : 'native'\n const styleLabel = t(`style.${style}` as keyof typeof zh)\n const cycleTheme = () => {\n const i = THEMES.indexOf(style as (typeof THEMES)[number])\n uiActions.setTheme(THEMES[(i + 1) % THEMES.length])\n }\n\n const panelRef = useRef<HTMLDivElement>(null)\n const drag = useRef<{ dx: number; dy: number } | null>(null)\n\n const handleDragStart = (e: React.MouseEvent) => {\n if (e.target !== e.currentTarget) return\n const rect = panelRef.current?.getBoundingClientRect()\n if (!rect) return\n drag.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top }\n const onMove = (ev: MouseEvent) => {\n if (!drag.current) return\n const width = panelRef.current?.offsetWidth ?? 380\n const height = panelRef.current?.offsetHeight ?? 480\n const x = Math.max(8, Math.min(window.innerWidth - width - 8, ev.clientX - drag.current.dx))\n const y = Math.max(8, Math.min(window.innerHeight - 64, ev.clientY - drag.current.dy))\n uiActions.setPanelPosition({ x, y })\n }\n const onUp = () => {\n drag.current = null\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n }\n\n // 会话切换时仅同步数据,不自动打开面板\n useEffect(() => {\n if (!sessionId) return\n // 仅当面板已打开时才自动刷新\n if (!ui.closed) {\n void refresh()\n }\n }, [sessionId])\n\n // 监听模型工具请求打开面板\n useEffect(() => {\n const ctxWithEvents = ctx\n const handler = () => {\n uiActions.open()\n if (Date.now() - Math.max(data.lastUpdate, syncedAt) > 30_000) {\n void refresh()\n }\n }\n ctxWithEvents?.events?.on?.('dsh:task-panel:show', handler)\n return () => {\n ctxWithEvents?.events?.off?.('dsh:task-panel:show', handler)\n }\n }, [ctx, uiActions, data.lastUpdate, syncedAt, refresh])\n\n // 彻底隐藏:不渲染任何东西\n if (ui.closed) {\n return null\n }\n\n // 折叠态:迷你条\n if (ui.minimized) {\n const label = boundTask\n ? `${t('minibar.current')}: ${boundTask.title}`\n : activeTasks.length > 0\n ? `${t('minibar.current')}: ${activeTasks.length} ${t('minibar.tasks')}`\n : t('minibar.no-task')\n return (\n <MiniBar\n label={label}\n hint={t('minibar.click-expand')}\n showHints={showHints}\n position={ui.panelPosition}\n theme={style}\n onMove={uiActions.setPanelPosition}\n open={expand}\n />\n )\n }\n\n const doneCount = activeTasks.filter((task) => {\n const steps = task.steps || []\n return steps.length > 0 && steps.every((s) => s.status === 'completed')\n }).length\n\n return (\n <div\n className={css.panel}\n ref={panelRef}\n style={{ left: ui.panelPosition.x, top: ui.panelPosition.y }}\n data-theme={style === 'native' ? undefined : style}\n >\n <div className={css.dragHandle} onMouseDown={handleDragStart} title={showHints ? t('task.drag') : undefined}>\n <div className={css.handleGrip} />\n </div>\n <header className={css.header}>\n <div className={css.headerLeft}>\n <Button\n type=\"button\"\n className={css.headerIconBtn}\n onClick={cycleTheme}\n title={showHints ? styleLabel : undefined}\n aria-label={styleLabel}\n >\n <IconFolderOpenOutline16 className={css.headerIcon} />\n </Button>\n <h2 className={css.headerTitle}>{viewTitle}</h2>\n </div>\n <div className={css.headerRight}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={cycleView}\n aria-label={t('view.cycle')}\n title={showHints ? `${t('view.cycle')}(${view} → ${VIEW_CYCLE[(VIEW_CYCLE.indexOf(view) + 1) % VIEW_CYCLE.length]})` : undefined}\n >\n {/* lucide notebook-tabs(视图循环图标) */}\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M2 6h4\" />\n <path d=\"M2 10h4\" />\n <path d=\"M2 14h4\" />\n <path d=\"M2 18h4\" />\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <path d=\"M15 2v20\" />\n <path d=\"M15 7h5\" />\n <path d=\"M15 12h5\" />\n <path d=\"M15 17h5\" />\n </svg>\n </Button>\n {view === 'task' && (\n <span className={css.counts}>\n {activeTasks.length > 0\n ? `${t('panel.active')} ${activeTasks.length} · ${doneCount}/${activeTasks.length}`\n : ''}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={showHints ? undefined : css.hintsOff}\n onClick={() => uiActions.toggleHints()}\n aria-pressed={!showHints}\n aria-label={showHints ? t('panel.hints-off') : t('panel.hints-on')}\n title={showHints ? t('panel.hints-off') : t('panel.hints-on')}\n >\n <IconQuestionOutline14 size={16} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => uiActions.minimize()}\n aria-label={t('panel.minimize')}\n title={showHints ? t('panel.minimize') : undefined}\n >\n <IconChevronDownOutline14 />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => uiActions.close()}\n aria-label={t('panel.close')}\n title={showHints ? t('panel.close') : undefined}\n >\n <IconCloseOutline16 />\n </Button>\n </div>\n </header>\n\n {!sessionId && <div className={css.notice}>{t('panel.no-session')}</div>}\n {syncError && <div className={css.notice}>{t('panel.sync-failed')}: {syncError}</div>}\n\n {view !== 'task' ? (\n <MemoryView ctx={ctx} sessionId={sessionId} scope={view as InsightScope} boundTaskId={data.boundTaskId} showHints={showHints} t={t} />\n ) : activeTasks.length === 0 ? (\n <div className={css.emptyState}>\n <p className={css.emptyTitle}>{t('panel.empty')}</p>\n <p className={css.emptyDesc}>{t('panel.empty-desc')}</p>\n {syncing && <p className={css.syncHint}>{t('panel.syncing')}</p>}\n </div>\n ) : (\n <div className={css.taskList}>\n {activeTasks.map((task) => {\n const steps = task.steps || []\n const expanded = ui.expandedTaskIds.includes(task.id)\n const isBound = data.boundTaskId === task.id\n return (\n <TaskCard\n key={task.id}\n task={task}\n isBound={isBound}\n expanded={expanded}\n onToggleExpand={() => uiActions.toggleTaskExpanded(task.id)}\n onSwitch={() => handleAction('switch', task.id)}\n onUnbind={() => runLine('/tasks unbind')}\n onArchive={() => handleAction('archive', task.id)}\n onRename={(value) => commitTitle(task.id, value)}\n onEditStep={(index, value) => commitStepText(task.id, index, value)}\n onCycleStatus={(index) => cycleStatus(task.id, index)}\n onReorderSteps={(from, to) => reorderSteps(task.id, from, to)}\n onInsightAction={(action, id) => void handleInsightTask(action, id)}\n showHints={showHints}\n syncing={syncing}\n t={t}\n />\n )\n })}\n {syncing && <div className={css.syncHint}>{t('panel.syncing')}</div>}\n </div>\n )}\n </div>\n )\n}","/**\n * /tasks、/task、/insight 命令在会话中的节点渲染器(conversation.chat.commandview,按命令名 key)。\n * 列表型命令(/tasks、无动词 /task、/insight list)只显示一行摘要;/insight 的动作类只显示一句结果——\n * 目的:大 JSON 载荷绝不整段渲染进对话(否则切视图会刷屏)。\n */\nimport { useEffect, useRef } from 'react'\nimport { IconFolderOpenOutline16 } from './icons.ts'\nimport { parseTaskPayloadText, taskDataStore } from './task-data-store.ts'\nimport { parseInsightPayloadText } from './MemoryView.tsx'\nimport { taskUIStore } from './task-ui-store.ts'\nimport css from './TaskCommandNode.module.css'\n\nexport function TaskCommandNode({ node }: { node?: any }) {\n const name = node?.name ?? 'task'\n const outcome = node?.outcome ?? null\n const args = typeof node?.args === 'string' ? node.args : ''\n const verb = args.trim().split(/\\s+/)[0] ?? ''\n const isList = name === 'tasks' || !verb\n const text = outcome?.text ?? ''\n\n const parsedTasks = name !== 'insight' ? parseTaskPayloadText(text) : null\n const parsedInsights = name === 'insight' ? parseInsightPayloadText(text) : null\n\n // 该节点是否“现场执行”(挂载时处于执行中):为 true 说明是用户当场输入的命令,\n // 完成后同步数据并打开面板。刷新/切换会话后历史节点以完成态重挂载,\n // 此时只做展示、不再写数据/开面板(面板保持关闭,与“刷新后不显示”一致)。\n const live = useRef(outcome === null)\n\n // 载荷进数据 store;列表型任务命令(/tasks、无动词 /task)同步数据并打开面板\n useEffect(() => {\n if (!parsedTasks || !live.current) return\n taskDataStore.actions.setTasks({\n tasks: parsedTasks.tasks,\n boundTaskId: parsedTasks.boundId,\n archivedCount: parsedTasks.archived,\n })\n if (isList) taskUIStore.actions.open()\n }, [text])\n\n if (outcome === null) {\n return <div className={css.row} data-variant=\"running\">/{name} 执行中…</div>\n }\n\n if (outcome.kind === 'error') {\n const brief = String(text ?? '').split('\\n')[0].slice(0, 120)\n return <div className={css.row} data-variant=\"error\">/{name} 失败{brief ? `:${brief}` : ''}</div>\n }\n\n // /insight:列表只显示一行摘要,动作类只显示一句结果(永不整段渲染)\n if (name === 'insight') {\n if (verb === 'list' && parsedInsights) {\n const scope = parsedInsights.scope\n const count = parsedInsights.count ?? parsedInsights.items.length\n return (\n <div className={css.row} data-variant=\"ok\">\n <IconFolderOpenOutline16 className={css.icon} />\n <span>记忆 {scope} · {count} 条 · 已同步到记忆视图</span>\n </div>\n )\n }\n const note = String(text ?? '').split('\\n')[0].slice(0, 120)\n return <div className={css.row} data-variant=\"ok\">/insight {verb} {note || '已完成'}</div>\n }\n\n if (!isList) {\n const note = String(text ?? '')\n .split(/\\n{2,}/)[0]\n .replace(/```.*$/s, '')\n .trim()\n .slice(0, 200)\n return <div className={css.row} data-variant=\"ok\">/{name} {note || '已完成'}</div>\n }\n\n const count = parsedTasks ? parsedTasks.tasks.length : 0\n const archived = parsedTasks ? parsedTasks.archived : 0\n const label = parsedTasks\n ? `任务 ${count} 套${archived ? `(归档 ${archived})` : ''} · 已同步到任务面板`\n : `/${name} 已执行`\n return (\n <div className={css.row} data-variant=\"ok\">\n <IconFolderOpenOutline16 className={css.icon} />\n <span>{label}</span>\n </div>\n )\n}","/**\n * 自建 `/` 触发器源:把工作流的三个视图入口收进一个带图标和小节标题的「工作流」组。\n *\n * 为什么必须自建源:`/` 菜单里的「分组」就是触发器源(ui-input-trigger 的 roster),\n * 而宿主 ui-commands 给目录行装配外观时只认第一方 definitionId 白名单\n * (presentation.ts 的 HOST_FACES / SECTION_ROWS),且宿主 CommandDescriptor 只有\n * name/description/input —— 没有 icon、没有分组、没有隐藏开关。第三方宿主命令因此\n * 永远只是「指令」小节末尾一行纯文字。\n *\n * 两个宿主约束决定了这里的写法:\n * 1. **分组标题走候选的 `section`,不走 `slash.menu` 词典。** 组标题查的是 `slash.menu`\n * namespace,而它由 ui-input-trigger 独占:`register('slash.menu','zh')` 会抛\n * \"already has locale\",未知 key 则原样回显源名。MenuView 在「组内任一行带 section」时\n * 干脆不渲染组标题行,只渲染 section 标题 —— 于是标题文案回到我们手里,还能按语言切换。\n * 2. **只做增量,不抢宿主的分发。** 这里不实现 matchSpace / matchEnter,所以手敲 `/tasks`、\n * 面板调 remote.commands.execute 全部走宿主原有路径。本源只是往菜单里多添一组行。\n *\n * 与「指令」组的重复:合并前插件注册了 /tasks、/task、/insight 三条宿主命令,菜单里就是三行\n * 去不掉的原始行 —— 宿主命令只要注册就会出现在目录里,`commands.list()` 与\n * `commands.execute()` 读同一个视图,`CommandDefinition` 也没有 hidden 字段,插件无法隐藏。\n * 现在宿主只剩一条 /tasks(见 src/commands/workflow.js),重复降到一行;那一行也是插件\n * 执行宿主侧工作的唯一通道(插件没有自己的 client→host RPC)。\n */\nimport type { ComponentType } from 'react'\nimport { createTranslate, en, zh } from './locales.ts'\nimport { IconChecklistOutline16, IconGlobeOutline16, IconLightOutline16 } from './icons.ts'\n\n/** 源的稳定标识:同一 trigger 内唯一,重复注册会抛错。 */\nexport const SLASH_SOURCE_NAME = 'project-memory'\n\n/**\n * 组的排序权重(越小越靠前,未设时默认 0)。\n * 宿主内置源都取默认 0,所以 1 = 一定排在「指令 / 技能 / 子智能体」之后。\n * 没有能同时满足「在宿主之后」与「在所有其他插件之前」的取值:其他插件若也留默认 0\n * 就会排在我们前面。1 是最接近的折中,且不会去抢宿主主位置。\n */\nexport const SLASH_SOURCE_ORDER = 1\n\n/** 一行候选:候选 name 与标题同源(本地化文本),名称即身份、即标题。 */\ninterface SlashRow {\n /** 词典 key:既作候选 name(组内唯一身份)也作行标题。 */\n readonly labelKey: string\n /** 行描述词典 key。 */\n readonly descriptionKey: string\n /** 行图标;图标名按宿主版本自适应,见 icons.ts。 */\n readonly icon: ComponentType<{ size?: number; className?: string }>\n /** 额外搜索词:候选 name 是中文,拉丁输入(task / memory…)靠这些命中。 */\n readonly match: readonly string[]\n /** 点击后经 remote.commands.execute 执行的完整命令行。 */\n readonly line: string\n}\n\n/** 菜单三行。顺序即渲染顺序;标题复用面板已有的 view.* 文案,保证与面板视图名一致。 */\nconst ROWS: readonly SlashRow[] = [\n {\n labelKey: 'view.task',\n descriptionKey: 'slash.tasks-desc',\n icon: IconChecklistOutline16,\n match: ['tasks', 'task'],\n line: '/tasks',\n },\n {\n labelKey: 'view.project',\n descriptionKey: 'slash.project-desc',\n icon: IconLightOutline16,\n match: ['memory', 'project', 'insight'],\n line: '/tasks insight list project',\n },\n {\n labelKey: 'view.global',\n descriptionKey: 'slash.global-desc',\n icon: IconGlobeOutline16,\n match: ['memory', 'global', 'insight'],\n line: '/tasks insight list global',\n },\n]\n\n/** 本插件的 client 上下文投影:只看得到这几个能力,避免把整个 cordis ctx 传进来。 */\nexport interface SlashSourceDeps {\n /** 会话服务(`sessions`):把 sessionId 换回会话 scope,用于消费触发 token。 */\n readonly sessions: any\n /** 执行一条完整命令行;返回 composer 认得的 SubmitOutcome 形状。 */\n run(session: any, line: string, attachments?: readonly unknown[]): Promise<{ kind: 'success' | 'error'; text?: string }>\n}\n\n/** 翻译函数签名(key 来自 ROWS,不是字面量,故不做类型约束)。 */\ntype Translate = (key: string, params?: Record<string, string | number>) => string\n\n/** 按当前语言取翻译函数。 */\nfunction translator(ctx: any): Translate {\n const dict = ctx?.locale?.getSnapshot?.()?.active === 'zh' ? zh : en\n return createTranslate(dict) as unknown as Translate\n}\n\n/**\n * 一轮候选:把三行装配成菜单行,再按查询与位置过滤。\n *\n * 三行都不接参数(动作全在面板卡片里),所以位置过滤只做一件事:行内出现的 `/` 多半是路径,\n * 不弹这一整组(宿主对无 input 命令在前导/行内都放行,这里更保守)。\n * @param t - 翻译函数。\n * @param req - 宿主给的候选请求(query / position)。\n * @returns 菜单行;永不抛出。\n */\nexport function buildSlashCandidates(t: Translate, req: any): readonly Record<string, unknown>[] {\n if (req?.position !== undefined && req.position !== 'leading') return []\n const query = typeof req?.query === 'string' ? req.query.trim().toLowerCase() : ''\n const rows = ROWS.map((row) => {\n const title = t(row.labelKey)\n return {\n name: title,\n // label 与 name 相同 → MenuView 不渲染尾随别名(这些是视图入口,不是命令名)\n label: title,\n description: t(row.descriptionKey),\n icon: row.icon,\n // 每一行都带 section → MenuView 不渲染组标题行,只渲染这个标题。\n section: t('slash.group'),\n line: row.line,\n terms: [title, ...row.match].map((term) => term.toLowerCase()),\n }\n })\n return rows\n .filter((row) => query === '' || row.terms.some((term) => term.startsWith(query)))\n .map(({ terms: _terms, ...candidate }) => candidate)\n}\n\n/**\n * 把触发 token 从草稿里删掉(span 做 CAS:草稿被改过就拒绝,什么都不动)。\n * 这是宿主 command 源消费菜单点击的同一条契约事件。\n * @returns true 表示确实消费掉了。\n */\nfunction consumeSpan(deps: SlashSourceDeps, pick: any): boolean {\n try {\n const scope = deps.sessions?.scope?.(pick?.session?.sessionId)\n if (!scope || typeof scope.bail !== 'function') return false\n return scope.bail(scope, 'slash/input-consume-token', {\n guard: { kind: 'span', span: pick.span },\n }) === true\n } catch (err) {\n console.warn('[dsh-project-memory] slash token consume failed:', err)\n return false\n }\n}\n\n/**\n * 一次菜单点击:消费掉触发 token 后立刻执行该行对应的命令行。\n *\n * 不返回 claim(回填 `/xxx ` 再等回车):这三行都是「打开某个视图」,claim 会多要一次回车,\n * 而且子动词(`insight list project`)也没法由一个 claim token 表达。消费失败时仍然执行,\n * 只是草稿里残留的触发文本要用户自己清掉 —— 比回填一个会执行错命令的 claim 安全。\n * @param t - 翻译函数(按当前语言把候选 name 映射回 ROWS)。\n * @param deps - 会话服务与命令执行通道。\n * @param pick - 宿主给的点击载荷。\n * @returns PickOutcome;拿不到可用形状时返回 undefined(菜单照常关闭,草稿不动)。\n */\nexport function dispatchSlashPick(t: Translate, deps: SlashSourceDeps, pick: any): unknown {\n const title = pick?.candidate?.name\n if (typeof title !== 'string' || title === '') return undefined\n const row = ROWS.find((candidate) => t(candidate.labelKey) === title)\n if (row === undefined) return undefined\n consumeSpan(deps, pick)\n void deps.run(pick.session, row.line, []).catch((err: unknown) => {\n console.warn(`[dsh-project-memory] ${row.line} failed:`, err)\n })\n return 'handled'\n}\n\n/**\n * 造出注册给 `ctx.inputTriggers.registerSource` 的源对象。\n * @param ctx - client 根上下文(只读 locale)。\n * @param deps - 会话服务与命令执行通道。\n * @returns 触发器源;只依赖宿主的公开契约字段。\n */\nexport function createSlashSource(ctx: any, deps: SlashSourceDeps): Record<string, unknown> {\n const t = translator(ctx)\n return {\n trigger: '/',\n name: SLASH_SOURCE_NAME,\n order: SLASH_SOURCE_ORDER,\n // 组标题不渲染:行上都有 section,MenuView 会用 section 标题取代它。\n showGroupTitle: false,\n candidates: async (_session: unknown, req: any) => buildSlashCandidates(t, req),\n onPick: (pick: any) => dispatchSlashPick(t, deps, pick),\n }\n}\n","/**\n * dsh-project-memory Client Entry\n *\n * dsh web (rc.1) 的 client 插件契约为 cordis client plugin:\n * export const inject = [<client 服务名>...]\n * export function apply(ctx) { ... }\n * 面板注册进 `shell.overlay`(Frame 级浮动层,additive 列表槽):\n * 该槽由 ui-layout 的 AppFrame 声明渲染(scope root,独立于滚动容器),\n * 默认 click-through,条目自身需开启 pointer-events。\n *\n * 只依赖宿主 seed 提供的模块(react / dsh-client-ui-primitives),\n * 数据经 remote.commands.execute 执行 /tasks 命令获取 JSON 快照。\n *\n * 另有一个可选增强:自建的 `/` 菜单源(slash.ts),把三条命令收进一个带图标和\n * 小节标题的「工作流」组。它**整体是可选的**——宿主没有 slash 触发器服务时静默跳过。\n */\nimport { createElement } from 'react'\nimport { TaskPanelEntry } from './TaskPanel.tsx'\nimport { TaskCommandNode } from './TaskCommandNode.tsx'\nimport { createSlashSource } from './slash.ts'\n\nconst NS = 'dsh-project-memory'\n\nexport const name = NS\n\n/** Required client services: slots registry, session scopes, commands remote (data 通道). */\nexport const inject = ['slots', 'sessions', 'remote', 'remote.commands', 'locale']\n\n/**\n * 执行一条命令行,映射成 composer 的 SubmitOutcome。\n * 与 TaskPanel 走同一个 remote.commands.execute 通道(同样的返回信封)。\n * @param commands - ctx.remote.commands\n * @param session - 会话投影(只读 sessionId)\n * @param line - 完整命令行(含前导斜杠)\n * @param attachments - 提交附件(菜单路径恒为空)\n * @returns {kind:'success'|'error', text?}\n */\nasync function runCommand(\n commands: any,\n session: any,\n line: string,\n attachments: readonly unknown[] = [],\n): Promise<{ kind: 'success' | 'error'; text?: string }> {\n const sessionId = session?.sessionId\n if (typeof sessionId !== 'string' || !commands || typeof commands.execute !== 'function') {\n return { kind: 'error', text: `no session / commands service for ${line}` }\n }\n const response: any = await commands.execute(sessionId, line, [...attachments])\n const envelope = response as { ok?: boolean; error?: any; value?: any } | null | undefined\n if (envelope && typeof envelope === 'object' && envelope.ok === false) {\n return { kind: 'error', text: `command.execute failed: ${envelope.error?.code ?? 'unknown'}` }\n }\n const execution = envelope && typeof envelope === 'object' && 'value' in envelope ? envelope.value : envelope\n const result = execution?.result ?? execution\n if (result?.kind === 'error') return { kind: 'error', text: result.text ?? `${line} failed` }\n return { kind: 'success' }\n}\n\n/**\n * 注册自建的 `/` 菜单源(见 slash.ts)。\n *\n * 整段都是**可选增强**:宿主没有 `inputTriggers` 服务、或该服务换了契约时,绝不能因此\n * 让整个 client 插件挂掉——那会连任务面板一起消失。`inputTriggers` 因此不进顶层 `inject`\n * (顶层 inject 未满足时 cordis 根本不会调用 apply),而是走嵌套 inject + 两层 try/catch。\n * @param ctx - client 根上下文\n */\nfunction registerSlashSource(ctx: any): void {\n if (typeof ctx?.inject !== 'function') {\n console.warn(`[${NS}] host has no ctx.inject — slash menu group disabled`)\n return\n }\n try {\n ctx.inject(['inputTriggers', 'sessions', 'remote.commands'], (scope: any) => {\n try {\n const inputTriggers = scope?.inputTriggers\n if (!inputTriggers || typeof inputTriggers.registerSource !== 'function') {\n console.warn(`[${NS}] host has no inputTriggers.registerSource — slash menu group disabled`)\n return\n }\n const source = createSlashSource(scope, {\n sessions: scope.sessions,\n run: (session, line, attachments) => runCommand(scope?.remote?.commands, session, line, attachments),\n })\n scope.effect(() => inputTriggers.registerSource(source), 'dsh-project-memory: slash source')\n } catch (err) {\n console.warn(`[${NS}] slash source registration failed:`, err)\n }\n })\n } catch (err) {\n console.warn(`[${NS}] slash source injection failed:`, err)\n }\n}\n\nexport function apply(ctx: any): void {\n const slots = ctx?.slots\n if (!slots || typeof slots.inject !== 'function') {\n console.warn(`[${NS}] host has no slots service — task panel disabled`)\n } else {\n try {\n slots.inject('shell.overlay', () => slots.register(\n {\n name: 'shell.overlay',\n id: 'dsh-project-memory-task-panel',\n order: 100, // 浮层顺序:低于 toast/弹窗即可,越高越靠后渲染\n },\n () => createElement(TaskPanelEntry, { ctx })\n ))\n\n // 会话内命令节点:按命令名 key 接管渲染,替换内置大段文本卡片\n // (文本含 JSON 载荷,只有面板需要它),避免载荷刷屏对话。\n // 合并后只剩一条用户命令 /tasks(子动词都记在同一个命令名下)。\n const nodeKeys = ['tasks']\n for (const key of nodeKeys) {\n slots.inject('conversation.chat.commandview', () => slots.register(\n { name: 'conversation.chat.commandview', key },\n TaskCommandNode\n ))\n }\n } catch (err) {\n console.warn(`[${NS}] task panel registration failed:`, err)\n }\n }\n\n registerSlashSource(ctx)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["primitives","createElement","useSyncExternalStore","useSyncExternalStore","useState","useRef","useCallback","css","useRef","useState","Button","useState","useCallback","useRef","css","Button","useState","Component","css","useRef","Button","useRef","css","useRef","createElement"],"sources":["../src/client/icons.ts","../src/client/locales.ts","../src/client/task-data-store.ts","../src/client/task-ui-store.ts","../src/client/task-hooks.ts","../src/client/TaskComponents.tsx","../src/client/MemoryView.tsx","../src/client/session-id.js","../src/client/TaskPanel.tsx","../src/client/TaskCommandNode.tsx","../src/client/ShowTaskPanelNode.tsx","../src/client/slash.ts","../src/client/client.ts"],"sourcesContent":["/**\n * 宿主图标兼容层(dsh 0.1.5 ↔ 0.1.7+)。\n *\n * 命名契约变过一次:\n * - dsh 0.1.5(含 0.1.5-rc.x):尺寸写进名字,如 `IconFolderOpenOutline16`;\n * - dsh 0.1.7+:去掉尺寸后缀、改为字重后缀,如 `IconFolderOpenOutlineRegular` /\n * `IconFolderOpenOutlineMedium`,尺寸改由 `size` prop 传入。\n * ui-primitives 是 web shell 的冻结 seed 模块(不是插件行),插件无法固定它,\n * 同一份产物会拿到宿主那一版的导出;直接按某一版的名字解构会在另一版上得到\n * `undefined`,React 渲染时抛 \"Element type is invalid\" 把面板整个打崩。\n *\n * 因此这里按旧名导出同名组件,运行时在两个名字里取存在的那个,并把旧名里的\n * 尺寸作为默认 `size`(两版的图标都接受 `size` prop,0.1.5 的默认值正是旧名后缀)。\n * 两版都没有该名字时降级为空组件并告警,而不是让面板崩溃。\n */\nimport { createElement, type ComponentType } from 'react'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\n\ntype IconProps = { size?: number; className?: string }\ntype IconComponent = ComponentType<IconProps>\n\nconst table = primitives as unknown as Record<string, unknown>\n\nfunction resolveIcon(names: readonly string[]): IconComponent | null {\n for (const name of names) {\n const candidate = table[name]\n if (typeof candidate === 'function' || (typeof candidate === 'object' && candidate !== null)) {\n return candidate as IconComponent\n }\n }\n return null\n}\n\nfunction icon(legacyName: string, currentName: string, defaultSize: number): IconComponent {\n const impl = resolveIcon([legacyName, currentName])\n if (impl === null) {\n console.warn(\n `[dsh-project-memory] host ui-primitives exports neither ${legacyName} nor ${currentName}; that icon renders nothing`,\n )\n return function MissingIcon() {\n return null\n }\n }\n function CompatIcon({ size = defaultSize, ...rest }: IconProps) {\n return createElement(impl as IconComponent, { size, ...rest })\n }\n CompatIcon.displayName = legacyName\n return CompatIcon\n}\n\nexport const IconChevronDownOutline14 = icon('IconChevronDownOutline14', 'IconChevronDownOutlineRegular', 14)\nexport const IconChevronUpOutline14 = icon('IconChevronUpOutline14', 'IconChevronUpOutlineRegular', 14)\nexport const IconQuestionOutline14 = icon('IconQuestionOutline14', 'IconQuestionOutlineRegular', 14)\nexport const IconCloseOutline16 = icon('IconCloseOutline16', 'IconCloseOutlineRegular', 16)\nexport const IconFolderOpenOutline16 = icon('IconFolderOpenOutline16', 'IconFolderOpenOutlineRegular', 16)\nexport const IconCheckOutline16 = icon('IconCheckOutline16', 'IconCheckOutlineRegular', 16)\nexport const IconPlayOutline16 = icon('IconPlayOutline16', 'IconPlayOutlineRegular', 16)\n\n// `/` 菜单行图标。旧名的尺寸后缀两版并不一致(有的是 14 有的是 16),\n// 所以这里的默认 size 只影响\"宿主两版都没有该名字\"的降级路径——正常路径由宿主自己决定。\nexport const IconChecklistOutline16 = icon('IconChecklistOutline14', 'IconChecklistOutlineRegular', 14)\nexport const IconLightOutline16 = icon('IconLightOutline16', 'IconLightOutlineRegular', 16)\nexport const IconGlobeOutline16 = icon('IconGlobeOutline14', 'IconGlobeOutlineRegular', 14)\n","/**\n * Locale dictionaries for Task Panel\n */\nexport const zh = {\n 'panel.title': '工作流任务',\n 'panel.active': '进行中',\n 'panel.total': '总计',\n 'panel.minimize': '收起为顶部迷你条',\n 'panel.close': '关闭面板(隐藏,/task 可唤起)',\n 'panel.refresh': '同步最新任务',\n 'panel.style': '切换面板风格',\n 'style.native': '原生',\n 'style.glass': '玻璃',\n 'style.brutal': '粗野',\n 'style.mono': '终端',\n 'panel.syncing': '同步中…',\n 'panel.sync-failed': '同步失败',\n 'panel.hints-on': '显示提示信息',\n 'panel.hints-off': '隐藏提示信息',\n 'drag.cancel': '取消拖拽',\n 'panel.empty': '暂无任务',\n 'panel.empty-desc': '让模型开始工作并维护 todo 清单后会自动建档',\n 'panel.no-session': '还没有会话',\n 'task.progress': '进度',\n 'task.steps': '步骤',\n 'task.files': '文件',\n 'task.current': '当前',\n 'task.title-edit': '双击修改标题',\n 'task.switch': '切换到此任务',\n 'task.unbind': '取消当前任务',\n 'task.archive': '归档',\n 'task.drag': '拖拽移动',\n 'step.completed': '已完成',\n 'step.in-progress': '进行中',\n 'step.pending': '待办',\n 'step.edit-hint': '双击编辑步骤文案;点击图标循环 待办/进行中/已完成',\n 'file.copy': '复制路径',\n 'file.copied': '已复制路径',\n 'minibar.current': '当前任务',\n 'minibar.click-expand': '点击展开并同步',\n 'minibar.tasks': '个任务',\n 'minibar.no-task': '暂无任务 · 点击查看',\n 'view.cycle': '切换视图:任务 / 项目记忆 / 全局记忆',\n 'view.task': '任务',\n 'view.project': '项目记忆',\n 'view.global': '全局记忆',\n 'mem.scope.task': '本任务草稿',\n 'mem.scope.project': '项目记忆',\n 'mem.scope.global': '全局记忆',\n 'mem.empty': '暂无记忆条目(反思或 save_lesson 后出现)',\n 'mem.confirm': '审核',\n 'mem.promote': '提升',\n 'mem.demote': '降级',\n 'mem.archive': '归档',\n 'mem.restore': '恢复',\n 'mem.delete': '删除',\n 'mem.draft': '草稿',\n 'mem.archived': '已归档',\n 'mem.loading': '加载中…',\n 'mem.error': '同步失败',\n 'mem.kind.lesson': '坑',\n 'mem.kind.decision': '权衡',\n 'mem.kind.procedure': '指南',\n 'mem.kind.experience': '经验',\n 'mem.needs-bound': '需绑定任务后可降级',\n 'mem.new': '新建',\n 'mem.save': '保存',\n 'mem.cancel': '取消',\n 'mem.f.title': '标题(教训模式/主题/指南名)',\n 'mem.f.kind': '类型',\n 'mem.f.body': '做法 / 理由 / 解法',\n 'mem.f.steps': '步骤(每行一步)',\n 'mem.f.trigger': '作为 Skill:触发关键词(逗号分隔)',\n 'mem.saved': '已保存',\n 'mem.edit': '编辑',\n 'mem.section-label': '任务记忆',\n // `/` 菜单:自建 slash 源的行文案。分组标题走候选的 section(见 slash.ts),\n // 不走 slash.menu 词典——那个 namespace 由宿主的 ui-input-trigger 独占,重复注册会抛错。\n // 三个行标题直接复用上面面板的 view.* 文案,保证菜单与面板叫同一个名字。\n 'slash.group': '工作流',\n 'slash.tasks-desc': '任务清单:步骤进度、涉及文件、当前会话绑定',\n 'slash.project-desc': '项目记忆:本项目的教训 / 决策 / 流程',\n 'slash.global-desc': '全局记忆:跨项目的经验条目',\n}\n\nexport const en = {\n 'panel.title': 'Task Flow',\n 'panel.active': 'Active',\n 'panel.total': 'Total',\n 'panel.minimize': 'Collapse to mini bar',\n 'panel.close': 'Close panel (hidden; /task reopens)',\n 'panel.refresh': 'Sync latest tasks',\n 'panel.style': 'Panel style',\n 'style.native': 'Native',\n 'style.glass': 'Glass',\n 'style.brutal': 'Brutal',\n 'style.mono': 'Mono',\n 'panel.syncing': 'Syncing…',\n 'panel.sync-failed': 'Sync failed',\n 'panel.hints-on': 'Show hints',\n 'panel.hints-off': 'Hide hints',\n 'drag.cancel': 'Cancel drag',\n 'panel.empty': 'No Tasks',\n 'panel.empty-desc': 'Tasks are created automatically when the model maintains a todo list',\n 'panel.no-session': 'No session yet',\n 'task.progress': 'Progress',\n 'task.steps': 'Steps',\n 'task.files': 'Files',\n 'task.current': 'Current',\n 'task.title-edit': 'Double-click to rename',\n 'task.switch': 'Switch to this task',\n 'task.unbind': 'Unbind current task',\n 'task.archive': 'Archive',\n 'task.drag': 'Drag to move',\n 'step.completed': 'Completed',\n 'step.in-progress': 'In Progress',\n 'step.pending': 'Pending',\n 'step.edit-hint': 'Double-click to edit; click the icon to cycle status',\n 'file.copy': 'Copy path',\n 'file.copied': 'Path copied',\n 'minibar.current': 'Current task',\n 'minibar.click-expand': 'Click to expand & sync',\n 'minibar.tasks': 'tasks',\n 'minibar.no-task': 'No tasks · click to view',\n 'view.cycle': 'Switch view: tasks / project memory / global memory',\n 'view.task': 'Tasks',\n 'view.project': 'Project Memory',\n 'view.global': 'Global Memory',\n 'mem.scope.task': 'Task drafts',\n 'mem.scope.project': 'Project memory',\n 'mem.scope.global': 'Global memory',\n 'mem.empty': 'No memory entries yet (created by reflection or save_lesson)',\n 'mem.confirm': 'Approve',\n 'mem.promote': 'Promote',\n 'mem.demote': 'Demote',\n 'mem.archive': 'Archive',\n 'mem.restore': 'Restore',\n 'mem.delete': 'Delete',\n 'mem.draft': 'draft',\n 'mem.archived': 'archived',\n 'mem.loading': 'Loading…',\n 'mem.error': 'Sync failed',\n 'mem.kind.lesson': 'lesson',\n 'mem.kind.decision': 'decision',\n 'mem.kind.procedure': 'procedure',\n 'mem.kind.experience': 'experience',\n 'mem.needs-bound': 'Bind a task to demote',\n 'mem.new': 'New',\n 'mem.save': 'Save',\n 'mem.cancel': 'Cancel',\n 'mem.f.title': 'Title (pattern / topic / procedure name)',\n 'mem.f.kind': 'Kind',\n 'mem.f.body': 'Fix / reason / solution',\n 'mem.f.steps': 'Steps (one per line)',\n 'mem.f.trigger': 'As Skill: trigger keywords (comma separated)',\n 'mem.saved': 'Saved',\n 'mem.edit': 'Edit',\n 'mem.section-label': 'Task memory',\n 'slash.group': 'Workflow',\n 'slash.tasks-desc': 'Task list: progress, involved files, current session binding',\n 'slash.project-desc': 'Project memory: this project’s lessons / decisions / procedures',\n 'slash.global-desc': 'Global memory: experience entries shared across projects',\n}\n\nexport type LocaleDict = typeof zh\n\nexport function createTranslate(dict: LocaleDict) {\n return (key: keyof LocaleDict, params?: Record<string, string | number>) => {\n let text = dict[key] ?? key\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n text = text.replace(new RegExp(`\\\\{${k}\\\\}`, 'g'), String(v))\n }\n }\n return text\n }\n}\n","/**\n * Task Data Store — 仅管服务端同步的数据(tasks、boundTaskId、archivedCount)\n * - 单向数据流:命令执行结果 → setTasks → 广播给其他标签页\n * - 无 UI 状态,无 localStorage,纯内存 + BroadcastChannel 同步\n */\nimport { useSyncExternalStore } from 'react'\n\nexport interface TaskStep {\n content: string\n status: 'pending' | 'in_progress' | 'completed'\n}\n\nexport interface TaskFile {\n path: string\n line?: number\n}\n\nexport interface TaskInsight {\n id: string\n kind: string\n title: string\n draft?: boolean\n}\n\nexport interface Task {\n id: string\n title: string\n steps: TaskStep[]\n files: TaskFile[]\n lastActiveAt: string\n updatedAt: string\n archived?: boolean\n insights?: TaskInsight[]\n}\n\nexport interface TaskPayload {\n tasks: Task[]\n boundId: string | null\n archived: number\n}\n\nexport function parseTaskPayloadText(text?: string | null): TaskPayload | null {\n if (!text) return null\n let jsonBlock: string | null = null\n const fenced = text.match(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/)\n if (fenced) jsonBlock = fenced[1]\n else {\n const lastBrace = text.lastIndexOf('{')\n if (lastBrace !== -1) jsonBlock = text.slice(lastBrace)\n }\n if (!jsonBlock) return null\n try {\n const data = JSON.parse(jsonBlock)\n if (!Array.isArray(data.tasks)) return null\n return { tasks: data.tasks, boundId: data.boundId ?? null, archived: data.archived ?? 0 }\n } catch {\n return null\n }\n}\n\ninterface TaskDataState {\n tasks: Task[]\n boundTaskId: string | null\n archivedCount: number\n lastUpdate: number\n}\n\nconst SYNC_CHANNEL = typeof window !== 'undefined' ? new BroadcastChannel('dsh-pm-tasks-data') : null\n\nlet dataState: TaskDataState = {\n tasks: [],\n boundTaskId: null,\n archivedCount: 0,\n lastUpdate: 0,\n}\n\nconst dataListeners = new Set<() => void>()\n\nfunction setDataState(next: TaskDataState | ((prev: TaskDataState) => TaskDataState)): void {\n // 兼容对象与函数式 updater(BroadcastChannel 曾误把 updater 当对象写入,\n // 导致 dataState 变成函数、tasks 丢失 → 面板崩溃)。写入一律归一化为完整 shape。\n const patch = typeof next === 'function' ? next(dataState) : next\n dataState = {\n tasks: Array.isArray(patch?.tasks) ? patch.tasks : [],\n boundTaskId: patch?.boundTaskId ?? null,\n archivedCount: typeof patch?.archivedCount === 'number' ? patch.archivedCount : 0,\n lastUpdate: typeof patch?.lastUpdate === 'number' ? patch.lastUpdate : 0,\n }\n for (const listener of dataListeners) listener()\n}\n\nfunction broadcastDataUpdate(tasks: Task[], archivedCount: number): void {\n if (!SYNC_CHANNEL) return\n SYNC_CHANNEL.postMessage({\n type: 'PROJECT_TASKS_UPDATED',\n payload: { tasks: Array.isArray(tasks) ? tasks : [], archivedCount },\n })\n}\n\nif (SYNC_CHANNEL) {\n SYNC_CHANNEL.onmessage = (event) => {\n const msg = event.data\n if (msg?.type === 'PROJECT_TASKS_UPDATED' && msg.payload) {\n const { tasks, archivedCount } = msg.payload\n setDataState(prev => ({\n ...prev,\n tasks: Array.isArray(tasks) ? tasks : [],\n archivedCount: typeof archivedCount === 'number' ? archivedCount : prev.archivedCount,\n lastUpdate: Date.now(),\n }))\n }\n }\n}\n\nexport const taskDataStore = {\n subscribe(listener: () => void): () => void {\n dataListeners.add(listener)\n return () => { dataListeners.delete(listener) }\n },\n getSnapshot(): TaskDataState {\n return dataState\n },\n actions: {\n setTasks(payload: { tasks: Task[]; boundTaskId: string | null; archivedCount: number }): void {\n const nextTasks = payload.tasks || []\n const nextArchived = payload.archivedCount ?? 0\n setDataState({\n tasks: nextTasks,\n boundTaskId: payload.boundTaskId ?? null,\n archivedCount: nextArchived,\n lastUpdate: Date.now(),\n })\n broadcastDataUpdate(nextTasks, nextArchived)\n },\n reset(): void {\n setDataState({\n tasks: [],\n boundTaskId: null,\n archivedCount: 0,\n lastUpdate: 0,\n })\n },\n },\n}\n\nexport function useTaskData(): TaskDataState {\n return useSyncExternalStore(taskDataStore.subscribe, taskDataStore.getSnapshot, taskDataStore.getSnapshot)\n}\n\nexport function useTaskDataActions() {\n return taskDataStore.actions\n}","/**\n * Task UI Store — 仅管本地 UI 状态(closed、minimized、position、expandedIds、theme、showHints)\n * - 持久化到 localStorage(key: dsh-pm-task-panel-ui)\n * - 不跨标签页同步(每个标签页独立)\n * - 启动/刷新强制 closed: true,面板默认不显示\n */\nimport { useSyncExternalStore } from 'react'\n\nconst STORAGE_KEY = 'dsh-pm-task-panel-ui'\n\n/**\n * 面板的三个视图页。**单一事实来源**:面板的切页按钮与 `/` 菜单的三行都读它。\n * 两边各抄一份必然漂移 —— 实测就是这样:菜单行去执行宿主命令\"开记忆页\",而面板的 view\n * 是组件内部 state,谁也够不着它,于是点击没有任何可见效果。\n */\nexport const PANEL_VIEWS = ['task', 'project', 'global'] as const\nexport type PanelView = (typeof PANEL_VIEWS)[number]\n\n/** 把任意值收敛成一个合法视图页(脏 localStorage / 外部传入都要过这一关)。 */\nexport function normalizeView(value: unknown): PanelView {\n return (PANEL_VIEWS as readonly unknown[]).includes(value) ? (value as PanelView) : 'task'\n}\n\ninterface TaskUIState {\n expandedTaskIds: string[]\n panelPosition: { x: number; y: number }\n minimized: boolean\n closed: boolean\n theme: string\n /** 是否显示悬停提示信息(title 气泡);false 时面板内所有功能提示都不弹出。 */\n showHints: boolean\n /**\n * 当前视图页。放在 store 而不是 TaskPanel 的局部 state —— `/` 菜单那三行就是\n * 「打开某一页」,它们从**组件外面**触发,必须有一个可寻址的落点。\n */\n view: PanelView\n}\n\nfunction defaultPosition(): { x: number; y: number } {\n if (typeof window !== 'undefined') {\n return { x: Math.max(16, window.innerWidth - 408), y: 72 }\n }\n return { x: 0, y: 0 }\n}\n\n/**\n * 启动时的初始状态:\n * - closed 恒为 true(不读取 localStorage 的 closed),刷新后面板隐藏;\n * - 其余(展开项/位置/主题)可恢复上次会话偏好,minimized 默认折叠成迷你条。\n */\nfunction getDefaultUIState(): TaskUIState {\n if (typeof window !== 'undefined') {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return {\n expandedTaskIds: Array.isArray(parsed.expandedTaskIds) ? parsed.expandedTaskIds : [],\n panelPosition: parsed.panelPosition ?? defaultPosition(),\n minimized: parsed.minimized !== false,\n closed: true,\n theme: typeof parsed.theme === 'string' ? parsed.theme : 'native',\n showHints: parsed.showHints !== false,\n // 视图页可恢复:它是\"上次在看哪一页\",刷新后仍该停在那里(与 closed 不同)。\n view: normalizeView(parsed.view),\n }\n }\n } catch { /* corrupt state — fall through to defaults */ }\n }\n return {\n expandedTaskIds: [],\n panelPosition: defaultPosition(),\n minimized: true,\n closed: true,\n theme: 'native',\n showHints: true,\n view: 'task',\n }\n}\n\nfunction persistUI(state: TaskUIState): void {\n if (typeof window === 'undefined') return\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(state))\n } catch { /* storage full/unavailable — non-fatal */ }\n}\n\nlet uiState: TaskUIState = getDefaultUIState()\nconst uiListeners = new Set<() => void>()\n\nfunction setUIState(next: TaskUIState): void {\n uiState = next\n persistUI(next)\n for (const listener of uiListeners) listener()\n}\n\nexport const taskUIStore = {\n subscribe(listener: () => void): () => void {\n uiListeners.add(listener)\n return () => { uiListeners.delete(listener) }\n },\n getSnapshot(): TaskUIState {\n return uiState\n },\n actions: {\n toggleTaskExpanded(taskId: string): void {\n const prev = uiState\n const ids = prev.expandedTaskIds.includes(taskId)\n ? prev.expandedTaskIds.filter((id) => id !== taskId)\n : [...prev.expandedTaskIds, taskId]\n setUIState({ ...prev, expandedTaskIds: ids })\n },\n expandAll(taskIds: string[]): void {\n setUIState({ ...uiState, expandedTaskIds: taskIds })\n },\n setPanelPosition(pos: { x: number; y: number }): void {\n setUIState({ ...uiState, panelPosition: pos })\n },\n open(): void {\n setUIState({ ...uiState, minimized: false, closed: false })\n },\n /**\n * 切页但不动开合状态(面板里那个循环按钮用)。\n * 非法值一律忽略 —— 这个入口会被菜单行与脏 localStorage 碰到,静默归一比抛错合适。\n */\n setView(view: PanelView): void {\n if (!(PANEL_VIEWS as readonly unknown[]).includes(view)) return\n if (uiState.view === view) return\n setUIState({ ...uiState, view })\n },\n /**\n * 打开面板并切到指定页 —— `/` 菜单那三行的**全部**动作。\n *\n * 纯客户端:不再绕 `remote.commands.execute('/tasks insight list …')` 一圈。那条路\n * 只在对话里留下一个命令节点,而客户端渲染命令节点的是按**命令名**分发的\n * `TaskCommandNode`(`name === 'tasks'`),它拿任务解析器去解记忆载荷,解析必然失败\n * —— 于是点菜单\"开记忆页\"什么都不会发生。\n * @param view - 目标视图页;非法值直接忽略(不打开面板,避免\"点了没反应还弹窗\")。\n */\n openView(view: PanelView): void {\n if (!(PANEL_VIEWS as readonly unknown[]).includes(view)) return\n setUIState({ ...uiState, view, minimized: false, closed: false })\n },\n minimize(): void {\n setUIState({ ...uiState, minimized: true, closed: false })\n },\n close(): void {\n setUIState({ ...uiState, minimized: true, closed: true })\n },\n setTheme(theme: string): void {\n setUIState({ ...uiState, theme })\n },\n toggleHints(): void {\n setUIState({ ...uiState, showHints: !uiState.showHints })\n },\n setShowHints(showHints: boolean): void {\n setUIState({ ...uiState, showHints })\n },\n reset(): void {\n setUIState(getDefaultUIState())\n },\n },\n}\n\nexport function useTaskUI(): TaskUIState {\n return useSyncExternalStore(taskUIStore.subscribe, taskUIStore.getSnapshot, taskUIStore.getSnapshot)\n}\n\nexport function useTaskUIActions() {\n return taskUIStore.actions\n}\n","/**\n * Task Panel Hooks — 步骤拖拽交互逻辑(useTaskDrag)。\n * 只依赖 react + task-data-store 类型,不碰数据/UI store。\n */\nimport { useEffect, useRef, useState, useCallback } from 'react'\nimport { TaskStep } from './task-data-store.ts'\n\ninterface DragState {\n fromIndex: number\n stepContent: string\n clientX: number\n clientY: number\n dragging: boolean\n}\n\n/**\n * useTaskDrag — 步骤拖拽重排(绑定任务内,同一任务卡的步骤行间移动)。\n *\n * 交互模型(拖动全程按住鼠标):\n * - 步骤行上按下(左键、非按钮/输入区域)→ 进入预览;\n * - 按住 350ms 不松,或按住后移动超过 6px → 唤起跟随鼠标的浮动幽灵卡片;\n * - 幽灵悬停到本任务卡内的步骤行时显示蓝色插入线(上半=插到该行前,下半=插到该行后);\n * - 松手(mouseup):落在有效位置 → onReorder 落子;落在卡外/别的任务卡/原行\n * (插入自身前后)/按钮输入等控件上 → 取消;\n * - 350ms 内原地松手 = 普通点击,不产生幽灵;Esc → 取消。\n */\nexport function useTaskDrag(\n taskId: string,\n steps: TaskStep[],\n isBound: boolean,\n onReorder: (fromIndex: number, toIndex: number) => void\n) {\n const [dragState, setDragState] = useState<DragState | null>(null)\n const [dropTargetIndex, setDropTargetIndex] = useState<number | null>(null)\n\n // 最新值镜像:拖拽期间 window 监听只在“会话开始/结束”时挂载/卸载,\n // 避免每次 mousemove 更新状态导致监听器重挂、连 350ms 定时器都被清掉。\n const dragRef = useRef(dragState)\n dragRef.current = dragState\n const longPressTimer = useRef<number | undefined>(undefined)\n const dragOrigin = useRef<{ x: number; y: number } | null>(null)\n\n const clearTimer = useCallback(() => {\n if (longPressTimer.current !== undefined) {\n window.clearTimeout(longPressTimer.current)\n longPressTimer.current = undefined\n }\n }, [])\n\n const cancelDrag = useCallback(() => {\n clearTimer()\n dragOrigin.current = null\n document.body.style.userSelect = ''\n setDropTargetIndex(null)\n setDragState(null)\n }, [clearTimer])\n\n const startDrag = useCallback((\n fromIndex: number,\n stepContent: string,\n e: React.MouseEvent\n ) => {\n if (!isBound || e.button !== 0) return\n if (dragRef.current) return // 已有预览/拖拽会话\n e.preventDefault()\n e.stopPropagation()\n document.body.style.userSelect = 'none'\n dragOrigin.current = { x: e.clientX, y: e.clientY }\n setDropTargetIndex(null)\n setDragState({ fromIndex, stepContent, clientX: e.clientX, clientY: e.clientY, dragging: false })\n clearTimer()\n longPressTimer.current = window.setTimeout(() => {\n longPressTimer.current = undefined\n // 350ms 长按 → 唤起幽灵卡片\n setDragState(prev => (prev ? { ...prev, dragging: true } : null))\n }, 350)\n }, [isBound, clearTimer])\n\n /** 计算某行上 y 坐标对应的插入位(行数下标:上半=该行前,下半=该行后);非本任务卡返回 null */\n const dropIndexAt = useCallback((row: Element, clientY: number): number | null => {\n const parentOl = row.closest('ol')\n if (!parentOl || !parentOl.closest(`article[data-task-id=\"${taskId}\"]`)) return null\n const index = Array.from(parentOl.children).indexOf(row)\n const rect = row.getBoundingClientRect()\n return clientY < rect.top + rect.height / 2 ? index : index + 1\n }, [taskId])\n\n /** 在 (x,y) 处结算:命中有效落点则重排,否则取消;并结束本次拖拽 */\n const commitDrop = useCallback((x: number, y: number) => {\n const cur = dragRef.current\n if (!cur || !cur.dragging) return\n const el = document.elementFromPoint(x, y) as HTMLElement | null\n // 松手点在按钮/输入等交互控件上:不落子,直接取消\n if (el && !el.closest('button, input, textarea, a')) {\n const row = el.closest('[data-step-row]')\n if (row) {\n const drop = dropIndexAt(row, y)\n if (drop !== null) {\n // 行下标形式的落点:插到目标行前/后;落在自身原位视为取消(不产生空推送)\n const effective = drop > cur.fromIndex ? drop - 1 : drop\n if (effective !== cur.fromIndex) onReorder(cur.fromIndex, drop)\n }\n }\n }\n cancelDrag()\n }, [dropIndexAt, onReorder, cancelDrag])\n\n const active = dragState !== null\n\n useEffect(() => {\n if (!active) return\n\n const onMouseMove = (e: MouseEvent) => {\n const cur = dragRef.current\n if (!cur) return\n if (!cur.dragging) {\n // 未到 350ms:移动超过阈值视为拖拽开始(不必死等长按)\n const origin = dragOrigin.current\n if (!origin) return\n if (Math.hypot(e.clientX - origin.x, e.clientY - origin.y) < 6) return\n clearTimer()\n setDragState(prev => (prev ? { ...prev, dragging: true, clientX: e.clientX, clientY: e.clientY } : null))\n } else {\n setDragState(prev => (prev ? { ...prev, clientX: e.clientX, clientY: e.clientY } : null))\n }\n const row = document.elementFromPoint(e.clientX, e.clientY)?.closest('[data-step-row]')\n setDropTargetIndex(row ? dropIndexAt(row, e.clientY) : null)\n }\n\n const onMouseUp = (e: MouseEvent) => {\n const cur = dragRef.current\n if (!cur) return\n if (cur.dragging) {\n // 拖拽中松手 = 落子/取消\n commitDrop(e.clientX, e.clientY)\n } else {\n // 350ms 内原地松手 = 普通点击\n cancelDrag()\n }\n }\n\n const onClick = (e: MouseEvent) => {\n // 兜底:mouseup 发生在窗口外等情况时,下一次点击直接结算\n const cur = dragRef.current\n if (!cur || !cur.dragging) return\n commitDrop(e.clientX, e.clientY)\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') cancelDrag()\n }\n\n window.addEventListener('mousemove', onMouseMove)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('click', onClick, true)\n window.addEventListener('keydown', onKeyDown)\n return () => {\n window.removeEventListener('mousemove', onMouseMove)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('click', onClick, true)\n window.removeEventListener('keydown', onKeyDown)\n document.body.style.userSelect = ''\n }\n }, [active, taskId, dropIndexAt, onReorder, cancelDrag, commitDrop])\n\n useEffect(() => () => clearTimer(), [clearTimer])\n\n return { dragState, dropTargetIndex, startDrag, cancelDrag }\n}\n","/**\n * Task Panel Presentational 组件 — MiniBar(折叠迷你条)与 TaskCard(任务卡)。\n * 纯渲染 + 卡片局部行内编辑/拖拽状态,动作经 props 回调交给容器(TaskPanel.tsx)。\n */\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\n// 图标走兼容层:0.1.5 用 IconXxx14/16,0.1.7+ 改成 IconXxxRegular + size prop\nimport {\n IconChevronDownOutline14,\n IconChevronUpOutline14,\n IconCheckOutline16,\n IconPlayOutline16,\n IconFolderOpenOutline16,\n} from './icons.ts'\nimport { createTranslate } from './locales.ts'\nimport { useTaskDrag } from './task-hooks.ts'\nimport { type Task, type TaskInsight, type TaskStep } from './task-data-store.ts'\nimport css from './TaskPanel.module.css'\n\nfunction insightKindLabel(kind: string, t: ReturnType<typeof createTranslate>): string {\n const map: Record<string, string> = {\n lesson: t('mem.kind.lesson'),\n decision: t('mem.kind.decision'),\n procedure: t('mem.kind.procedure'),\n experience: t('mem.kind.experience'),\n }\n return map[kind] ?? kind\n}\n\ntype InsightAction = 'confirm' | 'promote' | 'delete'\n\nfunction timeAgo(iso?: string) {\n if (!iso) return ''\n const diff = Date.now() - new Date(iso).getTime()\n const m = Math.floor(diff / 60000)\n if (m < 1) return '刚刚'\n if (m < 60) return `${m}分钟前`\n const h = Math.floor(m / 60)\n if (h < 24) return `${h}小时前`\n return `${Math.floor(h / 24)}天前`\n}\n\nfunction StepIcon({ status }: { status: TaskStep['status'] }) {\n if (status === 'completed') return <IconCheckOutline16 className={css.stepDone} />\n if (status === 'in_progress') return <IconPlayOutline16 className={css.stepRun} />\n return <span className={css.stepPending} />\n}\n\n/**\n * 双击判定窗口(ms)。\n * 单击(如卡片展开/收起)会延迟该时长执行:若期间收到第二次点击则按“双击”处理并取消单击,\n * 从而避免“第一下先展开/收起、布局位移后第二下点不到目标”的问题。\n * 数值是可感知与可靠性的折中:太小慢速双击会失效,太大单击会显“肉”。\n */\nconst CLICK_SINGLE_DELAY_MS = 250\n\n/**\n * 行内自适应高度文本编辑器(textarea)。\n * 编辑体验与单行输入一致(Enter 提交 / Shift+Enter 换行 / Esc 取消 / 失焦提交),\n * 但高度随内容自动增长(按实际渲染行高测量),最多 maxRows 行后内部滚动,\n * 解决长步骤/长任务名只能挤在一行里横向滚动编辑的问题。\n */\ninterface InlineEditorProps {\n value: string\n className?: string\n maxRows?: number\n onValueChange: (value: string) => void\n onCommit: () => void\n onCancel: () => void\n}\n\nfunction InlineEditor({ value, className, maxRows = 8, onValueChange, onCommit, onCancel }: InlineEditorProps) {\n const ref = useRef<HTMLTextAreaElement>(null)\n\n // 在绘制前按真实内容测量并写死高度:内容 <= maxRows 行时刚好包住,超出后内部滚动。\n useLayoutEffect(() => {\n const el = ref.current\n if (!el) return\n el.style.height = 'auto'\n const cs = getComputedStyle(el)\n const lineHeight = parseFloat(cs.lineHeight) || 20\n const padV = (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0)\n const borderV = (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0)\n const cap = maxRows * lineHeight + padV + borderV\n const height = Math.min(el.scrollHeight, cap)\n el.style.height = `${height}px`\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden'\n }, [value, maxRows])\n\n return (\n <textarea\n ref={ref}\n className={className}\n rows={1}\n value={value}\n autoFocus\n spellCheck={false}\n onChange={(e) => onValueChange(e.target.value)}\n onFocus={(e) => {\n // 光标放到末尾,便于直接在原文后继续输入\n const len = e.target.value.length\n e.target.setSelectionRange(len, len)\n }}\n onBlur={onCommit}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onCommit()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n onCancel()\n }\n }}\n />\n )\n}\n\ninterface MiniBarProps {\n label: string\n hint: string\n showHints: boolean\n position: { x: number; y: number }\n theme: string\n onMove: (pos: { x: number; y: number }) => void\n open: () => void\n}\n\nexport function MiniBar({ label, hint, showHints, position, theme, onMove, open }: MiniBarProps) {\n const barRef = useRef<HTMLDivElement>(null)\n const down = useRef<{ dx: number; dy: number; sx: number; sy: number; moved: boolean } | null>(null)\n\n const onMouseDown = (e: React.MouseEvent) => {\n if (e.button !== 0) return\n const rect = barRef.current?.getBoundingClientRect()\n if (!rect) return\n down.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top, sx: e.clientX, sy: e.clientY, moved: false }\n const onMoveEv = (ev: MouseEvent) => {\n const d = down.current\n if (!d) return\n if (!d.moved && Math.abs(ev.clientX - d.sx) + Math.abs(ev.clientY - d.sy) > 4) d.moved = true\n if (d.moved) {\n const w = barRef.current?.offsetWidth ?? 260\n const h = barRef.current?.offsetHeight ?? 34\n const x = Math.max(8, Math.min(window.innerWidth - w - 8, ev.clientX - d.dx))\n const y = Math.max(8, Math.min(window.innerHeight - h - 8, ev.clientY - d.dy))\n onMove({ x, y })\n }\n }\n const onUpEv = () => {\n const d = down.current\n down.current = null\n window.removeEventListener('mousemove', onMoveEv)\n window.removeEventListener('mouseup', onUpEv)\n if (d && !d.moved) open()\n }\n window.addEventListener('mousemove', onMoveEv)\n window.addEventListener('mouseup', onUpEv)\n }\n\n return (\n <div\n ref={barRef}\n className={css.miniBar}\n style={{ left: position.x, top: position.y }}\n data-theme={theme === 'native' ? undefined : theme}\n onMouseDown={onMouseDown}\n role=\"button\"\n title={showHints ? hint : undefined}\n aria-label={hint}\n >\n <IconFolderOpenOutline16 className={css.miniIcon} />\n <span className={css.miniText}>{label}</span>\n <IconChevronUpOutline14 className={css.miniChevron} />\n </div>\n )\n}\n\ninterface TaskCardProps {\n task: Task\n isBound: boolean\n expanded: boolean\n onToggleExpand: () => void\n onSwitch: () => void\n onUnbind: () => void\n onArchive: () => void\n onRename: (value: string) => void\n onEditStep: (index: number, value: string) => void\n onCycleStatus: (index: number) => void\n onReorderSteps: (fromIndex: number, toIndex: number) => void\n onInsightAction?: (action: InsightAction, id: string) => void\n showHints: boolean\n syncing: boolean\n t: ReturnType<typeof createTranslate>\n}\n\nexport function TaskCard({\n task,\n isBound,\n expanded,\n onToggleExpand,\n onSwitch,\n onUnbind,\n onArchive,\n onRename,\n onEditStep,\n onCycleStatus,\n onReorderSteps,\n onInsightAction,\n showHints,\n syncing,\n t,\n}: TaskCardProps) {\n const steps = task.steps || []\n const { dragState, dropTargetIndex, startDrag, cancelDrag } = useTaskDrag(task.id, steps, isBound, onReorderSteps)\n\n // 行内编辑状态(本卡片局部):双击进入,Enter/失焦提交,Esc 取消。\n const [stepEdit, setStepEdit] = useState<{ index: number; value: string } | null>(null)\n const [titleEdit, setTitleEdit] = useState<{ value: string } | null>(null)\n\n const done = steps.filter((s) => s.status === 'completed').length\n const pct = steps.length > 0 ? Math.round((done / steps.length) * 100) : 0\n\n const commitStepEdit = (index: number) => {\n if (!stepEdit || stepEdit.index !== index) return\n const value = stepEdit.value\n setStepEdit(null)\n onEditStep(index, value)\n }\n\n const commitTitleEdit = () => {\n if (titleEdit === null) return\n const value = titleEdit.value\n setTitleEdit(null)\n onRename(value)\n }\n\n // —— 卡片头单击(展开/收起)与双击(编辑任务名)的时序判定 ——\n // 单击动作延迟 CLICK_SINGLE_DELAY_MS 执行;若在窗口内收到第二次点击,取消单击、\n // 命中任务名则直接进入编辑,避免“第一下已展开/收起、布局位移、第二下点不到任务名”。\n const headClickTimer = useRef<number | null>(null)\n // 编辑状态下,点卡片头任意处会先触发失焦提交;该次点击不应再当作“切换展开”的单击。\n const suppressHeadClick = useRef(false)\n useEffect(() => () => {\n if (headClickTimer.current !== null) window.clearTimeout(headClickTimer.current)\n }, [])\n\n const handleHeadClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (suppressHeadClick.current) {\n // 上一次 mousedown 落在标题编辑框内(失焦提交产生),吞掉这次点击,不切换展开\n suppressHeadClick.current = false\n return\n }\n if (titleEdit !== null) return\n const target = e.target as HTMLElement\n const onTitle = isBound && target.closest('[data-card-title]') !== null\n if (headClickTimer.current !== null) {\n // 第二次点击 → 双击:取消待执行的单击动作\n window.clearTimeout(headClickTimer.current)\n headClickTimer.current = null\n if (onTitle) setTitleEdit({ value: String(task.title ?? '') })\n else onToggleExpand()\n return\n }\n headClickTimer.current = window.setTimeout(() => {\n headClickTimer.current = null\n onToggleExpand()\n }, CLICK_SINGLE_DELAY_MS)\n }\n\n return (\n <article data-task-id={task.id} className={`${css.card}${isBound ? ` ${css.cardBound}` : ''}`}>\n <button\n className={css.cardHead}\n onClick={handleHeadClick}\n onMouseDownCapture={() => {\n // 标题编辑中,点击卡片头任意处都会先失焦提交;标记该次点击以在 onClick 中吞掉,\n // 避免“改名提交一下、卡片又收起/展开一下”的误切换。\n if (titleEdit !== null) suppressHeadClick.current = true\n }}\n onDoubleClick={(e) => e.preventDefault()}\n aria-expanded={expanded}\n >\n <div className={css.cardTitleRow}>\n {isBound && <span className={css.boundBadge}>{t('task.current')}</span>}\n {isBound && titleEdit !== null ? (\n <InlineEditor\n className={css.editorArea}\n value={titleEdit.value}\n maxRows={4}\n onValueChange={(value) => setTitleEdit({ value })}\n onCommit={commitTitleEdit}\n onCancel={() => setTitleEdit(null)}\n />\n ) : (\n <span\n data-card-title\n className={`${css.cardTitle}${isBound ? ` ${css.cardTitleEditable}` : ''}`}\n title={isBound && showHints ? t('task.title-edit') : undefined}\n onDoubleClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n if (isBound) setTitleEdit({ value: String(task.title ?? '') })\n }}\n >\n {task.title}\n </span>\n )}\n </div>\n <div className={css.cardMeta}>\n {steps.length > 0 && <span className={css.progressText}>{done}/{steps.length}</span>}\n <span className={css.updated}>{timeAgo(task.updatedAt || task.lastActiveAt)}</span>\n <span className={css.chevron}>{expanded ? <IconChevronUpOutline14 /> : <IconChevronDownOutline14 />}</span>\n </div>\n </button>\n {steps.length > 0 && (\n <div className={css.track}>\n <div className={css.trackFill} style={{ width: `${pct}%` }} />\n </div>\n )}\n {expanded && (\n <div className={css.cardBody}>\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('task.steps')}\n {steps.length > 0 && <span className={css.sectionCount}>{steps.length}</span>}\n </div>\n {steps.length > 0 ? (\n <>\n <ol className={css.stepsList}>\n {steps.map((step, i) => {\n const stepIsEditing = stepEdit !== null && stepEdit.index === i\n const stepIsDragging = dragState?.dragging && dragState.fromIndex === i\n const isDropTarget = dropTargetIndex === i\n const isDropTargetAfter = dropTargetIndex === i + 1\n return (\n <li\n key={i}\n data-step-row\n className={`${css.stepRow}${stepIsDragging ? ` ${css.stepDragging}` : ''}${isDropTarget ? ` ${css.dropTargetBefore}` : ''}${isDropTargetAfter ? ` ${css.dropTargetAfter}` : ''}`}\n onMouseDown={(e) => {\n if (e.button !== 0) return\n if (!isBound || syncing) return\n // 交互控件(状态图标、编辑输入框等)上不进入拖拽\n const el = e.target as HTMLElement\n if (el.closest('button, input, textarea, a')) return\n startDrag(i, step.content, e)\n }}\n >\n {isBound ? (\n <button\n type=\"button\"\n className={css.stepToggle}\n disabled={syncing}\n onClick={(e) => { e.stopPropagation(); onCycleStatus(i) }}\n title={showHints ? `${t('step.completed')}/${t('step.in-progress')}/${t('step.pending')}` : undefined}\n >\n <StepIcon status={step.status} />\n </button>\n ) : (\n <StepIcon status={step.status} />\n )}\n {stepIsEditing ? (\n <InlineEditor\n className={css.editorArea}\n value={stepEdit!.value}\n maxRows={10}\n onValueChange={(value) => setStepEdit({ index: i, value })}\n onCommit={() => commitStepEdit(i)}\n onCancel={() => setStepEdit(null)}\n />\n ) : (\n <span\n className={`${css.stepContent}${step.status === 'completed' ? ` ${css.stepContentDone}` : ''}${step.status === 'in_progress' ? ` ${css.stepContentRun}` : ''}${isBound ? ` ${css.stepEditable}` : ''}`}\n title={isBound && showHints ? t('step.edit-hint') : undefined}\n onDoubleClick={(e) => {\n e.stopPropagation()\n if (isBound) setStepEdit({ index: i, value: String(step.content ?? '') })\n }}\n >\n {step.content}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n {dragState && dragState.dragging && (\n <div\n className={css.dragGhost}\n style={{\n left: dragState.clientX + 12,\n top: dragState.clientY - 20,\n }}\n >\n <div className={css.dragGhostCard}>\n <span className={css.dragGhostContent}>{dragState.stepContent}</span>\n <button\n type=\"button\"\n className={css.dragGhostClose}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => { e.stopPropagation(); cancelDrag() }}\n title={showHints ? t('drag.cancel') : undefined}\n aria-label={t('drag.cancel')}\n >\n ×\n </button>\n </div>\n </div>\n )}\n </>\n ) : (\n <div className={css.muted}>{t('panel.empty-desc')}</div>\n )}\n </div>\n\n {(task.files?.length ?? 0) > 0 && (\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('task.files')}\n <span className={css.sectionCount}>{task.files.length}</span>\n </div>\n <ul className={css.filesList}>\n {task.files.slice(0, 12).map((file, i) => (\n <li key={i}>\n <button\n className={css.fileRow}\n onClick={() => navigator.clipboard?.writeText(file.path)}\n title={showHints ? `${t('file.copy')}: ${file.path}${file.line ? `:${file.line}` : ''}` : undefined}\n >\n <span className={css.fileDot} />\n <span className={css.filePath}>{file.path}</span>\n {file.line && <span className={css.fileLine}>:{file.line}</span>}\n </button>\n </li>\n ))}\n {(task.files?.length ?? 0) > 12 && (\n <li className={css.muted}>… 共 {task.files.length} 个</li>\n )}\n </ul>\n </div>\n )}\n\n {onInsightAction && Array.isArray(task.insights) && task.insights.length > 0 && (\n <div className={css.section}>\n <div className={css.sectionLabel}>\n {t('mem.section-label')}\n <span className={css.sectionCount}>{task.insights.length}</span>\n </div>\n <ul className={css.memList}>\n {(task.insights as TaskInsight[]).map((ins) => (\n <li key={ins.id} className={css.memRow}>\n <div className={css.memTitle}>\n <span className={css.kindBadge}>{insightKindLabel(ins.kind, t)}</span>\n <span>{ins.title || ins.id}</span>\n {ins.draft && <span className={`${css.badge} ${css.badgeDraft}`}>{t('mem.draft')}</span>}\n </div>\n <div className={css.memActs}>\n {ins.draft && (\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('confirm', ins.id)}>\n {t('mem.confirm')}\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('promote', ins.id)}>\n {t('mem.promote')}\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={() => onInsightAction('delete', ins.id)}>\n {t('mem.delete')}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n <div className={css.cardFooter}>\n <Button variant=\"outline\" size=\"sm\" disabled={isBound || syncing} onClick={onSwitch}>\n {t('task.switch')}\n </Button>\n {isBound && (\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={onUnbind} title={showHints ? t('task.unbind') : undefined}>\n {t('task.unbind')}\n </Button>\n )}\n <Button variant=\"outline\" size=\"sm\" disabled={syncing} onClick={onArchive}>\n {t('task.archive')}\n </Button>\n </div>\n </div>\n )}\n </article>\n )\n}\n","/**\n * Memory View — 记忆三作用域列表(Task 草稿 / Project / Global)\n * 数据通道与任务面板一致:remote.commands.execute 执行 /insight 命令,取 JSON 载荷。\n * 动作:confirm(草稿审核) / promote(向上提升) / demote(向下降级,需绑定任务) / archive / restore / delete\n */\nimport { useEffect, useCallback, useRef, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport css from './TaskPanel.module.css'\n\nexport type InsightScope = 'task' | 'project' | 'global'\n\nexport interface InsightRow {\n id: string\n kind: string\n scope: InsightScope\n title: string\n body?: string\n fix?: string\n solution?: string\n reason?: string\n pattern?: string\n problem?: string\n choice?: string\n draft?: boolean\n archived?: boolean\n confidence?: number | null\n hitCount?: number\n members?: number\n files?: number\n symbols?: number\n trigger?: { keywords: string[]; scope: string[] } | null\n steps?: string[]\n taskId?: string\n taskTitle?: string\n updatedAt?: string\n}\n\ninterface ListPayload {\n scope: InsightScope\n count: number\n items: InsightRow[]\n}\n\nexport function parseInsightPayloadText(text?: string | null): ListPayload | null {\n if (!text) return null\n let jsonBlock: string | null = null\n const fenced = text.match(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/)\n if (fenced) jsonBlock = fenced[1]\n else {\n const lastBrace = text.lastIndexOf('{')\n if (lastBrace !== -1) jsonBlock = text.slice(lastBrace)\n }\n if (!jsonBlock) return null\n try {\n const data = JSON.parse(jsonBlock)\n if (!Array.isArray(data.items)) return null\n return { scope: data.scope ?? 'project', count: data.count ?? data.items.length, items: data.items }\n } catch {\n return null\n }\n}\n\nfunction kindText(kind: string, t: any): string {\n const map: Record<string, string> = {\n lesson: t('mem.kind.lesson'),\n decision: t('mem.kind.decision'),\n procedure: t('mem.kind.procedure'),\n experience: t('mem.kind.experience'),\n }\n return map[kind] ?? kind\n}\n\nexport function MemoryView({\n ctx,\n sessionId,\n scope,\n boundTaskId,\n showHints,\n t,\n}: {\n ctx: any\n sessionId: string | null\n scope: InsightScope\n boundTaskId: string | null\n showHints: boolean\n t: any\n}) {\n const [payload, setPayload] = useState<ListPayload | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(false)\n const [busy, setBusy] = useState(false)\n const [showNew, setShowNew] = useState(false)\n const [editingId, setEditingId] = useState<string | null>(null)\n const [form, setForm] = useState({ title: '', kind: 'lesson', body: '', steps: '', trigger: '' })\n const [savedTip, setSavedTip] = useState<string | null>(null)\n\n const runLine = useCallback(\n async (line: string): Promise<{ ok: boolean; text: string }> => {\n const commands = ctx?.remote?.commands\n if (!sessionId || !commands || typeof commands.execute !== 'function') {\n return { ok: false, text: 'no session / commands service' }\n }\n try {\n const response = await commands.execute(sessionId, line, [])\n const envelope = response as { ok?: boolean; value?: any } | null | undefined\n const execution = envelope && typeof envelope === 'object' && 'value' in envelope ? envelope.value : envelope\n const result = execution?.result ?? execution\n if (result?.kind === 'error') return { ok: false, text: result.text ?? 'command error' }\n return { ok: true, text: result?.text ?? '' }\n } catch (err) {\n return { ok: false, text: String((err as Error)?.message ?? err) }\n }\n },\n [ctx, sessionId],\n )\n\n // 用 ref 做并发/频控守卫:loading 状态不能进 refresh 的依赖数组,\n // 否则 loading 每次翻转都会重建 refresh → effect 重跑 → 无限循环刷 /insight 命令。\n const inflightRef = useRef(false)\n const lastRunRef = useRef(0)\n\n const refresh = useCallback(async (force = false): Promise<void> => {\n // 没有活跃会话时不发命令、也不报错:面板顶部已经显示「还没有会话」,\n // 再报一次\"同步失败\"会让人以为记忆库坏了(0.1.7 上会话快照结构变化时就是这个表象)。\n if (!sessionId) {\n setPayload(null)\n setError(null)\n setLoading(false)\n return\n }\n if (inflightRef.current) return\n const now = Date.now()\n if (!force && now - lastRunRef.current < 800) return\n inflightRef.current = true\n lastRunRef.current = now\n setLoading(true)\n setError(null)\n try {\n const res = await runLine(`/tasks insight list ${scope}`)\n if (!res.ok) {\n setError(res.text)\n setPayload(null)\n return\n }\n const parsed = parseInsightPayloadText(res.text)\n setPayload(parsed)\n if (!parsed) setError('unparsable payload')\n } finally {\n inflightRef.current = false\n setLoading(false)\n }\n }, [runLine, scope])\n\n useEffect(() => {\n void refresh()\n }, [refresh])\n\n const act = async (action: string, id: string): Promise<void> => {\n if (busy) return\n setBusy(true)\n setError(null)\n try {\n const line = `/tasks insight ${action} ${scope} ${id}${action === 'demote' && scope === 'project' && boundTaskId ? ` ${boundTaskId}` : ''}`\n const res = await runLine(line)\n if (!res.ok) setError(res.text)\n else void refresh(true)\n } finally {\n setBusy(false)\n }\n }\n\n const rowToForm = (row: InsightRow) => {\n // 正文按 kind 取专属字段(fix/solution/reason),避免把与标题相同的 pattern/problem 当正文\n const main =\n row.kind === 'lesson' ? row.fix\n : row.kind === 'experience' ? row.solution\n : row.kind === 'decision' ? row.reason\n : row.body\n const body = main && main !== row.title ? main : ''\n return {\n title: row.title || '',\n kind: row.kind || 'lesson',\n body,\n steps: Array.isArray((row as InsightRow & { steps?: string[] }).steps) ? ((row as InsightRow & { steps?: string[] }).steps as string[]).join('\\n') : '',\n trigger: (row.trigger?.keywords || []).join(','),\n }\n }\n\n const startEdit = (row: InsightRow) => {\n setEditingId(row.id)\n setForm(rowToForm(row))\n setShowNew(true)\n setError(null)\n }\n\n const closeForm = () => {\n setShowNew(false)\n setEditingId(null)\n setForm({ title: '', kind: 'lesson', body: '', steps: '', trigger: '' })\n }\n\n // 切换类型时把当前输入迁移到目标类型的主内容区,避免换类型后“刚写的东西消失”\n const changeKind = (next: string) => {\n setForm(prev => {\n if (prev.kind === next) return prev\n const fromProc = prev.kind === 'procedure'\n const toProc = next === 'procedure'\n let body = prev.body\n let steps = prev.steps\n if (fromProc && !toProc && !body && steps.trim()) body = steps.trim() // procedure → 正文\n if (toProc && !fromProc && !steps.trim() && body.trim()) steps = body.trim() // 正文 → 步骤\n return { ...prev, kind: next, body, steps }\n })\n }\n\n const submitNew = async (): Promise<void> => {\n if (scope === 'task' && !editingId) return\n if (busy) return\n const title = form.title.trim()\n if (!title) return\n setBusy(true)\n setError(null)\n try {\n const fields: Record<string, unknown> = { title, kind: form.kind }\n if (form.kind === 'lesson') fields.pattern = title\n if (form.kind === 'decision') fields.choice = title\n if (form.kind === 'experience') fields.problem = title\n if (form.body.trim()) {\n if (form.kind === 'lesson') fields.fix = form.body.trim()\n else if (form.kind === 'decision') fields.reason = form.body.trim()\n else if (form.kind === 'experience') fields.solution = form.body.trim()\n else fields.body = form.body.trim()\n }\n if (form.kind === 'procedure' && form.steps.trim()) {\n fields.steps = form.steps.split('\\n').map((s) => s.trim()).filter(Boolean)\n }\n if (form.kind === 'procedure' && form.trigger.trim()) {\n fields.trigger = { keywords: form.trigger.split(/[,,]/).map((s) => s.trim()).filter(Boolean) }\n }\n const line = editingId\n ? `/tasks insight edit ${scope} ${editingId} ${JSON.stringify(fields)}`\n : `/tasks insight save ${scope} ${JSON.stringify(fields)}`\n const res = await runLine(line)\n if (!res.ok) {\n setError(res.text)\n } else {\n setSavedTip(t('mem.saved'))\n closeForm()\n window.setTimeout(() => setSavedTip(null), 2500)\n void refresh(true)\n }\n } finally {\n setBusy(false)\n }\n }\n\n const items = payload?.items ?? []\n\n return (\n <div className={css.memoryPane}>\n <div className={css.memToolbar}>\n <span className={css.memCount}>\n {scope === 'task' ? t('mem.scope.task') : scope === 'global' ? t('mem.scope.global') : t('mem.scope.project')}\n {payload ? ` · ${payload.count}` : ''}\n </span>\n <span className={css.memToolbarActs}>\n {savedTip && <span className={css.badge}>{savedTip}</span>}\n {scope !== 'task' && !showNew && (\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => { setShowNew(true); setEditingId(null); setError(null) }}>{t('mem.new')}</Button>\n )}\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refresh(true)} disabled={loading} title={showHints ? t('panel.refresh') : undefined} aria-label={t('panel.refresh')}>\n ↻\n </Button>\n </span>\n </div>\n {showNew && scope !== 'task' && (\n <div className={css.memNew}>\n <input className={css.stepInput} placeholder={t('mem.f.title')} value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })} autoFocus />\n <div className={css.memNewRow}>\n <label className={css.memLabel}>{t('mem.f.kind')}\n <select className={css.stepInput} value={form.kind} onChange={(e) => changeKind(e.target.value)}>\n <option value=\"lesson\">lesson</option>\n <option value=\"decision\">decision</option>\n <option value=\"procedure\">procedure</option>\n <option value=\"experience\">experience</option>\n </select>\n </label>\n </div>\n {form.kind !== 'procedure' && (\n <textarea className={css.stepInput} placeholder={t('mem.f.body')} rows={2} value={form.body}\n onChange={(e) => setForm({ ...form, body: e.target.value })} />\n )}\n {form.kind === 'procedure' && (\n <>\n <textarea className={css.stepInput} placeholder={t('mem.f.steps')} rows={3} value={form.steps}\n onChange={(e) => setForm({ ...form, steps: e.target.value })} />\n <input className={css.stepInput} placeholder={t('mem.f.trigger')} value={form.trigger}\n onChange={(e) => setForm({ ...form, trigger: e.target.value })} />\n </>\n )}\n <div className={css.memActs}>\n <Button variant=\"outline\" size=\"sm\" disabled={busy || !form.title.trim()} onClick={() => void submitNew()}>{t('mem.save')}</Button>\n <Button variant=\"outline\" size=\"sm\" onClick={closeForm}>{t('mem.cancel')}</Button>\n </div>\n </div>\n )}\n {error && <div className={css.notice}>{t('mem.error')}: {error}</div>}\n {loading && !items.length && <div className={css.muted}>{t('mem.loading')}</div>}\n {!loading && !error && items.length === 0 && <div className={css.muted}>{t('mem.empty')}</div>}\n <div className={css.memList}>\n {items.map((row) => {\n const canDemoteToTask = scope === 'project' && !!boundTaskId\n return (\n <div key={row.id} className={`${css.memRow}${row.archived ? ` ${css.memRowArchived}` : ''}`}>\n <div className={css.memRowMain}>\n <span className={css.memTitle}>\n <span className={css.kindBadge}>{kindText(row.kind, t)}</span>\n {row.title || row.body}\n </span>\n <span className={css.memMeta}>\n {row.draft && <span className={`${css.badge} ${css.badgeDraft}`}>{t('mem.draft')}</span>}\n {row.archived && <span className={`${css.badge} ${css.badgeArchived}`}>{t('mem.archived')}</span>}\n {row.taskTitle && <span className={css.badge}>@{row.taskTitle}</span>}\n {row.members !== undefined && row.members > 0 && <span className={css.badge}>×{row.members}</span>}\n {row.confidence != null && <span className={css.badge}>{Math.round(row.confidence * 100)}%</span>}\n {row.trigger && row.trigger.keywords.length > 0 && <span className={css.badge}>⚡{row.trigger.keywords.slice(0, 2).join(',')}</span>}\n </span>\n </div>\n {row.body && row.body !== row.title && <div className={css.memBody}>{String(row.body).slice(0, 160)}</div>}\n <div className={css.memActs}>\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => startEdit(row)}>{t('mem.edit')}</Button>\n {scope === 'task' && !row.archived && (\n <>\n {row.draft && <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('confirm', row.id)}>{t('mem.confirm')}</Button>}\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('promote', row.id)}>{t('mem.promote')}</Button>\n </>\n )}\n {scope === 'project' && (\n <>\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('promote', row.id)}>{t('mem.promote')}</Button>\n <Button variant=\"outline\" size=\"sm\" disabled={busy || !canDemoteToTask} title={showHints && !canDemoteToTask ? t('mem.needs-bound') : undefined} onClick={() => void act('demote', row.id)}>{t('mem.demote')}</Button>\n </>\n )}\n {scope === 'global' && (\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('demote', row.id)}>{t('mem.demote')}</Button>\n )}\n {row.archived\n ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('restore', row.id)}>{t('mem.restore')}</Button>\n : <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('archive', row.id)}>{t('mem.archive')}</Button>}\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => void act('delete', row.id)}>{t('mem.delete')}</Button>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n","/**\n * 会话列表快照 → 当前会话 id(宿主版本兼容层)。\n *\n * 快照结构被宿主改过一次,旧写法只认第一种:\n * - dsh ≤0.1.6:`{ current?: id, items: [{ sessionId, blank }] }`\n * - dsh 0.1.7+:`{ ids: id[], byId: Record<id, SessionSummary>, phase, projectionsBySession }`\n * —— `current` 与 `items` **都不存在了**。\n *\n * 后果一(永远 null):0.1.7 上 `snap.current` 和 `snap.items` 都是 undefined → 旧代码永远\n * 返回 null → 面板显示「还没有会话」、记忆视图报 `同步失败: no session / commands service`。\n * 而**任务视图渲染的是 task-data-store 里的缓存快照**,看起来还正常,所以这个故障很容易被\n * 误读成\"数据格式/旧版本兼容\"问题。\n *\n * 后果二(不跟随切换):光\"取一个非 null 的 id\"不够 —— 兜底取的是宿主列表里第一个非 blank 的\n * 会话,它**不随用户切换对话而变化**,面板会一直停在同一个会话(从而显示错项目的任务)。\n * 0.1.7 判断\"当前会话\"的正式依据是 `SessionSummary.retainedBy.mainView > 0`:\n * 主视图正在 retain 的那个就是用户正在看的那个(第一方同款判据,见 ui-layout/DocumentTitle.tsx\n * 与 ui-session)。它就在**列表快照的 byId 行上**,而 retain 计数变化会 `list.set(...)` 重新发布\n * 快照(session-controller/.../sessions/service.ts 的 publishRetention),所以订阅\n * `ctx.sessions.list` 的组件会在切换会话时自动重渲染 —— 这条必须走快照内字段,不能另开\n * `retainInfo()` 订阅,否则切换不会触发重渲染。\n *\n * 实测形状见 `packages/api/session-controller/src/client/sessions/service.ts` 的\n * `SessionListState` / `SessionSummary`。\n */\n\n/** 正数才算持有(retain 计数缺失/0/负数一律当没有)。 */\nfunction heldCount(value) {\n return typeof value === 'number' && value > 0 ? value : 0\n}\n\n/** 从一行 summary 抽出本模块关心的三个事实。 */\nfunction rowFacts(row) {\n return {\n blank: row?.blank === true,\n /** 主视图对这条会话的 retain 计数;> 0 即\"用户正在看它\"。 */\n mainView: heldCount(row?.retainedBy?.mainView),\n }\n}\n\n/**\n * 把两种快照形状统一成 `{ id, blank, mainView }` 列表,顺序保持宿主给的顺序。\n * @param {object|undefined|null} snap - `ctx.sessions.list.getSnapshot()`\n * @returns {Array<{id: string, blank: boolean, mainView: number}>} 认不出的形状返回空数组\n */\nexport function sessionRows(snap) {\n if (!snap || typeof snap !== 'object') return []\n // 旧形状:items 里每行自带 sessionId / blank / retainedBy\n if (Array.isArray(snap.items)) {\n return snap.items\n .map((row) => ({ id: row?.sessionId, ...rowFacts(row) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n const byId = snap.byId && typeof snap.byId === 'object' ? snap.byId : null\n // 0.1.7 形状:ids 表达宿主列表成员(顺序权威),行数据在 byId 里\n if (Array.isArray(snap.ids)) {\n return snap.ids\n .map((id) => ({ id, ...rowFacts(byId?.[id]) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n // 只有 byId 的半成品形状:仍然可用,只是丢了宿主顺序\n if (byId) {\n return Object.keys(byId)\n .map((id) => ({ id, ...rowFacts(byId[id]) }))\n .filter((row) => typeof row.id === 'string' && row.id !== '')\n }\n return []\n}\n\n/**\n * 选出一个可用于执行命令的会话 id(即\"用户正在看的那个\")。\n *\n * 优先级:\n * 1. 旧形状的显式 `current`(≤0.1.6 的权威字段,保持原语义);\n * 2. `retainedBy.mainView > 0` 的会话(0.1.7 的权威判据,**跟随会话切换**);\n * 3. 第一个非 blank → 第一个(对两种形状都适用的兜底)。\n * @param {object|undefined|null} snap - `ctx.sessions.list.getSnapshot()`\n * @returns {string|null} 会话 id;拿不到返回 null(调用方据此显示「还没有会话」)\n */\nexport function pickSessionId(snap) {\n if (!snap || typeof snap !== 'object') return null\n if (typeof snap.current === 'string' && snap.current !== '') return snap.current\n const rows = sessionRows(snap)\n const live = rows.find((row) => row.mainView > 0)\n if (live) return live.id\n const chosen = rows.find((row) => !row.blank) ?? rows[0]\n return chosen ? chosen.id : null\n}\n","/**\n * Task Panel — dsh web `shell.overlay` 浮动任务面板。\n * Container 组件:负责数据获取、命令桥接、状态协调\n * Presentational 组件在 TaskComponents.tsx\n */\nimport { Component, useEffect, useRef, useState, type ReactNode } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\n// 图标走兼容层:0.1.5 用 IconXxx14/16,0.1.7+ 改成 IconXxxRegular + size prop\nimport {\n IconChevronDownOutline14,\n IconCloseOutline16,\n IconFolderOpenOutline16,\n IconQuestionOutline14,\n} from './icons.ts'\nimport { createTranslate, zh, en } from './locales.ts'\nimport { useTaskData, useTaskDataActions, taskDataStore, parseTaskPayloadText, type TaskStep } from './task-data-store.ts'\nimport { useTaskUI, useTaskUIActions, PANEL_VIEWS } from './task-ui-store.ts'\nimport { MiniBar, TaskCard } from './TaskComponents.tsx'\nimport { MemoryView, type InsightScope } from './MemoryView.tsx'\nimport { pickSessionId } from './session-id.js'\nimport css from './TaskPanel.module.css'\n\nconst NS = 'dsh-project-memory'\n\nconst STATUS_CYCLE = ['pending', 'in_progress', 'completed'] as const\n// 视图列表的唯一事实来源在 UI store(`/` 菜单那三行也读它);这里不再抄一份。\nconst VIEW_CYCLE = PANEL_VIEWS\n\nfunction getT(ctx: any) {\n const locale = ctx?.locale?.getSnapshot?.()?.active === 'zh' ? zh : en\n return createTranslate(locale)\n}\n\nfunction useSessionId(ctx: any): string | null {\n const [, force] = useState(0)\n useEffect(() => {\n const list = ctx?.sessions?.list\n if (!list || typeof list.subscribe !== 'function') return\n return list.subscribe(() => force((n) => n + 1))\n }, [ctx])\n // 快照结构在 dsh 0.1.7 变过(current/items → ids/byId):解析与兼容都在 session-id.js,\n // 那里有单测;这里只负责订阅与取值。\n return pickSessionId(ctx?.sessions?.list?.getSnapshot?.())\n}\n\nclass PanelErrorBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false }\n static getDerivedStateFromError() { return { failed: true } }\n componentDidCatch(error: unknown) {\n console.warn('[dsh-project-memory] task panel render crashed:', error)\n }\n render() {\n if (!this.state.failed) return this.props.children\n return (\n <button className={css.boundaryFallback} onClick={() => this.setState({ failed: false })} title=\"重新渲染任务面板\">\n 任务面板(点击重试)\n </button>\n )\n }\n}\n\nexport function TaskPanelEntry({ ctx }: { ctx: any }) {\n return (\n <PanelErrorBoundary>\n <TaskPanelView ctx={ctx} />\n </PanelErrorBoundary>\n )\n}\n\nfunction TaskPanelView({ ctx }: { ctx: any }) {\n const t = getT(ctx)\n const data = useTaskData()\n const ui = useTaskUI()\n const sessionId = useSessionId(ctx)\n const [syncing, setSyncing] = useState(false)\n const [syncedAt, setSyncedAt] = useState(0)\n const [syncError, setSyncError] = useState<string | null>(null)\n // 提示信息开关落在 UI store(持久化):关掉后面板内所有悬停 title 气泡都不再弹出。\n const showHints = ui.showHints\n const dataActions = useTaskDataActions()\n const uiActions = useTaskUIActions()\n // 视图页同样落在 UI store:`/` 菜单的三行是\"打开某一页\",它们必须能从这个组件外面切页。\n const view = ui.view\n const cycleView = () => {\n const i = VIEW_CYCLE.indexOf(view)\n uiActions.setView(VIEW_CYCLE[(i + 1) % VIEW_CYCLE.length])\n }\n const viewTitle =\n view === 'task' ? t('panel.title')\n : view === 'global' ? t('view.global')\n : t('view.project')\n\n const tasks = Array.isArray(data.tasks) ? data.tasks : []\n const activeTasks = tasks.filter((task) => !task.archived)\n const boundTask = data.boundTaskId ? tasks.find((task) => task.id === data.boundTaskId) ?? null : null\n\n const applyPayload = (text?: string): boolean => {\n const parsed = parseTaskPayloadText(text)\n if (!parsed) return false\n dataActions.setTasks({ tasks: parsed.tasks, boundTaskId: parsed.boundId, archivedCount: parsed.archived })\n setSyncedAt(Date.now())\n setSyncError(null)\n return true\n }\n\n const runLine = async (line: string): Promise<boolean> => {\n const commands = ctx?.remote?.commands\n if (!sessionId || !commands || typeof commands.execute !== 'function') {\n setSyncError('no session / commands service')\n return false\n }\n let response: any\n try {\n response = await commands.execute(sessionId, line, [])\n } catch (err) {\n setSyncError(String((err as { message?: unknown } | null | undefined)?.message ?? err))\n return false\n }\n const envelope = response as { ok?: boolean; value?: any } | null | undefined\n const execution = envelope && typeof envelope === 'object' && 'value' in envelope ? envelope.value : envelope\n const result = execution?.result ?? execution\n if (result?.kind === 'error') {\n setSyncError(result.text ?? 'command error')\n return false\n }\n return applyPayload(result?.text)\n }\n\n const refresh = async (): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n const prevBoundId = data.boundTaskId\n await runLine('/tasks')\n const newBoundId = taskDataStore.getSnapshot().boundTaskId\n if (newBoundId && newBoundId !== prevBoundId) {\n await runLine(`/tasks switch ${newBoundId}`)\n }\n } finally {\n setSyncing(false)\n }\n }\n\n const handleAction = async (verb: 'switch' | 'archive', taskId: string): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n await runLine(`/tasks ${verb} ${taskId}`)\n } finally {\n setSyncing(false)\n }\n }\n\n // v0.5:任务卡内联记忆动作(confirm/promote/delete 于 /insight task 层),随后刷新任务数据\n const handleInsightTask = async (action: 'confirm' | 'promote' | 'delete', id: string): Promise<void> => {\n if (syncing) return\n setSyncing(true)\n try {\n await runLine(`/tasks insight ${action} task ${id}`)\n await refresh()\n } finally {\n setSyncing(false)\n }\n }\n\n const pushSteps = (taskId: string, steps: TaskStep[]): void => {\n void runLine(`/tasks todos ${JSON.stringify(steps.map((s) => ({ content: s.content, status: s.status })))}`)\n }\n\n const cycleStatus = (taskId: string, index: number) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n if (!task) return\n const steps = task.steps || []\n const next = steps.map((s, i) => {\n if (i !== index) return s\n const cur = STATUS_CYCLE.indexOf(s.status)\n return { ...s, status: STATUS_CYCLE[(cur + 1) % STATUS_CYCLE.length] }\n })\n pushSteps(taskId, next)\n }\n\n const commitStepText = (taskId: string, index: number, value: string) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n const trimmed = value.trim()\n if (!task) return\n const same = (task.steps || [])[index]?.content === trimmed\n if (same || !trimmed) return\n const next = (task.steps || []).map((s, i) => (i === index ? { ...s, content: trimmed } : s))\n pushSteps(taskId, next)\n }\n\n const reorderSteps = (taskId: string, fromIndex: number, toIndex: number) => {\n if (fromIndex === toIndex) return\n const task = data.tasks.find((tt) => tt.id === taskId)\n if (!task) return\n const steps = [...(task.steps || [])]\n const [moved] = steps.splice(fromIndex, 1)\n const targetIndex = toIndex > fromIndex ? toIndex - 1 : toIndex\n steps.splice(targetIndex, 0, moved)\n pushSteps(taskId, steps)\n }\n\n const commitTitle = (taskId: string, value: string) => {\n const task = data.tasks.find((tt) => tt.id === taskId)\n const trimmed = value.trim()\n if (!task) return\n const same = task.title === trimmed\n if (same || !trimmed) return\n void runLine(`/tasks rename ${taskId} ${JSON.stringify(trimmed)}`)\n }\n\n const expand = () => {\n uiActions.open()\n if (Date.now() - Math.max(data.lastUpdate, syncedAt) > 30_000) {\n void refresh()\n }\n }\n\n const THEMES = ['native', 'glass', 'brutal', 'mono'] as const\n const style = (THEMES as readonly string[]).includes(ui.theme) ? ui.theme : 'native'\n const styleLabel = t(`style.${style}` as keyof typeof zh)\n const cycleTheme = () => {\n const i = THEMES.indexOf(style as (typeof THEMES)[number])\n uiActions.setTheme(THEMES[(i + 1) % THEMES.length])\n }\n\n const panelRef = useRef<HTMLDivElement>(null)\n const drag = useRef<{ dx: number; dy: number } | null>(null)\n\n const handleDragStart = (e: React.MouseEvent) => {\n if (e.target !== e.currentTarget) return\n const rect = panelRef.current?.getBoundingClientRect()\n if (!rect) return\n drag.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top }\n const onMove = (ev: MouseEvent) => {\n if (!drag.current) return\n const width = panelRef.current?.offsetWidth ?? 380\n const height = panelRef.current?.offsetHeight ?? 480\n const x = Math.max(8, Math.min(window.innerWidth - width - 8, ev.clientX - drag.current.dx))\n const y = Math.max(8, Math.min(window.innerHeight - 64, ev.clientY - drag.current.dy))\n uiActions.setPanelPosition({ x, y })\n }\n const onUp = () => {\n drag.current = null\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n }\n\n // 会话切换时仅同步数据,不自动打开面板\n useEffect(() => {\n if (!sessionId) return\n // 仅当面板已打开时才自动刷新\n if (!ui.closed) {\n void refresh()\n }\n }, [sessionId])\n\n // 监听模型工具请求打开面板\n useEffect(() => {\n const ctxWithEvents = ctx\n const handler = () => {\n uiActions.open()\n if (Date.now() - Math.max(data.lastUpdate, syncedAt) > 30_000) {\n void refresh()\n }\n }\n ctxWithEvents?.events?.on?.('dsh:task-panel:show', handler)\n return () => {\n ctxWithEvents?.events?.off?.('dsh:task-panel:show', handler)\n }\n }, [ctx, uiActions, data.lastUpdate, syncedAt, refresh])\n\n // 彻底隐藏:不渲染任何东西\n if (ui.closed) {\n return null\n }\n\n // 折叠态:迷你条\n if (ui.minimized) {\n const label = boundTask\n ? `${t('minibar.current')}: ${boundTask.title}`\n : activeTasks.length > 0\n ? `${t('minibar.current')}: ${activeTasks.length} ${t('minibar.tasks')}`\n : t('minibar.no-task')\n return (\n <MiniBar\n label={label}\n hint={t('minibar.click-expand')}\n showHints={showHints}\n position={ui.panelPosition}\n theme={style}\n onMove={uiActions.setPanelPosition}\n open={expand}\n />\n )\n }\n\n const doneCount = activeTasks.filter((task) => {\n const steps = task.steps || []\n return steps.length > 0 && steps.every((s) => s.status === 'completed')\n }).length\n\n return (\n <div\n className={css.panel}\n ref={panelRef}\n style={{ left: ui.panelPosition.x, top: ui.panelPosition.y }}\n data-theme={style === 'native' ? undefined : style}\n >\n <div className={css.dragHandle} onMouseDown={handleDragStart} title={showHints ? t('task.drag') : undefined}>\n <div className={css.handleGrip} />\n </div>\n <header className={css.header}>\n <div className={css.headerLeft}>\n <Button\n type=\"button\"\n className={css.headerIconBtn}\n onClick={cycleTheme}\n title={showHints ? styleLabel : undefined}\n aria-label={styleLabel}\n >\n <IconFolderOpenOutline16 className={css.headerIcon} />\n </Button>\n <h2 className={css.headerTitle}>{viewTitle}</h2>\n </div>\n <div className={css.headerRight}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={cycleView}\n aria-label={t('view.cycle')}\n title={showHints ? `${t('view.cycle')}(${view} → ${VIEW_CYCLE[(VIEW_CYCLE.indexOf(view) + 1) % VIEW_CYCLE.length]})` : undefined}\n >\n {/* lucide notebook-tabs(视图循环图标) */}\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M2 6h4\" />\n <path d=\"M2 10h4\" />\n <path d=\"M2 14h4\" />\n <path d=\"M2 18h4\" />\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <path d=\"M15 2v20\" />\n <path d=\"M15 7h5\" />\n <path d=\"M15 12h5\" />\n <path d=\"M15 17h5\" />\n </svg>\n </Button>\n {view === 'task' && (\n <span className={css.counts}>\n {activeTasks.length > 0\n ? `${t('panel.active')} ${activeTasks.length} · ${doneCount}/${activeTasks.length}`\n : ''}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className={showHints ? undefined : css.hintsOff}\n onClick={() => uiActions.toggleHints()}\n aria-pressed={!showHints}\n aria-label={showHints ? t('panel.hints-off') : t('panel.hints-on')}\n title={showHints ? t('panel.hints-off') : t('panel.hints-on')}\n >\n <IconQuestionOutline14 size={16} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => uiActions.minimize()}\n aria-label={t('panel.minimize')}\n title={showHints ? t('panel.minimize') : undefined}\n >\n <IconChevronDownOutline14 />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => uiActions.close()}\n aria-label={t('panel.close')}\n title={showHints ? t('panel.close') : undefined}\n >\n <IconCloseOutline16 />\n </Button>\n </div>\n </header>\n\n {!sessionId && <div className={css.notice}>{t('panel.no-session')}</div>}\n {syncError && <div className={css.notice}>{t('panel.sync-failed')}: {syncError}</div>}\n\n {view !== 'task' ? (\n <MemoryView ctx={ctx} sessionId={sessionId} scope={view as InsightScope} boundTaskId={data.boundTaskId} showHints={showHints} t={t} />\n ) : activeTasks.length === 0 ? (\n <div className={css.emptyState}>\n <p className={css.emptyTitle}>{t('panel.empty')}</p>\n <p className={css.emptyDesc}>{t('panel.empty-desc')}</p>\n {syncing && <p className={css.syncHint}>{t('panel.syncing')}</p>}\n </div>\n ) : (\n <div className={css.taskList}>\n {activeTasks.map((task) => {\n const steps = task.steps || []\n const expanded = ui.expandedTaskIds.includes(task.id)\n const isBound = data.boundTaskId === task.id\n return (\n <TaskCard\n key={task.id}\n task={task}\n isBound={isBound}\n expanded={expanded}\n onToggleExpand={() => uiActions.toggleTaskExpanded(task.id)}\n onSwitch={() => handleAction('switch', task.id)}\n onUnbind={() => runLine('/tasks unbind')}\n onArchive={() => handleAction('archive', task.id)}\n onRename={(value) => commitTitle(task.id, value)}\n onEditStep={(index, value) => commitStepText(task.id, index, value)}\n onCycleStatus={(index) => cycleStatus(task.id, index)}\n onReorderSteps={(from, to) => reorderSteps(task.id, from, to)}\n onInsightAction={(action, id) => void handleInsightTask(action, id)}\n showHints={showHints}\n syncing={syncing}\n t={t}\n />\n )\n })}\n {syncing && <div className={css.syncHint}>{t('panel.syncing')}</div>}\n </div>\n )}\n </div>\n )\n}","/**\n * /tasks、/task、/insight 命令在会话中的节点渲染器(conversation.chat.commandview,按命令名 key)。\n * 列表型命令(/tasks、无动词 /task、/insight list)只显示一行摘要;/insight 的动作类只显示一句结果——\n * 目的:大 JSON 载荷绝不整段渲染进对话(否则切视图会刷屏)。\n */\nimport { useEffect, useRef } from 'react'\nimport { IconFolderOpenOutline16 } from './icons.ts'\nimport { parseTaskPayloadText, taskDataStore } from './task-data-store.ts'\nimport { parseInsightPayloadText } from './MemoryView.tsx'\nimport { taskUIStore } from './task-ui-store.ts'\nimport css from './TaskCommandNode.module.css'\n\nexport function TaskCommandNode({ node }: { node?: any }) {\n const name = node?.name ?? 'task'\n const outcome = node?.outcome ?? null\n const args = typeof node?.args === 'string' ? node.args : ''\n const verb = args.trim().split(/\\s+/)[0] ?? ''\n const isList = name === 'tasks' || !verb\n const text = outcome?.text ?? ''\n\n const parsedTasks = name !== 'insight' ? parseTaskPayloadText(text) : null\n const parsedInsights = name === 'insight' ? parseInsightPayloadText(text) : null\n\n // 该节点是否“现场执行”(挂载时处于执行中):为 true 说明是用户当场输入的命令,\n // 完成后同步数据并打开面板。刷新/切换会话后历史节点以完成态重挂载,\n // 此时只做展示、不再写数据/开面板(面板保持关闭,与“刷新后不显示”一致)。\n const live = useRef(outcome === null)\n\n // 载荷进数据 store;列表型任务命令(/tasks、无动词 /task)同步数据并打开面板\n useEffect(() => {\n if (!parsedTasks || !live.current) return\n taskDataStore.actions.setTasks({\n tasks: parsedTasks.tasks,\n boundTaskId: parsedTasks.boundId,\n archivedCount: parsedTasks.archived,\n })\n if (isList) taskUIStore.actions.open()\n }, [text])\n\n if (outcome === null) {\n return <div className={css.row} data-variant=\"running\">/{name} 执行中…</div>\n }\n\n if (outcome.kind === 'error') {\n const brief = String(text ?? '').split('\\n')[0].slice(0, 120)\n return <div className={css.row} data-variant=\"error\">/{name} 失败{brief ? `:${brief}` : ''}</div>\n }\n\n // /insight:列表只显示一行摘要,动作类只显示一句结果(永不整段渲染)\n if (name === 'insight') {\n if (verb === 'list' && parsedInsights) {\n const scope = parsedInsights.scope\n const count = parsedInsights.count ?? parsedInsights.items.length\n return (\n <div className={css.row} data-variant=\"ok\">\n <IconFolderOpenOutline16 className={css.icon} />\n <span>记忆 {scope} · {count} 条 · 已同步到记忆视图</span>\n </div>\n )\n }\n const note = String(text ?? '').split('\\n')[0].slice(0, 120)\n return <div className={css.row} data-variant=\"ok\">/insight {verb} {note || '已完成'}</div>\n }\n\n if (!isList) {\n const note = String(text ?? '')\n .split(/\\n{2,}/)[0]\n .replace(/```.*$/s, '')\n .trim()\n .slice(0, 200)\n return <div className={css.row} data-variant=\"ok\">/{name} {note || '已完成'}</div>\n }\n\n const count = parsedTasks ? parsedTasks.tasks.length : 0\n const archived = parsedTasks ? parsedTasks.archived : 0\n const label = parsedTasks\n ? `任务 ${count} 套${archived ? `(归档 ${archived})` : ''} · 已同步到任务面板`\n : `/${name} 已执行`\n return (\n <div className={css.row} data-variant=\"ok\">\n <IconFolderOpenOutline16 className={css.icon} />\n <span>{label}</span>\n </div>\n )\n}","/**\n * `show_task_panel` 工具调用的会话内视图 —— 它的作用就是**把面板打开**。\n *\n * 为什么这件事必须在这里做:面板的显示状态(closed / minimized)是**浏览器侧**的\n * (`task-ui-store.ts`),宿主进程碰不到它。宿主侧原本写的是\n * `exec.ctx.events.emit('dsh:task-panel:show')`,而宿主契约里根本没有 `ctx`:\n *\n * packages/core/tools/src/index.ts:418\n * export interface ToolRunContext extends ToolExecution {\n * deferContext(context: UserMessage): void\n * concludeTurn(): void\n * }\n *\n * 于是那个工具每次都只返回「无法获取上下文」,面板从来不会打开 —— 插件里唯一的\n * 宿主命令之外,这是第二个\"写了但没生效\"的面(详见 CHANGELOG 0.5.14)。\n *\n * 正确的位置是宿主给出的扩展点:`ui-tool` 注册了 `conversation.chat.node`(key `tool-call`),\n * 其下有个按**工具名**分发的子槽 `tool.call.toolview`(契约原文:*Any name is allowed,\n * including tools registered by your package. Register with `key: '<tool name>'`*)。\n * 在这里认领 `show_task_panel` 这个 key,工具结果一渲染就把面板打开。\n */\nimport { useEffect, useRef } from 'react'\nimport { taskUIStore } from './task-ui-store.ts'\n\n/**\n * 只在**现场执行**时打开面板。\n *\n * 历史节点在刷新 / 切换会话后挂载时会**直接**处于 `result` 阶段;现场调用则会先经过\n * `preparing` / `start`。这与 `/tasks` 命令节点用的判据同款(见 `TaskCommandNode.tsx`\n * 的 `live` ref):刷新后只展示、不再开面板,否则每次打开会话都会弹一次面板。\n */\nexport function ShowTaskPanelNode(props: any) {\n const phase = props?.phase\n const live = useRef(phase !== 'result')\n useEffect(() => {\n if (phase !== 'result' || !live.current) return\n live.current = false\n taskUIStore.actions.open()\n }, [phase])\n // 不渲染任何行:认领 key 会**替换**通用工具行,而这次调用的全部意义就是开面板,\n // 留一行\"打开面板\"的噪音不如让面板自己说话。\n return null\n}\n\n/** 把 `show_task_panel` 的视图注册进宿主的 `tool.call.toolview` 槽。 */\nexport function registerShowTaskPanelView(slots: any): void {\n slots.inject('tool.call.toolview', () => slots.register(\n { name: 'tool.call.toolview', key: 'show_task_panel' },\n ShowTaskPanelNode,\n ))\n}\n","/**\n * 自建 `/` 触发器源:把工作流的三个视图入口收进一个带图标和小节标题的「工作流」组。\n *\n * 为什么必须自建源:`/` 菜单里的「分组」就是触发器源(ui-input-trigger 的 roster),\n * 而宿主 ui-commands 给目录行装配外观时只认第一方 definitionId 白名单\n * (presentation.ts 的 HOST_FACES / SECTION_ROWS),且宿主 CommandDescriptor 只有\n * name/description/input —— 没有 icon、没有分组、没有隐藏开关。第三方宿主命令因此\n * 永远只是「指令」小节末尾一行纯文字。\n *\n * 两个宿主约束决定了这里的写法:\n * 1. **分组标题走候选的 `section`,不走 `slash.menu` 词典。** 组标题查的是 `slash.menu`\n * namespace,而它由 ui-input-trigger 独占:`register('slash.menu','zh')` 会抛\n * \"already has locale\",未知 key 则原样回显源名。MenuView 在「组内任一行带 section」时\n * 干脆不渲染组标题行,只渲染 section 标题 —— 于是标题文案回到我们手里,还能按语言切换。\n * 2. **只做增量,不抢宿主的分发。** 这里不实现 matchSpace / matchEnter,所以手敲 `/tasks`、\n * 面板调 remote.commands.execute 全部走宿主原有路径。本源只是往菜单里多添一组行。\n *\n * 与「指令」组的重复:合并前插件注册了 /tasks、/task、/insight 三条宿主命令,菜单里就是三行\n * 去不掉的原始行 —— 宿主命令只要注册就会出现在目录里,`commands.list()` 与\n * `commands.execute()` 读同一个视图,`CommandDefinition` 也没有 hidden 字段,插件无法隐藏。\n * 现在宿主只剩一条 /tasks(见 src/commands/workflow.js),重复降到一行;那一行是插件执行\n * 宿主侧工作的唯一通道(插件没有自己的 client→host RPC)。\n *\n * **这三行不发命令。** 它们是「打开面板的某一页」,而面板的 `closed` / `view` 是浏览器侧\n * UI store 的状态 —— 宿主命令碰不到。旧实现绕了一圈 `remote.commands.execute('/tasks insight\n * list project')`:命令确实在宿主执行了,但客户端渲染命令节点的是按**命令名**分发的\n * `TaskCommandNode`(`name === 'tasks'`),它拿任务解析器去解记忆载荷 → 解析失败 → 面板毫无\n * 变化。于是用户看到的就是\"点了没反应\"。现在直接调 `openView(view)`。\n */\nimport type { ComponentType } from 'react'\nimport { createTranslate, en, zh } from './locales.ts'\nimport type { PanelView } from './task-ui-store.ts'\nimport { IconChecklistOutline16, IconGlobeOutline16, IconLightOutline16 } from './icons.ts'\n\n/** 源的稳定标识:同一 trigger 内唯一,重复注册会抛错。 */\nexport const SLASH_SOURCE_NAME = 'project-memory'\n\n/**\n * 组的排序权重(越小越靠前,未设时默认 0)。\n * 宿主内置源都取默认 0,所以 1 = 一定排在「指令 / 技能 / 子智能体」之后。\n * 没有能同时满足「在宿主之后」与「在所有其他插件之前」的取值:其他插件若也留默认 0\n * 就会排在我们前面。1 是最接近的折中,且不会去抢宿主主位置。\n */\nexport const SLASH_SOURCE_ORDER = 1\n\n/** 一行候选:候选 name 与标题同源(本地化文本),名称即身份、即标题。 */\ninterface SlashRow {\n /** 词典 key:既作候选 name(组内唯一身份)也作行标题。 */\n readonly labelKey: string\n /** 行描述词典 key。 */\n readonly descriptionKey: string\n /** 行图标;图标名按宿主版本自适应,见 icons.ts。 */\n readonly icon: ComponentType<{ size?: number; className?: string }>\n /** 额外搜索词:候选 name 是中文,拉丁输入(task / memory…)靠这些命中。 */\n readonly match: readonly string[]\n /** 点击后经 remote.commands.execute 执行的完整命令行。 */\n /** 点击后要打开的面板视图页。**纯客户端动作**,不绕宿主命令。 */\n readonly view: PanelView\n}\n\n/** 菜单三行。顺序即渲染顺序;标题复用面板已有的 view.* 文案,保证与面板视图名一致。 */\nconst ROWS: readonly SlashRow[] = [\n {\n labelKey: 'view.task',\n descriptionKey: 'slash.tasks-desc',\n icon: IconChecklistOutline16,\n match: ['tasks', 'task'],\n view: 'task',\n },\n {\n labelKey: 'view.project',\n descriptionKey: 'slash.project-desc',\n icon: IconLightOutline16,\n match: ['memory', 'project', 'insight'],\n view: 'project',\n },\n {\n labelKey: 'view.global',\n descriptionKey: 'slash.global-desc',\n icon: IconGlobeOutline16,\n match: ['memory', 'global', 'insight'],\n view: 'global',\n },\n]\n\n/** 本插件的 client 上下文投影:只看得到这几个能力,避免把整个 cordis ctx 传进来。 */\nexport interface SlashSourceDeps {\n /** 会话服务(`sessions`):把 sessionId 换回会话 scope,用于消费触发 token。 */\n readonly sessions: any\n /** 打开面板并切到指定页(`taskUIStore.actions.openView`)。注入而非直接 import,\n * 这样源本身可以在最小替身里单测,不需要真的挂一个 React 面板。 */\n openView(view: PanelView): void\n}\n\n/** 翻译函数签名(key 来自 ROWS,不是字面量,故不做类型约束)。 */\ntype Translate = (key: string, params?: Record<string, string | number>) => string\n\n/** 按当前语言取翻译函数。 */\nfunction translator(ctx: any): Translate {\n const dict = ctx?.locale?.getSnapshot?.()?.active === 'zh' ? zh : en\n return createTranslate(dict) as unknown as Translate\n}\n\n/**\n * 一轮候选:把三行装配成菜单行,再按查询与位置过滤。\n *\n * 三行都不接参数(动作全在面板卡片里),所以位置过滤只做一件事:行内出现的 `/` 多半是路径,\n * 不弹这一整组(宿主对无 input 命令在前导/行内都放行,这里更保守)。\n * @param t - 翻译函数。\n * @param req - 宿主给的候选请求(query / position)。\n * @returns 菜单行;永不抛出。\n */\nexport function buildSlashCandidates(t: Translate, req: any): readonly Record<string, unknown>[] {\n if (req?.position !== undefined && req.position !== 'leading') return []\n const query = typeof req?.query === 'string' ? req.query.trim().toLowerCase() : ''\n const rows = ROWS.map((row) => {\n const title = t(row.labelKey)\n return {\n name: title,\n // label 与 name 相同 → MenuView 不渲染尾随别名(这些是视图入口,不是命令名)\n label: title,\n description: t(row.descriptionKey),\n icon: row.icon,\n // 每一行都带 section → MenuView 不渲染组标题行,只渲染这个标题。\n section: t('slash.group'),\n // **不带 line**:这三行不是命令,是打开面板某一页;动作在 onPick 里按 name 查表得到。\n terms: [title, ...row.match].map((term) => term.toLowerCase()),\n }\n })\n return rows\n .filter((row) => query === '' || row.terms.some((term) => term.startsWith(query)))\n .map(({ terms: _terms, ...candidate }) => candidate)\n}\n\n/**\n * 把触发 token 从草稿里删掉(span 做 CAS:草稿被改过就拒绝,什么都不动)。\n * 这是宿主 command 源消费菜单点击的同一条契约事件。\n * @returns true 表示确实消费掉了。\n */\nfunction consumeSpan(deps: SlashSourceDeps, pick: any): boolean {\n try {\n const scope = deps.sessions?.scope?.(pick?.session?.sessionId)\n if (!scope || typeof scope.bail !== 'function') return false\n return scope.bail(scope, 'slash/input-consume-token', {\n guard: { kind: 'span', span: pick.span },\n }) === true\n } catch (err) {\n console.warn('[dsh-project-memory] slash token consume failed:', err)\n return false\n }\n}\n\n/**\n * 一次菜单点击:消费掉触发 token 后**直接打开面板的对应页**。\n *\n * 这三行是「打开某个视图」,不是「执行某条命令」,所以走客户端自己的 UI store:\n * 面板的 `closed` / `view` 都是浏览器侧状态,宿主命令碰不到它们。旧实现执行\n * `remote.commands.execute('/tasks insight list project')`,只在对话里留下一个命令节点,\n * 而客户端渲染命令节点的是按**命令名**分发的 `TaskCommandNode`(`name === 'tasks'`),\n * 它拿任务解析器去解记忆载荷 → 解析失败 → 对面板零影响。**这就是\"点了没反应\"的原因。**\n *\n * 不返回 claim(回填 `/xxx ` 再等回车):claim 会多要一次回车,而这三行没有参数要填。\n * 消费失败时仍然切页 —— 草稿里残留的触发文本要用户自己清掉,比\"点了完全没反应\"好。\n * @param t - 翻译函数(按当前语言把候选 name 映射回 ROWS)。\n * @param deps - 会话服务与 UI store 动作。\n * @param pick - 宿主给的点击载荷。\n * @returns PickOutcome;拿不到可用形状时返回 undefined(菜单照常关闭,草稿不动)。\n */\nexport function dispatchSlashPick(t: Translate, deps: SlashSourceDeps, pick: any): unknown {\n const title = pick?.candidate?.name\n if (typeof title !== 'string' || title === '') return undefined\n const row = ROWS.find((candidate) => t(candidate.labelKey) === title)\n if (row === undefined) return undefined\n consumeSpan(deps, pick)\n try {\n deps.openView(row.view)\n } catch (err) {\n console.warn(`[dsh-project-memory] open view ${row.view} failed:`, err)\n }\n return 'handled'\n}\n\n/**\n * 造出注册给 `ctx.inputTriggers.registerSource` 的源对象。\n * @param ctx - client 根上下文(只读 locale)。\n * @param deps - 会话服务与命令执行通道。\n * @returns 触发器源;只依赖宿主的公开契约字段。\n */\nexport function createSlashSource(ctx: any, deps: SlashSourceDeps): Record<string, unknown> {\n const t = translator(ctx)\n return {\n trigger: '/',\n name: SLASH_SOURCE_NAME,\n order: SLASH_SOURCE_ORDER,\n // 组标题不渲染:行上都有 section,MenuView 会用 section 标题取代它。\n showGroupTitle: false,\n candidates: async (_session: unknown, req: any) => buildSlashCandidates(t, req),\n onPick: (pick: any) => dispatchSlashPick(t, deps, pick),\n }\n}\n","/**\n * dsh-project-memory Client Entry\n *\n * dsh web (rc.1) 的 client 插件契约为 cordis client plugin:\n * export const inject = [<client 服务名>...]\n * export function apply(ctx) { ... }\n * 面板注册进 `shell.overlay`(Frame 级浮动层,additive 列表槽):\n * 该槽由 ui-layout 的 AppFrame 声明渲染(scope root,独立于滚动容器),\n * 默认 click-through,条目自身需开启 pointer-events。\n *\n * 只依赖宿主 seed 提供的模块(react / dsh-client-ui-primitives),\n * 数据经 remote.commands.execute 执行 /tasks 命令获取 JSON 快照。\n *\n * 另有一个可选增强:自建的 `/` 菜单源(slash.ts),把三条命令收进一个带图标和\n * 小节标题的「工作流」组。它**整体是可选的**——宿主没有 slash 触发器服务时静默跳过。\n */\nimport { createElement } from 'react'\nimport { TaskPanelEntry } from './TaskPanel.tsx'\nimport { TaskCommandNode } from './TaskCommandNode.tsx'\nimport { registerShowTaskPanelView } from './ShowTaskPanelNode.tsx'\nimport { taskUIStore } from './task-ui-store.ts'\nimport { createSlashSource } from './slash.ts'\n\nconst NS = 'dsh-project-memory'\n\nexport const name = NS\n\n/** Required client services: slots registry, session scopes, commands remote (data 通道). */\nexport const inject = ['slots', 'sessions', 'remote', 'remote.commands', 'locale']\n\n/**\n * 注册自建的 `/` 菜单源(见 slash.ts)。\n *\n * 整段都是**可选增强**:宿主没有 `inputTriggers` 服务、或该服务换了契约时,绝不能因此\n * 让整个 client 插件挂掉——那会连任务面板一起消失。`inputTriggers` 因此不进顶层 `inject`\n * (顶层 inject 未满足时 cordis 根本不会调用 apply),而是走嵌套 inject + 两层 try/catch。\n * @param ctx - client 根上下文\n */\nfunction registerSlashSource(ctx: any): void {\n if (typeof ctx?.inject !== 'function') {\n console.warn(`[${NS}] host has no ctx.inject — slash menu group disabled`)\n return\n }\n try {\n ctx.inject(['inputTriggers', 'sessions', 'remote.commands'], (scope: any) => {\n try {\n const inputTriggers = scope?.inputTriggers\n if (!inputTriggers || typeof inputTriggers.registerSource !== 'function') {\n console.warn(`[${NS}] host has no inputTriggers.registerSource — slash menu group disabled`)\n return\n }\n const source = createSlashSource(scope, {\n sessions: scope.sessions,\n // 菜单行是「打开面板的某一页」:直接落到 UI store,不绕宿主命令\n // (面板的 closed/view 是浏览器侧状态,宿主命令碰不到)。\n openView: (view) => taskUIStore.actions.openView(view),\n })\n scope.effect(() => inputTriggers.registerSource(source), 'dsh-project-memory: slash source')\n } catch (err) {\n console.warn(`[${NS}] slash source registration failed:`, err)\n }\n })\n } catch (err) {\n console.warn(`[${NS}] slash source injection failed:`, err)\n }\n}\n\nexport function apply(ctx: any): void {\n const slots = ctx?.slots\n if (!slots || typeof slots.inject !== 'function') {\n console.warn(`[${NS}] host has no slots service — task panel disabled`)\n } else {\n try {\n slots.inject('shell.overlay', () => slots.register(\n {\n name: 'shell.overlay',\n id: 'dsh-project-memory-task-panel',\n order: 100, // 浮层顺序:低于 toast/弹窗即可,越高越靠后渲染\n },\n () => createElement(TaskPanelEntry, { ctx })\n ))\n\n // 会话内命令节点:按命令名 key 接管渲染,替换内置大段文本卡片\n // (文本含 JSON 载荷,只有面板需要它),避免载荷刷屏对话。\n // 合并后只剩一条用户命令 /tasks(子动词都记在同一个命令名下)。\n const nodeKeys = ['tasks']\n for (const key of nodeKeys) {\n slots.inject('conversation.chat.commandview', () => slots.register(\n { name: 'conversation.chat.commandview', key },\n TaskCommandNode\n ))\n }\n\n // 工具调用视图:`show_task_panel` 的唯一实际效果就是开面板,而面板状态在浏览器侧;\n // 宿主进程碰不到它(宿主契约里 `ToolRunContext` 没有 `ctx`)。认领这个**工具名**后,\n // 工具结果一渲染就把面板打开 —— 见 ShowTaskPanelNode.tsx。\n registerShowTaskPanelView(slots)\n } catch (err) {\n console.warn(`[${NS}] task panel registration failed:`, err)\n }\n }\n\n registerSlashSource(ctx)\n}\n"],"mappings":"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"}
|