From 769b8f10b03140cf7811b8e3ba3f7fa03c3fe2b6 Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 4 Mar 2026 22:27:43 -0800 Subject: [PATCH 1/2] support blueprint create metadata --- src/commands/blueprint/create.ts | 24 +++++++++++++++++++++++ src/commands/blueprint/from-dockerfile.ts | 22 +++++++++++++++++++++ src/utils/commands.ts | 2 ++ 3 files changed, 48 insertions(+) diff --git a/src/commands/blueprint/create.ts b/src/commands/blueprint/create.ts index a2a8d9fc..1a02dc71 100644 --- a/src/commands/blueprint/create.ts +++ b/src/commands/blueprint/create.ts @@ -16,9 +16,27 @@ interface CreateBlueprintOptions { availablePorts?: string[]; root?: boolean; user?: string; + metadata?: string[]; output?: string; } +// Parse metadata from key=value format +function parseMetadata(metadata: string[]): Record { + const result: Record = {}; + for (const item of metadata) { + const eqIndex = item.indexOf("="); + if (eqIndex === -1) { + throw new Error( + `Invalid metadata format: ${item}. Expected key=value`, + ); + } + const key = item.substring(0, eqIndex); + const value = item.substring(eqIndex + 1); + result[key] = value; + } + return result; +} + export async function createBlueprint(options: CreateBlueprintOptions) { try { const client = getClient(); @@ -60,6 +78,11 @@ export async function createBlueprint(options: CreateBlueprintOptions) { launchParameters.user_parameters = userParameters; } + // Parse metadata if provided + const metadata = options.metadata + ? parseMetadata(options.metadata) + : undefined; + const blueprint = await client.blueprints.create({ name: options.name, dockerfile: dockerfileContents, @@ -67,6 +90,7 @@ export async function createBlueprint(options: CreateBlueprintOptions) { launch_parameters: launchParameters as Parameters< typeof client.blueprints.create >[0]["launch_parameters"], + metadata, }); // Default: output JSON diff --git a/src/commands/blueprint/from-dockerfile.ts b/src/commands/blueprint/from-dockerfile.ts index 5db14672..61b17c9d 100644 --- a/src/commands/blueprint/from-dockerfile.ts +++ b/src/commands/blueprint/from-dockerfile.ts @@ -24,11 +24,27 @@ interface FromDockerfileOptions { availablePorts?: string[]; root?: boolean; user?: string; + metadata?: string[]; ttl?: string; noWait?: boolean; output?: string; } +// Parse metadata from key=value format +function parseMetadata(metadata: string[]): Record { + const result: Record = {}; + for (const item of metadata) { + const eqIndex = item.indexOf("="); + if (eqIndex === -1) { + throw new Error(`Invalid metadata format: ${item}. Expected key=value`); + } + const key = item.substring(0, eqIndex); + const value = item.substring(eqIndex + 1); + result[key] = value; + } + return result; +} + // Helper to check if we should show progress function shouldShowProgress(options: FromDockerfileOptions): boolean { return !options.output || options.output === "text"; @@ -161,6 +177,11 @@ export async function createBlueprintFromDockerfile( logProgress(`\n⏳ [2/3] Creating blueprint...`, options); const createStart = Date.now(); + // Parse metadata if provided + const metadata = options.metadata + ? parseMetadata(options.metadata) + : undefined; + const createParams: BlueprintCreateParams = { name: options.name, dockerfile: dockerfileContents, @@ -171,6 +192,7 @@ export async function createBlueprintFromDockerfile( type: "object", object_id: storageObject.id, }, + metadata, }; const blueprintResponse = await client.blueprints.create(createParams); diff --git a/src/utils/commands.ts b/src/utils/commands.ts index 8107e6c6..07c67d0b 100644 --- a/src/utils/commands.ts +++ b/src/utils/commands.ts @@ -462,6 +462,7 @@ export function createProgram(): Command { .option("--available-ports ", "Available ports") .option("--root", "Run as root") .option("--user ", "Run as this user (format: username:uid)") + .option("--metadata ", "Metadata tags (format: key=value)") .option( "-o, --output [format]", "Output format: text|json|yaml (default: json)", @@ -552,6 +553,7 @@ export function createProgram(): Command { .option("--available-ports ", "Available ports") .option("--root", "Run as root") .option("--user ", "Run as this user (format: username:uid)") + .option("--metadata ", "Metadata tags (format: key=value)") .option( "--ttl ", "TTL in seconds for the build context object (default: 3600)", From 9561140644a0b5025cf6c0b4abd2eac89eeae58d Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 4 Mar 2026 22:28:00 -0800 Subject: [PATCH 2/2] cp --- src/commands/blueprint/create.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/commands/blueprint/create.ts b/src/commands/blueprint/create.ts index 1a02dc71..b2036810 100644 --- a/src/commands/blueprint/create.ts +++ b/src/commands/blueprint/create.ts @@ -26,9 +26,7 @@ function parseMetadata(metadata: string[]): Record { for (const item of metadata) { const eqIndex = item.indexOf("="); if (eqIndex === -1) { - throw new Error( - `Invalid metadata format: ${item}. Expected key=value`, - ); + throw new Error(`Invalid metadata format: ${item}. Expected key=value`); } const key = item.substring(0, eqIndex); const value = item.substring(eqIndex + 1);