@moxt-ai/mobius 0.0.15 → 0.0.17

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.
Files changed (31) hide show
  1. package/dist/acp/session-config/grok-build-session-config.d.ts +10 -0
  2. package/dist/acp/session-config/grok-build-session-config.d.ts.map +1 -0
  3. package/dist/acp/session-config/grok-build-session-config.js +202 -0
  4. package/dist/acp/session-config/grok-build-session-config.js.map +1 -0
  5. package/dist/acp/session-config/session-config-protocol.d.ts +32 -0
  6. package/dist/acp/session-config/session-config-protocol.d.ts.map +1 -0
  7. package/dist/acp/session-config/session-config-protocol.js +237 -0
  8. package/dist/acp/session-config/session-config-protocol.js.map +1 -0
  9. package/dist/acp/session-config/session-config-registry.d.ts +3 -0
  10. package/dist/acp/session-config/session-config-registry.d.ts.map +1 -0
  11. package/dist/acp/session-config/session-config-registry.js +8 -0
  12. package/dist/acp/session-config/session-config-registry.js.map +1 -0
  13. package/dist/acp/session-manager.d.ts.map +1 -1
  14. package/dist/acp/session-manager.js +29 -155
  15. package/dist/acp/session-manager.js.map +1 -1
  16. package/dist/agent-catalog/agent-specification.d.ts +1 -0
  17. package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
  18. package/dist/agent-catalog/agent-specification.js +1 -0
  19. package/dist/agent-catalog/agent-specification.js.map +1 -1
  20. package/dist/agent-catalog/agents/workbuddy-agent.d.ts +3 -1
  21. package/dist/agent-catalog/agents/workbuddy-agent.d.ts.map +1 -1
  22. package/dist/agent-catalog/agents/workbuddy-agent.js +33 -1
  23. package/dist/agent-catalog/agents/workbuddy-agent.js.map +1 -1
  24. package/dist/agent-catalog/executable-discovery.d.ts.map +1 -1
  25. package/dist/agent-catalog/executable-discovery.js +18 -8
  26. package/dist/agent-catalog/executable-discovery.js.map +1 -1
  27. package/dist/cli.js +641 -254
  28. package/dist/cli.js.map +4 -4
  29. package/dist/index.js +662 -275
  30. package/dist/index.js.map +4 -4
  31. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21139,7 +21139,7 @@ function loadDaemonConfig() {
21139
21139
  // src/acp/session-manager.ts
21140
21140
  import { spawn as spawn2 } from "node:child_process";
21141
21141
  import {
21142
- methods as methods2,
21142
+ methods as methods3,
21143
21143
  ndJsonStream,
21144
21144
  PROTOCOL_VERSION,
21145
21145
  RequestError
@@ -21653,6 +21653,491 @@ var nativeSessionPageSchema = external_exports.object({
21653
21653
  nextCursor: external_exports.string().min(1).max(4096).nullish()
21654
21654
  }).readonly();
21655
21655
 
21656
+ // src/acp/session-config/session-config-protocol.ts
21657
+ import { methods as methods2 } from "@agentclientprotocol/sdk";
21658
+ var AGENT_DEFAULT_REASONING_EFFORT = "agent_default";
21659
+ var MAXIMUM_CONFIG_OPTIONS = 100;
21660
+ var SessionConfigProtocolError = class extends Error {
21661
+ code = "invalid_session_configuration_response";
21662
+ constructor(message, options = {}) {
21663
+ super(message, options);
21664
+ this.name = "SessionConfigProtocolError";
21665
+ }
21666
+ };
21667
+ function isRecord3(value) {
21668
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21669
+ }
21670
+ function readString2(value, fallback = "") {
21671
+ return typeof value === "string" ? value : fallback;
21672
+ }
21673
+ function truncate2(value, maximum) {
21674
+ return value.length <= maximum ? value : value.slice(0, maximum);
21675
+ }
21676
+ function readBoolean(value, fallback = false) {
21677
+ return typeof value === "boolean" ? value : fallback;
21678
+ }
21679
+ function normalizeConfigValue(option, groupId = "", groupName = "") {
21680
+ return {
21681
+ description: truncate2(readString2(option["description"]), 500),
21682
+ groupId: truncate2(groupId, 128),
21683
+ groupName: truncate2(groupName, 255),
21684
+ name: truncate2(
21685
+ readString2(option["name"], readString2(option["value"])),
21686
+ 255
21687
+ ),
21688
+ value: truncate2(readString2(option["value"]), 500)
21689
+ };
21690
+ }
21691
+ function normalizeConfigValues(value) {
21692
+ if (!Array.isArray(value)) {
21693
+ return [];
21694
+ }
21695
+ const normalized = [];
21696
+ for (const entry of value) {
21697
+ if (!isRecord3(entry)) {
21698
+ continue;
21699
+ }
21700
+ const groupedOptions = entry["options"];
21701
+ if (Array.isArray(groupedOptions)) {
21702
+ const groupId = readString2(entry["group"]);
21703
+ const groupName = readString2(entry["name"]);
21704
+ for (const groupedOption of groupedOptions) {
21705
+ if (isRecord3(groupedOption)) {
21706
+ normalized.push(
21707
+ normalizeConfigValue(groupedOption, groupId, groupName)
21708
+ );
21709
+ }
21710
+ }
21711
+ continue;
21712
+ }
21713
+ normalized.push(normalizeConfigValue(entry));
21714
+ }
21715
+ return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
21716
+ }
21717
+ function normalizeConfigOptions(value, modes) {
21718
+ const normalized = [];
21719
+ if (Array.isArray(value)) {
21720
+ for (const option of value) {
21721
+ if (!isRecord3(option)) {
21722
+ continue;
21723
+ }
21724
+ const id = truncate2(readString2(option["id"]), 128);
21725
+ const name = truncate2(readString2(option["name"], id), 255);
21726
+ if (id.length === 0 || name.length === 0) {
21727
+ continue;
21728
+ }
21729
+ if (option["type"] === "boolean") {
21730
+ normalized.push({
21731
+ booleanValue: readBoolean(option["currentValue"]),
21732
+ category: truncate2(readString2(option["category"]), 128),
21733
+ currentValue: "",
21734
+ description: truncate2(readString2(option["description"]), 500),
21735
+ id,
21736
+ name,
21737
+ type: "boolean",
21738
+ values: []
21739
+ });
21740
+ continue;
21741
+ }
21742
+ if (option["type"] === "select") {
21743
+ const values = normalizeConfigValues(option["options"]);
21744
+ const currentValue = truncate2(readString2(option["currentValue"]), 500);
21745
+ if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
21746
+ normalized.push({
21747
+ booleanValue: false,
21748
+ category: truncate2(readString2(option["category"]), 128),
21749
+ currentValue,
21750
+ description: truncate2(readString2(option["description"]), 500),
21751
+ id,
21752
+ name,
21753
+ type: "select",
21754
+ values
21755
+ });
21756
+ }
21757
+ }
21758
+ }
21759
+ }
21760
+ if (isRecord3(modes)) {
21761
+ const values = [];
21762
+ const availableModes = modes["availableModes"];
21763
+ if (Array.isArray(availableModes)) {
21764
+ for (const mode of availableModes) {
21765
+ if (!isRecord3(mode)) {
21766
+ continue;
21767
+ }
21768
+ const id = truncate2(readString2(mode["id"]), 500);
21769
+ if (id.length === 0) {
21770
+ continue;
21771
+ }
21772
+ values.push({
21773
+ description: truncate2(readString2(mode["description"]), 500),
21774
+ groupId: "",
21775
+ groupName: "",
21776
+ name: truncate2(readString2(mode["name"], id), 255),
21777
+ value: id
21778
+ });
21779
+ }
21780
+ }
21781
+ const currentValue = truncate2(readString2(modes["currentModeId"]), 500);
21782
+ if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
21783
+ normalized.unshift({
21784
+ booleanValue: false,
21785
+ category: "mode",
21786
+ currentValue,
21787
+ description: "Agent session mode",
21788
+ id: "mode",
21789
+ name: "Mode",
21790
+ type: "select",
21791
+ values
21792
+ });
21793
+ }
21794
+ }
21795
+ return normalized.slice(0, 100);
21796
+ }
21797
+ function ensureReasoningEffortOption(current) {
21798
+ if (current.some((option) => option.category === "thought_level")) {
21799
+ return current;
21800
+ }
21801
+ const unavailable = {
21802
+ booleanValue: false,
21803
+ category: "thought_level",
21804
+ currentValue: AGENT_DEFAULT_REASONING_EFFORT,
21805
+ description: "This Agent does not expose adjustable reasoning effort for the selected model.",
21806
+ id: "reasoning_effort",
21807
+ name: "Reasoning effort",
21808
+ type: "select",
21809
+ values: [
21810
+ {
21811
+ description: "Selected by the Agent",
21812
+ groupId: "",
21813
+ groupName: "",
21814
+ name: "Agent default",
21815
+ value: AGENT_DEFAULT_REASONING_EFFORT
21816
+ }
21817
+ ]
21818
+ };
21819
+ const modelIndex = current.findIndex((option) => option.category === "model");
21820
+ if (current.length < MAXIMUM_CONFIG_OPTIONS) {
21821
+ if (modelIndex < 0) {
21822
+ return [...current, unavailable];
21823
+ }
21824
+ return [
21825
+ ...current.slice(0, modelIndex + 1),
21826
+ unavailable,
21827
+ ...current.slice(modelIndex + 1)
21828
+ ];
21829
+ }
21830
+ if (modelIndex < 0) {
21831
+ return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
21832
+ }
21833
+ if (modelIndex < MAXIMUM_CONFIG_OPTIONS - 1) {
21834
+ return [
21835
+ ...current.slice(0, modelIndex + 1),
21836
+ unavailable,
21837
+ ...current.slice(modelIndex + 1, MAXIMUM_CONFIG_OPTIONS - 1)
21838
+ ];
21839
+ }
21840
+ const model = current[modelIndex];
21841
+ if (model === void 0) {
21842
+ return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
21843
+ }
21844
+ return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 2), model, unavailable];
21845
+ }
21846
+ function normalizeStandardLifecycle(response) {
21847
+ const lifecycle = isRecord3(response) ? response : {};
21848
+ return ensureReasoningEffortOption(
21849
+ normalizeConfigOptions(lifecycle["configOptions"], lifecycle["modes"])
21850
+ );
21851
+ }
21852
+ function replaceStandardConfigOptions(current, value) {
21853
+ const next = normalizeConfigOptions(value, void 0);
21854
+ const withMode = next.some((option) => option.category === "mode") ? next : [
21855
+ ...current.filter((option) => option.category === "mode"),
21856
+ ...next
21857
+ ].slice(0, 100);
21858
+ return ensureReasoningEffortOption(withMode);
21859
+ }
21860
+ function updateCurrentValue(current, configId, value) {
21861
+ return current.map(
21862
+ (option) => option.id === configId ? { ...option, currentValue: value } : option
21863
+ );
21864
+ }
21865
+ var StandardSessionConfigProtocol = class {
21866
+ configure = async (current, change, nativeSessionId, transport) => {
21867
+ const existing = current.find((option) => option.id === change.configId);
21868
+ if (existing === void 0) {
21869
+ return current;
21870
+ }
21871
+ if (existing.type === "select" && existing.category === "mode") {
21872
+ await transport.request(
21873
+ methods2.agent.session.setMode,
21874
+ { modeId: change.value, sessionId: nativeSessionId },
21875
+ "ACP agent exited while setting the session mode",
21876
+ change.signal
21877
+ );
21878
+ return updateCurrentValue(current, existing.id, change.value);
21879
+ }
21880
+ const params = existing.type === "boolean" ? {
21881
+ configId: existing.id,
21882
+ sessionId: nativeSessionId,
21883
+ type: "boolean",
21884
+ value: change.booleanValue
21885
+ } : {
21886
+ configId: existing.id,
21887
+ sessionId: nativeSessionId,
21888
+ value: change.value
21889
+ };
21890
+ const response = await transport.request(
21891
+ methods2.agent.session.setConfigOption,
21892
+ params,
21893
+ "ACP agent exited while changing session configuration",
21894
+ change.signal
21895
+ );
21896
+ if (!isRecord3(response) || !Array.isArray(response["configOptions"])) {
21897
+ throw new SessionConfigProtocolError(
21898
+ "The Agent returned an invalid session configuration response"
21899
+ );
21900
+ }
21901
+ return replaceStandardConfigOptions(current, response["configOptions"]);
21902
+ };
21903
+ normalizeLifecycle = (response) => normalizeStandardLifecycle(response);
21904
+ normalizeUpdate = (current, value) => replaceStandardConfigOptions(current, value);
21905
+ };
21906
+ var standardSessionConfigProtocol = new StandardSessionConfigProtocol();
21907
+
21908
+ // src/acp/session-config/grok-build-session-config.ts
21909
+ var LEGACY_MODEL_CONFIG_ID = "grok_build_legacy_model";
21910
+ var LEGACY_REASONING_EFFORT_CONFIG_ID = "grok_build_legacy_reasoning_effort";
21911
+ function legacyOptions(response) {
21912
+ if (!isRecord3(response)) {
21913
+ return [];
21914
+ }
21915
+ const metadata = response["_meta"];
21916
+ if (!isRecord3(metadata)) {
21917
+ return [];
21918
+ }
21919
+ const sessionConfig = metadata["x.ai/sessionConfig"];
21920
+ if (!isRecord3(sessionConfig) || !Array.isArray(sessionConfig["options"])) {
21921
+ return [];
21922
+ }
21923
+ return sessionConfig["options"].slice(0, 500).filter(isRecord3);
21924
+ }
21925
+ function legacyValue(option) {
21926
+ const value = readString2(option["id"]);
21927
+ return {
21928
+ description: readString2(option["description"]).slice(0, 500),
21929
+ groupId: "",
21930
+ groupName: "",
21931
+ name: readString2(option["label"], value).slice(0, 255),
21932
+ value: value.slice(0, 500)
21933
+ };
21934
+ }
21935
+ function modelsRecord(response) {
21936
+ if (!isRecord3(response) || !isRecord3(response["models"])) {
21937
+ return {};
21938
+ }
21939
+ return response["models"];
21940
+ }
21941
+ function legacyModelOptions(response) {
21942
+ const options = legacyOptions(response);
21943
+ const models = modelsRecord(response);
21944
+ const values = [];
21945
+ for (const option of options) {
21946
+ if (option["category"] === "model") {
21947
+ const value = legacyValue(option);
21948
+ if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
21949
+ values.push(value);
21950
+ }
21951
+ }
21952
+ }
21953
+ if (values.length === 0 && Array.isArray(models["availableModels"])) {
21954
+ for (const model of models["availableModels"]) {
21955
+ if (!isRecord3(model)) {
21956
+ continue;
21957
+ }
21958
+ const value = readString2(model["modelId"]).slice(0, 500);
21959
+ if (value.length === 0) {
21960
+ continue;
21961
+ }
21962
+ if (!values.some((existing) => existing.value === value)) {
21963
+ values.push({
21964
+ description: "",
21965
+ groupId: "",
21966
+ groupName: "",
21967
+ name: readString2(model["name"], value).slice(0, 255),
21968
+ value
21969
+ });
21970
+ }
21971
+ }
21972
+ }
21973
+ const selected = options.find(
21974
+ (option) => option["category"] === "model" && option["selected"] === true
21975
+ );
21976
+ const currentValue = readString2(
21977
+ models["currentModelId"],
21978
+ selected === void 0 ? "" : readString2(selected["id"])
21979
+ ).slice(0, 500);
21980
+ if (values.length === 0 || !values.some((value) => value.value === currentValue)) {
21981
+ return [];
21982
+ }
21983
+ const result = {
21984
+ booleanValue: false,
21985
+ category: "model",
21986
+ currentValue,
21987
+ description: "Model used by Grok Build",
21988
+ id: LEGACY_MODEL_CONFIG_ID,
21989
+ name: "Model",
21990
+ type: "select",
21991
+ values: values.slice(0, 500)
21992
+ };
21993
+ return [result];
21994
+ }
21995
+ function legacyReasoningEffortOptions(response) {
21996
+ const options = legacyOptions(response);
21997
+ const values = [];
21998
+ for (const option of options) {
21999
+ if (option["category"] !== "mode") {
22000
+ continue;
22001
+ }
22002
+ const value = legacyValue(option);
22003
+ if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
22004
+ values.push(value);
22005
+ }
22006
+ }
22007
+ if (values.length === 0) {
22008
+ return [];
22009
+ }
22010
+ const selected = options.find(
22011
+ (option) => option["category"] === "mode" && option["selected"] === true
22012
+ );
22013
+ if (selected === void 0) {
22014
+ values.unshift({
22015
+ description: "Use the selected model's default reasoning effort",
22016
+ groupId: "",
22017
+ groupName: "",
22018
+ name: "Agent default",
22019
+ value: AGENT_DEFAULT_REASONING_EFFORT
22020
+ });
22021
+ }
22022
+ const currentValue = selected === void 0 ? AGENT_DEFAULT_REASONING_EFFORT : readString2(selected["id"], AGENT_DEFAULT_REASONING_EFFORT);
22023
+ if (!values.some((value) => value.value === currentValue)) {
22024
+ return [];
22025
+ }
22026
+ const result = {
22027
+ booleanValue: false,
22028
+ category: "thought_level",
22029
+ currentValue,
22030
+ description: "Reasoning effort used by Grok Build",
22031
+ id: LEGACY_REASONING_EFFORT_CONFIG_ID,
22032
+ name: "Reasoning effort",
22033
+ type: "select",
22034
+ values: values.slice(0, 500)
22035
+ };
22036
+ return [result];
22037
+ }
22038
+ function normalizeGrokLifecycle(response) {
22039
+ const lifecycle = isRecord3(response) ? response : {};
22040
+ const standard = normalizeConfigOptions(
22041
+ lifecycle["configOptions"],
22042
+ lifecycle["modes"]
22043
+ );
22044
+ const normalized = [...standard];
22045
+ if (!normalized.some((option) => option.category === "model")) {
22046
+ normalized.push(...legacyModelOptions(response));
22047
+ }
22048
+ if (!normalized.some((option) => option.category === "thought_level")) {
22049
+ const efforts = legacyReasoningEffortOptions(response);
22050
+ if (efforts.length > 0) {
22051
+ const modelIndex = normalized.findIndex(
22052
+ (option) => option.category === "model"
22053
+ );
22054
+ normalized.splice(
22055
+ modelIndex < 0 ? normalized.length : modelIndex + 1,
22056
+ 0,
22057
+ ...efforts
22058
+ );
22059
+ }
22060
+ }
22061
+ return ensureReasoningEffortOption(normalized.slice(0, 100));
22062
+ }
22063
+ function updateCurrentValue2(current, category, value) {
22064
+ return current.map(
22065
+ (option) => option.category === category ? { ...option, currentValue: value } : option
22066
+ );
22067
+ }
22068
+ function validateGrokResponse(response, modelId) {
22069
+ if (!isRecord3(response) || !isRecord3(response["_meta"])) {
22070
+ throw new SessionConfigProtocolError(
22071
+ "Grok Build returned an invalid session configuration response"
22072
+ );
22073
+ }
22074
+ const model = response["_meta"]["model"];
22075
+ const appliedModel = isRecord3(model) ? model["Ok"] : model;
22076
+ if (appliedModel !== modelId) {
22077
+ throw new SessionConfigProtocolError(
22078
+ "Grok Build returned an invalid session configuration response"
22079
+ );
22080
+ }
22081
+ }
22082
+ var GrokBuildSessionConfigProtocol = class {
22083
+ configure = async (current, change, nativeSessionId, transport) => {
22084
+ const existing = current.find((option) => option.id === change.configId);
22085
+ if (existing === void 0 || existing.id !== LEGACY_MODEL_CONFIG_ID && existing.id !== LEGACY_REASONING_EFFORT_CONFIG_ID) {
22086
+ return await standardSessionConfigProtocol.configure(
22087
+ current,
22088
+ change,
22089
+ nativeSessionId,
22090
+ transport
22091
+ );
22092
+ }
22093
+ const model = current.find((option) => option.category === "model");
22094
+ if (model === void 0) {
22095
+ return current;
22096
+ }
22097
+ if (existing.category === "thought_level" && change.value === AGENT_DEFAULT_REASONING_EFFORT) {
22098
+ return current;
22099
+ }
22100
+ const modelId = existing.category === "model" ? change.value : model.currentValue;
22101
+ const params = {
22102
+ modelId,
22103
+ sessionId: nativeSessionId
22104
+ };
22105
+ if (existing.category === "thought_level") {
22106
+ params["_meta"] = {
22107
+ reasoningEffort: change.value
22108
+ };
22109
+ }
22110
+ const response = await transport.request(
22111
+ "session/set_model",
22112
+ params,
22113
+ existing.category === "model" ? "Grok Build exited while setting the session model" : "Grok Build exited while setting reasoning effort",
22114
+ change.signal
22115
+ );
22116
+ validateGrokResponse(response, modelId);
22117
+ const updated = updateCurrentValue2(
22118
+ current,
22119
+ existing.category,
22120
+ change.value
22121
+ );
22122
+ return existing.category === "thought_level" ? updated.map(
22123
+ (option) => option.category === "thought_level" ? {
22124
+ ...option,
22125
+ values: option.values.filter(
22126
+ (value) => value.value !== AGENT_DEFAULT_REASONING_EFFORT
22127
+ )
22128
+ } : option
22129
+ ) : updated;
22130
+ };
22131
+ normalizeLifecycle = (response) => normalizeGrokLifecycle(response);
22132
+ normalizeUpdate = (current, value) => standardSessionConfigProtocol.normalizeUpdate(current, value);
22133
+ };
22134
+ var grokBuildSessionConfigProtocol = new GrokBuildSessionConfigProtocol();
22135
+
22136
+ // src/acp/session-config/session-config-registry.ts
22137
+ function sessionConfigProtocolForAgent(agentId) {
22138
+ return agentId === "grok-build" ? grokBuildSessionConfigProtocol : standardSessionConfigProtocol;
22139
+ }
22140
+
21656
22141
  // src/acp/session-history.ts
