@coralai/sps-cli 0.51.11 → 0.51.13

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.
@@ -7,8 +7,8 @@
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
9
  <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
10
- <script type="module" crossorigin src="/assets/index-DKc9idxO.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-BJ1T4p1K.css">
10
+ <script type="module" crossorigin src="/assets/index-Diuf9X57.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-BPZgV2XB.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module core/claudeJsonl
3
+ * @description 解析 Claude CLI 自身写的 ACP session 历史 jsonl
4
+ *
5
+ * @layer core
6
+ *
7
+ * Claude CLI 把每个 ACP session 的完整对话写在
8
+ * ~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl
9
+ * 一个 sessionId 一个 jsonl 文件(1:1)。
10
+ *
11
+ * 把它解析成 ChatMessage[] 后,Console 就能展示 `sps agent --chat` /
12
+ * `sps agent --name foo` 创建的 CLI 会话历史,而不必双写到
13
+ * ~/.coral/chat-sessions/.
14
+ */
15
+ import type { ChatMessage } from '../services/ChatService.js';
16
+ export interface JsonlSummary {
17
+ /** 文件存在且至少含一条非 meta user/assistant 消息 */
18
+ exists: boolean;
19
+ /** 解析出的可展示消息条数 */
20
+ messageCount: number;
21
+ /** 最后一条消息的 ISO 时间 */
22
+ lastMessageAt: string | null;
23
+ /** 第一条非 meta user 消息的纯文本(作为 title 候选) */
24
+ firstUserText: string | null;
25
+ /** 文件 mtime(ISO),用于排序兜底 */
26
+ fileMTime: string | null;
27
+ }
28
+ /** 文件是否存在(不解析内容) */
29
+ export declare function jsonlExists(cwd: string, sessionId: string): boolean;
30
+ /**
31
+ * 读 jsonl 并转成 ChatMessage[]。
32
+ * - 跳过 isMeta / system / progress / queue-operation / file-history-snapshot / attachment / last-prompt
33
+ * - sidechain(subagent)目前一并跳过 —— 主对话流更纯
34
+ * - 每个 assistant record 是一条 ChatMessage(一次模型 turn 内的多 record 不再合并 —— Claude 的 jsonl 已经分好了)
35
+ * - tool_use 块映射为 ChatMessageBlock; thinking 不展示
36
+ */
37
+ export declare function parseJsonlMessages(cwd: string, sessionId: string): ChatMessage[];
38
+ /**
39
+ * 摘要(list() 用)。复用 parseJsonlMessages 保持计数与真实可展示条数一致 ——
40
+ * 大文件下会读全文,但解析本身仍是 O(n) 行扫,对 list 的 SLA 足够。
41
+ */
42
+ export declare function summarizeJsonl(cwd: string, sessionId: string): JsonlSummary;
43
+ //# sourceMappingURL=claudeJsonl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeJsonl.d.ts","sourceRoot":"","sources":["../../src/core/claudeJsonl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAwC9D,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,kBAAkB;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yCAAyC;IACzC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,2BAA2B;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,oBAAoB;AACpB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CA+BhF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CA2B3E"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * @module core/claudeJsonl
3
+ * @description 解析 Claude CLI 自身写的 ACP session 历史 jsonl
4
+ *
5
+ * @layer core
6
+ *
7
+ * Claude CLI 把每个 ACP session 的完整对话写在
8
+ * ~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl
9
+ * 一个 sessionId 一个 jsonl 文件(1:1)。
10
+ *
11
+ * 把它解析成 ChatMessage[] 后,Console 就能展示 `sps agent --chat` /
12
+ * `sps agent --name foo` 创建的 CLI 会话历史,而不必双写到
13
+ * ~/.coral/chat-sessions/.
14
+ */
15
+ import { existsSync, readFileSync, statSync } from 'node:fs';
16
+ import { claudeJsonlFile } from '../shared/runtimePaths.js';
17
+ /** 文件是否存在(不解析内容) */
18
+ export function jsonlExists(cwd, sessionId) {
19
+ return existsSync(claudeJsonlFile(cwd, sessionId));
20
+ }
21
+ /**
22
+ * 读 jsonl 并转成 ChatMessage[]。
23
+ * - 跳过 isMeta / system / progress / queue-operation / file-history-snapshot / attachment / last-prompt
24
+ * - sidechain(subagent)目前一并跳过 —— 主对话流更纯
25
+ * - 每个 assistant record 是一条 ChatMessage(一次模型 turn 内的多 record 不再合并 —— Claude 的 jsonl 已经分好了)
26
+ * - tool_use 块映射为 ChatMessageBlock; thinking 不展示
27
+ */
28
+ export function parseJsonlMessages(cwd, sessionId) {
29
+ const path = claudeJsonlFile(cwd, sessionId);
30
+ if (!existsSync(path))
31
+ return [];
32
+ let raw;
33
+ try {
34
+ raw = readFileSync(path, 'utf-8');
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ const messages = [];
40
+ for (const line of raw.split('\n')) {
41
+ if (!line.trim())
42
+ continue;
43
+ let rec;
44
+ try {
45
+ rec = JSON.parse(line);
46
+ }
47
+ catch {
48
+ continue;
49
+ }
50
+ if (rec.isMeta)
51
+ continue;
52
+ if (rec.isSidechain)
53
+ continue;
54
+ if (rec.type === 'user') {
55
+ const m = recordToUserMessage(rec);
56
+ if (m)
57
+ messages.push(m);
58
+ }
59
+ else if (rec.type === 'assistant') {
60
+ const m = recordToAssistantMessage(rec);
61
+ if (m)
62
+ messages.push(m);
63
+ }
64
+ // 其它 type(system / progress / file-history-snapshot / queue-operation /
65
+ // attachment / last-prompt)不展示
66
+ }
67
+ return messages;
68
+ }
69
+ /**
70
+ * 摘要(list() 用)。复用 parseJsonlMessages 保持计数与真实可展示条数一致 ——
71
+ * 大文件下会读全文,但解析本身仍是 O(n) 行扫,对 list 的 SLA 足够。
72
+ */
73
+ export function summarizeJsonl(cwd, sessionId) {
74
+ const path = claudeJsonlFile(cwd, sessionId);
75
+ if (!existsSync(path)) {
76
+ return { exists: false, messageCount: 0, lastMessageAt: null, firstUserText: null, fileMTime: null };
77
+ }
78
+ let mtime = null;
79
+ try {
80
+ mtime = statSync(path).mtime.toISOString();
81
+ }
82
+ catch {
83
+ /* ignore */
84
+ }
85
+ const msgs = parseJsonlMessages(cwd, sessionId);
86
+ const lastTs = msgs.length > 0 ? msgs[msgs.length - 1].ts : null;
87
+ let firstUser = null;
88
+ for (const m of msgs) {
89
+ if (m.role === 'user' && m.content.trim()) {
90
+ firstUser = m.content.trim().slice(0, 120);
91
+ break;
92
+ }
93
+ }
94
+ return {
95
+ exists: true,
96
+ messageCount: msgs.length,
97
+ lastMessageAt: lastTs,
98
+ firstUserText: firstUser,
99
+ fileMTime: mtime,
100
+ };
101
+ }
102
+ // ─── 内部转换 ─────────────────────────────────────────────────────────────
103
+ function recordToUserMessage(rec) {
104
+ const content = rec.message?.content;
105
+ if (content == null)
106
+ return null;
107
+ let text = '';
108
+ if (typeof content === 'string') {
109
+ text = content;
110
+ }
111
+ else if (Array.isArray(content)) {
112
+ // user content array 通常是 tool_result + text 混合 —— 只展示 text 块
113
+ for (const blk of content) {
114
+ if (blk && typeof blk === 'object' && blk.type === 'text') {
115
+ text += blk.text;
116
+ }
117
+ }
118
+ // 全是 tool_result 没有 text 的话,跳过这条记录(避免空气泡)
119
+ if (text === '')
120
+ return null;
121
+ }
122
+ // 过滤 Claude CLI 内部包装:slash 命令、stdout 注入、caveat 提示
123
+ if (isClaudeMetaText(text))
124
+ return null;
125
+ return {
126
+ id: rec.uuid ?? cryptoRandomId(),
127
+ role: 'user',
128
+ content: text,
129
+ ts: rec.timestamp ?? new Date().toISOString(),
130
+ };
131
+ }
132
+ /** 识别 Claude CLI 自动包装的非用户文本,避免污染 chat 视图 */
133
+ function isClaudeMetaText(text) {
134
+ const t = text.trim();
135
+ if (t === '')
136
+ return true;
137
+ if (t.startsWith('<command-name>'))
138
+ return true;
139
+ if (t.startsWith('<local-command-stdout>'))
140
+ return true;
141
+ if (t.startsWith('<local-command-stderr>'))
142
+ return true;
143
+ if (t.startsWith('<local-command-caveat>'))
144
+ return true;
145
+ if (t.startsWith('<system-reminder>'))
146
+ return true;
147
+ return false;
148
+ }
149
+ function recordToAssistantMessage(rec) {
150
+ const blocks = rec.message?.content;
151
+ if (!Array.isArray(blocks))
152
+ return null;
153
+ let text = '';
154
+ const uiBlocks = [];
155
+ for (const blk of blocks) {
156
+ if (!blk || typeof blk !== 'object')
157
+ continue;
158
+ if (blk.type === 'text') {
159
+ text += blk.text;
160
+ uiBlocks.push({ type: 'text', text: blk.text });
161
+ }
162
+ else if (blk.type === 'tool_use') {
163
+ uiBlocks.push({
164
+ type: 'tool_use',
165
+ id: blk.id,
166
+ title: blk.name,
167
+ kind: blk.name,
168
+ status: 'complete',
169
+ });
170
+ }
171
+ // thinking 块刻意不展示(签名+原文较长,后端没必要给前端)
172
+ }
173
+ if (text === '' && uiBlocks.length === 0)
174
+ return null;
175
+ return {
176
+ id: rec.uuid ?? cryptoRandomId(),
177
+ role: 'assistant',
178
+ content: text,
179
+ blocks: uiBlocks.length > 0 ? uiBlocks : undefined,
180
+ ts: rec.timestamp ?? new Date().toISOString(),
181
+ };
182
+ }
183
+ function cryptoRandomId() {
184
+ // jsonl 必有 uuid;这里只是兜底,避免 strict TS 抱怨
185
+ return `gen-${Math.random().toString(36).slice(2, 12)}`;
186
+ }
187
+ //# sourceMappingURL=claudeJsonl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeJsonl.js","sourceRoot":"","sources":["../../src/core/claudeJsonl.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,10 @@ export interface ChatSession {
31
31
  * fall back to daemon's startup cwd (legacy behavior).
32
32
  */
33
33
  readonly cwd?: string | null;
34
+ /** v0.51.12:会话来源(同 ChatSessionSummary) */
35
+ readonly source?: 'console' | 'cli';
36
+ /** v0.51.12:CLI 会话只读 */
37
+ readonly readonly?: boolean;
34
38
  }
