dsh-agent-lines 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.en.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  English | [中文](CHANGELOG.md)
4
4
 
5
+ ## 0.3.3 (2026-11-04)
6
+
7
+ - Scenario-first landing page: hero, three cards, four-step real usage, first-use claim prompt, restart note.
8
+ - Landing page and social-preview are now included in the npm package and GitHub Release artifact.
9
+ - No runtime behavior change; schema remains v6.
10
+
11
+ ## 0.3.2 (2026-11-04)
12
+
13
+ - Zero-config bootstrap: with no plugin config, start one unbound manager line; a root Session can call line_claim_manager to bind itself.
14
+ - Default DB path follows DSH_HOME; without it, still ~/.dsh/agent-lines/lines.db.
15
+ - README now requires a DSH Web restart after install/update; explicit manager/worker config is optional.
16
+ - No schema change; remains v6.
17
+
5
18
  ## 0.3.1 (2026-11-04)
6
19
 
7
20
  - README is now user-first: scenarios and install come first; technical details are later.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  [English](CHANGELOG.en.md) | 中文
4
4
 
5
+ ## 0.3.3 (2026-11-04)
6
+
7
+ - 落地页改为场景化:hero、三张卡、一个真实用法四步、首次使用含 line_claim_manager、重启提示。
8
+ - 落地页与 social-preview 同步进入 npm 包和 GitHub Release 制品。
9
+ - 无运行时行为变化;schema 仍为 v6。
10
+
11
+ ## 0.3.2 (2026-11-04)
12
+
13
+ - 零配置启动:没有 plugin config 时自动启动一条未绑定 manager,根会话可调用 line_claim_manager 自己绑定。
14
+ - 默认 DB 路径跟随 DSH_HOME;未设置时仍为 ~/.dsh/agent-lines/lines.db。
15
+ - README 明确:安装或更新后必须重启 DSH Web;显式 manager/worker 配置变为可选。
16
+ - 无 schema 变化,仍为 v6。
17
+
5
18
  ## 0.3.1 (2026-11-04)
6
19
 
7
20
  - README 改为用户优先:先场景、安装和首次使用,技术细节后置;安装/快速开始不再要求手填 profile。
package/README.en.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  English | [中文](README.md)
4
4
 
