dsh-plugin-agent-tree 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## 未发布
3
+ ## 0.1.1 — 2026-10-29
4
4
 
5
- - **「等你拍板」的会话不再消失**:读实时状态里的 `pendingInteraction`(`question` / `approval` / `plan-review`),这类会话即使没在跑也会列出,琥珀色圆点 + `待答 / 待批 / 待审` 徽标,排在在跑的前面;标题栏变成「N 个等你处理 · M 个在跑 · K 个定时」。
6
- - **定时任务显示修复**:`remote.schedule` 是别的客户端插件挂上来的命名空间服务,只读 `ctx.remote.schedule` 在它还没挂上时会拿到 undefined,导致定时任务整段消失;现在用 `ctx.get('remote.schedule')` 兜底并继续轮询。
7
- - **codex 行名改成会话标题**:从 rollout 里取第一条真实用户消息(跳过 `environment_context` / `AGENTS.md` 注入)当行名,取不到才回落目录名;右侧加灰色目录小标签;同 cwd 的多个 codex 进程按时间各认领一条会话,避免多行同名。
8
- - **codex 的子对话**:读 `~/.codex/sessions/**/rollout-*.jsonl` 的 `session_meta`,按 `parent_thread_id` 还原 subagent 线程树,挂在 codex 行下面(昵称 + agent 路径 + 最后活动时间 / `running`);按 cwd、cwd 前缀、桌面端 originator 三级匹配主线程。
9
- - 顶层改成「本机 agent 列表」:`dsh` 与 `claude` / `codex` 同级,各自展开自己的子树;行规格统一。
5
+ - **定时 / 循环任务加小闹钟**:挂了定时任务的会话,标题前固定有一个 `⏰`,右侧显示距下次触发的倒计时(`8m` / `2h` / `3d`)。
6
+ 刚触发过、倒计时到期的显示 `now`,但 `⏰` 不会消失——之前只有「还没到点」的行才有标记,正在跑或刚跑完的循环任务看起来和普通会话一样。
7
+ - 倒计时不再重复画 `⏱` 图标:图标统一挪到标题前,右侧只留数字。
10
8
 
11
- ## 0.1.0 — 2026-10-28
9
+ ## 0.1.0 — 2026-10-29
12
10
 
13
11
  首个公开版本。从「一个会话里翻着看 subagent 太累」长出来的一张小卡片。
14
12
 
@@ -22,6 +20,11 @@
22
20
  - **外部 agent 进程(带子树)**:宿主半部只读接口 `GET /local/dsh-agent-tree/processes`,用 `ps` + `lsof` 发现本机正在跑的 `claude` / `codex` CLI,并按 `ppid` 把它们的子进程挂成子树(同类子进程归组成 `computer use ×4` / `MCP ×3` 这样的行)。它们和 `dsh` 是**同级的顶层 agent 节点**(本机 agent 列表),用同一套行规格,可折叠。
23
21
  - **点击跳转**:点任意一行 → `subagentAddress` + `uiWorkspace.openSession` 跳到对应会话(含 subagent)。
24
22
  - **拖动与记忆**:拖标题栏移动,位置存 `localStorage`。
23
+ - **「等你拍板」的会话不再消失**:读实时状态里的 `pendingInteraction`(`question` / `approval` / `plan-review`),这类会话即使没在跑也会列出,琥珀色圆点 + `待答 / 待批 / 待审` 徽标,排在在跑的前面;标题栏变成「N 个等你处理 · M 个在跑 · K 个定时」。
24
+ - **定时任务显示修复**:`remote.schedule` 是别的客户端插件挂上来的命名空间服务,只读 `ctx.remote.schedule` 在它还没挂上时会拿到 undefined,导致定时任务整段消失;现在用 `ctx.get('remote.schedule')` 兜底并继续轮询。
25
+ - **codex 行名改成会话标题**:从 rollout 里取第一条真实用户消息(跳过 `environment_context` / `AGENTS.md` 注入)当行名,取不到才回落目录名;右侧加灰色目录小标签;同 cwd 的多个 codex 进程按时间各认领一条会话,避免多行同名。
26
+ - **codex 的子对话**:读 `~/.codex/sessions/**/rollout-*.jsonl` 的 `session_meta`,按 `parent_thread_id` 还原 subagent 线程树,挂在 codex 行下面(昵称 + agent 路径 + 最后活动时间 / `running`);按 cwd、cwd 前缀、桌面端 originator 三级匹配主线程。
27
+ - 顶层改成「本机 agent 列表」:`dsh` 与 `claude` / `codex` 同级,各自展开自己的子树;行规格统一。
25
28
 
