@silo-code/sdk 0.44.0 → 0.45.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 +15 -2
- package/dist/ActivityGlyph.d.ts.map +1 -1
- package/dist/ActivityGlyph.js +11 -4
- package/dist/ActivityGlyph.js.map +1 -1
- package/dist/activity.d.ts +25 -2
- package/dist/activity.d.ts.map +1 -1
- package/dist/activity.js +29 -0
- package/dist/activity.js.map +1 -1
- package/dist/agents-service.d.ts +183 -0
- package/dist/agents-service.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-service.d.ts +12 -2
- package/dist/process-service.d.ts.map +1 -1
- package/dist/terminal-service.d.ts +78 -2
- package/dist/terminal-service.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ActivityGlyph.tsx +23 -2
- package/src/activity.test.ts +34 -1
- package/src/activity.ts +37 -2
- package/src/agents-service.ts +190 -0
- package/src/index.ts +7 -0
- package/src/process-service.ts +15 -2
- package/src/terminal-service.ts +82 -2
package/dist/ActivityGlyph.d.ts
CHANGED
|
@@ -8,18 +8,31 @@ import { type Activity as ActivityKind, type ActivitySize } from "./activity.js"
|
|
|
8
8
|
* Styled purely via host-provided `.silo-activity*` classes — no stylesheet
|
|
9
9
|
* import is needed in the extension.
|
|
10
10
|
*
|
|
11
|
+
* Pass `jitterKey` whenever several animated glyphs render together (a list of
|
|
12
|
+
* agent or workspace rows) so their pulses don't run in lockstep — and so each
|
|
13
|
+
* one starts mid-cycle instead of freezing on first paint.
|
|
14
|
+
*
|
|
11
15
|
* @example
|
|
12
16
|
* ```tsx
|
|
13
17
|
* <ActivityGlyph activity="working" size="md" />
|
|
14
|
-
* <ActivityGlyph activity="ready" />
|
|
18
|
+
* <ActivityGlyph activity="ready" jitterKey={row.id} />
|
|
15
19
|
* <ActivityGlyph size="sm" /> // workspace neutral (omit)
|
|
16
20
|
* ```
|
|
17
21
|
*
|
|
18
22
|
* @category Consumer Services
|
|
19
23
|
* @public
|
|
20
24
|
*/
|
|
21
|
-
export declare function ActivityGlyph({ activity, size, className, ...rest }: {
|
|
25
|
+
export declare function ActivityGlyph({ activity, size, className, jitterKey, style, ...rest }: {
|
|
22
26
|
activity?: ActivityKind;
|
|
23
27
|
size?: ActivitySize;
|
|
28
|
+
/**
|
|
29
|
+
* Stable id (a row or terminal id — never an array index) that gives this
|
|
30
|
+
* glyph a deterministic per-instance animation offset. Desynchronizes its
|
|
31
|
+
* pulse from other glyphs rendered alongside it, and makes the animation
|
|
32
|
+
* mount already in progress rather than pausing on first paint (a WebKit
|
|
33
|
+
* quirk when the glyph appears inside a just-shown container). Inert on
|
|
34
|
+
* non-animated glyphs.
|
|
35
|
+
*/
|
|
36
|
+
jitterKey?: string;
|
|
24
37
|
} & Omit<HTMLAttributes<HTMLSpanElement>, "children">): import("react").JSX.Element;
|
|
25
38
|
//# sourceMappingURL=ActivityGlyph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityGlyph.d.ts","sourceRoot":"","sources":["../src/ActivityGlyph.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ActivityGlyph.d.ts","sourceRoot":"","sources":["../src/ActivityGlyph.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAGL,KAAK,QAAQ,IAAI,YAAY,EAC7B,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAW,EACX,SAAS,EACT,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE;IACD,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,+BAcpD"}
|
package/dist/ActivityGlyph.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { activityClass, } from "./activity.js";
|
|
2
|
+
import { activityClass, activityJitterStyle, } from "./activity.js";
|
|
3
3
|
/**
|
|
4
4
|
* Host-painted activity glyph — same look on workspace rows, CenterDock tabs,
|
|
5
5
|
* and extension UI. Pick an {@link Activity}; the host owns color and motion
|
|
@@ -8,18 +8,25 @@ import { activityClass, } from "./activity.js";
|
|
|
8
8
|
* Styled purely via host-provided `.silo-activity*` classes — no stylesheet
|
|
9
9
|
* import is needed in the extension.
|
|
10
10
|
*
|
|
11
|
+
* Pass `jitterKey` whenever several animated glyphs render together (a list of
|
|
12
|
+
* agent or workspace rows) so their pulses don't run in lockstep — and so each
|
|
13
|
+
* one starts mid-cycle instead of freezing on first paint.
|
|
14
|
+
*
|
|
11
15
|
* @example
|
|
12
16
|
* ```tsx
|
|
13
17
|
* <ActivityGlyph activity="working" size="md" />
|
|
14
|
-
* <ActivityGlyph activity="ready" />
|
|
18
|
+
* <ActivityGlyph activity="ready" jitterKey={row.id} />
|
|
15
19
|
* <ActivityGlyph size="sm" /> // workspace neutral (omit)
|
|
16
20
|
* ```
|
|
17
21
|
*
|
|
18
22
|
* @category Consumer Services
|
|
19
23
|
* @public
|
|
20
24
|
*/
|
|
21
|
-
export function ActivityGlyph({ activity, size = "sm", className, ...rest }) {
|
|
25
|
+
export function ActivityGlyph({ activity, size = "sm", className, jitterKey, style, ...rest }) {
|
|
22
26
|
const classes = activityClass(activity, size);
|
|
23
|
-
|
|
27
|
+
const mergedStyle = jitterKey != null
|
|
28
|
+
? { ...activityJitterStyle(jitterKey), ...style }
|
|
29
|
+
: style;
|
|
30
|
+
return (_jsx("span", { className: className ? `${classes} ${className}` : classes, style: mergedStyle, "aria-hidden": rest["aria-label"] == null ? true : undefined, ...rest }));
|
|
24
31
|
}
|
|
25
32
|
//# sourceMappingURL=ActivityGlyph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityGlyph.js","sourceRoot":"","sources":["../src/ActivityGlyph.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,aAAa,
|
|
1
|
+
{"version":3,"file":"ActivityGlyph.js","sourceRoot":"","sources":["../src/ActivityGlyph.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,aAAa,EACb,mBAAmB,GAGpB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,SAAS,EACT,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EAa4C;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,WAAW,GACf,SAAS,IAAI,IAAI;QACf,CAAC,CAAE,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAoB;QACpE,CAAC,CAAC,KAAK,CAAC;IACZ,OAAO,CACL,eACE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,EAC1D,KAAK,EAAE,WAAW,iBACL,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KACtD,IAAI,GACR,CACH,CAAC;AACJ,CAAC"}
|
package/dist/activity.d.ts
CHANGED
|
@@ -9,8 +9,11 @@ import type { AgentActivity } from "./agents-service.js";
|
|
|
9
9
|
*/
|
|
10
10
|
export type Activity = "working" | "ready" | "warn" | "error";
|
|
11
11
|
/**
|
|
12
|
-
* Glyph size for {@link Activity}. `"sm"`
|
|
13
|
-
*
|
|
12
|
+
* Glyph size for {@link Activity}. `"sm"` (8px at the default `uiFontSize`) is
|
|
13
|
+
* the workbench size — workspace status rows and CenterDock / SideDock tabs;
|
|
14
|
+
* `"md"` (10px) is the roomier one, for a list that leads with the dot rather
|
|
15
|
+
* than tucking it into chrome. Both scale with `uiFontSize` rather than being
|
|
16
|
+
* fixed pixels.
|
|
14
17
|
*
|
|
15
18
|
* @category Core Types
|
|
16
19
|
* @public
|
|
@@ -33,4 +36,24 @@ export declare function activityFromAgent(a: AgentActivity): Activity | null;
|
|
|
33
36
|
* @internal
|
|
34
37
|
*/
|
|
35
38
|
export declare function activityClass(activity: Activity | undefined, size?: ActivitySize): string;
|
|
39
|
+
/**
|
|
40
|
+
* Deterministic per-instance `animation-delay` (via the `--silo-activity-jitter`
|
|
41
|
+
* custom property) for an animated {@link Activity} glyph, keyed off a stable id
|
|
42
|
+
* — a row or terminal id, not an array index. Two purposes:
|
|
43
|
+
*
|
|
44
|
+
* - **Desync.** Several `working` / `ready` glyphs rendered side by side would
|
|
45
|
+
* otherwise pulse in perfect lockstep; a per-id offset staggers them.
|
|
46
|
+
* - **Start mid-cycle.** The value is a *negative* delay, so the animation
|
|
47
|
+
* mounts already in progress rather than pausing on first paint — a WebKit
|
|
48
|
+
* quirk that bites when the glyph is created inside a container that was
|
|
49
|
+
* `display: none` moments earlier (e.g. a Navigator view on its first
|
|
50
|
+
* activation), where a zero delay can leave the pulse frozen until the next
|
|
51
|
+
* show/hide toggle.
|
|
52
|
+
*
|
|
53
|
+
* Hashed rather than random so the offset is stable across re-renders. Pinned
|
|
54
|
+
* by unit tests.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export declare function activityJitterStyle(key: string): Record<"--silo-activity-jitter", string>;
|
|
36
59
|
//# sourceMappingURL=activity.d.ts.map
|
package/dist/activity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D
|
|
1
|
+
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,GAAG,QAAQ,GAAG,IAAI,CAYnE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,IAAI,GAAE,YAAmB,GACxB,MAAM,CAGR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,GACV,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAS1C"}
|
package/dist/activity.js
CHANGED
|
@@ -30,4 +30,33 @@ export function activityClass(activity, size = "sm") {
|
|
|
30
30
|
const kind = activity ?? "none";
|
|
31
31
|
return `silo-activity silo-activity-${kind} silo-activity-${size}`;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Deterministic per-instance `animation-delay` (via the `--silo-activity-jitter`
|
|
35
|
+
* custom property) for an animated {@link Activity} glyph, keyed off a stable id
|
|
36
|
+
* — a row or terminal id, not an array index. Two purposes:
|
|
37
|
+
*
|
|
38
|
+
* - **Desync.** Several `working` / `ready` glyphs rendered side by side would
|
|
39
|
+
* otherwise pulse in perfect lockstep; a per-id offset staggers them.
|
|
40
|
+
* - **Start mid-cycle.** The value is a *negative* delay, so the animation
|
|
41
|
+
* mounts already in progress rather than pausing on first paint — a WebKit
|
|
42
|
+
* quirk that bites when the glyph is created inside a container that was
|
|
43
|
+
* `display: none` moments earlier (e.g. a Navigator view on its first
|
|
44
|
+
* activation), where a zero delay can leave the pulse frozen until the next
|
|
45
|
+
* show/hide toggle.
|
|
46
|
+
*
|
|
47
|
+
* Hashed rather than random so the offset is stable across re-renders. Pinned
|
|
48
|
+
* by unit tests.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
export function activityJitterStyle(key) {
|
|
53
|
+
let hash = 0;
|
|
54
|
+
for (let i = 0; i < key.length; i++) {
|
|
55
|
+
hash = (hash * 31 + key.charCodeAt(i)) | 0;
|
|
56
|
+
}
|
|
57
|
+
// 1.8s is the longest activity animation period (`silo-activity-wave`), so the
|
|
58
|
+
// offset spans one full cycle.
|
|
59
|
+
const delaySeconds = -(((hash >>> 0) % 1000) / 1000) * 1.8;
|
|
60
|
+
return { "--silo-activity-jitter": `${delaySeconds.toFixed(3)}s` };
|
|
61
|
+
}
|
|
33
62
|
//# sourceMappingURL=activity.js.map
|
package/dist/activity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAwBA;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAgB;IAChD,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA8B,EAC9B,OAAqB,IAAI;IAEzB,MAAM,IAAI,GAAG,QAAQ,IAAI,MAAM,CAAC;IAChC,OAAO,+BAA+B,IAAI,kBAAkB,IAAI,EAAE,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAW;IAEX,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,+EAA+E;IAC/E,+BAA+B;IAC/B,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC3D,OAAO,EAAE,wBAAwB,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACrE,CAAC"}
|
package/dist/agents-service.d.ts
CHANGED
|
@@ -160,6 +160,180 @@ export interface CatalogAgentSummary {
|
|
|
160
160
|
readonly displayName: string;
|
|
161
161
|
readonly icon?: AgentIcon;
|
|
162
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* One **Agent Profile** as an extension may read it through
|
|
165
|
+
* {@link AgentProfilesService.list} — a named recipe for starting a coding
|
|
166
|
+
* agent in a terminal, defined by the user on Settings → Agents → Profiles.
|
|
167
|
+
* Deliberately a summary, never the host's own profile record: the command
|
|
168
|
+
* line, its config directory, and every other launch detail stay host-owned
|
|
169
|
+
* (RFC 0033).
|
|
170
|
+
*
|
|
171
|
+
* @category Consumer Services
|
|
172
|
+
* @public
|
|
173
|
+
* @beta
|
|
174
|
+
*/
|
|
175
|
+
export interface AgentProfileSummary {
|
|
176
|
+
/** Stable id — pass it to {@link AgentProfilesService.launch}. */
|
|
177
|
+
readonly id: string;
|
|
178
|
+
/** The user's own name for this profile, e.g. `"Claude (work)"`. Show this;
|
|
179
|
+
* never show or parse the id. */
|
|
180
|
+
readonly label: string;
|
|
181
|
+
/** True for the single profile marked default, which is what `launch()`
|
|
182
|
+
* starts when no `profileId` is given. False for every profile when the
|
|
183
|
+
* user has not chosen one. */
|
|
184
|
+
readonly isDefault: boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Whether this profile's agent can be given an **opening prompt**. A static
|
|
187
|
+
* fact about the agent, not about any particular launch — so a picker can
|
|
188
|
+
* grey out or annotate a profile up front instead of discovering
|
|
189
|
+
* `"agent-takes-none"` after the user has already typed one.
|
|
190
|
+
*/
|
|
191
|
+
readonly acceptsPrompt: boolean;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Why an opening prompt could not be delivered. Silo refuses rather than
|
|
195
|
+
* approximating: a prompt it cannot quote exactly is never typed, and no agent
|
|
196
|
+
* is started without the prompt the caller asked for.
|
|
197
|
+
*
|
|
198
|
+
* @category Consumer Services
|
|
199
|
+
* @public
|
|
200
|
+
* @beta
|
|
201
|
+
*/
|
|
202
|
+
export type PromptRefusal =
|
|
203
|
+
/** The profile matches no agent Silo knows, so there is no way to tell how
|
|
204
|
+
* its CLI takes a prompt. The user can fix this by setting the agent on the
|
|
205
|
+
* profile. */
|
|
206
|
+
"no-agent"
|
|
207
|
+
/** The profile's agent has no way to accept an opening prompt while staying
|
|
208
|
+
* interactive. Check {@link AgentProfileSummary.acceptsPrompt} first to
|
|
209
|
+
* avoid offering a prompt for such a profile at all. */
|
|
210
|
+
| "agent-takes-none"
|
|
211
|
+
/** Silo has no exact quoting rule for the shell this terminal would run and
|
|
212
|
+
* will not guess one. bash, zsh, and fish are supported. */
|
|
213
|
+
| "unsupported-shell"
|
|
214
|
+
/**
|
|
215
|
+
* The prompt exceeds Silo's 2 KiB limit — roughly a page of prose.
|
|
216
|
+
*
|
|
217
|
+
* The ceiling is low because the prompt is *typed* into the user's shell,
|
|
218
|
+
* and a shell with syntax highlighting or autosuggestions cannot reliably
|
|
219
|
+
* consume more than a few KiB in one go. Silo refuses well short of where
|
|
220
|
+
* delivery starts failing, because a truncated prompt would reach the agent
|
|
221
|
+
* looking complete. Trim it and retry.
|
|
222
|
+
*/
|
|
223
|
+
| "too-large";
|
|
224
|
+
/**
|
|
225
|
+
* Options for {@link AgentProfilesService.launch}. Every field is optional —
|
|
226
|
+
* a bare `launch()` starts the default profile in the active workspace.
|
|
227
|
+
*
|
|
228
|
+
* @category Consumer Services
|
|
229
|
+
* @public
|
|
230
|
+
* @beta
|
|
231
|
+
*/
|
|
232
|
+
export interface LaunchAgentProfileOptions {
|
|
233
|
+
/** Which profile to start. Defaults to the one marked default, else the
|
|
234
|
+
* first — the same profile the built-in "New Agent" command uses. */
|
|
235
|
+
profileId?: string;
|
|
236
|
+
/** Which workspace to start it in. Defaults to the active one. A
|
|
237
|
+
* background workspace works: the session is spawned eagerly, since no
|
|
238
|
+
* panel will mount to do it. */
|
|
239
|
+
workspaceId?: string;
|
|
240
|
+
/** Working directory for the new terminal. Defaults to the workspace folder. */
|
|
241
|
+
cwd?: string;
|
|
242
|
+
/**
|
|
243
|
+
* An opening prompt to hand the agent on its launch line.
|
|
244
|
+
*
|
|
245
|
+
* The text is delivered as a literal — it is never interpreted by the
|
|
246
|
+
* shell, so `$HOME`, backticks, quotes, and newlines are all safe. If Silo
|
|
247
|
+
* cannot deliver it exactly, the launch is **refused** rather than mangled
|
|
248
|
+
* or silently dropped: nothing is typed, no terminal is created, and
|
|
249
|
+
* `launch()` returns the reason.
|
|
250
|
+
*
|
|
251
|
+
* Keep it to an opening instruction. The limit is **2 KiB** — about a page —
|
|
252
|
+
* and anything longer is refused with `"too-large"`; see that member for
|
|
253
|
+
* why the ceiling is where it is.
|
|
254
|
+
*
|
|
255
|
+
* The composed line is typed into the user's own interactive shell, so it
|
|
256
|
+
* appears in scrollback and in shell history exactly as if they had typed
|
|
257
|
+
* it. Don't put a secret in one.
|
|
258
|
+
*/
|
|
259
|
+
prompt?: string;
|
|
260
|
+
/**
|
|
261
|
+
* Activate the target workspace and focus the new terminal. Defaults to
|
|
262
|
+
* `true`. Pass `false` to start an agent without stealing the user's place.
|
|
263
|
+
*/
|
|
264
|
+
activate?: boolean;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* What {@link AgentProfilesService.launch} did. A **result**, never a throw:
|
|
268
|
+
* every foreseeable reason a launch cannot happen is a value you can branch
|
|
269
|
+
* on and report to your own user.
|
|
270
|
+
*
|
|
271
|
+
* @category Consumer Services
|
|
272
|
+
* @public
|
|
273
|
+
* @beta
|
|
274
|
+
*/
|
|
275
|
+
export type LaunchAgentProfileResult = {
|
|
276
|
+
readonly ok: true;
|
|
277
|
+
/** The created terminal's record id — the same id
|
|
278
|
+
* {@link AgentsService.getByTerminalId} and `ctx.terminals` take. */
|
|
279
|
+
readonly terminalId: string;
|
|
280
|
+
} | {
|
|
281
|
+
readonly ok: false;
|
|
282
|
+
/** Why nothing was launched. `"no-profile"` — the named profile does
|
|
283
|
+
* not exist, or there are no profiles at all. `"no-workspace"` — the
|
|
284
|
+
* named workspace does not exist, or none is open. Otherwise one of the
|
|
285
|
+
* {@link PromptRefusal} reasons. */
|
|
286
|
+
readonly refusal: PromptRefusal | "no-profile" | "no-workspace";
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Read the user's **Agent Profiles** and start one, optionally with an opening
|
|
290
|
+
* prompt — exposed as `ctx.agents.profiles` (RFC 0033).
|
|
291
|
+
*
|
|
292
|
+
* A profile is a way to *start* a terminal, not a way to talk to an agent:
|
|
293
|
+
* what comes up is a PTY running a real agent CLI, exactly as if the user had
|
|
294
|
+
* typed the command themselves. There is no agent-agnostic messaging layer
|
|
295
|
+
* here and there is not meant to be one.
|
|
296
|
+
*
|
|
297
|
+
* There is deliberately no `pick()` — build one from `list()` and
|
|
298
|
+
* `ctx.ui.showMenu`, which is the shared chrome — and no `get()`, which is
|
|
299
|
+
* `list().find()`.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* // Let the user choose a profile, then start it on a task.
|
|
304
|
+
* const profiles = ctx.agents.profiles.list();
|
|
305
|
+
* const chosen = await ctx.ui.showMenu(
|
|
306
|
+
* profiles.map((p) => ({ id: p.id, label: p.label })),
|
|
307
|
+
* );
|
|
308
|
+
* if (chosen) {
|
|
309
|
+
* const result = ctx.agents.profiles.launch({
|
|
310
|
+
* profileId: chosen,
|
|
311
|
+
* prompt: "Fix the failing test in src/foo.test.ts",
|
|
312
|
+
* });
|
|
313
|
+
* if (!result.ok) ctx.ui.notify("warn", `Couldn't start it: ${result.refusal}`);
|
|
314
|
+
* }
|
|
315
|
+
* ```
|
|
316
|
+
*
|
|
317
|
+
* @category Consumer Services
|
|
318
|
+
* @public
|
|
319
|
+
* @beta
|
|
320
|
+
*/
|
|
321
|
+
export interface AgentProfilesService {
|
|
322
|
+
/**
|
|
323
|
+
* Every Agent Profile the user has defined, in the order they appear in
|
|
324
|
+
* Settings. The returned array is **read-only and deeply frozen**; it is
|
|
325
|
+
* recomputed when the profile list changes, not on every call.
|
|
326
|
+
*/
|
|
327
|
+
list(): readonly AgentProfileSummary[];
|
|
328
|
+
/**
|
|
329
|
+
* Start a profile in a terminal. Returns the created terminal's id, or a
|
|
330
|
+
* typed refusal — see {@link LaunchAgentProfileResult}.
|
|
331
|
+
*
|
|
332
|
+
* A refused prompt creates nothing at all: no terminal record, no workspace
|
|
333
|
+
* activation, no focus change.
|
|
334
|
+
*/
|
|
335
|
+
launch(options?: LaunchAgentProfileOptions): LaunchAgentProfileResult;
|
|
336
|
+
}
|
|
163
337
|
/**
|
|
164
338
|
* Host-computed coding-agent observability — exposed as
|
|
165
339
|
* {@link ExtensionContext.agents}. Detection (what OSC/output signals mean
|
|
@@ -239,5 +413,14 @@ export interface AgentsService {
|
|
|
239
413
|
* @public
|
|
240
414
|
*/
|
|
241
415
|
catalog(): readonly CatalogAgentSummary[];
|
|
416
|
+
/**
|
|
417
|
+
* The user's **Agent Profiles** — read them, and start one, optionally with
|
|
418
|
+
* an opening prompt. See {@link AgentProfilesService}.
|
|
419
|
+
*
|
|
420
|
+
* @category Consumer Services
|
|
421
|
+
* @public
|
|
422
|
+
* @beta
|
|
423
|
+
*/
|
|
424
|
+
readonly profiles: AgentProfilesService;
|
|
242
425
|
}
|
|
243
426
|
//# sourceMappingURL=agents-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-service.d.ts","sourceRoot":"","sources":["../src/agents-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,wFAAwF;IACxF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb;+BAC2B;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;kFAC8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,EAAE,CAAC;IAC7D,8EAA8E;IAC9E,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3D;;;;OAIG;IACH,SAAS,CACP,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,EACtC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GACpC,UAAU,CAAC;IACd;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;;;;;;;;OAWG;IACH,OAAO,IAAI,SAAS,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"agents-service.d.ts","sourceRoot":"","sources":["../src/agents-service.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ export type { EditorService, EditorSaveHandlers, OpenFileOptions, EditorViewInfo
|
|
|
22
22
|
export type { LayoutService, LayoutState, SidePanelColumnState, SideLocation, SheetOptions, } from "./layout-service.js";
|
|
23
23
|
export type { ProcessService, ProcessSession, ProcessSpawnOptions, ProcessExecOptions, ProcessExecResult, } from "./process-service.js";
|
|
24
24
|
export type { ProcessesService, ProcessInfo, ProcessStats, ProcessTreeNode, } from "./processes-service.js";
|
|
25
|
-
export type { AgentsService, AgentInfo, AgentActivity, AgentIcon, AgentIconMode, CatalogAgentSummary, } from "./agents-service.js";
|
|
26
|
-
export type { TerminalService, CreateTerminalInput, TerminalKind, TerminalRecord, TerminalTabDecoration, TerminalTabDecorationProvider, OscEvent, } from "./terminal-service.js";
|
|
25
|
+
export type { AgentsService, AgentInfo, AgentActivity, AgentIcon, AgentIconMode, CatalogAgentSummary, AgentProfilesService, AgentProfileSummary, LaunchAgentProfileOptions, LaunchAgentProfileResult, PromptRefusal, } from "./agents-service.js";
|
|
26
|
+
export type { TerminalService, CreateTerminalInput, TerminalKind, TerminalRecord, TerminalTabDecoration, TerminalTabDecorationProvider, OscEvent, OutputOrigin, SubscribeOutputOptions, } from "./terminal-service.js";
|
|
27
27
|
export type { TabAdornmentColor, TabIconAdornment, TabHighlightAdornment, TabIndicatorAdornment, TabIndicatorFlash, TabActivityAdornment, TabActivityFlash, TabIconContribution, TabHighlightContribution, TabIndicatorContribution, TabActivityContribution, TabIconBinder, TabHighlightBinder, TabIndicatorBinder, TabActivityBinder, TabAdornmentMethods, } from "./tab-adornment.js";
|
|
28
28
|
export type { Activity, ActivitySize } from "./activity.js";
|
|
29
29
|
export { activityFromAgent } from "./activity.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,YAAY,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,MAAM,EACN,eAAe,EACf,QAAQ,EACR,OAAO,EACP,MAAM,EACN,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC;AAKjB,YAAY,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,aAAa,GACd,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,EACT,aAAa,EACb,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAoIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA8BlE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAyBzC,sEAAsE;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkCjD,8EAA8E;AAC9E,8EAA8E;AAC9E,6DAA6D;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,yEAAyE;AACzE,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,4EAA4E;AAC5E,qDAAqD;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,4DAA4D;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,wEAAwE;AACxE,iFAAiF;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAUvE,6EAA6E;AAC7E,wEAAwE;AACxE,+CAA+C;AAC/C,OAAO,EACL,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Disposable } from "./types.js";
|
|
2
|
+
import type { OutputOrigin, SubscribeOutputOptions } from "./terminal-service.js";
|
|
2
3
|
/**
|
|
3
4
|
* Options for spawning a process session. Today sessions are shell PTYs, so
|
|
4
5
|
* `cwd` is required (the webview has no ambient working directory).
|
|
@@ -54,8 +55,17 @@ export interface ProcessSession {
|
|
|
54
55
|
getBuffer(): Promise<string>;
|
|
55
56
|
/** Persist an output buffer for later restore. */
|
|
56
57
|
saveBuffer(data: string): Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Subscribe to output data. Dispose to stop listening.
|
|
60
|
+
*
|
|
61
|
+
* By default only **live** output is delivered. A session survives app
|
|
62
|
+
* restarts, so re-attaching to one replays its recent scrollback; delivering
|
|
63
|
+
* that by default would make every reattach look like a burst of output
|
|
64
|
+
* arriving right now. Pass `{ includeReplay: true }` to receive the replayed
|
|
65
|
+
* history too — for instance to paint scrollback into a fresh view — and read
|
|
66
|
+
* `origin.replay` to tell the two apart.
|
|
67
|
+
*/
|
|
68
|
+
onData(listener: (data: string, origin: OutputOrigin) => void, options?: SubscribeOutputOptions): Disposable;
|
|
59
69
|
/** Subscribe to session exit. Dispose to stop listening. */
|
|
60
70
|
onExit(listener: (exitCode: number) => void): Disposable;
|
|
61
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-service.d.ts","sourceRoot":"","sources":["../src/process-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"process-service.d.ts","sourceRoot":"","sources":["../src/process-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAK/E;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,oDAAoD;IACpD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,6EAA6E;IAC7E,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,kDAAkD;IAClD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC;;;;;;;;;OASG;IACH,MAAM,CACJ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,EACtD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,UAAU,CAAC;IACd,4DAA4D;IAC5D,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;CAC1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,KAAK,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1D;;;OAGG;IACH,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GACtC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,IAAI,CACF,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B"}
|
|
@@ -21,6 +21,51 @@ export interface OscEvent {
|
|
|
21
21
|
/** The raw payload string after the code and its separating semicolon. */
|
|
22
22
|
payload: string;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Where a chunk of terminal output came from in time.
|
|
26
|
+
*
|
|
27
|
+
* A terminal session outlives the app, so re-attaching to one replays the
|
|
28
|
+
* session host's recent scrollback — bytes that are byte-for-byte identical to
|
|
29
|
+
* live output but describe things that already happened, sometimes long ago.
|
|
30
|
+
* Treating them as live is what makes a reattached agent terminal announce a
|
|
31
|
+
* turn that finished before the app started.
|
|
32
|
+
*
|
|
33
|
+
* @category Consumer Services
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export interface OutputOrigin {
|
|
37
|
+
/**
|
|
38
|
+
* `true` when the chunk is scrollback the session host is replaying on
|
|
39
|
+
* attach, `false` when the session produced it just now.
|
|
40
|
+
*
|
|
41
|
+
* Only ever `true` for a subscription that opted in with
|
|
42
|
+
* {@link SubscribeOutputOptions.includeReplay}.
|
|
43
|
+
*/
|
|
44
|
+
replay: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for {@link TerminalService.subscribeOutput} and
|
|
48
|
+
* {@link TerminalService.subscribeOsc}.
|
|
49
|
+
*
|
|
50
|
+
* @category Consumer Services
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export interface SubscribeOutputOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Deliver the scrollback the session host replays when re-attaching to a
|
|
56
|
+
* terminal, in addition to live output. Defaults to `false`.
|
|
57
|
+
*
|
|
58
|
+
* Leave it off for anything that reads output as *activity* — "the agent is
|
|
59
|
+
* working", "something just happened", a notification — because replayed
|
|
60
|
+
* bytes would fire all of it for events that are already over.
|
|
61
|
+
*
|
|
62
|
+
* Turn it on for anything that needs the terminal's *history*: rendering the
|
|
63
|
+
* scrollback, or identifying which program is running in a terminal you have
|
|
64
|
+
* only just attached to. Each chunk then arrives with an
|
|
65
|
+
* {@link OutputOrigin} saying which kind it is.
|
|
66
|
+
*/
|
|
67
|
+
includeReplay?: boolean;
|
|
68
|
+
}
|
|
24
69
|
export type { TerminalKind, TerminalRecord } from "./domain-types.js";
|
|
25
70
|
/**
|
|
26
71
|
* @deprecated Prefer {@link TerminalService.setIndicator} /
|
|
@@ -214,8 +259,16 @@ export interface TerminalService extends TabAdornmentMethods {
|
|
|
214
259
|
* });
|
|
215
260
|
* ctx.subscriptions.push(sub);
|
|
216
261
|
* ```
|
|
262
|
+
*
|
|
263
|
+
* @remarks
|
|
264
|
+
* OSC sequences ride the raw output stream, so the same replay rule applies
|
|
265
|
+
* as for {@link TerminalService.subscribeOutput}: by default only sequences
|
|
266
|
+
* from **live** output are delivered, and `{ includeReplay: true }` adds
|
|
267
|
+
* those found in the scrollback replayed on attach. Status titles are the
|
|
268
|
+
* usual reason to leave it off — a replayed "busy" title describes a turn
|
|
269
|
+
* that is already over.
|
|
217
270
|
*/
|
|
218
|
-
subscribeOsc(terminalId: string, handler: (event: OscEvent) => void): Disposable;
|
|
271
|
+
subscribeOsc(terminalId: string, handler: (event: OscEvent, origin: OutputOrigin) => void, options?: SubscribeOutputOptions): Disposable;
|
|
219
272
|
/**
|
|
220
273
|
* Subscribe to the raw PTY output stream of the terminal identified by
|
|
221
274
|
* `terminalId`. The `handler` is called with every chunk of bytes the PTY
|
|
@@ -232,19 +285,42 @@ export interface TerminalService extends TabAdornmentMethods {
|
|
|
232
285
|
* not the underlying PTY session id, so it survives terminal recreation within
|
|
233
286
|
* the same record.
|
|
234
287
|
*
|
|
288
|
+
* By default only **live** output is delivered. A terminal session outlives
|
|
289
|
+
* the app, so attaching to one replays its recent scrollback; without this
|
|
290
|
+
* default every reattach would look like a burst of activity happening right
|
|
291
|
+
* now. Pass `{ includeReplay: true }` to receive that history too — each
|
|
292
|
+
* chunk then arrives with an {@link OutputOrigin} saying which kind it is.
|
|
293
|
+
*
|
|
235
294
|
* Returns a {@link Disposable} that cancels the subscription.
|
|
236
295
|
*
|
|
237
296
|
* @example
|
|
238
297
|
* ```ts
|
|
239
298
|
* // Track the last time any output arrived to confirm agent activity.
|
|
299
|
+
* // Replayed scrollback is excluded by default, so re-attaching to a
|
|
300
|
+
* // long-idle terminal doesn't read as fresh activity.
|
|
240
301
|
* let lastOutputAt = 0;
|
|
241
302
|
* const sub = ctx.terminals.subscribeOutput(terminalId, () => {
|
|
242
303
|
* lastOutputAt = Date.now();
|
|
243
304
|
* });
|
|
244
305
|
* ctx.subscriptions.push(sub);
|
|
245
306
|
* ```
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```ts
|
|
310
|
+
* // Opt in to the replayed scrollback — needed to work out what is running
|
|
311
|
+
* // in a terminal you just attached to — and keep the two apart.
|
|
312
|
+
* const sub = ctx.terminals.subscribeOutput(
|
|
313
|
+
* terminalId,
|
|
314
|
+
* (chunk, { replay }) => {
|
|
315
|
+
* identifyProgram(chunk); // history is evidence
|
|
316
|
+
* if (!replay) noteActivity(); // …but only live output is activity
|
|
317
|
+
* },
|
|
318
|
+
* { includeReplay: true },
|
|
319
|
+
* );
|
|
320
|
+
* ctx.subscriptions.push(sub);
|
|
321
|
+
* ```
|
|
246
322
|
*/
|
|
247
|
-
subscribeOutput(terminalId: string, handler: (data: string) => void): Disposable;
|
|
323
|
+
subscribeOutput(terminalId: string, handler: (data: string, origin: OutputOrigin) => void, options?: SubscribeOutputOptions): Disposable;
|
|
248
324
|
/**
|
|
249
325
|
* The record id of the terminal tab that is currently active in the active
|
|
250
326
|
* workspace's center dock, or `null` when an editor tab (or nothing) is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-service.d.ts","sourceRoot":"","sources":["../src/terminal-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,QAAQ;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC5C,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAAC;CAC3D;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,eAAgB,SAAQ,mBAAmB;IAC1D;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,mBAAmB,GAAG,cAAc,GAAG,SAAS,CAAC;IAChE;;;;OAIG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1C;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEvE;;;;OAIG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;;;OAKG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/C;;;OAGG;IACH;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IAEjD,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,EAAE,6BAA6B,GAAG,UAAU,CAAC;IAE3E;;;OAGG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAAC;IAEnE;;OAEG;IACH,wBAAwB,IAAI,IAAI,CAAC;IAEjC;;OAEG;IACH,uBAAuB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC;IAE1D
|
|
1
|
+
{"version":3,"file":"terminal-service.d.ts","sourceRoot":"","sources":["../src/terminal-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/ActivityGlyph.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { HTMLAttributes } from "react";
|
|
1
|
+
import type { CSSProperties, HTMLAttributes } from "react";
|
|
2
2
|
import {
|
|
3
3
|
activityClass,
|
|
4
|
+
activityJitterStyle,
|
|
4
5
|
type Activity as ActivityKind,
|
|
5
6
|
type ActivitySize,
|
|
6
7
|
} from "./activity";
|
|
@@ -13,10 +14,14 @@ import {
|
|
|
13
14
|
* Styled purely via host-provided `.silo-activity*` classes — no stylesheet
|
|
14
15
|
* import is needed in the extension.
|
|
15
16
|
*
|
|
17
|
+
* Pass `jitterKey` whenever several animated glyphs render together (a list of
|
|
18
|
+
* agent or workspace rows) so their pulses don't run in lockstep — and so each
|
|
19
|
+
* one starts mid-cycle instead of freezing on first paint.
|
|
20
|
+
*
|
|
16
21
|
* @example
|
|
17
22
|
* ```tsx
|
|
18
23
|
* <ActivityGlyph activity="working" size="md" />
|
|
19
|
-
* <ActivityGlyph activity="ready" />
|
|
24
|
+
* <ActivityGlyph activity="ready" jitterKey={row.id} />
|
|
20
25
|
* <ActivityGlyph size="sm" /> // workspace neutral (omit)
|
|
21
26
|
* ```
|
|
22
27
|
*
|
|
@@ -27,15 +32,31 @@ export function ActivityGlyph({
|
|
|
27
32
|
activity,
|
|
28
33
|
size = "sm",
|
|
29
34
|
className,
|
|
35
|
+
jitterKey,
|
|
36
|
+
style,
|
|
30
37
|
...rest
|
|
31
38
|
}: {
|
|
32
39
|
activity?: ActivityKind;
|
|
33
40
|
size?: ActivitySize;
|
|
41
|
+
/**
|
|
42
|
+
* Stable id (a row or terminal id — never an array index) that gives this
|
|
43
|
+
* glyph a deterministic per-instance animation offset. Desynchronizes its
|
|
44
|
+
* pulse from other glyphs rendered alongside it, and makes the animation
|
|
45
|
+
* mount already in progress rather than pausing on first paint (a WebKit
|
|
46
|
+
* quirk when the glyph appears inside a just-shown container). Inert on
|
|
47
|
+
* non-animated glyphs.
|
|
48
|
+
*/
|
|
49
|
+
jitterKey?: string;
|
|
34
50
|
} & Omit<HTMLAttributes<HTMLSpanElement>, "children">) {
|
|
35
51
|
const classes = activityClass(activity, size);
|
|
52
|
+
const mergedStyle =
|
|
53
|
+
jitterKey != null
|
|
54
|
+
? ({ ...activityJitterStyle(jitterKey), ...style } as CSSProperties)
|
|
55
|
+
: style;
|
|
36
56
|
return (
|
|
37
57
|
<span
|
|
38
58
|
className={className ? `${classes} ${className}` : classes}
|
|
59
|
+
style={mergedStyle}
|
|
39
60
|
aria-hidden={rest["aria-label"] == null ? true : undefined}
|
|
40
61
|
{...rest}
|
|
41
62
|
/>
|
package/src/activity.test.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
activityClass,
|
|
4
|
+
activityFromAgent,
|
|
5
|
+
activityJitterStyle,
|
|
6
|
+
} from "./activity";
|
|
3
7
|
|
|
4
8
|
describe("activityClass", () => {
|
|
5
9
|
it("maps kinds and sizes", () => {
|
|
@@ -33,3 +37,32 @@ describe("activityFromAgent", () => {
|
|
|
33
37
|
expect(activityFromAgent("dead")).toBeNull();
|
|
34
38
|
});
|
|
35
39
|
});
|
|
40
|
+
|
|
41
|
+
describe("activityJitterStyle", () => {
|
|
42
|
+
const delay = (key: string) =>
|
|
43
|
+
Number.parseFloat(activityJitterStyle(key)["--silo-activity-jitter"]);
|
|
44
|
+
|
|
45
|
+
it("is deterministic for a given key", () => {
|
|
46
|
+
expect(activityJitterStyle("term-42")).toEqual(
|
|
47
|
+
activityJitterStyle("term-42"),
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("spreads different keys across the cycle", () => {
|
|
52
|
+
const keys = ["a", "b", "c", "d", "e", "term-1", "ws:build", "term-2"];
|
|
53
|
+
const delays = keys.map(delay);
|
|
54
|
+
// Not all landing on the same offset (the lockstep bug).
|
|
55
|
+
expect(new Set(delays).size).toBeGreaterThan(1);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("emits a negative delay within one animation period", () => {
|
|
59
|
+
for (const key of ["", "x", "a-very-long-stable-row-identifier", "ws:1"]) {
|
|
60
|
+
const d = delay(key);
|
|
61
|
+
expect(d).toBeLessThanOrEqual(0);
|
|
62
|
+
expect(d).toBeGreaterThan(-1.8);
|
|
63
|
+
expect(activityJitterStyle(key)["--silo-activity-jitter"]).toMatch(
|
|
64
|
+
/^-?\d+\.\d{3}s$/,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
package/src/activity.ts
CHANGED
|
@@ -11,8 +11,11 @@ import type { AgentActivity } from "./agents-service";
|
|
|
11
11
|
export type Activity = "working" | "ready" | "warn" | "error";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Glyph size for {@link Activity}. `"sm"`
|
|
15
|
-
*
|
|
14
|
+
* Glyph size for {@link Activity}. `"sm"` (8px at the default `uiFontSize`) is
|
|
15
|
+
* the workbench size — workspace status rows and CenterDock / SideDock tabs;
|
|
16
|
+
* `"md"` (10px) is the roomier one, for a list that leads with the dot rather
|
|
17
|
+
* than tucking it into chrome. Both scale with `uiFontSize` rather than being
|
|
18
|
+
* fixed pixels.
|
|
16
19
|
*
|
|
17
20
|
* @category Core Types
|
|
18
21
|
* @public
|
|
@@ -55,3 +58,35 @@ export function activityClass(
|
|
|
55
58
|
const kind = activity ?? "none";
|
|
56
59
|
return `silo-activity silo-activity-${kind} silo-activity-${size}`;
|
|
57
60
|
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Deterministic per-instance `animation-delay` (via the `--silo-activity-jitter`
|
|
64
|
+
* custom property) for an animated {@link Activity} glyph, keyed off a stable id
|
|
65
|
+
* — a row or terminal id, not an array index. Two purposes:
|
|
66
|
+
*
|
|
67
|
+
* - **Desync.** Several `working` / `ready` glyphs rendered side by side would
|
|
68
|
+
* otherwise pulse in perfect lockstep; a per-id offset staggers them.
|
|
69
|
+
* - **Start mid-cycle.** The value is a *negative* delay, so the animation
|
|
70
|
+
* mounts already in progress rather than pausing on first paint — a WebKit
|
|
71
|
+
* quirk that bites when the glyph is created inside a container that was
|
|
72
|
+
* `display: none` moments earlier (e.g. a Navigator view on its first
|
|
73
|
+
* activation), where a zero delay can leave the pulse frozen until the next
|
|
74
|
+
* show/hide toggle.
|
|
75
|
+
*
|
|
76
|
+
* Hashed rather than random so the offset is stable across re-renders. Pinned
|
|
77
|
+
* by unit tests.
|
|
78
|
+
*
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
export function activityJitterStyle(
|
|
82
|
+
key: string,
|
|
83
|
+
): Record<"--silo-activity-jitter", string> {
|
|
84
|
+
let hash = 0;
|
|
85
|
+
for (let i = 0; i < key.length; i++) {
|
|
86
|
+
hash = (hash * 31 + key.charCodeAt(i)) | 0;
|
|
87
|
+
}
|
|
88
|
+
// 1.8s is the longest activity animation period (`silo-activity-wave`), so the
|
|
89
|
+
// offset spans one full cycle.
|
|
90
|
+
const delaySeconds = -(((hash >>> 0) % 1000) / 1000) * 1.8;
|
|
91
|
+
return { "--silo-activity-jitter": `${delaySeconds.toFixed(3)}s` };
|
|
92
|
+
}
|
package/src/agents-service.ts
CHANGED
|
@@ -172,6 +172,187 @@ export interface CatalogAgentSummary {
|
|
|
172
172
|
readonly icon?: AgentIcon;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/**
|
|
176
|
+
* One **Agent Profile** as an extension may read it through
|
|
177
|
+
* {@link AgentProfilesService.list} — a named recipe for starting a coding
|
|
178
|
+
* agent in a terminal, defined by the user on Settings → Agents → Profiles.
|
|
179
|
+
* Deliberately a summary, never the host's own profile record: the command
|
|
180
|
+
* line, its config directory, and every other launch detail stay host-owned
|
|
181
|
+
* (RFC 0033).
|
|
182
|
+
*
|
|
183
|
+
* @category Consumer Services
|
|
184
|
+
* @public
|
|
185
|
+
* @beta
|
|
186
|
+
*/
|
|
187
|
+
export interface AgentProfileSummary {
|
|
188
|
+
/** Stable id — pass it to {@link AgentProfilesService.launch}. */
|
|
189
|
+
readonly id: string;
|
|
190
|
+
/** The user's own name for this profile, e.g. `"Claude (work)"`. Show this;
|
|
191
|
+
* never show or parse the id. */
|
|
192
|
+
readonly label: string;
|
|
193
|
+
/** True for the single profile marked default, which is what `launch()`
|
|
194
|
+
* starts when no `profileId` is given. False for every profile when the
|
|
195
|
+
* user has not chosen one. */
|
|
196
|
+
readonly isDefault: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Whether this profile's agent can be given an **opening prompt**. A static
|
|
199
|
+
* fact about the agent, not about any particular launch — so a picker can
|
|
200
|
+
* grey out or annotate a profile up front instead of discovering
|
|
201
|
+
* `"agent-takes-none"` after the user has already typed one.
|
|
202
|
+
*/
|
|
203
|
+
readonly acceptsPrompt: boolean;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Why an opening prompt could not be delivered. Silo refuses rather than
|
|
208
|
+
* approximating: a prompt it cannot quote exactly is never typed, and no agent
|
|
209
|
+
* is started without the prompt the caller asked for.
|
|
210
|
+
*
|
|
211
|
+
* @category Consumer Services
|
|
212
|
+
* @public
|
|
213
|
+
* @beta
|
|
214
|
+
*/
|
|
215
|
+
export type PromptRefusal =
|
|
216
|
+
/** The profile matches no agent Silo knows, so there is no way to tell how
|
|
217
|
+
* its CLI takes a prompt. The user can fix this by setting the agent on the
|
|
218
|
+
* profile. */
|
|
219
|
+
| "no-agent"
|
|
220
|
+
/** The profile's agent has no way to accept an opening prompt while staying
|
|
221
|
+
* interactive. Check {@link AgentProfileSummary.acceptsPrompt} first to
|
|
222
|
+
* avoid offering a prompt for such a profile at all. */
|
|
223
|
+
| "agent-takes-none"
|
|
224
|
+
/** Silo has no exact quoting rule for the shell this terminal would run and
|
|
225
|
+
* will not guess one. bash, zsh, and fish are supported. */
|
|
226
|
+
| "unsupported-shell"
|
|
227
|
+
/**
|
|
228
|
+
* The prompt exceeds Silo's 2 KiB limit — roughly a page of prose.
|
|
229
|
+
*
|
|
230
|
+
* The ceiling is low because the prompt is *typed* into the user's shell,
|
|
231
|
+
* and a shell with syntax highlighting or autosuggestions cannot reliably
|
|
232
|
+
* consume more than a few KiB in one go. Silo refuses well short of where
|
|
233
|
+
* delivery starts failing, because a truncated prompt would reach the agent
|
|
234
|
+
* looking complete. Trim it and retry.
|
|
235
|
+
*/
|
|
236
|
+
| "too-large";
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Options for {@link AgentProfilesService.launch}. Every field is optional —
|
|
240
|
+
* a bare `launch()` starts the default profile in the active workspace.
|
|
241
|
+
*
|
|
242
|
+
* @category Consumer Services
|
|
243
|
+
* @public
|
|
244
|
+
* @beta
|
|
245
|
+
*/
|
|
246
|
+
export interface LaunchAgentProfileOptions {
|
|
247
|
+
/** Which profile to start. Defaults to the one marked default, else the
|
|
248
|
+
* first — the same profile the built-in "New Agent" command uses. */
|
|
249
|
+
profileId?: string;
|
|
250
|
+
/** Which workspace to start it in. Defaults to the active one. A
|
|
251
|
+
* background workspace works: the session is spawned eagerly, since no
|
|
252
|
+
* panel will mount to do it. */
|
|
253
|
+
workspaceId?: string;
|
|
254
|
+
/** Working directory for the new terminal. Defaults to the workspace folder. */
|
|
255
|
+
cwd?: string;
|
|
256
|
+
/**
|
|
257
|
+
* An opening prompt to hand the agent on its launch line.
|
|
258
|
+
*
|
|
259
|
+
* The text is delivered as a literal — it is never interpreted by the
|
|
260
|
+
* shell, so `$HOME`, backticks, quotes, and newlines are all safe. If Silo
|
|
261
|
+
* cannot deliver it exactly, the launch is **refused** rather than mangled
|
|
262
|
+
* or silently dropped: nothing is typed, no terminal is created, and
|
|
263
|
+
* `launch()` returns the reason.
|
|
264
|
+
*
|
|
265
|
+
* Keep it to an opening instruction. The limit is **2 KiB** — about a page —
|
|
266
|
+
* and anything longer is refused with `"too-large"`; see that member for
|
|
267
|
+
* why the ceiling is where it is.
|
|
268
|
+
*
|
|
269
|
+
* The composed line is typed into the user's own interactive shell, so it
|
|
270
|
+
* appears in scrollback and in shell history exactly as if they had typed
|
|
271
|
+
* it. Don't put a secret in one.
|
|
272
|
+
*/
|
|
273
|
+
prompt?: string;
|
|
274
|
+
/**
|
|
275
|
+
* Activate the target workspace and focus the new terminal. Defaults to
|
|
276
|
+
* `true`. Pass `false` to start an agent without stealing the user's place.
|
|
277
|
+
*/
|
|
278
|
+
activate?: boolean;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* What {@link AgentProfilesService.launch} did. A **result**, never a throw:
|
|
283
|
+
* every foreseeable reason a launch cannot happen is a value you can branch
|
|
284
|
+
* on and report to your own user.
|
|
285
|
+
*
|
|
286
|
+
* @category Consumer Services
|
|
287
|
+
* @public
|
|
288
|
+
* @beta
|
|
289
|
+
*/
|
|
290
|
+
export type LaunchAgentProfileResult =
|
|
291
|
+
| {
|
|
292
|
+
readonly ok: true;
|
|
293
|
+
/** The created terminal's record id — the same id
|
|
294
|
+
* {@link AgentsService.getByTerminalId} and `ctx.terminals` take. */
|
|
295
|
+
readonly terminalId: string;
|
|
296
|
+
}
|
|
297
|
+
| {
|
|
298
|
+
readonly ok: false;
|
|
299
|
+
/** Why nothing was launched. `"no-profile"` — the named profile does
|
|
300
|
+
* not exist, or there are no profiles at all. `"no-workspace"` — the
|
|
301
|
+
* named workspace does not exist, or none is open. Otherwise one of the
|
|
302
|
+
* {@link PromptRefusal} reasons. */
|
|
303
|
+
readonly refusal: PromptRefusal | "no-profile" | "no-workspace";
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Read the user's **Agent Profiles** and start one, optionally with an opening
|
|
308
|
+
* prompt — exposed as `ctx.agents.profiles` (RFC 0033).
|
|
309
|
+
*
|
|
310
|
+
* A profile is a way to *start* a terminal, not a way to talk to an agent:
|
|
311
|
+
* what comes up is a PTY running a real agent CLI, exactly as if the user had
|
|
312
|
+
* typed the command themselves. There is no agent-agnostic messaging layer
|
|
313
|
+
* here and there is not meant to be one.
|
|
314
|
+
*
|
|
315
|
+
* There is deliberately no `pick()` — build one from `list()` and
|
|
316
|
+
* `ctx.ui.showMenu`, which is the shared chrome — and no `get()`, which is
|
|
317
|
+
* `list().find()`.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```ts
|
|
321
|
+
* // Let the user choose a profile, then start it on a task.
|
|
322
|
+
* const profiles = ctx.agents.profiles.list();
|
|
323
|
+
* const chosen = await ctx.ui.showMenu(
|
|
324
|
+
* profiles.map((p) => ({ id: p.id, label: p.label })),
|
|
325
|
+
* );
|
|
326
|
+
* if (chosen) {
|
|
327
|
+
* const result = ctx.agents.profiles.launch({
|
|
328
|
+
* profileId: chosen,
|
|
329
|
+
* prompt: "Fix the failing test in src/foo.test.ts",
|
|
330
|
+
* });
|
|
331
|
+
* if (!result.ok) ctx.ui.notify("warn", `Couldn't start it: ${result.refusal}`);
|
|
332
|
+
* }
|
|
333
|
+
* ```
|
|
334
|
+
*
|
|
335
|
+
* @category Consumer Services
|
|
336
|
+
* @public
|
|
337
|
+
* @beta
|
|
338
|
+
*/
|
|
339
|
+
export interface AgentProfilesService {
|
|
340
|
+
/**
|
|
341
|
+
* Every Agent Profile the user has defined, in the order they appear in
|
|
342
|
+
* Settings. The returned array is **read-only and deeply frozen**; it is
|
|
343
|
+
* recomputed when the profile list changes, not on every call.
|
|
344
|
+
*/
|
|
345
|
+
list(): readonly AgentProfileSummary[];
|
|
346
|
+
/**
|
|
347
|
+
* Start a profile in a terminal. Returns the created terminal's id, or a
|
|
348
|
+
* typed refusal — see {@link LaunchAgentProfileResult}.
|
|
349
|
+
*
|
|
350
|
+
* A refused prompt creates nothing at all: no terminal record, no workspace
|
|
351
|
+
* activation, no focus change.
|
|
352
|
+
*/
|
|
353
|
+
launch(options?: LaunchAgentProfileOptions): LaunchAgentProfileResult;
|
|
354
|
+
}
|
|
355
|
+
|
|
175
356
|
/**
|
|
176
357
|
* Host-computed coding-agent observability — exposed as
|
|
177
358
|
* {@link ExtensionContext.agents}. Detection (what OSC/output signals mean
|
|
@@ -250,4 +431,13 @@ export interface AgentsService {
|
|
|
250
431
|
* @public
|
|
251
432
|
*/
|
|
252
433
|
catalog(): readonly CatalogAgentSummary[];
|
|
434
|
+
/**
|
|
435
|
+
* The user's **Agent Profiles** — read them, and start one, optionally with
|
|
436
|
+
* an opening prompt. See {@link AgentProfilesService}.
|
|
437
|
+
*
|
|
438
|
+
* @category Consumer Services
|
|
439
|
+
* @public
|
|
440
|
+
* @beta
|
|
441
|
+
*/
|
|
442
|
+
readonly profiles: AgentProfilesService;
|
|
253
443
|
}
|
package/src/index.ts
CHANGED
|
@@ -110,6 +110,11 @@ export type {
|
|
|
110
110
|
AgentIcon,
|
|
111
111
|
AgentIconMode,
|
|
112
112
|
CatalogAgentSummary,
|
|
113
|
+
AgentProfilesService,
|
|
114
|
+
AgentProfileSummary,
|
|
115
|
+
LaunchAgentProfileOptions,
|
|
116
|
+
LaunchAgentProfileResult,
|
|
117
|
+
PromptRefusal,
|
|
113
118
|
} from "./agents-service";
|
|
114
119
|
export type {
|
|
115
120
|
TerminalService,
|
|
@@ -119,6 +124,8 @@ export type {
|
|
|
119
124
|
TerminalTabDecoration,
|
|
120
125
|
TerminalTabDecorationProvider,
|
|
121
126
|
OscEvent,
|
|
127
|
+
OutputOrigin,
|
|
128
|
+
SubscribeOutputOptions,
|
|
122
129
|
} from "./terminal-service";
|
|
123
130
|
export type {
|
|
124
131
|
TabAdornmentColor,
|
package/src/process-service.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Disposable } from "./types";
|
|
2
|
+
import type { OutputOrigin, SubscribeOutputOptions } from "./terminal-service";
|
|
2
3
|
|
|
3
4
|
// `ctx.process` — persistent process / PTY sessions that survive app restarts.
|
|
4
5
|
// The core primitive under the terminal (and future task runners / REPLs).
|
|
@@ -59,8 +60,20 @@ export interface ProcessSession {
|
|
|
59
60
|
getBuffer(): Promise<string>;
|
|
60
61
|
/** Persist an output buffer for later restore. */
|
|
61
62
|
saveBuffer(data: string): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Subscribe to output data. Dispose to stop listening.
|
|
65
|
+
*
|
|
66
|
+
* By default only **live** output is delivered. A session survives app
|
|
67
|
+
* restarts, so re-attaching to one replays its recent scrollback; delivering
|
|
68
|
+
* that by default would make every reattach look like a burst of output
|
|
69
|
+
* arriving right now. Pass `{ includeReplay: true }` to receive the replayed
|
|
70
|
+
* history too — for instance to paint scrollback into a fresh view — and read
|
|
71
|
+
* `origin.replay` to tell the two apart.
|
|
72
|
+
*/
|
|
73
|
+
onData(
|
|
74
|
+
listener: (data: string, origin: OutputOrigin) => void,
|
|
75
|
+
options?: SubscribeOutputOptions,
|
|
76
|
+
): Disposable;
|
|
64
77
|
/** Subscribe to session exit. Dispose to stop listening. */
|
|
65
78
|
onExit(listener: (exitCode: number) => void): Disposable;
|
|
66
79
|
}
|
package/src/terminal-service.ts
CHANGED
|
@@ -26,6 +26,53 @@ export interface OscEvent {
|
|
|
26
26
|
payload: string;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Where a chunk of terminal output came from in time.
|
|
31
|
+
*
|
|
32
|
+
* A terminal session outlives the app, so re-attaching to one replays the
|
|
33
|
+
* session host's recent scrollback — bytes that are byte-for-byte identical to
|
|
34
|
+
* live output but describe things that already happened, sometimes long ago.
|
|
35
|
+
* Treating them as live is what makes a reattached agent terminal announce a
|
|
36
|
+
* turn that finished before the app started.
|
|
37
|
+
*
|
|
38
|
+
* @category Consumer Services
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export interface OutputOrigin {
|
|
42
|
+
/**
|
|
43
|
+
* `true` when the chunk is scrollback the session host is replaying on
|
|
44
|
+
* attach, `false` when the session produced it just now.
|
|
45
|
+
*
|
|
46
|
+
* Only ever `true` for a subscription that opted in with
|
|
47
|
+
* {@link SubscribeOutputOptions.includeReplay}.
|
|
48
|
+
*/
|
|
49
|
+
replay: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Options for {@link TerminalService.subscribeOutput} and
|
|
54
|
+
* {@link TerminalService.subscribeOsc}.
|
|
55
|
+
*
|
|
56
|
+
* @category Consumer Services
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export interface SubscribeOutputOptions {
|
|
60
|
+
/**
|
|
61
|
+
* Deliver the scrollback the session host replays when re-attaching to a
|
|
62
|
+
* terminal, in addition to live output. Defaults to `false`.
|
|
63
|
+
*
|
|
64
|
+
* Leave it off for anything that reads output as *activity* — "the agent is
|
|
65
|
+
* working", "something just happened", a notification — because replayed
|
|
66
|
+
* bytes would fire all of it for events that are already over.
|
|
67
|
+
*
|
|
68
|
+
* Turn it on for anything that needs the terminal's *history*: rendering the
|
|
69
|
+
* scrollback, or identifying which program is running in a terminal you have
|
|
70
|
+
* only just attached to. Each chunk then arrives with an
|
|
71
|
+
* {@link OutputOrigin} saying which kind it is.
|
|
72
|
+
*/
|
|
73
|
+
includeReplay?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
29
76
|
// Re-export the terminal domain types so consumers can name them from the SDK.
|
|
30
77
|
export type { TerminalKind, TerminalRecord } from "./domain-types";
|
|
31
78
|
|
|
@@ -234,10 +281,19 @@ export interface TerminalService extends TabAdornmentMethods {
|
|
|
234
281
|
* });
|
|
235
282
|
* ctx.subscriptions.push(sub);
|
|
236
283
|
* ```
|
|
284
|
+
*
|
|
285
|
+
* @remarks
|
|
286
|
+
* OSC sequences ride the raw output stream, so the same replay rule applies
|
|
287
|
+
* as for {@link TerminalService.subscribeOutput}: by default only sequences
|
|
288
|
+
* from **live** output are delivered, and `{ includeReplay: true }` adds
|
|
289
|
+
* those found in the scrollback replayed on attach. Status titles are the
|
|
290
|
+
* usual reason to leave it off — a replayed "busy" title describes a turn
|
|
291
|
+
* that is already over.
|
|
237
292
|
*/
|
|
238
293
|
subscribeOsc(
|
|
239
294
|
terminalId: string,
|
|
240
|
-
handler: (event: OscEvent) => void,
|
|
295
|
+
handler: (event: OscEvent, origin: OutputOrigin) => void,
|
|
296
|
+
options?: SubscribeOutputOptions,
|
|
241
297
|
): Disposable;
|
|
242
298
|
|
|
243
299
|
/**
|
|
@@ -256,21 +312,45 @@ export interface TerminalService extends TabAdornmentMethods {
|
|
|
256
312
|
* not the underlying PTY session id, so it survives terminal recreation within
|
|
257
313
|
* the same record.
|
|
258
314
|
*
|
|
315
|
+
* By default only **live** output is delivered. A terminal session outlives
|
|
316
|
+
* the app, so attaching to one replays its recent scrollback; without this
|
|
317
|
+
* default every reattach would look like a burst of activity happening right
|
|
318
|
+
* now. Pass `{ includeReplay: true }` to receive that history too — each
|
|
319
|
+
* chunk then arrives with an {@link OutputOrigin} saying which kind it is.
|
|
320
|
+
*
|
|
259
321
|
* Returns a {@link Disposable} that cancels the subscription.
|
|
260
322
|
*
|
|
261
323
|
* @example
|
|
262
324
|
* ```ts
|
|
263
325
|
* // Track the last time any output arrived to confirm agent activity.
|
|
326
|
+
* // Replayed scrollback is excluded by default, so re-attaching to a
|
|
327
|
+
* // long-idle terminal doesn't read as fresh activity.
|
|
264
328
|
* let lastOutputAt = 0;
|
|
265
329
|
* const sub = ctx.terminals.subscribeOutput(terminalId, () => {
|
|
266
330
|
* lastOutputAt = Date.now();
|
|
267
331
|
* });
|
|
268
332
|
* ctx.subscriptions.push(sub);
|
|
269
333
|
* ```
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```ts
|
|
337
|
+
* // Opt in to the replayed scrollback — needed to work out what is running
|
|
338
|
+
* // in a terminal you just attached to — and keep the two apart.
|
|
339
|
+
* const sub = ctx.terminals.subscribeOutput(
|
|
340
|
+
* terminalId,
|
|
341
|
+
* (chunk, { replay }) => {
|
|
342
|
+
* identifyProgram(chunk); // history is evidence
|
|
343
|
+
* if (!replay) noteActivity(); // …but only live output is activity
|
|
344
|
+
* },
|
|
345
|
+
* { includeReplay: true },
|
|
346
|
+
* );
|
|
347
|
+
* ctx.subscriptions.push(sub);
|
|
348
|
+
* ```
|
|
270
349
|
*/
|
|
271
350
|
subscribeOutput(
|
|
272
351
|
terminalId: string,
|
|
273
|
-
handler: (data: string) => void,
|
|
352
|
+
handler: (data: string, origin: OutputOrigin) => void,
|
|
353
|
+
options?: SubscribeOutputOptions,
|
|
274
354
|
): Disposable;
|
|
275
355
|
|
|
276
356
|
/**
|