dsh-webui-studio 0.1.0 → 0.2.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 (51) hide show
  1. package/PRODUCT.md +11 -7
  2. package/README.md +69 -21
  3. package/README.zh-CN.md +64 -20
  4. package/dist/bridge.js +10 -10
  5. package/dist/studio.css +1 -1
  6. package/dist/studio.js +16691 -10202
  7. package/docs/bidirectional-connection-handoff.md +729 -0
  8. package/docs/harmony-api-requirements.md +17 -13
  9. package/docs/remote-development.md +80 -0
  10. package/lib/bridge/element-style-selector.d.ts +1 -0
  11. package/lib/bridge/element-style-selector.js +53 -0
  12. package/lib/contracts.d.ts +152 -83
  13. package/lib/contracts.js +0 -2
  14. package/lib/host/agent.d.ts +15 -13
  15. package/lib/host/agent.js +213 -56
  16. package/lib/host/automatic-patch.d.ts +9 -0
  17. package/lib/host/automatic-patch.js +433 -0
  18. package/lib/host/backend.d.ts +134 -4
  19. package/lib/host/backend.js +465 -114
  20. package/lib/host/drafts.d.ts +1 -1
  21. package/lib/host/drafts.js +65 -15
  22. package/lib/host/element-source.d.ts +9 -0
  23. package/lib/host/element-source.js +295 -0
  24. package/lib/host/mcp.d.ts +4 -0
  25. package/lib/host/mcp.js +97 -0
  26. package/lib/host/preview-draft.d.ts +22 -0
  27. package/lib/host/preview-draft.js +162 -0
  28. package/lib/host/preview-port.d.ts +8 -0
  29. package/lib/host/preview-port.js +32 -0
  30. package/lib/host/preview-worker.d.ts +65 -2
  31. package/lib/host/preview-worker.js +203 -76
  32. package/lib/host/preview.d.ts +26 -5
  33. package/lib/host/preview.js +130 -49
  34. package/lib/host/readiness.d.ts +2 -2
  35. package/lib/host/readiness.js +14 -17
  36. package/lib/host/routes.d.ts +1 -7
  37. package/lib/host/routes.js +41 -50
  38. package/lib/host/runtime-profile.d.ts +2 -1
  39. package/lib/host/runtime-profile.js +30 -8
  40. package/lib/host/source-resolution.d.ts +11 -1
  41. package/lib/host/source-resolution.js +69 -24
  42. package/lib/host/studio-service.d.ts +129 -0
  43. package/lib/host/studio-service.js +53 -0
  44. package/lib/index.d.ts +5 -0
  45. package/lib/index.js +64 -30
  46. package/lib/studio-remote.d.ts +126 -0
  47. package/lib/studio-remote.js +188 -0
  48. package/lib/variable-tree.d.ts +2 -0
  49. package/lib/variable-tree.js +13 -0
  50. package/package.json +62 -25
  51. package/studio.patch.yml +12 -0
@@ -1,24 +1,28 @@
1
1
  # Harmony API requirements
2
2
 
3
- WebUI Studio is a Harmony extension. It imports no Harmony source files and
4
- communicates with Harmony through the `harmony` Cordis service exposed by the
5
- public `dsh-harmony` package.
3
+ WebUI Studio is an ordinary DSH plugin loaded after Harmony. It imports no
4
+ Harmony source files and communicates with Harmony through the public
5
+ `dsh-harmony` package.
6
6
 
7
7
  The Studio production path requires Harmony to provide:
8
8
 
9
- - extension discovery for profile dependencies declaring
10
- `dsh.harmony.extension`;
11
- - `HarmonyService.binEntry` and `HarmonyService.profileDir`;
12
- - `HarmonyService.inspect()` and `inspectDependencies()`;
13
- - `HarmonyService.prepareDraft()` with staged, active, preview-pending, and
14
- closed Draft transitions;
9
+ - `HarmonyService.profile()` and transactional `updateProfile()` for the stable
10
+ Host's plugin order and provider enablement;
11
+ - `HarmonyService.inspect()` for Patch state, targets, match counts, and errors;
12
+ - the public `dsh-harmony/bin` export and `harmony reload` command for
13
+ transactionally reloading a built Draft and its Patch declarations; Studio
14
+ owns the Preview lifecycle transitions;
15
15
  - source Patch declaration metadata and optional render trace metadata used by
16
16
  Preview inspection.
17
17
 
