From 2a44f607853e5777f027ab6ef6e86fe56cfc77e2 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 27 Apr 2026 14:47:00 +0100 Subject: [PATCH] fix(cli): strip virtual-LLM lifecycle fields from llm apply-doc YAML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smoke test \`llm.smoke > round-trips yaml output → apply -f\` failed after v1 of the virtual-LLM feature: \`mcpctl get llm -o yaml\` output now starts with \`kind: public\` (the new schema column) instead of \`kind: llm\` (the apply-doc envelope), because toApplyDocs spread the cleaned item AFTER setting the kind, so the cleaned item's \`kind\` overwrote. Fix: in toApplyDocs, when serialising the \`llms\` resource, drop the new lifecycle fields (kind, status, lastHeartbeatAt, inactiveSince, providerSessionId) before merging. They collide with the apply-doc envelope and aren't apply-able anyway — they're derived runtime state owned by VirtualLlmService. Public-LLM round-trip is now byte-clean (those fields default to public/active anyway). Virtual rows are created by the registrar, not via apply -f, so dropping them on output is the right call. CLI suite: 437/437. Smoke will re-run against the live mcpd via scripts/release.sh after merge. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/cli/src/commands/get.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cli/src/commands/get.ts b/src/cli/src/commands/get.ts index c55f572..ea78f33 100644 --- a/src/cli/src/commands/get.ts +++ b/src/cli/src/commands/get.ts @@ -408,6 +408,17 @@ function toApplyDocs(resource: string, items: unknown[]): Array<{ kind: string } const kind = RESOURCE_KIND[resource] ?? resource; return items.map((item) => { const cleaned = stripInternalFields(item as Record); + // Llm-specific: the new virtual-provider lifecycle fields collide with + // the apply-doc `kind` envelope (the schema uses `kind: public|virtual`) + // and aren't apply-able anyway — they're derived runtime state managed + // by VirtualLlmService. Drop them so YAML round-trips stay clean. + if (resource === 'llms') { + delete cleaned['kind']; + delete cleaned['status']; + delete cleaned['lastHeartbeatAt']; + delete cleaned['inactiveSince']; + delete cleaned['providerSessionId']; + } return { kind, ...cleaned }; }); }