@rigkit/provider-cmux 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigkit/provider-cmux",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,8 +17,8 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "@rigkit/sdk": "0.2.3",
21
- "@rigkit/engine": "0.2.3"
20
+ "@rigkit/sdk": "0.2.4",
21
+ "@rigkit/engine": "0.2.4"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/bun": "latest",
package/src/host.ts CHANGED
@@ -13,7 +13,11 @@ import {
13
13
  type CmuxWaitForRemoteOptions,
14
14
  type CmuxWorkspace,
15
15
  } from "./index.ts";
16
- import { defineHostCapability, type HostCapabilityHandler } from "@rigkit/sdk/host";
16
+ import {
17
+ defineHostCapability,
18
+ type HostCapabilityContext,
19
+ type HostCapabilityHandler,
20
+ } from "@rigkit/sdk/host";
17
21
  import {
18
22
  CMUX_OPEN_CAPABILITY,
19
23
  type CmuxOpenInput,
@@ -39,6 +43,7 @@ export type CmuxOpenClient = Pick<
39
43
  export type CmuxOpenHostOptions = {
40
44
  client?: CmuxOpenClient;
41
45
  clientOptions?: CmuxClientOptions;
46
+ logger?: (message: string) => void;
42
47
  };
43
48
 
44
49
  export function createCmuxOpenHostCapability(
@@ -46,7 +51,11 @@ export function createCmuxOpenHostCapability(
46
51
  ): CmuxHostCapabilityHandler {
47
52
  return defineHostCapability(CMUX_OPEN_CAPABILITY.id, {
48
53
  schemaHash: CMUX_OPEN_CAPABILITY.schemaHash,
49
- handle: async (params) => await openCmux(params, options),
54
+ handle: async (params, context) =>
55
+ await openCmux(params, {
56
+ ...options,
57
+ logger: options.logger ?? hostCapabilityLogger(context) ?? options.clientOptions?.logger,
58
+ }),
50
59
  });
51
60
  }
52
61
 
@@ -57,18 +66,26 @@ export async function openCmux(
57
66
  options: CmuxOpenHostOptions = {},
58
67
  ): Promise<CmuxOpenResult> {
59
68
  const input = parseCmuxOpenInput(params);
60
- const cmux = options.client ?? createCmuxClient(options.clientOptions);
69
+ const logger = cmuxOpenLogger(options);
70
+ const cmux = options.client ?? createCmuxClient({
71
+ ...options.clientOptions,
72
+ ...(options.logger ? { logger: options.logger } : {}),
73
+ printCommands: options.clientOptions?.printCommands ?? false,
74
+ });
61
75
  const command = commandForInput(input);
62
76
  let workspace: CmuxWorkspace;
63
77
  let terminalPane: CmuxPane | undefined;
64
78
 
79
+ logger?.(`cmux: opening ${input.name}`);
65
80
  if (input.ssh) {
81
+ logger?.("cmux: connecting remote workspace");
66
82
  workspace = await cmux.ssh({
67
83
  ...cmuxSshOptionsForInput(input.ssh),
68
84
  name: input.name,
69
85
  noFocus: input.focus === false,
70
86
  });
71
87
  } else {
88
+ logger?.("cmux: creating workspace");
72
89
  const workspaceOptions: CmuxNewWorkspaceOptions = {
73
90
  name: input.name,
74
91
  cwd: input.cwd,
@@ -81,6 +98,7 @@ export async function openCmux(
81
98
  const workspaceId = workspace.id ?? workspace.handle;
82
99
 
83
100
  if (input.ssh && command) {
101
+ logger?.(input.cwd ? `cmux: starting command in ${input.cwd}` : "cmux: starting command");
84
102
  const paneOptions: CmuxNewPaneOptions = {
85
103
  workspace: workspaceId,
86
104
  type: "terminal",
@@ -98,10 +116,12 @@ export async function openCmux(
98
116
 
99
117
  const waitOptions = remoteReadyOptionsForInput(input);
100
118
  if (input.ssh && waitOptions) {
119
+ logger?.("cmux: waiting for remote ports");
101
120
  await cmux.waitForRemoteReady(workspaceId, waitOptions);
102
121
  }
103
122
 
104
123
  if (input.ssh && terminalPane?.surface) {
124
+ logger?.("cmux: refreshing remote ports");
105
125
  const kickOptions: CmuxPortsKickOptions = {
106
126
  workspace: workspaceId,
107
127
  surface: terminalPane.surface,
@@ -112,6 +132,7 @@ export async function openCmux(
112
132
 
113
133
  let browserPane: CmuxPane | undefined;
114
134
  if (input.url) {
135
+ logger?.(`cmux: opening ${input.url}`);
115
136
  const browserOptions: CmuxBrowserOpenOptions = {
116
137
  workspace: workspaceId,
117
138
  url: input.url,
@@ -121,9 +142,11 @@ export async function openCmux(
121
142
  }
122
143
 
123
144
  if (input.focus !== false) {
145
+ logger?.("cmux: focusing workspace");
124
146
  await cmux.selectWorkspace(workspaceId);
125
147
  }
126
148
 
149
+ logger?.(`cmux: ready ${input.name}`);
127
150
  return {
128
151
  sessionId: workspaceId,
129
152
  workspaceId,
@@ -135,6 +158,15 @@ export async function openCmux(
135
158
  };
136
159
  }
137
160
 
161
+ function cmuxOpenLogger(options: CmuxOpenHostOptions): ((message: string) => void) | undefined {
162
+ return options.logger ?? options.clientOptions?.logger;
163
+ }
164
+
165
+ function hostCapabilityLogger(context: HostCapabilityContext | undefined): ((message: string) => void) | undefined {
166
+ if (!context) return undefined;
167
+ return (message) => context.log(message, { label: "cmux" });
168
+ }
169
+
138
170
  export function parseCmuxOpenInput(value: unknown): CmuxOpenInput {
139
171
  if (!isRecord(value)) throw new Error(`cmux.open requires an object input`);
140
172
  const name = requiredString(value, "name");
package/src/index.test.ts CHANGED
@@ -402,6 +402,7 @@ describe("cmux sdk", () => {
402
402
 
403
403
  test("handles cmux.open host capability for an ssh workspace", async () => {
404
404
  const calls: Array<{ method: string; params: unknown }> = [];
405
+ const logs: string[] = [];
405
406
  const client = fakeOpenClient(calls);
406
407
 
407
408
  const result = await openCmux({
@@ -414,7 +415,7 @@ describe("cmux sdk", () => {
414
415
  cwd: "/workspace/site",
415
416
  command: "pnpm dev",
416
417
  url: "http://localhost:4321",
417
- }, { client });
418
+ }, { client, logger: (message) => logs.push(message) });
418
419
 
419
420
  expect(result).toEqual({
420
421
  sessionId: "workspace-1",
@@ -480,6 +481,16 @@ describe("cmux sdk", () => {
480
481
  },
481
482
  ]);
482
483
  expect(calls[0]?.params).not.toHaveProperty("terminalStartupCommand");
484
+ expect(logs).toEqual([
485
+ "cmux: opening website",
486
+ "cmux: connecting remote workspace",
487
+ "cmux: starting command in /workspace/site",
488
+ "cmux: waiting for remote ports",
489
+ "cmux: refreshing remote ports",
490
+ "cmux: opening http://localhost:4321",
491
+ "cmux: focusing workspace",
492
+ "cmux: ready website",
493
+ ]);
483
494
  });
484
495
 
485
496
  test("forwards an explicit cmux ssh terminal startup command", async () => {
@@ -513,8 +524,10 @@ describe("cmux sdk", () => {
513
524
  const controller = await cmuxProviderPlugin.createProvider({
514
525
  provider: { providerId: "cmux", config: {} },
515
526
  storage: memoryProviderStorage("cmux"),
527
+ hostStorage: memoryProviderStorage("cmux"),
528
+ local: { open: async () => {} },
516
529
  });
517
- const requests: Array<{ capability: string; params: unknown }> = [];
530
+ const requests: Array<{ capability: string; params: unknown; options: unknown }> = [];
518
531
  const runtime = await controller.runtime({
519
532
  workflow: "test",
520
533
  nodePath: "operation.open",
@@ -525,8 +538,8 @@ describe("cmux sdk", () => {
525
538
  metadata: () => {},
526
539
  local: {
527
540
  open: async () => {},
528
- requestCapability: async <Result,>(capability: string, params: unknown) => {
529
- requests.push({ capability, params });
541
+ requestCapability: async <Result,>(capability: string, params: unknown, options: unknown) => {
542
+ requests.push({ capability, params, options });
530
543
  return { sessionId: "workspace-1", workspaceId: "workspace-1" } as Result;
531
544
  },
532
545
  },
@@ -538,6 +551,7 @@ describe("cmux sdk", () => {
538
551
  {
539
552
  capability: "cmux.open",
540
553
  params: { name: "workspace" },
554
+ options: { nodePath: "operation.open" },
541
555
  },
542
556
  ]);
543
557
  expect(session.sessionId).toBe("workspace-1");
@@ -554,6 +568,8 @@ describe("cmux sdk", () => {
554
568
  const controller = await cmuxProviderPlugin.createProvider({
555
569
  provider: { providerId: "cmux", config: {} },
556
570
  storage: memoryProviderStorage("cmux"),
571
+ hostStorage: memoryProviderStorage("cmux"),
572
+ local: { open: async () => {} },
557
573
  });
558
574
  let resolveClosed!: () => void;
559
575
  const runtime = await controller.runtime({
@@ -566,9 +582,10 @@ describe("cmux sdk", () => {
566
582
  metadata: () => {},
567
583
  local: {
568
584
  open: async () => {},
569
- requestCapabilitySession: async <Result,>(capability: string, params: unknown) => {
585
+ requestCapabilitySession: async <Result,>(capability: string, params: unknown, options: unknown) => {
570
586
  expect(capability).toBe("cmux.open");
571
587
  expect(params).toEqual({ name: "workspace" });
588
+ expect(options).toEqual({ nodePath: "operation.open" });
572
589
  return {
573
590
  result: { sessionId: "workspace-1", workspaceId: "workspace-1" } as Result,
574
591
  closed: new Promise<void>((resolve) => {
package/src/provider.ts CHANGED
@@ -37,24 +37,25 @@ export const cmuxProviderPlugin: BaseProviderPlugin = {
37
37
  return {
38
38
  providerId: CMUX_PROVIDER_ID,
39
39
  runtime(context) {
40
- return createCmuxRuntime(context.local);
40
+ return createCmuxRuntime(context.local, context.nodePath);
41
41
  },
42
42
  };
43
43
  },
44
44
  };
45
45
 
46
- function createCmuxRuntime(local: LocalWorkspaceRuntime): CmuxRuntime {
46
+ function createCmuxRuntime(local: LocalWorkspaceRuntime, nodePath: string): CmuxRuntime {
47
47
  return {
48
- open: async (input) => await requestCmuxOpen(local, input),
48
+ open: async (input) => await requestCmuxOpen(local, input, { nodePath }),
49
49
  };
50
50
  }
51
51
 
52
52
  export async function requestCmuxOpen(
53
53
  local: LocalWorkspaceRuntime,
54
54
  input: CmuxOpenInput,
55
+ options: { nodePath?: string } = {},
55
56
  ): Promise<CmuxOpenSession> {
56
57
  if (local.requestCapabilitySession) {
57
- const session = await local.requestCapabilitySession<CmuxOpenResult>(CMUX_OPEN_CAPABILITY_ID, input);
58
+ const session = await local.requestCapabilitySession<CmuxOpenResult>(CMUX_OPEN_CAPABILITY_ID, input, options);
58
59
  return {
59
60
  ...parseCmuxOpenResult(session.result),
60
61
  closed: session.closed,
@@ -64,7 +65,7 @@ export async function requestCmuxOpen(
64
65
  throw new Error(`Host capability ${CMUX_OPEN_CAPABILITY_ID} is unavailable in this runtime`);
65
66
  }
66
67
  const result = parseCmuxOpenResult(
67
- await local.requestCapability(CMUX_OPEN_CAPABILITY_ID, input),
68
+ await local.requestCapability(CMUX_OPEN_CAPABILITY_ID, input, options),
68
69
  );
69
70
  return {
70
71
  ...result,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const RIGKIT_PROVIDER_CMUX_VERSION = "0.2.3";
1
+ export const RIGKIT_PROVIDER_CMUX_VERSION = "0.2.4";