@xmanrui/dsh-im 4.6.0 → 4.7.0
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/README.en.md +2 -0
- package/README.md +2 -0
- package/lib/client.js +1 -1
- package/lib/index.js +213 -212
- package/package.json +1 -1
- package/src/channels/dingtalk/dingtalk-bridge.mjs +1 -0
- package/src/channels/feishu/bridge.mjs +33 -8
- package/src/channels/feishu/feishu-cards.mjs +2 -0
- package/src/channels/qq/qq-bridge.mjs +1 -0
- package/src/channels/shared/i18n-en/feishu.mjs +2 -2
- package/src/channels/shared/i18n-en/shared-a.mjs +2 -0
- package/src/channels/shared/i18n-en/shared-b.mjs +2 -2
- package/src/channels/shared/text-harness-bridge.mjs +1 -0
- package/src/channels/shared/workspace-command.mjs +22 -3
- package/src/channels/wecom/wecom-bridge.mjs +1 -0
- package/src/channels/weixin/weixin-bridge.mjs +1 -0
package/package.json
CHANGED
|
@@ -82,6 +82,7 @@ const HELP_TEXT_LINES = [
|
|
|
82
82
|
'/workspace 工作区序号或绝对路径 切换工作区',
|
|
83
83
|
'/workspacelist 列出工作区绝对路径',
|
|
84
84
|
'/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题',
|
|
85
|
+
'/sessionlist --limit N 仅列出当前工作区前 N 个会话',
|
|
85
86
|
'/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话',
|
|
86
87
|
'/models 按序号列出所有可用模型',
|
|
87
88
|
'/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级',
|
|
@@ -47,7 +47,12 @@ import {
|
|
|
47
47
|
isPresetCommand,
|
|
48
48
|
runPresetCommand,
|
|
49
49
|
} from '../shared/preset-command.mjs';
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
parseSessionListArgument,
|
|
52
|
+
resolveSessionListWorkspace,
|
|
53
|
+
runWorkspaceCommand,
|
|
54
|
+
workspacePathSnapshot,
|
|
55
|
+
} from '../shared/workspace-command.mjs';
|
|
51
56
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
52
57
|
import { captureContextEnhancement, enhanceContextContent } from '../shared/context-enhancement.mjs';
|
|
53
58
|
import { deliverOutboundArtifacts } from '../shared/semantic/artifact-delivery.mjs';
|
|
@@ -160,6 +165,7 @@ const WORKSPACE_HELP_LINES = [
|
|
|
160
165
|
'/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话',
|
|
161
166
|
'/workspacelist 列出工作区绝对路径',
|
|
162
167
|
'/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题',
|
|
168
|
+
'/sessionlist --limit N 仅列出当前工作区前 N 个会话',
|
|
163
169
|
];
|
|
164
170
|
|
|
165
171
|
/** Safe user-facing text for bind/workspace failures (no raw messages). */
|
|
@@ -1085,8 +1091,18 @@ export class FeishuHarnessBridge {
|
|
|
1085
1091
|
return;
|
|
1086
1092
|
}
|
|
1087
1093
|
if (SESSION_LIST_PREFIX.test(commandText)) {
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1094
|
+
const argument = commandText.replace(/^\/(?:sessionlist|sessions)/i, '').trim();
|
|
1095
|
+
const request = parseSessionListArgument(argument);
|
|
1096
|
+
if (request.error) {
|
|
1097
|
+
await this.#send(event.message.chat_id, request.error, { replyTo: event.message.message_id });
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
await this.#showSessions(
|
|
1101
|
+
{ chatId: event.message.chat_id, key, replyTo: event.message.message_id },
|
|
1102
|
+
request.selector || null,
|
|
1103
|
+
0,
|
|
1104
|
+
{ limit: request.limit },
|
|
1105
|
+
);
|
|
1090
1106
|
return;
|
|
1091
1107
|
}
|
|
1092
1108
|
if (WORKSPACE_LIST_COMMAND.test(commandText)) {
|
|
@@ -1850,6 +1866,7 @@ export class FeishuHarnessBridge {
|
|
|
1850
1866
|
messageId = null,
|
|
1851
1867
|
sessionWorkspace = null,
|
|
1852
1868
|
sessionPage = 0,
|
|
1869
|
+
sessionLimit = null,
|
|
1853
1870
|
selections = [],
|
|
1854
1871
|
}) {
|
|
1855
1872
|
// Confirmations triggered by a card interaction stay anchored to the
|
|
@@ -1861,7 +1878,7 @@ export class FeishuHarnessBridge {
|
|
|
1861
1878
|
{ chatId, key, replyTo: messageId },
|
|
1862
1879
|
sessionWorkspace,
|
|
1863
1880
|
page,
|
|
1864
|
-
{ updateMessageId: messageId },
|
|
1881
|
+
{ updateMessageId: messageId, limit: sessionLimit },
|
|
1865
1882
|
);
|
|
1866
1883
|
return;
|
|
1867
1884
|
}
|
|
@@ -2040,7 +2057,7 @@ export class FeishuHarnessBridge {
|
|
|
2040
2057
|
{ chatId, key, replyTo: messageId },
|
|
2041
2058
|
sessionWorkspace,
|
|
2042
2059
|
sessionPage,
|
|
2043
|
-
{ updateMessageId: messageId },
|
|
2060
|
+
{ updateMessageId: messageId, limit: sessionLimit },
|
|
2044
2061
|
);
|
|
2045
2062
|
}
|
|
2046
2063
|
return;
|
|
@@ -2056,7 +2073,7 @@ export class FeishuHarnessBridge {
|
|
|
2056
2073
|
{ chatId, key, replyTo: messageId },
|
|
2057
2074
|
sessionWorkspace,
|
|
2058
2075
|
sessionPage,
|
|
2059
|
-
{ updateMessageId: messageId },
|
|
2076
|
+
{ updateMessageId: messageId, limit: sessionLimit },
|
|
2060
2077
|
);
|
|
2061
2078
|
}
|
|
2062
2079
|
}
|
|
@@ -2141,7 +2158,7 @@ export class FeishuHarnessBridge {
|
|
|
2141
2158
|
{ chatId, key, replyTo = null },
|
|
2142
2159
|
selector,
|
|
2143
2160
|
page = 0,
|
|
2144
|
-
{ updateMessageId = null } = {},
|
|
2161
|
+
{ updateMessageId = null, limit = null } = {},
|
|
2145
2162
|
) {
|
|
2146
2163
|
try {
|
|
2147
2164
|
const signal = this.#cardDataSignal();
|
|
@@ -2151,7 +2168,11 @@ export class FeishuHarnessBridge {
|
|
|
2151
2168
|
return;
|
|
2152
2169
|
}
|
|
2153
2170
|
const listed = await this.#harness.listWorkspaceSessions(resolved.workspace, { signal });
|
|
2154
|
-
const
|
|
2171
|
+
const visibleSessions = this.#visibleSessions(Array.isArray(listed?.sessions) ? listed.sessions : []);
|
|
2172
|
+
const sessionLimit = Number.isSafeInteger(limit) && limit > 0 ? limit : null;
|
|
2173
|
+
const sessions = sessionLimit === null
|
|
2174
|
+
? visibleSessions
|
|
2175
|
+
: visibleSessions.slice(0, sessionLimit);
|
|
2155
2176
|
const workspace = listed?.workspace ?? resolved.workspace;
|
|
2156
2177
|
if (sessions.length === 0) {
|
|
2157
2178
|
await this.#send(chatId, t('工作区:{workspace}\n该工作区暂无会话。', { workspace }), { replyTo });
|
|
@@ -2178,6 +2199,7 @@ export class FeishuHarnessBridge {
|
|
|
2178
2199
|
// list response's workspace is display data and is not authoritative.
|
|
2179
2200
|
sessionWorkspace: resolved.workspace,
|
|
2180
2201
|
sessionPage: safePage,
|
|
2202
|
+
sessionLimit,
|
|
2181
2203
|
},
|
|
2182
2204
|
);
|
|
2183
2205
|
} catch (error) {
|
|
@@ -2246,6 +2268,9 @@ export class FeishuHarnessBridge {
|
|
|
2246
2268
|
sessionPage: Number.isSafeInteger(options.sessionPage) && options.sessionPage >= 0
|
|
2247
2269
|
? options.sessionPage
|
|
2248
2270
|
: 0,
|
|
2271
|
+
sessionLimit: Number.isSafeInteger(options.sessionLimit) && options.sessionLimit > 0
|
|
2272
|
+
? options.sessionLimit
|
|
2273
|
+
: null,
|
|
2249
2274
|
});
|
|
2250
2275
|
if (this.#cardKeys.size > 200) {
|
|
2251
2276
|
const oldest = this.#cardKeys.keys().next().value;
|
|
@@ -488,6 +488,7 @@ export function menuHelpText() {
|
|
|
488
488
|
'',
|
|
489
489
|
'📋 会话 / 工作区',
|
|
490
490
|
'/sessionlist 或 /sessions 列出工作区会话',
|
|
491
|
+
'/sessionlist --limit N 仅列出当前工作区前 N 个会话',
|
|
491
492
|
'/session ID 绑定已有会话',
|
|
492
493
|
'/workspacelist 列出工作区',
|
|
493
494
|
'/workspace 工作区序号或绝对路径 切换工作区',
|
|
@@ -554,6 +555,7 @@ const HELP_TEXT_COMMANDS = [
|
|
|
554
555
|
'`/new` — 开启全新会话',
|
|
555
556
|
'`/session ID` — 绑定已有会话',
|
|
556
557
|
'`/sessionlist [工作区]` 或 `/sessions [工作区]` — 列出会话',
|
|
558
|
+
'`/sessionlist --limit N` 或 `/sessions --limit N` — 仅列出当前工作区前 N 个会话',
|
|
557
559
|
'`/workspace 工作区序号或绝对路径` — 切换工作区',
|
|
558
560
|
'`/workspacelist` — 列出工作区',
|
|
559
561
|
'`/status` — 查看连接状态',
|
|
@@ -91,6 +91,7 @@ function helpText() {
|
|
|
91
91
|
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
92
92
|
t('/workspacelist 列出工作区绝对路径'),
|
|
93
93
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
94
|
+
t('/sessionlist --limit N 仅列出当前工作区前 N 个会话'),
|
|
94
95
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
95
96
|
t('/models 按序号列出所有可用模型'),
|
|
96
97
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|
|
@@ -246,8 +246,8 @@ export default {
|
|
|
246
246
|
'/steer 指令 给 Agent 补充指令': '/steer INSTRUCTION Steer the Agent',
|
|
247
247
|
'**📋 卡片功能**\n\n1. 会话下拉 — 切换当前绑定会话\n2. 工作区下拉 — 切换工作区\n3. 🤖 预设下拉 — 切换 Agent 预设\n4. 🧠 模型下拉 — 切换模型\n5. 🆕 新会话 — 开启全新会话\n6. 📋 会话/关注 — 查看/绑定会话,管理关注\n7. ⏹ 停止 — 停止当前任务\n8. 📐 压缩 — 压缩当前会话上下文\n9. 补充指令 — 给 Agent 发送指令\n10. 🗄 归档切换 — 显示/隐藏归档会话\n11. 📊 状态 — 查看系统连接状态\n12. 📖 帮助 — 查看本帮助':
|
|
248
248
|
'**📋 Card features**\n\n1. Session dropdown — switch the bound session\n2. Workspace dropdown — switch workspace\n3. 🤖 Preset dropdown — switch Agent Preset\n4. 🧠 Model dropdown — switch model\n5. 🆕 New session — start fresh\n6. 📋 Sessions/watches — view or bind sessions and manage watches\n7. ⏹ Stop — stop the current task\n8. 📐 Compact — compact the current session context\n9. Steer task — send an instruction to the Agent\n10. 🗄 Archived toggle — show or hide archived sessions\n11. 📊 Status — view connection status\n12. 📖 Help — view this help',
|
|
249
|
-
'**⌨️ 文本命令**\n\n`/m` — 打开菜单卡片\n`/new` — 开启全新会话\n`/session ID` — 绑定已有会话\n`/sessionlist [工作区]` 或 `/sessions [工作区]` — 列出会话\n`/workspace 工作区序号或绝对路径` — 切换工作区\n`/workspacelist` — 列出工作区\n`/status` — 查看连接状态\n`/compact` — 压缩上下文\n`/stop` — 停止当前任务\n`/steer 指令` — 补充指令\n`/watch ID` — 关注会话\n`/watchlist` — 关注列表\n`/unwatch ID` — 取消关注\n`/archived on/off` — 归档显隐\n`/presetlist` 或 `/presets` — 列出预设\n`/preset [序号/ID]` — 切换预设\n`/preset --default` — 跟随默认\n`/models` — 列出模型\n`/reasoninglist` 或 `/reasonings` — 按序号列出当前模型可用推理等级\n`/reasoning [序号、等级ID或 --default]` — 查看或切换当前推理等级\n`/model [序号或完整模型ID] [推理等级ID]` — 查看或切换当前会话模型\n`/batch` — 开启批量输入(仅私聊,最多 10 条文字)\n`/send` — 提交当前批次\n`/cancel` — 取消当前批次\n`/repair` — 补全飞书权限与卡片回调':
|
|
250
|
-
'**⌨️ Text commands**\n\n`/m` — open the menu card\n`/new` — start a new session\n`/session ID` — bind an existing session\n`/sessionlist [workspace]` or `/sessions [workspace]` — list sessions\n`/workspace <workspace index or absolute path>` — switch workspace\n`/workspacelist` — list workspaces\n`/status` — view connection status\n`/compact` — compact context\n`/stop` — stop the current task\n`/steer INSTRUCTION` — steer the task\n`/watch ID` — watch a session\n`/watchlist` — list watched sessions\n`/unwatch ID` — stop watching\n`/archived on/off` — show or hide archived sessions\n`/presetlist` or `/presets` — list presets\n`/preset [index/ID]` — switch preset\n`/preset --default` — follow default\n`/models` — list models\n`/reasoninglist` or `/reasonings` — list reasoning efforts for the current model\n`/reasoning [index, effort ID, or --default]` — show or switch reasoning effort\n`/model [index or full model ID] [reasoning effort ID]` — show or switch the current Session model\n`/batch` — start batch input (direct messages only, up to 10 text messages)\n`/send` — submit the current batch\n`/cancel` — cancel the current batch\n`/repair` — complete Feishu permissions and the card callback',
|
|
249
|
+
'**⌨️ 文本命令**\n\n`/m` — 打开菜单卡片\n`/new` — 开启全新会话\n`/session ID` — 绑定已有会话\n`/sessionlist [工作区]` 或 `/sessions [工作区]` — 列出会话\n`/sessionlist --limit N` 或 `/sessions --limit N` — 仅列出当前工作区前 N 个会话\n`/workspace 工作区序号或绝对路径` — 切换工作区\n`/workspacelist` — 列出工作区\n`/status` — 查看连接状态\n`/compact` — 压缩上下文\n`/stop` — 停止当前任务\n`/steer 指令` — 补充指令\n`/watch ID` — 关注会话\n`/watchlist` — 关注列表\n`/unwatch ID` — 取消关注\n`/archived on/off` — 归档显隐\n`/presetlist` 或 `/presets` — 列出预设\n`/preset [序号/ID]` — 切换预设\n`/preset --default` — 跟随默认\n`/models` — 列出模型\n`/reasoninglist` 或 `/reasonings` — 按序号列出当前模型可用推理等级\n`/reasoning [序号、等级ID或 --default]` — 查看或切换当前推理等级\n`/model [序号或完整模型ID] [推理等级ID]` — 查看或切换当前会话模型\n`/batch` — 开启批量输入(仅私聊,最多 10 条文字)\n`/send` — 提交当前批次\n`/cancel` — 取消当前批次\n`/repair` — 补全飞书权限与卡片回调':
|
|
250
|
+
'**⌨️ Text commands**\n\n`/m` — open the menu card\n`/new` — start a new session\n`/session ID` — bind an existing session\n`/sessionlist [workspace]` or `/sessions [workspace]` — list sessions\n`/sessionlist --limit N` or `/sessions --limit N` — list only the first N sessions in the current workspace\n`/workspace <workspace index or absolute path>` — switch workspace\n`/workspacelist` — list workspaces\n`/status` — view connection status\n`/compact` — compact context\n`/stop` — stop the current task\n`/steer INSTRUCTION` — steer the task\n`/watch ID` — watch a session\n`/watchlist` — list watched sessions\n`/unwatch ID` — stop watching\n`/archived on/off` — show or hide archived sessions\n`/presetlist` or `/presets` — list presets\n`/preset [index/ID]` — switch preset\n`/preset --default` — follow default\n`/models` — list models\n`/reasoninglist` or `/reasonings` — list reasoning efforts for the current model\n`/reasoning [index, effort ID, or --default]` — show or switch reasoning effort\n`/model [index or full model ID] [reasoning effort ID]` — show or switch the current Session model\n`/batch` — start batch input (direct messages only, up to 10 text messages)\n`/send` — submit the current batch\n`/cancel` — cancel the current batch\n`/repair` — complete Feishu permissions and the card callback',
|
|
251
251
|
'**💡 数字兜底**\n回复数字快速操作:\n**1**工作区列表 · **2**新会话 · **3**会话/关注\n**4**状态 · **5**补全权限 · **6**帮助':
|
|
252
252
|
'**💡 Number fallback**\nReply with a number for a quick action:\n**1** Workspace list · **2** New session · **3** Sessions/watches\n**4** Status · **5** Complete permissions · **6** Help',
|
|
253
253
|
'从下方下拉选择补充指令;最后一项可自定义输入。':
|
|
@@ -127,6 +127,8 @@ export default {
|
|
|
127
127
|
'/sessionlist [workspace index or absolute path] List session IDs and titles',
|
|
128
128
|
'/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题':
|
|
129
129
|
'/sessionlist or /sessions [workspace index or absolute path] List session IDs and titles',
|
|
130
|
+
'/sessionlist --limit N 仅列出当前工作区前 N 个会话':
|
|
131
|
+
'/sessionlist --limit N List only the first N sessions in the current workspace',
|
|
130
132
|
'/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话':
|
|
131
133
|
'/session <Session ID or workspace index> Bind this chat to the specified session',
|
|
132
134
|
'/models 按序号列出所有可用模型': '/models List all available models by index',
|
|
@@ -3,8 +3,8 @@ export default {
|
|
|
3
3
|
// workspace-command.mjs
|
|
4
4
|
'用法:/session Session ID 或当前工作区序号(/session N)':
|
|
5
5
|
'Usage: /session Session ID or the session index in the current Workspace (/session N)',
|
|
6
|
-
'用法:\n/sessionlist 列出当前工作区会话\n/sessionlist 工作区序号 按 /workspacelist 序号列出会话\n/sessionlist 工作区绝对路径 列出指定工作区会话':
|
|
7
|
-
'Usage:\n/sessionlist List Sessions in the current Workspace\n/sessionlist Workspace index List Sessions by /workspacelist index\n/sessionlist Workspace absolute path List Sessions in the given Workspace',
|
|
6
|
+
'用法:\n/sessionlist 列出当前工作区会话\n/sessionlist --limit N 列出当前工作区前 N 个会话(N 为正整数)\n/sessionlist 工作区序号 按 /workspacelist 序号列出会话\n/sessionlist 工作区绝对路径 列出指定工作区会话':
|
|
7
|
+
'Usage:\n/sessionlist List Sessions in the current Workspace\n/sessionlist --limit N List the first N Sessions in the current Workspace (N must be a positive integer)\n/sessionlist Workspace index List Sessions by /workspacelist index\n/sessionlist Workspace absolute path List Sessions in the given Workspace',
|
|
8
8
|
'工作区必须是绝对路径。\n{usage}': 'The Workspace must be an absolute path.\n{usage}',
|
|
9
9
|
'工作区路径包含不支持的字符或长度超过限制。\n{usage}':
|
|
10
10
|
'The Workspace path contains unsupported characters or exceeds the length limit.\n{usage}',
|
|
@@ -597,6 +597,7 @@ export class TextHarnessBridge {
|
|
|
597
597
|
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
598
598
|
t('/workspacelist 列出工作区绝对路径'),
|
|
599
599
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
600
|
+
t('/sessionlist --limit N 仅列出当前工作区前 N 个会话'),
|
|
600
601
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
601
602
|
t('/models 按序号列出所有可用模型'),
|
|
602
603
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|
|
@@ -18,6 +18,7 @@ const SESSION_BIND_USAGE = '用法:/session Session ID 或当前工作区序
|
|
|
18
18
|
const SESSION_LIST_USAGE = [
|
|
19
19
|
'用法:',
|
|
20
20
|
'/sessionlist 列出当前工作区会话',
|
|
21
|
+
'/sessionlist --limit N 列出当前工作区前 N 个会话(N 为正整数)',
|
|
21
22
|
'/sessionlist 工作区序号 按 /workspacelist 序号列出会话',
|
|
22
23
|
'/sessionlist 工作区绝对路径 列出指定工作区会话',
|
|
23
24
|
].join('\n');
|
|
@@ -45,6 +46,20 @@ function validSessionId(value) {
|
|
|
45
46
|
&& !UNSAFE_DISPLAY_TEXT.test(value);
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
export function parseSessionListArgument(value) {
|
|
50
|
+
const argument = typeof value === 'string' ? value.trim() : '';
|
|
51
|
+
if (!argument) return { selector: '', limit: null };
|
|
52
|
+
if (!argument.toLowerCase().startsWith('--limit')) {
|
|
53
|
+
return { selector: argument, limit: null };
|
|
54
|
+
}
|
|
55
|
+
const match = /^--limit[ \t]+(\d+)$/iu.exec(argument);
|
|
56
|
+
const limit = match ? Number(match[1]) : null;
|
|
57
|
+
if (!Number.isSafeInteger(limit) || limit < 1) {
|
|
58
|
+
return { error: t(SESSION_LIST_USAGE) };
|
|
59
|
+
}
|
|
60
|
+
return { selector: '', limit };
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
async function existingWorkspacePaths(values) {
|
|
49
64
|
const checked = await Promise.all(values.map(async (value) => {
|
|
50
65
|
const workspace = normalizedWorkspacePath(value);
|
|
@@ -235,12 +250,13 @@ async function currentSessionListWorkspace(harness) {
|
|
|
235
250
|
}
|
|
236
251
|
|
|
237
252
|
async function runSessionListCommand(match, harness) {
|
|
253
|
+
const request = parseSessionListArgument(match[1]);
|
|
254
|
+
if (request.error) return commandResult(request.error);
|
|
238
255
|
if (typeof harness?.listWorkspaceSessions !== 'function') {
|
|
239
256
|
return commandResult(t('当前机器人暂不支持列出工作区会话。'));
|
|
240
257
|
}
|
|
241
|
-
const selector = match[1]?.trim() ?? '';
|
|
242
258
|
try {
|
|
243
|
-
const resolved = await resolveSessionListWorkspace(selector, harness);
|
|
259
|
+
const resolved = await resolveSessionListWorkspace(request.selector, harness);
|
|
244
260
|
if (resolved.error) return commandResult(resolved.error);
|
|
245
261
|
const listed = await harness.listWorkspaceSessions(resolved.workspace);
|
|
246
262
|
if (!listed || !Array.isArray(listed.sessions)) {
|
|
@@ -249,7 +265,10 @@ async function runSessionListCommand(match, harness) {
|
|
|
249
265
|
harness.assertWorkspaceScope?.();
|
|
250
266
|
const workspace = normalizedWorkspacePath(listed.workspace) ?? resolved.workspace;
|
|
251
267
|
const currentWorkspace = await currentSessionListWorkspace(harness);
|
|
252
|
-
const
|
|
268
|
+
const sessions = request.limit === null
|
|
269
|
+
? listed.sessions
|
|
270
|
+
: listed.sessions.slice(0, request.limit);
|
|
271
|
+
const message = sessionListMessage(workspace, sessions, {
|
|
253
272
|
currentWorkspace: workspace === currentWorkspace,
|
|
254
273
|
});
|
|
255
274
|
return commandResult(message, splitWorkspaceCommandMessage(message));
|
|
@@ -74,6 +74,7 @@ function helpText() {
|
|
|
74
74
|
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
75
75
|
t('/workspacelist 列出工作区绝对路径'),
|
|
76
76
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
77
|
+
t('/sessionlist --limit N 仅列出当前工作区前 N 个会话'),
|
|
77
78
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
78
79
|
t('/models 按序号列出所有可用模型'),
|
|
79
80
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|
|
@@ -88,6 +88,7 @@ const HELP_TEXT = () => [
|
|
|
88
88
|
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
89
89
|
t('/workspacelist 列出工作区绝对路径'),
|
|
90
90
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
91
|
+
t('/sessionlist --limit N 仅列出当前工作区前 N 个会话'),
|
|
91
92
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
92
93
|
t('/models 按序号列出所有可用模型'),
|
|
93
94
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|