lody 0.89.3 → 0.90.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
@@ -14,27 +14,27 @@ import * as os$1 from "node:os";
14
14
  import os__default, { userInfo, homedir, cpus } from "node:os";
15
15
  import * as path from "node:path";
16
16
  import path__default, { posix as posix$1, basename, win32, join as join$2, resolve as resolve$1, dirname as dirname$1, relative as relative$1, isAbsolute as isAbsolute$2, sep as sep$1, delimiter, normalize } from "node:path";
17
- import { _ as _coercedNumber, Z as ZodNumber$1, o as object$1, s as string$1, l as literal$1, n as number$4, b as boolean, a as _enum$1, c as array$2, d as discriminatedUnion, e as _instanceof, r as record$1, u as unknown, f as union$7, p as preprocess, g as ZodError$1, h as _null, i as normalizeParams, $ as $constructor, j as $ZodObject, k as defineLazy, m as $ZodType, q as parse$5, t as safeParse$1, v as parseAsync, w as safeParseAsync$1, x as clone$2, y as looseObject, z as intersection, A as optional$1, B as datetime, C as custom$1, D as toJSONSchema, E as ZodOptional$1, F as never$1, G as xor } from "./chunks/schemas-Du3qLZPS.js";
17
+ import { _ as _coercedNumber, Z as ZodNumber$1, o as object$1, s as string$1, l as literal$1, n as number$4, b as boolean, a as _enum$1, c as array$2, r as record$1, d as discriminatedUnion, e as _instanceof, u as unknown, f as union$7, p as preprocess, g as ZodError$1, h as _null, i as normalizeParams, $ as $constructor, j as $ZodObject, k as defineLazy, m as $ZodType, q as parse$5, t as safeParse$1, v as parseAsync, w as safeParseAsync$1, x as clone$2, y as looseObject, z as intersection, A as optional$1, B as datetime, C as custom$1, D as toJSONSchema, E as ZodOptional$1, F as never$1, G as xor } from "./chunks/schemas-Du3qLZPS.js";
18
18
  import require$$0$4, { once as once$1, EventEmitter as EventEmitter$1 } from "node:events";
19
- import Gx__default, { execFile, spawn as spawn$1, execFileSync } from "node:child_process";
19
+ import Tw__default, { execFile, spawn as spawn$1, execFileSync } from "node:child_process";
20
20
  import process$2 from "node:process";
21
21
  import tty from "node:tty";
22
22
  import * as os from "os";
23
23
  import os__default$1 from "os";
24
24
  import crypto__default$1, { randomFillSync, randomUUID, createHash, randomBytes, timingSafeEqual } from "node:crypto";
25
25
  import require$$0$5, { promisify as promisify$1 } from "util";
26
- import So, { Transform as Transform$1, Readable as Readable$1 } from "stream";
26
+ import xo, { Transform as Transform$1, Readable as Readable$1 } from "stream";
27
27
  import require$$0$6, { Buffer as Buffer$1 } from "buffer";
28
28
  import require$$0$7, { EventEmitter as EventEmitter$2 } from "events";
29
- import * as Ei from "zlib";
30
- import Ei__default from "zlib";
29
+ import * as Ri from "zlib";
30
+ import Ri__default from "zlib";
31
31
  import require$$1$2 from "tty";
32
32
  import require$$1$3 from "string_decoder";
33
33
  import http from "http";
34
34
  import require$$1__default from "https";
35
35
  import require$$0$8, { promisify, inspect as inspect$1, stripVTControlCharacters, isDeepStrictEqual } from "node:util";
36
- import * as Yt from "node:fs/promises";
37
- import Yt__default, { mkdir as mkdir$1, realpath, symlink, mkdtemp, chmod, writeFile, rm, rename, readFile, readdir, stat, lstat, unlink, open, opendir } from "node:fs/promises";
36
+ import * as Xt from "node:fs/promises";
37
+ import Xt__default, { mkdir as mkdir$1, realpath, symlink, mkdtemp, chmod, writeFile, rm, rename, readFile, readdir, stat, lstat, unlink, open, opendir } from "node:fs/promises";
38
38
  import zlib__default, { gzip, gunzip as gunzip$1, gunzipSync, brotliDecompressSync } from "node:zlib";
39
39
  import require$$1$8, { exec, execFile as execFile$1, spawn as spawn$2 } from "child_process";
40
40
  import { i as imports, _ as __wbg_set_wasm$1, r as rawWasm, L as LoroDoc, E as EphemeralStoreWasm, U as UndoManager, a as isValidContainerId, c as callPendingEvents$3, b as LoroTree, d as LoroText, e as LoroMovableList, f as LoroList, g as LoroMap, V as VersionVector, h as __vite__initWasm, j as decodeImportBlobMeta, __tla as __tla_0 } from "./chunks/loro_wasm_bg-Br-Fa9wV.js";
@@ -42,7 +42,7 @@ import { performance as performance$1 } from "perf_hooks";
42
42
  import require$$0$9 from "net";
43
43
  import require$$4$2 from "tls";
44
44
  import require$$7$2, { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1 } from "url";
45
- import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, a as DEEPSEEK_HARNESS_AGENT_PRESETS, b as DEEPSEEK_HARNESS_MODELS, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, A as ACP_EXTENSION_DSH_CAPABILITY_SOURCE_VERSION, d as createDeepSeekHarnessCordisConfig, e as ACP_EXTENSION_DSH_VERSION, f as ACP_EXTENSION_DSH_PROFILE_REVISION, g as ACP_EXTENSION_DSH_QUERY_PATH_ENV, h as ACP_EXTENSION_DSH_SESSION_ROOT_ENV, i as DEEPSEEK_HARNESS_NPX_PACKAGES, j as DEEPSEEK_HARNESS_VERSION, k as DEEPSEEK_HARNESS_DEFAULT_SESSION_COMPRESSION } from "./chunks/profile-Cxxl5hCq.js";
45
+ import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, a as DEEPSEEK_HARNESS_AGENT_PRESETS, b as DEEPSEEK_HARNESS_MODELS, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, A as ACP_EXTENSION_DSH_CAPABILITY_SOURCE_VERSION, d as createDeepSeekHarnessCordisConfig, e as ACP_EXTENSION_DSH_VERSION, f as ACP_EXTENSION_DSH_PROFILE_REVISION, g as ACP_EXTENSION_DSH_QUERY_PATH_ENV, h as ACP_EXTENSION_DSH_SESSION_ROOT_ENV, i as DEEPSEEK_HARNESS_NPX_PACKAGES, j as DEEPSEEK_HARNESS_VERSION, k as DEEPSEEK_HARNESS_DEFAULT_SESSION_COMPRESSION } from "./chunks/profile-CPDWaQXE.js";
46
46
  import assert from "assert";
47
47
  import * as fs$2 from "fs/promises";
48
48
  import fs__default$2 from "fs/promises";
@@ -62,11 +62,11 @@ import require$$1$5, { fileURLToPath, pathToFileURL } from "node:url";
62
62
  import require$$1$6 from "node:console";
63
63
  import require$$1$7 from "node:dns";
64
64
  import { C as CodeCollabV2FileIndexRequestSchema, a as CodeCollabV2OpenTextRequestSchema, b as CodeCollabV2RefreshTextRequestSchema, c as CodeCollabV2SaveTextRequestSchema, d as CodeCollabV2OpenCurrentDiffRequestSchema, e as CodeCollabV2OpenAllChangesDiffRequestSchema, f as CodeCollabV2OpenTurnDiffRequestSchema, g as CodeCollabV2InitDirectoryRequestSchema, h as CodeCollabV2FileIndexSnapshotSchema, i as CodeCollabV2OpenTextOkSchema, j as CodeCollabV2RefreshTextResponseSchema, k as CodeCollabV2SaveTextResponseSchema, l as CodeCollabV2OpenCurrentDiffResponseSchema, m as CodeCollabV2OpenAllChangesDiffResponseSchema, n as CodeCollabV2OpenTurnDiffResponseSchema, o as CodeCollabV2InitDirectoryOkSchema, p as CodeCollabV2LspUnsupportedSchema, q as CodeCollabV2ErrorSchema, r as CodeCollabV2RpcContentEnvelopeSchema, s as deriveCodeCollabV2ContentKeyId, t as CodeCollabV2ErrorCodeSchema, u as CodeCollabV2RpcResponseSchema, v as deriveCodeCollabV2ContentKeyBytes, w as readCodeCollabFileIndexSignalFromFlock, x as writeCodeCollabFileIndexSignalToFlock, y as writeCodeCollabFileIndexToFlock, z as buildCodeCollabFileIndexState, A as CODE_COLLAB_V2_TEXT_LIMITS, B as CODE_COLLAB_V2_ALL_CHANGES_DIFF_LIMITS, D as computeAllChanges, E as codeCollabFileIndexStatesEqual, F as scanGitDirectoryEntries, G as closeDirectoryQuietly } from "./chunks/directory-handle-Bp47LF5g.js";
65
- import { C as ClientSideConnection, P as PROTOCOL_VERSION, n as ndJsonStream } from "./chunks/acp-CrvzLY5A.js";
65
+ import { C as ClientSideConnection, P as PROTOCOL_VERSION, n as ndJsonStream, c as client$2, m as methods$1 } from "./chunks/acp-DBqkNziA.js";
66
66
  import { StringDecoder } from "node:string_decoder";
67
67
  import { L as LODY_EXTENSION_METHODS, n as normalizeLodyExtensionMethod } from "./chunks/methods-CvEDMahD.js";
68
68
  import { pipeline, finished } from "node:stream/promises";
69
- import { p as packageJson } from "./chunks/package-4KuPYsnp.js";
69
+ import { p as packageJson } from "./chunks/package-DlotPnLa.js";
70
70
  import { r as runtimeManifest } from "./chunks/runtime-manifest-DnyvD_EC.js";
71
71
  import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
72
72
  import { createRequire } from "module";
@@ -4325,7 +4325,7 @@ Upgrade Node, then re-run: npx lody@latest`;
4325
4325
  }
4326
4326
  const name$2 = "lody";
4327
4327
  const name$1 = "@lody/cli-cloud";
4328
- const version$9 = "0.89.3";
4328
+ const version$9 = "0.90.0";
4329
4329
  const type$2 = "module";
4330
4330
  const scripts = {
4331
4331
  "dev": "node dev.mjs",
@@ -4878,7 +4878,7 @@ Upgrade Node, then re-run: npx lody@latest`;
4878
4878
  },
4879
4879
  {
4880
4880
  id: "default",
4881
- name: "Default",
4881
+ name: "Manual",
4882
4882
  description: "Standard behavior, prompts for dangerous operations"
4883
4883
  },
4884
4884
  {
@@ -4895,33 +4895,38 @@ Upgrade Node, then re-run: npx lody@latest`;
4895
4895
  id: "dontAsk",
4896
4896
  name: "Don't Ask",
4897
4897
  description: "Don't prompt for permissions, deny if not pre-approved"
4898
+ },
4899
+ {
4900
+ id: "bypassPermissions",
4901
+ name: "Bypass Permissions",
4902
+ description: "Bypass all permission checks"
4898
4903
  }
4899
4904
  ];
4900
4905
  const CLAUDE_STATIC_MODELS = [
4901
4906
  {
4902
4907
  modelId: "default",
4903
- name: "Default",
4904
- description: "Claude Code default model"
4908
+ name: "Default (recommended)",
4909
+ description: "Opus (1M context)"
4905
4910
  },
4906
4911
  {
4907
- modelId: "opus",
4908
- name: "Opus",
4909
- description: "Claude Opus"
4912
+ modelId: "opus[1m]",
4913
+ name: "Opus (1M context)",
4914
+ description: "Opus 5 with 1M context \xB7 Best for everyday, complex tasks"
4910
4915
  },
4911
4916
  {
4912
- modelId: "claude-fable-5[1m]",
4917
+ modelId: "claude-fable-5-1[1m]",
4913
4918
  name: "Fable",
4914
- description: "Claude Fable 5 with 1M context"
4919
+ description: "Fable 5.1 \xB7 Most capable for your hardest and longest-running tasks"
4915
4920
  },
4916
4921
  {
4917
4922
  modelId: "sonnet",
4918
4923
  name: "Sonnet",
4919
- description: "Claude Sonnet"
4924
+ description: "Sonnet 5 \xB7 Efficient for routine tasks"
4920
4925
  },
4921
4926
  {
4922
4927
  modelId: "haiku",
4923
4928
  name: "Haiku",
4924
- description: "Claude Haiku"
4929
+ description: "Haiku 4.5 \xB7 Fastest for quick answers"
4925
4930
  }
4926
4931
  ];
4927
4932
  [
@@ -4974,8 +4979,25 @@ Upgrade Node, then re-run: npx lody@latest`;
4974
4979
  {
4975
4980
  value: "high",
4976
4981
  name: "High"
4982
+ },
4983
+ {
4984
+ value: "xhigh",
4985
+ name: "Xhigh"
4986
+ },
4987
+ {
4988
+ value: "max",
4989
+ name: "Max"
4977
4990
  }
4978
4991
  ]
4992
+ },
4993
+ {
4994
+ id: "fast",
4995
+ name: "Fast mode",
4996
+ description: "Faster responses on supported models",
4997
+ category: "model_config",
4998
+ type: "boolean",
4999
+ currentValue: false,
5000
+ options: []
4979
5001
  }
4980
5002
  ];
4981
5003
  const KIMI_STATIC_MODES = [
@@ -5892,6 +5914,16 @@ Requirements:
5892
5914
  "ANTHROPIC_VERTEX_PROJECT_ID"
5893
5915
  ];
5894
5916
  const hasBuiltinEnvAuthentication = (agentType, env2) => agentType === "claude" && CLAUDE_ENV_AUTH_KEYS.some((key2) => Boolean(env2?.[key2]?.trim()));
5917
+ const ACP_AUTH_METHOD_MAX_COUNT = 32;
5918
+ const ACP_AUTH_FORM_FIELD_MAX_COUNT = 32;
5919
+ const ACP_AUTH_SELECT_OPTION_MAX_COUNT = 256;
5920
+ const ACP_AUTH_ID_MAX_LENGTH = 1024;
5921
+ const ACP_AUTH_LABEL_MAX_LENGTH = 4096;
5922
+ const ACP_AUTH_TEXT_MAX_LENGTH = 16384;
5923
+ const ACP_AUTHORIZATION_URL_MAX_LENGTH = 8192;
5924
+ const ACP_AUTHENTICATION_FORM_MAX_BYTES = 256 * 1024;
5925
+ const textEncoder$5 = new TextEncoder();
5926
+ const isAcpAuthenticationFormWithinByteLimit = (form) => textEncoder$5.encode(JSON.stringify(form)).byteLength <= ACP_AUTHENTICATION_FORM_MAX_BYTES;
5895
5927
  function getMapFieldSchema(schema2, key2) {
5896
5928
  if (!schema2) return void 0;
5897
5929
  if (Object.prototype.hasOwnProperty.call(schema2.definition, key2)) {
@@ -10917,6 +10949,12 @@ Requirements:
10917
10949
  url: schema.String(),
10918
10950
  number: schema.Number()
10919
10951
  });
10952
+ const agentRoleIdSchema = schema.String({
10953
+ required: false
10954
+ }).transform({
10955
+ decode: (value) => value,
10956
+ encode: (value) => value
10957
+ });
10920
10958
  const acpSessionConfigSchema = schema.LoroMap({
10921
10959
  prompt: schema.String(),
10922
10960
  inputBlocks: schema.Any({
@@ -10945,6 +10983,10 @@ Requirements:
10945
10983
  taskToolsEnabled: schema.Boolean({
10946
10984
  required: false
10947
10985
  }),
10986
+ agentRoleId: agentRoleIdSchema,
10987
+ agentRoleRevision: schema.Number({
10988
+ required: false
10989
+ }),
10948
10990
  chainDepth: schema.Number({
10949
10991
  required: false
10950
10992
  })
@@ -11464,6 +11506,10 @@ Requirements:
11464
11506
  connection: CliBackendConnectionSchema
11465
11507
  }).strict().optional(),
11466
11508
  connectedWorkspaces: array$2(CliRuntimeWorkspaceSchema).optional(),
11509
+ connectionAges: object$1({
11510
+ backendNotConnectedSinceMs: number$4().int().nonnegative().optional(),
11511
+ workspaceNotConnectedSinceMs: record$1(string$1().min(1), number$4().int().nonnegative()).optional()
11512
+ }).strict().optional(),
11467
11513
  machineId: string$1().min(1).optional(),
11468
11514
  pid: number$4().int(),
11469
11515
  updatedAtMs: number$4(),
@@ -12079,6 +12125,8 @@ Requirements:
12079
12125
  configOptionValues: AcpConfigOptionValuesSchema.optional(),
12080
12126
  mcpServerIds: array$2(string$1()).optional(),
12081
12127
  taskToolsEnabled: boolean().optional(),
12128
+ agentRoleId: string$1().trim().min(1).nullable().optional(),
12129
+ agentRoleRevision: number$4().int().nonnegative().optional(),
12082
12130
  issuePRMentions: array$2(IssuePRMentionSchema).optional(),
12083
12131
  resume: ACPSessionIdSchema.optional(),
12084
12132
  chainDepth: number$4().int().nonnegative().optional()
@@ -12095,6 +12143,8 @@ Requirements:
12095
12143
  configOptionValues: AcpConfigOptionValuesSchema.optional(),
12096
12144
  mcpServerIds: array$2(string$1()).optional(),
12097
12145
  taskToolsEnabled: boolean().optional(),
12146
+ agentRoleId: string$1().trim().min(1).nullable().optional(),
12147
+ agentRoleRevision: number$4().int().nonnegative().optional(),
12098
12148
  issuePRMentions: array$2(IssuePRMentionSchema).optional(),
12099
12149
  resume: ACPSessionIdSchema.optional(),
12100
12150
  chainDepth: number$4().int().nonnegative().optional()
@@ -12166,6 +12216,18 @@ Requirements:
12166
12216
  if (taskToolsEnabled !== void 0) {
12167
12217
  normalized.taskToolsEnabled = taskToolsEnabled;
12168
12218
  }
12219
+ if (record2.agentRoleId === null) {
12220
+ normalized.agentRoleId = null;
12221
+ } else {
12222
+ const agentRoleId = trimOptionalString(record2.agentRoleId);
12223
+ if (agentRoleId) {
12224
+ normalized.agentRoleId = agentRoleId;
12225
+ }
12226
+ }
12227
+ const agentRoleRevision = maybeParseField(number$4().int().nonnegative(), record2.agentRoleRevision);
12228
+ if (agentRoleRevision !== void 0) {
12229
+ normalized.agentRoleRevision = agentRoleRevision;
12230
+ }
12169
12231
  const issuePRMentions = maybeParseField(array$2(IssuePRMentionSchema), record2.issuePRMentions);
12170
12232
  if (issuePRMentions) {
12171
12233
  normalized.issuePRMentions = issuePRMentions;
@@ -12681,21 +12743,101 @@ Requirements:
12681
12743
  "env_var",
12682
12744
  "terminal"
12683
12745
  ]),
12684
- id: string$1().optional(),
12685
- name: string$1().optional(),
12686
- description: string$1().optional(),
12687
- args: array$2(string$1()).optional()
12746
+ id: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH).optional(),
12747
+ name: string$1().max(ACP_AUTH_LABEL_MAX_LENGTH).optional(),
12748
+ description: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12749
+ args: array$2(string$1().max(ACP_AUTH_LABEL_MAX_LENGTH)).max(64).optional()
12688
12750
  }).strict();
12751
+ const MachineAcpAuthenticationFormFieldSchema = discriminatedUnion("type", [
12752
+ object$1({
12753
+ id: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12754
+ type: literal$1("text"),
12755
+ label: string$1().trim().min(1).max(ACP_AUTH_LABEL_MAX_LENGTH),
12756
+ description: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12757
+ required: boolean(),
12758
+ defaultValue: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional()
12759
+ }).strict(),
12760
+ object$1({
12761
+ id: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12762
+ type: literal$1("secret"),
12763
+ label: string$1().trim().min(1).max(ACP_AUTH_LABEL_MAX_LENGTH),
12764
+ description: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12765
+ required: boolean()
12766
+ }).strict(),
12767
+ object$1({
12768
+ id: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12769
+ type: literal$1("select"),
12770
+ label: string$1().trim().min(1).max(ACP_AUTH_LABEL_MAX_LENGTH),
12771
+ description: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12772
+ required: boolean(),
12773
+ options: array$2(object$1({
12774
+ value: string$1().min(1).max(ACP_AUTH_TEXT_MAX_LENGTH),
12775
+ label: string$1().trim().min(1).max(ACP_AUTH_LABEL_MAX_LENGTH)
12776
+ }).strict()).min(1).max(ACP_AUTH_SELECT_OPTION_MAX_COUNT),
12777
+ defaultValue: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional()
12778
+ }).strict()
12779
+ ]);
12780
+ const MachineAcpAuthenticationFormSchema = object$1({
12781
+ title: string$1().max(ACP_AUTH_LABEL_MAX_LENGTH).optional(),
12782
+ description: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12783
+ fields: array$2(MachineAcpAuthenticationFormFieldSchema).min(1).max(ACP_AUTH_FORM_FIELD_MAX_COUNT)
12784
+ }).strict().superRefine((value, context2) => {
12785
+ if (!isAcpAuthenticationFormWithinByteLimit(value)) {
12786
+ context2.addIssue({
12787
+ code: "custom",
12788
+ message: "Authentication form exceeds the serialized size limit"
12789
+ });
12790
+ }
12791
+ const fieldIds = /* @__PURE__ */ new Set();
12792
+ value.fields.forEach((field, fieldIndex) => {
12793
+ if (fieldIds.has(field.id)) {
12794
+ context2.addIssue({
12795
+ code: "custom",
12796
+ path: [
12797
+ "fields",
12798
+ fieldIndex,
12799
+ "id"
12800
+ ],
12801
+ message: "Authentication form field ids must be unique"
12802
+ });
12803
+ }
12804
+ fieldIds.add(field.id);
12805
+ if (field.type !== "select") return;
12806
+ const optionValues = /* @__PURE__ */ new Set();
12807
+ field.options.forEach((option2, optionIndex) => {
12808
+ if (optionValues.has(option2.value)) {
12809
+ context2.addIssue({
12810
+ code: "custom",
12811
+ path: [
12812
+ "fields",
12813
+ fieldIndex,
12814
+ "options",
12815
+ optionIndex,
12816
+ "value"
12817
+ ],
12818
+ message: "Authentication select option values must be unique"
12819
+ });
12820
+ }
12821
+ optionValues.add(option2.value);
12822
+ });
12823
+ if (field.defaultValue !== void 0 && !optionValues.has(field.defaultValue)) {
12824
+ context2.addIssue({
12825
+ code: "custom",
12826
+ path: [
12827
+ "fields",
12828
+ fieldIndex,
12829
+ "defaultValue"
12830
+ ],
12831
+ message: "Authentication select default must match an option"
12832
+ });
12833
+ }
12834
+ });
12835
+ });
12689
12836
  const MachineAcpCapabilitiesRefreshRequestSchema = object$1({
12690
12837
  type: literal$1("machine/acp-capabilities-refresh"),
12691
12838
  machineId: MachineIdSchema$1,
12692
12839
  workspaceId: WorkspaceIdSchema,
12693
- configId: AgentConfigIdSchema,
12694
- cliType: AgentConfigCliTypeSchema,
12695
- agentType: string$1().trim().min(1),
12696
- customAcp: CustomAcpLaunchSpecSchema.optional(),
12697
- runtimeOverrides: BuiltinRuntimeOverridesSchema.optional(),
12698
- env: record$1(string$1(), string$1()).optional()
12840
+ configId: AgentConfigIdSchema
12699
12841
  }).strict();
12700
12842
  const MachineAcpCapabilitiesRefreshResponseSchema = object$1({
12701
12843
  type: literal$1("machine/acp-capabilities-refresh_response"),
@@ -12717,55 +12859,36 @@ Requirements:
12717
12859
  description: string$1().optional()
12718
12860
  })).optional(),
12719
12861
  authRequired: boolean().optional(),
12720
- authMethods: array$2(MachineAcpAuthMethodSummarySchema).optional(),
12862
+ authMethods: array$2(MachineAcpAuthMethodSummarySchema).max(ACP_AUTH_METHOD_MAX_COUNT).optional(),
12721
12863
  error: string$1().optional()
12722
12864
  }).strict();
12723
- const MachineAcpAuthenticateRequestSchema = object$1({
12865
+ const MachineAcpAuthenticateRequestBaseSchema = object$1({
12724
12866
  type: literal$1("machine/acp-authenticate"),
12725
12867
  machineId: MachineIdSchema$1,
12726
12868
  workspaceId: WorkspaceIdSchema,
12727
- requestId: string$1().trim().min(1),
12728
- action: _enum$1([
12729
- "start",
12730
- "cancel",
12731
- "submit-code"
12732
- ]),
12733
- authenticationRequestId: string$1().trim().min(1).optional(),
12734
- authorizationCode: string$1().trim().min(1).max(4096).optional(),
12735
- methodId: string$1().trim().min(1).max(256).optional(),
12736
- configId: AgentConfigIdSchema.optional(),
12737
- cliType: AgentConfigCliTypeSchema,
12738
- agentType: string$1().trim().min(1),
12739
- customAcp: CustomAcpLaunchSpecSchema.optional(),
12740
- runtimeOverrides: BuiltinRuntimeOverridesSchema.optional(),
12741
- env: record$1(string$1(), string$1()).optional()
12742
- }).strict().superRefine((value, context2) => {
12743
- if (value.action === "submit-code") {
12744
- if (!value.authenticationRequestId) {
12745
- context2.addIssue({
12746
- code: "custom",
12747
- path: [
12748
- "authenticationRequestId"
12749
- ],
12750
- message: "authenticationRequestId is required when submitting an authorization code"
12751
- });
12752
- }
12753
- if (!value.authorizationCode) {
12754
- context2.addIssue({
12755
- code: "custom",
12756
- path: [
12757
- "authorizationCode"
12758
- ],
12759
- message: "authorizationCode is required when submitting an authorization code"
12760
- });
12761
- }
12762
- } else if (value.authenticationRequestId || value.authorizationCode) {
12763
- context2.addIssue({
12764
- code: "custom",
12765
- message: "Authorization-code fields are only valid for submit-code"
12766
- });
12767
- }
12869
+ requestId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH)
12768
12870
  });
12871
+ const MachineAcpAuthenticateRequestSchema = discriminatedUnion("action", [
12872
+ MachineAcpAuthenticateRequestBaseSchema.extend({
12873
+ action: literal$1("start"),
12874
+ configId: AgentConfigIdSchema
12875
+ }).strict(),
12876
+ MachineAcpAuthenticateRequestBaseSchema.extend({
12877
+ action: literal$1("cancel"),
12878
+ authenticationRequestId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH)
12879
+ }).strict(),
12880
+ MachineAcpAuthenticateRequestBaseSchema.extend({
12881
+ action: literal$1("submit-code"),
12882
+ authenticationRequestId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12883
+ authorizationCode: string$1().trim().min(1).max(ACP_AUTH_LABEL_MAX_LENGTH)
12884
+ }).strict(),
12885
+ MachineAcpAuthenticateRequestBaseSchema.extend({
12886
+ action: literal$1("submit-input"),
12887
+ authenticationRequestId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12888
+ interactionId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH),
12889
+ authenticationInput: string$1().min(1).max(65536)
12890
+ }).strict()
12891
+ ]);
12769
12892
  const MachineAcpAuthenticateResponseSchema = object$1({
12770
12893
  type: literal$1("machine/acp-authenticate_response"),
12771
12894
  machineId: MachineIdSchema$1,
@@ -12782,7 +12905,7 @@ Requirements:
12782
12905
  ]),
