@otto-code/client 0.8.19 → 0.9.2

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.
@@ -1,3 +1,5 @@
1
+ import { normalizeFetchAgentOptions } from "./fetch-agent-options.js";
2
+ import { resolveAgentConfig } from "./create-agent-config.js";
1
3
  import { CLIENT_CAPS } from "@otto-code/protocol/client-capabilities";
2
4
  import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, SessionInboundMessageSchema, } from "@otto-code/protocol/messages";
3
5
  import { validateWSOutboundMessage } from "@otto-code/protocol/validation/ws-outbound";
@@ -23,17 +25,6 @@ function normalizePassword(value) {
23
25
  }
24
26
  return value.length > 0 ? value : null;
25
27
  }
26
- // COMPAT(daemon-client-object-options): added in v0.1.102; remove after
27
- // 2026-12-29 once SDK callers have migrated to object parameters.
28
- function normalizeFetchAgentOptions(input, legacyOptions) {
29
- if (typeof input !== "string") {
30
- return input;
31
- }
32
- if (typeof legacyOptions === "string") {
33
- return { agentId: input, requestId: legacyOptions };
34
- }
35
- return { agentId: input, ...legacyOptions };
36
- }
37
28
  function normalizeListCommandsOptions(input, legacyOptions) {
38
29
  if (typeof input !== "string") {
39
30
  return input;
@@ -253,6 +244,35 @@ function unwrapBrainJob(payload) {
253
244
  // A repo clone can take minutes on a large history, so it gets its own budget
254
245
  // rather than the default request timeout.
255
246
  const PROJECT_GITHUB_CLONE_TIMEOUT_MS = 5 * 60 * 1000;
247
+ function buildWorkflowStartRequest(input) {
248
+ return {
249
+ flavor: input.flavor,
250
+ cwd: input.cwd,
251
+ ...(input.workspaceId !== undefined ? { workspaceId: input.workspaceId } : {}),
252
+ ...(input.title !== undefined ? { title: input.title } : {}),
253
+ ...(input.description !== undefined ? { description: input.description } : {}),
254
+ ...(input.orchestratorPersonalityId !== undefined
255
+ ? { orchestratorPersonalityId: input.orchestratorPersonalityId }
256
+ : {}),
257
+ ...(input.orchestratorProvider !== undefined
258
+ ? { orchestratorProvider: input.orchestratorProvider }
259
+ : {}),
260
+ ...(input.orchestratorModel !== undefined
261
+ ? { orchestratorModel: input.orchestratorModel }
262
+ : {}),
263
+ ...(input.orchestratorThinkingOptionId !== undefined
264
+ ? { orchestratorThinkingOptionId: input.orchestratorThinkingOptionId }
265
+ : {}),
266
+ ...(input.prompt !== undefined ? { prompt: input.prompt } : {}),
267
+ ...(input.graphId !== undefined ? { graphId: input.graphId } : {}),
268
+ ...(input.graphInputs !== undefined ? { graphInputs: input.graphInputs } : {}),
269
+ ...(input.startConfirmationToken !== undefined
270
+ ? { startConfirmationToken: input.startConfirmationToken }
271
+ : {}),
272
+ ...(input.draft !== undefined ? { draft: input.draft } : {}),
273
+ ...(input.runId !== undefined ? { runId: input.runId } : {}),
274
+ };
275
+ }
256
276
  export class DaemonClient {
257
277
  constructor(config) {
258
278
  this.config = config;
@@ -1061,6 +1081,7 @@ export class DaemonClient {
1061
1081
  ...(options?.sort ? { sort: options.sort } : {}),
1062
1082
  ...(options?.page ? { page: options.page } : {}),
1063
1083
  ...(options?.subscribe ? { subscribe: options.subscribe } : {}),
1084
+ ...(options?.sync ? { sync: options.sync } : {}),
1064
1085
  });
1065
1086
  return this.sendRequest({
1066
1087
  requestId: resolvedRequestId,
@@ -1143,6 +1164,7 @@ export class DaemonClient {
1143
1164
  ...(options?.sort ? { sort: options.sort } : {}),
1144
1165
  ...(options?.page ? { page: options.page } : {}),
1145
1166
  ...(options?.subscribe ? { subscribe: options.subscribe } : {}),
1167
+ ...(options?.sync ? { sync: options.sync } : {}),
1146
1168
  });
1147
1169
  return this.sendRequest({
1148
1170
  requestId: resolvedRequestId,
@@ -1159,6 +1181,74 @@ export class DaemonClient {
1159
1181
  },
1160
1182
  });
1161
1183
  }
1184
+ listWorkspaceLabels(options) {
1185
+ return this.sendNamespacedCorrelatedSessionRequest({
1186
+ requestId: options.requestId,
1187
+ message: {
1188
+ type: "workspace.label.list.request",
1189
+ subscribe: { subscriptionId: options.subscriptionId },
1190
+ ...(options.sync ? { sync: options.sync } : {}),
1191
+ },
1192
+ });
1193
+ }
1194
+ setWorkspaceLabel(options) {
1195
+ return this.sendNamespacedCorrelatedSessionRequest({
1196
+ requestId: options.requestId,
1197
+ message: {
1198
+ type: "workspace.label.assignment.set.request",
1199
+ workspaceId: options.workspaceId,
1200
+ label: options.label,
1201
+ assigned: options.assigned,
1202
+ },
1203
+ });
1204
+ }
1205
+ updateWorkspaceLabel(options) {
1206
+ return this.sendNamespacedCorrelatedSessionRequest({
1207
+ requestId: options.requestId,
1208
+ message: {
1209
+ type: "workspace.label.update.request",
1210
+ name: options.name,
1211
+ ...(options.newName === undefined ? {} : { newName: options.newName }),
1212
+ ...(options.color === undefined ? {} : { color: options.color }),
1213
+ },
1214
+ });
1215
+ }
1216
+ deleteWorkspaceLabel(options) {
1217
+ return this.sendNamespacedCorrelatedSessionRequest({
1218
+ requestId: options.requestId,
1219
+ message: { type: "workspace.label.delete.request", name: options.name },
1220
+ });
1221
+ }
1222
+ inspectWorkspaceLabelDelete(options) {
1223
+ return this.sendNamespacedCorrelatedSessionRequest({
1224
+ requestId: options.requestId,
1225
+ message: {
1226
+ type: "workspace.label.delete.inspect.request",
1227
+ name: options.name,
1228
+ },
1229
+ });
1230
+ }
1231
+ async listProjects(options) {
1232
+ const requestId = typeof options === "string" ? options : options?.requestId;
1233
+ const resolvedRequestId = this.createRequestId(requestId);
1234
+ const message = SessionInboundMessageSchema.parse({
1235
+ type: "project.list.request",
1236
+ requestId: resolvedRequestId,
1237
+ ...(typeof options === "object" && options.sync ? { sync: options.sync } : {}),
1238
+ });
1239
+ return this.sendRequest({
1240
+ requestId: resolvedRequestId,
1241
+ message,
1242
+ options: { skipQueue: true },
1243
+ select: (msg) => {
1244
+ if (msg.type !== "project.list.response")
1245
+ return null;
1246
+ if (msg.payload.requestId !== resolvedRequestId)
1247
+ return null;
1248
+ return msg.payload;
1249
+ },
1250
+ });
1251
+ }
1162
1252
  async openProject(cwd, requestId) {
1163
1253
  return this.sendCorrelatedSessionRequest({
1164
1254
  requestId,
@@ -1419,6 +1509,9 @@ export class DaemonClient {
1419
1509
  ...(options.personality ? { personality: options.personality } : {}),
1420
1510
  ...(options.env ? { env: options.env } : {}),
1421
1511
  ...(options.workspaceId !== undefined ? { workspaceId: options.workspaceId } : {}),
1512
+ ...(options.architecturalViewDraft
1513
+ ? { architecturalViewDraft: options.architecturalViewDraft }
1514
+ : {}),
1422
1515
  ...(options.callerAgentId !== undefined ? { callerAgentId: options.callerAgentId } : {}),
1423
1516
  ...(options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}),
1424
1517
  ...(options.clientMessageId ? { clientMessageId: options.clientMessageId } : {}),
@@ -1622,13 +1715,14 @@ export class DaemonClient {
1622
1715
  * a single-element array; the "Start all" collective action passes the whole
1623
1716
  * pending queue. Resolves to the count started; throws only if all failed.
1624
1717
  */
1625
- async startSuggestedTasks(parentAgentId, taskIds, mode) {
1718
+ async startSuggestedTasks(parentAgentId, taskIds, mode, launch) {
1626
1719
  const payload = await this.sendNamespacedCorrelatedSessionRequest({
1627
1720
  message: {
1628
1721
  type: "tasks.suggested.start.request",
1629
1722
  parentAgentId,
1630
1723
  taskIds: [...taskIds],
1631
1724
  mode,
1725
+ launch,
1632
1726
  },
1633
1727
  });
1634
1728
  if (!payload.accepted) {
@@ -1703,6 +1797,26 @@ export class DaemonClient {
1703
1797
  });
1704
1798
  return payload.graphs;
1705
1799
  }
1800
+ /** List saved Workflow Graphs for one project, never the legacy host library. */
1801
+ async listProjectWorkflowGraphs(cwd) {
1802
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1803
+ message: { type: "workflows.graphs.list.request", cwd },
1804
+ });
1805
+ if (payload.error !== undefined) {
1806
+ throw new Error(payload.error);
1807
+ }
1808
+ return payload.graphs;
1809
+ }
1810
+ /** Persist a Graph in the selected project Workflow store. */
1811
+ async saveProjectWorkflowGraph(cwd, graph) {
1812
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1813
+ message: { type: "workflows.graph.save.request", cwd, graph },
1814
+ });
1815
+ if (payload.error !== undefined || payload.graph === undefined) {
1816
+ throw new Error(payload.error ?? "Project Workflow Graph save rejected");
1817
+ }
1818
+ return payload.graph;
1819
+ }
1706
1820
  /** Orchestration: upsert a graph template. Returns the persisted graph. */
1707
1821
  async saveOrchestrationGraph(graph) {
1708
1822
  const payload = await this.sendNamespacedCorrelatedSessionRequest({
@@ -1723,6 +1837,22 @@ export class DaemonClient {
1723
1837
  }
1724
1838
  return payload.deleted;
1725
1839
  }
1840
+ async exportWorkflowGraph(graphId) {
1841
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1842
+ message: { type: "workflows.graph.export.request", graphId },
1843
+ });
1844
+ if (!payload.export)
1845
+ throw new Error(payload.error ?? "Graph export rejected");
1846
+ return payload.export;
1847
+ }
1848
+ async importWorkflowGraph(input) {
1849
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1850
+ message: { type: "workflows.graph.import.request", ...input },
1851
+ });
1852
+ if (!payload.result)
1853
+ throw new Error(payload.error ?? "Graph import rejected");
1854
+ return payload.result;
1855
+ }
1726
1856
  /** Orchestration: list the host's reusable prompt templates and snippets. */
1727
1857
  async listPromptTemplates() {
1728
1858
  const payload = await this.sendNamespacedCorrelatedSessionRequest({
@@ -1730,6 +1860,32 @@ export class DaemonClient {
1730
1860
  });
1731
1861
  return payload.templates;
1732
1862
  }
1863
+ async listProjectWorkflowTemplates(cwd) {
1864
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1865
+ message: { type: "workflows.templates.list.request", cwd },
1866
+ });
1867
+ if (payload.error !== undefined)
1868
+ throw new Error(payload.error);
1869
+ return payload.templates;
1870
+ }
1871
+ async saveProjectWorkflowTemplate(cwd, template) {
1872
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1873
+ message: { type: "workflows.template.save.request", cwd, template },
1874
+ });
1875
+ if (payload.error !== undefined || payload.template === undefined) {
1876
+ throw new Error(payload.error ?? "Project Workflow template save rejected");
1877
+ }
1878
+ return payload.template;
1879
+ }
1880
+ async transferProjectWorkflowRecord(input) {
1881
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1882
+ message: { type: "workflows.storage.transfer.request", ...input },
1883
+ });
1884
+ if (payload.error !== undefined || payload.receipt === undefined) {
1885
+ throw new Error(payload.error ?? "Project Workflow transfer rejected");
1886
+ }
1887
+ return payload.receipt;
1888
+ }
1733
1889
  /** Orchestration: upsert a prompt template. Returns the persisted template. */
