dsh-side-chat-plus 0.3.2 → 0.3.4

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,384 +1,415 @@
1
- /**
2
- * Structural types for the cordis services this plugin consumes, plus the
3
- * Context augmentation both halves share. A third-party plugin resolves
4
- * outside the DSH monorepo's single cordis instance, so the upstream
5
- * `declare module 'cordis'` augmentations do not reach this Context; the
6
- * members below mirror the actual runtime shapes this plugin touches.
7
- *
8
- * The `sessions` field is a union of the HOST store face (get/list) and the
9
- * CLIENT list feed (list.getSnapshot/subscribe): each half only touches its
10
- * own side, and the shared declaration keeps the two cordis instance layers
11
- * from colliding under one tsconfig.
12
- */
13
- import type { IncomingMessage, ServerResponse } from 'node:http'
14
- import type { Context } from 'cordis'
15
-
16
- /** One named webserver route. */
17
- export interface SideWebRoute {
18
- kind: 'exact' | 'prefix'
19
- path: string
20
- handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>
21
- }
22
-
23
- /** The webServer service face this plugin uses. */
24
- export interface SideWebServer {
25
- register(route: SideWebRoute): () => void
26
- }
27
-
28
- /** A published session's header slice (authoritative cwd, lineage, origin). */
29
- export interface SideSessionHeader {
30
- cwd?: string
31
- parentSession?: string
32
- origin?: 'subagent'
33
- delegationDepth?: number
34
- }
35
-
36
- /** One session event (fold source for history and permission current). */
37
- export interface SideSessionEvent {
38
- type: string
39
- seq: number
40
- time: number
41
- data: Record<string, unknown>
42
- surfaceOp?: 'append' | 'replace' | 'remove'
43
- sourceEventSeqs?: number[]
44
- }
45
-
46
- /** The live session face the host reads (header + append-only event log). */
47
- export interface SideSession {
48
- id: string
49
- header: SideSessionHeader
50
- events?: readonly SideSessionEvent[]
51
- requestHeader?: () => { config?: { provider?: string; model?: string; reasoningEffort?: string; maxTokens?: number } } | undefined
52
- }
53
-
54
- /** The host session store face (`ctx.sessions` host side). */
55
- export interface SideSessionStore {
56
- get(id: string): SideSession | undefined
57
- list(): SideSession[]
58
- }
59
-
60
- /** One session list row (client list feed). */
61
- export interface SideSessionSummary {
62
- id: string
63
- displayTitle: string
64
- cwd?: string
65
- origin?: 'subagent'
66
- parentId?: string
67
- running: boolean
68
- }
69
-
70
- /** The session list snapshot the browser half subscribes to. */
71
- export interface SideSessionList {
72
- current: string | undefined
73
- byId: Record<string, SideSessionSummary>
74
- }
75
-
76
- /** One selectable answer in a user-question dialog. */
77
- export interface SideQuestionOption {
78
- label: string
79
- description?: string
80
- }
81
-
82
- /** One question in a pending user-question dialog. */
83
- export interface SideQuestionItem {
84
- id: string
85
- question: string
86
- detail?: string
87
- header?: string
88
- options?: SideQuestionOption[]
89
- multiSelect?: boolean
90
- }
91
-
92
- /** A pending main-conversation interaction (question / plan-review / approval dialog). */
93
- export interface SidePendingInteraction {
94
- /** Presentation discriminator: the question family, or an approval. */
95
- kind: 'question' | 'plan-review' | 'approval'
96
- /** Opaque render identity and request key (e.g. `question:1`). */
97
- key: string
98
- sessionId: string
99
- /** The request's question list (present for the question family). */
100
- questions?: SideQuestionItem[]
101
- }
102
-
103
- /** The per-session pending-interaction source exposed by the `uiSession` service. */
104
- export interface SidePendingInteractionStore {
105
- getSnapshot(): ReadonlyMap<string, SidePendingInteraction>
106
- subscribe(fn: () => void): () => void
107
- }
108
-
109
- /** The client sessions service face (list feed + scope resolution). */
110
- export interface SideSessionsService {
111
- list: {
112
- getSnapshot(): SideSessionList
113
- subscribe(fn: () => void): () => void
114
- }
115
- /** Resolve an Agent-scoped context view for a listed session id (use-and-discard). */
116
- scope(id: string): Context | undefined
117
- }
118
-
119
- /** The client UI-session service face (per-session pending interactions). */
120
- export interface SideUiSessionService {
121
- /** Per-session pending UI interaction (question / plan-review / approval). */
122
- pendingInteractions: SidePendingInteractionStore
123
- }
124
-
125
- /** Agent options (provider/model/maxTokens). */
126
- export interface SideAgentOptions {
127
- provider?: string
128
- model?: string
129
- maxTokens?: number
130
- }
131
-
132
- /** The live agent face (`ctx.agents.get(id)` / `AgentHandle.agent`). */
133
- export interface SideAgent {
134
- readonly id: string
135
- readonly options: SideAgentOptions
136
- readonly session: SideSession
137
- readonly status: string
138
- readonly ctx: Context
139
- followup(message: unknown): void
140
- inject(message: unknown): void
141
- cancel(cause: { kind: 'user' | 'parent' | 'disposed' } | { kind: 'hook'; reason: string }): void
142
- whenIdle(): Promise<void>
143
- }
144
-
145
- /** The agent handle `ctx.agents.create` resolves (owner tears the agent down). */
146
- export interface SideAgentHandle {
147
- agent: SideAgent
148
- dispose(): Promise<void>
149
- }
150
-
151
- /** `ctx.agents.create` options (mirror of CreateAgentOptions). */
152
- export interface SideCreateAgentOptions {
153
- sessionId: string
154
- meta?: {
155
- cwd?: string
156
- parentSession?: string
157
- agentPreset?: string
158
- }
159
- agentOptions?: SideAgentOptions
160
- setup?: (agentCtx: Context) => void | Promise<void>
161
- }
162
-
163
- /** The host agent registry face. */
164
- export interface SideAgentsService {
165
- get(id: string): SideAgent | undefined
166
- create(options: SideCreateAgentOptions): Promise<SideAgentHandle>
167
- }
168
-
169
- /** Live provider / model / reasoning-effort selection for one agent. */
170
- export interface SideModelSelection {
171
- provider: string
172
- model: string
173
- reasoningEffort?: string
174
- }
175
-
176
- /**
177
- * Mutable selection plus the value captured when the current step entered
178
- * prompt assembly (`current` / `assembled`).
179
- */
180
- export interface SideModelSelectionRef {
181
- current: SideModelSelection | undefined
182
- assembled: SideModelSelection | undefined
183
- }
184
-
185
- /**
186
- * Couple a mutable selection to an agent's prompt assembly and request routing
187
- * (`installModelSelection` on the agent package). Typed structurally rather
188
- * than imported: this plugin resolves outside the DSH monorepo's single cordis
189
- * instance, so the upstream export is reached through a loose signature.
190
- */
191
- export type SideInstallModelSelection = (agentCtx: Context, selection: SideModelSelectionRef) => () => void
192
-
193
- /** The workspace registry face (archive a session durably). */
194
- export interface SideWorkspaceRegistry {
195
- archiveSession(sessionId: string): Promise<void>
196
- }
197
-
198
- /** `sessionQuery.readSession` snapshot. */
199
- export interface SideSessionLogSnapshot {
200
- session: SideSessionHeader
201
- events: SideSessionEvent[]
202
- }
203
-
204
- /** The session query face. */
205
- export interface SideSessionQuery {
206
- readSession(sessionId: string): Promise<SideSessionLogSnapshot>
207
- }
208
-
209
- /** Sandbox mode vocabulary (read from the session override). */
210
- export type SideSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
211
-
212
- /** The sandbox policy face. */
213
- export interface SideSandboxPolicy {
214
- overrideOf(session: SideSession): SideSandboxMode | undefined
215
- }
216
-
217
- /** One permission preset option. */
218
- export interface SidePresetOption {
219
- value: string
220
- name: string
221
- description?: string
222
- }
223
-
224
- /** The permission presets face. */
225
- export interface SidePermissionPresets {
226
- current(events: readonly SideSessionEvent[]): string
227
- set(session: SideSession, name: string): void
228
- selectFor(state: unknown): { options: SidePresetOption[]; currentValue: string }
229
- }
230
-
231
- /** The agent presets face (composeFrom joins a child to the parent's composition). */
232
- export interface SideAgentPresets {
233
- composeFrom(agentCtx: Context, parentCtx: Context): string | undefined
234
- }
235
-
236
- /** One provider route. */
237
- export interface SideLlmProvider {
238
- id: string
239
- name: string
240
- }
241
-
242
- /** One model entry. */
243
- export interface SideLlmModel {
244
- provider: string
245
- id: string
246
- name: string
247
- description?: string
248
- }
249
-
250
- /** One reasoning-effort entry. */
251
- export interface SideLlmEffort {
252
- id: string
253
- name: string
254
- description?: string
255
- }
256
-
257
- /** One model-request stream chunk (minimal structural view for text collection). */
258
- export interface SideLlmStreamChunk {
259
- type: string
260
- text?: string
261
- }
262
-
263
- /** Minimal generate options the summarize route builds (a hand-built user prompt). */
264
- export interface SideLlmGenerateOptions {
265
- provider: string
266
- model: string
267
- reasoningEffort?: string
268
- maxTokens?: number
269
- signal?: AbortSignal
270
- messages: Array<{
271
- id?: string
272
- role: 'user' | 'assistant' | 'system'
273
- content: Array<{ type: 'text'; text: string }>
274
- source?: { kind: string }
275
- }>
276
- }
277
-
278
- /** The llm face (model/effort catalog + one-shot streaming calls). */
279
- export interface SideLlm {
280
- listProviders(): SideLlmProvider[]
281
- listModels(provider: string): Promise<SideLlmModel[]>
282
- resolveModelInfo(provider: string, model: string): Promise<{
283
- provider: string
284
- id: string
285
- name: string
286
- reasoning?: { efforts: readonly SideLlmEffort[]; defaultEffort?: string }
287
- }>
288
- stream(options: SideLlmGenerateOptions): AsyncIterable<SideLlmStreamChunk>
289
- }
290
-
291
- /** The client locale service face. */
292
- export interface SideLocaleService {
293
- getSnapshot(): { active: string }
294
- subscribe(fn: () => void): () => void
295
- register(ns: string, locale: string, dict: Record<string, string>): () => void
296
- }
297
-
298
- /** The host settings service face (namespace registration + read/write). */
299
- export interface SideSettingsService {
300
- register(ns: unknown, schema: unknown): { get(): unknown; watch(cb: (next: unknown, prev: unknown) => void): () => void }
301
- describe(opts: { redactSecrets?: boolean }): Array<{ ns: unknown; value?: unknown; revision?: number }>
302
- update(ns: unknown, patch: Record<string, unknown>, expectedRevision?: number): Promise<void>
303
- }
304
-
305
- /** The client slots service face (settings.section registration). */
306
- export interface SideSlotsService {
307
- inject(name: string, factory: () => () => void): void
308
- register(options: Record<string, unknown>, component: unknown): () => void
309
- }
310
-
311
- /** One durable image reference (mirror of ImageAttachmentRef). */
312
- export interface SideImageAttachmentRef {
313
- attachmentId: string
314
- mediaType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
315
- bytes: number
316
- width: number
317
- height: number
318
- name?: string
319
- }
320
-
321
- /** The host attachment store face (`ctx.attachments`). */
322
- export interface SideAttachmentStore {
323
- readonly imageLimits: {
324
- maxImageBytes: number
325
- maxImagesPerMessage: number
326
- maxMessageImageBytes: number
327
- maxImagePixels: number
328
- mediaTypes: readonly string[]
329
- }
330
- validateImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<void>
331
- saveImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<SideImageAttachmentRef>
332
- readImage(ref: SideImageAttachmentRef): Promise<{ ref: SideImageAttachmentRef; data: Uint8Array }>
333
- }
334
-
335
- /** The host command registry face (`ctx.commands`). */
336
- export interface SideCommandsService {
337
- list(agent: SideAgent): Array<{ name: string; description: string }>
338
- execute(agent: SideAgent, line: string, signal: AbortSignal): Promise<unknown>
339
- }
340
-
341
- /** The per-session composer input face this plugin writes to (draft-only). */
342
- export interface SideSessionInput {
343
- /** Replace the session composer draft (never submits). */
344
- setDraft(text: string): void
345
- /** Live input state store (draft read). */
346
- state: { getSnapshot(): { draft: string } }
347
- /** Surface a notice on the session composer. */
348
- notify(level: 'info' | 'error', text: string): void
349
- }
350
-
351
- /** The conversation service face (`ctx.conversation`) — input registry only. */
352
- export interface SideConversationService {
353
- input: {
354
- /** Resolve the input facade for one session-scope context. */
355
- for(actx: Context): SideSessionInput
356
- }
357
- }
358
-
359
- declare module 'cordis' {
360
- interface Context {
361
- webServer: SideWebServer
362
- sessions: SideSessionStore & SideSessionsService
363
- agents: SideAgentsService
364
- workspaceRegistry: SideWorkspaceRegistry
365
- sessionQuery: SideSessionQuery
366
- sandboxPolicy: SideSandboxPolicy
367
- permissionPresets: SidePermissionPresets
368
- agentPresets: SideAgentPresets
369
- llm: SideLlm
370
- locale: SideLocaleService
371
- settings: SideSettingsService
372
- slots: SideSlotsService
373
- attachments: SideAttachmentStore
374
- commands: SideCommandsService
375
- conversation: SideConversationService
376
- uiSession: SideUiSessionService
377
- inject(deps: string[], callback: (ctx: Context) => void): void
378
- get(name: string): unknown | undefined
379
- on(name: string, listener: (...args: any[]) => any): () => void
380
- effect(fn: () => void | (() => void), label?: string): void
381
- }
382
- }
383
-
384
- export type { Context }
1
+ /**
2
+ * Structural types for the cordis services this plugin consumes, plus the
3
+ * Context augmentation both halves share. A third-party plugin resolves
4
+ * outside the DSH monorepo's single cordis instance, so the upstream
5
+ * `declare module 'cordis'` augmentations do not reach this Context; the
6
+ * members below mirror the actual runtime shapes this plugin touches.
7
+ *
8
+ * The `sessions` field is a union of the HOST store face (get/list) and the
9
+ * CLIENT list feed (list.getSnapshot/subscribe): each half only touches its
10
+ * own side, and the shared declaration keeps the two cordis instance layers
11
+ * from colliding under one tsconfig.
12
+ */
13
+ import type { IncomingMessage, ServerResponse } from 'node:http'
14
+ import type { Context } from 'cordis'
15
+
16
+ /** One named webserver route. */
17
+ export interface SideWebRoute {
18
+ kind: 'exact' | 'prefix'
19
+ path: string
20
+ handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>
21
+ }
22
+
23
+ /** The webServer service face this plugin uses. */
24
+ export interface SideWebServer {
25
+ register(route: SideWebRoute): () => void
26
+ }
27
+
28
+ /** A published session's header slice (authoritative cwd, lineage, origin). */
29
+ export interface SideSessionHeader {
30
+ cwd?: string
31
+ parentSession?: string
32
+ origin?: 'subagent'
33
+ delegationDepth?: number
34
+ }
35
+
36
+ /** One session event (fold source for history and permission current). */
37
+ export interface SideSessionEvent {
38
+ type: string
39
+ seq: number
40
+ time: number
41
+ data: Record<string, unknown>
42
+ surfaceOp?: 'append' | 'replace' | 'remove'
43
+ sourceEventSeqs?: number[]
44
+ }
45
+
46
+ /** The live session face the host reads (header + append-only event log). */
47
+ export interface SideSession {
48
+ id: string
49
+ header: SideSessionHeader
50
+ /**
51
+ * 0.1.2-era event getter. Removed in 0.1.5 (snapshotEvents takes over), so
52
+ * host code reads through `sessionEvents()` which prefers the new method.
53
+ */
54
+ events?: readonly SideSessionEvent[]
55
+ /** 0.1.5+ snapshot of the full event log; absent on 0.1.2-era sessions. */
56
+ snapshotEvents?: (fromSeq?: number, toSeqExclusive?: number) => readonly SideSessionEvent[]
57
+ requestHeader?: () => { config?: { provider?: string; model?: string; reasoningEffort?: string; maxTokens?: number } } | undefined
58
+ }
59
+
60
+ /** The host session store face (`ctx.sessions` host side). */
61
+ export interface SideSessionStore {
62
+ get(id: string): SideSession | undefined
63
+ list(): SideSession[]
64
+ }
65
+
66
+ /** One session list row (client list feed). */
67
+ export interface SideSessionSummary {
68
+ id: string
69
+ displayTitle: string
70
+ cwd?: string
71
+ origin?: 'subagent'
72
+ parentId?: string
73
+ running: boolean
74
+ }
75
+
76
+ /** The session list snapshot the browser half subscribes to. */
77
+ export interface SideSessionList {
78
+ current: string | undefined
79
+ byId: Record<string, SideSessionSummary>
80
+ }
81
+
82
+ /** One selectable answer in a user-question dialog. */
83
+ export interface SideQuestionOption {
84
+ label: string
85
+ description?: string
86
+ }
87
+
88
+ /** One question in a pending user-question dialog. */
89
+ export interface SideQuestionItem {
90
+ id: string
91
+ question: string
92
+ detail?: string
93
+ header?: string
94
+ options?: SideQuestionOption[]
95
+ multiSelect?: boolean
96
+ }
97
+
98
+ /** A pending main-conversation interaction (question / plan-review / approval dialog). */
99
+ export interface SidePendingInteraction {
100
+ /** Presentation discriminator: the question family, or an approval. */
101
+ kind: 'question' | 'plan-review' | 'approval'
102
+ /** Opaque render identity and request key (e.g. `question:1`). */
103
+ key: string
104
+ sessionId: string
105
+ /** The request's question list (present for the question family). */
106
+ questions?: SideQuestionItem[]
107
+ }
108
+
109
+ /** The per-session pending-interaction source exposed by the `uiSession` service. */
110
+ export interface SidePendingInteractionStore {
111
+ getSnapshot(): ReadonlyMap<string, SidePendingInteraction>
112
+ subscribe(fn: () => void): () => void
113
+ }
114
+
115
+ /** The client sessions service face (list feed + scope resolution). */
116
+ export interface SideSessionsService {
117
+ list: {
118
+ getSnapshot(): SideSessionList
119
+ subscribe(fn: () => void): () => void
120
+ }
121
+ /** Resolve an Agent-scoped context view for a listed session id (use-and-discard). */
122
+ scope(id: string): Context | undefined
123
+ }
124
+
125
+ /** The client UI-session service face (per-session pending interactions). */
126
+ export interface SideUiSessionService {
127
+ /** Per-session pending UI interaction (question / plan-review / approval). */
128
+ pendingInteractions: SidePendingInteractionStore
129
+ }
130
+
131
+ /** Agent options (provider/model/maxTokens). */
132
+ export interface SideAgentOptions {
133
+ provider?: string
134
+ model?: string
135
+ maxTokens?: number
136
+ }
137
+
138
+ /** The live agent face (`ctx.agents.get(id)` / `AgentHandle.agent`). */
139
+ export interface SideAgent {
140
+ readonly id: string
141
+ readonly options: SideAgentOptions
142
+ readonly session: SideSession
143
+ readonly status: string
144
+ readonly ctx: Context
145
+ followup(message: unknown): void
146
+ inject(message: unknown): void
147
+ cancel(cause: { kind: 'user' | 'parent' | 'disposed' } | { kind: 'hook'; reason: string }): void
148
+ whenIdle(): Promise<void>
149
+ }
150
+
151
+ /** The agent handle `ctx.agents.create` resolves (owner tears the agent down). */
152
+ export interface SideAgentHandle {
153
+ agent: SideAgent
154
+ dispose(): Promise<void>
155
+ }
156
+
157
+ /** `ctx.agents.create` options (mirror of CreateAgentOptions). */
158
+ export interface SideCreateAgentOptions {
159
+ sessionId: string
160
+ meta?: {
161
+ cwd?: string
162
+ parentSession?: string
163
+ agentPreset?: string
164
+ }
165
+ agentOptions?: SideAgentOptions
166
+ setup?: (agentCtx: Context) => void | Promise<void>
167
+ }
168
+
169
+ /** The host agent registry face. */
170
+ export interface SideAgentsService {
171
+ get(id: string): SideAgent | undefined
172
+ create(options: SideCreateAgentOptions): Promise<SideAgentHandle>
173
+ }
174
+
175
+ /** Live provider / model / reasoning-effort selection for one agent. */
176
+ export interface SideModelSelection {
177
+ provider: string
178
+ model: string
179
+ reasoningEffort?: string
180
+ }
181
+
182
+ /**
183
+ * Mutable selection plus the value captured when the current step entered
184
+ * prompt assembly (`current` / `assembled`).
185
+ */
186
+ export interface SideModelSelectionRef {
187
+ current: SideModelSelection | undefined
188
+ assembled: SideModelSelection | undefined
189
+ }
190
+
191
+ /**
192
+ * Couple a mutable selection to an agent's prompt assembly and request routing
193
+ * (`installModelSelection` on the agent package). Typed structurally rather
194
+ * than imported: this plugin resolves outside the DSH monorepo's single cordis
195
+ * instance, so the upstream export is reached through a loose signature.
196
+ */
197
+ export type SideInstallModelSelection = (agentCtx: Context, selection: SideModelSelectionRef) => () => void
198
+
199
+ /** The workspace registry face (archive a session durably). */
200
+ export interface SideWorkspaceRegistry {
201
+ archiveSession(sessionId: string): Promise<void>
202
+ }
203
+
204
+ /** `sessionQuery.readSession` snapshot. */
205
+ export interface SideSessionLogSnapshot {
206
+ session: SideSessionHeader
207
+ events: SideSessionEvent[]
208
+ }
209
+
210
+ /** The session query face. */
211
+ export interface SideSessionQuery {
212
+ readSession(sessionId: string): Promise<SideSessionLogSnapshot>
213
+ }
214
+
215
+ /** Sandbox mode vocabulary (read from the session override). */
216
+ export type SideSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
217
+
218
+ /** The sandbox policy face. */
219
+ export interface SideSandboxPolicy {
220
+ overrideOf(session: SideSession): SideSandboxMode | undefined
221
+ }
222
+
223
+ /** One permission preset option. */
224
+ export interface SidePresetOption {
225
+ value: string
226
+ name: string
227
+ description?: string
228
+ }
229
+
230
+ /** The permission presets face (`current` reads the SESSION, not event rows). */
231
+ export interface SidePermissionPresets {
232
+ current(session: SideSession): string
233
+ set(session: SideSession, name: string): void
234
+ selectFor(state: unknown): { options: SidePresetOption[]; currentValue: string }
235
+ }
236
+
237
+ /** The agent presets face (composeFrom joins a child to the parent's composition). */
238
+ export interface SideAgentPresets {
239
+ composeFrom(agentCtx: Context, parentCtx: Context): string | undefined
240
+ }
241
+
242
+ /** One provider route. */
243
+ export interface SideLlmProvider {
244
+ id: string
245
+ name: string
246
+ }
247
+
248
+ /** One model entry. */
249
+ export interface SideLlmModel {
250
+ provider: string
251
+ id: string
252
+ name: string
253
+ description?: string
254
+ }
255
+
256
+ /** One reasoning-effort entry. */
257
+ export interface SideLlmEffort {
258
+ id: string
259
+ name: string
260
+ description?: string
261
+ }
262
+
263
+ /** One model-request stream chunk (minimal structural view for text collection). */
264
+ export interface SideLlmStreamChunk {
265
+ type: string
266
+ text?: string
267
+ }
268
+
269
+ /** Minimal generate options the summarize route builds (a hand-built user prompt). */
270
+ export interface SideLlmGenerateOptions {
271
+ provider: string
272
+ model: string
273
+ reasoningEffort?: string
274
+ maxTokens?: number
275
+ signal?: AbortSignal
276
+ messages: Array<{
277
+ id?: string
278
+ role: 'user' | 'assistant' | 'system'
279
+ content: Array<{ type: 'text'; text: string }>
280
+ source?: { kind: string }
281
+ }>
282
+ }
283
+
284
+ /** The llm face (model/effort catalog + one-shot streaming calls). */
285
+ export interface SideLlm {
286
+ listProviders(): SideLlmProvider[]
287
+ listModels(provider: string): Promise<SideLlmModel[]>
288
+ resolveModelInfo(provider: string, model: string): Promise<{
289
+ provider: string
290
+ id: string
291
+ name: string
292
+ reasoning?: { efforts: readonly SideLlmEffort[]; defaultEffort?: string }
293
+ }>
294
+ stream(options: SideLlmGenerateOptions): AsyncIterable<SideLlmStreamChunk>
295
+ }
296
+
297
+ /** The client locale service face. */
298
+ export interface SideLocaleService {
299
+ getSnapshot(): { active: string }
300
+ subscribe(fn: () => void): () => void
301
+ register(ns: string, locale: string, dict: Record<string, string>): () => void
302
+ }
303
+
304
+ /** The host settings service face (namespace registration + read/write). */
305
+ export interface SideSettingsService {
306
+ register(ns: unknown, schema: unknown): { get(): unknown; watch(cb: (next: unknown, prev: unknown) => void): () => void }
307
+ describe(opts: { redactSecrets?: boolean }): Array<{ ns: unknown; value?: unknown; revision?: number }>
308
+ update(ns: unknown, patch: Record<string, unknown>, expectedRevision?: number): Promise<void>
309
+ }
310
+
311
+ /** The client slots service face (settings.section registration). */
312
+ export interface SideSlotsService {
313
+ inject(name: string, factory: () => () => void): () => void
314
+ register(options: Record<string, unknown>, component: unknown): () => void
315
+ }
316
+
317
+ /** One right-sidebar tab type definition (dsh-client-ui-sidebar-right contract, mirror). */
318
+ export interface SideTabDefinition {
319
+ /** Stable unique key; the body seat entry registers under the same key. */
320
+ id: string
321
+ /** Discriminator used by `openTab(kind)` and the pane dispatch. */
322
+ kind: string
323
+ /** Registry band ('builtin' | 'extension' | 'fallback'); defaults to the extension band. */
324
+ priority?: string
325
+ /** Fresh title for the tab chip captured at open time. */
326
+ title(address: string): string
327
+ }
328
+
329
+ /** The right-sidebar tab-type registry face (`ctx.sidebarRight.tabs`). */
330
+ export interface SideSidebarRightTabs {
331
+ /** Register a tab type; returns a disposer (hold it in the caller's ctx.effect). */
332
+ register(definition: SideTabDefinition): () => void
333
+ }
334
+
335
+ /** The cross-plugin right-sidebar face (`ctx.sidebarRight`, ui-sidebar-right). */
336
+ export interface SideSidebarRight {
337
+ tabs: SideSidebarRightTabs
338
+ /** Open a page type by kind in the mounted session; reveals the column. */
339
+ openTab(kind: string, options?: { paneId?: string; replaceTab?: boolean; revealIfOpened?: boolean }): void
340
+ }
341
+
342
+ /** One durable image reference (mirror of ImageAttachmentRef). */
343
+ export interface SideImageAttachmentRef {
344
+ attachmentId: string
345
+ mediaType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
346
+ bytes: number
347
+ width: number
348
+ height: number
349
+ name?: string
350
+ }
351
+
352
+ /** The host attachment store face (`ctx.attachments`). */
353
+ export interface SideAttachmentStore {
354
+ readonly imageLimits: {
355
+ maxImageBytes: number
356
+ maxImagesPerMessage: number
357
+ maxMessageImageBytes: number
358
+ maxImagePixels: number
359
+ mediaTypes: readonly string[]
360
+ }
361
+ validateImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<void>
362
+ saveImage(input: { data: Uint8Array; mediaType: string; name?: string }): Promise<SideImageAttachmentRef>
363
+ readImage(ref: SideImageAttachmentRef): Promise<{ ref: SideImageAttachmentRef; data: Uint8Array }>
364
+ }
365
+
366
+ /** The host command registry face (`ctx.commands`). */
367
+ export interface SideCommandsService {
368
+ list(agent: SideAgent): Array<{ name: string; description: string }>
369
+ execute(agent: SideAgent, line: string, submittedAttachments: readonly unknown[], signal: AbortSignal): Promise<unknown>
370
+ }
371
+
372
+ /** The per-session composer input face this plugin writes to (draft-only). */
373
+ export interface SideSessionInput {
374
+ /** Replace the session composer draft (never submits). */
375
+ setDraft(text: string): void
376
+ /** Live input state store (draft read). */
377
+ state: { getSnapshot(): { draft: string } }
378
+ /** Surface a notice on the session composer. */
379
+ notify(level: 'info' | 'error', text: string): void
380
+ }
381
+
382
+ /** The conversation service face (`ctx.conversation`) — input registry only. */
383
+ export interface SideConversationService {
384
+ input: {
385
+ /** Resolve the input facade for one session-scope context. */
386
+ for(actx: Context): SideSessionInput
387
+ }
388
+ }
389
+
390
+ declare module 'cordis' {
391
+ interface Context {
392
+ webServer: SideWebServer
393
+ sessions: SideSessionStore & SideSessionsService
394
+ agents: SideAgentsService
395
+ workspaceRegistry: SideWorkspaceRegistry
396
+ sessionQuery: SideSessionQuery
397
+ sandboxPolicy: SideSandboxPolicy
398
+ permissionPresets: SidePermissionPresets
399
+ agentPresets: SideAgentPresets
400
+ llm: SideLlm
401
+ locale: SideLocaleService
402
+ settings: SideSettingsService
403
+ slots: SideSlotsService
404
+ attachments: SideAttachmentStore
405
+ commands: SideCommandsService
406
+ conversation: SideConversationService
407
+ uiSession: SideUiSessionService
408
+ inject(deps: string[], callback: (ctx: Context) => void): void
409
+ get(name: string): unknown | undefined
410
+ on(name: string, listener: (...args: any[]) => any): () => void
411
+ effect(fn: () => void | (() => void), label?: string): void
412
+ }
413
+ }
414
+
415
+ export type { Context }