chatroom-cli 1.58.5 → 1.59.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/index.js CHANGED
@@ -28762,6 +28762,747 @@ var init_claude = __esm(() => {
28762
28762
  init_claude_code_agent_service();
28763
28763
  });
28764
28764
 
28765
+ // src/infrastructure/services/remote-agents/wire-native-stream-adapter.ts
28766
+ function wireNativeStreamAdapter(args2) {
28767
+ args2.adapter.setAssistantTextCapture((text) => {
28768
+ for (const cb of args2.assistantTextCallbacks)
28769
+ cb(text);
28770
+ });
28771
+ args2.adapter.onOutput(() => {
28772
+ args2.entry.lastOutputAt = Date.now();
28773
+ for (const cb of args2.outputCallbacks)
28774
+ cb();
28775
+ });
28776
+ args2.adapter.onAgentEnd(() => {
28777
+ for (const cb of args2.agentEndCallbacks)
28778
+ cb();
28779
+ });
28780
+ }
28781
+
28782
+ // src/infrastructure/services/remote-agents/with-timeout.ts
28783
+ async function withTimeout(p, ms, label) {
28784
+ let timer;
28785
+ try {
28786
+ return await Promise.race([
28787
+ p,
28788
+ new Promise((_, reject) => {
28789
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
28790
+ })
28791
+ ]);
28792
+ } finally {
28793
+ if (timer)
28794
+ clearTimeout(timer);
28795
+ }
28796
+ }
28797
+
28798
+ // src/infrastructure/services/remote-agents/claude-sdk/claude-sdk-package.ts
28799
+ import { existsSync, readFileSync as readFileSync3 } from "node:fs";
28800
+ import { createRequire as createRequire3 } from "node:module";
28801
+ import { dirname as dirname2, join as join7 } from "node:path";
28802
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
28803
+ function resolveChatroomCliRoot(moduleRef = import.meta.url) {
28804
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath2(moduleRef) : moduleRef;
28805
+ let dir = dirname2(filePath);
28806
+ while (dir !== dirname2(dir)) {
28807
+ const packageJsonPath = join7(dir, "package.json");
28808
+ if (existsSync(packageJsonPath)) {
28809
+ const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
28810
+ if (pkg.name === "chatroom-cli") {
28811
+ return dir;
28812
+ }
28813
+ }
28814
+ dir = dirname2(dir);
28815
+ }
28816
+ throw new ClaudeSdkPackageError(`Could not locate chatroom-cli package root while resolving ${CLAUDE_AGENT_SDK_PKG}. ${REINSTALL_HINT}`);
28817
+ }
28818
+ function readPinnedSdkVersion(chatroomCliRoot) {
28819
+ const pkg = JSON.parse(readFileSync3(join7(chatroomCliRoot, "package.json"), "utf8"));
28820
+ const specifier = pkg.dependencies?.[CLAUDE_AGENT_SDK_PKG];
28821
+ const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
28822
+ const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
28823
+ if (!match17) {
28824
+ throw new ClaudeSdkPackageError(`chatroom-cli must pin an exact ${CLAUDE_AGENT_SDK_PKG} version (found "${specifier ?? "none"}"). ${REINSTALL_HINT}`);
28825
+ }
28826
+ return match17[1];
28827
+ }
28828
+ function readInstalledSdkVersion(entryPath) {
28829
+ const packageJsonPath = join7(dirname2(entryPath), "package.json");
28830
+ const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
28831
+ return pkg.version;
28832
+ }
28833
+ function resolvePlatformPackageName() {
28834
+ const key = `${process.platform}-${process.arch}`;
28835
+ const map18 = {
28836
+ "darwin-arm64": "@anthropic-ai/claude-agent-sdk-darwin-arm64",
28837
+ "darwin-x64": "@anthropic-ai/claude-agent-sdk-darwin-x64",
28838
+ "linux-arm64": "@anthropic-ai/claude-agent-sdk-linux-arm64",
28839
+ "linux-x64": "@anthropic-ai/claude-agent-sdk-linux-x64",
28840
+ "win32-arm64": "@anthropic-ai/claude-agent-sdk-win32-arm64",
28841
+ "win32-x64": "@anthropic-ai/claude-agent-sdk-win32-x64"
28842
+ };
28843
+ const pkg = map18[key];
28844
+ if (!pkg) {
28845
+ throw new ClaudeSdkPackageError(`Unsupported platform for ${CLAUDE_AGENT_SDK_PKG}: ${key}. ${REINSTALL_HINT}`);
28846
+ }
28847
+ return pkg;
28848
+ }
28849
+ function resolveNativeCliBinaryPath(sdkEntryPath) {
28850
+ const require3 = createRequire3(sdkEntryPath);
28851
+ const platformPkg = resolvePlatformPackageName();
28852
+ const binaryName = process.platform === "win32" ? "claude.exe" : "claude";
28853
+ let pkgDir;
28854
+ try {
28855
+ pkgDir = dirname2(require3.resolve(`${platformPkg}/package.json`));
28856
+ } catch {
28857
+ throw new ClaudeSdkPackageError(`Native CLI binary package ${platformPkg} is not installed. ${REINSTALL_HINT}`);
28858
+ }
28859
+ const binaryPath = join7(pkgDir, binaryName);
28860
+ if (!existsSync(binaryPath)) {
28861
+ throw new ClaudeSdkPackageError(`Native CLI binary is missing: ${binaryPath}. ${REINSTALL_HINT}`);
28862
+ }
28863
+ return binaryPath;
28864
+ }
28865
+ async function resolvePathToClaudeCodeExecutable(moduleRef = import.meta.url) {
28866
+ if (cachedExecutablePath)
28867
+ return cachedExecutablePath;
28868
+ const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
28869
+ const require3 = createRequire3(join7(chatroomCliRoot, "package.json"));
28870
+ const sdkEntryPath = require3.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
28871
+ const embeddedPath = resolveNativeCliBinaryPath(sdkEntryPath);
28872
+ const { extractFromBunfs } = await import("@anthropic-ai/claude-agent-sdk/extract");
28873
+ cachedExecutablePath = extractFromBunfs(embeddedPath);
28874
+ return cachedExecutablePath;
28875
+ }
28876
+ async function importBundledClaudeSdk(moduleRef = import.meta.url) {
28877
+ const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
28878
+ const require3 = createRequire3(join7(chatroomCliRoot, "package.json"));
28879
+ const pinnedVersion = readPinnedSdkVersion(chatroomCliRoot);
28880
+ const entryPath = require3.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
28881
+ const installedVersion = readInstalledSdkVersion(entryPath);
28882
+ if (installedVersion !== pinnedVersion) {
28883
+ throw new ClaudeSdkPackageError(`${CLAUDE_AGENT_SDK_PKG}@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT}`);
28884
+ }
28885
+ if (!existsSync(entryPath)) {
28886
+ throw new ClaudeSdkPackageError(`${CLAUDE_AGENT_SDK_PKG} entry file is missing: ${entryPath}. ${REINSTALL_HINT}`);
28887
+ }
28888
+ return import(pathToFileURL(entryPath).href);
28889
+ }
28890
+ function getBundledClaudeSdkVersion(moduleRef = import.meta.url) {
28891
+ const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
28892
+ const require3 = createRequire3(join7(chatroomCliRoot, "package.json"));
28893
+ const entryPath = require3.resolve(CLAUDE_AGENT_SDK_PKG, { paths: [chatroomCliRoot] });
28894
+ return readInstalledSdkVersion(entryPath);
28895
+ }
28896
+ function formatClaudeSdkLoadError(err) {
28897
+ if (err instanceof ClaudeSdkPackageError) {
28898
+ return err.message;
28899
+ }
28900
+ const message = err instanceof Error ? err.message : String(err);
28901
+ if (message.includes("Native CLI binary")) {
28902
+ return `${message} ${REINSTALL_HINT}`;
28903
+ }
28904
+ return message;
28905
+ }
28906
+ var CLAUDE_AGENT_SDK_PKG = "@anthropic-ai/claude-agent-sdk", REINSTALL_HINT = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", ClaudeSdkPackageError, cachedExecutablePath;
28907
+ var init_claude_sdk_package = __esm(() => {
28908
+ ClaudeSdkPackageError = class ClaudeSdkPackageError extends Error {
28909
+ code = "CLAUDE_SDK_PACKAGE_INCOMPLETE";
28910
+ constructor(message) {
28911
+ super(message);
28912
+ this.name = "ClaudeSdkPackageError";
28913
+ }
28914
+ };
28915
+ });
28916
+
28917
+ // src/infrastructure/services/remote-agents/assistant-text-capture.ts
28918
+ function createAssistantTextCapture() {
28919
+ let onAssistantText;
28920
+ return {
28921
+ setAssistantTextCapture(cb) {
28922
+ onAssistantText = cb;
28923
+ },
28924
+ captureAssistantText(text) {
28925
+ onAssistantText?.(text);
28926
+ }
28927
+ };
28928
+ }
28929
+
28930
+ // src/infrastructure/services/remote-agents/native-stream-adapter-base.ts
28931
+ class NativeStreamAdapterBase {
28932
+ logPrefix;
28933
+ emitLogLine;
28934
+ agentEndCallbacks = [];
28935
+ outputCallbacks = [];
28936
+ agentEndEmitted = false;
28937
+ assistantTextCapture = createAssistantTextCapture();
28938
+ constructor(logPrefix, emitLogLine) {
28939
+ this.logPrefix = logPrefix;
28940
+ this.emitLogLine = emitLogLine;
28941
+ }
28942
+ setAssistantTextCapture(cb) {
28943
+ this.assistantTextCapture.setAssistantTextCapture(cb);
28944
+ }
28945
+ onAgentEnd(cb) {
28946
+ this.agentEndCallbacks.push(cb);
28947
+ }
28948
+ onOutput(cb) {
28949
+ this.outputCallbacks.push(cb);
28950
+ }
28951
+ notifyOutput() {
28952
+ for (const cb of this.outputCallbacks)
28953
+ cb();
28954
+ }
28955
+ writeLine(line) {
28956
+ this.emitLogLine?.(line);
28957
+ }
28958
+ }
28959
+ var init_native_stream_adapter_base = () => {};
28960
+
28961
+ // src/infrastructure/services/remote-agents/claude-sdk/claude-sdk-stream-adapter.ts
28962
+ var ClaudeSdkStreamAdapter;
28963
+ var init_claude_sdk_stream_adapter = __esm(() => {
28964
+ init_native_stream_adapter_base();
28965
+ ClaudeSdkStreamAdapter = class ClaudeSdkStreamAdapter extends NativeStreamAdapterBase {
28966
+ textBuffer = "";
28967
+ thinkingBuffer = "";
28968
+ handleMessage(message) {
28969
+ this.notifyOutput();
28970
+ switch (message.type) {
28971
+ case "stream_event":
28972
+ this.handleStreamEvent(message);
28973
+ break;
28974
+ case "assistant":
28975
+ this.handleAssistant(message);
28976
+ break;
28977
+ case "user":
28978
+ this.handleUser(message);
28979
+ break;
28980
+ case "system":
28981
+ if (message.subtype === "init") {
28982
+ this.writeLine(formatAgentLogLine(this.logPrefix, "system: init"));
28983
+ }
28984
+ break;
28985
+ case "result":
28986
+ if (message.is_error) {
28987
+ const errors2 = "errors" in message && Array.isArray(message.errors) ? message.errors.join("; ") : "turn failed";
28988
+ this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", errors2));
28989
+ }
28990
+ break;
28991
+ default:
28992
+ break;
28993
+ }
28994
+ }
28995
+ finish() {
28996
+ this.flushText();
28997
+ this.flushThinking();
28998
+ this.emitAgentEnd();
28999
+ }
29000
+ handleStreamEvent(message) {
29001
+ const event = message.event;
29002
+ if (event.type === "content_block_delta") {
29003
+ const delta = event.delta;
29004
+ if (delta.type === "text_delta") {
29005
+ this.appendText(delta.text);
29006
+ } else if (delta.type === "thinking_delta") {
29007
+ this.appendThinking(delta.thinking);
29008
+ }
29009
+ }
29010
+ }
29011
+ handleAssistant(message) {
29012
+ if (message.error) {
29013
+ this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", `assistant error: ${message.error}`));
29014
+ }
29015
+ for (const block of message.message.content) {
29016
+ if (block.type === "text") {
29017
+ this.appendText(block.text);
29018
+ this.flushText();
29019
+ } else if (block.type === "thinking") {
29020
+ this.appendThinking(block.thinking);
29021
+ this.flushThinking();
29022
+ } else if (block.type === "tool_use") {
29023
+ this.flushText();
29024
+ this.flushThinking();
29025
+ const bashCmd = resolveBashCommandForLog(block.name, block.input);
29026
+ if (bashCmd !== null) {
29027
+ this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(bashCmd)));
29028
+ break;
29029
+ }
29030
+ const argsStr = block.input != null ? ` args: ${JSON.stringify(block.input)}` : "";
29031
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool", `${block.name}${argsStr}`));
29032
+ }
29033
+ }
29034
+ }
29035
+ handleUser(message) {
29036
+ if (message.tool_use_result === undefined)
29037
+ return;
29038
+ const content = message.message.content;
29039
+ const blocks = Array.isArray(content) ? content : [content];
29040
+ for (const block of blocks) {
29041
+ if (typeof block === "string")
29042
+ continue;
29043
+ if (block.type === "tool_result") {
29044
+ const resultStr = typeof block.content === "string" ? block.content : JSON.stringify(block.content);
29045
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool_result", `tool result: ${resultStr}`));
29046
+ }
29047
+ }
29048
+ }
29049
+ emitAgentEnd() {
29050
+ if (this.agentEndEmitted)
29051
+ return;
29052
+ this.agentEndEmitted = true;
29053
+ this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
29054
+ for (const cb of this.agentEndCallbacks)
29055
+ cb();
29056
+ }
29057
+ appendText(delta) {
29058
+ this.flushThinking();
29059
+ this.textBuffer += delta;
29060
+ this.assistantTextCapture.captureAssistantText(delta);
29061
+ if (this.textBuffer.includes(`
29062
+ `))
29063
+ this.flushText();
29064
+ }
29065
+ appendThinking(delta) {
29066
+ this.flushText();
29067
+ this.thinkingBuffer += delta;
29068
+ if (this.thinkingBuffer.includes(`
29069
+ `))
29070
+ this.flushThinking();
29071
+ }
29072
+ flushText() {
29073
+ if (!this.textBuffer)
29074
+ return;
29075
+ const lines = this.textBuffer.split(`
29076
+ `);
29077
+ const remaining = this.textBuffer.endsWith(`
29078
+ `) ? "" : lines.pop() ?? "";
29079
+ for (const line of lines) {
29080
+ if (line.length > 0) {
29081
+ this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
29082
+ }
29083
+ }
29084
+ this.textBuffer = remaining;
29085
+ }
29086
+ flushThinking() {
29087
+ if (!this.thinkingBuffer)
29088
+ return;
29089
+ const lines = this.thinkingBuffer.split(`
29090
+ `);
29091
+ const remaining = this.thinkingBuffer.endsWith(`
29092
+ `) ? "" : lines.pop() ?? "";
29093
+ for (const line of lines) {
29094
+ if (line.length > 0) {
29095
+ this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", line));
29096
+ }
29097
+ }
29098
+ this.thinkingBuffer = remaining;
29099
+ }
29100
+ writeLine(line) {
29101
+ process.stderr.write(`${line}
29102
+ `);
29103
+ this.emitLogLine?.(line);
29104
+ }
29105
+ };
29106
+ });
29107
+
29108
+ // src/infrastructure/services/remote-agents/claude-sdk/claude-sdk-agent-service.ts
29109
+ async function loadSdk() {
29110
+ if (_sdkCache)
29111
+ return _sdkCache;
29112
+ if (_sdkLoadError)
29113
+ throw _sdkLoadError;
29114
+ try {
29115
+ _sdkCache = await importBundledClaudeSdk();
29116
+ return _sdkCache;
29117
+ } catch (err) {
29118
+ _sdkLoadError = err;
29119
+ throw err;
29120
+ }
29121
+ }
29122
+ function getSdkPackageVersion() {
29123
+ if (cachedSdkPackageVersion)
29124
+ return cachedSdkPackageVersion;
29125
+ cachedSdkPackageVersion = getBundledClaudeSdkVersion();
29126
+ return cachedSdkPackageVersion;
29127
+ }
29128
+ function waitForResumeOrAbort(session2) {
29129
+ if (session2.aborted)
29130
+ return Promise.resolve(null);
29131
+ const queued = session2.pendingResumePrompt;
29132
+ if (queued !== undefined) {
29133
+ session2.pendingResumePrompt = undefined;
29134
+ return Promise.resolve(queued);
29135
+ }
29136
+ return Promise.race([
29137
+ new Promise((resolve2) => {
29138
+ session2.resumeResolve = (prompt) => {
29139
+ session2.resumeResolve = undefined;
29140
+ session2.abortResolve = undefined;
29141
+ resolve2(prompt);
29142
+ };
29143
+ }),
29144
+ new Promise((resolve2) => {
29145
+ session2.abortResolve = () => {
29146
+ session2.resumeResolve = undefined;
29147
+ session2.abortResolve = undefined;
29148
+ resolve2(null);
29149
+ };
29150
+ })
29151
+ ]);
29152
+ }
29153
+ function writeSpawnError(logPrefix, err, emitLogLine) {
29154
+ const line = formatAgentLogLine(logPrefix, "spawn-error", formatClaudeSdkLoadError(err));
29155
+ process.stderr.write(`${line}
29156
+ `);
29157
+ emitLogLine?.(line);
29158
+ console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
29159
+ }
29160
+ function captureSessionId(message, session2) {
29161
+ if ("session_id" in message && typeof message.session_id === "string") {
29162
+ session2.sessionId = message.session_id;
29163
+ }
29164
+ }
29165
+ var CLAUDE_SDK_COMMAND = "claude-sdk", DEFAULT_MAX_TURNS2 = 200, TURN_TIMEOUT_MS = 3600000, _sdkCache, _sdkLoadError, cachedSdkPackageVersion, ClaudeSdkAgentService;
29166
+ var init_claude_sdk_agent_service = __esm(() => {
29167
+ init_esm();
29168
+ init_base_cli_agent_service();
29169
+ init_claude_models();
29170
+ init_detection_result();
29171
+ init_claude_sdk_package();
29172
+ init_claude_sdk_stream_adapter();
29173
+ ClaudeSdkAgentService = class ClaudeSdkAgentService extends BaseCLIAgentService {
29174
+ id = "claude-sdk";
29175
+ displayName = "Claude Code (SDK)";
29176
+ command = CLAUDE_SDK_COMMAND;
29177
+ sessions = new Map;
29178
+ constructor(deps) {
29179
+ super(deps);
29180
+ }
29181
+ async isInstalled() {
29182
+ try {
29183
+ await loadSdk();
29184
+ await resolvePathToClaudeCodeExecutable();
29185
+ return true;
29186
+ } catch (err) {
29187
+ console.warn(`[claude-sdk] unavailable: ${formatClaudeSdkLoadError(err)}`);
29188
+ return false;
29189
+ }
29190
+ }
29191
+ detectInstallationEffect() {
29192
+ return exports_Effect.promise(async () => {
29193
+ const installed = await this.isInstalled();
29194
+ return installed ? DetectionResult.Installed() : DetectionResult.NotInstalled();
29195
+ });
29196
+ }
29197
+ async getVersion() {
29198
+ const match17 = getSdkPackageVersion().match(/^(\d+)\.(\d+)\.(\d+)/);
29199
+ if (!match17)
29200
+ return null;
29201
+ return {
29202
+ version: `${match17[1]}.${match17[2]}.${match17[3]}`,
29203
+ major: parseInt(match17[1], 10)
29204
+ };
29205
+ }
29206
+ async listModels() {
29207
+ const dynamic = await fetchClaudeModels();
29208
+ if (dynamic)
29209
+ return dynamic;
29210
+ return [...CLAUDE_FALLBACK_MODELS];
29211
+ }
29212
+ async resumeTurn(pid, prompt) {
29213
+ const session2 = this.sessions.get(pid);
29214
+ if (!session2) {
29215
+ throw new Error(`No claude-sdk session for pid=${pid}`);
29216
+ }
29217
+ if (session2.resumeResolve) {
29218
+ const resolve2 = session2.resumeResolve;
29219
+ session2.resumeResolve = undefined;
29220
+ session2.abortResolve = undefined;
29221
+ resolve2(prompt);
29222
+ return;
29223
+ }
29224
+ session2.pendingResumePrompt = prompt;
29225
+ }
29226
+ async stop(pid, _options) {
29227
+ const session2 = this.sessions.get(pid);
29228
+ if (session2) {
29229
+ session2.aborted = true;
29230
+ session2.abortResolve?.();
29231
+ try {
29232
+ await withTimeout(session2.activeQuery?.interrupt() ?? Promise.resolve(), 5000, "interrupt");
29233
+ } catch (err) {
29234
+ console.warn(`[claude-sdk] interrupt for pid=${pid} failed:`, err instanceof Error ? err.message : err);
29235
+ }
29236
+ try {
29237
+ session2.keeper.kill();
29238
+ } catch {}
29239
+ this.sessions.delete(pid);
29240
+ }
29241
+ await super.stop(pid);
29242
+ }
29243
+ spawnKeeper(workingDir) {
29244
+ const keeper = this.deps.spawn(process.execPath, ["-e", "setInterval(()=>{},2147483647)"], {
29245
+ cwd: workingDir,
29246
+ stdio: "ignore",
29247
+ shell: false,
29248
+ detached: true
29249
+ });
29250
+ if (!keeper.pid) {
29251
+ keeper.kill();
29252
+ throw new Error("Failed to spawn claude-sdk keeper process");
29253
+ }
29254
+ return keeper;
29255
+ }
29256
+ startRunningSession(args2) {
29257
+ const {
29258
+ pid,
29259
+ keeper,
29260
+ context: context5,
29261
+ workingDir,
29262
+ model,
29263
+ initialPrompt,
29264
+ deferInitialTurn = false,
29265
+ storedSystemPrompt,
29266
+ executablePath
29267
+ } = args2;
29268
+ const entry = this.registerProcess(pid, context5);
29269
+ const logPrefix = buildAgentLogPrefix("claude-sdk", context5);
29270
+ const sdkSession = {
29271
+ keeper,
29272
+ aborted: false,
29273
+ storedSystemPrompt
29274
+ };
29275
+ this.sessions.set(pid, sdkSession);
29276
+ const exitCallbacks = [];
29277
+ const outputCallbacks = [];
29278
+ const agentEndCallbacks = [];
29279
+ const logLineCallbacks = [];
29280
+ const assistantTextCallbacks = [];
29281
+ const emitLogLine = (line) => {
29282
+ for (const cb of logLineCallbacks)
29283
+ cb(line);
29284
+ };
29285
+ const finishExit = (code2, signal) => {
29286
+ sdkSession.activeQuery = undefined;
29287
+ this.sessions.delete(pid);
29288
+ this.deleteProcess(pid);
29289
+ for (const cb of exitCallbacks) {
29290
+ cb({ code: code2, signal, context: context5 });
29291
+ }
29292
+ };
29293
+ this.runTurnLoop({
29294
+ sdkSession,
29295
+ entry,
29296
+ logPrefix,
29297
+ workingDir,
29298
+ model,
29299
+ executablePath,
29300
+ initialPrompt,
29301
+ deferInitialTurn,
29302
+ finishExit,
29303
+ outputCallbacks,
29304
+ agentEndCallbacks,
29305
+ assistantTextCallbacks,
29306
+ emitLogLine
29307
+ });
29308
+ return {
29309
+ pid,
29310
+ harnessSessionId: undefined,
29311
+ onExit: (cb) => {
29312
+ exitCallbacks.push(cb);
29313
+ },
29314
+ onOutput: (cb) => {
29315
+ outputCallbacks.push(cb);
29316
+ },
29317
+ onAgentEnd: (cb) => {
29318
+ agentEndCallbacks.push(cb);
29319
+ },
29320
+ onLogLine: (cb) => {
29321
+ logLineCallbacks.push(cb);
29322
+ },
29323
+ onAssistantText: (cb) => {
29324
+ assistantTextCallbacks.push(cb);
29325
+ }
29326
+ };
29327
+ }
29328
+ runTurnLoop(args2) {
29329
+ const {
29330
+ sdkSession,
29331
+ logPrefix,
29332
+ workingDir,
29333
+ model,
29334
+ executablePath,
29335
+ initialPrompt,
29336
+ deferInitialTurn = false,
29337
+ finishExit,
29338
+ entry,
29339
+ outputCallbacks,
29340
+ agentEndCallbacks,
29341
+ assistantTextCallbacks,
29342
+ emitLogLine
29343
+ } = args2;
29344
+ let exited = false;
29345
+ this.executeTurnLoop({
29346
+ sdkSession,
29347
+ logPrefix,
29348
+ workingDir,
29349
+ model,
29350
+ executablePath,
29351
+ initialPrompt,
29352
+ deferInitialTurn,
29353
+ finishExit,
29354
+ entry,
29355
+ outputCallbacks,
29356
+ agentEndCallbacks,
29357
+ assistantTextCallbacks,
29358
+ emitLogLine,
29359
+ isExited: () => exited,
29360
+ markExited: () => {
29361
+ exited = true;
29362
+ }
29363
+ }).catch((err) => {
29364
+ writeSpawnError(logPrefix, err, emitLogLine);
29365
+ if (exited)
29366
+ return;
29367
+ exited = true;
29368
+ try {
29369
+ sdkSession.keeper.kill();
29370
+ } catch {}
29371
+ finishExit(1, null);
29372
+ });
29373
+ }
29374
+ async executeTurnLoop(args2) {
29375
+ const {
29376
+ sdkSession,
29377
+ logPrefix,
29378
+ workingDir,
29379
+ model,
29380
+ executablePath,
29381
+ initialPrompt,
29382
+ deferInitialTurn,
29383
+ finishExit,
29384
+ entry,
29385
+ outputCallbacks,
29386
+ agentEndCallbacks,
29387
+ assistantTextCallbacks,
29388
+ emitLogLine,
29389
+ isExited,
29390
+ markExited
29391
+ } = args2;
29392
+ let exitCode = 0;
29393
+ let exitSignal = null;
29394
+ let nextPrompt = deferInitialTurn ? null : initialPrompt;
29395
+ let isFirstQuery = true;
29396
+ try {
29397
+ const { query } = await loadSdk();
29398
+ while (!sdkSession.aborted) {
29399
+ try {
29400
+ if (nextPrompt === null) {
29401
+ const deferredResume = await waitForResumeOrAbort(sdkSession);
29402
+ if (deferredResume === null || sdkSession.aborted) {
29403
+ if (sdkSession.aborted) {
29404
+ exitCode = 1;
29405
+ exitSignal = "SIGTERM";
29406
+ }
29407
+ break;
29408
+ }
29409
+ nextPrompt = deferredResume;
29410
+ }
29411
+ const adapter = new ClaudeSdkStreamAdapter(logPrefix, emitLogLine);
29412
+ wireNativeStreamAdapter({
29413
+ adapter,
29414
+ assistantTextCallbacks,
29415
+ outputCallbacks,
29416
+ agentEndCallbacks,
29417
+ entry
29418
+ });
29419
+ const queryInstance = query({
29420
+ prompt: nextPrompt,
29421
+ options: {
29422
+ cwd: workingDir,
29423
+ model,
29424
+ maxTurns: DEFAULT_MAX_TURNS2,
29425
+ pathToClaudeCodeExecutable: executablePath,
29426
+ includePartialMessages: true,
29427
+ systemPrompt: isFirstQuery ? sdkSession.storedSystemPrompt : undefined,
29428
+ resume: !isFirstQuery ? sdkSession.sessionId : undefined,
29429
+ settingSources: []
29430
+ }
29431
+ });
29432
+ sdkSession.activeQuery = queryInstance;
29433
+ isFirstQuery = false;
29434
+ nextPrompt = null;
29435
+ await withTimeout((async () => {
29436
+ for await (const message of queryInstance) {
29437
+ if (sdkSession.aborted)
29438
+ break;
29439
+ captureSessionId(message, sdkSession);
29440
+ adapter.handleMessage(message);
29441
+ if (message.type === "result")
29442
+ break;
29443
+ }
29444
+ })(), TURN_TIMEOUT_MS, "query");
29445
+ sdkSession.activeQuery = undefined;
29446
+ if (sdkSession.aborted) {
29447
+ exitCode = 1;
29448
+ exitSignal = "SIGTERM";
29449
+ break;
29450
+ }
29451
+ adapter.finish();
29452
+ } catch (turnErr) {
29453
+ exitCode = 1;
29454
+ writeSpawnError(logPrefix, turnErr, emitLogLine);
29455
+ break;
29456
+ }
29457
+ }
29458
+ } catch (err) {
29459
+ exitCode = 1;
29460
+ writeSpawnError(logPrefix, err, emitLogLine);
29461
+ } finally {
29462
+ if (isExited())
29463
+ return;
29464
+ markExited();
29465
+ try {
29466
+ sdkSession.keeper.kill();
29467
+ } catch {}
29468
+ finishExit(exitCode, exitSignal);
29469
+ }
29470
+ }
29471
+ async spawn(options) {
29472
+ const deferInitialTurn = options.deferInitialTurn ?? false;
29473
+ const keeper = this.spawnKeeper(options.workingDir);
29474
+ const pid = keeper.pid;
29475
+ const context5 = options.context;
29476
+ const fullPrompt = deferInitialTurn ? "" : options.prompt;
29477
+ let executablePath;
29478
+ try {
29479
+ await loadSdk();
29480
+ executablePath = await resolvePathToClaudeCodeExecutable();
29481
+ } catch (err) {
29482
+ keeper.kill();
29483
+ this.deleteProcess(pid);
29484
+ throw err;
29485
+ }
29486
+ return this.startRunningSession({
29487
+ pid,
29488
+ keeper,
29489
+ context: context5,
29490
+ workingDir: options.workingDir,
29491
+ model: options.model,
29492
+ initialPrompt: fullPrompt,
29493
+ deferInitialTurn,
29494
+ storedSystemPrompt: options.systemPrompt,
29495
+ executablePath
29496
+ });
29497
+ }
29498
+ };
29499
+ });
29500
+
29501
+ // src/infrastructure/services/remote-agents/claude-sdk/index.ts
29502
+ var init_claude_sdk = __esm(() => {
29503
+ init_claude_sdk_agent_service();
29504
+ });
29505
+
28765
29506
  // src/infrastructure/services/remote-agents/commandcode/command-code-stream-reader.ts