12783
12906
  capabilitiesRefreshed: boolean().optional(),
12784
12907
  authRequired: boolean().optional(),
12785
- authMethods: array$2(MachineAcpAuthMethodSummarySchema).optional(),
12908
+ authMethods: array$2(MachineAcpAuthMethodSummarySchema).max(ACP_AUTH_METHOD_MAX_COUNT).optional(),
12786
12909
  error: string$1().optional()
12787
12910
  }).strict();
12788
12911
  const MachineAcpAuthenticationProgressMessageSchema = object$1({
@@ -12792,23 +12915,34 @@ Requirements:
12792
12915
  agentType: string$1().trim().min(1),
12793
12916
  status: _enum$1([
12794
12917
  "starting",
12918
+ "auth-methods",
12795
12919
  "authorization",
12920
+ "input-required",
12796
12921
  "output",
12797
12922
  "authenticated",
12798
12923
  "cancelled",
12799
12924
  "error"
12800
12925
  ]),
12801
- authorizationUrl: string$1().url().max(8192).optional(),
12926
+ authMethods: array$2(MachineAcpAuthMethodSummarySchema).max(ACP_AUTH_METHOD_MAX_COUNT).optional(),
12927
+ interactionId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH).optional(),
12928
+ message: string$1().max(ACP_AUTH_TEXT_MAX_LENGTH).optional(),
12929
+ form: MachineAcpAuthenticationFormSchema.optional(),
12930
+ authorizationUrl: string$1().url().max(ACP_AUTHORIZATION_URL_MAX_LENGTH).refine((value) => {
12931
+ const protocol = new URL(value).protocol;
12932
+ return protocol === "https:" || protocol === "http:";
12933
+ }, "authorizationUrl must use http or https").optional(),
12802
12934
  userCode: string$1().trim().min(1).max(128).optional(),
12803
12935
  acceptsAuthorizationCode: boolean().optional(),
12804
12936
  authorizationCodePublicKey: RpcSecretPublicKeySchema.optional(),
12937
+ authenticationInputPublicKey: RpcSecretPublicKeySchema.optional(),
12938
+ requiresAuthorizationConsent: boolean().optional(),
12805
12939
  expiresInSeconds: number$4().int().positive().optional(),
12806
12940
  stream: _enum$1([
12807
12941
  "stdout",
12808
12942
  "stderr"
12809
12943
  ]).optional(),
12810
- output: string$1().optional(),
12811
- error: string$1().optional()
12944
+ output: string$1().max(16384).optional(),
12945
+ error: string$1().max(65536).optional()
12812
12946
  }).strict().superRefine((value, context2) => {
12813
12947
  if (value.status === "authorization" && !value.authorizationUrl) {
12814
12948
  context2.addIssue({
@@ -12819,6 +12953,33 @@ Requirements:
12819
12953
  message: "authorizationUrl is required for authorization progress"
12820
12954
  });
12821
12955
  }
12956
+ if (value.status === "auth-methods" && (!value.interactionId || !value.authMethods?.length || value.authMethods.some((method) => !method.id || method.type !== "agent") || new Set(value.authMethods.map((method) => method.id)).size !== value.authMethods.length)) {
12957
+ context2.addIssue({
12958
+ code: "custom",
12959
+ path: [
12960
+ "authMethods"
12961
+ ],
12962
+ message: "auth-methods progress requires an interaction and methods with ids"
12963
+ });
12964
+ }
12965
+ if (value.status === "input-required" && (!value.interactionId || !value.form)) {
12966
+ context2.addIssue({
12967
+ code: "custom",
12968
+ path: [
12969
+ "form"
12970
+ ],
12971
+ message: "input-required progress requires an interaction and form"
12972
+ });
12973
+ }
12974
+ if (value.status === "authorization" && value.requiresAuthorizationConsent && !value.interactionId) {
12975
+ context2.addIssue({
12976
+ code: "custom",
12977
+ path: [
12978
+ "interactionId"
12979
+ ],
12980
+ message: "URL consent requires an interaction id"
12981
+ });
12982
+ }
12822
12983
  });
12823
12984
  const MachineAcpBinaryStatusRequestSchema = object$1({
12824
12985
  type: literal$1("machine/acp-binary-status"),
@@ -18437,6 +18598,13 @@ ${outputTail}` : blockTail.output;
18437
18598
  "~/.cursor/skills"
18438
18599
  ]),
18439
18600
  deepagents: skillDirs([], []),
18601
+ deepseek: skillDirs([
18602
+ DEFAULT_PROJECT_SKILL_DIR,
18603
+ ".dsh/skills"
18604
+ ], [
18605
+ "~/.dsh/skills",
18606
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18607
+ ]),
18440
18608
  devin: skillDirs([
18441
18609
  ".devin/skills",
18442
18610
  ".windsurf/skills"
@@ -18520,6 +18688,17 @@ ${outputTail}` : blockTail.output;
18520
18688
  "~/.config/goose/skills",
18521
18689
  DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18522
18690
  ]),
18691
+ grok: skillDirs([
18692
+ DEFAULT_PROJECT_SKILL_DIR,
18693
+ ".grok/skills",
18694
+ CLAUDE_PROJECT_SKILL_DIR,
18695
+ ".cursor/skills"
18696
+ ], [
18697
+ "~/.grok/skills",
18698
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR,
18699
+ CLAUDE_GLOBAL_SKILL_DIR,
18700
+ "~/.cursor/skills"
18701
+ ]),
18523
18702
  "hermes-agent": skillDirs([
18524
18703
  ".hermes/skills"
18525
18704
  ], [
@@ -18578,16 +18757,25 @@ ${outputTail}` : blockTail.output;
18578
18757
  ]),
18579
18758
  kimi: skillDirs([
18580
18759
  DEFAULT_PROJECT_SKILL_DIR,
18581
- ".kimi/skills"
18582
- ], []),
18760
+ ".kimi-code/skills"
18761
+ ], [
18762
+ "~/.kimi-code/skills",
18763
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18764
+ ]),
18583
18765
  "kimi-code": skillDirs([
18584
18766
  DEFAULT_PROJECT_SKILL_DIR,
18585
- ".kimi/skills"
18586
- ], []),
18767
+ ".kimi-code/skills"
18768
+ ], [
18769
+ "~/.kimi-code/skills",
18770
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18771
+ ]),
18587
18772
  "kimi-code-cli": skillDirs([
18588
18773
  DEFAULT_PROJECT_SKILL_DIR,
18589
- ".kimi/skills"
18590
- ], []),
18774
+ ".kimi-code/skills"
18775
+ ], [
18776
+ "~/.kimi-code/skills",
18777
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18778
+ ]),
18591
18779
  kode: skillDirs([
18592
18780
  ".kode/skills"
18593
18781
  ], [
@@ -18657,13 +18845,15 @@ ${outputTail}` : blockTail.output;
18657
18845
  DEFAULT_PROJECT_SKILL_DIR,
18658
18846
  ".pi/skills"
18659
18847
  ], [
18660
- "~/.pi/agent/skills"
18848
+ "~/.pi/agent/skills",
18849
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18661
18850
  ]),
18662
18851
  "pi-acp": skillDirs([
18663
18852
  DEFAULT_PROJECT_SKILL_DIR,
18664
18853
  ".pi/skills"
18665
18854
  ], [
18666
- "~/.pi/agent/skills"
18855
+ "~/.pi/agent/skills",
18856
+ DEFAULT_AGENTS_GLOBAL_SKILL_DIR
18667
18857
  ]),
18668
18858
  pochi: skillDirs([
18669
18859
  ".pochi/skills"
@@ -20686,14 +20876,17 @@ ${tailedOutput}` : null;
20686
20876
  return parsed;
20687
20877
  };
20688
20878
  const MACHINE_PROTOCOL_CAPABILITIES = {
20879
+ acpAuthenticationInteractions: "acpAuthenticationInteractions",
20689
20880
  localProjectRemoval: "localProjectRemoval",
20690
20881
  providerSetup: "providerSetup",
20691
20882
  acpProtocolAuthentication: "acpProtocolAuthentication"
20692
20883
  };
20884
+ const ACP_AUTHENTICATION_INTERACTIONS_PROTOCOL_VERSION = 2;
20693
20885
  const LOCAL_PROJECT_REMOVAL_PROTOCOL_VERSION = 1;
20694
20886
  const PROVIDER_SETUP_PROTOCOL_VERSION = 1;
20695
- const ACP_PROTOCOL_AUTHENTICATION_VERSION = 1;
20887
+ const ACP_PROTOCOL_AUTHENTICATION_VERSION = 2;
20696
20888
  const CURRENT_MACHINE_PROTOCOL_CAPABILITIES = {
20889
+ [MACHINE_PROTOCOL_CAPABILITIES.acpAuthenticationInteractions]: ACP_AUTHENTICATION_INTERACTIONS_PROTOCOL_VERSION,
20697
20890
  [MACHINE_PROTOCOL_CAPABILITIES.localProjectRemoval]: LOCAL_PROJECT_REMOVAL_PROTOCOL_VERSION,
20698
20891
  [MACHINE_PROTOCOL_CAPABILITIES.providerSetup]: PROVIDER_SETUP_PROTOCOL_VERSION,
20699
20892
  [MACHINE_PROTOCOL_CAPABILITIES.acpProtocolAuthentication]: ACP_PROTOCOL_AUTHENTICATION_VERSION
@@ -20714,6 +20907,29 @@ ${tailedOutput}` : null;
20714
20907
  }
20715
20908
  return false;
20716
20909
  };
20910
+ const collectSessionConversationSources = (history, messageQueue = []) => {
20911
+ const sources = [];
20912
+ for (let index = messageQueue.length - 1; index >= 0; index -= 1) {
20913
+ const item = messageQueue[index];
20914
+ const itemId = typeof item?.$cid === "string" ? item.$cid : String(index);
20915
+ const userTurnId = typeof item?.userTurnId === "string" && item.userTurnId.trim() ? item.userTurnId.trim() : null;
20916
+ sources.push({
20917
+ value: item?.acpSessionConfig,
20918
+ configKey: `queue:${itemId}`,
20919
+ turnKey: `turn:${userTurnId ?? `queued-${itemId}`}`
20920
+ });
20921
+ }
20922
+ for (let index = history.length - 1; index >= 0; index -= 1) {
20923
+ const entry = history[index];
20924
+ if (entry?.role !== "user") continue;
20925
+ sources.push({
20926
+ value: entry.inputConfig,
20927
+ configKey: `history:${entry.id}`,
20928
+ turnKey: `turn:${entry.id}`
20929
+ });
20930
+ }
20931
+ return sources;
20932
+ };
20717
20933
  const resolveSessionConversationConfig = (history, messageQueue = []) => {
20718
20934
  const resolveConfig = (value, sourceConfigKey) => {
20719
20935
  const inputConfig = normalizeSessionTurnInputConfig(value);
@@ -20736,23 +20952,32 @@ ${tailedOutput}` : null;
20736
20952
  } : {},
20737
20953
  ...typeof inputConfig.taskToolsEnabled === "boolean" ? {
20738
20954
  taskToolsEnabled: inputConfig.taskToolsEnabled
20955
+ } : {},
20956
+ ...inputConfig.agentRoleId !== void 0 ? {
20957
+ agentRoleId: inputConfig.agentRoleId
20958
+ } : {},
20959
+ ...typeof inputConfig.agentRoleId === "string" && inputConfig.agentRoleRevision !== void 0 ? {
20960
+ agentRoleRevision: inputConfig.agentRoleRevision
20739
20961
  } : {}
20740
20962
  };
20741
20963
  };
20742
- const latestQueuedIndex = messageQueue.length - 1;
20743
- if (latestQueuedIndex >= 0) {
20744
- const item = messageQueue[latestQueuedIndex];
20745
- const itemId = typeof item?.$cid === "string" ? item.$cid : String(latestQueuedIndex);
20746
- return resolveConfig(item?.acpSessionConfig, `queue:${itemId}`) ?? {};
20747
- }
20748
- for (let index = history.length - 1; index >= 0; index -= 1) {
20749
- const entry = history[index];
20750
- if (entry?.role !== "user") {
20751
- continue;
20752
- }
20753
- return resolveConfig(entry.inputConfig, `history:${entry.id}`) ?? {};
20964
+ const sources = collectSessionConversationSources(history, messageQueue);
20965
+ const latest2 = sources[0];
20966
+ if (!latest2) return {};
20967
+ const resolved = resolveConfig(latest2.value, latest2.configKey) ?? {};
20968
+ if (resolved.agentRoleId !== void 0) return resolved;
20969
+ for (const source of sources.slice(1)) {
20970
+ const older = normalizeSessionTurnInputConfig(source.value);
20971
+ if (!older || older.agentRoleId === void 0) continue;
20972
+ return {
20973
+ ...resolved,
20974
+ agentRoleId: older.agentRoleId,
20975
+ ...older.agentRoleId !== null && older.agentRoleRevision !== void 0 ? {
20976
+ agentRoleRevision: older.agentRoleRevision
20977
+ } : {}
20978
+ };
20754
20979
  }
20755
- return {};
20980
+ return resolved;
20756
20981
  };
20757
20982
  const resolveSessionMcpSelection = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).mcpServerIds ?? [];
20758
20983
  const resolveSessionTaskToolsEnabled = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).taskToolsEnabled === true;
@@ -21000,6 +21225,12 @@ ${tailedOutput}` : null;
21000
21225
  ...args2.taskToolsEnabled !== void 0 ? {
21001
21226
  taskToolsEnabled: args2.taskToolsEnabled === true
21002
21227
  } : {},
21228
+ ...args2.agentRoleId !== void 0 ? {
21229
+ agentRoleId: args2.agentRoleId
21230
+ } : {},
21231
+ ...typeof args2.agentRoleId === "string" && args2.agentRoleRevision !== void 0 ? {
21232
+ agentRoleRevision: args2.agentRoleRevision
21233
+ } : {},
21003
21234
  issuePRMentions: args2.issuePRMentions,
21004
21235
  resume: args2.resume
21005
21236
  };
@@ -23115,28 +23346,35 @@ ${context2.authorReply.trim()}
23115
23346
  ...right2
23116
23347
  ];
23117
23348
  };
