@h-rig/pi-rig 0.0.6-alpha.78 → 0.0.6-alpha.79

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.
@@ -0,0 +1,186 @@
1
+ import { RIG_PROTOCOL_VERSION } from "@rig/contracts";
2
+ export { RIG_PROTOCOL_VERSION };
3
+ export type RigExtensionContext = {
4
+ readonly active: boolean;
5
+ readonly runId?: string;
6
+ readonly taskId?: string;
7
+ readonly serverUrl?: string;
8
+ readonly projectRoot?: string;
9
+ readonly authToken?: string;
10
+ readonly steeringPollMs?: number;
11
+ readonly operatorSession?: boolean;
12
+ };
13
+ export type RigBridgeFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
14
+ /**
15
+ * Result of the client–server protocol handshake performed at extension init.
16
+ *
17
+ * - "compatible": the server reports the same RIG_PROTOCOL_VERSION.
18
+ * - "mismatch": the server reports a different (or no) protocol version; the
19
+ * bridge must disable itself instead of failing on a later request.
20
+ * - "indeterminate": the server could not be reached, so compatibility is
21
+ * unknown; the bridge stays enabled and normal error handling applies.
22
+ */
23
+ export type RigProtocolCheck = {
24
+ readonly status: "compatible" | "mismatch" | "indeterminate";
25
+ readonly serverProtocolVersion: number | null;
26
+ readonly message: string | null;
27
+ };
28
+ export declare function createRigContextFromEnv(env?: Record<string, string | undefined>): RigExtensionContext;
29
+ /** Upper bound on any single bridge request. Observed remote servers answer
30
+ * in 0.5–25s under load; without a bound, one wedged fetch freezes every
31
+ * gate-dependent surface (commands, tools, steering) for the session. */
32
+ export declare const BRIDGE_REQUEST_TIMEOUT_MS = 30000;
33
+ /** Tighter bound for the protocol handshake: a timeout maps to
34
+ * "indeterminate" (bridge stays enabled, handshake retries on the next
35
+ * bridge call), so failing fast here only shortens the blind window. */
36
+ export declare const PROTOCOL_CHECK_TIMEOUT_MS = 10000;
37
+ export declare class RigBridgeClient {
38
+ readonly context: RigExtensionContext;
39
+ readonly fetchImpl: RigBridgeFetch;
40
+ constructor(input: {
41
+ context: RigExtensionContext;
42
+ fetchImpl?: RigBridgeFetch;
43
+ });
44
+ request(pathname: string, init?: RequestInit, timeoutMs?: number): Promise<unknown>;
45
+ status(timeoutMs?: number): Promise<Record<string, unknown>>;
46
+ /**
47
+ * Validate that this pi-rig speaks the same protocol as the Rig server.
48
+ * Reads `protocolVersion` from the server bootstrap/status payload; servers
49
+ * that predate the handshake report none and count as v0 (mismatch).
50
+ */
51
+ checkProtocolCompatibility(): Promise<RigProtocolCheck>;
52
+ listTasks(): Promise<Array<Record<string, unknown>>>;
53
+ runTask(taskId?: string): Promise<{
54
+ runId: string;
55
+ }>;
56
+ attach(runId?: string | undefined): Promise<Record<string, unknown>>;
57
+ runLogs(runId?: string | undefined, limit?: number): Promise<Array<Record<string, unknown>>>;
58
+ runTimeline(runId?: string | undefined, limit?: number): Promise<Array<Record<string, unknown>>>;
59
+ steer(message: string, runId?: string | undefined): Promise<Record<string, unknown>>;
60
+ stop(runId?: string | undefined): Promise<Record<string, unknown>>;
61
+ pollSteering(runId?: string | undefined): Promise<Array<Record<string, unknown>>>;
62
+ consumeSteering(runId?: string | undefined): Promise<Array<Record<string, unknown>>>;
63
+ emitEvent(event: Record<string, unknown>): Promise<Record<string, unknown>>;
64
+ readTaskMetadata(taskId?: string | undefined): Promise<Record<string, unknown>>;
65
+ private piProxy;
66
+ /** The worker session's slash commands (name + description). */
67
+ workerCommands(runId?: string | undefined): Promise<Array<Record<string, unknown>>>;
68
+ /** Run one of the worker session's slash commands. */
69
+ workerRunCommand(command: string, args: string, runId?: string | undefined): Promise<Record<string, unknown>>;
70
+ /** Execute a shell command inside the WORKER's workspace. */
71
+ workerShell(command: string, runId?: string | undefined): Promise<Record<string, unknown>>;
72
+ /** Abort the worker session's current turn. */
73
+ workerAbort(runId?: string | undefined): Promise<Record<string, unknown>>;
74
+ /** The worker session's real capabilities (tools, extensions, hooks, skills, model, cwd). */
75
+ workerCapabilities(runId?: string | undefined): Promise<Record<string, unknown>>;
76
+ /** Answer a worker extension-UI request (select/confirm/input) via the server proxy. */
77
+ workerRespondExtensionUi(requestId: string, response: Record<string, unknown>, runId?: string | undefined): Promise<Record<string, unknown>>;
78
+ /** The run's full Pi session transcript (jsonl) — the cockpit's source of truth. */
79
+ fetchRunSessionFile(runId?: string | undefined): Promise<{
80
+ fileName: string;
81
+ content: string;
82
+ } | null>;
83
+ }
84
+ export type RigWebSocketEvent = {
85
+ readonly data?: unknown;
86
+ };
87
+ /**
88
+ * Minimal WebSocket surface the bridge needs. Matches the global
89
+ * `WebSocket` available in Bun and Node >= 22; tests inject fakes.
90
+ */
91
+ export type RigWebSocketLike = {
92
+ addEventListener(type: "open" | "message" | "close" | "error", listener: (event: RigWebSocketEvent) => void): void;
93
+ send(data: string): void;
94
+ close(): void;
95
+ };
96
+ export type RigWebSocketFactory = (url: string) => RigWebSocketLike;
97
+ export type RigBridgeSocketHandlers = {
98
+ /** Steering message pushed for this context's run (already runId-filtered). */
99
+ readonly onSteeringMessage?: (message: Record<string, unknown>) => void;
100
+ /** Any engine event on the `rig.event` channel (NOT runId-filtered). */
101
+ readonly onRigEvent?: (event: Record<string, unknown>) => void;
102
+ readonly onSnapshotInvalidated?: () => void;
103
+ readonly onConnect?: () => void;
104
+ readonly onDisconnect?: () => void;
105
+ };
106
+ export declare function buildRigWebSocketUrl(serverUrl: string, authToken?: string): string;
107
+ /**
108
+ * Reconnecting WebSocket subscriber for Rig server push channels.
109
+ *
110
+ * - Connects to the same host as the HTTP base URL (`ws://`/`wss://`,
111
+ * token as query param).
112
+ * - Reconnects with exponential backoff (1s doubling to 30s); `connected`
113
+ * lets callers gate their HTTP-polling fallback on socket health.
114
+ * - Steering delivery is confirmed over the same socket via the
115
+ * `rig.ackRunSteering` RPC method.
116
+ */
117
+ export declare class RigBridgeSocket {
118
+ private readonly context;
119
+ private readonly handlers;
120
+ private readonly factory;
121
+ private readonly reconnectBaseMs;
122
+ private readonly reconnectMaxMs;
123
+ private socket;
124
+ private connectedFlag;
125
+ private closed;
126
+ private started;
127
+ private attempt;
128
+ private reconnectTimer;
129
+ private ackSequence;
130
+ constructor(input: {
131
+ readonly context: RigExtensionContext;
132
+ readonly handlers?: RigBridgeSocketHandlers;
133
+ readonly webSocketFactory?: RigWebSocketFactory;
134
+ readonly reconnectBaseMs?: number;
135
+ readonly reconnectMaxMs?: number;
136
+ });
137
+ get connected(): boolean;
138
+ /** Returns false when no server URL or WebSocket implementation exists. */
139
+ start(): boolean;
140
+ close(): void;
141
+ /** Confirm steering delivery over the socket. Fire-and-forget: on failure the
142
+ * polling fallback re-delivers and the caller's dedupe set absorbs it. */
143
+ ackSteering(runId: string, ids: readonly string[]): void;
144
+ private connect;
145
+ private scheduleReconnect;
146
+ private handleMessage;
147
+ }
148
+ /** WS URL for the server's worker-session event proxy
149
+ * (`/api/runs/:id/pi/events` → daemon events). Token rides the query param
150
+ * (the upgrade handler reads it); rigProjectRoot scopes multi-root servers. */
151
+ export declare function buildRunPiEventsWebSocketUrl(context: RigExtensionContext): string | null;
152
+ /**
153
+ * Reconnecting subscriber for the worker session's event stream (the same
154
+ * frames the worker daemon emits: `pi.event` envelopes, `status.update`,
155
+ * `activity.update`). This is the live-mirror transport: the operator
156
+ * console renders worker turns from these frames.
157
+ *
158
+ * The proxy returns 202 while the session is still starting and the run may
159
+ * outlive several daemon generations, so reconnection uses the same backoff
160
+ * discipline as RigBridgeSocket.
161
+ */
162
+ export declare class RigWorkerEventsSocket {
163
+ private readonly context;
164
+ private readonly handlers;
165
+ private readonly factory;
166
+ private readonly reconnectBaseMs;
167
+ private readonly reconnectMaxMs;
168
+ private socket;
169
+ private connectedFlag;
170
+ private closed;
171
+ private started;
172
+ private attempt;
173
+ private reconnectTimer;
174
+ constructor(input: {
175
+ readonly context: RigExtensionContext;
176
+ readonly handlers?: RigWorkerEventsSocket["handlers"];
177
+ readonly webSocketFactory?: RigWebSocketFactory;
178
+ readonly reconnectBaseMs?: number;
179
+ readonly reconnectMaxMs?: number;
180
+ });
181
+ get connected(): boolean;
182
+ start(): boolean;
183
+ close(): void;
184
+ private connect;
185
+ private scheduleReconnect;
186
+ }
@@ -266,10 +266,11 @@ class RigBridgeClient {
266
266
  return commands.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
267
267
  }