28766
29507
  import { createInterface as createInterface3 } from "node:readline";
28767
29508
 
@@ -28989,68 +29730,68 @@ __export(exports_cursor_sdk_package, {
28989
29730
  getBundledCursorSdkVersion: () => getBundledCursorSdkVersion,
28990
29731
  formatCursorSdkLoadError: () => formatCursorSdkLoadError
28991
29732
  });
28992
- import { existsSync, readFileSync as readFileSync3 } from "node:fs";
28993
- import { createRequire as createRequire3 } from "node:module";
28994
- import { dirname as dirname2, join as join7 } from "node:path";
28995
- import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
28996
- function resolveChatroomCliRoot(moduleRef = import.meta.url) {
28997
- const filePath = moduleRef.startsWith("file:") ? fileURLToPath2(moduleRef) : moduleRef;
28998
- let dir = dirname2(filePath);
28999
- while (dir !== dirname2(dir)) {
29000
- const packageJsonPath = join7(dir, "package.json");
29001
- if (existsSync(packageJsonPath)) {
29002
- const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
29733
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
29734
+ import { createRequire as createRequire4 } from "node:module";
29735
+ import { dirname as dirname3, join as join8 } from "node:path";
29736
+ import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
29737
+ function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
29738
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
29739
+ let dir = dirname3(filePath);
29740
+ while (dir !== dirname3(dir)) {
29741
+ const packageJsonPath = join8(dir, "package.json");
29742
+ if (existsSync2(packageJsonPath)) {
29743
+ const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
29003
29744
  if (pkg.name === "chatroom-cli") {
29004
29745
  return dir;
29005
29746
  }
29006
29747
  }
29007
- dir = dirname2(dir);
29748
+ dir = dirname3(dir);
29008
29749
  }
29009
- throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT}`);
29750
+ throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT2}`);
29010
29751
  }
