@av-pi-studio/client 0.0.110 → 0.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
- import type { AgentCloneResponse, AgentCompactResponse, AgentCycleModelResponse, AgentExportHtmlResponse, AgentForkMessagesResponse, AgentForkResponse, AgentLastAssistantTextResponse, AgentListCommandsResponse, AgentNewSessionResponse, AgentSessionStatsResponse, AgentSetModelResponse, AgentSetSessionNameResponse, AgentSetThinkingResponse, AgentStreamEvent, AgentSwitchSessionResponse, AgentThinkingLevelsResponse, AgentUiPendingRequest, AgentUiRequest, AgentUiResolved, AgentUiResponse, AgentUiSurface, CreateAgentRequest, ExtensionPacksListResponse, ExtensionPacksSetResponse, FetchAgentTimelineResponse, ProviderAuthInfo, ProviderAuthType, SessionMessage, TimelineDirection, ViewerSettings, ViewerSettingsPatchEntry } from "@av-pi-studio/protocol";
1
+ import type { AgentCloneResponse, AgentCompactResponse, AgentCycleModelResponse, AgentExportHtmlResponse, AgentForkMessagesResponse, AgentForkResponse, AgentLastAssistantTextResponse, AgentListCommandsResponse, AgentNewSessionResponse, AgentSessionStatsResponse, AgentSetModelResponse, AgentSetSessionNameResponse, AgentSetThinkingResponse, AgentStreamEvent, AgentSwitchSessionResponse, AgentThinkingLevelsResponse, AgentUiPendingRequest, AgentUiRequest, AgentUiResolved, AgentUiResponse, AgentUiSurface, CreateAgentRequest, ExtensionPacksListResponse, ExtensionPacksSetResponse, FetchAgentTimelineResponse, ProviderAuthInfo, ProviderAuthType, SessionMessage, SkillsInstallResponse, SkillsListResponse, SkillsPreviewResponse, SkillsRemoveResponse, SkillsSetEnabledResponse, SkillsUpdateAllResponse, TimelineDirection, ViewerSettings, ViewerSettingsPatchEntry } from "@av-pi-studio/protocol";
2
2
  import type { DaemonClient } from "./daemon-client.js";
3
+ export { detectSkillSource } from "@av-pi-studio/protocol";
3
4
  /**
4
5
  * High-level `PiStudioClient` SDK facade over the low-level `DaemonClient` driver.
5
6
  *
@@ -22,6 +23,28 @@ import type { DaemonClient } from "./daemon-client.js";
22
23
  * this call (`rpcTimeoutMs ≠ socket death`); compaction progress keeps following the stream.
23
24
  */
24
25
  export declare const COMPACT_TIMEOUT_MS: number;
26
+ /**
27
+ * RPC timeout for `skills_remove_request`. The daemon bounds its own spawn at 600 s
28
+ * (`swe/architecture/pi-resource-management.md` § Timeouts); the SDK timeout is set above that so
29
+ * a slow `skills remove`/`pi remove` process reports its own `timeout` domain error before the
30
+ * client gives up and treats the socket as dead.
31
+ */
32
+ export declare const REMOVE_SKILL_TIMEOUT_MS: number;
33
+ /**
34
+ * RPC timeout for `skills_update_all_request`. Updates both engines (`agent-skills`, `pi-packages`)
35
+ * sequentially, each bounded at 600 s daemon-side; 1 300 s covers both spawns plus margin.
36
+ */
37
+ export declare const UPDATE_ALL_SKILLS_TIMEOUT_MS: number;
38
+ /**
39
+ * RPC timeout for `skills_preview_request`. The daemon bounds its own clone/fetch spawn at 120 s
40
+ * (`swe/architecture/pi-resource-management.md` § Timeouts); the SDK timeout is set above that.
41
+ */
42
+ export declare const PREVIEW_SKILL_SOURCE_TIMEOUT_MS: number;
43
+ /**
44
+ * RPC timeout for `skills_install_request`. The daemon bounds its own `pi install`/`skills add`
45
+ * spawn at 600 s; 660 s covers one spawn plus margin (same idiom as `REMOVE_SKILL_TIMEOUT_MS`).
46
+ */
47
+ export declare const INSTALL_SKILLS_TIMEOUT_MS: number;
25
48
  export type PiStudioAgentUpdateHandler = (update: AgentUpdateMessage) => void;
