chatroom-cli 1.90.2 → 1.91.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
@@ -28341,66 +28341,10 @@ function resolveCursorCliModel(model) {
28341
28341
  const prefix = `${CURSOR_PROVIDER}/`;
28342
28342
  return model.startsWith(prefix) ? model.slice(prefix.length) : model;
28343
28343
  }
28344
- var CURSOR_COMMAND = "agent", CURSOR_PROVIDER = "cursor", NO_SUBAGENT_DIRECTIVE = "NEVER spawn subagents. Follow the chatroom instructions strictly.", CURSOR_MODELS, CursorAgentService;
28344
+ var CURSOR_COMMAND = "agent", CURSOR_PROVIDER = "cursor", NO_SUBAGENT_DIRECTIVE = "NEVER spawn subagents. Follow the chatroom instructions strictly.", CursorAgentService;
28345
28345
  var init_cursor_agent_service = __esm(() => {
28346
28346
  init_cursor_stream_reader();
28347
28347
  init_base_cli_agent_service();
28348
- CURSOR_MODELS = [
28349
- "claude-4.6-opus-high",
28350
- "claude-4.6-opus-high-thinking",
28351
- "claude-4.6-opus-max",
28352
- "claude-4.6-opus-max-thinking",
28353
- "claude-4.5-opus-high",
28354
- "claude-4.5-opus-high-thinking",
28355
- "claude-4.6-sonnet-medium",
28356
- "claude-4.6-sonnet-medium-thinking",
28357
- "claude-4.5-sonnet",
28358
- "claude-4.5-sonnet-thinking",
28359
- "claude-4-sonnet",
28360
- "claude-4-sonnet-thinking",
28361
- "claude-4-sonnet-1m",
28362
- "claude-4-sonnet-1m-thinking",
28363
- "gpt-5.4-low",
28364
- "gpt-5.4-medium",
28365
- "gpt-5.4-medium-fast",
28366
- "gpt-5.4-high",
28367
- "gpt-5.4-high-fast",
28368
- "gpt-5.4-xhigh",
28369
- "gpt-5.4-xhigh-fast",
28370
- "gpt-5.3-codex-low",
28371
- "gpt-5.3-codex-low-fast",
28372
- "gpt-5.3-codex",
28373
- "gpt-5.3-codex-fast",
28374
- "gpt-5.3-codex-high",
28375
- "gpt-5.3-codex-high-fast",
28376
- "gpt-5.3-codex-xhigh",
28377
- "gpt-5.3-codex-xhigh-fast",
28378
- "gpt-5.3-codex-spark-preview",
28379
- "gpt-5.2",
28380
- "gpt-5.2-high",
28381
- "gpt-5.2-codex-low",
28382
- "gpt-5.2-codex-low-fast",
28383
- "gpt-5.2-codex",
28384
- "gpt-5.2-codex-fast",
28385
- "gpt-5.2-codex-high",
28386
- "gpt-5.2-codex-high-fast",
28387
- "gpt-5.2-codex-xhigh",
28388
- "gpt-5.2-codex-xhigh-fast",
28389
- "gpt-5.1-high",
28390
- "gpt-5.1-codex-max",
28391
- "gpt-5.1-codex-max-high",
28392
- "gpt-5.1-codex-mini",
28393
- "gemini-3.1-pro",
28394
- "gemini-3-pro",
28395
- "gemini-3-flash",
28396
- "grok",
28397
- "kimi-k2.5",
28398
- "auto",
28399
- "composer-2.5",
28400
- "composer-2",
28401
- "composer-1.5",
28402
- "composer-1"
28403
- ];
28404
28348
  CursorAgentService = class CursorAgentService extends BaseCLIAgentService {
28405
28349
  id = "cursor";
28406
28350
  displayName = "Cursor";
@@ -28415,7 +28359,7 @@ var init_cursor_agent_service = __esm(() => {
28415
28359
  return this.checkVersion(CURSOR_COMMAND);
28416
28360
  }
28417
28361
  async listModels() {
28418
- return CURSOR_MODELS;
28362
+ return [];
28419
28363
  }
28420
28364
  async spawn(options) {
28421
28365
  const args2 = ["-p", "--force", "--output-format", "stream-json"];
@@ -28617,18 +28561,7 @@ var init_copilot_agent_service = __esm(() => {
28617
28561
  return this.checkVersion(COPILOT_COMMAND);
28618
28562
  }
28619
28563
  async listModels() {
28620
- return [
28621
- "claude-3-5-sonnet-20241022",
28622
- "claude-3-5-haiku-20241022",
28623
- "claude-haiku-4.5",
28624
- "claude-sonnet-4-6",
28625
- "claude-opus-4-6",
28626
- "gpt-4o",
28627
- "gpt-4o-mini",
28628
- "gpt-4-turbo",
28629
- "gemini-3-pro-preview",
28630
- "gemini-2-5-flash"
28631
- ];
28564
+ return [];
28632
28565
  }
28633
28566
  async spawn(options) {
28634
28567
  const { prompt } = options;
@@ -29826,6 +29759,999 @@ var init_claude_sdk = __esm(() => {
29826
29759
  init_claude_sdk_agent_service();
29827
29760
  });
29828
29761
 
29762
+ // ../../services/backend/src/domain/entities/harness/codex-sdk.model-variants.ts
29763
+ var CODEX_MODEL_VARIANT_COMBINATIONS;
29764
+ var init_codex_sdk_model_variants = __esm(() => {
29765
+ CODEX_MODEL_VARIANT_COMBINATIONS = [
29766
+ {},
29767
+ { reasoning: "none" },
29768
+ { reasoning: "low" },
29769
+ { reasoning: "medium" },
29770
+ { reasoning: "high" },
29771
+ { reasoning: "xhigh" }
29772
+ ];
29773
+ });
29774
+
29775
+ // ../../services/backend/src/domain/entities/harness/model-variant.ts
29776
+ function parseParamList(encoded, paramsPart) {
29777
+ const params = {};
29778
+ for (const param of paramsPart.split(",")) {
29779
+ if (!PARAM_RE.test(param)) {
29780
+ throw new ModelVariantParseError(`malformed variant param "${param}" in "${encoded}" (expected key=value)`);
29781
+ }
29782
+ const eq = param.indexOf("=");
29783
+ const key = param.slice(0, eq);
29784
+ if (Object.prototype.hasOwnProperty.call(params, key)) {
29785
+ throw new ModelVariantParseError(`duplicate variant param "${key}" in "${encoded}"`);
29786
+ }
29787
+ params[key] = param.slice(eq + 1);
29788
+ }
29789
+ return params;
29790
+ }
29791
+ function decodeModelVariant(encoded) {
29792
+ if (encoded.length === 0) {
29793
+ throw new ModelVariantParseError("empty model variant");
29794
+ }
29795
+ const match17 = MODEL_VARIANT_RE.exec(encoded);
29796
+ if (!match17) {
29797
+ throw new ModelVariantParseError(`malformed model variant: "${encoded}"`);
29798
+ }
29799
+ const [, model, paramsPart] = match17;
29800
+ if (paramsPart === undefined) {
29801
+ return { model, params: {} };
29802
+ }
29803
+ return { model, params: parseParamList(encoded, paramsPart) };
29804
+ }
29805
+ function describeCombination(combo) {
29806
+ const entries2 = Object.entries(combo);
29807
+ return entries2.length === 0 ? "no params" : entries2.map(([k, v3]) => `${k}=${v3}`).join(",");
29808
+ }
29809
+ function validateModelVariantParams(variant, schema) {
29810
+ const supported = schema.find((combo) => Object.keys(combo).length === Object.keys(variant.params).length && Object.entries(combo).every(([key, value]) => variant.params[key] === value));
29811
+ if (!supported) {
29812
+ throw new ModelVariantValidationError(`unsupported variant params for model "${variant.model}": ` + `${describeCombination(variant.params)}; ` + `allowed: ${schema.map(describeCombination).join(" | ")}`);
29813
+ }
29814
+ return variant;
29815
+ }
29816
+ var ModelVariantParseError, ModelVariantValidationError, MODEL_VARIANT_RE, PARAM_RE;
29817
+ var init_model_variant = __esm(() => {
29818
+ ModelVariantParseError = class ModelVariantParseError extends Error {
29819
+ code = "MODEL_VARIANT_PARSE";
29820
+ constructor(message) {
29821
+ super(message);
29822
+ this.name = "ModelVariantParseError";
29823
+ }
29824
+ };
29825
+ ModelVariantValidationError = class ModelVariantValidationError extends Error {
29826
+ code = "MODEL_VARIANT_VALIDATION";
29827
+ constructor(message) {
29828
+ super(message);
29829
+ this.name = "ModelVariantValidationError";
29830
+ }
29831
+ };
29832
+ MODEL_VARIANT_RE = /^([^\[\]]+?)(?:\[([^\]]*)\])?$/;
29833
+ PARAM_RE = /^[A-Za-z0-9_-]+=[^,\[\]\=]+$/;
29834
+ });
29835
+
29836
+ // src/daemon/infrastructure/local/harness/services/codex-sdk/codex-sdk-package.ts
29837
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
29838
+ import { createRequire as createRequire4 } from "node:module";
29839
+ import { dirname as dirname3, join as join8 } from "node:path";
29840
+ import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
29841
+ function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
29842
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
29843
+ let dir = dirname3(filePath);
29844
+ while (dir !== dirname3(dir)) {
29845
+ const packageJsonPath = join8(dir, "package.json");
29846
+ if (existsSync2(packageJsonPath)) {
29847
+ const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
29848
+ if (pkg.name === "chatroom-cli") {
29849
+ return dir;
29850
+ }
29851
+ }
29852
+ dir = dirname3(dir);
29853
+ }
29854
+ throw new CodexSdkPackageError(`Could not locate chatroom-cli package root while resolving @openai/codex-sdk. ${REINSTALL_HINT2}`);
29855
+ }
29856
+ function readPinnedSdkVersion2(chatroomCliRoot) {
29857
+ const pkg = JSON.parse(readFileSync4(join8(chatroomCliRoot, "package.json"), "utf8"));
29858
+ const specifier = pkg.dependencies?.["@openai/codex-sdk"];
29859
+ const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
29860
+ const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
29861
+ if (!match17) {
29862
+ throw new CodexSdkPackageError(`chatroom-cli must pin an exact @openai/codex-sdk version (found "${specifier ?? "none"}"). ${REINSTALL_HINT2}`);
29863
+ }
29864
+ return match17[1];
29865
+ }
29866
+ function readInstalledSdkVersion2(packageJsonPath) {
29867
+ const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
29868
+ return pkg.version;
29869
+ }
29870
+ function resolveCodexSdkPackageJson(chatroomCliRoot) {
29871
+ const require3 = createRequire4(join8(chatroomCliRoot, "package.json"));
29872
+ try {
29873
+ return require3.resolve("@openai/codex-sdk/package.json", { paths: [chatroomCliRoot] });
29874
+ } catch {
29875
+ const candidate = join8(chatroomCliRoot, "node_modules", "@openai", "codex-sdk", "package.json");
29876
+ if (existsSync2(candidate)) {
29877
+ return candidate;
29878
+ }
29879
+ throw new CodexSdkPackageError(`Could not locate @openai/codex-sdk package.json from ${chatroomCliRoot}. ${REINSTALL_HINT2}`);
29880
+ }
29881
+ }
29882
+ async function importBundledCodexSdk(moduleRef = import.meta.url) {
29883
+ const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
29884
+ const pinnedVersion = readPinnedSdkVersion2(chatroomCliRoot);
29885
+ const packageJsonPath = resolveCodexSdkPackageJson(chatroomCliRoot);
29886
+ const installedVersion = readInstalledSdkVersion2(packageJsonPath);
29887
+ if (installedVersion !== pinnedVersion) {
29888
+ throw new CodexSdkPackageError(`@openai/codex-sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT2}`);
29889
+ }
29890
+ const entryPath = join8(dirname3(packageJsonPath), "dist", "index.js");
29891
+ if (!existsSync2(entryPath)) {
29892
+ throw new CodexSdkPackageError(`@openai/codex-sdk entry file is missing: ${entryPath}. ${REINSTALL_HINT2}`);
29893
+ }
29894
+ return import(pathToFileURL2(entryPath).href);
29895
+ }
29896
+ function getBundledCodexSdkVersion(moduleRef = import.meta.url) {
29897
+ const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
29898
+ return readInstalledSdkVersion2(resolveCodexSdkPackageJson(chatroomCliRoot));
29899
+ }
29900
+ function formatCodexSdkError(err) {
29901
+ if (err instanceof Error) {
29902
+ const sdkErr = err;
29903
+ const code2 = sdkErr.code ? `[${sdkErr.code}] ` : "";
29904
+ const name = sdkErr.name && sdkErr.name !== "Error" ? `${sdkErr.name}: ` : "";
29905
+ return `${name}${code2}${err.message}`.trim();
29906
+ }
29907
+ return String(err);
29908
+ }
29909
+ function formatCodexSdkLoadError(err) {
29910
+ if (err instanceof CodexSdkPackageError) {
29911
+ return err.message;
29912
+ }
29913
+ return formatCodexSdkError(err);
29914
+ }
29915
+ var REINSTALL_HINT2 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", CodexSdkPackageError;
29916
+ var init_codex_sdk_package = __esm(() => {
29917
+ CodexSdkPackageError = class CodexSdkPackageError extends Error {
29918
+ code = "CODEX_SDK_PACKAGE_INCOMPLETE";
29919
+ constructor(message) {
29920
+ super(message);
29921
+ this.name = "CodexSdkPackageError";
29922
+ }
29923
+ };
29924
+ });
29925
+
29926
+ // src/daemon/domain/usecase/detect-terminal-provider-error.ts
29927
+ function matchesQuotaPhrase(blob) {
29928
+ const text = blob.toLowerCase();
29929
+ return QUOTA_PHRASES.some((phrase) => text.includes(phrase));
29930
+ }
29931
+ function matchesStructuredProviderErrorText(blob) {
29932
+ const text = blob.toLowerCase();
29933
+ const hasProviderName = PROVIDER_ERROR_NAMES.some((name) => text.includes(name));
29934
+ return hasProviderName && matchesQuotaPhrase(blob);
29935
+ }
29936
+ function matchesFatalHarnessErrorText(blob) {
29937
+ const text = blob.toLowerCase();
29938
+ return FATAL_HARNESS_PHRASES.some((phrase) => text.includes(phrase));
29939
+ }
29940
+ function matchesTerminalProviderErrorText(blob) {
29941
+ return matchesQuotaPhrase(blob) || matchesStructuredProviderErrorText(blob);
29942
+ }
29943
+ function isNonRetryableHarnessFailureText(blob) {
29944
+ return matchesTerminalProviderErrorText(blob) || matchesFatalHarnessErrorText(blob);
29945
+ }
29946
+ function isTerminalProviderError(error) {
29947
+ if (typeof error === "string") {
29948
+ return isNonRetryableHarnessFailureText(error);
29949
+ }
29950
+ if (!error || typeof error !== "object") {
29951
+ return false;
29952
+ }
29953
+ const e = error;
29954
+ if (typeof e.error === "string" && isNonRetryableHarnessFailureText(e.error)) {
29955
+ return true;
29956
+ }
29957
+ const name = extractName(e);
29958
+ const message = extractMessage(e);
29959
+ return matchesQuotaPhrase(message) || matchesQuotaPhrase(`${name} ${message}`) || matchesFatalHarnessErrorText(message) || matchesFatalHarnessErrorText(`${name} ${message}`);
29960
+ }
29961
+ function isClassifiableHarnessLogLine(line) {
29962
+ if (/\b(?:text|thinking)\]/.test(line))
29963
+ return false;
29964
+ if (/\btool:/.test(line))
29965
+ return false;
29966
+ if (line.includes("agent_end]"))
29967
+ return true;
29968
+ if (line.includes("spawn-error]"))
29969
+ return true;
29970
+ if (line.includes(" error]"))
29971
+ return true;
29972
+ if (line.includes(" run-error]"))
29973
+ return true;
29974
+ return false;
29975
+ }
29976
+ function extractName(e) {
29977
+ const name = e.name;
29978
+ if (typeof name === "string")
29979
+ return name.toLowerCase();
29980
+ const type = e.type;
29981
+ if (typeof type === "string")
29982
+ return type.toLowerCase();
29983
+ return "";
29984
+ }
29985
+ function extractMessage(e) {
29986
+ const fromData = messageFromData(e.data);
29987
+ if (fromData)
29988
+ return fromData;
29989
+ if (typeof e.message === "string")
29990
+ return e.message.toLowerCase();
29991
+ if (typeof e.responseBody === "string")
29992
+ return e.responseBody.toLowerCase();
29993
+ if (typeof e.error === "string")
29994
+ return e.error.toLowerCase();
29995
+ if (e.error && typeof e.error === "object") {
29996
+ return extractMessage(e.error);
29997
+ }
29998
+ return "";
29999
+ }
30000
+ function messageFromData(data) {
30001
+ if (!data || typeof data !== "object")
30002
+ return;
30003
+ const msg = data.message;
30004
+ return typeof msg === "string" ? msg.toLowerCase() : undefined;
30005
+ }
30006
+ var FATAL_HARNESS_PHRASES, QUOTA_PHRASES, PROVIDER_ERROR_NAMES;
30007
+ var init_detect_terminal_provider_error = __esm(() => {
30008
+ FATAL_HARNESS_PHRASES = [
30009
+ "failed to load model",
30010
+ "model loading was stopped",
30011
+ "insufficient system resources",
30012
+ "sandboxing is not supported",
30013
+ "disable local.sandboxoptions.enabled"
30014
+ ];
30015
+ QUOTA_PHRASES = [
30016
+ "usagelimit",
30017
+ "usage limit",
30018
+ "enable usage from your available balance",
30019
+ "rate limit",
30020
+ "ratelimit",
30021
+ "too many requests",
30022
+ "x-ratelimit-exceeded",
30023
+ "weekly rate limit",
30024
+ "exceeded your weekly"
30025
+ ];
30026
+ PROVIDER_ERROR_NAMES = ["ai_apicallerror", "ai_retryerror"];
30027
+ });
30028
+
30029
+ // src/daemon/domain/usecase/classify-provider-error.ts
30030
+ function providerUnavailableAgentEndReason(reason) {
30031
+ if (reason === "model_capacity")
30032
+ return PROVIDER_MODEL_CAPACITY_AGENT_END;
30033
+ if (reason === "rate_limit")
30034
+ return "provider_rate_limit";
30035
+ return "provider_quota";
30036
+ }
30037
+ function includesPhrase(message, phrases) {
30038
+ const normalized = message.toLowerCase();
30039
+ return phrases.some((phrase) => normalized.includes(phrase));
30040
+ }
30041
+ function classification(reason, message) {
30042
+ return { reason, message: message.trim(), recoverable: providerUnavailableRecoverable(reason) };
30043
+ }
30044
+ function classifyProviderErrorMessage(message) {
30045
+ if (includesPhrase(message, MODEL_CAPACITY_PHRASES)) {
30046
+ return classification("model_capacity", message);
30047
+ }
30048
+ if (includesPhrase(message, RATE_LIMIT_PHRASES)) {
30049
+ return classification("rate_limit", message);
30050
+ }
30051
+ if (includesPhrase(message, QUOTA_PHRASES2)) {
30052
+ return classification("quota", message);
30053
+ }
30054
+ return null;
30055
+ }
30056
+ function classifyProviderErrorLogLine(line) {
30057
+ if (!isClassifiableHarnessLogLine(line))
30058
+ return null;
30059
+ const marker = isProviderUnavailableAgentEndReason(line);
30060
+ if (marker)
30061
+ return classification(marker, line);
30062
+ return classifyProviderErrorMessage(line);
30063
+ }
30064
+ function classifyProviderErrorFromLogs(logLines) {
30065
+ for (let index = logLines.length - 1;index >= 0; index -= 1) {
30066
+ const result = classifyProviderErrorLogLine(logLines[index]);
30067
+ if (result)
30068
+ return result;
30069
+ }
30070
+ return null;
30071
+ }
30072
+ function isProviderUnavailableAgentEndReason(reason) {
30073
+ const normalized = reason.toLowerCase();
30074
+ if (normalized.includes(PROVIDER_MODEL_CAPACITY_AGENT_END))
30075
+ return "model_capacity";
30076
+ if (normalized.includes("provider_rate_limit"))
30077
+ return "rate_limit";
30078
+ if (normalized.includes("provider_quota"))
30079
+ return "quota";
30080
+ return null;
30081
+ }
30082
+ function providerUnavailableRecoverable(reason) {
30083
+ return reason !== "quota";
30084
+ }
30085
+ var PROVIDER_MODEL_CAPACITY_AGENT_END = "provider_model_capacity", MODEL_CAPACITY_PHRASES, RATE_LIMIT_PHRASES, QUOTA_PHRASES2;
30086
+ var init_classify_provider_error = __esm(() => {
30087
+ init_detect_terminal_provider_error();
30088
+ MODEL_CAPACITY_PHRASES = ["selected model is at capacity", "model is at capacity"];
30089
+ RATE_LIMIT_PHRASES = [
30090
+ "rate limit",
30091
+ "ratelimit",
30092
+ "too many requests",
30093
+ "x-ratelimit-exceeded",
30094
+ "weekly rate limit"
30095
+ ];
30096
+ QUOTA_PHRASES2 = [
30097
+ "usagelimit",
30098
+ "usage limit",
30099
+ "enable usage from your available balance",
30100
+ "exceeded your weekly"
30101
+ ];
30102
+ });
30103
+
30104
+ // src/daemon/infrastructure/local/harness/services/codex-sdk/codex-sdk-stream-adapter.ts
30105
+ var CodexSdkStreamAdapter;
30106
+ var init_codex_sdk_stream_adapter = __esm(() => {
30107
+ init_classify_provider_error();
30108
+ init_native_stream_adapter_base();
30109
+ CodexSdkStreamAdapter = class CodexSdkStreamAdapter extends NativeStreamAdapterBase {
30110
+ textBuffer = "";
30111
+ handleEvent(event) {
30112
+ this.notifyOutput();
30113
+ switch (event.type) {
30114
+ case "item.started":
30115
+ case "item.updated":
30116
+ case "item.completed":
30117
+ this.handleItem(event.item);
30118
+ break;
30119
+ case "turn.completed":
30120
+ break;
30121
+ case "turn.failed":
30122
+ this.flushText();
30123
+ this.writeProviderUnavailableMarker(event.error.message);
30124
+ this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", event.error.message));
30125
+ break;
30126
+ case "error":
30127
+ this.flushText();
30128
+ this.writeProviderUnavailableMarker(event.message);
30129
+ this.writeLine(formatAgentLogLine(this.logPrefix, "run-error", event.message));
30130
+ break;
30131
+ case "thread.started":
30132
+ case "turn.started":
30133
+ default:
30134
+ break;
30135
+ }
30136
+ }
30137
+ finish() {
30138
+ this.flushText();
30139
+ this.emitAgentEnd();
30140
+ }
30141
+ handleItem(item) {
30142
+ switch (item.type) {
30143
+ case "agent_message":
30144
+ this.appendAssistantText(item.text);
30145
+ break;
30146
+ case "reasoning":
30147
+ this.logReasoning(item);
30148
+ break;
30149
+ case "command_execution":
30150
+ this.logCommandExecution(item);
30151
+ break;
30152
+ case "file_change":
30153
+ this.logFileChange(item);
30154
+ break;
30155
+ case "mcp_tool_call":
30156
+ this.logMcpToolCall(item);
30157
+ break;
30158
+ case "web_search":
30159
+ this.logWebSearch(item);
30160
+ break;
30161
+ case "error":
30162
+ this.flushText();
30163
+ this.writeLine(formatAgentLogLine(this.logPrefix, "error", item.message));
30164
+ break;
30165
+ case "todo_list":
30166
+ break;
30167
+ default:
30168
+ break;
30169
+ }
30170
+ }
30171
+ logReasoning(item) {
30172
+ this.flushText();
30173
+ this.writeLine(formatAgentLogLine(this.logPrefix, "thinking", item.text));
30174
+ }
30175
+ logCommandExecution(item) {
30176
+ this.flushText();
30177
+ this.writeLine(formatAgentLogLine(this.logPrefix, BASH_TOOL_KIND, formatBashRunningPayload(item.command)));
30178
+ if (item.aggregated_output && item.aggregated_output.trim().length > 0) {
30179
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool-output", item.aggregated_output));
30180
+ }
30181
+ if (item.status === "failed") {
30182
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool-error", `${item.command} exited with ${item.exit_code ?? "unknown"}`));
30183
+ }
30184
+ }
30185
+ logFileChange(item) {
30186
+ this.flushText();
30187
+ const summary5 = item.changes.map((change) => `${change.kind} ${change.path}`).join(", ");
30188
+ this.writeLine(formatAgentLogLine(this.logPrefix, "file", `${summary5}${item.status === "failed" ? " (patch failed)" : ""}`));
30189
+ }
30190
+ logMcpToolCall(item) {
30191
+ this.flushText();
30192
+ if (item.status === "failed" || item.error) {
30193
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool-error", `${item.server}/${item.tool}: ${item.error?.message ?? "failed"}`));
30194
+ return;
30195
+ }
30196
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool", `${item.server}/${item.tool} ${JSON.stringify(item.arguments ?? {})}`));
30197
+ }
30198
+ logWebSearch(item) {
30199
+ this.flushText();
30200
+ this.writeLine(formatAgentLogLine(this.logPrefix, "tool: web_search", item.query));
30201
+ }
30202
+ appendAssistantText(text) {
30203
+ this.textBuffer += text;
30204
+ this.assistantTextCapture.captureAssistantText(text);
30205
+ if (this.textBuffer.includes(`
30206
+ `))
30207
+ this.flushText();
30208
+ }
30209
+ flushText() {
30210
+ if (!this.textBuffer)
30211
+ return;
30212
+ for (const line of this.textBuffer.split(`
30213
+ `)) {
30214
+ if (line)
30215
+ this.writeLine(formatAgentLogLine(this.logPrefix, "text", line));
30216
+ }
30217
+ this.textBuffer = "";
30218
+ }
30219
+ emitAgentEnd() {
30220
+ if (this.agentEndEmitted)
30221
+ return;
30222
+ this.agentEndEmitted = true;
30223
+ this.flushText();
30224
+ this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end"));
30225
+ for (const cb of this.agentEndCallbacks)
30226
+ cb();
30227
+ }
30228
+ writeProviderUnavailableMarker(message) {
30229
+ const classification2 = classifyProviderErrorMessage(message);
30230
+ if (!classification2)
30231
+ return;
30232
+ this.writeLine(formatAgentLogLine(this.logPrefix, "agent_end", `reason: ${providerUnavailableAgentEndReason(classification2.reason)}`));
30233
+ }
30234
+ writeLine(formatted) {
30235
+ process.stdout.write(`${formatted}
30236
+ `);
30237
+ this.emitLogLine?.(formatted);
30238
+ }
30239
+ };
30240
+ });
30241
+
30242
+ // src/daemon/infrastructure/local/harness/services/codex-sdk/codex-sdk-agent-service.ts
30243
+ import { randomUUID as randomUUID2 } from "node:crypto";
30244
+ async function loadSdk2() {
30245
+ if (_sdkCache2)
30246
+ return _sdkCache2;
30247
+ if (_sdkLoadError2)
30248
+ throw _sdkLoadError2;
30249
+ try {
30250
+ _sdkCache2 = await importBundledCodexSdk();
30251
+ return _sdkCache2;
30252
+ } catch (err) {
30253
+ _sdkLoadError2 = err;
30254
+ throw err;
30255
+ }
30256
+ }
30257
+ function getSdkPackageVersion2() {
30258
+ if (cachedSdkPackageVersion2)
30259
+ return cachedSdkPackageVersion2;
30260
+ cachedSdkPackageVersion2 = getBundledCodexSdkVersion();
30261
+ return cachedSdkPackageVersion2;
30262
+ }
30263
+ function buildAgentName(context5) {
30264
+ return `${context5.role}@${context5.chatroomId.slice(-6)}`;
30265
+ }
30266
+ function decodeCodexVariant(encoded) {
30267
+ if (encoded === undefined)
30268
+ return;
30269
+ return validateModelVariantParams(decodeModelVariant(encoded), CODEX_MODEL_VARIANT_COMBINATIONS);
30270
+ }
30271
+ function buildThreadOptions(workingDir, variant) {
30272
+ const options = {
30273
+ workingDirectory: workingDir,
30274
+ skipGitRepoCheck: true,
30275
+ sandboxMode: "danger-full-access",
30276
+ networkAccessEnabled: true
30277
+ };
30278
+ if (!variant)
30279
+ return options;
30280
+ options.model = variant.model;
30281
+ const reasoning = variant.params.reasoning;
30282
+ if (reasoning !== undefined && reasoning !== "none") {
30283
+ options.modelReasoningEffort = reasoning;
30284
+ }
30285
+ return options;
30286
+ }
30287
+ function buildCodexEnv(resolvedConvexUrl) {
30288
+ return Object.fromEntries(Object.entries(buildAgentSpawnEnv(resolvedConvexUrl)).filter((entry) => entry[1] !== undefined));
30289
+ }
30290
+ function waitForResumeOrAbort2(session2) {
30291
+ if (session2.aborted)
30292
+ return Promise.resolve(null);
30293
+ const queued = session2.pendingResumePrompt;
30294
+ if (queued !== undefined) {
30295
+ session2.pendingResumePrompt = undefined;
30296
+ return Promise.resolve(queued);
30297
+ }
30298
+ return Promise.race([
30299
+ new Promise((resolve2) => {
30300
+ session2.resumeResolve = (prompt) => {
30301
+ session2.resumeResolve = undefined;
30302
+ session2.abortResolve = undefined;
30303
+ resolve2(prompt);
30304
+ };
30305
+ }),
30306
+ new Promise((resolve2) => {
30307
+ session2.abortResolve = () => {
30308
+ session2.resumeResolve = undefined;
30309
+ session2.abortResolve = undefined;
30310
+ resolve2(null);
30311
+ };
30312
+ })
30313
+ ]);
30314
+ }
30315
+ function writeSpawnError2(logPrefix, err, emitLogLine) {
30316
+ const line = formatAgentLogLine(logPrefix, "spawn-error", formatCodexSdkError(err));
30317
+ process.stderr.write(`${line}
30318
+ `);
30319
+ emitLogLine?.(line);
30320
+ console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
30321
+ }
30322
+ function notifyResumableThreadId(threadId, session2, correlationId, callbacks) {
30323
+ if (session2.threadId === threadId) {
30324
+ return;
30325
+ }
30326
+ session2.threadId = threadId;
30327
+ const info = {
30328
+ correlationId,
30329
+ resumableId: threadId,
30330
+ source: "provider_allocated"
30331
+ };
30332
+ for (const cb of callbacks) {
30333
+ cb(info);
30334
+ }
30335
+ }
30336
+ var CODEX_SDK_COMMAND = "codex", TURN_TIMEOUT_MS2 = 3600000, _sdkCache2, _sdkLoadError2, cachedSdkPackageVersion2, CodexSdkAgentService;
30337
+ var init_codex_sdk_agent_service = __esm(() => {
30338
+ init_codex_sdk_model_variants();
30339
+ init_model_variant();
30340
+ init_esm();
30341
+ init_codex_sdk_package();
30342
+ init_codex_sdk_stream_adapter();
30343
+ init_spawn_env();
30344
+ init_base_cli_agent_service();
30345
+ init_detection_result();
30346
+ CodexSdkAgentService = class CodexSdkAgentService extends BaseCLIAgentService {
30347
+ id = "codex-sdk";
30348
+ displayName = "Codex (SDK)";
30349
+ command = CODEX_SDK_COMMAND;
30350
+ sessions = new Map;
30351
+ constructor(deps) {
30352
+ super(deps);
30353
+ }
30354
+ async isInstalled() {
30355
+ try {
30356
+ await loadSdk2();
30357
+ return true;
30358
+ } catch (err) {
30359
+ console.warn(`[codex-sdk] unavailable: ${formatCodexSdkLoadError(err)}`);
30360
+ return false;
30361
+ }
30362
+ }
30363
+ detectInstallationEffect() {
30364
+ return exports_Effect.promise(async () => {
30365
+ const installed2 = await this.isInstalled();
30366
+ return installed2 ? DetectionResult.Installed() : DetectionResult.NotInstalled();
30367
+ });
30368
+ }
30369
+ async getVersion() {
30370
+ const match17 = getSdkPackageVersion2().match(/^(\d+)\.(\d+)\.(\d+)/);
30371
+ if (!match17)
30372
+ return null;
30373
+ return {
30374
+ version: `${match17[1]}.${match17[2]}.${match17[3]}`,
30375
+ major: parseInt(match17[1], 10)
30376
+ };
30377
+ }
30378
+ async listModels() {
30379
+ return [];
30380
+ }
30381
+ async resumeTurn(pid, prompt) {
30382
+ const session2 = this.sessions.get(pid);
30383
+ if (!session2) {
30384
+ throw new Error(`No codex-sdk session for pid=${pid}`);
30385
+ }
30386
+ if (session2.resumeResolve) {
30387
+ const resolve2 = session2.resumeResolve;
30388
+ session2.resumeResolve = undefined;
30389
+ session2.abortResolve = undefined;
30390
+ resolve2(prompt);
30391
+ return;
30392
+ }
30393
+ session2.pendingResumePrompt = prompt;
30394
+ }
30395
+ async stop(pid, _options) {
30396
+ const session2 = this.sessions.get(pid);
30397
+ if (session2) {
30398
+ session2.aborted = true;
30399
+ session2.abortResolve?.();
30400
+ try {
30401
+ session2.abortController?.abort();
30402
+ } catch {}
30403
+ try {
30404
+ session2.keeper.kill();
30405
+ } catch {}
30406
+ this.sessions.delete(pid);
30407
+ }
30408
+ await super.stop(pid);
30409
+ }
30410
+ getHarnessReconnectContext(pid) {
30411
+ const session2 = this.sessions.get(pid);
30412
+ if (!session2) {
30413
+ return;
30414
+ }
30415
+ return {
30416
+ agentName: session2.agentName,
30417
+ ...session2.model ? { model: session2.model } : {}
30418
+ };
30419
+ }
30420
+ spawnKeeper(workingDir) {
30421
+ const keeper = this.deps.spawn(process.execPath, ["-e", "setInterval(()=>{},2147483647)"], {
30422
+ cwd: workingDir,
30423
+ stdio: "ignore",
30424
+ shell: false,
30425
+ detached: true
30426
+ });
30427
+ if (!keeper.pid) {
30428
+ keeper.kill();
30429
+ throw new Error("Failed to spawn codex-sdk keeper process");
30430
+ }
30431
+ return keeper;
30432
+ }
30433
+ startRunningSession(args2) {
30434
+ const {
30435
+ pid,
30436
+ keeper,
30437
+ codex,
30438
+ thread,
30439
+ context: context5,
30440
+ model,
30441
+ initialPrompt,
30442
+ deferInitialTurn = false,
30443
+ storedSystemPrompt,
30444
+ resumedThreadId
30445
+ } = args2;
30446
+ const entry = this.registerProcess(pid, context5);
30447
+ const logPrefix = buildAgentLogPrefix("codex-sdk", context5);
30448
+ const agentName = buildAgentName(context5);
30449
+ const harnessSessionId = randomUUID2();
30450
+ const session2 = {
30451
+ keeper,
30452
+ codex,
30453
+ thread,
30454
+ aborted: false,
30455
+ agentName,
30456
+ model,
30457
+ storedSystemPrompt,
30458
+ ...resumedThreadId ? { threadId: resumedThreadId } : {}
30459
+ };
30460
+ this.sessions.set(pid, session2);
30461
+ const callbacks = this.buildSessionCallbacks(pid, context5);
30462
+ this.runTurnLoop({
30463
+ session: session2,
30464
+ correlationId: harnessSessionId,
30465
+ sessionIdUpdatedCallbacks: callbacks.sessionIdUpdatedCallbacks,
30466
+ entry,
30467
+ logPrefix,
30468
+ initialPrompt,
30469
+ deferInitialTurn,
30470
+ finishExit: callbacks.finishExit,
30471
+ outputCallbacks: callbacks.outputCallbacks,
30472
+ agentEndCallbacks: callbacks.agentEndCallbacks,
30473
+ assistantTextCallbacks: callbacks.assistantTextCallbacks,
30474
+ emitLogLine: callbacks.emitLogLine
30475
+ });
30476
+ return this.buildSpawnResult({
30477
+ pid,
30478
+ harnessSessionId,
30479
+ resumedThreadId,
30480
+ exitCallbacks: callbacks.exitCallbacks,
30481
+ outputCallbacks: callbacks.outputCallbacks,
30482
+ agentEndCallbacks: callbacks.agentEndCallbacks,
30483
+ logLineCallbacks: callbacks.logLineCallbacks,
30484
+ assistantTextCallbacks: callbacks.assistantTextCallbacks,
30485
+ sessionIdUpdatedCallbacks: callbacks.sessionIdUpdatedCallbacks
30486
+ });
30487
+ }
30488
+ buildSessionCallbacks(pid, context5) {
30489
+ const exitCallbacks = [];
30490
+ const outputCallbacks = [];
30491
+ const agentEndCallbacks = [];
30492
+ const logLineCallbacks = [];
30493
+ const assistantTextCallbacks = [];
30494
+ const sessionIdUpdatedCallbacks = [];
30495
+ const emitLogLine = (line) => {
30496
+ for (const cb of logLineCallbacks)
30497
+ cb(line);
30498
+ };
30499
+ const finishExit = (code2, signal) => {
30500
+ this.sessions.delete(pid);
30501
+ this.deleteProcess(pid);
30502
+ for (const cb of exitCallbacks) {
30503
+ cb({ code: code2, signal, context: context5 });
30504
+ }
30505
+ };
30506
+ return {
30507
+ exitCallbacks,
30508
+ outputCallbacks,
30509
+ agentEndCallbacks,
30510
+ logLineCallbacks,
30511
+ assistantTextCallbacks,
30512
+ sessionIdUpdatedCallbacks,
30513
+ emitLogLine,
30514
+ finishExit
30515
+ };
30516
+ }
30517
+ buildSpawnResult(args2) {
30518
+ const {
30519
+ pid,
30520
+ harnessSessionId,
30521
+ resumedThreadId,
30522
+ exitCallbacks,
30523
+ outputCallbacks,
30524
+ agentEndCallbacks,
30525
+ logLineCallbacks,
30526
+ assistantTextCallbacks,
30527
+ sessionIdUpdatedCallbacks
30528
+ } = args2;
30529
+ return {
30530
+ pid,
30531
+ harnessSessionId,
30532
+ onExit: (cb) => {
30533
+ exitCallbacks.push(cb);
30534
+ },
30535
+ onOutput: (cb) => {
30536
+ outputCallbacks.push(cb);
30537
+ },
30538
+ onAgentEnd: (cb) => {
30539
+ agentEndCallbacks.push(cb);
30540
+ },
30541
+ onLogLine: (cb) => {
30542
+ logLineCallbacks.push(cb);
30543
+ },
30544
+ onAssistantText: (cb) => {
30545
+ assistantTextCallbacks.push(cb);
30546
+ },
30547
+ onHarnessSessionIdUpdated: (cb) => {
30548
+ sessionIdUpdatedCallbacks.push(cb);
30549
+ if (resumedThreadId) {
30550
+ cb({
30551
+ correlationId: harnessSessionId,
30552
+ resumableId: resumedThreadId,
30553
+ source: "provider_allocated"
30554
+ });
30555
+ }
30556
+ }
30557
+ };
30558
+ }
30559
+ runTurnLoop(args2) {
30560
+ const {
30561
+ session: session2,
30562
+ correlationId,
30563
+ sessionIdUpdatedCallbacks,
30564
+ logPrefix,
30565
+ initialPrompt,
30566
+ deferInitialTurn = false,
30567
+ finishExit,
30568
+ entry,
30569
+ outputCallbacks,
30570
+ agentEndCallbacks,
30571
+ assistantTextCallbacks,
30572
+ emitLogLine
30573
+ } = args2;
30574
+ let exited = false;
30575
+ (async () => {
30576
+ let exitCode = 0;
30577
+ let exitSignal = null;
30578
+ let nextPrompt = deferInitialTurn ? null : initialPrompt;
30579
+ let prependSystemOnNextResume = deferInitialTurn;
30580
+ const storedSystemPrompt = session2.storedSystemPrompt;
30581
+ try {
30582
+ while (!session2.aborted) {
30583
+ if (nextPrompt === null) {
30584
+ const deferredResume = await waitForResumeOrAbort2(session2);
30585
+ if (deferredResume === null || session2.aborted) {
30586
+ if (session2.aborted) {
30587
+ exitCode = 1;
30588
+ exitSignal = "SIGTERM";
30589
+ }
30590
+ break;
30591
+ }
30592
+ nextPrompt = prependSystemOnNextResume && storedSystemPrompt ? `${storedSystemPrompt}
30593
+
30594
+ ${deferredResume}` : deferredResume;
30595
+ prependSystemOnNextResume = false;
30596
+ }
30597
+ try {
30598
+ await this.runOneTurn({
30599
+ session: session2,
30600
+ prompt: nextPrompt,
30601
+ correlationId,
30602
+ sessionIdUpdatedCallbacks,
30603
+ entry,
30604
+ logPrefix,
30605
+ outputCallbacks,
30606
+ agentEndCallbacks,
30607
+ assistantTextCallbacks,
30608
+ emitLogLine
30609
+ });
30610
+ nextPrompt = null;
30611
+ } catch (turnErr) {
30612
+ exitCode = 1;
30613
+ writeSpawnError2(logPrefix, turnErr, emitLogLine);
30614
+ break;
30615
+ }
30616
+ if (session2.aborted) {
30617
+ exitCode = 1;
30618
+ exitSignal = "SIGTERM";
30619
+ break;
30620
+ }
30621
+ }
30622
+ } catch (err) {
30623
+ exitCode = 1;
30624
+ writeSpawnError2(logPrefix, err, emitLogLine);
30625
+ } finally {
30626
+ if (exited)
30627
+ return;
30628
+ exited = true;
30629
+ try {
30630
+ session2.keeper.kill();
30631
+ } catch {}
30632
+ finishExit(exitCode, exitSignal);
30633
+ }
30634
+ })().catch((err) => {
30635
+ writeSpawnError2(logPrefix, err, emitLogLine);
30636
+ if (exited)
30637
+ return;
30638
+ exited = true;
30639
+ try {
30640
+ session2.keeper.kill();
30641
+ } catch {}
30642
+ finishExit(1, null);
30643
+ });
30644
+ }
30645
+ async runOneTurn(args2) {
30646
+ const {
30647
+ session: session2,
30648
+ prompt,
30649
+ correlationId,
30650
+ sessionIdUpdatedCallbacks,
30651
+ entry,
30652
+ logPrefix,
30653
+ outputCallbacks,
30654
+ agentEndCallbacks,
30655
+ assistantTextCallbacks,
30656
+ emitLogLine
30657
+ } = args2;
30658
+ const adapter = new CodexSdkStreamAdapter(logPrefix, emitLogLine);
30659
+ wireNativeStreamAdapter({
30660
+ adapter,
30661
+ assistantTextCallbacks,
30662
+ outputCallbacks,
30663
+ agentEndCallbacks,
30664
+ entry
30665
+ });
30666
+ const abortController = new AbortController;
30667
+ session2.abortController = abortController;
30668
+ try {
30669
+ await withTimeout((async () => {
30670
+ const { events } = await session2.thread.runStreamed(prompt, {
30671
+ signal: abortController.signal
30672
+ });
30673
+ for await (const event of events) {
30674
+ if (session2.aborted)
30675
+ break;
30676
+ adapter.handleEvent(event);
30677
+ if (event.type === "thread.started") {
30678
+ notifyResumableThreadId(event.thread_id, session2, correlationId, sessionIdUpdatedCallbacks);
30679
+ }
30680
+ }
30681
+ })(), TURN_TIMEOUT_MS2, "thread.runStreamed");
30682
+ } finally {
30683
+ session2.abortController = undefined;
30684
+ }
30685
+ adapter.finish();
30686
+ }
30687
+ async spawn(options) {
30688
+ const variant = decodeCodexVariant(options.model);
30689
+ const deferInitialTurn = options.deferInitialTurn ?? false;
30690
+ const keeper = this.spawnKeeper(options.workingDir);
30691
+ const pid = keeper.pid;
30692
+ const context5 = options.context;
30693
+ const fullPrompt = deferInitialTurn ? "" : `${options.systemPrompt}
30694
+
30695
+ ${options.prompt}`;
30696
+ let codex;
30697
+ let thread;
30698
+ try {
30699
+ const { Codex } = await loadSdk2();
30700
+ codex = new Codex({ env: buildCodexEnv(options.resolvedConvexUrl) });
30701
+ thread = codex.startThread(buildThreadOptions(options.workingDir, variant));
30702
+ } catch (err) {
30703
+ writeSpawnError2(buildAgentLogPrefix("codex-sdk", context5), err);
30704
+ keeper.kill();
30705
+ this.deleteProcess(pid);
30706
+ throw err;
30707
+ }
30708
+ return this.startRunningSession({
30709
+ pid,
30710
+ keeper,
30711
+ codex,
30712
+ thread,
30713
+ context: context5,
30714
+ workingDir: options.workingDir,
30715
+ model: options.model,
30716
+ initialPrompt: fullPrompt,
30717
+ deferInitialTurn,
30718
+ storedSystemPrompt: options.systemPrompt
30719
+ });
30720
+ }
30721
+ async resumeFromDaemonMemory(options, stored) {
30722
+ try {
30723
+ const keeper = this.spawnKeeper(stored.workingDir);
30724
+ const pid = keeper.pid;
30725
+ const variant = decodeCodexVariant(options.model ?? stored.model);
30726
+ const { Codex } = await loadSdk2();
30727
+ const codex = new Codex({ env: buildCodexEnv(options.resolvedConvexUrl) });
30728
+ const thread = codex.resumeThread(stored.harnessSessionId, buildThreadOptions(stored.workingDir, variant));
30729
+ return this.startRunningSession({
30730
+ pid,
30731
+ keeper,
30732
+ codex,
30733
+ thread,
30734
+ context: options.context,
30735
+ workingDir: stored.workingDir,
30736
+ model: options.model ?? stored.model,
30737
+ initialPrompt: options.prompt,
30738
+ storedSystemPrompt: options.systemPrompt,
30739
+ resumedThreadId: stored.harnessSessionId
30740
+ });
30741
+ } catch (err) {
30742
+ writeSpawnError2(buildAgentLogPrefix("codex-sdk", options.context), err, (line) => process.stderr.write(`${line}
30743
+ `));
30744
+ return this.spawn(options);
30745
+ }
30746
+ }
30747
+ };
30748
+ });
30749
+
30750
+ // src/daemon/infrastructure/local/harness/services/codex-sdk/index.ts
30751
+ var init_codex_sdk = __esm(() => {
30752
+ init_codex_sdk_agent_service();
30753
+ });
30754
+
29829
30755
  // src/daemon/infrastructure/local/harness/services/commandcode/command-code-stream-reader.ts
29830
30756
  import { createInterface as createInterface3 } from "node:readline";
29831
30757
 
@@ -30054,68 +30980,68 @@ __export(exports_cursor_sdk_package, {
30054
30980
  formatCursorSdkLoadError: () => formatCursorSdkLoadError,
30055
30981
  formatCursorSdkError: () => formatCursorSdkError
30056
30982
  });
30057
- import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
30058
- import { createRequire as createRequire4 } from "node:module";
30059
- import { dirname as dirname3, join as join8 } from "node:path";
30060
- import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
30061
- function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
30062
- const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
30063
- let dir = dirname3(filePath);
30064
- while (dir !== dirname3(dir)) {
30065
- const packageJsonPath = join8(dir, "package.json");
30066
- if (existsSync2(packageJsonPath)) {
30067
- const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
30983
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
30984
+ import { createRequire as createRequire5 } from "node:module";
30985
+ import { dirname as dirname4, join as join9 } from "node:path";
30986
+ import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
30987
+ function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
30988
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath4(moduleRef) : moduleRef;
30989
+ let dir = dirname4(filePath);
30990
+ while (dir !== dirname4(dir)) {
30991
+ const packageJsonPath = join9(dir, "package.json");
30992
+ if (existsSync3(packageJsonPath)) {
30993
+ const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
30068
30994
  if (pkg.name === "chatroom-cli") {
30069
30995
  return dir;
30070
30996
  }
30071
30997
  }
30072
- dir = dirname3(dir);
30998
+ dir = dirname4(dir);
30073
30999
  }
30074
- throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT2}`);
31000
+ throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT3}`);
30075
31001
  }
30076
- function readPinnedSdkVersion2(chatroomCliRoot) {
30077
- const pkg = JSON.parse(readFileSync4(join8(chatroomCliRoot, "package.json"), "utf8"));
31002
+ function readPinnedSdkVersion3(chatroomCliRoot) {
31003
+ const pkg = JSON.parse(readFileSync5(join9(chatroomCliRoot, "package.json"), "utf8"));
30078
31004
  const specifier = pkg.dependencies?.["@cursor/sdk"];
30079
31005
  const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
30080
31006
  const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
30081
31007
  if (!match17) {
30082
- throw new CursorSdkPackageError(`chatroom-cli must pin an exact @cursor/sdk version (found "${specifier ?? "none"}"). ${REINSTALL_HINT2}`);
31008
+ throw new CursorSdkPackageError(`chatroom-cli must pin an exact @cursor/sdk version (found "${specifier ?? "none"}"). ${REINSTALL_HINT3}`);
30083
31009
  }
30084
31010
  return match17[1];
30085
31011
  }
30086
- function readInstalledSdkVersion2(entryPath) {
30087
- const packageJsonPath = join8(dirname3(entryPath), "..", "..", "package.json");
30088
- const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
31012
+ function readInstalledSdkVersion3(entryPath) {
31013
+ const packageJsonPath = join9(dirname4(entryPath), "..", "..", "package.json");
31014
+ const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
30089
31015
  return pkg.version;
30090
31016
  }
30091
31017
  function resolveSdkEsmImportPath(cjsEntryPath) {
30092
31018
  const importPath = cjsEntryPath.includes("/dist/cjs/") ? cjsEntryPath.replace("/dist/cjs/", "/dist/esm/") : cjsEntryPath;
30093
- if (!existsSync2(importPath)) {
30094
- throw new CursorSdkPackageError(`@cursor/sdk ESM entry file is missing: ${importPath}. ${REINSTALL_HINT2}`);
31019
+ if (!existsSync3(importPath)) {
31020
+ throw new CursorSdkPackageError(`@cursor/sdk ESM entry file is missing: ${importPath}. ${REINSTALL_HINT3}`);
30095
31021
  }
30096
31022
  return importPath;
30097
31023
  }
30098
31024
  async function importBundledCursorSdk(moduleRef = import.meta.url) {
30099
- const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
30100
- const require3 = createRequire4(join8(chatroomCliRoot, "package.json"));
30101
- const pinnedVersion = readPinnedSdkVersion2(chatroomCliRoot);
31025
+ const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
31026
+ const require3 = createRequire5(join9(chatroomCliRoot, "package.json"));
31027
+ const pinnedVersion = readPinnedSdkVersion3(chatroomCliRoot);
30102
31028
  const entryPath = require3.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
30103
- const installedVersion = readInstalledSdkVersion2(entryPath);
31029
+ const installedVersion = readInstalledSdkVersion3(entryPath);
30104
31030
  if (installedVersion !== pinnedVersion) {
30105
- throw new CursorSdkPackageError(`@cursor/sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT2}`);
31031
+ throw new CursorSdkPackageError(`@cursor/sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT3}`);
30106
31032
  }
30107
- if (!existsSync2(entryPath)) {
30108
- throw new CursorSdkPackageError(`@cursor/sdk entry file is missing: ${entryPath}. ${REINSTALL_HINT2}`);
31033
+ if (!existsSync3(entryPath)) {
31034
+ throw new CursorSdkPackageError(`@cursor/sdk entry file is missing: ${entryPath}. ${REINSTALL_HINT3}`);
30109
31035
  }
30110
- const sdk = await import(pathToFileURL2(resolveSdkEsmImportPath(entryPath)).href);
31036
+ const sdk = await import(pathToFileURL3(resolveSdkEsmImportPath(entryPath)).href);
30111
31037
  sdk.configureCursorSdk({ local: { useHttp1ForAgent: true } });
30112
31038
  return sdk;
30113
31039
  }
30114
31040
  function getBundledCursorSdkVersion(moduleRef = import.meta.url) {
30115
- const chatroomCliRoot = resolveChatroomCliRoot2(moduleRef);
30116
- const require3 = createRequire4(join8(chatroomCliRoot, "package.json"));
31041
+ const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
31042
+ const require3 = createRequire5(join9(chatroomCliRoot, "package.json"));
30117
31043
  const entryPath = require3.resolve("@cursor/sdk", { paths: [chatroomCliRoot] });
30118
- return readInstalledSdkVersion2(entryPath);
31044
+ return readInstalledSdkVersion3(entryPath);
30119
31045
  }
30120
31046
  function formatCursorSdkError(err) {
30121
31047
  if (err instanceof Error) {
@@ -30133,11 +31059,11 @@ function formatCursorSdkLoadError(err) {
30133
31059
  const message = formatCursorSdkError(err);
30134
31060
  const chunkMatch = message.match(/(\d+)\.index\.js/);
30135
31061
  if (chunkMatch) {
30136
- return `@cursor/sdk installation is incomplete (missing ${chunkMatch[1]}.index.js). ${REINSTALL_HINT2}`;
31062
+ return `@cursor/sdk installation is incomplete (missing ${chunkMatch[1]}.index.js). ${REINSTALL_HINT3}`;
30137
31063
  }
30138
31064
  return message;
30139
31065
  }
30140
- var REINSTALL_HINT2 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", CursorSdkPackageError;
31066
+ var REINSTALL_HINT3 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", CursorSdkPackageError;
30141
31067
  var init_cursor_sdk_package = __esm(() => {
30142
31068
  CursorSdkPackageError = class CursorSdkPackageError extends Error {
30143
31069
  code = "CURSOR_SDK_PACKAGE_INCOMPLETE";
@@ -30358,30 +31284,30 @@ function tapProcessStreamWrites(onWrite) {
30358
31284
  }
30359
31285
 
30360
31286
  // src/daemon/infrastructure/local/harness/services/cursor-sdk/cursor-sdk-agent-service.ts
30361
- import { randomUUID as randomUUID2 } from "node:crypto";
30362
- async function loadSdk2() {
30363
- if (_sdkCache2)
30364
- return _sdkCache2;
30365
- if (_sdkLoadError2)
30366
- throw _sdkLoadError2;
31287
+ import { randomUUID as randomUUID3 } from "node:crypto";
31288
+ async function loadSdk3() {
31289
+ if (_sdkCache3)
31290
+ return _sdkCache3;
31291
+ if (_sdkLoadError3)
31292
+ throw _sdkLoadError3;
30367
31293
  try {
30368
- _sdkCache2 = await importBundledCursorSdk();
30369
- return _sdkCache2;
31294
+ _sdkCache3 = await importBundledCursorSdk();
31295
+ return _sdkCache3;
30370
31296
  } catch (err) {
30371
- _sdkLoadError2 = err;
31297
+ _sdkLoadError3 = err;
30372
31298
  throw err;
30373
31299
  }
30374
31300
  }
30375
- function getSdkPackageVersion2() {
30376
- if (cachedSdkPackageVersion2)
30377
- return cachedSdkPackageVersion2;
30378
- cachedSdkPackageVersion2 = getBundledCursorSdkVersion();
30379
- return cachedSdkPackageVersion2;
31301
+ function getSdkPackageVersion3() {
31302
+ if (cachedSdkPackageVersion3)
31303
+ return cachedSdkPackageVersion3;
31304
+ cachedSdkPackageVersion3 = getBundledCursorSdkVersion();
31305
+ return cachedSdkPackageVersion3;
30380
31306
  }
30381
- function buildAgentName(context5) {
31307
+ function buildAgentName2(context5) {
30382
31308
  return `${context5.role}@${context5.chatroomId.slice(-6)}`;
30383
31309
  }
30384
- function waitForResumeOrAbort2(session2) {
31310
+ function waitForResumeOrAbort3(session2) {
30385
31311
  if (session2.aborted)
30386
31312
  return Promise.resolve(null);
30387
31313
  const queued = session2.pendingResumePrompt;
@@ -30415,14 +31341,14 @@ function buildLocalAgentOptions(cwd) {
30415
31341
  settingSources: []
30416
31342
  };
30417
31343
  }
30418
- function writeSpawnError2(logPrefix, err, emitLogLine) {
31344
+ function writeSpawnError3(logPrefix, err, emitLogLine) {
30419
31345
  const line = formatAgentLogLine(logPrefix, "spawn-error", formatCursorSdkError(err));
30420
31346
  process.stderr.write(`${line}
30421
31347
  `);
30422
31348
  emitLogLine?.(line);
30423
31349
  console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
30424
31350
  }
30425
- 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;
31351
+ var NO_SUBAGENT_DIRECTIVE2 = "NEVER spawn subagents. Follow the chatroom instructions strictly.", _sdkCache3, _sdkLoadError3, 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, cachedSdkPackageVersion3, CursorSdkAgentService;
30426
31352
  var init_cursor_sdk_agent_service = __esm(() => {
30427
31353
  init_esm();
30428
31354
  init_cursor_sdk_package();
@@ -30441,7 +31367,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
30441
31367
  if (!process.env.CURSOR_API_KEY?.trim())
30442
31368
  return false;
30443
31369
  try {
30444
- await loadSdk2();
31370
+ await loadSdk3();
30445
31371
  return true;
30446
31372
  } catch (err) {
30447
31373
  console.warn(`[cursor-sdk] unavailable: ${formatCursorSdkLoadError(err)}`);
@@ -30455,7 +31381,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
30455
31381
  });
30456
31382
  }
30457
31383
  async getVersion() {
30458
- const match17 = getSdkPackageVersion2().match(/^(\d+)\.(\d+)\.(\d+)/);
31384
+ const match17 = getSdkPackageVersion3().match(/^(\d+)\.(\d+)\.(\d+)/);
30459
31385
  if (!match17)
30460
31386
  return null;
30461
31387
  return {
@@ -30468,7 +31394,7 @@ var init_cursor_sdk_agent_service = __esm(() => {
30468
31394
  if (!apiKey)
30469
31395
  return [];
30470
31396
  try {
30471
- const { Cursor } = await loadSdk2();
31397
+ const { Cursor } = await loadSdk3();
30472
31398
  const models = await withTimeout(Cursor.models.list({ apiKey }), MODELS_LIST_TIMEOUT_MS, "Cursor.models.list");
30473
31399
  const listedModelIds = models.map((m) => m.id).filter((id3) => id3.length > 0);
30474
31400
  return normalizeCursorSdkListedModels(listedModelIds);
@@ -30546,14 +31472,14 @@ ${options.systemPrompt}` : NO_SUBAGENT_DIRECTIVE2;
30546
31472
  ${options.prompt}`;
30547
31473
  let agent;
30548
31474
  try {
30549
- const { Agent } = await loadSdk2();
31475
+ const { Agent } = await loadSdk3();
30550
31476
  agent = await withTimeout(Agent.resume(stored.harnessSessionId, {
30551
31477
  apiKey,
30552
31478
  model: { id: modelId },
30553
31479
  local: buildLocalAgentOptions(stored.workingDir)
30554
31480
  }), AGENT_CREATE_TIMEOUT_MS, "Agent.resume");
30555
31481
  } catch (err) {
30556
- writeSpawnError2(logPrefix, err);
31482
+ writeSpawnError3(logPrefix, err);
30557
31483
  process.stderr.write(`[${new Date().toISOString()}] role:${context5.role} daemon-resume-fallback] ${formatCursorSdkError(err)} — cold spawning
30558
31484
  `);
30559
31485
  keeper.kill();
@@ -30696,7 +31622,7 @@ ${options.prompt}`;
30696
31622
  while (!session2.aborted) {
30697
31623
  try {
30698
31624
  if (nextPrompt === null) {
30699
- const deferredResume = await waitForResumeOrAbort2(session2);
31625
+ const deferredResume = await waitForResumeOrAbort3(session2);
30700
31626
  if (deferredResume === null || session2.aborted) {
30701
31627
  if (session2.aborted) {
30702
31628
  exitCode = 1;
@@ -30722,7 +31648,7 @@ ${deferredResume}` : deferredResume;
30722
31648
  let adapter;
30723
31649
  const run3 = await withTimeout(agent.send(nextPrompt, {
30724
31650
  local: { force: isFirstTurn },
30725
- idempotencyKey: randomUUID2(),
31651
+ idempotencyKey: randomUUID3(),
30726
31652
  onDelta: ({ update: update5 }) => {
30727
31653
  adapter?.handleInteractionDelta(update5);
30728
31654
  }
@@ -30745,7 +31671,7 @@ ${deferredResume}` : deferredResume;
30745
31671
  }
30746
31672
  } catch (streamErr) {
30747
31673
  exitCode = 1;
30748
- writeSpawnError2(logPrefix, streamErr, emitLogLine);
31674
+ writeSpawnError3(logPrefix, streamErr, emitLogLine);
30749
31675
  break;
30750
31676
  }
30751
31677
  if (session2.aborted) {
@@ -30758,7 +31684,7 @@ ${deferredResume}` : deferredResume;
30758
31684
  result = await withTimeout(run3.wait(), RUN_WAIT_TIMEOUT_MS, "run.wait");
30759
31685
  } catch (waitErr) {
30760
31686
  exitCode = 1;
30761
- writeSpawnError2(logPrefix, waitErr, emitLogLine);
31687
+ writeSpawnError3(logPrefix, waitErr, emitLogLine);
30762
31688
  break;
30763
31689
  }
30764
31690
  adapter.flushPendingOutput();
@@ -30778,13 +31704,13 @@ ${deferredResume}` : deferredResume;
30778
31704
  }
30779
31705
  } catch (turnErr) {
30780
31706
  exitCode = 1;
30781
- writeSpawnError2(logPrefix, turnErr, emitLogLine);
31707
+ writeSpawnError3(logPrefix, turnErr, emitLogLine);
30782
31708
  break;
30783
31709
  }
30784
31710
  }
30785
31711
  } catch (err) {
30786
31712
  exitCode = 1;
30787
- writeSpawnError2(logPrefix, err, emitLogLine);
31713
+ writeSpawnError3(logPrefix, err, emitLogLine);
30788
31714
  } finally {
30789
31715
  if (exited)
30790
31716
  return;
@@ -30796,7 +31722,7 @@ ${deferredResume}` : deferredResume;
30796
31722
  finishExit(exitCode, exitSignal);
30797
31723
  }
30798
31724
  })().catch((err) => {
30799
- writeSpawnError2(logPrefix, err, emitLogLine);
31725
+ writeSpawnError3(logPrefix, err, emitLogLine);
30800
31726
  if (exited)
30801
31727
  return;
30802
31728
  exited = true;
@@ -30817,7 +31743,7 @@ ${deferredResume}` : deferredResume;
30817
31743
  const pid = keeper.pid;
30818
31744
  const context5 = options.context;
30819
31745
  const logPrefix = buildAgentLogPrefix("cursor-sdk", context5);
30820
- const agentName = buildAgentName(context5);
31746
+ const agentName = buildAgentName2(context5);
30821
31747
  const modelId = resolveModelId(options.model);
30822
31748
  const systemPrompt = options.systemPrompt ? `${NO_SUBAGENT_DIRECTIVE2}
30823
31749
 
@@ -30827,7 +31753,7 @@ ${options.systemPrompt}` : NO_SUBAGENT_DIRECTIVE2;
30827
31753
  ${options.prompt}`;
30828
31754
  let agent;
30829
31755
  try {
30830
- const { Agent } = await loadSdk2();
31756
+ const { Agent } = await loadSdk3();
30831
31757
  agent = await withTimeout(Agent.create({
30832
31758
  apiKey,
30833
31759
  name: agentName,
@@ -30835,7 +31761,7 @@ ${options.prompt}`;
30835
31761
  local: buildLocalAgentOptions(options.workingDir)
30836
31762
  }), AGENT_CREATE_TIMEOUT_MS, "Agent.create");
30837
31763
  } catch (err) {
30838
- writeSpawnError2(logPrefix, err);
31764
+ writeSpawnError3(logPrefix, err);
30839
31765
  keeper.kill();
30840
31766
  this.deleteProcess(pid);
30841
31767
  throw err;
@@ -32883,94 +33809,6 @@ var init_opencode_session_status = __esm(() => {
32883
33809
  OPENCODE_SESSION_STATUSES = ["idle", "busy", "retry"];
32884
33810
  });
32885
33811
 
32886
- // src/daemon/domain/usecase/detect-terminal-provider-error.ts
32887
- function matchesQuotaPhrase(blob) {
32888
- const text = blob.toLowerCase();
32889
- return QUOTA_PHRASES.some((phrase) => text.includes(phrase));
32890
- }
32891
- function matchesStructuredProviderErrorText(blob) {
32892
- const text = blob.toLowerCase();
32893
- const hasProviderName = PROVIDER_ERROR_NAMES.some((name) => text.includes(name));
32894
- return hasProviderName && matchesQuotaPhrase(blob);
32895
- }
32896
- function matchesFatalHarnessErrorText(blob) {
32897
- const text = blob.toLowerCase();
32898
- return FATAL_HARNESS_PHRASES.some((phrase) => text.includes(phrase));
32899
- }
32900
- function matchesTerminalProviderErrorText(blob) {
32901
- return matchesQuotaPhrase(blob) || matchesStructuredProviderErrorText(blob);
32902
- }
32903
- function isNonRetryableHarnessFailureText(blob) {
32904
- return matchesTerminalProviderErrorText(blob) || matchesFatalHarnessErrorText(blob);
32905
- }
32906
- function isTerminalProviderError(error) {
32907
- if (typeof error === "string") {
32908
- return isNonRetryableHarnessFailureText(error);
32909
- }
32910
- if (!error || typeof error !== "object") {
32911
- return false;
32912
- }
32913
- const e = error;
32914
- if (typeof e.error === "string" && isNonRetryableHarnessFailureText(e.error)) {
32915
- return true;
32916
- }
32917
- const name = extractName(e);
32918
- const message = extractMessage(e);
32919
- return matchesQuotaPhrase(message) || matchesQuotaPhrase(`${name} ${message}`) || matchesFatalHarnessErrorText(message) || matchesFatalHarnessErrorText(`${name} ${message}`);
32920
- }
32921
- function extractName(e) {
32922
- const name = e.name;
32923
- if (typeof name === "string")
32924
- return name.toLowerCase();
32925
- const type = e.type;
32926
- if (typeof type === "string")
32927
- return type.toLowerCase();
32928
- return "";
32929
- }
32930
- function extractMessage(e) {
32931
- const fromData = messageFromData(e.data);
32932
- if (fromData)
32933
- return fromData;
32934
- if (typeof e.message === "string")
32935
- return e.message.toLowerCase();
32936
- if (typeof e.responseBody === "string")
32937
- return e.responseBody.toLowerCase();
32938
- if (typeof e.error === "string")
32939
- return e.error.toLowerCase();
32940
- if (e.error && typeof e.error === "object") {
32941
- return extractMessage(e.error);
32942
- }
32943
- return "";
32944
- }
32945
- function messageFromData(data) {
32946
- if (!data || typeof data !== "object")
32947
- return;
32948
- const msg = data.message;
32949
- return typeof msg === "string" ? msg.toLowerCase() : undefined;
32950
- }
32951
- var FATAL_HARNESS_PHRASES, QUOTA_PHRASES, PROVIDER_ERROR_NAMES;
32952
- var init_detect_terminal_provider_error = __esm(() => {
32953
- FATAL_HARNESS_PHRASES = [
32954
- "failed to load model",
32955
- "model loading was stopped",
32956
- "insufficient system resources",
32957
- "sandboxing is not supported",
32958
- "disable local.sandboxoptions.enabled"
32959
- ];
32960
- QUOTA_PHRASES = [
32961
- "usagelimit",
32962
- "usage limit",
32963
- "enable usage from your available balance",
32964
- "rate limit",
32965
- "ratelimit",
32966
- "too many requests",
32967
- "x-ratelimit-exceeded",
32968
- "weekly rate limit",
32969
- "exceeded your weekly"
32970
- ];
32971
- PROVIDER_ERROR_NAMES = ["ai_apicallerror", "ai_retryerror"];
32972
- });
32973
-
32974
33812
  // src/daemon/infrastructure/local/harness/services/opencode-sdk/session-event-forwarder.ts
32975
33813
  function formatLogLine(options, kind, payload) {
32976
33814
  return formatTimestampedLogLine(options.role, kind, payload, options.now);
@@ -33308,27 +34146,27 @@ var init_session_event_forwarder = __esm(() => {
33308
34146
  });
33309
34147
 
33310
34148
  // src/daemon/infrastructure/local/harness/services/opencode-sdk/session-metadata-store.ts
33311
- import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync5, writeFileSync } from "node:fs";
34149
+ import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "node:fs";
33312
34150
  import { homedir as homedir2 } from "node:os";
33313
- import { dirname as dirname4, join as join9 } from "node:path";
34151
+ import { dirname as dirname5, join as join10 } from "node:path";
33314
34152
 
33315
34153
  class FileSessionMetadataStore {
33316
34154
  filePath;
33317
34155
  constructor(filePath) {
33318
- this.filePath = filePath ?? join9(homedir2(), ".chatroom", "opencode-sdk-sessions.json");
34156
+ this.filePath = filePath ?? join10(homedir2(), ".chatroom", "opencode-sdk-sessions.json");
33319
34157
  }
33320
34158
  load() {
33321
34159
  try {
33322
- if (existsSync3(this.filePath)) {
33323
- return JSON.parse(readFileSync5(this.filePath, "utf-8"));
34160
+ if (existsSync4(this.filePath)) {
34161
+ return JSON.parse(readFileSync6(this.filePath, "utf-8"));
33324
34162
  }
33325
34163
  } catch {}
33326
34164
  return {};
33327
34165
  }
33328
34166
  save(sessions) {
33329
34167
  try {
33330
- const dir = dirname4(this.filePath);
33331
- if (!existsSync3(dir)) {
34168
+ const dir = dirname5(this.filePath);
34169
+ if (!existsSync4(dir)) {
33332
34170
  mkdirSync(dir, { recursive: true });
33333
34171
  }
33334
34172
  writeFileSync(this.filePath, JSON.stringify(sessions, null, 2));
@@ -33890,47 +34728,47 @@ __export(exports_pi_sdk_package, {
33890
34728
  getBundledPiSdkVersion: () => getBundledPiSdkVersion,
33891
34729
  formatPiSdkLoadError: () => formatPiSdkLoadError
33892
34730
  });
33893
- import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
33894
- import { dirname as dirname5, join as join10 } from "node:path";
33895
- import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
33896
- function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
33897
- const filePath = moduleRef.startsWith("file:") ? fileURLToPath4(moduleRef) : moduleRef;
33898
- let dir = dirname5(filePath);
33899
- while (dir !== dirname5(dir)) {
33900
- const packageJsonPath = join10(dir, "package.json");
33901
- if (existsSync4(packageJsonPath)) {
33902
- const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
34731
+ import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
34732
+ import { dirname as dirname6, join as join11 } from "node:path";
34733
+ import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL4 } from "node:url";
34734
+ function resolveChatroomCliRoot4(moduleRef = import.meta.url) {
34735
+ const filePath = moduleRef.startsWith("file:") ? fileURLToPath5(moduleRef) : moduleRef;
34736
+ let dir = dirname6(filePath);
34737
+ while (dir !== dirname6(dir)) {
34738
+ const packageJsonPath = join11(dir, "package.json");
34739
+ if (existsSync5(packageJsonPath)) {
34740
+ const pkg = JSON.parse(readFileSync7(packageJsonPath, "utf8"));
33903
34741
  if (pkg.name === "chatroom-cli") {
33904
34742
  return dir;
33905
34743
  }
33906
34744
  }
33907
- dir = dirname5(dir);
34745
+ dir = dirname6(dir);
33908
34746
  }
33909
- throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT3}`);
34747
+ throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT4}`);
33910
34748
  }
33911
- function readPinnedSdkVersion3(chatroomCliRoot) {
33912
- const pkg = JSON.parse(readFileSync6(join10(chatroomCliRoot, "package.json"), "utf8"));
34749
+ function readPinnedSdkVersion4(chatroomCliRoot) {
34750
+ const pkg = JSON.parse(readFileSync7(join11(chatroomCliRoot, "package.json"), "utf8"));
33913
34751
  const specifier = pkg.dependencies?.[PI_CODING_AGENT_PKG];
33914
34752
  const pinned = specifier?.replace(/^[\^~>=<]+/, "").trim() ?? "";
33915
34753
  const match17 = pinned.match(/^(\d+\.\d+\.\d+)/);
33916
34754
  if (!match17) {
33917
- throw new PiSdkPackageError(`chatroom-cli must pin an exact ${PI_CODING_AGENT_PKG} version (found "${specifier ?? "none"}"). ${REINSTALL_HINT3}`);
34755
+ throw new PiSdkPackageError(`chatroom-cli must pin an exact ${PI_CODING_AGENT_PKG} version (found "${specifier ?? "none"}"). ${REINSTALL_HINT4}`);
33918
34756
  }
33919
34757
  return match17[1];
33920
34758
  }
33921
- function readInstalledSdkVersion3(entryPath) {
33922
- const packageJsonPath = join10(dirname5(entryPath), "..", "package.json");
33923
- const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
34759
+ function readInstalledSdkVersion4(entryPath) {
34760
+ const packageJsonPath = join11(dirname6(entryPath), "..", "package.json");
34761
+ const pkg = JSON.parse(readFileSync7(packageJsonPath, "utf8"));
33924
34762
  return pkg.version;
33925
34763
  }
33926
34764
  function resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot) {
33927
34765
  let dir = chatroomCliRoot;
33928
- while (dir !== dirname5(dir)) {
33929
- const entryPath = join10(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
33930
- if (existsSync4(entryPath)) {
34766
+ while (dir !== dirname6(dir)) {
34767
+ const entryPath = join11(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
34768
+ if (existsSync5(entryPath)) {
33931
34769
  return entryPath;
33932
34770
  }
33933
- dir = dirname5(dir);
34771
+ dir = dirname6(dir);
33934
34772
  }
33935
34773
  return;
33936
34774
  }
@@ -33938,32 +34776,32 @@ function resolvePiSdkEntryPath(chatroomCliRoot) {
33938
34776
  const resolveMeta = import.meta.resolve;
33939
34777
  if (typeof resolveMeta === "function") {
33940
34778
  try {
33941
- const parentUrl = pathToFileURL3(join10(chatroomCliRoot, "package.json")).href;
33942
- return fileURLToPath4(resolveMeta(PI_CODING_AGENT_PKG, parentUrl));
34779
+ const parentUrl = pathToFileURL4(join11(chatroomCliRoot, "package.json")).href;
34780
+ return fileURLToPath5(resolveMeta(PI_CODING_AGENT_PKG, parentUrl));
33943
34781
  } catch {}
33944
34782
  }
33945
34783
  const entryPath = resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot);
33946
34784
  if (entryPath) {
33947
34785
  return entryPath;
33948
34786
  }
33949
- throw new PiSdkPackageError(`Could not resolve ${PI_CODING_AGENT_PKG} from ${chatroomCliRoot}. ${REINSTALL_HINT3}`);
34787
+ throw new PiSdkPackageError(`Could not resolve ${PI_CODING_AGENT_PKG} from ${chatroomCliRoot}. ${REINSTALL_HINT4}`);
33950
34788
  }
33951
34789
  async function importBundledPiSdk(moduleRef = import.meta.url) {
33952
- const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
33953
- const pinnedVersion = readPinnedSdkVersion3(chatroomCliRoot);
34790
+ const chatroomCliRoot = resolveChatroomCliRoot4(moduleRef);
34791
+ const pinnedVersion = readPinnedSdkVersion4(chatroomCliRoot);
33954
34792
  const entryPath = resolvePiSdkEntryPath(chatroomCliRoot);
33955
- const installedVersion = readInstalledSdkVersion3(entryPath);
34793
+ const installedVersion = readInstalledSdkVersion4(entryPath);
33956
34794
  if (installedVersion !== pinnedVersion) {
33957
- throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG}@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT3}`);
34795
+ throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG}@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT4}`);
33958
34796
  }
33959
- if (!existsSync4(entryPath)) {
33960
- throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG} entry file is missing: ${entryPath}. ${REINSTALL_HINT3}`);
34797
+ if (!existsSync5(entryPath)) {
34798
+ throw new PiSdkPackageError(`${PI_CODING_AGENT_PKG} entry file is missing: ${entryPath}. ${REINSTALL_HINT4}`);
33961
34799
  }
33962
- return import(pathToFileURL3(entryPath).href);
34800
+ return import(pathToFileURL4(entryPath).href);
33963
34801
  }
33964
34802
  function getBundledPiSdkVersion(moduleRef = import.meta.url) {
33965
- const chatroomCliRoot = resolveChatroomCliRoot3(moduleRef);
33966
- return readInstalledSdkVersion3(resolvePiSdkEntryPath(chatroomCliRoot));
34803
+ const chatroomCliRoot = resolveChatroomCliRoot4(moduleRef);
34804
+ return readInstalledSdkVersion4(resolvePiSdkEntryPath(chatroomCliRoot));
33967
34805
  }
33968
34806
  function formatPiSdkLoadError(err) {
33969
34807
  if (err instanceof PiSdkPackageError) {
@@ -33971,7 +34809,7 @@ function formatPiSdkLoadError(err) {
33971
34809
  }
33972
34810
  return err instanceof Error ? err.message : String(err);
33973
34811
  }
33974
- var PI_CODING_AGENT_PKG = "@earendil-works/pi-coding-agent", REINSTALL_HINT3 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", PiSdkPackageError;
34812
+ var PI_CODING_AGENT_PKG = "@earendil-works/pi-coding-agent", REINSTALL_HINT4 = "Reinstall chatroom-cli: npm install -g chatroom-cli@latest", PiSdkPackageError;
33975
34813
  var init_pi_sdk_package = __esm(() => {
33976
34814
  PiSdkPackageError = class PiSdkPackageError extends Error {
33977
34815
  code = "PI_SDK_PACKAGE_INCOMPLETE";
@@ -34090,26 +34928,26 @@ var init_pi_sdk_stream_adapter = __esm(() => {
34090
34928
  });
34091
34929
 
34092
34930
  // src/daemon/infrastructure/local/harness/services/pi-sdk/pi-sdk-agent-service.ts
34093
- async function loadSdk3() {
34094
- if (_sdkCache3)
34095
- return _sdkCache3;
34096
- if (_sdkLoadError3)
34097
- throw _sdkLoadError3;
34931
+ async function loadSdk4() {
34932
+ if (_sdkCache4)
34933
+ return _sdkCache4;
34934
+ if (_sdkLoadError4)
34935
+ throw _sdkLoadError4;
34098
34936
  try {
34099
- _sdkCache3 = await importBundledPiSdk();
34100
- return _sdkCache3;
34937
+ _sdkCache4 = await importBundledPiSdk();
34938
+ return _sdkCache4;
34101
34939
  } catch (err) {
34102
- _sdkLoadError3 = err;
34940
+ _sdkLoadError4 = err;
34103
34941
  throw err;
34104
34942
  }
34105
34943
  }
34106
- function getSdkPackageVersion3() {
34107
- if (cachedSdkPackageVersion3)
34108
- return cachedSdkPackageVersion3;
34109
- cachedSdkPackageVersion3 = getBundledPiSdkVersion();
34110
- return cachedSdkPackageVersion3;
34944
+ function getSdkPackageVersion4() {
34945
+ if (cachedSdkPackageVersion4)
34946
+ return cachedSdkPackageVersion4;
34947
+ cachedSdkPackageVersion4 = getBundledPiSdkVersion();
34948
+ return cachedSdkPackageVersion4;
34111
34949
  }
34112
- function waitForResumeOrAbort3(session2) {
34950
+ function waitForResumeOrAbort4(session2) {
34113
34951
  if (session2.aborted)
34114
34952
  return Promise.resolve(null);
34115
34953
  const queued = session2.pendingResumePrompt;
@@ -34146,14 +34984,14 @@ function resolveModel(modelRegistry, model) {
34146
34984
  }
34147
34985
  return modelRegistry.getAvailable()[0];
34148
34986
  }
34149
- function writeSpawnError3(logPrefix, err, emitLogLine) {
34987
+ function writeSpawnError4(logPrefix, err, emitLogLine) {
34150
34988
  const line = formatAgentLogLine(logPrefix, "spawn-error", formatPiSdkLoadError(err));
34151
34989
  process.stderr.write(`${line}
34152
34990
  `);
34153
34991
  emitLogLine?.(line);
34154
34992
  console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
34155
34993
  }
34156
- var PI_SDK_COMMAND = "pi-sdk", SESSION_CREATE_TIMEOUT_MS2 = 60000, PROMPT_TIMEOUT_MS = 3600000, _sdkCache3, _sdkLoadError3, cachedSdkPackageVersion3, PiSdkAgentService;
34994
+ var PI_SDK_COMMAND = "pi-sdk", SESSION_CREATE_TIMEOUT_MS2 = 60000, PROMPT_TIMEOUT_MS = 3600000, _sdkCache4, _sdkLoadError4, cachedSdkPackageVersion4, PiSdkAgentService;
34157
34995
  var init_pi_sdk_agent_service = __esm(() => {
34158
34996
  init_esm();
34159
34997
  init_pi_sdk_package();
@@ -34171,7 +35009,7 @@ var init_pi_sdk_agent_service = __esm(() => {
34171
35009
  }
34172
35010
  async isInstalled() {
34173
35011
  try {
34174
- const { ModelRegistry, AuthStorage } = await loadSdk3();
35012
+ const { ModelRegistry, AuthStorage } = await loadSdk4();
34175
35013
  const authStorage = AuthStorage.create();
34176
35014
  const modelRegistry = ModelRegistry.create(authStorage);
34177
35015
  return modelRegistry.getAvailable().length > 0;
@@ -34187,7 +35025,7 @@ var init_pi_sdk_agent_service = __esm(() => {
34187
35025
  });
34188
35026
  }
34189
35027
  async getVersion() {
34190
- const match17 = getSdkPackageVersion3().match(/^(\d+)\.(\d+)\.(\d+)/);
35028
+ const match17 = getSdkPackageVersion4().match(/^(\d+)\.(\d+)\.(\d+)/);
34191
35029
  if (!match17)
34192
35030
  return null;
34193
35031
  return {
@@ -34197,7 +35035,7 @@ var init_pi_sdk_agent_service = __esm(() => {
34197
35035
  }
34198
35036
  async listModels() {
34199
35037
  try {
34200
- const { ModelRegistry, AuthStorage } = await loadSdk3();
35038
+ const { ModelRegistry, AuthStorage } = await loadSdk4();
34201
35039
  const authStorage = AuthStorage.create();
34202
35040
  const modelRegistry = ModelRegistry.create(authStorage);
34203
35041
  return modelRegistry.getAvailable().map((entry) => `${entry.provider}/${entry.id}`);
@@ -34262,7 +35100,7 @@ var init_pi_sdk_agent_service = __esm(() => {
34262
35100
  getAgentDir,
34263
35101
  ModelRegistry,
34264
35102
  SessionManager
34265
- } = await loadSdk3();
35103
+ } = await loadSdk4();
34266
35104
  const authStorage = AuthStorage.create();
34267
35105
  const modelRegistry = ModelRegistry.create(authStorage);
34268
35106
  const resolvedModel = resolveModel(modelRegistry, args2.model);
@@ -34378,7 +35216,7 @@ var init_pi_sdk_agent_service = __esm(() => {
34378
35216
  while (!sdkSession.aborted) {
34379
35217
  try {
34380
35218
  if (nextPrompt === null) {
34381
- const deferredResume = await waitForResumeOrAbort3(sdkSession);
35219
+ const deferredResume = await waitForResumeOrAbort4(sdkSession);
34382
35220
  if (deferredResume === null || sdkSession.aborted) {
34383
35221
  if (sdkSession.aborted) {
34384
35222
  exitCode = 1;
@@ -34416,13 +35254,13 @@ ${deferredResume}` : deferredResume;
34416
35254
  nextPrompt = null;
34417
35255
  } catch (turnErr) {
34418
35256
  exitCode = 1;
34419
- writeSpawnError3(logPrefix, turnErr, emitLogLine);
35257
+ writeSpawnError4(logPrefix, turnErr, emitLogLine);
34420
35258
  break;
34421
35259
  }
34422
35260
  }
34423
35261
  } catch (err) {
34424
35262
  exitCode = 1;
34425
- writeSpawnError3(logPrefix, err, emitLogLine);
35263
+ writeSpawnError4(logPrefix, err, emitLogLine);
34426
35264
  } finally {
34427
35265
  if (exited)
34428
35266
  return;
@@ -34437,7 +35275,7 @@ ${deferredResume}` : deferredResume;
34437
35275
  finishExit(exitCode, exitSignal);
34438
35276
  }
34439
35277
  })().catch((err) => {
34440
- writeSpawnError3(logPrefix, err, emitLogLine);
35278
+ writeSpawnError4(logPrefix, err, emitLogLine);
34441
35279
  if (exited)
34442
35280
  return;
34443
35281
  exited = true;
@@ -34500,6 +35338,7 @@ function initHarnessRegistry() {
34500
35338
  registerHarness(new CursorSdkAgentService);
34501
35339
  registerHarness(new ClaudeCodeAgentService);
34502
35340
  registerHarness(new ClaudeSdkAgentService);
35341
+ registerHarness(new CodexSdkAgentService);
34503
35342
  registerHarness(new CommandCodeAgentService);
34504
35343
  registerHarness(new CopilotAgentService);
34505
35344
  initialized = true;
@@ -34508,6 +35347,7 @@ var initialized = false;
34508
35347
  var init_registry3 = __esm(() => {
34509
35348
  init_claude();
34510
35349
  init_claude_sdk();
35350
+ init_codex_sdk();
34511
35351
  init_commandcode();
34512
35352
  init_copilot();
34513
35353
  init_cursor();
@@ -34597,10 +35437,10 @@ var init_detection = __esm(() => {
34597
35437
  var MACHINE_CONFIG_VERSION = "1";
34598
35438
 
34599
35439
  // src/infrastructure/machine/storage.ts
34600
- import { randomBytes, randomUUID as randomUUID3 } from "node:crypto";
35440
+ import { randomBytes, randomUUID as randomUUID4 } from "node:crypto";
34601
35441
  import * as fs4 from "node:fs/promises";
34602
35442
  import { homedir as homedir3, hostname as hostname2 } from "node:os";
34603
- import { join as join11 } from "node:path";
35443
+ import { join as join12 } from "node:path";
34604
35444
  function enqueueMachineConfigSave(task) {
34605
35445
  const run3 = saveChain.then(task, task);
34606
35446
  saveChain = run3.catch(() => {
@@ -34609,14 +35449,14 @@ function enqueueMachineConfigSave(task) {
34609
35449
  return run3;
34610
35450
  }
34611
35451
  function chatroomConfigDir() {
34612
- return join11(homedir3(), ".chatroom");
35452
+ return join12(homedir3(), ".chatroom");
34613
35453
  }
34614
35454
  async function ensureConfigDir2() {
34615
35455
  const dir = chatroomConfigDir();
34616
35456
  await fs4.mkdir(dir, { recursive: true, mode: 448 });
34617
35457
  }
34618
35458
  function getMachineConfigPath() {
34619
- return join11(chatroomConfigDir(), MACHINE_FILE);
35459
+ return join12(chatroomConfigDir(), MACHINE_FILE);
34620
35460
  }
34621
35461
  async function loadConfigFile() {
34622
35462
  const configPath = getMachineConfigPath();
@@ -34670,7 +35510,7 @@ async function createNewEndpointConfig() {
34670
35510
  const now = new Date().toISOString();
34671
35511
  const availableHarnesses = await detectAvailableHarnesses();
34672
35512
  return {
34673
- machineId: randomUUID3(),
35513
+ machineId: randomUUID4(),
34674
35514
  hostname: hostname2(),
34675
35515
  os: process.platform,
34676
35516
  registeredAt: now,
@@ -34718,7 +35558,7 @@ var init_storage2 = __esm(() => {
34718
35558
  // src/infrastructure/machine/daemon-state.ts
34719
35559
  import * as fs5 from "node:fs/promises";
34720
35560
  import { homedir as homedir4 } from "node:os";
34721
- import { join as join12 } from "node:path";
35561
+ import { join as join13 } from "node:path";
34722
35562
  function agentKey(chatroomId, role) {
34723
35563
  return `${chatroomId}/${role}`;
34724
35564
  }
@@ -34726,7 +35566,7 @@ async function ensureStateDir() {
34726
35566
  await fs5.mkdir(STATE_DIR, { recursive: true, mode: 448 });
34727
35567
  }
34728
35568
  function stateFilePath(machineId) {
34729
- return join12(STATE_DIR, `${machineId}.json`);
35569
+ return join13(STATE_DIR, `${machineId}.json`);
34730
35570
  }
34731
35571
  async function loadDaemonState(machineId) {
34732
35572
  const filePath = stateFilePath(machineId);
@@ -34808,8 +35648,8 @@ async function loadEventCursor(machineId) {
34808
35648
  }
34809
35649
  var CHATROOM_DIR2, STATE_DIR, STATE_VERSION = "1";
34810
35650
  var init_daemon_state = __esm(() => {
34811
- CHATROOM_DIR2 = join12(homedir4(), ".chatroom");
34812
- STATE_DIR = join12(CHATROOM_DIR2, "machines", "state");
35651
+ CHATROOM_DIR2 = join13(homedir4(), ".chatroom");
35652
+ STATE_DIR = join13(CHATROOM_DIR2, "machines", "state");
34813
35653
  });
34814
35654
 
34815
35655
  // src/infrastructure/machine/index.ts
@@ -35251,9 +36091,9 @@ var init_init = __esm(() => {
35251
36091
  });
35252
36092
 
35253
36093
  // src/tools/output.ts
35254
- import { join as join13 } from "node:path";
36094
+ import { join as join14 } from "node:path";
35255
36095
  function resolveChatroomDir(workingDir) {
35256
- return join13(workingDir, CHATROOM_DIR3);
36096
+ return join14(workingDir, CHATROOM_DIR3);
35257
36097
  }
35258
36098
  async function ensureChatroomDir(deps, workingDir) {
35259
36099
  const dir = resolveChatroomDir(workingDir);
@@ -35261,7 +36101,7 @@ async function ensureChatroomDir(deps, workingDir) {
35261
36101
  return dir;
35262
36102
  }
35263
36103
  async function ensureGitignore(deps, workingDir) {
35264
- const gitignorePath = join13(workingDir, ".gitignore");
36104
+ const gitignorePath = join14(workingDir, ".gitignore");
35265
36105
  const entry = CHATROOM_DIR3;
35266
36106
  let content = "";
35267
36107
  try {
@@ -35291,7 +36131,7 @@ function formatOutputTimestamp(date = new Date) {
35291
36131
  function generateOutputPath(workingDir, toolName, extension, date) {
35292
36132
  const timestamp = formatOutputTimestamp(date);
35293
36133
  const filename = `${toolName}-${timestamp}.${extension}`;
35294
- return join13(resolveChatroomDir(workingDir), filename);
36134
+ return join14(resolveChatroomDir(workingDir), filename);
35295
36135
  }
35296
36136
  var CHATROOM_DIR3 = ".chatroom";
35297
36137
  var init_output = () => {};
@@ -36100,8 +36940,8 @@ var init_index_esm = __esm(() => {
36100
36940
  var ENVIRONMENT_IS_NODE = typeof process == "object" && process.versions?.node && process.type != "renderer";
36101
36941
  var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
36102
36942
  if (ENVIRONMENT_IS_NODE) {
36103
- const { createRequire: createRequire5 } = await import("module");
36104
- var require3 = createRequire5(import.meta.url);
36943
+ const { createRequire: createRequire6 } = await import("module");
36944
+ var require3 = createRequire6(import.meta.url);
36105
36945
  }
36106
36946
  var thisProgram = "./this.program";
36107
36947
  var _scriptName = import.meta.url;
@@ -41307,7 +42147,7 @@ var require_filesystem = __commonJS((exports, module) => {
41307
42147
  var LDD_PATH = "/usr/bin/ldd";
41308
42148
  var SELF_PATH = "/proc/self/exe";
41309
42149
  var MAX_LENGTH = 2048;
41310
- var readFileSync7 = (path2) => {
42150
+ var readFileSync8 = (path2) => {
41311
42151
  const fd = fs6.openSync(path2, "r");
41312
42152
  const buffer = Buffer.alloc(MAX_LENGTH);
41313
42153
  const bytesRead = fs6.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -41330,7 +42170,7 @@ var require_filesystem = __commonJS((exports, module) => {
41330
42170
  module.exports = {
41331
42171
  LDD_PATH,
41332
42172
  SELF_PATH,
41333
- readFileSync: readFileSync7,
42173
+ readFileSync: readFileSync8,
41334
42174
  readFile: readFile4
41335
42175
  };
41336
42176
  });
@@ -41373,7 +42213,7 @@ var require_elf = __commonJS((exports, module) => {
41373
42213
  var require_detect_libc = __commonJS((exports, module) => {
41374
42214
  var childProcess = __require("child_process");
41375
42215
  var { isLinux, getReport } = require_process();
41376
- var { LDD_PATH, SELF_PATH, readFile: readFile4, readFileSync: readFileSync7 } = require_filesystem();
42216
+ var { LDD_PATH, SELF_PATH, readFile: readFile4, readFileSync: readFileSync8 } = require_filesystem();
41377
42217
  var { interpreterPath } = require_elf();
41378
42218
  var cachedFamilyInterpreter;
41379
42219
  var cachedFamilyFilesystem;
@@ -41464,7 +42304,7 @@ var require_detect_libc = __commonJS((exports, module) => {
41464
42304
  }
41465
42305
  cachedFamilyFilesystem = null;
41466
42306
  try {
41467
- const lddContent = readFileSync7(LDD_PATH);
42307
+ const lddContent = readFileSync8(LDD_PATH);
41468
42308
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
41469
42309
  } catch (e) {}
41470
42310
  return cachedFamilyFilesystem;
@@ -41487,7 +42327,7 @@ var require_detect_libc = __commonJS((exports, module) => {
41487
42327
  }
41488
42328
  cachedFamilyInterpreter = null;
41489
42329
  try {
41490
- const selfContent = readFileSync7(SELF_PATH);
42330
+ const selfContent = readFileSync8(SELF_PATH);
41491
42331
  const path2 = interpreterPath(selfContent);
41492
42332
  cachedFamilyInterpreter = familyFromInterpreterPath(path2);
41493
42333
  } catch (e) {}
@@ -41549,7 +42389,7 @@ var require_detect_libc = __commonJS((exports, module) => {
41549
42389
  }
41550
42390
  cachedVersionFilesystem = null;
41551
42391
  try {
41552
- const lddContent = readFileSync7(LDD_PATH);
42392
+ const lddContent = readFileSync8(LDD_PATH);
41553
42393
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
41554
42394
  if (versionMatch) {
41555
42395
  cachedVersionFilesystem = versionMatch[1];
@@ -47744,12 +48584,12 @@ var init_pdfium_renderer = __esm(() => {
47744
48584
  });
47745
48585
 
47746
48586
  // ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/engines/pdf/pdfjsImporter.js
47747
- import { fileURLToPath as fileURLToPath5 } from "node:url";
47748
- import { dirname as dirname6 } from "node:path";
48587
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
48588
+ import { dirname as dirname7 } from "node:path";
47749
48589
  async function importPdfJs() {
47750
48590
  const pdfUrl = new URL("../../vendor/pdfjs/pdf.mjs", import.meta.url);
47751
48591
  const pdfjs = await import(pdfUrl.href);
47752
- const dirPath = dirname6(fileURLToPath5(pdfUrl));
48592
+ const dirPath = dirname7(fileURLToPath6(pdfUrl));
47753
48593
  return {
47754
48594
  fn: pdfjs.getDocument,
47755
48595
  dir: dirPath
@@ -69766,7 +70606,7 @@ function applyMarkupTags(markup, text) {
69766
70606
  // ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/processing/gridDebugLogger.js
69767
70607
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
69768
70608
  import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
69769
- import { dirname as dirname7 } from "path";
70609
+ import { dirname as dirname8 } from "path";
69770
70610
 
69771
70611
  class GridDebugLogger {
69772
70612
  config;
@@ -70093,14 +70933,14 @@ class GridDebugLogger {
70093
70933
  flushSync() {
70094
70934
  if (!this.config.outputPath || this.entries.length === 0)
70095
70935
  return;
70096
- mkdirSync2(dirname7(this.config.outputPath), { recursive: true });
70936
+ mkdirSync2(dirname8(this.config.outputPath), { recursive: true });
70097
70937
  writeFileSync2(this.config.outputPath, this.formatEntries(), "utf-8");
70098
70938
  this.entries = [];
70099
70939
  }
70100
70940
  async flush() {
70101
70941
  if (!this.config.outputPath || this.entries.length === 0)
70102
70942
  return;
70103
- await mkdir4(dirname7(this.config.outputPath), { recursive: true });
70943
+ await mkdir4(dirname8(this.config.outputPath), { recursive: true });
70104
70944
  await writeFile4(this.config.outputPath, this.formatEntries(), "utf-8");
70105
70945
  this.entries = [];
70106
70946
  }
@@ -76841,6 +77681,14 @@ var init_new = __esm(() => {
76841
77681
  init_view_template();
76842
77682
  });
76843
77683
 
77684
+ // ../../services/backend/prompts/cli/context/read.ts
77685
+ function contextReadCommand(params = {}) {
77686
+ const prefix = params.cliEnvPrefix ?? "";
77687
+ const chatroomId = params.chatroomId ?? "<chatroom-id>";
77688
+ const role = params.role ?? "<role>";
77689
+ return `${prefix}chatroom context read --chatroom-id="${chatroomId}" --role="${role}"`;
77690
+ }
77691
+
76844
77692
  // ../../services/backend/prompts/cli/task-started/main-prompt.ts
76845
77693
  var init_main_prompt = __esm(() => {
76846
77694
  init_new();
@@ -77550,6 +78398,218 @@ var init_get_next_task = __esm(() => {
77550
78398
  init_get_next_task_session_service();
77551
78399
  });
77552
78400
 
78401
+ // ../../services/backend/src/domain/entities/team-presets.ts
78402
+ function getTeamPreset(teamId) {
78403
+ return TEAM_PRESETS[teamId];
78404
+ }
78405
+ function listTeamPresetIds() {
78406
+ return Object.keys(TEAM_PRESETS);
78407
+ }
78408
+ var TEAM_PRESETS, DEFAULT_TEAM_PRESET_ID = "duo";
78409
+ var init_team_presets = __esm(() => {
78410
+ TEAM_PRESETS = {
78411
+ duo: {
78412
+ name: "Duo",
78413
+ description: "A planner and builder working as a pair, planner as coordinator",
78414
+ roles: ["planner", "builder"],
78415
+ entryPoint: "planner"
78416
+ },
78417
+ solo: {
78418
+ name: "Solo",
78419
+ description: "A single agent working independently",
78420
+ roles: ["solo"],
78421
+ entryPoint: "solo"
78422
+ }
78423
+ };
78424
+ });
78425
+
78426
+ // src/commands/team/index.ts
78427
+ var exports_team = {};
78428
+ __export(exports_team, {
78429
+ setTeam: () => setTeam,
78430
+ listTeamPresets: () => listTeamPresets,
78431
+ getTeam: () => getTeam
78432
+ });
78433
+ async function createDefaultDeps8() {
78434
+ const client4 = await getConvexClient();
78435
+ return {
78436
+ backend: {
78437
+ mutation: (endpoint, args2) => client4.mutation(endpoint, args2),
78438
+ query: (endpoint, args2) => client4.query(endpoint, args2)
78439
+ },
78440
+ session: { getSessionId }
78441
+ };
78442
+ }
78443
+ async function requireSession(deps) {
78444
+ const sessionId = await deps.session.getSessionId();
78445
+ if (!sessionId)
78446
+ throw new Error("Not authenticated. Please run: chatroom auth login");
78447
+ return sessionId;
78448
+ }
78449
+ async function listTeamPresets() {
78450
+ console.log("Team presets:");
78451
+ const teamIds = [
78452
+ DEFAULT_TEAM_PRESET_ID,
78453
+ ...listTeamPresetIds().filter((teamId) => teamId !== DEFAULT_TEAM_PRESET_ID)
78454
+ ];
78455
+ for (const teamId of teamIds) {
78456
+ const preset = TEAM_PRESETS[teamId];
78457
+ if (!preset)
78458
+ continue;
78459
+ console.log(` ${teamId} — ${preset.name} (${preset.roles.join(", ")}) entry: ${preset.entryPoint}`);
78460
+ }
78461
+ }
78462
+ async function getTeam(chatroomId, deps) {
78463
+ const d = deps ?? await createDefaultDeps8();
78464
+ const sessionId = await requireSession(d);
78465
+ const team = await d.backend.query(api.chatrooms.get, {
78466
+ sessionId,
78467
+ chatroomId
78468
+ });
78469
+ if (!team)
78470
+ throw new Error(`Chatroom not found or access denied: ${chatroomId}`);
78471
+ console.log(`Current team: ${team.teamId} (${team.teamName})`);
78472
+ console.log(` Roles: ${team.teamRoles.join(", ")}`);
78473
+ console.log(` Entry point: ${team.teamEntryPoint}`);
78474
+ }
78475
+ async function setTeam(chatroomId, teamId, deps) {
78476
+ const preset = getTeamPreset(teamId);
78477
+ if (!preset) {
78478
+ throw new Error(`Unknown team preset "${teamId}". Available presets: ${listTeamPresetIds().join(", ")}`);
78479
+ }
78480
+ const d = deps ?? await createDefaultDeps8();
78481
+ const sessionId = await requireSession(d);
78482
+ await d.backend.mutation(api.chatrooms.updateTeam, {
78483
+ sessionId,
78484
+ chatroomId,
78485
+ teamId,
78486
+ teamName: preset.name,
78487
+ teamRoles: preset.roles,
78488
+ teamEntryPoint: preset.entryPoint
78489
+ });
78490
+ console.log(`✅ Team set to ${teamId} (${preset.name})`);
78491
+ console.log(` Roles: ${preset.roles.join(", ")}`);
78492
+ console.log(` Entry point: ${preset.entryPoint}`);
78493
+ }
78494
+ var init_team = __esm(() => {
78495
+ init_team_presets();
78496
+ init_api3();
78497
+ init_storage();
78498
+ init_client2();
78499
+ });
78500
+
78501
+ // src/commands/agent/index.ts
78502
+ var exports_agent = {};
78503
+ __export(exports_agent, {
78504
+ startAgent: () => startAgent,
78505
+ setAgentConfig: () => setAgentConfig,
78506
+ getAgentConfig: () => getAgentConfig
78507
+ });
78508
+ async function createDefaultDeps9() {
78509
+ const client4 = await getConvexClient();
78510
+ return {
78511
+ backend: {
78512
+ mutation: (endpoint, args2) => client4.mutation(endpoint, args2),
78513
+ query: (endpoint, args2) => client4.query(endpoint, args2)
78514
+ },
78515
+ session: { getSessionId },
78516
+ machine: { getMachineId, loadMachineConfig }
78517
+ };
78518
+ }
78519
+ async function requireSession2(deps) {
78520
+ const sessionId = await deps.session.getSessionId();
78521
+ if (!sessionId)
78522
+ throw new Error("Not authenticated. Please run: chatroom auth login");
78523
+ return sessionId;
78524
+ }
78525
+ async function requireMachineId(deps) {
78526
+ const machineId = await deps.machine.getMachineId();
78527
+ if (!machineId)
78528
+ throw new Error("Run machine daemon start first");
78529
+ return machineId;
78530
+ }
78531
+ function configuredWorkingDir(config3) {
78532
+ return config3?.workingDir;
78533
+ }
78534
+ async function getConfigs(deps, sessionId, chatroomId) {
78535
+ return await deps.backend.query(api.machines.getTeamAgentConfigs, {
78536
+ sessionId,
78537
+ chatroomId
78538
+ });
78539
+ }
78540
+ async function getAgentConfig(chatroomId, role, deps) {
78541
+ const d = deps ?? await createDefaultDeps9();
78542
+ const sessionId = await requireSession2(d);
78543
+ const config3 = (await getConfigs(d, sessionId, chatroomId)).find((candidate) => candidate.role.toLowerCase() === role.toLowerCase());
78544
+ if (!config3)
78545
+ throw new Error(`No agent config found for role "${role}"`);
78546
+ console.log(`Agent config: ${role}`);
78547
+ console.log(` Harness: ${config3.agentHarness ?? "(unset)"}`);
78548
+ console.log(` Model: ${config3.model ?? "(unset)"}`);
78549
+ console.log(` Working directory: ${config3.workingDir ?? "(unset)"}`);
78550
+ console.log(` Machine ID: ${config3.machineId ?? "(unset)"}`);
78551
+ console.log(` Desired state: ${config3.desiredState ?? "(unset)"}`);
78552
+ }
78553
+ async function setAgentConfig(chatroomId, options, deps) {
78554
+ const d = deps ?? await createDefaultDeps9();
78555
+ const sessionId = await requireSession2(d);
78556
+ const machineId = await requireMachineId(d);
78557
+ const machineConfig = await d.machine.loadMachineConfig();
78558
+ const workingDir = options.workingDir ?? configuredWorkingDir(machineConfig) ?? process.cwd();
78559
+ await d.backend.mutation(api.machines.saveTeamAgentConfig, {
78560
+ sessionId,
78561
+ chatroomId,
78562
+ role: options.role,
78563
+ type: "remote",
78564
+ machineId,
78565
+ agentHarness: options.harness,
78566
+ model: options.model,
78567
+ workingDir
78568
+ });
78569
+ console.log(`✅ Agent config saved for ${options.role}`);
78570
+ console.log(` Harness: ${options.harness}`);
78571
+ console.log(` Model: ${options.model}`);
78572
+ console.log(` Working directory: ${workingDir}`);
78573
+ console.log(` Machine ID: ${machineId}`);
78574
+ }
78575
+ async function startAgent(chatroomId, options, deps) {
78576
+ const d = deps ?? await createDefaultDeps9();
78577
+ const sessionId = await requireSession2(d);
78578
+ const machineId = await requireMachineId(d);
78579
+ const configs = await getConfigs(d, sessionId, chatroomId);
78580
+ const existing = configs.find((candidate) => candidate.role.toLowerCase() === options.role.toLowerCase());
78581
+ const machineConfig = await d.machine.loadMachineConfig();
78582
+ const harness = options.harness ?? existing?.agentHarness;
78583
+ const model = options.model ?? existing?.model;
78584
+ const workingDir = options.workingDir ?? existing?.workingDir ?? configuredWorkingDir(machineConfig) ?? process.cwd();
78585
+ if (!harness || !model) {
78586
+ throw new Error("Harness and model are required; provide flags or configure the agent first");
78587
+ }
78588
+ await d.backend.mutation(api.machines.sendCommand, {
78589
+ sessionId,
78590
+ machineId,
78591
+ type: "start-agent",
78592
+ payload: {
78593
+ chatroomId,
78594
+ role: options.role,
78595
+ agentHarness: harness,
78596
+ model,
78597
+ workingDir
78598
+ }
78599
+ });
78600
+ console.log(`✅ Start command sent for ${options.role}`);
78601
+ console.log(` Harness: ${harness}`);
78602
+ console.log(` Model: ${model}`);
78603
+ console.log(` Working directory: ${workingDir}`);
78604
+ console.log(` Machine ID: ${machineId}`);
78605
+ }
78606
+ var init_agent = __esm(() => {
78607
+ init_api3();
78608
+ init_storage();
78609
+ init_client2();
78610
+ init_storage2();
78611
+ });
78612
+
77553
78613
  // ../../services/backend/prompts/native/handoff-visibility.ts
77554
78614
  function recipientLabel(toRole) {
77555
78615
  return toRole.toLowerCase() === "user" ? "The user" : `The \`${toRole}\` agent`;
@@ -78001,14 +79061,6 @@ After the enhancer returns **advisory** feedback, you make the **final call**
78001
79061
  }
78002
79062
  var init_planner_to_enhancer = () => {};
78003
79063
 
78004
- // ../../services/backend/prompts/cli/context/read.ts
78005
- function contextReadCommand(params = {}) {
78006
- const prefix = params.cliEnvPrefix ?? "";
78007
- const chatroomId = params.chatroomId ?? "<chatroom-id>";
78008
- const role = params.role ?? "<role>";
78009
- return `${prefix}chatroom context read --chatroom-id="${chatroomId}" --role="${role}"`;
78010
- }
78011
-
78012
79064
  // ../../services/backend/prompts/utils/context-disclosure.ts
78013
79065
  function getContextReadDisclosureComment(params = {}) {
78014
79066
  const command = contextReadCommand(params);
@@ -78036,14 +79088,27 @@ function messagesAnchorCommand(params = {}) {
78036
79088
  const role = params.role ?? "<role>";
78037
79089
  return `${prefix}chatroom messages anchor --chatroom-id="${chatroomId}" --role="${role}"`;
78038
79090
  }
79091
+ function messagesDownloadSinceCommand(params = {}) {
79092
+ const prefix = params.cliEnvPrefix ?? "";
79093
+ const chatroomId = params.chatroomId ?? "<chatroom-id>";
79094
+ const role = params.role ?? "<role>";
79095
+ const sinceMessageId = params.sinceMessageId ?? "<id>";
79096
+ const limit = params.limit ?? 100;
79097
+ return `${prefix}chatroom messages download --chatroom-id="${chatroomId}" --role="${role}" --since-message-id="${sinceMessageId}" --limit=${limit}`;
79098
+ }
78039
79099
  function getProofOfVerificationComment(params = {}) {
78040
79100
  const anchorCmd = messagesAnchorCommand(params);
79101
+ const downloadCmd = messagesDownloadSinceCommand({
79102
+ ...params,
79103
+ sinceMessageId: "<from-anchor>",
79104
+ limit: 100
79105
+ });
78041
79106
  return `<!-- Entry-point proof-of-completion workflow — run before filling this section:
78042
79107
  1. \`${anchorCmd}\` — locate the user's last message (and prior user messages for context)
78043
- 2. \`messages download --since-message-id=<id>\` — download grep-friendly history since anchor; read handoffs and goals
79108
+ 2. \`${downloadCmd}\` — download grep-friendly history since anchor; read handoffs and goals
78044
79109
  3. If the user's last message was terse (e.g. "do it", "raise a PR"), review prior user messages from anchor output and widen --limit before validating
78045
79110
  4. Validate commits/PRs against ALL requirements — not just the last slice. Incomplete → rework; do NOT hand off to user.
78046
- Then: ${anchorCmd} → messages download --since-message-id=<id> from anchor output -->`;
79111
+ Then: \`${anchorCmd}\`\`${downloadCmd}\` (use the message ID from anchor output as --since-message-id) -->`;
78047
79112
  }
78048
79113
  function getEntryPointProofOfCompletionVerificationBlock(params = {}) {
78049
79114
  return `${getProofOfVerificationComment(params)}
@@ -78671,6 +79736,22 @@ var init_claude_config = __esm(() => {
78671
79736
  };
78672
79737
  });
78673
79738
 
79739
+ // ../../services/backend/src/domain/entities/harness/codex-sdk.config.ts
79740
+ var codexSdkCapabilities;
79741
+ var init_codex_sdk_config = __esm(() => {
79742
+ codexSdkCapabilities = {
79743
+ runtimeKind: "sdk",
79744
+ supportsDaemonMemoryResume: true,
79745
+ supportsNativeIntegration: true,
79746
+ lifecycle: {
79747
+ turnCompleted: true,
79748
+ outputActivity: true,
79749
+ processExited: true
79750
+ },
79751
+ wireEvents: ["sdk.codex.event"]
79752
+ };
79753
+ });
79754
+
78674
79755
  // ../../services/backend/src/domain/entities/harness/commandcode.config.ts
78675
79756
  var commandcodeCapabilities;
78676
79757
  var init_commandcode_config = __esm(() => {
@@ -78820,6 +79901,7 @@ var HARNESS_CAPABILITIES;
78820
79901
  var init_types = __esm(() => {
78821
79902
  init_claude_sdk_config();
78822
79903
  init_claude_config();
79904
+ init_codex_sdk_config();
78823
79905
  init_commandcode_config();
78824
79906
  init_copilot_config();
78825
79907
  init_cursor_sdk_config();
@@ -78831,6 +79913,7 @@ var init_types = __esm(() => {
78831
79913
  HARNESS_CAPABILITIES = {
78832
79914
  claude: claudeCapabilities,
78833
79915
  "claude-sdk": claudeSdkCapabilities,
79916
+ "codex-sdk": codexSdkCapabilities,
78834
79917
  commandcode: commandcodeCapabilities,
78835
79918
  copilot: copilotCapabilities,
78836
79919
  cursor: cursorCapabilities,
@@ -78908,7 +79991,7 @@ __export(exports_handoff, {
78908
79991
  handoffEffect: () => handoffEffect,
78909
79992
  handoff: () => handoff
78910
79993
  });
78911
- async function createDefaultDeps8() {
79994
+ async function createDefaultDeps10() {
78912
79995
  const client4 = await getConvexClient();
78913
79996
  return {
78914
79997
  backend: {
@@ -78985,7 +80068,7 @@ ${err.cause instanceof Error ? err.cause.message : String(err.cause)}`);
78985
80068
  });
78986
80069
  }
78987
80070
  async function handoff(chatroomId, options, deps) {
78988
- const d = deps ?? await createDefaultDeps8();
80071
+ const d = deps ?? await createDefaultDeps10();
78989
80072
  const layer = commandServicesLayerFromDeps(d);
78990
80073
  await exports_Effect.runPromise(handoffEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleHandoffError(err)), exports_Effect.provide(layer)));
78991
80074
  }
@@ -79048,7 +80131,7 @@ var exports_complete = {};
79048
80131
  __export(exports_complete, {
79049
80132
  agenticQueryComplete: () => agenticQueryComplete
79050
80133
  });
79051
- async function createDefaultDeps9() {
80134
+ async function createDefaultDeps11() {
79052
80135
  const client4 = await getConvexClient();
79053
80136
  return {
79054
80137
  backend: {
@@ -79080,7 +80163,7 @@ ${err.errorData?.message ?? err.cause.message}`);
79080
80163
  });
79081
80164
  }
79082
80165
  async function agenticQueryComplete(chatroomId, options) {
79083
- const deps = await createDefaultDeps9();
80166
+ const deps = await createDefaultDeps11();
79084
80167
  await exports_Effect.runPromise(agenticQueryCompleteEffect(chatroomId, options).pipe(exports_Effect.provide(commandServicesLayerFromDeps(deps)), exports_Effect.catchAll(handleCompleteError)));
79085
80168
  }
79086
80169
  var agenticQueryCompleteEffect = (chatroomId, options) => exports_Effect.gen(function* () {
@@ -79125,7 +80208,7 @@ var exports_complete2 = {};
79125
80208
  __export(exports_complete2, {
79126
80209
  enhancerComplete: () => enhancerComplete
79127
80210
  });
79128
- async function createDefaultDeps10() {
80211
+ async function createDefaultDeps12() {
79129
80212
  const client4 = await getConvexClient();
79130
80213
  return {
79131
80214
  backend: {
@@ -79157,7 +80240,7 @@ ${err.errorData?.message ?? err.cause.message}`);
79157
80240
  });
79158
80241
  }
79159
80242
  async function enhancerComplete(chatroomId, options) {
79160
- const deps = await createDefaultDeps10();
80243
+ const deps = await createDefaultDeps12();
79161
80244
  await exports_Effect.runPromise(enhancerCompleteEffect(chatroomId, options).pipe(exports_Effect.provide(commandServicesLayerFromDeps(deps)), exports_Effect.catchAll(handleCompleteError2)));
79162
80245
  }
79163
80246
  var enhancerCompleteEffect = (chatroomId, options) => exports_Effect.gen(function* () {
@@ -79305,7 +80388,7 @@ function buildBaseLayer(d) {
79305
80388
  function buildFsLayer(fs11) {
79306
80389
  return fs11 ? BacklogFsServiceFrom(fs11) : BacklogFsServiceLive;
79307
80390
  }
79308
- async function createDefaultDeps11() {
80391
+ async function createDefaultDeps13() {
79309
80392
  const client4 = await getConvexClient();
79310
80393
  const fs11 = await import("node:fs/promises");
79311
80394
  return {
@@ -79361,51 +80444,51 @@ function computeContentHash(content) {
79361
80444
  return createHash("sha256").update(content).digest("hex");
79362
80445
  }
79363
80446
  async function listBacklog(chatroomId, options, deps) {
79364
- const d = deps ?? await createDefaultDeps11();
80447
+ const d = deps ?? await createDefaultDeps13();
79365
80448
  await exports_Effect.runPromise(listBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79366
80449
  }
79367
80450
  async function addBacklog(chatroomId, options, deps) {
79368
- const d = deps ?? await createDefaultDeps11();
80451
+ const d = deps ?? await createDefaultDeps13();
79369
80452
  await exports_Effect.runPromise(addBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79370
80453
  }
79371
80454
  async function completeBacklog(chatroomId, options, deps) {
79372
- const d = deps ?? await createDefaultDeps11();
80455
+ const d = deps ?? await createDefaultDeps13();
79373
80456
  await exports_Effect.runPromise(completeBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79374
80457
  }
79375
80458
  async function reopenBacklog(chatroomId, options, deps) {
79376
- const d = deps ?? await createDefaultDeps11();
80459
+ const d = deps ?? await createDefaultDeps13();
79377
80460
  await exports_Effect.runPromise(reopenBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79378
80461
  }
79379
80462
  async function patchBacklog(chatroomId, options, deps) {
79380
- const d = deps ?? await createDefaultDeps11();
80463
+ const d = deps ?? await createDefaultDeps13();
79381
80464
  await exports_Effect.runPromise(patchBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79382
80465
  }
79383
80466
  async function scoreBacklog(chatroomId, options, deps) {
79384
- const d = deps ?? await createDefaultDeps11();
80467
+ const d = deps ?? await createDefaultDeps13();
79385
80468
  await exports_Effect.runPromise(scoreBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79386
80469
  }
79387
80470
  async function markForReviewBacklog(chatroomId, options, deps) {
79388
- const d = deps ?? await createDefaultDeps11();
80471
+ const d = deps ?? await createDefaultDeps13();
79389
80472
  await exports_Effect.runPromise(markForReviewBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79390
80473
  }
79391
80474
  async function historyBacklog(chatroomId, options, deps) {
79392
- const d = deps ?? await createDefaultDeps11();
80475
+ const d = deps ?? await createDefaultDeps13();
79393
80476
  await exports_Effect.runPromise(historyBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79394
80477
  }
79395
80478
  async function updateBacklog(chatroomId, options, deps) {
79396
- const d = deps ?? await createDefaultDeps11();
80479
+ const d = deps ?? await createDefaultDeps13();
79397
80480
  await exports_Effect.runPromise(updateBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79398
80481
  }
79399
80482
  async function closeBacklog(chatroomId, options, deps) {
79400
- const d = deps ?? await createDefaultDeps11();
80483
+ const d = deps ?? await createDefaultDeps13();
79401
80484
  await exports_Effect.runPromise(closeBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79402
80485
  }
79403
80486
  async function deleteBacklog(chatroomId, options, deps) {
79404
- const d = deps ?? await createDefaultDeps11();
80487
+ const d = deps ?? await createDefaultDeps13();
79405
80488
  await exports_Effect.runPromise(deleteBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(buildBaseLayer(d))));
79406
80489
  }
79407
80490
  async function exportBacklog(chatroomId, options, deps) {
79408
- const d = deps ?? await createDefaultDeps11();
80491
+ const d = deps ?? await createDefaultDeps13();
79409
80492
  if (!d.fs) {
79410
80493
  console.error("❌ File system operations not available");
79411
80494
  process.exit(1);
@@ -79414,7 +80497,7 @@ async function exportBacklog(chatroomId, options, deps) {
79414
80497
  await exports_Effect.runPromise(exportBacklogEffect(chatroomId, options).pipe(exports_Effect.catchAll(handleBacklogError), exports_Effect.provide(exports_Layer.merge(buildBaseLayer(d), buildFsLayer(d.fs)))));
79415
80498
  }
79416
80499
  async function importBacklog(chatroomId, options, deps) {
79417
- const d = deps ?? await createDefaultDeps11();
80500
+ const d = deps ?? await createDefaultDeps13();
79418
80501
  if (!d.fs) {
79419
80502
  console.error("❌ File system operations not available");
79420
80503
  process.exit(1);
@@ -80201,7 +81284,7 @@ __export(exports_read, {
80201
81284
  taskReadEffect: () => taskReadEffect,
80202
81285
  taskRead: () => taskRead
80203
81286
  });
80204
- async function createDefaultDeps12() {
81287
+ async function createDefaultDeps14() {
80205
81288
  const client4 = await getConvexClient();
80206
81289
  return {
80207
81290
  backend: {
@@ -80243,7 +81326,7 @@ function handleTaskReadError(err) {
80243
81326
  });
80244
81327
  }
80245
81328
  async function taskRead(chatroomId, options, deps) {
80246
- const d = deps ?? await createDefaultDeps12();
81329
+ const d = deps ?? await createDefaultDeps14();
80247
81330
  const layer = commandServicesLayerFromDeps(d);
80248
81331
  await exports_Effect.runPromise(taskReadEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleTaskReadError(err)), exports_Effect.provide(layer)));
80249
81332
  }
@@ -80334,7 +81417,7 @@ __export(exports_skill, {
80334
81417
  activateSkillEffect: () => activateSkillEffect,
80335
81418
  activateSkill: () => activateSkill
80336
81419
  });
80337
- async function createDefaultDeps13() {
81420
+ async function createDefaultDeps15() {
80338
81421
  const client4 = await getConvexClient();
80339
81422
  return {
80340
81423
  backend: {
@@ -80403,12 +81486,12 @@ function handleActivateSkillError(err) {
80403
81486
  });
80404
81487
  }
80405
81488
  async function listSkills(chatroomId, options, deps) {
80406
- const d = deps ?? await createDefaultDeps13();
81489
+ const d = deps ?? await createDefaultDeps15();
80407
81490
  const layer = commandServicesLayerFromDeps(d);
80408
81491
  await exports_Effect.runPromise(listSkillsEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleListSkillsError(err)), exports_Effect.provide(layer)));
80409
81492
  }
80410
81493
  async function activateSkill(chatroomId, skillId, options, deps) {
80411
- const d = deps ?? await createDefaultDeps13();
81494
+ const d = deps ?? await createDefaultDeps15();
80412
81495
  const layer = commandServicesLayerFromDeps(d);
80413
81496
  await exports_Effect.runPromise(activateSkillEffect(chatroomId, skillId, options).pipe(exports_Effect.catchAll((err) => handleActivateSkillError(err)), exports_Effect.provide(layer)));
80414
81497
  }
@@ -80478,6 +81561,59 @@ var init_skill = __esm(() => {
80478
81561
  init_convex_error();
80479
81562
  });
80480
81563
 
81564
+ // src/commands/messages/send.ts
81565
+ var exports_send = {};
81566
+ __export(exports_send, {
81567
+ sendUserMessage: () => sendUserMessage
81568
+ });
81569
+ async function createDefaultDeps16() {
81570
+ const client4 = await getConvexClient();
81571
+ return {
81572
+ backend: {
81573
+ mutation: (endpoint, args2) => client4.mutation(endpoint, args2),
81574
+ query: (endpoint, args2) => client4.query(endpoint, args2)
81575
+ },
81576
+ session: { getSessionId }
81577
+ };
81578
+ }
81579
+ async function requireSession3(deps) {
81580
+ const sessionId = await deps.session.getSessionId();
81581
+ if (!sessionId)
81582
+ throw new Error("Not authenticated. Please run: chatroom auth login");
81583
+ return sessionId;
81584
+ }
81585
+ async function sendUserMessage(chatroomId, options, deps) {
81586
+ if (!options.content.trim())
81587
+ throw new Error("Message content cannot be empty");
81588
+ const d = deps ?? await createDefaultDeps16();
81589
+ const sessionId = await requireSession3(d);
81590
+ const chatroom = await d.backend.query(api.chatrooms.get, {
81591
+ sessionId,
81592
+ chatroomId
81593
+ });
81594
+ if (!chatroom)
81595
+ throw new Error(`Chatroom not found or access denied: ${chatroomId}`);
81596
+ const targetRole = options.targetRole ?? chatroom.teamEntryPoint;
81597
+ if (!targetRole)
81598
+ throw new Error("Chatroom has no team entry point");
81599
+ const messageId = await d.backend.mutation(api.messages.sendMessage, {
81600
+ sessionId,
81601
+ chatroomId,
81602
+ senderRole: "user",
81603
+ content: options.content,
81604
+ targetRole,
81605
+ type: "message"
81606
+ });
81607
+ console.log(`✅ Message sent to ${targetRole}`);
81608
+ console.log(` Message ID: ${messageId}`);
81609
+ console.log(" Check task status with: chatroom messages list");
81610
+ }
81611
+ var init_send = __esm(() => {
81612
+ init_api3();
81613
+ init_storage();
81614
+ init_client2();
81615
+ });
81616
+
80481
81617
  // src/commands/messages/messages-fs-service.ts
80482
81618
  import * as nodeFs2 from "node:fs/promises";
80483
81619
  function messageFilename(msg) {
@@ -80845,7 +81981,7 @@ __export(exports_messages, {
80845
81981
  anchorMessagesEffect: () => anchorMessagesEffect,
80846
81982
  anchorMessages: () => anchorMessages
80847
81983
  });
80848
- async function createDefaultDeps14() {
81984
+ async function createDefaultDeps17() {
80849
81985
  const client4 = await getConvexClient();
80850
81986
  return {
80851
81987
  backend: {
@@ -80905,12 +82041,12 @@ function handleMessagesError(err) {
80905
82041
  });
80906
82042
  }
80907
82043
  async function listBySenderRole(chatroomId, options, deps) {
80908
- const d = deps ?? await createDefaultDeps14();
82044
+ const d = deps ?? await createDefaultDeps17();
80909
82045
  const layer = commandServicesLayerFromDeps(d);
80910
82046
  await exports_Effect.runPromise(listBySenderRoleEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleMessagesError(err)), exports_Effect.provide(layer)));
80911
82047
  }
80912
82048
  async function listSinceMessage(chatroomId, options, deps) {
80913
- const d = deps ?? await createDefaultDeps14();
82049
+ const d = deps ?? await createDefaultDeps17();
80914
82050
  const layer = commandServicesLayerFromDeps(d);
80915
82051
  await exports_Effect.runPromise(listSinceMessageEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleMessagesError(err)), exports_Effect.provide(layer)));
80916
82052
  }
@@ -81036,7 +82172,7 @@ __export(exports_context2, {
81036
82172
  inspectContextEffect: () => inspectContextEffect,
81037
82173
  inspectContext: () => inspectContext
81038
82174
  });
81039
- async function createDefaultDeps15() {
82175
+ async function createDefaultDeps18() {
81040
82176
  const client4 = await getConvexClient();
81041
82177
  return {
81042
82178
  backend: {
@@ -81077,17 +82213,17 @@ function handleContextError(err) {
81077
82213
  });
81078
82214
  }
81079
82215
  async function readContext(chatroomId, options, deps) {
81080
- const d = deps ?? await createDefaultDeps15();
82216
+ const d = deps ?? await createDefaultDeps18();
81081
82217
  const layer = commandServicesLayerFromDeps(d);
81082
82218
  await exports_Effect.runPromise(readContextEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleContextError(err)), exports_Effect.provide(layer)));
81083
82219
  }
81084
82220
  async function newContext(chatroomId, options, deps) {
81085
- const d = deps ?? await createDefaultDeps15();
82221
+ const d = deps ?? await createDefaultDeps18();
81086
82222
  const layer = commandServicesLayerFromDeps(d);
81087
82223
  await exports_Effect.runPromise(newContextEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleContextError(err)), exports_Effect.provide(layer)));
81088
82224
  }
81089
82225
  async function listContexts(chatroomId, options, deps) {
81090
- const d = deps ?? await createDefaultDeps15();
82226
+ const d = deps ?? await createDefaultDeps18();
81091
82227
  const layer = commandServicesLayerFromDeps(d);
81092
82228
  await exports_Effect.runPromise(listContextsEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleContextError(err)), exports_Effect.provide(layer)));
81093
82229
  }
@@ -81095,7 +82231,7 @@ function viewTemplate() {
81095
82231
  return getContextViewTemplate();
81096
82232
  }
81097
82233
  async function inspectContext(chatroomId, options, deps) {
81098
- const d = deps ?? await createDefaultDeps15();
82234
+ const d = deps ?? await createDefaultDeps18();
81099
82235
  const layer = commandServicesLayerFromDeps(d);
81100
82236
  await exports_Effect.runPromise(inspectContextEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleContextError(err)), exports_Effect.provide(layer)));
81101
82237
  }
@@ -81335,7 +82471,7 @@ __export(exports_guidelines, {
81335
82471
  listGuidelineTypesEffect: () => listGuidelineTypesEffect,
81336
82472
  listGuidelineTypes: () => listGuidelineTypes
81337
82473
  });
81338
- async function createDefaultDeps16() {
82474
+ async function createDefaultDeps19() {
81339
82475
  const client4 = await getConvexClient();
81340
82476
  return {
81341
82477
  backend: {
@@ -81376,12 +82512,12 @@ function handleListGuidelineTypesError(err) {
81376
82512
  });
81377
82513
  }
81378
82514
  async function viewGuidelines(options, deps) {
81379
- const d = deps ?? await createDefaultDeps16();
82515
+ const d = deps ?? await createDefaultDeps19();
81380
82516
  const layer = layerFromDeps7(d);
81381
82517
  await exports_Effect.runPromise(viewGuidelinesEffect(options).pipe(exports_Effect.catchAll((err) => handleViewGuidelinesError(err)), exports_Effect.provide(layer)));
81382
82518
  }
81383
82519
  async function listGuidelineTypes(deps) {
81384
- const d = deps ?? await createDefaultDeps16();
82520
+ const d = deps ?? await createDefaultDeps19();
81385
82521
  const layer = layerFromDeps7(d);
81386
82522
  await exports_Effect.runPromise(listGuidelineTypesEffect().pipe(exports_Effect.catchAll((err) => handleListGuidelineTypesError(err)), exports_Effect.provide(layer)));
81387
82523
  }
@@ -81451,7 +82587,7 @@ __export(exports_artifact, {
81451
82587
  createArtifactEffect: () => createArtifactEffect,
81452
82588
  createArtifact: () => createArtifact
81453
82589
  });
81454
- async function createDefaultDeps17() {
82590
+ async function createDefaultDeps20() {
81455
82591
  const client4 = await getConvexClient();
81456
82592
  return {
81457
82593
  backend: {
@@ -81473,19 +82609,19 @@ function handleArtifactError(err) {
81473
82609
  });
81474
82610
  }
81475
82611
  async function createArtifact(chatroomId, options, deps) {
81476
- const d = deps ?? await createDefaultDeps17();
82612
+ const d = deps ?? await createDefaultDeps20();
81477
82613
  const layer = commandServicesLayerFromDeps(d);
81478
82614
  return exports_Effect.runPromise(createArtifactEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleArtifactError(err).pipe(exports_Effect.map(() => {
81479
82615
  return;
81480
82616
  }))), exports_Effect.provide(layer)));
81481
82617
  }
81482
82618
  async function viewArtifact(chatroomId, options, deps) {
81483
- const d = deps ?? await createDefaultDeps17();
82619
+ const d = deps ?? await createDefaultDeps20();
81484
82620
  const layer = commandServicesLayerFromDeps(d);
81485
82621
  await exports_Effect.runPromise(viewArtifactEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleArtifactError(err)), exports_Effect.provide(layer)));
81486
82622
  }
81487
82623
  async function viewManyArtifacts(chatroomId, options, deps) {
81488
- const d = deps ?? await createDefaultDeps17();
82624
+ const d = deps ?? await createDefaultDeps20();
81489
82625
  const layer = commandServicesLayerFromDeps(d);
81490
82626
  await exports_Effect.runPromise(viewManyArtifactsEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleArtifactError(err)), exports_Effect.provide(layer)));
81491
82627
  }
@@ -81835,7 +82971,7 @@ __export(exports_telegram, {
81835
82971
  sendMessageEffect: () => sendMessageEffect,
81836
82972
  sendMessage: () => sendMessage
81837
82973
  });
81838
- async function createDefaultDeps18() {
82974
+ async function createDefaultDeps21() {
81839
82975
  const client4 = await getConvexClient();
81840
82976
  return {
81841
82977
  backend: {
@@ -81917,7 +83053,7 @@ ${err.cause.message}`);
81917
83053
  });
81918
83054
  }
81919
83055
  async function sendMessage(options, deps) {
81920
- const d = deps ?? await createDefaultDeps18();
83056
+ const d = deps ?? await createDefaultDeps21();
81921
83057
  const layer = layerFromDeps8(d);
81922
83058
  await exports_Effect.runPromise(sendMessageEffect(options).pipe(exports_Effect.catchAll((err) => handleSendMessageError(err)), exports_Effect.provide(layer)));
81923
83059
  }
@@ -82053,6 +83189,11 @@ var init_daemon_layers = __esm(() => {
82053
83189
  init_process();
82054
83190
  });
82055
83191
 
83192
+ // src/daemon/entry/daemon-types.ts
83193
+ function asConvexSessionId(sessionId) {
83194
+ return sessionId;
83195
+ }
83196
+
82056
83197
  // src/daemon/entry/events/event-bus.ts
82057
83198
  class DaemonEventBus {
82058
83199
  listeners = new Map;
@@ -82180,35 +83321,35 @@ var init_daemon_startup_log = __esm(() => {
82180
83321
  import { createHash as createHash2 } from "node:crypto";
82181
83322
  import {
82182
83323
  appendFileSync,
82183
- existsSync as existsSync5,
83324
+ existsSync as existsSync6,
82184
83325
  mkdirSync as mkdirSync4,
82185
- readFileSync as readFileSync7,
83326
+ readFileSync as readFileSync8,
82186
83327
  renameSync,
82187
83328
  unlinkSync,
82188
83329
  writeFileSync as writeFileSync3
82189
83330
  } from "node:fs";
82190
83331
  import { homedir as homedir5 } from "node:os";
82191
- import { join as join16 } from "node:path";
83332
+ import { join as join17 } from "node:path";
82192
83333
  function getUrlHash() {
82193
83334
  const url2 = getConvexUrl();
82194
83335
  return createHash2("sha256").update(url2).digest("hex").substring(0, 8);
82195
83336
  }
82196
83337
  function getChildPidsFilePath() {
82197
- const dir = join16(homedir5(), ".chatroom");
82198
- return join16(dir, `daemon-children-${getUrlHash()}.pids`);
83338
+ const dir = join17(homedir5(), ".chatroom");
83339
+ return join17(dir, `daemon-children-${getUrlHash()}.pids`);
82199
83340
  }
82200
83341
  function ensureChatroomDir2() {
82201
- const dir = join16(homedir5(), ".chatroom");
82202
- if (!existsSync5(dir)) {
83342
+ const dir = join17(homedir5(), ".chatroom");
83343
+ if (!existsSync6(dir)) {
82203
83344
  mkdirSync4(dir, { recursive: true, mode: 448 });
82204
83345
  }
82205
83346
  }
82206
83347
  function readPids() {
82207
83348
  const filePath = getChildPidsFilePath();
82208
- if (!existsSync5(filePath))
83349
+ if (!existsSync6(filePath))
82209
83350
  return [];
82210
83351
  try {
82211
- return readFileSync7(filePath, "utf-8").split(`
83352
+ return readFileSync8(filePath, "utf-8").split(`
82212
83353
  `).map((line) => parseInt(line.trim(), 10)).filter((n) => Number.isFinite(n) && n > 0);
82213
83354
  } catch {
82214
83355
  return [];
@@ -82226,9 +83367,9 @@ function trackChildPid(pid) {
82226
83367
  function untrackChildPid(pid) {
82227
83368
  try {
82228
83369
  const filePath = getChildPidsFilePath();
82229
- if (!existsSync5(filePath))
83370
+ if (!existsSync6(filePath))
82230
83371
  return;
82231
- const remaining = readFileSync7(filePath, "utf-8").split(`
83372
+ const remaining = readFileSync8(filePath, "utf-8").split(`
82232
83373
  `).filter((line) => {
82233
83374
  const n = parseInt(line.trim(), 10);
82234
83375
  return Number.isFinite(n) && n > 0 && n !== pid;
@@ -82245,7 +83386,7 @@ function untrackChildPid(pid) {
82245
83386
  function clearTrackedPids() {
82246
83387
  try {
82247
83388
  const filePath = getChildPidsFilePath();
82248
- if (existsSync5(filePath)) {
83389
+ if (existsSync6(filePath)) {
82249
83390
  unlinkSync(filePath);
82250
83391
  }
82251
83392
  } catch {}
@@ -82313,7 +83454,7 @@ var init_orphan_tracker = __esm(() => {
82313
83454
  // src/daemon/entry/handlers/process/output-store.ts
82314
83455
  import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile6, rm as rm2 } from "node:fs/promises";
82315
83456
  import { tmpdir } from "node:os";
82316
- import { join as join17 } from "node:path";
83457
+ import { join as join18 } from "node:path";
82317
83458
 
82318
83459
  class TempFileOutputStore {
82319
83460
  state;
@@ -82376,7 +83517,7 @@ function createOutputStore(runId) {
82376
83517
  if (!RUN_ID_RE.test(runId)) {
82377
83518
  throw new Error(`Invalid runId: ${runId}`);
82378
83519
  }
82379
- const filePath = join17(TEMP_DIR, `${runId}.log`);
83520
+ const filePath = join18(TEMP_DIR, `${runId}.log`);
82380
83521
  return new TempFileOutputStore(filePath);
82381
83522
  }
82382
83523
  async function ensureTempDir() {
@@ -82390,7 +83531,7 @@ async function cleanOrphanTempFiles() {
82390
83531
  var TAIL_WINDOW_BYTES, TEMP_DIR, RUN_ID_RE, MAX_TAIL_LINES_V2 = 50;
82391
83532
  var init_output_store = __esm(() => {
82392
83533
  TAIL_WINDOW_BYTES = 32 * 1024;
82393
- TEMP_DIR = join17(tmpdir(), "chatroom-cli", "runs");
83534
+ TEMP_DIR = join18(tmpdir(), "chatroom-cli", "runs");
82394
83535
  RUN_ID_RE = /^[a-z0-9]+$/i;
82395
83536
  });
82396
83537
 
@@ -98206,9 +99347,9 @@ var init_state_recovery = __esm(() => {
98206
99347
 
98207
99348
  // src/commands/machine/pid.ts
98208
99349
  import { createHash as createHash3 } from "node:crypto";
98209
- import { existsSync as existsSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
99350
+ import { existsSync as existsSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
98210
99351
  import { homedir as homedir6 } from "node:os";
98211
- import { join as join18 } from "node:path";
99352
+ import { join as join19 } from "node:path";
98212
99353
  function getUrlHash2() {
98213
99354
  const url3 = getConvexUrl();
98214
99355
  return createHash3("sha256").update(url3).digest("hex").substring(0, 8);
@@ -98217,12 +99358,12 @@ function getPidFileName() {
98217
99358
  return `daemon-${getUrlHash2()}.pid`;
98218
99359
  }
98219
99360
  function ensureChatroomDir3() {
98220
- if (!existsSync6(CHATROOM_DIR4)) {
99361
+ if (!existsSync7(CHATROOM_DIR4)) {
98221
99362
  mkdirSync5(CHATROOM_DIR4, { recursive: true, mode: 448 });
98222
99363
  }
98223
99364
  }
98224
99365
  function getPidFilePath() {
98225
- return join18(CHATROOM_DIR4, getPidFileName());
99366
+ return join19(CHATROOM_DIR4, getPidFileName());
98226
99367
  }
98227
99368
  function isProcessRunning(pid) {
98228
99369
  try {
@@ -98234,11 +99375,11 @@ function isProcessRunning(pid) {
98234
99375
  }
98235
99376
  function readPid() {
98236
99377
  const pidPath = getPidFilePath();
98237
- if (!existsSync6(pidPath)) {
99378
+ if (!existsSync7(pidPath)) {
98238
99379
  return null;
98239
99380
  }
98240
99381
  try {
98241
- const content = readFileSync8(pidPath, "utf-8").trim();
99382
+ const content = readFileSync9(pidPath, "utf-8").trim();
98242
99383
  const pid = parseInt(content, 10);
98243
99384
  if (isNaN(pid) || pid <= 0) {
98244
99385
  return null;
@@ -98256,7 +99397,7 @@ function writePid() {
98256
99397
  function removePid() {
98257
99398
  const pidPath = getPidFilePath();
98258
99399
  try {
98259
- if (existsSync6(pidPath)) {
99400
+ if (existsSync7(pidPath)) {
98260
99401
  unlinkSync2(pidPath);
98261
99402
  }
98262
99403
  } catch {}
@@ -98319,7 +99460,7 @@ function releaseLock() {
98319
99460
  var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000;
98320
99461
  var init_pid = __esm(() => {
98321
99462
  init_client2();
98322
- CHATROOM_DIR4 = join18(homedir6(), ".chatroom");
99463
+ CHATROOM_DIR4 = join19(homedir6(), ".chatroom");
98323
99464
  });
98324
99465
 
98325
99466
  // src/infrastructure/machine/crash-loop-tracker.ts
@@ -99518,6 +100659,7 @@ class AgentProcessManager {
99518
100659
  }
99519
100660
  }
99520
100661
  async runHandleNativeTurnEnd(opts, slot) {
100662
+ this.maybeEmitProviderUnavailable(opts.chatroomId, opts.role, slot);
99521
100663
  if (await tryAbortResumeStorm({
99522
100664
  resumeStormTracker: this.deps.resumeStormTracker,
99523
100665
  backend: createTurnCompletedBackend(this.deps),
@@ -99560,6 +100702,7 @@ class AgentProcessManager {
99560
100702
  }
99561
100703
  const stopReason = resolveStopReason(opts.code, opts.signal);
99562
100704
  const ctx = this.captureExitContext(slot, opts, stopReason);
100705
+ this.maybeEmitProviderUnavailable(opts.chatroomId, opts.role, slot);
99563
100706
  notifyNativeHarnessSessionLostOnExit({
99564
100707
  chatroomId: opts.chatroomId,
99565
100708
  role: opts.role,
@@ -99675,6 +100818,24 @@ class AgentProcessManager {
99675
100818
  console.log(`[AgentProcessManager] cursor-sdk run-error detected: ${formatCursorSdkRunErrorMessage(recentLogLines)}`);
99676
100819
  return true;
99677
100820
  }
100821
+ maybeEmitProviderUnavailable(chatroomId, role, slot) {
100822
+ if (!slot || slot.harness !== "codex-sdk" || slot.providerUnavailableEmitted)
100823
+ return;
100824
+ const classification2 = classifyProviderErrorFromLogs(slot.recentLogLines ?? []);
100825
+ if (!classification2)
100826
+ return;
100827
+ slot.providerUnavailableEmitted = true;
100828
+ this.deps.backend.mutation(api.machines.emitAgentProviderUnavailable, {
100829
+ sessionId: this.deps.sessionId,
100830
+ machineId: this.deps.machineId,
100831
+ chatroomId,
100832
+ role,
100833
+ reason: classification2.reason,
100834
+ model: slot.model ?? "",
100835
+ message: classification2.message,
100836
+ recoverable: providerUnavailableRecoverable(classification2.reason)
100837
+ }).catch(() => {});
100838
+ }
99678
100839
  maybeRestartAgent(opts, ctx) {
99679
100840
  const { harness, model, workingDir, recentLogLines } = ctx;
99680
100841
  const logs = recentLogLines ?? [];
@@ -100347,6 +101508,7 @@ class AgentProcessManager {
100347
101508
  slot.startedAt = this.deps.clock.now();
100348
101509
  slot.pendingOperation = undefined;
100349
101510
  slot.recentLogLines = [];
101511
+ slot.providerUnavailableEmitted = false;
100350
101512
  this.deps.resumeStormTracker.reset(opts.chatroomId, opts.role);
100351
101513
  }
100352
101514
  emitSpawnedAgentUpdate(opts, spawnResult, pid) {
@@ -100619,6 +101781,7 @@ var init_agent_process_manager = __esm(() => {
100619
101781
  init_agent_lifecycle_types();
100620
101782
  init_spawn_policy();
100621
101783
  init_abort_resume_storm();
101784
+ init_classify_provider_error();
100622
101785
  init_classify_resume_storm_reason();
100623
101786
  init_decide_resume_path();
100624
101787
  init_handle_turn_completed();
@@ -100651,7 +101814,7 @@ async function discoverModelsForHarness(harness, service3) {
100651
101814
  async function discoverModels(agentServices) {
100652
101815
  return exports_Effect.runPromise(discoverModelsEffect(agentServices));
100653
101816
  }
100654
- function createDefaultDeps19() {
101817
+ function createDefaultDeps22() {
100655
101818
  return {
100656
101819
  backend: {
100657
101820
  mutation: async () => {
@@ -100804,7 +101967,7 @@ Run: ${formatAuthLoginCommand(convexUrl)}`);
100804
101967
  return yield* waitForAuthenticationEffect(convexUrl);
100805
101968
  }), validateSessionEffect = (client4, sessionId, convexUrl) => exports_Effect.gen(function* () {
100806
101969
  const validation = yield* exports_Effect.tryPromise({
100807
- try: () => client4.query(api.cliAuth.validateSession, { sessionId }),
101970
+ try: () => client4.query(api.cliAuth.validateSession, { sessionId: asConvexSessionId(sessionId) }),
100808
101971
  catch: (e) => e
100809
101972
  });
100810
101973
  if (validation.valid) {
@@ -100818,7 +101981,9 @@ Run: ${formatAuthLoginCommand(convexUrl)}`);
100818
101981
  const newSessionId2 = yield* waitForAuthenticationEffect(convexUrl);
100819
101982
  const typedNewSession = newSessionId2;
100820
101983
  const revalidation = yield* exports_Effect.tryPromise({
100821
- try: () => client4.query(api.cliAuth.validateSession, { sessionId: typedNewSession }),
101984
+ try: () => client4.query(api.cliAuth.validateSession, {
101985
+ sessionId: asConvexSessionId(typedNewSession)
101986
+ }),
100822
101987
  catch: (e) => e
100823
101988
  });
100824
101989
  if (!revalidation.valid) {
@@ -100845,7 +102010,7 @@ Run: ${formatAuthLoginCommand(convexUrl)}`);
100845
102010
  }
100846
102011
  return config4;
100847
102012
  }), registerMachineEffect = (client4, sessionId, config4) => exports_Effect.catchAll(exports_Effect.tryPromise(() => client4.mutation(api.machines.register, {
100848
- sessionId,
102013
+ sessionId: asConvexSessionId(sessionId),
100849
102014
  machineId: config4.machineId,
100850
102015
  hostname: config4.hostname,
100851
102016
  os: config4.os,
@@ -100854,7 +102019,10 @@ Run: ${formatAuthLoginCommand(convexUrl)}`);
100854
102019
  })), (error51) => exports_Effect.sync(() => {
100855
102020
  console.warn(`⚠️ Machine registration update failed: ${getErrorMessage(error51)}`);
100856
102021
  })), fetchCachedMachineModelsEffect = (client4, sessionId, machineId) => exports_Effect.tryPromise({
100857
- try: () => client4.query(api.machines.getMachineModels, { sessionId, machineId }),
102022
+ try: () => client4.query(api.machines.getMachineModels, {
102023
+ sessionId: asConvexSessionId(sessionId),
102024
+ machineId
102025
+ }),
100858
102026
  catch: (e) => e
100859
102027
  }).pipe(exports_Effect.map((result) => result?.availableModels ?? {}), exports_Effect.catchAll(() => exports_Effect.succeed({}))), connectOnceEffect = (client4, sessionId, convexUrl) => exports_Effect.gen(function* () {
100860
102028
  const typedSessionId = yield* validateSessionEffect(client4, sessionId, convexUrl);
@@ -100868,7 +102036,7 @@ Run: ${formatAuthLoginCommand(convexUrl)}`);
100868
102036
  return { typedSessionId, config: config4, machineId, agentServices, cachedModels };
100869
102037
  }), connectDaemonEffect = (client4, sessionId, machineId) => exports_Effect.tryPromise({
100870
102038
  try: () => client4.mutation(api.machines.updateDaemonStatus, {
100871
- sessionId,
102039
+ sessionId: asConvexSessionId(sessionId),
100872
102040
  machineId,
100873
102041
  connected: true
100874
102042
  }),
@@ -100990,7 +102158,7 @@ var init_init_daemon = __esm(() => {
100990
102158
  convexUrl,
100991
102159
  agentServices,
100992
102160
  cachedModels,
100993
- deps: createDefaultDeps19()
102161
+ deps: createDefaultDeps22()
100994
102162
  });
100995
102163
  yield* registerEventListenersEffect().pipe(exports_Effect.provide(daemonSessionToLayers(init2)));
100996
102164
  yield* logStartupEffect(cachedModels).pipe(exports_Effect.provide(daemonSessionToLayers(init2)));
@@ -101003,6 +102171,35 @@ var init_init_daemon = __esm(() => {
101003
102171
  function hasEntries(map19) {
101004
102172
  return Object.keys(map19).length > 0;
101005
102173
  }
102174
+ function getCatalogEndpoints() {
102175
+ const harnesses = api.harnesses;
102176
+ return {
102177
+ "codex-sdk": harnesses?.codexSdk,
102178
+ copilot: harnesses?.copilot,
102179
+ cursor: harnesses?.cursor
102180
+ };
102181
+ }
102182
+ async function fetchHarnessCatalog(client4, sessionId) {
102183
+ const endpoints = getCatalogEndpoints();
102184
+ const entries2 = await Promise.all(Object.keys(endpoints).map(async (harness) => {
102185
+ const endpoint = endpoints[harness]?.listModels;
102186
+ if (!endpoint)
102187
+ return;
102188
+ try {
102189
+ return [harness, await client4.query(endpoint, { sessionId })];
102190
+ } catch (error51) {
102191
+ console.warn(`[${formatTimestamp()}] ⚠️ Server model catalog fetch failed for ${harness}: ${getErrorMessage(error51)}`);
102192
+ return;
102193
+ }
102194
+ }));
102195
+ return Object.fromEntries(entries2.filter((entry) => entry !== undefined));
102196
+ }
102197
+ function applyCatalogOverlay(discovered, catalog) {
102198
+ for (const [harness, models] of Object.entries(catalog)) {
102199
+ discovered[harness] = models;
102200
+ }
102201
+ return discovered;
102202
+ }
101006
102203
  function difference4(a, b) {
101007
102204
  const exclude3 = new Set(b);
101008
102205
  return (a ?? []).filter((model) => !exclude3.has(model));
@@ -101050,6 +102247,15 @@ function logPushOutcome(modelDiff, totalCount, options) {
101050
102247
  }
101051
102248
  logRefreshOutcome(modelDiff, totalCount);
101052
102249
  }
102250
+ function nextSnapshotAfterHarness(current, harness, result, catalog) {
102251
+ const next4 = { ...current ?? {} };
102252
+ if (result.installed) {
102253
+ next4[harness] = catalog[harness] ?? result.models;
102254
+ } else {
102255
+ delete next4[harness];
102256
+ }
102257
+ return next4;
102258
+ }
101053
102259
  var pushModelsSnapshotMutationEffect = (models, modelDiff, nextHarnessFingerprint, ctxConfig, options) => exports_Effect.gen(function* () {
101054
102260
  const session2 = yield* DaemonSessionService;
101055
102261
  yield* exports_Effect.tryPromise({
@@ -101089,16 +102295,10 @@ var pushModelsSnapshotMutationEffect = (models, modelDiff, nextHarnessFingerprin
101089
102295
  const message = getErrorMessage(error51);
101090
102296
  console.warn(`[${formatTimestamp()}] ⚠️ Model refresh failed: ${message}`);
101091
102297
  return { kind: "failed", message };
101092
- }))), refreshModelsEffect, discoverAndPushHarnessModelsEffect = (harness, service3) => exports_Effect.gen(function* () {
102298
+ }))), refreshModelsEffect, discoverAndPushHarnessModelsEffect = (harness, service3, catalog) => exports_Effect.gen(function* () {
101093
102299
  const mutable = yield* DaemonMutableStateService;
101094
102300
  const result = yield* exports_Effect.promise(() => discoverModelsForHarness(harness, service3));
101095
- const current = (yield* exports_Ref.get(mutable.lastPushedModels)) ?? {};
101096
- const next4 = { ...current };
101097
- if (result.installed) {
101098
- next4[harness] = result.models;
101099
- } else {
101100
- delete next4[harness];
101101
- }
102301
+ const next4 = nextSnapshotAfterHarness(yield* exports_Ref.get(mutable.lastPushedModels), harness, result, catalog);
101102
102302
  const pushOutcome = yield* pushModelsSnapshotIfChangedEffect(next4, {
101103
102303
  logPrefix: `${harness} models updated`
101104
102304
  });
@@ -101122,10 +102322,12 @@ var init_models_refresh = __esm(() => {
101122
102322
  }
101123
102323
  const ctxConfig = session2.config;
101124
102324
  const outcome = yield* exports_Effect.gen(function* () {
102325
+ const catalog = yield* exports_Effect.promise(() => fetchHarnessCatalog(session2.client, session2.sessionId));
101125
102326
  const models = yield* exports_Effect.tryPromise({
101126
102327
  try: async () => discoverModels(session2.agentServices),
101127
102328
  catch: (e) => e
101128
102329
  });
102330
+ applyCatalogOverlay(models, catalog);
101129
102331
  const freshConfig = yield* exports_Effect.tryPromise({
101130
102332
  try: async () => ensureMachineRegistered(),
101131
102333
  catch: (e) => e
@@ -101155,7 +102357,8 @@ var init_models_refresh = __esm(() => {
101155
102357
  const session2 = yield* DaemonSessionService;
101156
102358
  if (!session2.config)
101157
102359
  return;
101158
- yield* exports_Effect.forEach(Array.from(session2.agentServices.entries()), ([harness, service3]) => discoverAndPushHarnessModelsEffect(harness, service3), { concurrency: "unbounded" });
102360
+ const catalog = yield* exports_Effect.promise(() => fetchHarnessCatalog(session2.client, session2.sessionId));
102361
+ yield* exports_Effect.forEach(Array.from(session2.agentServices.entries()), ([harness, service3]) => discoverAndPushHarnessModelsEffect(harness, service3, catalog), { concurrency: "unbounded" });
101159
102362
  });
101160
102363
  });
101161
102364
 
@@ -101198,12 +102401,24 @@ var init_capabilities_bridge = __esm(() => {
101198
102401
  });
101199
102402
 
101200
102403
  // ../../services/backend/config/featureFlags.ts
101201
- var featureFlags;
102404
+ function getAllowedSignupMethodsForEnvironment(nodeEnv, convexDeployment) {
102405
+ if (convexDeployment?.startsWith("local:")) {
102406
+ return ["self", "invite"];
102407
+ }
102408
+ if (nodeEnv && DEV_NODE_ENVS.has(nodeEnv)) {
102409
+ return ["self", "invite"];
102410
+ }
102411
+ return ["invite"];
102412
+ }
102413
+ var DEV_NODE_ENVS, featureFlags;
101202
102414
  var init_featureFlags = __esm(() => {
102415
+ DEV_NODE_ENVS = new Set(["development", "test"]);
101203
102416
  featureFlags = {
101204
102417
  disableLogin: false,
101205
102418
  directHarnessWorkers: true,
101206
- allowedSignupMethods: ["self"]
102419
+ get allowedSignupMethods() {
102420
+ return getAllowedSignupMethodsForEnvironment("development", process.env.CONVEX_DEPLOYMENT);
102421
+ }
101207
102422
  };
101208
102423
  });
101209
102424
 
@@ -103015,16 +104230,16 @@ var init_jsonc = __esm(() => {
103015
104230
 
103016
104231
  // src/infrastructure/services/workspace/workspace-resolver.ts
103017
104232
  import { readFile as readFile7, readdir, stat as stat3 } from "node:fs/promises";
103018
- import { join as join19, basename, resolve as resolve4 } from "node:path";
104233
+ import { join as join20, basename, resolve as resolve4 } from "node:path";
103019
104234
  async function resolveGlobPatternStar(rootDir, cleaned) {
103020
- const parentDir = join19(rootDir, cleaned.slice(0, -2));
104235
+ const parentDir = join20(rootDir, cleaned.slice(0, -2));
103021
104236
  try {
103022
104237
  const entries2 = await readdir(parentDir, { withFileTypes: true });
103023
104238
  const dirs = [];
103024
104239
  for (const entry of entries2) {
103025
104240
  if (!entry.isDirectory())
103026
104241
  continue;
103027
- const dirPath = join19(parentDir, entry.name);
104242
+ const dirPath = join20(parentDir, entry.name);
103028
104243
  if (resolve4(dirPath).startsWith(resolve4(rootDir))) {
103029
104244
  dirs.push(dirPath);
103030
104245
  }
@@ -103035,7 +104250,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
103035
104250
  }
103036
104251
  }
103037
104252
  async function resolveLiteralPath(rootDir, cleaned) {
103038
- const dir = join19(rootDir, cleaned);
104253
+ const dir = join20(rootDir, cleaned);
103039
104254
  try {
103040
104255
  if (!resolve4(dir).startsWith(resolve4(rootDir)))
103041
104256
  return [];
@@ -103055,7 +104270,7 @@ async function resolveGlobPattern(rootDir, pattern) {
103055
104270
  }
103056
104271
  async function readPackageJson(dir) {
103057
104272
  try {
103058
- const content = await readFile7(join19(dir, "package.json"), "utf-8");
104273
+ const content = await readFile7(join20(dir, "package.json"), "utf-8");
103059
104274
  const pkg = JSON.parse(content);
103060
104275
  return {
103061
104276
  name: pkg.name || basename(dir),
@@ -103067,7 +104282,7 @@ async function readPackageJson(dir) {
103067
104282
  }
103068
104283
  async function readPnpmWorkspacePatterns(rootDir) {
103069
104284
  try {
103070
- const content = await readFile7(join19(rootDir, "pnpm-workspace.yaml"), "utf-8");
104285
+ const content = await readFile7(join20(rootDir, "pnpm-workspace.yaml"), "utf-8");
103071
104286
  const patterns = [];
103072
104287
  let inPackages = false;
103073
104288
  for (const line of content.split(`
@@ -103094,7 +104309,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
103094
104309
  }
103095
104310
  async function readPackageJsonWorkspacePatterns(rootDir) {
103096
104311
  try {
103097
- const content = await readFile7(join19(rootDir, "package.json"), "utf-8");
104312
+ const content = await readFile7(join20(rootDir, "package.json"), "utf-8");
103098
104313
  const pkg = JSON.parse(content);
103099
104314
  if (!pkg.workspaces)
103100
104315
  return [];
@@ -103175,11 +104390,11 @@ var MAX_NAME_LENGTH = 256;
103175
104390
 
103176
104391
  // src/infrastructure/services/workspace/command-discovery.ts
103177
104392
  import { access as access2, readFile as readFile8 } from "node:fs/promises";
103178
- import { join as join20, relative, basename as basename2 } from "node:path";
104393
+ import { join as join21, relative, basename as basename2 } from "node:path";
103179
104394
  async function detectPackageManager(workingDir) {
103180
104395
  for (const { file: file2, manager } of LOCKFILE_MAP) {
103181
104396
  try {
103182
- await access2(join20(workingDir, file2));
104397
+ await access2(join21(workingDir, file2));
103183
104398
  return manager;
103184
104399
  } catch {}
103185
104400
  }
@@ -103248,7 +104463,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
103248
104463
  }
103249
104464
  async function readRootPackageJson(workingDir, pm, scriptPrefix) {
103250
104465
  let rootPackageName = basename2(workingDir);
103251
- const pkg = await readJsonFile(join20(workingDir, "package.json"), "root package.json");
104466
+ const pkg = await readJsonFile(join21(workingDir, "package.json"), "root package.json");
103252
104467
  if (!pkg)
103253
104468
  return { commands: [], rootPackageName };
103254
104469
  if (pkg.name)
@@ -103264,7 +104479,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
103264
104479
  }
103265
104480
  async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
103266
104481
  const turboTaskNames = [];
103267
- const turbo = await readJsonFile(join20(workingDir, "turbo.json"), "turbo.json");
104482
+ const turbo = await readJsonFile(join21(workingDir, "turbo.json"), "turbo.json");
103268
104483
  if (!turbo?.tasks || typeof turbo.tasks !== "object")
103269
104484
  return turboTaskNames;
103270
104485
  for (const taskName of Object.keys(turbo.tasks)) {
@@ -103277,7 +104492,7 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
103277
104492
  async function readDenoJson(workingDir) {
103278
104493
  const commands = [];
103279
104494
  for (const fileName of ["deno.json", "deno.jsonc"]) {
103280
- const deno = await readJsonFile(join20(workingDir, fileName), fileName);
104495
+ const deno = await readJsonFile(join21(workingDir, fileName), fileName);
103281
104496
  if (!deno?.tasks || typeof deno.tasks !== "object")
103282
104497
  continue;
103283
104498
  const pkgName = deno.name ?? basename2(workingDir);
@@ -103300,7 +104515,7 @@ async function readMakefile(workingDir) {
103300
104515
  const commands = [];
103301
104516
  for (const fileName of ["Makefile", "makefile"]) {
103302
104517
  try {
103303
- const content = await readFile8(join20(workingDir, fileName), "utf-8");
104518
+ const content = await readFile8(join21(workingDir, fileName), "utf-8");
103304
104519
  const targets = parseMakefileTargets(content);
103305
104520
  if (targets.length === 0)
103306
104521
  continue;
@@ -103484,7 +104699,7 @@ var init_on_request_restart_agent = __esm(() => {
103484
104699
  });
103485
104700
 
103486
104701
  // src/daemon/domain/usecase/start-agent.ts
103487
- async function startAgent(deps, input) {
104702
+ async function startAgent2(deps, input) {
103488
104703
  const now = deps.now?.() ?? Date.now();
103489
104704
  const log4 = deps.log ?? console.log;
103490
104705
  if (now > input.deadline) {
@@ -103521,7 +104736,7 @@ async function startAgent(deps, input) {
103521
104736
  var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
103522
104737
  const agentPm = yield* DaemonAgentProcessManagerService;
103523
104738
  const session2 = yield* DaemonSessionService;
103524
- yield* exports_Effect.promise(() => startAgent(createStartAgentDeps(agentPm, session2), {
104739
+ yield* exports_Effect.promise(() => startAgent2(createStartAgentDeps(agentPm, session2), {
103525
104740
  commandId: event._id.toString(),
103526
104741
  chatroomId: event.chatroomId,
103527
104742
  role: event.role,
@@ -104227,7 +105442,7 @@ async function dispatchCommandInboundEvent(event) {
104227
105442
  var handler;
104228
105443
 
104229
105444
  // src/daemon/infrastructure/local/harness/adapters/claude-sdk/claude-session.ts
104230
- import { randomUUID as randomUUID4 } from "node:crypto";
105445
+ import { randomUUID as randomUUID5 } from "node:crypto";
104231
105446
 
104232
105447
  class ClaudeSdkSession {
104233
105448
  opencodeSessionId;
@@ -104269,7 +105484,7 @@ class ClaudeSdkSession {
104269
105484
  throw new Error("Session is closed");
104270
105485
  const text = input.parts.map((p) => p.text).join(`
104271
105486
  `);
104272
- const messageId = randomUUID4();
105487
+ const messageId = randomUUID5();
104273
105488
  const model = resolveClaudeModel(this.defaultModel, input.model);
104274
105489
  const useResume = Boolean(this.providerSessionId) && (!this.isFirstQuery || this.resumeOnFirstQuery);
104275
105490
  this.sawTextDelta = false;
@@ -104425,17 +105640,17 @@ var DEFAULT_MAX_TURNS3 = 200, DEFAULT_EFFORT2 = "medium", QUERY_TIMEOUT_MS = 360
104425
105640
  var init_claude_session = () => {};
104426
105641
 
104427
105642
  // src/daemon/infrastructure/local/harness/adapters/claude-sdk/claude-harness.ts
104428
- import { randomUUID as randomUUID5 } from "node:crypto";
104429
- async function loadSdk4() {
104430
- if (_sdkCache4)
104431
- return _sdkCache4;
104432
- if (_sdkLoadError4)
104433
- throw _sdkLoadError4;
105643
+ import { randomUUID as randomUUID6 } from "node:crypto";
105644
+ async function loadSdk5() {
105645
+ if (_sdkCache5)
105646
+ return _sdkCache5;
105647
+ if (_sdkLoadError5)
105648
+ throw _sdkLoadError5;
104434
105649
  try {
104435
- _sdkCache4 = await importBundledClaudeSdk();
104436
- return _sdkCache4;
105650
+ _sdkCache5 = await importBundledClaudeSdk();
105651
+ return _sdkCache5;
104437
105652
  } catch (err) {
104438
- _sdkLoadError4 = err;
105653
+ _sdkLoadError5 = err;
104439
105654
  throw err;
104440
105655
  }
104441
105656
  }
@@ -104490,7 +105705,7 @@ class ClaudeSdkHarness {
104490
105705
  async newSession(config4) {
104491
105706
  if (this.closed)
104492
105707
  throw new Error("Harness is closed");
104493
- const opencodeSessionId = randomUUID5();
105708
+ const opencodeSessionId = randomUUID6();
104494
105709
  const session2 = new ClaudeSdkSession({
104495
105710
  cwd: this.cwd,
104496
105711
  executablePath: this.executablePath,
@@ -104538,9 +105753,9 @@ class ClaudeSdkHarness {
104538
105753
  this.sessions.clear();
104539
105754
  }
104540
105755
  }
104541
- var DEFAULT_MODEL2 = "anthropic/sonnet", _sdkCache4, _sdkLoadError4, _executablePathCache, startClaudeSdkHarness = async (config4) => {
105756
+ var DEFAULT_MODEL2 = "anthropic/sonnet", _sdkCache5, _sdkLoadError5, _executablePathCache, startClaudeSdkHarness = async (config4) => {
104542
105757
  try {
104543
- const sdk = await loadSdk4();
105758
+ const sdk = await loadSdk5();
104544
105759
  const executablePath = await loadExecutablePath();
104545
105760
  return new ClaudeSdkHarness(config4.workingDir, sdk, executablePath);
104546
105761
  } catch (err) {
@@ -104587,7 +105802,7 @@ var init_claude_sdk2 = __esm(() => {
104587
105802
  });
104588
105803
 
104589
105804
  // src/daemon/infrastructure/local/harness/adapters/cursor-sdk/cursor-session.ts
104590
- import { randomUUID as randomUUID6 } from "node:crypto";
105805
+ import { randomUUID as randomUUID7 } from "node:crypto";
104591
105806
  function warnWriteLine(line) {
104592
105807
  console.warn(line);
104593
105808
  }
@@ -104617,13 +105832,13 @@ class CursorSdkSession {
104617
105832
  throw new Error("Session is closed");
104618
105833
  const text = input.parts.map((p) => p.text).join(`
104619
105834
  `);
104620
- const messageId = randomUUID6();
105835
+ const messageId = randomUUID7();
104621
105836
  const isFirstTurn = this.turnCount === 0;
104622
105837
  this.turnCount += 1;
104623
105838
  const modelId = input.model ? resolveModelFromPrompt(input.model.providerID, input.model.modelID) : undefined;
104624
105839
  const run3 = await withTimeout(this.agent.send(text, {
104625
105840
  local: { force: isFirstTurn },
104626
- idempotencyKey: randomUUID6(),
105841
+ idempotencyKey: randomUUID7(),
104627
105842
  ...modelId ? { model: { id: modelId } } : {},
104628
105843
  onDelta: ({ update: update6 }) => {
104629
105844
  this.handleInteractionDelta(messageId, update6);
@@ -104739,16 +105954,16 @@ var init_cursor_session = __esm(() => {
104739
105954
  });
104740
105955
 
104741
105956
  // src/daemon/infrastructure/local/harness/adapters/cursor-sdk/cursor-harness.ts
104742
- async function loadSdk5() {
104743
- if (_sdkCache5)
104744
- return _sdkCache5;
104745
- if (_sdkLoadError5)
104746
- throw _sdkLoadError5;
105957
+ async function loadSdk6() {
105958
+ if (_sdkCache6)
105959
+ return _sdkCache6;
105960
+ if (_sdkLoadError6)
105961
+ throw _sdkLoadError6;
104747
105962
  try {
104748
- _sdkCache5 = await importBundledCursorSdk();
104749
- return _sdkCache5;
105963
+ _sdkCache6 = await importBundledCursorSdk();
105964
+ return _sdkCache6;
104750
105965
  } catch (err) {
104751
- _sdkLoadError5 = err;
105966
+ _sdkLoadError6 = err;
104752
105967
  throw err;
104753
105968
  }
104754
105969
  }
@@ -104783,7 +105998,7 @@ class CursorSdkHarness {
104783
105998
  const apiKey = process.env.CURSOR_API_KEY?.trim();
104784
105999
  if (!apiKey)
104785
106000
  return [];
104786
- const { Cursor } = await loadSdk5();
106001
+ const { Cursor } = await loadSdk6();
104787
106002
  const listed = await withTimeout(Cursor.models.list({ apiKey }), MODELS_LIST_TIMEOUT_MS2, "Cursor.models.list");
104788
106003
  const modelIds = normalizeCursorSdkListedModels(listed.map((m) => m.id).filter((id3) => id3.length > 0));
104789
106004
  return [
@@ -104801,7 +106016,7 @@ class CursorSdkHarness {
104801
106016
  if (!apiKey)
104802
106017
  throw new Error("CURSOR_API_KEY is not set");
104803
106018
  const modelId = resolveCursorSdkModel(config4.model ?? DEFAULT_MODEL3);
104804
- const { Agent } = await loadSdk5();
106019
+ const { Agent } = await loadSdk6();
104805
106020
  const agent = await withTimeout(Agent.create({
104806
106021
  apiKey,
104807
106022
  model: { id: modelId },
@@ -104825,7 +106040,7 @@ class CursorSdkHarness {
104825
106040
  const apiKey = process.env.CURSOR_API_KEY?.trim();
104826
106041
  if (!apiKey)
104827
106042
  throw new Error("CURSOR_API_KEY is not set");
104828
- const { Agent } = await loadSdk5();
106043
+ const { Agent } = await loadSdk6();
104829
106044
  const agent = await withTimeout(Agent.resume(sessionId, {
104830
106045
  apiKey,
104831
106046
  model: { id: DEFAULT_MODEL3 },
@@ -104855,9 +106070,9 @@ class CursorSdkHarness {
104855
106070
  this.sessions.clear();
104856
106071
  }
104857
106072
  }
104858
- var DEFAULT_MODEL3 = "composer-2.5", MODELS_LIST_TIMEOUT_MS2 = 60000, AGENT_CREATE_TIMEOUT_MS2 = 60000, _sdkCache5, _sdkLoadError5, startCursorSdkHarness = async (config4) => {
106073
+ var DEFAULT_MODEL3 = "composer-2.5", MODELS_LIST_TIMEOUT_MS2 = 60000, AGENT_CREATE_TIMEOUT_MS2 = 60000, _sdkCache6, _sdkLoadError6, startCursorSdkHarness = async (config4) => {
104859
106074
  try {
104860
- await loadSdk5();
106075
+ await loadSdk6();
104861
106076
  } catch (err) {
104862
106077
  throw new Error(`cursor-sdk unavailable: ${formatCursorSdkLoadError(err)}`);
104863
106078
  }
@@ -105415,7 +106630,7 @@ var init_opencode_harness = __esm(() => {
105415
106630
  });
105416
106631
 
105417
106632
  // src/daemon/infrastructure/local/harness/adapters/pi-sdk/pi-session.ts
105418
- import { randomUUID as randomUUID7 } from "node:crypto";
106633
+ import { randomUUID as randomUUID8 } from "node:crypto";
105419
106634
 
105420
106635
  class PiSdkSession {
105421
106636
  opencodeSessionId;
@@ -105442,7 +106657,7 @@ class PiSdkSession {
105442
106657
  throw new Error("Session is closed");
105443
106658
  const text = input.parts.map((p) => p.text).join(`
105444
106659
  `);
105445
- const messageId = randomUUID7();
106660
+ const messageId = randomUUID8();
105446
106661
  const onSessionEvent = (event) => {
105447
106662
  if (this.closed)
105448
106663
  return;
@@ -105502,16 +106717,16 @@ var PROMPT_TIMEOUT_MS2 = 3600000;
105502
106717
  var init_pi_session = () => {};
105503
106718
 
105504
106719
  // src/daemon/infrastructure/local/harness/adapters/pi-sdk/pi-harness.ts
105505
- async function loadSdk6() {
105506
- if (_sdkCache6)
105507
- return _sdkCache6;
105508
- if (_sdkLoadError6)
105509
- throw _sdkLoadError6;
106720
+ async function loadSdk7() {
106721
+ if (_sdkCache7)
106722
+ return _sdkCache7;
106723
+ if (_sdkLoadError7)
106724
+ throw _sdkLoadError7;
105510
106725
  try {
105511
- _sdkCache6 = await importBundledPiSdk();
105512
- return _sdkCache6;
106726
+ _sdkCache7 = await importBundledPiSdk();
106727
+ return _sdkCache7;
105513
106728
  } catch (err) {
105514
- _sdkLoadError6 = err;
106729
+ _sdkLoadError7 = err;
105515
106730
  throw err;
105516
106731
  }
105517
106732
  }
@@ -105583,7 +106798,7 @@ class PiSdkHarness {
105583
106798
  const existing = this.sessions.get(sessionId);
105584
106799
  if (existing)
105585
106800
  return existing;
105586
- const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk6();
106801
+ const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk7();
105587
106802
  const sessions = await SessionManager.list(this.cwd, getPiSessionDir(this.cwd));
105588
106803
  const match17 = sessions.find((s) => s.id === sessionId);
105589
106804
  if (!match17) {
@@ -105631,7 +106846,7 @@ class PiSdkHarness {
105631
106846
  this.sessions.clear();
105632
106847
  }
105633
106848
  async createAgentSession(systemPrompt, model) {
105634
- const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk6();
106849
+ const { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } = await loadSdk7();
105635
106850
  const resolvedModel = resolveModel2(this.modelRegistry, model ?? DEFAULT_MODEL4);
105636
106851
  if (!resolvedModel) {
105637
106852
  throw new Error("No Pi model available — configure provider credentials in ~/.pi/agent/auth.json");
@@ -105653,9 +106868,9 @@ class PiSdkHarness {
105653
106868
  return session2;
105654
106869
  }
105655
106870
  }
105656
- var SESSION_CREATE_TIMEOUT_MS3 = 60000, DEFAULT_MODEL4 = "opencode/big-pickle", _sdkCache6, _sdkLoadError6, startPiSdkHarness = async (config4) => {
106871
+ var SESSION_CREATE_TIMEOUT_MS3 = 60000, DEFAULT_MODEL4 = "opencode/big-pickle", _sdkCache7, _sdkLoadError7, startPiSdkHarness = async (config4) => {
105657
106872
  try {
105658
- const { AuthStorage, ModelRegistry } = await loadSdk6();
106873
+ const { AuthStorage, ModelRegistry } = await loadSdk7();
105659
106874
  const authStorage = AuthStorage.create();
105660
106875
  const modelRegistry = ModelRegistry.create(authStorage);
105661
106876
  if (modelRegistry.getAvailable().length === 0) {
@@ -107296,7 +108511,7 @@ var init_assert_registered_working_dir = __esm(() => {
107296
108511
 
107297
108512
  // src/infrastructure/services/workspace/workspace-path-security.ts
107298
108513
  import { realpath } from "node:fs/promises";
107299
- import { dirname as dirname8, isAbsolute, relative as relative2, resolve as resolve5, sep } from "node:path";
108514
+ import { dirname as dirname9, isAbsolute, relative as relative2, resolve as resolve5, sep } from "node:path";
107300
108515
  import { gunzipSync } from "node:zlib";
107301
108516
  function validateRelativePathSegments(filePath) {
107302
108517
  if (filePath.includes("\x00"))
@@ -107324,7 +108539,7 @@ function assertContained(workspaceRoot, targetPath) {
107324
108539
  return { ok: true };
107325
108540
  }
107326
108541
  async function resolveNonExistentTarget(workspaceRoot, candidate) {
107327
- let current = dirname8(candidate);
108542
+ let current = dirname9(candidate);
107328
108543
  for (;; ) {
107329
108544
  try {
107330
108545
  const ancestorReal = await realpath(current);
@@ -107342,7 +108557,7 @@ async function resolveNonExistentTarget(workspaceRoot, candidate) {
107342
108557
  if (code2 !== "ENOENT") {
107343
108558
  return { ok: false, error: "Invalid file path" };
107344
108559
  }
107345
- const parent = dirname8(current);
108560
+ const parent = dirname9(current);
107346
108561
  if (parent === current) {
107347
108562
  return { ok: false, error: "Path escapes workspace" };
107348
108563
  }
@@ -107568,8 +108783,8 @@ var init_file_content_fulfillment = __esm(() => {
107568
108783
  console.log(`[${formatTimestamp()}] ⏳ File not on disk yet, deferring content sync: ${filePath}`);
107569
108784
  continue;
107570
108785
  }
107571
- const classification = classifyFileContent(filePath, new Uint8Array(buffer));
107572
- if (classification.kind === "binary") {
108786
+ const classification2 = classifyFileContent(filePath, new Uint8Array(buffer));
108787
+ if (classification2.kind === "binary") {
107573
108788
  yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[Binary file]", false, "binary");
107574
108789
  const elapsed4 = Date.now() - startTime;
107575
108790
  console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content synced to Convex: ${filePath} [binary] (${elapsed4}ms)`);
@@ -108274,7 +109489,7 @@ var init_file_tree_scanner = __esm(() => {
108274
109489
  });
108275
109490
 
108276
109491
  // src/infrastructure/services/workspace/git-workspace-porcelain.ts
108277
- import { existsSync as existsSync7 } from "node:fs";
109492
+ import { existsSync as existsSync8 } from "node:fs";
108278
109493
  import path4 from "node:path";
108279
109494
  function isEmptyRepoHeadError(error51) {
108280
109495
  const message = error51.message.toLowerCase();
@@ -108450,7 +109665,7 @@ function porcelainPathsLeftSnapshot(args2) {
108450
109665
  return left3.sort((a, b) => a.localeCompare(b));
108451
109666
  }
108452
109667
  function porcelainUntrackedDeletedEvents(args2) {
108453
- const exists3 = args2.pathExists ?? ((p) => existsSync7(p));
109668
+ const exists3 = args2.pathExists ?? ((p) => existsSync8(p));
108454
109669
  const left3 = porcelainPathsLeftSnapshot({
108455
109670
  workspaceRoot: args2.workspaceRoot,
108456
109671
  node: args2.node,
@@ -109145,9 +110360,9 @@ class NodeFsHandler {
109145
110360
  if (this.fsw.closed) {
109146
110361
  return;
109147
110362
  }
109148
- const dirname10 = sp.dirname(file2);
110363
+ const dirname11 = sp.dirname(file2);
109149
110364
  const basename4 = sp.basename(file2);
109150
- const parent = this.fsw._getWatchedDir(dirname10);
110365
+ const parent = this.fsw._getWatchedDir(dirname11);
109151
110366
  let prevStats = stats;
109152
110367
  if (parent.has(basename4))
109153
110368
  return;
@@ -109174,7 +110389,7 @@ class NodeFsHandler {
109174
110389
  prevStats = newStats2;
109175
110390
  }
109176
110391
  } catch (error51) {
109177
- this.fsw._remove(dirname10, basename4);
110392
+ this.fsw._remove(dirname11, basename4);
109178
110393
  }
109179
110394
  } else if (parent.has(basename4)) {
109180
110395
  const at = newStats.atimeMs;
@@ -110561,10 +111776,10 @@ function diffPathIndexes(previous, next4) {
110561
111776
  }
110562
111777
 
110563
111778
  // src/infrastructure/services/workspace/workspace-sync-state.ts
110564
- import { createHash as createHash8, randomUUID as randomUUID8 } from "node:crypto";
111779
+ import { createHash as createHash8, randomUUID as randomUUID9 } from "node:crypto";
110565
111780
  import * as fs11 from "node:fs/promises";
110566
111781
  import { homedir as homedir7 } from "node:os";
110567
- import { join as join23 } from "node:path";
111782
+ import { join as join24 } from "node:path";
110568
111783
  function workspaceKeyFor(workingDir) {
110569
111784
  const normalized = normalizeWorkingDirForLookup(workingDir);
110570
111785
  return createHash8("sha256").update(normalized).digest("hex").slice(0, 16);
@@ -110578,10 +111793,10 @@ function buildPathIndex(entries2) {
110578
111793
  }
110579
111794
  function manifestPath(machineId, workingDir) {
110580
111795
  const key = workspaceKeyFor(workingDir);
110581
- return join23(SYNC_STATE_DIR, machineId, key, "manifest.json");
111796
+ return join24(SYNC_STATE_DIR, machineId, key, "manifest.json");
110582
111797
  }
110583
111798
  async function ensureDir(filePath) {
110584
- await fs11.mkdir(join23(filePath, ".."), { recursive: true, mode: 448 });
111799
+ await fs11.mkdir(join24(filePath, ".."), { recursive: true, mode: 448 });
110585
111800
  }
110586
111801
  async function loadWorkspaceSyncManifest(machineId, workingDir) {
110587
111802
  try {
@@ -110623,7 +111838,7 @@ function createManifestFromTree(args2) {
110623
111838
  version: SYNC_STATE_VERSION,
110624
111839
  machineId: args2.machineId,
110625
111840
  workingDir: normalizeWorkingDirForLookup(args2.workingDir),
110626
- syncGeneration: randomUUID8(),
111841
+ syncGeneration: randomUUID9(),
110627
111842
  completedAt: Date.now(),
110628
111843
  scanner: args2.scanner,
110629
111844
  dataHash: args2.dataHash,
@@ -110641,11 +111856,11 @@ function entriesFromPathIndex(paths) {
110641
111856
  }
110642
111857
  var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
110643
111858
  var init_workspace_sync_state = __esm(() => {
110644
- SYNC_STATE_DIR = join23(homedir7(), ".chatroom", "sync-state");
111859
+ SYNC_STATE_DIR = join24(homedir7(), ".chatroom", "sync-state");
110645
111860
  });
110646
111861
 
110647
111862
  // src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
110648
- import { randomUUID as randomUUID9 } from "node:crypto";
111863
+ import { randomUUID as randomUUID10 } from "node:crypto";
110649
111864
  import path7 from "node:path";
110650
111865
  function deltaEntry(paths, pathValue) {
110651
111866
  const type = paths[pathValue];
@@ -110672,7 +111887,7 @@ function buildPendingDeltas(previous, next4) {
110672
111887
  const result = [];
110673
111888
  for (let offset = 0;offset < operations.length; offset += MAX_DELTA_OPERATIONS) {
110674
111889
  const delta = {
110675
- operationId: randomUUID9(),
111890
+ operationId: randomUUID10(),
110676
111891
  added: [],
110677
111892
  removed: [],
110678
111893
  typeChanged: [],
@@ -110946,7 +112161,7 @@ var init_workspace_file_tree_coordinator = __esm(() => {
110946
112161
  });
110947
112162
 
110948
112163
  // src/daemon/entry/files/file-tree-subscription.ts
110949
- import { randomUUID as randomUUID10 } from "node:crypto";
112164
+ import { randomUUID as randomUUID11 } from "node:crypto";
110950
112165
  import { gzipSync as gzipSync3 } from "node:zlib";
110951
112166
  function logSubscriptionWarn(label, err) {
110952
112167
  console.warn(`[${formatTimestamp()}] ⚠️ ${label}: ${getErrorMessage(err)}`);
@@ -111016,7 +112231,7 @@ function toDeltaOperations(delta) {
111016
112231
  }
111017
112232
  async function publishCheckpoint(session2, normalizedWorkingDir, tree, revision) {
111018
112233
  const dataHash = computeFileTreeDataHash(tree);
111019
- const syncGeneration = randomUUID10();
112234
+ const syncGeneration = randomUUID11();
111020
112235
  const snapshot = await syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration);
111021
112236
  let checkpointRevision = revision;
111022
112237
  let result = await session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
@@ -111223,7 +112438,7 @@ var init_file_write_request_priority = __esm(() => {
111223
112438
 
111224
112439
  // src/daemon/entry/files/file-write-fulfillment.ts
111225
112440
  import { access as access4, mkdir as mkdir10, rename as rename4, rm as rm4, writeFile as writeFile9 } from "node:fs/promises";
111226
- import { dirname as dirname11 } from "node:path";
112441
+ import { dirname as dirname12 } from "node:path";
111227
112442
  function isTerminalFileWriteError(errorMessage) {
111228
112443
  const terminalMessages = new Set([
111229
112444
  "Invalid file path",
@@ -111322,7 +112537,7 @@ async function validateWriteOperation(operation, absolutePath) {
111322
112537
  }
111323
112538
  async function writePayloadToDisk(absolutePath, operation, content) {
111324
112539
  if (operation === "create") {
111325
- await mkdir10(dirname11(absolutePath), { recursive: true });
112540
+ await mkdir10(dirname12(absolutePath), { recursive: true });
111326
112541
  await writeFile9(absolutePath, content, { flag: "wx" });
111327
112542
  return;
111328
112543
  }
@@ -111400,7 +112615,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
111400
112615
  });
111401
112616
  return;
111402
112617
  }
111403
- await mkdir10(dirname11(targetResolved.absolutePath), { recursive: true });
112618
+ await mkdir10(dirname12(targetResolved.absolutePath), { recursive: true });
111404
112619
  await rename4(resolved.absolutePath, targetResolved.absolutePath);
111405
112620
  await completeWriteRequest(session2, claimed._id, claimed.revision, { status: "done" });
111406
112621
  const elapsed4 = Date.now() - startTime;
@@ -111618,7 +112833,7 @@ function consumePendingFullSync(runId) {
111618
112833
  }
111619
112834
  function startLogObserverSubscription(session2, wsClient2) {
111620
112835
  const queryArgs = {
111621
- sessionId: session2.sessionId,
112836
+ sessionId: asConvexSessionId(session2.sessionId),
111622
112837
  machineId: session2.machineId
111623
112838
  };
111624
112839
  let stopped = false;
@@ -114037,9 +115252,9 @@ var init_deps = __esm(() => {
114037
115252
 
114038
115253
  // src/daemon/entry/persistence-path.ts
114039
115254
  import { homedir as homedir8 } from "node:os";
114040
- import { join as join24 } from "node:path";
115255
+ import { join as join25 } from "node:path";
114041
115256
  function resolvePersistenceDbPath(machineId) {
114042
- return join24(homedir8(), ".chatroom", "daemon", machineId, "events.sqlite");
115257
+ return join25(homedir8(), ".chatroom", "daemon", machineId, "events.sqlite");
114043
115258
  }
114044
115259
  var init_persistence_path = () => {};
114045
115260
 
@@ -115053,10 +116268,10 @@ var init_schema = __esm(() => {
115053
116268
 
115054
116269
  // src/daemon/infrastructure/persistence/open-database.ts
115055
116270
  import { mkdirSync as mkdirSync6 } from "node:fs";
115056
- import { dirname as dirname12 } from "node:path";
116271
+ import { dirname as dirname13 } from "node:path";
115057
116272
  import { DatabaseSync } from "node:sqlite";
115058
116273
  function openDatabase(dbPath) {
115059
- mkdirSync6(dirname12(dbPath), { recursive: true });
116274
+ mkdirSync6(dirname13(dbPath), { recursive: true });
115060
116275
  const db = new DatabaseSync(dbPath);
115061
116276
  for (const sql of MIGRATIONS) {
115062
116277
  db.exec(sql);
@@ -115215,7 +116430,7 @@ async function startDaemon() {
115215
116430
  const localWeb = await startLocalWebServer({ host: "127.0.0.1", port: localWebPort }, { persistence, streamHub: daemonDeps.streamHub });
115216
116431
  const subscribers = startAllSubscribers({
115217
116432
  wsClient: wsClient2,
115218
- sessionId: init2.sessionId,
116433
+ sessionId: asConvexSessionId(init2.sessionId),
115219
116434
  machineId: init2.machineId,
115220
116435
  router: createDefaultEventRouterDeps()
115221
116436
  });
@@ -115401,7 +116616,7 @@ async function isChatroomInstalledDefault() {
115401
116616
  return false;
115402
116617
  }
115403
116618
  }
115404
- async function createDefaultDeps20() {
116619
+ async function createDefaultDeps23() {
115405
116620
  const client4 = await getConvexClient();
115406
116621
  const fs12 = await import("fs/promises");
115407
116622
  return {
@@ -115476,7 +116691,7 @@ After installation, run this command again.`;
115476
116691
  });
115477
116692
  }
115478
116693
  async function installTool(options = {}, deps) {
115479
- const d = deps ?? await createDefaultDeps20();
116694
+ const d = deps ?? await createDefaultDeps23();
115480
116695
  const layer = layerFromDeps9(d);
115481
116696
  return exports_Effect.runPromise(installToolEffect(options).pipe(exports_Effect.catchAll((err) => handleInstallError(err)), exports_Effect.provide(layer)));
115482
116697
  }
@@ -116003,6 +117218,39 @@ program2.command("get-next-task").description("Join a chatroom and get the next
116003
117218
  });
116004
117219
  });
116005
117220
  var handoffCommandGroup = program2.command("handoff").description("Complete your task and hand off to the next role");
117221
+ var teamCommand = program2.command("team").description("Manage chatroom team configuration");
117222
+ teamCommand.command("list").description("List available team presets").action(async () => {
117223
+ await maybeRequireAuth();
117224
+ const { listTeamPresets: listTeamPresets2 } = await Promise.resolve().then(() => (init_team(), exports_team));
117225
+ await listTeamPresets2();
117226
+ });
117227
+ var agentCommand = program2.command("agent").description("Manage agent harness and lifecycle");
117228
+ var agentConfigCommand = agentCommand.command("config").description("Agent configuration");
117229
+ agentConfigCommand.command("get").description("Show agent configuration for a role").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Agent role").action(async (options) => {
117230
+ await maybeRequireAuth();
117231
+ const { getAgentConfig: getAgentConfig2 } = await Promise.resolve().then(() => (init_agent(), exports_agent));
117232
+ await getAgentConfig2(options.chatroomId, options.role);
117233
+ });
117234
+ agentConfigCommand.command("set").description("Save agent harness and model configuration").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Agent role").requiredOption("--harness <harness>", "Agent harness").requiredOption("--model <model>", "Model identifier").option("--working-dir <dir>", "Agent working directory").action(async (options) => {
117235
+ await maybeRequireAuth();
117236
+ const { setAgentConfig: setAgentConfig2 } = await Promise.resolve().then(() => (init_agent(), exports_agent));
117237
+ await setAgentConfig2(options.chatroomId, options);
117238
+ });
117239
+ agentCommand.command("start").description("Start a configured remote agent").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Agent role").option("--harness <harness>", "Agent harness override").option("--model <model>", "Model identifier override").option("--working-dir <dir>", "Agent working directory override").action(async (options) => {
117240
+ await maybeRequireAuth();
117241
+ const { startAgent: startAgent3 } = await Promise.resolve().then(() => (init_agent(), exports_agent));
117242
+ await startAgent3(options.chatroomId, options);
117243
+ });
117244
+ teamCommand.command("get").description("Show the current team configuration").requiredOption("--chatroom-id <id>", "Chatroom identifier").action(async (options) => {
117245
+ await maybeRequireAuth();
117246
+ const { getTeam: getTeam2 } = await Promise.resolve().then(() => (init_team(), exports_team));
117247
+ await getTeam2(options.chatroomId);
117248
+ });
117249
+ teamCommand.command("set").description("Set the team preset for a chatroom").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--team <id>", "Team preset (duo|solo)").action(async (options) => {
117250
+ await maybeRequireAuth();
117251
+ const { setTeam: setTeam2 } = await Promise.resolve().then(() => (init_team(), exports_team));
117252
+ await setTeam2(options.chatroomId, options.team);
117253
+ });
116006
117254
  handoffCommandGroup.command("view-template").description("Print the handoff message template for a role pair").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Target role for the handoff").option("--team-id <teamId>", "Team id (solo, duo); defaults to duo").action(async (options) => {
116007
117255
  const { printHandoffViewTemplate: printHandoffViewTemplate2 } = await Promise.resolve().then(() => (init_view_template3(), exports_view_template));
116008
117256
  try {
@@ -116204,6 +117452,12 @@ skillCommand.command("activate <skill-name>").description("Activate a named skil
116204
117452
  await activateSkill2(options.chatroomId, skillName, { role: options.role });
116205
117453
  });
116206
117454
  var messagesCommand = program2.command("messages").description("List and filter chatroom messages");
117455
+ var messageCommand = program2.command("message").description("Send chatroom messages");
117456
+ messageCommand.command("send").description("Send a user message to a chatroom").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--content <text>", "Message content").option("--target-role <role>", "Target role (defaults to team entry point)").action(async (options) => {
117457
+ await maybeRequireAuth();
117458
+ const { sendUserMessage: sendUserMessage2 } = await Promise.resolve().then(() => (init_send(), exports_send));
117459
+ await sendUserMessage2(options.chatroomId, options);
117460
+ });
116207
117461
  messagesCommand.command("list").description("List messages by sender role or since a specific message").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").option("--sender-role <senderRole>", "Filter by sender role (e.g., user, builder, planner)").option("--since-message-id <messageId>", "Get all messages since this message ID (inclusive)").option("--limit <n>", "Maximum number of messages to show").option("--full", "Show full message content without truncation").action(async (options) => {
116208
117462
  if (!options.senderRole && !options.sinceMessageId) {
116209
117463
  console.error("❌ Must specify either --sender-role or --since-message-id");
@@ -116244,6 +117498,11 @@ messagesCommand.command("anchor").description("Locate the last user message and
116244
117498
  priorLimit: parsedPriorLimit
116245
117499
  });
116246
117500
  });
117501
+ messagesCommand.command("send").description("Send a user message to a chatroom").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--content <text>", "Message content").option("--target-role <role>", "Target role (defaults to team entry point)").action(async (options) => {
117502
+ await maybeRequireAuth();
117503
+ const { sendUserMessage: sendUserMessage2 } = await Promise.resolve().then(() => (init_send(), exports_send));
117504
+ await sendUserMessage2(options.chatroomId, options);
117505
+ });
116247
117506
  messagesCommand.command("download").description("Download chatroom message history to local files for reading/grep").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").option("--format <format>", "Download format (default: linear)", "linear").option("--output-dir <path>", "Output directory (default: .chatroom/downloads/messages/linear/<download-id>)").option("--limit <n>", "Max messages to download (default: 10, max: 5000)").option("--since-message-id <messageId>", "Download history since this message ID (inclusive, ascending)").action(async (options) => {
116248
117507
  await maybeRequireAuth();
116249
117508
  if (options.format && options.format !== "linear") {
@@ -116412,4 +117671,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
116412
117671
  });
116413
117672
  program2.parse();
116414
117673
 
116415
- //# debugId=B2378E8C8597995864756E2164756E21
117674
+ //# debugId=D279A4D8F6CF2F1C64756E2164756E21