Add dynamic command secret validation schema

Introduce dynamic_command secret metadata and static argv binding persistence behind the existing experimental rollout path.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Nicky LeachandPaperclip committed 2026-06-25 21:58:30 +00:00
1 parent f6f742d2f5
commit d495974f95
17 files changed
+284 -30

No files matched your search

@@ -0,0 +1,5 @@
ALTER TABLE "company_secrets"
ADD COLUMN IF NOT EXISTS "dynamic_command" jsonb;
--> statement-breakpoint
ALTER TABLE "company_secret_bindings"
ADD COLUMN IF NOT EXISTS "static_argv" jsonb NOT NULL DEFAULT '[]'::jsonb;
@@ -792,6 +792,13 @@
"when": 1781902600000,
"tag": "0112_rename_skill_create_permission_key",
"breakpoints": true
},
{
"idx": 113,
"version": "7",
"when": 1782417600000,
"tag": "0113_dynamic_secret_command_config",
"breakpoints": true
}
]
}
@@ -1,4 +1,4 @@
import { boolean, index, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
import { boolean, index, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
import { companies } from "./companies.js";
import { companySecrets } from "./company_secrets.js";
@@ -14,6 +14,7 @@ export const companySecretBindings = pgTable(
versionSelector: text("version_selector").notNull().default("latest"),
required: boolean("required").notNull().default(true),
label: text("label"),
staticArgv: jsonb("static_argv").$type<string[]>().notNull().default([]),
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
},
@@ -14,6 +14,11 @@ export const companySecrets = pgTable(
status: text("status").notNull().default("active"),
managedMode: text("managed_mode").notNull().default("paperclip_managed"),
externalRef: text("external_ref"),
dynamicCommand: jsonb("dynamic_command").$type<{
provider: "host-command";
command: string;
ttlSeconds: number;
}>(),
providerConfigId: uuid("provider_config_id").references(() => companySecretProviderConfigs.id, { onDelete: "set null" }),
providerMetadata: jsonb("provider_metadata").$type<Record<string, unknown>>(),
latestVersion: integer("latest_version").notNull().default(1),
+2 -2
View File
@@ -4,7 +4,7 @@ import {
BIND_MODES,
DEPLOYMENT_EXPOSURES,
DEPLOYMENT_MODES,
SECRET_PROVIDERS,
SECRET_STORAGE_PROVIDERS,
STORAGE_PROVIDERS,
} from "./constants.js";
import { validateConfiguredBindMode } from "./network-bind.js";
@@ -92,7 +92,7 @@ export const secretsLocalEncryptedConfigSchema = z.object({
});
export const secretsConfigSchema = z.object({
provider: z.enum(SECRET_PROVIDERS).default("local_encrypted"),
provider: z.enum(SECRET_STORAGE_PROVIDERS).default("local_encrypted"),
strictMode: z.boolean().default(false),
localEncrypted: secretsLocalEncryptedConfigSchema.default({
keyFilePath: "~/.paperclip/instances/default/secrets/master.key",
+8 -2
View File
@@ -546,12 +546,18 @@ export const APPROVAL_STATUSES = [
] as const;
export type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];
export const SECRET_PROVIDERS = [
export const SECRET_STORAGE_PROVIDERS = [
"local_encrypted",
"aws_secrets_manager",
"gcp_secret_manager",
"vault",
] as const;
export type SecretStorageProvider = (typeof SECRET_STORAGE_PROVIDERS)[number];
export const SECRET_PROVIDERS = [
...SECRET_STORAGE_PROVIDERS,
"host_command",
] as const;
export type SecretProvider = (typeof SECRET_PROVIDERS)[number];
export const SECRET_PROVIDER_CONFIG_STATUSES = [
@@ -575,7 +581,7 @@ export type SecretProviderConfigHealthStatus =
export const SECRET_STATUSES = ["active", "disabled", "archived", "deleted"] as const;
export type SecretStatus = (typeof SECRET_STATUSES)[number];
export const SECRET_MANAGED_MODES = ["paperclip_managed", "external_reference"] as const;
export const SECRET_MANAGED_MODES = ["paperclip_managed", "external_reference", "dynamic_command"] as const;
export type SecretManagedMode = (typeof SECRET_MANAGED_MODES)[number];
export const SECRET_VERSION_STATUSES = [
+5
View File
@@ -126,6 +126,7 @@ export {
PROJECT_COLORS,
APPROVAL_TYPES,
APPROVAL_STATUSES,
SECRET_STORAGE_PROVIDERS,
SECRET_PROVIDERS,
SECRET_PROVIDER_CONFIG_STATUSES,
SECRET_PROVIDER_CONFIG_HEALTH_STATUSES,
@@ -255,6 +256,7 @@ export {
type PauseReason,
type ApprovalType,
type ApprovalStatus,
type SecretStorageProvider,
type SecretProvider,
type SecretProviderConfigStatus,
type SecretProviderConfigHealthStatus,
@@ -730,6 +732,7 @@ export type {
EnvPlainBinding,
EnvSecretRefBinding,
AgentEnvConfig,
DynamicSecretCommandConfig,
CompanySecret,
CompanySecretProviderConfig,
SecretProviderConfigPayload,
@@ -1188,6 +1191,8 @@ export {
envBindingSecretRefSchema,
envBindingSchema,
envConfigSchema,
dynamicSecretCommandSchema,
staticArgvSchema,
createSecretSchema,
createSecretProviderConfigSchema,
updateSecretProviderConfigSchema,
+1
View File
@@ -410,6 +410,7 @@ export type {
CompanySecretBindingTarget,
CompanySecretUsageBinding,
CompanySecretVersion,
DynamicSecretCommandConfig,
SecretAccessEvent,
RemoteSecretImportCandidate,
RemoteSecretImportCandidateStatus,
+8
View File
@@ -38,6 +38,12 @@ export type EnvBinding = string | EnvPlainBinding | EnvSecretRefBinding;
export type AgentEnvConfig = Record<string, EnvBinding>;
export interface DynamicSecretCommandConfig {
provider: "host-command";
command: string;
ttlSeconds: number;
}
export interface CompanySecret {
id: string;
companyId: string;
@@ -47,6 +53,7 @@ export interface CompanySecret {
status: SecretStatus;
managedMode: SecretManagedMode;
externalRef: string | null;
dynamicCommand: DynamicSecretCommandConfig | null;
providerConfigId: string | null;
providerMetadata: Record<string, unknown> | null;
latestVersion: number;
@@ -197,6 +204,7 @@ export interface CompanySecretBinding {
versionSelector: SecretVersionSelector;
required: boolean;
label: string | null;
staticArgv: string[];
createdAt: Date;
updatedAt: Date;
}
+2
View File
@@ -439,6 +439,8 @@ export {
envBindingSecretRefSchema,
envBindingSchema,
envConfigSchema,
dynamicSecretCommandSchema,
staticArgvSchema,
createSecretSchema,
createSecretProviderConfigSchema,
updateSecretProviderConfigSchema,
@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import {
createSecretBindingSchema,
createSecretProviderConfigSchema,
createSecretSchema,
remoteSecretImportPreviewSchema,
@@ -10,6 +11,61 @@ import {
} from "./secret.js";
describe("secret validators", () => {
it("allows dynamic command secrets with host-command generator config", () => {
const parsed = createSecretSchema.parse({
name: "GitHub App token",
managedMode: "dynamic_command",
dynamicCommand: {
provider: "host-command",
command: "/usr/local/bin/mint-github-token",
ttlSeconds: 3600,
},
});
expect(parsed.dynamicCommand).toEqual({
provider: "host-command",
command: "/usr/local/bin/mint-github-token",
ttlSeconds: 3600,
});
});
it("rejects value and externalRef on dynamic command secrets", () => {
expect(() =>
createSecretSchema.parse({
name: "Invalid dynamic secret",
managedMode: "dynamic_command",
value: "static-secret",
externalRef: "arn:aws:secretsmanager:us-east-1:123456789012:secret:shared/other",
dynamicCommand: {
provider: "host-command",
command: "/usr/local/bin/mint-token",
ttlSeconds: 300,
},
}),
).toThrow(/Dynamic command secrets cannot set value/);
});
it("requires generator config for dynamic command secrets", () => {
expect(() =>
createSecretSchema.parse({
name: "Missing generator",
managedMode: "dynamic_command",
}),
).toThrow(/require generator command config/);
});
it("accepts operator-set static argv params on secret bindings", () => {
const parsed = createSecretBindingSchema.parse({
secretId: "11111111-1111-4111-8111-111111111111",
targetType: "agent",
targetId: "agent-1",
configPath: "env.GITHUB_TOKEN",
staticArgv: ["--installation", "12345", "--repo", "paperclipai/paperclip"],
});
expect(parsed.staticArgv).toEqual(["--installation", "12345", "--repo", "paperclipai/paperclip"]);
});
it("rejects externalRef on managed secrets", () => {
expect(() =>
createSecretSchema.parse({
+60 -3
View File
@@ -4,6 +4,7 @@ import {
SECRET_MANAGED_MODES,
SECRET_PROVIDER_CONFIG_STATUSES,
SECRET_PROVIDERS,
SECRET_STORAGE_PROVIDERS,
SECRET_STATUSES,
} from "../constants.js";
@@ -27,6 +28,14 @@ export const envBindingSchema = z.union([
export const envConfigSchema = z.record(z.string(), envBindingSchema);
export const dynamicSecretCommandSchema = z.object({
provider: z.literal("host-command"),
command: z.string().trim().min(1).max(2048),
ttlSeconds: z.number().int().min(1).max(86_400),
}).strict();
export const staticArgvSchema = z.array(z.string().max(4096)).max(64).default([]);
export const createSecretSchema = z.object({
name: z.string().min(1),
key: z.string().min(1).regex(/^[a-zA-Z0-9_.-]+$/).optional(),
@@ -34,12 +43,21 @@ export const createSecretSchema = z.object({
providerConfigId: z.string().uuid().optional().nullable(),
managedMode: z.enum(SECRET_MANAGED_MODES).optional(),
value: z.string().min(1).optional().nullable(),
dynamicCommand: dynamicSecretCommandSchema.optional().nullable(),
description: z.string().optional().nullable(),
externalRef: z.string().optional().nullable(),
providerMetadata: z.record(z.string(), z.unknown()).optional().nullable(),
providerVersionRef: z.string().optional().nullable(),
}).superRefine((value, ctx) => {
if ((value.managedMode ?? "paperclip_managed") === "external_reference") {
const managedMode = value.managedMode ?? "paperclip_managed";
if (managedMode === "external_reference") {
if (value.provider === "host_command") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["provider"],
message: "Host command provider requires dynamic_command mode",
});
}
if (!value.externalRef?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
@@ -49,6 +67,44 @@ export const createSecretSchema = z.object({
}
return;
}
if (managedMode === "dynamic_command") {
if ((value.provider ?? "host_command") !== "host_command") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["provider"],
message: "Dynamic command secrets require host_command provider",
});
}
if (value.value?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["value"],
message: "Dynamic command secrets cannot set value",
});
}
if (value.externalRef?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["externalRef"],
message: "Dynamic command secrets cannot set externalRef",
});
}
if (!value.dynamicCommand) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["dynamicCommand"],
message: "Dynamic command secrets require generator command config",
});
}
return;
}
if (value.provider === "host_command") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["provider"],
message: "Host command provider requires dynamic_command mode",
});
}
if (value.externalRef?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
@@ -99,6 +155,7 @@ export const createSecretBindingSchema = secretBindingTargetSchema.extend({
versionSelector: z.union([z.literal("latest"), z.number().int().positive()]).default("latest"),
required: z.boolean().default(true),
label: z.string().optional().nullable(),
staticArgv: staticArgvSchema,
});
export type CreateSecretBinding = z.infer<typeof createSecretBindingSchema>;
@@ -194,7 +251,7 @@ export const secretProviderConfigPayloadSchema = z.discriminatedUnion("provider"
]);
export const createSecretProviderConfigSchema = z.object({
provider: z.enum(SECRET_PROVIDERS),
provider: z.enum(SECRET_STORAGE_PROVIDERS),
displayName: z.string().trim().min(1).max(120),
status: z.enum(SECRET_PROVIDER_CONFIG_STATUSES).optional(),
isDefault: z.boolean().optional(),
@@ -263,7 +320,7 @@ export const remoteSecretImportPreviewSchema = z.object({
export type RemoteSecretImportPreview = z.infer<typeof remoteSecretImportPreviewSchema>;
export const secretProviderConfigDiscoveryPreviewSchema = z.object({
provider: z.enum(SECRET_PROVIDERS),
provider: z.enum(SECRET_STORAGE_PROVIDERS),
config: z.record(z.unknown()).default({}),
query: z.string().trim().max(200).optional().nullable(),
nextToken: z.string().trim().min(1).max(4096).optional().nullable(),
@@ -145,6 +145,50 @@ describeEmbeddedPostgres("secretService", () => {
).rejects.toThrow(/already exists/i);
});
it("persists dynamic command secrets and operator static argv bindings without secret material", async () => {
const companyId = await seedCompany();
const svc = secretService(db);
const secret = await svc.create(companyId, {
name: `dynamic-${randomUUID()}`,
provider: "host_command",
managedMode: "dynamic_command",
dynamicCommand: {
provider: "host-command",
command: "/usr/local/bin/mint-github-token",
ttlSeconds: 3600,
},
});
expect(secret).toMatchObject({
managedMode: "dynamic_command",
provider: "host_command",
externalRef: null,
latestVersion: 0,
dynamicCommand: {
provider: "host-command",
command: "/usr/local/bin/mint-github-token",
ttlSeconds: 3600,
},
});
const versions = await db
.select()
.from(companySecretVersions)
.where(eq(companySecretVersions.secretId, secret.id));
expect(versions).toHaveLength(0);
const binding = await svc.createBinding({
companyId,
secretId: secret.id,
targetType: "agent",
targetId: "agent-1",
configPath: "env.GITHUB_TOKEN",
staticArgv: ["--installation", "12345"],
});
expect(binding.staticArgv).toEqual(["--installation", "12345"]);
});
it("syncs top-level secret refs idempotently", async () => {
const companyId = await seedCompany();
const svc = secretService(db);
+6 -6
View File
@@ -10,13 +10,13 @@ import {
BIND_MODES,
DEPLOYMENT_EXPOSURES,
DEPLOYMENT_MODES,
SECRET_PROVIDERS,
SECRET_STORAGE_PROVIDERS,
STORAGE_PROVIDERS,
type BindMode,
type AuthBaseUrlMode,
type DeploymentExposure,
type DeploymentMode,
type SecretProvider,
type SecretStorageProvider,
type StorageProvider,
inferBindModeFromHost,
resolveRuntimeBind,
@@ -71,7 +71,7 @@ export interface Config {
databaseBackupDir: string;
serveUi: boolean;
uiDevMiddleware: boolean;
secretsProvider: SecretProvider;
secretsProvider: SecretStorageProvider;
secretsStrictMode: boolean;
secretsMasterKeyFilePath: string;
storageProvider: StorageProvider;
@@ -123,11 +123,11 @@ export function loadConfig(): Config {
const providerFromEnvRaw = process.env.PAPERCLIP_SECRETS_PROVIDER;
const providerFromEnv =
providerFromEnvRaw && SECRET_PROVIDERS.includes(providerFromEnvRaw as SecretProvider)
? (providerFromEnvRaw as SecretProvider)
providerFromEnvRaw && SECRET_STORAGE_PROVIDERS.includes(providerFromEnvRaw as SecretStorageProvider)
? (providerFromEnvRaw as SecretStorageProvider)
: null;
const providerFromFile = fileSecrets?.provider;
const secretsProvider: SecretProvider = providerFromEnv ?? providerFromFile ?? "local_encrypted";
const secretsProvider: SecretStorageProvider = providerFromEnv ?? providerFromFile ?? "local_encrypted";
const storageProviderFromEnvRaw = process.env.PAPERCLIP_STORAGE_PROVIDER;
const storageProviderFromEnv =
+2 -1
View File
@@ -279,10 +279,11 @@ export function secretRoutes(db: Db) {
{
name: req.body.name,
key: req.body.key,
provider: req.body.provider ?? defaultProvider,
provider: req.body.provider ?? (req.body.managedMode === "dynamic_command" ? "host_command" : defaultProvider),
providerConfigId: req.body.providerConfigId,
managedMode: req.body.managedMode,
value: req.body.value,
dynamicCommand: req.body.dynamicCommand,
description: req.body.description,
externalRef: req.body.externalRef,
providerVersionRef: req.body.providerVersionRef,
+4 -4
View File
@@ -1,8 +1,8 @@
import { SECRET_PROVIDERS, type SecretProvider } from "@paperclipai/shared";
import { SECRET_STORAGE_PROVIDERS, type SecretStorageProvider } from "@paperclipai/shared";
export function getConfiguredSecretProvider(): SecretProvider {
export function getConfiguredSecretProvider(): SecretStorageProvider {
const configuredProvider = process.env.PAPERCLIP_SECRETS_PROVIDER;
return configuredProvider && SECRET_PROVIDERS.includes(configuredProvider as SecretProvider)
? configuredProvider as SecretProvider
return configuredProvider && SECRET_STORAGE_PROVIDERS.includes(configuredProvider as SecretStorageProvider)
? configuredProvider as SecretStorageProvider
: "local_encrypted";
}
+67 -11
View File
@@ -27,6 +27,7 @@ import type {
SecretProviderConfigHealthStatus,
SecretProviderConfigStatus,
SecretVersionSelector,
DynamicSecretCommandConfig,
} from "@paperclipai/shared";
import {
createSecretProviderConfigSchema,
@@ -64,6 +65,7 @@ const COMING_SOON_SECRET_PROVIDERS: ReadonlySet<SecretProvider> = new Set([
"gcp_secret_manager",
"vault",
]);
const EMPTY_STATIC_ARGV: string[] = [];
type DbTransaction = Parameters<Parameters<Db["transaction"]>[0]>[0];
type SecretBindingDb = Pick<Db | DbTransaction, "select" | "delete" | "insert">;
@@ -1700,7 +1702,8 @@ export function secretService(db: Db) {
providerConfigId?: string | null;
value?: string | null;
key?: string | null;
managedMode?: "paperclip_managed" | "external_reference";
managedMode?: "paperclip_managed" | "external_reference" | "dynamic_command";
dynamicCommand?: DynamicSecretCommandConfig | null;
description?: string | null;
externalRef?: string | null;
providerVersionRef?: string | null;
@@ -1724,21 +1727,61 @@ export function secretService(db: Db) {
if (duplicateKey) throw conflict(`Secret key already exists: ${key}`);
const managedMode = input.managedMode ?? "paperclip_managed";
if (managedMode === "external_reference" && !input.externalRef?.trim()) {
throw unprocessable("External reference secrets require externalRef");
}
if (managedMode === "external_reference" && input.provider === "host_command") {
throw unprocessable("Host command provider requires dynamic_command mode");
}
if (managedMode === "paperclip_managed" && input.externalRef?.trim()) {
throw unprocessable("Managed secrets cannot override externalRef");
}
if (managedMode === "paperclip_managed" && input.provider === "host_command") {
throw unprocessable("Host command provider requires dynamic_command mode");
}
if (managedMode === "paperclip_managed" && !input.value?.trim()) {
throw unprocessable("Managed secrets require value");
}
if (managedMode === "dynamic_command") {
if (input.provider !== "host_command") {
throw unprocessable("Dynamic command secrets require host_command provider");
}
if (!input.dynamicCommand) {
throw unprocessable("Dynamic command secrets require generator command config");
}
if (input.value?.trim()) {
throw unprocessable("Dynamic command secrets cannot set value");
}
if (input.externalRef?.trim()) {
throw unprocessable("Dynamic command secrets cannot set externalRef");
}
return db
.insert(companySecrets)
.values({
companyId,
key,
name: input.name,
provider: input.provider,
providerConfigId: input.providerConfigId ?? null,
status: "active",
managedMode,
externalRef: null,
dynamicCommand: input.dynamicCommand,
providerMetadata: input.providerMetadata ?? null,
latestVersion: 0,
description: input.description ?? null,
createdByAgentId: actor?.agentId ?? null,
createdByUserId: actor?.userId ?? null,
})
.returning()
.then((rows) => rows[0]);
}
const provider = getSecretProvider(input.provider);
const providerConfig = await getSelectableRuntimeProviderConfig({
companyId,
provider: input.provider,
providerConfigId: input.providerConfigId,
});
if (managedMode === "external_reference" && !input.externalRef?.trim()) {
throw unprocessable("External reference secrets require externalRef");
}
if (managedMode === "paperclip_managed" && input.externalRef?.trim()) {
throw unprocessable("Managed secrets cannot override externalRef");
}
if (managedMode === "paperclip_managed" && !input.value?.trim()) {
throw unprocessable("Managed secrets require value");
}
const providerWriteContext = {
companyId,
secretKey: key,
@@ -1756,6 +1799,7 @@ export function secretService(db: Db) {
status: "archived",
managedMode,
externalRef: null,
dynamicCommand: null,
providerMetadata: input.providerMetadata ?? null,
latestVersion: 0,
description: input.description ?? null,
@@ -1894,6 +1938,9 @@ export function secretService(db: Db) {
providerConfigId,
});
const nextVersion = secret.latestVersion + 1;
if (secret.managedMode === "dynamic_command") {
throw unprocessable("Dynamic command secrets do not support rotation; update generator config instead");
}
if (secret.managedMode === "external_reference" && !(input.externalRef ?? secret.externalRef)?.trim()) {
throw unprocessable("External reference secrets require externalRef");
}
@@ -2049,7 +2096,10 @@ export function secretService(db: Db) {
if (deleting && secret.managedMode === "paperclip_managed") {
throw unprocessable("Managed secrets must be deleted through DELETE /secrets/:id");
}
if (secret.managedMode !== "external_reference" && patch.externalRef !== undefined) {
if (secret.managedMode === "dynamic_command" && patch.externalRef !== undefined) {
throw unprocessable("Dynamic command secrets cannot override externalRef");
}
if (secret.managedMode === "paperclip_managed" && patch.externalRef !== undefined) {
throw unprocessable("Managed secrets cannot override externalRef");
}
if (
@@ -2118,6 +2168,7 @@ export function secretService(db: Db) {
versionSelector?: SecretVersionSelector;
required?: boolean;
label?: string | null;
staticArgv?: string[];
}) => {
await assertSecretInCompany(input.companyId, input.secretId);
const existing = await db
@@ -2144,6 +2195,7 @@ export function secretService(db: Db) {
versionSelector: String(input.versionSelector ?? "latest"),
required: input.required ?? true,
label: input.label ?? null,
staticArgv: input.staticArgv ?? EMPTY_STATIC_ARGV,
})
.returning()
.then((rows) => rows[0]);
@@ -2158,6 +2210,7 @@ export function secretService(db: Db) {
versionSelector?: SecretVersionSelector;
required?: boolean;
label?: string | null;
staticArgv?: string[];
}>,
) => {
const normalizedRefs: Array<{
@@ -2166,6 +2219,7 @@ export function secretService(db: Db) {
versionSelector: SecretVersionSelector;
required: boolean;
label: string | null;
staticArgv: string[];
}> = [];
for (const ref of refs) {
await assertSecretInCompany(companyId, ref.secretId);
@@ -2175,6 +2229,7 @@ export function secretService(db: Db) {
versionSelector: ref.versionSelector ?? "latest",
required: ref.required ?? true,
label: ref.label ?? null,
staticArgv: ref.staticArgv ?? EMPTY_STATIC_ARGV,
});
}
@@ -2219,6 +2274,7 @@ export function secretService(db: Db) {
versionSelector: String(ref.versionSelector),
required: ref.required,
label: ref.label,
staticArgv: ref.staticArgv,
})),
);
});