268
268
  async workerRunCommand(command, args, runId = this.context.runId) {
269
+ const text = `/${command}${args.trim() ? ` ${args.trim()}` : ""}`;
269
270
  const payload = await this.piProxy("commands/run", {
270
271
  method: "POST",
271
272
  headers: { "content-type": "application/json" },
272
- body: JSON.stringify({ command, args })
273
+ body: JSON.stringify({ text })
273
274
  }, runId);
274
275
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
275
276
  }
@@ -277,7 +278,7 @@ class RigBridgeClient {
277
278
  const payload = await this.piProxy("shell", {
278
279
  method: "POST",
279
280
  headers: { "content-type": "application/json" },
280
- body: JSON.stringify({ command })
281
+ body: JSON.stringify({ text: command })
281
282
  }, runId);
282
283
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
283
284
  }
@@ -293,7 +294,7 @@ class RigBridgeClient {
293
294
  const payload = await this.piProxy("extension-ui/respond", {
294
295
  method: "POST",
295
296
  headers: { "content-type": "application/json" },
296
- body: JSON.stringify({ requestId, response })
297
+ body: JSON.stringify({ requestId, ...response })
297
298
  }, runId);
298
299
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
299
300
  }
@@ -0,0 +1,10 @@
1
+ import type { RigExtensionContext, RigBridgeClient } from "./client";
2
+ export type RigCommandDefinition = {
3
+ readonly description: string;
4
+ readonly handler: (args: string, ctx: unknown) => Promise<void>;
5
+ };
6
+ export declare function createRigSlashCommands(input: {
7
+ readonly context: RigExtensionContext;
8
+ readonly client: RigBridgeClient;
9
+ readonly notify?: (message: string, level?: "info" | "error") => void;
10
+ }): Record<string, RigCommandDefinition>;
@@ -0,0 +1,59 @@
1
+ import { RigBridgeClient, type RigExtensionContext, type RigProtocolCheck, type RigWebSocketFactory } from "./client";
2
+ export type MinimalPiApi = {
3
+ registerCommand?: (name: string, command: {
4
+ description?: string;
5
+ handler: (args: string, ctx: unknown) => Promise<void>;
6
+ }) => void;
7
+ registerTool?: (tool: {
8
+ name: string;
9
+ } & Record<string, unknown>) => void;
10
+ on?: (eventName: string, handler: (event: unknown, ctx: unknown) => unknown) => void;
11
+ sendUserMessage?: (content: string, options?: {
12
+ deliverAs?: "steer" | "followUp" | "nextTurn";
13
+ triggerTurn?: boolean;
14
+ }) => void | Promise<void>;
15
+ /** Stock Pi custom-message injection: rendered in the transcript without
16
+ * triggering a turn. The operator console's live worker mirror rides this. */
17
+ sendMessage?: (message: {
18
+ customType: string;
19
+ content: string;
20
+ display?: boolean;
21
+ details?: unknown;
22
+ }, options?: {
23
+ triggerTurn?: boolean;
24
+ }) => void | Promise<void>;
25
+ /** Stock custom-message renderer registration: the live mirror renders
26
+ * worker turns through Pi's own components via this seam. */
27
+ registerMessageRenderer?: (customType: string, renderer: (message: unknown, options: {
28
+ expanded: boolean;
29
+ }, theme: unknown) => unknown) => void;
30
+ };
31
+ export type PiRigExtensionState = RigExtensionContext & {
32
+ readonly client: RigBridgeClient;
33
+ /** Test seam: lets the suite fake the push socket. Defaults to the global WebSocket. */
34
+ readonly webSocketFactory?: RigWebSocketFactory;
35
+ };
36
+ export declare function createPiRigExtensionState(input?: {
37
+ readonly env?: Record<string, string | undefined>;
38
+ readonly fetchImpl?: typeof fetch;
39
+ readonly webSocketFactory?: RigWebSocketFactory;
40
+ }): PiRigExtensionState;
41
+ export type PiRigBridgeGate = {
42
+ readonly allowed: boolean;
43
+ readonly message: string | null;
44
+ /** Handshake outcome: "compatible" means the server speaks this protocol
45
+ * version and therefore supports the WS push surface. */
46
+ readonly status: RigProtocolCheck["status"];
47
+ };
48
+ export type PiRigBridgeGateCheck = (ctx: unknown) => Promise<PiRigBridgeGate>;
49
+ /** Live refresh control handed to the operator widget by the WS bridge:
50
+ * while the socket is up, pushes (rig.event / snapshotInvalidated) drive the
51
+ * widget instead of the 1s status poll. */
52
+ export type OperatorLiveRefresh = {
53
+ isConnected(): boolean;
54
+ /** Returns true (and resets) when a push arrived since the last check. */
55
+ consumePushTrigger(): boolean;
56
+ };
57
+ export default function createPiRigExtension(pi: MinimalPiApi, options?: {
58
+ state?: PiRigExtensionState;
59
+ }): void;
package/dist/src/index.js CHANGED
@@ -268,10 +268,11 @@ class RigBridgeClient {
268
268
  return commands.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
269
269
  }