26
49
  export type PiStudioWorkspaceUpdateHandler = (update: WorkspaceUpdateMessage) => void;
27
50
  /** Metadata carried alongside a live `agent_stream` event (daemon-owned, not provider-replayed). */
@@ -484,6 +507,54 @@ export declare class PiStudioClient {
484
507
  * from "does this daemon speak the `agent_ui_*` RPC family at all".
485
508
  */
486
509
  extensionUiAvailable(): boolean;
510
+ /** True iff the daemon advertised the `skills` capability in `server_info.features`. */
511
+ hasSkillsCapability(): boolean;
512
+ /** Every resolved Agent Skill plus every resolved `settings.json` package — `skills_list_request`.
513
+ * A domain failure (e.g. unreadable `settings.json`) resolves `{ok:false, error}`, never throws. */
514
+ listSkills(): Promise<SkillsListResponse>;
515
+ /** Enables/disables one skill by path — `skills_set_enabled_request`. Resolves to the full
516
+ * post-mutation `{skills, packages}` document (domain `{ok:false}` on failure, never thrown). */
517
+ setSkillEnabled(path: string, enabled: boolean): Promise<SkillsSetEnabledResponse>;
518
+ /** Removes one top-level skill by `path`, or one `settings.json` package by `packageSource` —
519
+ * exactly one must be set — `skills_remove_request`. Resolves to the full post-mutation
520
+ * `{skills, packages}` document (domain `{ok:false, error}` on failure, never thrown); the
521
+ * daemon's own spawn bound is 600 s, so the SDK timeout (`REMOVE_SKILL_TIMEOUT_MS`) is set
522
+ * above that rather than the client's default. */
523
+ removeSkill(target: {
524
+ path: string;
525
+ packageSource?: undefined;
526
+ } | {
527
+ path?: undefined;
528
+ packageSource: string;
529
+ }): Promise<SkillsRemoveResponse>;
530
+ /** Updates every removable skill engine (`agent-skills` via `skills update -g -y`, `pi-packages`
531
+ * via `pi update --extensions`) — `skills_update_all_request`. Resolves to a per-engine
532
+ * `results: ItemResult[]` (a mixed ok/failed array is expected, not an overall failure) plus the
533
+ * full post-mutation `{skills, packages}` document. Both spawns are bounded at 600 s
534
+ * daemon-side; `UPDATE_ALL_SKILLS_TIMEOUT_MS` covers both plus margin. */
535
+ updateAllSkills(): Promise<SkillsUpdateAllResponse>;
536
+ /** Previews one install source's picklist before installing — `skills_preview_request`.
537
+ * `pi_npm`/`pi_git` always resolve `{ok:true, kind, source, skills: []}` (package kinds install
538
+ * as a unit, nothing to pick); `skills_repo`/`local_path` resolve the candidate `skills` array.
539
+ * Domain failure (e.g. `invalid_source`) resolves `{ok:false, error}`, never thrown; the daemon
540
+ * bounds its own clone/fetch spawn at 120 s, so `PREVIEW_SKILL_SOURCE_TIMEOUT_MS` (150 s) is set
541
+ * above that rather than the client's default. */
542
+ previewSkillSource(source: string): Promise<SkillsPreviewResponse>;
543
+ /** Installs one source — `skills_install_request`. `skills` is the picked names from a prior
544
+ * `previewSkillSource()` call (meaningful for `skills_repo` only; `pi_npm`/`pi_git` install
545
+ * every skill the package ships, `local_path` registers the whole folder); `replace` resends an
546
+ * already-installed picked name instead of excluding it as `name_exists`. Resolves one
547
+ * `ItemResult` per engine/picked-name outcome plus the full post-mutation `{skills, packages}`
548
+ * document (domain `{ok:false, error}` on failure, never thrown); the daemon's own spawn bound
549
+ * is 600 s, so `INSTALL_SKILLS_TIMEOUT_MS` (660 s) is set above that. */
550
+ installSkills(opts: {
551
+ source: string;
552
+ skills?: string[];
553
+ replace?: boolean;
554
+ }): Promise<SkillsInstallResponse>;
555
+ /** Subscribe to the daemon's `skills_changed` broadcast — fired after any mutation (this
556
+ * client's own or another's) or an external filesystem change the daemon detected. */
557
+ onSkillsChanged(handler: (reason: string) => void): () => void;
487
558
  }