35
39
  export interface ChatSessionSummary {
36
40
  readonly id: string;
@@ -40,6 +44,19 @@ export interface ChatSessionSummary {
40
44
  readonly project: string | null;
41
45
  readonly messageCount: number;
42
46
  readonly cwd?: string | null;
47
+ /**
48
+ * v0.51.12:会话来源。
49
+ * - `console`:Console /chat 页创建的会话,持久化在 ~/.coral/chat-sessions/<id>.json
50
+ * - `cli`:`sps agent --chat` / `sps agent --name` 在 daemon 里建的会话,
51
+ * 历史从 Claude CLI 的 ~/.claude/projects/<cwd>/<sessionId>.jsonl 读
52
+ */
53
+ readonly source?: 'console' | 'cli';
54
+ /** v0.51.12:CLI 会话独有的 daemon slot 名(id 也等于此值),用于路由消息 */
55
+ readonly slot?: string;
56
+ /** v0.51.12:CLI 会话当前的 daemon 状态(offline / busy / ready / ...) */
57
+ readonly sessionState?: string | null;
58
+ /** v0.51.12:CLI 会话目前不能从 Console 续聊(只读历史),Console 会话可写 */
59
+ readonly readonly?: boolean;
43
60
  }
44
61
  export interface CreateSessionInput {
45
62
  title?: string;
@@ -48,10 +65,16 @@ export interface CreateSessionInput {
48
65
  cwd?: string | null;
49
66
  }
50
67
  export interface ChatExecutor {
51
- /** 停止会话对应的 daemon worker(Delete 时清理) */
68
+ /** 停止会话对应的 daemon worker(Console 路径:会自动加 chat- 前缀) */
52
69
  stopSession(sessionId: string): Promise<void>;
53
70
  /** 中断正在进行的 assistant turn */
54
71
  cancelRun(sessionId: string): Promise<void>;
72
+ /**
73
+ * v0.51.13:按完整 slot 名停 daemon session(CLI 路径用)。
74
+ * 调用方已知 slot 名形如 `session-default` / `session-foo`,不需要再拼前缀。
75
+ * Slot 不存在或 daemon 未运行时静默 no-op。
76
+ */
77
+ stopExactSlot(slot: string): Promise<void>;
55
78
  }
56
79
  export interface ChatServiceDeps {
57
80
  readonly fs: FileSystem;
@@ -63,6 +86,8 @@ export declare class ChatService {
63
86
  private readonly deps;
64
87
  constructor(deps: ChatServiceDeps);
65
88
  list(): Promise<Result<ChatSessionSummary[], DomainError>>;
89
+ /** 读 daemon state.json 取 sessions —— 文件不存在或损坏返回空数组 */
90
+ private readDaemonSessions;
66
91
  create(input?: CreateSessionInput): Promise<Result<ChatSessionSummary, DomainError>>;
67
92
  get(id: string): Promise<Result<ChatSession, DomainError>>;
68
93
  /** 返回 since 之后的消息(供 SSE 重连补偿)。since 缺省返回全部。 */
@@ -71,6 +96,11 @@ export declare class ChatService {
71
96
  total: number;
72
97
  }, DomainError>>;
73
98
  delete(id: string): Promise<Result<void, DomainError>>;
99
+ /**
100
+ * 从 daemon state.json 里把 slot 删掉,让 list() 不再返回。
101
+ * jsonl 文件刻意留着 —— 那是 Claude CLI 自己的存档,跨边界删除越权。
102
+ */
103
+ private removeDaemonSession;
74
104
  interrupt(id: string): Promise<Result<void, DomainError>>;
75
105
  private sessionPath;
76
106
  private summarize;
@@ -1 +1 @@
1
- {"version":3,"file":"ChatService.d.ts","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatService.d.ts","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"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"}
@@ -15,37 +15,64 @@
15
15
  */
16
16
  import { randomUUID } from 'node:crypto';
17
17
  import { resolve } from 'node:path';
18
+ import { jsonlExists, parseJsonlMessages, summarizeJsonl, } from '../core/claudeJsonl.js';
18
19
  import { domainError } from '../shared/errors.js';
19
20
  import { err, ok } from '../shared/result.js';
20
- import { chatSessionsDir } from '../shared/runtimePaths.js';
21
+ import { chatSessionsDir, sessionsDir } from '../shared/runtimePaths.js';
21
22
  export class ChatService {
22
23
  deps;
23
24
  constructor(deps) {
24
25
  this.deps = deps;
25
26
  }
26
27
  async list() {
27
- const dir = chatSessionsDir();
28
- if (!this.deps.fs.exists(dir))
29
- return ok([]);
30
- let files;
31
- try {
32
- files = this.deps.fs.readDir(dir).filter((e) => e.isFile && e.name.endsWith('.json'));
33
- }
34
- catch (cause) {
35
- return err(domainError('internal', 'CHAT_LIST_FAIL', '会话列表读取失败', { cause }));
36
- }
37
28
  const summaries = [];
38
- for (const entry of files) {
39
- const path = resolve(dir, entry.name);
29
+ // 1) Console 会话 —— ~/.coral/chat-sessions/<id>.json
30
+ const dir = chatSessionsDir();
31
+ const consoleIds = new Set();
32
+ if (this.deps.fs.exists(dir)) {
33
+ let files;
40
34
  try {
41
- const raw = this.deps.fs.readFile(path);
42
- const session = JSON.parse(raw);
43
- summaries.push(this.summarize(session));
35
+ files = this.deps.fs.readDir(dir).filter((e) => e.isFile && e.name.endsWith('.json'));
44
36
  }
45
- catch {
46
- /* 跳过坏 session */
37
+ catch (cause) {
38
+ return err(domainError('internal', 'CHAT_LIST_FAIL', '会话列表读取失败', { cause }));
39
+ }
40
+ for (const entry of files) {
41
+ const path = resolve(dir, entry.name);
42
+ try {
43
+ const raw = this.deps.fs.readFile(path);
44
+ const session = JSON.parse(raw);
45
+ summaries.push({ ...this.summarize(session), source: 'console', readonly: false });
46
+ consoleIds.add(session.id);
47
+ }
48
+ catch {
49
+ /* 跳过坏 session */
50
+ }
47
51
  }
48
52
  }
53
+ // 2) CLI 会话 —— daemon state.json + Claude jsonl 历史
54
+ // 跳过 Console 用 `session-chat-<consoleId>` 占的 slot,避免重复
55
+ for (const cli of this.readDaemonSessions()) {
56
+ const consoleId = stripChatPrefix(cli.slot);
57
+ if (consoleId && consoleIds.has(consoleId))
58
+ continue;
59
+ if (!jsonlExists(cli.cwd, cli.sessionId))
60
+ continue;
61
+ const summary = summarizeJsonl(cli.cwd, cli.sessionId);
62
+ summaries.push({
63
+ id: cli.slot,
64
+ createdAt: cli.createdAt,
65
+ lastMessageAt: summary.lastMessageAt ?? cli.lastSeenAt ?? cli.updatedAt,
66
+ title: summary.firstUserText || stripSessionPrefix(cli.slot),
67
+ project: null,
68
+ messageCount: summary.messageCount,
69
+ cwd: cli.cwd,
70
+ source: 'cli',
71
+ slot: cli.slot,
72
+ sessionState: cli.sessionState,
73
+ readonly: true,
74
+ });
75
+ }
49
76
  summaries.sort((a, b) => {
50
77
  const ta = a.lastMessageAt ?? a.createdAt;
51
78
  const tb = b.lastMessageAt ?? b.createdAt;
@@ -53,6 +80,20 @@ export class ChatService {
53
80
  });
54
81
  return ok(summaries);
55
82
  }
83
+ /** 读 daemon state.json 取 sessions —— 文件不存在或损坏返回空数组 */
84
+ readDaemonSessions() {
85
+ const path = resolve(sessionsDir(), 'state.json');
86
+ if (!this.deps.fs.exists(path))
87
+ return [];
88
+ try {
89
+ const raw = this.deps.fs.readFile(path);
90
+ const parsed = JSON.parse(raw);
91
+ return Object.values(parsed.sessions ?? {});
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
56
97
  async create(input = {}) {
57
98
  // v0.51.4: validate cwd if provided
58
99
  let cwd = null;
@@ -85,17 +126,39 @@ export class ChatService {
85
126
  async get(id) {
86
127
  if (!isValidSessionId(id))
87
128
  return err(invalidId());
129
+ // 1) Console session —— chat-sessions/<id>.json
88
130
  const path = this.sessionPath(id);
89
- if (!this.deps.fs.exists(path)) {
90
- return err(domainError('not-found', 'CHAT_SESSION_NOT_FOUND', '会话不存在'));
91
- }
92
- try {
93
- const raw = this.deps.fs.readFile(path);
94
- return ok(JSON.parse(raw));
131
+ if (this.deps.fs.exists(path)) {
132
+ try {
133
+ const raw = this.deps.fs.readFile(path);
134
+ return ok(JSON.parse(raw));
135
+ }
136
+ catch (cause) {
137
+ return err(domainError('internal', 'CHAT_READ_FAIL', '会话读取失败', { cause }));
138
+ }
95
139
  }
96
- catch (cause) {
97
- return err(domainError('internal', 'CHAT_READ_FAIL', '会话读取失败', { cause }));
140
+ // 2) CLI session —— id 是 daemon slot 名,从 jsonl 实时解析
141
+ if (id.startsWith('session-')) {
142
+ const cli = this.readDaemonSessions().find((s) => s.slot === id);
143
+ if (cli && jsonlExists(cli.cwd, cli.sessionId)) {
144
+ const messages = parseJsonlMessages(cli.cwd, cli.sessionId);
145
+ const lastTs = messages.length > 0 ? messages[messages.length - 1].ts : null;
146
+ const firstUser = messages.find((m) => m.role === 'user' && m.content.trim());
147
+ return ok({
148
+ id,
149
+ createdAt: cli.createdAt,
150
+ lastMessageAt: lastTs ?? cli.lastSeenAt ?? cli.updatedAt,
151
+ title: firstUser?.content.trim().slice(0, 120) || stripSessionPrefix(id),
152
+ project: null,
153
+ messageCount: messages.length,
154
+ messages,
155
+ cwd: cli.cwd,
156
+ source: 'cli',
157
+ readonly: true,
158
+ });
159
+ }
98
160
  }
161
+ return err(domainError('not-found', 'CHAT_SESSION_NOT_FOUND', '会话不存在'));
99
162
  }
100
163
  /** 返回 since 之后的消息(供 SSE 重连补偿)。since 缺省返回全部。 */
101
164
  async getMessages(id, since) {
@@ -109,6 +172,24 @@ export class ChatService {
109
172
  async delete(id) {
110
173
  if (!isValidSessionId(id))
111
174
  return err(invalidId());
175
+ // CLI 会话:停 daemon slot + 从 state.json 移除;保留 Claude jsonl 存档(Claude 自己的文件)。
176
+ if (id.startsWith('session-')) {
177
+ if (this.deps.executor) {
178
+ try {
179
+ await this.deps.executor.stopExactSlot(id);
180
+ }
181
+ catch {
182
+ /* daemon 没起或 slot 已不在,照样推进 */
183
+ }
184
+ }
185
+ try {
186
+ this.removeDaemonSession(id);
187
+ }
188
+ catch (cause) {
189
+ return err(domainError('internal', 'CHAT_DELETE_FAIL', '从 daemon state 移除会话失败', { cause }));
190
+ }
191
+ return ok(undefined);
192
+ }
112
193
  const path = this.sessionPath(id);
113
194
  if (this.deps.fs.exists(path)) {
114
195
  try {
@@ -129,9 +210,35 @@ export class ChatService {
129
210
  }
130
211
  return ok(undefined);
131
212
  }
213
+ /**
214
+ * 从 daemon state.json 里把 slot 删掉,让 list() 不再返回。
215
+ * jsonl 文件刻意留着 —— 那是 Claude CLI 自己的存档,跨边界删除越权。
216
+ */
217
+ removeDaemonSession(slot) {
218
+ const path = resolve(sessionsDir(), 'state.json');
219
+ if (!this.deps.fs.exists(path))
220
+ return;
221
+ let parsed;
222
+ try {
223
+ parsed = JSON.parse(this.deps.fs.readFile(path));
224
+ }
225
+ catch {
226
+ // 损坏的 state.json:交给 daemon 自己重建,这里不动
227
+ return;
228
+ }
229
+ if (!parsed.sessions || !parsed.sessions[slot])
230
+ return;
231
+ delete parsed.sessions[slot];
232
+ parsed.updatedAt = this.deps.clock.nowIso();
233
+ parsed.updatedBy = 'chat-service-delete';
234
+ this.deps.fs.writeFileAtomic(path, JSON.stringify(parsed, null, 2));
235
+ }
132
236
  async interrupt(id) {
133
237
  if (!isValidSessionId(id))
134
238
  return err(invalidId());
239
+ if (id.startsWith('session-')) {
240
+ return err(domainError('validation', 'CHAT_CLI_READ_ONLY', 'CLI 会话只读,无法从 Console 中断'));
241
+ }
135
242
  if (!this.deps.executor) {
136
243
  return err(domainError('internal', 'EXECUTOR_MISSING', 'ChatExecutor 未注入'));
137
244
  }
@@ -160,7 +267,16 @@ export class ChatService {
160
267
  }
161
268
  }
162
269
  function isValidSessionId(id) {
163
- return typeof id === 'string' && /^[a-zA-Z0-9-]+$/.test(id);
270
+ return typeof id === 'string' && /^[a-zA-Z0-9_-]+$/.test(id);
271
+ }
272
+ /** Console 占的 daemon slot 形如 `session-chat-<consoleId>` —— 抽出 consoleId 用于去重 */
273
+ function stripChatPrefix(slot) {
274
+ const m = /^session-chat-(.+)$/.exec(slot);
275
+ return m ? m[1] : null;
276
+ }
277
+ /** `session-foo` → `foo`,给 CLI 会话提供个简短 fallback title */
278
+ function stripSessionPrefix(slot) {
279
+ return slot.replace(/^session-/, '');
164
280
  }
165
281
  function invalidId() {
166
282
  return domainError('validation', 'INVALID_SESSION_ID', 'session id 非法');
@@ -1 +1 @@
1
- {"version":3,"file":"ChatService.js","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatService.js","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,7 @@ export declare class DefaultPipelineExecutor implements PipelineExecutor {
47
47
  export declare class DefaultChatExecutor implements ChatExecutor {
48
48
  stopSession(sessionId: string): Promise<void>;
49
49
  cancelRun(sessionId: string): Promise<void>;
50
+ stopExactSlot(slot: string): Promise<void>;
50
51
  }
51
52
  export declare class DefaultProjectInitExecutor implements ProjectInitExecutor {
52
53
  init(project: string, opts: ProjectInitOpts): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../../src/services/executors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,qBAAa,qBAAsB,YAAW,cAAc;IACpD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2EnD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgCzD;AAQD,qBAAa,uBAAwB,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE9C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;;;;;;;;OASG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkEtD;;;OAGG;YACW,iBAAiB;CAkBhC;AAMD,qBAAa,mBAAoB,YAAW,YAAY;IAChD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQlD;AAID,qBAAa,0BAA2B,YAAW,mBAAmB;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAIlE"}
1
+ {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../../src/services/executors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,qBAAa,qBAAsB,YAAW,cAAc;IACpD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2EnD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgCzD;AAQD,qBAAa,uBAAwB,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE9C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;;;;;;;;OASG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkEtD;;;OAGG;YACW,iBAAiB;CAkBhC;AAMD,qBAAa,mBAAoB,YAAW,YAAY;IAChD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMjD;AAID,qBAAa,0BAA2B,YAAW,mBAAmB;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAIlE"}
@@ -232,6 +232,13 @@ export class DefaultChatExecutor {
232
232
  }
233
233
  await client.cancelRun(`${CHAT_SLOT_PREFIX}${sessionId}`);
234
234
  }
235
+ async stopExactSlot(slot) {
236
+ const { DaemonClient } = await import('../daemon/daemonClient.js');
237
+ const client = new DaemonClient();
238
+ if (!(await client.isRunning()))
239
+ return;
240
+ await client.stopSession(slot).catch(() => undefined);
241
+ }
235
242
  }
236
243
  // ─── ProjectInitExecutor —— 直接调 executeProjectInit ─────────────────
237
244
  export class DefaultProjectInitExecutor {