23118
- const classifyIpv4 = ([first2, second, third, fourth]) => {
23349
+ const isBenchmarkingIpv4 = ([first2, second]) => first2 === 198 && (second === 18 || second === 19);
23350
+ const classifyIpv4 = (octets) => {
23351
+ const [first2, second, third, fourth] = octets;
23119
23352
  if (first2 === 127) return "loopback";
23120
23353
  if (first2 === 10 || first2 === 172 && second >= 16 && second <= 31) return "private-lan";
23121
23354
  if (first2 === 192 && second === 168) return "private-lan";
23122
- const prohibited = first2 === 0 || first2 >= 224 || first2 === 100 && second >= 64 && second <= 127 || first2 === 169 && second === 254 || first2 === 192 && second === 0 && third === 0 || first2 === 192 && second === 0 && third === 2 || first2 === 198 && (second === 18 || second === 19) || first2 === 198 && second === 51 && third === 100 || first2 === 203 && second === 0 && third === 113 || first2 === 255 && second === 255 && third === 255 && fourth === 255;
23355
+ const prohibited = first2 === 0 || first2 >= 224 || first2 === 100 && second >= 64 && second <= 127 || first2 === 169 && second === 254 || first2 === 192 && second === 0 && third === 0 || first2 === 192 && second === 0 && third === 2 || isBenchmarkingIpv4(octets) || first2 === 198 && second === 51 && third === 100 || first2 === 203 && second === 0 && third === 113 || first2 === 255 && second === 255 && third === 255 && fourth === 255;
23123
23356
  return prohibited ? "prohibited" : "public";
23124
23357
  };
23358
+ const mappedIpv4 = (segments) => {
23359
+ if (!segments.slice(0, 5).every((segment) => segment === 0) || segments[5] !== 65535) {
23360
+ return null;
23361
+ }
23362
+ const high = segments[6] ?? 0;
23363
+ const low = segments[7] ?? 0;
23364
+ return [
23365
+ high >> 8,
23366
+ high & 255,
23367
+ low >> 8,
23368
+ low & 255
23369
+ ];
23370
+ };
23125
23371
  const classifyIpv6 = (segments) => {
23126
23372
  if (segments.every((segment) => segment === 0)) return "prohibited";
23127
23373
  if (segments.slice(0, 7).every((segment) => segment === 0) && segments[7] === 1) {
23128
23374
  return "loopback";
23129
23375
  }
23130
- if (segments.slice(0, 5).every((segment) => segment === 0) && segments[5] === 65535) {
23131
- const high = segments[6] ?? 0;
23132
- const low = segments[7] ?? 0;
23133
- return classifyIpv4([
23134
- high >> 8,
23135
- high & 255,
23136
- low >> 8,
23137
- low & 255
23138
- ]);
23139
- }
23376
+ const mapped = mappedIpv4(segments);
23377
+ if (mapped) return classifyIpv4(mapped);
23140
23378
  const first2 = segments[0] ?? 0;
23141
23379
  if ((first2 & 65024) === 64512) return "private-lan";
23142
23380
  if ((first2 & 65472) === 65152 || (first2 & 65280) === 65280) return "prohibited";
@@ -23870,7 +24108,7 @@ ${context2.authorReply.trim()}
23870
24108
  }
23871
24109
  case "agentConfig": {
23872
24110
  const config2 = normalizeAgentConfigMeta$1(value);
23873
- return config2 ? {
24111
+ return config2 && config2.id === parsedKey.agentConfigId ? {
23874
24112
  key: parsedKey.key,
23875
24113
  value: config2
23876
24114
  } : void 0;
@@ -26407,7 +26645,7 @@ ${context2.authorReply.trim()}
26407
26645
  if (hasRequiredCommand$1) return command$1;
26408
26646
  hasRequiredCommand$1 = 1;
26409
26647
  const EventEmitter2 = require$$0$4.EventEmitter;
26410
- const childProcess = Gx__default;
26648
+ const childProcess = Tw__default;
26411
26649
  const path2 = path__default;
26412
26650
  const fs2 = fs__default$1;
26413
26651
  const process2 = process$2;
@@ -31349,7 +31587,7 @@ ${originalIndentation}`;
31349
31587
  function requireStream$3() {
31350
31588
  if (hasRequiredStream$3) return stream$3;
31351
31589
  hasRequiredStream$3 = 1;
31352
- stream$3 = So;
31590
+ stream$3 = xo;
31353
31591
  return stream$3;
31354
31592
  }
31355
31593
  var destroy_1;
@@ -34940,7 +35178,7 @@ ${originalIndentation}`;
34940
35178
  if (hasRequiredReadable$1) return readable$1.exports;
34941
35179
  hasRequiredReadable$1 = 1;
34942
35180
  (function(module2, exports$1) {
34943
- var Stream = So;
35181
+ var Stream = xo;
34944
35182
  if (process.env.READABLE_STREAM === "disable" && Stream) {
34945
35183
  module2.exports = Stream.Readable;
34946
35184
  Object.assign(module2.exports, Stream);
@@ -37846,7 +38084,7 @@ ${originalIndentation}`;
37846
38084
  const fs2 = fs__default;
37847
38085
  const path2 = path__default$1;
37848
38086
  const asyncSeries = requireSeries();
37849
- const zlib = Ei__default;
38087
+ const zlib = Ri__default;
37850
38088
  const { MESSAGE } = requireTripleBeam();
37851
38089
  const { Stream, PassThrough: PassThrough2 } = requireReadable$1();
37852
38090
  const TransportStream = requireWinstonTransport();
@@ -44783,10 +45021,10 @@ ${originalIndentation}`;
44783
45021
  const os2 = os__default$1;
44784
45022
  const path2 = path__default$1;
44785
45023
  const util2 = require$$0$5;
44786
- const zlib = Ei__default;
45024
+ const zlib = Ri__default;
44787
45025
  const hash2 = requireObjectHash();
44788
45026
  const MESSAGE = requireTripleBeam().MESSAGE;
44789
- const PassThrough2 = So.PassThrough;
45027
+ const PassThrough2 = xo.PassThrough;
44790
45028
  const Transport = requireWinstonTransport();
44791
45029
  const loggerDefaults = {
44792
45030
  json: false,
@@ -45238,7 +45476,7 @@ ${value.slice(value.length - safeTailChars)}`;
45238
45476
  return files;
45239
45477
  }
45240
45478
  async function readDailyLogFile(file2) {
45241
- const raw2 = await Yt__default.readFile(file2.path);
45479
+ const raw2 = await Xt__default.readFile(file2.path);
45242
45480
  if (!file2.compressed) return raw2.toString("utf8");
45243
45481
  return (await gunzip(raw2)).toString("utf8");
45244
45482
  }
@@ -50156,7 +50394,7 @@ ${fromBody}`;
50156
50394
  function isRecord$6(value) {
50157
50395
  return typeof value === "object" && value !== null && !Array.isArray(value);
50158
50396
  }
50159
- function asRecord$1(value) {
50397
+ function asRecord$2(value) {
50160
50398
  return isRecord$6(value) ? value : null;
50161
50399
  }
50162
50400
  function readSessionUserFromResponse(response2) {
@@ -50169,7 +50407,7 @@ ${fromBody}`;
50169
50407
  return nested;
50170
50408
  }
50171
50409
  }
50172
- const user = asRecord$1(response2.user);
50410
+ const user = asRecord$2(response2.user);
50173
50411
  const parsed = SessionUserSchema.safeParse(user);
50174
50412
  if (!parsed.success) {
50175
50413
  return null;
@@ -65153,7 +65391,7 @@ ${peerId}`;
65153
65391
  function requirePermessageDeflate$1() {
65154
65392
  if (hasRequiredPermessageDeflate$1) return permessageDeflate$1;
65155
65393
  hasRequiredPermessageDeflate$1 = 1;
65156
- const zlib = Ei__default;
65394
+ const zlib = Ri__default;
65157
65395
  const bufferUtil2 = requireBufferUtil();
65158
65396
  const Limiter = requireLimiter();
65159
65397
  const { kStatusCode } = requireConstants$5();
@@ -65608,7 +65846,7 @@ ${peerId}`;
65608
65846
  function requireReceiver$1() {
65609
65847
  if (hasRequiredReceiver$1) return receiver$1;
65610
65848
  hasRequiredReceiver$1 = 1;
65611
- const { Writable } = So;
65849
+ const { Writable } = xo;
65612
65850
  const PerMessageDeflate = requirePermessageDeflate$1();
65613
65851
  const { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = requireConstants$5();
65614
65852
  const { concat: concat2, toArrayBuffer: toArrayBuffer2, unmask } = requireBufferUtil();
@@ -65975,7 +66213,7 @@ ${peerId}`;
65975
66213
  function requireSender$1() {
65976
66214
  if (hasRequiredSender$1) return sender$1;
65977
66215
  hasRequiredSender$1 = 1;
65978
- const { Duplex } = So;
66216
+ const { Duplex } = xo;
65979
66217
  const { randomFillSync: randomFillSync2 } = crypto__default;
65980
66218
  const PerMessageDeflate = requirePermessageDeflate$1();
65981
66219
  const { EMPTY_BUFFER, kWebSocket, NOOP } = requireConstants$5();
@@ -66712,7 +66950,7 @@ ${peerId}`;
66712
66950
  const net2 = require$$0$9;
66713
66951
  const tls = require$$4$2;
66714
66952
  const { randomBytes: randomBytes2, createHash: createHash2 } = crypto__default;
66715
- const { Duplex, Readable: Readable2 } = So;
66953
+ const { Duplex, Readable: Readable2 } = xo;
66716
66954
  const { URL: URL2 } = require$$7$2;
66717
66955
  const PerMessageDeflate = requirePermessageDeflate$1();
66718
66956
  const Receiver = requireReceiver$1();
@@ -67450,7 +67688,7 @@ ${peerId}`;
67450
67688
  if (hasRequiredStream$1) return stream$1;
67451
67689
  hasRequiredStream$1 = 1;
67452
67690
  requireWebsocket$1();
67453
- const { Duplex } = So;
67691
+ const { Duplex } = xo;
67454
67692
  function emitClose(stream2) {
67455
67693
  stream2.emit("close");
67456
67694
  }
@@ -67601,7 +67839,7 @@ ${peerId}`;
67601
67839
  hasRequiredWebsocketServer = 1;
67602
67840
  const EventEmitter2 = require$$0$7;
67603
67841
  const http$12 = http;
67604
- const { Duplex } = So;
67842
+ const { Duplex } = xo;
67605
67843
  const { createHash: createHash2 } = crypto__default;
67606
67844
  const extension2 = requireExtension();
67607
67845
  const PerMessageDeflate = requirePermessageDeflate$1();
@@ -101628,15 +101866,15 @@ ${value}`;
101628
101866
  }
101629
101867
  undiciDiagnosticsInstalled = true;
101630
101868
  channel("undici:client:connected").subscribe((message) => {
101631
- const record2 = asRecord(message);
101632
- const socket = asRecord(record2?.socket);
101633
- const connectParams = asRecord(record2?.connectParams);
101869
+ const record2 = asRecord$1(message);
101870
+ const socket = asRecord$1(record2?.socket);
101871
+ const connectParams = asRecord$1(record2?.connectParams);
101634
101872
  const alpn = readString(socket, "alpnProtocol") ?? "unknown";
101635
101873
  const origin = readString(connectParams, "origin") ?? readString(connectParams, "host") ?? readString(connectParams, "hostname") ?? "unknown";
101636
101874
  logger2.debug(`[http-transport] undici connected origin=${sanitizeUrlForLogging(origin)} alpn=${alpn}`);
101637
101875
  });
101638
101876
  channel("undici:proxy:connected").subscribe((message) => {
101639
- const record2 = asRecord(message);
101877
+ const record2 = asRecord$1(message);
101640
101878
  const proxy = readString(record2, "proxy") ?? readString(record2, "origin") ?? "configured";
101641
101879
  logger2.debug(`[http-transport] undici proxy connected proxy=${sanitizeUrlForLogging(proxy)}`);
101642
101880
  });
@@ -101672,7 +101910,7 @@ ${value}`;
101672
101910
  const parsed = Number.parseInt(value, 10);
101673
101911
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback2;
101674
101912
  }
101675
- function asRecord(value) {
101913
+ function asRecord$1(value) {
101676
101914
  return typeof value === "object" && value !== null ? value : null;
101677
101915
  }
101678
101916
  function readString(record2, key2) {
@@ -101931,7 +102169,7 @@ ${value}`;
101931
102169
  return "internal";
101932
102170
  }
101933
102171
  }
101934
- async function withDeadline$1(operation, options) {
102172
+ async function withDeadline(operation, options) {
101935
102173
  const { timeoutMs, signal } = options;
101936
102174
  if (timeoutMs === void 0 && !signal) return operation;
101937
102175
  if (signal?.aborted) options.onAbort();
@@ -102263,7 +102501,7 @@ ${value}`;
102263
102501
  });
102264
102502
  }
102265
102503
  awaitWithDeadline(operation, options, ctx) {
102266
- return withDeadline$1(operation, {
102504
+ return withDeadline(operation, {
102267
102505
  timeoutMs: options?.timeout,
102268
102506
  signal: options?.signal,
102269
102507
  onTimeout: () => {
@@ -103718,6 +103956,21 @@ ${value}`;
103718
103956
  ...entry,
103719
103957
  inputConfig: normalizeSessionTurnInputConfig(entry.inputConfig)
103720
103958
  });
103959
+ const isValidDaemonLaunchConfig = (config2, expectedConfigId, expectedMachineId) => {
103960
+ if (config2.id !== expectedConfigId || config2.machineId !== expectedMachineId || typeof config2.agentType !== "string" || config2.agentType.trim().length === 0 || typeof config2.env !== "object" || config2.env === null || Array.isArray(config2.env) || Object.values(config2.env).some((value) => typeof value !== "string")) {
103961
+ return false;
103962
+ }
103963
+ if (config2.cliType === "custom") {
103964
+ return CustomAcpLaunchSpecSchema.safeParse(config2.customAcp).success && config2.runtimeOverrides === void 0;
103965
+ }
103966
+ if (config2.cliType === "registry") {
103967
+ return config2.customAcp === void 0 && config2.runtimeOverrides === void 0;
103968
+ }
103969
+ if (config2.cliType === "builtin") {
103970
+ return config2.customAcp === void 0 && (config2.runtimeOverrides === void 0 || BuiltinRuntimeOverridesSchema.safeParse(config2.runtimeOverrides).success);
103971
+ }
103972
+ return false;
103973
+ };
103721
103974
  const localLoroDataPlaneScheduler = createLocalLoroDataPlaneScheduler((work) => {
103722
103975
  const handle = setImmediate(work);
103723
103976
  return () => clearImmediate(handle);
@@ -104460,6 +104713,24 @@ ${value}`;
104460
104713
  const configs = await listMergedAgentConfigs(this.repo, this.workspaceId);
104461
104714
  return configs.find((config2) => config2.id === agentConfigId) ?? null;
104462
104715
  }
104716
+ async getAgentConfigForMachineLaunch(agentConfigId, machineId) {
104717
+ const config2 = await this.getAgentConfigById(agentConfigId, machineId);
104718
+ if (config2) {
104719
+ return isValidDaemonLaunchConfig(config2, agentConfigId, machineId) ? config2 : null;
104720
+ }
104721
+ const handle = await this.repo.openFlockDoc(getMachineFlockDocId(this.workspaceId, machineId));
104722
+ const rows = readMachineFlockRowsFromFlock(handle.flock, {
104723
+ prefixes: [
104724
+ machineFlockKeys.providerSetup(agentConfigId),
104725
+ machineFlockKeys.providerSetupCancellation(agentConfigId)
104726
+ ]
104727
+ });
104728
+ if (getMachineFlockProviderSetupCancellations(rows)[agentConfigId]) {
104729
+ return null;
104730
+ }
104731
+ const setup = getMachineFlockProviderSetups(rows)[agentConfigId];
104732
+ return setup?.machineId === machineId && isValidDaemonLaunchConfig(setup.config, agentConfigId, machineId) ? setup.config : null;
104733
+ }
104463
104734
  async createAgentConfig(cliType, agentType, machineId, name2) {
104464
104735
  const agentConfigId = v4();
104465
104736
  await upsertMachineAgentConfig(this.repo, this.workspaceId, {
@@ -105886,6 +106157,7 @@ ${value}`;
105886
106157
  return pair;
105887
106158
  };
105888
106159
  const getMachineAcpAuthorizationCodeSecretContext = (options) => `machine/acp-authenticate\0${options.workspaceId}\0${options.machineId}\0${options.authenticationRequestId}`;
106160
+ const getMachineAcpAuthenticationInputSecretContext = (options) => `machine/acp-authenticate-input\0${options.workspaceId}\0${options.machineId}\0${options.authenticationRequestId}\0${options.interactionId}`;
105889
106161
  const createRpcSecretRecipient = async () => {
105890
106162
  const pair = await createKeyPair();
105891
106163
  const keyIdBytes = new Uint8Array(16);
@@ -106035,12 +106307,7 @@ ${value}`;
106035
106307
  const LoroMachineAcpCapabilitiesRefreshRpcRequestSchema = BaseRpcRequestSchema.extend({
106036
106308
  method: literal$1("machine/acp-capabilities-refresh"),
106037
106309
  params: object$1({
106038
- configId: AgentConfigIdSchema,
106039
- cliType: AgentConfigCliTypeSchema,
106040
- agentType: string$1().trim().min(1),
106041
- customAcp: CustomAcpLaunchSpecSchema.optional(),
106042
- runtimeOverrides: BuiltinRuntimeOverridesSchema.optional(),
106043
- env: record$1(string$1(), string$1()).optional()
106310
+ configId: AgentConfigIdSchema
106044
106311
  }).strict()
106045
106312
  }).strict();
106046
106313
  const LoroMachineAcpCapabilitiesRefreshCancelRpcRequestSchema = BaseRpcRequestSchema.extend({
@@ -106051,37 +106318,31 @@ ${value}`;
106051
106318
  }).strict();
106052
106319
  const LoroMachineAcpAuthenticateRpcRequestSchema = BaseRpcRequestSchema.extend({
106053
106320
  method: literal$1("machine/acp-authenticate"),
106054
- params: object$1({
106055
- requestId: string$1().trim().min(1),
106056
- action: _enum$1([
106057
- "start",
106058
- "cancel",
106059
- "submit-code"
106060
- ]),
106061
- authenticationRequestId: string$1().trim().min(1).optional(),
106062
- authorizationCodeEnvelope: RpcSecretEnvelopeSchema.optional(),
106063
- methodId: string$1().trim().min(1).max(256).optional(),
106064
- configId: AgentConfigIdSchema.optional(),
106065
- cliType: AgentConfigCliTypeSchema,
106066
- agentType: string$1().trim().min(1),
106067
- customAcp: CustomAcpLaunchSpecSchema.optional(),
106068
- runtimeOverrides: BuiltinRuntimeOverridesSchema.optional(),
106069
- env: record$1(string$1(), string$1()).optional()
106070
- }).strict().superRefine((value, context2) => {
106071
- if (value.action === "submit-code") {
106072
- if (!value.authenticationRequestId || !value.authorizationCodeEnvelope) {
106073
- context2.addIssue({
106074
- code: "custom",
106075
- message: "submit-code requires an authentication request and authorization code"
106076
- });
106077
- }
106078
- } else if (value.authenticationRequestId || value.authorizationCodeEnvelope) {
106079
- context2.addIssue({
106080
- code: "custom",
106081
- message: "Authorization-code fields are only valid for submit-code"
106082
- });
106083
- }
106084
- })
106321
+ params: discriminatedUnion("action", [
106322
+ object$1({
106323
+ requestId: string$1().trim().min(1).max(1024),
106324
+ action: literal$1("start"),
106325
+ configId: AgentConfigIdSchema
106326
+ }).strict(),
106327
+ object$1({
106328
+ requestId: string$1().trim().min(1).max(1024),
106329
+ action: literal$1("cancel"),
106330
+ authenticationRequestId: string$1().trim().min(1).max(1024)
106331
+ }).strict(),
106332
+ object$1({
106333
+ requestId: string$1().trim().min(1).max(1024),
106334
+ action: literal$1("submit-code"),
106335
+ authenticationRequestId: string$1().trim().min(1).max(1024),
106336
+ authorizationCodeEnvelope: RpcSecretEnvelopeSchema
106337
+ }).strict(),
106338
+ object$1({
106339
+ requestId: string$1().trim().min(1).max(1024),
106340
+ action: literal$1("submit-input"),
106341
+ authenticationRequestId: string$1().trim().min(1).max(1024),
106342
+ interactionId: string$1().trim().min(1).max(1024),
106343
+ authenticationInputEnvelope: RpcSecretEnvelopeSchema
106344
+ }).strict()
106345
+ ])
106085
106346
  }).strict();
106086
106347
  const LoroMachineAcpBinaryStatusRpcRequestSchema = BaseRpcRequestSchema.extend({
106087
106348
  method: literal$1("machine/acp-binary-status"),
@@ -107393,18 +107654,14 @@ ${value}`;
107393
107654
  onAcpBinaryProgress: options.onProgress,
107394
107655
  signal: options.signal,
107395
107656
  params: {
107396
- configId: options.configId,
107397
- cliType: options.cliType,
107398
- agentType: options.agentType,
107399
- customAcp: options.customAcp,
107400
- runtimeOverrides: options.runtimeOverrides,
107401
- env: options.env
107657
+ configId: options.configId
107402
107658
  }
107403
107659
  });
107404
107660
  }
107405
107661
  async requestMachineAcpAuthenticate(options) {
107406
- const authenticationRequestId = options.authenticationRequestId;
107662
+ const authenticationRequestId = options.action === "start" ? void 0 : options.authenticationRequestId;
107407
107663
  let authorizationCodeEnvelope;
107664
+ let authenticationInputEnvelope;
107408
107665
  if (options.action === "submit-code") {
107409
107666
  if (!authenticationRequestId || !options.authorizationCode?.trim() || options.authorizationCode.length > 4096) {
107410
107667
  throw new Error("Submitting an authorization code requires an authentication request.");
@@ -107419,36 +107676,79 @@ ${value}`;
107419
107676
  authenticationRequestId
107420
107677
  }));
107421
107678
  }
107679
+ if (options.action === "submit-input") {
107680
+ if (!authenticationRequestId || !options.interactionId || !options.authenticationInput || options.authenticationInput.length > 65536) {
107681
+ throw new Error("Submitting authentication input requires an active interaction.");
107682
+ }
107683
+ const publicKey = this.acpAuthorizationCodePublicKeys.get(authenticationRequestId);
107684
+ if (!publicKey) {
107685
+ throw new Error("The target machine did not provide an authentication-input key.");
107686
+ }
107687
+ authenticationInputEnvelope = await encryptRpcSecret(publicKey, options.authenticationInput, getMachineAcpAuthenticationInputSecretContext({
107688
+ workspaceId: this.options.workspaceId,
107689
+ machineId: this.options.machineId,
107690
+ authenticationRequestId,
107691
+ interactionId: options.interactionId
107692
+ }));
107693
+ }
107422
107694
  const onProgress = (progress) => {
107423
- if (progress.authorizationCodePublicKey) {
107424
- this.acpAuthorizationCodePublicKeys.set(progress.requestId, progress.authorizationCodePublicKey);
107695
+ const inputPublicKey = progress.authenticationInputPublicKey ?? progress.authorizationCodePublicKey;
107696
+ if (inputPublicKey) {
107697
+ this.acpAuthorizationCodePublicKeys.set(progress.requestId, inputPublicKey);
107425
107698
  }
107426
107699
  options.onProgress?.(progress);
107427
107700
  };
107428
107701
  try {
107702
+ const params = (() => {
107703
+ switch (options.action) {
107704
+ case "start":
107705
+ return {
107706
+ requestId: options.requestId,
107707
+ action: options.action,
107708
+ configId: options.configId
107709
+ };
107710
+ case "cancel":
107711
+ return {
107712
+ requestId: options.requestId,
107713
+ action: options.action,
107714
+ authenticationRequestId: options.authenticationRequestId
107715
+ };
107716
+ case "submit-code":
107717
+ if (!authorizationCodeEnvelope) {
107718
+ throw new Error("Authorization-code encryption did not produce an envelope.");
107719
+ }
107720
+ return {
107721
+ requestId: options.requestId,
107722
+ action: options.action,
107723
+ authenticationRequestId: options.authenticationRequestId,
107724
+ authorizationCodeEnvelope
107725
+ };
107726
+ case "submit-input":
107727
+ if (!authenticationInputEnvelope) {
107728
+ throw new Error("Authentication-input encryption did not produce an envelope.");
107729
+ }
107730
+ return {
107731
+ requestId: options.requestId,
107732
+ action: options.action,
107733
+ authenticationRequestId: options.authenticationRequestId,
107734
+ interactionId: options.interactionId,
107735
+ authenticationInputEnvelope
107736
+ };
107737
+ default:
107738
+ throw new Error("Unsupported ACP authentication action.");
107739
+ }
107740
+ })();
107429
107741
  return await this.sendRequest({
107430
107742
  method: "machine/acp-authenticate",
107431
107743
  timeoutMs: options.timeoutMs ?? 3e5,
107432
107744
  onAcpAuthenticationProgress: onProgress,
107433
- params: {
107434
- requestId: options.requestId,
107435
- action: options.action,
107436
- authenticationRequestId,
107437
- authorizationCodeEnvelope,
107438
- ...options.methodId ? {
107439
- methodId: options.methodId
107440
- } : {},
107441
- configId: options.configId,
107442
- cliType: options.cliType,
107443
- agentType: options.agentType,
107444
- customAcp: options.customAcp,
107445
- runtimeOverrides: options.runtimeOverrides,
107446
- env: options.env
107447
- }
107745
+ params
107448
107746
  });
107449
107747
  } finally {
107450
- if (options.action === "start" || options.action === "cancel") {
107748
+ if (options.action === "start") {
107451
107749
  this.acpAuthorizationCodePublicKeys.delete(options.requestId);
107750
+ } else if (options.action === "cancel") {
107751
+ this.acpAuthorizationCodePublicKeys.delete(options.authenticationRequestId);
107452
107752
  }
107453
107753
  }
107454
107754
  }
@@ -107813,8 +108113,8 @@ ${value}`;
107813
108113
  timeoutMs,
107814
108114
  refreshContext: args2.method === "machine/acp-capabilities-refresh" ? {
107815
108115
  configId: args2.params.configId,
107816
- cliType: args2.params.cliType,
107817
- agentType: args2.params.agentType
108116
+ cliType: "builtin",
108117
+ agentType: "unknown"
107818
108118
  } : void 0,
107819
108119
  pingContext: args2.method === "machine/ping" ? {
107820
108120
  requestId: args2.params.requestId
@@ -107826,7 +108126,7 @@ ${value}`;
107826
108126
  requestId: args2.params.requestId
107827
108127
  } : void 0,
107828
108128
  binaryContext: args2.method === "machine/acp-authenticate" ? {
107829
- agentType: args2.params.agentType,
108129
+ agentType: "unknown",
107830
108130
  requestId: args2.params.requestId
107831
108131
  } : args2.method === "machine/acp-binary-status" || args2.method === "machine/acp-binary-install" ? {
107832
108132
  agentType: args2.params.agentType
@@ -108241,14 +108541,29 @@ ${value}`;
108241
108541
  const redactRpcRequestForLog = (raw2) => {
108242
108542
  if (typeof raw2 !== "object" || raw2 === null) return raw2;
108243
108543
  const request2 = raw2;
108244
- if (request2.method !== "machine/acp-authenticate" || typeof request2.params !== "object" || request2.params === null || !Object.hasOwn(request2.params, "authorizationCode")) {
108544
+ if (request2.method !== "machine/acp-authenticate" && request2.method !== "machine/acp-capabilities-refresh" || typeof request2.params !== "object" || request2.params === null) {
108245
108545
  return raw2;
108246
108546
  }
108547
+ const params = request2.params;
108247
108548
  return {
108248
108549
  ...request2,
108249
108550
  params: {
108250
- ...request2.params,
108251
- authorizationCode: "[REDACTED]"
108551
+ ...params,
108552
+ ...Object.hasOwn(params, "env") ? {
108553
+ env: "[REDACTED]"
108554
+ } : {},
108555
+ ...Object.hasOwn(params, "authorizationCode") ? {
108556
+ authorizationCode: "[REDACTED]"
108557
+ } : {},
108558
+ ...Object.hasOwn(params, "authenticationInput") ? {
108559
+ authenticationInput: "[REDACTED]"
108560
+ } : {},
108561
+ ...Object.hasOwn(params, "authorizationCodeEnvelope") ? {
108562
+ authorizationCodeEnvelope: "[REDACTED]"
108563
+ } : {},
108564
+ ...Object.hasOwn(params, "authenticationInputEnvelope") ? {
108565
+ authenticationInputEnvelope: "[REDACTED]"
108566
+ } : {}
108252
108567
  }
108253
108568
  };
108254
108569
  };
@@ -108493,7 +108808,7 @@ ${value}`;
108493
108808
  return false;
108494
108809
  }
108495
108810
  const action = request2.params.action;
108496
- return action === "cancel" || action === "submit-code";
108811
+ return action === "cancel" || action === "submit-code" || action === "submit-input";
108497
108812
  }
108498
108813
  async runRequestTask(raw2, lane, options) {
108499
108814
  if (options?.deferredAcquire) {
@@ -108607,11 +108922,6 @@ ${value}`;
108607
108922
  };
108608
108923
  const response2 = await this.deps.refreshMachineAcpCapabilities({
108609
108924
  configId: request2.params.configId,
108610
- cliType: request2.params.cliType,
108611
- agentType: request2.params.agentType,
108612
- customAcp: request2.params.customAcp,
108613
- runtimeOverrides: request2.params.runtimeOverrides,
108614
- env: request2.params.env,
108615
108925
  onAcpBinaryProgress: appendProgress,
108616
108926
  signal: controller.signal
108617
108927
  });
@@ -108648,19 +108958,23 @@ ${value}`;
108648
108958
  }
108649
108959
  let progressWrites = Promise.resolve();
108650
108960
  const appendProgress = (progress) => {
108651
- const safeProgress = progress.acceptsAuthorizationCode && recipient ? {
108961
+ const acceptsInteractionInput = progress.status === "auth-methods" || progress.status === "input-required" || progress.requiresAuthorizationConsent === true;
108962
+ const safeProgress = recipient && (progress.acceptsAuthorizationCode || acceptsInteractionInput) ? {
108652
108963
  ...progress,
108653
- authorizationCodePublicKey: recipient.publicKey
108964
+ ...progress.acceptsAuthorizationCode ? {
108965
+ authorizationCodePublicKey: recipient.publicKey
108966
+ } : {},
108967
+ ...acceptsInteractionInput ? {
108968
+ authenticationInputPublicKey: recipient.publicKey
108969
+ } : {}
108654
108970
  } : progress;
108655
108971
  progressWrites = progressWrites.then(() => this.appendResultResponse(request2.replyTo, request2.id, request2.method, safeProgress)).catch(() => void 0);
108656
108972
  };
108657
108973
  let authorizationCode;
108974
+ let authenticationInput;
108658
108975
  if (request2.params.action === "submit-code") {
108659
108976
  const authenticationRequestId = request2.params.authenticationRequestId;
108660
108977
  const authorizationCodeEnvelope = request2.params.authorizationCodeEnvelope;
108661
- if (!authenticationRequestId || !authorizationCodeEnvelope) {
108662
- throw new Error("Missing encrypted authorization-code input.");
108663
- }
108664
108978
  const activeRecipient = this.acpAuthorizationCodeRecipients.get(authenticationRequestId);
108665
108979
  if (!activeRecipient) {
108666
108980
  throw new Error("Authorization-code recipient is no longer active.");
@@ -108674,27 +108988,79 @@ ${value}`;
108674
108988
  throw new Error("Invalid decrypted authorization-code input.");
108675
108989
  }
108676
108990
  }
108991
+ if (request2.params.action === "submit-input") {
108992
+ const authenticationRequestId = request2.params.authenticationRequestId;
108993
+ const interactionId = request2.params.interactionId;
108994
+ const authenticationInputEnvelope = request2.params.authenticationInputEnvelope;
108995
+ const activeRecipient = this.acpAuthorizationCodeRecipients.get(authenticationRequestId);
108996
+ if (!activeRecipient) {
108997
+ throw new Error("Authentication-input recipient is no longer active.");
108998
+ }
108999
+ authenticationInput = await activeRecipient.decrypt(authenticationInputEnvelope, getMachineAcpAuthenticationInputSecretContext({
109000
+ workspaceId: this.deps.workspaceId,
109001
+ machineId: this.deps.machineId,
109002
+ authenticationRequestId,
109003
+ interactionId
109004
+ }));
109005
+ if (!authenticationInput || authenticationInput.length > 65536) {
109006
+ throw new Error("Invalid decrypted authentication input.");
109007
+ }
109008
+ }
108677
109009
  try {
108678
- const response2 = await this.deps.authenticateMachineAcp({
108679
- requestId: request2.params.requestId,
108680
- action: request2.params.action,
108681
- authenticationRequestId: request2.params.authenticationRequestId,
108682
- authorizationCode,
108683
- methodId: request2.params.methodId,
108684
- configId: request2.params.configId,
108685
- cliType: request2.params.cliType,
108686
- agentType: request2.params.agentType,
108687
- customAcp: request2.params.customAcp,
108688
- runtimeOverrides: request2.params.runtimeOverrides,
108689
- env: request2.params.env,
108690
- onProgress: appendProgress
108691
- });
109010
+ const response2 = await (() => {
109011
+ switch (request2.params.action) {
109012
+ case "start":
109013
+ return this.deps.authenticateMachineAcp?.({
109014
+ requestId: request2.params.requestId,
109015
+ action: request2.params.action,
109016
+ configId: request2.params.configId,
109017
+ onProgress: appendProgress
109018
+ });
109019
+ case "cancel":
109020
+ return this.deps.authenticateMachineAcp?.({
109021
+ requestId: request2.params.requestId,
109022
+ action: request2.params.action,
109023
+ authenticationRequestId: request2.params.authenticationRequestId,
109024
+ onProgress: appendProgress
109025
+ });
109026
+ case "submit-code":
109027
+ if (authorizationCode === void 0) {
109028
+ throw new Error("Missing decrypted authorization-code input.");
109029
+ }
109030
+ return this.deps.authenticateMachineAcp?.({
109031
+ requestId: request2.params.requestId,
109032
+ action: request2.params.action,
109033
+ authenticationRequestId: request2.params.authenticationRequestId,
109034
+ authorizationCode,
109035
+ onProgress: appendProgress
109036
+ });
109037
+ case "submit-input":
109038
+ if (authenticationInput === void 0) {
109039
+ throw new Error("Missing decrypted authentication input.");
109040
+ }
109041
+ return this.deps.authenticateMachineAcp?.({
109042
+ requestId: request2.params.requestId,
109043
+ action: request2.params.action,
109044
+ authenticationRequestId: request2.params.authenticationRequestId,
109045
+ interactionId: request2.params.interactionId,
109046
+ authenticationInput,
109047
+ onProgress: appendProgress
109048
+ });
109049
+ default:
109050
+ throw new Error("Unsupported ACP authentication action.");
109051
+ }
109052
+ })();
109053
+ if (!response2) {
109054
+ throw new Error("ACP authentication is not available on this machine.");
109055
+ }
108692
109056
  await progressWrites;
108693
109057
  await this.appendResultResponse(request2.replyTo, request2.id, request2.method, response2);
108694
109058
  return;
108695
109059
  } finally {
108696
- if (isStart || request2.params.action === "cancel") {
109060
+ if (isStart) {
108697
109061
  this.acpAuthorizationCodeRecipients.delete(request2.params.requestId);
109062
+ } else if (request2.params.action === "cancel") {
109063
+ this.acpAuthorizationCodeRecipients.delete(request2.params.authenticationRequestId);
108698
109064
  }
108699
109065
  }
108700
109066
  }
@@ -109435,12 +109801,7 @@ ${value}`;
109435
109801
  type: "machine/acp-capabilities-refresh",
109436
109802
  machineId: this.machineId,
109437
109803
  workspaceId: this.workspaceId,
109438
- configId: verifying.config.id,
109439
- cliType: verifying.config.cliType,
109440
- agentType: verifying.config.agentType,
109441
- customAcp: verifying.config.customAcp,
109442
- runtimeOverrides: verifying.config.runtimeOverrides,
109443
- env: verifying.config.env
109804
+ configId: verifying.config.id
109444
109805
  });
109445
109806
  if (response2.success) {
109446
109807
  await this.publishVerifiedConfig(verifying.id, attempt);
@@ -109864,20 +110225,20 @@ ${value}`;
109864
110225
  };
109865
110226
  const parsed = DaemonUpgradeIntentSchema.parse(value);
109866
110227
  const dir = path.dirname(DAEMON_UPGRADE_INTENT_FILE);
109867
- await Yt.mkdir(dir, {
110228
+ await Xt.mkdir(dir, {
109868
110229
  recursive: true
109869
110230
  });
109870
110231
  const tmpPath = path.join(dir, `.${path.basename(DAEMON_UPGRADE_INTENT_FILE)}.${process.pid}.tmp`);
109871
- await Yt.writeFile(tmpPath, `${JSON.stringify(parsed, null, 2)}
110232
+ await Xt.writeFile(tmpPath, `${JSON.stringify(parsed, null, 2)}
109872
110233
  `, {
109873
110234
  encoding: "utf8",
109874
110235
  mode: 384
109875
110236
  });
109876
- await Yt.rename(tmpPath, DAEMON_UPGRADE_INTENT_FILE);
110237
+ await Xt.rename(tmpPath, DAEMON_UPGRADE_INTENT_FILE);
109877
110238
  };
109878
110239
  const readDaemonUpgradeIntent = async () => {
109879
110240
  try {
109880
- const raw2 = await Yt.readFile(DAEMON_UPGRADE_INTENT_FILE, "utf8");
110241
+ const raw2 = await Xt.readFile(DAEMON_UPGRADE_INTENT_FILE, "utf8");
109881
110242
  const parsed = DaemonUpgradeIntentSchema.safeParse(JSON.parse(raw2));
109882
110243
  return parsed.success ? parsed.data : null;
109883
110244
  } catch {
@@ -109886,7 +110247,7 @@ ${value}`;
109886
110247
  };
109887
110248
  const clearDaemonUpgradeIntent = async () => {
109888
110249
  try {
109889
- await Yt.unlink(DAEMON_UPGRADE_INTENT_FILE);
110250
+ await Xt.unlink(DAEMON_UPGRADE_INTENT_FILE);
109890
110251
  } catch {
109891
110252
  }
109892
110253
  };
@@ -117523,7 +117884,7 @@ ${error2.message}` : execaMessage;
117523
117884
  function requireBufferStream() {
117524
117885
  if (hasRequiredBufferStream) return bufferStream;
117525
117886
  hasRequiredBufferStream = 1;
117526
- const { PassThrough: PassThroughStream } = So;
117887
+ const { PassThrough: PassThroughStream } = xo;
117527
117888
  bufferStream = (options) => {
117528
117889
  options = {
117529
117890
  ...options
@@ -117572,7 +117933,7 @@ ${error2.message}` : execaMessage;
117572
117933
  if (hasRequiredGetStream) return getStream.exports;
117573
117934
  hasRequiredGetStream = 1;
117574
117935
  const { constants: BufferConstants } = require$$0$6;
117575
- const stream2 = So;
117936
+ const stream2 = xo;
117576
117937
  const { promisify: promisify2 } = require$$0$5;
117577
117938
  const bufferStream2 = requireBufferStream();
117578
117939
  const streamPipelinePromisified = promisify2(stream2.pipeline);
@@ -117632,7 +117993,7 @@ ${error2.message}` : execaMessage;
117632
117993
  function requireMergeStream() {
117633
117994
  if (hasRequiredMergeStream) return mergeStream;
117634
117995
  hasRequiredMergeStream = 1;
117635
- const { PassThrough: PassThrough2 } = So;
117996
+ const { PassThrough: PassThrough2 } = xo;
117636
117997
  mergeStream = function() {
117637
117998
  var sources = [];
117638
117999
  var output = new PassThrough2({
@@ -119363,7 +119724,7 @@ ${error2.message}` : execaMessage;
119363
119724
  validate: validate2
119364
119725
  });
119365
119726
  };
119366
- const realZlibConstants = Ei__default.constants || {
119727
+ const realZlibConstants = Ri__default.constants || {
119367
119728
  ZLIB_VERNUM: 4736
119368
119729
  };
119369
119730
  const constants = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
@@ -119523,11 +119884,11 @@ ${error2.message}` : execaMessage;
119523
119884
  this.#flushFlag = opts.flush ?? 0;
119524
119885
  this.#finishFlushFlag = opts.finishFlush ?? 0;
119525
119886
  this.#fullFlushFlag = opts.fullFlushFlag ?? 0;
119526
- if (typeof Ei[mode2] !== "function") {
119887
+ if (typeof Ri[mode2] !== "function") {
119527
119888
  throw new TypeError("Compression method not supported: " + mode2);
119528
119889
  }
119529
119890
  try {
119530
- this.#handle = new Ei[mode2](opts);
119891
+ this.#handle = new Ri[mode2](opts);
119531
119892
  } catch (er) {
119532
119893
  throw new ZlibError(er, this.constructor);
119533
119894
  }
@@ -122542,7 +122903,7 @@ ${error2.message}` : execaMessage;
122542
122903
  return checkCwd(dir, done2);
122543
122904
  }
122544
122905
  if (preserve) {
122545
- return Yt__default.mkdir(dir, {
122906
+ return Xt__default.mkdir(dir, {
122546
122907
  mode: mode2,
122547
122908
  recursive: true
122548
122909
  }).then((made) => done2(null, made ?? void 0), done2);
@@ -123792,7 +124153,7 @@ ${error2.message}` : execaMessage;
123792
124153
  hasRequiredFdSlicer = 1;
123793
124154
  var fs2 = fs__default;
123794
124155
  var util2 = require$$0$5;
123795
- var stream2 = So;
124156
+ var stream2 = xo;
123796
124157
  var Readable2 = stream2.Readable;
123797
124158
  var Writable = stream2.Writable;
123798
124159
  var PassThrough2 = stream2.PassThrough;
@@ -124358,14 +124719,14 @@ ${error2.message}` : execaMessage;
124358
124719
  if (hasRequiredYauzl) return yauzl;
124359
124720
  hasRequiredYauzl = 1;
124360
124721
  var fs2 = fs__default;
124361
- var zlib = Ei__default;
124722
+ var zlib = Ri__default;
124362
124723
  var fd_slicer = requireFdSlicer();
124363
124724
  var crc322 = requireBufferCrc32();
124364
124725
  var util2 = require$$0$5;
124365
124726
  var EventEmitter2 = require$$0$7.EventEmitter;
124366
- var Transform2 = So.Transform;
124367
- var PassThrough2 = So.PassThrough;
124368
- var Writable = So.Writable;
124727
+ var Transform2 = xo.Transform;
124728
+ var PassThrough2 = xo.PassThrough;
124729
+ var Writable = xo.Writable;
124369
124730
  yauzl.open = open2;
124370
124731
  yauzl.fromFd = fromFd;
124371
124732
  yauzl.fromBuffer = fromBuffer;
@@ -125806,99 +126167,99 @@ ${error2.message}` : execaMessage;
125806
126167
  const grokPackageJson = {
125807
126168
  version: version$6
125808
126169
  };
125809
- const version$5 = "2.1.251";
126170
+ const version$5 = "2.1.258";
125810
126171
  const platforms = {
125811
126172
  "darwin-arm64": {
125812
126173
  "binary": "claude",
125813
- "checksum": "625869b01e0050f260b2980fac248fd9cef9e462612bded4ec9d3d49ff8969a5",
125814
- "size": 197171680
126174
+ "checksum": "b63136194160791c27cfa7b0403060d85eb0752991625fde8c09f9acacb17c78",
126175
+ "size": 199027600
125815
126176
  },
125816
126177
  "darwin-x64": {
125817
126178
  "binary": "claude",
125818
- "checksum": "44221d72a3f35772faa85ad9a36a678084a516f720e64b45e26eb9015315500b",
125819
- "size": 205778256
126179
+ "checksum": "c857db5cd712865623bd61e806cf3f7e8e279c9e5c7c0af5eca06ca6717fc7fb",
126180
+ "size": 207778640
125820
126181
  },
125821
126182
  "linux-arm64": {
125822
126183
  "binary": "claude",
125823
- "checksum": "65445bd4dd042079cc3fa43791b561370a05c8599e8ec47580e25a81050abbdd",
125824
- "size": 213835016
126184
+ "checksum": "43dc490af55262edcb3e9b1cb315de22cc09ccb08bd52a4c39bc5eabaa63100f",
126185
+ "size": 215014736
125825
126186
  },
125826
126187
  "linux-x64": {
125827
126188
  "binary": "claude",
125828
- "checksum": "fd5f10ff0eb58daec04900466b143ea98aab50abf208a422bc008eaec13f61f7",
125829
- "size": 214326616
126189
+ "checksum": "704f1334ac65d3e89e1c6c1d7663293ad786a6166afdb71b5075337df630f976",
126190
+ "size": 215473560
125830
126191
  },
125831
126192
  "linux-arm64-musl": {
125832
126193
  "binary": "claude",
125833
- "checksum": "165f6236abf5b0c42892b164c2299c82023421805e0c3eaddf925a3195513f84",
125834
- "size": 206648896
126194
+ "checksum": "d3bef6ba403fe3efba684fa93e1bb26bc7a08c054bd516639d54e77c77bb9821",
126195
+ "size": 207894168
125835
126196
  },
125836
126197
  "linux-x64-musl": {
125837
126198
  "binary": "claude",
125838
- "checksum": "5056970c13f46dd2bff2c44dd2a7f766553a63392615412d5711278264730e07",
125839
- "size": 208301944
126199
+ "checksum": "e74a226cf174d911664aff982486c55ca770d9c00007e52e86b13d10bae72af3",
126200
+ "size": 209493960
125840
126201
  },
125841
126202
  "win32-x64": {
125842
126203
  "binary": "claude.exe",
125843
- "checksum": "8d1229a281281b98fd2dee72b3253a704be4fce4d45207200cd32a9bb5a6c909",
125844
- "size": 217360032
126204
+ "checksum": "22f5f3a44093e14c75a4d1c8ce25c730b21dd634318fbe3268e9057d12b17c41",
126205
+ "size": 218507936
125845
126206
  },
125846
126207
  "win32-arm64": {
125847
126208
  "binary": "claude.exe",
125848
- "checksum": "89e91fed2dc6f6278fa1e179e6401c0a1c252fe80c57ee47f17f10f7f7b4e99c",
125849
- "size": 208465056
126209
+ "checksum": "42675c431b6014ad7243fea0ed0e371045dedc89d94aac81a9a0f528e644ed97",
126210
+ "size": 209548960
125850
126211
  }
125851
126212
  };
125852
126213
  const claudeSdkManifestJson = {
125853
126214
  version: version$5,
125854
126215
  platforms
125855
126216
  };
125856
- const version$4 = "0.3.251";
126217
+ const version$4 = "0.3.258";
125857
126218
  const claudeSdkPackageJson = {
125858
126219
  version: version$4
125859
126220
  };
125860
- const sdkVersion = "0.3.251";
125861
- const version$3 = "2.1.251";
126221
+ const sdkVersion = "0.3.258";
126222
+ const version$3 = "2.1.258";
125862
126223
  const artifacts$1 = {
125863
126224
  "darwin-arm64": {
125864
- "fileName": "anthropic-ai-claude-agent-sdk-darwin-arm64-0.3.251.tar.zst",
125865
- "sha256": "536a3755844d168b87250af3ee6e3dd103391305514f28abe564f91a5aa856ee",
125866
- "size": 71945899
126225
+ "fileName": "anthropic-ai-claude-agent-sdk-darwin-arm64-0.3.258.tar.zst",
126226
+ "sha256": "dd01a1ae8868c41ac7755e89fa4fc087d28e265b6d7ab122c18317dfd7023ed2",
126227
+ "size": 73550133
125867
126228
  },
125868
126229
  "darwin-x64": {
125869
- "fileName": "anthropic-ai-claude-agent-sdk-darwin-x64-0.3.251.tar.zst",
125870
- "sha256": "68e88be76d4399d1dea054d9dbbf7106c393578fa1fa5714c9a8890b6ff3213c",
125871
- "size": 75692035
126230
+ "fileName": "anthropic-ai-claude-agent-sdk-darwin-x64-0.3.258.tar.zst",
126231
+ "sha256": "f46392ec768822fca40d61f6986d7d293a42b3ee5820b0c1a6c14bee474fdb02",
126232
+ "size": 77362894
125872
126233
  },
125873
126234
  "linux-arm64": {
125874
- "fileName": "anthropic-ai-claude-agent-sdk-linux-arm64-0.3.251.tar.zst",
125875
- "sha256": "92e61ffb31b8beae919beb6a9458f4a376067bf25d4df7e5c8fe29b84ed1edaa",
125876
- "size": 81951594
126235
+ "fileName": "anthropic-ai-claude-agent-sdk-linux-arm64-0.3.258.tar.zst",
126236
+ "sha256": "b2df6e0ac548e348a1609d5cba8c1c22c8f4f98b9a3ab54f5ce2082ff96db0f2",
126237
+ "size": 83313235
125877
126238
  },
125878
126239
  "linux-x64": {
125879
- "fileName": "anthropic-ai-claude-agent-sdk-linux-x64-0.3.251.tar.zst",
125880
- "sha256": "9e51358bb06885a29c0cdcaff6ffbbed47718e3210b8e92ae074802440a46dd3",
125881
- "size": 81994218
126240
+ "fileName": "anthropic-ai-claude-agent-sdk-linux-x64-0.3.258.tar.zst",
126241
+ "sha256": "ea9bfd7a1cfe218b9c9451450401d654711787bf1972b8a22d3b5f7b495a73f8",
126242
+ "size": 83414920
125882
126243
  },
125883
126244
  "linux-arm64-musl": {
125884
- "fileName": "anthropic-ai-claude-agent-sdk-linux-arm64-musl-0.3.251.tar.zst",
125885
- "sha256": "bfad7556c20b01776c2205898c7f76a31448e42b7c2e7254476d25aac9c0d84c",
125886
- "size": 80166022
126245
+ "fileName": "anthropic-ai-claude-agent-sdk-linux-arm64-musl-0.3.258.tar.zst",
126246
+ "sha256": "9293b47fd63fa6f368fe0a9fa2930fd6963e6108e65b34584f854919df7f227b",
126247
+ "size": 81542174
125887
126248
  },
125888
126249
  "linux-x64-musl": {
125889
- "fileName": "anthropic-ai-claude-agent-sdk-linux-x64-musl-0.3.251.tar.zst",
125890
- "sha256": "143efe291c6cd6501681fff2930c58c9eeeef5f924dded6b340e84a9e069e1d1",
125891
- "size": 80324347
126250
+ "fileName": "anthropic-ai-claude-agent-sdk-linux-x64-musl-0.3.258.tar.zst",
126251
+ "sha256": "ba0e031ff3266f41d73a28effc25d4334d992891b0495542ca7cf3b2a75632c8",
126252
+ "size": 81733248
125892
126253
  },
125893
126254
  "win32-arm64": {
125894
- "fileName": "anthropic-ai-claude-agent-sdk-win32-arm64-0.3.251.tar.zst",
125895
- "sha256": "0d70dd262d40b39fe354e3b7c0e5a1b3a4895beef2692509a3830511ff184023",
125896
- "size": 81916953
126255
+ "fileName": "anthropic-ai-claude-agent-sdk-win32-arm64-0.3.258.tar.zst",
126256
+ "sha256": "13cd9e1ad2958bc8dbaaf908362852136b63f8ce4f452beade38d0323a40774d",
126257
+ "size": 83257894
125897
126258
  },
125898
126259
  "win32-x64": {
125899
- "fileName": "anthropic-ai-claude-agent-sdk-win32-x64-0.3.251.tar.zst",
125900
- "sha256": "db8bcee96e0f0bc42b01977c1897977c204d5cee07464656ec49fa44d31014aa",
125901
- "size": 84974808
126260
+ "fileName": "anthropic-ai-claude-agent-sdk-win32-x64-0.3.258.tar.zst",
126261
+ "sha256": "ae93d318561a4c069d7074726d345224b588e1b3b0a6955b604f6a06ec0c3195",
126262
+ "size": 86357676
125902
126263
  }
125903
126264
  };
125904
126265
  const claudeRuntimeManifestJson = {
@@ -127248,7 +127609,6 @@ ${error2.message}` : execaMessage;
127248
127609
  return {
127249
127610
  command: "npx",
127250
127611
  args: [
127251
- "--force",
127252
127612
  "--prefer-offline",
127253
127613
  "-y",
127254
127614
  ...DEEPSEEK_HARNESS_NPX_PACKAGES.flatMap((packageName) => [
@@ -127788,19 +128148,33 @@ ${error2.message}` : execaMessage;
127788
128148
  let streamStarted = false;
127789
128149
  let pendingController = null;
127790
128150
  let stdoutEnded = false;
127791
- stdout.on("data", (chunk) => {
128151
+ let controllerClosed = false;
128152
+ const onData = (chunk) => {
128153
+ if (controllerClosed) return;
127792
128154
  if (streamStarted && pendingController) {
127793
128155
  pendingController.enqueue(chunk);
127794
128156
  } else {
127795
128157
  bufferedChunks.push(chunk);
127796
128158
  }
127797
- });
127798
- stdout.on("end", () => {
128159
+ };
128160
+ const closeController = () => {
128161
+ if (!pendingController || controllerClosed) return;
128162
+ controllerClosed = true;
128163
+ const controller = pendingController;
128164
+ pendingController = null;
128165
+ controller.close();
128166
+ };
128167
+ const onEnd = () => {
127799
128168
  stdoutEnded = true;
127800
- if (streamStarted && pendingController) {
127801
- pendingController.close();
127802
- }
127803
- });
128169
+ if (streamStarted) closeController();
128170
+ detach();
128171
+ };
128172
+ const detach = () => {
128173
+ stdout.removeListener("data", onData);
128174
+ stdout.removeListener("end", onEnd);
128175
+ };
128176
+ stdout.on("data", onData);
128177
+ stdout.on("end", onEnd);
127804
128178
  return new ReadableStream({
127805
128179
  start(controller) {
127806
128180
  pendingController = controller;
@@ -127810,8 +128184,14 @@ ${error2.message}` : execaMessage;
127810
128184
  bufferedChunks.length = 0;
127811
128185
  streamStarted = true;
127812
128186
  if (stdoutEnded) {
127813
- controller.close();
128187
+ closeController();
127814
128188
  }
128189
+ },
128190
+ cancel() {
128191
+ controllerClosed = true;
128192
+ pendingController = null;
128193
+ bufferedChunks.length = 0;
128194
+ detach();
127815
128195
  }
127816
128196
  });
127817
128197
  }
@@ -128705,7 +129085,7 @@ ${fallbackStderrTail}` : errorMessage2;
128705
129085
  sessionResponse
128706
129086
  };
128707
129087
  };
128708
- function waitForChildProcessExit$1(child, timeoutMs) {
129088
+ function waitForChildProcessExit$2(child, timeoutMs) {
128709
129089
  if (child.exitCode !== null) {
128710
129090
  return Promise.resolve(true);
128711
129091
  }
@@ -128742,7 +129122,7 @@ ${fallbackStderrTail}` : errorMessage2;
128742
129122
  } catch {
128743
129123
  return;
128744
129124
  }
128745
- if (await waitForChildProcessExit$1(child, exitTimeoutMs)) {
129125
+ if (await waitForChildProcessExit$2(child, exitTimeoutMs)) {
128746
129126
  return;
128747
129127
  }
128748
129128
  logger2.debug(`[${sessionLabel}] ACP agent process did not exit within ${exitTimeoutMs}ms of SIGTERM; escalating to SIGKILL`);
@@ -128751,7 +129131,7 @@ ${fallbackStderrTail}` : errorMessage2;
128751
129131
  } catch {
128752
129132
  return;
128753
129133
  }
128754
- await waitForChildProcessExit$1(child, exitTimeoutMs);
129134
+ await waitForChildProcessExit$2(child, exitTimeoutMs);
128755
129135
  }
128756
129136
  const spawnAcpProcess = (options) => {
128757
129137
  let command2 = options.command;
@@ -129202,217 +129582,6 @@ ${fallbackStderrTail}` : errorMessage2;
129202
129582
  super(isLikelyAuthorizationUrl, false);
129203
129583
  }
129204
129584
  }
129205
- const ACP_AUTHENTICATION_INITIALIZE_TIMEOUT_MS = 6e4;
129206
- const AUTHENTICATION_TERMINATION_GRACE_MS = 3e3;
129207
- function normalizeAcpAuthMethod(method) {
129208
- const record2 = method;
129209
- const id2 = typeof record2.id === "string" ? record2.id.trim() : "";
129210
- if (!id2) return null;
129211
- const type2 = record2.type === "terminal" || record2.type === "env_var" ? record2.type : "agent";
129212
- const args2 = Array.isArray(record2.args) && record2.args.every((arg) => typeof arg === "string") ? record2.args : void 0;
129213
- const env2 = typeof record2.env === "object" && record2.env !== null ? Object.fromEntries(Object.entries(record2.env).filter((entry) => typeof entry[1] === "string")) : void 0;
129214
- return {
129215
- type: type2,
129216
- id: id2,
129217
- ...typeof record2.name === "string" ? {
129218
- name: record2.name
129219
- } : {},
129220
- ...typeof record2.description === "string" ? {
129221
- description: record2.description
129222
- } : {},
129223
- ...args2 ? {
129224
- args: args2
129225
- } : {},
129226
- ...env2 && Object.keys(env2).length > 0 ? {
129227
- env: env2
129228
- } : {}
129229
- };
129230
- }
129231
- function describeAcpAuthMethod(method) {
129232
- return method.name?.trim() ? method.name : method.id;
129233
- }
129234
- function formatEnvVarAuthMethodError(method, normalized) {
129235
- const vars = method.vars;
129236
- const names2 = Array.isArray(vars) ? vars.map((entry) => typeof entry === "object" && entry !== null && typeof entry.name === "string" ? entry.name : null).filter((name2) => Boolean(name2)) : [];
129237
- const suffix = names2.length > 0 ? `: ${names2.join(", ")}` : "";
129238
- return `${describeAcpAuthMethod(normalized)} authenticates through environment variables. Add them to this agent's environment in its settings${suffix}.`;
129239
- }
129240
- function selectAuthMethod(methods2, methodId) {
129241
- for (const method of methods2) {
129242
- const normalized = normalizeAcpAuthMethod(method);
129243
- if (!normalized) continue;
129244
- if (methodId === void 0 || normalized.id === methodId) {
129245
- return {
129246
- method,
129247
- normalized
129248
- };
129249
- }
129250
- }
129251
- return null;
129252
- }
129253
- function withDeadline(promise2, timeoutMs, label2) {
129254
- let timeoutHandle;
129255
- const timeout2 = new Promise((_resolve, reject2) => {
129256
- timeoutHandle = setTimeout(() => reject2(new Error(`${label2} timed out after ${Math.round(timeoutMs / 1e3)}s`)), timeoutMs);
129257
- timeoutHandle.unref?.();
129258
- });
129259
- return Promise.race([
129260
- promise2,
129261
- timeout2
129262
- ]).finally(() => {
129263
- if (timeoutHandle) clearTimeout(timeoutHandle);
129264
- });
129265
- }
129266
- async function runAcpProtocolAuthentication(options) {
129267
- options.signal?.throwIfAborted();
129268
- const child = spawnAcpProcess({
129269
- cliType: options.cliType,
129270
- agentType: options.agentType,
129271
- workdir: options.workdir,
129272
- env: options.env,
129273
- command: options.launch.command,
129274
- args: options.launch.args,
129275
- spawnImpl: options.spawnProcess
129276
- });
129277
- options.attachProcess?.(child);
129278
- let stderrTail = "";
129279
- const parser = new AcpAgentAuthorizationOutputParser();
129280
- child.stderr?.setEncoding("utf8");
129281
- child.stderr?.on("data", (chunk) => {
129282
- if (!chunk) return;
129283
- stderrTail = appendStderrTail(stderrTail, chunk);
129284
- const authorization = parser.push(chunk);
129285
- if (authorization) {
129286
- options.onProgress?.({
129287
- status: "authorization",
129288
- ...authorization
129289
- });
129290
- }
129291
- });
129292
- let rejectProcessFailure;
129293
- const processFailure = new Promise((_resolve, reject2) => {
129294
- rejectProcessFailure = reject2;
129295
- });
129296
- const handleExit = (code2, signal) => {
129297
- rejectProcessFailure?.(new Error(`${options.agentType} exited during authentication (code ${code2 ?? "null"}${signal ? `, signal ${signal}` : ""})${stderrTail ? `: ${stderrTail}` : ""}`));
129298
- };
129299
- const handleError2 = (error2) => {
129300
- rejectProcessFailure?.(new Error(`${options.agentType} failed to start: ${error2.message}`));
129301
- };
129302
- child.once("exit", handleExit);
129303
- child.once("error", handleError2);
129304
- processFailure.catch(() => void 0);
129305
- const handleAbort = () => {
129306
- rejectProcessFailure?.(new DOMException("ACP authentication was cancelled", "AbortError"));
129307
- };
129308
- options.signal?.addEventListener("abort", handleAbort, {
129309
- once: true
129310
- });
129311
- const terminate = () => {
129312
- child.off("exit", handleExit);
129313
- child.off("error", handleError2);
129314
- options.signal?.removeEventListener("abort", handleAbort);
129315
- void shutdownLocalAcpAgent({
129316
- agentProcess: child,
129317
- logger: options.logger,
129318
- sessionLabel: `acp-auth-protocol:${options.agentType}`,
129319
- exitTimeoutMs: AUTHENTICATION_TERMINATION_GRACE_MS
129320
- }).catch((error2) => {
129321
- options.logger.debug(`[acp-auth] Failed to stop ${options.agentType} after authentication: ${formatErrorMessage(error2)}`);
129322
- });
129323
- };
129324
- try {
129325
- if (!child.stdout || !child.stdin) {
129326
- throw new Error("Agent process stdio is not available");
129327
- }
129328
- const stream2 = ndJsonStream(createStdinWritableStream(child.stdin), createStdoutReadableStream(child.stdout));
129329
- const connection2 = new ClientSideConnection(() => ({
129330
- requestPermission: async () => ({
129331
- outcome: {
129332
- outcome: "cancelled"
129333
- }
129334
- }),
129335
- sessionUpdate: () => {
129336
- }
129337
- }), stream2);
129338
- const initializeResponse = await Promise.race([
129339
- withDeadline(connection2.initialize({
129340
- protocolVersion: PROTOCOL_VERSION,
129341
- clientCapabilities: {
129342
- terminal: false,
129343
- fs: {
129344
- readTextFile: false,
129345
- writeTextFile: false
129346
- },
129347
- auth: {
129348
- terminal: true
129349
- }
129350
- }
129351
- }), Math.max(1, options.initializeTimeoutMs ?? ACP_AUTHENTICATION_INITIALIZE_TIMEOUT_MS), `${options.agentType} initialize`),
129352
- processFailure
129353
- ]);
129354
- options.signal?.throwIfAborted();
129355
- const advertised = initializeResponse.authMethods ?? [];
129356
- if (advertised.length === 0) {
129357
- return {
129358
- kind: "error",
129359
- error: `${options.agentType} does not advertise an authentication method. Check the agent's own setup instructions or configure its credentials in this agent's environment.`
129360
- };
129361
- }
129362
- const selected = selectAuthMethod(advertised, options.methodId);
129363
- if (!selected) {
129364
- if (options.methodId !== void 0) {
129365
- return {
129366
- kind: "error",
129367
- error: `${options.agentType} no longer advertises the authentication method "${options.methodId}"`
129368
- };
129369
- }
129370
- return {
129371
- kind: "error",
129372
- error: `${options.agentType} advertised no usable authentication method`
129373
- };
129374
- }
129375
- const normalizedMethods = advertised.map(normalizeAcpAuthMethod).filter((method) => method !== null);
129376
- if (options.methodId === void 0 && normalizedMethods.length > 1) {
129377
- return {
129378
- kind: "method-required",
129379
- authMethods: normalizedMethods
129380
- };
129381
- }
129382
- if (selected.normalized.type === "env_var") {
129383
- return {
129384
- kind: "error",
129385
- error: formatEnvVarAuthMethodError(selected.method, selected.normalized)
129386
- };
129387
- }
129388
- if (selected.normalized.type === "terminal") {
129389
- return {
129390
- kind: "terminal-method",
129391
- method: selected.normalized
129392
- };
129393
- }
129394
- options.logger.debug(`[acp-auth] ${options.agentType} authenticate methodId=${selected.normalized.id}`);
129395
- await Promise.race([
129396
- connection2.authenticate({
129397
- methodId: selected.normalized.id
129398
- }),
129399
- processFailure
129400
- ]);
129401
- return {
129402
- kind: "authenticated"
129403
- };
129404
- } catch (error2) {
129405
- if (error2 instanceof DOMException && error2.name === "AbortError") {
129406
- throw error2;
129407
- }
129408
- return {
129409
- kind: "error",
129410
- error: formatErrorMessage(error2)
129411
- };
129412
- } finally {
129413
- terminate();
129414
- }
129415
- }
129416
129585
  const DEFAULT_AUTHENTICATION_TIMEOUT_MS = 285e3;
129417
129586
  const DEFAULT_TERMINATION_GRACE_MS$1 = 3e3;
129418
129587
  const DEFAULT_STATUS_PROBE_TIMEOUT_MS = 15e3;
@@ -129461,6 +129630,139 @@ ${fallbackStderrTail}` : errorMessage2;
129461
129630
  }
129462
129631
  ]
129463
129632
  };
129633
+ const AcpAuthenticationInteractionInputSchema = discriminatedUnion("action", [
129634
+ object$1({
129635
+ action: literal$1("accept"),
129636
+ methodId: string$1().trim().min(1).max(ACP_AUTH_ID_MAX_LENGTH).optional(),
129637
+ content: record$1(string$1(), unknown()).optional()
129638
+ }).strict(),
129639
+ object$1({
129640
+ action: _enum$1([
129641
+ "decline",
129642
+ "cancel"
129643
+ ])
129644
+ }).strict()
129645
+ ]);
129646
+ const asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
129647
+ function isAllowedAuthorizationUrl(value) {
129648
+ if (value.length > ACP_AUTHORIZATION_URL_MAX_LENGTH) return false;
129649
+ try {
129650
+ const protocol = new URL(value).protocol;
129651
+ return protocol === "https:" || protocol === "http:";
129652
+ } catch {
129653
+ return false;
129654
+ }
129655
+ }
129656
+ function toAuthenticationForm(request2) {
129657
+ const rawRequest = asRecord(request2);
129658
+ const schema2 = asRecord(rawRequest?.requestedSchema);
129659
+ const properties2 = asRecord(schema2?.properties);
129660
+ if (!rawRequest || rawRequest.mode !== "form" || !schema2 || !properties2) return null;
129661
+ const propertyEntries = Object.entries(properties2);
129662
+ if (propertyEntries.length === 0 || propertyEntries.length > ACP_AUTH_FORM_FIELD_MAX_COUNT) {
129663
+ return null;
129664
+ }
129665
+ if (typeof schema2.title === "string" && schema2.title.length > ACP_AUTH_LABEL_MAX_LENGTH || typeof schema2.description === "string" && schema2.description.length > ACP_AUTH_TEXT_MAX_LENGTH) {
129666
+ return null;
129667
+ }
129668
+ if (schema2.required !== void 0 && (!Array.isArray(schema2.required) || schema2.required.some((value) => typeof value !== "string"))) {
129669
+ return null;
129670
+ }
129671
+ const required2 = new Set(schema2.required ?? []);
129672
+ if ([
129673
+ ...required2
129674
+ ].some((id2) => !Object.hasOwn(properties2, id2))) return null;
129675
+ const fields = [];
129676
+ for (const [id2, rawProperty] of propertyEntries) {
129677
+ const property = asRecord(rawProperty);
129678
+ if (!property || property.type !== "string") return null;
129679
+ const label2 = typeof property.title === "string" && property.title.trim() ? property.title : id2;
129680
+ const description2 = typeof property.description === "string" ? property.description : void 0;
129681
+ if (!id2.trim() || id2.length > ACP_AUTH_ID_MAX_LENGTH || !label2.trim() || label2.length > ACP_AUTH_LABEL_MAX_LENGTH || (description2?.length ?? 0) > ACP_AUTH_TEXT_MAX_LENGTH) {
129682
+ return null;
129683
+ }
129684
+ const meta = asRecord(property._meta);
129685
+ const secret = getLodyElicitationMeta(property._meta)?.secret === true || meta?.secret === true || meta?.sensitive === true || property.format === "password";
129686
+ const defaultValue = !secret && typeof property.default === "string" ? property.default : void 0;
129687
+ if ((defaultValue?.length ?? 0) > ACP_AUTH_TEXT_MAX_LENGTH) return null;
129688
+ if (property.oneOf !== void 0 && !Array.isArray(property.oneOf) || property.enum !== void 0 && !Array.isArray(property.enum)) {
129689
+ return null;
129690
+ }
129691
+ const titledOptions = Array.isArray(property.oneOf) ? property.oneOf.map((rawOption) => {
129692
+ const option2 = asRecord(rawOption);
129693
+ if (!option2 || typeof option2.const !== "string" || !option2.const) return null;
129694
+ const optionLabel = typeof option2.title === "string" && option2.title.trim() ? option2.title : option2.const;
129695
+ return {
129696
+ value: option2.const,
129697
+ label: optionLabel
129698
+ };
129699
+ }) : [];
129700
+ const enumOptions = Array.isArray(property.enum) ? property.enum.map((value) => typeof value === "string" && value ? {
129701
+ value,
129702
+ label: value
129703
+ } : null) : [];
129704
+ if (titledOptions.some((option2) => option2 === null) || enumOptions.some((option2) => option2 === null)) {
129705
+ return null;
129706
+ }
129707
+ const options = titledOptions.length > 0 ? titledOptions : enumOptions;
129708
+ if ((Array.isArray(property.oneOf) || Array.isArray(property.enum)) && options.length === 0 || options.length > ACP_AUTH_SELECT_OPTION_MAX_COUNT || options.some((option2) => option2 === null || option2.value.length > ACP_AUTH_TEXT_MAX_LENGTH || option2.label.length > ACP_AUTH_LABEL_MAX_LENGTH)) {
129709
+ return null;
129710
+ }
129711
+ if (options.length > 0) {
129712
+ if (new Set(options.map((option2) => option2?.value)).size !== options.length) {
129713
+ return null;
129714
+ }
129715
+ if (defaultValue !== void 0 && !options.some((option2) => option2?.value === defaultValue)) {
129716
+ return null;
129717
+ }
129718
+ fields.push({
129719
+ id: id2,
129720
+ type: "select",
129721
+ label: label2,
129722
+ ...description2 !== void 0 ? {
129723
+ description: description2
129724
+ } : {},
129725
+ required: required2.has(id2),
129726
+ options: options.filter((option2) => !!option2),
129727
+ ...defaultValue !== void 0 ? {
129728
+ defaultValue
129729
+ } : {}
129730
+ });
129731
+ continue;
129732
+ }
129733
+ fields.push(secret ? {
129734
+ id: id2,
129735
+ type: "secret",
129736
+ label: label2,
129737
+ ...description2 !== void 0 ? {
129738
+ description: description2
129739
+ } : {},
129740
+ required: required2.has(id2)
129741
+ } : {
129742
+ id: id2,
129743
+ type: "text",
129744
+ label: label2,
129745
+ ...description2 !== void 0 ? {
129746
+ description: description2
129747
+ } : {},
129748
+ required: required2.has(id2),
129749
+ ...defaultValue !== void 0 ? {
129750
+ defaultValue
129751
+ } : {}
129752
+ });
129753
+ }
129754
+ if (fields.length === 0) return null;
129755
+ const form = {
129756
+ title: typeof schema2.title === "string" ? schema2.title : void 0,
129757
+ description: typeof schema2.description === "string" ? schema2.description : void 0,
129758
+ fields
129759
+ };
129760
+ return isAcpAuthenticationFormWithinByteLimit(form) ? form : null;
129761
+ }
129762
+ function getAuthMethodType(method) {
129763
+ const type2 = asRecord(method)?.type;
129764
+ return type2 === "env_var" || type2 === "terminal" ? type2 : "agent";
129765
+ }
129464
129766
  function getBuiltinDisplayName(agentType) {
129465
129767
  return getManagedBuiltinRuntimeByAgentType(agentType)?.displayName ?? agentType;
129466
129768
  }
@@ -129477,7 +129779,7 @@ ${fallbackStderrTail}` : errorMessage2;
129477
129779
  NO_COLOR: "1"
129478
129780
  };
129479
129781
  delete baseEnv.FORCE_COLOR;
129480
- return withoutElectronBootstrapCredentials(withDefaultAcpPathEntries(mergeACPProcessEnv(options.launch, mergeLoginShellEnv(baseEnv, loginShellEnv)), options.agentType));
129782
+ return withLoopbackNoProxy(withoutElectronBootstrapCredentials(withLodyNpmCacheForNpx(options.launch.command, withDefaultAcpPathEntries(mergeACPProcessEnv(options.launch, mergeLoginShellEnv(baseEnv, loginShellEnv)), options.agentType))));
129481
129783
  }
129482
129784
  async function probeBuiltinAuthentication(options) {
129483
129785
  options.signal?.throwIfAborted();
@@ -129601,8 +129903,8 @@ ${fallbackStderrTail}` : errorMessage2;
129601
129903
  spawnProcess;
129602
129904
  resolveLoginShellEnv;
129603
129905
  async authenticate(options) {
129604
- const managedBuiltinAgentType = options.cliType === "builtin" && isManagedBuiltinAgentType(options.agentType) ? options.agentType : null;
129605
- const displayName = managedBuiltinAgentType ? getBuiltinDisplayName(managedBuiltinAgentType) : options.agentType;
129906
+ const isBuiltinAuthentication = options.cliType === "builtin" && isManagedBuiltinAgentType(options.agentType);
129907
+ const displayName = isBuiltinAuthentication ? getBuiltinDisplayName(options.agentType) : options.agentType;
129606
129908
  if (this.runningByAgentType.has(options.agentType)) {
129607
129909
  return {
129608
129910
  success: false,
@@ -129617,7 +129919,7 @@ ${fallbackStderrTail}` : errorMessage2;
129617
129919
  terminating: false,
129618
129920
  acceptsAuthorizationCode: false,
129619
129921
  authorizationCodeSubmitted: false,
129620
- abort: new AbortController()
129922
+ abortController: new AbortController()
129621
129923
  };
129622
129924
  this.runningByAgentType.set(options.agentType, running2);
129623
129925
  let timeoutHandle;
@@ -129648,6 +129950,11 @@ ${fallbackStderrTail}` : errorMessage2;
129648
129950
  timeoutHandle = setTimeout(() => {
129649
129951
  if (running2.cancelled) return;
129650
129952
  running2.timedOut = true;
129953
+ running2.abortController.abort();
129954
+ running2.pendingInteraction?.resolve({
129955
+ action: "cancel"
129956
+ });
129957
+ running2.pendingInteraction = void 0;
129651
129958
  if (!running2.child && this.runningByAgentType.get(options.agentType) === running2) {
129652
129959
  this.runningByAgentType.delete(options.agentType);
129653
129960
  }
@@ -129655,18 +129962,103 @@ ${fallbackStderrTail}` : errorMessage2;
129655
129962
  }, this.authenticationTimeoutMs);
129656
129963
  timeoutHandle.unref?.();
129657
129964
  try {
129658
- const result = managedBuiltinAgentType ? await this.runBuiltinLogin({
129659
- options,
129660
- running: running2,
129661
- interruptedResult,
129662
- agentType: managedBuiltinAgentType,
129663
- displayName
129664
- }) : await this.runProtocolAuthentication({
129665
- options,
129666
- running: running2,
129667
- interruptedResult
129965
+ if (!isBuiltinAuthentication) {
129966
+ return await this.authenticateProtocolDrivenAcp(options, running2);
129967
+ }
129968
+ const agentType = options.agentType;
129969
+ const launch = await resolveBuiltinAuthenticationProcessLaunch({
129970
+ cliType: options.cliType,
129971
+ agentType: options.agentType,
129972
+ runtimeOverrides: options.runtimeOverrides,
129973
+ action: "login"
129668
129974
  });
129669
- return result;
129975
+ if (!launch) {
129976
+ throw new Error(`${displayName} authentication is unavailable`);
129977
+ }
129978
+ const launchInterruption = interruptedResult();
129979
+ if (launchInterruption) return launchInterruption;
129980
+ const env2 = await buildAuthenticationProcessEnv({
129981
+ launch,
129982
+ agentType: options.agentType,
129983
+ env: options.env,
129984
+ resolveLoginShellEnv: this.resolveLoginShellEnv
129985
+ });
129986
+ const preparationInterruption = interruptedResult();
129987
+ if (preparationInterruption) return preparationInterruption;
129988
+ options.onProgress?.({
129989
+ status: "starting"
129990
+ });
129991
+ const child = this.spawnProcess(launch.command, launch.args, {
129992
+ cwd: os__default$1.homedir(),
129993
+ env: env2,
129994
+ stdio: [
129995
+ "pipe",
129996
+ "pipe",
129997
+ "pipe"
129998
+ ],
129999
+ detached: process.platform !== "win32",
130000
+ windowsHide: true
130001
+ });
130002
+ running2.child = child;
130003
+ child.stdin?.on("error", (error2) => {
130004
+ this.logger.debug(`[acp-auth] ${displayName} authorization input failed: ${formatErrorMessage(error2)}`);
130005
+ });
130006
+ const outputParser = new BuiltinAuthenticationOutputParser(agentType);
130007
+ const emitOutput = (stream2, chunk) => {
130008
+ const output = String(chunk);
130009
+ if (output.length === 0) return;
130010
+ const authorization = outputParser.push(output);
130011
+ if (authorization) {
130012
+ running2.acceptsAuthorizationCode = authorization.acceptsAuthorizationCode === true;
130013
+ options.onProgress?.({
130014
+ status: "authorization",
130015
+ ...authorization
130016
+ });
130017
+ }
130018
+ options.onProgress?.({
130019
+ status: "output",
130020
+ stream: stream2,
130021
+ output: output.slice(0, 16384)
130022
+ });
130023
+ };
130024
+ child.stdout?.on("data", (chunk) => emitOutput("stdout", chunk));
130025
+ child.stderr?.on("data", (chunk) => emitOutput("stderr", chunk));
130026
+ const exit2 = await new Promise((resolve2) => {
130027
+ let settled = false;
130028
+ const finish = (result) => {
130029
+ if (settled) return;
130030
+ settled = true;
130031
+ resolve2(result);
130032
+ };
130033
+ child.once("error", (error2) => finish({
130034
+ code: null,
130035
+ error: error2
130036
+ }));
130037
+ child.once("exit", (code2) => finish({
130038
+ code: code2
130039
+ }));
130040
+ });
130041
+ const processInterruption = interruptedResult();
130042
+ if (processInterruption) return processInterruption;
130043
+ if (exit2.error !== void 0 || exit2.code !== 0) {
130044
+ const error2 = exit2.error !== void 0 ? formatErrorMessage(exit2.error) : formatAuthenticationExitError(agentType, displayName, exit2.code);
130045
+ options.onProgress?.({
130046
+ status: "error",
130047
+ error: error2
130048
+ });
130049
+ return {
130050
+ success: false,
130051
+ disposition: "error",
130052
+ error: error2
130053
+ };
130054
+ }
130055
+ options.onProgress?.({
130056
+ status: "authenticated"
130057
+ });
130058
+ return {
130059
+ success: true,
130060
+ disposition: "authenticated"
130061
+ };
129670
130062
  } catch (error2) {
129671
130063
  const interruption2 = interruptedResult();
129672
130064
  if (interruption2) return interruption2;
@@ -129689,250 +130081,24 @@ ${fallbackStderrTail}` : errorMessage2;
129689
130081
  }
129690
130082
  }
129691
130083
  }
129692
- async runBuiltinLogin(ctx) {
129693
- const { options, interruptedResult, agentType, displayName } = ctx;
129694
- const launch = await resolveBuiltinAuthenticationProcessLaunch({
129695
- cliType: options.cliType,
129696
- agentType: options.agentType,
129697
- runtimeOverrides: options.runtimeOverrides,
129698
- action: "login"
129699
- });
129700
- if (!launch) {
129701
- throw new Error(`${displayName} authentication is unavailable`);
129702
- }
129703
- const launchInterruption = interruptedResult();
129704
- if (launchInterruption) return launchInterruption;
129705
- const env2 = await buildAuthenticationProcessEnv({
129706
- launch,
129707
- agentType: options.agentType,
129708
- env: options.env,
129709
- resolveLoginShellEnv: this.resolveLoginShellEnv
129710
- });
129711
- const preparationInterruption = interruptedResult();
129712
- if (preparationInterruption) return preparationInterruption;
129713
- options.onProgress?.({
129714
- status: "starting"
129715
- });
129716
- return await this.runLoginProcess({
129717
- ...ctx,
129718
- displayName,
129719
- command: launch.command,
129720
- args: launch.args,
129721
- env: env2,
129722
- parser: new BuiltinAuthenticationOutputParser(agentType),
129723
- formatExitError: (code2) => formatAuthenticationExitError(agentType, displayName, code2),
129724
- acceptsAuthorizationCodeOnStdin: true
129725
- });
130084
+ getAgentType(requestId) {
130085
+ return this.findRunningAuthentication(requestId)?.agentType;
129726
130086
  }
129727
- async runProtocolAuthentication(ctx) {
129728
- const { options, running: running2, interruptedResult } = ctx;
129729
- const launch = await resolveACPProcessLaunchAsync({
129730
- cliType: options.cliType,
129731
- agentType: options.agentType,
129732
- customAcp: options.customAcp,
129733
- runtimeOverrides: options.runtimeOverrides,
129734
- signal: running2.abort.signal
129735
- });
129736
- const launchInterruption = interruptedResult();
129737
- if (launchInterruption) return launchInterruption;
129738
- const env2 = await this.buildAcpAuthenticationProcessEnv(launch, options, {
129739
- protocolStdio: true
129740
- });
129741
- const preparationInterruption = interruptedResult();
129742
- if (preparationInterruption) return preparationInterruption;
129743
- options.onProgress?.({
129744
- status: "starting"
129745
- });
129746
- const outcome = await runAcpProtocolAuthentication({
129747
- launch: {
129748
- command: launch.command,
129749
- args: launch.args
129750
- },
129751
- cliType: options.cliType,
129752
- agentType: options.agentType,
129753
- workdir: os__default$1.homedir(),
129754
- env: env2,
129755
- methodId: options.methodId,
129756
- logger: this.logger,
129757
- signal: running2.abort.signal,
129758
- onProgress: options.onProgress,
129759
- attachProcess: (child) => {
129760
- running2.child = child;
129761
- },
129762
- spawnProcess: this.spawnProcess
129763
- });
129764
- const outcomeInterruption = interruptedResult();
129765
- if (outcomeInterruption) return outcomeInterruption;
129766
- if (outcome.kind === "authenticated") {
129767
- options.onProgress?.({
129768
- status: "authenticated"
129769
- });
129770
- return {
129771
- success: true,
129772
- disposition: "authenticated"
129773
- };
129774
- }
129775
- if (outcome.kind === "method-required") {
129776
- return {
129777
- success: true,
129778
- disposition: "method-required",
129779
- authMethods: outcome.authMethods.map((method) => ({
129780
- type: method.type,
129781
- id: method.id,
129782
- ...method.name ? {
129783
- name: method.name
129784
- } : {},
129785
- ...method.description ? {
129786
- description: method.description
129787
- } : {}
129788
- }))
129789
- };
129790
- }
129791
- if (outcome.kind === "terminal-method") {
129792
- running2.child = void 0;
129793
- return await this.runTerminalAuthMethod(ctx, outcome.method);
129794
- }
129795
- options.onProgress?.({
129796
- status: "error",
129797
- error: outcome.error
129798
- });
129799
- return {
129800
- success: false,
129801
- disposition: "error",
129802
- error: outcome.error
129803
- };
129804
- }
129805
- async runTerminalAuthMethod(ctx, method) {
129806
- const { options, interruptedResult } = ctx;
129807
- const displayName = describeAcpAuthMethod(method);
129808
- const launch = await resolveACPProcessLaunchAsync({
129809
- cliType: options.cliType,
129810
- agentType: options.agentType,
129811
- customAcp: options.customAcp,
129812
- runtimeOverrides: options.runtimeOverrides,
129813
- extraArgs: [
129814
- ...method.args ?? []
129815
- ],
129816
- signal: ctx.running.abort.signal
129817
- });
129818
- const launchInterruption = interruptedResult();
129819
- if (launchInterruption) return launchInterruption;
129820
- const env2 = await this.buildAcpAuthenticationProcessEnv(launch, options, {
129821
- methodEnv: method.env
129822
- });
129823
- const preparationInterruption = interruptedResult();
129824
- if (preparationInterruption) return preparationInterruption;
129825
- return await this.runLoginProcess({
129826
- ...ctx,
129827
- displayName,
129828
- command: launch.command,
129829
- args: launch.args,
129830
- env: env2,
129831
- parser: new AcpAgentAuthorizationOutputParser(),
129832
- formatExitError: (code2) => `${options.agentType} authentication exited with code ${code2 ?? "unknown"}`,
129833
- acceptsAuthorizationCodeOnStdin: false
129834
- });
129835
- }
129836
- async buildAcpAuthenticationProcessEnv(launch, options, settings = {}) {
129837
- const env2 = await buildAuthenticationProcessEnv({
129838
- launch,
129839
- agentType: options.agentType,
129840
- env: settings.methodEnv ? {
129841
- ...options.env,
129842
- ...settings.methodEnv
129843
- } : options.env,
129844
- resolveLoginShellEnv: this.resolveLoginShellEnv
129845
- });
129846
- if (settings.protocolStdio) {
129847
- delete env2.TERM;
129848
- }
129849
- return withLodyNpmCacheForNpx(launch.command, env2);
129850
- }
129851
- async runLoginProcess(ctx) {
129852
- const { options, running: running2, interruptedResult, displayName } = ctx;
129853
- const child = this.spawnProcess(ctx.command, ctx.args, {
129854
- cwd: os__default$1.homedir(),
129855
- env: ctx.env,
129856
- stdio: [
129857
- "pipe",
129858
- "pipe",
129859
- "pipe"
129860
- ],
129861
- detached: process.platform !== "win32",
129862
- windowsHide: true
129863
- });
129864
- running2.child = child;
129865
- if (running2.cancelled || running2.timedOut) {
129866
- this.terminateAuthentication(options.agentType, running2, running2.cancelled ? "cancelled" : "timed out");
129867
- }
129868
- child.stdin?.on("error", (error2) => {
129869
- this.logger.debug(`[acp-auth] ${displayName} authorization input failed: ${formatErrorMessage(error2)}`);
129870
- });
129871
- const emitOutput = (stream2, chunk) => {
129872
- const output = String(chunk);
129873
- if (output.length === 0) return;
129874
- const authorization = ctx.parser.push(output);
129875
- if (authorization) {
129876
- running2.acceptsAuthorizationCode = ctx.acceptsAuthorizationCodeOnStdin && authorization.acceptsAuthorizationCode === true;
129877
- options.onProgress?.({
129878
- status: "authorization",
129879
- ...authorization
129880
- });
129881
- }
129882
- options.onProgress?.({
129883
- status: "output",
129884
- stream: stream2,
129885
- output: output.slice(0, 16384)
129886
- });
129887
- };
129888
- child.stdout?.on("data", (chunk) => emitOutput("stdout", chunk));
129889
- child.stderr?.on("data", (chunk) => emitOutput("stderr", chunk));
129890
- const exit2 = await new Promise((resolve2) => {
129891
- let settled = false;
129892
- const finish = (result) => {
129893
- if (settled) return;
129894
- settled = true;
129895
- resolve2(result);
129896
- };
129897
- child.once("error", (error2) => finish({
129898
- code: null,
129899
- error: error2
129900
- }));
129901
- child.once("exit", (code2) => finish({
129902
- code: code2
129903
- }));
129904
- });
129905
- const processInterruption = interruptedResult();
129906
- if (processInterruption) return processInterruption;
129907
- if (exit2.error !== void 0 || exit2.code !== 0) {
129908
- const error2 = exit2.error !== void 0 ? formatErrorMessage(exit2.error) : ctx.formatExitError(exit2.code);
129909
- options.onProgress?.({
129910
- status: "error",
129911
- error: error2
129912
- });
129913
- return {
129914
- success: false,
129915
- disposition: "error",
129916
- error: error2
129917
- };
129918
- }
129919
- options.onProgress?.({
129920
- status: "authenticated"
129921
- });
129922
- return {
129923
- success: true,
129924
- disposition: "authenticated"
129925
- };
129926
- }
129927
- cancel(agentType, requestId) {
129928
- const running2 = this.runningByAgentType.get(agentType);
129929
- if (!running2 || running2.requestId !== requestId) {
130087
+ cancel(requestId) {
130088
+ const active2 = this.findRunningAuthentication(requestId);
130089
+ if (!active2) {
129930
130090
  return {
129931
130091
  success: true,
129932
130092
  disposition: "not-running"
129933
130093
  };
129934
130094
  }
130095
+ const { agentType, running: running2 } = active2;
129935
130096
  running2.cancelled = true;
130097
+ running2.abortController.abort();
130098
+ running2.pendingInteraction?.resolve({
130099
+ action: "cancel"
130100
+ });
130101
+ running2.pendingInteraction = void 0;
129936
130102
  if (!running2.child && this.runningByAgentType.get(agentType) === running2) {
129937
130103
  this.runningByAgentType.delete(agentType);
129938
130104
  }
@@ -129942,14 +130108,15 @@ ${fallbackStderrTail}` : errorMessage2;
129942
130108
  disposition: "cancelled"
129943
130109
  };
129944
130110
  }
129945
- submitAuthorizationCode(agentType, requestId, authorizationCode) {
129946
- const running2 = this.runningByAgentType.get(agentType);
129947
- if (!running2 || running2.requestId !== requestId) {
130111
+ submitAuthorizationCode(requestId, authorizationCode) {
130112
+ const active2 = this.findRunningAuthentication(requestId);
130113
+ if (!active2) {
129948
130114
  return {
129949
130115
  success: true,
129950
130116
  disposition: "not-running"
129951
130117
  };
129952
130118
  }
130119
+ const { agentType, running: running2 } = active2;
129953
130120
  if (!running2.acceptsAuthorizationCode) {
129954
130121
  return {
129955
130122
  success: false,
@@ -129997,8 +130164,327 @@ ${fallbackStderrTail}` : errorMessage2;
129997
130164
  };
129998
130165
  }
129999
130166
  }
130167
+ submitAuthenticationInput(requestId, interactionId, authenticationInput) {
130168
+ const active2 = this.findRunningAuthentication(requestId);
130169
+ if (!active2) {
130170
+ return {
130171
+ success: true,
130172
+ disposition: "not-running"
130173
+ };
130174
+ }
130175
+ const { agentType, running: running2 } = active2;
130176
+ const pending2 = running2.pendingInteraction;
130177
+ if (!pending2 || pending2.id !== interactionId) {
130178
+ return {
130179
+ success: false,
130180
+ disposition: "error",
130181
+ error: `${getBuiltinDisplayName(agentType)} is not waiting for this authentication input`
130182
+ };
130183
+ }
130184
+ const parsedJson = (() => {
130185
+ try {
130186
+ return JSON.parse(authenticationInput);
130187
+ } catch {
130188
+ return null;
130189
+ }
130190
+ })();
130191
+ const parsed = AcpAuthenticationInteractionInputSchema.safeParse(parsedJson);
130192
+ if (!parsed.success) {
130193
+ return {
130194
+ success: false,
130195
+ disposition: "error",
130196
+ error: "Invalid authentication input"
130197
+ };
130198
+ }
130199
+ running2.pendingInteraction = void 0;
130200
+ pending2.resolve(parsed.data);
130201
+ return {
130202
+ success: true,
130203
+ disposition: "input-accepted"
130204
+ };
130205
+ }
130206
+ findRunningAuthentication(requestId) {
130207
+ for (const [agentType, running2] of this.runningByAgentType) {
130208
+ if (running2.requestId === requestId) return {
130209
+ agentType,
130210
+ running: running2
130211
+ };
130212
+ }
130213
+ return void 0;
130214
+ }
130215
+ waitForAuthenticationInput(running2, interactionId) {
130216
+ if (running2.pendingInteraction) {
130217
+ return null;
130218
+ }
130219
+ return new Promise((resolve2) => {
130220
+ running2.pendingInteraction = {
130221
+ id: interactionId,
130222
+ resolve: resolve2
130223
+ };
130224
+ if (running2.abortController.signal.aborted) {
130225
+ running2.pendingInteraction = void 0;
130226
+ resolve2({
130227
+ action: "cancel"
130228
+ });
130229
+ }
130230
+ });
130231
+ }
130232
+ async authenticateProtocolDrivenAcp(options, running2) {
130233
+ const launch = await resolveACPProcessLaunchAsync({
130234
+ cliType: options.cliType,
130235
+ agentType: options.agentType,
130236
+ customAcp: options.customAcp,
130237
+ runtimeOverrides: options.runtimeOverrides,
130238
+ signal: running2.abortController.signal
130239
+ });
130240
+ const env2 = await buildAuthenticationProcessEnv({
130241
+ launch,
130242
+ agentType: options.agentType,
130243
+ env: options.env,
130244
+ resolveLoginShellEnv: this.resolveLoginShellEnv
130245
+ });
130246
+ delete env2.TERM;
130247
+ running2.abortController.signal.throwIfAborted();
130248
+ let lastStderrTail = "";
130249
+ await withAcpSessionStartSlot({
130250
+ label: `acp-auth:${options.agentType}`,
130251
+ logger: this.logger,
130252
+ abortSignal: running2.abortController.signal
130253
+ }, async () => await runNpxStartupWithRecovery({
130254
+ command: launch.command,
130255
+ args: launch.args,
130256
+ env: env2,
130257
+ logger: this.logger,
130258
+ logPrefix: "[acp-auth]",
130259
+ getStderrTail: () => lastStderrTail,
130260
+ attempt: async ({ args: args2 }) => {
130261
+ running2.abortController.signal.throwIfAborted();
130262
+ lastStderrTail = "";
130263
+ options.onProgress?.({
130264
+ status: "starting"
130265
+ });
130266
+ const child = spawnAcpProcess({
130267
+ cliType: options.cliType,
130268
+ agentType: options.agentType,
130269
+ customAcp: options.customAcp,
130270
+ runtimeOverrides: options.runtimeOverrides,
130271
+ workdir: process.cwd(),
130272
+ env: env2,
130273
+ command: launch.command,
130274
+ args: [
130275
+ ...args2
130276
+ ],
130277
+ spawnImpl: this.spawnProcess
130278
+ });
130279
+ running2.child = child;
130280
+ running2.terminating = false;
130281
+ child.stderr?.setEncoding("utf8");
130282
+ const authorizationParser = new AcpAgentAuthorizationOutputParser();
130283
+ child.stderr?.on("data", (chunk) => {
130284
+ lastStderrTail = appendStderrTail(lastStderrTail, chunk);
130285
+ const authorization = authorizationParser.push(chunk);
130286
+ if (authorization && isAllowedAuthorizationUrl(authorization.authorizationUrl)) {
130287
+ options.onProgress?.({
130288
+ status: "authorization",
130289
+ ...authorization
130290
+ });
130291
+ }
130292
+ });
130293
+ const startupMonitor = createAcpStartupMonitor({
130294
+ onExit: (listener) => {
130295
+ child.on("exit", listener);
130296
+ return () => child.off("exit", listener);
130297
+ },
130298
+ onError: (listener) => {
130299
+ child.on("error", listener);
130300
+ return () => child.off("error", listener);
130301
+ }
130302
+ }, {
130303
+ sessionId: `acp-auth:${options.agentType}`,
130304
+ command: launch.command,
130305
+ args: [
130306
+ ...args2
130307
+ ],
130308
+ getStderrTail: () => ""
130309
+ });
130310
+ try {
130311
+ running2.abortController.signal.throwIfAborted();
130312
+ if (!child.stdin || !child.stdout) {
130313
+ throw new Error(`${options.agentType} ACP authentication streams are unavailable`);
130314
+ }
130315
+ let interactionError;
130316
+ const app = client$2({
130317
+ name: "lody-authentication"
130318
+ }).onRequest(methods$1.client.elicitation.create, async ({ params }) => {
130319
+ const raw2 = asRecord(params);
130320
+ if (raw2?.mode === "url") {
130321
+ if (typeof raw2.url !== "string" || !isAllowedAuthorizationUrl(raw2.url)) {
130322
+ const error2 = `${options.agentType} requested an unsafe authentication URL. Lody only opens HTTP and HTTPS authorization pages.`;
130323
+ interactionError = error2;
130324
+ this.logger.debug(`[acp-auth] ${error2}`);
130325
+ options.onProgress?.({
130326
+ status: "error",
130327
+ error: error2
130328
+ });
130329
+ return {
130330
+ action: "decline"
130331
+ };
130332
+ }
130333
+ const interactionId2 = randomUUID();
130334
+ const inputPromise2 = this.waitForAuthenticationInput(running2, interactionId2);
130335
+ if (!inputPromise2) return {
130336
+ action: "decline"
130337
+ };
130338
+ options.onProgress?.({
130339
+ status: "authorization",
130340
+ authorizationUrl: raw2.url,
130341
+ interactionId: interactionId2,
130342
+ message: typeof raw2.message === "string" ? raw2.message.slice(0, ACP_AUTH_TEXT_MAX_LENGTH) : void 0,
130343
+ requiresAuthorizationConsent: true
130344
+ });
130345
+ const input22 = await inputPromise2;
130346
+ return input22.action === "accept" ? {
130347
+ action: "accept"
130348
+ } : {
130349
+ action: input22.action
130350
+ };
130351
+ }
130352
+ const form = toAuthenticationForm(params);
130353
+ if (!form) {
130354
+ const error2 = `${options.agentType} requested an unsupported authentication form or one larger than Lody's ${ACP_AUTHENTICATION_FORM_MAX_BYTES / 1024} KiB limit. Lody currently supports text, secret, and single-select fields.`;
130355
+ interactionError = error2;
130356
+ this.logger.debug(`[acp-auth] ${error2}`);
130357
+ options.onProgress?.({
130358
+ status: "error",
130359
+ error: error2
130360
+ });
130361
+ return {
130362
+ action: "decline"
130363
+ };
130364
+ }
130365
+ const interactionId = randomUUID();
130366
+ const inputPromise = this.waitForAuthenticationInput(running2, interactionId);
130367
+ if (!inputPromise) return {
130368
+ action: "decline"
130369
+ };
130370
+ options.onProgress?.({
130371
+ status: "input-required",
130372
+ interactionId,
130373
+ message: typeof raw2?.message === "string" ? raw2.message.slice(0, ACP_AUTH_TEXT_MAX_LENGTH) : `Enter the information requested by ${options.agentType}`,
130374
+ form
130375
+ });
130376
+ const input2 = await inputPromise;
130377
+ return input2.action === "accept" ? {
130378
+ action: "accept",
130379
+ content: input2.content ?? {}
130380
+ } : {
130381
+ action: input2.action
130382
+ };
130383
+ });
130384
+ const stream2 = ndJsonStream(createStdinWritableStream(child.stdin), createStdoutReadableStream(child.stdout));
130385
+ await Promise.race([
130386
+ app.connectWith(stream2, async (context2) => {
130387
+ const initialized2 = await context2.request(methods$1.agent.initialize, {
130388
+ protocolVersion: PROTOCOL_VERSION,
130389
+ clientCapabilities: {
130390
+ auth: {
130391
+ terminal: false
130392
+ },
130393
+ elicitation: {
130394
+ form: {},
130395
+ url: {}
130396
+ }
130397
+ },
130398
+ clientInfo: {
130399
+ name: "lody",
130400
+ title: "Lody",
130401
+ version: "1"
130402
+ }
130403
+ }, {
130404
+ cancellationSignal: running2.abortController.signal
130405
+ });
130406
+ const advertisedMethods = [
130407
+ ...initialized2.authMethods ?? []
130408
+ ];
130409
+ const methods2 = advertisedMethods.filter((method) => getAuthMethodType(method) === "agent");
130410
+ if (methods2.length === 0) {
130411
+ const unsupportedTypes = new Set(advertisedMethods.map((method) => getAuthMethodType(method)));
130412
+ const hasDeprecatedEnv = unsupportedTypes.has("env_var");
130413
+ const hasUnsupportedTerminal = unsupportedTypes.has("terminal");
130414
+ throw new Error(hasDeprecatedEnv && hasUnsupportedTerminal ? `${options.agentType} only advertised deprecated env_var and unsupported terminal authentication methods` : hasDeprecatedEnv ? `${options.agentType} only advertised the deprecated ACP env_var authentication method` : hasUnsupportedTerminal ? `${options.agentType} only advertised terminal authentication, which requires an interactive terminal that is not available over Machine RPC` : `${options.agentType} did not advertise an authentication method`);
130415
+ }
130416
+ if (methods2.length > ACP_AUTH_METHOD_MAX_COUNT || new Set(methods2.map((method) => method.id)).size !== methods2.length || methods2.some((method) => typeof method.id !== "string" || !method.id.trim() || method.id.length > ACP_AUTH_ID_MAX_LENGTH)) {
130417
+ throw new Error(`${options.agentType} advertised too many or invalid authentication methods`);
130418
+ }
130419
+ let methodId;
130420
+ if (methods2.length === 1) {
130421
+ methodId = methods2[0]?.id;
130422
+ }
130423
+ if (!methodId) {
130424
+ const interactionId = randomUUID();
130425
+ const inputPromise = this.waitForAuthenticationInput(running2, interactionId);
130426
+ if (!inputPromise) {
130427
+ throw new Error(`${options.agentType} requested overlapping authentication interactions`);
130428
+ }
130429
+ options.onProgress?.({
130430
+ status: "auth-methods",
130431
+ interactionId,
130432
+ authMethods: methods2
130433
+ });
130434
+ const input2 = await inputPromise;
130435
+ if (input2.action !== "accept" || !input2.methodId) {
130436
+ throw new DOMException("ACP authentication was cancelled", "AbortError");
130437
+ }
130438
+ methodId = input2.methodId;
130439
+ }
130440
+ const selectedMethod = methods2.find((method) => method.id === methodId);
130441
+ if (!selectedMethod) {
130442
+ const advertisedMethod = advertisedMethods.find((method) => method.id === methodId);
130443
+ if (advertisedMethod) {
130444
+ throw new Error(getAuthMethodType(advertisedMethod) === "env_var" ? `${options.agentType} authentication method ${methodId} uses deprecated env_var authentication` : `${options.agentType} authentication method ${methodId} requires an interactive terminal that is not available over Machine RPC`);
130445
+ }
130446
+ throw new Error(`${options.agentType} no longer advertises authentication method ${methodId}`);
130447
+ }
130448
+ await context2.request(methods$1.agent.authenticate, {
130449
+ methodId
130450
+ }, {
130451
+ cancellationSignal: running2.abortController.signal
130452
+ });
130453
+ if (interactionError) {
130454
+ throw new Error(interactionError);
130455
+ }
130456
+ }),
130457
+ startupMonitor.abortPromise
130458
+ ]);
130459
+ } finally {
130460
+ running2.pendingInteraction?.resolve({
130461
+ action: "cancel"
130462
+ });
130463
+ running2.pendingInteraction = void 0;
130464
+ startupMonitor.dispose();
130465
+ await shutdownLocalAcpAgent({
130466
+ agentProcess: child,
130467
+ logger: this.logger,
130468
+ sessionLabel: `acp-auth:${options.agentType}:protocol`,
130469
+ exitTimeoutMs: this.terminationGraceMs
130470
+ }).catch((error2) => {
130471
+ this.logger.debug(`[acp-auth] Failed to terminate protocol authentication process: ${formatErrorMessage(error2)}`);
130472
+ });
130473
+ if (running2.child === child) running2.child = void 0;
130474
+ }
130475
+ }
130476
+ }));
130477
+ running2.abortController.signal.throwIfAborted();
130478
+ options.onProgress?.({
130479
+ status: "authenticated"
130480
+ });
130481
+ return {
130482
+ success: true,
130483
+ disposition: "authenticated"
130484
+ };
130485
+ }
130000
130486
  terminateAuthentication(agentType, running2, reason) {
130001
- running2.abort.abort();
130487
+ running2.abortController.abort();
130002
130488
  if (running2.terminating || !running2.child) return;
130003
130489
  running2.terminating = true;
130004
130490
  void shutdownLocalAcpAgent({
@@ -134371,6 +134857,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
134371
134857
  };
134372
134858
  const shouldRecoverStaleACPConnectionPrompt = (args2) => !args2.alreadyAttempted && !args2.hasPromptOutput && (isAgentDisconnectedError(args2.error) || isAcpSessionNotFoundError(args2.error));
134373
134859
  const TURN_FINALIZATION_STAGE_WARN_MS = 5e3;
134860
+ const ACP_AUTHENTICATION_WORKFLOW_DEADLINE_MS = 295e3;
134861
+ const ACP_POST_AUTH_REFRESH_MAX_MS = 6e4;
134374
134862
  const SILENT_TURN_FAILURE_MESSAGE = "The agent ended the turn without producing any output. The model call most likely failed upstream (a context-length or rate-limit rejection is the usual cause) and the agent reported it as a normal completion instead of an error. Retry your message, or start a new session if this conversation has grown too long.";
134375
134863
  class SessionTurnCancelled extends TaggedError("SessionTurnCancelled") {
134376
134864
  }
@@ -134419,19 +134907,23 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
134419
134907
  const summarizeAcpAuthMethod = (method) => {
134420
134908
  const record2 = typeof method === "object" && method !== null ? method : {};
134421
134909
  const type2 = record2.type === "terminal" || record2.type === "env_var" ? record2.type : "agent";
134910
+ const boundedString = (value, maxLength) => typeof value === "string" ? value.slice(0, maxLength) : void 0;
134911
+ const id2 = boundedString(record2.id, 1024);
134912
+ const name2 = boundedString(record2.name, 4096);
134913
+ const description2 = boundedString(record2.description, 16384);
134422
134914
  return {
134423
134915
  type: type2,
134424
- ...typeof record2.id === "string" ? {
134425
- id: record2.id
134916
+ ...id2 !== void 0 ? {
134917
+ id: id2
134426
134918
  } : {},
134427
- ...typeof record2.name === "string" ? {
134428
- name: record2.name
134919
+ ...name2 !== void 0 ? {
134920
+ name: name2
134429
134921
  } : {},
134430
- ...typeof record2.description === "string" ? {
134431
- description: record2.description
134922
+ ...description2 !== void 0 ? {
134923
+ description: description2
134432
134924
  } : {},
134433
134925
  ...Array.isArray(record2.args) && record2.args.every((arg) => typeof arg === "string") ? {
134434
- args: record2.args
134926
+ args: record2.args.slice(0, 64).map((arg) => arg.slice(0, 4096))
134435
134927
  } : {}
134436
134928
  };
134437
134929
  };
@@ -137190,11 +137682,14 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
137190
137682
  });
137191
137683
  }
137192
137684
  async authenticateMachineAcp(message, options = {}) {
137685
+ const workflowStartedAt = Date.now();
137686
+ const targetRequestId = message.action === "start" ? message.requestId : message.authenticationRequestId;
137687
+ const activeAgentType = this.acpAuthenticationManager.getAgentType(targetRequestId);
137193
137688
  const base = {
137194
137689
  type: "machine/acp-authenticate_response",
137195
137690
  machineId: this.deps.machineId,
137196
137691
  requestId: message.requestId,
137197
- agentType: message.agentType
137692
+ agentType: activeAgentType ?? "unknown"
137198
137693
  };
137199
137694
  if (message.machineId !== this.deps.machineId) {
137200
137695
  return {
@@ -137207,68 +137702,100 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
137207
137702
  if (message.action === "cancel") {
137208
137703
  return {
137209
137704
  ...base,
137210
- ...this.acpAuthenticationManager.cancel(message.agentType, message.requestId)
137705
+ ...this.acpAuthenticationManager.cancel(message.authenticationRequestId)
137211
137706
  };
137212
137707
  }
137213
137708
  if (message.action === "submit-code") {
137214
- if (!message.authenticationRequestId || !message.authorizationCode) {
137215
- return {
137216
- ...base,
137217
- success: false,
137218
- disposition: "error",
137219
- error: "Missing authentication request or authorization code"
137220
- };
137221
- }
137222
137709
  return {
137223
137710
  ...base,
137224
- ...this.acpAuthenticationManager.submitAuthorizationCode(message.agentType, message.authenticationRequestId, message.authorizationCode)
137711
+ ...this.acpAuthenticationManager.submitAuthorizationCode(message.authenticationRequestId, message.authorizationCode)
137712
+ };
137713
+ }
137714
+ if (message.action === "submit-input") {
137715
+ return {
137716
+ ...base,
137717
+ ...this.acpAuthenticationManager.submitAuthenticationInput(message.authenticationRequestId, message.interactionId, message.authenticationInput)
137718
+ };
137719
+ }
137720
+ const config2 = await this.deps.workspaceDocument.getAgentConfigForMachineLaunch(message.configId, this.deps.machineId);
137721
+ if (!config2 || config2.cliType === "custom" && !config2.customAcp) {
137722
+ return {
137723
+ ...base,
137724
+ success: false,
137725
+ disposition: "error",
137726
+ error: `Provider config not found or invalid on this machine: ${message.configId}`
137225
137727
  };
137226
137728
  }
137729
+ const resolvedBase = {
137730
+ ...base,
137731
+ agentType: config2.agentType
137732
+ };
137227
137733
  const onProgress = (event) => {
137734
+ if (event.status === "auth-methods") {
137735
+ options.onProgress?.({
137736
+ type: "machine/acp-authentication-progress",
137737
+ machineId: this.deps.machineId,
137738
+ requestId: message.requestId,
137739
+ agentType: config2.agentType,
137740
+ status: event.status,
137741
+ interactionId: event.interactionId,
137742
+ authMethods: event.authMethods.map(summarizeAcpAuthMethod)
137743
+ });
137744
+ return;
137745
+ }
137228
137746
  options.onProgress?.({
137229
137747
  type: "machine/acp-authentication-progress",
137230
137748
  machineId: this.deps.machineId,
137231
137749
  requestId: message.requestId,
137232
- agentType: message.agentType,
137750
+ agentType: config2.agentType,
137233
137751
  ...event
137234
137752
  });
137235
137753
  };
137236
137754
  const result = await this.acpAuthenticationManager.authenticate({
137237
137755
  requestId: message.requestId,
137238
- cliType: message.cliType,
137239
- agentType: message.agentType,
137240
- customAcp: message.customAcp,
137241
- runtimeOverrides: message.runtimeOverrides,
137242
- env: message.env,
137243
- methodId: message.methodId,
137756
+ cliType: config2.cliType,
137757
+ agentType: config2.agentType,
137758
+ customAcp: config2.customAcp,
137759
+ runtimeOverrides: config2.runtimeOverrides,
137760
+ env: config2.env,
137244
137761
  onProgress
137245
137762
  });
137246
- if (result.disposition === "method-required") {
137247
- return {
137248
- ...base,
137249
- success: true,
137250
- disposition: "method-required",
137251
- authRequired: true,
137252
- authMethods: result.authMethods.map((method) => ({
137253
- ...method
137254
- }))
137255
- };
137256
- }
137257
- if (result.success && result.disposition === "authenticated" && message.configId) {
137258
- const refresh = await this.refreshMachineAcpCapabilities({
137259
- type: "machine/acp-capabilities-refresh",
137260
- machineId: message.machineId,
137261
- workspaceId: message.workspaceId,
137262
- configId: message.configId,
137263
- cliType: message.cliType,
137264
- agentType: message.agentType,
137265
- customAcp: message.customAcp,
137266
- runtimeOverrides: message.runtimeOverrides,
137267
- env: message.env
137268
- });
137763
+ if (result.success && result.disposition === "authenticated") {
137764
+ const refreshController = new AbortController();
137765
+ const refreshTimeoutMs = Math.max(1, Math.min(ACP_POST_AUTH_REFRESH_MAX_MS, ACP_AUTHENTICATION_WORKFLOW_DEADLINE_MS - (Date.now() - workflowStartedAt)));
137766
+ const refreshTimeout = setTimeout(() => refreshController.abort(), refreshTimeoutMs);
137767
+ refreshTimeout.unref?.();
137768
+ let refresh;
137769
+ try {
137770
+ refresh = await this.refreshMachineAcpCapabilitiesForConfig({
137771
+ type: "machine/acp-capabilities-refresh",
137772
+ machineId: message.machineId,
137773
+ workspaceId: message.workspaceId,
137774
+ configId: message.configId,
137775
+ cliType: config2.cliType,
137776
+ agentType: config2.agentType,
137777
+ customAcp: config2.customAcp,
137778
+ runtimeOverrides: config2.runtimeOverrides,
137779
+ env: config2.env
137780
+ }, {
137781
+ signal: refreshController.signal
137782
+ });
137783
+ } catch (error2) {
137784
+ refresh = {
137785
+ type: "machine/acp-capabilities-refresh_response",
137786
+ machineId: message.machineId,
137787
+ configId: message.configId,
137788
+ cliType: config2.cliType,
137789
+ agentType: config2.agentType,
137790
+ success: false,
137791
+ error: refreshController.signal.aborted ? "Authentication succeeded, but capability verification timed out" : formatErrorMessage(error2)
137792
+ };
137793
+ } finally {
137794
+ clearTimeout(refreshTimeout);
137795
+ }
137269
137796
  if (!refresh.success) {
137270
137797
  return {
137271
- ...base,
137798
+ ...resolvedBase,
137272
137799
  ...result,
137273
137800
  capabilitiesRefreshed: false,
137274
137801
  authRequired: refresh.authRequired,
@@ -137277,13 +137804,13 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
137277
137804
  };
137278
137805
  }
137279
137806
  return {
137280
- ...base,
137807
+ ...resolvedBase,
137281
137808
  ...result,
137282
137809
  capabilitiesRefreshed: true
137283
137810
  };
137284
137811
  }
137285
137812
  return {
137286
- ...base,
137813
+ ...resolvedBase,
137287
137814
  ...result
137288
137815
  };
137289
137816
  }
@@ -137293,12 +137820,34 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
137293
137820
  type: "machine/acp-capabilities-refresh_response",
137294
137821
  machineId: this.deps.machineId,
137295
137822
  configId: message.configId,
137296
- cliType: message.cliType,
137297
- agentType: message.agentType,
137823
+ cliType: "builtin",
137824
+ agentType: "unknown",
137298
137825
  success: false,
137299
137826
  error: `Machine mismatch: expected ${this.deps.machineId}, got ${message.machineId}`
137300
137827
  };
137301
137828
  }
137829
+ const config2 = await this.deps.workspaceDocument.getAgentConfigForMachineLaunch(message.configId, this.deps.machineId);
137830
+ if (!config2) {
137831
+ return {
137832
+ type: "machine/acp-capabilities-refresh_response",
137833
+ machineId: this.deps.machineId,
137834
+ configId: message.configId,
137835
+ cliType: "builtin",
137836
+ agentType: "unknown",
137837
+ success: false,
137838
+ error: `Provider config not found on this machine: ${message.configId}`
137839
+ };
137840
+ }
137841
+ return await this.refreshMachineAcpCapabilitiesForConfig({
137842
+ ...message,
137843
+ cliType: config2.cliType,
137844
+ agentType: config2.agentType,
137845
+ customAcp: config2.customAcp,
137846
+ runtimeOverrides: config2.runtimeOverrides,
137847
+ env: config2.env
137848
+ }, options);
137849
+ }
137850
+ async refreshMachineAcpCapabilitiesForConfig(message, options = {}) {
137302
137851
  const dedupeKey = computeAcpRefreshDedupeKey(message.configId, message.cliType, message.agentType, message.env, message.customAcp, message.runtimeOverrides);
137303
137852
  this.deps.logger.debug(`[acp-capabilities] Refresh requested (cliType=${message.cliType} agentType=${message.agentType})`);
137304
137853
  if (options.signal?.aborted) {
@@ -139003,6 +139552,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
139003
139552
  configOptionValues: entry.inputConfig?.configOptionValues,
139004
139553
  mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
139005
139554
  taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
139555
+ agentRoleId: entry.inputConfig?.agentRoleId,
139556
+ agentRoleRevision: entry.inputConfig?.agentRoleRevision,
139006
139557
  issuePRMentions: entry.inputConfig?.issuePRMentions,
139007
139558
  resume: entry.inputConfig?.resume ?? resolveDispatchAcpSessionId(meta)
139008
139559
  },
@@ -139036,6 +139587,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
139036
139587
  configOptionValues: entry.inputConfig?.configOptionValues,
139037
139588
  mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
139038
139589
  taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
139590
+ agentRoleId: entry.inputConfig?.agentRoleId,
139591
+ agentRoleRevision: entry.inputConfig?.agentRoleRevision,
139039
139592
  issuePRMentions: entry.inputConfig?.issuePRMentions,
139040
139593
  resume: entry.inputConfig?.resume
139041
139594
  },
@@ -139092,6 +139645,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
139092
139645
  configOptionValues: isConfigOptionValueRecord(queuedItem.acpSessionConfig?.configOptionValues) ? queuedItem.acpSessionConfig.configOptionValues : void 0,
139093
139646
  mcpServerIds: normalizeMcpServerIdSelection(queuedItem.acpSessionConfig?.mcpServerIds) ?? [],
139094
139647
  taskToolsEnabled: queuedItem.acpSessionConfig?.taskToolsEnabled === true,
139648
+ agentRoleId: queuedItem.acpSessionConfig?.agentRoleId,
139649
+ agentRoleRevision: queuedItem.acpSessionConfig?.agentRoleRevision,
139095
139650
  issuePRMentions: queuedItem.acpSessionConfig?.issuePRMentions,
139096
139651
  resume: resolveResumableAcpSessionId(meta)
139097
139652
  });
@@ -153575,10 +154130,7 @@ ${edit.newString}` : edit.newString;
153575
154130
  type: "machine/acp-capabilities-refresh",
153576
154131
  machineId: machine.id,
153577
154132
  workspaceId: workspace.id,
153578
- configId: config2.id,
153579
- cliType: config2.cliType,
153580
- agentType: config2.agentType,
153581
- env: config2.env
154133
+ configId: config2.id
153582
154134
  }));
153583
154135
  if (!response2.success) {
153584
154136
  throw new Error(response2.error ?? `Failed to refresh capabilities for ${config2.name} on machine ${machine.id}.`);
@@ -157126,11 +157678,11 @@ ${entry.text}`).join("\n\n");
157126
157678
  return null;
157127
157679
  }
157128
157680
  try {
157129
- const stat2 = await Yt.stat(absolutePath);
157681
+ const stat2 = await Xt.stat(absolutePath);
157130
157682
  if (!stat2.isFile() || stat2.size > (options?.maxBytes ?? defaultMaxTextFileBytes)) {
157131
157683
  return null;
157132
157684
  }
157133
- const content = await Yt.readFile(absolutePath);
157685
+ const content = await Xt.readFile(absolutePath);
157134
157686
  if (content.includes(0)) {
157135
157687
  return null;
157136
157688
  }
@@ -165930,7 +166482,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
165930
166482
  const ACP_OPERATION_TIMEOUT_MS = 12e4;
165931
166483
  const ACP_PROCESS_EXIT_TIMEOUT_MS = 3e3;
165932
166484
  const MAX_LOCAL_PROJECT_HISTORY_CATALOG_SESSIONS = 100;
165933
- function waitForChildProcessExit(child, timeoutMs) {
166485
+ function waitForChildProcessExit$1(child, timeoutMs) {
165934
166486
  if (child.exitCode !== null) {
165935
166487
  return Promise.resolve(true);
165936
166488
  }
@@ -165962,7 +166514,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
165962
166514
  } catch {
165963
166515
  return;
165964
166516
  }
165965
- if (await waitForChildProcessExit(child, ACP_PROCESS_EXIT_TIMEOUT_MS)) {
166517
+ if (await waitForChildProcessExit$1(child, ACP_PROCESS_EXIT_TIMEOUT_MS)) {
165966
166518
  return;
165967
166519
  }
165968
166520
  try {
@@ -165970,7 +166522,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
165970
166522
  } catch {
165971
166523
  return;
165972
166524
  }
165973
- await waitForChildProcessExit(child, ACP_PROCESS_EXIT_TIMEOUT_MS);
166525
+ await waitForChildProcessExit$1(child, ACP_PROCESS_EXIT_TIMEOUT_MS);
165974
166526
  }
165975
166527
  async function withTimeout(promise2, label2) {
165976
166528
  let timeout2 = null;
@@ -167895,38 +168447,59 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
167895
168447
  this.triggerPendingProcessLifecycleAction(response2.requestId);
167896
168448
  }
167897
168449
  },
167898
- refreshMachineAcpCapabilities: async ({ configId, cliType, agentType, customAcp, runtimeOverrides, env: env2, onAcpBinaryProgress, signal }) => await this.executionService.refreshMachineAcpCapabilities({
168450
+ refreshMachineAcpCapabilities: async ({ configId, onAcpBinaryProgress, signal }) => await this.executionService.refreshMachineAcpCapabilities({
167899
168451
  type: "machine/acp-capabilities-refresh",
167900
168452
  machineId: this.machineId,
167901
168453
  workspaceId: this.workspaceId,
167902
- configId,
167903
- cliType,
167904
- agentType,
167905
- customAcp,
167906
- runtimeOverrides,
167907
- env: env2
168454
+ configId
167908
168455
  }, {
167909
168456
  onAcpBinaryProgress,
167910
168457
  signal
167911
168458
  }),
167912
- authenticateMachineAcp: async ({ requestId, action, authenticationRequestId, authorizationCode, methodId, configId, cliType, agentType, customAcp, runtimeOverrides, env: env2, onProgress }) => await this.authenticateMachineAcpAndResumeSetup({
167913
- type: "machine/acp-authenticate",
167914
- machineId: this.machineId,
167915
- workspaceId: this.workspaceId,
167916
- requestId,
167917
- action,
167918
- authenticationRequestId,
167919
- authorizationCode,
167920
- methodId,
167921
- configId,
167922
- cliType,
167923
- agentType,
167924
- customAcp,
167925
- runtimeOverrides,
167926
- env: env2
167927
- }, {
167928
- onProgress
167929
- }),
168459
+ authenticateMachineAcp: async (args2) => {
168460
+ const common2 = {
168461
+ type: "machine/acp-authenticate",
168462
+ machineId: this.machineId,
168463
+ workspaceId: this.workspaceId,
168464
+ requestId: args2.requestId
168465
+ };
168466
+ const message = (() => {
168467
+ switch (args2.action) {
168468
+ case "start":
168469
+ return {
168470
+ ...common2,
168471
+ action: args2.action,
168472
+ configId: args2.configId
168473
+ };
168474
+ case "cancel":
168475
+ return {
168476
+ ...common2,
168477
+ action: args2.action,
168478
+ authenticationRequestId: args2.authenticationRequestId
168479
+ };
168480
+ case "submit-code":
168481
+ return {
168482
+ ...common2,
168483
+ action: args2.action,
168484
+ authenticationRequestId: args2.authenticationRequestId,
168485
+ authorizationCode: args2.authorizationCode
168486
+ };
168487
+ case "submit-input":
168488
+ return {
168489
+ ...common2,
168490
+ action: args2.action,
168491
+ authenticationRequestId: args2.authenticationRequestId,
168492
+ interactionId: args2.interactionId,
168493
+ authenticationInput: args2.authenticationInput
168494
+ };
168495
+ default:
168496
+ throw new Error("Unsupported ACP authentication action");
168497
+ }
168498
+ })();
168499
+ return await this.authenticateMachineAcpAndResumeSetup(message, {
168500
+ onProgress: args2.onProgress
168501
+ });
168502
+ },
167930
168503
  getMachineAcpBinaryStatus: async ({ agentType }) => await this.executionService.getMachineAcpBinaryStatus({
167931
168504
  type: "machine/acp-binary-status",
167932
168505
  machineId: this.machineId,
@@ -171711,19 +172284,64 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
171711
172284
  const project = meta.project;
171712
172285
  const ownerSessionId = meta.parentSessionId ?? sessionId;
171713
172286
  if (project?.kind === "local") {
171714
- const workspaceRoot = await resolveWorkspaceLocalProjectRootPath(this.workspaceDocument.repo, this.workspaceId, this.machineId, project.localProjectId);
171715
- if (!workspaceRoot) {
172287
+ const originalRootPath = await resolveWorkspaceLocalProjectRootPath(this.workspaceDocument.repo, this.workspaceId, this.machineId, project.localProjectId);
172288
+ if (!originalRootPath) {
171716
172289
  return {
171717
172290
  ok: false,
171718
172291
  error: "workspace_unavailable",
171719
172292
  message: `Local project not found in workspace: ${project.localProjectId}`
171720
172293
  };
171721
172294
  }
172295
+ const isLocalWorktree = meta.isWorktree === true || project.useWorktree === true;
172296
+ if (!isLocalWorktree) {
172297
+ return {
172298
+ ok: true,
172299
+ workspaceRoot: originalRootPath,
172300
+ source: `local-project:${project.localProjectId}`,
172301
+ ...ownerSessionIdField(ownerSessionId)
172302
+ };
172303
+ }
172304
+ const worktreeManager = getWorktreeManager({
172305
+ repoId: deriveRepoIdFromLocalProjectPath(originalRootPath),
172306
+ source: {
172307
+ kind: "local-shared",
172308
+ originalRootPath
172309
+ },
172310
+ logger: this.logger
172311
+ });
172312
+ if (worktreeManager.hasWorktree(ownerSessionId)) {
172313
+ return {
172314
+ ok: true,
172315
+ workspaceRoot: worktreeManager.getWorktreeHostPath(ownerSessionId),
172316
+ source: `local-worktree-existing:${ownerSessionId}`,
172317
+ ...ownerSessionIdField(ownerSessionId)
172318
+ };
172319
+ }
172320
+ this.logCodeCollabDebug(`[${sessionId}] Code Collab v2 workspace resolution waiting for local worktree ownerSessionId=${ownerSessionId} project=${project.localProjectId}`);
172321
+ const waited = await waitForSessionWorkspaceRoot({
172322
+ targetSessionId: ownerSessionId,
172323
+ activeSource: ownerSessionId === sessionId ? "active-session-after-wait" : `active-parent-session:${ownerSessionId}`,
172324
+ pendingSource: ownerSessionId === sessionId ? "pending-session-after-wait" : `pending-parent-session:${ownerSessionId}`,
172325
+ timeoutMs: CODE_COLLAB_WORKSPACE_WAIT_TIMEOUT_MS
172326
+ });
172327
+ if (waited) {
172328
+ return waited.ok ? {
172329
+ ...waited,
172330
+ ...ownerSessionIdField(ownerSessionId)
172331
+ } : waited;
172332
+ }
172333
+ if (worktreeManager.hasWorktree(ownerSessionId)) {
172334
+ return {
172335
+ ok: true,
172336
+ workspaceRoot: worktreeManager.getWorktreeHostPath(ownerSessionId),
172337
+ source: `local-worktree-existing-after-wait:${ownerSessionId}`,
172338
+ ...ownerSessionIdField(ownerSessionId)
172339
+ };
172340
+ }
171722
172341
  return {
171723
- ok: true,
171724
- workspaceRoot,
171725
- source: `local-project:${project.localProjectId}`,
171726
- ...ownerSessionIdField(ownerSessionId)
172342
+ ok: false,
172343
+ error: "session_initializing",
172344
+ message: "Session workspace is still being prepared. Code Collab will start after the session is ready."
171727
172345
  };
171728
172346
  }
171729
172347
  if (meta.parentSessionId) {
@@ -173221,7 +173839,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
173221
173839
  }
173222
173840
  async authenticateMachineAcpAndResumeSetup(message, options = {}) {
173223
173841
  const response2 = await this.executionService.authenticateMachineAcp(message, options);
173224
- if (message.action === "start" && message.configId && response2.success && response2.disposition === "authenticated") {
173842
+ if (message.action === "start" && response2.success && response2.disposition === "authenticated") {
173225
173843
  try {
173226
173844
  await this.providerSetupManager.resumeAfterAuthentication(message.configId);
173227
173845
  } catch (error2) {
@@ -192848,20 +193466,29 @@ ${trimmed2}${closing}`;
192848
193466
  phase = "starting";
192849
193467
  startupStage = "bootstrap";
192850
193468
  connectivity;
192851
- backend = {
192852
- authorization: "pending",
192853
- connection: "connecting"
192854
- };
193469
+ backend;
193470
+ backendNotConnectedSinceMs;
192855
193471
  connectedWorkspaces = [];
193472
+ workspaceNotConnectedSinceMs = /* @__PURE__ */ new Map();
192856
193473
  machineId;
192857
193474
  activeSessionCount = 0;
192858
193475
  connectedRoomCount = 0;
192859
- updatedAtMs = Date.now();
193476
+ updatedAtMs;
192860
193477
  issuesByCode = /* @__PURE__ */ new Map();
193478
+ trackBackendConnectionAge;
193479
+ now;
192861
193480
  constructor(options = {}) {
192862
193481
  this.pid = options.pid ?? process.pid;
192863
193482
  this.machineId = options.machineId;
192864
193483
  this.supervisor = options.supervisor;
193484
+ this.trackBackendConnectionAge = options.trackBackendConnectionAge ?? true;
193485
+ this.now = options.now ?? Date.now;
193486
+ this.updatedAtMs = this.now();
193487
+ this.backend = {
193488
+ authorization: "pending",
193489
+ connection: "connecting"
193490
+ };
193491
+ this.backendNotConnectedSinceMs = this.trackBackendConnectionAge ? this.updatedAtMs : void 0;
192865
193492
  }
192866
193493
  setMachineId(machineId) {
192867
193494
  if (this.machineId === machineId) {
@@ -192909,24 +193536,52 @@ ${trimmed2}${closing}`;
192909
193536
  this.touch();
192910
193537
  }
192911
193538
  setBackendConnection(connection2) {
192912
- if (this.backend.connection === connection2) {
193539
+ const nowMs2 = this.now();
193540
+ const notConnectedSinceMs = !this.trackBackendConnectionAge || connection2 === "connected" ? void 0 : this.backend.connection === "connected" ? nowMs2 : this.backendNotConnectedSinceMs ?? nowMs2;
193541
+ if (this.backend.connection === connection2 && this.backendNotConnectedSinceMs === notConnectedSinceMs) {
192913
193542
  return;
192914
193543
  }
192915
193544
  this.backend = {
192916
193545
  ...this.backend,
192917
193546
  connection: connection2
192918
193547
  };
193548
+ this.backendNotConnectedSinceMs = notConnectedSinceMs;
192919
193549
  this.touch();
192920
193550
  }
192921
193551
  setConnectedWorkspaces(workspaces) {
192922
- if (JSON.stringify(this.connectedWorkspaces) === JSON.stringify(workspaces)) {
193552
+ const nowMs2 = this.now();
193553
+ const previousById = new Map(this.connectedWorkspaces.map((workspace) => [
193554
+ workspace.id,
193555
+ workspace
193556
+ ]));
193557
+ const nextWorkspaceNotConnectedSinceMs = /* @__PURE__ */ new Map();
193558
+ const nextWorkspaces = workspaces.map((workspace) => {
193559
+ const previous = previousById.get(workspace.id);
193560
+ const notConnectedSinceMs = !this.trackBackendConnectionAge || workspace.backendConnection === "connected" ? void 0 : previous?.backendConnection === "connected" ? nowMs2 : this.workspaceNotConnectedSinceMs.get(workspace.id) ?? nowMs2;
193561
+ if (notConnectedSinceMs !== void 0) {
193562
+ nextWorkspaceNotConnectedSinceMs.set(workspace.id, notConnectedSinceMs);
193563
+ }
193564
+ return {
193565
+ id: workspace.id,
193566
+ name: workspace.name,
193567
+ slug: workspace.slug,
193568
+ role: workspace.role,
193569
+ backendConnection: workspace.backendConnection
193570
+ };
193571
+ });
193572
+ if (JSON.stringify(this.connectedWorkspaces) === JSON.stringify(nextWorkspaces) && JSON.stringify([
193573
+ ...this.workspaceNotConnectedSinceMs
193574
+ ]) === JSON.stringify([
193575
+ ...nextWorkspaceNotConnectedSinceMs
193576
+ ])) {
192923
193577
  return;
192924
193578
  }
192925
- this.connectedWorkspaces = workspaces;
193579
+ this.connectedWorkspaces = nextWorkspaces;
193580
+ this.workspaceNotConnectedSinceMs = nextWorkspaceNotConnectedSinceMs;
192926
193581
  this.touch();
192927
193582
  }
192928
193583
  upsertIssue(input2) {
192929
- const nowMs2 = Date.now();
193584
+ const nowMs2 = this.now();
192930
193585
  const existing = this.issuesByCode.get(input2.code);
192931
193586
  if (existing) {
192932
193587
  const next2 = {
@@ -192991,6 +193646,14 @@ ${trimmed2}${closing}`;
192991
193646
  connectivity: this.connectivity,
192992
193647
  backend: this.backend,
192993
193648
  connectedWorkspaces: this.connectedWorkspaces,
193649
+ connectionAges: this.trackBackendConnectionAge ? {
193650
+ ...this.backendNotConnectedSinceMs === void 0 ? {} : {
193651
+ backendNotConnectedSinceMs: this.backendNotConnectedSinceMs
193652
+ },
193653
+ ...this.workspaceNotConnectedSinceMs.size === 0 ? {} : {
193654
+ workspaceNotConnectedSinceMs: Object.fromEntries(this.workspaceNotConnectedSinceMs)
193655
+ }
193656
+ } : void 0,
192994
193657
  machineId: this.machineId,
192995
193658
  pid: this.pid,
192996
193659
  updatedAtMs: this.updatedAtMs,
@@ -193017,7 +193680,7 @@ ${trimmed2}${closing}`;
193017
193680
  }
193018
193681
  }
193019
193682
  touch() {
193020
- this.updatedAtMs = Date.now();
193683
+ this.updatedAtMs = this.now();
193021
193684
  this.phase = this.computePhase();
193022
193685
  }
193023
193686
  computePhase() {
@@ -193563,7 +194226,7 @@ Shutting down gracefully${reason}...`);
193563
194226
  }
193564
194227
  if (!hostRecord) {
193565
194228
  hostRecord = parseRecord(value);
193566
- if (!hostRecord || hostRecord.instanceId !== options.instanceId || options.expectedPid !== void 0 && hostRecord.pid !== options.expectedPid || hostRecord.mode !== options.expectedMode) {
194229
+ if (!hostRecord || hostRecord.instanceId !== options.instanceId || options.expectedPid !== void 0 && hostRecord.pid !== options.expectedPid || options.expectedMode !== void 0 && hostRecord.mode !== options.expectedMode) {
193567
194230
  finish({
193568
194231
  ok: false,
193569
194232
  error: "owner_mismatch"
@@ -193729,7 +194392,8 @@ Shutting down gracefully${reason}...`);
193729
194392
  };
193730
194393
  const authFailureExitCode = supervisorIdentity ? EXIT_CODE_AUTH_FAILURE : 1;
193731
194394
  const runtimeStateReporter = new CliRuntimeStateReporter({
193732
- supervisor: toRuntimeSupervisorIdentity(supervisorIdentity)
194395
+ supervisor: toRuntimeSupervisorIdentity(supervisorIdentity),
194396
+ trackBackendConnectionAge: platformKind === "cloud"
193733
194397
  });
193734
194398
  runtimeStateReporter.setStartupStage("bootstrap");
193735
194399
  const electronManaged = supervisorIdentity?.launchMode === "electron";
@@ -197165,7 +197829,7 @@ Shutting down gracefully${reason}...`);
197165
197829
  function requireLib$1() {
197166
197830
  if (hasRequiredLib$1) return lib$1;
197167
197831
  hasRequiredLib$1 = 1;
197168
- const Stream = So;
197832
+ const Stream = xo;
197169
197833
  class MuteStream2 extends Stream {
197170
197834
  #isTTY = null;
197171
197835
  constructor(opts = {}) {
@@ -206643,7 +207307,7 @@ ${page}${helpTipBottom}${choiceDescription}${error2}${ansiEscapes.cursorHide}`;
206643
207307
  function requireStreams() {
206644
207308
  if (hasRequiredStreams) return streams;
206645
207309
  hasRequiredStreams = 1;
206646
- var Buffer2 = require$$0$6.Buffer, Transform2 = So.Transform;
207310
+ var Buffer2 = require$$0$6.Buffer, Transform2 = xo.Transform;
206647
207311
  streams = function(iconv2) {
206648
207312
  iconv2.encodeStream = function encodeStream(encoding2, options) {
206649
207313
  return new IconvLiteEncoderStream(iconv2.getEncoder(encoding2, options), options);
@@ -206863,7 +207527,7 @@ ${page}${helpTipBottom}${choiceDescription}${error2}${ansiEscapes.cursorHide}`;
206863
207527
  return length2;
206864
207528
  };
206865
207529
  if (iconv2.supportsStreams) {
206866
- var Readable2 = So.Readable;
207530
+ var Readable2 = xo.Readable;
206867
207531
  original.ReadableSetEncoding = Readable2.prototype.setEncoding;
206868
207532
  Readable2.prototype.setEncoding = function setEncoding(enc, options) {
206869
207533
  this._readableState.decoder = iconv2.getDecoder(enc, options);
@@ -206884,7 +207548,7 @@ ${page}${helpTipBottom}${choiceDescription}${error2}${ansiEscapes.cursorHide}`;
206884
207548
  Buffer2.prototype.toString = original.BufferToString;
206885
207549
  Buffer2.prototype.write = original.BufferWrite;
206886
207550
  if (iconv2.supportsStreams) {
206887
- var Readable2 = So.Readable;
207551
+ var Readable2 = xo.Readable;
206888
207552
  Readable2.prototype.setEncoding = original.ReadableSetEncoding;
206889
207553
  delete Readable2.prototype.collect;
206890
207554
  }
@@ -221562,7 +222226,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
221562
222226
  data = createReviewBundleSnapshot(bundle);
221563
222227
  }
221564
222228
  const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
221565
- const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-bQ2iglyz.js").then(async (m) => {
222229
+ const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-CGdWKpLa.js").then(async (m) => {
221566
222230
  await m.__tla;
221567
222231
  return m;
221568
222232
  });
@@ -221732,7 +222396,7 @@ ${result.stderr}`;
221732
222396
  const DEFAULT_HEALTHY_RUN_MS = 6e4;
221733
222397
  const DEFAULT_TERMINATION_GRACE_MS = 3e4;
221734
222398
  const DEFAULT_FORCE_KILL_WAIT_MS = 5e3;
221735
- function isChildProcessRunning(child) {
222399
+ function isChildProcessRunning$1(child) {
221736
222400
  return child !== null && child.exitCode === null && child.signalCode === null;
221737
222401
  }
221738
222402
  function runtimeMatchesHost(runtime, host) {
@@ -222152,7 +222816,7 @@ ${result.stderr}`;
222152
222816
  startHealthyRunTimer(run2) {
222153
222817
  this.clearHealthyRunTimer();
222154
222818
  const timer2 = setTimeout(() => {
222155
- if (this.healthyRunTimer !== timer2 || this.activeRun !== run2 || !this.isCurrent(run2.generation) || !isChildProcessRunning(run2.handle.child)) {
222819
+ if (this.healthyRunTimer !== timer2 || this.activeRun !== run2 || !this.isCurrent(run2.generation) || !isChildProcessRunning$1(run2.handle.child)) {
222156
222820
  return;
222157
222821
  }
222158
222822
  this.healthyRunTimer = null;
@@ -222202,7 +222866,7 @@ ${result.stderr}`;
222202
222866
  this.signalChild(run2.handle.child, "SIGTERM");
222203
222867
  }
222204
222868
  signalChild(child, signal) {
222205
- if (!isChildProcessRunning(child)) return;
222869
+ if (!isChildProcessRunning$1(child)) return;
222206
222870
  try {
222207
222871
  child.kill(signal);
222208
222872
  } catch {
@@ -222223,7 +222887,7 @@ ${result.stderr}`;
222223
222887
  }
222224
222888
  }
222225
222889
  async waitForChildExit(child) {
222226
- if (!isChildProcessRunning(child)) return;
222890
+ if (!isChildProcessRunning$1(child)) return;
222227
222891
  await new Promise((resolve2) => {
222228
222892
  let settled = false;
222229
222893
  const finish = () => {
@@ -222235,7 +222899,7 @@ ${result.stderr}`;
222235
222899
  };
222236
222900
  child.once("exit", finish);
222237
222901
  child.once("close", finish);
222238
- if (!isChildProcessRunning(child)) finish();
222902
+ if (!isChildProcessRunning$1(child)) finish();
222239
222903
  });
222240
222904
  }
222241
222905
  async abortable(operation, signal, message) {
@@ -222425,7 +223089,7 @@ ${result.stderr}`;
222425
223089
  }
222426
223090
  buildState() {
222427
223091
  const runtime = this.latestRuntimeState;
222428
- const childRunning = isChildProcessRunning(this.activeRun?.handle.child ?? null);
223092
+ const childRunning = isChildProcessRunning$1(this.activeRun?.handle.child ?? null);
222429
223093
  let phase;
222430
223094
  if (this.desiredState === "stopped") {
222431
223095
  phase = childRunning ? "stopping" : runtime ? phaseFromRuntime(runtime) : "stopped";
@@ -222589,6 +223253,8 @@ ${result.stdout ?? ""}`;
222589
223253
  const DAEMON_RUNNER_READY_FD = 3;
222590
223254
  const DAEMON_RUNNER_READY_TIMEOUT_MS = 3e4;
222591
223255
  const DAEMON_RUNNER_READY_MAX_BUFFER = 8 * 1024;
223256
+ const DAEMON_RUNNER_SHUTDOWN_GRACE_MS = 4e4;
223257
+ const DAEMON_RUNNER_FORCE_KILL_WAIT_MS = 5e3;
222592
223258
  const DaemonRunnerLaunchOutcomeSchema = discriminatedUnion("status", [
222593
223259
  object$1({
222594
223260
  status: literal$1("ready"),
@@ -222621,6 +223287,94 @@ ${result.stdout ?? ""}`;
222621
223287
  } catch {
222622
223288
  }
222623
223289
  }
223290
+ function interpretDaemonRunnerLaunchOutcome(outcome, runnerPid) {
223291
+ switch (outcome.status) {
223292
+ case "ready":
223293
+ return {
223294
+ outcome: {
223295
+ status: "ready",
223296
+ pid: runnerPid,
223297
+ instanceId: outcome.instanceId
223298
+ },
223299
+ cancelRunner: false
223300
+ };
223301
+ case "occupied":
223302
+ return {
223303
+ outcome: {
223304
+ status: "occupied",
223305
+ runnerPid,
223306
+ ownerMode: outcome.ownerMode,
223307
+ ownerPid: outcome.ownerPid
223308
+ },
223309
+ cancelRunner: false
223310
+ };
223311
+ case "error":
223312
+ return {
223313
+ outcome: {
223314
+ status: "error",
223315
+ runnerPid,
223316
+ message: outcome.message
223317
+ },
223318
+ cancelRunner: true
223319
+ };
223320
+ default: {
223321
+ const unreachable = outcome;
223322
+ return unreachable;
223323
+ }
223324
+ }
223325
+ }
223326
+ function isChildProcessRunning(child) {
223327
+ return child.exitCode === null && child.signalCode === null;
223328
+ }
223329
+ async function waitForChildProcessExit(child, timeoutMs) {
223330
+ if (!isChildProcessRunning(child)) return true;
223331
+ return await new Promise((resolve2) => {
223332
+ let settled = false;
223333
+ let timeout2;
223334
+ let onExit2;
223335
+ const finish = (exited) => {
223336
+ if (settled) return;
223337
+ settled = true;
223338
+ if (timeout2 !== void 0) clearTimeout(timeout2);
223339
+ child.off("exit", onExit2);
223340
+ child.off("close", onExit2);
223341
+ resolve2(exited);
223342
+ };
223343
+ onExit2 = () => finish(true);
223344
+ timeout2 = setTimeout(() => finish(!isChildProcessRunning(child)), timeoutMs);
223345
+ child.once("exit", onExit2);
223346
+ child.once("close", onExit2);
223347
+ if (!isChildProcessRunning(child)) finish(true);
223348
+ });
223349
+ }
223350
+ async function terminateSpawnedDaemonRunner(child, runnerPid, options = {}) {
223351
+ if (!isChildProcessRunning(child)) return true;
223352
+ const pidRecord = readPidFileRecord();
223353
+ let gracefulShutdownRequested = false;
223354
+ if (pidRecord?.pid === runnerPid) {
223355
+ const requested = await requestLocalCliHostShutdown({
223356
+ instanceId: pidRecord.instanceId,
223357
+ token: pidRecord.controlToken,
223358
+ expectedPid: runnerPid,
223359
+ expectedMode: "daemon"
223360
+ });
223361
+ gracefulShutdownRequested = requested.ok;
223362
+ }
223363
+ if (!gracefulShutdownRequested) {
223364
+ try {
223365
+ child.kill("SIGTERM");
223366
+ } catch {
223367
+ }
223368
+ }
223369
+ if (await waitForChildProcessExit(child, options.shutdownGraceMs ?? DAEMON_RUNNER_SHUTDOWN_GRACE_MS)) {
223370
+ return true;
223371
+ }
223372
+ try {
223373
+ child.kill("SIGKILL");
223374
+ } catch {
223375
+ }
223376
+ return await waitForChildProcessExit(child, options.forceKillWaitMs ?? DAEMON_RUNNER_FORCE_KILL_WAIT_MS);
223377
+ }
222624
223378
  async function spawnDaemonRunnerAndAwaitReady(passthroughArgs, options = {}) {
222625
223379
  const bin = resolveLodyBin();
222626
223380
  const env2 = {
@@ -222658,26 +223412,30 @@ ${result.stdout ?? ""}`;
222658
223412
  };
222659
223413
  }
222660
223414
  const readyPipe = child.stdio[DAEMON_RUNNER_READY_FD] ?? null;
222661
- const result = await new Promise((resolve2) => {
223415
+ const waitResult = await new Promise((resolve2) => {
222662
223416
  let settled = false;
222663
223417
  let buffer2 = "";
222664
- const finish = (outcome) => {
223418
+ let timeout2;
223419
+ const finish = (outcome, cancelRunner = false) => {
222665
223420
  if (settled) return;
222666
223421
  settled = true;
222667
- clearTimeout(timeout2);
222668
- resolve2(outcome);
223422
+ if (timeout2 !== void 0) clearTimeout(timeout2);
223423
+ resolve2({
223424
+ outcome,
223425
+ cancelRunner
223426
+ });
222669
223427
  };
222670
- const timeout2 = setTimeout(() => finish({
223428
+ timeout2 = setTimeout(() => finish({
222671
223429
  status: "timeout",
222672
223430
  runnerPid
222673
- }), options.timeoutMs ?? DAEMON_RUNNER_READY_TIMEOUT_MS);
223431
+ }, true), options.timeoutMs ?? DAEMON_RUNNER_READY_TIMEOUT_MS);
222674
223432
  timeout2.unref?.();
222675
223433
  if (!readyPipe) {
222676
223434
  finish({
222677
223435
  status: "error",
222678
223436
  runnerPid,
222679
223437
  message: "readiness channel unavailable"
222680
- });
223438
+ }, true);
222681
223439
  return;
222682
223440
  }
222683
223441
  readyPipe.on("data", (chunk) => {
@@ -222689,7 +223447,7 @@ ${result.stdout ?? ""}`;
222689
223447
  status: "error",
222690
223448
  runnerPid,
222691
223449
  message: "invalid readiness report"
222692
- });
223450
+ }, true);
222693
223451
  }
222694
223452
  return;
222695
223453
  }
@@ -222701,7 +223459,7 @@ ${result.stdout ?? ""}`;
222701
223459
  status: "error",
222702
223460
  runnerPid,
222703
223461
  message: "invalid readiness report"
222704
- });
223462
+ }, true);
222705
223463
  return;
222706
223464
  }
222707
223465
  const outcome = DaemonRunnerLaunchOutcomeSchema.safeParse(parsed);
@@ -222710,41 +223468,31 @@ ${result.stdout ?? ""}`;
222710
223468
  status: "error",
222711
223469
  runnerPid,
222712
223470
  message: "invalid readiness report"
222713
- });
223471
+ }, true);
222714
223472
  return;
222715
223473
  }
222716
- if (outcome.data.status === "ready") {
222717
- finish({
222718
- status: "ready",
222719
- pid: runnerPid,
222720
- instanceId: outcome.data.instanceId
222721
- });
222722
- } else if (outcome.data.status === "occupied") {
222723
- finish({
222724
- status: "occupied",
222725
- runnerPid,
222726
- ownerMode: outcome.data.ownerMode,
222727
- ownerPid: outcome.data.ownerPid
222728
- });
222729
- } else {
222730
- finish({
222731
- status: "error",
222732
- runnerPid,
222733
- message: outcome.data.message
222734
- });
222735
- }
223474
+ const interpreted = interpretDaemonRunnerLaunchOutcome(outcome.data, runnerPid);
223475
+ finish(interpreted.outcome, interpreted.cancelRunner);
222736
223476
  });
222737
223477
  readyPipe.once("end", () => finish({
222738
223478
  status: "runner_exited",
222739
223479
  runnerPid
222740
- }));
223480
+ }, true));
222741
223481
  readyPipe.once("error", () => finish({
222742
223482
  status: "runner_exited",
222743
223483
  runnerPid
222744
- }));
223484
+ }, true));
222745
223485
  });
222746
223486
  readyPipe?.removeAllListeners();
222747
223487
  readyPipe?.destroy();
223488
+ let result = waitResult.outcome;
223489
+ if (waitResult.cancelRunner && !await terminateSpawnedDaemonRunner(child, runnerPid)) {
223490
+ result = {
223491
+ status: "error",
223492
+ runnerPid,
223493
+ message: `Daemon launch failed (${result.status}) and runner ${runnerPid} did not exit`
223494
+ };
223495
+ }
222748
223496
  child.unref();
222749
223497
  return result;
222750
223498
  }
@@ -222849,21 +223597,115 @@ ${result.stdout ?? ""}`;
222849
223597
  ...sanitized
222850
223598
  ];
222851
223599
  }
222852
- function formatDaemonBackendStatus(runtimeState) {
223600
+ const DAEMON_CONNECTION_ERROR_AFTER_MS = 6e4;
223601
+ const defaultPalette = {
223602
+ success: chalk.green,
223603
+ warning: chalk.yellow,
223604
+ error: chalk.red,
223605
+ muted: chalk.gray
223606
+ };
223607
+ function formatElapsed(elapsedMs) {
223608
+ const totalSeconds = Math.max(0, Math.floor(elapsedMs / 1e3));
223609
+ if (totalSeconds < 60) return `${totalSeconds}s`;
223610
+ const totalMinutes = Math.floor(totalSeconds / 60);
223611
+ const seconds2 = totalSeconds % 60;
223612
+ if (totalMinutes < 60) {
223613
+ return seconds2 === 0 ? `${totalMinutes}m` : `${totalMinutes}m ${seconds2}s`;
223614
+ }
223615
+ const totalHours = Math.floor(totalMinutes / 60);
223616
+ const minutes2 = totalMinutes % 60;
223617
+ if (totalHours < 24) {
223618
+ return minutes2 === 0 ? `${totalHours}h` : `${totalHours}h ${minutes2}m`;
223619
+ }
223620
+ const days2 = Math.floor(totalHours / 24);
223621
+ const hours2 = totalHours % 24;
223622
+ return hours2 === 0 ? `${days2}d` : `${days2}d ${hours2}h`;
223623
+ }
223624
+ function formatAuthorization(authorization, palette) {
223625
+ switch (authorization) {
223626
+ case "authorized":
223627
+ return palette.success(authorization);
223628
+ case "pending":
223629
+ return palette.warning(authorization);
223630
+ case "rejected":
223631
+ return palette.error(authorization);
223632
+ case "unknown":
223633
+ return palette.muted(authorization);
223634
+ default: {
223635
+ const unreachable = authorization;
223636
+ return unreachable;
223637
+ }
223638
+ }
223639
+ }
223640
+ function formatConnection(connection2, notConnectedSinceMs, options) {
223641
+ if (connection2 === "connected") {
223642
+ return {
223643
+ formatted: options.palette.success(connection2),
223644
+ unavailableFor: null,
223645
+ stale: false
223646
+ };
223647
+ }
223648
+ if (connection2 === "unknown") {
223649
+ return {
223650
+ formatted: options.palette.muted(connection2),
223651
+ unavailableFor: null,
223652
+ stale: false
223653
+ };
223654
+ }
223655
+ const elapsedMs = notConnectedSinceMs === void 0 ? null : Math.max(0, options.nowMs - notConnectedSinceMs);
223656
+ const unavailableFor = elapsedMs === null ? null : formatElapsed(elapsedMs);
223657
+ const label2 = unavailableFor === null ? connection2 : `${connection2} (${unavailableFor})`;
223658
+ const stale = elapsedMs !== null && elapsedMs >= options.connectionErrorAfterMs;
223659
+ const tone = stale || connection2 === "disconnected" ? options.palette.error : options.palette.warning;
223660
+ return {
223661
+ formatted: tone(label2),
223662
+ unavailableFor,
223663
+ stale
223664
+ };
223665
+ }
223666
+ function formatDaemonConnectivityStatus(connectivity, palette = defaultPalette) {
223667
+ switch (connectivity) {
223668
+ case "online":
223669
+ return palette.success(connectivity);
223670
+ case "reconnecting":
223671
+ return palette.warning(connectivity);
223672
+ case "offline":
223673
+ return palette.error(connectivity);
223674
+ default: {
223675
+ const unreachable = connectivity;
223676
+ return unreachable;
223677
+ }
223678
+ }
223679
+ }
223680
+ function formatDaemonBackendStatus(runtimeState, options = {}) {
223681
+ const resolvedOptions = {
223682
+ nowMs: options.nowMs ?? Date.now(),
223683
+ connectionErrorAfterMs: options.connectionErrorAfterMs ?? DAEMON_CONNECTION_ERROR_AFTER_MS,
223684
+ palette: options.palette ?? defaultPalette
223685
+ };
223686
+ const authorization = runtimeState.backend?.authorization ?? "unknown";
223687
+ const backendConnection = formatConnection(runtimeState.backend?.connection ?? "unknown", runtimeState.connectionAges?.backendNotConnectedSinceMs, resolvedOptions);
222853
223688
  const lines2 = [
222854
- ` Backend Auth: ${runtimeState.backend?.authorization ?? "unknown"}`,
222855
- ` Backend Link: ${runtimeState.backend?.connection ?? "unknown"}`
223689
+ ` Backend Auth: ${formatAuthorization(authorization, resolvedOptions.palette)}`,
223690
+ ` Backend Link: ${backendConnection.formatted}`
222856
223691
  ];
223692
+ if (backendConnection.stale && backendConnection.unavailableFor) {
223693
+ lines2.push(resolvedOptions.palette.error(` Backend Error: not connected for ${backendConnection.unavailableFor}`));
223694
+ }
222857
223695
  if (!runtimeState.connectedWorkspaces) {
222858
- lines2.push(" Workspaces: unavailable");
223696
+ lines2.push(` Workspaces: ${resolvedOptions.palette.muted("unavailable")}`);
222859
223697
  return lines2;
222860
223698
  }
222861
223699
  lines2.push(` Workspaces: ${runtimeState.connectedWorkspaces.length}`);
222862
223700
  for (const workspace of runtimeState.connectedWorkspaces) {
222863
223701
  const label2 = workspace.slug ? `${workspace.name} (${workspace.slug})` : workspace.name;
223702
+ const connection2 = formatConnection(workspace.backendConnection, runtimeState.connectionAges?.workspaceNotConnectedSinceMs?.[workspace.id], resolvedOptions);
222864
223703
  lines2.push(` - ${label2} [${workspace.role}]`);
222865
223704
  lines2.push(` ID: ${workspace.id}`);
222866
- lines2.push(` Backend: ${workspace.backendConnection}`);
223705
+ lines2.push(` Backend: ${connection2.formatted}`);
223706
+ if (connection2.stale && connection2.unavailableFor) {
223707
+ lines2.push(resolvedOptions.palette.error(` Error: not connected for ${connection2.unavailableFor}`));
223708
+ }
222867
223709
  }
222868
223710
  return lines2;
222869
223711
  }
@@ -222959,7 +223801,7 @@ ${result.stdout ?? ""}`;
222959
223801
  };
222960
223802
  case "error":
222961
223803
  return {
222962
- status: "runner_error",
223804
+ status: "startup_error",
222963
223805
  pid: result.runnerPid,
222964
223806
  message: result.message
222965
223807
  };
@@ -222974,7 +223816,7 @@ ${result.stdout ?? ""}`;
222974
223816
  };
222975
223817
  case "timeout":
222976
223818
  return {
222977
- status: "claim_timeout",
223819
+ status: "startup_timeout",
222978
223820
  pid: result.runnerPid
222979
223821
  };
222980
223822
  default: {
@@ -223085,11 +223927,11 @@ ${result.stdout ?? ""}`;
223085
223927
  await exitDaemonCommand(1);
223086
223928
  return;
223087
223929
  }
223088
- if (result.status === "runner_error") {
223930
+ if (result.status === "startup_error") {
223089
223931
  captureDaemonEvent("daemon_start_failed", {
223090
- reason_code: "runner_error"
223932
+ reason_code: "startup_error"
223091
223933
  });
223092
- console.error(`Daemon runner (PID ${result.pid}) failed to start: ${result.message}`);
223934
+ console.error(`Daemon startup (runner PID ${result.pid}) failed: ${result.message}`);
223093
223935
  await exitDaemonCommand(1);
223094
223936
  return;
223095
223937
  }
@@ -223097,15 +223939,15 @@ ${result.stdout ?? ""}`;
223097
223939
  captureDaemonEvent("daemon_start_failed", {
223098
223940
  reason_code: "runner_exited"
223099
223941
  });
223100
- console.error(`Daemon runner (PID ${result.pid}) exited before claiming ownership.`);
223942
+ console.error(`Daemon runner (PID ${result.pid}) exited before its worker became ready.`);
223101
223943
  await exitDaemonCommand(1);
223102
223944
  return;
223103
223945
  }
223104
- if (result.status === "claim_timeout") {
223946
+ if (result.status === "startup_timeout") {
223105
223947
  captureDaemonEvent("daemon_start_failed", {
223106
- reason_code: "claim_timeout"
223948
+ reason_code: "startup_timeout"
223107
223949
  });
223108
- console.error(`Daemon runner (PID ${result.pid}) did not claim ownership in time.`);
223950
+ console.error(`Daemon worker (PID ${result.pid}) did not become ready in time.`);
223109
223951
  await exitDaemonCommand(1);
223110
223952
  return;
223111
223953
  }
@@ -223167,9 +224009,9 @@ ${result.stdout ?? ""}`;
223167
224009
  console.log(` Stage: ${runtimeState.startupStage}`);
223168
224010
  }
223169
224011
  if (runtimeBelongsToDaemon && runtimeState.connectivity) {
223170
- console.log(` Connectivity: ${runtimeState.connectivity}`);
224012
+ console.log(` Connectivity: ${formatDaemonConnectivityStatus(runtimeState.connectivity)}`);
223171
224013
  }
223172
- if (runtimeBelongsToDaemon) {
224014
+ if (runtimeBelongsToDaemon && getCliPlatformKind() === "cloud") {
223173
224015
  for (const line3 of formatDaemonBackendStatus(runtimeState)) {
223174
224016
  console.log(line3);
223175
224017
  }
@@ -223302,18 +224144,18 @@ ${result.stdout ?? ""}`;
223302
224144
  await exitDaemonCommand(1);
223303
224145
  return;
223304
224146
  }
223305
- if (startResult.status === "runner_error") {
223306
- console.error(`Daemon runner (PID ${startResult.pid}) failed to start: ${startResult.message}`);
224147
+ if (startResult.status === "startup_error") {
224148
+ console.error(`Daemon startup (runner PID ${startResult.pid}) failed: ${startResult.message}`);
223307
224149
  await exitDaemonCommand(1);
223308
224150
  return;
223309
224151
  }
223310
224152
  if (startResult.status === "runner_exited") {
223311
- console.error(`Daemon runner (PID ${startResult.pid}) exited before claiming ownership.`);
224153
+ console.error(`Daemon runner (PID ${startResult.pid}) exited before its worker became ready.`);
223312
224154
  await exitDaemonCommand(1);
223313
224155
  return;
223314
224156
  }
223315
- if (startResult.status === "claim_timeout") {
223316
- console.error(`Daemon runner (PID ${startResult.pid}) did not claim ownership in time.`);
224157
+ if (startResult.status === "startup_timeout") {
224158
+ console.error(`Daemon worker (PID ${startResult.pid}) did not become ready in time.`);
223317
224159
  await exitDaemonCommand(1);
223318
224160
  return;
223319
224161
  }
@@ -223325,6 +224167,23 @@ ${result.stdout ?? ""}`;
223325
224167
  await exitDaemonCommand(0);
223326
224168
  return;
223327
224169
  }));
224170
+ const MAX_STARTUP_ERROR_CHARS = 2e3;
224171
+ function isDaemonWorkerReady(state2) {
224172
+ return state2.runtime?.startupStage === "ready" && state2.runtime.phase !== "fatal";
224173
+ }
224174
+ function isRetryableDaemonWorkerStartupExit(result) {
224175
+ return result.code === EXIT_CODE_RETRYABLE_STARTUP;
224176
+ }
224177
+ function describeDaemonWorkerStartupFailure(result) {
224178
+ const output = (result.stderr.trim() || result.stdout.trim()).split("\0").join("");
224179
+ if (output) {
224180
+ return output.length <= MAX_STARTUP_ERROR_CHARS ? output : `\u2026${output.slice(-MAX_STARTUP_ERROR_CHARS)}`;
224181
+ }
224182
+ if (result.signal) {
224183
+ return `CLI worker exited from signal ${result.signal} before becoming ready`;
224184
+ }
224185
+ return `CLI worker exited with code ${result.code ?? "unknown"} before becoming ready`;
224186
+ }
223328
224187
  function launchLodyStart(passthroughArgs, identity2) {
223329
224188
  const bin = resolveLodyBin();
223330
224189
  const args2 = [
@@ -223406,6 +224265,12 @@ ${result.stdout ?? ""}`;
223406
224265
  instanceId: randomUUID(),
223407
224266
  token: `${randomUUID()}${randomUUID()}`
223408
224267
  };
224268
+ let launchOutcomePending = process.env[DAEMON_RUNNER_READY_FD_ENV] !== void 0;
224269
+ const reportLaunchOutcome = (outcome) => {
224270
+ if (!launchOutcomePending) return;
224271
+ launchOutcomePending = false;
224272
+ reportDaemonRunnerLaunchOutcome(outcome);
224273
+ };
223409
224274
  let hostShutdownRequested = false;
223410
224275
  let hostShutdownHandler = null;
223411
224276
  const requestHostShutdown = () => {
@@ -223424,7 +224289,7 @@ ${result.stdout ?? ""}`;
223424
224289
  if (initialLease.status === "occupied") {
223425
224290
  const owner = initialLease.record ? `${initialLease.record.mode} process ${initialLease.record.pid}` : "another local CLI host";
223426
224291
  logger2.error(`Cannot start daemon: ${owner} already owns the local agent runtime.`);
223427
- reportDaemonRunnerLaunchOutcome({
224292
+ reportLaunchOutcome({
223428
224293
  status: "occupied",
223429
224294
  ...initialLease.record ? {
223430
224295
  ownerMode: initialLease.record.mode,
@@ -223443,18 +224308,13 @@ ${result.stdout ?? ""}`;
223443
224308
  hostLease = null;
223444
224309
  const message = error2 instanceof Error ? error2.message : String(error2);
223445
224310
  logger2.error(`Failed to claim daemon ownership: ${message}`);
223446
- reportDaemonRunnerLaunchOutcome({
224311
+ reportLaunchOutcome({
223447
224312
  status: "error",
223448
224313
  message
223449
224314
  });
223450
224315
  await flushTelemetry();
223451
224316
  process.exit(1);
223452
224317
  }
223453
- reportDaemonRunnerLaunchOutcome({
223454
- status: "ready",
223455
- pid: process.pid,
223456
- instanceId: supervisorIdentity.instanceId
223457
- });
223458
224318
  logger2.info(`Daemon watchdog started (PID ${process.pid})`);
223459
224319
  await normalizeCurrentProcessResourceProfile(logger2);
223460
224320
  for (const diagnostic of getRuntimeDiagnostics(version$9)) {
@@ -223581,6 +224441,17 @@ ${result.stdout ?? ""}`;
223581
224441
  }
223582
224442
  },
223583
224443
  decideExit: async (result, signal) => {
224444
+ if (launchOutcomePending && !isRetryableDaemonWorkerStartupExit(result)) {
224445
+ const message = describeDaemonWorkerStartupFailure(result);
224446
+ reportLaunchOutcome({
224447
+ status: "error",
224448
+ message
224449
+ });
224450
+ return {
224451
+ action: "fatal",
224452
+ message: `Initial daemon worker startup failed: ${message}`
224453
+ };
224454
+ }
223584
224455
  if (result.code === 0) {
223585
224456
  return {
223586
224457
  action: "stop",
@@ -223648,6 +224519,13 @@ ${result.stdout ?? ""}`;
223648
224519
  },
223649
224520
  onStateChange: (state2) => {
223650
224521
  reportSupervisorAnalytics(state2);
224522
+ if (launchOutcomePending && isDaemonWorkerReady(state2)) {
224523
+ reportLaunchOutcome({
224524
+ status: "ready",
224525
+ pid: process.pid,
224526
+ instanceId: supervisorIdentity.instanceId
224527
+ });
224528
+ }
223651
224529
  if (state2.phase === "fatal") {
223652
224530
  logger2.error(`Fatal: ${state2.message ?? "unknown"}`);
223653
224531
  } else if (state2.message) {
@@ -239877,6 +240755,8 @@ ${result.stdout ?? ""}`;
239877
240755
  const SESSION_CREATE_MANY_TOOL_NAME = "lody_session_create_many";
239878
240756
  const SESSION_CHAT_MANY_TOOL_NAME = "lody_session_chat_many";
239879
240757
  const SESSION_ARCHIVE_TOOL_NAME = "lody_session_archive";
240758
+ const SESSION_RENAME_TOOL_NAME = "lody_session_rename";
240759
+ const SESSION_RENAME_MANY_TOOL_NAME = "lody_session_rename_many";
239880
240760
  const OPERATION_GET_TOOL_NAME = "lody_operation_get";
239881
240761
  const OPERATION_CANCEL_TOOL_NAME = "lody_operation_cancel";
239882
240762
  const TASK_LIST_TOOL_NAME = "lody_task_list";
@@ -239901,6 +240781,7 @@ ${result.stdout ?? ""}`;
239901
240781
  const DEFAULT_MCP_SESSION_HISTORY_LIMIT = 10;
239902
240782
  const MAX_MCP_SESSION_HISTORY_LIMIT = 50;
239903
240783
  const MAX_MCP_SESSION_HISTORY_BYTES = 128 * 1024;
240784
+ const MAX_MCP_SESSION_TITLE_CHARS = 200;
239904
240785
  const MAX_MCP_TASK_BODY_BYTES = 64 * 1024;
239905
240786
  const MAX_MCP_TASK_LINKS = 50;
239906
240787
  const MAX_MCP_TASK_EDIT_CHARS = 64e3;
@@ -240031,7 +240912,7 @@ ${result.stdout ?? ""}`;
240031
240912
  resume: boolean().optional().describe("Set to true to resume an accepted Operation without resending its input."),
240032
240913
  wait: literal$1(true).optional().describe("Wait for the assistant reply using the temporary legacy adapter."),
240033
240914
  timeoutSeconds: number$4().int().positive().max(MAX_MCP_SESSION_WAIT_TIMEOUT_SECONDS).optional().describe("Legacy wait timeout in seconds, up to one hour."),
240034
- useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session; cannot be combined with workContext."),
240915
+ useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session that reuses the exact same workspace directory; cannot be combined with workContext."),
240035
240916
  workContext: SessionWorkContextInputSchema.optional().describe("Execution context for an independent Session; cannot be combined with useCurrentSessionAsParent=true.")
240036
240917
  }).strict().superRefine((value, ctx) => {
240037
240918
  const result = SessionCreateRuntimeInputSchema.safeParse(value);
@@ -240153,7 +241034,7 @@ ${result.stdout ?? ""}`;
240153
241034
  ]);
240154
241035
  const SessionCreateBatchPublishedItemSchema = object$1({
240155
241036
  ...SessionCreateBatchItemShape,
240156
- useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session; cannot be combined with workContext."),
241037
+ useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session that reuses the exact same workspace directory; cannot be combined with workContext."),
240157
241038
  workContext: SessionWorkContextInputSchema.optional().describe("Execution context for an independent Session; cannot be combined with useCurrentSessionAsParent=true.")
240158
241039
  }).strict();
240159
241040
  const SessionCreateManyToolInputSchema = object$1({
@@ -240185,6 +241066,18 @@ ${result.stdout ?? ""}`;
240185
241066
  const SessionArchiveToolInputSchema = object$1({
240186
241067
  sessionId: string$1().trim().min(1)
240187
241068
  }).strict();
241069
+ const SessionTitleToolInputSchema = string$1().trim().min(1).max(MAX_MCP_SESSION_TITLE_CHARS).describe(`New session title, up to ${MAX_MCP_SESSION_TITLE_CHARS} characters.`);
241070
+ const SessionRenameToolInputSchema = object$1({
241071
+ sessionId: string$1().trim().min(1).optional().describe("Target session id, or current. Defaults to current."),
241072
+ title: SessionTitleToolInputSchema
241073
+ }).strict();
241074
+ const SessionRenameManyItemSchema = object$1({
241075
+ sessionId: string$1().trim().min(1).describe("Target session id, or current."),
241076
+ title: SessionTitleToolInputSchema
241077
+ }).strict();
241078
+ const SessionRenameManyToolInputSchema = object$1({
241079
+ items: array$2(SessionRenameManyItemSchema).min(1).max(MAX_MCP_COMMAND_BATCH_SIZE).refine((items2) => new Set(items2.map((item) => item.sessionId)).size === items2.length, "sessionId values must be unique")
241080
+ }).strict();
240188
241081
  const SessionStatusManyToolInputSchema = object$1({
240189
241082
  sessionIds: array$2(string$1().trim().min(1)).max(1e3).refine((items2) => new Set(items2).size === items2.length, "sessionIds must be unique")
240190
241083
  }).strict();
@@ -240299,30 +241192,22 @@ ${result.stdout ?? ""}`;
240299
241192
  } : {}
240300
241193
  });
240301
241194
  const jsonTextResult = (value, isError2 = false) => textResult(JSON.stringify(value, null, 2), isError2);
240302
- const mcpErrorResult = (error2) => {
241195
+ const normalizeMcpError = (error2) => {
240303
241196
  if (error2 instanceof LodyOperationStoreError) {
240304
- return jsonTextResult({
240305
- ok: false,
240306
- error: error2.toLodyError()
240307
- }, true);
241197
+ return error2.toLodyError();
240308
241198
  }
240309
241199
  if (error2 instanceof LocalDaemonAvailabilityError) {
240310
- return jsonTextResult({
240311
- ok: false,
240312
- error: error2.toLodyError()
240313
- }, true);
241200
+ return error2.toLodyError();
240314
241201
  }
240315
241202
  if (error2 instanceof WorkspaceSyncUnavailableError) {
240316
- return jsonTextResult({
240317
- ok: false,
240318
- error: error2.toLodyError()
240319
- }, true);
241203
+ return error2.toLodyError();
240320
241204
  }
240321
- return jsonTextResult({
240322
- ok: false,
240323
- error: makeLodyError("INTERNAL_ERROR", formatMcpErrorMessage(error2), false)
240324
- }, true);
241205
+ return makeLodyError("INTERNAL_ERROR", formatMcpErrorMessage(error2), false);
240325
241206
  };
241207
+ const mcpErrorResult = (error2) => jsonTextResult({
241208
+ ok: false,
241209
+ error: normalizeMcpError(error2)
241210
+ }, true);
240326
241211
  const postSessionControl = async (request2, localControlSocketPath, timeoutMs = SESSION_CONTROL_TIMEOUT_MS) => {
240327
241212
  const responses = await runPromise(makeLocalControlClientAuto({
240328
241213
  socketPath: localControlSocketPath
@@ -241656,6 +242541,60 @@ ${prompt2}` : prompt2;
241656
242541
  }, worker));
241657
242542
  return output;
241658
242543
  };
242544
+ const resolveSessionRenameItems = (items2, ctx) => {
242545
+ assertBatchSize(items2.length, MAX_MCP_COMMAND_BATCH_SIZE);
242546
+ const resolved = items2.map((item) => ({
242547
+ sessionId: resolveMcpSessionId(item.sessionId, ctx),
242548
+ title: item.title
242549
+ }));
242550
+ if (new Set(resolved.map((item) => item.sessionId)).size !== resolved.length) {
242551
+ throw new LodyOperationStoreError("DUPLICATE_SESSION", "A session may appear only once in a rename batch.", false);
242552
+ }
242553
+ return resolved;
242554
+ };
242555
+ const applySessionRenameItems = async (items2, rename2) => await mapWithConcurrency(items2, 5, async (item) => {
242556
+ try {
242557
+ await rename2(item);
242558
+ return {
242559
+ sessionId: item.sessionId,
242560
+ ok: true,
242561
+ title: item.title
242562
+ };
242563
+ } catch (error2) {
242564
+ return {
242565
+ sessionId: item.sessionId,
242566
+ ok: false,
242567
+ error: normalizeMcpError(error2)
242568
+ };
242569
+ }
242570
+ });
242571
+ const persistSessionRenameItems = async (manager, items2, syncReason) => {
242572
+ const results = await applySessionRenameItems(items2, async (item) => {
242573
+ const session2 = await readCurrentSessionMeta(manager, item.sessionId);
242574
+ if (!session2) {
242575
+ throw new LodyOperationStoreError("SESSION_NOT_FOUND", `Session not found: ${item.sessionId}`, false);
242576
+ }
242577
+ await manager.repo.upsertDocMeta(getSessionRoomId(item.sessionId), {
242578
+ title: item.title,
242579
+ titleSource: "user"
242580
+ });
242581
+ });
242582
+ if (results.some((item) => item.ok)) {
242583
+ await ensureWorkspaceMetaSynced(manager, syncReason);
242584
+ }
242585
+ return results;
242586
+ };
242587
+ const renameSessionItems = async (input2) => {
242588
+ const ctx = getSessionContext();
242589
+ const resolved = resolveSessionRenameItems(input2.items, ctx);
242590
+ const auth = getAuthContextOrThrow$1("mcp");
242591
+ const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
242592
+ return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
242593
+ const reason = `mcp.session_rename_many:${ctx.sessionId}`;
242594
+ await syncWorkspaceMetaForRead(manager, reason);
242595
+ return await persistSessionRenameItems(manager, resolved, reason);
242596
+ });
242597
+ };
241659
242598
  const buildOperationTargetCancelArgs = (workspaceId, item) => [
241660
242599
  "session",
241661
242600
  "cancel",
@@ -242636,6 +243575,41 @@ ${lines2.join("\n")}` : ""}${suffix}`);
242636
243575
  return mcpErrorResult(error2);
242637
243576
  }
242638
243577
  });
243578
+ server.registerTool(SESSION_RENAME_TOOL_NAME, {
243579
+ title: "Rename a Lody session",
243580
+ description: "Set the title of one Session. Omit sessionId (or pass current) to rename the current Session. The durable rename is treated as a user-directed title and is not replaced by later automatic title generation.",
243581
+ inputSchema: SessionRenameToolInputSchema
243582
+ }, async (args2) => {
243583
+ try {
243584
+ const [item] = await renameSessionItems({
243585
+ items: [
243586
+ {
243587
+ sessionId: args2.sessionId ?? "current",
243588
+ title: args2.title
243589
+ }
243590
+ ]
243591
+ });
243592
+ if (!item) {
243593
+ throw new Error("Session rename returned no result.");
243594
+ }
243595
+ return jsonTextResult(item, item.ok === false);
243596
+ } catch (error2) {
243597
+ return mcpErrorResult(error2);
243598
+ }
243599
+ });
243600
+ server.registerTool(SESSION_RENAME_MANY_TOOL_NAME, {
243601
+ title: "Rename multiple Lody sessions",
243602
+ description: "Set titles for 1-20 Sessions. Session ids must be unique. Results preserve input order and failures are isolated per item; successful renames remain applied when another item fails.",
243603
+ inputSchema: SessionRenameManyToolInputSchema
243604
+ }, async (args2) => {
243605
+ try {
243606
+ return jsonTextResult({
243607
+ items: await renameSessionItems(args2)
243608
+ });
243609
+ } catch (error2) {
243610
+ return mcpErrorResult(error2);
243611
+ }
243612
+ });
242639
243613
  server.registerTool(SESSION_ARCHIVE_TOOL_NAME, {
242640
243614
  title: "Archive a Lody session",
242641
243615
  description: "Idempotently archive a Session. Archiving a parent cascades to child Sessions; pending Operation Deliveries remain pending until a human restores the Session.",