Skip to content

Commit 308ba54

Browse files
authored
Merge branch 'main' into feat/commitlint-release-please
2 parents 1bd152a + f159333 commit 308ba54

5 files changed

Lines changed: 12 additions & 95 deletions

File tree

packages/cli/src/__tests__/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,19 @@ bun test src/__tests__/manifest.test.ts
7373

7474
### Cloud-specific
7575
- `aws.test.ts` — AWS credential cache, SigV4 signing helpers
76+
- `billing-guidance.test.ts``isBillingError`, `handleBillingError`, `showNonBillingError`
7677
- `cloud-init.test.ts``getPackagesForTier`, `needsNode`, `needsBun`, `NODE_INSTALL_CMD`
7778
- `check-entity.test.ts` / `check-entity-messages.test.ts` — Entity validation
7879
- `agent-tarball.test.ts``tryTarballInstall`: GitHub Release tarball install, fallback, URL validation
7980
- `gateway-resilience.test.ts``startGateway` systemd unit with auto-restart and cron heartbeat
8081
- `do-snapshot.test.ts``findSpawnSnapshot`: DigitalOcean snapshot lookup, filtering, error handling
81-
- `ui-utils.test.ts``validateServerName`, `validateRegionName`, `validateModelId`, `toKebabCase`, `sanitizeTermValue`, `jsonEscape`
82+
- `ui-utils.test.ts``validateServerName`, `validateRegionName`, `toKebabCase`, `sanitizeTermValue`, `jsonEscape`
83+
84+
### Agent-specific
85+
- `junie-agent.test.ts` — Junie CLI agent configuration validation
86+
87+
### Shared helpers
88+
- `shared-helpers.test.ts``generateEnvConfig`, `hasStatus`, `toObjectArray`, `toRecord`
8289

8390
### OAuth and auth
8491
- `oauth-code-validation.test.ts``OAUTH_CODE_REGEX` format validation

packages/cli/src/__tests__/billing-guidance.test.ts

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ mock.module("../shared/ui", () => ({
1313
prompt: mockPrompt,
1414
}));
1515

16-
const { getBillingUrl, getSetupSteps, handleBillingError, isBillingError, showNonBillingError } = await import(
17-
"../shared/billing-guidance"
18-
);
16+
const { handleBillingError, isBillingError, showNonBillingError } = await import("../shared/billing-guidance");
1917

2018
describe("isBillingError", () => {
2119
describe("hetzner", () => {
@@ -84,51 +82,13 @@ describe("isBillingError", () => {
8482
});
8583
});
8684

87-
describe("daytona", () => {
88-
it("matches billing/plan errors", () => {
89-
expect(isBillingError("daytona", "quota exceeded")).toBe(true);
90-
expect(isBillingError("daytona", "plan limit reached")).toBe(true);
91-
});
92-
93-
it("returns false for non-billing errors", () => {
94-
expect(isBillingError("daytona", "sandbox creation failed")).toBe(false);
95-
expect(isBillingError("daytona", "internal server error")).toBe(false);
96-
});
97-
});
98-
9985
describe("unknown cloud", () => {
10086
it("returns false for unknown clouds", () => {
10187
expect(isBillingError("unknown", "billing error")).toBe(false);
10288
});
10389
});
10490
});
10591

106-
describe("getBillingUrl", () => {
107-
it("returns correct URLs for known clouds", () => {
108-
expect(getBillingUrl("hetzner")).toBe("https://console.hetzner.cloud/");
109-
expect(getBillingUrl("digitalocean")).toBe("https://cloud.digitalocean.com/account/billing");
110-
expect(getBillingUrl("aws")).toBe("https://lightsail.aws.amazon.com/");
111-
expect(getBillingUrl("gcp")).toBe("https://console.cloud.google.com/billing");
112-
expect(getBillingUrl("daytona")).toBe("https://app.daytona.io/dashboard");
113-
});
114-
115-
it("returns undefined for unknown clouds", () => {
116-
expect(getBillingUrl("unknown")).toBeUndefined();
117-
});
118-
});
119-
120-
describe("getSetupSteps", () => {
121-
it("returns steps for known clouds", () => {
122-
const steps = getSetupSteps("hetzner");
123-
expect(steps.length).toBeGreaterThan(0);
124-
expect(steps[0]).toContain("Hetzner");
125-
});
126-
127-
it("returns empty array for unknown clouds", () => {
128-
expect(getSetupSteps("unknown")).toEqual([]);
129-
});
130-
});
131-
13292
describe("handleBillingError", () => {
13393
let stderrSpy: ReturnType<typeof spyOn>;
13494

packages/cli/src/__tests__/ui-utils.test.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { describe, expect, it } from "bun:test";
22

3-
const { validateServerName, validateRegionName, validateModelId, toKebabCase, sanitizeTermValue, jsonEscape } =
4-
await import("../shared/ui.js");
3+
const { validateServerName, validateRegionName, toKebabCase, sanitizeTermValue, jsonEscape } = await import(
4+
"../shared/ui.js"
5+
);
56

67
// ── validateServerName ──────────────────────────────────────────────
78

@@ -62,26 +63,6 @@ describe("validateRegionName", () => {
6263
});
6364
});
6465

