@rigkit/provider-freestyle 0.2.6 → 0.2.8

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
@@ -12,6 +12,6 @@ This package supplies:
12
12
  - Freestyle SDK exports like `VmSpec` and `VmBaseImage`, so configs use one SDK instance for specs and clients
13
13
  - Freestyle-specific JSON state helpers backed by Rigkit provider storage
14
14
 
15
- Pass Rigkit's `step.log` to Freestyle SDK calls that accept `logger` to stream SDK progress into the CLI.
15
+ Pass `console.log` to Freestyle SDK calls that accept `logger` to stream SDK progress into the CLI. Console output inside a task handler is intercepted by the Rigkit runtime and emitted as leveled `log.output` events.
16
16
 
17
- By default the provider authenticates through a browser login and stores Freestyle credentials in Rigkit's provider host storage, outside project `.rigkit/state.sqlite`. Pass `auth: { apiKey }` to use API-key auth instead.
17
+ By default the provider authenticates through a browser login and stores Freestyle credentials in Rigkit's provider host storage, outside project `.rigkit/state.sqlite`. Pass `freestyle.provider({ apiKey })` or `freestyle.provider(apiKey)` to use API-key auth instead.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigkit/provider-freestyle",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,9 +17,9 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "zod": "^4",
20
- "@rigkit/sdk": "0.2.6",
21
- "@rigkit/provider-cmux": "0.2.6",
22
- "@rigkit/engine": "0.2.6"
20
+ "@rigkit/sdk": "0.2.8",
21
+ "@rigkit/engine": "0.2.8",
22
+ "@rigkit/provider-cmux": "0.2.8"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "freestyle": "^0.1.51"
@@ -7,9 +7,10 @@ import type {
7
7
  WorkflowProviderController,
8
8
  WorkflowEvent,
9
9
  } from "@rigkit/engine";
10
- import { FREESTYLE_PROVIDER_ID, freestyleProviderPlugin } from "./index.ts";
10
+ import { FREESTYLE_PROVIDER_ID, freestyle, freestyleProviderPlugin } from "./index.ts";
11
11
  import { createFreestyleProxyFetch } from "./host-auth.ts";
12
12
  import type { FreestyleRuntime } from "./provider.ts";
13
+ import { RIGKIT_PROVIDER_FREESTYLE_VERSION } from "./version.ts";
13
14
 
14
15
  const originalFreestyleApiKey = process.env.FREESTYLE_API_KEY;
15
16
  const originalFreestyleTeamId = process.env.FREESTYLE_TEAM_ID;
@@ -20,19 +21,54 @@ afterEach(() => {
20
21
  });
21
22
 