26
29
  ### 健壮性
27
30
 
package/README.en.md CHANGED
@@ -19,6 +19,7 @@ at which depth, on which model, for how long, and when its next scheduled run fi
19
19
  - **Always-on entry** — idle collapses to `● Agent tree ▸`; work re-expands it; manual collapse wins.
20
20
  - **Color = depth** — green dot for top-level conversations, blue for level-2 subagents, violet for deeper ones, grey for finished rows.
21
21
  - **Per-row model chip** (right aligned) — from the session projection `modelSelection` (`next` → `lastUsed`), shortened to `v4.1-flash`; subagents without their own record inherit the parent's (tooltip says so).
22
+ - **Alarm clock on loop sessions** — any session driven by a schedule keeps a `⏰` in front of its title, with the countdown to the next run on the right (`8m` / `2h` / `3d`); a round that just fired shows `now` and still keeps the clock, so a running loop never looks like a plain conversation.
22
23
  - **Scheduled-task countdown** — reads `schedule.catalog()` from Automation tasks (the `remote.schedule` service, with a `ctx.get` fallback while its namespace is not mounted yet); sessions driven by a schedule are listed even while idle, with `⏱8m / ⏱2h / ⏱3d` and a `N running · M scheduled` headline.
23
24
  - **Sessions that need your call come first** — when an agent asks a question, waits for an approval, or waits for a plan review (`pendingInteraction` = `question` / `approval` / `plan-review`), that row turns **amber**, carries a `待答 / 待批 / 待审` badge and **sorts above running rows**. Previously such a session disappeared because it was no longer running.
24
25
  - **Local external agent processes, also as a tree** — the plugin's host half exposes a read-only endpoint that finds running **claude / codex CLIs** via `ps` + `lsof` and nests their children by `ppid` (e.g. codex's `computer use ×4` / `MCP ×3` / `code mode`). They show up as **top-level agents next to `dsh`**, with exactly the same row spec. ChatGPT desktop's `Codex Framework` helpers are not mistaken for CLIs themselves.
package/README.md CHANGED
@@ -83,6 +83,7 @@ dsh plugin --profile web add "$PWD"
83
83
  | `▾ ● codex 推进一下能推进的任务… devline` | codex 的**会话标题**(首条真实用户消息)+ 目录名;不是目录名兜底 |
84
84
  | `▾ ● claude proj-alpha 12m 3%` | 本机另一个 agent(和 `dsh` 同级):claude CLI,工作目录 `proj-alpha`,跑了 12 分钟、3% CPU |
85
85
  | `│ └─ computer use ×2 41m` | 它的子进程,自动按种类归组(`×N` + 最长的那个时长) |
86
+ | `├─ ⏰ 推进 backlog 任务并设循环 now` | 挂了定时 / 循环任务的会话:标题前固定一个小闹钟,右侧是距下次触发的倒计时(到期显示 `now`,闹钟不消失) |
86
87
  | `│ ├─ ● Hubble advance_review_logic running` | codex 的子对话(subagent 线程):昵称 + agent 路径,右边是「正在工作 / 最后活动多久前」 |
87
88
  | `会话 6 · 子代理 3 · 运行中 5(live)` | 自检:快照里的会话数 / 子代理数 / 运行中数量;`live` 表示官方实时状态流 |
88
89
 