29011
- function readPinnedSdkVersion(chatroomCliRoot) {
29012
- const pkg = JSON.parse(readFileSync3(join7(chatroomCliRoot, "package.json"), "utf8"));
29752
+ function readPinnedSdkVersion2(chatroomCliRoot) {
29753
+ const pkg = JSON.parse(readFileSync4(join8(chatroomCliRoot, "package.json"), "utf8"));
29013
29754
  const specifier = pkg.dependencies?.["@cursor/sdk"];
29014
29755
  const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
29015
29756
  const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
29016
29757
  if (!match17) {
29017
- throw new CursorSdkPackageError(`chatroom-cli must pin an exact @cursor/sdk version (found "${specifier ?? "none"}"). ${REINSTALL_HINT}`);
29758
+ throw new CursorSdkPackageError(`chatroom-cli must pin an exact @cursor/sdk version (found "${specifier ?? "none"}"). ${REINSTALL_HINT2}`);
29018
29759
  }
29019
29760
  return match17[1];
29020
29761
  }
29021
- function readInstalledSdkVersion(entryPath) {
29022
- const packageJsonPath = join7(dirname2(entryPath), "..", "..", "package.json");
29023
- const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
29762
+ function readInstalledSdkVersion2(entryPath) {
29763
+ const packageJsonPath = join8(dirname3(entryPath), "..", "..", "package.json");
29764
+ const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
29024
29765
  return pkg.version;
29025
29766
  }
29026
29767
  function resolveSdkEsmImportPath(cjsEntryPath) {
29027
29768
  const importPath = cjsEntryPath.includes("/dist/cjs/") ? cjsEntryPath.replace("/dist/cjs/", "/dist/esm/") : cjsEntryPath;
29028
- if (!existsSync(importPath)) {
29029
- throw new CursorSdkPackageError(`@cursor/sdk ESM entry file is missing: ${importPath}. ${REINSTALL_HINT}`);
29769
+ if (!existsSync2(importPath)) {
29770
+ throw new CursorSdkPackageError(`@cursor/sdk ESM entry file is missing: ${importPath}. ${REINSTALL_HINT2}`);
29030
29771
  }
29031
29772
  return importPath;
29032
29773
  }
29033
29774
  async function importBundledCursorSdk(moduleRef = import.meta.url) {
29034
- const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
29035
- const require3 = createRequire3(join7(chatroomCliRoot, "package.json"));
29036
- const pinnedVersion = readPinnedSdkVersion(chatroomCliRoot);
29775
+ const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
29776
+ const require3 = createRequire4(join8(chatroomCliRoot, "package.json"));
29777
+ const pinnedVersion = readPinnedSdkVersion2(chatroomCliRoot);
29037
29778
  const entryPath = require3.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
29038
- const installedVersion = readInstalledSdkVersion(entryPath);
29779
+ const installedVersion = readInstalledSdkVersion2(entryPath);
29039
29780
  if (installedVersion !== pinnedVersion) {
29040
- throw new CursorSdkPackageError(`@cursor/sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT}`);
29781
+ throw new CursorSdkPackageError(`@cursor/sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT2}`);
29041
29782
  }
29042
- if (!existsSync(entryPath)) {
29043
- throw new CursorSdkPackageError(`@cursor/sdk entry file is missing: ${entryPath}. ${REINSTALL_HINT}`);
29783
+ if (!existsSync2(entryPath)) {
29784
+ throw new CursorSdkPackageError(`@cursor/sdk entry file is missing: ${entryPath}. ${REINSTALL_HINT2}`);
29044
29785
  }
29045
- const sdk = await import(pathToFileURL(resolveSdkEsmImportPath(entryPath)).href);
29786
+ const sdk = await import(pathToFileURL2(resolveSdkEsmImportPath(entryPath)).href);
29046
29787
  sdk.configureCursorSdk({ local: { useHttp1ForAgent: true } });
29047
29788
  return sdk;
29048
29789
  }
29049
29790
  function getBundledCursorSdkVersion(moduleRef = import.meta.url) {
29050
- const chatroomCliRoot = resolveChatroomCliRoot(moduleRef);
29051
- const require3 = createRequire3(join7(chatroomCliRoot, "package.json"));
29791
+ const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
29792
+ const require3 = createRequire4(join8(chatroomCliRoot, "package.json"));
29052
29793
  const entryPath = require3.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
29053
- return readInstalledSdkVersion(entryPath);
29794
+ return readInstalledSdkVersion2(entryPath);
29054
29795
  }
29055
29796
  function formatCursorSdkLoadError(err) {
29056
29797
  if (err instanceof CursorSdkPackageError) {
@@ -29059,11 +29800,11 @@ function formatCursorSdkLoadError(err) {
29059
29800
  const message = err instanceof Error ? err.message : String(err);
29060
29801
  const chunkMatch = message.match(/(\d+)\.index\.js/);
29061
29802
  if (chunkMatch) {
29062
- return `@cursor/sdk installation is incomplete (missing ${chunkMatch[1]}.index.js). ${REINSTALL_HINT}`;
29803
+ return `@cursor/sdk installation is incomplete (missing ${chunkMatch[1]}.index.js). ${REINSTALL_HINT2}`;
29063
29804
  }
29064
29805
  return message;
29065
29806
  }
29066
- var REINSTALL_HINT = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", CursorSdkPackageError;
29807
+ var REINSTALL_HINT2 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", CursorSdkPackageError;
29067
29808
  var init_cursor_sdk_package = __esm(() => {
29068
29809
  CursorSdkPackageError = class CursorSdkPackageError extends Error {
29069
29810
  code = "CURSOR_SDK_PACKAGE_INCOMPLETE";
@@ -29087,144 +29828,113 @@ function closeCursorAgentOnFailure(agent, session2, exitCode, force = false) {
29087
29828
  }
29088
29829
 
29089
29830
  // src/infrastructure/services/remote-agents/cursor-sdk/cursor-sdk-stream-adapter.ts
29090
- class CursorSdkStreamAdapter {
29091
- logPrefix;
29092
- emitLogLine;
29093
- agentEndCallbacks = [];
29094
- outputCallbacks = [];
29095
- agentEndEmitted = false;
29096
- textBuffer = "";
29097
- constructor(logPrefix, emitLogLine) {
29098
- this.logPrefix = logPrefix;
29099
- this.emitLogLine = emitLogLine;
29100
- }
29101
- onAgentEnd(cb) {
29102
- this.agentEndCallbacks.push(cb);
29103
- }
29104
- onOutput(cb) {
29105
- this.outputCallbacks.push(cb);
29106
- }
29107
- handleMessage(message) {
29108
- this.notifyOutput();
29109
- switch (message.type) {
29110
- case "assistant":
29111
- this.handleAssistant(message);
29112
- break;
29113
- case "tool_call": {
29114
- this.flushText();
29115
- const bashCmd = extractBashCommandFromToolInput(message.name, message.args);
29116
- if (bashCmd !== null) {
29117
- this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(bashCmd)));
29831
+ var CursorSdkStreamAdapter;
29832
+ var init_cursor_sdk_stream_adapter = __esm(() => {
29833
+ init_native_stream_adapter_base();
29834
+ CursorSdkStreamAdapter = class CursorSdkStreamAdapter extends NativeStreamAdapterBase {
29835
+ textBuffer = "";
29836
+ handleMessage(message) {
29837
+ this.notifyOutput();
29838
+ switch (message.type) {
29839
+ case "assistant":
29840
+ this.handleAssistant(message);
29841
+ break;
29842
+ case "tool_call": {
29843
+ this.flushText();
29844
+ const bashCmd = extractBashCommandFromToolInput(message.name, message.args);
29845
+ if (bashCmd !== null) {
29846
+ this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(bashCmd)));
29847
+ break;
29848
+ }
29849
+ this.writeLine(formatAgentLogLine(this.logPrefix, `tool: ${message.call_id} ${message.name} ${JSON.stringify({ status: message.status, args: message.args })}`));
29118
29850
  break;
29119
29851
  }
29120
- this.writeLine(formatAgentLogLine(this.logPrefix, `tool: ${message.call_id} ${message.name} ${JSON.stringify({ status: message.status, args: message.args })}`));
29121
- break;
29852
+ case "status":
29853
+ this.writeLine(formatAgentLogLine(this.logPrefix, `status: ${message.status}`));
29854
+ break;
29855
+ case "thinking":
29856
+ this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", message.text));
29857
+ break;
29858
+ case "system":
29859
+ if (message.subtype === "init") {
29860
+ this.writeLine(formatAgentLogLine(this.logPrefix, "system: init"));
29861
+ }
29862
+ break;
29863
+ default:
29864
+ break;
29122
29865
  }
29123
- case "status":
29124
- this.writeLine(formatAgentLogLine(this.logPrefix, `status: ${message.status}`));
29125
- break;
29126
- case "thinking":
29127
- this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", message.text));
29128
- break;
29129
- case "system":
29130
- if (message.subtype === "init") {
29131
- this.writeLine(formatAgentLogLine(this.logPrefix, "system: init"));
29132
- }
29133
- break;
29134
- default:
29135
- break;
29136
29866
  }
29137
- }
29138
- flushPendingOutput() {
29139
- this.flushText();
29140
- }
29141
- finish() {
29142
- this.flushText();
29143
- this.emitAgentEnd();
29144
- }
29145
- handleAssistant(message) {
29146
- for (const block of message.message.content) {
29147
- if (block.type === "text") {
29148
- this.textBuffer += block.text;
29149
- if (this.textBuffer.includes(`
29867
+ flushPendingOutput() {
29868
+ this.flushText();
29869
+ }
29870
+ finish() {
29871
+ this.flushText();
29872
+ this.emitAgentEnd();
29873
+ }
29874
+ handleAssistant(message) {
29875
+ for (const block of message.message.content) {
29876
+ if (block.type === "text") {
29877
+ this.textBuffer += block.text;
29878
+ this.assistantTextCapture.captureAssistantText(block.text);
29879
+ if (this.textBuffer.includes(`
29150
29880
  `)) {
29151
- this.flushText();
29881
+ this.flushText();
29882
+ }
29152
29883
  }
29153
29884
  }
29154
29885
  }
29155
- }
29156
- flushText() {
29157
- if (!this.textBuffer)
29158
- return;
29159
- for (const line of this.textBuffer.split(`
29886
+ flushText() {
29887
+ if (!this.textBuffer)
29888
+ return;
29889
+ for (const line of this.textBuffer.split(`
29160
29890
  `)) {
29161
- if (line)
29162
- this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
29891
+ if (line)
29892
+ this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
29893
+ }
29894
+ this.textBuffer = "";
29163
29895
  }
29164
- this.textBuffer = "";
29165
- }
29166
- emitAgentEnd() {
29167
- if (this.agentEndEmitted)
29168
- return;
29169
- this.agentEndEmitted = true;
29170
- this.flushText();
29171
- this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
29172
- for (const cb of this.agentEndCallbacks)
29173
- cb();
29174
- }
29175
- writeLine(formatted) {
29176
- process.stdout.write(`${formatted}
29896
+ emitAgentEnd() {
29897
+ if (this.agentEndEmitted)
29898
+ return;
29899
+ this.agentEndEmitted = true;
29900
+ this.flushText();
29901
+ this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
29902
+ for (const cb of this.agentEndCallbacks)
29903
+ cb();
29904
+ }
29905
+ writeLine(formatted) {
29906
+ process.stdout.write(`${formatted}
29177
29907
  `);
29178
- this.emitLogLine?.(formatted);
29179
- }
29180
- notifyOutput() {
29181
- for (const cb of this.outputCallbacks)
29182
- cb();
29183
- }
29184
- }
29185
- var init_cursor_sdk_stream_adapter = () => {};
29186
-
29187
- // src/infrastructure/services/remote-agents/with-timeout.ts
29188
- async function withTimeout(p, ms, label) {
29189
- let timer;
29190
- try {
29191
- return await Promise.race([
29192
- p,
29193
- new Promise((_, reject) => {
29194
- timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
29195
- })
29196
- ]);
29197
- } finally {
29198
- if (timer)
29199
- clearTimeout(timer);
29200
- }
29201
- }
29908
+ this.emitLogLine?.(formatted);
29909
+ }
29910
+ };
29911
+ });
29202
29912
 
29203
29913
  // src/infrastructure/services/remote-agents/cursor-sdk/cursor-sdk-agent-service.ts
29204
29914
  import { randomUUID } from "node:crypto";
29205
- async function loadSdk() {
29206
- if (_sdkCache)
29207
- return _sdkCache;
29208
- if (_sdkLoadError)
29209
- throw _sdkLoadError;
29915
+ async function loadSdk2() {
29916
+ if (_sdkCache2)
29917
+ return _sdkCache2;
29918
+ if (_sdkLoadError2)
29919
+ throw _sdkLoadError2;
29210
29920
  try {
29211
- _sdkCache = await importBundledCursorSdk();
29212
- return _sdkCache;
29921
+ _sdkCache2 = await importBundledCursorSdk();
29922
+ return _sdkCache2;
29213
29923
  } catch (err) {
29214
- _sdkLoadError = err;
29924
+ _sdkLoadError2 = err;
29215
29925
  throw err;
29216
29926
  }
29217
29927
  }
29218
- function getSdkPackageVersion() {
29219
- if (cachedSdkPackageVersion)
29220
- return cachedSdkPackageVersion;
29221
- cachedSdkPackageVersion = getBundledCursorSdkVersion();
29222
- return cachedSdkPackageVersion;
29928
+ function getSdkPackageVersion2() {
29929
+ if (cachedSdkPackageVersion2)
29930
+ return cachedSdkPackageVersion2;
29931
+ cachedSdkPackageVersion2 = getBundledCursorSdkVersion();
29932
+ return cachedSdkPackageVersion2;
29223
29933
  }
29224
29934
  function buildAgentName(context5) {
29225
29935
  return `${context5.role}@${context5.chatroomId.slice(-6)}`;
29226
29936
  }
29227
- function waitForResumeOrAbort(session2) {
29937
+ function waitForResumeOrAbort2(session2) {
29228
29938
  if (session2.aborted)
29229
29939
  return Promise.resolve(null);
29230
29940
  const queued = session2.pendingResumePrompt;
@@ -29252,14 +29962,14 @@ function waitForResumeOrAbort(session2) {
29252
29962
  function resolveModelId(model) {
29253
29963
  return model ? resolveCursorSdkModel(model) : DEFAULT_MODEL;
29254
29964
  }
29255
- function writeSpawnError(logPrefix, err, emitLogLine) {
29965
+ function writeSpawnError2(logPrefix, err, emitLogLine) {
29256
29966
  const line = formatAgentLogLine(logPrefix, "spawn-error", formatCursorSdkLoadError(err));
29257
29967
  process.stderr.write(`${line}
29258
29968
  `);
29259
29969
  emitLogLine?.(line);
29260
29970
  console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
29261
29971
  }
29262
- var NO_SUBAGENT_DIRECTIVE2 = "NEVER spawn subagents. Follow the chatroom instructions strictly.", _sdkCache, _sdkLoadError, CURSOR_SDK_COMMAND = "cursor-sdk", DEFAULT_MODEL = "composer-2.5", AGENT_CREATE_TIMEOUT_MS = 60000, SEND_TIMEOUT_MS = 60000, RUN_WAIT_TIMEOUT_MS = 3600000, MODELS_LIST_TIMEOUT_MS = 60000, RUN_CANCEL_TIMEOUT_MS = 5000, cachedSdkPackageVersion, CursorSdkAgentService;
29972
+ var NO_SUBAGENT_DIRECTIVE2 = "NEVER spawn subagents. Follow the chatroom instructions strictly.", _sdkCache2, _sdkLoadError2, CURSOR_SDK_COMMAND = "cursor-sdk", DEFAULT_MODEL = "composer-2.5", AGENT_CREATE_TIMEOUT_MS = 60000, SEND_TIMEOUT_MS = 60000, RUN_WAIT_TIMEOUT_MS = 3600000, MODELS_LIST_TIMEOUT_MS = 60000, RUN_CANCEL_TIMEOUT_MS = 5000, cachedSdkPackageVersion2, CursorSdkAgentService;
29263
29973
  var init_cursor_sdk_agent_service = __esm(() => {
29264
29974
  init_esm();
29265
29975
  init_base_cli_agent_service();
@@ -29278,7 +29988,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
29278
29988
  if (!process.env.CURSOR_API_KEY?.trim())
29279
29989
  return false;
29280
29990
  try {
29281
- await loadSdk();
29991
+ await loadSdk2();
29282
29992
  return true;
29283
29993
  } catch (err) {
29284
29994
  console.warn(`[cursor-sdk] unavailable: ${formatCursorSdkLoadError(err)}`);
@@ -29292,7 +30002,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
29292
30002
  });
29293
30003
  }
29294
30004
  async getVersion() {
29295
- const match17 = getSdkPackageVersion().match(/^(\d+)\.(\d+)\.(\d+)/);
30005
+ const match17 = getSdkPackageVersion2().match(/^(\d+)\.(\d+)\.(\d+)/);
29296
30006
  if (!match17)
29297
30007
  return null;
29298
30008
  return {
@@ -29305,7 +30015,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
29305
30015
  if (!apiKey)
29306
30016
  return [];
29307
30017
  try {
29308
- const { Cursor } = await loadSdk();
30018
+ const { Cursor } = await loadSdk2();
29309
30019
  const models = await withTimeout(Cursor.models.list({ apiKey }), MODELS_LIST_TIMEOUT_MS, "Cursor.models.list");
29310
30020
  const listedModelIds = models.map((m) => m.id).filter((id3) => id3.length > 0);
29311
30021
  return normalizeCursorSdkListedModels(listedModelIds);
@@ -29382,7 +30092,7 @@ ${options.systemPrompt}` : NO_SUBAGENT_DIRECTIVE2;
29382
30092
  ${options.prompt}`;
29383
30093
  let agent;
29384
30094
  try {
29385
- const { Agent } = await loadSdk();
30095
+ const { Agent } = await loadSdk2();
29386
30096
  agent = await withTimeout(Agent.resume(stored.harnessSessionId, {
29387
30097
  apiKey,
29388
30098
  model: { id: modelId },
@@ -29453,6 +30163,7 @@ ${options.prompt}`;
29453
30163
  const outputCallbacks = [];
29454
30164
  const agentEndCallbacks = [];
29455
30165
  const logLineCallbacks = [];
30166
+ const assistantTextCallbacks = [];
29456
30167
  const emitLogLine = (line) => {
29457
30168
  for (const cb of logLineCallbacks)
29458
30169
  cb(line);
@@ -29477,6 +30188,7 @@ ${options.prompt}`;
29477
30188
  finishExit,
29478
30189
  outputCallbacks,
29479
30190
  agentEndCallbacks,
30191
+ assistantTextCallbacks,
29480
30192
  emitLogLine
29481
30193
  });
29482
30194
  return {
@@ -29497,6 +30209,9 @@ ${options.prompt}`;
29497
30209
  },
29498
30210
  onLogLine: (cb) => {
29499
30211
  logLineCallbacks.push(cb);
30212
+ },
30213
+ onAssistantText: (cb) => {
30214
+ assistantTextCallbacks.push(cb);
29500
30215
  }
29501
30216
  };
29502
30217
  }
@@ -29512,6 +30227,7 @@ ${options.prompt}`;
29512
30227
  entry,
29513
30228
  outputCallbacks,
29514
30229
  agentEndCallbacks,
30230
+ assistantTextCallbacks,
29515
30231
  emitLogLine
29516
30232
  } = args2;
29517
30233
  let exited = false;
@@ -29526,7 +30242,7 @@ ${options.prompt}`;
29526
30242
  while (!session2.aborted) {
29527
30243
  try {
29528
30244
  if (nextPrompt === null) {
29529
- const deferredResume = await waitForResumeOrAbort(session2);
30245
+ const deferredResume = await waitForResumeOrAbort2(session2);
29530
30246
  if (deferredResume === null || session2.aborted) {
29531
30247
  if (session2.aborted) {
29532
30248
  exitCode = 1;
@@ -29549,14 +30265,12 @@ ${deferredResume}` : deferredResume;
29549
30265
  session2.run = run3;
29550
30266
  isFirstTurn = false;
29551
30267
  const adapter = new CursorSdkStreamAdapter(logPrefix, emitLogLine);
29552
- adapter.onOutput(() => {
29553
- entry.lastOutputAt = Date.now();
29554
- for (const cb of outputCallbacks)
29555
- cb();
29556
- });
29557
- adapter.onAgentEnd(() => {
29558
- for (const cb of agentEndCallbacks)
29559
- cb();
30268
+ wireNativeStreamAdapter({
30269
+ adapter,
30270
+ assistantTextCallbacks,
30271
+ outputCallbacks,
30272
+ agentEndCallbacks,
30273
+ entry
29560
30274
  });
29561
30275
  try {
29562
30276
  for await (const message of run3.stream()) {
@@ -29566,7 +30280,7 @@ ${deferredResume}` : deferredResume;
29566
30280
  }
29567
30281
  } catch (streamErr) {
29568
30282
  exitCode = 1;
29569
- writeSpawnError(logPrefix, streamErr, emitLogLine);
30283
+ writeSpawnError2(logPrefix, streamErr, emitLogLine);
29570
30284
  break;
29571
30285
  }
29572
30286
  if (session2.aborted) {
@@ -29579,7 +30293,7 @@ ${deferredResume}` : deferredResume;
29579
30293
  result = await withTimeout(run3.wait(), RUN_WAIT_TIMEOUT_MS, "run.wait");
29580
30294
  } catch (waitErr) {
29581
30295
  exitCode = 1;
29582
- writeSpawnError(logPrefix, waitErr, emitLogLine);
30296
+ writeSpawnError2(logPrefix, waitErr, emitLogLine);
29583
30297
  break;
29584
30298
  }
29585
30299
  adapter.flushPendingOutput();
@@ -29596,13 +30310,13 @@ ${deferredResume}` : deferredResume;
29596
30310
  nextPrompt = null;
29597
30311
  } catch (turnErr) {
29598
30312
  exitCode = 1;
29599
- writeSpawnError(logPrefix, turnErr, emitLogLine);
30313
+ writeSpawnError2(logPrefix, turnErr, emitLogLine);
29600
30314
  break;
29601
30315
  }
29602
30316
  }
29603
30317
  } catch (err) {
29604
30318
  exitCode = 1;
29605
- writeSpawnError(logPrefix, err, emitLogLine);
30319
+ writeSpawnError2(logPrefix, err, emitLogLine);
29606
30320
  } finally {
29607
30321
  if (exited)
29608
30322
  return;
@@ -29614,7 +30328,7 @@ ${deferredResume}` : deferredResume;
29614
30328
  finishExit(exitCode, exitSignal);
29615
30329
  }
29616
30330
  })().catch((err) => {
29617
- writeSpawnError(logPrefix, err, emitLogLine);
30331
+ writeSpawnError2(logPrefix, err, emitLogLine);
29618
30332
  if (exited)
29619
30333
  return;
29620
30334
  exited = true;
@@ -29644,7 +30358,7 @@ ${options.systemPrompt}` : NO_SUBAGENT_DIRECTIVE2;
29644
30358
  ${options.prompt}`;
29645
30359
  let agent;
29646
30360
  try {
29647
- const { Agent } = await loadSdk();
30361
+ const { Agent } = await loadSdk2();
29648
30362
  agent = await withTimeout(Agent.create({
29649
30363
  apiKey,
29650
30364
  name: agentName,
@@ -31920,8 +32634,10 @@ function startSessionEventForwarder(client4, options) {
31920
32634
  }
31921
32635
  async function handleTextPartUpdate(props, part) {
31922
32636
  const chunk2 = resolvePartContent(props?.delta, part.text);
31923
- if (chunk2)
32637
+ if (chunk2) {
32638
+ options.onAssistantText?.(chunk2);
31924
32639
  logLine(target, "text", chunk2);
32640
+ }
31925
32641
  }
31926
32642
  async function handleReasoningPartUpdate(props, part) {
31927
32643
  const chunk2 = resolvePartContent(props?.delta, part.text);
@@ -32088,27 +32804,27 @@ var init_session_event_forwarder = __esm(() => {
32088
32804
  });
32089
32805
 
32090
32806
  // src/infrastructure/services/remote-agents/opencode-sdk/session-metadata-store.ts
32091
- import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "node:fs";
32807
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync5, writeFileSync } from "node:fs";
32092
32808
  import { homedir as homedir2 } from "node:os";
32093
- import { dirname as dirname3, join as join8 } from "node:path";
32809
+ import { dirname as dirname4, join as join9 } from "node:path";
32094
32810
 
32095
32811
  class FileSessionMetadataStore {
32096
32812
  filePath;
32097
32813
  constructor(filePath) {
32098
- this.filePath = filePath ?? join8(homedir2(), ".chatroom", "opencode-sdk-sessions.json");
32814
+ this.filePath = filePath ?? join9(homedir2(), ".chatroom", "opencode-sdk-sessions.json");
32099
32815
  }
32100
32816
  load() {
32101
32817
  try {
32102
- if (existsSync2(this.filePath)) {
32103
- return JSON.parse(readFileSync4(this.filePath, "utf-8"));
32818
+ if (existsSync3(this.filePath)) {
32819
+ return JSON.parse(readFileSync5(this.filePath, "utf-8"));
32104
32820
  }
32105
32821
  } catch {}
32106
32822
  return {};
32107
32823
  }
32108
32824
  save(sessions) {
32109
32825
  try {
32110
- const dir = dirname3(this.filePath);
32111
- if (!existsSync2(dir)) {
32826
+ const dir = dirname4(this.filePath);
32827
+ if (!existsSync3(dir)) {
32112
32828
  mkdirSync(dir, { recursive: true });
32113
32829
  }
32114
32830
  writeFileSync(this.filePath, JSON.stringify(sessions, null, 2));
@@ -32187,6 +32903,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32187
32903
  init_terminal_provider_error();
32188
32904
  OpenCodeSdkAgentService = class OpenCodeSdkAgentService extends OpenCodeBinaryAgentService {
32189
32905
  agentEndCallbacksByPid = new Map;
32906
+ assistantTextCallbacksByPid = new Map;
32190
32907
  id = "opencode-sdk";
32191
32908
  displayName = "OpenCode (SDK)";
32192
32909
  listModelsHarnessId = "opencode-sdk";
@@ -32312,6 +33029,9 @@ var init_opencode_sdk_agent_service = __esm(() => {
32312
33029
  const entry = this.registerProcess(pid, context5);
32313
33030
  if (forwarder)
32314
33031
  this.forwarders.set(pid, forwarder);
33032
+ if (args2.assistantTextCallbacks) {
33033
+ this.assistantTextCallbacksByPid.set(pid, args2.assistantTextCallbacks);
33034
+ }
32315
33035
  const outputCallbacks = args2.outputCallbacks ?? [];
32316
33036
  this.wireChildOutput(childProcess, pid, entry, emitLogLine, outputCallbacks);
32317
33037
  return {
@@ -32330,6 +33050,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32330
33050
  }
32331
33051
  this.sessionStore.remove(sessionId);
32332
33052
  this.agentEndCallbacksByPid.delete(pid);
33053
+ this.assistantTextCallbacksByPid.delete(pid);
32333
33054
  this.deleteProcess(pid);
32334
33055
  cb({ code: code2, signal, context: context5 });
32335
33056
  });
@@ -32345,6 +33066,11 @@ var init_opencode_sdk_agent_service = __esm(() => {
32345
33066
  },
32346
33067
  onLogLine: (cb) => {
32347
33068
  logLineCallbacks.push(cb);
33069
+ },
33070
+ onAssistantText: (cb) => {
33071
+ const callbacks = this.assistantTextCallbacksByPid.get(pid) ?? args2.assistantTextCallbacks ?? [];
33072
+ callbacks.push(cb);
33073
+ this.assistantTextCallbacksByPid.set(pid, callbacks);
32348
33074
  }
32349
33075
  };
32350
33076
  }
@@ -32358,6 +33084,16 @@ var init_opencode_sdk_agent_service = __esm(() => {
32358
33084
  }
32359
33085
  };
32360
33086
  }
33087
+ createAssistantTextEmitter() {
33088
+ const assistantTextCallbacks = [];
33089
+ return {
33090
+ assistantTextCallbacks,
33091
+ emitAssistantText: (text) => {
33092
+ for (const cb of assistantTextCallbacks)
33093
+ cb(text);
33094
+ }
33095
+ };
33096
+ }
32361
33097
  async startServeAndClient(workingDir, resolvedConvexUrl) {
32362
33098
  const childProcess = this.spawnServeProcess(workingDir, resolvedConvexUrl);
32363
33099
  const pid = childProcess.pid;
@@ -32406,7 +33142,12 @@ var init_opencode_sdk_agent_service = __esm(() => {
32406
33142
  const newSessionId2 = sessionCreateResult.data.id;
32407
33143
  const forwarder = startSessionEventForwarder(client4, {
32408
33144
  sessionId: newSessionId2,
32409
- role: args2.context.role
33145
+ role: args2.context.role,
33146
+ onAssistantText: (text) => {
33147
+ const callbacks2 = this.assistantTextCallbacksByPid.get(args2.pid) ?? [];
33148
+ for (const cb of callbacks2)
33149
+ cb(text);
33150
+ }
32410
33151
  });
32411
33152
  const callbacks = this.agentEndCallbacksByPid.get(args2.pid) ?? [];
32412
33153
  for (const cb of callbacks) {
@@ -32442,6 +33183,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32442
33183
  const { childProcess, pid, baseUrl, client: client4 } = await this.startServeAndClient(workingDir, options.resolvedConvexUrl);
32443
33184
  let forwarder;
32444
33185
  const { logLineCallbacks, emitLogLine } = this.createLogLineEmitter();
33186
+ const { assistantTextCallbacks, emitAssistantText } = this.createAssistantTextEmitter();
32445
33187
  const outputCallbacks = [];
32446
33188
  try {
32447
33189
  const sessionInfo = await withTimeout(client4.session.get({ path: { id: sessionId } }), SESSION_GET_TIMEOUT_MS, "session.get");
@@ -32452,6 +33194,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32452
33194
  sessionId,
32453
33195
  role: context5.role,
32454
33196
  onLogLine: emitLogLine,
33197
+ onAssistantText: emitAssistantText,
32455
33198
  onActivity: () => {
32456
33199
  for (const cb of outputCallbacks)
32457
33200
  cb();
@@ -32483,6 +33226,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32483
33226
  model: modelForSession,
32484
33227
  workingDir,
32485
33228
  logLineCallbacks,
33229
+ assistantTextCallbacks,
32486
33230
  outputCallbacks
32487
33231
  });
32488
33232
  }
@@ -32495,6 +33239,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32495
33239
  let agentName;
32496
33240
  let deferredSystemPrompt;
32497
33241
  const { logLineCallbacks, emitLogLine } = this.createLogLineEmitter();
33242
+ const { assistantTextCallbacks, emitAssistantText } = this.createAssistantTextEmitter();
32498
33243
  const outputCallbacks = [];
32499
33244
  try {
32500
33245
  const sessionCreateResult = await withTimeout(client4.session.create({ body: {} }), SESSION_CREATE_TIMEOUT_MS, "session.create");
@@ -32506,6 +33251,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32506
33251
  sessionId,
32507
33252
  role: context5.role,
32508
33253
  onLogLine: emitLogLine,
33254
+ onAssistantText: emitAssistantText,
32509
33255
  onActivity: () => {
32510
33256
  for (const cb of outputCallbacks)
32511
33257
  cb();
@@ -32545,6 +33291,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
32545
33291
  model,
32546
33292
  workingDir: options.workingDir,
32547
33293
  logLineCallbacks,
33294
+ assistantTextCallbacks,
32548
33295
  deferredSystemPrompt,
32549
33296
  outputCallbacks
32550
33297
  });
@@ -32611,47 +33358,47 @@ __export(exports_pi_sdk_package, {
32611
33358
  getBundledPiSdkVersion: () => getBundledPiSdkVersion,
32612
33359
  formatPiSdkLoadError: () => formatPiSdkLoadError
32613
33360
  });
32614
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
32615
- import { dirname as dirname4, join as join9 } from "node:path";
32616
- import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
32617
- function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
32618
- const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
32619
- let dir = dirname4(filePath);
32620
- while (dir !== dirname4(dir)) {
32621
- const packageJsonPath = join9(dir, "package.json");
32622
- if (existsSync3(packageJsonPath)) {
32623
- const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
33361
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
33362
+ import { dirname as dirname5, join as join10 } from "node:path";
33363
+ import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
33364
+ function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
33365
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath4(moduleRef) : moduleRef;
33366
+ let dir = dirname5(filePath);
33367
+ while (dir !== dirname5(dir)) {
33368
+ const packageJsonPath = join10(dir, "package.json");
33369
+ if (existsSync4(packageJsonPath)) {
33370
+ const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
32624
33371
  if (pkg.name === "chatroom-cli") {
32625
33372
  return dir;
32626
33373
  }
32627
33374
  }
32628
- dir = dirname4(dir);
33375
+ dir = dirname5(dir);
32629
33376
  }
32630
- throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT2}`);
33377
+ throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT3}`);
32631
33378
  }
32632
- function readPinnedSdkVersion2(chatroomCliRoot) {
32633
- const pkg = JSON.parse(readFileSync5(join9(chatroomCliRoot, "package.json"), "utf8"));
33379
+ function readPinnedSdkVersion3(chatroomCliRoot) {
33380
+ const pkg = JSON.parse(readFileSync6(join10(chatroomCliRoot, "package.json"), "utf8"));
32634
33381
  const specifier = pkg.dependencies?.[PI_CODING_AGENT_PKG];
32635
33382
  const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
32636
33383
  const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
32637
33384
  if (!match17) {
32638
- throw new PiSdkPackageError(`chatroom-cli must pin an exact ${PI_CODING_AGENT_PKG} version (found "${specifier ?? "none"}"). ${REINSTALL_HINT2}`);
33385
+ throw new PiSdkPackageError(`chatroom-cli must pin an exact ${PI_CODING_AGENT_PKG} version (found "${specifier ?? "none"}"). ${REINSTALL_HINT3}`);
32639
33386
  }
32640
33387
  return match17[1];
32641
33388
  }
32642
- function readInstalledSdkVersion2(entryPath) {
32643
- const packageJsonPath = join9(dirname4(entryPath), "..", "package.json");
32644
- const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
33389
+ function readInstalledSdkVersion3(entryPath) {
33390
+ const packageJsonPath = join10(dirname5(entryPath), "..", "package.json");
33391
+ const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
32645
33392
  return pkg.version;
32646
33393
  }
32647
33394
  function resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot) {
32648
33395
  let dir = chatroomCliRoot;
32649
- while (dir !== dirname4(dir)) {
32650
- const entryPath = join9(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
32651
- if (existsSync3(entryPath)) {
33396
+ while (dir !== dirname5(dir)) {
33397
+ const entryPath = join10(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
33398
+ if (existsSync4(entryPath)) {
32652
33399
  return entryPath;
32653
33400
  }
32654
- dir = dirname4(dir);
33401
+ dir = dirname5(dir);
32655
33402
  }
32656
33403
  return;
32657
33404
  }
@@ -32659,32 +33406,32 @@ function resolvePiSdkEntryPath(chatroomCliRoot) {
32659
33406
  const resolveMeta = import.meta.resolve;
32660
33407
  if (typeof resolveMeta === "function") {
32661
33408
  try {
32662
- const parentUrl = pathToFileURL2(join9(chatroomCliRoot, "package.json")).href;
32663
- return fileURLToPath3(resolveMeta(PI_CODING_AGENT_PKG, parentUrl));
33409
+ const parentUrl = pathToFileURL3(join10(chatroomCliRoot, "package.json")).href;
33410
+ return fileURLToPath4(resolveMeta(PI_CODING_AGENT_PKG, parentUrl));
32664
33411
  } catch {}
32665
33412
  }
32666
33413
  const entryPath = resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot);
32667
33414
  if (entryPath) {
32668
33415
  return entryPath;
32669
33416
  }
32670
- throw new PiSdkPackageError(`Could not resolve ${PI_CODING_AGENT_PKG} from ${chatroomCliRoot}. ${REINSTALL_HINT2}`);
33417
+ throw new PiSdkPackageError(`Could not resolve ${PI_CODING_AGENT_PKG} from ${chatroomCliRoot}. ${REINSTALL_HINT3}`);
32671
33418
  }
32672
33419
  async function importBundledPiSdk(moduleRef = import.meta.url) {
32673
- const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
32674
- const pinnedVersion = readPinnedSdkVersion2(chatroomCliRoot);
33420
+ const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
33421
+ const pinnedVersion = readPinnedSdkVersion3(chatroomCliRoot);
32675
33422
  const entryPath = resolvePiSdkEntryPath(chatroomCliRoot);
32676
- const installedVersion = readInstalledSdkVersion2(entryPath);
33423
+ const installedVersion = readInstalledSdkVersion3(entryPath);
32677
33424
  if (installedVersion !== pinnedVersion) {
32678
- throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG}@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT2}`);
33425
+ throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG}@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT3}`);
32679
33426
  }
32680
- if (!existsSync3(entryPath)) {
32681
- throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG} entry file is missing: ${entryPath}. ${REINSTALL_HINT2}`);
33427
+ if (!existsSync4(entryPath)) {
33428
+ throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG} entry file is missing: ${entryPath}. ${REINSTALL_HINT3}`);
32682
33429
  }
32683
- return import(pathToFileURL2(entryPath).href);
33430
+ return import(pathToFileURL3(entryPath).href);
32684
33431
  }
32685
33432
  function getBundledPiSdkVersion(moduleRef = import.meta.url) {
32686
- const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
32687
- return readInstalledSdkVersion2(resolvePiSdkEntryPath(chatroomCliRoot));
33433
+ const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
33434
+ return readInstalledSdkVersion3(resolvePiSdkEntryPath(chatroomCliRoot));
32688
33435
  }
32689
33436
  function formatPiSdkLoadError(err) {
32690
33437
  if (err instanceof PiSdkPackageError) {
@@ -32692,7 +33439,7 @@ function formatPiSdkLoadError(err) {
32692
33439
  }
32693
33440
  return err instanceof Error ? err.message : String(err);
32694
33441
  }
32695
- var PI_CODING_AGENT_PKG = "@earendil-works/pi-coding-agent", REINSTALL_HINT2 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", PiSdkPackageError;
33442
+ var PI_CODING_AGENT_PKG = "@earendil-works/pi-coding-agent", REINSTALL_HINT3 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", PiSdkPackageError;
32696
33443
  var init_pi_sdk_package = __esm(() => {
32697
33444
  PiSdkPackageError = class PiSdkPackageError extends Error {
32698
33445
  code = "PI_SDK_PACKAGE_INCOMPLETE";
@@ -32704,148 +33451,133 @@ var init_pi_sdk_package = __esm(() => {
32704
33451
  });
32705
33452
 
32706
33453
  // src/infrastructure/services/remote-agents/pi-sdk/pi-sdk-stream-adapter.ts
32707
- class PiSdkStreamAdapter {
32708
- logPrefix;
32709
- emitLogLine;
32710
- agentEndCallbacks = [];
32711
- outputCallbacks = [];
32712
- agentEndEmitted = false;
32713
- textBuffer = "";
32714
- thinkingBuffer = "";
32715
- constructor(logPrefix, emitLogLine) {
32716
- this.logPrefix = logPrefix;
32717
- this.emitLogLine = emitLogLine;
32718
- }
32719
- onAgentEnd(cb) {
32720
- this.agentEndCallbacks.push(cb);
32721
- }
32722
- onOutput(cb) {
32723
- this.outputCallbacks.push(cb);
32724
- }
32725
- handleEvent(event) {
32726
- this.notifyOutput();
32727
- switch (event.type) {
32728
- case "message_update": {
32729
- const assistantEvent = event.assistantMessageEvent;
32730
- if (assistantEvent.type === "text_delta") {
32731
- this.appendText(assistantEvent.delta);
32732
- } else if (assistantEvent.type === "thinking_delta") {
32733
- this.appendThinking(assistantEvent.delta);
33454
+ var PiSdkStreamAdapter;
33455
+ var init_pi_sdk_stream_adapter = __esm(() => {
33456
+ init_native_stream_adapter_base();
33457
+ PiSdkStreamAdapter = class PiSdkStreamAdapter extends NativeStreamAdapterBase {
33458
+ textBuffer = "";
33459
+ thinkingBuffer = "";
33460
+ handleEvent(event) {
33461
+ this.notifyOutput();
33462
+ switch (event.type) {
33463
+ case "message_update": {
33464
+ const assistantEvent = event.assistantMessageEvent;
33465
+ if (assistantEvent.type === "text_delta") {
33466
+ this.appendText(assistantEvent.delta);
33467
+ } else if (assistantEvent.type === "thinking_delta") {
33468
+ this.appendThinking(assistantEvent.delta);
33469
+ }
33470
+ break;
32734
33471
  }
32735
- break;
32736
- }
32737
- case "tool_execution_start": {
32738
- this.flushText();
32739
- this.flushThinking();
32740
- const bashCmd = resolveBashCommandForLog(event.toolName, event.args);
32741
- if (bashCmd !== null) {
32742
- this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(bashCmd)));
33472
+ case "tool_execution_start": {
33473
+ this.flushText();
33474
+ this.flushThinking();
33475
+ const bashCmd = resolveBashCommandForLog(event.toolName, event.args);
33476
+ if (bashCmd !== null) {
33477
+ this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(bashCmd)));
33478
+ break;
33479
+ }
33480
+ const argsStr = event.args != null ? ` args: ${JSON.stringify(event.args)}` : "";
33481
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool", `${event.toolName}${argsStr}`));
32743
33482
  break;
32744
33483
  }
32745
- const argsStr = event.args != null ? ` args: ${JSON.stringify(event.args)}` : "";
32746
- this.writeLine(formatAgentLogLine(this.logPrefix, "tool", `${event.toolName}${argsStr}`));
32747
- break;
32748
- }
32749
- case "tool_execution_end": {
32750
- const resultStr = typeof event.result === "string" ? event.result : JSON.stringify(event.result);
32751
- this.writeLine(formatAgentLogLine(this.logPrefix, "tool_result", `${event.toolName} result: ${resultStr}`));
32752
- break;
33484
+ case "tool_execution_end": {
33485
+ const resultStr = typeof event.result === "string" ? event.result : JSON.stringify(event.result);
33486
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool_result", `${event.toolName} result: ${resultStr}`));
33487
+ break;
33488
+ }
33489
+ case "agent_end":
33490
+ this.emitAgentEnd();
33491
+ break;
33492
+ default:
33493
+ break;
32753
33494
  }
32754
- case "agent_end":
32755
- this.emitAgentEnd();
32756
- break;
32757
- default:
32758
- break;
32759
33495
  }
32760
- }
32761
- finish() {
32762
- this.flushText();
32763
- this.flushThinking();
32764
- this.emitAgentEnd();
32765
- }
32766
- emitAgentEnd() {
32767
- if (this.agentEndEmitted)
32768
- return;
32769
- this.agentEndEmitted = true;
32770
- this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
32771
- for (const cb of this.agentEndCallbacks)
32772
- cb();
32773
- }
32774
- appendText(delta) {
32775
- this.flushThinking();
32776
- this.textBuffer += delta;
32777
- if (this.textBuffer.includes(`
33496
+ finish() {
33497
+ this.flushText();
33498
+ this.flushThinking();
33499
+ this.emitAgentEnd();
33500
+ }
33501
+ emitAgentEnd() {
33502
+ if (this.agentEndEmitted)
33503
+ return;
33504
+ this.agentEndEmitted = true;
33505
+ this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
33506
+ for (const cb of this.agentEndCallbacks)
33507
+ cb();
33508
+ }
33509
+ appendText(delta) {
33510
+ this.flushThinking();
33511
+ this.textBuffer += delta;
33512
+ this.assistantTextCapture.captureAssistantText(delta);
33513
+ if (this.textBuffer.includes(`
32778
33514
  `))
33515
+ this.flushText();
33516
+ }
33517
+ appendThinking(delta) {
32779
33518
  this.flushText();
32780
- }
32781
- appendThinking(delta) {
32782
- this.flushText();
32783
- this.thinkingBuffer += delta;
32784
- if (this.thinkingBuffer.includes(`
33519
+ this.thinkingBuffer += delta;
33520
+ if (this.thinkingBuffer.includes(`
32785
33521
  `))
32786
- this.flushThinking();
32787
- }
32788
- flushText() {
32789
- if (!this.textBuffer)
32790
- return;
32791
- const lines = this.textBuffer.split(`
33522
+ this.flushThinking();
33523
+ }
33524
+ flushText() {
33525
+ if (!this.textBuffer)
33526
+ return;
33527
+ const lines = this.textBuffer.split(`
32792
33528
  `);
32793
- const remaining = this.textBuffer.endsWith(`
33529
+ const remaining = this.textBuffer.endsWith(`
32794
33530
  `) ? "" : lines.pop() ?? "";
32795
- for (const line of lines) {
32796
- if (line.length > 0) {
32797
- this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
33531
+ for (const line of lines) {
33532
+ if (line.length > 0) {
33533
+ this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
33534
+ }
32798
33535
  }
33536
+ this.textBuffer = remaining;
32799
33537
  }
32800
- this.textBuffer = remaining;
32801
- }
32802
- flushThinking() {
32803
- if (!this.thinkingBuffer)
32804
- return;
32805
- const lines = this.thinkingBuffer.split(`
33538
+ flushThinking() {
33539
+ if (!this.thinkingBuffer)
33540
+ return;
33541
+ const lines = this.thinkingBuffer.split(`
32806
33542
  `);
32807
- const remaining = this.thinkingBuffer.endsWith(`
33543
+ const remaining = this.thinkingBuffer.endsWith(`
32808
33544
  `) ? "" : lines.pop() ?? "";
32809
- for (const line of lines) {
32810
- if (line.length > 0) {
32811
- this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", line));
33545
+ for (const line of lines) {
33546
+ if (line.length > 0) {
33547
+ this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", line));
33548
+ }
32812
33549
  }
33550
+ this.thinkingBuffer = remaining;
32813
33551
  }
32814
- this.thinkingBuffer = remaining;
32815
- }
32816
- notifyOutput() {
32817
- for (const cb of this.outputCallbacks)
32818
- cb();
32819
- }
32820
- writeLine(line) {
32821
- process.stderr.write(`${line}
33552
+ writeLine(line) {
33553
+ process.stderr.write(`${line}
32822
33554
  `);
32823
- this.emitLogLine?.(line);
32824
- }
32825
- }
32826
- var init_pi_sdk_stream_adapter = () => {};
33555
+ this.emitLogLine?.(line);
33556
+ }
33557
+ };
33558
+ });
32827
33559
 
32828
33560
  // src/infrastructure/services/remote-agents/pi-sdk/pi-sdk-agent-service.ts
32829
- async function loadSdk2() {
32830
- if (_sdkCache2)
32831
- return _sdkCache2;
32832
- if (_sdkLoadError2)
32833
- throw _sdkLoadError2;
33561
+ async function loadSdk3() {
33562
+ if (_sdkCache3)
33563
+ return _sdkCache3;
33564
+ if (_sdkLoadError3)
33565
+ throw _sdkLoadError3;
32834
33566
  try {
32835
- _sdkCache2 = await importBundledPiSdk();
32836
- return _sdkCache2;
33567
+ _sdkCache3 = await importBundledPiSdk();
33568
+ return _sdkCache3;
32837
33569
  } catch (err) {
32838
- _sdkLoadError2 = err;
33570
+ _sdkLoadError3 = err;
32839
33571
  throw err;
32840
33572
  }
32841
33573
  }
32842
- function getSdkPackageVersion2() {
32843
- if (cachedSdkPackageVersion2)
32844
- return cachedSdkPackageVersion2;
32845
- cachedSdkPackageVersion2 = getBundledPiSdkVersion();
32846
- return cachedSdkPackageVersion2;
33574
+ function getSdkPackageVersion3() {
33575
+ if (cachedSdkPackageVersion3)
33576
+ return cachedSdkPackageVersion3;
33577
+ cachedSdkPackageVersion3 = getBundledPiSdkVersion();
33578
+ return cachedSdkPackageVersion3;
32847
33579
  }
32848
- function waitForResumeOrAbort2(session2) {
33580
+ function waitForResumeOrAbort3(session2) {
32849
33581
  if (session2.aborted)
32850
33582
  return Promise.resolve(null);
32851
33583
  const queued = session2.pendingResumePrompt;
@@ -32882,14 +33614,14 @@ function resolveModel(modelRegistry, model) {
32882
33614
  }
32883
33615
  return modelRegistry.getAvailable()[0];
32884
33616
  }
32885
- function writeSpawnError2(logPrefix, err, emitLogLine) {
33617
+ function writeSpawnError3(logPrefix, err, emitLogLine) {
32886
33618
  const line = formatAgentLogLine(logPrefix, "spawn-error", formatPiSdkLoadError(err));
32887
33619
  process.stderr.write(`${line}
32888
33620
  `);
32889
33621
  emitLogLine?.(line);
32890
33622
  console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
32891
33623
  }
32892
- var PI_SDK_COMMAND = "pi-sdk", SESSION_CREATE_TIMEOUT_MS2 = 60000, PROMPT_TIMEOUT_MS = 3600000, _sdkCache2, _sdkLoadError2, cachedSdkPackageVersion2, PiSdkAgentService;
33624
+ var PI_SDK_COMMAND = "pi-sdk", SESSION_CREATE_TIMEOUT_MS2 = 60000, PROMPT_TIMEOUT_MS = 3600000, _sdkCache3, _sdkLoadError3, cachedSdkPackageVersion3, PiSdkAgentService;
32893
33625
  var init_pi_sdk_agent_service = __esm(() => {
32894
33626
  init_esm();
32895
33627
  init_base_cli_agent_service();
@@ -32907,7 +33639,7 @@ var init_pi_sdk_agent_service = __esm(() => {
32907
33639
  }
32908
33640
  async isInstalled() {
32909
33641
  try {
32910
- const { ModelRegistry, AuthStorage } = await loadSdk2();
33642
+ const { ModelRegistry, AuthStorage } = await loadSdk3();
32911
33643
  const authStorage = AuthStorage.create();
32912
33644
  const modelRegistry = ModelRegistry.create(authStorage);
32913
33645
  return modelRegistry.getAvailable().length > 0;
@@ -32923,7 +33655,7 @@ var init_pi_sdk_agent_service = __esm(() => {
32923
33655
  });
32924
33656
  }
32925
33657
  async getVersion() {
32926
- const match17 = getSdkPackageVersion2().match(/^(\d+)\.(\d+)\.(\d+)/);
33658
+ const match17 = getSdkPackageVersion3().match(/^(\d+)\.(\d+)\.(\d+)/);
32927
33659
  if (!match17)
32928
33660
  return null;
32929
33661
  return {
@@ -32933,7 +33665,7 @@ var init_pi_sdk_agent_service = __esm(() => {
32933
33665
  }
32934
33666
  async listModels() {
32935
33667
  try {
32936
- const { ModelRegistry, AuthStorage } = await loadSdk2();
33668
+ const { ModelRegistry, AuthStorage } = await loadSdk3();
32937
33669
  const authStorage = AuthStorage.create();
32938
33670
  const modelRegistry = ModelRegistry.create(authStorage);
32939
33671
  return modelRegistry.getAvailable().map((entry) => `${entry.provider}/${entry.id}`);
@@ -32998,7 +33730,7 @@ var init_pi_sdk_agent_service = __esm(() => {
32998
33730
  getAgentDir,
32999
33731
  ModelRegistry,
33000
33732
  SessionManager
33001
- } = await loadSdk2();
33733
+ } = await loadSdk3();
33002
33734
  const authStorage = AuthStorage.create();
33003
33735
  const modelRegistry = ModelRegistry.create(authStorage);
33004
33736
  const resolvedModel = resolveModel(modelRegistry, args2.model);
@@ -33045,6 +33777,7 @@ var init_pi_sdk_agent_service = __esm(() => {
33045
33777
  const outputCallbacks = [];
33046
33778
  const agentEndCallbacks = [];
33047
33779
  const logLineCallbacks = [];
33780
+ const assistantTextCallbacks = [];
33048
33781
  const emitLogLine = (line) => {
33049
33782
  for (const cb of logLineCallbacks)
33050
33783
  cb(line);
@@ -33066,6 +33799,7 @@ var init_pi_sdk_agent_service = __esm(() => {
33066
33799
  finishExit,
33067
33800
  outputCallbacks,
33068
33801
  agentEndCallbacks,
33802
+ assistantTextCallbacks,
33069
33803
  emitLogLine
33070
33804
  });
33071
33805
  return {
@@ -33082,6 +33816,9 @@ var init_pi_sdk_agent_service = __esm(() => {
33082
33816
  },
33083
33817
  onLogLine: (cb) => {
33084
33818
  logLineCallbacks.push(cb);
33819
+ },
33820
+ onAssistantText: (cb) => {
33821
+ assistantTextCallbacks.push(cb);
33085
33822
  }
33086
33823
  };
33087
33824
  }
@@ -33095,6 +33832,7 @@ var init_pi_sdk_agent_service = __esm(() => {
33095
33832
  entry,
33096
33833
  outputCallbacks,
33097
33834
  agentEndCallbacks,
33835
+ assistantTextCallbacks,
33098
33836
  emitLogLine
33099
33837
  } = args2;
33100
33838
  let exited = false;
@@ -33108,7 +33846,7 @@ var init_pi_sdk_agent_service = __esm(() => {
33108
33846
  while (!sdkSession.aborted) {
33109
33847
  try {
33110
33848
  if (nextPrompt === null) {
33111
- const deferredResume = await waitForResumeOrAbort2(sdkSession);
33849
+ const deferredResume = await waitForResumeOrAbort3(sdkSession);
33112
33850
  if (deferredResume === null || sdkSession.aborted) {
33113
33851
  if (sdkSession.aborted) {
33114
33852
  exitCode = 1;
@@ -33122,14 +33860,12 @@ ${deferredResume}` : deferredResume;
33122
33860
  prependSystemOnNextResume = false;
33123
33861
  }
33124
33862
  const adapter = new PiSdkStreamAdapter(logPrefix, emitLogLine);
33125
- adapter.onOutput(() => {
33126
- entry.lastOutputAt = Date.now();
33127
- for (const cb of outputCallbacks)
33128
- cb();
33129
- });
33130
- adapter.onAgentEnd(() => {
33131
- for (const cb of agentEndCallbacks)
33132
- cb();
33863
+ wireNativeStreamAdapter({
33864
+ adapter,
33865
+ assistantTextCallbacks,
33866
+ outputCallbacks,
33867
+ agentEndCallbacks,
33868
+ entry
33133
33869
  });
33134
33870
  const onSessionEvent = (event) => {
33135
33871
  if (sdkSession.aborted)
@@ -33148,13 +33884,13 @@ ${deferredResume}` : deferredResume;
33148
33884
  nextPrompt = null;
33149
33885
  } catch (turnErr) {
33150
33886
  exitCode = 1;
33151
- writeSpawnError2(logPrefix, turnErr, emitLogLine);
33887
+ writeSpawnError3(logPrefix, turnErr, emitLogLine);
33152
33888
  break;
33153
33889
  }
33154
33890
  }
33155
33891
  } catch (err) {
33156
33892
  exitCode = 1;
33157
- writeSpawnError2(logPrefix, err, emitLogLine);
33893
+ writeSpawnError3(logPrefix, err, emitLogLine);
33158
33894
  } finally {
33159
33895
  if (exited)
33160
33896
  return;
@@ -33169,7 +33905,7 @@ ${deferredResume}` : deferredResume;
33169
33905
  finishExit(exitCode, exitSignal);
33170
33906
  }
33171
33907
  })().catch((err) => {
33172
- writeSpawnError2(logPrefix, err, emitLogLine);
33908
+ writeSpawnError3(logPrefix, err, emitLogLine);
33173
33909
  if (exited)
33174
33910
  return;
33175
33911
  exited = true;
@@ -33249,6 +33985,7 @@ function initHarnessRegistry() {
33249
33985
  registerHarness(new CursorAgentService);
33250
33986
  registerHarness(new CursorSdkAgentService);
33251
33987
  registerHarness(new ClaudeCodeAgentService);
33988
+ registerHarness(new ClaudeSdkAgentService);
33252
33989
  registerHarness(new CommandCodeAgentService);
33253
33990
  registerHarness(new CopilotAgentService);
33254
33991
  initialized = true;
@@ -33256,6 +33993,7 @@ function initHarnessRegistry() {
33256
33993
  var initialized = false;
33257
33994
  var init_init_registry = __esm(() => {
33258
33995
  init_claude();
33996
+ init_claude_sdk();
33259
33997
  init_commandcode();
33260
33998
  init_copilot();
33261
33999
  init_cursor();
@@ -33343,16 +34081,16 @@ var MACHINE_CONFIG_VERSION = "1";
33343
34081
  import { randomUUID as randomUUID2 } from "node:crypto";
33344
34082
  import * as fs4 from "node:fs/promises";
33345
34083
  import { homedir as homedir3, hostname as hostname2 } from "node:os";
33346
- import { join as join10 } from "node:path";
34084
+ import { join as join11 } from "node:path";
33347
34085
  function chatroomConfigDir() {
33348
- return join10(homedir3(), ".chatroom");
34086
+ return join11(homedir3(), ".chatroom");
33349
34087
  }
33350
34088
  async function ensureConfigDir2() {
33351
34089
  const dir = chatroomConfigDir();
33352
34090
  await fs4.mkdir(dir, { recursive: true, mode: 448 });
33353
34091
  }
33354
34092
  function getMachineConfigPath() {
33355
- return join10(chatroomConfigDir(), MACHINE_FILE);
34093
+ return join11(chatroomConfigDir(), MACHINE_FILE);
33356
34094
  }
33357
34095
  async function loadConfigFile() {
33358
34096
  const configPath = getMachineConfigPath();
@@ -33444,7 +34182,7 @@ var init_storage2 = __esm(() => {
33444
34182
  // src/infrastructure/machine/daemon-state.ts
33445
34183
  import * as fs5 from "node:fs/promises";
33446
34184
  import { homedir as homedir4 } from "node:os";
33447
- import { join as join11 } from "node:path";
34185
+ import { join as join12 } from "node:path";
33448
34186
  function agentKey(chatroomId, role) {
33449
34187
  return `${chatroomId}/${role}`;
33450
34188
  }
@@ -33452,7 +34190,7 @@ async function ensureStateDir() {
33452
34190
  await fs5.mkdir(STATE_DIR, { recursive: true, mode: 448 });
33453
34191
  }
33454
34192
  function stateFilePath(machineId) {
33455
- return join11(STATE_DIR, `${machineId}.json`);
34193
+ return join12(STATE_DIR, `${machineId}.json`);
33456
34194
  }
33457
34195
  async function loadDaemonState(machineId) {
33458
34196
  const filePath = stateFilePath(machineId);
@@ -33534,8 +34272,8 @@ async function loadEventCursor(machineId) {
33534
34272
  }
33535
34273
  var CHATROOM_DIR2, STATE_DIR, STATE_VERSION = "1";
33536
34274
  var init_daemon_state = __esm(() => {
33537
- CHATROOM_DIR2 = join11(homedir4(), ".chatroom");
33538
- STATE_DIR = join11(CHATROOM_DIR2, "machines", "state");
34275
+ CHATROOM_DIR2 = join12(homedir4(), ".chatroom");
34276
+ STATE_DIR = join12(CHATROOM_DIR2, "machines", "state");
33539
34277
  });
33540
34278
 
33541
34279
  // src/infrastructure/machine/index.ts
@@ -33977,9 +34715,9 @@ var init_init = __esm(() => {
33977
34715
  });
33978
34716
 
33979
34717
  // src/tools/output.ts
33980
- import { join as join12 } from "node:path";
34718
+ import { join as join13 } from "node:path";
33981
34719
  function resolveChatroomDir(workingDir) {
33982
- return join12(workingDir, CHATROOM_DIR3);
34720
+ return join13(workingDir, CHATROOM_DIR3);
33983
34721
  }
33984
34722
  async function ensureChatroomDir(deps, workingDir) {
33985
34723
  const dir = resolveChatroomDir(workingDir);
@@ -33987,7 +34725,7 @@ async function ensureChatroomDir(deps, workingDir) {
33987
34725
  return dir;
33988
34726
  }
33989
34727
  async function ensureGitignore(deps, workingDir) {
33990
- const gitignorePath = join12(workingDir, ".gitignore");
34728
+ const gitignorePath = join13(workingDir, ".gitignore");
33991
34729
  const entry = CHATROOM_DIR3;
33992
34730
  let content = "";
33993
34731
  try {
@@ -34017,7 +34755,7 @@ function formatOutputTimestamp(date = new Date) {
34017
34755
  function generateOutputPath(workingDir, toolName, extension, date) {
34018
34756
  const timestamp = formatOutputTimestamp(date);
34019
34757
  const filename = `${toolName}-${timestamp}.${extension}`;
34020
- return join12(resolveChatroomDir(workingDir), filename);
34758
+ return join13(resolveChatroomDir(workingDir), filename);
34021
34759
  }
34022
34760
  var CHATROOM_DIR3 = ".chatroom";
34023
34761
  var init_output = () => {};
@@ -34826,8 +35564,8 @@ var init_index_esm = __esm(() => {
34826
35564
  var ENVIRONMENT_IS_NODE = typeof process == "object" && process.versions?.node && process.type != "renderer";
34827
35565
  var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
34828
35566
  if (ENVIRONMENT_IS_NODE) {
34829
- const { createRequire: createRequire4 } = await import("module");
34830
- var require3 = createRequire4(import.meta.url);
35567
+ const { createRequire: createRequire5 } = await import("module");
35568
+ var require3 = createRequire5(import.meta.url);
34831
35569
  }
34832
35570
  var thisProgram = "./this.program";
34833
35571
  var _scriptName = import.meta.url;
@@ -40033,7 +40771,7 @@ var require_filesystem = __commonJS((exports, module) => {
40033
40771
  var LDD_PATH = "/usr/bin/ldd";
40034
40772
  var SELF_PATH = "/proc/self/exe";
40035
40773
  var MAX_LENGTH = 2048;
40036
- var readFileSync6 = (path2) => {
40774
+ var readFileSync7 = (path2) => {
40037
40775
  const fd = fs6.openSync(path2, "r");
40038
40776
  const buffer = Buffer.alloc(MAX_LENGTH);
40039
40777
  const bytesRead = fs6.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -40056,7 +40794,7 @@ var require_filesystem = __commonJS((exports, module) => {
40056
40794
  module.exports = {
40057
40795
  LDD_PATH,
40058
40796
  SELF_PATH,
40059
- readFileSync: readFileSync6,
40797
+ readFileSync: readFileSync7,
40060
40798
  readFile: readFile4
40061
40799
  };
40062
40800
  });
@@ -40099,7 +40837,7 @@ var require_elf = __commonJS((exports, module) => {
40099
40837
  var require_detect_libc = __commonJS((exports, module) => {
40100
40838
  var childProcess = __require("child_process");
40101
40839
  var { isLinux, getReport } = require_process();
40102
- var { LDD_PATH, SELF_PATH, readFile: readFile4, readFileSync: readFileSync6 } = require_filesystem();
40840
+ var { LDD_PATH, SELF_PATH, readFile: readFile4, readFileSync: readFileSync7 } = require_filesystem();
40103
40841
  var { interpreterPath } = require_elf();
40104
40842
  var cachedFamilyInterpreter;
40105
40843
  var cachedFamilyFilesystem;
@@ -40190,7 +40928,7 @@ var require_detect_libc = __commonJS((exports, module) => {
40190
40928
  }
40191
40929
  cachedFamilyFilesystem = null;
40192
40930
  try {
40193
- const lddContent = readFileSync6(LDD_PATH);
40931
+ const lddContent = readFileSync7(LDD_PATH);
40194
40932
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
40195
40933
  } catch (e) {}
40196
40934
  return cachedFamilyFilesystem;
@@ -40213,7 +40951,7 @@ var require_detect_libc = __commonJS((exports, module) => {
40213
40951
  }
40214
40952
  cachedFamilyInterpreter = null;
40215
40953
  try {
40216
- const selfContent = readFileSync6(SELF_PATH);
40954
+ const selfContent = readFileSync7(SELF_PATH);
40217
40955
  const path2 = interpreterPath(selfContent);
40218
40956
  cachedFamilyInterpreter = familyFromInterpreterPath(path2);
40219
40957
  } catch (e) {}
@@ -40275,7 +41013,7 @@ var require_detect_libc = __commonJS((exports, module) => {
40275
41013
  }
40276
41014
  cachedVersionFilesystem = null;
40277
41015
  try {
40278
- const lddContent = readFileSync6(LDD_PATH);
41016
+ const lddContent = readFileSync7(LDD_PATH);
40279
41017
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
40280
41018
  if (versionMatch) {
40281
41019
  cachedVersionFilesystem = versionMatch[1];
@@ -46473,12 +47211,12 @@ var init_pdfium_renderer = __esm(() => {
46473
47211
  });
46474
47212
 
46475
47213
  // ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/engines/pdf/pdfjsImporter.js
46476
- import { fileURLToPath as fileURLToPath4 } from "node:url";
46477
- import { dirname as dirname5 } from "node:path";
47214
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
47215
+ import { dirname as dirname6 } from "node:path";
46478
47216
  async function importPdfJs() {
46479
47217
  const pdfUrl = new URL("../../vendor/pdfjs/pdf.mjs", import.meta.url);
46480
47218
  const pdfjs = await import(pdfUrl.href);
46481
- const dirPath = dirname5(fileURLToPath4(pdfUrl));
47219
+ const dirPath = dirname6(fileURLToPath5(pdfUrl));
46482
47220
  return {
46483
47221
  fn: pdfjs.getDocument,
46484
47222
  dir: dirPath
@@ -67827,7 +68565,7 @@ function applyMarkupTags(markup, text) {
67827
68565
  // ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/processing/gridDebugLogger.js
67828
68566
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
67829
68567
  import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
67830
- import { dirname as dirname6 } from "path";
68568
+ import { dirname as dirname7 } from "path";
67831
68569
 
67832
68570
  class GridDebugLogger {
67833
68571
  config;
@@ -68154,14 +68892,14 @@ class GridDebugLogger {
68154
68892
  flushSync() {
68155
68893
  if (!this.config.outputPath || this.entries.length === 0)
68156
68894
  return;
68157
- mkdirSync2(dirname6(this.config.outputPath), { recursive: true });
68895
+ mkdirSync2(dirname7(this.config.outputPath), { recursive: true });
68158
68896
  writeFileSync2(this.config.outputPath, this.formatEntries(), "utf-8");
68159
68897
  this.entries = [];
68160
68898
  }
68161
68899
  async flush() {
68162
68900
  if (!this.config.outputPath || this.entries.length === 0)
68163
68901
  return;
68164
- await mkdir4(dirname6(this.config.outputPath), { recursive: true });
68902
+ await mkdir4(dirname7(this.config.outputPath), { recursive: true });
68165
68903
  await writeFile4(this.config.outputPath, this.formatEntries(), "utf-8");
68166
68904
  this.entries = [];
68167
68905
  }
@@ -75581,10 +76319,7 @@ Put your **complete** deliverable in the handoff message — not in session text
75581
76319
  }
75582
76320
 
75583
76321
  // ../../services/backend/prompts/utils/code-change-verification.ts
75584
- var CODE_CHANGE_VERIFICATION_COMMAND = "pnpm typecheck && pnpm test", CODE_CHANGE_VERIFICATION_CONFIRMATION;
75585
- var init_code_change_verification = __esm(() => {
75586
- CODE_CHANGE_VERIFICATION_CONFIRMATION = `- [ ] I confirm that I have run \`${CODE_CHANGE_VERIFICATION_COMMAND}\` (only required if code changes were made)`;
75587
- });
76322
+ var CODE_CHANGE_VERIFICATION_CONFIRMATION = "- [ ] I confirm that I have run typecheck and tests for the project (only required if code changes were made)";
75588
76323
 
75589
76324
  // ../../services/backend/prompts/cli/context/read.ts
75590
76325
  function contextReadCommand(params = {}) {
@@ -75663,7 +76398,6 @@ ${CODE_CHANGE_VERIFICATION_CONFIRMATION}
75663
76398
  \`\`\``;
75664
76399
  }
75665
76400
  var init_builder_to_planner = __esm(() => {
75666
- init_code_change_verification();
75667
76401
  init_context_disclosure();
75668
76402
  init_role_guidance_disclosure();
75669
76403
  });
@@ -75820,7 +76554,6 @@ ${CODE_CHANGE_VERIFICATION_CONFIRMATION}
75820
76554
  \`\`\``;
75821
76555
  }
75822
76556
  var init_planner_to_user = __esm(() => {
75823
- init_code_change_verification();
75824
76557
  init_context_disclosure();
75825
76558
  init_role_guidance_disclosure();
75826
76559
  });
@@ -75919,7 +76652,6 @@ ${CODE_CHANGE_VERIFICATION_CONFIRMATION}
75919
76652
  \`\`\``;
75920
76653
  }
75921
76654
  var init_solo_to_user = __esm(() => {
75922
- init_code_change_verification();
75923
76655
  init_context_disclosure();
75924
76656
  init_role_guidance_disclosure();
75925
76657
  });
@@ -76155,8 +76887,6 @@ var init_commands_reference = __esm(() => {
76155
76887
  init_command2();
76156
76888
  init_utils3();
76157
76889
  });
76158
- // ../../services/backend/src/domain/usecase/skills/modules/attachments/index.ts
76159
- var init_attachments = () => {};
76160
76890
 
76161
76891
  // ../../services/backend/prompts/cli/backlog/command.ts
76162
76892
  var init_command3 = __esm(() => {
@@ -76173,7 +76903,6 @@ var init_code_review = () => {};
76173
76903
 
76174
76904
  // ../../services/backend/src/domain/usecase/skills/registry.ts
76175
76905
  var init_registry3 = __esm(() => {
76176
- init_attachments();
76177
76906
  init_backlog();
76178
76907
  init_code_review();
76179
76908
  });
@@ -76203,8 +76932,7 @@ var init_glossary = __esm(() => {
76203
76932
  },
76204
76933
  {
76205
76934
  term: "attachments",
76206
- definition: "Message attachment types (task, backlog, message, snippet) and their compose, delivery, and task-read paths. " + "Use when adding or changing attachment UI, delivery XML, or agent-facing attachment formats.",
76207
- linkedSkillId: "attachments"
76935
+ definition: "Message attachment types (task, backlog, message, snippet) delivered in agent prompts as XML when users attach context to messages."
76208
76936
  },
76209
76937
  {
76210
76938
  term: "code-review",
@@ -76347,6 +77075,22 @@ var init_next_step = __esm(() => {
76347
77075
  // ../../services/backend/prompts/sections/session-vs-chatroom-task.ts
76348
77076
  var init_session_vs_chatroom_task = () => {};
76349
77077
 
77078
+ // ../../services/backend/src/domain/entities/harness/claude-sdk.config.ts
77079
+ var claudeSdkCapabilities;
77080
+ var init_claude_sdk_config = __esm(() => {
77081
+ claudeSdkCapabilities = {
77082
+ runtimeKind: "sdk",
77083
+ supportsDaemonMemoryResume: false,
77084
+ supportsNativeIntegration: true,
77085
+ lifecycle: {
77086
+ turnCompleted: true,
77087
+ outputActivity: true,
77088
+ processExited: true
77089
+ },
77090
+ wireEvents: ["sdk.claude.message"]
77091
+ };
77092
+ });
77093
+
76350
77094
  // ../../services/backend/src/domain/entities/harness/claude.config.ts
76351
77095
  var claudeCapabilities;
76352
77096
  var init_claude_config = __esm(() => {
@@ -76510,6 +77254,7 @@ function isNativeHarness(harness) {
76510
77254
  }
76511
77255
  var HARNESS_CAPABILITIES;
76512
77256
  var init_types = __esm(() => {
77257
+ init_claude_sdk_config();
76513
77258
  init_claude_config();
76514
77259
  init_commandcode_config();
76515
77260
  init_copilot_config();
@@ -76521,6 +77266,7 @@ var init_types = __esm(() => {
76521
77266
  init_pi_config();
76522
77267
  HARNESS_CAPABILITIES = {
76523
77268
  claude: claudeCapabilities,
77269
+ "claude-sdk": claudeSdkCapabilities,
76524
77270
  commandcode: commandcodeCapabilities,
76525
77271
  copilot: copilotCapabilities,
76526
77272
  cursor: cursorCapabilities,
@@ -76599,15 +77345,6 @@ function handleHandoffError(err) {
76599
77345
  } else if (err._tag === "InvalidChatroomId") {
76600
77346
  formatChatroomIdError(err.id);
76601
77347
  process.exit(1);
76602
- } else if (err._tag === "ArtifactsInvalid") {
76603
- formatError("One or more artifacts not found", [
76604
- "Please create artifacts first:",
76605
- `chatroom artifact create <chatroom-id> --from-file=... --filename=...`
76606
- ]);
76607
- process.exit(1);
76608
- } else if (err._tag === "ArtifactValidationFailed") {
76609
- formatError("Failed to validate artifacts", [String(err.cause)]);
76610
- process.exit(1);
76611
77348
  } else if (err._tag === "HandoffFailed") {
76612
77349
  console.error(`
76613
77350
  ❌ ERROR: Handoff failed`);
@@ -76670,7 +77407,7 @@ async function handoff(chatroomId, options, deps) {
76670
77407
  var handoffEffect = (chatroomId, options) => exports_Effect.gen(function* () {
76671
77408
  const session2 = yield* SessionService;
76672
77409
  const backend2 = yield* BackendService;
76673
- const { role, message, nextRole, attachedArtifactIds = [] } = options;
77410
+ const { role, message, nextRole } = options;
76674
77411
  const sessionId = yield* requireSessionIdEffect((a) => ({
76675
77412
  _tag: "NotAuthenticated",
76676
77413
  convexUrl: a.convexUrl,
@@ -76680,24 +77417,12 @@ var handoffEffect = (chatroomId, options) => exports_Effect.gen(function* () {
76680
77417
  _tag: "InvalidChatroomId",
76681
77418
  id: id3
76682
77419
  }));
76683
- if (attachedArtifactIds.length > 0) {
76684
- const areValid = yield* backend2.query(api.artifacts.validateArtifactIds, {
76685
- sessionId,
76686
- artifactIds: attachedArtifactIds
76687
- }).pipe(exports_Effect.mapError((cause3) => ({ _tag: "ArtifactValidationFailed", cause: cause3 })));
76688
- if (!areValid) {
76689
- return yield* exports_Effect.fail({ _tag: "ArtifactsInvalid" });
76690
- }
76691
- }
76692
77420
  const result = yield* backend2.mutation(api.messages.handoff, {
76693
77421
  sessionId,
76694
77422
  chatroomId,
76695
77423
  senderRole: role,
76696
77424
  content: message,
76697
- targetRole: nextRole,
76698
- ...attachedArtifactIds.length > 0 && {
76699
- attachedArtifactIds
76700
- }
77425
+ targetRole: nextRole
76701
77426
  }).pipe(exports_Effect.mapError((cause3) => {
76702
77427
  let errorData;
76703
77428
  if (cause3 instanceof ConvexError) {
@@ -76720,12 +77445,6 @@ var handoffEffect = (chatroomId, options) => exports_Effect.gen(function* () {
76720
77445
  convexUrl,
76721
77446
  supportsNativeIntegration: result.supportsNativeIntegration
76722
77447
  }));
76723
- if (attachedArtifactIds.length > 0) {
76724
- console.log(`\uD83D\uDCCE Attached artifacts: ${attachedArtifactIds.length}`);
76725
- attachedArtifactIds.forEach((id3) => {
76726
- console.log(` • ${id3}`);
76727
- });
76728
- }
76729
77448
  });
76730
77449
  });
76731
77450
  var init_handoff = __esm(() => {
@@ -79306,35 +80025,35 @@ function formatTimestamp() {
79306
80025
  import { createHash as createHash2 } from "node:crypto";
79307
80026
  import {
79308
80027
  appendFileSync,
79309
- existsSync as existsSync4,
80028
+ existsSync as existsSync5,
79310
80029
  mkdirSync as mkdirSync4,
79311
- readFileSync as readFileSync6,
80030
+ readFileSync as readFileSync7,
79312
80031
  renameSync,
79313
80032
  unlinkSync,
79314
80033
  writeFileSync as writeFileSync3
79315
80034
  } from "node:fs";
79316
80035
  import { homedir as homedir5 } from "node:os";
79317
- import { join as join14 } from "node:path";
80036
+ import { join as join15 } from "node:path";
79318
80037
  function getUrlHash() {
79319
80038
  const url2 = getConvexUrl();
79320
80039
  return createHash2("sha256").update(url2).digest("hex").substring(0, 8);
79321
80040
  }
79322
80041
  function getChildPidsFilePath() {
79323
- const dir = join14(homedir5(), ".chatroom");
79324
- return join14(dir, `daemon-children-${getUrlHash()}.pids`);
80042
+ const dir = join15(homedir5(), ".chatroom");
80043
+ return join15(dir, `daemon-children-${getUrlHash()}.pids`);
79325
80044
  }
79326
80045
  function ensureChatroomDir2() {
79327
- const dir = join14(homedir5(), ".chatroom");
79328
- if (!existsSync4(dir)) {
80046
+ const dir = join15(homedir5(), ".chatroom");
80047
+ if (!existsSync5(dir)) {
79329
80048
  mkdirSync4(dir, { recursive: true, mode: 448 });
79330
80049
  }
79331
80050
  }
79332
80051
  function readPids() {
79333
80052
  const filePath = getChildPidsFilePath();
79334
- if (!existsSync4(filePath))
80053
+ if (!existsSync5(filePath))
79335
80054
  return [];
79336
80055
  try {
79337
- return readFileSync6(filePath, "utf-8").split(`
80056
+ return readFileSync7(filePath, "utf-8").split(`
79338
80057
  `).map((line) => parseInt(line.trim(), 10)).filter((n) => Number.isFinite(n) && n > 0);
79339
80058
  } catch {
79340
80059
  return [];
@@ -79352,9 +80071,9 @@ function trackChildPid(pid) {
79352
80071
  function untrackChildPid(pid) {
79353
80072
  try {
79354
80073
  const filePath = getChildPidsFilePath();
79355
- if (!existsSync4(filePath))
80074
+ if (!existsSync5(filePath))
79356
80075
  return;
79357
- const remaining = readFileSync6(filePath, "utf-8").split(`
80076
+ const remaining = readFileSync7(filePath, "utf-8").split(`
79358
80077
  `).filter((line) => {
79359
80078
  const n = parseInt(line.trim(), 10);
79360
80079
  return Number.isFinite(n) && n > 0 && n !== pid;
@@ -79371,7 +80090,7 @@ function untrackChildPid(pid) {
79371
80090
  function clearTrackedPids() {
79372
80091
  try {
79373
80092
  const filePath = getChildPidsFilePath();
79374
- if (existsSync4(filePath)) {
80093
+ if (existsSync5(filePath)) {
79375
80094
  unlinkSync(filePath);
79376
80095
  }
79377
80096
  } catch {}
@@ -79656,7 +80375,7 @@ var init_log_observer_sync = __esm(() => {
79656
80375
  // src/commands/machine/daemon-start/handlers/process/output-store.ts
79657
80376
  import { appendFile as appendFile2, mkdir as mkdir7, readFile as readFile6, rm } from "node:fs/promises";
79658
80377
  import { tmpdir } from "node:os";
79659
- import { join as join15 } from "node:path";
80378
+ import { join as join16 } from "node:path";
79660
80379
 
79661
80380
  class TempFileOutputStore {
79662
80381
  state;
@@ -79719,7 +80438,7 @@ function createOutputStore(runId) {
79719
80438
  if (!RUN_ID_RE.test(runId)) {
79720
80439
  throw new Error(`Invalid runId: ${runId}`);
79721
80440
  }
79722
- const filePath = join15(TEMP_DIR, `${runId}.log`);
80441
+ const filePath = join16(TEMP_DIR, `${runId}.log`);
79723
80442
  return new TempFileOutputStore(filePath);
79724
80443
  }
79725
80444
  async function ensureTempDir() {
@@ -79733,7 +80452,7 @@ async function cleanOrphanTempFiles() {
79733
80452
  var TAIL_WINDOW_BYTES, TEMP_DIR, RUN_ID_RE, MAX_TAIL_LINES_V2 = 50;
79734
80453
  var init_output_store = __esm(() => {
79735
80454
  TAIL_WINDOW_BYTES = 32 * 1024;
79736
- TEMP_DIR = join15(tmpdir(), "chatroom-cli", "runs");
80455
+ TEMP_DIR = join16(tmpdir(), "chatroom-cli", "runs");
79737
80456
  RUN_ID_RE = /^[a-z0-9]+$/i;
79738
80457
  });
79739
80458
 
@@ -80828,9 +81547,9 @@ var init_local_actions = __esm(() => {
80828
81547
 
80829
81548
  // src/commands/machine/pid.ts
80830
81549
  import { createHash as createHash3 } from "node:crypto";
80831
- import { existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
81550
+ import { existsSync as existsSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
80832
81551
  import { homedir as homedir6 } from "node:os";
80833
- import { join as join16 } from "node:path";
81552
+ import { join as join17 } from "node:path";
80834
81553
  function getUrlHash2() {
80835
81554
  const url2 = getConvexUrl();
80836
81555
  return createHash3("sha256").update(url2).digest("hex").substring(0, 8);
@@ -80839,12 +81558,12 @@ function getPidFileName() {
80839
81558
  return `daemon-${getUrlHash2()}.pid`;
80840
81559
  }
80841
81560
  function ensureChatroomDir3() {
80842
- if (!existsSync5(CHATROOM_DIR4)) {
81561
+ if (!existsSync6(CHATROOM_DIR4)) {
80843
81562
  mkdirSync5(CHATROOM_DIR4, { recursive: true, mode: 448 });
80844
81563
  }
80845
81564
  }
80846
81565
  function getPidFilePath() {
80847
- return join16(CHATROOM_DIR4, getPidFileName());
81566
+ return join17(CHATROOM_DIR4, getPidFileName());
80848
81567
  }
80849
81568
  function isProcessRunning(pid) {
80850
81569
  try {
@@ -80856,11 +81575,11 @@ function isProcessRunning(pid) {
80856
81575
  }
80857
81576
  function readPid() {
80858
81577
  const pidPath = getPidFilePath();
80859
- if (!existsSync5(pidPath)) {
81578
+ if (!existsSync6(pidPath)) {
80860
81579
  return null;
80861
81580
  }
80862
81581
  try {
80863
- const content = readFileSync7(pidPath, "utf-8").trim();
81582
+ const content = readFileSync8(pidPath, "utf-8").trim();
80864
81583
  const pid = parseInt(content, 10);
80865
81584
  if (isNaN(pid) || pid <= 0) {
80866
81585
  return null;
@@ -80878,7 +81597,7 @@ function writePid() {
80878
81597
  function removePid() {
80879
81598
  const pidPath = getPidFilePath();
80880
81599
  try {
80881
- if (existsSync5(pidPath)) {
81600
+ if (existsSync6(pidPath)) {
80882
81601
  unlinkSync2(pidPath);
80883
81602
  }
80884
81603
  } catch {}
@@ -80941,7 +81660,7 @@ function releaseLock() {
80941
81660
  var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000;
80942
81661
  var init_pid = __esm(() => {
80943
81662
  init_client2();
80944
- CHATROOM_DIR4 = join16(homedir6(), ".chatroom");
81663
+ CHATROOM_DIR4 = join17(homedir6(), ".chatroom");
80945
81664
  });
80946
81665
 
80947
81666
  // src/commands/machine/daemon-start/workspace-cache.ts
@@ -81854,16 +82573,16 @@ var init_jsonc = __esm(() => {
81854
82573
 
81855
82574
  // src/infrastructure/services/workspace/workspace-resolver.ts
81856
82575
  import { readFile as readFile7, readdir, stat as stat2 } from "node:fs/promises";
81857
- import { join as join17, basename, resolve as resolve3 } from "node:path";
82576
+ import { join as join18, basename, resolve as resolve3 } from "node:path";
81858
82577
  async function resolveGlobPatternStar(rootDir, cleaned) {
81859
- const parentDir = join17(rootDir, cleaned.slice(0, -2));
82578
+ const parentDir = join18(rootDir, cleaned.slice(0, -2));
81860
82579
  try {
81861
82580
  const entries2 = await readdir(parentDir, { withFileTypes: true });
81862
82581
  const dirs = [];
81863
82582
  for (const entry of entries2) {
81864
82583
  if (!entry.isDirectory())
81865
82584
  continue;
81866
- const dirPath = join17(parentDir, entry.name);
82585
+ const dirPath = join18(parentDir, entry.name);
81867
82586
  if (resolve3(dirPath).startsWith(resolve3(rootDir))) {
81868
82587
  dirs.push(dirPath);
81869
82588
  }
@@ -81874,7 +82593,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
81874
82593
  }
81875
82594
  }
81876
82595
  async function resolveLiteralPath(rootDir, cleaned) {
81877
- const dir = join17(rootDir, cleaned);
82596
+ const dir = join18(rootDir, cleaned);
81878
82597
  try {
81879
82598
  if (!resolve3(dir).startsWith(resolve3(rootDir)))
81880
82599
  return [];
@@ -81894,7 +82613,7 @@ async function resolveGlobPattern(rootDir, pattern) {
81894
82613
  }
81895
82614
  async function readPackageJson(dir) {
81896
82615
  try {
81897
- const content = await readFile7(join17(dir, "package.json"), "utf-8");
82616
+ const content = await readFile7(join18(dir, "package.json"), "utf-8");
81898
82617
  const pkg = JSON.parse(content);
81899
82618
  return {
81900
82619
  name: pkg.name || basename(dir),
@@ -81906,7 +82625,7 @@ async function readPackageJson(dir) {
81906
82625
  }
81907
82626
  async function readPnpmWorkspacePatterns(rootDir) {
81908
82627
  try {
81909
- const content = await readFile7(join17(rootDir, "pnpm-workspace.yaml"), "utf-8");
82628
+ const content = await readFile7(join18(rootDir, "pnpm-workspace.yaml"), "utf-8");
81910
82629
  const patterns = [];
81911
82630
  let inPackages = false;
81912
82631
  for (const line of content.split(`
@@ -81933,7 +82652,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
81933
82652
  }
81934
82653
  async function readPackageJsonWorkspacePatterns(rootDir) {
81935
82654
  try {
81936
- const content = await readFile7(join17(rootDir, "package.json"), "utf-8");
82655
+ const content = await readFile7(join18(rootDir, "package.json"), "utf-8");
81937
82656
  const pkg = JSON.parse(content);
81938
82657
  if (!pkg.workspaces)
81939
82658
  return [];
@@ -81982,11 +82701,11 @@ var init_workspace_resolver = () => {};
81982
82701
 
81983
82702
  // src/infrastructure/services/workspace/command-discovery.ts
81984
82703
  import { access as access4, readFile as readFile8 } from "node:fs/promises";
81985
- import { join as join18, relative, basename as basename2 } from "node:path";
82704
+ import { join as join19, relative, basename as basename2 } from "node:path";
81986
82705
  async function detectPackageManager(workingDir) {
81987
82706
  for (const { file, manager } of LOCKFILE_MAP) {
81988
82707
  try {
81989
- await access4(join18(workingDir, file));
82708
+ await access4(join19(workingDir, file));
81990
82709
  return manager;
81991
82710
  } catch {}
81992
82711
  }
@@ -82055,7 +82774,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
82055
82774
  }
82056
82775
  async function readRootPackageJson(workingDir, pm, scriptPrefix) {
82057
82776
  let rootPackageName = basename2(workingDir);
82058
- const pkg = await readJsonFile(join18(workingDir, "package.json"), "root package.json");
82777
+ const pkg = await readJsonFile(join19(workingDir, "package.json"), "root package.json");
82059
82778
  if (!pkg)
82060
82779
  return { commands: [], rootPackageName };
82061
82780
  if (pkg.name)
@@ -82071,7 +82790,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
82071
82790
  }
82072
82791
  async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
82073
82792
  const turboTaskNames = [];
82074
- const turbo = await readJsonFile(join18(workingDir, "turbo.json"), "turbo.json");
82793
+ const turbo = await readJsonFile(join19(workingDir, "turbo.json"), "turbo.json");
82075
82794
  if (!turbo?.tasks || typeof turbo.tasks !== "object")
82076
82795
  return turboTaskNames;
82077
82796
  for (const taskName of Object.keys(turbo.tasks)) {
@@ -83075,16 +83794,16 @@ var SEND_TIMEOUT_MS2 = 60000, RUN_WAIT_TIMEOUT_MS2 = 3600000;
83075
83794
  var init_cursor_session = () => {};
83076
83795
 
83077
83796
  // src/infrastructure/harnesses/cursor-sdk/cursor-harness.ts
83078
- async function loadSdk3() {
83079
- if (_sdkCache3)
83080
- return _sdkCache3;
83081
- if (_sdkLoadError3)
83082
- throw _sdkLoadError3;
83797
+ async function loadSdk4() {
83798
+ if (_sdkCache4)
83799
+ return _sdkCache4;
83800
+ if (_sdkLoadError4)
83801
+ throw _sdkLoadError4;
83083
83802
  try {
83084
- _sdkCache3 = await importBundledCursorSdk();
83085
- return _sdkCache3;
83803
+ _sdkCache4 = await importBundledCursorSdk();
83804
+ return _sdkCache4;
83086
83805
  } catch (err) {
83087
- _sdkLoadError3 = err;
83806
+ _sdkLoadError4 = err;
83088
83807
  throw err;
83089
83808
  }
83090
83809
  }
@@ -83119,7 +83838,7 @@ class CursorSdkHarness {
83119
83838
  const apiKey = process.env.CURSOR_API_KEY?.trim();
83120
83839
  if (!apiKey)
83121
83840
  return [];
83122
- const { Cursor } = await loadSdk3();
83841
+ const { Cursor } = await loadSdk4();
83123
83842
  const listed = await withTimeout(Cursor.models.list({ apiKey }), MODELS_LIST_TIMEOUT_MS2, "Cursor.models.list");
83124
83843
  const modelIds = normalizeCursorSdkListedModels(listed.map((m) => m.id).filter((id3) => id3.length > 0));
83125
83844
  return [
@@ -83137,7 +83856,7 @@ class CursorSdkHarness {
83137
83856
  if (!apiKey)
83138
83857
  throw new Error("CURSOR_API_KEY is not set");
83139
83858
  const modelId = resolveCursorSdkModel(config3.model ?? DEFAULT_MODEL2);
83140
- const { Agent } = await loadSdk3();
83859
+ const { Agent } = await loadSdk4();
83141
83860
  const agent = await withTimeout(Agent.create({
83142
83861
  apiKey,
83143
83862
  model: { id: modelId },
@@ -83161,7 +83880,7 @@ class CursorSdkHarness {
83161
83880
  const apiKey = process.env.CURSOR_API_KEY?.trim();
83162
83881
  if (!apiKey)
83163
83882
  throw new Error("CURSOR_API_KEY is not set");
83164
- const { Agent } = await loadSdk3();
83883
+ const { Agent } = await loadSdk4();
83165
83884
  const agent = await withTimeout(Agent.resume(sessionId, {
83166
83885
  apiKey,
83167
83886
  model: { id: DEFAULT_MODEL2 },
@@ -83191,9 +83910,9 @@ class CursorSdkHarness {
83191
83910
  this.sessions.clear();
83192
83911
  }
83193
83912
  }
83194
- var DEFAULT_MODEL2 = "composer-2.5", MODELS_LIST_TIMEOUT_MS2 = 60000, AGENT_CREATE_TIMEOUT_MS2 = 60000, _sdkCache3, _sdkLoadError3, startCursorSdkHarness = async (config3) => {
83913
+ var DEFAULT_MODEL2 = "composer-2.5", MODELS_LIST_TIMEOUT_MS2 = 60000, AGENT_CREATE_TIMEOUT_MS2 = 60000, _sdkCache4, _sdkLoadError4, startCursorSdkHarness = async (config3) => {
83195
83914
  try {
83196
- await loadSdk3();
83915
+ await loadSdk4();
83197
83916
  } catch (err) {
83198
83917
  throw new Error(`cursor-sdk unavailable: ${formatCursorSdkLoadError(err)}`);
83199
83918
  }
@@ -83858,16 +84577,16 @@ var PROMPT_TIMEOUT_MS2 = 3600000;
83858
84577
  var init_pi_session = () => {};
83859
84578
 
83860
84579
  // src/infrastructure/harnesses/pi-sdk/pi-harness.ts
83861
- async function loadSdk4() {
83862
- if (_sdkCache4)
83863
- return _sdkCache4;
83864
- if (_sdkLoadError4)
83865
- throw _sdkLoadError4;
84580
+ async function loadSdk5() {
84581
+ if (_sdkCache5)
84582
+ return _sdkCache5;
84583
+ if (_sdkLoadError5)
84584
+ throw _sdkLoadError5;
83866
84585
  try {
83867
- _sdkCache4 = await importBundledPiSdk();
83868
- return _sdkCache4;
84586
+ _sdkCache5 = await importBundledPiSdk();
84587
+ return _sdkCache5;
83869
84588
  } catch (err) {
83870
- _sdkLoadError4 = err;
84589
+ _sdkLoadError5 = err;
83871
84590
  throw err;
83872
84591
  }
83873
84592
  }
@@ -83939,7 +84658,7 @@ class PiSdkHarness {
83939
84658
  const existing = this.sessions.get(sessionId);
83940
84659
  if (existing)
83941
84660
  return existing;
83942
- const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk4();
84661
+ const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk5();
83943
84662
  const sessions = await SessionManager.list(this.cwd, getPiSessionDir(this.cwd));
83944
84663
  const match17 = sessions.find((s) => s.id === sessionId);
83945
84664
  if (!match17) {
@@ -83987,7 +84706,7 @@ class PiSdkHarness {
83987
84706
  this.sessions.clear();
83988
84707
  }
83989
84708
  async createAgentSession(systemPrompt, model) {
83990
- const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk4();
84709
+ const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk5();
83991
84710
  const resolvedModel = resolveModel2(this.modelRegistry, model ?? DEFAULT_MODEL3);
83992
84711
  if (!resolvedModel) {
83993
84712
  throw new Error("No Pi model available — configure provider credentials in ~/.pi/agent/auth.json");
@@ -84009,9 +84728,9 @@ class PiSdkHarness {
84009
84728
  return session2;
84010
84729
  }
84011
84730
  }
84012
- var SESSION_CREATE_TIMEOUT_MS3 = 60000, DEFAULT_MODEL3 = "opencode/big-pickle", _sdkCache4, _sdkLoadError4, startPiSdkHarness = async (config3) => {
84731
+ var SESSION_CREATE_TIMEOUT_MS3 = 60000, DEFAULT_MODEL3 = "opencode/big-pickle", _sdkCache5, _sdkLoadError5, startPiSdkHarness = async (config3) => {
84013
84732
  try {
84014
- const { AuthStorage, ModelRegistry } = await loadSdk4();
84733
+ const { AuthStorage, ModelRegistry } = await loadSdk5();
84015
84734
  const authStorage = AuthStorage.create();
84016
84735
  const modelRegistry = ModelRegistry.create(authStorage);
84017
84736
  if (modelRegistry.getAvailable().length === 0) {
@@ -85912,7 +86631,7 @@ var init_crash_loop_tracker = __esm(() => {
85912
86631
  });
85913
86632
 
85914
86633
  // ../../services/backend/src/domain/entities/participant.ts
85915
- var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", ONLINE_OR_STARTING_STATUSES;
86634
+ var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", NATIVE_HANDOFF_REMINDER = "Reminder: Use the handoff command to send your response to the team.", ONLINE_OR_STARTING_STATUSES;
85916
86635
  var init_participant = __esm(() => {
85917
86636
  ONLINE_OR_STARTING_STATUSES = new Set([
85918
86637
  "agent.waiting",
@@ -86017,9 +86736,6 @@ function isInjectableNativeAction(action) {
86017
86736
  return true;
86018
86737
  return action === NATIVE_WAITING_ACTION;
86019
86738
  }
86020
- function shouldEmitNativeWaitingOnTurnEnd(lastStatus) {
86021
- return lastStatus !== "task.acknowledged" && lastStatus !== "task.inProgress";
86022
- }
86023
86739
  function isNativeIdleAfterTaskComplete(participant) {
86024
86740
  return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
86025
86741
  }
@@ -87137,6 +87853,16 @@ class AgentProcessManager {
87137
87853
  }
87138
87854
  await service3.resumeTurn(slot.pid, args2.prompt);
87139
87855
  }
87856
+ async injectHarnessReminder(chatroomId, role, prompt) {
87857
+ const key = agentKey3(chatroomId, role);
87858
+ const slot = this.slots.get(key);
87859
+ if (!slot?.pid || !slot.harness)
87860
+ return;
87861
+ const service3 = this.deps.agentServices.get(slot.harness);
87862
+ if (!service3?.resumeTurn)
87863
+ return;
87864
+ await service3.resumeTurn(slot.pid, prompt);
87865
+ }
87140
87866
  async stop(opts) {
87141
87867
  const key = agentKey3(opts.chatroomId, opts.role);
87142
87868
  const slot = this.slots.get(key);
@@ -87267,9 +87993,20 @@ class AgentProcessManager {
87267
87993
  console.log(`[AgentProcessManager] ⛔ Terminal provider error for ${opts.role} — emitted agent.startFailed`);
87268
87994
  return;
87269
87995
  }
87270
- const emitted = await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.harness, "turn-end");
87271
- if (emitted) {
87272
- console.log(`[AgentProcessManager] ✅ Native harness idle for ${opts.role} (native:waiting)`);
87996
+ try {
87997
+ const result = await this.deps.backend.mutation(api.participants.handleNativeAgentEnd, {
87998
+ sessionId: this.deps.sessionId,
87999
+ chatroomId: opts.chatroomId,
88000
+ role: opts.role
88001
+ });
88002
+ if (result?.needsHandoffReminder) {
88003
+ await this.injectHarnessReminder(opts.chatroomId, opts.role, NATIVE_HANDOFF_REMINDER);
88004
+ console.log(`[AgentProcessManager] ⏩ Handoff reminder injected for ${opts.role}`);
88005
+ return;
88006
+ }
88007
+ console.log(`[AgentProcessManager] ✅ Native agent_end handled for ${opts.role}`);
88008
+ } catch (err) {
88009
+ console.log(` ⚠️ Failed native agent_end for ${opts.role}: ${err.message}`);
87273
88010
  }
87274
88011
  }
87275
88012
  async handleExit(opts) {
@@ -88035,25 +88772,9 @@ class AgentProcessManager {
88035
88772
  this.registerSpawnCallbacks(slot, opts, spawnResult, pid);
88036
88773
  await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
88037
88774
  }
88038
- async emitNativeWaiting(chatroomId, role, harness, reason = "spawn") {
88775
+ async emitNativeWaiting(chatroomId, role, harness) {
88039
88776
  if (!getHarnessCapabilities(harness).supportsNativeIntegration)
88040
88777
  return false;
88041
- if (reason === "turn-end") {
88042
- try {
88043
- const participant = await this.deps.backend.query(api.participants.getByRole, {
88044
- sessionId: this.deps.sessionId,
88045
- chatroomId,
88046
- role
88047
- });
88048
- if (!shouldEmitNativeWaitingOnTurnEnd(participant?.lastStatus)) {
88049
- console.log(`[AgentProcessManager] Skipping native:waiting for ${role} — active work (${participant?.lastStatus})`);
88050
- return false;
88051
- }
88052
- } catch (err) {
88053
- console.log(` ⚠️ Failed to check status before native:waiting for ${role}: ${err.message}`);
88054
- return false;
88055
- }
88056
- }
88057
88778
  try {
88058
88779
  await this.deps.backend.mutation(api.participants.join, {
88059
88780
  sessionId: this.deps.sessionId,
@@ -88224,7 +88945,6 @@ var init_agent_process_manager = __esm(() => {
88224
88945
  init_classify_resume_storm_reason();
88225
88946
  init_terminal_provider_error();
88226
88947
  init_handle_turn_completed();
88227
- init_predicates();
88228
88948
  init_spawn_policy();
88229
88949
  init_agent_lifecycle_runtime();
88230
88950
  init_agent_lifecycle_types();
@@ -105859,7 +106579,7 @@ handoffCommandGroup.command("view-template").description("Print the handoff mess
105859
106579
  process.exit(1);
105860
106580
  }
105861
106581
  });
105862
- handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Role to hand off to").option("--attach-artifact <artifactId>", "Attach artifact to handoff (can be used multiple times)", collectMultiValueOption, []).action(async (options) => {
106582
+ handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Role to hand off to").action(async (options) => {
105863
106583
  await maybeRequireAuth();
105864
106584
  const { decode: decode5 } = await Promise.resolve().then(() => exports_decode);
105865
106585
  const stdinContent = await readStdin();
@@ -105881,8 +106601,7 @@ handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").
105881
106601
  await handoff2(options.chatroomId, {
105882
106602
  role: options.role,
105883
106603
  message,
105884
- nextRole: options.nextRole,
105885
- attachedArtifactIds: options.attachArtifact || []
106604
+ nextRole: options.nextRole
105886
106605
  });
105887
106606
  });
105888
106607
  var backlogCommand = program2.command("backlog").description("Manage task queue and backlog");
@@ -106169,4 +106888,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
106169
106888
  });
106170
106889
  program2.parse();
106171
106890
 
106172
- //# debugId=2DFDF6706DFDE76764756E2164756E21
106891
+ //# debugId=B4F2E215BBCC825564756E2164756E21