22
23
  describe("Freestyle provider host auth", () => {
24
+ test("accepts an API key as the provider shorthand", () => {
25
+ expect(freestyle.provider("shorthand-api-key").config).toEqual({
26
+ apiKey: "shorthand-api-key",
27
+ });
28
+ });
29
+
30
+ test("rejects the old nested auth config shape", async () => {
31
+ const projectStorage = new MemoryProviderStorage(FREESTYLE_PROVIDER_ID);
32
+ const hostStorage = new MemoryProviderStorage(FREESTYLE_PROVIDER_ID);
33
+
34
+ await expect(freestyleProviderPlugin.createProvider({
35
+ provider: {
36
+ providerId: FREESTYLE_PROVIDER_ID,
37
+ config: {
38
+ auth: { apiKey: "nested-api-key" },
39
+ },
40
+ },
41
+ storage: projectStorage,
42
+ hostStorage,
43
+ local: { open: async () => {} },
44
+ })).rejects.toThrow("Invalid Freestyle provider config");
45
+ });
46
+
23
47
  test("uses explicit API-key auth and stores identity tokens in host storage", async () => {
24
48
  process.env.FREESTYLE_API_KEY = "ignored-env-api-key";
25
49
  delete process.env.FREESTYLE_TEAM_ID;
26
50
 
27
51
  const projectStorage = new MemoryProviderStorage(FREESTYLE_PROVIDER_ID);
28
52
  const hostStorage = new MemoryProviderStorage(FREESTYLE_PROVIDER_ID);
29
- const requests: Array<{ url: string; method: string; authorization: string | null }> = [];
53
+ const requests: Array<{
54
+ url: string;
55
+ method: string;
56
+ authorization: string | null;
57
+ rigkit: string | null;
58
+ rigkitVersion: string | null;
59
+ }> = [];
30
60
  const previousFetch = globalThis.fetch;
31
61
  globalThis.fetch = testFetch((resource, init) => {
32
62
  const url = resourceUrl(resource);
33
63
  const method = init?.method ?? "GET";
34
- const authorization = new Headers(init?.headers).get("authorization");
35
- requests.push({ url: url.href, method, authorization });
64
+ const headers = new Headers(init?.headers);
65
+ requests.push({
66
+ url: url.href,
67
+ method,
68
+ authorization: headers.get("authorization"),
69
+ rigkit: headers.get("x-rigkit"),
70
+ rigkitVersion: headers.get("x-rigkit-version"),
71
+ });
36
72
  if (url.pathname === "/identity/v1/identities" && method === "POST") {
37
73
  return Response.json({ id: "identity-api-key" });
38
74
  }
@@ -47,7 +83,7 @@ describe("Freestyle provider host auth", () => {
47
83
  provider: {
48
84
  providerId: FREESTYLE_PROVIDER_ID,
49
85
  config: {
50
- auth: { apiKey: "object-api-key" },
86
+ apiKey: "object-api-key",
51
87
  },
52
88
  },
53
89
  storage: projectStorage,
@@ -72,11 +108,15 @@ describe("Freestyle provider host auth", () => {
72
108
  url: "https://api.freestyle.sh/identity/v1/identities",
73
109
  method: "POST",
74
110
  authorization: "Bearer object-api-key",
111
+ rigkit: "true",
112
+ rigkitVersion: RIGKIT_PROVIDER_FREESTYLE_VERSION,
75
113
  },
76
114
  {
77
115
  url: "https://api.freestyle.sh/identity/v1/identities/identity-api-key/tokens",
78
116
  method: "POST",
79
117
  authorization: "Bearer object-api-key",
118
+ rigkit: "true",
119
+ rigkitVersion: RIGKIT_PROVIDER_FREESTYLE_VERSION,
80
120
  },
81
121
  ]);
82
122
  } finally {
@@ -122,9 +162,7 @@ describe("Freestyle provider host auth", () => {
122
162
  provider: {
123
163
  providerId: FREESTYLE_PROVIDER_ID,
124
164
  config: {
125
- auth: {
126
- teamId: "team_123",
127
- },
165
+ teamId: "team_123",
128
166
  },
129
167
  },
130
168
  storage: projectStorage,
@@ -160,7 +198,10 @@ describe("Freestyle provider host auth", () => {
160
198
  teamId: "team_123",
161
199
  path: "identity/v1/identities",
162
200
  method: "POST",
163
- headers: expect.any(Object),
201
+ headers: expect.objectContaining({
202
+ "x-rigkit": "true",
203
+ "x-rigkit-version": RIGKIT_PROVIDER_FREESTYLE_VERSION,
204
+ }),
164
205
  },
165
206
  },
166
207
  {
@@ -169,7 +210,10 @@ describe("Freestyle provider host auth", () => {
169
210
  teamId: "team_123",
170
211
  path: "identity/v1/identities/identity-browser/tokens",
171
212
  method: "POST",
172
- headers: expect.any(Object),
213
+ headers: expect.objectContaining({
214
+ "x-rigkit": "true",
215
+ "x-rigkit-version": RIGKIT_PROVIDER_FREESTYLE_VERSION,
216
+ }),
173
217
  },
174
218
  },
175
219
  ]);
@@ -258,6 +302,8 @@ describe("Freestyle provider proxy fetch", () => {
258
302
  const url = resourceUrl(resource);
259
303
  expect(url.href).toBe("https://dash.freestyle.sh/api/proxy/request");
260
304
  expect(init?.method).toBe("POST");
305
+ expect(new Headers(init?.headers).get("x-rigkit")).toBe("true");
306
+ expect(new Headers(init?.headers).get("x-rigkit-version")).toBe(RIGKIT_PROVIDER_FREESTYLE_VERSION);
261
307
 
262
308
  const body = JSON.parse(String(init?.body));
263
309
  expect(body).toMatchObject({
@@ -266,6 +312,10 @@ describe("Freestyle provider proxy fetch", () => {
266
312
  teamId: "team_123",
267
313
  path: "v1/vms",
268
314
  method: "POST",
315
+ headers: {
316
+ "x-rigkit": "true",
317
+ "x-rigkit-version": RIGKIT_PROVIDER_FREESTYLE_VERSION,
318
+ },
269
319
  },
270
320
  });
271
321
 
@@ -290,6 +340,65 @@ describe("Freestyle provider proxy fetch", () => {
290
340
  status: "pending",
291
341
  });
292
342
  });
343
+
344
+ test("preserves proxy error details for run logs", async () => {
345
+ const proxyFetch = createFreestyleProxyFetch({
346
+ dashboardUrl: "https://dash.freestyle.sh",
347
+ accessToken: "stack-access-token",
348
+ teamId: "team_123",
349
+ fetch: testFetch(async () =>
350
+ Response.json({
351
+ error: "VM setup failed",
352
+ requestId: "req_123",
353
+ logs: ["failed to boot base image"],
354
+ accessToken: "secret-token",
355
+ }, { status: 500 })
356
+ ),
357
+ });
358
+
359
+ const response = await proxyFetch("https://api.freestyle.sh/v1/vms", {
360
+ method: "POST",
361
+ body: "{}",
362
+ });
363
+
364
+ expect(response.status).toBe(500);
365
+ await expect(response.json()).resolves.toEqual({
366
+ code: "INTERNAL_ERROR",
367
+ message: "VM setup failed",
368
+ details: {
369
+ error: "VM setup failed",
370
+ requestId: "req_123",
371
+ logs: ["failed to boot base image"],
372
+ accessToken: "[redacted]",
373
+ },
374
+ });
375
+ });
376
+
377
+ test("redacts sensitive fields on coded proxy errors", async () => {
378
+ const proxyFetch = createFreestyleProxyFetch({
379
+ dashboardUrl: "https://dash.freestyle.sh",
380
+ accessToken: "stack-access-token",
381
+ teamId: "team_123",
382
+ fetch: testFetch(async () =>
383
+ Response.json({
384
+ code: "INTERNAL_ERROR",
385
+ message: "Internal server error",
386
+ requestId: "req_123",
387
+ accessToken: "secret-token",
388
+ }, { status: 500 })
389
+ ),
390
+ });
391
+
392
+ const response = await proxyFetch("https://api.freestyle.sh/v1/vms");
393
+
394
+ expect(response.status).toBe(500);
395
+ await expect(response.json()).resolves.toEqual({
396
+ code: "INTERNAL_ERROR",
397
+ message: "Internal server error",
398
+ requestId: "req_123",
399
+ accessToken: "[redacted]",
400
+ });
401
+ });
293
402
  });
294
403
 
295
404
  class MemoryProviderStorage implements ProviderStorage {
package/src/host-auth.ts CHANGED
@@ -4,6 +4,7 @@ import type { LocalWorkspaceRuntime, ProviderStorage } from "@rigkit/engine";
4
4
  import type { JsonValue } from "@rigkit/sdk";
5
5
  import { freestyleIdentityId, freestyleToken, freestyleTokenId } from "./auth.ts";
6
6
  import { createFreestyleStore } from "./store.ts";
7
+ import { RIGKIT_PROVIDER_FREESTYLE_VERSION } from "./version.ts";
7
8
 
8
9
  const DEFAULT_STACK_API_URL = "https://api.stack-auth.com";
9
10
  const DEFAULT_STACK_APP_URL = "https://dash.freestyle.sh";
@@ -11,17 +12,15 @@ const DEFAULT_STACK_PROJECT_ID = "0edf478c-f123-46fb-818f-34c0024a9f35";
11
12
  const DEFAULT_STACK_PUBLISHABLE_CLIENT_KEY = "pck_h2aft7g9pqjzrkdnzs199h1may5wjtdtdxeex7m2wzp1r";
12
13
  const DEFAULT_CLI_AUTH_TIMEOUT_MILLIS = 10 * 60 * 1000;
13
14
  const DEFAULT_POLL_INTERVAL_MILLIS = 2000;
15
+ const RIGKIT_HEADER = "x-rigkit";
16
+ const RIGKIT_VERSION_HEADER = "x-rigkit-version";
14
17
 
15
- export type FreestyleProviderAuthConfig = {
18
+ export type FreestyleProviderConfig = {
16
19
  apiKey?: string;
17
20
  profile?: string;
18
21
  teamId?: string;
19
22
  apiUrl?: string;
20
23
  dashboardUrl?: string;
21
- stackApiUrl?: string;
22
- stackAppUrl?: string;
23
- stackProjectId?: string;
24
- stackPublishableClientKey?: string;
25
24
  };
26
25
 
27
26
  export type FreestyleAuthenticatedClient = {
@@ -32,7 +31,7 @@ export type FreestyleAuthenticatedClient = {
32
31
  };
33
32
 
34
33
  type CreateFreestyleAuthenticatedClientInput = {
35
- auth?: FreestyleProviderAuthConfig;
34
+ config?: FreestyleProviderConfig;
36
35
  hostStorage: ProviderStorage;
37
36
  local: LocalWorkspaceRuntime;
38
37
  fetch?: typeof fetch;
@@ -119,16 +118,16 @@ export function createFreestyleProxyFetch(input: {
119
118
  const path = `${url.pathname}${url.search}`.replace(/^\/+/, "");
120
119
  const proxyResponse = await fetchFn(`${dashboardUrl}/api/proxy/request`, {
121
120
  method: "POST",
122
- headers: {
121
+ headers: withRigkitHeaders({
123
122
  "Content-Type": "application/json",
124
- },
123
+ }),
125
124
  body: JSON.stringify({
126
125
  data: {
127
126
  accessToken: input.accessToken,
128
127
  teamId: input.teamId,
129
128
  path,
130
129
  method: init?.method ?? "GET",
131
- headers: init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {},
130
+ headers: Object.fromEntries(withRigkitHeaders(init?.headers).entries()),
132
131
  body: init?.body ? String(init.body) : undefined,
133
132
  },
134
133
  }),
@@ -162,9 +161,20 @@ export function createFreestyleProxyFetch(input: {
162
161
  }) as typeof fetch;
163
162
  }
164
163
 
164
+ export function createFreestyleSdkFetch(fetchFn: typeof fetch = globalThis.fetch): typeof fetch {
165
+ const rigkitFetch = (async (resource, init) =>
166
+ await fetchFn(resource, {
167
+ ...init,
168
+ headers: withRigkitHeaders(init?.headers),
169
+ })) as typeof fetch;
170
+ return Object.assign(rigkitFetch, {
171
+ preconnect: fetchFn.preconnect?.bind(fetchFn) ?? (() => {}),
172
+ }) as typeof fetch;
173
+ }
174
+
165
175
  async function resolveClientAuth(input: CreateFreestyleAuthenticatedClientInput): Promise<ResolvedClientAuth> {
166
- const apiKey = nonEmpty(input.auth?.apiKey);
167
- const apiUrl = nonEmpty(input.auth?.apiUrl) ?? nonEmpty(process.env.FREESTYLE_API_URL);
176
+ const apiKey = nonEmpty(input.config?.apiKey);
177
+ const apiUrl = nonEmpty(input.config?.apiUrl) ?? nonEmpty(process.env.FREESTYLE_API_URL);
168
178
  const fetchFn = input.fetch ?? globalThis.fetch;
169
179
 
170
180
  if (apiKey) {
@@ -172,13 +182,13 @@ async function resolveClientAuth(input: CreateFreestyleAuthenticatedClientInput)
172
182
  client: new Freestyle({
173
183
  apiKey,
174
184
  ...(apiUrl ? { baseUrl: apiUrl } : {}),
175
- fetch: fetchFn,
185
+ fetch: createFreestyleSdkFetch(fetchFn),
176
186
  }),
177
187
  identityKey: `api-key:${fingerprint({ apiUrl: apiUrl ?? "default", apiKey })}`,
178
188
  };
179
189
  }
180
190
 
181
- const stack = resolveStackAuthConfig(input.auth);
191
+ const stack = resolveStackAuthConfig(input.config);
182
192
  const stackStateKey = stackAuthStateKey(stack);
183
193
  const stored = readStackAuthState(input.hostStorage.get(stackStateKey)?.value);
184
194
  const refreshed = await resolveStackAccessToken({
@@ -192,7 +202,7 @@ async function resolveClientAuth(input: CreateFreestyleAuthenticatedClientInput)
192
202
  pollIntervalMs: input.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MILLIS,
193
203
  });
194
204
  const teamId = await resolveTeamId({
195
- configuredTeamId: input.auth?.teamId,
205
+ configuredTeamId: input.config?.teamId,
196
206
  stored: readStackAuthState(input.hostStorage.get(stackStateKey)?.value) ?? stored,
197
207
  accessToken: refreshed.accessToken,
198
208
  config: stack,
@@ -222,7 +232,7 @@ async function resolveClientAuth(input: CreateFreestyleAuthenticatedClientInput)
222
232
  };
223
233
  }
224
234
 
225
- function resolveStackAuthConfig(auth: FreestyleProviderAuthConfig | undefined): StackAuthConfig {
235
+ function resolveStackAuthConfig(auth: FreestyleProviderConfig | undefined): StackAuthConfig {
226
236
  const dashboardUrl = trimTrailingSlash(
227
237
  nonEmpty(auth?.dashboardUrl) ??
228
238
  nonEmpty(process.env.FREESTYLE_DASHBOARD_URL) ??
@@ -230,25 +240,21 @@ function resolveStackAuthConfig(auth: FreestyleProviderAuthConfig | undefined):
230
240
  );
231
241
  return {
232
242
  stackApiUrl: trimTrailingSlash(
233
- nonEmpty(auth?.stackApiUrl) ??
234
- nonEmpty(process.env.FREESTYLE_STACK_API_URL) ??
243
+ nonEmpty(process.env.FREESTYLE_STACK_API_URL) ??
235
244
  DEFAULT_STACK_API_URL,
236
245
  ),
237
246
  appUrl: trimTrailingSlash(
238
- nonEmpty(auth?.stackAppUrl) ??
239
- nonEmpty(process.env.FREESTYLE_STACK_APP_URL) ??
247
+ nonEmpty(process.env.FREESTYLE_STACK_APP_URL) ??
240
248
  dashboardUrl,
241
249
  ),
242
250
  dashboardUrl,
243
251
  projectId:
244
- nonEmpty(auth?.stackProjectId) ??
245
- nonEmpty(process.env.FREESTYLE_STACK_PROJECT_ID) ??
252
+ nonEmpty(process.env.FREESTYLE_STACK_PROJECT_ID) ??
246
253
  nonEmpty(process.env.NEXT_PUBLIC_STACK_PROJECT_ID) ??
247
254
  nonEmpty(process.env.VITE_STACK_PROJECT_ID) ??
248
255
  DEFAULT_STACK_PROJECT_ID,
249
256
  publishableClientKey:
250
- nonEmpty(auth?.stackPublishableClientKey) ??
251
- nonEmpty(process.env.FREESTYLE_STACK_PUBLISHABLE_CLIENT_KEY) ??
257
+ nonEmpty(process.env.FREESTYLE_STACK_PUBLISHABLE_CLIENT_KEY) ??
252
258
  nonEmpty(process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY) ??
253
259
  nonEmpty(process.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY) ??
254
260
  DEFAULT_STACK_PUBLISHABLE_CLIENT_KEY,
@@ -256,6 +262,13 @@ function resolveStackAuthConfig(auth: FreestyleProviderAuthConfig | undefined):
256
262
  };
257
263
  }
258
264
 
265
+ function withRigkitHeaders(headers: HeadersInit | undefined): Headers {
266
+ const next = new Headers(headers);
267
+ next.set(RIGKIT_HEADER, "true");
268
+ next.set(RIGKIT_VERSION_HEADER, RIGKIT_PROVIDER_FREESTYLE_VERSION);
269
+ return next;
270
+ }
271
+
259
272
  async function resolveStackAccessToken(input: {
260
273
  config: StackAuthConfig;
261
274
  storage: ProviderStorage;
@@ -432,7 +445,7 @@ async function resolveTeamId(input: {
432
445
 
433
446
  const choices = teams.map((team) => `${team.displayName ?? team.id} (${team.id})`).join(", ");
434
447
  throw new Error(
435
- `Freestyle authentication found multiple teams. Set freestyle.provider({ auth: { teamId } }) or FREESTYLE_TEAM_ID. Teams: ${choices}`,
448
+ `Freestyle authentication found multiple teams. Set freestyle.provider({ teamId }) or FREESTYLE_TEAM_ID. Teams: ${choices}`,
436
449
  );
437
450
  }
438
451
 
@@ -515,14 +528,14 @@ function normalizeProxyError(errorText: string, status: number): { body: string;
515
528
  try {
516
529
  const parsed = JSON.parse(errorText) as Record<string, unknown>;
517
530
  if (typeof parsed.code === "string" && typeof parsed.message === "string") {
518
- return { body: JSON.stringify(parsed), contentType: "application/json" };
531
+ return { body: JSON.stringify(redactProxyErrorDetails(parsed)), contentType: "application/json" };
519
532
  }
520
533
  const message = [parsed.error, parsed.message, parsed.reason].find((value) =>
521
534
  typeof value === "string" && value.length > 0
522
535
  );
523
536
  if (typeof message === "string") {
524
537
  return {
525
- body: JSON.stringify({ code: fallbackCode, message }),
538
+ body: JSON.stringify({ code: fallbackCode, message, details: redactProxyErrorDetails(parsed) }),
526
539
  contentType: "application/json",
527
540
  };
528
541
  }
@@ -535,6 +548,17 @@ function normalizeProxyError(errorText: string, status: number): { body: string;
535
548
  };
536
549
  }
537
550
 
551
+ function redactProxyErrorDetails(value: Record<string, unknown>): Record<string, unknown> {
552
+ const details: Record<string, unknown> = {};
553
+ for (const [key, field] of Object.entries(value)) {
554
+ details[key] = /authorization|api[-_]?key|access[-_]?token|refresh[-_]?token|password|secret|credential|cookie/i
555
+ .test(key)
556
+ ? "[redacted]"
557
+ : field;
558
+ }
559
+ return details;
560
+ }
561
+
538
562
  function isBackgroundRequestPending(value: unknown): boolean {
539
563
  return Boolean(
540
564
  isRecord(value) &&
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ import { freestyleIdentityId, freestyleToken, freestyleTokenId } from "./auth.ts
8
8
  import {
9
9
  createFreestyleAuthenticatedClient,
10
10
  createFreestyleProxyFetch,
11
- type FreestyleProviderAuthConfig,
11
+ type FreestyleProviderConfig,
12
12
  } from "./host-auth.ts";
13
13
  import {
14
14
  FREESTYLE_PROVIDER_ID,
@@ -18,22 +18,15 @@ import {
18
18
  } from "./provider.ts";
19
19
  import type { FreestyleRuntime, FreestyleTerminalRuntime } from "./provider.ts";
20
20
 
21
- const freestyleProviderConfigSchema = z.object({
22
- auth: z.optional(z.object({
23
- apiKey: z.optional(z.string().check(z.minLength(1))),
24
- profile: z.optional(z.string().check(z.minLength(1))),
25
- teamId: z.optional(z.string().check(z.minLength(1))),
26
- apiUrl: z.optional(z.string().check(z.minLength(1))),
27
- dashboardUrl: z.optional(z.string().check(z.minLength(1))),
28
- stackApiUrl: z.optional(z.string().check(z.minLength(1))),
29
- stackAppUrl: z.optional(z.string().check(z.minLength(1))),
30
- stackProjectId: z.optional(z.string().check(z.minLength(1))),
31
- stackPublishableClientKey: z.optional(z.string().check(z.minLength(1))),
32
- })),
21
+ const freestyleProviderConfigSchema = z.strictObject({
22
+ apiKey: z.optional(z.string().check(z.minLength(1))),
23
+ profile: z.optional(z.string().check(z.minLength(1))),
24
+ teamId: z.optional(z.string().check(z.minLength(1))),
25
+ apiUrl: z.optional(z.string().check(z.minLength(1))),
26
+ dashboardUrl: z.optional(z.string().check(z.minLength(1))),
33
27
  });
34
28
 
35
- export type FreestyleProviderConfig = z.output<typeof freestyleProviderConfigSchema>;
36
- export type { FreestyleProviderAuthConfig };
29
+ export type { FreestyleProviderConfig };
37
30
 
38
31
  export type FreestyleProviderDefinition = WorkflowProviderDefinition<
39
32
  typeof FREESTYLE_PROVIDER_ID,
@@ -41,6 +34,10 @@ export type FreestyleProviderDefinition = WorkflowProviderDefinition<
41
34
  FreestyleRuntime
42
35
  >;
43
36
 
37
+ export type FreestyleProviderOptions =
38
+ | string
39
+ | FreestyleProviderDefinition["config"];
40
+
44
41
  export type FreestyleTerminalProviderDefinition = WorkflowProviderDefinition<
45
42
  typeof FREESTYLE_TERMINAL_PROVIDER_ID,
46
43
  {},
@@ -48,9 +45,9 @@ export type FreestyleTerminalProviderDefinition = WorkflowProviderDefinition<
48
45
  >;
49
46
 
50
47
  export function provider(
51
- config: FreestyleProviderDefinition["config"] = {},
48
+ config: FreestyleProviderOptions = {},
52
49
  ): FreestyleProviderDefinition {
53
- return defineProvider(FREESTYLE_PROVIDER_ID, config, freestyleProviderPlugin);
50
+ return defineProvider(FREESTYLE_PROVIDER_ID, normalizeFreestyleProviderOptions(config), freestyleProviderPlugin);
54
51
  }
55
52
 
56
53
  export function terminal(): FreestyleTerminalProviderDefinition {
@@ -69,7 +66,7 @@ export const freestyleProviderPlugin: BaseProviderPlugin = {
69
66
  async createProvider({ provider, hostStorage, local }) {
70
67
  const config = parseFreestyleProviderConfig(provider.config);
71
68
  const authenticated = await createFreestyleAuthenticatedClient({
72
- auth: config.auth,
69
+ config,
73
70
  hostStorage,
74
71
  local,
75
72
  });
@@ -91,6 +88,7 @@ export const freestyleTerminalPlugin: BaseProviderPlugin = {
91
88
  export {
92
89
  createFreestyleAuthenticatedClient,
93
90
  createFreestyleProxyFetch,
91
+ createFreestyleSdkFetch,
94
92
  } from "./host-auth.ts";
95
93
  export {
96
94
  freestyleIdentityId,
@@ -124,9 +122,16 @@ export type {
124
122
  export type { FreestyleGitRelationship, FreestyleIdentity } from "./store.ts";
125
123
 
126
124
  function parseFreestyleProviderConfig(value: unknown): FreestyleProviderConfig {
127
- const result = z.safeParse(freestyleProviderConfigSchema, value);
125
+ const result = z.safeParse(freestyleProviderConfigSchema, normalizeFreestyleProviderOptions(value));
128
126
  if (!result.success) {
129
127
  throw new Error(`Invalid Freestyle provider config:\n${z.prettifyError(result.error)}`);
130
128
  }
131
129
  return result.data;
132
130
  }
131
+
132
+ function normalizeFreestyleProviderOptions(value: unknown): FreestyleProviderDefinition["config"] {
133
+ if (typeof value === "string") {
134
+ return { apiKey: value };
135
+ }
136
+ return value as FreestyleProviderDefinition["config"];
137
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const RIGKIT_PROVIDER_FREESTYLE_VERSION = "0.2.6";
1
+ export const RIGKIT_PROVIDER_FREESTYLE_VERSION = "0.2.8";