package/client.js CHANGED
@@ -182,6 +182,22 @@ window.__ModuleLoader__.load({
182
182
  return map;
183
183
  }
184
184
 
185
+ /**
186
+ * 定时任务的行内标记:`mark` 放在标题前面当小闹钟,`label` 放在右侧当倒计时。
187
+ * 倒计时已经到期(`now`)时 label 仍然给 `now`,mark 不消失——一眼就知道这行是循环任务。
188
+ */
189
+ function scheduleMark(scheduled, now) {
190
+ if (scheduled === undefined || scheduled === null) return null;
191
+ const label = countdownLabel(scheduled.nextAt, now);
192
+ return {
193
+ mark: '\u23f0',
194
+ label,
195
+ title: `${scheduled.count} 个定时任务${
196
+ Number.isFinite(scheduled.nextAt) ? `,下次 ${new Date(scheduled.nextAt).toLocaleString()}` : ''
197
+ }`,
198
+ };
199
+ }
200
+
185
201
  /** 距离下次触发还有多久,比如 `8m` / `2h` / `3d`。 */
186
202
  function countdownLabel(nextAt, now) {
187
203
  if (!Number.isFinite(nextAt)) return '';
@@ -483,6 +499,24 @@ window.__ModuleLoader__.load({
483
499
  }
484
500
 
485
501
  /** 「等你拍板」的小徽标:琥珀色 `待答` / `待批` / `待审`。 */
502
+ /** 定时 / 循环任务的小闹钟。 */
503
+ function AlarmMark({ title }) {
504
+ return h(
505
+ 'span',
506
+ {
507
+ title,
508
+ style: {
509
+ flex: 'none',
510
+ fontSize: 9,
511
+ lineHeight: 1,
512
+ opacity: 0.75,
513
+ color: 'var(--dsw-alias-label-tertiary)',
514
+ },
515
+ },
516
+ '\u23f0',
517
+ );
518
+ }
519
+
486
520
  function WaitBadge({ kind }) {
487
521
  const info = WAIT[kind];
488
522
  if (!info) return null;
@@ -560,19 +594,16 @@ window.__ModuleLoader__.load({
560
594
  const expanded = !collapsedNodes[key];
561
595
  const own = modelLabel(node.row.projectionValues);
562
596
  const model = own || inheritedModel || '';
563
- const scheduled = node.schedule;
564
- const clock = scheduled
597
+ const schedule = scheduleMark(node.schedule, now);
598
+ const alarm = schedule ? h(AlarmMark, { title: schedule.title }) : null;
599
+ const clock = schedule
565
600
  ? h(
566
601
  'span',
567
602
  {
568
- title: `${scheduled.count} 个定时任务${
569
- Number.isFinite(scheduled.nextAt)
570
- ? `,下次 ${new Date(scheduled.nextAt).toLocaleString()}`
571
- : ''
572
- }`,
603
+ title: schedule.title,
573
604
  style: { flex: 'none', fontSize: 8.5, color: 'var(--dsw-alias-label-tertiary)' },
574
605
  },
575
- `⏱${countdownLabel(scheduled.nextAt, now)}`,
606
+ schedule.label,
576
607
  )
577
608
  : null;
578
609
 
@@ -619,6 +650,7 @@ window.__ModuleLoader__.load({
619
650
  : node.active
620
651
  ? h(Dot, { color: DOT.conversation, active: true })
621
652
  : null,
653
+ alarm,
622
654
  clampSpan(shortTitle(node.row), {
623
655
  fontSize: 10.5,
624
656
  fontWeight: node.waiting || node.active ? 600 : 500,
@@ -652,6 +684,7 @@ window.__ModuleLoader__.load({
652
684
  },
653
685
  glyph(connector),
654
686
  h(Dot, { color: node.waiting ? WAIT[node.waiting].color : color, active: node.active || Boolean(node.waiting) }),
687
+ alarm,
655
688
  clampSpan(shortTitle(node.row), {
656
689
  fontSize: 10.5,
657
690
  color: node.waiting
@@ -1253,6 +1286,7 @@ window.__ModuleLoader__.load({
1253
1286
  groupProcessChildren,
1254
1287
  modelLabel,
1255
1288
  toScheduleMap,
1289
+ scheduleMark,
1256
1290
  countdownLabel,
1257
1291
  formatElapsed,
1258
1292
  },
Binary file
package/docs/manual.en.md CHANGED
@@ -76,7 +76,7 @@ The `dsh` root row collapses every workspace at once; its right side shows the w
76
76
  | `▾ / ▸` | this row has children — expand / collapsed |
77
77
  | `●` | status dot, colored by depth (below) |
78
78
  | Title | session title (`displayTitle`), elided when long; running rows are bolder |
79
- | `⏱8m` | countdown to the next scheduled run: `now` / `<1m` / `8m` / `2h` / `3d` |
79
+ | `⏰` + `8m` | countdown to the next scheduled run: `now` / `<1m` / `8m` / `2h` / `3d` |
80
80
  | `v4.1-flash` | model chip (right aligned) from `modelSelection`, with `deepseek-` / `anthropic-` prefixes stripped |
81
81
  | `1m5s` | elapsed duration (subagent rows only): `45s` / `12m` / `1h5m` |
82
82
 
package/docs/manual.md CHANGED
@@ -8,11 +8,11 @@
8
8
  ├──────────────────────────────────────────────────┤
9
9
  │ ▾ ● dsh 2 个 workspace │ ← 顶层 agent:这个 DSH 实例
10
10
  │ ├─ ▾ proj-alpha 2 │ ← workspace
11
- │ │ ├─ ▾ ● Refactor billing flow ⏱8m v4.1-pro │ ← 对话(绿点)
11
+ │ │ ├─ ▾ ● ⏰ Refactor billing flow 8m v4.1-pro │ ← 对话(绿点,挂了定时)
12
12
  │ │ │ ├─ ● Explore repo structure 1m5s │ ← subagent(蓝点)
13
13
  │ │ │ │ └─ ● Run unit tests 9s │ ← 孙代理(紫点)
14
14
  │ │ │ └─ ● Write migration plan 31s │
15
- │ │ └─ Fix flaky login test ⏱2h v4.1-flash │ ← 有定时、当前空闲
15
+ │ │ └─ ⏰ Fix flaky login test 2h v4.1-flash │ ← 有定时、当前空闲
16
16
  │ ├─ ▾ my-repo 1 │
17
17
  │ │ └─ ● Triage CI failures v4.1-pro │
18
18
  │ ▾ ● claude proj-alpha 12m 3% │ ← 顶层 agent:本机 claude(和 dsh 同级)
@@ -78,7 +78,7 @@ dsh(这个实例) claude / codex(本机其它 agent)
78
78
  | `▾ / ▸` | 这一行有子代理,可展开 / 已收起 |
79
79
  | `●` | 状态点:颜色见下表 |
80
80
  | 标题 | 会话标题(`displayTitle`),过长省略;运行的会话字更粗更深 |
81
- | `⏱8m` | 定时任务的倒计时:`now` / `<1m` / `8m` / `2h` / `3d` |
81
+ | `⏰` + `8m` | 标题前的小闹钟表示这行挂了定时 / 循环任务;右侧是倒计时:`now` / `<1m` / `8m` / `2h` / `3d`(到期显示 `now`,闹钟不消失) |
82
82
  | `v4.1-flash` | 模型标签(右侧对齐):来自 `modelSelection`,`deepseek-` / `anthropic-` 前缀会去掉 |
83
83
  | `1m5s` | 运行或已运行时长(subagent 行才有):`45s` / `12m` / `1h5m` |
84
84
 
@@ -100,7 +100,12 @@ subagent 的 `modelSelection` 常常为空,这时用最近一个祖先会话
100
100
  ## 5. 定时任务行
101
101
 
102
102
  DSH 的 Automation tasks(`schedule.catalog()`)驱动的是「间歇式工作」的会话:它们大部分时间空闲,
103
- 到点自己跑一次。卡片会把这些会话**即使不在跑也列出来**,右侧 `⏱` 是下一次触发时间;
103
+ 到点自己跑一次。卡片会把这些会话**即使不在跑也列出来**:
104
+
105
+ - 标题前固定一个 `⏰`(小闹钟),一眼认出「这行是循环任务」;
106
+ - 右侧是距下次触发的倒计时;
107
+ - 刚跑完、倒计时到期时显示 `now`,但 `⏰` 保持——正在跑的循环任务不会看起来像普通会话。
108
+
104
109
  点它同样能跳过去看上一次跑出来的东西。
105
110
 
106
111
  ## 6. 本机外部 agent(和 dsh 同级)
@@ -113,7 +118,8 @@ DSH 的 Automation tasks(`schedule.catalog()`)驱动的是「间歇式工作
113
118
  ▾ ● codex ChatGPT 69h35m 2%
114
119
  ```
115
120
 
116
- - `label` 的取值顺序:进程真实 cwd 的目录名 → 命令行里的 `--cwd/--cd/-C` → `ChatGPT`(桌面端 backend)→ 空。
121
+ - 行名(`label`)的取值顺序:该 codex 会话的第一条真实用户消息(跳过 `environment_context` / `AGENTS.md` 注入)
122
+ → 进程真实 cwd 的目录名 → 命令行里的 `--cwd/--cd/-C` → `ChatGPT`(桌面端 backend)→ 空。
117
123
  - 只显示前 8 条;结果缓存 3 秒;接口需要登录态(未登录 401)。
118
124
  - 目的是「我在 DSH 里干活时,本机还有没有别的 agent 在偷偷跑」;点这一行可折叠子树。
119
125
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-agent-tree",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "DSH Web mini agent tree: a tiny always-on floating card showing workspace → conversation → subagent as a live tree, with per-row model, scheduled-task countdowns, and external claude/codex CLI processes.",
5
5
  "keywords": [
6
6
  "dsh",