@nuvin/session 0.1.0-rc.9 → 0.1.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.
Files changed (48) hide show
  1. package/dist/chunk-7HGJO7ZX.js +9 -0
  2. package/dist/chunk-HJLRL64D.js +13 -0
  3. package/dist/{chunk-3IPZO7LP.js → chunk-TUNCGICQ.js} +19 -1
  4. package/dist/{chunk-FR3R66RD.js → chunk-WAMOWOCO.js} +20 -2
  5. package/dist/{chunk-3J44LBXZ.js → chunk-WB4FEWBI.js} +1 -1
  6. package/dist/client/daemon-client.d.ts +50 -0
  7. package/dist/client/daemon-client.d.ts.map +1 -0
  8. package/dist/client/data-client.d.ts +21 -3
  9. package/dist/client/data-client.d.ts.map +1 -1
  10. package/dist/client/directory.d.ts +7 -12
  11. package/dist/client/directory.d.ts.map +1 -1
  12. package/dist/client/http-data-client.d.ts +2 -0
  13. package/dist/client/http-data-client.d.ts.map +1 -1
  14. package/dist/client/index.d.ts +1 -0
  15. package/dist/client/index.d.ts.map +1 -1
  16. package/dist/client/index.js +1300 -979
  17. package/dist/client/session-client.d.ts +19 -6
  18. package/dist/client/session-client.d.ts.map +1 -1
  19. package/dist/client/transport.d.ts +18 -2
  20. package/dist/client/transport.d.ts.map +1 -1
  21. package/dist/client/websocket.d.ts +5 -0
  22. package/dist/client/websocket.d.ts.map +1 -1
  23. package/dist/controller/index.js +129 -40
  24. package/dist/controller/session-controller.d.ts +18 -5
  25. package/dist/controller/session-controller.d.ts.map +1 -1
  26. package/dist/grant/index.d.ts +1 -1
  27. package/dist/grant/index.d.ts.map +1 -1
  28. package/dist/grant/index.js +2 -1
  29. package/dist/protocol/data-rpc.d.ts +70 -3
  30. package/dist/protocol/data-rpc.d.ts.map +1 -1
  31. package/dist/protocol/index.d.ts +1 -0
  32. package/dist/protocol/index.d.ts.map +1 -1
  33. package/dist/protocol/index.js +12 -3
  34. package/dist/protocol/model-identity.d.ts +7 -0
  35. package/dist/protocol/model-identity.d.ts.map +1 -0
  36. package/dist/protocol/types.d.ts +176 -83
  37. package/dist/protocol/types.d.ts.map +1 -1
  38. package/dist/protocol/version.d.ts +1 -1
  39. package/dist/state/approvals.d.ts +6 -3
  40. package/dist/state/approvals.d.ts.map +1 -1
  41. package/dist/state/index.js +5 -1
  42. package/dist/state/session.d.ts.map +1 -1
  43. package/dist/state/tool-preview.d.ts.map +1 -1
  44. package/dist/state/tool-preview.js +50 -1
  45. package/dist/test-utils/fake-relay.d.ts.map +1 -1
  46. package/dist/test-utils/index.js +6 -4
  47. package/package.json +5 -4
  48. package/dist/chunk-NN43LVAS.js +0 -0
@@ -1,9 +1,10 @@
1
1
  import type { AgentInput, AskUserAnswers } from "@nuvin/agent-core/shared";
2
- import type { AgentCatalogEntry, AgentDetail, CommandDetail, ConfigPatch, McpServerInfo, ModelCompletion, ServerEvent, SessionViewState, SetConfigResult, SkillCatalogEntry, SkillDetail, SlashCommandDescriptor } from "../protocol/types.ts";
2
+ import type { AgentCatalogEntry, AgentDetail, ChatGptCredentialInput, CommandDetail, ConfigPatch, CustomProviderInput, GrantCapability, McpAction, McpActionResult, McpServerInfo, ModelCompletion, ServerEvent, SessionViewState, SetConfigResult, SkillCatalogEntry, SkillDetail, SlashCommandDescriptor } from "../protocol/types.ts";
3
3
  import type { ClientTransport } from "./transport.ts";
4
4
  export type ClientSubmitOptions = {
5
5
  displayText: string;
6
6
  attachmentLabels?: string[];
7
+ turnId?: string;
7
8
  };
8
9
  /**
9
10
  * Client-side mirror of the replicated session state. Applies every incoming
@@ -29,17 +30,14 @@ export interface SessionClient {
29
30
  * republishes through a state-reset event; this resolves on the ack.
30
31
  */
