@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.
@@ -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,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAEL,KAAK,QAAQ,IAAI,YAAY,EAC7B,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAW,EACX,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,+BASpD"}
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"}
@@ -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
- return (_jsx("span", { className: className ? `${classes} ${className}` : classes, "aria-hidden": rest["aria-label"] == null ? true : undefined, ...rest }));
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,GAGd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,SAAS,EACT,GAAG,IAAI,EAI4C;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,CACL,eACE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,iBAC7C,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KACtD,IAAI,GACR,CACH,CAAC;AACJ,CAAC"}
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"}
@@ -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"` matches workspace status rows (~6px);
13
- * `"md"` is slightly larger for CenterDock / SideDock tabs.
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
@@ -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;;;;;;GAMG;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"}
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
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAqBA;;;;;;;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"}
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"}
@@ -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;CAC3C"}
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";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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;AA6HH,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
+ {"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
- /** Subscribe to output data. Dispose to stop listening. */
58
- onData(listener: (data: string) => void): Disposable;
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;AAK1C;;;;;;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,2DAA2D;IAC3D,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;IACrD,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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,YAAY,CACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GACjC,UAAU,CAAC;IAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,eAAe,CACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC9B,UAAU,CAAC;IAEd;;;;;;OAMG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAE3B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,UAAU,CAAC;CAC5E"}
1
+ {"version":3,"file":"terminal-service.d.ts","sourceRoot":"","sources":["../src/terminal-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silo-code/sdk",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "The public, types-first SDK for building Silo extensions — the only surface third-party extensions import.",
5
5
  "license": "MIT",
6
6
  "author": "Dave Weaver",
@@ -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
  />
@@ -1,5 +1,9 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { activityClass, activityFromAgent } from "./activity";
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"` matches workspace status rows (~6px);
15
- * `"md"` is slightly larger for CenterDock / SideDock tabs.
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
+ }
@@ -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,
@@ -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
- /** Subscribe to output data. Dispose to stop listening. */
63
- onData(listener: (data: string) => void): Disposable;
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
  }
@@ -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
  /**