1734
1890
  async savePromptTemplate(template) {
1735
1891
  const payload = await this.sendNamespacedCorrelatedSessionRequest({
@@ -1751,37 +1907,20 @@ export class DaemonClient {
1751
1907
  return payload.deleted;
1752
1908
  }
1753
1909
  /**
1754
- * Orchestration: start (or draft) a user-initiated orchestration. Returns the
1755
- * run id (graph flavor) and the orchestrator chat's agent id to navigate to.
1910
+ * Workflow: start (or draft) a user-initiated Workflow. Returns the workflow
1911
+ * id (graph flavor) and the orchestrator chat's agent id to navigate to.
1756
1912
  */
1757
- async startOrchestration(input) {
1758
- const payload = await this.sendNamespacedCorrelatedSessionRequest({
1759
- message: {
1760
- type: "runs.start.request",
1761
- flavor: input.flavor,
1762
- cwd: input.cwd,
1763
- ...(input.workspaceId !== undefined ? { workspaceId: input.workspaceId } : {}),
1764
- ...(input.title !== undefined ? { title: input.title } : {}),
1765
- ...(input.description !== undefined ? { description: input.description } : {}),
1766
- ...(input.orchestratorPersonalityId !== undefined
1767
- ? { orchestratorPersonalityId: input.orchestratorPersonalityId }
1768
- : {}),
1769
- ...(input.orchestratorProvider !== undefined
1770
- ? { orchestratorProvider: input.orchestratorProvider }
1771
- : {}),
1772
- ...(input.orchestratorModel !== undefined
1773
- ? { orchestratorModel: input.orchestratorModel }
1774
- : {}),
1775
- ...(input.orchestratorThinkingOptionId !== undefined
1776
- ? { orchestratorThinkingOptionId: input.orchestratorThinkingOptionId }
1777
- : {}),
1778
- ...(input.prompt !== undefined ? { prompt: input.prompt } : {}),
1779
- ...(input.graphId !== undefined ? { graphId: input.graphId } : {}),
1780
- ...(input.graphInputs !== undefined ? { graphInputs: input.graphInputs } : {}),
1781
- ...(input.draft !== undefined ? { draft: input.draft } : {}),
1782
- ...(input.runId !== undefined ? { runId: input.runId } : {}),
1783
- },
1784
- });
1913
+ async startWorkflow(input) {
1914
+ const request = buildWorkflowStartRequest(input);
1915
+ // COMPAT(runsStartRpc): retain the established request against older
1916
+ // daemons until the legacy pair retires after 2027-02-28.
1917
+ const payload = this.lastServerInfoMessage?.features?.workflowStartRpc === true
1918
+ ? await this.sendNamespacedCorrelatedSessionRequest({
1919
+ message: { type: "workflows.start.request", ...request },
1920
+ })
1921
+ : await this.sendNamespacedCorrelatedSessionRequest({
1922
+ message: { type: "runs.start.request", ...request },
1923
+ });
1785
1924
  if (payload.error !== undefined) {
1786
1925
  throw new Error(payload.error);
1787
1926
  }
@@ -1789,8 +1928,19 @@ export class DaemonClient {
1789
1928
  ...(payload.runId !== undefined ? { runId: payload.runId } : {}),
1790
1929
  ...(payload.agentId !== undefined ? { agentId: payload.agentId } : {}),
1791
1930
  ...(payload.workspaceId !== undefined ? { workspaceId: payload.workspaceId } : {}),
1931
+ ...(payload.confirmation !== undefined ? { confirmation: payload.confirmation } : {}),
1932
+ ...(payload.confirmationToken !== undefined
1933
+ ? { confirmationToken: payload.confirmationToken }
1934
+ : {}),
1792
1935
  };
1793
1936
  }
1937
+ /** Answer a daemon-owned AI Workflow start confirmation. */
1938
+ async respondToWorkflowStartConfirmation(input) {
1939
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1940
+ message: { type: "workflows.start_confirmation.respond.request", ...input },
1941
+ });
1942
+ return payload.accepted;
1943
+ }
1794
1944
  async updateAgent(agentId, updates) {
1795
1945
  const requestId = this.createRequestId();
1796
1946
  const message = SessionInboundMessageSchema.parse({
@@ -2213,25 +2363,6 @@ export class DaemonClient {
2213
2363
  }
2214
2364
  return { baseRef: payload.baseRef, commits: payload.commits };
2215
2365
  }
2216
- async listProjects(requestId) {
2217
- const resolvedRequestId = this.createRequestId(requestId);
2218
- const message = SessionInboundMessageSchema.parse({
2219
- type: "project.list.request",
2220
- requestId: resolvedRequestId,
2221
- });
2222
- return this.sendRequest({
2223
- requestId: resolvedRequestId,
2224
- message,
2225
- options: { skipQueue: true },
2226
- select: (msg) => {
2227
- if (msg.type !== "project.list.response")
2228
- return null;
2229
- if (msg.payload.requestId !== resolvedRequestId)
2230
- return null;
2231
- return msg.payload;
2232
- },
2233
- });
2234
- }
2235
2366
  onAgentAttentionRequired(handler) {
2236
2367
  const unsubscribeLegacy = this.on("agent_stream", (message) => {
2237
2368
  if (message.payload.event.type !== "attention_required") {
@@ -2359,6 +2490,7 @@ export class DaemonClient {
2359
2490
  ...(typeof options.limit === "number" ? { limit: options.limit } : {}),
2360
2491
  ...(options.projection ? { projection: options.projection } : {}),
2361
2492
  ...(options.mergeWindow === true ? { mergeWindow: true } : {}),
2493
+ ...(options.includePromptIndex === true ? { includePromptIndex: true } : {}),
2362
2494
  });
2363
2495
  const payload = await this.sendRequest({
2364
2496
  requestId: resolvedRequestId,
@@ -2443,6 +2575,7 @@ export class DaemonClient {
2443
2575
  agentId,
2444
2576
  text,
2445
2577
  ...(messageId ? { messageId } : {}),
2578
+ ...(options?.activeTurnBehavior ? { activeTurnBehavior: options.activeTurnBehavior } : {}),
2446
2579
  ...(options?.images ? { images: options.images } : {}),
2447
2580
  ...(options?.attachments ? { attachments: options.attachments } : {}),
2448
2581
  ...(options?.delivery ? { delivery: options.delivery } : {}),
@@ -3709,7 +3842,7 @@ export class DaemonClient {
3709
3842
  // ============================================================================
3710
3843
  // File Explorer
3711
3844
  // ============================================================================
3712
- async requestFileExplorer(cwd, path, mode, requestId, acceptBinary = false) {
3845
+ async requestFileExplorer(cwd, path, mode, requestId, acceptBinary = false, maxBytes) {
3713
3846
  return this.sendCorrelatedSessionRequest({
3714
3847
  requestId,
3715
3848
  message: {
@@ -3718,6 +3851,7 @@ export class DaemonClient {
3718
3851
  path,
3719
3852
  mode,
3720
3853
  ...(acceptBinary ? { acceptBinary: true } : {}),
3854
+ ...(maxBytes ? { maxBytes } : {}),
3721
3855
  },
3722
3856
  responseType: "file_explorer_response",
3723
3857
  });
@@ -3732,11 +3866,11 @@ export class DaemonClient {
3732
3866
  }
3733
3867
  return payload.directory;
3734
3868
  }
3735
- async readFile(cwd, path, requestId) {
3869
+ async readFile(cwd, path, requestId, maxBytes) {
3736
3870
  const resolvedRequestId = this.createRequestId(requestId);
3737
- this.pendingBinaryFileReads.set(resolvedRequestId, { cwd, path });
3871
+ this.pendingBinaryFileReads.set(resolvedRequestId, { cwd, path, maxBytes });
3738
3872
  try {
3739
- const payload = await this.requestFileExplorer(cwd, path, "file", resolvedRequestId, true);
3873
+ const payload = await this.requestFileExplorer(cwd, path, "file", resolvedRequestId, true, maxBytes);
3740
3874
  if (payload.error) {
3741
3875
  throw new Error(payload.error);
3742
3876
  }
@@ -4371,10 +4505,14 @@ export class DaemonClient {
4371
4505
  responseType: "context.prompt.preview.get.response",
4372
4506
  });
4373
4507
  }
4374
- async listProjectKnowledge(workspaceId, requestId) {
4508
+ async listProjectKnowledge(workspaceId, options) {
4375
4509
  return this.sendNamespacedCorrelatedSessionRequest({
4376
- requestId,
4377
- message: { type: "project.knowledge.list.request", workspaceId },
4510
+ requestId: options?.requestId,
4511
+ message: {
4512
+ type: "project.knowledge.list.request",
4513
+ workspaceId,
4514
+ ...(options?.includeRootBodies === false ? { includeRootBodies: false } : {}),
4515
+ },
4378
4516
  });
4379
4517
  }
4380
4518
  async getProjectKnowledge(input, requestId) {
@@ -4383,6 +4521,12 @@ export class DaemonClient {
4383
4521
  message: { type: "project.knowledge.get.request", ...input },
4384
4522
  });
4385
4523
  }
4524
+ async getProjectKnowledgeRoot(input, requestId) {
4525
+ return this.sendNamespacedCorrelatedSessionRequest({
4526
+ requestId,
4527
+ message: { type: "project.knowledge.root.get.request", ...input },
4528
+ });
4529
+ }
4386
4530
  async createProjectKnowledge(input, requestId) {
4387
4531
  return this.sendNamespacedCorrelatedSessionRequest({
4388
4532
  requestId,
@@ -4610,6 +4754,37 @@ export class DaemonClient {
4610
4754
  timeout: options?.timeout,
4611
4755
  });
4612
4756
  }
4757
+ async reloadDaemonConfig(requestId) {
4758
+ this.requireDaemonConfigReloadSupport();
4759
+ return this.sendNamespacedCorrelatedSessionRequest({
4760
+ requestId,
4761
+ message: { type: "daemon.config.reload.request" },
4762
+ });
4763
+ }
4764
+ async connectHub(hubUrl, token, requestId) {
4765
+ this.requireHubRelationshipSupport();
4766
+ return this.sendCorrelatedSessionRequest({
4767
+ requestId,
4768
+ message: { type: "hub.management.daemon.connect.request", hubUrl, token },
4769
+ responseType: "hub.management.daemon.connect.response",
4770
+ });
4771
+ }
4772
+ async getHubStatus(requestId) {
4773
+ this.requireHubRelationshipSupport();
4774
+ return this.sendCorrelatedSessionRequest({
4775
+ requestId,
4776
+ message: { type: "hub.management.daemon.get_status.request" },
4777
+ responseType: "hub.management.daemon.get_status.response",
4778
+ });
4779
+ }
4780
+ async disconnectHub(force = false, requestId) {
4781
+ this.requireHubRelationshipSupport();
4782
+ return this.sendCorrelatedSessionRequest({
4783
+ requestId,
4784
+ message: { type: "hub.management.daemon.disconnect.request", force },
4785
+ responseType: "hub.management.daemon.disconnect.response",
4786
+ });
4787
+ }
4613
4788
  async getDaemonPairingOffer(options) {
4614
4789
  return this.sendCorrelatedSessionRequest({
4615
4790
  requestId: options?.requestId,
@@ -5549,6 +5724,135 @@ export class DaemonClient {
5549
5724
  response,
5550
5725
  });
5551
5726
  }
5727
+ async getPluginCatalog() {
5728
+ const requestId = this.createRequestId();
5729
+ const payload = await this.sendCorrelatedSessionRequest({
5730
+ requestId,
5731
+ message: { type: "plugin.catalog.get.request", requestId },
5732
+ responseType: "plugin.catalog.get.response",
5733
+ });
5734
+ return payload.plugins;
5735
+ }
5736
+ async listPlugins() {
5737
+ const requestId = this.createRequestId();
5738
+ const payload = await this.sendCorrelatedSessionRequest({
5739
+ requestId,
5740
+ message: { type: "plugin.list.request", requestId },
5741
+ responseType: "plugin.list.response",
5742
+ });
5743
+ return payload.plugins;
5744
+ }
5745
+ async getPluginLogs(pluginId) {
5746
+ const requestId = this.createRequestId();
5747
+ const payload = await this.sendCorrelatedSessionRequest({
5748
+ requestId,
5749
+ message: { type: "plugin.logs.get.request", requestId, pluginId },
5750
+ responseType: "plugin.logs.get.response",
5751
+ });
5752
+ return payload.entries;
5753
+ }
5754
+ async getAgentSkillsStatus() {
5755
+ const requestId = this.createRequestId();
5756
+ return this.sendCorrelatedSessionRequest({
5757
+ message: { type: "agent.skills.get_status.request", requestId },
5758
+ responseType: "agent.skills.get_status.response",
5759
+ });
5760
+ }
5761
+ async reconcileAgentSkills() {
5762
+ const requestId = this.createRequestId();
5763
+ return this.sendCorrelatedSessionRequest({
5764
+ message: { type: "agent.skills.reconcile.request", requestId },
5765
+ responseType: "agent.skills.reconcile.response",
5766
+ });
5767
+ }
5768
+ async uninstallAgentSkills() {
5769
+ const requestId = this.createRequestId();
5770
+ return this.sendCorrelatedSessionRequest({
5771
+ message: { type: "agent.skills.uninstall.request", requestId },
5772
+ responseType: "agent.skills.uninstall.response",
5773
+ });
5774
+ }
5775
+ async saveAgentSkillsSelection(selection, confirmedRemovals) {
5776
+ const requestId = this.createRequestId();
5777
+ return this.sendCorrelatedSessionRequest({
5778
+ message: {
5779
+ type: "agent.skills.save_selection.request",
5780
+ requestId,
5781
+ selection,
5782
+ ...(confirmedRemovals ? { confirmedRemovals: [...confirmedRemovals] } : {}),
5783
+ },
5784
+ responseType: "agent.skills.save_selection.response",
5785
+ });
5786
+ }
5787
+ async importLegacyAgentSkillsSelection(selection) {
5788
+ const requestId = this.createRequestId();
5789
+ return this.sendCorrelatedSessionRequest({
5790
+ message: {
5791
+ type: "agent.skills.import_legacy_selection.request",
5792
+ requestId,
5793
+ selection,
5794
+ },
5795
+ responseType: "agent.skills.import_legacy_selection.response",
5796
+ });
5797
+ }
5798
+ async installDirectoryPlugin(path, id) {
5799
+ const requestId = this.createRequestId();
5800
+ const payload = await this.sendCorrelatedSessionRequest({
5801
+ requestId,
5802
+ message: { type: "plugin.directory.install.request", requestId, path, ...(id ? { id } : {}) },
5803
+ responseType: "plugin.directory.install.response",
5804
+ });
5805
+ return payload.plugin;
5806
+ }
5807
+ async inspectDirectoryPlugin(path) {
5808
+ const requestId = this.createRequestId();
5809
+ return this.sendCorrelatedSessionRequest({
5810
+ requestId,
5811
+ message: { type: "plugin.directory.inspect.request", requestId, path },
5812
+ responseType: "plugin.directory.inspect.response",
5813
+ });
5814
+ }
5815
+ async reloadPlugin(pluginId) {
5816
+ return this.managePlugin("reload", pluginId);
5817
+ }
5818
+ async enablePlugin(pluginId) {
5819
+ return this.managePlugin("enable", pluginId);
5820
+ }
5821
+ async disablePlugin(pluginId) {
5822
+ return this.managePlugin("disable", pluginId);
5823
+ }
5824
+ async removePlugin(pluginId) {
5825
+ const requestId = this.createRequestId();
5826
+ await this.sendCorrelatedSessionRequest({
5827
+ requestId,
5828
+ message: { type: "plugin.remove.request", requestId, pluginId },
5829
+ responseType: "plugin.remove.response",
5830
+ });
5831
+ }
5832
+ async managePlugin(action, pluginId) {
5833
+ const requestId = this.createRequestId();
5834
+ const payload = await this.sendCorrelatedSessionRequest({
5835
+ requestId,
5836
+ message: { type: `plugin.${action}.request`, requestId, pluginId },
5837
+ responseType: `plugin.${action}.response`,
5838
+ });
5839
+ return payload.plugin;
5840
+ }
5841
+ async invokePluginRpc(pluginId, method, input) {
5842
+ const requestId = this.createRequestId();
5843
+ const payload = await this.sendCorrelatedSessionRequest({
5844
+ requestId,
5845
+ message: {
5846
+ type: "plugin.rpc.invoke.request",
5847
+ requestId,
5848
+ pluginId,
5849
+ method,
5850
+ input,
5851
+ },
5852
+ responseType: "plugin.rpc.invoke.response",
5853
+ });
5854
+ return payload.output;
5855
+ }
5552
5856
  async respondToPermissionAndWait(agentId, requestId, response, timeout = 15000) {
5553
5857
  const message = SessionInboundMessageSchema.parse({
5554
5858
  type: "agent_permission_response",
@@ -5974,6 +6278,32 @@ export class DaemonClient {
5974
6278
  responseType: "artifact.list.response",
5975
6279
  });
5976
6280
  }
6281
+ async setProjectArtifactStoreLocation(input) {
6282
+ const payload = await this.sendCorrelatedSessionRequest({
6283
+ requestId: input.requestId,
6284
+ message: {
6285
+ type: "project.artifact.store.set.request",
6286
+ projectId: input.projectId,
6287
+ location: input.location,
6288
+ },
6289
+ responseType: "project.artifact.store.set.response",
6290
+ });
6291
+ if (!payload.accepted)
6292
+ throw new Error(payload.error ?? "Artifact storage update rejected");
6293
+ }
6294
+ /** Requires server_info.features.categoryStorageResolver for Workflows. */
6295
+ async setProjectWorkflowStoreLocation(input) {
6296
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
6297
+ requestId: input.requestId,
6298
+ message: {
6299
+ type: "project.workflow.store.set.request",
6300
+ projectId: input.projectId,
6301
+ location: input.location,
6302
+ },
6303
+ });
6304
+ if (!payload.accepted)
6305
+ throw new Error(payload.error ?? "Workflow storage update rejected");
6306
+ }
5977
6307
  async artifactCreate(options) {
5978
6308
  return this.sendCorrelatedSessionRequest({
5979
6309
  requestId: options.requestId,
@@ -6062,6 +6392,164 @@ export class DaemonClient {
6062
6392
  responseType: "artifact.get-content.response",
6063
6393
  });
6064
6394
  }
6395
+ async artifactRepair(options) {
6396
+ return this.sendCorrelatedSessionRequest({
6397
+ requestId: options.requestId,
6398
+ message: {
6399
+ type: "artifact.repair.request",
6400
+ artifactId: options.artifactId,
6401
+ },
6402
+ responseType: "artifact.repair.response",
6403
+ });
6404
+ }
6405
+ async artifactGetData(options) {
6406
+ return this.sendCorrelatedSessionRequest({
6407
+ requestId: options.requestId,
6408
+ message: {
6409
+ type: "artifact.data.get.request",
6410
+ artifactId: options.artifactId,
6411
+ },
6412
+ responseType: "artifact.data.get.response",
6413
+ });
6414
+ }
6415
+ async artifactUpdateData(options) {
6416
+ return this.sendCorrelatedSessionRequest({
6417
+ requestId: options.requestId,
6418
+ message: {
6419
+ type: "artifact.data.update.request",
6420
+ artifactId: options.artifactId,
6421
+ data: options.data,
6422
+ },
6423
+ responseType: "artifact.data.update.response",
6424
+ });
6425
+ }
6426
+ async artifactMoveStore(options) {
6427
+ return this.sendCorrelatedSessionRequest({
6428
+ requestId: options.requestId,
6429
+ message: {
6430
+ type: "artifact.store.move.request",
6431
+ artifactId: options.artifactId,
6432
+ destination: options.destination,
6433
+ },
6434
+ responseType: "artifact.store.move.response",
6435
+ });
6436
+ }
6437
+ async deliverArchitecturalView(options) {
6438
+ return this.sendCorrelatedSessionRequest({
6439
+ requestId: options.requestId,
6440
+ message: {
6441
+ type: "architectural-views.deliver.request",
6442
+ workspaceId: options.workspaceId,
6443
+ viewId: options.viewId,
6444
+ title: options.title,
6445
+ knowledgeReferences: options.knowledgeReferences,
6446
+ sourcePath: options.sourcePath,
6447
+ ...(options.diagramType ? { diagramType: options.diagramType } : {}),
6448
+ ...(options.quality ? { quality: options.quality } : {}),
6449
+ },
6450
+ responseType: "architectural-views.deliver.response",
6451
+ });
6452
+ }
6453
+ async listArchitecturalViews(options) {
6454
+ return this.sendCorrelatedSessionRequest({
6455
+ requestId: options.requestId,
6456
+ message: {
6457
+ type: "architectural-views.list.request",
6458
+ workspaceId: options.workspaceId,
6459
+ ...(options.knowledgeReference ? { knowledgeReference: options.knowledgeReference } : {}),
6460
+ },
6461
+ responseType: "architectural-views.list.response",
6462
+ });
6463
+ }
6464
+ async getArchitecturalViewContent(options) {
6465
+ return this.sendCorrelatedSessionRequest({
6466
+ requestId: options.requestId,
6467
+ message: {
6468
+ type: "architectural-views.get-content.request",
6469
+ workspaceId: options.workspaceId,
6470
+ viewId: options.viewId,
6471
+ },
6472
+ responseType: "architectural-views.get-content.response",
6473
+ });
6474
+ }
6475
+ async createArchitecturalViewDraft(options) {
6476
+ return this.sendCorrelatedSessionRequest({
6477
+ requestId: options.requestId,
6478
+ message: {
6479
+ type: "architectural-views.draft.create.request",
6480
+ workspaceId: options.workspaceId,
6481
+ viewId: options.viewId,
6482
+ draftId: options.draftId,
6483
+ title: options.title,
6484
+ knowledgeReferences: options.knowledgeReferences,
6485
+ ...(options.sourcePath ? { sourcePath: options.sourcePath } : {}),
6486
+ ...(options.diagramType ? { diagramType: options.diagramType } : {}),
6487
+ ...(options.quality ? { quality: options.quality } : {}),
6488
+ },
6489
+ responseType: "architectural-views.draft.create.response",
6490
+ });
6491
+ }
6492
+ async publishArchitecturalViewDraft(options) {
6493
+ return this.sendCorrelatedSessionRequest({
6494
+ requestId: options.requestId,
6495
+ message: {
6496
+ type: "architectural-views.draft.publish.request",
6497
+ workspaceId: options.workspaceId,
6498
+ viewId: options.viewId,
6499
+ draftId: options.draftId,
6500
+ },
6501
+ responseType: "architectural-views.draft.publish.response",
6502
+ });
6503
+ }
6504
+ async updateArchitecturalViewDraft(options) {
6505
+ return this.sendCorrelatedSessionRequest({
6506
+ requestId: options.requestId,
6507
+ message: {
6508
+ type: "architectural-views.draft.update.request",
6509
+ workspaceId: options.workspaceId,
6510
+ viewId: options.viewId,
6511
+ draftId: options.draftId,
6512
+ sourcePath: options.sourcePath,
6513
+ ...(options.quality ? { quality: options.quality } : {}),
6514
+ },
6515
+ responseType: "architectural-views.draft.update.response",
6516
+ });
6517
+ }
6518
+ async discardArchitecturalViewDraft(options) {
6519
+ return this.sendCorrelatedSessionRequest({
6520
+ requestId: options.requestId,
6521
+ message: {
6522
+ type: "architectural-views.draft.discard.request",
6523
+ workspaceId: options.workspaceId,
6524
+ viewId: options.viewId,
6525
+ draftId: options.draftId,
6526
+ },
6527
+ responseType: "architectural-views.draft.discard.response",
6528
+ });
6529
+ }
6530
+ async getArchitecturalViewDraftContent(options) {
6531
+ return this.sendCorrelatedSessionRequest({
6532
+ requestId: options.requestId,
6533
+ message: {
6534
+ type: "architectural-views.draft.get-content.request",
6535
+ workspaceId: options.workspaceId,
6536
+ viewId: options.viewId,
6537
+ draftId: options.draftId,
6538
+ },
6539
+ responseType: "architectural-views.draft.get-content.response",
6540
+ });
6541
+ }
6542
+ async listArchitecturalViewDrafts(options) {
6543
+ return this.sendCorrelatedSessionRequest({
6544
+ requestId: options.requestId,
6545
+ message: {
6546
+ type: "architectural-views.draft.list.request",
6547
+ workspaceId: options.workspaceId,
6548
+ ...(options.knowledgeReference ? { knowledgeReference: options.knowledgeReference } : {}),
6549
+ },
6550
+ responseType: "architectural-views.draft.list.response",
6551
+ });
6552
+ }
6065
6553
  onTerminalStreamEvent(handler) {
6066
6554
  return this.terminalStreams.onEvent(handler);
6067
6555
  }
@@ -6110,6 +6598,12 @@ export class DaemonClient {
6110
6598
  getInboundDispatchTimings(sinceMs) {
6111
6599
  return this.runtimeMetrics?.getInboundDispatchTimings(sinceMs) ?? [];
6112
6600
  }
6601
+ requireDaemonConfigReloadSupport() {
6602
+ // COMPAT(daemonConfigReload): added in v0.4.0, remove gate after 2027-02-14.
6603
+ if (this.lastServerInfoMessage?.features?.daemonConfigReload !== true) {
6604
+ throw new Error("Update the host to reload daemon configuration.");
6605
+ }
6606
+ }
6113
6607
  resolveTransportUrlForAttempt() {
6114
6608
  return this.config.url;
6115
6609
  }
@@ -6346,9 +6840,31 @@ export class DaemonClient {
6346
6840
  return;
6347
6841
  }
6348
6842
  if (frame.opcode === FileTransferOpcode.FileChunk) {
6843
+ // COMPAT(fileReadByteBudget): added in v0.5.0, remove after 2027-02-21 once daemon floor >= v0.5.0.
6844
+ // Old daemons stream despite maxBytes; discard before client-side accumulation.
6845
+ if (transfer.maxBytes && transfer.size > transfer.maxBytes) {
6846
+ return;
6847
+ }
6349
6848
  transfer.chunks.push(frame.payload);
6350
6849
  return;
6351
6850
  }
6851
+ // COMPAT(fileReadByteBudget): added in v0.5.0, remove after 2027-02-21 once daemon floor >= v0.5.0.
6852
+ if (transfer.maxBytes && transfer.size > transfer.maxBytes) {
6853
+ this.activeBinaryFileTransfers.delete(frame.requestId);
6854
+ this.handleSessionMessage({
6855
+ type: "file_explorer_response",
6856
+ payload: {
6857
+ cwd: transfer.cwd,
6858
+ path: transfer.path,
6859
+ mode: "file",
6860
+ directory: null,
6861
+ file: null,
6862
+ error: "File is too large to display",
6863
+ requestId: frame.requestId,
6864
+ },
6865
+ });
6866
+ return;
6867
+ }
6352
6868
  const bytes = concatByteChunks(transfer.chunks, transfer.size);
6353
6869
  this.activeBinaryFileTransfers.delete(frame.requestId);
6354
6870
  this.completedBinaryFileReads.set(frame.requestId, {
@@ -6752,30 +7268,6 @@ export class DaemonClient {
6752
7268
  responseType: "workspace.script.stop.response",
6753
7269
  });
6754
7270
  }
6755
- async connectHub(hubUrl, token, requestId) {
6756
- this.requireHubRelationshipSupport();
6757
- return this.sendCorrelatedSessionRequest({
6758
- requestId,
6759
- message: { type: "hub.management.daemon.connect.request", hubUrl, token },
6760
- responseType: "hub.management.daemon.connect.response",
6761
- });
6762
- }
6763
- async getHubStatus(requestId) {
6764
- this.requireHubRelationshipSupport();
6765
- return this.sendCorrelatedSessionRequest({
6766
- requestId,
6767
- message: { type: "hub.management.daemon.get_status.request" },
6768
- responseType: "hub.management.daemon.get_status.response",
6769
- });
6770
- }
6771
- async disconnectHub(force = false, requestId) {
6772
- this.requireHubRelationshipSupport();
6773
- return this.sendCorrelatedSessionRequest({
6774
- requestId,
6775
- message: { type: "hub.management.daemon.disconnect.request", force },
6776
- responseType: "hub.management.daemon.disconnect.response",
6777
- });
6778
- }
6779
7271
  requireHubRelationshipSupport() {
6780
7272
  // COMPAT(hubRelationship): added in v0.2.5, drop the gate when floor >= v0.2.5.
6781
7273
  if (this.lastServerInfoMessage?.features?.hubRelationship !== true) {
@@ -6783,21 +7275,4 @@ export class DaemonClient {
6783
7275
  }
6784
7276
  }
6785
7277
  }
6786
- function resolveAgentConfig(options) {
6787
- const { config, provider, cwd, env: _env, workspaceId: _workspaceId, initialPrompt: _initialPrompt, images: _images, git: _git, worktreeName: _worktreeName, requestId: _requestId, labels: _labels, ...overrides } = options;
6788
- const baseConfig = {
6789
- ...(provider ? { provider } : {}),
6790
- ...(cwd ? { cwd } : {}),
6791
- ...overrides,
6792
- };
6793
- const merged = config ? { ...baseConfig, ...config } : baseConfig;
6794
- if (!merged.provider || !merged.cwd) {
6795
- throw new Error("createAgent requires provider and cwd");
6796
- }
6797
- return {
6798
- ...merged,
6799
- provider: merged.provider,
6800
- cwd: merged.cwd,
6801
- };
6802
- }
6803
7278
  //# sourceMappingURL=daemon-client.js.map