31
32
  loadHistory(historyId: string): Promise<void>;
32
- /**
33
- * Signal the daemon to reload provider keys / config after local onboarding
34
- * wrote them to the shared config dir (spec §10/§12). Resolves on the ack.
35
- */
36
- reloadConfig(): Promise<void>;
37
33
  /**
38
34
  * Abort the in-flight MCP OAuth login (spec §10). Sends `cancel-auth-flow`;
39
35
  * the daemon invokes its live cancel handle, which publishes a cleared
40
36
  * `auth-flow` event. Resolves on the ack.
41
37
  */
42
38
  cancelAuthFlow(): Promise<void>;
39
+ /** Execute one authoritative MCP mutation in the attached daemon session. */
40
+ mcpAction(action: McpAction, serverName: string): Promise<McpActionResult>;
43
41
  /** Server-executed slash command descriptors from the attach snapshot. */
44
42
  serverCommands(): SlashCommandDescriptor[];
45
43
  /**
@@ -73,6 +71,21 @@ export interface SessionClient {
73
71
  getCommand(name: string): Promise<CommandDetail>;
74
72
  /** MCP servers with live status + per-server tools for the MCP tab. */
75
73
  listMcpServers(): Promise<McpServerInfo[]>;
74
+ /**
75
+ * Effective grant capabilities from the transport's latest welcome (UI hint).
76
+ * Empty when the transport does not expose capabilities.
77
+ */
78
+ capabilities(): readonly GrantCapability[];
79
+ /**
80
+ * Complete ChatGPT/Codex device-code login. Provider id is locked to
81
+ * `openai-codex`; callers cannot select another. Resolves on the ack.
82
+ */
83
+ completeProviderAuth(credential: ChatGptCredentialInput): Promise<void>;
84
+ /**
85
+ * Register a custom provider (base URL + API key + surface) on the attached
86
+ * host. Sends `add-custom-provider` and resolves on the ack.
87
+ */
88
+ addCustomProvider(provider: CustomProviderInput): Promise<void>;
76
89
  close(): void;
77
90
  }
78
91
  export declare function createSessionClient(transport: ClientTransport): SessionClient;