21657
22142
  var AcpHistoryReplay = class {
21658
22143
  #messages = [];
@@ -21757,7 +22242,7 @@ var FoundAcpStoredSession = class extends AcpStoredSessionLookup {
21757
22242
  var DeletedAcpStoredSession = class extends AcpStoredSessionLookup {
21758
22243
  found = false;
21759
22244
  };
21760
- function readString2(value, field) {
22245
+ function readString3(value, field) {
21761
22246
  if (typeof value !== "string" || value.length === 0) {
21762
22247
  throw new Error(`Stored ACP session has an invalid ${field}`);
21763
22248
  }
@@ -21787,10 +22272,10 @@ function decodeSessionRow(row) {
21787
22272
  throw new Error("Stored ACP session is not an object");
21788
22273
  }
21789
22274
  return new AcpStoredSession(
21790
- readString2(Reflect.get(row, "session_id"), "session ID"),
21791
- readString2(Reflect.get(row, "agent_id"), "agent ID"),
21792
- readString2(Reflect.get(row, "native_session_id"), "native session ID"),
21793
- readString2(Reflect.get(row, "cwd"), "working directory"),
22275
+ readString3(Reflect.get(row, "session_id"), "session ID"),
22276
+ readString3(Reflect.get(row, "agent_id"), "agent ID"),
22277
+ readString3(Reflect.get(row, "native_session_id"), "native session ID"),
22278
+ readString3(Reflect.get(row, "cwd"), "working directory"),
21794
22279
  readAdditionalDirectories(Reflect.get(row, "additional_directories_json")),
21795
22280
  readPrompted(Reflect.get(row, "prompted"))
21796
22281
  );
@@ -22052,149 +22537,18 @@ function createWritableAcpStream(output2) {
22052
22537
  }
22053
22538
  });
22054
22539
  }
22055
- function truncate2(value, maximumLength) {
22540
+ function truncate3(value, maximumLength) {
22056
22541
  return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
22057
22542
  }
22058
- function isRecord3(value) {
22543
+ function isRecord4(value) {
22059
22544
  return typeof value === "object" && value !== null && !Array.isArray(value);
22060
22545
  }
22061
- function readString3(value, fallback = "") {
22546
+ function readString4(value, fallback = "") {
22062
22547
  return typeof value === "string" ? value : fallback;
22063
22548
  }
22064
- function readBoolean(value, fallback = false) {
22065
- return typeof value === "boolean" ? value : fallback;
22066
- }
22067
22549
  function arraysEqual(left, right) {
22068
22550
  return left.length === right.length && left.every((value, index) => value === right[index]);
22069
22551
  }
22070
- function normalizeConfigValue(option, groupId = "", groupName = "") {
22071
- return {
22072
- description: truncate2(readString3(option["description"]), 500),
22073
- groupId: truncate2(groupId, 128),
22074
- groupName: truncate2(groupName, 255),
22075
- name: truncate2(
22076
- readString3(option["name"], readString3(option["value"])),
22077
- 255
22078
- ),
22079
- value: truncate2(readString3(option["value"]), 500)
22080
- };
22081
- }
22082
- function normalizeConfigValues(value) {
22083
- if (!Array.isArray(value)) {
22084
- return [];
22085
- }
22086
- const normalized = [];
22087
- for (const entry of value) {
22088
- if (!isRecord3(entry)) {
22089
- continue;
22090
- }
22091
- const groupedOptions = entry["options"];
22092
- if (Array.isArray(groupedOptions)) {
22093
- const groupId = readString3(entry["group"]);
22094
- const groupName = readString3(entry["name"]);
22095
- for (const groupedOption of groupedOptions) {
22096
- if (isRecord3(groupedOption)) {
22097
- normalized.push(
22098
- normalizeConfigValue(groupedOption, groupId, groupName)
22099
- );
22100
- }
22101
- }
22102
- continue;
22103
- }
22104
- normalized.push(normalizeConfigValue(entry));
22105
- }
22106
- return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
22107
- }
22108
- function normalizeConfigOptions(value, modes) {
22109
- const normalized = [];
22110
- if (Array.isArray(value)) {
22111
- for (const option of value) {
22112
- if (!isRecord3(option)) {
22113
- continue;
22114
- }
22115
- const id = truncate2(readString3(option["id"]), 128);
22116
- const name = truncate2(readString3(option["name"], id), 255);
22117
- if (id.length === 0 || name.length === 0) {
22118
- continue;
22119
- }
22120
- if (option["type"] === "boolean") {
22121
- normalized.push({
22122
- booleanValue: readBoolean(option["currentValue"]),
22123
- category: truncate2(readString3(option["category"]), 128),
22124
- currentValue: "",
22125
- description: truncate2(readString3(option["description"]), 500),
22126
- id,
22127
- name,
22128
- type: "boolean",
22129
- values: []
22130
- });
22131
- continue;
22132
- }
22133
- if (option["type"] === "select") {
22134
- const values = normalizeConfigValues(option["options"]);
22135
- const currentValue = truncate2(readString3(option["currentValue"]), 500);
22136
- if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
22137
- normalized.push({
22138
- booleanValue: false,
22139
- category: truncate2(readString3(option["category"]), 128),
22140
- currentValue,
22141
- description: truncate2(readString3(option["description"]), 500),
22142
- id,
22143
- name,
22144
- type: "select",
22145
- values
22146
- });
22147
- }
22148
- }
22149
- }
22150
- }
22151
- if (isRecord3(modes)) {
22152
- const values = [];
22153
- const availableModes = modes["availableModes"];
22154
- if (Array.isArray(availableModes)) {
22155
- for (const mode of availableModes) {
22156
- if (!isRecord3(mode)) {
22157
- continue;
22158
- }
22159
- const id = truncate2(readString3(mode["id"]), 500);
22160
- if (id.length === 0) {
22161
- continue;
22162
- }
22163
- values.push({
22164
- description: truncate2(readString3(mode["description"]), 500),
22165
- groupId: "",
22166
- groupName: "",
22167
- name: truncate2(readString3(mode["name"], id), 255),
22168
- value: id
22169
- });
22170
- }
22171
- }
22172
- const currentValue = truncate2(readString3(modes["currentModeId"]), 500);
22173
- if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
22174
- normalized.unshift({
22175
- booleanValue: false,
22176
- category: "mode",
22177
- currentValue,
22178
- description: "Agent session mode",
22179
- id: "mode",
22180
- name: "Mode",
22181
- type: "select",
22182
- values
22183
- });
22184
- }
22185
- }
22186
- return normalized.slice(0, 100);
22187
- }
22188
- function replaceConfigOptionsKeepingMode(current, value) {
22189
- const next = normalizeConfigOptions(value, void 0);
22190
- if (next.some((option) => option.category === "mode")) {
22191
- return next;
22192
- }
22193
- return [
22194
- ...current.filter((option) => option.category === "mode"),
22195
- ...next
22196
- ].slice(0, 100);
22197
- }
22198
22552
  function normalizeCapabilities(capabilities) {
22199
22553
  const session = capabilities.sessionCapabilities;
22200
22554
  const prompt = capabilities.promptCapabilities;
@@ -22231,11 +22585,11 @@ function normalizeElicitationOptions(schema) {
22231
22585
  const oneOf = schema["oneOf"];
22232
22586
  if (Array.isArray(oneOf)) {
22233
22587
  for (const option of oneOf) {
22234
- if (isRecord3(option) && typeof option["const"] === "string") {
22588
+ if (isRecord4(option) && typeof option["const"] === "string") {
22235
22589
  normalized.push({
22236
- description: truncate2(readString3(option["description"]), 500),
22237
- label: truncate2(readString3(option["title"], option["const"]), 255),
22238
- value: truncate2(option["const"], 500)
22590
+ description: truncate3(readString4(option["description"]), 500),
22591
+ label: truncate3(readString4(option["title"], option["const"]), 255),
22592
+ value: truncate3(option["const"], 500)
22239
22593
  });
22240
22594
  }
22241
22595
  }
@@ -22251,7 +22605,7 @@ function normalizeElicitationOptions(schema) {
22251
22605
  return normalized.slice(0, 200);
22252
22606
  }
22253
22607
  const items = schema["items"];
22254
- if (!isRecord3(items)) {
22608
+ if (!isRecord4(items)) {
22255
22609
  return normalized;
22256
22610
  }
22257
22611
  const anyOf = items["anyOf"];
@@ -22264,7 +22618,7 @@ function numericString(value) {
22264
22618
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
22265
22619
  }
22266
22620
  function normalizeElicitationFields(requestedSchema) {
22267
- if (!isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
22621
+ if (!isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
22268
22622
  return [];
22269
22623
  }
22270
22624
  const properties = requestedSchema["properties"];
@@ -22274,7 +22628,7 @@ function normalizeElicitationFields(requestedSchema) {
22274
22628
  );
22275
22629
  const normalized = [];
22276
22630
  for (const [name, property] of Object.entries(properties)) {
22277
- if (!isRecord3(property)) {
22631
+ if (!isRecord4(property)) {
22278
22632
  continue;
22279
22633
  }
22280
22634
  const type = elicitationFieldType(property["type"]);
@@ -22284,9 +22638,9 @@ function normalizeElicitationFields(requestedSchema) {
22284
22638
  normalized.push({
22285
22639
  defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
22286
22640
  defaultNumberValue: typeof defaultValue === "number" && Number.isFinite(defaultValue) ? defaultValue : 0,
22287
- defaultStringValue: typeof defaultValue === "string" ? truncate2(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate2(JSON.stringify(defaultValue), 1e4) : "",
22288
- description: truncate2(readString3(property["description"]), 500),
22289
- format: truncate2(readString3(property["format"]), 64),
22641
+ defaultStringValue: typeof defaultValue === "string" ? truncate3(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate3(JSON.stringify(defaultValue), 1e4) : "",
22642
+ description: truncate3(readString4(property["description"]), 500),
22643
+ format: truncate3(readString4(property["format"]), 64),
22290
22644
  hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
22291
22645
  maximum: numericString(property["maximum"]),
22292
22646
  maximumLength: numericString(
@@ -22296,11 +22650,11 @@ function normalizeElicitationFields(requestedSchema) {
22296
22650
  minimumLength: numericString(
22297
22651
  property["minLength"] ?? property["minItems"]
22298
22652
  ),
22299
- name: truncate2(name, 128),
22653
+ name: truncate3(name, 128),
22300
22654
  options,
22301
- pattern: truncate2(readString3(property["pattern"]), 500),
22655
+ pattern: truncate3(readString4(property["pattern"]), 500),
22302
22656
  required: required2.has(name),
22303
- title: truncate2(readString3(property["title"], name), 255),
22657
+ title: truncate3(readString4(property["title"], name), 255),
22304
22658
  type: normalizedType
22305
22659
  });
22306
22660
  }
@@ -22369,7 +22723,7 @@ function validateElicitationContent(encoded, requestedSchema) {
22369
22723
  "invalid_elicitation_response"
22370
22724
  );
22371
22725
  }
22372
- if (!isRecord3(decoded) || !isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
22726
+ if (!isRecord4(decoded) || !isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
22373
22727
  throw new AcpExecutionError(
22374
22728
  "Elicitation response does not match the requested form",
22375
22729
  {},
@@ -22393,7 +22747,7 @@ function validateElicitationContent(encoded, requestedSchema) {
22393
22747
  const validated = {};
22394
22748
  for (const [name, value] of Object.entries(decoded)) {
22395
22749
  const property = properties[name];
22396
- if (!isRecord3(property)) {
22750
+ if (!isRecord4(property)) {
22397
22751
  throw new AcpExecutionError(
22398
22752
  `Elicitation field ${name} was not requested`,
22399
22753
  {},
@@ -22545,6 +22899,7 @@ var AcpProcessSession = class _AcpProcessSession {
22545
22899
  #pendingPermissions = /* @__PURE__ */ new Map();
22546
22900
  #preSessionUpdates = [];
22547
22901
  #processExit;
22902
+ #sessionConfigProtocol;
22548
22903
  #store;
22549
22904
  #verifiedAgentVersion;
22550
22905
  #preSessionUpdateBytes = 0;
@@ -22563,6 +22918,7 @@ var AcpProcessSession = class _AcpProcessSession {
22563
22918
  unstableForkSession: false
22564
22919
  };
22565
22920
  #commands = [];
22921
+ #configRevision = 0;
22566
22922
  #configOptions = [];
22567
22923
  #nativeSessionId = "";
22568
22924
  #prompted = false;
@@ -22580,6 +22936,7 @@ var AcpProcessSession = class _AcpProcessSession {
22580
22936
  this.#cwd = cwd;
22581
22937
  this.#getObserver = getObserver;
22582
22938
  this.#mobiusSessionId = mobiusSessionId;
22939
+ this.#sessionConfigProtocol = sessionConfigProtocolForAgent(agent.id);
22583
22940
  this.#store = store;
22584
22941
  this.#verifiedAgentVersion = agent.agentVersion;
22585
22942
  this.#child = spawn2(agent.adapterPath, [...agent.arguments], {
@@ -22684,7 +23041,7 @@ var AcpProcessSession = class _AcpProcessSession {
22684
23041
  try {
22685
23042
  await this.race(
22686
23043
  this.#connection.agent.request(
22687
- methods2.agent.session.load,
23044
+ methods3.agent.session.load,
22688
23045
  {
22689
23046
  additionalDirectories: [...this.#additionalDirectories],
22690
23047
  cwd: this.#cwd,
@@ -22706,7 +23063,7 @@ var AcpProcessSession = class _AcpProcessSession {
22706
23063
  async #initializeAgent(signal) {
22707
23064
  const initialized = await this.race(
22708
23065
  this.#connection.agent.request(
22709
- methods2.agent.initialize,
23066
+ methods3.agent.initialize,
22710
23067
  {
22711
23068
  clientCapabilities: {
22712
23069
  elicitation: { form: {}, url: {} },
@@ -22733,11 +23090,11 @@ var AcpProcessSession = class _AcpProcessSession {
22733
23090
  }
22734
23091
  const capabilities = initialized.agentCapabilities ?? {};
22735
23092
  this.#capabilities = normalizeCapabilities(capabilities);
22736
- this.#agentName = truncate2(
23093
+ this.#agentName = truncate3(
22737
23094
  initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId,
22738
23095
  255
22739
23096
  );
22740
- this.#agentVersion = truncate2(
23097
+ this.#agentVersion = truncate3(
22741
23098
  this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
22742
23099
  128
22743
23100
  );
@@ -22774,7 +23131,7 @@ var AcpProcessSession = class _AcpProcessSession {
22774
23131
  );
22775
23132
  const forked = await this.race(
22776
23133
  this.#connection.agent.request(
22777
- methods2.agent.session.fork,
23134
+ methods3.agent.session.fork,
22778
23135
  {
22779
23136
  sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
22780
23137
  cwd: this.#cwd,
@@ -22807,7 +23164,7 @@ var AcpProcessSession = class _AcpProcessSession {
22807
23164
  if (this.#capabilities.resumeSession) {
22808
23165
  lifecycleResponse = await this.race(
22809
23166
  this.#connection.agent.request(
22810
- methods2.agent.session.resume,
23167
+ methods3.agent.session.resume,
22811
23168
  {
22812
23169
  additionalDirectories: [...this.#additionalDirectories],
22813
23170
  cwd: this.#cwd,
@@ -22824,7 +23181,7 @@ var AcpProcessSession = class _AcpProcessSession {
22824
23181
  try {
22825
23182
  lifecycleResponse = await this.race(
22826
23183
  this.#connection.agent.request(
22827
- methods2.agent.session.load,
23184
+ methods3.agent.session.load,
22828
23185
  {
22829
23186
  additionalDirectories: [...this.#additionalDirectories],
22830
23187
  cwd: this.#cwd,
@@ -22860,7 +23217,7 @@ var AcpProcessSession = class _AcpProcessSession {
22860
23217
  }
22861
23218
  const created = await this.race(
22862
23219
  this.#connection.agent.request(
22863
- methods2.agent.session.new,
23220
+ methods3.agent.session.new,
22864
23221
  {
22865
23222
  additionalDirectories: [...this.#additionalDirectories],
22866
23223
  cwd: this.#cwd,
@@ -22874,11 +23231,7 @@ var AcpProcessSession = class _AcpProcessSession {
22874
23231
  this.selectNativeSession(created.sessionId);
22875
23232
  lifecycleResponse = created;
22876
23233
  }
22877
- const lifecycleRecord = isRecord3(lifecycleResponse) ? lifecycleResponse : {};
22878
- this.#configOptions = normalizeConfigOptions(
22879
- lifecycleRecord["configOptions"],
22880
- lifecycleRecord["modes"]
22881
- );
23234
+ this.#configOptions = this.#sessionConfigProtocol.normalizeLifecycle(lifecycleResponse);
22882
23235
  await this.#updateTail;
22883
23236
  signal.throwIfAborted();
22884
23237
  if (this.#prompted) {
@@ -22903,7 +23256,7 @@ var AcpProcessSession = class _AcpProcessSession {
22903
23256
  );
22904
23257
  const response = await this.race(
22905
23258
  this.#connection.agent.request(
22906
- methods2.agent.session.list,
23259
+ methods3.agent.session.list,
22907
23260
  cursor === null ? {} : { cursor },
22908
23261
  { cancellationSignal: signal }
22909
23262
  ),
@@ -22928,7 +23281,7 @@ var AcpProcessSession = class _AcpProcessSession {
22928
23281
  );
22929
23282
  await this.race(
22930
23283
  this.#connection.agent.request(
22931
- methods2.agent.session.delete,
23284
+ methods3.agent.session.delete,
22932
23285
  { sessionId: nativeSessionIdSchema.parse(nativeSessionId) },
22933
23286
  { cancellationSignal: signal }
22934
23287
  ),
@@ -22949,64 +23302,50 @@ var AcpProcessSession = class _AcpProcessSession {
22949
23302
  );
22950
23303
  }
22951
23304
  if (existing.type === "select") {
22952
- if (!existing.values.some((entry) => entry.value === options.value)) {
23305
+ if (existing.values.length < 2) {
22953
23306
  throw new AcpExecutionError(
22954
- "The requested ACP configuration value is unavailable",
23307
+ "The requested ACP configuration option is unavailable",
22955
23308
  {},
22956
23309
  "invalid_session_configuration"
22957
23310
  );
22958
23311
  }
22959
- if (existing.category === "mode") {
22960
- await this.race(
22961
- this.#connection.agent.request(
22962
- methods2.agent.session.setMode,
22963
- { modeId: options.value, sessionId: this.#nativeSessionId },
22964
- { cancellationSignal: options.signal }
22965
- ),
22966
- "ACP agent exited while setting the session mode",
22967
- options.signal
22968
- );
22969
- this.#configOptions = this.#configOptions.map(
22970
- (option) => option.id === existing.id ? { ...option, currentValue: options.value } : option
22971
- );
22972
- } else {
22973
- const response = await this.race(
22974
- this.#connection.agent.request(
22975
- methods2.agent.session.setConfigOption,
22976
- {
22977
- configId: existing.id,
22978
- sessionId: this.#nativeSessionId,
22979
- value: options.value
22980
- },
22981
- { cancellationSignal: options.signal }
22982
- ),
22983
- "ACP agent exited while changing session configuration",
22984
- options.signal
22985
- );
22986
- this.#configOptions = replaceConfigOptionsKeepingMode(
22987
- this.#configOptions,
22988
- response.configOptions
23312
+ if (!existing.values.some((entry) => entry.value === options.value)) {
23313
+ throw new AcpExecutionError(
23314
+ "The requested ACP configuration value is unavailable",
23315
+ {},
23316
+ "invalid_session_configuration"
22989
23317
  );
22990
23318
  }
22991
- } else {
22992
- const response = await this.race(
22993
- this.#connection.agent.request(
22994
- methods2.agent.session.setConfigOption,
22995
- {
22996
- configId: existing.id,
22997
- sessionId: this.#nativeSessionId,
22998
- type: "boolean",
22999
- value: options.booleanValue
23000
- },
23001
- { cancellationSignal: options.signal }
23002
- ),
23003
- "ACP agent exited while changing session configuration",
23004
- options.signal
23005
- );
23006
- this.#configOptions = replaceConfigOptionsKeepingMode(
23319
+ }
23320
+ const configRevision = this.#configRevision;
23321
+ try {
23322
+ const configured = await this.#sessionConfigProtocol.configure(
23007
23323
  this.#configOptions,
23008
- response.configOptions
23324
+ options,
23325
+ this.#nativeSessionId,
23326
+ {
23327
+ request: async (method, params, failureMessage, signal) => await this.race(
23328
+ this.#connection.agent.request(method, params, {
23329
+ cancellationSignal: signal
23330
+ }),
23331
+ failureMessage,
23332
+ signal
23333
+ )
23334
+ }
23009
23335
  );
23336
+ await this.#updateTail;
23337
+ if (this.#configRevision === configRevision) {
23338
+ this.#configOptions = configured;
23339
+ }
23340
+ } catch (error61) {
23341
+ if (error61 instanceof SessionConfigProtocolError) {
23342
+ throw new AcpExecutionError(
23343
+ error61.message,
23344
+ { cause: error61 },
23345
+ error61.code
23346
+ );
23347
+ }
23348
+ throw error61;
23010
23349
  }
23011
23350
  return this.#configOptions;
23012
23351
  };
@@ -23090,7 +23429,7 @@ var AcpProcessSession = class _AcpProcessSession {
23090
23429
  try {
23091
23430
  const response = await this.race(
23092
23431
  this.#connection.agent.request(
23093
- methods2.agent.session.prompt,
23432
+ methods3.agent.session.prompt,
23094
23433
  { prompt, sessionId: this.#nativeSessionId },
23095
23434
  { cancellationSignal: options.signal }
23096
23435
  ),
@@ -23137,7 +23476,7 @@ var AcpProcessSession = class _AcpProcessSession {
23137
23476
  try {
23138
23477
  await this.cancelPendingInteractions();
23139
23478
  if (this.#turn.running) {
23140
- await this.#connection.agent.notify(methods2.agent.session.cancel, {
23479
+ await this.#connection.agent.notify(methods3.agent.session.cancel, {
23141
23480
  sessionId: this.#nativeSessionId
23142
23481
  });
23143
23482
  }
@@ -23227,8 +23566,8 @@ var AcpProcessSession = class _AcpProcessSession {
23227
23566
  const interactionId = `permission-${crypto.randomUUID()}`;
23228
23567
  const options = request.options.slice(0, 20).map((option) => ({
23229
23568
  kind: option.kind,
23230
- name: truncate2(option.name, 255),
23231
- optionId: truncate2(option.optionId, 255)
23569
+ name: truncate3(option.name, 255),
23570
+ optionId: truncate3(option.optionId, 255)
23232
23571
  }));
23233
23572
  if (options.length === 0) {
23234
23573
  throw new AcpExecutionError(
@@ -23253,9 +23592,9 @@ var AcpProcessSession = class _AcpProcessSession {
23253
23592
  kind: SESSION_PERMISSION_REQUESTED_KIND,
23254
23593
  options,
23255
23594
  sessionId: this.#mobiusSessionId,
23256
- title: truncate2(request.toolCall.title ?? "Permission required", 500),
23257
- toolCallId: truncate2(request.toolCall.toolCallId, 255),
23258
- toolKind: truncate2(request.toolCall.kind ?? "other", 64)
23595
+ title: truncate3(request.toolCall.title ?? "Permission required", 500),
23596
+ toolCallId: truncate3(request.toolCall.toolCallId, 255),
23597
+ toolKind: truncate3(request.toolCall.kind ?? "other", 64)
23259
23598
  });
23260
23599
  return await pending.completion.promise;
23261
23600
  } finally {
@@ -23284,7 +23623,7 @@ var AcpProcessSession = class _AcpProcessSession {
23284
23623
  const schemaValue = Reflect.get(request, "requestedSchema");
23285
23624
  const requestedSchema = request.mode === "form" ? schemaValue : {};
23286
23625
  const elicitationIdValue = Reflect.get(request, "elicitationId");
23287
- const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate2(elicitationIdValue, 255) : "";
23626
+ const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
23288
23627
  const pending = new PendingElicitation(
23289
23628
  interactionId,
23290
23629
  elicitationId,
@@ -23303,10 +23642,10 @@ var AcpProcessSession = class _AcpProcessSession {
23303
23642
  fields: normalizeElicitationFields(requestedSchema),
23304
23643
  interactionId,
23305
23644
  kind: SESSION_ELICITATION_REQUESTED_KIND,
23306
- message: truncate2(request.message, 2e3),
23645
+ message: truncate3(request.message, 2e3),
23307
23646
  mode: request.mode,
23308
23647
  sessionId: this.#mobiusSessionId,
23309
- url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate2(readString3(Reflect.get(request, "url")), 4096) : ""
23648
+ url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString4(Reflect.get(request, "url")), 4096) : ""
23310
23649
  });
23311
23650
  return await pending.completion.promise;
23312
23651
  } finally {
@@ -23395,7 +23734,7 @@ var AcpProcessSession = class _AcpProcessSession {
23395
23734
  content: normalizeContentBlock(update.content),
23396
23735
  contentId: `content-${crypto.randomUUID()}`,
23397
23736
  kind: AGENT_CONTENT_KIND,
23398
- messageId: truncate2(update.messageId ?? "", 255),
23737
+ messageId: truncate3(update.messageId ?? "", 255),
23399
23738
  sessionId: this.#mobiusSessionId
23400
23739
  });
23401
23740
  }
@@ -23433,9 +23772,9 @@ var AcpProcessSession = class _AcpProcessSession {
23433
23772
  }
23434
23773
  if (update.sessionUpdate === "available_commands_update") {
23435
23774
  const commands = update.availableCommands.slice(0, 500).map((command) => ({
23436
- description: truncate2(command.description, 500),
23437
- inputHint: truncate2(command.input?.hint ?? "", 255),
23438
- name: truncate2(command.name, 128)
23775
+ description: truncate3(command.description, 500),
23776
+ inputHint: truncate3(command.input?.hint ?? "", 255),
23777
+ name: truncate3(command.name, 128)
23439
23778
  })).filter((command) => command.name.length > 0);
23440
23779
  this.#commands = commands;
23441
23780
  await this.#getObserver().onCommands({
@@ -23446,10 +23785,11 @@ var AcpProcessSession = class _AcpProcessSession {
23446
23785
  return;
23447
23786
  }
23448
23787
  if (update.sessionUpdate === "config_option_update") {
23449
- this.#configOptions = replaceConfigOptionsKeepingMode(
23788
+ this.#configOptions = this.#sessionConfigProtocol.normalizeUpdate(
23450
23789
  this.#configOptions,
23451
23790
  update.configOptions
23452
23791
  );
23792
+ this.#configRevision += 1;
23453
23793
  await this.emitConfigUpdate();
23454
23794
  return;
23455
23795
  }
@@ -23457,15 +23797,16 @@ var AcpProcessSession = class _AcpProcessSession {
23457
23797
  this.#configOptions = this.#configOptions.map(
23458
23798
  (option) => option.category === "mode" ? { ...option, currentValue: update.currentModeId } : option
23459
23799
  );
23800
+ this.#configRevision += 1;
23460
23801
  await this.emitConfigUpdate();
23461
23802
  return;
23462
23803
  }
23463
23804
  if (update.sessionUpdate === "session_info_update") {
23464
23805
  if (Object.hasOwn(update, "title")) {
23465
- this.#sessionTitle = truncate2(update.title ?? "", 500);
23806
+ this.#sessionTitle = truncate3(update.title ?? "", 500);
23466
23807
  }
23467
23808
  if (Object.hasOwn(update, "updatedAt")) {
23468
- this.#sessionUpdatedAt = truncate2(update.updatedAt ?? "", 128);
23809
+ this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
23469
23810
  }
23470
23811
  await this.#getObserver().onInfo({
23471
23812
  kind: SESSION_INFO_UPDATED_KIND,
@@ -23478,7 +23819,7 @@ var AcpProcessSession = class _AcpProcessSession {
23478
23819
  if (update.sessionUpdate === "usage_update") {
23479
23820
  await this.#getObserver().onUsage({
23480
23821
  costAmount: update.cost?.amount ?? 0,
23481
- costCurrency: truncate2(update.cost?.currency ?? "", 16),
23822
+ costCurrency: truncate3(update.cost?.currency ?? "", 16),
23482
23823
  hasCost: update.cost !== void 0 && update.cost !== null,
23483
23824
  kind: SESSION_USAGE_UPDATED_KIND,
23484
23825
  sessionId: this.#mobiusSessionId,
@@ -23493,7 +23834,7 @@ var AcpProcessSession = class _AcpProcessSession {
23493
23834
  if (this.#capabilities.closeSession && this.#nativeSessionId.length > 0) {
23494
23835
  try {
23495
23836
  await this.#connection.agent.request(
23496
- methods2.agent.session.close,
23837
+ methods3.agent.session.close,
23497
23838
  { sessionId: this.#nativeSessionId },
23498
23839
  {
23499
23840
  cancellationSignal: AbortSignal.timeout(
@@ -24347,7 +24688,7 @@ var ManagedNpmPackageError = class extends Error {
24347
24688
  this.name = "ManagedNpmPackageError";
24348
24689
  }
24349
24690
  };
24350
- function isRecord4(value) {
24691
+ function isRecord5(value) {
24351
24692
  return typeof value === "object" && value !== null && !Array.isArray(value);
24352
24693
  }
24353
24694
  function packagePath(root, packageName) {
@@ -24371,7 +24712,7 @@ async function readJsonRecord(path2, maximumBytes) {
24371
24712
  const value = JSON.parse(
24372
24713
  await handle.readFile({ encoding: "utf8" })
24373
24714
  );
24374
- if (!isRecord4(value)) {
24715
+ if (!isRecord5(value)) {
24375
24716
  throw new ManagedNpmPackageError(
24376
24717
  "managed_package_verification_failed",
24377
24718
  "The managed npm package metadata is invalid"
@@ -24397,7 +24738,7 @@ function readBinPath(packageMetadata, executableName) {
24397
24738
  if (typeof bin === "string") {
24398
24739
  return bin;
24399
24740
  }
24400
- if (isRecord4(bin) && typeof bin[executableName] === "string") {
24741
+ if (isRecord5(bin) && typeof bin[executableName] === "string") {
24401
24742
  return bin[executableName];
24402
24743
  }
24403
24744
  throw new ManagedNpmPackageError(
@@ -24413,7 +24754,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
24413
24754
  );
24414
24755
  }
24415
24756
  const packages = lock["packages"];
24416
- if (!isRecord4(packages)) {
24757
+ if (!isRecord5(packages)) {
24417
24758
  throw new ManagedNpmPackageError(
24418
24759
  "managed_package_verification_failed",
24419
24760
  "The managed npm package lockfile is invalid"
@@ -24427,7 +24768,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
24427
24768
  if (verifyDependencyClosure && normalizedKey.length > 0) {
24428
24769
  let resolved;
24429
24770
  try {
24430
- if (!normalizedKey.split("/").includes("node_modules") || !isRecord4(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
24771
+ if (!normalizedKey.split("/").includes("node_modules") || !isRecord5(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
24431
24772
  throw new Error("Invalid locked dependency");
24432
24773
  }
24433
24774
  resolved = new URL(candidate["resolved"]);
@@ -24450,7 +24791,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
24450
24791
  matches += 1;
24451
24792
  }
24452
24793
  }
24453
- if (matches !== 1 || !isRecord4(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
24794
+ if (matches !== 1 || !isRecord5(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
24454
24795
  throw new ManagedNpmPackageError(
24455
24796
  "managed_package_verification_failed",
24456
24797
  "The managed npm package lockfile does not match the pinned artifact"
@@ -24672,6 +25013,7 @@ var LocalAgentSpecification = class {
24672
25013
  };
24673
25014
  createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
24674
25015
  recoveryCommand = () => "";
25016
+ resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
24675
25017
  supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
24676
25018
  verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
24677
25019
  };
@@ -24778,11 +25120,11 @@ var AgentProbeError = class extends Error {
24778
25120
 
24779
25121
  // src/agent-catalog/agents/verify-session-creation.ts
24780
25122
  import {
24781
- methods as methods3
25123
+ methods as methods4
24782
25124
  } from "@agentclientprotocol/sdk";
24783
25125
  async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
24784
25126
  const session = await connection.agent.request(
24785
- methods3.agent.session.new,
25127
+ methods4.agent.session.new,
24786
25128
  {
24787
25129
  additionalDirectories: [],
24788
25130
  cwd: defaultWorkspace,
@@ -24798,7 +25140,7 @@ async function verifySessionCreation(connection, capabilities, defaultWorkspace,
24798
25140
  }
24799
25141
  if (capabilities.sessionCapabilities?.close != null) {
24800
25142
  await connection.agent.request(
24801
- methods3.agent.session.close,
25143
+ methods4.agent.session.close,
24802
25144
  { sessionId: session.sessionId },
24803
25145
  { cancellationSignal: signal }
24804
25146
  );
@@ -25383,7 +25725,7 @@ var ManagedAgentArchiveError = class extends Error {
25383
25725
  var ManagedAgentArchiveDownloader = class {
25384
25726
  download = async (options) => await downloadVerifiedFile(options);
25385
25727
  };
25386
- function isRecord5(value) {
25728
+ function isRecord6(value) {
25387
25729
  return typeof value === "object" && value !== null && !Array.isArray(value);
25388
25730
  }
25389
25731
  function isContainedPath3(root, candidate) {
@@ -25442,7 +25784,7 @@ async function readManifest(path2) {
25442
25784
  const parsed = JSON.parse(
25443
25785
  await handle.readFile({ encoding: "utf8" })
25444
25786
  );
25445
- if (!isRecord5(parsed)) {
25787
+ if (!isRecord6(parsed)) {
25446
25788
  throw new ManagedAgentArchiveError(
25447
25789
  "managed_archive_verification_failed",
25448
25790
  "The managed Agent archive manifest is invalid"
@@ -25729,7 +26071,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
25729
26071
  // src/agent-catalog/agents/pi-agent.ts
25730
26072
  import { join as join10 } from "node:path";
25731
26073
  import {
25732
- methods as methods4
26074
+ methods as methods5
25733
26075
  } from "@agentclientprotocol/sdk";
25734
26076
 
25735
26077
  // src/agent-installation/pi-managed-packages.ts
@@ -25801,7 +26143,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
25801
26143
  );
25802
26144
  }
25803
26145
  const session = await connection.agent.request(
25804
- methods4.agent.session.new,
26146
+ methods5.agent.session.new,
25805
26147
  {
25806
26148
  additionalDirectories: [],
25807
26149
  cwd: defaultWorkspace,
@@ -25816,7 +26158,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
25816
26158
  );
25817
26159
  }
25818
26160
  const prompt = await connection.agent.request(
25819
- methods4.agent.session.prompt,
26161
+ methods5.agent.session.prompt,
25820
26162
  {
25821
26163
  prompt: [{ text: "/session", type: "text" }],
25822
26164
  sessionId: session.sessionId
@@ -25833,7 +26175,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
25833
26175
  };
25834
26176
 
25835
26177
  // src/agent-catalog/agents/workbuddy-agent.ts
25836
- import { join as join11 } from "node:path";
26178
+ import { isAbsolute as isAbsolute5, join as join11 } from "node:path";
25837
26179
 
25838
26180
  // src/agent-installation/workbuddy-managed-package.ts
25839
26181
  var WORKBUDDY_MANAGED_VERSION = "2.146.0";
@@ -25853,6 +26195,15 @@ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
25853
26195
  );
25854
26196
 
25855
26197
  // src/agent-catalog/agents/workbuddy-agent.ts
26198
+ var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
26199
+ "WorkBuddy.app",
26200
+ "Contents",
26201
+ "Resources",
26202
+ "app.asar.unpacked",
26203
+ "cli",
26204
+ "bin",
26205
+ "codebuddy"
26206
+ ]);
25856
26207
  var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
25857
26208
  adapterVersion = WORKBUDDY_MANAGED_VERSION;
25858
26209
  authenticationCommand = () => "codebuddy";
@@ -25885,6 +26236,30 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
25885
26236
  signal.throwIfAborted();
25886
26237
  return executable;
25887
26238
  };
26239
+ resolveInstalledAgentExecutables = async (context) => {
26240
+ context.signal.throwIfAborted();
26241
+ if ((context.platform ?? process.platform) !== "darwin") {
26242
+ return [];
26243
+ }
26244
+ const requestedPaths = [
26245
+ join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)
26246
+ ];
26247
+ const homeDirectory = context.environment["HOME"];
26248
+ if (homeDirectory !== void 0 && isAbsolute5(homeDirectory)) {
26249
+ requestedPaths.unshift(
26250
+ join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)
26251
+ );
26252
+ }
26253
+ const executables = [];
26254
+ for (const requestedPath of requestedPaths) {
26255
+ const executable = await resolveExecutablePath(requestedPath, "darwin");
26256
+ context.signal.throwIfAborted();
26257
+ if (executable !== null) {
26258
+ executables.push(executable);
26259
+ }
26260
+ }
26261
+ return executables;
26262
+ };
25888
26263
  verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
25889
26264
  const capabilities = initialized.agentCapabilities ?? {};
25890
26265
  if (capabilities.loadSession !== true || (initialized.authMethods ?? []).length === 0) {
@@ -25920,14 +26295,14 @@ function supportedLocalAgentSpecifications() {
25920
26295
  // src/agent-catalog/acp-readiness-probe.ts
25921
26296
  import { spawn as spawn3 } from "node:child_process";
25922
26297
  import {
25923
- methods as methods5,
26298
+ methods as methods6,
25924
26299
  ndJsonStream as ndJsonStream2,
25925
26300
  PROTOCOL_VERSION as PROTOCOL_VERSION2,
25926
26301
  RequestError as RequestError2
25927
26302
  } from "@agentclientprotocol/sdk";
25928
26303
 
25929
26304
  // src/agent-catalog/executable-discovery.ts
25930
- import { isAbsolute as isAbsolute5, join as join13 } from "node:path";
26305
+ import { isAbsolute as isAbsolute6, join as join13 } from "node:path";
25931
26306
 
25932
26307
  // src/agent-installation/managed-adapter-installer.ts
25933
26308
  import { join as join12 } from "node:path";
@@ -26044,10 +26419,10 @@ async function resolveManagedAdapterExecutable(specification, context) {
26044
26419
  }
26045
26420
  return managed;
26046
26421
  }
26047
- async function resolveSpecificationExecutables(executableName, overrideVariable, resolveManaged, context) {
26422
+ async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
26048
26423
  const override = context.environment[overrideVariable];
26049
26424
  if (override !== void 0) {
26050
- if (override.length === 0 || !isAbsolute5(override)) {
26425
+ if (override.length === 0 || !isAbsolute6(override)) {
26051
26426
  return [];
26052
26427
  }
26053
26428
  const executable = await resolveExecutablePath(override, context.platform);
@@ -26058,19 +26433,30 @@ async function resolveSpecificationExecutables(executableName, overrideVariable,
26058
26433
  context.environment,
26059
26434
  context.platform
26060
26435
  );
26436
+ const installed = await resolveInstalled();
26061
26437
  const managed = await resolveManaged();
26062
- if (external === null) {
26063
- return managed === null ? [] : [managed];
26438
+ const executables = [];
26439
+ const paths = /* @__PURE__ */ new Set();
26440
+ if (external !== null) {
26441
+ executables.push(external);
26442
+ paths.add(external.path);
26064
26443
  }
26065
- if (managed === null || managed.path === external.path) {
26066
- return [external];
26444
+ for (const executable of installed) {
26445
+ if (!paths.has(executable.path)) {
26446
+ executables.push(executable);
26447
+ paths.add(executable.path);
26448
+ }
26449
+ }
26450
+ if (managed !== null && !paths.has(managed.path)) {
26451
+ executables.push(managed);
26067
26452
  }
26068
- return [external, managed];
26453
+ return executables;
26069
26454
  }
26070
26455
  async function resolveAgentExecutables(specification, context) {
26071
26456
  return await resolveSpecificationExecutables(
26072
26457
  specification.agentExecutable,
26073
26458
  specification.agentOverrideVariable,
26459
+ async () => await specification.resolveInstalledAgentExecutables(context),
26074
26460
  async () => await resolveManagedExecutable(specification, context),
26075
26461
  context
26076
26462
  );
@@ -26085,6 +26471,7 @@ async function resolveAdapterExecutables(specification, context) {
26085
26471
  return await resolveSpecificationExecutables(
26086
26472
  specification.adapterExecutable,
26087
26473
  specification.adapterOverrideVariable,
26474
+ () => Promise.resolve([]),
26088
26475
  async () => await resolveManagedAdapterExecutable(specification, context),
26089
26476
  context
26090
26477
  );
@@ -26261,7 +26648,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
26261
26648
  try {
26262
26649
  const initialized = await Promise.race([
26263
26650
  connection.agent.request(
26264
- methods5.agent.initialize,
26651
+ methods6.agent.initialize,
26265
26652
  {
26266
26653
  clientCapabilities: {},
26267
26654
  clientInfo: { name: "mobius", version: "0.0.3" },
@@ -26504,7 +26891,7 @@ var PairingClientError = class extends Error {
26504
26891
  this.name = "PairingClientError";
26505
26892
  }
26506
26893
  };
26507
- function isRecord6(value) {
26894
+ function isRecord7(value) {
26508
26895
  return typeof value === "object" && value !== null && !Array.isArray(value);
26509
26896
  }
26510
26897
  function hasExactKeys(value, expectedKeys) {
@@ -26657,9 +27044,9 @@ async function readJsonResponse(response) {
26657
27044
  }
26658
27045
  }
26659
27046
  function readRelayError(value) {
26660
- if (isRecord6(value)) {
27047
+ if (isRecord7(value)) {
26661
27048
  const error61 = value["error"];
26662
- if (isRecord6(error61)) {
27049
+ if (isRecord7(error61)) {
26663
27050
  const code = error61["code"];
26664
27051
  const message = error61["message"];
26665
27052
  if (typeof code === "string" && typeof message === "string") {
@@ -26673,7 +27060,7 @@ function readRelayError(value) {
26673
27060
  );
26674
27061
  }
26675
27062
  function decodeClaimResponse(value) {
26676
- if (!isRecord6(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
27063
+ if (!isRecord7(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
26677
27064
  throw new PairingClientError(
26678
27065
  "invalid_relay_response",
26679
27066
  "The relay returned an invalid pairing response"
@@ -26757,7 +27144,7 @@ async function persistConnection(channelId, relayOrigin, daemonToken, defaultWor
26757
27144
  return connectionPath;
26758
27145
  }
26759
27146
  function decodeSavedConnection(value, expectedChannelId) {
26760
- if (!isRecord6(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
27147
+ if (!isRecord7(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
26761
27148
  throw new PairingClientError(
26762
27149
  "invalid_connection",
26763
27150
  "The saved connection is invalid"
@@ -27509,11 +27896,11 @@ var FixedAgentInstallRecipe = class {
27509
27896
 
27510
27897
  // src/agent-installation/grok-build-install-recipe.ts
27511
27898
  import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27512
- import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute6, join as join15, relative as relative4, sep as sep4 } from "node:path";
27899
+ import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
27513
27900
  var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
27514
27901
  function isContainedPath4(root, candidate) {
27515
27902
  const difference = relative4(root, candidate);
27516
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute6(difference);
27903
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
27517
27904
  }
27518
27905
  async function resolveLifecycleScript(packageRoot) {
27519
27906
  try {
@@ -28345,7 +28732,7 @@ import { homedir as homedir2 } from "node:os";
28345
28732
  import {
28346
28733
  basename as basename2,
28347
28734
  dirname as dirname6,
28348
- isAbsolute as isAbsolute7,
28735
+ isAbsolute as isAbsolute8,
28349
28736
  join as join18,
28350
28737
  normalize as normalize2,
28351
28738
  relative as relative5
@@ -28398,20 +28785,20 @@ var WorkspaceDirectoryService = class {
28398
28785
  if (id === "home") return homedir2();
28399
28786
  if (id.startsWith("path-")) {
28400
28787
  const path2 = decodePath(id, "path-");
28401
- if (isAbsolute7(path2)) return path2;
28788
+ if (isAbsolute8(path2)) return path2;
28402
28789
  }
28403
28790
  throw new LocalAuthorizationError("The directory identifier is invalid");
28404
28791
  };
28405
28792
  resolvePath = async (requested, signal) => {
28406
28793
  signal.throwIfAborted();
28407
- if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28794
+ if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28408
28795
  throw new LocalAuthorizationError("The local directory path is invalid");
28409
28796
  try {
28410
28797
  const target = await realpath8(requested);
28411
28798
  signal.throwIfAborted();
28412
28799
  const metadata = await stat7(target);
28413
28800
  signal.throwIfAborted();
28414
- if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
28801
+ if (!isAbsolute8(target) || normalize2(target) !== target || !metadata.isDirectory())
28415
28802
  throw new LocalAuthorizationError(
28416
28803
  "The selected location is not a directory"
28417
28804
  );
@@ -28427,7 +28814,7 @@ var WorkspaceDirectoryService = class {
28427
28814
  };
28428
28815
  label = (path2) => {
28429
28816
  const suffix = relative5(homedir2(), path2);
28430
- return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28817
+ return suffix === "" ? "~" : !isAbsolute8(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28431
28818
  };
28432
28819
  identify = async (bindingId, requestedPath, signal) => {
28433
28820
  this.authorizeMachine(bindingId);