@freestyle-sh/with-opencode 0.0.1 → 0.0.2

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
@@ -50,19 +50,59 @@ const { client } = await vm.opencode.client({
50
50
  });
51
51
  ```
52
52
 
53
+ ### With Authentication
54
+
55
+ ```typescript
56
+ import { freestyle, VmSpec } from "freestyle-sandboxes";
57
+ import { VmOpenCode } from "@freestyle-sh/with-opencode";
58
+
59
+ const { vm } = await freestyle.vms.create({
60
+ spec: new VmSpec({
61
+ with: {
62
+ opencode: new VmOpenCode({
63
+ server: {
64
+ username: "serveradmin",
65
+ password: "secret-server-pass",
66
+ },
67
+ web: {
68
+ username: "webadmin",
69
+ password: "secret-web-pass",
70
+ },
71
+ }),
72
+ },
73
+ }),
74
+ });
75
+
76
+ // URLs will include credentials automatically
77
+ const { url } = await vm.opencode.routeWeb();
78
+ const { client } = await vm.opencode.client();
79
+ ```
80
+
53
81
  ## Options
54
82
 
55
83
  ```typescript
56
84
  new VmOpenCode({
57
- serverPort: 4096, // Optional: API server port (default: 4096)
58
- webPort: 4097, // Optional: Web UI port (default: 4097)
59
- })
85
+ server: {
86
+ port: 4096, // Optional: API server port (default: 4096)
87
+ username: "admin", // Optional: Basic auth username (default: "opencode" when password is set)
88
+ password: "secret", // Optional: Basic auth password
89
+ },
90
+ web: {
91
+ port: 4097, // Optional: Web UI port (default: 4097)
92
+ username: "admin", // Optional: Basic auth username (default: "opencode" when password is set)
93
+ password: "secret", // Optional: Basic auth password
94
+ },
95
+ });
60
96
  ```
61
97
 
62
- | Option | Type | Default | Description |
63
- |--------|------|---------|-------------|
64
- | `serverPort` | `number` | `4096` | Port for the OpenCode API server |
65
- | `webPort` | `number` | `4097` | Port for the OpenCode web UI |
98
+ | Option | Type | Default | Description |
99
+ | ----------------- | -------- | ------------ | ------------------------------------------------ |
100
+ | `server.port` | `number` | `4096` | Port for the OpenCode API server |
101
+ | `server.username` | `string` | `"opencode"` | Basic auth username (only used if password set) |
102
+ | `server.password` | `string` | - | Basic auth password for the API server |
103
+ | `web.port` | `number` | `4097` | Port for the OpenCode web UI |
104
+ | `web.username` | `string` | `"opencode"` | Basic auth username (only used if password set) |
105
+ | `web.password` | `string` | - | Basic auth password for the web UI |
66
106
 
67
107
  ## API
68
108
 
@@ -71,9 +111,10 @@ new VmOpenCode({
71
111
  Exposes the OpenCode web UI on a public domain.
72
112
 
73
113
  **Options:**
114
+
74
115
  - `domain?: string` - Custom domain to use. If not specified, generates a random subdomain.
75
116
 
76
- **Returns:** `Promise<{ url: string }>`
117
+ **Returns:** `Promise<{ url: string }>` - URL includes credentials if authentication is configured.
77
118
 
78
119
  ```typescript
79
120
  const { url } = await vm.opencode.routeWeb();
@@ -82,9 +123,10 @@ console.log(`OpenCode UI available at: ${url}`);
82
123
 
83
124
  ### `vm.opencode.client(options?)`
84
125
 
85
- Creates an OpenCode SDK client connected to the server.
126
+ Creates an OpenCode SDK client connected to the server. The client is automatically configured with credentials if authentication is enabled.
86
127
 
87
128
  **Options:**
129
+
88
130
  - `domain?: string` - Custom domain for the API endpoint. If not specified, generates a random subdomain.
89
131
 
90
132
  **Returns:** `Promise<{ client: OpencodeClient }>`
package/dist/index.d.ts CHANGED
@@ -2,13 +2,32 @@ import * as freestyle_sandboxes from 'freestyle-sandboxes';
2
2
  import { VmWith, VmWithInstance, VmSpec } from 'freestyle-sandboxes';
3
3
  import * as _opencode_ai_sdk from '@opencode-ai/sdk';
4
4
 
5
+ type OpenCodeAuthOptions = {
6
+ password?: string;
7
+ username?: string;
8
+ };
9
+ type ResolvedOpenCodeAuthOptions = {
10
+ password: string;
11
+ username: string;
12
+ } | {
13
+ password?: undefined;
14
+ username?: undefined;
15
+ };
5
16
  type OpenCodeOptions = {
6
- serverPort?: number;
7
- webPort?: number;
17
+ server?: {
18
+ port?: number;
19
+ } & OpenCodeAuthOptions;
20
+ web?: {
21
+ port?: number;
22
+ } & OpenCodeAuthOptions;
8
23
  };