@@ -1 +1 @@
1
- {"version":3,"file":"session-client.d.ts","sourceRoot":"","sources":["../../src/client/session-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-client.d.ts","sourceRoot":"","sources":["../../src/client/session-client.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,25 @@
1
- import type { ClientCommand, ServerFrame } from "../protocol/types.ts";
1
+ import type { ClientCommand, GrantCapability, ServerFrame } from "../protocol/types.ts";
2
2
  /** Client side of a session transport. Implementation: WebSocket over UDS (local) or TCP (remote). */
3
3
  export interface ClientTransport {
4
- send(command: ClientCommand): void;
4
+ /**
5
+ * Send a command frame. Return `false` when the frame was dropped (not attached /
6
+ * not connected) so callers can fail pending promises instead of hanging forever.
7
+ * Returning `true` or `undefined` means the frame was handed to the socket.
8
+ */
9
+ send(command: ClientCommand): boolean | undefined;
5
10
  /** Subscribe to frames. The transport MUST deliver a snapshot frame first (attach semantics). */
6
11
  onFrame(listener: (frame: ServerFrame) => void): () => void;
7
12
  close(): void;
13
+ /**
14
+ * Effective grant capabilities from the latest welcome (UI hint only). Optional
15
+ * so lightweight fakes and non-daemon transports need not implement it —
16
+ * SessionClient treats a missing reader as an empty capability set.
17
+ */
18
+ capabilities?(): readonly GrantCapability[];
19
+ /**
20
+ * Optional: notify when in-flight commands can no longer receive acks (socket
21
+ * drop / reconnect). SessionClient rejects pending promises on this signal.
22
+ */
23
+ onUndeliverable?(listener: () => void): () => void;
8
24
  }
9
25
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/client/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEvE,sGAAsG;AACtG,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,iGAAiG;IACjG,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5D,KAAK,IAAI,IAAI,CAAC;CACf"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/client/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExF,sGAAsG;AACtG,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;IAClD,iGAAiG;IACjG,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5D,KAAK,IAAI,IAAI,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,IAAI,SAAS,eAAe,EAAE,CAAC;IAC5C;;;OAGG;IACH,eAAe,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CACpD"}
@@ -1,3 +1,4 @@
1
+ import type { GrantCapability } from "../protocol/types.ts";
1
2
  import { type GetEndpoint } from "./endpoint.ts";
2
3
  import { type TransportSocket } from "./socket.ts";
3
4
  import type { ClientTransport } from "./transport.ts";
@@ -38,6 +39,10 @@ export type WebSocketTransportOptions = {
38
39
  export interface WebSocketClientTransport extends ClientTransport {
39
40
  connectionState(): WebSocketTransportState;
40
41
  onConnectionState(listener: (state: WebSocketTransportState) => void): () => void;
42
+ /** Effective capabilities from the latest welcome; empty while handshake is open or closed. */
43
+ capabilities(): readonly GrantCapability[];
44
+ /** Always present on the WebSocket transport — signals dropped/reconnect undeliverable commands. */
45
+ onUndeliverable(listener: () => void): () => void;
41
46
  }
42
47
  /**
43
48
  * ClientTransport over a WebSocket (spec §4.6): hello/welcome handshake, then
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAiD,MAAM,eAAe,CAAC;AAChG,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,WAAW,CAAC;AAE5F,MAAM,MAAM,yBAAyB,GAAG;IACtC,iHAAiH;IACjH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0GAA0G;IAC1G,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,eAAe,CAAC;IACjD,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,eAAe,IAAI,uBAAuB,CAAC;IAC3C,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACnF;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,wBAAwB,CAwO1B"}
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,WAAW,EAAiD,MAAM,eAAe,CAAC;AAChG,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,WAAW,CAAC;AAE5F,MAAM,MAAM,yBAAyB,GAAG;IACtC,iHAAiH;IACjH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0GAA0G;IAC1G,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,eAAe,CAAC;IACjD,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,eAAe,IAAI,uBAAuB,CAAC;IAC3C,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAClF,+FAA+F;IAC/F,YAAY,IAAI,SAAS,eAAe,EAAE,CAAC;IAC3C,oGAAoG;IACpG,eAAe,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CACnD;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,wBAAwB,CAgR1B"}
@@ -6,8 +6,9 @@ import {
6
6
  createMessageStateFromMessages,
7
7
  createSessionViewState,
8
8
  isAutoApprovedTool,
9
+ isToolAutoApprovedForMode,
9
10
  reduceSessionEvent
10
- } from "../chunk-FR3R66RD.js";
11
+ } from "../chunk-WAMOWOCO.js";
11
12
 
12
13
  // src/controller/agent-channel.ts
13
14
  import { EventEmitter } from "events";
@@ -67,15 +68,18 @@ var MAX_AUTO_COMPACTION_CHAIN = 10;
67
68
  function createSessionController(deps) {
68
69
  const now = deps.now ?? Date.now;
69
70
  const isAutoApproved = deps.isAutoApproved ?? isAutoApprovedTool;
70
- const errorDetail = deps.errorDetail ?? ((error) => String(error));
71
+ const errorDetail = deps.errorDetail ?? ((error) => error instanceof Error ? error.message : String(error));
71
72
  let serverCommands = deps.serverCommands ?? [];
72
73
  let compaction = deps.compaction;
73
74
  let guardPrompt = deps.guardPrompt;
74
75
  let autoCompactionChain = 0;
75
76
  let state = createSessionViewState();
76
77
  let seq = 0;
77
- let sudoMode = false;
78
+ let approvalMode = deps.approvalMode ?? "ask";
78
79
  let abortController = null;
80
+ let activeTurnId;
81
+ let activePolicyDenial;
82
+ let hostBusyCount = 0;
79
83
  let questionCounter = 0;
80
84
  const listeners = /* @__PURE__ */ new Set();
81
85
  const approvalResolvers = /* @__PURE__ */ new Map();
@@ -85,9 +89,15 @@ function createSessionController(deps) {
85
89
  let queueCounter = 0;
86
90
  const deliveryQueue = [];
87
91
  let draining = false;
88
- const emit = (body) => {
92
+ const emit = (body, explicitTurnId) => {
89
93
  seq += 1;
90
- const event = Object.assign({}, body, { seq, at: now() });
94
+ const turnId = explicitTurnId ?? activeTurnId;
95
+ const event = Object.assign(
96
+ {},
97
+ body,
98
+ { seq, at: now() },
99
+ turnId !== void 0 ? { turnId } : {}
100
+ );
91
101
  state = reduceSessionEvent(state, event);
92
102
  deliveryQueue.push(event);
93
103
  if (draining) return;
@@ -106,10 +116,10 @@ function createSessionController(deps) {
106
116
  draining = false;
107
117
  }
108
118
  };
109
- const emitTurnStatus = (busy) => {
119
+ const emitTurnStatus = () => {
110
120
  emit({
111
121
  type: "turn-status",
112
- busy,
122
+ busy: abortController !== null || hostBusyCount > 0,
113
123
  queuedCount: queue.length,
114
124
  queued: queue.map((q) => ({
115
125
  id: q.id,
@@ -123,6 +133,7 @@ function createSessionController(deps) {
123
133
  emit({ type: "agent-event", event, ...scope ? { scope } : {} });
124
134
  });
125
135
  const unsubscribeLoaded = deps.channel.onSessionLoaded((loaded) => {
136
+ queue.length = 0;
126
137
  abortController?.abort(new Error("Session loaded; the active turn was cancelled."));
127
138
  rejectAllPending("Session loaded; pending interactions were cancelled.");
128
139
  emit({
@@ -133,6 +144,7 @@ function createSessionController(deps) {
133
144
  // else a resumed session reverts to the empty seed meta (no model name).
134
145
  state: {
135
146
  ...createSessionViewState(),
147
+ busy: hostBusyCount > 0,
136
148
  meta: state.meta,
137
149
  messages: createMessageStateFromMessages(loaded.messages)
138
150
  }
@@ -142,8 +154,8 @@ function createSessionController(deps) {
142
154
  const { toolCall, agentId, parentToolCallId, dirAccess } = request;
143
155
  const scope = parentToolCallId !== void 0 ? { agentId, parentToolCallId } : void 0;
144
156
  const approvalKey = `${agentId}:${toolCall.name}`;
145
- const auto = !dirAccess && (sudoMode || alwaysApproved.has(approvalKey) || isAutoApproved(toolCall.name));
146
- if (dirAccess && sudoMode) {
157
+ const auto = !dirAccess && (alwaysApproved.has(approvalKey) || isToolAutoApprovedForMode(approvalMode, toolCall.name, isAutoApproved));
158
+ if (dirAccess && approvalMode === "sudo") {
147
159
  emit({
148
160
  type: "agent-event",
149
161
  event: { type: "tool_call", toolCall },
@@ -164,8 +176,13 @@ function createSessionController(deps) {
164
176
  emit({
165
177
  type: "agent-event",
166
178
  event: { type: "tool_call", toolCall },
179
+ ...deps.headless ? { toolStatus: "rejected" } : {},
167
180
  ...scope ? { scope } : {}
168
181
  });
182
+ if (deps.headless) {
183
+ activePolicyDenial = "Tool approval is unavailable in headless mode.";
184
+ return { action: "reject", reason: activePolicyDenial };
185
+ }
169
186
  const nickname = nicknameFor(parentToolCallId);
170
187
  const input = asJsonObject(toolCall.input);
171
188
  const descriptor = {
@@ -184,6 +201,10 @@ function createSessionController(deps) {
184
201
  });
185
202
  });
186
203
  deps.channel.setQuestionHandler((request) => {
204
+ if (deps.headless) {
205
+ activePolicyDenial = "Questions are unavailable in headless mode.";
206
+ return Promise.reject(new Error(activePolicyDenial));
207
+ }
187
208
  questionCounter += 1;
188
209
  const questionId = `question-${questionCounter}`;
189
210
  return new Promise((resolve, reject) => {
@@ -221,28 +242,39 @@ function createSessionController(deps) {
221
242
  }
222
243
  questionResolvers.clear();
223
244
  }
224
- function finalizeTurn(controller, reason) {
225
- if (abortController !== controller) return;
226
- abortController = null;
227
- rejectAllPending(reason);
228
- emitTurnStatus(false);
245
+ function startNextQueuedSubmission() {
246
+ if (abortController || hostBusyCount > 0) return;
229
247
  const next = queue.shift();
230
- if (next) {
231
- if (!next.opts.silent) {
232
- emit({
248
+ if (!next) return;
249
+ if (!next.opts.silent) {
250
+ emit(
251
+ {
233
252
  type: "user-message",
234
253
  text: next.opts.displayText,
235
254
  ...next.opts.attachmentLabels?.length ? { attachmentLabels: next.opts.attachmentLabels } : {}
236
- });
237
- }
238
- void runTurn(next.input, {});
255
+ },
256
+ next.opts.turnId
257
+ );
239
258
  }
259
+ void runTurn(next.input, { turnId: next.opts.turnId });
260
+ }
261
+ function finalizeTurn(controller, reason) {
262
+ if (abortController !== controller) return false;
263
+ abortController = null;
264
+ rejectAllPending(reason);
265
+ emitTurnStatus();
266
+ return true;
240
267
  }
241
268
  async function runTurn(input, opts) {
242
269
  const controller = new AbortController();
270
+ const previousTurnId = activeTurnId;
271
+ if (opts.turnId !== void 0) activeTurnId = opts.turnId;
272
+ if (!opts.systemInitiated) activePolicyDenial = void 0;
243
273
  abortController = controller;
274
+ let terminalStatus = "completed";
275
+ let terminalMessage;
244
276
  try {
245
- emitTurnStatus(true);
277
+ emitTurnStatus();
246
278
  if (!opts.systemInitiated) autoCompactionChain = 0;
247
279
  compaction?.setEnabled(true);
248
280
  let finalInput = input;
@@ -251,11 +283,15 @@ function createSessionController(deps) {
251
283
  try {
252
284
  guarded = await guardPrompt(input);
253
285
  } catch (error) {
254
- emit({ type: "error", message: `Turn failed: ${errorDetail(error)}` });
286
+ terminalStatus = "failed";
287
+ terminalMessage = errorDetail(error);
288
+ emit({ type: "error", message: terminalMessage });
255
289
  return;
256
290
  }
257
291
  if ("blocked" in guarded) {
258
- emit({ type: "error", message: `Prompt blocked: ${guarded.blocked.reason}` });
292
+ terminalStatus = "failed";
293
+ terminalMessage = `Prompt blocked: ${guarded.blocked.reason}`;
294
+ emit({ type: "error", message: terminalMessage });
259
295
  return;
260
296
  }
261
297
  finalInput = guarded.prompt;
@@ -281,27 +317,61 @@ function createSessionController(deps) {
281
317
  await compaction.run(compactionIo);
282
318
  };
283
319
  try {
284
- await deps.agent.send(finalInput, { streaming: true, signal: controller.signal });
320
+ const result = await deps.agent.send(finalInput, {
321
+ streaming: true,
322
+ signal: controller.signal
323
+ });
324
+ if (typeof result === "object" && result !== null && "status" in result && result.status === "aborted") {
325
+ terminalStatus = "aborted";
326
+ }
285
327
  if (compaction && !controller.signal.aborted) {
286
328
  if (compaction.consumePendingAction() === "compact") {
287
329
  await runCompaction();
288
330
  }
289
331
  }
290
332
  } catch (error) {
333
+ if (controller.signal.aborted || isAbortError(error)) {
334
+ terminalStatus = "aborted";
335
+ }
291
336
  try {
292
337
  const recovered = compaction ? compaction.messagesFromError(error) : null;
293
338
  if (recovered) {
294
339
  deps.agent.messages = recovered;
295
340
  await runCompaction();
296
341
  } else if (!controller.signal.aborted && !isAbortError(error)) {
297
- emit({ type: "error", message: `Turn failed: ${errorDetail(error)}` });
342
+ terminalStatus = "failed";
343
+ terminalMessage = errorDetail(error);
344
+ emit({ type: "error", message: terminalMessage });
298
345
  }
299
346
  } catch (recoveryError) {
300
- emit({ type: "error", message: `Turn failed: ${errorDetail(recoveryError)}` });
347
+ terminalStatus = "failed";
348
+ terminalMessage = errorDetail(recoveryError);
349
+ emit({ type: "error", message: terminalMessage });
301
350
  }
302
351
  }
303
352
  } finally {
304
- finalizeTurn(controller, "Turn ended before pending interactions could be resolved.");
353
+ const ownedTurn = finalizeTurn(
354
+ controller,
355
+ "Turn ended before pending interactions could be resolved."
356
+ );
357
+ if (activePolicyDenial !== void 0) {
358
+ terminalStatus = "failed";
359
+ terminalMessage = activePolicyDenial;
360
+ }
361
+ if (opts.turnId !== void 0) {
362
+ emit(
363
+ {
364
+ type: "turn-completed",
365
+ status: terminalStatus,
366
+ ...activePolicyDenial !== void 0 ? { reason: "policy-denied" } : {},
367
+ ...terminalMessage !== void 0 ? { message: terminalMessage } : {}
368
+ },
369
+ opts.turnId
370
+ );
371
+ }
372
+ if (!opts.systemInitiated) activePolicyDenial = void 0;
373
+ activeTurnId = previousTurnId;
374
+ if (ownedTurn) startNextQueuedSubmission();
305
375
  }
306
376
  }
307
377
  return {
@@ -340,7 +410,7 @@ function createSessionController(deps) {
340
410
  const index = queue.findIndex((q) => q.id === queuedId);
341
411
  if (index === -1) return false;
342
412
  queue.splice(index, 1);
343
- emitTurnStatus(abortController !== null);
413
+ emitTurnStatus();
344
414
  return true;
345
415
  },
346
416
  decideApproval(toolCallId, decision, comment, grantDir) {
@@ -388,6 +458,9 @@ function createSessionController(deps) {
388
458
  getSnapshot() {
389
459
  return { seq, state, serverCommands };
390
460
  },
461
+ isHostBusy() {
462
+ return hostBusyCount > 0;
463
+ },
391
464
  onEvent(listener) {
392
465
  listeners.add(listener);
393
466
  return () => listeners.delete(listener);
@@ -404,37 +477,53 @@ function createSessionController(deps) {
404
477
  publishAuthFlow(flow) {
405
478
  emit({ type: "auth-flow", flow });
406
479
  },
480
+ publishMcpState(mcpState) {
481
+ emit({ type: "mcp-state", state: mcpState });
482
+ },
407
483
  publishWorkflowProgress(runId, delta) {
408
484
  emit({ type: "workflow-progress", runId, delta });
409
485
  },
410
486
  reset() {
411
487
  queue.length = 0;
488
+ hostBusyCount = 0;
412
489
  abortController?.abort(new Error("Session reset."));
413
490
  rejectAllPending("Session reset; pending interactions were cancelled.");
414
491
  alwaysApproved.clear();
415
- sudoMode = false;
492
+ approvalMode = "ask";
416
493
  emit({
417
494
  type: "state-reset",
418
- state: { ...createSessionViewState(), meta: state.meta }
495
+ state: { ...createSessionViewState(), meta: state.meta, mcp: state.mcp }
419
496
  });
420
497
  },
421
- setSudoMode(value) {
422
- sudoMode = value;
498
+ setApprovalMode(mode) {
499
+ approvalMode = mode;
500
+ },
501
+ setBusy(busy) {
502
+ if (busy) {
503
+ hostBusyCount += 1;
504
+ } else if (hostBusyCount > 0) {
505
+ hostBusyCount -= 1;
506
+ }
507
+ emitTurnStatus();
508
+ startNextQueuedSubmission();
423
509
  },
424
510
  async submit(input, opts) {
425
- if (abortController) {
511
+ if (abortController || hostBusyCount > 0) {
426
512
  queue.push({ id: `q-${++queueCounter}`, input, opts });
427
- emitTurnStatus(true);
513
+ emitTurnStatus();
428
514
  return;
429
515
  }
430
516
  if (!opts.silent) {
431
- emit({
432
- type: "user-message",
433
- text: opts.displayText,
434
- ...opts.attachmentLabels?.length ? { attachmentLabels: opts.attachmentLabels } : {}
435
- });
517
+ emit(
518
+ {
519
+ type: "user-message",
520
+ text: opts.displayText,
521
+ ...opts.attachmentLabels?.length ? { attachmentLabels: opts.attachmentLabels } : {}
522
+ },
523
+ opts.turnId
524
+ );
436
525
  }
437
- await runTurn(input, {});
526
+ await runTurn(input, { turnId: opts.turnId });
438
527
  }
439
528
  };
440
529
  }
@@ -1,6 +1,7 @@
1
1
  import type { AgentMetricsSnapshot } from "@nuvin/agent-core/agent";
2
2
  import { type AgentInput, type AskUserAnswers, type Message } from "@nuvin/agent-core/shared";
3
- import type { McpAuthFlowState, ServerEvent, SessionMeta, SessionSnapshot, SlashCommandDescriptor, WorkflowProgressDelta } from "../protocol/types.ts";
3
+ import type { McpAuthFlowState, McpViewState, ServerEvent, SessionMeta, SessionSnapshot, SlashCommandDescriptor, WorkflowProgressDelta } from "../protocol/types.ts";
4
+ import { type SessionApprovalMode } from "../state/approvals.ts";
4
5
  import type { AgentChannel } from "./agent-channel.ts";
5
6
  /** Subset of Agent the controller needs — structurally satisfied by @nuvin/agent-core Agent. */
6
7
  export type AgentLike = {
@@ -53,6 +54,10 @@ export interface SessionControllerDeps {
53
54
  * attach snapshot for autocomplete. Defaults to an empty list.
54
55
  */
55
56
  serverCommands?: SlashCommandDescriptor[];
57
+ /** Non-interactive sessions never wait for an approval or question response. */
58
+ headless?: boolean;
59
+ /** Existing approval mode to apply when the controller is created. */
60
+ approvalMode?: SessionApprovalMode;
56
61
  }
57
62
  export type SubmitOptions = {
58
63
  displayText: string;
@@ -62,6 +67,8 @@ export type SubmitOptions = {
62
67
  * already echoed their text). `displayText` may be `""` in that case.
63
68
  */
64
69
  silent?: boolean;
70
+ /** Caller identifier copied onto all events produced by this turn. */
71
+ turnId?: string;
65
72
  };
66
73
  export interface SessionController {
67
74
  abort(): void;
@@ -106,6 +113,8 @@ export interface SessionController {
106
113
  * mutated in place. Callers must treat the returned state as read-only.
107
114
  */
108
115
  getSnapshot(): SessionSnapshot;
116
+ /** Return whether a host-controlled server operation currently owns busy state. */
117
+ isHostBusy(): boolean;
109
118
  onEvent(listener: (event: ServerEvent) => void): () => void;
110
119
  /**
111
120
  * Replace the server-executed slash-command descriptors surfaced in the attach
@@ -128,6 +137,8 @@ export interface SessionController {
128
137
  * reduces it like any other event. `null` clears the client modal.
129
138
  */
130
139
  publishAuthFlow(flow: McpAuthFlowState): void;
140
+ /** Publish the authoritative MCP catalog and operation state. */
141
+ publishMcpState(state: McpViewState): void;
131
142
  /**
132
143
  * Publish a workflow UI progress delta (spec §8.2/§13). The WorkflowManager
133
144
  * is the sole caller. emit-only — sequences + reduces into
@@ -136,13 +147,15 @@ export interface SessionController {
136
147
  publishWorkflowProgress(runId: string, delta: WorkflowProgressDelta): void;
137
148
  /**
138
149
  * Reset session state: abort any active turn, clear queued submissions,
139
- * reject pending approvals/questions, clear alwaysApproved + sudo, and emit
150
+ * reject pending approvals/questions, clear alwaysApproved + approvalMode, and emit
140
151
  * a state-reset with a fresh view state CARRYING OVER the last published
141
- * meta. Runtime-side resets (sessionStore.startNewSession, agent system
142
- * prompt, metrics) are the HOST's job — it calls those, then this.
152
+ * meta and authoritative MCP state. Runtime-side resets
153
+ * (sessionStore.startNewSession, agent system prompt, metrics) are the HOST's
154
+ * job — it calls those, then this.
143
155
  */
144
156
  reset(): void;
145
- setSudoMode(value: boolean): void;
157
+ setApprovalMode(mode: SessionApprovalMode): void;
158
+ setBusy(busy: boolean): void;
146
159
  /**
147
160
  * Submit user input. If no turn is active, the returned promise resolves
148
161
  * when the turn completes. If a turn is already active, the submission is
@@ -1 +1 @@
1
- {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/controller/session-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,KAAK,UAAU,EACf,KAAK,cAAc,EAEnB,KAAK,OAAO,EAEb,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAEV,gBAAgB,EAChB,WAAW,EAEX,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,gGAAgG;AAChG,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9F,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAEnF;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,+EAA+E;IAC/E,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,kEAAkE;IAClE,oBAAoB,IAAI,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpD,iFAAiF;IACjF,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IACpD,mFAAmF;IACnF,GAAG,CAAC,IAAI,EAAE;QACR,MAAM,EAAE,WAAW,CAAC;QACpB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;QAClC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;KACpC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,oDAAoD;IACpD,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACzC;;;OAGG;IACH,cAAc,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,KAAK,IAAI,IAAI,CAAC;IACd;;;;;;;OAOG;IACH,eAAe,CAAC,KAAK,EAAE;QACrB,UAAU,CAAC,EAAE,eAAe,CAAC;QAC7B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;KAC3D,GAAG,IAAI,CAAC;IACT;;;;;;;OAOG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;IACrE,yDAAyD;IACzD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,uFAAuF;IACvF,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,KAAK,IAAI,IAAI,CAAC;IACd;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IACX,gGAAgG;IAChG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjE;;;;OAIG;IACH,WAAW,IAAI,eAAe,CAAC;IAC/B,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5D;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC;IAC5D,+FAA+F;IAC/F,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrD;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC3E;;;;;;OAMG;IACH,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAYD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,iBAAiB,CAuetF"}
1
+ {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/controller/session-controller.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { GrantPayload } from "../protocol/types.ts";
1
+ import { type GrantPayload } from "../protocol/types.ts";
2
2
  /** ±5 min clock-skew tolerance on expiry/issuedAt checks (relay spec §7). */
3
3
  export declare const DEFAULT_GRANT_SKEW_MS: number;
4
4
  /** base64 DER key pair: `publicKey` SPKI (daemon.yaml), `privateKey` PKCS#8 (server secret). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grant/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,QAAgB,CAAC;AAEnD,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAC1B,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,eAAe,GACf,WAAW,CAAC;AAEhB,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE9C,wBAAgB,oBAAoB,IAAI,YAAY,CAMnD;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CASjF;AAcD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3E,iBAAiB,CAuCnB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grant/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE7E,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,QAAgB,CAAC;AAEnD,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAC1B,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,eAAe,GACf,WAAW,CAAC;AAEhB,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE9C,wBAAgB,oBAAoB,IAAI,YAAY,CAMnD;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CASjF;AA+BD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3E,iBAAiB,CAuCnB"}
@@ -3,7 +3,8 @@ import {
3
3
  generateGrantKeyPair,
4
4
  signGrant,
5
5
  verifyGrant
6
- } from "../chunk-3IPZO7LP.js";
6
+ } from "../chunk-TUNCGICQ.js";
7
+ import "../chunk-HJLRL64D.js";
7
8
  export {
8
9
  DEFAULT_GRANT_SKEW_MS,
9
10
  generateGrantKeyPair,
@@ -1,4 +1,24 @@
1
- import type { HistoryPage, SessionSnapshot, WorkspaceSummary } from "./types.ts";
1
+ import type { ConfigMutationResult, HistoryPage, ProfileSummary, ProviderConfigSummary, ProviderCredentialInput, ProviderSurfaceId, SessionSnapshot, WorkspaceConfigSummary } from "./types.ts";
2
+ export type DataRpcErrorCode = "invalid-input" | "not-found" | "conflict" | "unsupported" | "unauthorized" | "daemon-offline" | "internal";
3
+ export type DataRpcError = {
4
+ code: DataRpcErrorCode;
5
+ message: string;
6
+ };
7
+ export type ProfileScope = {
8
+ profile?: string;
9
+ };
10
+ export type AddProviderInput = ProfileScope & {
11
+ name: string;
12
+ surface: ProviderSurfaceId;
13
+ baseUrl?: string;
14
+ defaultModel?: string;
15
+ credential: ProviderCredentialInput;
16
+ activate?: boolean;
17
+ };
18
+ export type UpdateWorkspaceInput = ProfileScope & {
19
+ activeProvider?: string;
20
+ toggles?: Record<string, boolean>;
21
+ };
2
22
  /**
3
23
  * The read/management data plane: ONE schema, two transports into the daemon
4
24
  * (local REST via rest-http.ts, relay control RPC via daemons.controller.ts →
@@ -39,7 +59,7 @@ export type DataRpcSchema = {
39
59
  params: {
40
60
  profile?: string;
41
61
  };
42
- result: WorkspaceSummary[];
62
+ result: WorkspaceConfigSummary[];
43
63
  };
44
64
  "create-workspace": {
45
65
  params: {
@@ -47,7 +67,54 @@ export type DataRpcSchema = {
47
67
  root?: string;
48
68
  profile?: string;
49
69
  };
50
- result: WorkspaceSummary;
70
+ result: WorkspaceConfigSummary;
71
+ };
72
+ "list-profiles": {
73
+ params: Record<string, never>;
74
+ result: ProfileSummary[];
75
+ };
76
+ "list-providers": {
77
+ params: ProfileScope;
78
+ result: ProviderConfigSummary[];
79
+ };
80
+ "add-provider": {
81
+ params: AddProviderInput;
82
+ result: ConfigMutationResult<ProviderConfigSummary>;
83
+ };
84
+ "remove-provider": {
85
+ params: {
86
+ providerId: string;
87
+ profile?: string;
88
+ };
89
+ result: ConfigMutationResult<null>;
90
+ };
91
+ "set-default-provider": {
92
+ params: {
93
+ providerId: string;
94
+ profile?: string;
95
+ };
96
+ result: ConfigMutationResult<null>;
97
+ };
98
+ "set-provider-auth": {
99
+ params: {
100
+ providerId: string;
101
+ credential: ProviderCredentialInput;
102
+ profile?: string;
103
+ };
104
+ result: ConfigMutationResult<null>;
105
+ };
106
+ "clear-provider-auth": {
107
+ params: {
108
+ providerId: string;
109
+ profile?: string;
110
+ };
111
+ result: ConfigMutationResult<null>;
112
+ };
113
+ "update-workspace": {
114
+ params: UpdateWorkspaceInput & {
115
+ name: string;
116
+ };
117
+ result: ConfigMutationResult<WorkspaceConfigSummary>;
51
118
  };
52
119
  };
53
120
  export type DataRpcMethod = keyof DataRpcSchema;