@openma/deepseek-harness-acp 0.4.1 → 0.4.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/dist/bridge.js +135 -16
- package/dist/index.js +135 -16
- package/package.json +1 -1
package/dist/bridge.js
CHANGED
|
@@ -265,8 +265,14 @@ var SessionProjection = class {
|
|
|
265
265
|
toolCalls = /* @__PURE__ */ new Map();
|
|
266
266
|
window = emptyWindow();
|
|
267
267
|
lastContextUse;
|
|
268
|
-
|
|
268
|
+
/** Client renders `_meta.terminal_output` display terminals (Zed extension). */
|
|
269
|
+
terminalOutput;
|
|
270
|
+
/** Session working directory, advertised on display terminals. */
|
|
271
|
+
cwd;
|
|
272
|
+
constructor(contextWindow, options) {
|
|
269
273
|
this.contextWindow = contextWindow;
|
|
274
|
+
this.terminalOutput = options?.terminalOutput ?? false;
|
|
275
|
+
this.cwd = options?.cwd;
|
|
270
276
|
}
|
|
271
277
|
/** Reset per-prompt accumulators; call when a new `session/prompt` starts. */
|
|
272
278
|
beginPrompt() {
|
|
@@ -395,6 +401,7 @@ var SessionProjection = class {
|
|
|
395
401
|
const rawArguments = typeof data["arguments"] === "string" ? data["arguments"] : "{}";
|
|
396
402
|
const facts = classifyToolCall(name3, rawArguments);
|
|
397
403
|
this.toolCalls.set(callId, facts);
|
|
404
|
+
const displayTerminal = this.terminalOutput && facts.kind === "execute";
|
|
398
405
|
return [
|
|
399
406
|
{
|
|
400
407
|
sessionUpdate: "tool_call",
|
|
@@ -404,7 +411,16 @@ var SessionProjection = class {
|
|
|
404
411
|
kind: facts.kind,
|
|
405
412
|
status: "in_progress",
|
|
406
413
|
rawInput: facts.rawInput,
|
|
407
|
-
...facts.locations.length > 0 ? { locations: facts.locations } : {}
|
|
414
|
+
...facts.locations.length > 0 ? { locations: facts.locations } : {},
|
|
415
|
+
...displayTerminal ? {
|
|
416
|
+
content: [{ type: "terminal", terminalId: callId }],
|
|
417
|
+
_meta: {
|
|
418
|
+
terminal_info: {
|
|
419
|
+
terminal_id: callId,
|
|
420
|
+
...this.cwd !== void 0 ? { cwd: this.cwd } : {}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
} : {}
|
|
408
424
|
}
|
|
409
425
|
];
|
|
410
426
|
}
|
|
@@ -421,6 +437,7 @@ var SessionProjection = class {
|
|
|
421
437
|
})() : void 0
|
|
422
438
|
) ?? asString(data["callId"]);
|
|
423
439
|
if (callId === void 0) return [];
|
|
440
|
+
const facts = this.toolCalls.get(callId);
|
|
424
441
|
const { failed, text, diffs } = extractToolResult(data);
|
|
425
442
|
const content = diffs.map((diff) => ({
|
|
426
443
|
type: "diff",
|
|
@@ -428,8 +445,36 @@ var SessionProjection = class {
|
|
|
428
445
|
...diff.oldText !== null ? { oldText: diff.oldText } : {},
|
|
429
446
|
newText: diff.newText
|
|
430
447
|
}));
|
|
448
|
+
const isCommand = facts?.kind === "execute";
|
|
449
|
+
if (this.terminalOutput && isCommand) {
|
|
450
|
+
this.toolCalls.delete(callId);
|
|
451
|
+
return [
|
|
452
|
+
...text.length > 0 ? [
|
|
453
|
+
{
|
|
454
|
+
sessionUpdate: "tool_call_update",
|
|
455
|
+
toolCallId: callId,
|
|
456
|
+
_meta: { terminal_output: { terminal_id: callId, data: text } }
|
|
457
|
+
}
|
|
458
|
+
] : [],
|
|
459
|
+
{
|
|
460
|
+
sessionUpdate: "tool_call_update",
|
|
461
|
+
toolCallId: callId,
|
|
462
|
+
status: failed ? "failed" : "completed",
|
|
463
|
+
...text.length > 0 ? { rawOutput: { output: text, isError: failed } } : {},
|
|
464
|
+
_meta: {
|
|
465
|
+
terminal_exit: { terminal_id: callId, exit_code: failed ? 1 : 0, signal: null }
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
];
|
|
469
|
+
}
|
|
431
470
|
if (text.length > 0 && diffs.length === 0) {
|
|
432
|
-
const block = {
|
|
471
|
+
const block = {
|
|
472
|
+
type: "text",
|
|
473
|
+
text: isCommand ? `\`\`\`sh
|
|
474
|
+
${text.replace(/\n+$/, "")}
|
|
475
|
+
\`\`\`
|
|
476
|
+
` : text
|
|
477
|
+
};
|
|
433
478
|
content.push({ type: "content", content: block });
|
|
434
479
|
}
|
|
435
480
|
this.toolCalls.delete(callId);
|
|
@@ -591,6 +636,7 @@ async function apply(ctx, config = {}) {
|
|
|
591
636
|
const sessions = /* @__PURE__ */ new Map();
|
|
592
637
|
let closed = false;
|
|
593
638
|
let conn;
|
|
639
|
+
let clientTerminalOutput = false;
|
|
594
640
|
const modelCandidates = () => {
|
|
595
641
|
const seen = /* @__PURE__ */ new Set();
|
|
596
642
|
if (config.model !== void 0) seen.add(config.model);
|
|
@@ -908,6 +954,7 @@ async function apply(ctx, config = {}) {
|
|
|
908
954
|
delete record.selection;
|
|
909
955
|
ensureSelection(record);
|
|
910
956
|
setApprovalPolicy(record, record.approvals);
|
|
957
|
+
publishCommands(acpSessionId, record);
|
|
911
958
|
};
|
|
912
959
|
const setApprovalPolicy = (record, policy) => {
|
|
913
960
|
try {
|
|
@@ -1039,18 +1086,64 @@ async function apply(ctx, config = {}) {
|
|
|
1039
1086
|
}
|
|
1040
1087
|
return result;
|
|
1041
1088
|
};
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1089
|
+
const BUILTIN_COMMANDS = [
|
|
1090
|
+
{ name: "status", description: "Show adapter, model, mode, and token status" },
|
|
1091
|
+
{
|
|
1092
|
+
name: "login",
|
|
1093
|
+
description: "Save a DeepSeek API key into the harness credential store (~/.dsh/.credentials.yaml)",
|
|
1094
|
+
input: { hint: "<api-key>" }
|
|
1095
|
+
},
|
|
1096
|
+
{ name: "logout", description: "Remove the API key stored in the harness credential store" }
|
|
1097
|
+
];
|
|
1098
|
+
const availableCommandsFor = async (record) => {
|
|
1099
|
+
const list = [...BUILTIN_COMMANDS];
|
|
1100
|
+
const seen = new Set(list.map((command) => command.name));
|
|
1101
|
+
const commandsSvc = ctx.get("commands");
|
|
1102
|
+
if (commandsSvc !== void 0) {
|
|
1103
|
+
try {
|
|
1104
|
+
for (const descriptor of commandsSvc.list(record.agent)) {
|
|
1105
|
+
if (seen.has(descriptor.name)) continue;
|
|
1106
|
+
seen.add(descriptor.name);
|
|
1107
|
+
list.push({
|
|
1108
|
+
name: descriptor.name,
|
|
1109
|
+
description: descriptor.description,
|
|
1110
|
+
...descriptor.input !== void 0 ? { input: { hint: descriptor.input.hint } } : {}
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
logWarn(`command listing failed: ${String(error)}`);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
const skillsSvc = ctx.get("skills");
|
|
1118
|
+
if (skillsSvc !== void 0) {
|
|
1119
|
+
try {
|
|
1120
|
+
const skills = await skillsSvc.list({
|
|
1121
|
+
...record.agent.session.header.cwd !== void 0 ? { cwd: record.agent.session.header.cwd } : {},
|
|
1122
|
+
scope: record.agent
|
|
1123
|
+
});
|
|
1124
|
+
for (const skill of skills) {
|
|
1125
|
+
if (skill.invocation.userInvocable !== true) continue;
|
|
1126
|
+
if (seen.has(skill.name)) continue;
|
|
1127
|
+
seen.add(skill.name);
|
|
1128
|
+
list.push({
|
|
1129
|
+
name: skill.name,
|
|
1130
|
+
description: skill.description,
|
|
1131
|
+
input: { hint: "instructions for the skill" }
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
} catch (error) {
|
|
1135
|
+
logDebug(`skill listing failed: ${String(error)}`);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
return list;
|
|
1139
|
+
};
|
|
1140
|
+
const publishCommands = (sessionId, record) => {
|
|
1141
|
+
const target = record ?? sessions.get(sessionId);
|
|
1142
|
+
if (target === void 0) return;
|
|
1143
|
+
void availableCommandsFor(target).then((availableCommands) => {
|
|
1144
|
+
notify(sessionId, { sessionUpdate: "available_commands_update", availableCommands });
|
|
1145
|
+
}).catch((error) => {
|
|
1146
|
+
logWarn(`publishing commands failed: ${String(error)}`);
|
|
1054
1147
|
});
|
|
1055
1148
|
};
|
|
1056
1149
|
const credentialStore = () => {
|
|
@@ -1143,7 +1236,10 @@ async function apply(ctx, config = {}) {
|
|
|
1143
1236
|
const record = {
|
|
1144
1237
|
agent,
|
|
1145
1238
|
dispose,
|
|
1146
|
-
projection: projection ?? new SessionProjection(
|
|
1239
|
+
projection: projection ?? new SessionProjection(void 0, {
|
|
1240
|
+
terminalOutput: clientTerminalOutput,
|
|
1241
|
+
...agent.session.header.cwd !== void 0 ? { cwd: agent.session.header.cwd } : {}
|
|
1242
|
+
}),
|
|
1147
1243
|
modeId,
|
|
1148
1244
|
model,
|
|
1149
1245
|
approvals: modeId === "danger-full-access" ? "never" : "ask",
|
|
@@ -1213,6 +1309,8 @@ async function apply(ctx, config = {}) {
|
|
|
1213
1309
|
initialize(params) {
|
|
1214
1310
|
const hasPersistence = ctx.get("sessionPersistence") !== void 0;
|
|
1215
1311
|
const requested = params.protocolVersion;
|
|
1312
|
+
const capsMeta = params.clientCapabilities?.["_meta"];
|
|
1313
|
+
clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
|
|
1216
1314
|
return Promise.resolve({
|
|
1217
1315
|
protocolVersion: typeof requested === "number" && requested >= 1 && requested < PROTOCOL_VERSION ? requested : PROTOCOL_VERSION,
|
|
1218
1316
|
agentInfo: { name: "dsh-acp", title: "DeepSeek Harness", version: VERSION },
|
|
@@ -1393,6 +1491,27 @@ async function apply(ctx, config = {}) {
|
|
|
1393
1491
|
return respond(await loginText(trimmed.slice(commandMatch[0].length)));
|
|
1394
1492
|
}
|
|
1395
1493
|
if (commandMatch?.[1] === "logout") return respond(await logoutText());
|
|
1494
|
+
if (commandMatch !== null && commandMatch[1] !== void 0) {
|
|
1495
|
+
const commandsSvc = ctx.get("commands");
|
|
1496
|
+
if (commandsSvc !== void 0) {
|
|
1497
|
+
let execution;
|
|
1498
|
+
try {
|
|
1499
|
+
execution = await commandsSvc.execute(
|
|
1500
|
+
record.agent,
|
|
1501
|
+
trimmed,
|
|
1502
|
+
new AbortController().signal
|
|
1503
|
+
);
|
|
1504
|
+
} catch (error) {
|
|
1505
|
+
return respond(`\u26A0 /${commandMatch[1]} failed: ${errorChain2(error)}`);
|
|
1506
|
+
}
|
|
1507
|
+
if (execution !== void 0) {
|
|
1508
|
+
const { result } = execution;
|
|
1509
|
+
const text = result.text ?? (result.kind === "success" ? `/${commandMatch[1]} \u2713` : `/${commandMatch[1]} failed`);
|
|
1510
|
+
publishCommands(params.sessionId, record);
|
|
1511
|
+
return respond(result.kind === "error" ? `\u26A0 ${text}` : text);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1396
1515
|
if (!await credentialPresent()) {
|
|
1397
1516
|
return respond(
|
|
1398
1517
|
[
|
package/dist/index.js
CHANGED
|
@@ -290,8 +290,14 @@ var SessionProjection = class {
|
|
|
290
290
|
toolCalls = /* @__PURE__ */ new Map();
|
|
291
291
|
window = emptyWindow();
|
|
292
292
|
lastContextUse;
|
|
293
|
-
|
|
293
|
+
/** Client renders `_meta.terminal_output` display terminals (Zed extension). */
|
|
294
|
+
terminalOutput;
|
|
295
|
+
/** Session working directory, advertised on display terminals. */
|
|
296
|
+
cwd;
|
|
297
|
+
constructor(contextWindow, options) {
|
|
294
298
|
this.contextWindow = contextWindow;
|
|
299
|
+
this.terminalOutput = options?.terminalOutput ?? false;
|
|
300
|
+
this.cwd = options?.cwd;
|
|
295
301
|
}
|
|
296
302
|
/** Reset per-prompt accumulators; call when a new `session/prompt` starts. */
|
|
297
303
|
beginPrompt() {
|
|
@@ -420,6 +426,7 @@ var SessionProjection = class {
|
|
|
420
426
|
const rawArguments = typeof data["arguments"] === "string" ? data["arguments"] : "{}";
|
|
421
427
|
const facts = classifyToolCall(name3, rawArguments);
|
|
422
428
|
this.toolCalls.set(callId, facts);
|
|
429
|
+
const displayTerminal = this.terminalOutput && facts.kind === "execute";
|
|
423
430
|
return [
|
|
424
431
|
{
|
|
425
432
|
sessionUpdate: "tool_call",
|
|
@@ -429,7 +436,16 @@ var SessionProjection = class {
|
|
|
429
436
|
kind: facts.kind,
|
|
430
437
|
status: "in_progress",
|
|
431
438
|
rawInput: facts.rawInput,
|
|
432
|
-
...facts.locations.length > 0 ? { locations: facts.locations } : {}
|
|
439
|
+
...facts.locations.length > 0 ? { locations: facts.locations } : {},
|
|
440
|
+
...displayTerminal ? {
|
|
441
|
+
content: [{ type: "terminal", terminalId: callId }],
|
|
442
|
+
_meta: {
|
|
443
|
+
terminal_info: {
|
|
444
|
+
terminal_id: callId,
|
|
445
|
+
...this.cwd !== void 0 ? { cwd: this.cwd } : {}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
} : {}
|
|
433
449
|
}
|
|
434
450
|
];
|
|
435
451
|
}
|
|
@@ -446,6 +462,7 @@ var SessionProjection = class {
|
|
|
446
462
|
})() : void 0
|
|
447
463
|
) ?? asString(data["callId"]);
|
|
448
464
|
if (callId === void 0) return [];
|
|
465
|
+
const facts = this.toolCalls.get(callId);
|
|
449
466
|
const { failed, text, diffs } = extractToolResult(data);
|
|
450
467
|
const content = diffs.map((diff) => ({
|
|
451
468
|
type: "diff",
|
|
@@ -453,8 +470,36 @@ var SessionProjection = class {
|
|
|
453
470
|
...diff.oldText !== null ? { oldText: diff.oldText } : {},
|
|
454
471
|
newText: diff.newText
|
|
455
472
|
}));
|
|
473
|
+
const isCommand = facts?.kind === "execute";
|
|
474
|
+
if (this.terminalOutput && isCommand) {
|
|
475
|
+
this.toolCalls.delete(callId);
|
|
476
|
+
return [
|
|
477
|
+
...text.length > 0 ? [
|
|
478
|
+
{
|
|
479
|
+
sessionUpdate: "tool_call_update",
|
|
480
|
+
toolCallId: callId,
|
|
481
|
+
_meta: { terminal_output: { terminal_id: callId, data: text } }
|
|
482
|
+
}
|
|
483
|
+
] : [],
|
|
484
|
+
{
|
|
485
|
+
sessionUpdate: "tool_call_update",
|
|
486
|
+
toolCallId: callId,
|
|
487
|
+
status: failed ? "failed" : "completed",
|
|
488
|
+
...text.length > 0 ? { rawOutput: { output: text, isError: failed } } : {},
|
|
489
|
+
_meta: {
|
|
490
|
+
terminal_exit: { terminal_id: callId, exit_code: failed ? 1 : 0, signal: null }
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
];
|
|
494
|
+
}
|
|
456
495
|
if (text.length > 0 && diffs.length === 0) {
|
|
457
|
-
const block = {
|
|
496
|
+
const block = {
|
|
497
|
+
type: "text",
|
|
498
|
+
text: isCommand ? `\`\`\`sh
|
|
499
|
+
${text.replace(/\n+$/, "")}
|
|
500
|
+
\`\`\`
|
|
501
|
+
` : text
|
|
502
|
+
};
|
|
458
503
|
content.push({ type: "content", content: block });
|
|
459
504
|
}
|
|
460
505
|
this.toolCalls.delete(callId);
|
|
@@ -616,6 +661,7 @@ async function apply(ctx, config = {}) {
|
|
|
616
661
|
const sessions = /* @__PURE__ */ new Map();
|
|
617
662
|
let closed = false;
|
|
618
663
|
let conn;
|
|
664
|
+
let clientTerminalOutput = false;
|
|
619
665
|
const modelCandidates = () => {
|
|
620
666
|
const seen = /* @__PURE__ */ new Set();
|
|
621
667
|
if (config.model !== void 0) seen.add(config.model);
|
|
@@ -933,6 +979,7 @@ async function apply(ctx, config = {}) {
|
|
|
933
979
|
delete record.selection;
|
|
934
980
|
ensureSelection(record);
|
|
935
981
|
setApprovalPolicy(record, record.approvals);
|
|
982
|
+
publishCommands(acpSessionId, record);
|
|
936
983
|
};
|
|
937
984
|
const setApprovalPolicy = (record, policy) => {
|
|
938
985
|
try {
|
|
@@ -1064,18 +1111,64 @@ async function apply(ctx, config = {}) {
|
|
|
1064
1111
|
}
|
|
1065
1112
|
return result;
|
|
1066
1113
|
};
|
|
1067
|
-
const
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1114
|
+
const BUILTIN_COMMANDS = [
|
|
1115
|
+
{ name: "status", description: "Show adapter, model, mode, and token status" },
|
|
1116
|
+
{
|
|
1117
|
+
name: "login",
|
|
1118
|
+
description: "Save a DeepSeek API key into the harness credential store (~/.dsh/.credentials.yaml)",
|
|
1119
|
+
input: { hint: "<api-key>" }
|
|
1120
|
+
},
|
|
1121
|
+
{ name: "logout", description: "Remove the API key stored in the harness credential store" }
|
|
1122
|
+
];
|
|
1123
|
+
const availableCommandsFor = async (record) => {
|
|
1124
|
+
const list = [...BUILTIN_COMMANDS];
|
|
1125
|
+
const seen = new Set(list.map((command) => command.name));
|
|
1126
|
+
const commandsSvc = ctx.get("commands");
|
|
1127
|
+
if (commandsSvc !== void 0) {
|
|
1128
|
+
try {
|
|
1129
|
+
for (const descriptor of commandsSvc.list(record.agent)) {
|
|
1130
|
+
if (seen.has(descriptor.name)) continue;
|
|
1131
|
+
seen.add(descriptor.name);
|
|
1132
|
+
list.push({
|
|
1133
|
+
name: descriptor.name,
|
|
1134
|
+
description: descriptor.description,
|
|
1135
|
+
...descriptor.input !== void 0 ? { input: { hint: descriptor.input.hint } } : {}
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
logWarn(`command listing failed: ${String(error)}`);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
const skillsSvc = ctx.get("skills");
|
|
1143
|
+
if (skillsSvc !== void 0) {
|
|
1144
|
+
try {
|
|
1145
|
+
const skills = await skillsSvc.list({
|
|
1146
|
+
...record.agent.session.header.cwd !== void 0 ? { cwd: record.agent.session.header.cwd } : {},
|
|
1147
|
+
scope: record.agent
|
|
1148
|
+
});
|
|
1149
|
+
for (const skill of skills) {
|
|
1150
|
+
if (skill.invocation.userInvocable !== true) continue;
|
|
1151
|
+
if (seen.has(skill.name)) continue;
|
|
1152
|
+
seen.add(skill.name);
|
|
1153
|
+
list.push({
|
|
1154
|
+
name: skill.name,
|
|
1155
|
+
description: skill.description,
|
|
1156
|
+
input: { hint: "instructions for the skill" }
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
} catch (error) {
|
|
1160
|
+
logDebug(`skill listing failed: ${String(error)}`);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
return list;
|
|
1164
|
+
};
|
|
1165
|
+
const publishCommands = (sessionId, record) => {
|
|
1166
|
+
const target = record ?? sessions.get(sessionId);
|
|
1167
|
+
if (target === void 0) return;
|
|
1168
|
+
void availableCommandsFor(target).then((availableCommands) => {
|
|
1169
|
+
notify(sessionId, { sessionUpdate: "available_commands_update", availableCommands });
|
|
1170
|
+
}).catch((error) => {
|
|
1171
|
+
logWarn(`publishing commands failed: ${String(error)}`);
|
|
1079
1172
|
});
|
|
1080
1173
|
};
|
|
1081
1174
|
const credentialStore = () => {
|
|
@@ -1168,7 +1261,10 @@ async function apply(ctx, config = {}) {
|
|
|
1168
1261
|
const record = {
|
|
1169
1262
|
agent,
|
|
1170
1263
|
dispose,
|
|
1171
|
-
projection: projection ?? new SessionProjection(
|
|
1264
|
+
projection: projection ?? new SessionProjection(void 0, {
|
|
1265
|
+
terminalOutput: clientTerminalOutput,
|
|
1266
|
+
...agent.session.header.cwd !== void 0 ? { cwd: agent.session.header.cwd } : {}
|
|
1267
|
+
}),
|
|
1172
1268
|
modeId,
|
|
1173
1269
|
model,
|
|
1174
1270
|
approvals: modeId === "danger-full-access" ? "never" : "ask",
|
|
@@ -1238,6 +1334,8 @@ async function apply(ctx, config = {}) {
|
|
|
1238
1334
|
initialize(params) {
|
|
1239
1335
|
const hasPersistence = ctx.get("sessionPersistence") !== void 0;
|
|
1240
1336
|
const requested = params.protocolVersion;
|
|
1337
|
+
const capsMeta = params.clientCapabilities?.["_meta"];
|
|
1338
|
+
clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
|
|
1241
1339
|
return Promise.resolve({
|
|
1242
1340
|
protocolVersion: typeof requested === "number" && requested >= 1 && requested < PROTOCOL_VERSION ? requested : PROTOCOL_VERSION,
|
|
1243
1341
|
agentInfo: { name: "dsh-acp", title: "DeepSeek Harness", version: VERSION },
|
|
@@ -1418,6 +1516,27 @@ async function apply(ctx, config = {}) {
|
|
|
1418
1516
|
return respond(await loginText(trimmed.slice(commandMatch[0].length)));
|
|
1419
1517
|
}
|
|
1420
1518
|
if (commandMatch?.[1] === "logout") return respond(await logoutText());
|
|
1519
|
+
if (commandMatch !== null && commandMatch[1] !== void 0) {
|
|
1520
|
+
const commandsSvc = ctx.get("commands");
|
|
1521
|
+
if (commandsSvc !== void 0) {
|
|
1522
|
+
let execution;
|
|
1523
|
+
try {
|
|
1524
|
+
execution = await commandsSvc.execute(
|
|
1525
|
+
record.agent,
|
|
1526
|
+
trimmed,
|
|
1527
|
+
new AbortController().signal
|
|
1528
|
+
);
|
|
1529
|
+
} catch (error) {
|
|
1530
|
+
return respond(`\u26A0 /${commandMatch[1]} failed: ${errorChain2(error)}`);
|
|
1531
|
+
}
|
|
1532
|
+
if (execution !== void 0) {
|
|
1533
|
+
const { result } = execution;
|
|
1534
|
+
const text = result.text ?? (result.kind === "success" ? `/${commandMatch[1]} \u2713` : `/${commandMatch[1]} failed`);
|
|
1535
|
+
publishCommands(params.sessionId, record);
|
|
1536
|
+
return respond(result.kind === "error" ? `\u26A0 ${text}` : text);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1421
1540
|
if (!await credentialPresent()) {
|
|
1422
1541
|
return respond(
|
|
1423
1542
|
[
|