feat: improve agent runtime update flow (#1982)
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
---
|
||||
spec: docs/specs/agents/runtime-updates.md
|
||||
created: 2026-07-27
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Implementation Plan: Agent Runtime Update Dialog
|
||||
|
||||
## Overview
|
||||
|
||||
PR #1950 placed retained update state, versions, output, and results directly
|
||||
inside installed-agent cards. It also configured PR previews with
|
||||
`KANDEV_MOCK_AGENT=only`, which intentionally removes every real agent from the
|
||||
registry and therefore leaves the install catalogue empty. This repair restores
|
||||
the preview catalogue, adds a read-only update-preview contract, and moves the
|
||||
approval and ephemeral streaming lifecycle into a responsive dialog.
|
||||
|
||||
## Confirmed root causes
|
||||
|
||||
- `apps/backend/cmd/preview/sprite_ops.go` exports
|
||||
`KANDEV_MOCK_AGENT=only`. `registry.Provide` treats `only` as an isolated E2E
|
||||
mode and registers only `mock-agent`; `ListAvailableAgents` can only return
|
||||
registry entries, so Settings receives no real install candidates.
|
||||
- `AgentRuntimeUpdateControl` is rendered inside `InstalledAgentCard`, so all
|
||||
versions, output, and terminal state expand the card.
|
||||
- `useAgentRuntimeUpdates` calls `listAgentUpdateJobs` on mount and upserts
|
||||
retained backend jobs into the global Settings store, explicitly restoring
|
||||
output and terminal state after a page restart.
|
||||
- The only preparation path is `POST /agent-update/:agentName`; target-version
|
||||
resolution happens after enqueue, so the UI cannot show the next version and
|
||||
exact command before mutation.
|
||||
|
||||
## Backend
|
||||
|
||||
### Preview environment catalogue
|
||||
|
||||
Change `buildExtractScript` in
|
||||
`apps/backend/cmd/preview/sprite_ops.go` to use
|
||||
`KANDEV_MOCK_AGENT=true`. That mode retains the enabled mock agent while loading
|
||||
the built-in real-agent catalogue, allowing unavailable agents with install
|
||||
scripts to appear in Settings. Update the focused script assertion in
|
||||
`apps/backend/cmd/preview/sprite_ops_test.go`; keep the registry mode test as
|
||||
supporting evidence that `true` loads defaults and `only` does not.
|
||||
|
||||
### Read-only update preview
|
||||
|
||||
Add `AgentUpdatePreviewDTO` in
|
||||
`apps/backend/internal/agent/settings/dto/dto.go` with agent, package, current
|
||||
version, target version, argv, and display command fields.
|
||||
|
||||
Add `Controller.PreviewAgentUpdate(ctx, name)` in
|
||||
`apps/backend/internal/agent/settings/controller/agent_update.go`. It validates
|
||||
the same built-in `ManagedNPMRuntimeAgent` boundary as enqueue, reads the current
|
||||
capability version, resolves the upstream target through `RuntimeUpdater`, and
|
||||
serializes `CacheUpdateCommand()` with the existing `buildCommandString`
|
||||
helper. Extend that helper to preserve empty argv entries as `""`, so the
|
||||
displayed recipe remains an exact representation of the direct argv command.
|
||||
It never claims maintenance state, creates a job, or executes the update command.
|
||||
|
||||
Register `GET /api/v1/agent-update/:agentName/preview` and a focused handler in
|
||||
`apps/backend/internal/agent/settings/handlers/handlers.go`. Reuse the existing
|
||||
update error classification for not-found, unsupported, unavailable, and
|
||||
version-resolution failures.
|
||||
|
||||
## Frontend
|
||||
|
||||
### API and page-local update lifecycle
|
||||
|
||||
Add `AgentUpdatePreview` and `previewAgentUpdate` to
|
||||
`apps/web/lib/api/domains/agent-update-api.ts`.
|
||||
|
||||
Refactor `useAgentRuntimeUpdates` so it does not list or hydrate retained update
|
||||
jobs on mount. Starting an update returns or binds the accepted job identity for
|
||||
the currently open dialog; WebSocket snapshots and chunks may continue using
|
||||
the existing bounded Settings store, but the dialog displays only the job
|
||||
started or recovered during its current page-local interaction.
|
||||
|
||||
### Installed-agent card and responsive update surface
|
||||
|
||||
Replace the inline `AgentRuntimeUpdateControl` composition with a compact
|
||||
icon-only trigger in `apps/web/components/settings/installed-agent-card.tsx`.
|
||||
The icon remains visually small while its standalone hitbox is at least 44px
|
||||
and has an agent-specific accessible label and tooltip. Unmanaged agents omit
|
||||
the trigger.
|
||||
|
||||
Replace `agent-runtime-update-control.tsx` with a responsive update surface:
|
||||
|
||||
- Desktop uses a centered `Dialog`.
|
||||
- Phone uses an inset bottom `Drawer`, following
|
||||
`components/kanban/mobile-menu-sheet.tsx`, because this is a temporary,
|
||||
single-purpose approval flow rather than a primary route.
|
||||
- Header and approval/dismiss actions remain fixed; one `min-h-0 flex-1
|
||||
overflow-y-auto` body owns scrolling and clears the bottom safe area.
|
||||
- Opening fetches the read-only preview and shows current/target versions,
|
||||
host-only scope, automatic capability refresh, unchanged active sessions,
|
||||
and the exact wrapping command.
|
||||
- Approval is disabled until preview succeeds and is the only action that
|
||||
sends the update POST.
|
||||
- After approval, the same surface shows phase, bounded stdout/stderr, terminal
|
||||
result, and retry. Closing or restarting the page discards the UI selection
|
||||
and presentation state.
|
||||
- No update information is rendered in the card.
|
||||
|
||||
### Public documentation
|
||||
|
||||
Update `docs/public/agents-and-profiles.md` to describe the icon-triggered
|
||||
preview and approval flow, the exact-command disclosure, dialog-only streaming,
|
||||
and the intentionally ephemeral browser presentation. The preview launcher
|
||||
environment change is internal and does not need public environment-variable
|
||||
documentation.
|
||||
|
||||
## Tests
|
||||
|
||||
- **Preview catalogue mode:** change `TestBuildExtractScript` first and confirm
|
||||
it fails while the script still exports `only`, then make it pass with
|
||||
`true`. File: `apps/backend/cmd/preview/sprite_ops_test.go`.
|
||||
- **Read-only preview:** controller tests prove current/target/command output,
|
||||
empty-argument display, unmanaged rejection, registry failure, and absence
|
||||
of update execution.
|
||||
File:
|
||||
`apps/backend/internal/agent/settings/controller/agent_update_test.go`.
|
||||
- **Exact display command:** extend the existing table test for
|
||||
`buildCommandString` with an empty argument. File:
|
||||
`apps/backend/internal/agent/settings/controller/controller_test.go`.
|
||||
- **Preview handler:** handler tests prove the GET response and errors while
|
||||
preserving POST enqueue behavior. File:
|
||||
`apps/backend/internal/agent/settings/handlers/agent_update_handlers_test.go`.
|
||||
- **Ephemeral state helper behavior:** retain focused Settings slice/WS tests
|
||||
for bounded same-job output merging, and remove the retained-job hydration
|
||||
expectation from the hook path. Files:
|
||||
`apps/web/lib/state/slices/settings/settings-slice.test.ts` and
|
||||
`apps/web/lib/ws/handlers/agents.test.ts`.
|
||||
- **Public docs:** run `node --test scripts/validate-public-docs.test.mjs` and
|
||||
`node scripts/validate-public-docs.mjs`.
|
||||
|
||||
## E2E Tests
|
||||
|
||||
- **Desktop approval:** opening the card icon shows versions, explanation, and
|
||||
exact command while POST count remains zero; approving starts one job and
|
||||
streams output/result inside the dialog.
|
||||
- **Restart reset:** after progress or a terminal result, restarting the page
|
||||
leaves only the icon on the card; a newly opened dialog contains a fresh
|
||||
preview and no prior output/result.
|
||||
- **Mobile parity:** the Pixel 5 flow taps the 44px icon, uses the bottom
|
||||
drawer, reads the preview before approval, streams a long output without
|
||||
document horizontal overflow, and reaches the fixed final actions.
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/web/e2e/tests/settings/agent-runtime-update.spec.ts`
|
||||
- `apps/web/e2e/tests/settings/mobile-agent-runtime-update.spec.ts`
|
||||
- `apps/web/e2e/tests/settings/agent-runtime-update-helpers.ts`
|
||||
|
||||
## Implementation Waves And Parallel Candidates
|
||||
|
||||
Execution is sequential in the primary conversation. No subagents are
|
||||
authorized.
|
||||
|
||||
Wave 1:
|
||||
|
||||
- [x] [Task 01: Restore the preview install catalogue](task-01-preview-catalogue.md)
|
||||
- [x] [Task 02: Add the read-only update preview API](task-02-update-preview-api.md)
|
||||
|
||||
Wave 2:
|
||||
|
||||
- [x] [Task 03: Move updates into an ephemeral responsive dialog](task-03-update-dialog-ui.md)
|
||||
|
||||
Wave 3:
|
||||
|
||||
- [x] [Task 04: Verify desktop and mobile update flows](task-04-update-dialog-e2e.md)
|
||||
|
||||
Tasks 01 and 02 touch disjoint files, but remain sequential unless the user
|
||||
explicitly authorizes subagents after the model checkpoint.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: "01-preview-catalogue"
|
||||
title: "Restore the preview install catalogue"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/agents/runtime-updates.md"
|
||||
---
|
||||
|
||||
# Task 01: Restore the preview install catalogue
|
||||
|
||||
## Acceptance
|
||||
|
||||
- PR previews enable `mock-agent` while retaining the built-in real-agent
|
||||
catalogue.
|
||||
- Settings can derive unavailable built-in agents and their install scripts
|
||||
from the preview registry.
|
||||
- E2E-only `KANDEV_MOCK_AGENT=only` semantics remain unchanged elsewhere.
|
||||
|
||||
## Verification
|
||||
|
||||
- RED/GREEN:
|
||||
`cd apps/backend && go test -run TestBuildExtractScript ./cmd/preview`
|
||||
- Supporting:
|
||||
`cd apps/backend && go test -run TestProvide_MockAgentModes ./internal/agent/registry`
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/backend/cmd/preview/sprite_ops.go`
|
||||
- `apps/backend/cmd/preview/sprite_ops_test.go`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential by default. It is file-disjoint from Task 02 and may run in
|
||||
parallel only with explicit user authorization.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec agent-catalogue and Settings scenarios
|
||||
- `registry.Provide` mock-mode contract
|
||||
- Confirmed preview script root cause in `plan.md`
|
||||
|
||||
## Output contract
|
||||
|
||||
Report RED and GREEN results, changed files, preview-mode risk, and update this
|
||||
task plus `plan.md` status in the primary conversation.
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
id: "02-update-preview-api"
|
||||
title: "Add the read-only update preview API"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/agents/runtime-updates.md"
|
||||
---
|
||||
|
||||
# Task 02: Add the read-only update preview API
|
||||
|
||||
## Acceptance
|
||||
|
||||
- A managed installed agent exposes current version, upstream target version,
|
||||
trusted update argv, and a display command through a read-only endpoint.
|
||||
- The display command quotes the update recipe's empty final argv entry as
|
||||
`""`, preserving the exact direct-execution command.
|
||||
- Preview never creates a job, claims maintenance state, or executes the
|
||||
update command.
|
||||
- Unmanaged, missing, unavailable-updater, and registry-resolution failures
|
||||
return explicit errors and do not mutate runtime state.
|
||||
|
||||
## Verification
|
||||
|
||||
- RED/GREEN controller:
|
||||
`cd apps/backend && go test -run 'TestAgentUpdatePreview' ./internal/agent/settings/controller`
|
||||
- RED/GREEN handler:
|
||||
`cd apps/backend && go test -run 'TestAgentUpdatePreviewEndpoint' ./internal/agent/settings/handlers`
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/backend/internal/agent/settings/dto/dto.go`
|
||||
- `apps/backend/internal/agent/settings/controller/controller.go`
|
||||
- `apps/backend/internal/agent/settings/controller/controller_test.go`
|
||||
- `apps/backend/internal/agent/settings/controller/agent_update.go`
|
||||
- `apps/backend/internal/agent/settings/controller/agent_update_test.go`
|
||||
- `apps/backend/internal/agent/settings/handlers/handlers.go`
|
||||
- `apps/backend/internal/agent/settings/handlers/agent_update_handlers_test.go`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential by default. It is file-disjoint from Task 01 and may run in
|
||||
parallel only with explicit user authorization.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec update-preview API and approval scenarios
|
||||
- Existing `RuntimeUpdater`, `ManagedNPMRuntimeSpec.CacheUpdateCommand`, and
|
||||
`buildCommandString`
|
||||
- Existing update handler error mapping and direct-argv security boundary
|
||||
|
||||
## Output contract
|
||||
|
||||
Report RED and GREEN results, response/error contracts, changed files, command
|
||||
trust-boundary risk, and update this task plus `plan.md` status.
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
id: "03-update-dialog-ui"
|
||||
title: "Move updates into an ephemeral responsive dialog"
|
||||
status: done
|
||||
wave: 2
|
||||
depends_on: ["02-update-preview-api"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/agents/runtime-updates.md"
|
||||
---
|
||||
|
||||
# Task 03: Move updates into an ephemeral responsive dialog
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Managed cards show only a compact, accessible update icon; versions, command,
|
||||
output, progress, and results appear only in the opened surface.
|
||||
- Opening is read-only and approval is unavailable until current version,
|
||||
target version, explanation, and exact command are visible.
|
||||
- The approved job streams stdout/stderr and terminal state in the current
|
||||
surface, while closing or restarting the page discards its presentation.
|
||||
- Desktop uses a centered dialog; phone uses an inset bottom drawer with a
|
||||
44px trigger, fixed header/footer, one safe-area-aware scrolling body, and no
|
||||
document horizontal overflow.
|
||||
- Public Agents documentation describes the preview/approval dialog and notes
|
||||
that its visible progress and results reset on page restart.
|
||||
|
||||
## Verification
|
||||
|
||||
- Targeted state/WS tests:
|
||||
`cd apps && pnpm --filter @kandev/web test -- --run lib/state/slices/settings/settings-slice.test.ts lib/ws/handlers/agents.test.ts`
|
||||
- Typecheck:
|
||||
`cd apps/web && pnpm run typecheck`
|
||||
- Lint:
|
||||
`cd apps && pnpm --filter @kandev/web lint`
|
||||
- Public docs:
|
||||
`node --test scripts/validate-public-docs.test.mjs && node scripts/validate-public-docs.mjs`
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/lib/api/domains/agent-update-api.ts`
|
||||
- `apps/web/lib/api/index.ts`
|
||||
- `apps/web/hooks/domains/settings/use-agent-runtime-updates.ts`
|
||||
- `apps/web/app/settings/agents/page.tsx`
|
||||
- `apps/web/components/settings/installed-agent-card.tsx`
|
||||
- `apps/web/components/settings/agent-runtime-update-control.tsx`
|
||||
- `apps/web/components/settings/use-agent-update-dialog-state.ts`
|
||||
- `apps/web/lib/state/slices/settings/settings-slice.test.ts`
|
||||
- `docs/public/agents-and-profiles.md`
|
||||
|
||||
## Dependencies
|
||||
|
||||
Task 02 defines the read-only preview contract.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec approval, non-persistence, failure, and mobile scenarios
|
||||
- `components/kanban/mobile-menu-sheet.tsx` mobile surface exemplar
|
||||
- Existing Settings WS job merging and install/update conflict handling
|
||||
- Mobile contract in `plan.md`
|
||||
- `/docs-maintainer` task-oriented documentation requirements
|
||||
|
||||
## Output contract
|
||||
|
||||
Report RED/GREEN evidence where non-visual logic changes, rendered desktop and
|
||||
phone evidence, changed files, accessibility/mobile/state risks, and update
|
||||
this task plus `plan.md` status.
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: "04-update-dialog-e2e"
|
||||
title: "Verify desktop and mobile update dialog flows"
|
||||
status: done
|
||||
wave: 3
|
||||
depends_on: ["01-preview-catalogue", "02-update-preview-api", "03-update-dialog-ui"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/agents/runtime-updates.md"
|
||||
---
|
||||
|
||||
# Task 04: Verify desktop and mobile update dialog flows
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Desktop Playwright proves the icon opens a read-only preview, approval starts
|
||||
one job, and stdout/stderr plus terminal state remain inside the dialog.
|
||||
- Restart coverage proves prior progress/output/result is absent from the card
|
||||
and a newly opened dialog.
|
||||
- Mobile Chrome proves the 44px icon and bottom drawer deliver the same value,
|
||||
keep long content internally reachable, clear safe areas, and do not create
|
||||
document horizontal overflow.
|
||||
|
||||
## Verification
|
||||
|
||||
- Desktop:
|
||||
`cd apps/web && pnpm e2e:run tests/settings/agent-runtime-update.spec.ts`
|
||||
- Mobile:
|
||||
`cd apps/web && pnpm e2e:run tests/settings/mobile-agent-runtime-update.spec.ts -- --project=mobile-chrome`
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/e2e/tests/settings/agent-runtime-update-helpers.ts`
|
||||
- `apps/web/e2e/tests/settings/agent-runtime-update.spec.ts`
|
||||
- `apps/web/e2e/tests/settings/mobile-agent-runtime-update.spec.ts`
|
||||
- Runtime-update UI files only for test IDs or regressions exposed by RED
|
||||
|
||||
## Dependencies
|
||||
|
||||
Tasks 01-03.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Every revised user-visible spec scenario
|
||||
- `/e2e` production-build and mobile input-modality requirements
|
||||
- Mobile geometry contract in `plan.md`
|
||||
|
||||
## Output contract
|
||||
|
||||
Report exact RED and GREEN commands/results, rendered artifacts inspected,
|
||||
desktop/mobile geometry evidence, uncertainties, and update this task plus
|
||||
`plan.md` status.
|
||||
@@ -24,19 +24,22 @@ The status shown on this page is authoritative for the current host. A CLI that
|
||||
|
||||
### Update a managed agent runtime
|
||||
|
||||
Installed Claude, Codex, OpenCode, Copilot, and Gemini cards provide an
|
||||
**Update agent** action. Kandev invokes these managed npm runtimes without an
|
||||
Installed Claude, Codex, OpenCode, Copilot, and Gemini cards provide an update
|
||||
icon. Kandev invokes these managed npm runtimes without an
|
||||
exact version or `latest` tag during ordinary launches, so npm can reuse its
|
||||
best-effort execution cache. The version reported by the agent is the
|
||||
authoritative current version; Kandev does not infer it from the application
|
||||
release.
|
||||
|
||||
Select **Update agent** to deliberately check npm and refresh the managed
|
||||
runtime on the Kandev host. The card shows the current and upstream target
|
||||
versions, streams progress, and remains disabled until the update finishes.
|
||||
After the package update, Kandev automatically starts a fresh ACP capability
|
||||
probe. A successful probe replaces the advertised models, modes, configuration
|
||||
options, commands, and runtime version without a page reload.
|
||||
Select the update icon to deliberately check npm and refresh the managed
|
||||
runtime on the Kandev host. Before anything changes, the update dialog shows
|
||||
the current and upstream target versions, the exact command Kandev will run,
|
||||
and how the update affects sessions. Select **Approve update** to start it.
|
||||
The dialog streams progress and stdout/stderr until the update finishes; those
|
||||
details do not appear on the agent card and are cleared when you restart the
|
||||
page. After the package update, Kandev automatically starts a fresh ACP
|
||||
capability probe. A successful probe replaces the advertised models, modes,
|
||||
configuration options, commands, and runtime version without a page reload.
|
||||
|
||||
The action changes later host probes and sessions only. It does not restart an
|
||||
active session, update a separately configured passthrough or authentication
|
||||
@@ -44,11 +47,11 @@ helper, or update remote executors and running containers. Those environments
|
||||
resolve their own unversioned runtime when they launch.
|
||||
|
||||
If registry lookup or package execution fails, Kandev keeps the previous
|
||||
capability catalogue and shows the captured failure. If the package updates but
|
||||
the follow-up probe requires authentication, the card reports the update plus
|
||||
the refresh error; authenticate the host agent and refresh again. Update job
|
||||
history is short-lived and does not survive a backend restart, and npm cache
|
||||
contents are not a durable Kandev installation record.
|
||||
capability catalogue and shows the captured failure in the dialog. If the
|
||||
package updates but the follow-up probe requires authentication, the dialog
|
||||
reports the update plus the refresh error; authenticate the host agent and
|
||||
refresh again. Update job history is short-lived and does not survive a backend
|
||||
restart, and npm cache contents are not a durable Kandev installation record.
|
||||
|
||||
### Add a custom terminal agent
|
||||
|
||||
|
||||
@@ -20,10 +20,16 @@ cache is already present.
|
||||
tag.
|
||||
- Normal launches may reuse npm's execution cache. Cache reuse is best-effort;
|
||||
Kandev does not present it as a durable installed-version guarantee.
|
||||
- Each supported installed agent has a visible **Update agent** action on the
|
||||
Settings > Agents page on desktop and mobile.
|
||||
- Starting an update shows the current runtime version, the upstream target
|
||||
version, live progress, and the terminal success or failure state.
|
||||
- Each supported installed agent has a compact, accessible update icon action
|
||||
on its Settings > Agents card on desktop and mobile. Update versions,
|
||||
command details, progress, output, and results are not rendered in the card.
|
||||
- Opening the update action is read-only. It opens an update dialog that
|
||||
resolves and shows the current runtime version, upstream target version,
|
||||
exact built-in command, host-only scope, capability refresh, and active
|
||||
session behavior before an update can start.
|
||||
- The update starts only after the operator approves it in the dialog. The
|
||||
dialog then shows live stdout/stderr, progress, and the terminal success or
|
||||
failure state.
|
||||
- A successful package update automatically starts a fresh host capability
|
||||
probe. The returned runtime version, models, modes, configuration options,
|
||||
commands, and capability status replace the previous cached values.
|
||||
@@ -74,6 +80,9 @@ runtime version. Unmanaged agents omit `runtime_update`.
|
||||
|
||||
### Update jobs
|
||||
|
||||
- `GET /api/v1/agent-update/:agentName/preview` resolves the current and
|
||||
upstream target versions and returns the exact trusted built-in update
|
||||
command without starting an update.
|
||||
- `POST /api/v1/agent-update/:agentName` starts or returns the active update
|
||||
job for a built-in managed agent.
|
||||
- `GET /api/v1/agent-update/jobs` returns active and recently completed update
|
||||
@@ -105,6 +114,32 @@ An update job contains:
|
||||
notifications with the same job identity and state. Output notifications carry
|
||||
only the appended output chunk.
|
||||
|
||||
An update preview contains:
|
||||
|
||||
```json
|
||||
{
|
||||
"agent_name": "claude-acp",
|
||||
"package": "@agentclientprotocol/claude-agent-acp",
|
||||
"current_version": "0.62.0",
|
||||
"target_version": "0.63.0",
|
||||
"command": [
|
||||
"npm",
|
||||
"exec",
|
||||
"--yes",
|
||||
"--prefer-online",
|
||||
"--package=@agentclientprotocol/claude-agent-acp",
|
||||
"--",
|
||||
"node",
|
||||
"-e",
|
||||
""
|
||||
],
|
||||
"command_string": "npm exec --yes --prefer-online --package=@agentclientprotocol/claude-agent-acp -- node -e \"\""
|
||||
}
|
||||
```
|
||||
|
||||
The preview endpoint accepts only the built-in agent name. Package names,
|
||||
versions, registry URLs, and command arguments are not caller-controlled.
|
||||
|
||||
## State machine
|
||||
|
||||
| State | Trigger | Observable behavior |
|
||||
@@ -122,6 +157,8 @@ Jobs are terminal after `succeeded` or `failed`. Retrying creates a new job.
|
||||
|
||||
- If npm registry metadata cannot be resolved, the job fails before changing
|
||||
the runtime and retains the prior capability data.
|
||||
- If preview version resolution fails, the dialog shows the error and keeps
|
||||
approval disabled. No update job or package command starts.
|
||||
- If the package update command fails or times out, the job fails and retains
|
||||
the prior capability data.
|
||||
- If the package update succeeds but the capability probe fails because
|
||||
@@ -142,6 +179,9 @@ Jobs are terminal after `succeeded` or `failed`. Retrying creates a new job.
|
||||
- Update jobs and capability data are process-local and do not survive a Kandev
|
||||
backend restart.
|
||||
- Completed jobs remain queryable for the existing short job-retention window.
|
||||
- Settings does not rehydrate retained update jobs after a browser page
|
||||
restart. Update dialog state, output, and results are intentionally
|
||||
page-local and disappear when the page is restarted.
|
||||
- npm's host cache may survive Kandev restarts, but Kandev does not own or
|
||||
guarantee that cache.
|
||||
- After a backend restart, normal host capability probing reports whichever
|
||||
@@ -153,8 +193,12 @@ Jobs are terminal after `succeeded` or `failed`. Retrying creates a new job.
|
||||
without an explicit update, **THEN** Kandev invokes the unversioned package
|
||||
spec and does not require a repository-maintained version pin.
|
||||
- **GIVEN** Claude reports runtime version `0.62.0` and npm reports `0.63.0`,
|
||||
**WHEN** the operator selects **Update agent**, **THEN** the card shows
|
||||
`0.62.0 → 0.63.0` and streams progress until the job is terminal.
|
||||
**WHEN** the operator opens its update action, **THEN** the dialog shows
|
||||
`0.62.0 → 0.63.0`, the exact built-in command, and how the host update
|
||||
affects capabilities and active sessions without starting the command.
|
||||
- **GIVEN** the update dialog has a resolved preview, **WHEN** the operator
|
||||
approves the update, **THEN** Kandev starts exactly one update and the dialog
|
||||
streams stdout/stderr until the job is terminal.
|
||||
- **GIVEN** an update succeeds and the new runtime advertises an additional
|
||||
model, **WHEN** the automatic capability probe completes, **THEN** the new
|
||||
model appears without a page reload or manual Rescan.
|
||||
@@ -164,16 +208,25 @@ Jobs are terminal after `succeeded` or `failed`. Retrying creates a new job.
|
||||
- **GIVEN** an install is active for an agent, **WHEN** an update is requested
|
||||
for that agent, **THEN** Kandev returns the active maintenance job rather
|
||||
than running install and update concurrently.
|
||||
- **GIVEN** npm registry lookup fails, **WHEN** an update is requested,
|
||||
**THEN** the card shows a retryable failure and retains the previous models.
|
||||
- **GIVEN** npm registry lookup fails while preparing the dialog, **WHEN** the
|
||||
update action is opened, **THEN** the dialog shows a retryable preview failure,
|
||||
keeps approval disabled, and starts no update job.
|
||||
- **GIVEN** npm registry lookup succeeds for the preview but fails after
|
||||
approval because the registry changed, **WHEN** the update job resolves its
|
||||
target again, **THEN** the dialog shows a retryable update failure and retains
|
||||
the previous models.
|
||||
- **GIVEN** the package update succeeds but the fresh probe requires
|
||||
authentication, **WHEN** the job finishes, **THEN** the card reports the new
|
||||
package version, shows the refresh error, retains the previous models, and
|
||||
keeps the existing authentication recovery action available.
|
||||
authentication, **WHEN** the job finishes, **THEN** the dialog reports the new
|
||||
package version and refresh error, the previous models remain available, and
|
||||
the card keeps its existing authentication recovery action.
|
||||
- **GIVEN** an agent is unmanaged or native-only, **WHEN** Settings renders its
|
||||
installed card, **THEN** no update action is shown.
|
||||
- **GIVEN** an update dialog has shown progress or a terminal result, **WHEN**
|
||||
the operator restarts the page, **THEN** the dialog is closed and no prior
|
||||
update details, output, or result appear on the agent card or in a newly
|
||||
opened dialog.
|
||||
- **GIVEN** an update is running on a phone viewport, **WHEN** the operator
|
||||
views the installed-agent card, **THEN** current and target versions,
|
||||
views the update surface, **THEN** current and target versions, the command,
|
||||
progress, output, and retry state are reachable by touch without horizontal
|
||||
page scrolling.
|
||||
- **GIVEN** an agent session is already running, **WHEN** its host runtime is
|
||||
@@ -191,3 +244,4 @@ Jobs are terminal after `succeeded` or `failed`. Retrying creates a new job.
|
||||
- Managing native-only update channels such as Cursor.
|
||||
- Updating separately distributed passthrough or authentication helper
|
||||
packages when they are not the managed ACP runtime.
|
||||
- Resuming or recovering update dialog state after a browser page restart.
|
||||
|
||||
Reference in New Issue
Block a user