270
270
  async workerRunCommand(command, args, runId = this.context.runId) {
271
+ const text = `/${command}${args.trim() ? ` ${args.trim()}` : ""}`;
271
272
  const payload = await this.piProxy("commands/run", {
272
273
  method: "POST",
273
274
  headers: { "content-type": "application/json" },
274
- body: JSON.stringify({ command, args })
275
+ body: JSON.stringify({ text })
275
276
  }, runId);
276
277
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
277
278
  }
@@ -279,7 +280,7 @@ class RigBridgeClient {
279
280
  const payload = await this.piProxy("shell", {
280
281
  method: "POST",
281
282
  headers: { "content-type": "application/json" },
282
- body: JSON.stringify({ command })
283
+ body: JSON.stringify({ text: command })
283
284
  }, runId);
284
285
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
285
286
  }
@@ -295,7 +296,7 @@ class RigBridgeClient {
295
296
  const payload = await this.piProxy("extension-ui/respond", {
296
297
  method: "POST",
297
298
  headers: { "content-type": "application/json" },
298
- body: JSON.stringify({ requestId, response })
299
+ body: JSON.stringify({ requestId, ...response })
299
300
  }, runId);
300
301
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
301
302
  }
@@ -759,8 +760,15 @@ async function createLiveMirror(input) {
759
760
  let streamingTurn = null;
760
761
  let sequence = 0;
761
762
  let tui = null;
763
+ let renderTimer = null;
762
764
  const requestRender = () => {
763
- tui?.requestRender?.();
765
+ if (renderTimer)
766
+ return;
767
+ renderTimer = setTimeout(() => {
768
+ renderTimer = null;
769
+ tui?.requestRender?.();
770
+ }, 33);
771
+ renderTimer.unref?.();
764
772
  };
765
773
  pi.registerMessageRenderer?.(DRONE_MESSAGE_TYPE, (message) => {
766
774
  const details = recordOf(recordOf(message)?.details);
@@ -1444,21 +1452,21 @@ async function forwardWorkerUiRequest(state, ctx, event) {
1444
1452
  notify(ctx, `Failed to answer the drone's question: ${error instanceof Error ? error.message : String(error)}`, "error");
1445
1453
  }
1446
1454
  }
1447
- async function registerWorkerCommands(pi, state, ctx) {
1455
+ async function registerWorkerCommands(pi, state, ctx, registeredNames = new Set) {
1448
1456
  if (!state.operatorSession || !state.active || !state.runId)
1449
- return;
1457
+ return false;
1450
1458
  if (typeof pi.registerCommand !== "function")
1451
- return;
1459
+ return false;
1452
1460
  let commands = [];
1453
1461
  try {
1454
1462
  commands = await state.client.workerCommands(state.runId);
1455
1463
  } catch {
1456
- return;
1464
+ return false;
1457
1465
  }
1458
1466
  let registered = 0;
1459
1467
  for (const command of commands) {
1460
1468
  const name = typeof command.name === "string" && command.name.trim() ? command.name.trim() : null;
1461
- if (!name || name === "rig")
1469
+ if (!name || name === "rig" || registeredNames.has(name))
1462
1470
  continue;
1463
1471
  const description = typeof command.description === "string" && command.description.trim() ? `[worker] ${command.description.trim()}` : "[worker] remote session command";
1464
1472
  try {
@@ -1473,12 +1481,47 @@ async function registerWorkerCommands(pi, state, ctx) {
1473
1481
  }
1474
1482
  }
1475
1483
  });
1484
+ registeredNames.add(name);
1476
1485
  registered += 1;
1477
- } catch {}
1486
+ } catch {
1487
+ registeredNames.add(name);
1488
+ }
1478
1489
  }