488
559
  /** Convenience re-export of the import operation (not agent-scoped). */
489
560
  export declare function importAgentSession(daemon: DaemonClient, args: {
@@ -1,3 +1,6 @@
1
+ // Pure skill-install-source classifier (sprint-077/task-002, `@av-pi-studio/protocol`) —
2
+ // re-exported so the web client can classify a pasted source string without a round trip.
3
+ export { detectSkillSource } from "@av-pi-studio/protocol";
1
4
  /**
2
5
  * High-level `PiStudioClient` SDK facade over the low-level `DaemonClient` driver.
3
6
  *
@@ -20,6 +23,28 @@
20
23
  * this call (`rpcTimeoutMs ≠ socket death`); compaction progress keeps following the stream.
21
24
  */
22
25
  export const COMPACT_TIMEOUT_MS = 10 * 60_000;
26
+ /**
27
+ * RPC timeout for `skills_remove_request`. The daemon bounds its own spawn at 600 s
28
+ * (`swe/architecture/pi-resource-management.md` § Timeouts); the SDK timeout is set above that so
29
+ * a slow `skills remove`/`pi remove` process reports its own `timeout` domain error before the
30
+ * client gives up and treats the socket as dead.
31
+ */
32
+ export const REMOVE_SKILL_TIMEOUT_MS = 660 * 1000;
33
+ /**
34
+ * RPC timeout for `skills_update_all_request`. Updates both engines (`agent-skills`, `pi-packages`)
35
+ * sequentially, each bounded at 600 s daemon-side; 1 300 s covers both spawns plus margin.
36
+ */
37
+ export const UPDATE_ALL_SKILLS_TIMEOUT_MS = 1300 * 1000;
38
+ /**
39
+ * RPC timeout for `skills_preview_request`. The daemon bounds its own clone/fetch spawn at 120 s
40
+ * (`swe/architecture/pi-resource-management.md` § Timeouts); the SDK timeout is set above that.
41
+ */
42
+ export const PREVIEW_SKILL_SOURCE_TIMEOUT_MS = 150 * 1000;
43
+ /**
44
+ * RPC timeout for `skills_install_request`. The daemon bounds its own `pi install`/`skills add`
45
+ * spawn at 600 s; 660 s covers one spawn plus margin (same idiom as `REMOVE_SKILL_TIMEOUT_MS`).
46
+ */
47
+ export const INSTALL_SKILLS_TIMEOUT_MS = 660 * 1000;
23
48
  /** Narrows an inbound session message to the `provider_auth_flow_event` push. */
24
49
  export function isProviderAuthFlowEvent(message) {
25
50
  const m = message;
@@ -469,6 +494,67 @@ export class PiStudioClient {
469
494
  extensionUiAvailable() {
470
495
  return this.daemon.hasFeature("extensionUi");
471
496
  }
497
+ // ─── Skills (skills_*, sprint-075) ─────────────────────────────────────────
498
+ /** True iff the daemon advertised the `skills` capability in `server_info.features`. */
499
+ hasSkillsCapability() {
500
+ return this.daemon.hasFeature("skills");
501
+ }
502
+ /** Every resolved Agent Skill plus every resolved `settings.json` package — `skills_list_request`.
503
+ * A domain failure (e.g. unreadable `settings.json`) resolves `{ok:false, error}`, never throws. */
504
+ async listSkills() {
505
+ return this.daemon.request("skills_list_request", {});
506
+ }
507
+ /** Enables/disables one skill by path — `skills_set_enabled_request`. Resolves to the full
508
+ * post-mutation `{skills, packages}` document (domain `{ok:false}` on failure, never thrown). */
509
+ async setSkillEnabled(path, enabled) {
510
+ return this.daemon.request("skills_set_enabled_request", {
511
+ path,
512
+ enabled,
513
+ });
514
+ }
515
+ /** Removes one top-level skill by `path`, or one `settings.json` package by `packageSource` —
516
+ * exactly one must be set — `skills_remove_request`. Resolves to the full post-mutation
517
+ * `{skills, packages}` document (domain `{ok:false, error}` on failure, never thrown); the
518
+ * daemon's own spawn bound is 600 s, so the SDK timeout (`REMOVE_SKILL_TIMEOUT_MS`) is set
519
+ * above that rather than the client's default. */
520
+ async removeSkill(target) {
521
+ return this.daemon.request("skills_remove_request", target, REMOVE_SKILL_TIMEOUT_MS);
522
+ }
523
+ /** Updates every removable skill engine (`agent-skills` via `skills update -g -y`, `pi-packages`
524
+ * via `pi update --extensions`) — `skills_update_all_request`. Resolves to a per-engine
525
+ * `results: ItemResult[]` (a mixed ok/failed array is expected, not an overall failure) plus the
526
+ * full post-mutation `{skills, packages}` document. Both spawns are bounded at 600 s
527
+ * daemon-side; `UPDATE_ALL_SKILLS_TIMEOUT_MS` covers both plus margin. */
528
+ async updateAllSkills() {
529
+ return this.daemon.request("skills_update_all_request", {}, UPDATE_ALL_SKILLS_TIMEOUT_MS);
530
+ }
531
+ /** Previews one install source's picklist before installing — `skills_preview_request`.
532
+ * `pi_npm`/`pi_git` always resolve `{ok:true, kind, source, skills: []}` (package kinds install
533
+ * as a unit, nothing to pick); `skills_repo`/`local_path` resolve the candidate `skills` array.
534
+ * Domain failure (e.g. `invalid_source`) resolves `{ok:false, error}`, never thrown; the daemon
535
+ * bounds its own clone/fetch spawn at 120 s, so `PREVIEW_SKILL_SOURCE_TIMEOUT_MS` (150 s) is set
536
+ * above that rather than the client's default. */
537
+ async previewSkillSource(source) {
538
+ return this.daemon.request("skills_preview_request", { source }, PREVIEW_SKILL_SOURCE_TIMEOUT_MS);
539
+ }
540
+ /** Installs one source — `skills_install_request`. `skills` is the picked names from a prior
541
+ * `previewSkillSource()` call (meaningful for `skills_repo` only; `pi_npm`/`pi_git` install
542
+ * every skill the package ships, `local_path` registers the whole folder); `replace` resends an
543
+ * already-installed picked name instead of excluding it as `name_exists`. Resolves one
544
+ * `ItemResult` per engine/picked-name outcome plus the full post-mutation `{skills, packages}`
545
+ * document (domain `{ok:false, error}` on failure, never thrown); the daemon's own spawn bound
546
+ * is 600 s, so `INSTALL_SKILLS_TIMEOUT_MS` (660 s) is set above that. */
547
+ async installSkills(opts) {
548
+ return this.daemon.request("skills_install_request", opts, INSTALL_SKILLS_TIMEOUT_MS);
549
+ }
550
+ /** Subscribe to the daemon's `skills_changed` broadcast — fired after any mutation (this
551
+ * client's own or another's) or an external filesystem change the daemon detected. */
552
+ onSkillsChanged(handler) {
553
+ return this.daemon.onSessionMessage((msg) => {
554
+ if (msg.type === "skills_changed")
555
+ handler(msg.reason);
556
+ });
557
+ }
472
558
  }
473
559
  // ─── Handle classes ──────────────────────────────────────────────────────────────
474
560
  class TimelineHandle {
@@ -245,6 +245,95 @@ export function makeScriptedDaemon(opts) {
245
245
  });
246
246
  return;
247
247
  }
248
+ case "skills_list_request": {
249
+ reply({
250
+ type: "skills_list_response",
251
+ requestId,
252
+ ok: true,
253
+ skills: [
254
+ {
255
+ name: "brave-search",
256
+ path: "/home/u/.pi/agent/skills/brave-search",
257
+ enabled: true,
258
+ origin: "agent_dir",
259
+ originLabel: "User",
260
+ removable: true,
261
+ },
262
+ ],
263
+ packages: [],
264
+ });
265
+ return;
266
+ }
267
+ case "skills_set_enabled_request": {
268
+ reply({
269
+ type: "skills_set_enabled_response",
270
+ requestId,
271
+ ok: true,
272
+ skills: [
273
+ {
274
+ name: "brave-search",
275
+ path: msg.path,
276
+ enabled: msg.enabled,
277
+ origin: "agent_dir",
278
+ originLabel: "User",
279
+ removable: true,
280
+ },
281
+ ],
282
+ packages: [],
283
+ });
284
+ return;
285
+ }
286
+ case "skills_remove_request": {
287
+ reply({
288
+ type: "skills_remove_response",
289
+ requestId,
290
+ ok: true,
291
+ skills: [],
292
+ packages: [],
293
+ });
294
+ return;
295
+ }
296
+ case "skills_update_all_request": {
297
+ reply({
298
+ type: "skills_update_all_response",
299
+ requestId,
300
+ ok: true,
301
+ results: [{ target: "agent-skills", ok: true }],
302
+ skills: [],
303
+ packages: [],
304
+ });
305
+ return;
306
+ }
307
+ case "skills_preview_request": {
308
+ reply({
309
+ type: "skills_preview_response",
310
+ requestId,
311
+ ok: true,
312
+ kind: "skills_repo",
313
+ source: msg.source,
314
+ skills: [
315
+ {
316
+ name: "code-review",
317
+ description: "Review a diff",
318
+ relPath: "skills/code-review",
319
+ valid: true,
320
+ exists: false,
321
+ },
322
+ ],
323
+ });
324
+ return;
325
+ }
326
+ case "skills_install_request": {
327
+ reply({
328
+ type: "skills_install_response",
329
+ requestId,
330
+ ok: true,
331
+ results: [{ target: String(msg.source), ok: true }],
332
+ skills: [],
333
+ packages: [],
334
+ });
335
+ return;
336
+ }
248
337
  default:
249
338
  reply({ type: `${String(msg.type)}_response`, requestId, payload: { ok: true } });
250
339
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@av-pi-studio/client",
3
- "version": "0.0.110",
3
+ "version": "0.0.112",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.map",
@@ -20,7 +20,7 @@
20
20
  "clean": "rm -rf dist *.tsbuildinfo"
21
21
  },
22
22
  "dependencies": {
23
- "@av-pi-studio/protocol": "^0.0.110",
24
- "@av-pi-studio/relay": "^0.0.110"
23
+ "@av-pi-studio/protocol": "^0.0.112",
24
+ "@av-pi-studio/relay": "^0.0.112"
25
25
  }
26
26
  }