refactor(agents): user-friendly agent version handling — warn once, never block - #463
refactor(agents): user-friendly agent version handling — warn once, never block#463SleepySML wants to merge 13 commits into
Conversation
…r/hasUpdate/isBelowMinimum)
… BaseAgentAdapter.run()
| @@ -285,7 +289,7 @@ export function createUpdateCommand(): Command { | |||
| if (!result.hasUpdate) { | |||
There was a problem hiding this comment.
Both branches of if (agent.name === 'claude') / else now print the exact same string — this used to differ ("latest supported version" for Claude), but the text was dropped when pinned versions were
removed (EPMCDME-13734), leaving the branch and the comment above it stale. Dead code. Can be simplified to:
spinner.succeed(${agent.displayName} is already up to date (${result.currentVersion}));
return;
There was a problem hiding this comment.
Done — collapsed into a single spinner.succeed line in 1581850. The "For Claude, clarify…" comment is gone too since it no longer applies.
| } | ||
| // One-time untested-version notice for the freshly-installed CLI. | ||
| // No-op if the tuple has already been acknowledged in a prior session. | ||
| if (displayVersion && 'warnOnceIfUntested' in agent) { |
There was a problem hiding this comment.
warnOnceIfUntested is now a required (non-optional) method on AgentAdapter, so the 'warnOnceIfUntested' in agent check and the unknown cast here are unnecessary:
if (displayVersion) {
await agent.warnOnceIfUntested();
}
There was a problem hiding this comment.
Done — dropped both the 'warnOnceIfUntested' in agent guard and the unknown cast in 1581850. Direct await agent.warnOnceIfUntested() now.
| await fs.writeFile(file, JSON.stringify(history, null, 2), 'utf-8'); | ||
| } | ||
|
|
||
| static async hasWarned( |
There was a problem hiding this comment.
The "already warned" key includes the CodeMie version, not just the agent version. Practically: every time CodeMie itself ships a new release, all previously-acknowledged agent versions go back to
"Untested," and the user sees the warning again on their next launch even though the agent itself didn't change. This doesn't block anything, it just means the notice can reappear more often than the
ticket implies ("warn once, then stay silent"). This is a documented, intentional choice in spec.md just want to confirm it's the intended behavior and not an oversight.
There was a problem hiding this comment.
Confirmed intentional. The compatibility surface is (agent-version × codemie-version), not agent-version alone — CodeMie 0.11 → 0.12 can ship a change in how it wraps the agent (env mapping, hooks, proxy behavior), so an acknowledgement of claude 2.1.218 × codemie 0.11.0 doesn't automatically extend to claude 2.1.218 × codemie 0.12.0. The signal is the mildest possible: one chalk.yellow line to stderr on interactive TTY, logger.warn only in non-interactive contexts, never blocks. Reset is one command: codemie doctor --reset-version-warnings. Documented in spec.md under "State file" / "Warn once per (agent, agentVersion, codemieVersion) tuple" — happy to revisit the key shape (drop codemieVersion, or downgrade to log-only after N consecutive CodeMie releases) if it turns out too noisy in practice; just wanted to lock the strict interpretation of "one-time per tuple" first.
There was a problem hiding this comment.
Fair point — walking back my previous reply. Went back to the ticket and my "documented intentional design" defense was rationalisation:
- The ticket AC feat: Add Release Manager agent and CI/CD automation #2 literally says "for a specific agent agent version combination" — 2-tuple language.
- The Summary says "warns once per agent version" — not per (agent × codemie).
- The user story says "not nagged repeatedly about something I cannot or choose not to change" — a CodeMie release is a change on our side, so re-nagging on it is exactly the failure mode the ticket describes.
- There is no "supported version" concept anywhere in the new design — that was the OLD behavior we removed. My 3-tuple was quietly re-introducing it through
codemieVersionas an implicit epoch.
Fixed in b98efbf:
VersionWarningStore.hasWarned(agent, agentVersion)andrecordWarning(agent, agentVersion)— 2-tuple,codemieVersionfield removed fromVersionWarningRecord.BaseAgentAdapter.warnOnceIfUntested()uses the 2-tuple key; the running CodeMie version still appears in the banner text for context (falls back to"unknown"whengetCurrentCliVersion()returns null — user still gets the notice) but is no longer part of the lookup.AgentsCheck"Acknowledged / Untested with CodeMie X" still shows the current running version — user-facing display unchanged.spec.mdrewritten to reflect the 2-tuple design and the reason for excludingcodemieVersionfrom the key.- 2660 unit tests green, including a regression test that asserts
codemieVersionis not persisted in the marker record.
Effect: once a user acknowledges claude 2.1.218, they stay silent on every CodeMie release until claude itself ships a new version.
…e, redundant duck-type)
Course correction — constants restoredAfter discussion with @Evgenii_Kurdakov, the ticket's Description text turned out to be misleading. The intent is not to remove the pinned version constants — it is to make the version check completely non-blocking, while keeping the constants as the reference point. Fixed in 71722d5: Restored:
Kept from the non-blocking refactor:
New trigger for the notice: fires only when Jira ticket updated with the correction: https://jiraeu.epam.com/browse/EPMCDME-13734 (see latest comment). Local verification: 2666 unit tests pass, typecheck + lint clean. Sorry for the churn — should have questioned the "remove entirely" wording earlier when I first read the ticket, instead of taking it at face value. |
|
approved |
Summary
EPMCDME-13734. Replace the blocking agent-version checks with a one-time, non-blocking "untested version" notice per
(agent, agent-version, codemie-version)tuple. Every pinned per-agent supported-version constant is removed, so agent CLIs can release independently without a CodeMie release to keep users unblocked.Users are never prevented from launching a wrapped agent by a version check; they are never nagged more than once about the same tuple; and non-interactive/ACP/silent contexts never
throwand never open aninquirer.prompt.Changes
BaseAgentAdapter.warnOnceIfUntested()andgetVersionInfo()seams.run()'s old blockinginquirer.prompt/process.exit/throwversion-check block is gone.warnOnceIfUntested()islogger.warn+ optionalchalk.yellowbanner to stderr — never blocks, never throws.~/.codemie/version-warnings.jsonviaVersionWarningStore(MigrationTracker pattern). Idempotent record/read, graceful degradation on read failures (hasWarnedreturningfalse) and write failures (marker re-emits on next launch).CLAUDE_SUPPORTED_VERSION,CLAUDE_MINIMUM_SUPPORTED_VERSION, and the codex / gemini / kimi equivalents — 8 constants total.AgentMetadata.supportedVersion/minimumSupportedVersionandVersionCompatibilityResultdeleted.install.ts(--supportedis now a silent alias for--latest; post-installwarnOnceIfUntested()records the marker),update.ts(queries npm registry directly for Claude; emitswarnOnceIfUntested()after every update path),setup.ts(3-second Promise.race wraps bothgetVersionInfoandwarnOnceIfUntested).codemie doctor --reset-version-warningsflag clears the store.AgentsCheckrenders three states — Acknowledged (chalk.green), Untested (chalk.yellow), Not installed (chalk.gray). Deprecated-npm-install warning preserved.tests/setup/agent-build-setup.tsno longer importsCLAUDE_SUPPORTED_VERSION— it unconditionally installsclaude --latestso integration tests always run against a predictable binary.hasWarnedthrows,install.tsno longer readsmetadata.supportedVersion, codex plugin one-time-warning contract).Impact
User-visible behavior change. First launch with an unacknowledged agent version:
Subsequent launches of the same tuple: silent. Non-interactive / ACP / CI:
logger.warnonly, no stdout prose, never blocks.Deliberate behavior change to call out: ACP
silentModeused tothrowonisBelowMinimum(per the prior ADR). It now logs and proceeds. This is the ticket AC's "never throw and never block on version mismatch" contract — callers that treated the throw as an integration signal should switch to readingcodemie doctoroutput or the log file.codemie install <agent> --supportedstill works (silent alias for--latest) — no script breakage.Checklist
request-changes→ checkapprove)docs/superpowers/tasks/2026-08-04-untested-agent-version-warning-non-blocking/)throw→log-and-proceedis called out aboveLocal skipped gates (still enforced by CI):
license-check— npm cache EACCES in this environmentvalidate:secrets— no local container engine; CI runs gitleaks unconditionallyvitest run --project agent) — requires live Claude installation + credentials