1479
1490
  if (registered > 0) {
1480
1491
  notify(ctx, `Worker session commands available: ${registered} registered from the run's Pi session.`);
1481
1492
  }
1493
+ return true;
1494
+ }
1495
+ function startWorkerCommandRegistration(pi, state, ctx) {
1496
+ const registeredNames = new Set;
1497
+ let attempts = 0;
1498
+ let inFlight = false;
1499
+ const attempt = async () => {
1500
+ if (inFlight)
1501
+ return false;
1502
+ inFlight = true;
1503
+ attempts += 1;
1504
+ try {
1505
+ return await registerWorkerCommands(pi, state, ctx, registeredNames);
1506
+ } finally {
1507
+ inFlight = false;
1508
+ }
1509
+ };
1510
+ attempt().then((ready) => {
1511
+ if (ready)
1512
+ return;
1513
+ const timer = setInterval(() => {
1514
+ if (attempts >= 60) {
1515
+ clearInterval(timer);
1516
+ return;
1517
+ }
1518
+ attempt().then((nextReady) => {
1519
+ if (nextReady)
1520
+ clearInterval(timer);
1521
+ });
1522
+ }, 2000);
1523
+ unrefTimer(timer);
1524
+ });
1482
1525
  }
1483
1526
  function startSteeringBridge(pi, state, ctx, gate, deliveredIds) {
1484
1527
  if (state.operatorSession || !state.active || !state.runId || typeof pi.sendUserMessage !== "function")
@@ -1610,7 +1653,7 @@ function createPiRigExtension(pi, options = {}) {
1610
1653
  startOperatorRunStatusLine(state, ctx, live);
1611
1654
  if (state.operatorSession && gateResult.status === "compatible") {
1612
1655
  startWorkerSessionMirror(pi, state, ctx);
1613
- registerWorkerCommands(pi, state, ctx);
1656
+ startWorkerCommandRegistration(pi, state, ctx);
1614
1657
  }
1615
1658
  await consumeQueuedSteering(pi, state, ctx, gate, deliveredSteeringIds);
1616
1659
  });