9
24
  type OpenCodeResolvedOptions = {
10
- serverPort: number;
11
- webPort: number;
25
+ server: {
26
+ port: number;
27
+ } & ResolvedOpenCodeAuthOptions;
28
+ web: {
29
+ port: number;
30
+ } & ResolvedOpenCodeAuthOptions;
12
31
  };
13
32
  declare class VmOpenCode extends VmWith<VmOpenCodeInstance> {
14
33
  options: OpenCodeResolvedOptions;
@@ -37,4 +56,4 @@ declare class VmOpenCodeInstance extends VmWithInstance {
37
56
  }
38
57
 
39
58
  export { VmOpenCode };
40
- export type { OpenCodeOptions, OpenCodeResolvedOptions };
59
+ export type { OpenCodeAuthOptions, OpenCodeOptions, OpenCodeResolvedOptions, ResolvedOpenCodeAuthOptions };
package/dist/index.js CHANGED
@@ -1,16 +1,24 @@
1
1
  import { VmWith, VmSpec, VmWithInstance } from 'freestyle-sandboxes';
2
2
  import { createOpencodeClient } from '@opencode-ai/sdk';
3
3
 
4
+ function resolveAuth(opts) {
5
+ return opts?.password ? { password: opts.password, username: opts.username ?? "opencode" } : {};
6
+ }
4
7
  class VmOpenCode extends VmWith {
5
8
  options;
6
9
  constructor(options) {
7
10
  super();
8
11
  this.options = {
9
- serverPort: options?.serverPort ?? 4096,
10
- webPort: options?.webPort ?? 4097
12
+ server: {
13
+ port: options?.server?.port ?? 4096,
14
+ ...resolveAuth(options?.server)
15
+ },
16
+ web: { port: options?.web?.port ?? 4097, ...resolveAuth(options?.web) }
11
17
  };
12
18
  }
13
19
  configureSnapshotSpec(spec) {
20
+ const webAuthEnv = this.options.web.username ? `OPENCODE_SERVER_USERNAME=${this.options.web.username} OPENCODE_SERVER_PASSWORD=${this.options.web.password}`.trim() : "";
21
+ const serverAuthEnv = this.options.server.username ? `OPENCODE_SERVER_USERNAME=${this.options.server.username} OPENCODE_SERVER_PASSWORD=${this.options.server.password}`.trim() : "";
14
22
  return this.composeSpecs(
15
23
  spec,
16
24
  new VmSpec({
@@ -27,7 +35,7 @@ class VmOpenCode extends VmWith {
27
35
  #!/bin/bash
28
36
 
29
37
  export PATH="$HOME/.local/bin:$PATH"
30
- /root/.opencode/bin/opencode web --hostname 0.0.0.0 --port ${this.options.webPort}
38
+ ${webAuthEnv} /root/.opencode/bin/opencode web --hostname 0.0.0.0 --port ${this.options.web.port}
31
39
  `
32
40
  },
33
41
  "/opt/run-opencode-server.sh": {
@@ -35,7 +43,7 @@ class VmOpenCode extends VmWith {
35
43
  #!/bin/bash
36
44
 
37
45
  export PATH="$HOME/.local/bin:$PATH"
38
- /root/.opencode/bin/opencode serve --hostname 0.0.0.0 --port ${this.options.serverPort}
46
+ ${serverAuthEnv} /root/.opencode/bin/opencode serve --hostname 0.0.0.0 --port ${this.options.server.port}
39
47
  `
40
48
  }
41
49
  },
@@ -95,10 +103,10 @@ class VmOpenCodeInstance extends VmWithInstance {
95
103
  this.builder = builder;
96
104
  }
97
105
  webPort() {
98
- return this.builder.options.webPort;
106
+ return this.builder.options.web.port;
99
107
  }
100
108
  serverPort() {
101
- return this.builder.options.serverPort;
109
+ return this.builder.options.server.port;
102
110
  }
103
111
  async client({ domain } = {}) {
104
112
  const resolvedDomain = domain ?? `${crypto.randomUUID()}-opencode.style.dev`;
@@ -110,7 +118,12 @@ class VmOpenCodeInstance extends VmWithInstance {
110
118
  });
111
119
  return {
112
120
  client: createOpencodeClient({
113
- baseUrl: `https://${resolvedDomain}`
121
+ baseUrl: `https://${resolvedDomain}`,
122
+ headers: this.builder.options.server.username ? {
123
+ Authorization: `Basic ${btoa(
124
+ `${this.builder.options.server.username}:${this.builder.options.server.password}`
125
+ )}`
126
+ } : {}
114
127
  })
115
128
  };
116
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freestyle-sh/with-opencode",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "packageManager": "pnpm@10.11.0",
5
5
  "private": false,
6
6
  "dependencies": {