fix: 遵守仓库硬约束(禁止修改 DSH 源码)——tasks.output 改为会话事件回放

- 回退对 harness peek 缝隙的依赖:输出查看不再调用注册表,改为从属主
  会话事件日志回放 task_output 的 tool/call+tool/result 对(模型已读内容)
- read:false 时面板提示「模型尚未读取」;'(no new output)' 增量与错误
  结果过滤;截断上限不变;kill 走注册表原生 API(缺席时 503)
- AGENTS.md 新增 §0 硬约束:禁止修改 DSH 源码、挂载只走 cordis.patch.yml
  + profile 机制;设计文档同步实施偏差
- 测试:tasks-routes 重写为回放语义(拼接/过滤/read 标志/截断/503),
  视图新增 read:false 提示用例;全量 369 通过
This commit is contained in:
Menghuan1918
2026-08-12 23:04:30 +08:00
parent 8c521be26e
commit b90251cce5
10 changed files with 304 additions and 166 deletions
+14 -11
View File
@@ -359,13 +359,13 @@ function CatalogRows({
/**
* The shared output dock of the tasks section: ONE pane at the bottom of the
* sidebar body (sticky, terminal-like) shows the SELECTED task's FULL
* accumulated output via the host's NON-CONSUMING peek (`tasks.output`),
* refreshed every {@link TASK_POLL_MS} while the task runs and the page is
* visible. The model's own `task_output` cursor is never touched, so
* watching a stream cannot steal the agent's bytes. A single dock — not a
* panel per row — keeps the task list compact and stable when many tasks
* are running.
* sidebar body (sticky, terminal-like) shows the SELECTED task's output as
* the MODEL has read it so far (replayed from the owner session's event
* log), refreshed every {@link TASK_POLL_MS} while the task runs and the
* page is visible. The model's `task_output` cursor is never touched — the
* pane can never steal the agent's bytes, and it stays empty until the
* agent reads the task. A single dock — not a panel per row — keeps the
* task list compact and stable when many tasks are running.
*/
function TaskOutputPane(props: {
ownerSessionId: string
@@ -437,7 +437,9 @@ function TaskOutputPane(props: {
<>
{state.text.length > 0
? <pre ref={preRef} className={css.tasksPanePre}>{state.text}</pre>
: <div className={css.tasksPaneHint}>{t('taskNoOutput')}</div>}
: state.read
? <div className={css.tasksPaneHint}>{t('taskNoOutput')}</div>
: <div className={css.tasksPaneHint}>{t('taskNotReadYet')}</div>}
{state.truncated && <div className={css.tasksPaneHint}>{t('taskOutputTruncated')}</div>}
</>
)}
@@ -448,9 +450,10 @@ function TaskOutputPane(props: {
/**
* The background-task section of the Subagent page: every task of the whole
* current tree (main agent + subagents, owner-labeled), fed by the harness
* `session/tasks` push mirror. Clicking a row feeds its output to the shared
* bottom dock (non-consuming peek); live rows carry a two-click-confirm
* kill button. Renders nothing while the tree has no tasks.
* `session/tasks` push mirror. Clicking a row feeds its model-read output to
* the shared bottom dock (event replay — never the model's cursor); live
* rows carry a two-click-confirm kill button. Renders nothing while the
* tree has no tasks.
*/
function TasksSection(props: {
byId: SidebarSessionList['byId']