@silo-code/sdk 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ActivityGlyph.d.ts +25 -0
- package/dist/ActivityGlyph.d.ts.map +1 -0
- package/dist/ActivityGlyph.js +25 -0
- package/dist/ActivityGlyph.js.map +1 -0
- package/dist/IconButton.d.ts +23 -6
- package/dist/IconButton.d.ts.map +1 -1
- package/dist/IconButton.js +14 -5
- package/dist/IconButton.js.map +1 -1
- package/dist/activity.d.ts +36 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +33 -0
- package/dist/activity.js.map +1 -0
- package/dist/agents-service.d.ts +174 -0
- package/dist/agents-service.d.ts.map +1 -0
- package/dist/agents-service.js +2 -0
- package/dist/agents-service.js.map +1 -0
- package/dist/editor-service.d.ts +5 -1
- package/dist/editor-service.d.ts.map +1 -1
- package/dist/icon-button-classes.d.ts +10 -2
- package/dist/icon-button-classes.d.ts.map +1 -1
- package/dist/icon-button-classes.js +9 -5
- package/dist/icon-button-classes.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/phosphor-icon.d.ts +15 -0
- package/dist/phosphor-icon.d.ts.map +1 -0
- package/dist/phosphor-icon.js +2 -0
- package/dist/phosphor-icon.js.map +1 -0
- package/dist/tab-adornment.d.ts +193 -0
- package/dist/tab-adornment.d.ts.map +1 -0
- package/dist/tab-adornment.js +2 -0
- package/dist/tab-adornment.js.map +1 -0
- package/dist/terminal-service.d.ts +18 -35
- package/dist/terminal-service.d.ts.map +1 -1
- package/dist/toolbar-items.d.ts +171 -0
- package/dist/toolbar-items.d.ts.map +1 -0
- package/dist/toolbar-items.js +2 -0
- package/dist/toolbar-items.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace-service.d.ts +66 -45
- package/dist/workspace-service.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ActivityGlyph.tsx +43 -0
- package/src/IconButton.tsx +28 -6
- package/src/activity.test.ts +35 -0
- package/src/activity.ts +57 -0
- package/src/agents-service.ts +181 -0
- package/src/editor-service.ts +5 -1
- package/src/icon-button-classes.test.ts +10 -0
- package/src/icon-button-classes.ts +18 -5
- package/src/index.ts +33 -1
- package/src/phosphor-icon.ts +14 -0
- package/src/tab-adornment.ts +208 -0
- package/src/terminal-service.ts +21 -35
- package/src/toolbar-items.ts +190 -0
- package/src/types.ts +28 -0
- package/src/workspace-service.ts +72 -45
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Disposable } from "./types.js";
|
|
2
2
|
import type { Workspace } from "./domain-types.js";
|
|
3
|
+
import type { Activity } from "./activity.js";
|
|
3
4
|
export type { Workspace, TerminalRecord } from "./domain-types.js";
|
|
4
5
|
/**
|
|
5
6
|
* A single status row contributed by a {@link WorkspaceStatusProvider}.
|
|
@@ -11,8 +12,11 @@ export type { Workspace, TerminalRecord } from "./domain-types.js";
|
|
|
11
12
|
export interface WorkspaceStatusRow {
|
|
12
13
|
/** Stable key unique within this provider's results; used for reconciliation. */
|
|
13
14
|
id: string;
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Host-owned {@link Activity} glyph to the left of the label. Omit for the
|
|
17
|
+
* neutral gray fallback (same as today’s omitted `status`). See ADR 0030.
|
|
18
|
+
*/
|
|
19
|
+
activity?: Activity;
|
|
16
20
|
/** Short label — the host truncates with an ellipsis when space is tight. */
|
|
17
21
|
label: string;
|
|
18
22
|
/**
|
|
@@ -66,21 +70,22 @@ export interface WorkspaceBadge {
|
|
|
66
70
|
/** Short text rendered inside the badge. */
|
|
67
71
|
text: string;
|
|
68
72
|
/**
|
|
69
|
-
*
|
|
70
|
-
* muted
|
|
73
|
+
* Solid chip fill color. Text paints white on top for contrast. Falls back
|
|
74
|
+
* to a muted solid background + hi text when omitted.
|
|
71
75
|
*/
|
|
72
76
|
color?: string;
|
|
73
77
|
}
|
|
74
78
|
/**
|
|
75
|
-
* A badge
|
|
76
|
-
* workspace name in the Workspaces side panel.
|
|
77
|
-
* {@link WorkspaceService.registerBadge}
|
|
79
|
+
* A badge binder that contributes {@link WorkspaceBadge}s next to the
|
|
80
|
+
* workspace name in the Workspaces side panel. Prefer
|
|
81
|
+
* {@link WorkspaceService.bindBadge}; {@link WorkspaceService.registerBadge}
|
|
82
|
+
* remains as a deprecated alias.
|
|
78
83
|
*
|
|
79
84
|
* @category Consumer Services
|
|
80
85
|
* @public
|
|
81
86
|
*/
|
|
82
87
|
export interface WorkspaceBadgeProvider {
|
|
83
|
-
/** Unique id for this
|
|
88
|
+
/** Unique id for this binder — conventionally `"<extension-id>.badges"`. */
|
|
84
89
|
id: string;
|
|
85
90
|
/**
|
|
86
91
|
* Called synchronously for each workspace during render. Return an empty
|
|
@@ -89,15 +94,19 @@ export interface WorkspaceBadgeProvider {
|
|
|
89
94
|
provide(workspaceId: string): WorkspaceBadge[];
|
|
90
95
|
}
|
|
91
96
|
/**
|
|
92
|
-
* A status
|
|
93
|
-
* workspace rows in the Workspaces side panel.
|
|
94
|
-
* {@link WorkspaceService.registerStatus}
|
|
97
|
+
* A status binder that contributes {@link WorkspaceStatusRow}s to
|
|
98
|
+
* workspace rows in the Workspaces side panel. Prefer
|
|
99
|
+
* {@link WorkspaceService.bindStatus}; {@link WorkspaceService.registerStatus}
|
|
100
|
+
* remains as a deprecated alias.
|
|
101
|
+
*
|
|
102
|
+
* Unlike CenterDock tab `bindIndicator` (single adornment | null), status
|
|
103
|
+
* and badge binders return an **array** — one projection may emit many rows.
|
|
95
104
|
*
|
|
96
105
|
* @category Consumer Services
|
|
97
106
|
* @public
|
|
98
107
|
*/
|
|
99
108
|
export interface WorkspaceStatusProvider {
|
|
100
|
-
/** Unique id for this
|
|
109
|
+
/** Unique id for this binder — conventionally `"<extension-id>.status"`. */
|
|
101
110
|
id: string;
|
|
102
111
|
/**
|
|
103
112
|
* Called synchronously for each workspace during render. Return an empty
|
|
@@ -246,47 +255,56 @@ export interface WorkspaceService {
|
|
|
246
255
|
*/
|
|
247
256
|
delete(id: string): Promise<void>;
|
|
248
257
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
|
|
252
|
-
|
|
258
|
+
* Imperatively adorn a workspace row with a status line. `row.id` is the
|
|
259
|
+
* adornment key for {@link WorkspaceService.clearStatus}.
|
|
260
|
+
*/
|
|
261
|
+
setStatus(workspaceId: string, row: WorkspaceStatusRow): void;
|
|
262
|
+
/** Remove an imperative status row previously set via {@link WorkspaceService.setStatus}. */
|
|
263
|
+
clearStatus(workspaceId: string, rowId: string): void;
|
|
264
|
+
/**
|
|
265
|
+
* Keep a status projection in sync for every workspace. `provide` returns
|
|
266
|
+
* an array of rows (may be empty). Prefer this over repeatedly calling
|
|
267
|
+
* {@link WorkspaceService.setStatus}.
|
|
253
268
|
*
|
|
254
269
|
* @example
|
|
255
270
|
* ```ts
|
|
256
271
|
* ctx.subscriptions.push(
|
|
257
|
-
* ctx.workspaces.
|
|
272
|
+
* ctx.workspaces.bindStatus({
|
|
258
273
|
* id: "my-ext.status",
|
|
259
274
|
* provide(workspaceId) {
|
|
260
275
|
* const running = getRunningTasks(workspaceId);
|
|
261
|
-
* return running.map(t => ({ id: t.id,
|
|
276
|
+
* return running.map(t => ({ id: t.id, activity: "working", label: t.name, startedAt: t.startedAt }));
|
|
262
277
|
* },
|
|
263
278
|
* }),
|
|
264
|
-
* ctx.workspaces.subscribeStatus(() => ctx.workspaces.invalidateStatus()),
|
|
265
279
|
* );
|
|
266
280
|
* ```
|
|
267
281
|
*/
|
|
282
|
+
bindStatus(binder: WorkspaceStatusProvider): Disposable;
|
|
283
|
+
/**
|
|
284
|
+
* @deprecated Prefer {@link WorkspaceService.bindStatus}.
|
|
285
|
+
*/
|
|
268
286
|
registerStatus(provider: WorkspaceStatusProvider): Disposable;
|
|
269
287
|
/**
|
|
270
|
-
* Concatenate all
|
|
271
|
-
* registration order). Called synchronously during panel render —
|
|
272
|
-
* must be fast and side-effect-free.
|
|
288
|
+
* Concatenate imperative rows and all binders' rows for one workspace (in
|
|
289
|
+
* binder registration order). Called synchronously during panel render —
|
|
290
|
+
* binders must be fast and side-effect-free.
|
|
273
291
|
*/
|
|
274
292
|
getStatus(workspaceId: string): WorkspaceStatusRow[];
|
|
275
293
|
/**
|
|
276
|
-
* Signal that
|
|
294
|
+
* Signal that binder data has changed. Fires all listeners registered
|
|
277
295
|
* via {@link WorkspaceService.subscribeStatus}, causing the Workspaces
|
|
278
|
-
* panel to re-query
|
|
296
|
+
* panel to re-query binders and re-render the status rows.
|
|
279
297
|
*
|
|
280
298
|
* Call this after any mutation to the state your `provide` function reads.
|
|
299
|
+
* Imperative {@link WorkspaceService.setStatus} / {@link WorkspaceService.clearStatus}
|
|
300
|
+
* already notify listeners.
|
|
281
301
|
*/
|
|
282
302
|
invalidateStatus(): void;
|
|
283
303
|
/**
|
|
284
304
|
* Subscribe to status invalidations. The listener is called whenever
|
|
285
|
-
* {@link WorkspaceService.invalidateStatus} is invoked
|
|
286
|
-
* {@link Disposable} that cancels the
|
|
287
|
-
*
|
|
288
|
-
* The Workspaces panel subscribes internally; extensions may also subscribe
|
|
289
|
-
* to observe invalidations.
|
|
305
|
+
* {@link WorkspaceService.invalidateStatus} is invoked (or imperative
|
|
306
|
+
* set/clear runs). Returns a {@link Disposable} that cancels the
|
|
307
|
+
* subscription.
|
|
290
308
|
*/
|
|
291
309
|
subscribeStatus(listener: () => void): Disposable;
|
|
292
310
|
/**
|
|
@@ -353,15 +371,20 @@ export interface WorkspaceService {
|
|
|
353
371
|
*/
|
|
354
372
|
registerPropertyPage(page: WorkspacePropertyPage): Disposable;
|
|
355
373
|
/**
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
|
|
359
|
-
|
|
374
|
+
* Imperatively adorn a workspace name with a badge. `badge.id` is the
|
|
375
|
+
* adornment key for {@link WorkspaceService.clearBadge}.
|
|
376
|
+
*/
|
|
377
|
+
setBadge(workspaceId: string, badge: WorkspaceBadge): void;
|
|
378
|
+
/** Remove an imperative badge previously set via {@link WorkspaceService.setBadge}. */
|
|
379
|
+
clearBadge(workspaceId: string, badgeId: string): void;
|
|
380
|
+
/**
|
|
381
|
+
* Keep a badge projection in sync for every workspace. `provide` returns
|
|
382
|
+
* an array of badges (may be empty).
|
|
360
383
|
*
|
|
361
384
|
* @example
|
|
362
385
|
* ```ts
|
|
363
386
|
* ctx.subscriptions.push(
|
|
364
|
-
* ctx.workspaces.
|
|
387
|
+
* ctx.workspaces.bindBadge({
|
|
365
388
|
* id: "my-ext.badges",
|
|
366
389
|
* provide(workspaceId) {
|
|
367
390
|
* const status = getStatus(workspaceId);
|
|
@@ -372,25 +395,23 @@ export interface WorkspaceService {
|
|
|
372
395
|
* );
|
|
373
396
|
* ```
|
|
374
397
|
*/
|
|
398
|
+
bindBadge(binder: WorkspaceBadgeProvider): Disposable;
|
|
399
|
+
/**
|
|
400
|
+
* @deprecated Prefer {@link WorkspaceService.bindBadge}.
|
|
401
|
+
*/
|
|
375
402
|
registerBadge(provider: WorkspaceBadgeProvider): Disposable;
|
|
376
403
|
/**
|
|
377
|
-
* Concatenate all
|
|
378
|
-
* registration order).
|
|
379
|
-
* must be fast and side-effect-free.
|
|
404
|
+
* Concatenate imperative badges and all binders' badges for one workspace
|
|
405
|
+
* (in binder registration order).
|
|
380
406
|
*/
|
|
381
407
|
getBadges(workspaceId: string): WorkspaceBadge[];
|
|
382
408
|
/**
|
|
383
|
-
* Signal that badge data has changed.
|
|
384
|
-
*
|
|
385
|
-
* re-query providers and re-render the name row.
|
|
386
|
-
*
|
|
387
|
-
* Call this after any mutation to the state your `provide` function reads.
|
|
409
|
+
* Signal that badge binder data has changed. Imperative set/clear already
|
|
410
|
+
* notify listeners.
|
|
388
411
|
*/
|
|
389
412
|
invalidateBadges(): void;
|
|
390
413
|
/**
|
|
391
|
-
* Subscribe to badge invalidations.
|
|
392
|
-
* {@link WorkspaceService.invalidateBadges} is invoked. Returns a
|
|
393
|
-
* {@link Disposable} that cancels the subscription.
|
|
414
|
+
* Subscribe to badge invalidations.
|
|
394
415
|
*/
|
|
395
416
|
subscribeBadges(listener: () => void): Disposable;
|
|
396
417
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-service.d.ts","sourceRoot":"","sources":["../src/workspace-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace-service.d.ts","sourceRoot":"","sources":["../src/workspace-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import {
|
|
3
|
+
activityClass,
|
|
4
|
+
type Activity as ActivityKind,
|
|
5
|
+
type ActivitySize,
|
|
6
|
+
} from "./activity";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Host-painted activity glyph — same look on workspace rows, CenterDock tabs,
|
|
10
|
+
* and extension UI. Pick an {@link Activity}; the host owns color and motion
|
|
11
|
+
* (ADR 0030). Omit `activity` only for the workspace-row neutral gray fallback.
|
|
12
|
+
*
|
|
13
|
+
* Styled purely via host-provided `.silo-activity*` classes — no stylesheet
|
|
14
|
+
* import is needed in the extension.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <ActivityGlyph activity="working" size="md" />
|
|
19
|
+
* <ActivityGlyph activity="ready" />
|
|
20
|
+
* <ActivityGlyph size="sm" /> // workspace neutral (omit)
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @category Consumer Services
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export function ActivityGlyph({
|
|
27
|
+
activity,
|
|
28
|
+
size = "sm",
|
|
29
|
+
className,
|
|
30
|
+
...rest
|
|
31
|
+
}: {
|
|
32
|
+
activity?: ActivityKind;
|
|
33
|
+
size?: ActivitySize;
|
|
34
|
+
} & Omit<HTMLAttributes<HTMLSpanElement>, "children">) {
|
|
35
|
+
const classes = activityClass(activity, size);
|
|
36
|
+
return (
|
|
37
|
+
<span
|
|
38
|
+
className={className ? `${classes} ${className}` : classes}
|
|
39
|
+
aria-hidden={rest["aria-label"] == null ? true : undefined}
|
|
40
|
+
{...rest}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
package/src/IconButton.tsx
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { ButtonHTMLAttributes, ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
iconButtonClass,
|
|
4
|
+
type IconButtonSize,
|
|
5
|
+
type IconButtonVariant,
|
|
6
|
+
} from "./icon-button-classes";
|
|
3
7
|
|
|
4
|
-
export type { IconButtonSize };
|
|
8
|
+
export type { IconButtonSize, IconButtonVariant };
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* A square icon-only button — the kit's one answer for ✕, ⋮, ↻, ✏️, and
|
|
@@ -9,18 +13,27 @@ export type { IconButtonSize };
|
|
|
9
13
|
* label is the accessible name. Pair with {@link Tooltip} so sighted users
|
|
10
14
|
* get the same label on hover.
|
|
11
15
|
*
|
|
16
|
+
* Sized in terms of `--silo-font-size-base` so the hit target and child SVGs
|
|
17
|
+
* scale with Silo's UI zoom (`uiFontSize`). Prefer Phosphor `size="1em"`
|
|
18
|
+
* (or omit a fixed px size) so the glyph tracks the button.
|
|
19
|
+
*
|
|
12
20
|
* Styled purely via host-provided `.silo-icon-button*` classes — no
|
|
13
21
|
* stylesheet import is needed in the extension.
|
|
14
22
|
*
|
|
15
23
|
* @example
|
|
16
24
|
* ```tsx
|
|
17
25
|
* <IconButton aria-label="Refresh" onClick={refresh}>
|
|
18
|
-
* <RefreshIcon />
|
|
26
|
+
* <RefreshIcon size="1em" />
|
|
19
27
|
* </IconButton>
|
|
20
28
|
*
|
|
21
29
|
* // compact — e.g. in a ListRow's trailing slot
|
|
22
30
|
* <IconButton size="sm" aria-label="Pin" onClick={pin}>
|
|
23
|
-
* <PinIcon />
|
|
31
|
+
* <PinIcon size="1em" />
|
|
32
|
+
* </IconButton>
|
|
33
|
+
*
|
|
34
|
+
* // panel / breadcrumb toolbar (local-web-viewer tone)
|
|
35
|
+
* <IconButton size="sm" variant="toolbar" aria-label="Mark">
|
|
36
|
+
* <FlagIcon size="1em" weight="bold" />
|
|
24
37
|
* </IconButton>
|
|
25
38
|
* ```
|
|
26
39
|
*
|
|
@@ -29,19 +42,28 @@ export type { IconButtonSize };
|
|
|
29
42
|
*/
|
|
30
43
|
export function IconButton({
|
|
31
44
|
size = "normal",
|
|
45
|
+
variant = "normal",
|
|
32
46
|
className,
|
|
33
47
|
type = "button",
|
|
34
48
|
children,
|
|
35
49
|
"aria-label": ariaLabel,
|
|
36
50
|
...rest
|
|
37
51
|
}: {
|
|
38
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Hit-target size in `em` of `--silo-font-size-base` (tracks Zoom In/Out).
|
|
54
|
+
* `normal` = 2.5em, `sm` = 2em (local-web-viewer toolbar buttons).
|
|
55
|
+
*/
|
|
39
56
|
size?: IconButtonSize;
|
|
57
|
+
/**
|
|
58
|
+
* `"toolbar"` — black/white toolbar-text icons, hover fill only, no
|
|
59
|
+
* press-scale. Use on editor/terminal breadcrumb clusters and panel bars.
|
|
60
|
+
*/
|
|
61
|
+
variant?: IconButtonVariant;
|
|
40
62
|
/** Required — the icon is the only visual. */
|
|
41
63
|
"aria-label": string;
|
|
42
64
|
children?: ReactNode;
|
|
43
65
|
} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "aria-label">) {
|
|
44
|
-
const classes = iconButtonClass(size);
|
|
66
|
+
const classes = iconButtonClass(size, variant);
|
|
45
67
|
return (
|
|
46
68
|
<button
|
|
47
69
|
type={type}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { activityClass, activityFromAgent } from "./activity";
|
|
3
|
+
|
|
4
|
+
describe("activityClass", () => {
|
|
5
|
+
it("maps kinds and sizes", () => {
|
|
6
|
+
expect(activityClass("working", "md")).toBe(
|
|
7
|
+
"silo-activity silo-activity-working silo-activity-md",
|
|
8
|
+
);
|
|
9
|
+
expect(activityClass("ready")).toBe(
|
|
10
|
+
"silo-activity silo-activity-ready silo-activity-sm",
|
|
11
|
+
);
|
|
12
|
+
expect(activityClass("warn", "sm")).toBe(
|
|
13
|
+
"silo-activity silo-activity-warn silo-activity-sm",
|
|
14
|
+
);
|
|
15
|
+
expect(activityClass("error")).toBe(
|
|
16
|
+
"silo-activity silo-activity-error silo-activity-sm",
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("uses none fallback when activity is omitted", () => {
|
|
21
|
+
expect(activityClass(undefined)).toBe(
|
|
22
|
+
"silo-activity silo-activity-none silo-activity-sm",
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("activityFromAgent", () => {
|
|
28
|
+
it("maps overlapping agent states", () => {
|
|
29
|
+
expect(activityFromAgent("working")).toBe("working");
|
|
30
|
+
expect(activityFromAgent("idle")).toBe("ready");
|
|
31
|
+
expect(activityFromAgent("error")).toBe("error");
|
|
32
|
+
expect(activityFromAgent("none")).toBeNull();
|
|
33
|
+
expect(activityFromAgent("dead")).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
});
|
package/src/activity.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AgentActivity } from "./agents-service";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Host-owned activity state for chrome (workspace rows, CenterDock tabs,
|
|
5
|
+
* SideDock tabs, and the public {@link Activity} glyph). Extensions pick a
|
|
6
|
+
* kind only — never an icon, color, or motion. See ADR 0030.
|
|
7
|
+
*
|
|
8
|
+
* @category Core Types
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export type Activity = "working" | "ready" | "warn" | "error";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Glyph size for {@link Activity}. `"sm"` matches workspace status rows (~6px);
|
|
15
|
+
* `"md"` is slightly larger for CenterDock / SideDock tabs.
|
|
16
|
+
*
|
|
17
|
+
* @category Core Types
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export type ActivitySize = "sm" | "md";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Map {@link AgentActivity} onto UI {@link Activity}. Returns `null` when there
|
|
24
|
+
* is nothing to paint (`none` / `dead` — callers may map `dead` → `"error"`
|
|
25
|
+
* themselves if they want chrome).
|
|
26
|
+
*
|
|
27
|
+
* @category Core Types
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export function activityFromAgent(a: AgentActivity): Activity | null {
|
|
31
|
+
switch (a) {
|
|
32
|
+
case "working":
|
|
33
|
+
return "working";
|
|
34
|
+
case "idle":
|
|
35
|
+
return "ready";
|
|
36
|
+
case "error":
|
|
37
|
+
return "error";
|
|
38
|
+
case "none":
|
|
39
|
+
case "dead":
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the host `.silo-activity*` class string. Pinned by unit tests
|
|
46
|
+
* (RFC 0016 class-contract pattern). When `activity` is omitted, uses the
|
|
47
|
+
* neutral workspace fallback (gray “none” look).
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export function activityClass(
|
|
52
|
+
activity: Activity | undefined,
|
|
53
|
+
size: ActivitySize = "sm",
|
|
54
|
+
): string {
|
|
55
|
+
const kind = activity ?? "none";
|
|
56
|
+
return `silo-activity silo-activity-${kind} silo-activity-${size}`;
|
|
57
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { Disposable } from "./types";
|
|
2
|
+
import type { TerminalKind } from "./domain-types";
|
|
3
|
+
|
|
4
|
+
// `ctx.agents` — host-computed coding-agent activity and resume-identity
|
|
5
|
+
// observability. See RFC 0018 (docs/proposals/0018-ctx-agents-surface.md).
|
|
6
|
+
// Detection is fully sealed inside the host implementation — there is no
|
|
7
|
+
// registration API for detectors or resume-hint resolvers. Extensions only
|
|
8
|
+
// ever read this surface.
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* What a terminal's agent is currently doing, as classified by the host from
|
|
12
|
+
* OSC/output signals. `"none"` means no agent activity has been observed
|
|
13
|
+
* (including plain, non-agent shells). `"idle"` means the agent finished its
|
|
14
|
+
* last turn and is waiting for the next input — this is purely a fact about
|
|
15
|
+
* the agent itself, independent of whether anyone is looking at the
|
|
16
|
+
* terminal; see {@link AgentInfo.needsAttention} for the separate "has a
|
|
17
|
+
* human seen this" signal (an earlier design conflated the two into a
|
|
18
|
+
* `"waiting"`/`"done"` split on `activity` itself — dropped once it turned
|
|
19
|
+
* out to carry no information `needsAttention` didn't already have).
|
|
20
|
+
* `"dead"` is distinct from a merely `stale` restored state — see
|
|
21
|
+
* {@link AgentInfo.stale} — and means the terminal's backend was confirmed
|
|
22
|
+
* gone (no daemon to reattach to) after an unclean shutdown; nothing will
|
|
23
|
+
* arrive to resolve this on its own.
|
|
24
|
+
*
|
|
25
|
+
* @category Core Types
|
|
26
|
+
* @public
|
|
27
|
+
* @beta
|
|
28
|
+
*/
|
|
29
|
+
export type AgentActivity = "none" | "working" | "idle" | "error" | "dead";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Live agent-activity and resume-identity state for one terminal, computed
|
|
33
|
+
* once by the host and shared across every subscriber — never recomputed
|
|
34
|
+
* per-extension. Returned by {@link AgentsService.getState} and
|
|
35
|
+
* {@link AgentsService.getByTerminalId}; delivered to
|
|
36
|
+
* {@link AgentsService.subscribe} listeners on every change.
|
|
37
|
+
*
|
|
38
|
+
* @category Consumer Services
|
|
39
|
+
* @public
|
|
40
|
+
* @beta
|
|
41
|
+
*/
|
|
42
|
+
export interface AgentInfo {
|
|
43
|
+
/** The terminal record id this state belongs to. */
|
|
44
|
+
readonly terminalId: string;
|
|
45
|
+
/** The workspace this terminal belongs to. */
|
|
46
|
+
readonly workspaceId: string;
|
|
47
|
+
/** The terminal's kind at registration time (`"shell"`, `"claude"`, `"pi"`). */
|
|
48
|
+
readonly kind: TerminalKind;
|
|
49
|
+
/**
|
|
50
|
+
* Whether this terminal currently hosts an agent — true if it was created
|
|
51
|
+
* as one, or an agent-specific signal was observed in it (e.g. typing
|
|
52
|
+
* `claude` into a plain shell).
|
|
53
|
+
*/
|
|
54
|
+
readonly isAgent: boolean;
|
|
55
|
+
/** Current classified activity. */
|
|
56
|
+
readonly activity: AgentActivity;
|
|
57
|
+
/**
|
|
58
|
+
* Sticky "finished, go look" flag: set when the agent goes idle in a
|
|
59
|
+
* terminal that wasn't the active one at that moment, and cleared only by
|
|
60
|
+
* {@link AgentsService.acknowledge}. Never set at all if the terminal
|
|
61
|
+
* *was* already active the instant the agent went idle — being watched
|
|
62
|
+
* live counts as already seen, no acknowledgment needed.
|
|
63
|
+
*/
|
|
64
|
+
readonly needsAttention: boolean;
|
|
65
|
+
/** ISO timestamp of when `needsAttention` was set; undefined when not pending. */
|
|
66
|
+
readonly attentionSince?: string;
|
|
67
|
+
/** ISO timestamp of when the current `"working"` phase started; undefined otherwise. */
|
|
68
|
+
readonly workingSince?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Soft, time-gap-based, **self-clearing** signal: this restored `working`/
|
|
71
|
+
* `needsAttention` duration followed a gap long enough that it can't be
|
|
72
|
+
* fully trusted — the agent may have finished without it being observed.
|
|
73
|
+
* The next live signal clears it automatically. Distinct from
|
|
74
|
+
* `activity === "dead"`, which is a hard, structural, non-self-resolving
|
|
75
|
+
* fact — see {@link AgentActivity}.
|
|
76
|
+
*/
|
|
77
|
+
readonly stale: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Exact session identifier for the agent running in this terminal, when one
|
|
80
|
+
* could be determined. Present only when an opt-in `SessionStart` hook has
|
|
81
|
+
* reported it (see the Settings → Agents page); absent otherwise — Silo
|
|
82
|
+
* never *infers* a session id by directory/recency, since that can silently
|
|
83
|
+
* resolve to the wrong session. Populated live once the hook fires (not
|
|
84
|
+
* deferred to death), then persisted, so a consumer reacting to
|
|
85
|
+
* `activity === "dead"` can read it back.
|
|
86
|
+
*/
|
|
87
|
+
readonly sessionId?: string;
|
|
88
|
+
/**
|
|
89
|
+
* A ready-to-show (and copy/paste) resume hint. Either an exact
|
|
90
|
+
* `"claude --resume 01abc..."` (when {@link AgentInfo.sessionId} was
|
|
91
|
+
* resolved via a hook) or an honest, session-id-less
|
|
92
|
+
* `"was running claude in ~/foo"` note (when it wasn't). Attached the first
|
|
93
|
+
* time the terminal's agent is detected and persisted, so it is available
|
|
94
|
+
* both live and at `activity === "dead"`.
|
|
95
|
+
*/
|
|
96
|
+
readonly resumeCommand?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Human-readable agent name, e.g. `"Claude Code"` or `"Codex CLI"`. Tells
|
|
99
|
+
* you *which* agent CLI is running in this terminal, independent of
|
|
100
|
+
* whether an exact session id was ever resolved — populated as soon as a
|
|
101
|
+
* known agent leader is detected at all (same moment
|
|
102
|
+
* {@link AgentInfo.resumeCommand} is first attached), not deferred until
|
|
103
|
+
* {@link AgentInfo.sessionId} is available.
|
|
104
|
+
*/
|
|
105
|
+
readonly agentName?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Stable catalog key for the agent, e.g. `"claude"` or `"codex"` — unlike
|
|
108
|
+
* {@link AgentInfo.agentName} (a display string meant for showing to the
|
|
109
|
+
* user), this is meant for an extension's own code to switch or compare
|
|
110
|
+
* on, and won't change if the display name is ever reworded. Populated at
|
|
111
|
+
* the same moment and lifecycle as `agentName`.
|
|
112
|
+
*/
|
|
113
|
+
readonly agentId?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Host-computed coding-agent observability — exposed as
|
|
118
|
+
* {@link ExtensionContext.agents}. Detection (what OSC/output signals mean
|
|
119
|
+
* for a given agent) and resume-hint resolution are both sealed inside the
|
|
120
|
+
* host implementation; there is no registration API. Mirrors
|
|
121
|
+
* {@link ProcessesService} in shape: one shared, canonical answer, not
|
|
122
|
+
* something each extension recomputes — reads are unscoped, and
|
|
123
|
+
* {@link AgentsService.acknowledge} is the one deliberately scoped mutation,
|
|
124
|
+
* the same pattern {@link ProcessesService.kill} establishes.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const sub = ctx.agents.subscribe((agents) => {
|
|
129
|
+
* const dead = agents.find((a) => a.activity === "dead");
|
|
130
|
+
* if (dead) ctx.ui.notify("info", dead.resumeCommand ?? "An agent session ended.");
|
|
131
|
+
* });
|
|
132
|
+
* ctx.subscriptions.push(sub);
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @category Consumer Services
|
|
136
|
+
* @public
|
|
137
|
+
* @beta
|
|
138
|
+
*/
|
|
139
|
+
export interface AgentsService {
|
|
140
|
+
/**
|
|
141
|
+
* Current {@link AgentInfo} for every tracked terminal in the active
|
|
142
|
+
* workspace. Pass `{ allWorkspaces: true }` for every loaded workspace
|
|
143
|
+
* instead.
|
|
144
|
+
*/
|
|
145
|
+
getState(options?: { allWorkspaces?: boolean }): AgentInfo[];
|
|
146
|
+
/** Look up {@link AgentInfo} for a specific terminal tab by its record id. */
|
|
147
|
+
getByTerminalId(terminalId: string): AgentInfo | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* Subscribe to changes in the active workspace's agent state. Pass
|
|
150
|
+
* `{ allWorkspaces: true }` to be notified across every loaded workspace
|
|
151
|
+
* instead. Returns a {@link Disposable} that cancels the subscription.
|
|
152
|
+
*/
|
|
153
|
+
subscribe(
|
|
154
|
+
listener: (state: AgentInfo[]) => void,
|
|
155
|
+
options?: { allWorkspaces?: boolean },
|
|
156
|
+
): Disposable;
|
|
157
|
+
/**
|
|
158
|
+
* Acknowledge a finished run: clears {@link AgentInfo.needsAttention} (and
|
|
159
|
+
* its `attentionSince` timestamp). A no-op if the terminal wasn't pending
|
|
160
|
+
* attention. Doesn't touch `activity` — `"idle"` already correctly
|
|
161
|
+
* describes the agent both before and after acknowledgment; only whether
|
|
162
|
+
* a human has seen it changes.
|
|
163
|
+
*
|
|
164
|
+
* Deliberately **not** wired to focus automatically by the host — whether
|
|
165
|
+
* *viewing* a terminal should count as acknowledging it is a per-consumer
|
|
166
|
+
* policy call this method leaves to you, not a fixed rule `ctx.agents`
|
|
167
|
+
* imposes. Call it from wherever your own UI decides a run has been seen —
|
|
168
|
+
* typically `ctx.terminals.subscribeActive`, but it doesn't have to be.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* // Acknowledge whenever the user actually looks at the terminal.
|
|
173
|
+
* ctx.subscriptions.push(
|
|
174
|
+
* ctx.terminals.subscribeActive((terminalId) => {
|
|
175
|
+
* if (terminalId) ctx.agents.acknowledge(terminalId);
|
|
176
|
+
* }),
|
|
177
|
+
* );
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
acknowledge(terminalId: string): void;
|
|
181
|
+
}
|
package/src/editor-service.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Disposable } from "./types";
|
|
2
2
|
import type { Event } from "./event";
|
|
3
3
|
import type { EditorMode } from "./domain-types";
|
|
4
|
+
import type { TabAdornmentMethods } from "./tab-adornment";
|
|
4
5
|
|
|
5
6
|
// `ctx.editors` — the editor & document domain (public contract). Opening files
|
|
6
7
|
// into editor tabs, the active-editor save/close commands, the diff-content
|
|
@@ -225,10 +226,13 @@ export interface EditorSaveEvent {
|
|
|
225
226
|
* editors register save handlers. The single entry point for opening editors —
|
|
226
227
|
* prefer it over reaching into workspace/editor state.
|
|
227
228
|
*
|
|
229
|
+
* Tab chrome adornments (`setIcon` / `setIndicator` / …) take an **editor id**
|
|
230
|
+
* as the target — see {@link TabAdornmentMethods}.
|
|
231
|
+
*
|
|
228
232
|
* @category Consumer Services
|
|
229
233
|
* @public
|
|
230
234
|
*/
|
|
231
|
-
export interface EditorService {
|
|
235
|
+
export interface EditorService extends TabAdornmentMethods {
|
|
232
236
|
/**
|
|
233
237
|
* Open a file in an editor tab. Promotes an existing preview, focuses an
|
|
234
238
|
* already-open tab, or opens a new one.
|