65-
// ── validateModelId ─────────────────────────────────────────────────
66-
67-
describe("validateModelId", () => {
68-
it("accepts valid model IDs", () => {
69-
expect(validateModelId("anthropic/claude-3.5-sonnet")).toBe(true);
70-
expect(validateModelId("openai/gpt-4")).toBe(true);
71-
expect(validateModelId("meta-llama/llama-3:70b")).toBe(true);
72-
});
73-
74-
it("returns true for empty string", () => {
75-
expect(validateModelId("")).toBe(true);
76-
});
77-
78-
it("rejects model IDs with invalid characters", () => {
79-
expect(validateModelId("model name")).toBe(false);
80-
expect(validateModelId("model@id")).toBe(false);
81-
expect(validateModelId("model;id")).toBe(false);
82-
});
83-
});
84-
8566
// ── toKebabCase ─────────────────────────────────────────────────────
8667

8768
describe("toKebabCase", () => {

packages/cli/src/shared/billing-guidance.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const BILLING_URLS: Record<string, string> = {
99
digitalocean: "https://cloud.digitalocean.com/account/billing",
1010
aws: "https://lightsail.aws.amazon.com/",
1111
gcp: "https://console.cloud.google.com/billing",
12-
daytona: "https://app.daytona.io/dashboard",
1312
};
1413

1514
// ─── Setup steps per cloud ──────────────────────────────────────────────────
@@ -39,11 +38,6 @@ const SETUP_STEPS: Record<string, string[]> = {
3938
"3. Enable the Compute Engine API",
4039
"4. Return here and press Enter to retry",
4140
],
42-
daytona: [
43-
"1. Open the Daytona dashboard",
44-
"2. Complete account setup or upgrade your plan",
45-
"3. Return here and press Enter to retry",
46-
],
4741
};
4842

4943
// ─── Error patterns per cloud ───────────────────────────────────────────────
@@ -76,13 +70,6 @@ const ERROR_PATTERNS: Record<string, RegExp[]> = {
7670
/project.*has.*no.*billing/i,
7771
/account[_ ](?:is[_ ])?(?:suspended|closed)/i,
7872
],
79-
daytona: [
80-
/billing/i,
81-
/payment/i,
82-
/subscription/i,
83-
/quota[_ ]exceeded/i,
84-
/plan[_ ]limit/i,
85-
],
8673
};
8774

8875
/** Check if an error message matches known billing error patterns for a cloud. */
@@ -94,16 +81,6 @@ export function isBillingError(cloud: string, errorMsg: string): boolean {
9481
return patterns.some((p) => p.test(errorMsg));
9582
}
9683

97-
/** Get billing setup URL for a cloud. */
98-
export function getBillingUrl(cloud: string): string | undefined {
99-
return BILLING_URLS[cloud];
100-
}
101-
102-
/** Get setup steps for a cloud. */
103-
export function getSetupSteps(cloud: string): string[] {
104-
return SETUP_STEPS[cloud] || [];
105-
}
106-
10784
/**
10885
* Show billing guidance, open the billing page, and prompt user to retry.
10986
* Returns true if user wants to retry, false otherwise.

packages/cli/src/shared/ui.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,6 @@ export function validateRegionName(region: string): boolean {
272272
return /^[a-zA-Z0-9_-]{1,63}$/.test(region);
273273
}
274274

275-
/** Validate model ID format. */
276-
export function validateModelId(id: string): boolean {
277-
if (!id) {
278-
return true;
279-
}
280-
return /^[a-zA-Z0-9/_:.-]+$/.test(id);
281-
}
282-
283275
/** Convert display name to kebab-case. */
284276
export function toKebabCase(name: string): string {
285277
return name

0 commit comments

Comments
 (0)