@rigkit/provider-cmux 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -43,14 +43,13 @@ export default workflow("site", {
43
43
  })
44
44
  .sequence("site")
45
45
  .operation("open", {
46
- requiredHostCapabilities: [cmux.capabilities.open],
47
46
  run: async ({ providers }) => {
48
47
  await providers.cmux.open({
49
48
  name: "site",
50
49
  ssh: {
51
- host: "vm-ssh.freestyle.sh",
52
- username: "vm_123",
53
- auth: { type: "token", token: "token_123" },
50
+ host: "devbox.example.com",
51
+ username: "root",
52
+ sshOptions: ["ServerAliveInterval=15"],
54
53
  },
55
54
  cwd: "/workspace/site",
56
55
  command: "pnpm dev",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigkit/provider-cmux",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
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.1",
21
- "@rigkit/engine": "0.2.1"
20
+ "@rigkit/sdk": "0.2.3",
21
+ "@rigkit/engine": "0.2.3"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/bun": "latest",
@@ -1,7 +1,7 @@
1
1
  export const CMUX_OPEN_CAPABILITY_ID = "cmux.open";
2
2
 
3
3
  export const CMUX_OPEN_SCHEMA_HASH =
4
- "sha256:ed7f74b4fd1101ff87281c0269f9884f85783098d9a727fdfe05491efba2dd28";
4
+ "sha256:671373232fc79a7f75dd01c8c83c0c350af62b349a89bb3cfcc96af2cd76c878";
5
5
 
6
6
  export const CMUX_OPEN_CAPABILITY = {
7
7
  id: CMUX_OPEN_CAPABILITY_ID,
@@ -14,8 +14,6 @@ export type CmuxOpenSshInput = string | {
14
14
  host?: string;
15
15
  port?: number;
16
16
  username?: string;
17
- auth?: { type: "token"; token: string } | { type: "privateKey"; privateKey: string };
18
- command?: string;
19
17
  identity?: string;
20
18
  sshOptions?: readonly string[];
21
19
  remoteCommandArgs?: readonly string[];
package/src/host.ts CHANGED
@@ -41,15 +41,6 @@ export type CmuxOpenHostOptions = {
41
41
  clientOptions?: CmuxClientOptions;
42
42
  };
43
43
 
44
- const freestyleTokenSshOptions = [
45
- "StrictHostKeyChecking=no",
46
- "UserKnownHostsFile=/dev/null",
47
- "LogLevel=ERROR",
48
- "IdentitiesOnly=yes",
49
- "IdentityFile=/dev/null",
50
- "ControlMaster=no",
51
- ] as const;
52
-
53
44
  export function createCmuxOpenHostCapability(
54
45
  options: CmuxOpenHostOptions = {},
55
46
  ): CmuxHostCapabilityHandler {
@@ -171,8 +162,6 @@ function parseSshInput(value: unknown): CmuxOpenSshInput {
171
162
  ...optionalStringField(value, "host"),
172
163
  ...optionalNumberField(value, "port"),
173
164
  ...optionalStringField(value, "username"),
174
- ...(value.auth !== undefined ? { auth: parseSshAuth(value.auth) } : {}),
175
- ...optionalStringField(value, "command"),
176
165
  ...optionalStringField(value, "identity"),
177
166
  ...optionalStringArrayField(value, "sshOptions"),
178
167
  ...optionalStringArrayField(value, "remoteCommandArgs"),
@@ -183,17 +172,6 @@ function parseSshInput(value: unknown): CmuxOpenSshInput {
183
172
  };
184
173
  }
185
174
 
186
- function parseSshAuth(value: unknown): Exclude<Extract<CmuxOpenSshInput, object>["auth"], undefined> {
187
- if (!isRecord(value)) throw new Error(`cmux.open ssh.auth must be an object`);
188
- if (value.type === "token") {
189
- return { type: "token", token: requiredString(value, "token") };
190
- }
191
- if (value.type === "privateKey") {
192
- return { type: "privateKey", privateKey: requiredString(value, "privateKey") };
193
- }
194
- throw new Error(`cmux.open ssh.auth.type must be "token" or "privateKey"`);
195
- }
196
-
197
175
  function parseRemoteReadyOptions(value: unknown): boolean | CmuxRemoteReadyOptions {
198
176
  if (typeof value === "boolean") return value;
199
177
  if (!isRecord(value)) throw new Error(`cmux.open waitForRemoteReady must be a boolean or object`);
@@ -208,27 +186,22 @@ function cmuxSshOptionsForInput(ssh: CmuxOpenSshInput): CmuxSshOptions {
208
186
  if (typeof ssh === "string") return { destination: ssh };
209
187
 
210
188
  const destination = ssh.destination ?? sshDestination(ssh);
211
- const sshOptions = [
212
- ...(ssh.auth?.type === "token" ? freestyleTokenSshOptions : []),
213
- ...(ssh.sshOptions ?? []),
214
- ];
215
189
  return {
216
190
  destination,
217
- port: ssh.port,
218
- identity: ssh.identity,
219
- sshOptions,
220
- remoteCommandArgs: ssh.remoteCommandArgs,
221
- initialCommand: ssh.initialCommand,
222
- terminalStartupCommand: ssh.terminalStartupCommand ?? ssh.command,
223
- autoConnect: ssh.autoConnect,
224
- skipDaemonBootstrap: ssh.skipDaemonBootstrap,
191
+ ...(ssh.port !== undefined ? { port: ssh.port } : {}),
192
+ ...(ssh.identity !== undefined ? { identity: ssh.identity } : {}),
193
+ ...(ssh.sshOptions?.length ? { sshOptions: ssh.sshOptions } : {}),
194
+ ...(ssh.remoteCommandArgs !== undefined ? { remoteCommandArgs: ssh.remoteCommandArgs } : {}),
195
+ ...(ssh.initialCommand !== undefined ? { initialCommand: ssh.initialCommand } : {}),
196
+ ...(ssh.terminalStartupCommand !== undefined ? { terminalStartupCommand: ssh.terminalStartupCommand } : {}),
197
+ ...(ssh.autoConnect !== undefined ? { autoConnect: ssh.autoConnect } : {}),
198
+ ...(ssh.skipDaemonBootstrap !== undefined ? { skipDaemonBootstrap: ssh.skipDaemonBootstrap } : {}),
225
199
  };
226
200
  }
227
201
 
228
202
  function sshDestination(ssh: Extract<CmuxOpenSshInput, object>): string {
229
203
  if (!ssh.host) throw new Error(`cmux.open ssh.host is required when ssh.destination is omitted`);
230
204
  if (!ssh.username) throw new Error(`cmux.open ssh.username is required when ssh.destination is omitted`);
231
- if (ssh.auth?.type === "token") return `${ssh.username},${ssh.auth.token}@${ssh.host}`;
232
205
  return `${ssh.username}@${ssh.host}`;
233
206
  }
234
207
 
package/src/index.test.ts CHANGED
@@ -6,7 +6,6 @@ import { describe, expect, test } from "bun:test";
6
6
  import type { ProviderStorage, ProviderStorageRecord } from "@rigkit/engine";
7
7
  import type { JsonValue } from "@rigkit/sdk";
8
8
  import {
9
- CMUX_OPEN_CAPABILITY,
10
9
  CmuxCommandError,
11
10
  cmux,
12
11
  cmuxProviderPlugin,
@@ -409,10 +408,8 @@ describe("cmux sdk", () => {
409
408
  name: "website",
410
409
  ssh: {
411
410
  kind: "ssh",
412
- host: "vm-ssh.freestyle.sh",
413
- username: "vm_123",
414
- auth: { type: "token", token: "token_123" },
415
- command: "ssh vm_123:token_123@vm-ssh.freestyle.sh",
411
+ destination: "vm_123,token_123@vm-ssh.freestyle.sh",
412
+ sshOptions: ["ServerAliveInterval=15"],
416
413
  },
417
414
  cwd: "/workspace/site",
418
415
  command: "pnpm dev",
@@ -434,15 +431,7 @@ describe("cmux sdk", () => {
434
431
  params: expect.objectContaining({
435
432
  destination: "vm_123,token_123@vm-ssh.freestyle.sh",
436
433
  name: "website",
437
- terminalStartupCommand: "ssh vm_123:token_123@vm-ssh.freestyle.sh",
438
- sshOptions: [
439
- "StrictHostKeyChecking=no",
440
- "UserKnownHostsFile=/dev/null",
441
- "LogLevel=ERROR",
442
- "IdentitiesOnly=yes",
443
- "IdentityFile=/dev/null",
444
- "ControlMaster=no",
445
- ],
434
+ sshOptions: ["ServerAliveInterval=15"],
446
435
  }),
447
436
  },
448
437
  {
@@ -490,13 +479,36 @@ describe("cmux sdk", () => {
490
479
  params: "workspace-1",
491
480
  },
492
481
  ]);
482
+ expect(calls[0]?.params).not.toHaveProperty("terminalStartupCommand");
483
+ });
484
+
485
+ test("forwards an explicit cmux ssh terminal startup command", async () => {
486
+ const calls: Array<{ method: string; params: unknown }> = [];
487
+ const client = fakeOpenClient(calls);
488
+
489
+ await openCmux({
490
+ name: "website",
491
+ ssh: {
492
+ kind: "ssh",
493
+ destination: "vm_123,token_123@vm-ssh.freestyle.sh",
494
+ terminalStartupCommand: "ssh -tt vm_123:token_123@vm-ssh.freestyle.sh",
495
+ },
496
+ }, { client });
497
+
498
+ expect(calls[0]).toEqual({
499
+ method: "ssh",
500
+ params: expect.objectContaining({
501
+ destination: "vm_123,token_123@vm-ssh.freestyle.sh",
502
+ name: "website",
503
+ terminalStartupCommand: "ssh -tt vm_123:token_123@vm-ssh.freestyle.sh",
504
+ }),
505
+ });
493
506
  });
494
507
 
495
508
  test("exposes a provider facade that requests cmux.open from the local host", async () => {
496
509
  const definition = cmux.provider();
497
510
  expect(definition.providerId).toBe("cmux");
498
511
  expect(definition.plugin).toBe(cmuxProviderPlugin);
499
- expect(cmux.capabilities.open).toBe(CMUX_OPEN_CAPABILITY);
500
512
 
501
513
  const controller = await cmuxProviderPlugin.createProvider({
502
514
  provider: { providerId: "cmux", config: {} },
package/src/index.ts CHANGED
@@ -487,6 +487,8 @@ export {
487
487
  cmux,
488
488
  cmuxProviderPlugin,
489
489
  provider as defineCmuxProvider,
490
+ parseCmuxOpenResult,
491
+ requestCmuxOpen,
490
492
  type CmuxProviderDefinition,
491
493
  type CmuxRuntime,
492
494
  } from "./provider.ts";
package/src/provider.ts CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  } from "@rigkit/sdk";
6
6
  import type { BaseProviderPlugin, WorkflowProviderController } from "@rigkit/engine";
7
7
  import {
8
- CMUX_OPEN_CAPABILITY,
9
8
  CMUX_OPEN_CAPABILITY_ID,
10
9
  type CmuxOpenInput,
11
10
  type CmuxOpenResult,
@@ -30,10 +29,6 @@ export function provider(): CmuxProviderDefinition {
30
29
 
31
30
  export const cmux = {
32
31
  provider,
33
- capability: CMUX_OPEN_CAPABILITY,
34
- capabilities: {
35
- open: CMUX_OPEN_CAPABILITY,
36
- },
37
32
  };
38
33
 
39
34
  export const cmuxProviderPlugin: BaseProviderPlugin = {
@@ -50,29 +45,34 @@ export const cmuxProviderPlugin: BaseProviderPlugin = {
50
45
 
51
46
  function createCmuxRuntime(local: LocalWorkspaceRuntime): CmuxRuntime {
52
47
  return {
53
- async open(input) {
54
- if (local.requestCapabilitySession) {
55
- const session = await local.requestCapabilitySession<CmuxOpenResult>(CMUX_OPEN_CAPABILITY_ID, input);
56
- return {
57
- ...parseCmuxOpenResult(session.result),
58
- closed: session.closed,
59
- };
60
- }
61
- if (!local.requestCapability) {
62
- throw new Error(`Host capability ${CMUX_OPEN_CAPABILITY_ID} is unavailable in this runtime`);
63
- }
64
- const result = parseCmuxOpenResult(
65
- await local.requestCapability(CMUX_OPEN_CAPABILITY_ID, input),
66
- );
67
- return {
68
- ...result,
69
- closed: new Promise<void>(() => {}),
70
- };
71
- },
48
+ open: async (input) => await requestCmuxOpen(local, input),
49
+ };
50
+ }
51
+
52
+ export async function requestCmuxOpen(
53
+ local: LocalWorkspaceRuntime,
54
+ input: CmuxOpenInput,
55
+ ): Promise<CmuxOpenSession> {
56
+ if (local.requestCapabilitySession) {
57
+ const session = await local.requestCapabilitySession<CmuxOpenResult>(CMUX_OPEN_CAPABILITY_ID, input);
58
+ return {
59
+ ...parseCmuxOpenResult(session.result),
60
+ closed: session.closed,
61
+ };
62
+ }
63
+ if (!local.requestCapability) {
64
+ throw new Error(`Host capability ${CMUX_OPEN_CAPABILITY_ID} is unavailable in this runtime`);
65
+ }
66
+ const result = parseCmuxOpenResult(
67
+ await local.requestCapability(CMUX_OPEN_CAPABILITY_ID, input),
68
+ );
69
+ return {
70
+ ...result,
71
+ closed: new Promise<void>(() => {}),
72
72
  };
73
73
  }
74
74
 
75
- function parseCmuxOpenResult(value: unknown): CmuxOpenResult {
75
+ export function parseCmuxOpenResult(value: unknown): CmuxOpenResult {
76
76
  if (!isRecord(value)) throw new Error(`cmux.open returned a non-object result`);
77
77
  const sessionId = stringField(value, "sessionId");
78
78
  if (!sessionId) throw new Error(`cmux.open result is missing sessionId`);
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const RIGKIT_PROVIDER_CMUX_VERSION = "0.2.1";
1
+ export const RIGKIT_PROVIDER_CMUX_VERSION = "0.2.3";