adhdev 0.9.54 → 0.9.56
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/cli/index.js +421 -39
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +421 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/session-host-daemon/index.d.mts +2 -0
- package/vendor/session-host-daemon/index.d.ts +2 -0
- package/vendor/session-host-daemon/index.js +59 -1
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +59 -1
- package/vendor/session-host-daemon/index.mjs.map +1 -1
package/dist/index.js
CHANGED
|
@@ -963,7 +963,12 @@ function createDefaultGitCommandServices() {
|
|
|
963
963
|
turnId
|
|
964
964
|
}),
|
|
965
965
|
compareSnapshots: ({ beforeSnapshotId, afterSnapshotId }) => defaultSnapshotStore.compare(beforeSnapshotId, afterSnapshotId),
|
|
966
|
-
getLog: ({ workspace, limit, path: filePath, since, until }) => getGitLog(workspace, { limit, path: filePath, since, until })
|
|
966
|
+
getLog: ({ workspace, limit, path: filePath, since, until }) => getGitLog(workspace, { limit, path: filePath, since, until }),
|
|
967
|
+
checkpoint: async ({ workspace, message, includeUntracked = false }) => gitCheckpoint(workspace, message, includeUntracked),
|
|
968
|
+
stashPush: async ({ workspace, message, includeUntracked = false }) => gitStashPush(workspace, message, includeUntracked),
|
|
969
|
+
stashPop: async ({ workspace, stashRef }) => gitStashPop(workspace, stashRef),
|
|
970
|
+
checkoutFiles: async ({ workspace, paths }) => gitCheckoutFiles(workspace, paths),
|
|
971
|
+
getRemoteUrl: async ({ workspace, remote = "origin" }) => gitGetRemoteUrl(workspace, remote)
|
|
967
972
|
};
|
|
968
973
|
}
|
|
969
974
|
function validateWorkspace2(args) {
|
|
@@ -1026,9 +1031,6 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
1026
1031
|
if (!isGitCommandName(command)) {
|
|
1027
1032
|
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
1028
1033
|
}
|
|
1029
|
-
if (MUTATING_COMMAND_NAMES.has(command)) {
|
|
1030
|
-
return failure("invalid_args", `${command} is not implemented in daemon-core read-only Git routing`);
|
|
1031
|
-
}
|
|
1032
1034
|
const workspaceResult = validateWorkspace2(args);
|
|
1033
1035
|
if ("success" in workspaceResult) return workspaceResult;
|
|
1034
1036
|
const { workspace } = workspaceResult;
|
|
@@ -1088,10 +1090,153 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
1088
1090
|
}));
|
|
1089
1091
|
return "success" in log2 ? log2 : { success: true, log: log2 };
|
|
1090
1092
|
}
|
|
1093
|
+
case "git_checkpoint": {
|
|
1094
|
+
if (!services.checkpoint) return serviceNotImplemented(command);
|
|
1095
|
+
const msg = validateMutatingMessage(args?.message);
|
|
1096
|
+
if (typeof msg !== "string") return msg;
|
|
1097
|
+
const includeUntracked = Boolean(args?.includeUntracked);
|
|
1098
|
+
const checkpoint = await runService(() => services.checkpoint({ workspace, message: msg, includeUntracked }));
|
|
1099
|
+
return "success" in checkpoint ? checkpoint : { success: true, checkpoint };
|
|
1100
|
+
}
|
|
1101
|
+
case "git_stash_push": {
|
|
1102
|
+
if (!services.stashPush) return serviceNotImplemented(command);
|
|
1103
|
+
const msg = validateMutatingMessage(args?.message);
|
|
1104
|
+
if (typeof msg !== "string") return msg;
|
|
1105
|
+
const includeUntracked = Boolean(args?.includeUntracked);
|
|
1106
|
+
const stash = await runService(() => services.stashPush({ workspace, message: msg, includeUntracked }));
|
|
1107
|
+
return "success" in stash ? stash : { success: true, stash };
|
|
1108
|
+
}
|
|
1109
|
+
case "git_stash_pop": {
|
|
1110
|
+
if (!services.stashPop) return serviceNotImplemented(command);
|
|
1111
|
+
const stashRef = optionalString(args?.stashRef);
|
|
1112
|
+
if (stashRef !== void 0 && !/^stash@\{\d+\}$/.test(stashRef)) {
|
|
1113
|
+
return failure("invalid_args", "stashRef must match stash@{N} format");
|
|
1114
|
+
}
|
|
1115
|
+
const popResult = await runService(() => services.stashPop({ workspace, stashRef }));
|
|
1116
|
+
if (popResult !== void 0 && "success" in popResult) return popResult;
|
|
1117
|
+
return { success: true, stashPopped: true };
|
|
1118
|
+
}
|
|
1119
|
+
case "git_checkout_files": {
|
|
1120
|
+
if (!services.checkoutFiles) return serviceNotImplemented(command);
|
|
1121
|
+
const paths = args?.paths;
|
|
1122
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
1123
|
+
return failure("invalid_args", "paths must be a non-empty array");
|
|
1124
|
+
}
|
|
1125
|
+
if (paths.length > 50) {
|
|
1126
|
+
return failure("invalid_args", "paths array exceeds maximum of 50 entries");
|
|
1127
|
+
}
|
|
1128
|
+
const checkoutResult = await runService(() => services.checkoutFiles({ workspace, paths }));
|
|
1129
|
+
return "success" in checkoutResult ? checkoutResult : { success: true, checkedOut: checkoutResult.checkedOut };
|
|
1130
|
+
}
|
|
1131
|
+
case "git_remote_url": {
|
|
1132
|
+
if (!services.getRemoteUrl) return serviceNotImplemented(command);
|
|
1133
|
+
const remote = typeof args?.remote === "string" && args.remote.trim() ? args.remote.trim() : "origin";
|
|
1134
|
+
const remoteResult = await runService(() => services.getRemoteUrl({ workspace, remote }));
|
|
1135
|
+
if ("success" in remoteResult) return remoteResult;
|
|
1136
|
+
return { success: true, remoteUrl: remoteResult.remoteUrl, remote: remoteResult.remote };
|
|
1137
|
+
}
|
|
1091
1138
|
default:
|
|
1092
1139
|
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
1093
1140
|
}
|
|
1094
1141
|
}
|
|
1142
|
+
function validateMutatingMessage(value) {
|
|
1143
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
1144
|
+
return failure("invalid_args", "message must be a non-empty string");
|
|
1145
|
+
}
|
|
1146
|
+
const msg = value.trim();
|
|
1147
|
+
if (msg.length > 200) {
|
|
1148
|
+
return failure("invalid_args", "message must be 200 characters or fewer");
|
|
1149
|
+
}
|
|
1150
|
+
return msg;
|
|
1151
|
+
}
|
|
1152
|
+
async function gitCheckpoint(workspace, message, includeUntracked) {
|
|
1153
|
+
const repo = await resolveGitRepository(workspace);
|
|
1154
|
+
const repoRoot = repo.repoRoot;
|
|
1155
|
+
const statusResult = await getGitRepoStatus(workspace);
|
|
1156
|
+
if (statusResult.hasConflicts) {
|
|
1157
|
+
throw new GitCommandError("conflict", "Repository has conflicts \u2014 resolve before checkpointing");
|
|
1158
|
+
}
|
|
1159
|
+
const addArgs = includeUntracked ? ["-A"] : ["-u"];
|
|
1160
|
+
await runGit(repo, ["add", ...addArgs], { cwd: repoRoot });
|
|
1161
|
+
const fullMsg = `adhdev: checkpoint ${message}`;
|
|
1162
|
+
let commitSha;
|
|
1163
|
+
try {
|
|
1164
|
+
await runGit(repo, ["commit", "-m", fullMsg], { cwd: repoRoot });
|
|
1165
|
+
const revResult = await runGit(repo, ["rev-parse", "HEAD"], { cwd: repoRoot });
|
|
1166
|
+
commitSha = revResult.stdout.trim();
|
|
1167
|
+
} catch (err) {
|
|
1168
|
+
const output = (err?.stdout || "") + (err?.stderr || "");
|
|
1169
|
+
if (/nothing to commit/i.test(output)) {
|
|
1170
|
+
throw new GitCommandError("git_command_failed", "Nothing to commit");
|
|
1171
|
+
}
|
|
1172
|
+
throw err;
|
|
1173
|
+
}
|
|
1174
|
+
return {
|
|
1175
|
+
workspace: repo.workspace,
|
|
1176
|
+
repoRoot,
|
|
1177
|
+
isGitRepo: true,
|
|
1178
|
+
commit: commitSha,
|
|
1179
|
+
message: fullMsg,
|
|
1180
|
+
lastCheckedAt: Date.now()
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
async function gitStashPush(workspace, message, includeUntracked) {
|
|
1184
|
+
const repo = await resolveGitRepository(workspace);
|
|
1185
|
+
const repoRoot = repo.repoRoot;
|
|
1186
|
+
const stashArgs = ["stash", "push", "-m", message];
|
|
1187
|
+
if (includeUntracked) stashArgs.push("--include-untracked");
|
|
1188
|
+
const result = await runGit(repo, stashArgs, { cwd: repoRoot });
|
|
1189
|
+
if (/No local changes to save/i.test(result.stdout + result.stderr)) {
|
|
1190
|
+
throw new GitCommandError("git_command_failed", "Nothing to stash");
|
|
1191
|
+
}
|
|
1192
|
+
return {
|
|
1193
|
+
workspace: repo.workspace,
|
|
1194
|
+
repoRoot,
|
|
1195
|
+
isGitRepo: true,
|
|
1196
|
+
stashRef: "stash@{0}",
|
|
1197
|
+
message,
|
|
1198
|
+
lastCheckedAt: Date.now()
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
async function gitStashPop(workspace, stashRef) {
|
|
1202
|
+
const repo = await resolveGitRepository(workspace);
|
|
1203
|
+
const repoRoot = repo.repoRoot;
|
|
1204
|
+
const popArgs = stashRef ? ["stash", "pop", stashRef] : ["stash", "pop"];
|
|
1205
|
+
await runGit(repo, popArgs, { cwd: repoRoot });
|
|
1206
|
+
}
|
|
1207
|
+
async function gitCheckoutFiles(workspace, paths) {
|
|
1208
|
+
const repo = await resolveGitRepository(workspace);
|
|
1209
|
+
const repoRoot = repo.repoRoot;
|
|
1210
|
+
const normalizedPaths = [];
|
|
1211
|
+
for (const p of paths) {
|
|
1212
|
+
if (typeof p !== "string" || !p.trim() || p.includes("\0")) {
|
|
1213
|
+
throw new GitCommandError("invalid_args", `Invalid path: ${String(p)}`);
|
|
1214
|
+
}
|
|
1215
|
+
if (path3.isAbsolute(p)) {
|
|
1216
|
+
throw new GitCommandError("invalid_args", `Path must be repository-relative, not absolute: ${p}`);
|
|
1217
|
+
}
|
|
1218
|
+
const normalized = path3.normalize(p.trim()).split(path3.sep).join("/");
|
|
1219
|
+
if (normalized.startsWith("../") || normalized === "..") {
|
|
1220
|
+
throw new GitCommandError("path_outside_repo", `Path is outside repository root: ${p}`);
|
|
1221
|
+
}
|
|
1222
|
+
const absolutePath = path3.resolve(repoRoot, normalized);
|
|
1223
|
+
if (!isPathInside(repoRoot, absolutePath)) {
|
|
1224
|
+
throw new GitCommandError("path_outside_repo", `Path is outside repository root: ${p}`);
|
|
1225
|
+
}
|
|
1226
|
+
normalizedPaths.push(normalized);
|
|
1227
|
+
}
|
|
1228
|
+
await runGit(repo, ["checkout", "--", ...normalizedPaths], { cwd: repoRoot });
|
|
1229
|
+
return { checkedOut: normalizedPaths };
|
|
1230
|
+
}
|
|
1231
|
+
async function gitGetRemoteUrl(workspace, remote) {
|
|
1232
|
+
const repo = await resolveGitRepository(workspace);
|
|
1233
|
+
const result = await runGit(repo, ["remote", "get-url", remote], { cwd: repo.repoRoot });
|
|
1234
|
+
const remoteUrl = result.stdout.trim();
|
|
1235
|
+
if (!remoteUrl) {
|
|
1236
|
+
throw new GitCommandError("git_command_failed", `Remote '${remote}' has no URL`);
|
|
1237
|
+
}
|
|
1238
|
+
return { remoteUrl, remote };
|
|
1239
|
+
}
|
|
1095
1240
|
function formatOptionalGitLogRangeArg(flag, value) {
|
|
1096
1241
|
return value ? [`${flag}=${value}`] : [];
|
|
1097
1242
|
}
|
|
@@ -1149,7 +1294,7 @@ function validateGitLogPath(repoRoot, filePath) {
|
|
|
1149
1294
|
}
|
|
1150
1295
|
return normalized;
|
|
1151
1296
|
}
|
|
1152
|
-
var path3, GIT_COMMAND_NAMES,
|
|
1297
|
+
var path3, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices;
|
|
1153
1298
|
var init_git_commands = __esm({
|
|
1154
1299
|
"../../oss/packages/daemon-core/src/git/git-commands.ts"() {
|
|
1155
1300
|
"use strict";
|
|
@@ -1168,13 +1313,8 @@ var init_git_commands = __esm({
|
|
|
1168
1313
|
"git_checkpoint",
|
|
1169
1314
|
"git_stash_push",
|
|
1170
1315
|
"git_stash_pop",
|
|
1171
|
-
"git_checkout_files"
|
|
1172
|
-
|
|
1173
|
-
MUTATING_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
1174
|
-
"git_checkpoint",
|
|
1175
|
-
"git_stash_push",
|
|
1176
|
-
"git_stash_pop",
|
|
1177
|
-
"git_checkout_files"
|
|
1316
|
+
"git_checkout_files",
|
|
1317
|
+
"git_remote_url"
|
|
1178
1318
|
]);
|
|
1179
1319
|
SNAPSHOT_REASONS = /* @__PURE__ */ new Set([
|
|
1180
1320
|
"session_baseline",
|
|
@@ -1201,6 +1341,33 @@ var init_git_commands = __esm({
|
|
|
1201
1341
|
}
|
|
1202
1342
|
});
|
|
1203
1343
|
|
|
1344
|
+
// ../../oss/packages/daemon-core/src/git/turn-snapshot-tracker.ts
|
|
1345
|
+
var BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker;
|
|
1346
|
+
var init_turn_snapshot_tracker = __esm({
|
|
1347
|
+
"../../oss/packages/daemon-core/src/git/turn-snapshot-tracker.ts"() {
|
|
1348
|
+
"use strict";
|
|
1349
|
+
BUSY_STATUSES = /* @__PURE__ */ new Set(["streaming", "waiting_approval"]);
|
|
1350
|
+
TERMINAL_STATUSES = /* @__PURE__ */ new Set(["idle", "error"]);
|
|
1351
|
+
TurnSnapshotTracker = class {
|
|
1352
|
+
lastStatus = /* @__PURE__ */ new Map();
|
|
1353
|
+
onTurnCompleted;
|
|
1354
|
+
constructor(onTurnCompleted) {
|
|
1355
|
+
this.onTurnCompleted = onTurnCompleted;
|
|
1356
|
+
}
|
|
1357
|
+
record(sessionId, status, workspace) {
|
|
1358
|
+
const prev = this.lastStatus.get(sessionId);
|
|
1359
|
+
this.lastStatus.set(sessionId, status);
|
|
1360
|
+
if (workspace && prev && BUSY_STATUSES.has(prev) && TERMINAL_STATUSES.has(status)) {
|
|
1361
|
+
this.onTurnCompleted({ sessionId, workspace });
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
forget(sessionId) {
|
|
1365
|
+
this.lastStatus.delete(sessionId);
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1204
1371
|
// ../../oss/packages/daemon-core/src/git/index.ts
|
|
1205
1372
|
var init_git = __esm({
|
|
1206
1373
|
"../../oss/packages/daemon-core/src/git/index.ts"() {
|
|
@@ -1212,6 +1379,7 @@ var init_git = __esm({
|
|
|
1212
1379
|
init_git_snapshot_store();
|
|
1213
1380
|
init_git_monitor();
|
|
1214
1381
|
init_git_commands();
|
|
1382
|
+
init_turn_snapshot_tracker();
|
|
1215
1383
|
}
|
|
1216
1384
|
});
|
|
1217
1385
|
|
|
@@ -11367,6 +11535,16 @@ var init_handler = __esm({
|
|
|
11367
11535
|
return result;
|
|
11368
11536
|
}
|
|
11369
11537
|
}
|
|
11538
|
+
if (cmd === "send_chat" && this._ctx.onBeforeSendChat) {
|
|
11539
|
+
const sessionId = this._currentRoute.session?.sessionId;
|
|
11540
|
+
const workspace = sessionId ? this._ctx.instanceManager?.getInstance(sessionId)?.getState?.()?.workspace : void 0;
|
|
11541
|
+
if (workspace && sessionId) {
|
|
11542
|
+
try {
|
|
11543
|
+
this._ctx.onBeforeSendChat({ workspace, sessionId });
|
|
11544
|
+
} catch {
|
|
11545
|
+
}
|
|
11546
|
+
}
|
|
11547
|
+
}
|
|
11370
11548
|
try {
|
|
11371
11549
|
result = await this.dispatch(cmd, args);
|
|
11372
11550
|
this.logCommandEnd(cmd, result, startedAt);
|
|
@@ -13207,6 +13385,7 @@ function resolveCliAdapterConfig(provider) {
|
|
|
13207
13385
|
sendDelayMs: typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0,
|
|
13208
13386
|
sendKey: typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r",
|
|
13209
13387
|
submitStrategy: provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo",
|
|
13388
|
+
requirePromptEchoBeforeSubmit: provider.requirePromptEchoBeforeSubmit === true,
|
|
13210
13389
|
providerResolutionMeta: {
|
|
13211
13390
|
type: provider.type,
|
|
13212
13391
|
name: provider.name,
|
|
@@ -13472,6 +13651,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
13472
13651
|
this.sendDelayMs = resolvedConfig.sendDelayMs;
|
|
13473
13652
|
this.sendKey = resolvedConfig.sendKey;
|
|
13474
13653
|
this.submitStrategy = resolvedConfig.submitStrategy;
|
|
13654
|
+
this.requirePromptEchoBeforeSubmit = resolvedConfig.requirePromptEchoBeforeSubmit;
|
|
13475
13655
|
this.providerResolutionMeta = resolvedConfig.providerResolutionMeta;
|
|
13476
13656
|
this.cliScripts = provider.scripts || {};
|
|
13477
13657
|
const scriptNames = listCliScriptNames(this.cliScripts);
|
|
@@ -13568,6 +13748,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
13568
13748
|
accumulatedRawBuffer = "";
|
|
13569
13749
|
/** Current visible terminal screen snapshot */
|
|
13570
13750
|
terminalScreen = new TerminalScreen(24, 80);
|
|
13751
|
+
static MAX_RESPONSE_BUFFER = 8e3;
|
|
13752
|
+
static MAX_RECENT_OUTPUT_BUFFER = 1e3;
|
|
13753
|
+
responseBufferDroppedChars = 0;
|
|
13754
|
+
recentOutputDroppedChars = 0;
|
|
13755
|
+
accumulatedBufferDroppedChars = 0;
|
|
13756
|
+
accumulatedRawBufferDroppedChars = 0;
|
|
13571
13757
|
/** Max accumulated buffer size. Sized to comfortably hold a single long
|
|
13572
13758
|
* Hermes turn (tool calls + reasoning + final bubble) without the
|
|
13573
13759
|
* rolling window pushing the turn's ╭─ opening line out of view. */
|
|
@@ -13585,6 +13771,23 @@ var init_provider_cli_adapter = __esm({
|
|
|
13585
13771
|
providerResolutionMeta;
|
|
13586
13772
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
13587
13773
|
static MAX_FINISH_RETRIES = 2;
|
|
13774
|
+
getBufferState() {
|
|
13775
|
+
const build = (droppedChars, maxChars) => droppedChars > 0 ? { truncated: true, droppedChars, maxChars } : void 0;
|
|
13776
|
+
const responseBuffer = build(this.responseBufferDroppedChars, _ProviderCliAdapter.MAX_RESPONSE_BUFFER);
|
|
13777
|
+
const recentOutputBuffer = build(this.recentOutputDroppedChars, _ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
13778
|
+
const accumulatedBuffer = build(this.accumulatedBufferDroppedChars, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
13779
|
+
const accumulatedRawBuffer = build(this.accumulatedRawBufferDroppedChars, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
13780
|
+
if (!responseBuffer && !recentOutputBuffer && !accumulatedBuffer && !accumulatedRawBuffer) return void 0;
|
|
13781
|
+
return {
|
|
13782
|
+
...responseBuffer ? { responseBuffer } : {},
|
|
13783
|
+
...recentOutputBuffer ? { recentOutputBuffer } : {},
|
|
13784
|
+
...accumulatedBuffer ? { accumulatedBuffer } : {},
|
|
13785
|
+
...accumulatedRawBuffer ? { accumulatedRawBuffer } : {}
|
|
13786
|
+
};
|
|
13787
|
+
}
|
|
13788
|
+
recordBoundedAppendDrop(previousLength, appendedLength, nextLength) {
|
|
13789
|
+
return Math.max(0, previousLength + appendedLength - nextLength);
|
|
13790
|
+
}
|
|
13588
13791
|
buildCommittedMessagesActivitySignature() {
|
|
13589
13792
|
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
13590
13793
|
return [
|
|
@@ -13768,6 +13971,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
13768
13971
|
sendDelayMs;
|
|
13769
13972
|
sendKey;
|
|
13770
13973
|
submitStrategy;
|
|
13974
|
+
requirePromptEchoBeforeSubmit;
|
|
13771
13975
|
static SCRIPT_STATUS_DEBOUNCE_MS = 3e3;
|
|
13772
13976
|
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
13773
13977
|
setCliScripts(scripts) {
|
|
@@ -13949,7 +14153,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
13949
14153
|
this.scheduleStartupSettleCheck();
|
|
13950
14154
|
}
|
|
13951
14155
|
if (this.isWaitingForResponse && cleanData) {
|
|
13952
|
-
|
|
14156
|
+
const previousResponseLen = this.responseBuffer.length;
|
|
14157
|
+
this.responseBuffer = appendBoundedText(this.responseBuffer, cleanData, _ProviderCliAdapter.MAX_RESPONSE_BUFFER);
|
|
14158
|
+
this.responseBufferDroppedChars += this.recordBoundedAppendDrop(previousResponseLen, cleanData.length, this.responseBuffer.length);
|
|
13953
14159
|
}
|
|
13954
14160
|
if (cleanData.trim()) {
|
|
13955
14161
|
if (this.serverConn) {
|
|
@@ -13958,14 +14164,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
13958
14164
|
this.logBuffer.push({ message: cleanData.trim(), level: "info" });
|
|
13959
14165
|
}
|
|
13960
14166
|
}
|
|
14167
|
+
const prevRecentLen = this.recentOutputBuffer.length;
|
|
13961
14168
|
const prevAccumulatedLen = this.accumulatedBuffer.length;
|
|
13962
14169
|
const prevAccumulatedRawLen = this.accumulatedRawBuffer.length;
|
|
13963
|
-
this.recentOutputBuffer = appendBoundedText(this.recentOutputBuffer, cleanData,
|
|
14170
|
+
this.recentOutputBuffer = appendBoundedText(this.recentOutputBuffer, cleanData, _ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
13964
14171
|
this.accumulatedBuffer = appendBoundedText(this.accumulatedBuffer, cleanData, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
13965
14172
|
this.accumulatedRawBuffer = appendBoundedText(this.accumulatedRawBuffer, rawData, _ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
14173
|
+
const droppedRecent = this.recordBoundedAppendDrop(prevRecentLen, cleanData.length, this.recentOutputBuffer.length);
|
|
14174
|
+
const droppedClean = this.recordBoundedAppendDrop(prevAccumulatedLen, cleanData.length, this.accumulatedBuffer.length);
|
|
14175
|
+
const droppedRaw = this.recordBoundedAppendDrop(prevAccumulatedRawLen, rawData.length, this.accumulatedRawBuffer.length);
|
|
14176
|
+
this.recentOutputDroppedChars += droppedRecent;
|
|
14177
|
+
this.accumulatedBufferDroppedChars += droppedClean;
|
|
14178
|
+
this.accumulatedRawBufferDroppedChars += droppedRaw;
|
|
13966
14179
|
if (this.currentTurnScope) {
|
|
13967
|
-
const droppedClean = prevAccumulatedLen + cleanData.length - this.accumulatedBuffer.length;
|
|
13968
|
-
const droppedRaw = prevAccumulatedRawLen + rawData.length - this.accumulatedRawBuffer.length;
|
|
13969
14180
|
if (droppedClean > 0) {
|
|
13970
14181
|
this.currentTurnScope.bufferStart = Math.max(0, this.currentTurnScope.bufferStart - droppedClean);
|
|
13971
14182
|
}
|
|
@@ -14795,13 +15006,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
14795
15006
|
effectiveModal = parsedModal;
|
|
14796
15007
|
}
|
|
14797
15008
|
}
|
|
15009
|
+
const bufferState = this.getBufferState();
|
|
14798
15010
|
return {
|
|
14799
15011
|
status: effectiveStatus,
|
|
14800
15012
|
messages: [...this.committedMessages],
|
|
14801
15013
|
workingDir: this.workingDir,
|
|
14802
15014
|
activeModal: effectiveModal,
|
|
14803
15015
|
errorMessage: this.parseErrorMessage || void 0,
|
|
14804
|
-
errorReason: this.parseErrorMessage ? "parse_error" : void 0
|
|
15016
|
+
errorReason: this.parseErrorMessage ? "parse_error" : void 0,
|
|
15017
|
+
...bufferState ? { bufferState } : {}
|
|
14805
15018
|
};
|
|
14806
15019
|
}
|
|
14807
15020
|
seedCommittedMessages(messages) {
|
|
@@ -14983,10 +15196,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
14983
15196
|
messages: hydratedMessages,
|
|
14984
15197
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
14985
15198
|
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
15199
|
+
...this.getBufferState() ? { bufferState: this.getBufferState() } : {},
|
|
14986
15200
|
...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
14987
15201
|
};
|
|
14988
15202
|
} else {
|
|
14989
15203
|
const messages = [...this.committedMessages];
|
|
15204
|
+
const bufferState = this.getBufferState();
|
|
14990
15205
|
result = {
|
|
14991
15206
|
id: "cli_session",
|
|
14992
15207
|
status: this.currentStatus,
|
|
@@ -14997,7 +15212,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
14997
15212
|
index: typeof message.index === "number" ? message.index : index,
|
|
14998
15213
|
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
14999
15214
|
})),
|
|
15000
|
-
activeModal: this.activeModal
|
|
15215
|
+
activeModal: this.activeModal,
|
|
15216
|
+
...bufferState ? { bufferState } : {}
|
|
15001
15217
|
};
|
|
15002
15218
|
}
|
|
15003
15219
|
const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
@@ -15288,6 +15504,22 @@ var init_provider_cli_adapter = __esm({
|
|
|
15288
15504
|
}
|
|
15289
15505
|
}
|
|
15290
15506
|
if (elapsed >= state.maxEchoWaitMs) {
|
|
15507
|
+
const diagnostic = {
|
|
15508
|
+
elapsed,
|
|
15509
|
+
maxEchoWaitMs: state.maxEchoWaitMs,
|
|
15510
|
+
submitDelayMs: state.submitDelayMs,
|
|
15511
|
+
promptSnippet: state.normalizedPromptSnippet,
|
|
15512
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
15513
|
+
screenText: summarizeCliTraceText(screenText, 1e3)
|
|
15514
|
+
};
|
|
15515
|
+
this.recordTrace("submit_echo_missing", diagnostic);
|
|
15516
|
+
if (this.requirePromptEchoBeforeSubmit) {
|
|
15517
|
+
const message = `${this.cliName} prompt echo was not observed on the PTY screen before submit`;
|
|
15518
|
+
LOG.warn("CLI", `[${this.cliType}] ${message} elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
|
|
15519
|
+
completion.rejectOnce(new Error(message));
|
|
15520
|
+
return;
|
|
15521
|
+
}
|
|
15522
|
+
LOG.warn("CLI", `[${this.cliType}] prompt echo was not observed before submit; sending submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs}`);
|
|
15291
15523
|
this.submitSendKey(state, completion);
|
|
15292
15524
|
return;
|
|
15293
15525
|
}
|
|
@@ -15752,6 +15984,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
15752
15984
|
sendDelayMs: this.sendDelayMs,
|
|
15753
15985
|
sendKey: this.sendKey,
|
|
15754
15986
|
submitStrategy: this.submitStrategy,
|
|
15987
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
15755
15988
|
submitPendingUntil: this.submitPendingUntil,
|
|
15756
15989
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
15757
15990
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
@@ -37052,6 +37285,7 @@ var init_provider_schema = __esm({
|
|
|
37052
37285
|
"sendDelayMs",
|
|
37053
37286
|
"sendKey",
|
|
37054
37287
|
"submitStrategy",
|
|
37288
|
+
"requirePromptEchoBeforeSubmit",
|
|
37055
37289
|
"timeouts",
|
|
37056
37290
|
"disableUpstream"
|
|
37057
37291
|
]);
|
|
@@ -48627,6 +48861,7 @@ async function initDaemonComponents(config2) {
|
|
|
48627
48861
|
providerLoader,
|
|
48628
48862
|
instanceManager,
|
|
48629
48863
|
sessionRegistry,
|
|
48864
|
+
gitCommandServices: createDefaultGitCommandServices(),
|
|
48630
48865
|
onProviderSettingChanged: async (providerType) => {
|
|
48631
48866
|
await refreshProviderAvailability(providerType);
|
|
48632
48867
|
config2.onStatusChange?.();
|
|
@@ -48634,7 +48869,8 @@ async function initDaemonComponents(config2) {
|
|
|
48634
48869
|
onProviderSourceConfigChanged: async () => {
|
|
48635
48870
|
await refreshProviderAvailability();
|
|
48636
48871
|
config2.onStatusChange?.();
|
|
48637
|
-
}
|
|
48872
|
+
},
|
|
48873
|
+
onBeforeSendChat: config2.onBeforeSendChat
|
|
48638
48874
|
});
|
|
48639
48875
|
agentStreamManager = new DaemonAgentStreamManager(
|
|
48640
48876
|
LOG.forComponent("AgentStream").asLogFn(),
|
|
@@ -48760,6 +48996,7 @@ var init_daemon_lifecycle = __esm({
|
|
|
48760
48996
|
init_logger();
|
|
48761
48997
|
init_runtime_defaults();
|
|
48762
48998
|
init_config();
|
|
48999
|
+
init_git_commands();
|
|
48763
49000
|
}
|
|
48764
49001
|
});
|
|
48765
49002
|
|
|
@@ -48810,6 +49047,7 @@ __export(src_exports, {
|
|
|
48810
49047
|
ProviderLoader: () => ProviderLoader,
|
|
48811
49048
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS,
|
|
48812
49049
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
49050
|
+
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
48813
49051
|
VersionArchive: () => VersionArchive,
|
|
48814
49052
|
appendRecentActivity: () => appendRecentActivity,
|
|
48815
49053
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
@@ -49414,7 +49652,7 @@ function sendToPeer(peer, data) {
|
|
|
49414
49652
|
return false;
|
|
49415
49653
|
}
|
|
49416
49654
|
const json2 = JSON.stringify(data);
|
|
49417
|
-
if (messageType === "command_result" && json2
|
|
49655
|
+
if (messageType === "command_result" && Buffer.byteLength(json2, "utf8") > MAX_INLINE_JSON_MESSAGE_CHARS) {
|
|
49418
49656
|
return sendChunkedCommandResult(peer, peerId, requestId, json2);
|
|
49419
49657
|
}
|
|
49420
49658
|
try {
|
|
@@ -49427,21 +49665,51 @@ function sendToPeer(peer, data) {
|
|
|
49427
49665
|
return false;
|
|
49428
49666
|
}
|
|
49429
49667
|
}
|
|
49668
|
+
function buildCommandResultChunkEnvelope(requestId, chunkId, index, total, data) {
|
|
49669
|
+
return JSON.stringify({
|
|
49670
|
+
type: "command_result_chunk",
|
|
49671
|
+
id: requestId,
|
|
49672
|
+
chunkId,
|
|
49673
|
+
index,
|
|
49674
|
+
total,
|
|
49675
|
+
data
|
|
49676
|
+
});
|
|
49677
|
+
}
|
|
49678
|
+
function splitJsonIntoCommandResultChunks(json2, requestId, chunkId) {
|
|
49679
|
+
const chunks = [];
|
|
49680
|
+
let offset = 0;
|
|
49681
|
+
while (offset < json2.length) {
|
|
49682
|
+
let end = Math.min(json2.length, offset + JSON_CHUNK_PAYLOAD_CHARS);
|
|
49683
|
+
while (end > offset) {
|
|
49684
|
+
const candidate = json2.slice(offset, end);
|
|
49685
|
+
const envelope = buildCommandResultChunkEnvelope(requestId, chunkId, chunks.length, MAX_JSON_CHUNKS, candidate);
|
|
49686
|
+
if (Buffer.byteLength(envelope, "utf8") <= MAX_INLINE_JSON_MESSAGE_BYTES) break;
|
|
49687
|
+
end = offset + Math.max(1, Math.floor((end - offset) * 0.8));
|
|
49688
|
+
}
|
|
49689
|
+
chunks.push(json2.slice(offset, end));
|
|
49690
|
+
if (chunks.length > MAX_JSON_CHUNKS) return [];
|
|
49691
|
+
offset = end;
|
|
49692
|
+
}
|
|
49693
|
+
return chunks;
|
|
49694
|
+
}
|
|
49430
49695
|
function sendChunkedCommandResult(peer, peerId, requestId, json2) {
|
|
49431
49696
|
const chunkId = requestId || `command_result_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
49432
|
-
const
|
|
49697
|
+
const chunks = splitJsonIntoCommandResultChunks(json2, requestId, chunkId);
|
|
49698
|
+
const total = chunks.length;
|
|
49699
|
+
if (total === 0 || total > MAX_JSON_CHUNKS) {
|
|
49700
|
+
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} reason=too_many_chunks chunks=${total || "unknown"}`);
|
|
49701
|
+
return false;
|
|
49702
|
+
}
|
|
49433
49703
|
logDebug(`command_result chunked: peer=${peerId} id=${requestId || "-"} chars=${json2.length} chunks=${total}`);
|
|
49434
49704
|
for (let index = 0; index < total; index += 1) {
|
|
49435
|
-
const chunk =
|
|
49705
|
+
const chunk = chunks[index] || "";
|
|
49436
49706
|
try {
|
|
49437
|
-
|
|
49438
|
-
|
|
49439
|
-
|
|
49440
|
-
|
|
49441
|
-
|
|
49442
|
-
|
|
49443
|
-
data: chunk
|
|
49444
|
-
}));
|
|
49707
|
+
const envelope = buildCommandResultChunkEnvelope(requestId, chunkId, index, total, chunk);
|
|
49708
|
+
if (Buffer.byteLength(envelope, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES) {
|
|
49709
|
+
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} chunk=${index + 1}/${total} reason=chunk_too_large`);
|
|
49710
|
+
return false;
|
|
49711
|
+
}
|
|
49712
|
+
peer.dataChannel?.sendMessage(envelope);
|
|
49445
49713
|
} catch (error48) {
|
|
49446
49714
|
log(`command_result send failed: peer=${peerId} id=${requestId || "-"} chunk=${index + 1}/${total} error=${error48?.message || error48}`);
|
|
49447
49715
|
return false;
|
|
@@ -49449,10 +49717,58 @@ function sendChunkedCommandResult(peer, peerId, requestId, json2) {
|
|
|
49449
49717
|
}
|
|
49450
49718
|
return true;
|
|
49451
49719
|
}
|
|
49720
|
+
function parseChunkedJsonMessage(peerId, parsed) {
|
|
49721
|
+
const chunkType = typeof parsed?.type === "string" ? parsed.type : "";
|
|
49722
|
+
if (!chunkType.endsWith("_chunk")) return parsed;
|
|
49723
|
+
const chunkId = typeof parsed?.chunkId === "string" ? parsed.chunkId : "";
|
|
49724
|
+
const id = typeof parsed?.id === "string" ? parsed.id : "";
|
|
49725
|
+
const index = Number(parsed?.index);
|
|
49726
|
+
const total = Number(parsed?.total);
|
|
49727
|
+
const data = typeof parsed?.data === "string" ? parsed.data : "";
|
|
49728
|
+
if (!chunkId || !Number.isInteger(index) || !Number.isInteger(total) || index < 0 || total <= 0 || total > MAX_JSON_CHUNKS || index >= total || !data) {
|
|
49729
|
+
log(`chunked JSON ignored: peer=${peerId} type=${chunkType || "unknown"} reason=malformed`);
|
|
49730
|
+
return null;
|
|
49731
|
+
}
|
|
49732
|
+
const now = Date.now();
|
|
49733
|
+
incomingJsonChunks.forEach((entry2, key2) => {
|
|
49734
|
+
if (now - entry2.createdAt > JSON_CHUNK_TTL_MS) incomingJsonChunks.delete(key2);
|
|
49735
|
+
});
|
|
49736
|
+
const key = `${peerId}:${chunkId}`;
|
|
49737
|
+
let entry = incomingJsonChunks.get(key);
|
|
49738
|
+
if (!entry || entry.total !== total || entry.type !== chunkType) {
|
|
49739
|
+
entry = { total, chunks: new Array(total).fill(""), received: 0, createdAt: now, type: chunkType, id };
|
|
49740
|
+
incomingJsonChunks.set(key, entry);
|
|
49741
|
+
}
|
|
49742
|
+
if (!entry.chunks[index]) {
|
|
49743
|
+
entry.chunks[index] = data;
|
|
49744
|
+
entry.received += 1;
|
|
49745
|
+
}
|
|
49746
|
+
if (entry.received < entry.total) return null;
|
|
49747
|
+
incomingJsonChunks.delete(key);
|
|
49748
|
+
try {
|
|
49749
|
+
return JSON.parse(entry.chunks.join(""));
|
|
49750
|
+
} catch (error48) {
|
|
49751
|
+
log(`chunked JSON parse failed: peer=${peerId} type=${chunkType} id=${entry.id || "-"} error=${error48?.message || error48}`);
|
|
49752
|
+
return CHUNK_PARSE_FAILED;
|
|
49753
|
+
}
|
|
49754
|
+
}
|
|
49452
49755
|
function routeDataChannelMessage(peerId, msg, peers, handlers) {
|
|
49453
49756
|
const text = typeof msg === "string" ? msg : msg.toString("utf-8");
|
|
49454
49757
|
try {
|
|
49455
|
-
|
|
49758
|
+
let parsed = JSON.parse(text);
|
|
49759
|
+
const chunked = parseChunkedJsonMessage(peerId, parsed);
|
|
49760
|
+
if (chunked === null) return;
|
|
49761
|
+
if (chunked === CHUNK_PARSE_FAILED) {
|
|
49762
|
+
const peer = peers.get(peerId);
|
|
49763
|
+
const id = typeof parsed?.id === "string" ? parsed.id : "";
|
|
49764
|
+
if (parsed?.type === "command_chunk") {
|
|
49765
|
+
sendToPeer(peer, { type: "command_result", id, success: false, error: "Failed to reassemble chunked command" });
|
|
49766
|
+
} else if (id) {
|
|
49767
|
+
sendToPeer(peer, { id, type: "response", success: false, error: "Failed to reassemble chunked request" });
|
|
49768
|
+
}
|
|
49769
|
+
return;
|
|
49770
|
+
}
|
|
49771
|
+
parsed = chunked;
|
|
49456
49772
|
if (parsed.type !== "command" && parsed.type !== "pty_input" && parsed.type !== "pty_resize" && parsed.type !== "ping" && parsed.type !== "pong") {
|
|
49457
49773
|
logDebug(`Files message from peer ${peerId}: type=${parsed.type}`);
|
|
49458
49774
|
}
|
|
@@ -49748,7 +50064,7 @@ async function handleFileRequest(peerId, req, peers, handlers) {
|
|
|
49748
50064
|
}
|
|
49749
50065
|
sendToPeer(peer, response);
|
|
49750
50066
|
}
|
|
49751
|
-
var MAX_INLINE_JSON_MESSAGE_CHARS, JSON_CHUNK_PAYLOAD_CHARS;
|
|
50067
|
+
var MAX_INLINE_JSON_MESSAGE_CHARS, MAX_INLINE_JSON_MESSAGE_BYTES, JSON_CHUNK_PAYLOAD_CHARS, JSON_CHUNK_TTL_MS, MAX_JSON_CHUNKS, CHUNK_PARSE_FAILED, incomingJsonChunks;
|
|
49752
50068
|
var init_data_channel_router = __esm({
|
|
49753
50069
|
"src/daemon-p2p/data-channel-router.ts"() {
|
|
49754
50070
|
"use strict";
|
|
@@ -49756,18 +50072,23 @@ var init_data_channel_router = __esm({
|
|
|
49756
50072
|
init_permission();
|
|
49757
50073
|
init_log();
|
|
49758
50074
|
MAX_INLINE_JSON_MESSAGE_CHARS = 6e4;
|
|
49759
|
-
|
|
50075
|
+
MAX_INLINE_JSON_MESSAGE_BYTES = 6e4;
|
|
50076
|
+
JSON_CHUNK_PAYLOAD_CHARS = 16e3;
|
|
50077
|
+
JSON_CHUNK_TTL_MS = 6e4;
|
|
50078
|
+
MAX_JSON_CHUNKS = 1024;
|
|
50079
|
+
CHUNK_PARSE_FAILED = /* @__PURE__ */ Symbol("chunk_parse_failed");
|
|
50080
|
+
incomingJsonChunks = /* @__PURE__ */ new Map();
|
|
49760
50081
|
}
|
|
49761
50082
|
});
|
|
49762
50083
|
|
|
49763
50084
|
// src/daemon-p2p/screenshot-sender.ts
|
|
49764
|
-
var CHUNK_SIZE,
|
|
50085
|
+
var CHUNK_SIZE, MAX_INLINE_JSON_MESSAGE_BYTES2, JSON_CHUNK_PAYLOAD_CHARS2, ScreenshotSender;
|
|
49765
50086
|
var init_screenshot_sender = __esm({
|
|
49766
50087
|
"src/daemon-p2p/screenshot-sender.ts"() {
|
|
49767
50088
|
"use strict";
|
|
49768
50089
|
init_log();
|
|
49769
50090
|
CHUNK_SIZE = 6e4;
|
|
49770
|
-
|
|
50091
|
+
MAX_INLINE_JSON_MESSAGE_BYTES2 = 6e4;
|
|
49771
50092
|
JSON_CHUNK_PAYLOAD_CHARS2 = 16e3;
|
|
49772
50093
|
ScreenshotSender = class {
|
|
49773
50094
|
_ssDebugDone = false;
|
|
@@ -49811,7 +50132,7 @@ var init_screenshot_sender = __esm({
|
|
|
49811
50132
|
type: "topic_update",
|
|
49812
50133
|
update
|
|
49813
50134
|
});
|
|
49814
|
-
if (Buffer.byteLength(json2, "utf8") >
|
|
50135
|
+
if (Buffer.byteLength(json2, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES2) {
|
|
49815
50136
|
return this.sendChunkedTopicUpdate(peer, update, json2);
|
|
49816
50137
|
}
|
|
49817
50138
|
try {
|
|
@@ -49850,6 +50171,10 @@ var init_screenshot_sender = __esm({
|
|
|
49850
50171
|
let sentAny = false;
|
|
49851
50172
|
for (const peer of peers.values()) {
|
|
49852
50173
|
if (peer.state !== "connected" || !peer.dataChannel?.isOpen()) continue;
|
|
50174
|
+
if (Buffer.byteLength(msg, "utf8") > MAX_INLINE_JSON_MESSAGE_BYTES2) {
|
|
50175
|
+
if (this.sendChunkedSessionOutput(peer, sessionId, msg)) sentAny = true;
|
|
50176
|
+
continue;
|
|
50177
|
+
}
|
|
49853
50178
|
try {
|
|
49854
50179
|
peer.dataChannel.sendMessage(msg);
|
|
49855
50180
|
sentAny = true;
|
|
@@ -49858,6 +50183,27 @@ var init_screenshot_sender = __esm({
|
|
|
49858
50183
|
}
|
|
49859
50184
|
return sentAny;
|
|
49860
50185
|
}
|
|
50186
|
+
sendChunkedSessionOutput(peer, sessionId, json2) {
|
|
50187
|
+
const chunkId = `session_output:${sessionId}:${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;
|
|
50188
|
+
const total = Math.ceil(json2.length / JSON_CHUNK_PAYLOAD_CHARS2);
|
|
50189
|
+
logDebug(`session_output chunked: peer=${peer.peerId || "unknown"} sessionId=${sessionId || "-"} chars=${json2.length} chunks=${total}`);
|
|
50190
|
+
for (let index = 0; index < total; index += 1) {
|
|
50191
|
+
const chunk = json2.slice(index * JSON_CHUNK_PAYLOAD_CHARS2, (index + 1) * JSON_CHUNK_PAYLOAD_CHARS2);
|
|
50192
|
+
try {
|
|
50193
|
+
peer.dataChannel?.sendMessage(JSON.stringify({
|
|
50194
|
+
type: "session_output_chunk",
|
|
50195
|
+
sessionId,
|
|
50196
|
+
chunkId,
|
|
50197
|
+
index,
|
|
50198
|
+
total,
|
|
50199
|
+
data: chunk
|
|
50200
|
+
}));
|
|
50201
|
+
} catch {
|
|
50202
|
+
return false;
|
|
50203
|
+
}
|
|
50204
|
+
}
|
|
50205
|
+
return true;
|
|
50206
|
+
}
|
|
49861
50207
|
sendScreenshot(peers, base64Data, targetSessionId) {
|
|
49862
50208
|
const buffer = Buffer.from(base64Data, "base64");
|
|
49863
50209
|
return this.sendScreenshotBuffer(peers, buffer, targetSessionId);
|
|
@@ -58691,7 +59037,7 @@ var init_adhdev_daemon = __esm({
|
|
|
58691
59037
|
init_version();
|
|
58692
59038
|
init_src();
|
|
58693
59039
|
init_runtime_defaults();
|
|
58694
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
59040
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.56" });
|
|
58695
59041
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
58696
59042
|
localHttpServer = null;
|
|
58697
59043
|
localWss = null;
|
|
@@ -58715,6 +59061,19 @@ var init_adhdev_daemon = __esm({
|
|
|
58715
59061
|
sessionHostEndpoint = null;
|
|
58716
59062
|
sessionHostController = null;
|
|
58717
59063
|
gitWorkspaceMonitor = createGitWorkspaceMonitor();
|
|
59064
|
+
turnSnapshotTracker = new TurnSnapshotTracker(({ sessionId, workspace }) => {
|
|
59065
|
+
const gitServices = this.components?.commandHandler?.ctx?.gitCommandServices;
|
|
59066
|
+
if (gitServices?.createSnapshot) {
|
|
59067
|
+
void Promise.resolve(gitServices.createSnapshot({
|
|
59068
|
+
workspace,
|
|
59069
|
+
reason: "after_agent_work",
|
|
59070
|
+
sessionId
|
|
59071
|
+
})).catch(() => {
|
|
59072
|
+
});
|
|
59073
|
+
}
|
|
59074
|
+
void this.gitWorkspaceMonitor.refresh({ workspace, includeDiffSummary: false }).catch(() => {
|
|
59075
|
+
});
|
|
59076
|
+
});
|
|
58718
59077
|
running = false;
|
|
58719
59078
|
localPort;
|
|
58720
59079
|
ideType = "unknown";
|
|
@@ -58886,7 +59245,8 @@ var init_adhdev_daemon = __esm({
|
|
|
58886
59245
|
})),
|
|
58887
59246
|
instanceId: `daemon_${loadConfig().machineId || "daemon"}`,
|
|
58888
59247
|
version: pkgVersion,
|
|
58889
|
-
profile: "live"
|
|
59248
|
+
profile: "live",
|
|
59249
|
+
getGitSummaryForWorkspace: (workspace) => this.gitWorkspaceMonitor.getCompactSummary(workspace)
|
|
58890
59250
|
});
|
|
58891
59251
|
}
|
|
58892
59252
|
invalidateHotChatSnapshotCache() {
|
|
@@ -59072,7 +59432,8 @@ var init_adhdev_daemon = __esm({
|
|
|
59072
59432
|
})),
|
|
59073
59433
|
instanceId: `daemon_${loadConfig().machineId || "daemon"}`,
|
|
59074
59434
|
version: pkgVersion,
|
|
59075
|
-
profile: "metadata"
|
|
59435
|
+
profile: "metadata",
|
|
59436
|
+
getGitSummaryForWorkspace: (workspace) => this.gitWorkspaceMonitor.getCompactSummary(workspace)
|
|
59076
59437
|
});
|
|
59077
59438
|
}
|
|
59078
59439
|
buildDaemonMetadataUpdateForSubscription(subscription) {
|
|
@@ -59216,6 +59577,27 @@ ${err?.stack || ""}`);
|
|
|
59216
59577
|
onStreamsUpdated: (ideType, streams) => {
|
|
59217
59578
|
if (!this.components) return;
|
|
59218
59579
|
forwardAgentStreamsToIdeInstance(this.components.instanceManager, ideType, streams);
|
|
59580
|
+
for (const stream of streams) {
|
|
59581
|
+
if (stream.sessionId) {
|
|
59582
|
+
const workspace = this.components?.instanceManager?.getInstance(stream.sessionId)?.getState()?.workspace;
|
|
59583
|
+
this.turnSnapshotTracker.record(stream.sessionId, stream.status || "idle", workspace);
|
|
59584
|
+
}
|
|
59585
|
+
}
|
|
59586
|
+
},
|
|
59587
|
+
onBeforeSendChat: ({ workspace }) => {
|
|
59588
|
+
void this.gitWorkspaceMonitor.refresh({
|
|
59589
|
+
workspace,
|
|
59590
|
+
includeDiffSummary: false
|
|
59591
|
+
}).catch(() => {
|
|
59592
|
+
});
|
|
59593
|
+
const gitServices = this.components?.commandHandler?.ctx?.gitCommandServices;
|
|
59594
|
+
if (gitServices?.createSnapshot) {
|
|
59595
|
+
void Promise.resolve(gitServices.createSnapshot({
|
|
59596
|
+
workspace,
|
|
59597
|
+
reason: "before_user_input_dispatch"
|
|
59598
|
+
})).catch(() => {
|
|
59599
|
+
});
|
|
59600
|
+
}
|
|
59219
59601
|
}
|
|
59220
59602
|
});
|
|
59221
59603
|
const providerSourceConfig = this.components.providerLoader.getSourceConfig();
|