@ganglion/xacpx 0.24.0 → 0.24.1-beta.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/dist/bridge/bridge-main.js +6 -6
- package/dist/cli.js +267 -251
- package/dist/commands/handlers/session-handler.d.ts +6 -0
- package/dist/commands/handlers/session-recovery-handler.d.ts +7 -0
- package/dist/commands/router-types.d.ts +2 -0
- package/dist/commands/transport-diagnostics.d.ts +5 -0
- package/dist/control/control-event-bus.d.ts +7 -0
- package/dist/plugin-api.js +6 -6
- package/dist/recovery/discover-parent-package-paths.d.ts +49 -0
- package/dist/recovery/errors.d.ts +30 -0
- package/dist/weixin/agent/interface.d.ts +6 -0
- package/package.json +1 -1
|
@@ -4381,9 +4381,9 @@ var init_recovery = __esm(() => {
|
|
|
4381
4381
|
sessionInterrupted: (alias) => `Session "${alias}" was interrupted; no final reply received.`,
|
|
4382
4382
|
sessionInterruptedHint: "Retry directly. If the session remains unresponsive, send /cancel first, then retry.",
|
|
4383
4383
|
sessionInterruptedError: (summary) => `Error: ${summary}`,
|
|
4384
|
-
queueOverflowWarning: "
|
|
4385
|
-
queueOverflowHint: "
|
|
4386
|
-
queueOverflowUnconfirmedHint: "
|
|
4384
|
+
queueOverflowWarning: "",
|
|
4385
|
+
queueOverflowHint: "Reply was truncated for size — you can continue.",
|
|
4386
|
+
queueOverflowUnconfirmedHint: "Output was large and cleanup wasn't confirmed — send /cancel, then continue.",
|
|
4387
4387
|
autoInstallHeadlineFixed: "⚠️ Auto-install ran but could not fix the session startup problem",
|
|
4388
4388
|
autoInstallHeadlineFailed: "❌ Auto-install failed",
|
|
4389
4389
|
autoInstallOriginalError: "Original error:",
|
|
@@ -5512,9 +5512,9 @@ var init_recovery2 = __esm(() => {
|
|
|
5512
5512
|
sessionInterrupted: (alias) => `当前会话「${alias}」执行中断,未收到最终回复。`,
|
|
5513
5513
|
sessionInterruptedHint: "请直接重试;如果长时间无响应,可先发送 /cancel 后再重试。",
|
|
5514
5514
|
sessionInterruptedError: (summary) => `错误信息:${summary}`,
|
|
5515
|
-
queueOverflowWarning: "
|
|
5516
|
-
queueOverflowHint: "
|
|
5517
|
-
queueOverflowUnconfirmedHint: "
|
|
5515
|
+
queueOverflowWarning: "",
|
|
5516
|
+
queueOverflowHint: "部分回复因过长已收束,可直接继续。",
|
|
5517
|
+
queueOverflowUnconfirmedHint: "输出过长且清理未确认,请先发 /cancel 再继续。",
|
|
5518
5518
|
autoInstallHeadlineFixed: "⚠️ 自动安装已执行但未能修复会话启动问题",
|
|
5519
5519
|
autoInstallHeadlineFailed: "❌ 自动安装失败",
|
|
5520
5520
|
autoInstallOriginalError: "原始错误:",
|
package/dist/cli.js
CHANGED
|
@@ -302,9 +302,9 @@ var init_recovery = __esm(() => {
|
|
|
302
302
|
sessionInterrupted: (alias) => `Session "${alias}" was interrupted; no final reply received.`,
|
|
303
303
|
sessionInterruptedHint: "Retry directly. If the session remains unresponsive, send /cancel first, then retry.",
|
|
304
304
|
sessionInterruptedError: (summary) => `Error: ${summary}`,
|
|
305
|
-
queueOverflowWarning: "
|
|
306
|
-
queueOverflowHint: "
|
|
307
|
-
queueOverflowUnconfirmedHint: "
|
|
305
|
+
queueOverflowWarning: "",
|
|
306
|
+
queueOverflowHint: "Reply was truncated for size — you can continue.",
|
|
307
|
+
queueOverflowUnconfirmedHint: "Output was large and cleanup wasn't confirmed — send /cancel, then continue.",
|
|
308
308
|
autoInstallHeadlineFixed: "⚠️ Auto-install ran but could not fix the session startup problem",
|
|
309
309
|
autoInstallHeadlineFailed: "❌ Auto-install failed",
|
|
310
310
|
autoInstallOriginalError: "Original error:",
|
|
@@ -1433,9 +1433,9 @@ var init_recovery2 = __esm(() => {
|
|
|
1433
1433
|
sessionInterrupted: (alias) => `当前会话「${alias}」执行中断,未收到最终回复。`,
|
|
1434
1434
|
sessionInterruptedHint: "请直接重试;如果长时间无响应,可先发送 /cancel 后再重试。",
|
|
1435
1435
|
sessionInterruptedError: (summary) => `错误信息:${summary}`,
|
|
1436
|
-
queueOverflowWarning: "
|
|
1437
|
-
queueOverflowHint: "
|
|
1438
|
-
queueOverflowUnconfirmedHint: "
|
|
1436
|
+
queueOverflowWarning: "",
|
|
1437
|
+
queueOverflowHint: "部分回复因过长已收束,可直接继续。",
|
|
1438
|
+
queueOverflowUnconfirmedHint: "输出过长且清理未确认,请先发 /cancel 再继续。",
|
|
1439
1439
|
autoInstallHeadlineFixed: "⚠️ 自动安装已执行但未能修复会话启动问题",
|
|
1440
1440
|
autoInstallHeadlineFailed: "❌ 自动安装失败",
|
|
1441
1441
|
autoInstallOriginalError: "原始错误:",
|
|
@@ -34428,7 +34428,7 @@ async function executeChatTurn(params) {
|
|
|
34428
34428
|
}
|
|
34429
34429
|
});
|
|
34430
34430
|
return {
|
|
34431
|
-
text: response.text,
|
|
34431
|
+
text: response.silent ? undefined : response.text,
|
|
34432
34432
|
media: response.media,
|
|
34433
34433
|
usedReply
|
|
34434
34434
|
};
|
|
@@ -41980,6 +41980,239 @@ var init_acpx_queue_overflow = __esm(() => {
|
|
|
41980
41980
|
};
|
|
41981
41981
|
});
|
|
41982
41982
|
|
|
41983
|
+
// src/commands/transport-diagnostics.ts
|
|
41984
|
+
function summarizeTransportError(message) {
|
|
41985
|
+
return message.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
41986
|
+
}
|
|
41987
|
+
function summarizeTransportDiagnostic(output) {
|
|
41988
|
+
const trimmed = output.replace(/\s+/g, " ").trim();
|
|
41989
|
+
if (trimmed.length === 0) {
|
|
41990
|
+
return;
|
|
41991
|
+
}
|
|
41992
|
+
return trimmed.slice(0, 200);
|
|
41993
|
+
}
|
|
41994
|
+
function summarizeTransportDiagnosticTail(output) {
|
|
41995
|
+
const trimmed = output.replace(/\s+/g, " ").trim();
|
|
41996
|
+
if (trimmed.length === 0) {
|
|
41997
|
+
return;
|
|
41998
|
+
}
|
|
41999
|
+
return trimmed.slice(-200);
|
|
42000
|
+
}
|
|
42001
|
+
function summarizeTransportNdjson(output, prefix) {
|
|
42002
|
+
const lines = output.split(`
|
|
42003
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
42004
|
+
if (lines.length === 0) {
|
|
42005
|
+
return {};
|
|
42006
|
+
}
|
|
42007
|
+
const methods = new Set;
|
|
42008
|
+
let agentMessageChunkCount = 0;
|
|
42009
|
+
let stopReason;
|
|
42010
|
+
for (const line of lines) {
|
|
42011
|
+
try {
|
|
42012
|
+
const payload = JSON.parse(line);
|
|
42013
|
+
if (typeof payload.method === "string" && payload.method.length > 0) {
|
|
42014
|
+
methods.add(payload.method);
|
|
42015
|
+
}
|
|
42016
|
+
if (payload.params?.update?.sessionUpdate === "agent_message_chunk") {
|
|
42017
|
+
agentMessageChunkCount += 1;
|
|
42018
|
+
}
|
|
42019
|
+
if (typeof payload.result?.stopReason === "string" && payload.result.stopReason.length > 0) {
|
|
42020
|
+
stopReason = payload.result.stopReason;
|
|
42021
|
+
}
|
|
42022
|
+
} catch {
|
|
42023
|
+
continue;
|
|
42024
|
+
}
|
|
42025
|
+
}
|
|
42026
|
+
const summary = {
|
|
42027
|
+
[`${prefix}LineCount`]: lines.length
|
|
42028
|
+
};
|
|
42029
|
+
if (methods.size > 0) {
|
|
42030
|
+
summary[`${prefix}Methods`] = [...methods].join(",");
|
|
42031
|
+
}
|
|
42032
|
+
if (agentMessageChunkCount > 0) {
|
|
42033
|
+
summary[`${prefix}AgentMessageChunkCount`] = agentMessageChunkCount;
|
|
42034
|
+
}
|
|
42035
|
+
if (stopReason) {
|
|
42036
|
+
summary[`${prefix}StopReason`] = stopReason;
|
|
42037
|
+
}
|
|
42038
|
+
return summary;
|
|
42039
|
+
}
|
|
42040
|
+
function isPartialPromptOutputError(message) {
|
|
42041
|
+
return message.includes(ACPX_PARTIAL_OUTPUT_SENTINEL);
|
|
42042
|
+
}
|
|
42043
|
+
var ACPX_PARTIAL_OUTPUT_SENTINEL = "未收到最终回复";
|
|
42044
|
+
|
|
42045
|
+
// src/recovery/errors.ts
|
|
42046
|
+
var MissingOptionalDepError, AutoInstallFailedError;
|
|
42047
|
+
var init_errors4 = __esm(() => {
|
|
42048
|
+
MissingOptionalDepError = class MissingOptionalDepError extends Error {
|
|
42049
|
+
kind = "missing_optional_dep";
|
|
42050
|
+
package;
|
|
42051
|
+
parentPackagePath;
|
|
42052
|
+
rawMessage;
|
|
42053
|
+
constructor(payload) {
|
|
42054
|
+
super(payload.rawMessage);
|
|
42055
|
+
this.name = "MissingOptionalDepError";
|
|
42056
|
+
this.package = payload.package;
|
|
42057
|
+
this.parentPackagePath = payload.parentPackagePath;
|
|
42058
|
+
this.rawMessage = payload.rawMessage;
|
|
42059
|
+
}
|
|
42060
|
+
};
|
|
42061
|
+
AutoInstallFailedError = class AutoInstallFailedError extends Error {
|
|
42062
|
+
kind = "auto_install_failed";
|
|
42063
|
+
original;
|
|
42064
|
+
steps;
|
|
42065
|
+
logPath;
|
|
42066
|
+
constructor(original, steps, logPath) {
|
|
42067
|
+
super(`auto-install failed: ${original.package}`);
|
|
42068
|
+
this.name = "AutoInstallFailedError";
|
|
42069
|
+
this.original = original;
|
|
42070
|
+
this.steps = steps;
|
|
42071
|
+
this.logPath = logPath;
|
|
42072
|
+
}
|
|
42073
|
+
};
|
|
42074
|
+
});
|
|
42075
|
+
|
|
42076
|
+
// src/commands/handlers/session-recovery-handler.ts
|
|
42077
|
+
function queueOverflowTipText(confirmed) {
|
|
42078
|
+
const r = t().recovery;
|
|
42079
|
+
return [r.queueOverflowWarning, confirmed ? r.queueOverflowHint : r.queueOverflowUnconfirmedHint].filter((line) => line.length > 0).join(`
|
|
42080
|
+
`);
|
|
42081
|
+
}
|
|
42082
|
+
function renderTransportError(session3, error2) {
|
|
42083
|
+
if (error2 instanceof AcpxQueueOverflowError) {
|
|
42084
|
+
return { silent: true };
|
|
42085
|
+
}
|
|
42086
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
42087
|
+
const registryError = renderAdapterRegistryError(session3, message);
|
|
42088
|
+
if (registryError)
|
|
42089
|
+
return registryError;
|
|
42090
|
+
if (message.includes("No acpx session found")) {
|
|
42091
|
+
if (session3.transient) {
|
|
42092
|
+
return {
|
|
42093
|
+
text: [
|
|
42094
|
+
t().recovery.transientSessionFailed,
|
|
42095
|
+
t().recovery.transientSessionHint
|
|
42096
|
+
].join(`
|
|
42097
|
+
`)
|
|
42098
|
+
};
|
|
42099
|
+
}
|
|
42100
|
+
const quotedWs = quoteWorkspaceNameIfNeeded(session3.workspace);
|
|
42101
|
+
return {
|
|
42102
|
+
text: [
|
|
42103
|
+
t().recovery.sessionUnavailable(session3.alias),
|
|
42104
|
+
t().recovery.sessionUnavailableRenewHint(session3.alias, session3.agent, quotedWs),
|
|
42105
|
+
t().recovery.sessionUnavailableAttachHint(session3.alias, session3.agent, quotedWs)
|
|
42106
|
+
].join(`
|
|
42107
|
+
`)
|
|
42108
|
+
};
|
|
42109
|
+
}
|
|
42110
|
+
if (!isPartialPromptOutputError(message)) {
|
|
42111
|
+
throw error2;
|
|
42112
|
+
}
|
|
42113
|
+
return {
|
|
42114
|
+
text: [
|
|
42115
|
+
t().recovery.sessionInterrupted(session3.alias),
|
|
42116
|
+
t().recovery.sessionInterruptedHint,
|
|
42117
|
+
t().recovery.sessionInterruptedError(summarizeTransportError(message))
|
|
42118
|
+
].join(`
|
|
42119
|
+
`)
|
|
42120
|
+
};
|
|
42121
|
+
}
|
|
42122
|
+
function renderSessionCreationError(session3, error2) {
|
|
42123
|
+
if (error2 instanceof AutoInstallFailedError) {
|
|
42124
|
+
const { original, steps, logPath } = error2;
|
|
42125
|
+
const r = t().recovery;
|
|
42126
|
+
const allVerifyFailed = steps.length > 0 && steps.every((s) => s.reason === "verify-failed");
|
|
42127
|
+
const headline = allVerifyFailed ? r.autoInstallHeadlineFixed : r.autoInstallHeadlineFailed;
|
|
42128
|
+
const stepLines = steps.map((s) => {
|
|
42129
|
+
const perStepPath = s.path ?? (s.scope === "precise" ? original.parentPackagePath : null);
|
|
42130
|
+
const label = s.scope === "precise" ? r.autoInstallScopePrecise(s.manager, perStepPath ?? undefined) : r.autoInstallScopeGlobal;
|
|
42131
|
+
if (s.reason === "verify-failed") {
|
|
42132
|
+
return r.autoInstallStepVerifyFailed(label);
|
|
42133
|
+
}
|
|
42134
|
+
return r.autoInstallStepError(label, s.stderrTail);
|
|
42135
|
+
}).join(`
|
|
42136
|
+
|
|
42137
|
+
`);
|
|
42138
|
+
return {
|
|
42139
|
+
text: [
|
|
42140
|
+
headline,
|
|
42141
|
+
``,
|
|
42142
|
+
r.autoInstallOriginalError,
|
|
42143
|
+
original.rawMessage,
|
|
42144
|
+
``,
|
|
42145
|
+
stepLines,
|
|
42146
|
+
``,
|
|
42147
|
+
r.autoInstallManual(original.package),
|
|
42148
|
+
r.autoInstallLog(logPath)
|
|
42149
|
+
].join(`
|
|
42150
|
+
`)
|
|
42151
|
+
};
|
|
42152
|
+
}
|
|
42153
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
42154
|
+
const registryError = renderAdapterRegistryError(session3, message);
|
|
42155
|
+
if (registryError)
|
|
42156
|
+
return {
|
|
42157
|
+
text: [
|
|
42158
|
+
t().recovery.sessionCreationFailed,
|
|
42159
|
+
registryError.text
|
|
42160
|
+
].join(`
|
|
42161
|
+
`)
|
|
42162
|
+
};
|
|
42163
|
+
if (message.includes("timed out") && message.includes("sessions new")) {
|
|
42164
|
+
return renderSessionCreationFailure(session3, message);
|
|
42165
|
+
}
|
|
42166
|
+
throw error2;
|
|
42167
|
+
}
|
|
42168
|
+
function renderAdapterRegistryError(session3, message) {
|
|
42169
|
+
const registry2 = managedAdapterRegistryFromCommand(session3.agentCommand);
|
|
42170
|
+
if (!registry2 || !isNpmAdapterRegistryNotFoundOutput(message))
|
|
42171
|
+
return null;
|
|
42172
|
+
return {
|
|
42173
|
+
text: t().recovery.adapterRegistryE404(registry2, DEFAULT_ADAPTER_REGISTRY)
|
|
42174
|
+
};
|
|
42175
|
+
}
|
|
42176
|
+
function renderSessionCreationVerificationError(session3) {
|
|
42177
|
+
return renderSessionCreationFailure(session3, t().recovery.sessionCreationVerificationDetail);
|
|
42178
|
+
}
|
|
42179
|
+
function renderSessionCreationFailure(session3, detail) {
|
|
42180
|
+
const r = t().recovery;
|
|
42181
|
+
return {
|
|
42182
|
+
text: [
|
|
42183
|
+
r.sessionCreationFailed,
|
|
42184
|
+
r.sessionCreationError(summarizeTransportError(detail)),
|
|
42185
|
+
r.sessionCreationAttachHint(session3.alias, session3.agent, quoteWorkspaceNameIfNeeded(session3.workspace))
|
|
42186
|
+
].join(`
|
|
42187
|
+
`)
|
|
42188
|
+
};
|
|
42189
|
+
}
|
|
42190
|
+
async function tryRecoverMissingSession(ops, session3, error2) {
|
|
42191
|
+
if (error2 instanceof AcpxQueueOverflowError)
|
|
42192
|
+
return null;
|
|
42193
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
42194
|
+
if (!message.includes("No acpx session found")) {
|
|
42195
|
+
return null;
|
|
42196
|
+
}
|
|
42197
|
+
if (session3.transient) {
|
|
42198
|
+
return null;
|
|
42199
|
+
}
|
|
42200
|
+
const transportAgentCommand = await ops.resolveSessionAgentCommand(session3);
|
|
42201
|
+
if (!transportAgentCommand || transportAgentCommand === session3.agentCommand) {
|
|
42202
|
+
return null;
|
|
42203
|
+
}
|
|
42204
|
+
await ops.setSessionTransportAgentCommand(session3.alias, transportAgentCommand);
|
|
42205
|
+
return await ops.getSession(session3.alias);
|
|
42206
|
+
}
|
|
42207
|
+
var init_session_recovery_handler = __esm(() => {
|
|
42208
|
+
init_errors4();
|
|
42209
|
+
init_workspace_name();
|
|
42210
|
+
init_i18n();
|
|
42211
|
+
init_adapter_registry();
|
|
42212
|
+
init_adapter_catalog();
|
|
42213
|
+
init_acpx_queue_overflow();
|
|
42214
|
+
});
|
|
42215
|
+
|
|
41983
42216
|
// src/commands/handlers/session-handler.ts
|
|
41984
42217
|
function sessionHelp() {
|
|
41985
42218
|
const s = t().session;
|
|
@@ -42640,7 +42873,13 @@ async function handlePromptWithSession(context, session3, chatKey, text, reply,
|
|
|
42640
42873
|
diagnostic: error2.cleanupDiagnostic ?? (error2 instanceof Error ? error2.message.slice(0, 512) : String(error2).slice(0, 512)),
|
|
42641
42874
|
confirmed
|
|
42642
42875
|
});
|
|
42643
|
-
|
|
42876
|
+
context.onQueueOverflowTip?.({
|
|
42877
|
+
chatKey,
|
|
42878
|
+
sessionAlias: session3.alias,
|
|
42879
|
+
confirmed,
|
|
42880
|
+
text: queueOverflowTipText(confirmed)
|
|
42881
|
+
});
|
|
42882
|
+
return { silent: true };
|
|
42644
42883
|
}
|
|
42645
42884
|
const recovered = await context.recovery.tryRecoverMissingSession(session3, error2);
|
|
42646
42885
|
if (recovered) {
|
|
@@ -42739,6 +42978,7 @@ var init_session_handler = __esm(() => {
|
|
|
42739
42978
|
init_workspace_name();
|
|
42740
42979
|
init_i18n();
|
|
42741
42980
|
init_acpx_queue_overflow();
|
|
42981
|
+
init_session_recovery_handler();
|
|
42742
42982
|
});
|
|
42743
42983
|
|
|
42744
42984
|
// src/formatting/render-text.ts
|
|
@@ -43756,37 +43996,6 @@ var init_help_handler = __esm(() => {
|
|
|
43756
43996
|
init_i18n();
|
|
43757
43997
|
});
|
|
43758
43998
|
|
|
43759
|
-
// src/recovery/errors.ts
|
|
43760
|
-
var MissingOptionalDepError, AutoInstallFailedError;
|
|
43761
|
-
var init_errors4 = __esm(() => {
|
|
43762
|
-
MissingOptionalDepError = class MissingOptionalDepError extends Error {
|
|
43763
|
-
kind = "missing_optional_dep";
|
|
43764
|
-
package;
|
|
43765
|
-
parentPackagePath;
|
|
43766
|
-
rawMessage;
|
|
43767
|
-
constructor(payload) {
|
|
43768
|
-
super(payload.rawMessage);
|
|
43769
|
-
this.name = "MissingOptionalDepError";
|
|
43770
|
-
this.package = payload.package;
|
|
43771
|
-
this.parentPackagePath = payload.parentPackagePath;
|
|
43772
|
-
this.rawMessage = payload.rawMessage;
|
|
43773
|
-
}
|
|
43774
|
-
};
|
|
43775
|
-
AutoInstallFailedError = class AutoInstallFailedError extends Error {
|
|
43776
|
-
kind = "auto_install_failed";
|
|
43777
|
-
original;
|
|
43778
|
-
steps;
|
|
43779
|
-
logPath;
|
|
43780
|
-
constructor(original, steps, logPath) {
|
|
43781
|
-
super(`auto-install failed: ${original.package}`);
|
|
43782
|
-
this.name = "AutoInstallFailedError";
|
|
43783
|
-
this.original = original;
|
|
43784
|
-
this.steps = steps;
|
|
43785
|
-
this.logPath = logPath;
|
|
43786
|
-
}
|
|
43787
|
-
};
|
|
43788
|
-
});
|
|
43789
|
-
|
|
43790
43999
|
// src/commands/handlers/session-shortcut-handler.ts
|
|
43791
44000
|
async function handleSessionShortcutCommand(context, ops, chatKey, agent3, target, createNew) {
|
|
43792
44001
|
if (!context.config || !context.configStore) {
|
|
@@ -44384,213 +44593,6 @@ var init_native_session_handler = __esm(() => {
|
|
|
44384
44593
|
NATIVE_SESSION_CACHE_TTL_MS = 10 * 60 * 1000;
|
|
44385
44594
|
});
|
|
44386
44595
|
|
|
44387
|
-
// src/commands/transport-diagnostics.ts
|
|
44388
|
-
function summarizeTransportError(message) {
|
|
44389
|
-
return message.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
44390
|
-
}
|
|
44391
|
-
function summarizeTransportDiagnostic(output) {
|
|
44392
|
-
const trimmed = output.replace(/\s+/g, " ").trim();
|
|
44393
|
-
if (trimmed.length === 0) {
|
|
44394
|
-
return;
|
|
44395
|
-
}
|
|
44396
|
-
return trimmed.slice(0, 200);
|
|
44397
|
-
}
|
|
44398
|
-
function summarizeTransportDiagnosticTail(output) {
|
|
44399
|
-
const trimmed = output.replace(/\s+/g, " ").trim();
|
|
44400
|
-
if (trimmed.length === 0) {
|
|
44401
|
-
return;
|
|
44402
|
-
}
|
|
44403
|
-
return trimmed.slice(-200);
|
|
44404
|
-
}
|
|
44405
|
-
function summarizeTransportNdjson(output, prefix) {
|
|
44406
|
-
const lines = output.split(`
|
|
44407
|
-
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
44408
|
-
if (lines.length === 0) {
|
|
44409
|
-
return {};
|
|
44410
|
-
}
|
|
44411
|
-
const methods = new Set;
|
|
44412
|
-
let agentMessageChunkCount = 0;
|
|
44413
|
-
let stopReason;
|
|
44414
|
-
for (const line of lines) {
|
|
44415
|
-
try {
|
|
44416
|
-
const payload = JSON.parse(line);
|
|
44417
|
-
if (typeof payload.method === "string" && payload.method.length > 0) {
|
|
44418
|
-
methods.add(payload.method);
|
|
44419
|
-
}
|
|
44420
|
-
if (payload.params?.update?.sessionUpdate === "agent_message_chunk") {
|
|
44421
|
-
agentMessageChunkCount += 1;
|
|
44422
|
-
}
|
|
44423
|
-
if (typeof payload.result?.stopReason === "string" && payload.result.stopReason.length > 0) {
|
|
44424
|
-
stopReason = payload.result.stopReason;
|
|
44425
|
-
}
|
|
44426
|
-
} catch {
|
|
44427
|
-
continue;
|
|
44428
|
-
}
|
|
44429
|
-
}
|
|
44430
|
-
const summary = {
|
|
44431
|
-
[`${prefix}LineCount`]: lines.length
|
|
44432
|
-
};
|
|
44433
|
-
if (methods.size > 0) {
|
|
44434
|
-
summary[`${prefix}Methods`] = [...methods].join(",");
|
|
44435
|
-
}
|
|
44436
|
-
if (agentMessageChunkCount > 0) {
|
|
44437
|
-
summary[`${prefix}AgentMessageChunkCount`] = agentMessageChunkCount;
|
|
44438
|
-
}
|
|
44439
|
-
if (stopReason) {
|
|
44440
|
-
summary[`${prefix}StopReason`] = stopReason;
|
|
44441
|
-
}
|
|
44442
|
-
return summary;
|
|
44443
|
-
}
|
|
44444
|
-
function isPartialPromptOutputError(message) {
|
|
44445
|
-
return message.includes(ACPX_PARTIAL_OUTPUT_SENTINEL);
|
|
44446
|
-
}
|
|
44447
|
-
var ACPX_PARTIAL_OUTPUT_SENTINEL = "未收到最终回复";
|
|
44448
|
-
|
|
44449
|
-
// src/commands/handlers/session-recovery-handler.ts
|
|
44450
|
-
function renderTransportError(session3, error2) {
|
|
44451
|
-
if (error2 instanceof AcpxQueueOverflowError) {
|
|
44452
|
-
const confirmed = error2.cleanup?.ownerTerminationSucceeded === true;
|
|
44453
|
-
if (confirmed) {
|
|
44454
|
-
return {
|
|
44455
|
-
text: [t().recovery.queueOverflowWarning, t().recovery.queueOverflowHint].join(`
|
|
44456
|
-
`)
|
|
44457
|
-
};
|
|
44458
|
-
}
|
|
44459
|
-
return {
|
|
44460
|
-
text: [t().recovery.queueOverflowWarning, t().recovery.queueOverflowUnconfirmedHint].join(`
|
|
44461
|
-
`)
|
|
44462
|
-
};
|
|
44463
|
-
}
|
|
44464
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
44465
|
-
const registryError = renderAdapterRegistryError(session3, message);
|
|
44466
|
-
if (registryError)
|
|
44467
|
-
return registryError;
|
|
44468
|
-
if (message.includes("No acpx session found")) {
|
|
44469
|
-
if (session3.transient) {
|
|
44470
|
-
return {
|
|
44471
|
-
text: [
|
|
44472
|
-
t().recovery.transientSessionFailed,
|
|
44473
|
-
t().recovery.transientSessionHint
|
|
44474
|
-
].join(`
|
|
44475
|
-
`)
|
|
44476
|
-
};
|
|
44477
|
-
}
|
|
44478
|
-
const quotedWs = quoteWorkspaceNameIfNeeded(session3.workspace);
|
|
44479
|
-
return {
|
|
44480
|
-
text: [
|
|
44481
|
-
t().recovery.sessionUnavailable(session3.alias),
|
|
44482
|
-
t().recovery.sessionUnavailableRenewHint(session3.alias, session3.agent, quotedWs),
|
|
44483
|
-
t().recovery.sessionUnavailableAttachHint(session3.alias, session3.agent, quotedWs)
|
|
44484
|
-
].join(`
|
|
44485
|
-
`)
|
|
44486
|
-
};
|
|
44487
|
-
}
|
|
44488
|
-
if (!isPartialPromptOutputError(message)) {
|
|
44489
|
-
throw error2;
|
|
44490
|
-
}
|
|
44491
|
-
return {
|
|
44492
|
-
text: [
|
|
44493
|
-
t().recovery.sessionInterrupted(session3.alias),
|
|
44494
|
-
t().recovery.sessionInterruptedHint,
|
|
44495
|
-
t().recovery.sessionInterruptedError(summarizeTransportError(message))
|
|
44496
|
-
].join(`
|
|
44497
|
-
`)
|
|
44498
|
-
};
|
|
44499
|
-
}
|
|
44500
|
-
function renderSessionCreationError(session3, error2) {
|
|
44501
|
-
if (error2 instanceof AutoInstallFailedError) {
|
|
44502
|
-
const { original, steps, logPath } = error2;
|
|
44503
|
-
const r = t().recovery;
|
|
44504
|
-
const allVerifyFailed = steps.length > 0 && steps.every((s) => s.reason === "verify-failed");
|
|
44505
|
-
const headline = allVerifyFailed ? r.autoInstallHeadlineFixed : r.autoInstallHeadlineFailed;
|
|
44506
|
-
const stepLines = steps.map((s) => {
|
|
44507
|
-
const perStepPath = s.path ?? (s.scope === "precise" ? original.parentPackagePath : null);
|
|
44508
|
-
const label = s.scope === "precise" ? r.autoInstallScopePrecise(s.manager, perStepPath ?? undefined) : r.autoInstallScopeGlobal;
|
|
44509
|
-
if (s.reason === "verify-failed") {
|
|
44510
|
-
return r.autoInstallStepVerifyFailed(label);
|
|
44511
|
-
}
|
|
44512
|
-
return r.autoInstallStepError(label, s.stderrTail);
|
|
44513
|
-
}).join(`
|
|
44514
|
-
|
|
44515
|
-
`);
|
|
44516
|
-
return {
|
|
44517
|
-
text: [
|
|
44518
|
-
headline,
|
|
44519
|
-
``,
|
|
44520
|
-
r.autoInstallOriginalError,
|
|
44521
|
-
original.rawMessage,
|
|
44522
|
-
``,
|
|
44523
|
-
stepLines,
|
|
44524
|
-
``,
|
|
44525
|
-
r.autoInstallManual(original.package),
|
|
44526
|
-
r.autoInstallLog(logPath)
|
|
44527
|
-
].join(`
|
|
44528
|
-
`)
|
|
44529
|
-
};
|
|
44530
|
-
}
|
|
44531
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
44532
|
-
const registryError = renderAdapterRegistryError(session3, message);
|
|
44533
|
-
if (registryError)
|
|
44534
|
-
return {
|
|
44535
|
-
text: [
|
|
44536
|
-
t().recovery.sessionCreationFailed,
|
|
44537
|
-
registryError.text
|
|
44538
|
-
].join(`
|
|
44539
|
-
`)
|
|
44540
|
-
};
|
|
44541
|
-
if (message.includes("timed out") && message.includes("sessions new")) {
|
|
44542
|
-
return renderSessionCreationFailure(session3, message);
|
|
44543
|
-
}
|
|
44544
|
-
throw error2;
|
|
44545
|
-
}
|
|
44546
|
-
function renderAdapterRegistryError(session3, message) {
|
|
44547
|
-
const registry2 = managedAdapterRegistryFromCommand(session3.agentCommand);
|
|
44548
|
-
if (!registry2 || !isNpmAdapterRegistryNotFoundOutput(message))
|
|
44549
|
-
return null;
|
|
44550
|
-
return {
|
|
44551
|
-
text: t().recovery.adapterRegistryE404(registry2, DEFAULT_ADAPTER_REGISTRY)
|
|
44552
|
-
};
|
|
44553
|
-
}
|
|
44554
|
-
function renderSessionCreationVerificationError(session3) {
|
|
44555
|
-
return renderSessionCreationFailure(session3, t().recovery.sessionCreationVerificationDetail);
|
|
44556
|
-
}
|
|
44557
|
-
function renderSessionCreationFailure(session3, detail) {
|
|
44558
|
-
const r = t().recovery;
|
|
44559
|
-
return {
|
|
44560
|
-
text: [
|
|
44561
|
-
r.sessionCreationFailed,
|
|
44562
|
-
r.sessionCreationError(summarizeTransportError(detail)),
|
|
44563
|
-
r.sessionCreationAttachHint(session3.alias, session3.agent, quoteWorkspaceNameIfNeeded(session3.workspace))
|
|
44564
|
-
].join(`
|
|
44565
|
-
`)
|
|
44566
|
-
};
|
|
44567
|
-
}
|
|
44568
|
-
async function tryRecoverMissingSession(ops, session3, error2) {
|
|
44569
|
-
if (error2 instanceof AcpxQueueOverflowError)
|
|
44570
|
-
return null;
|
|
44571
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
44572
|
-
if (!message.includes("No acpx session found")) {
|
|
44573
|
-
return null;
|
|
44574
|
-
}
|
|
44575
|
-
if (session3.transient) {
|
|
44576
|
-
return null;
|
|
44577
|
-
}
|
|
44578
|
-
const transportAgentCommand = await ops.resolveSessionAgentCommand(session3);
|
|
44579
|
-
if (!transportAgentCommand || transportAgentCommand === session3.agentCommand) {
|
|
44580
|
-
return null;
|
|
44581
|
-
}
|
|
44582
|
-
await ops.setSessionTransportAgentCommand(session3.alias, transportAgentCommand);
|
|
44583
|
-
return await ops.getSession(session3.alias);
|
|
44584
|
-
}
|
|
44585
|
-
var init_session_recovery_handler = __esm(() => {
|
|
44586
|
-
init_errors4();
|
|
44587
|
-
init_workspace_name();
|
|
44588
|
-
init_i18n();
|
|
44589
|
-
init_adapter_registry();
|
|
44590
|
-
init_adapter_catalog();
|
|
44591
|
-
init_acpx_queue_overflow();
|
|
44592
|
-
});
|
|
44593
|
-
|
|
44594
44596
|
// src/recovery/auto-install-optional-dep.ts
|
|
44595
44597
|
import { spawn as spawn11 } from "node:child_process";
|
|
44596
44598
|
import { createWriteStream } from "node:fs";
|
|
@@ -45595,6 +45597,7 @@ class CommandRouter {
|
|
|
45595
45597
|
scheduled;
|
|
45596
45598
|
scheduledDelivery;
|
|
45597
45599
|
resolveNativeSessionListFormat;
|
|
45600
|
+
controlEvents;
|
|
45598
45601
|
logger;
|
|
45599
45602
|
autoInstall = autoInstallOptionalDep;
|
|
45600
45603
|
discoverPaths = discoverParentPackagePaths;
|
|
@@ -45607,7 +45610,7 @@ class CommandRouter {
|
|
|
45607
45610
|
activeTurns;
|
|
45608
45611
|
transportInvoker;
|
|
45609
45612
|
sessionControl;
|
|
45610
|
-
constructor(sessions, transport, config4, configStore, logger, resolveSessionAgentCommand = resolveSessionAgentCommandFromIndex, orchestration3, quota, scheduled, scheduledDelivery, resolveNativeSessionListFormat, activeTurns) {
|
|
45613
|
+
constructor(sessions, transport, config4, configStore, logger, resolveSessionAgentCommand = resolveSessionAgentCommandFromIndex, orchestration3, quota, scheduled, scheduledDelivery, resolveNativeSessionListFormat, activeTurns, controlEvents) {
|
|
45611
45614
|
this.sessions = sessions;
|
|
45612
45615
|
this.transport = transport;
|
|
45613
45616
|
this.config = config4;
|
|
@@ -45618,6 +45621,7 @@ class CommandRouter {
|
|
|
45618
45621
|
this.scheduled = scheduled;
|
|
45619
45622
|
this.scheduledDelivery = scheduledDelivery;
|
|
45620
45623
|
this.resolveNativeSessionListFormat = resolveNativeSessionListFormat;
|
|
45624
|
+
this.controlEvents = controlEvents;
|
|
45621
45625
|
this.logger = logger ?? createNoopAppLogger();
|
|
45622
45626
|
this.activeTurns = activeTurns;
|
|
45623
45627
|
this.transportInvoker = new TransportInvoker({
|
|
@@ -45836,7 +45840,18 @@ class CommandRouter {
|
|
|
45836
45840
|
lifecycle: this.createSessionLifecycleOps(reply, perfSpan),
|
|
45837
45841
|
interaction: this.createSessionInteractionOps(perfSpan),
|
|
45838
45842
|
recovery: this.createSessionRenderRecoveryOps(),
|
|
45839
|
-
...this.activeTurns ? { activeTurns: this.activeTurns } : {}
|
|
45843
|
+
...this.activeTurns ? { activeTurns: this.activeTurns } : {},
|
|
45844
|
+
...this.controlEvents ? {
|
|
45845
|
+
onQueueOverflowTip: (info) => {
|
|
45846
|
+
this.controlEvents.emit({
|
|
45847
|
+
type: "queue-overflow-tip",
|
|
45848
|
+
chatKey: info.chatKey,
|
|
45849
|
+
sessionAlias: info.sessionAlias,
|
|
45850
|
+
confirmed: info.confirmed,
|
|
45851
|
+
text: info.text
|
|
45852
|
+
});
|
|
45853
|
+
}
|
|
45854
|
+
} : {}
|
|
45840
45855
|
};
|
|
45841
45856
|
}
|
|
45842
45857
|
createSessionLifecycleOps(reply, perfSpan) {
|
|
@@ -60254,7 +60269,7 @@ ${envelope}` : envelope;
|
|
|
60254
60269
|
});
|
|
60255
60270
|
}
|
|
60256
60271
|
});
|
|
60257
|
-
if (response.text) {
|
|
60272
|
+
if (response.text && !response.silent) {
|
|
60258
60273
|
emitChunk(response.text);
|
|
60259
60274
|
}
|
|
60260
60275
|
this.deps.events.emit({
|
|
@@ -60262,7 +60277,8 @@ ${envelope}` : envelope;
|
|
|
60262
60277
|
chatKey: req.chatKey,
|
|
60263
60278
|
sessionAlias: req.sessionAlias,
|
|
60264
60279
|
ok: true,
|
|
60265
|
-
text: finalText,
|
|
60280
|
+
...finalText !== "" || !response.silent ? { text: finalText } : {},
|
|
60281
|
+
...response.silent ? { silent: true } : {},
|
|
60266
60282
|
...req.peerOrigin ? { peerOrigin: req.peerOrigin } : {}
|
|
60267
60283
|
});
|
|
60268
60284
|
return {
|
|
@@ -63331,7 +63347,7 @@ async function buildApp(paths, deps = {}) {
|
|
|
63331
63347
|
});
|
|
63332
63348
|
const router3 = new CommandRouter(sessions, transport, config4, configStore, logger, undefined, orchestration3, quota, scheduledService, deps.channel?.supportsScheduledMessages ? {
|
|
63333
63349
|
supportsScheduledMessages: deps.channel.supportsScheduledMessages.bind(deps.channel)
|
|
63334
|
-
} : undefined, deps.channel?.nativeSessionListFormat ? deps.channel.nativeSessionListFormat.bind(deps.channel) : undefined, activeTurns);
|
|
63350
|
+
} : undefined, deps.channel?.nativeSessionListFormat ? deps.channel.nativeSessionListFormat.bind(deps.channel) : undefined, activeTurns, controlEvents);
|
|
63335
63351
|
const agent3 = new ConsoleAgent(router3, logger);
|
|
63336
63352
|
const terminalService = createTerminalService({
|
|
63337
63353
|
events: controlEvents,
|
|
@@ -9,6 +9,12 @@ export interface SessionHandlerContext extends CommandRouterContext {
|
|
|
9
9
|
interaction: SessionInteractionOps;
|
|
10
10
|
recovery: SessionRenderRecoveryOps;
|
|
11
11
|
readonly activeTurns?: import("../../sessions/active-turn-registry.js").ActiveTurnRegistry;
|
|
12
|
+
onQueueOverflowTip?: (info: {
|
|
13
|
+
chatKey: string;
|
|
14
|
+
sessionAlias: string;
|
|
15
|
+
confirmed: boolean;
|
|
16
|
+
text: string;
|
|
17
|
+
}) => void;
|
|
12
18
|
}
|
|
13
19
|
export declare function sessionHelp(): HelpTopicMetadata;
|
|
14
20
|
export declare function nativeSessionHelp(): HelpTopicMetadata;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ResolvedSession } from "../../transport/types";
|
|
2
|
+
import type { RouterResponse, SessionRecoveryOps } from "../router-types";
|
|
3
|
+
export declare function queueOverflowTipText(confirmed: boolean): string;
|
|
4
|
+
export declare function renderTransportError(session: ResolvedSession, error: unknown): RouterResponse;
|
|
5
|
+
export declare function renderSessionCreationError(session: ResolvedSession, error: unknown): RouterResponse;
|
|
6
|
+
export declare function renderSessionCreationVerificationError(session: ResolvedSession): RouterResponse;
|
|
7
|
+
export declare function tryRecoverMissingSession(ops: SessionRecoveryOps, session: ResolvedSession, error: unknown): Promise<ResolvedSession | null>;
|
|
@@ -9,6 +9,8 @@ import type { PlanEntry, ToolUseEvent } from "../channels/types.js";
|
|
|
9
9
|
import type { PerfSpan } from "../perf/perf-tracer";
|
|
10
10
|
export interface RouterResponse {
|
|
11
11
|
text?: string;
|
|
12
|
+
/** When true, channels must not deliver `text` (including an empty bubble). */
|
|
13
|
+
silent?: boolean;
|
|
12
14
|
}
|
|
13
15
|
export interface PromptRouteMetadata {
|
|
14
16
|
chatKey: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function summarizeTransportError(message: string): string;
|
|
2
|
+
export declare function summarizeTransportDiagnostic(output: string): string | undefined;
|
|
3
|
+
export declare function summarizeTransportDiagnosticTail(output: string): string | undefined;
|
|
4
|
+
export declare function summarizeTransportNdjson(output: string, prefix: "stdout" | "stderr"): Record<string, string | number>;
|
|
5
|
+
export declare function isPartialPromptOutputError(message: string): boolean;
|
|
@@ -73,7 +73,14 @@ export type ControlEvent = {
|
|
|
73
73
|
errorMessage?: string;
|
|
74
74
|
cancelled?: boolean;
|
|
75
75
|
text?: string;
|
|
76
|
+
silent?: boolean;
|
|
76
77
|
peerOrigin?: PeerTurnOrigin;
|
|
78
|
+
} | {
|
|
79
|
+
type: "queue-overflow-tip";
|
|
80
|
+
chatKey: string;
|
|
81
|
+
sessionAlias: string;
|
|
82
|
+
confirmed: boolean;
|
|
83
|
+
text: string;
|
|
77
84
|
} | {
|
|
78
85
|
type: "sessions-changed";
|
|
79
86
|
} | {
|
package/dist/plugin-api.js
CHANGED
|
@@ -317,9 +317,9 @@ var init_recovery = __esm(() => {
|
|
|
317
317
|
sessionInterrupted: (alias) => `Session "${alias}" was interrupted; no final reply received.`,
|
|
318
318
|
sessionInterruptedHint: "Retry directly. If the session remains unresponsive, send /cancel first, then retry.",
|
|
319
319
|
sessionInterruptedError: (summary) => `Error: ${summary}`,
|
|
320
|
-
queueOverflowWarning: "
|
|
321
|
-
queueOverflowHint: "
|
|
322
|
-
queueOverflowUnconfirmedHint: "
|
|
320
|
+
queueOverflowWarning: "",
|
|
321
|
+
queueOverflowHint: "Reply was truncated for size — you can continue.",
|
|
322
|
+
queueOverflowUnconfirmedHint: "Output was large and cleanup wasn't confirmed — send /cancel, then continue.",
|
|
323
323
|
autoInstallHeadlineFixed: "⚠️ Auto-install ran but could not fix the session startup problem",
|
|
324
324
|
autoInstallHeadlineFailed: "❌ Auto-install failed",
|
|
325
325
|
autoInstallOriginalError: "Original error:",
|
|
@@ -1448,9 +1448,9 @@ var init_recovery2 = __esm(() => {
|
|
|
1448
1448
|
sessionInterrupted: (alias) => `当前会话「${alias}」执行中断,未收到最终回复。`,
|
|
1449
1449
|
sessionInterruptedHint: "请直接重试;如果长时间无响应,可先发送 /cancel 后再重试。",
|
|
1450
1450
|
sessionInterruptedError: (summary) => `错误信息:${summary}`,
|
|
1451
|
-
queueOverflowWarning: "
|
|
1452
|
-
queueOverflowHint: "
|
|
1453
|
-
queueOverflowUnconfirmedHint: "
|
|
1451
|
+
queueOverflowWarning: "",
|
|
1452
|
+
queueOverflowHint: "部分回复因过长已收束,可直接继续。",
|
|
1453
|
+
queueOverflowUnconfirmedHint: "输出过长且清理未确认,请先发 /cancel 再继续。",
|
|
1454
1454
|
autoInstallHeadlineFixed: "⚠️ 自动安装已执行但未能修复会话启动问题",
|
|
1455
1455
|
autoInstallHeadlineFailed: "❌ 自动安装失败",
|
|
1456
1456
|
autoInstallOriginalError: "原始错误:",
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type PackageManager = "npm" | "bun" | "pnpm" | "yarn";
|
|
2
|
+
export interface DiscoveredParentPath {
|
|
3
|
+
/** Absolute directory containing the parent package's package.json. */
|
|
4
|
+
path: string;
|
|
5
|
+
/** Which package manager owns this directory — determines which CLI to install with. */
|
|
6
|
+
manager: PackageManager;
|
|
7
|
+
}
|
|
8
|
+
export interface DiscoverDeps {
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
home?: string;
|
|
11
|
+
platform?: NodeJS.Platform;
|
|
12
|
+
/**
|
|
13
|
+
* Working directory used as the anchor for `require.resolve` style lookups.
|
|
14
|
+
* In production this is typically the bridge / acpx cwd, not the daemon's cwd.
|
|
15
|
+
* Defaults to `process.cwd()` which is usually wrong for daemonized use.
|
|
16
|
+
*/
|
|
17
|
+
cwd?: string;
|
|
18
|
+
fsExists?: (path: string) => Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve `<name>/package.json` via Node.js resolution, anchored on the provided cwd.
|
|
21
|
+
* Returns the parent package dir (containing package.json) or null.
|
|
22
|
+
*/
|
|
23
|
+
resolveFromCwd?: (parentName: string, cwd: string) => string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Query a package manager root. Short timeout; null if the CLI is unavailable.
|
|
26
|
+
*/
|
|
27
|
+
queryPackageManagerRoot?: (tool: "npm" | "pnpm" | "yarn") => Promise<string | null>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Strip platform / arch / libc suffixes from an npm optional platform package name.
|
|
31
|
+
* Examples:
|
|
32
|
+
* "opencode-windows-x64" → "opencode"
|
|
33
|
+
* "@scope/pkg-linux-arm64-musl" → "@scope/pkg"
|
|
34
|
+
* "esbuild-darwin-x64" → "esbuild"
|
|
35
|
+
* "@next/swc-win32-x64-msvc" → "@next/swc"
|
|
36
|
+
* "@rollup/rollup-linux-x64-gnu" → "@rollup/rollup"
|
|
37
|
+
*/
|
|
38
|
+
export declare function deriveParentPackageName(platformPackage: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Enumerate directories where the parent package might be installed across
|
|
41
|
+
* common package managers: npm (global), Bun (global), pnpm (global), Yarn (global),
|
|
42
|
+
* plus the local Node resolution tree. Each entry is tagged with its owning
|
|
43
|
+
* package manager so the installer can dispatch to the correct CLI — running
|
|
44
|
+
* `npm install` inside a Bun or pnpm tree would corrupt the managed store.
|
|
45
|
+
*
|
|
46
|
+
* Every returned path is guaranteed to exist and contain a package.json.
|
|
47
|
+
* Duplicates and non-existent paths are filtered out.
|
|
48
|
+
*/
|
|
49
|
+
export declare function discoverParentPackagePaths(platformPackage: string, seedPath: string | null, deps?: DiscoverDeps): Promise<DiscoveredParentPath[]>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface MissingOptionalDepPayload {
|
|
2
|
+
package: string;
|
|
3
|
+
parentPackagePath: string | null;
|
|
4
|
+
rawMessage: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class MissingOptionalDepError extends Error {
|
|
7
|
+
readonly kind: "missing_optional_dep";
|
|
8
|
+
readonly package: string;
|
|
9
|
+
readonly parentPackagePath: string | null;
|
|
10
|
+
readonly rawMessage: string;
|
|
11
|
+
constructor(payload: MissingOptionalDepPayload);
|
|
12
|
+
}
|
|
13
|
+
import type { PackageManager } from "./discover-parent-package-paths";
|
|
14
|
+
export interface AutoInstallStepError {
|
|
15
|
+
scope: "precise" | "global";
|
|
16
|
+
stderrTail: string;
|
|
17
|
+
code: number | null;
|
|
18
|
+
reason?: "timeout" | "spawn" | "exit" | "verify-failed";
|
|
19
|
+
/** The parent package directory this precise install was run in (only set for scope === "precise"). */
|
|
20
|
+
path?: string;
|
|
21
|
+
/** The package manager used for this precise install (only set for scope === "precise"). */
|
|
22
|
+
manager?: PackageManager;
|
|
23
|
+
}
|
|
24
|
+
export declare class AutoInstallFailedError extends Error {
|
|
25
|
+
readonly kind: "auto_install_failed";
|
|
26
|
+
readonly original: MissingOptionalDepError;
|
|
27
|
+
readonly steps: AutoInstallStepError[];
|
|
28
|
+
readonly logPath: string;
|
|
29
|
+
constructor(original: MissingOptionalDepError, steps: AutoInstallStepError[], logPath: string);
|
|
30
|
+
}
|
|
@@ -86,6 +86,12 @@ export interface ChatResponse {
|
|
|
86
86
|
* the same turn. May contain markdown and will be normalized before send.
|
|
87
87
|
*/
|
|
88
88
|
text?: string;
|
|
89
|
+
/**
|
|
90
|
+
* When true, the channel must not post `text` as a chat/agent message
|
|
91
|
+
* (including a blank bubble). Used for queue-overflow tips that only
|
|
92
|
+
* surface as a relay-web toast.
|
|
93
|
+
*/
|
|
94
|
+
silent?: boolean;
|
|
89
95
|
/** Reply media file(s). */
|
|
90
96
|
media?: OutboundChannelMedia | OutboundChannelMedia[];
|
|
91
97
|
}
|