feat: finish the fleets plugin, add ctx.hosts and host-commands SDK (B4)

This commit is contained in:
LukeGus committed 2026-09-23 11:24:16 -05:00
1 parent d2ff5fc78f
commit 3b2c849514
59 files changed
+31807 -2977

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
/**
* Extract a stable, human-readable message from an unknown thrown value.
* Mirrors src/ui/lib/error-message.ts - kept as a small standalone copy
* rather than a cross-plugin dependency for one pure function.
*/
export function getErrorMessage(
error: unknown,
fallback = "Unknown error",
): string {
return error instanceof Error ? error.message : fallback;
}
export interface SnippetInput {
key: string;
label: string;
}
const INPUT_PATTERN =
/\$\{INPUT_(\d+)(?::([^}$]+))?\}|\$INPUT_(\d+)(?![a-zA-Z0-9_])/g;
/**
* Finds the $INPUT_n placeholders in a command, for the fleet run box's
* input fields. Mirrors src/ui/lib/snippet-variables.ts extractSnippetInputs.
*/
export function extractSnippetInputs(content: string): SnippetInput[] {
const seen = new Map<string, SnippetInput>();
let match: RegExpExecArray | null;
INPUT_PATTERN.lastIndex = 0;
while ((match = INPUT_PATTERN.exec(content)) !== null) {
const digits = match[1] ?? match[3];
const key = `INPUT_${digits}`;
if (!seen.has(key)) {
seen.set(key, { key, label: match[2]?.trim() || `Input ${digits}` });
}
}
return Array.from(seen.values());
}