5
+ GitHub: [Lencen/dsh-agent-lines](https://github.com/Lencen/dsh-agent-lines)
6
+
5
7
  > Community plugin for DeepSeek Harness. Not an official DeepSeek product.
6
8
 
7
9
  > **100% Vibe Coding.** The architecture, code, tests, and docs were produced in AI agent sessions. It is experimental: review the code and run an integration test before production use.
@@ -31,13 +33,15 @@ One-command install (recommended; no need to find a profile):
31
33
 
32
34
  The script picks the DSH Web profile, installs the plugin, and verifies agent-lines. If it cannot decide, it lists existing profiles and tells you how to specify one.
33
35
 
36
+ **Restart DSH Web after install or update.** A running process does not load new plugin code. With no plugin config the plugin starts in zero-config mode: one unbound manager line, and a root Session can call line_claim_manager to bind itself. The explicit "Manager config" block is optional, for a fixed manager/worker setup.
37
+
34
38
  Offline or when npm is unavailable, use the local tarball:
35
39
 
36
- bash install.sh ./dsh-agent-lines-0.3.1.tgz
40
+ bash install.sh ./dsh-agent-lines-0.3.3.tgz
37
41
 
38
- When it finishes, the script prints the path to the manager config file. Paste the "Manager config" block below into that file once.
42
+ After install and restart, it works without a config. When you want a fixed manager/worker setup, paste the "Manager config" block below into the file printed by the installer.
39
43
 
40
- ### Manager config
44
+ ### Manager config (optional)
41
45
 
42
46
  ```yaml
43
47
  - id: agent-lines
@@ -64,8 +68,8 @@ Only `createFrom` may call `line_create`. Worker profiles should leave `allowCre
64
68
  ## Quick start
65
69
 
66
70
  1. Run the installer above.
67
- 2. Open the config file printed by the installer and paste the "Manager config" block once.
68
- 3. Start DSH Web and open any root Session.
71
+ 2. **Restart DSH Web** so the plugin is loaded.
72
+ 3. Open any root Session. The zero-config path needs no YAML.
69
73
  4. Call line_status; if the Session is not bound, call line_claim_manager({ confirm: "bind-manager" }).
70
74
  5. Say "create the first-use team"; wait for the member lines, then send the first task separately.
71
75
 
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  [English](README.en.md) | 中文
4
4
 
5
+ GitHub: [Lencen/dsh-agent-lines](https://github.com/Lencen/dsh-agent-lines)
6
+
5
7
  > DeepSeek Harness 社区插件,不是 DeepSeek 官方产品。
6
8
 
7
9
  > **100% Vibe Coding。** 架构、代码、测试、文档都在 AI agent 会话中完成。它是实验性项目:生产使用前请审阅代码并跑一遍集成测试。
@@ -31,13 +33,15 @@ DSH 的 super agent 平替插件。
31
33
 
32
34
  脚本会自动选择 DSH Web 使用的 profile,安装后检查 agent-lines 是否可用;如果判断不了,会列出已有配置并提示你怎么指定。
33
35
 
36
+ **安装或更新后必须重启 DSH Web。** 运行中的进程不会加载新插件代码。插件没有 config 时走零配置:启动一条未绑定 manager,根会话可以调用 line_claim_manager 自己绑定。显式“管理线配置”是可选的,用于固定 manager/worker。
37
+
34
38
  离线或 npm 不可用时,用本地 tarball:
35
39
 
36
- bash install.sh ./dsh-agent-lines-0.3.1.tgz
40
+ bash install.sh ./dsh-agent-lines-0.3.3.tgz
37
41
 
38
- 安装完成后,脚本会打印管理线配置文件的路径。把下面“管理线配置”整段粘贴进去一次即可。
42
+ 安装并重启后,不写配置也可以直接使用;需要固定管理线/worker 时,再把下面“管理线配置”粘贴到脚本打印的配置文件。
39
43
 
40
- ### 管理线配置
44
+ ### 管理线配置(可选)
41
45
 
42
46
  ```yaml
43
47
  - id: agent-lines
@@ -64,8 +68,8 @@ DSH 的 super agent 平替插件。
64
68
  ## 快速开始
65
69
 
66
70
  1. 运行上面的安装脚本。
67
- 2. 按脚本提示打开配置文件,把“管理线配置”整段粘贴进去(只做一次)。
68
- 3. 启动 DSH Web,打开任意根会话。
71
+ 2. **重启 DSH Web**,让插件加载。
72
+ 3. 打开任意根会话。零配置路径不需要改 YAML。
69
73
  4. 先调用 line_status;如果当前会话未绑定,调用 line_claim_manager({ confirm: "bind-manager" })。
70
74
  5. 直接说“按首次使用创建团队”,然后等它建好成员线;第一个任务再单独发。
71
75
 
@@ -3,8 +3,8 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>dsh-agent-lines — durable lines for DSH agents</title>
7
- <meta name="description" content="Durable, addressable peer messaging lines for DSH agents. One manager, several execution lines, local SQLite, community plugin.">
6
+ <title>dsh-agent-lines — let one AI lead run a team</title>
7
+ <meta name="description" content="State the goal. One AI lead splits the work, creates team lines, tracks progress, and reports back. Each line keeps its own context; work survives a restart.">
8
8
  <meta property="og:image" content="https://lencen.github.io/dsh-agent-lines/assets/social-preview.png">
9
9
  <style>
10
10
  :root{--bg:#080b10;--panel:#0d1117;--line:#263241;--text:#e6edf3;--muted:#8b949e;--cyan:#58a6ff;--green:#7ee787}
@@ -43,18 +43,18 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
43
43
  <div class="wrap">
44
44
  <header>
45
45
  <a class="brand" href="../"><span class="mark"></span>dsh-agent-lines</a>
46
- <nav><a href="../">中文</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.1">Release</a></nav>
46
+ <nav><a href="../">中文</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.3">Release</a></nav>
47
47
  </header>
48
48
  <main>
49
49
  <section class="hero" style="border:0;padding-bottom:22px">
50
50
  <div>
51
51
  <div class="kicker">Community plugin · Apache-2.0</div>
52
- <h1>Durable lines<br><span>for DSH agents</span></h1>
53
- <p class="lead">One manager, several execution lines. Each line is an ordinary DSH Session with its own context and durable inbox. Messages live in local SQLite, shared across processes, with no network service.</p>
52
+ <h1>Let one AI lead<br><span>run a team for you</span></h1>
53
+ <p class="lead">You state the goal. The lead splits it into research, architecture, UI, development, test, acceptance, release, and ops lines; assigns work, tracks progress, and reports back. Close the window or restart DSH; the work and messages remain.</p>
54
54
  <div class="install">curl -fsSL https://raw.githubusercontent.com/Lencen/dsh-agent-lines/main/install.sh -o install.sh &amp;&amp; bash install.sh</div>
55
55
  <div class="actions">
56
56
  <a class="btn primary" href="https://github.com/Lencen/dsh-agent-lines">GitHub repository</a>
57
- <a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.1">Download 0.3.1</a>
57
+ <a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.3">Download 0.3.3</a>
58
58
  </div>
59
59
  </div>
60
60
  <div class="shot">
@@ -63,22 +63,32 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
63
63
  </div>
64
64
  </section>
65
65
  <section>
66
- <h2>Not another chat box</h2>
66
+ <h2>What it takes off your plate</h2>
67
67
  <div class="cards">
68
- <div class="card"><b>Addressable lines</b><p>agent#line is a stable identity; a manager can create roles, send tasks, and collect results.</p></div>
69
- <div class="card"><b>Durable messages</b><p>Messages survive a receiver restart; at-least-once delivery with requestId idempotency in the DSH Session log.</p></div>
70
- <div class="card"><b>Clear boundaries</b><p>0.3 is local SQLite only: no handover, no process isolation, no built-in team UI.</p></div>
68
+ <div class="card"><b>No repeated context</b><p>Each member line is a long-lived DSH Session with its own context. Send new work to the right role instead of re-explaining the project.</p></div>
69
+ <div class="card"><b>No manual dispatch</b><p>The lead decomposes work, assigns it, coordinates, resolves disagreements, and collects results. You read the summary.</p></div>
70
+ <div class="card"><b>No lost work</b><p>Tasks and messages are stored locally. Restart DSH and continue; member state and unread messages are still there.</p></div>
71
71
  </div>
72
+ <p style="color:var(--muted);font-size:14px;margin-top:14px">Built for long-running projects and multi-role work. For a one-off subtask, DSH's built-in subagent / Agent Teams is simpler.</p>
72
73
  </section>
73
74
  <section>
74
- <h2>First use: one manager + 8 member lines</h2>
75
+ <h2>A real usage pattern</h2>
76
+ <div class="cards">
77
+ <div class="card"><b>1. You state the goal</b><p>“Add CSV export to the reports page, with tests and a short runbook.”</p></div>
78
+ <div class="card"><b>2. The lead forms the team</b><p>Split into research, architecture, UI/UX, development, test, acceptance, release, and ops; create each line.</p></div>
79
+ <div class="card"><b>3. The team works in parallel</b><p>Members do their parts; the lead tracks progress, resolves interface disagreements, and reassigns when needed.</p></div>
80
+ <div class="card"><b>4. You get the result</b><p>The lead reports conclusions, file paths, risks, and open questions. You do not chase every member yourself.</p></div>
81
+ </div>
82
+ </section>
83
+ <section>
84
+ <h2>First use: let the lead form the team</h2>
75
85
  <pre>You are the development team lead: own decomposition, assignment, coordination, tracking, and summary.
76
- Use line_create for:
86
+ First bind this Session with line_claim_manager, then use line_create for:
77
87
  research / architecture / uiux / dev / test / acceptance / release / ops
78
- Then call line_list and wait for my first task.</pre>
79
- <p style="color:var(--muted);font-size:14px">Full docs, protocol, and limits: <a href="https://github.com/Lencen/dsh-agent-lines">README</a>. Community plugin, not an official DeepSeek product.</p>
88
+ After creation, confirm with line_list, then wait for my first task.</pre>
89
+ <p style="color:var(--muted);font-size:14px">Restart DSH Web after install or update. Technical details, protocol, and limits: <a href="https://github.com/Lencen/dsh-agent-lines">README / architecture</a>. Community plugin, not an official DeepSeek product.</p>
80
90
  </section>
81
- <footer>dsh-agent-lines 0.3.1 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
91
+ <footer>dsh-agent-lines 0.3.3 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
82
92
  </main>
83
93
  </div>
84
94
  </body>
package/docs/index.html CHANGED
@@ -3,8 +3,8 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>dsh-agent-lines — DSH Agent 的持久消息线</title>
7
- <meta name="description" content="DSH Agent 的持久、可寻址消息线:一个管理线,多条执行线,本地 SQLite,社区插件。">
6
+ <title>dsh-agent-lines — 让 AI 负责人带一支 AI 团队</title>
7
+ <meta name="description" content="你说目标,AI 负责人拆任务、建团队、盯进度、收结果;每条成员线有独立会话和持久消息,重启不丢。">
8
8
  <meta property="og:image" content="https://lencen.github.io/dsh-agent-lines/assets/social-preview.png">
9
9
  <style>
10
10
  :root{--bg:#080b10;--panel:#0d1117;--line:#263241;--text:#e6edf3;--muted:#8b949e;--cyan:#58a6ff;--green:#7ee787}
@@ -43,18 +43,18 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
43
43
  <div class="wrap">
44
44
  <header>
45
45
  <a class="brand" href="./"><span class="mark"></span>dsh-agent-lines</a>
46
- <nav><a href="en/index.html">English</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.1">Release</a></nav>
46
+ <nav><a href="en/index.html">English</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.3">Release</a></nav>
47
47
  </header>
48
48
  <main>
49
49
  <section class="hero" style="border:0;padding-bottom:22px">
50
50
  <div>
51
51
  <div class="kicker">Community plugin · Apache-2.0</div>
52
- <h1>给 DSH Agent 的<br><span>持久消息线</span></h1>
53
- <p class="lead">一个管理线,多条执行线。每条线是普通 DSH Session,有独立上下文和持久收件箱;消息落本地 SQLite,跨进程共享,不依赖网络服务。</p>
52
+ <h1>让一个 AI 负责人<br><span>替你带一支 AI 团队</span></h1>
53
+ <p class="lead">你只管说目标。负责人会拆任务、建调研 / 架构 / 开发 / 测试等成员线、分配工作、追进度、收结果,最后给你一份汇总。关掉窗口或重启 DSH,任务和消息还在。</p>
54
54
  <div class="install">curl -fsSL https://raw.githubusercontent.com/Lencen/dsh-agent-lines/main/install.sh -o install.sh &amp;&amp; bash install.sh</div>
55
55
  <div class="actions">
56
56
  <a class="btn primary" href="https://github.com/Lencen/dsh-agent-lines">GitHub 仓库</a>
57
- <a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.1">下载 0.3.1</a>
57
+ <a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.3">下载 0.3.3</a>
58
58
  </div>
59
59
  </div>
60
60
  <div class="shot">
@@ -63,22 +63,32 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
63
63
  </div>
64
64
  </section>
65
65
  <section>
66
- <h2>为什么不是再做一个聊天框</h2>
66
+ <h2>它替你省掉什么</h2>
67
67
  <div class="cards">
68
- <div class="card"><b>线是可寻址的</b><p>agent#line 是稳定身份;管理线可以按角色建线、发任务、收结果。</p></div>
69
- <div class="card"><b>消息是持久的</b><p>接收方重启后消息仍在;至少一次投递,Session 日志用 requestId 做幂等。</p></div>
70
- <div class="card"><b>边界是清楚的</b><p>0.3 只做本地 SQLite;不做 handover、不做进程隔离、不内置团队 UI。</p></div>
68
+ <div class="card"><b>不用反复讲背景</b><p>每条成员线是一个独立的 DSH 会话,长期保留自己的上下文;新任务直接派给对应角色。</p></div>
69
+ <div class="card"><b>不用自己当调度</b><p>负责人拆任务、分配、协调、处理分歧、收结果;你只需要看最后的汇总。</p></div>
70
+ <div class="card"><b>不用怕关窗口</b><p>任务和消息保存在本地;重启 DSH 后还能接着做,成员状态和未处理消息都在。</p></div>
71
71
  </div>
72
+ <p style="color:var(--muted);font-size:14px;margin-top:14px">适合长期项目、多角色协作;一次性的临时子任务,直接用 DSH 内置 subagent / Agent Teams 更简单。</p>
72
73
  </section>
73
74
  <section>
74
- <h2>首次使用:一个管理线 + 8 条成员线</h2>
75
+ <h2>一个真实用法</h2>
76
+ <div class="cards">
77
+ <div class="card"><b>1. 你说目标</b><p>“给报表页加 CSV 导出,带测试和一页 runbook。”</p></div>
78
+ <div class="card"><b>2. 负责人组队</b><p>拆成调研、架构、UIUX、开发、测试、验收、发布、运维,按角色建线。</p></div>
79
+ <div class="card"><b>3. 团队并行</b><p>成员各自做事;负责人追进度、处理接口分歧,必要时重新分配。</p></div>
80
+ <div class="card"><b>4. 你收结果</b><p>负责人汇总结论、文件路径、风险和遗留问题;不用自己挨个问。</p></div>
81
+ </div>
82
+ </section>
83
+ <section>
84
+ <h2>首次使用:让负责人自己组队</h2>
75
85
  <pre>你是开发团队负责人:负责任务拆解、分配、协调、跟踪、汇总。
76
- 请用 line_create 创建:
86
+ 先用 line_claim_manager 把当前会话绑定为管理线,再用 line_create 创建:
77
87
  research / architecture / uiux / dev / test / acceptance / release / ops
78
- 创建后用 line_list 确认,然后待命。</pre>
79
- <p style="color:var(--muted);font-size:14px">完整说明、协议和限制见 <a href="https://github.com/Lencen/dsh-agent-lines">README</a>。社区插件,不是 DeepSeek 官方产品。</p>
88
+ 创建后用 line_list 确认,然后待命,等我发第一个任务。</pre>
89
+ <p style="color:var(--muted);font-size:14px">安装或更新后需要重启 DSH Web。技术细节、协议和限制见 <a href="https://github.com/Lencen/dsh-agent-lines">README / 架构文档</a>。社区插件,不是 DeepSeek 官方产品。</p>
80
90
  </section>
81
- <footer>dsh-agent-lines 0.3.1 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
91
+ <footer>dsh-agent-lines 0.3.3 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
82
92
  </main>
83
93
  </div>
84
94
  </body>
@@ -50,11 +50,11 @@
50
50
  ]
51
51
  },
52
52
  "dist-tags": {
53
- "latest": "0.3.1"
53
+ "latest": "0.3.3"
54
54
  },
55
55
  "versions": [
56
56
  {
57
- "version": "0.3.1",
57
+ "version": "0.3.3",
58
58
  "publishTimestamp": 1793771000,
59
59
  "source": {
60
60
  "type": "npm"
@@ -50,11 +50,11 @@
50
50
  ]
51
51
  },
52
52
  "dist-tags": {
53
- "latest": "0.3.1"
53
+ "latest": "0.3.3"
54
54
  },
55
55
  "versions": [
56
56
  {
57
- "version": "0.3.1",
57
+ "version": "0.3.3",
58
58
  "publishTimestamp": 1793771000,
59
59
  "source": {
60
60
  "type": "npm"
package/lib/index.js CHANGED
@@ -40,20 +40,25 @@ function normalizeLine(entry, agentId, index) {
40
40
  /** Validate and normalize plugin config. Exported for tests and the CLI. */
41
41
  export function normalizeConfig(raw = {}) {
42
42
  if (raw === null || typeof raw !== 'object') throw new LineError('LINE_INVALID_CONFIG', 'Plugin config must be an object')
43
- const agentId = validateAgentId(raw.agentId)
44
43
  const legacy = raw.line !== undefined && raw.sessionId !== undefined
45
44
  ? [{ label: raw.line, sessionId: raw.sessionId }]
46
45
  : []
47
46
  const rawLines = Array.isArray(raw.lines) ? raw.lines : legacy
48
- if (rawLines.length === 0) throw new LineError('LINE_INVALID_CONFIG', 'At least one line is required (lines[] or line/sessionId)')
49
- const lines = rawLines.map((entry, index) => normalizeLine(entry, agentId, index))
47
+ const zeroConfig = rawLines.length === 0 && raw.lines === undefined && raw.line === undefined
48
+ const agentId = raw.agentId === undefined && zeroConfig
49
+ ? 'agent-lines'
50
+ : validateAgentId(raw.agentId)
51
+ if (rawLines.length === 0 && !zeroConfig) throw new LineError('LINE_INVALID_CONFIG', 'At least one line is required (lines[] or line/sessionId)')
52
+ const lines = zeroConfig
53
+ ? [{ agentId, label: 'manager', sessionId: '', lineId: lineId(agentId, 'manager'), role: null }]
54
+ : rawLines.map((entry, index) => normalizeLine(entry, agentId, index))
50
55
  const labels = new Set()
51
56
  const sessions = new Set()
52
57
  for (const line of lines) {
53
58
  if (labels.has(line.label)) throw new LineError('LINE_INVALID_CONFIG', `Duplicate line label: ${line.label}`)
54
- if (sessions.has(line.sessionId)) throw new LineError('LINE_INVALID_CONFIG', `Duplicate sessionId: ${line.sessionId}`)
59
+ if (line.sessionId !== '' && sessions.has(line.sessionId)) throw new LineError('LINE_INVALID_CONFIG', `Duplicate sessionId: ${line.sessionId}`)
55
60
  labels.add(line.label)
56
- sessions.add(line.sessionId)
61
+ if (line.sessionId !== '') sessions.add(line.sessionId)
57
62
  }
58
63
  const createFrom = raw.createFrom === undefined ? lines[0].label : validateLineLabel(raw.createFrom)
59
64
  if (!labels.has(createFrom)) throw new LineError('LINE_INVALID_CONFIG', `createFrom must name a configured line: ${createFrom}`)
@@ -66,9 +71,9 @@ export function normalizeConfig(raw = {}) {
66
71
  transport,
67
72
  lines,
68
73
  createFrom,
69
- maxLines: integer(raw.maxLines, 16, { min: lines.length, max: 256 }),
70
- allowCreate: raw.allowCreate === true,
71
- allowClaim: raw.allowClaim === true,
74
+ maxLines: integer(raw.maxLines, 16, { min: Math.max(1, lines.length), max: 256 }),
75
+ allowCreate: raw.allowCreate === undefined ? zeroConfig : raw.allowCreate === true,
76
+ allowClaim: raw.allowClaim === undefined ? zeroConfig : raw.allowClaim === true,
72
77
  allowSelfSend: raw.allowSelfSend === true,
73
78
  dedupeWindowMs: integer(raw.dedupeWindowMs, 5_000, { min: 0, max: 3_600_000 }),
74
79
  maxReplyDepth: integer(raw.maxReplyDepth, 8, { min: 1, max: 100 }),
@@ -344,6 +349,10 @@ export async function apply(ctx, rawConfig) {
344
349
  startupLines.push(effective)
345
350
  }
346
351
  for (const def of startupLines) {
352
+ if (def.sessionId === '') {
353
+ ctx.logger?.info?.('agent-lines: manager %s is unbound; waiting for claim', def.label)
354
+ continue
355
+ }
347
356
  if (!(await sessionExists(def.sessionId))) {
348
357
  ctx.logger?.warn?.('agent-lines: Session %s for line %s is missing; line stays unbound until claimed', def.sessionId, def.label)
349
358
  lineDefs.set(def.sessionId, { ...def, missing: true })
package/lib/store.js CHANGED
@@ -101,7 +101,10 @@ PRAGMA user_version = 6;
101
101
  `
102
102
 
103
103
  export function defaultDbPath() {
104
- return resolve(homedir(), '.dsh', 'agent-lines', 'lines.db')
104
+ const home = process.env.DSH_HOME === undefined || process.env.DSH_HOME.trim() === ''
105
+ ? resolve(homedir(), '.dsh')
106
+ : resolve(process.env.DSH_HOME)
107
+ return resolve(home, 'agent-lines', 'lines.db')
105
108
  }
106
109
 
107
110
  function expandHome(path) {
package/lib/tools.js CHANGED
@@ -59,6 +59,7 @@ export function registerStatusTool(ctx, { config, store, lineDefs }) {
59
59
  const managerConfig = config.lines.find(line => line.label === config.createFrom)
60
60
  const managerDef = [...lineDefs.values()].find(line => line.label === config.createFrom)
61
61
  const managerSessionId = (managerDef ?? managerConfig)?.sessionId
62
+ const effectiveManagerSessionId = managerSessionId === undefined || managerSessionId === '' ? undefined : managerSessionId
62
63
  const persistence = ctx.get?.('sessionPersistence')
63
64
 
64
65
  const sessionState = async (sessionId) => {
@@ -71,12 +72,12 @@ export function registerStatusTool(ctx, { config, store, lineDefs }) {
71
72
  return { live, persisted }
72
73
  }
73
74
 
74
- const manager = managerSessionId === undefined
75
+ const manager = effectiveManagerSessionId === undefined
75
76
  ? null
76
77
  : {
77
78
  label: config.createFrom,
78
- sessionId: managerSessionId,
79
- ...(await sessionState(managerSessionId)),
79
+ sessionId: effectiveManagerSessionId,
80
+ ...(await sessionState(effectiveManagerSessionId)),
80
81
  lease: store.listLines().find(line => line.label === config.createFrom)?.lease ?? null,
81
82
  }
82
83
  const lines = store.listLines().map(line => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agent-lines",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "DSH Agent 的持久、可寻址消息线(社区插件)。",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",