18
- These APIs are public in `dsh-harmony@0.1.3`, which is the minimum compatible
19
- registry release for Studio Host integration.
18
+ Profile paths come from `HarmonyService.profile().dir`. Studio resolves the CLI
19
+ entry through the package export rather than through the Cordis service.
20
+ Studio and Harmony releases must keep this public contract aligned.
20
21
 
21
- `dsh-harmony-react@0.1.0` exposes the generic `./studio` React element and
22
+ `dsh-harmony-react@0.3.0` exposes the generic `./studio` React element and
22
23
  variable registration API used by the browser and Preview bridge. Studio uses
23
24
  the package published on the npm registry and resolves it exclusively through
24
- the `dsh-harmony-react/studio` package export.
25
+ the `dsh-harmony-react/studio` package export. Source persistence additionally
26
+ requires the `StudioVariableDefinition.defaultSource` anchors introduced by the
27
+ corresponding React package release; bindings without those anchors remain
28
+ Preview-only.
@@ -0,0 +1,80 @@
1
+ # Remote Docker development
2
+
3
+ Remote development runs one complete Studio Host per Agent on a Docker machine,
4
+ while the browser and source checkout remain local. Each Compose project owns
5
+ its own `DSH_HOME`, npm cache, pnpm store, Studio port, and fixed Preview port
6
+ range. SSH forwards only those loopback ports, so Studio and Draft Preview Hosts
7
+ remain unavailable directly from the LAN.
8
+
9
+ ## Remote prerequisite
10
+
11
+ The remote host must provide a running Docker Engine and a `docker` CLI that is
12
+ available to non-interactive SSH sessions. Node.js and DSH are installed in the
13
+ image and are not required on the remote macOS host.
14
+
15
+ Installing Docker Desktop, OrbStack, or another system runtime changes the
16
+ remote machine and is intentionally outside this repository's setup script.
17
+ After installation, verify the daemon from the local machine:
18
+
19
+ ```sh
20
+ npm run remote -- check
21
+ ```
22
+
23
+ The default SSH host is `macmini`. Override it with
24
+ `DSH_STUDIO_REMOTE=user@host` when needed.
25
+
26
+ ## Start isolated Agents
27
+
28
+ Choose a unique Studio port and non-overlapping Preview range for each Agent:
29
+
30
+ ```sh
31
+ npm run remote -- up agent-a 13081 13100-13115
32
+ npm run remote -- up agent-b 14081 14100-14115
33
+ ```
34
+
35
+ `up` sends the current checkout as the Docker build context, starts the remote
36
+ Compose project, and opens an SSH control connection that forwards the Studio
37
+ and Preview ports. Open the URL printed by the command. Re-run `up` after source
38
+ changes to rebuild the image.
39
+
40
+ Other lifecycle commands are:
41
+
42
+ ```sh
43
+ npm run remote -- logs agent-a
44
+ npm run remote -- status agent-a
45
+ npm run remote -- tunnel agent-a 13081 13100-13115
46
+ npm run remote -- down agent-a
47
+ ```
48
+
49
+ `down` removes the Agent's container but preserves its named volumes and Draft
50
+ state. Remove those volumes explicitly only when their data is no longer needed.
51
+
52
+ Docker Desktop must support host networking because DSH intentionally listens
53
+ on `127.0.0.1`. The fixed Preview range is enabled only in the container through
54
+ `DSH_STUDIO_PREVIEW_PORT_RANGE`; ordinary local Studio runs continue to pass
55
+ `--port 0` and use an operating-system-assigned port.
56
+
57
+ ## 中文说明
58
+
59
+ 远程开发模式会在 Docker 主机上为每个 Agent 运行一套完整 Studio Host,本机只保留
60
+ 源码工作区、浏览器和 SSH 隧道。每个 Compose project 都有独立的 `DSH_HOME`、npm
61
+ 缓存、pnpm store、Studio 端口和 Preview 端口段。DSH 仍只监听回环地址,局域网不能
62
+ 直接访问这些服务。
63
+
64
+ 远端只需安装并启动 Docker Engine,Node.js 和 DSH 均由镜像提供。仓库脚本不会安装
65
+ Docker Desktop、OrbStack 等系统软件。安装 Docker 后,可先运行:
66
+
67
+ ```sh
68
+ npm run remote -- check
69
+ ```
70
+
71
+ 随后为每个 Agent 分配互不重叠的端口并启动:
72
+
73
+ ```sh
74
+ npm run remote -- up agent-a 13081 13100-13115
75
+ npm run remote -- up agent-b 14081 14100-14115
76
+ ```
77
+
78
+ 源码改变后重新执行 `up` 即可在远端重建。`down` 只移除容器,保留该 Agent 的命名
79
+ 卷和 Draft 数据。远端 Docker Desktop 需要支持 host networking,因为 DSH 会继续
80
+ 绑定 `127.0.0.1`。
@@ -0,0 +1 @@
1
+ export declare function compileElementStyleSelector(selector: string, scope: string): string;
@@ -0,0 +1,53 @@
1
+ function escapesRoot(selector) {
2
+ const suffix = selector.slice(1);
3
+ let bracketDepth = 0;
4
+ let parenthesisDepth = 0;
5
+ let quote = '';
6
+ for (let index = 0; index < suffix.length; index += 1) {
7
+ const character = suffix[index];
8
+ if (quote !== '') {
9
+ if (character === quote && suffix[index - 1] !== '\\')
10
+ quote = '';
11
+ continue;
12
+ }
13
+ if (character === '"' || character === "'") {
14
+ quote = character;
15
+ continue;
16
+ }
17
+ if (character === '[') {
18
+ bracketDepth += 1;
19
+ continue;
20
+ }
21
+ if (character === ']') {
22
+ bracketDepth -= 1;
23
+ continue;
24
+ }
25
+ if (character === '(') {
26
+ parenthesisDepth += 1;
27
+ continue;
28
+ }
29
+ if (character === ')') {
30
+ parenthesisDepth -= 1;
31
+ continue;
32
+ }
33
+ if (bracketDepth !== 0 || parenthesisDepth !== 0)
34
+ continue;
35
+ if (character === '+' || character === '~')
36
+ return true;
37
+ if (character === '>')
38
+ return false;
39
+ if (/\s/.test(character)) {
40
+ while (/\s/.test(suffix[index + 1] ?? ''))
41
+ index += 1;
42
+ return suffix[index + 1] === '+' || suffix[index + 1] === '~';
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ export function compileElementStyleSelector(selector, scope) {
48
+ if (!selector.startsWith('&') || selector.indexOf('&', 1) !== -1 || /[{},;]/.test(selector)
49
+ || escapesRoot(selector)) {
50
+ throw new Error('Element CSS selectors must contain one leading & and stay within its subtree');
51
+ }
52
+ return selector.replace('&', scope);
53
+ }
@@ -1,37 +1,22 @@
1
+ import type { HarmonyInspection, HarmonyProfileView, HarmonyRuntimeProfileUpdateResult, HarmonyService } from 'dsh-harmony';
2
+ import type { StudioElementDefinition, StudioVariableNode, StudioVariableValue } from 'dsh-harmony-react/studio';
1
3
  export declare const STUDIO_PATH = "/studio";
2
- export declare const STUDIO_API_PATH = "/studio/api";
3
4
  export declare const STUDIO_PREVIEW_FRAGMENT = "dsh-studio-preview";
4
- export declare const STUDIO_PREVIEW_API_PATH = "/dsh-harmony/studio-preview/api";
5
- export interface StudioClientRequest {
6
- type: 'client-request';
7
- rpcId: string;
8
- method: string;
9
- payload: unknown;
10
- }
11
- export interface StudioServerResponse<T = unknown> {
12
- type: 'server-response';
13
- rpcId: string;
14
- result: {
15
- ok: true;
16
- value: T;
17
- } | {
18
- ok: false;
19
- error: {
20
- code: string;
21
- message: string;
22
- details?: unknown;
23
- };
24
- };
25
- }
26
5
  export interface StudioServerRequest<T = unknown> {
27
6
  type: 'server-request';
28
7
  rpcId: string;
29
8
  method: 'events.mux' | 'events.host';
30
9
  payload: T;
31
10
  }
32
- export interface StudioCreateAgentResult {
11
+ export interface StudioAgentBinding {
33
12
  sessionId: string;
34
13
  agentPreset?: string;
14
+ source: 'created' | 'existing';
15
+ }
16
+ export interface StudioCurrentInstanceView {
17
+ previewUrl: string;
18
+ bridgeCapability: string;
19
+ agent?: StudioAgentBinding;
35
20
  }
36
21
  export interface StudioReactSnapshot {
37
22
  component?: string;
@@ -45,7 +30,7 @@ export interface StudioReactSnapshot {
45
30
  export interface StudioPatchTrace {
46
31
  key: string;
47
32
  owner: string;
48
- effect: 'replace-element' | 'wrap-element' | 'insert-before' | 'insert-after' | 'transform-props';
33
+ effect: 'replace-element' | 'wrap-element' | 'insert-before' | 'insert-after' | 'transform-props' | 'decorate-component' | 'replace-component';
49
34
  declaration: string;
50
35
  target: {
51
36
  package: string;
@@ -86,6 +71,45 @@ export interface StudioSurfaceBoundary {
86
71
  surfaceId: string;
87
72
  path: string[];
88
73
  }
74
+ export interface StudioElementStyleTarget {
75
+ owner: string;
76
+ elementId: string;
77
+ boundary: StudioSurfaceBoundary;
78
+ selector: string;
79
+ property: string;
80
+ value?: string;
81
+ }
82
+ export interface StudioElementStyleDeclaration {
83
+ property: string;
84
+ value: string;
85
+ }
86
+ export interface StudioElementStyleRule {
87
+ selector: string;
88
+ declarations: StudioElementStyleDeclaration[];
89
+ }
90
+ export interface StudioElementStyleSource {
91
+ elementId: string;
92
+ rules: StudioElementStyleRule[];
93
+ }
94
+ export interface StudioElementSelectorTarget {
95
+ owner: string;
96
+ elementId: string;
97
+ boundary: StudioSurfaceBoundary;
98
+ }
99
+ export interface StudioElementSnapshot {
100
+ owner: string;
101
+ element: StudioElementDefinition;
102
+ values: Readonly<Record<string, StudioVariableValue>>;
103
+ }
104
+ export interface StudioVariablesSnapshot {
105
+ owner: string;
106
+ variables: readonly StudioVariableNode[];
107
+ values: Readonly<Record<string, StudioVariableValue>>;
108
+ }
109
+ export interface StudioRegistrySnapshot {
110
+ elements: readonly StudioElementSnapshot[];
111
+ variables: readonly StudioVariablesSnapshot[];
112
+ }
89
113
  export interface StudioPreviewStatus {
90
114
  connected: boolean;
91
115
  graphRev?: string;
@@ -93,6 +117,24 @@ export interface StudioPreviewStatus {
93
117
  selection?: StudioDomSelection;
94
118
  registry?: StudioRegistrySnapshot;
95
119
  }
120
+ export interface StudioAgentContext {
121
+ target: 'draft' | 'current-instance';
122
+ readOnly: boolean;
123
+ selection: StudioDomSelection | null;
124
+ project: StudioProjectState;
125
+ preview: StudioPreviewStatus;
126
+ projectFiles: StudioProjectFile[];
127
+ profile: HarmonyProfileView;
128
+ harmony: StudioHarmonyInspection | null;
129
+ targetRefs: Array<{
130
+ package: string;
131
+ file: string;
132
+ }>;
133
+ targetRefsTruncated: boolean;
134
+ readiness: {
135
+ findings: StudioReadinessFinding[];
136
+ };
137
+ }
96
138
  export interface StudioPreviewUpdate {
97
139
  connected: boolean;
98
140
  graphRev?: string;
@@ -100,40 +142,22 @@ export interface StudioPreviewUpdate {
100
142
  selection?: StudioDomSelection | null;
101
143
  registry?: StudioRegistrySnapshot | null;
102
144
  }
103
- export type { StudioRegistrySnapshot };
104
145
  export interface StudioProjectFile {
105
146
  path: string;
106
147
  size: number;
107
148
  }
108
- export interface StudioHarmonyInspection {
109
- patches: Array<{
110
- key: string;
111
- owner: string;
112
- target: {
113
- package: string;
114
- files: string[];
115
- version?: string;
116
- };
117
- kind: 'source' | 'semantic';
118
- state: 'pending' | 'bound' | 'disabled' | 'failed';
119
- loaded: boolean;
120
- declaration: string;
121
- file?: string;
122
- error?: string;
123
- }>;
124
- targets: Array<{
125
- package: string;
126
- file: string;
127
- original: string;
128
- final: string;
129
- steps: Array<{
130
- key: string;
131
- owner: string;
132
- matches: number;
133
- source: string;
134
- }>;
135
- }>;
149
+ export type StudioHarmonyInspection = HarmonyInspection;
150
+ export interface StudioRuntimePluginEntry {
151
+ entryId: string;
152
+ moduleName: string;
153
+ enabled: boolean;
136
154
  }
155
+ export type StudioHarmonyProfile = HarmonyProfileView & {
156
+ runtimePlugins: StudioRuntimePluginEntry[];
157
+ };
158
+ export type StudioHarmonyProfileUpdateResult = Omit<HarmonyRuntimeProfileUpdateResult, 'profile'> & {
159
+ profile: StudioHarmonyProfile;
160
+ };
137
161
  export type StudioReadinessLevel = 'error' | 'warning' | 'info';
138
162
  export interface StudioReadinessFinding {
139
163
  level: StudioReadinessLevel;
@@ -157,7 +181,7 @@ export interface StudioReadinessReport {
157
181
  export interface StudioProjectState {
158
182
  name: string;
159
183
  root: string;
160
- state: 'staged' | 'active' | 'preview-pending' | 'closed';
184
+ state: 'active' | 'preview-pending' | 'closed';
161
185
  graphRev: string;
162
186
  }
163
187
  export type StudioDraftProfileMode = 'main-home' | 'custom';
@@ -180,6 +204,7 @@ export interface StudioDraftRecord {
180
204
  root: string;
181
205
  runtimeHome: string;
182
206
  profileMode: StudioDraftProfileMode;
207
+ profileDirectory?: string;
183
208
  createdAt: string;
184
209
  }
185
210
  export interface StudioDraftView extends StudioDraftRecord {
@@ -191,11 +216,12 @@ export interface StudioDraftView extends StudioDraftRecord {
191
216
  log: string;
192
217
  };
193
218
  project?: StudioProjectState;
194
- agent?: StudioCreateAgentResult;
219
+ agent?: StudioAgentBinding;
195
220
  }
196
221
  export interface StudioCreateDraftInput {
197
222
  source: StudioDraftSource;
198
223
  profileMode: StudioDraftProfileMode;
224
+ profileDirectory?: string;
199
225
  destinationDirectory?: string;
200
226
  }
201
227
  export interface StudioWorkspaceState {
@@ -212,35 +238,78 @@ export interface StudioBuildResult {
212
238
  project: StudioProjectState;
213
239
  build: StudioBuildOutput;
214
240
  }
215
- export interface StudioHarmonyService {
216
- readonly binEntry: string;
217
- readonly profileDir: string;
218
- inspect(input?: {
219
- package?: string;
220
- file?: string;
221
- }): StudioHarmonyInspection;
222
- inspectDependencies(owner: string): StudioPatchDependency[];
223
- prepareDraft(input: {
224
- root: string;
225
- }): Promise<StudioPreviewDraftHandle>;
226
- }
227
- export interface StudioPreviewDraftHandle {
228
- snapshot(): StudioProjectState;
229
- activateAfterPreviewReady(graphRev: string): Promise<StudioProjectState>;
230
- applyBuild(): Promise<StudioProjectState>;
231
- deactivate(): Promise<void>;
241
+ export interface StudioAutomaticPatchTarget {
242
+ package: string;
243
+ file: string;
232
244
  }
233
- export interface StudioPreviewInspection {
234
- harmony: StudioHarmonyInspection;
235
- dependencies: StudioPatchDependency[];
245
+ export interface StudioAutomaticCssVariable {
246
+ id: string;
247
+ label: string;
248
+ property: string;
249
+ control: 'color' | 'length' | 'number' | 'enum' | 'string';
250
+ value: string | number;
251
+ options?: string[];
252
+ constraints?: {
253
+ min?: number;
254
+ max?: number;
255
+ step?: number;
256
+ };
236
257
  }
237
- export interface StudioPatchDependency {
238
- patch: string;
239
- target: {
240
- package: string;
258
+ export type StudioAutomaticPatchRequest = {
259
+ kind: 'replace-string';
260
+ targets: StudioAutomaticPatchTarget[];
261
+ text: string;
262
+ replacement: string;
263
+ clientFile: string;
264
+ boundary: StudioSurfaceBoundary;
265
+ targetSelector?: string;
266
+ selector: string;
267
+ elementId: string;
268
+ elementLabel: string;
269
+ elementSourceFile?: string;
270
+ } | {
271
+ kind: 'css-style';
272
+ targets: StudioAutomaticPatchTarget[];
273
+ component: string;
274
+ clientFile: string;
275
+ boundary: StudioSurfaceBoundary;
276
+ targetSelector?: string;
277
+ selector: string;
278
+ elementId: string;
279
+ elementLabel: string;
280
+ variables: StudioAutomaticCssVariable[];
281
+ };
282
+ export interface StudioAutomaticPatchMatch {
283
+ line: number;
284
+ column: number;
285
+ excerpt: string;
286
+ applicable: boolean;
287
+ reason?: string;
288
+ }
289
+ export interface StudioAutomaticPatchTargetAnalysis extends StudioAutomaticPatchTarget {
290
+ version: string;
291
+ matches: StudioAutomaticPatchMatch[];
292
+ }
293
+ export interface StudioAutomaticPatchPlan {
294
+ request: StudioAutomaticPatchRequest;
295
+ targets: StudioAutomaticPatchTargetAnalysis[];
296
+ canApply: boolean;
297
+ provider: {
298
+ file: string;
299
+ source: string;
300
+ patchIds: string[];
301
+ };
302
+ client?: {
241
303
  file: string;
304
+ source: string;
305
+ export: string;
306
+ entryFile: string;
242
307
  };
243
- providerCandidates: string[];
244
- reason: string;
245
308
  }
246
- import type { StudioRegistrySnapshot } from 'dsh-harmony-react/studio';
309
+ export interface StudioAutomaticPatchWriteResult extends StudioAutomaticPatchPlan {
310
+ files: string[];
311
+ }
312
+ export type StudioHarmonyService = HarmonyService;
313
+ export interface StudioPreviewInspection {
314
+ harmony: StudioHarmonyInspection;
315
+ }
package/lib/contracts.js CHANGED
@@ -1,4 +1,2 @@
1
1
  export const STUDIO_PATH = '/studio';
2
- export const STUDIO_API_PATH = `${STUDIO_PATH}/api`;
3
2
  export const STUDIO_PREVIEW_FRAGMENT = 'dsh-studio-preview';
4
- export const STUDIO_PREVIEW_API_PATH = '/dsh-harmony/studio-preview/api';
@@ -1,31 +1,33 @@
1
1
  import type { AgentRegistry } from '@deepseek-ai/dsh-agent';
2
- import type { StudioBuildResult, StudioDomSelection, StudioHarmonyInspection, StudioPreviewStatus, StudioProjectState } from '../contracts.js';
2
+ import type { HarmonyProfileView } from 'dsh-harmony';
3
+ import type { StudioAgentBinding, StudioAgentContext, StudioBuildResult, StudioDomSelection, StudioHarmonyInspection, StudioPreviewStatus, StudioProjectState } from '../contracts.js';
3
4
  export interface StudioAgentWorkspace {
5
+ readonly kind: 'draft' | 'current-instance';
4
6
  project(): StudioProjectState;
5
7
  selection(): StudioDomSelection | undefined;
8
+ context(): Promise<StudioAgentContext>;
6
9
  previewStatus(): StudioPreviewStatus;
10
+ harmonyProfile(): Promise<HarmonyProfileView>;
7
11
  inspectHarmony(input: {
8
12
  package?: string;
9
13
  file?: string;
10
14
  }): Promise<StudioHarmonyInspection>;
11
15
  readDependencySource(packageName: string, file: string): Promise<string>;
12
- readFile(path: string): Promise<string>;
13
- applyPatch(path: string, before: string, after: string): Promise<'created' | 'updated'>;
14
- build(signal: AbortSignal): Promise<StudioBuildResult>;
16
+ readFile?(path: string): Promise<string>;
17
+ applyPatch?(path: string, before: string, after: string): Promise<'created' | 'updated'>;
18
+ build?(signal: AbortSignal): Promise<StudioBuildResult>;
15
19
  }
16
20
  export declare class StudioAgentController {
17
21
  private readonly agents;
18
22
  private readonly workspace;
19
23
  private handle?;
24
+ private removeStudioMode?;
20
25
  private active?;
26
+ private activating;
21
27
  constructor(agents: AgentRegistry, workspace: StudioAgentWorkspace);
22
- snapshot(): {
23
- sessionId: string;
24
- agentPreset?: string;
25
- } | undefined;
26
- create(agentPreset?: string): Promise<{
27
- sessionId: string;
28
- agentPreset?: string;
29
- }>;
30
- dispose(): Promise<void>;
28
+ snapshot(): StudioAgentBinding | undefined;
29
+ create(agentPreset?: string): Promise<StudioAgentBinding>;
30
+ attach(sessionId: string): Promise<StudioAgentBinding>;
31
+ leave(): Promise<void>;
32
+ private beginActivation;
31
33
  }