@@ -0,0 +1,46 @@
1
+ import type { MinimalPiApi } from "./index";
2
+ /** What we use of pi-tui's Component contract. */
3
+ export type ComponentLike = {
4
+ render(width: number): string[];
5
+ };
6
+ type AssistantComponentLike = ComponentLike & {
7
+ updateContent(message: Record<string, unknown>): void;
8
+ };
9
+ type ToolComponentLike = ComponentLike & {
10
+ markExecutionStarted(): void;
11
+ updateArgs(args: unknown): void;
12
+ setArgsComplete(): void;
13
+ updateResult(result: {
14
+ content: Array<Record<string, unknown>>;
15
+ details?: unknown;
16
+ isError: boolean;
17
+ }, isPartial?: boolean): void;
18
+ };
19
+ type PiComponentModule = {
20
+ AssistantMessageComponent: new (message?: unknown) => AssistantComponentLike;
21
+ UserMessageComponent: new (text: string) => ComponentLike;
22
+ ToolExecutionComponent: new (toolName: string, toolCallId: string, args: unknown, options: Record<string, unknown>, toolDefinition: unknown, ui: unknown, cwd: string) => ToolComponentLike;
23
+ };
24
+ export type LiveMirrorModules = {
25
+ components: PiComponentModule;
26
+ };
27
+ export declare const DRONE_MESSAGE_TYPE = "rig-drone";
28
+ export declare const DRONE_USER_MESSAGE_TYPE = "rig-drone-user";
29
+ export type LiveMirror = {
30
+ /** Feed one worker `pi.event` frame's inner event into the mirror. */
31
+ handleWorkerEvent(event: Record<string, unknown>): void;
32
+ /** The setWidget factory used purely to capture the TUI handle. */
33
+ captureTui(tui: unknown): ComponentLike;
34
+ };
35
+ /**
36
+ * Wire the live mirror: registers the message renderers and returns the
37
+ * event feed. Call once per operator session, before events start flowing.
38
+ */
39
+ export declare function createLiveMirror(input: {
40
+ pi: MinimalPiApi;
41
+ /** Worker workspace path, for tool renderers (diff headers etc.). */
42
+ workerCwd?: string;
43
+ /** Test seam: fake Pi modules. Defaults to the real dynamic import. */
44
+ modules?: LiveMirrorModules;
45
+ }): Promise<LiveMirror>;
46
+ export {};
@@ -57,8 +57,15 @@ async function createLiveMirror(input) {
57
57
  let streamingTurn = null;
58
58
  let sequence = 0;
59
59
  let tui = null;
60
+ let renderTimer = null;
60
61
  const requestRender = () => {
61
- tui?.requestRender?.();
62
+ if (renderTimer)
63
+ return;
64
+ renderTimer = setTimeout(() => {
65
+ renderTimer = null;
66
+ tui?.requestRender?.();
67
+ }, 33);
68
+ renderTimer.unref?.();
62
69
  };
63
70
  pi.registerMessageRenderer?.(DRONE_MESSAGE_TYPE, (message) => {
64
71
  const details = recordOf(recordOf(message)?.details);
@@ -0,0 +1,19 @@
1
+ import type { RigBridgeClient, RigExtensionContext } from "./client";
2
+ export type RigToolResult = {
3
+ readonly content: Array<{
4
+ type: "text";
5
+ text: string;
6
+ }>;
7
+ readonly details?: Record<string, unknown>;
8
+ };
9
+ export type RigToolDefinition = {
10
+ readonly name: string;
11
+ readonly label: string;
12
+ readonly description: string;
13
+ readonly parameters: Record<string, unknown>;
14
+ readonly execute: (toolCallId: string, params: Record<string, unknown>) => Promise<RigToolResult>;
15
+ };
16
+ export declare function createRigTools(input: {
17
+ readonly context: RigExtensionContext;
18
+ readonly client: RigBridgeClient;
19
+ }): RigToolDefinition[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-rig/pi-rig",
3
- "version": "0.0.6-alpha.78",
3
+ "version": "0.0.6-alpha.79",
4
4
  "type": "module",
5
5
  "description": "Rig package",
6
6
  "license": "UNLICENSED",
@@ -10,15 +10,19 @@
10
10
  ],
11
11
  "exports": {
12
12
  ".": {
13
+ "types": "./dist/src/index.d.ts",
13
14
  "import": "./dist/src/index.js"
14
15
  },
15
16
  "./client": {
17
+ "types": "./dist/src/client.d.ts",
16
18
  "import": "./dist/src/client.js"
17
19
  },
18
20
  "./commands": {
21
+ "types": "./dist/src/commands.d.ts",
19
22
  "import": "./dist/src/commands.js"
20
23
  },
21
24
  "./tools": {
25
+ "types": "./dist/src/tools.d.ts",
22
26
  "import": "./dist/src/tools.js"
23
27
  }
24
28
  },
@@ -27,13 +31,14 @@
27
31
  },
28
32
  "main": "./dist/src/index.js",
29
33
  "module": "./dist/src/index.js",
34
+ "types": "./dist/src/index.d.ts",
30
35
  "pi": {
31
36
  "extensions": [
32
37
  "./dist/src/index.js"
33
38
  ]
34
39
  },
35
40
  "dependencies": {
36
- "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.78"
41
+ "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.79"
37
42
  },
38
43
  "peerDependencies": {
39
44
  "@earendil-works/pi-coding-agent": ">=0.79.0",