Commit Graph

3653 Commits

Author SHA1 Message Date
rcourtman d5609a2dc3 Re-pin frontend tests to the Patrol typed-action vocabulary
The Patrol lifecycle work renamed the queued-fix copy (Review fix ->
Recover action, proposed fix -> typed action, and the waiting-for-
approval summaries) and reshaped ApprovalSection's badge constant, but
the unit tests still asserted the old strings and identifiers, leaving
build-and-test red on main since last night. Expectations now match the
shipped source. ApprovalSection kept MetadataBadge and shared Button
variants, so the primitive guardrails re-pin to its current shape
(BADGE_PROPS, no warningSolid variant) rather than flagging a real
regression.
2026-07-11 10:40:20 +01:00
rcourtman eb9954618a Add governed storage pressure cleanup 2026-07-11 10:11:35 +01:00
rcourtman 500d3be2a7 Align Pro feature catalog names with the new Patrol vocabulary
The public pricing surface and in-app plan-selling copy now say
"Patrol investigates issues and explains the root cause" and
"Patrol applies safe fixes and verifies the result". Rename the
licensing catalog DisplayName/ComparisonName pairs to the title-cased
forms, align the ai_autofix UpgradeReason verbs (apply/verify the
result), regenerate the frontend catalog, and update the Go, vitest,
and Playwright pins plus README and PULSE_PRO docs.
2026-07-11 09:33:47 +01:00
rcourtman 1312da3acb Add governed host update autonomy 2026-07-11 01:25:14 +01:00
rcourtman 0b15855de3 Align in-app Plans & Billing copy with the new public pricing vocabulary
The public pricing surface (pulserelay.pro and the license-server pricing
model, pulse-pro 3d9e365/2da1290) now sells Pro with the real Patrol mode
names and plain-English job framing. The in-app plan cards still used the
old taxonomy (Choose Patrol mode, Patrol investigates issues, Patrol
handles safe fixes) and 'admin controls' phrasing. Pro plan-selling copy
now matches the public wording: mode names spelled out (Ask first, Safe
auto-fix, Autopilot), investigation explains the root cause, safe fixes
are verified, and RBAC/audit/reporting/agent profiles are 'team controls'.
Functional CTAs (the Choose Patrol mode link) and canonical mode labels
are unchanged. Test pins updated.

The Go-side feature catalog names (Patrol Investigates Issues / Patrol
Handles Safe Fixes) still carry the old phrasing and are a separate
follow-up since they regenerate from pkg/licensing.
2026-07-11 01:16:00 +01:00
rcourtman b57fb95e20 Fix click-dead zone on the Assistant launcher tab
The document root kept a forced scrollbar (html { overflow-y: scroll })
from before the app-scroll-shell owned scrolling. The root never
scrolls, so the rule only reserved a dead 11px gutter at the right
viewport edge and pulled every fixed right-anchored element off the
true screen edge - parking the desktop Assistant launcher tab under
the scroll shell's own scrollbar, which hit-tests above descendants.
Net effect: the tab's right quarter plus the whole screen-edge strip
silently swallowed clicks, exactly where an edge-docked control gets
aimed at.

Drop the legacy root-scrollbar rule and portal the launcher out of the
scroll shell so its full face receives clicks, flush to the real edge.

Verified live: elementFromPoint returns the button across its entire
width including the last pixel column, and an extreme-edge click opens
the drawer.
2026-07-11 01:02:01 +01:00
rcourtman 69b2028513 Add policy-scoped Patrol autonomy 2026-07-11 00:37:34 +01:00
rcourtman 1ae2c6726d Re-pin vSphere activity date-time guardrail to sortable head
The TrueNAS/vSphere sorting adoption (cf0f027b6) moved the activity
table's When header onto PlatformSortableTableHead, so the guardrail's
literal getPlatformTableHeadClassForKind('numeric-value') pin no longer
matches. The alignment intent survives as the sortable head's
kind="numeric-value" prop; pin that form instead. The metadata-badge
and Button guardrail failures predate the sorting commits and are left
for their owner.
2026-07-11 00:36:28 +01:00
rcourtman cf0f027b64 Adopt shared platform-table sorting on TrueNAS, vSphere, and Proxmox nodes tables
v5 parity follow-up to 20cccc1a9, completing the adoption sweep after the
Kubernetes pass (f66c4b46b). Adopts createPlatformTableSortState +
PlatformSortableTableHead across the TrueNAS systems / apps / services /
network shares / protection / storage topology / VMs tables and the vSphere
hosts / datastores / networks / activity tables: per-table storage keys,
descendingFirst on metric, count, and timestamp columns, the built-in order
preserved until the user sorts, and canonical kind-based alignment via the
sortable head. Composite summary columns (inventory, ports, images, access,
clients, devices, flags, hosts, consumers) stay non-sortable.

The TrueNAS storage topology sorts sibling groups and re-emits the tree
depth-first, so pools re-order against pools and every dataset or disk stays
under its parent; a new sort test pins that plus descending-first metrics and
persistence.

ProxmoxNodesTable drops its bespoke non-persisted createSignal sort for the
same fabric, so the nodes sort now survives reloads like every other platform
table. Its existing sort assertions pass unchanged; the suite now clears
localStorage between tests since the sort persists by design.

Also repairs the platformOverviewLayout guardrails at HEAD: f66c4b46b landed
with the TrueNAS/vSphere head assertions already flipped to the kind form and
the Kubernetes assertions still on the legacy form (a staging race between
parallel agents); this commit carries the version with both sets on the kind
form, which is green against the migrated tables.
2026-07-11 00:15:42 +01:00
rcourtman f66c4b46b3 Restore user column sorting on Kubernetes platform tables
v5 parity follow-up to 20cccc1a9 (v5 KubernetesClusters.tsx persisted
k8s-sort-key/k8s-sort-dir sorting; v6 shipped fixed ordering). Adopts the
shared platform-table sort fabric (createPlatformTableSortState +
PlatformSortableTableHead) across the clusters, nodes, pods, deployments,
controllers, services, storage, config, autoscaling, and networking tables:
per-table storage keys, descendingFirst on metric/count columns (pods Ready
stays ascending-first so the least-ready pods surface), the status-first
compare preserved as the base order until the user sorts, and canonical
kind-based alignment via the sortable head's kind prop. Composite summary
columns (ports, selectors, labels, access/policy, bounds, detail) stay
non-sortable. TrueNAS/vSphere adoption is landing separately.
2026-07-11 00:11:04 +01:00
rcourtman 20cccc1a91 Restore user column sorting on Docker platform tables
v5 parity: v6 platform tables shipped with fixed status-first ordering and
no sortable headers. Adds opt-in sortable-header support to the shared
platform table fabric (createPlatformTableSortState + PlatformSortableTableHead
in sharedPlatformPage.tsx): click cycles first-direction -> flipped -> built-in
order, state persists per table via usePersistentSignal, missing values sink
to the bottom, aria-sort and arrow indicator match the workloads table, and
alignment stays on the canonical kind helpers.

Adopted across the Docker tables (containers, hosts, images, services,
volumes, tasks, swarm nodes, secrets, configs). Container sorting applies
within host groups and stays orthogonal to grouping, unlike v5's
sort-by-host-equals-grouping design. Kubernetes and TrueNAS/vSphere adoption
are follow-ups.
2026-07-10 23:43:45 +01:00
rcourtman d5c4f9adf3 Restore grouped-by-host view and web links on Docker containers
v5 parity regressions reported by a Pro customer after the v6.0.5
upgrade:

- The Docker containers table lost the grouped view: add a
  Grouped/List segmented control (same fabric as the workloads
  table), grouped by host with count badges and host web links,
  persisted locally and defaulting to grouped for multi-host fleets.
- Container web-interface links were buried in the detail drawer's
  access section: the container name now renders through
  WebInterfaceNameLink, linking straight to the resource customUrl
  like VM/LXC guest names do. Applies to all docker native tables
  via the shared name cell.
2026-07-10 22:50:42 +01:00
rcourtman 5bbfce956d Complete Patrol action lifecycle continuity 2026-07-10 21:22:06 +01:00
rcourtman c89918d78e fix(setup): make onboarding actions explicit and truthful 2026-07-10 18:21:56 +01:00
rcourtman 8fbbed4d05 Harden mobile organization settings 2026-07-10 17:37:13 +01:00
rcourtman 27bc1b356f test(frontend): second-pass branch-coverage for vmwarePageModel and dockerPageModel
Add vmwarePageModel.coverage2.test.ts (130 cases; power-state/status mappers,
incident + activity row builders, search haystacks, activity resource
resolution) and dockerPageModel.coverage2.test.ts (108 cases; swarm node/service/
task status mappers, swarm evidence, storage-usage bucket, incident rows and
search). Cover functions disjoint from the existing coverage tests; new test
files only.
2026-07-10 17:11:03 +01:00
rcourtman 6230bc9584 Improve mobile layouts across product surfaces 2026-07-10 16:50:59 +01:00
rcourtman b04aaf876f test(frontend): second-pass branch-coverage for aiFindingPresentation and resourceDetailDrawerTrueNASModel
Add aiFindingPresentation.coverage2.test.ts (176 cases; finding source/severity
presentation, patrol verification/workflow summaries, resolution reason,
attention-queue sort, clipboard formatting) and
resourceDetailDrawerTrueNASModel.coverage2.test.ts (175 cases; percent/duration
formatters, port/volume/network labels, storage-state tone, section builders).
Cover functions disjoint from the existing coverage tests; new test files only.
2026-07-10 16:41:23 +01:00
rcourtman b380388d30 test(frontend): second-pass branch-coverage for truenasPageModel and agentMachineTableModel
Add truenasPageModel.coverage2.test.ts (93 cases; status mappers, incident/rollup
rows, topology cycle-termination, search tokenizers) and
agentMachineTableModel.coverage2.test.ts (55 cases; sortAgentMachines across every
sort key, RAID summary/detail builders, disk/network/thermal accessors). Target
still-uncovered functions from the v8 branch-coverage backlog; new test files only.
2026-07-10 16:29:09 +01:00
rcourtman 8e0a1fb290 Let users override cluster member connection addresses
Settings showed PVE cluster members as read-only rows, so a member whose
discovered address is unreachable from Pulse (internal cluster network IP,
stale DNS) had no manual fix; only agent re-registration could adopt a
better IP, which leaves agent-less members stranded. Surfaced in the
"Install issues with V6" support thread.

The node editor now lists cluster members with a per-member connection
address field that writes ClusterEndpoints[n].IPOverride, the field
re-discovery already preserves and EffectiveIP already prefers at poll
time (editing Host would be clobbered on the next cluster refresh).
PUT /api/config/nodes/{id} accepts write-only clusterEndpointOverrides
entries; only changed members ride the payload, an empty value clears
the override, and unknown members are rejected. The configured-nodes
cache mirrors saved overrides instead of spreading the write-only
payload field onto node config state.
2026-07-10 16:11:17 +01:00
rcourtman 9560fe6c07 feat(updates): surface digest-pinned Pro Docker update commands from the broker
A Docker install of the Pro runtime had no sane update path: the binary
self-updater refuses to run in a container, the customer compose file pins
the previous image digest (so `docker compose pull` never updates), and the
in-app guidance showed community `docker pull rcourtman/pulse:<tag>` commands
that silently downgrade the container to the community build - the same
failure mode 93bccaff1 fixed for binary installs.

The update check on the Pro binary already fetches the license server
download broker manifest (GET /v1/downloads/pulse-pro), which carries the
digest-pinned image ref plus ready-to-run compose commands. Relay that block
on UpdateInfo.dockerUpdate for Docker deployments, behind the existing
stable/rc channel guard, failing closed unless both compose commands
reference the digest-pinned ref (never a mutable tag).

Settings -> Updates now renders those commands as copy blocks when an update
is available, and the idle Docker box, the update banner, and the docker
update plan suppress every community-image command whenever the compiled
runtime identity is pro.

Contracts: api-contracts (update transport dockerUpdate block),
deployment-installability (Pro Docker update path), frontend-primitives
(install guide Pro-runtime guidance), with transport and settings-shell
proofs extended accordingly.
2026-07-10 16:03:59 +01:00
rcourtman 4908434f91 test(frontend): second-pass branch-coverage for resourceStateAdapters
Add resourceStateAdapters.coverage2.test.ts (87 cases) covering the canonical
resource/platform mappers (canonicalizeLegacyPlatformData, nodeFromResource,
buildMemory/buildDisk, PBS/PMG instance + job mappers, merge helpers) not
reached by the existing coverage test. Targets still-uncovered functions from
the v8 branch-coverage backlog; new test file only.
2026-07-10 15:57:42 +01:00
rcourtman 97a30b0600 Introduce the Patrol execution profiles: detection and investigation
Execution posture is now profile-owned through the core-only,
never-serialized tools.ExecutionProfile. Both Patrol profiles are
non-interactive, deny infrastructure mutations, and clear any inherited
autonomous mode. Detection restricts pulse-state mutations to an
explicit allowlist of the finding lifecycle tools - a blanket
pulse-state allowance would also permit alert dismissal and knowledge
writes - while investigation denies all pulse-state mutations, keeping
it structurally read-only. InvocationPolicy gains the allowlist and
Allows() is now tool-name-aware.

Chat turns build ONE effective request executor (control level,
autonomy, profile, resolved context) BEFORE provider projection and
clone that executor per provider attempt, reversing the previous
project-from-base-then-clone order so the offered schema and the
runtime boundary always agree. Scheduled Patrol (ExecutePatrolStream)
now runs under the detection profile instead of autonomous mode -
closing its direct view of Docker/Kubernetes mutation subactions - and
ListAvailableTools projects through the identical path.
toolsForExecutionMode's mode booleans are replaced by the profile on
the executor itself.

Non-interactive profiles independently hide pulse_question from the
manifest AND runtime-block it before the interactive-call-set special
case: a fabricated question call returns a non-interactive error
without emitting a waiting event, and sibling tool calls from the same
provider turn keep processing. Approval waits never block for
non-interactive profiles (they queue), and the tool-only-turn wrap-up
guardrail is interactive-profile-owned instead of keyed on autonomy.
The system prompt describes detection and investigation modes directly
rather than claiming controlled or autonomous execution; the
investigation prompt directs the model toward typed action proposals.

Proofs: detection allowlist enforcement (alerts resolve and knowledge
remember blocked, finding tools allowed, projection agrees),
investigation structural read-only (patrol mutation tools dropped from
the manifest and blocked at runtime), profile clone isolation, profile
prompt modes, and question-tool hiding across profiles.
2026-07-10 15:53:38 +01:00
rcourtman 391d3d0be0 Fix responsive navigation and mobile table layouts 2026-07-10 15:19:50 +01:00
rcourtman ebd15b8c67 test(frontend): branch-coverage for alertsConfigurationModel and alertOverridesModel
Add alertsConfigurationModel.snapshot.test.ts (83 cases, exercising the
factory-fallback branches of readAlertsConfigurationSnapshot and
buildAlertsConfigurationPayload) and alertOverridesModel.projected.test.ts
(81 cases, covering buildProjectedOverrides across every resource-type switch
branch plus the ID-candidate builders). Second-pass coverage targeting still
uncovered functions from the v8 branch-coverage backlog; new test files only.
2026-07-10 14:57:42 +01:00
rcourtman 0eaa636eb5 test(frontend): branch-coverage for toolPresentation and resourceDetailDrawerVmwareModel
Add toolPresentation.coverage.test.ts (42 cases) covering chat tool-call
input/output parsing and command-preview formatting, and
resourceDetailDrawerVmwareModel.coverage.test.ts (91 cases) covering the VMware
detail-drawer section builders. Both target previously uncovered pure functions
from the v8 branch-coverage backlog. New test files only; no source changes.
2026-07-10 14:32:58 +01:00
rcourtman 3aca9d8f7a test(frontend): branch-coverage for licensePresentation and patrolSummaryPresentation
Add licensePresentation.coverage.test.ts (75 cases) and
patrolSummaryPresentation.coverage.test.ts (98 cases) covering previously
uncovered pure presentation/plan/verification functions flagged by the v8
branch-coverage backlog. New test files only; no source changes.
2026-07-10 14:22:57 +01:00
rcourtman 0ebdbbe07c feat(frontend): stripe the reclaimable-cache memory segment
At warning level the used segment turns threshold-yellow, which sat
next to the amber cache segment as one indistinguishable yellow mass.
Give the cache segment a vertical-stripe SVG pattern so the used/cache
split stays readable at every severity color. Stripes are vertical
because the bar's preserveAspectRatio=none scaling would shear a
diagonal texture.
2026-07-10 14:09:17 +01:00
rcourtman 1685358872 fix(frontend): memory tooltip Used label tracks bar severity color
The stacked memory bar colors its used segment by threshold (green
below warning, yellow/red above), but the tooltip legend hard-coded
Used as green. At 80% used the bar read as all-yellow while the
tooltip claimed a green Used section. Derive the legend color from
the same severity as the segment.
2026-07-10 13:45:27 +01:00
rcourtman 99dad2b511 Add a guided Ollama quickstart blessing qwen3:8b for Patrol
Ollama is the zero-cost AI path but the setup row offered only a Server
URL, and Patrol then failed on models that cannot emit tool_calls
(#1463, #847, #1425, #1152, #880). Bless qwen3:8b, the model family
Ollama's own tool-calling docs are written against, verified locally
against Patrol's real preflight: qwen3:8b emitted the tool call on
every run; qwen3:4b never did (0/4), so no low-RAM tag is suggested.

- Registry: SuggestedModel/Note/Equivalents on AIProviderDefinition,
  projected on /api/settings/ai providers; Ollama default model goes
  llama3.2 -> qwen3:8b.
- Provider row: copyable 'ollama pull qwen3:8b' block with hardware
  note, and a next-step hint when a successful test resolves a model
  outside the blessing set.
- Model resolution: exact-ID blessed preference, so pulling qwen3:8b
  makes it the auto-resolved Patrol model with no manual selection.
- Readiness copy names the blessed model (its contract pins landed
  with 94ccc7a0c's staging; this commit restores green).
- manual_ollama_preflight_test.go is the env-gated re-blessing
  harness; contracts updated for ai-runtime, api-contracts,
  frontend-primitives, and the agent-lifecycle/storage-recovery
  dependent boundaries; subsystem_lookup_test line pins follow the
  api-contracts.md insertion.
2026-07-10 13:02:26 +01:00
rcourtman 8d07089eb3 Finish the Assistant & Patrol settings rename to Pulse Intelligence
Commit cc948b022 fixed the Patrol preflight strings that gated keyless
onboarding; this sweeps the rest. Error messages, readiness checks, and
guidance copy that still pointed at the retired Assistant & Patrol
settings page now name the real surfaces: Pulse Intelligence settings
for the area as a whole, and the Provider & Models settings page for
provider-credential guidance, matching the phrasing cc948b022
established. Pinning tests updated in step, including three
ai_handlers_test.go assertions cc948b022 had already left stale.
2026-07-10 12:04:03 +01:00
rcourtman cc948b022c Route keyless Patrol setup to Provider & Models instead of a dead-end model check
A fresh install with no AI provider looped: the Patrol zero state sent
users to the Patrol model check, the check told them to enable Pulse
Assistant in a settings page that does not exist by that name, and the
Patrol model field silently degraded to a bare text input with no hint
that a provider key or Ollama server was the missing step (#1463, #847).

- Preflight and readiness copy now names the real surfaces (Provider &
  Models, Patrol settings) and the real first step: add an API key or an
  Ollama server.
- The Patrol zero-state CTA, header Fix setup link, and readiness
  banners route config-level causes (assistant_disabled,
  provider_not_configured) to Provider & Models; model-level causes
  keep the Check Patrol model action.
- The Patrol model field shows a linked zero-provider notice instead of
  a bare text input when no provider is configured.
- The preflight result box no longer renders the same failure message
  twice.
2026-07-10 11:38:23 +01:00
rcourtman ef19e64b28 Stop dev-server full reloads when test files are saved
Once anything requests a test module through the Vite dev server it joins
the client module graph, and every later save of that file dead-ends HMR
into a full page reload broadcast to all connected clients. With parallel
agents saving test files continuously, the dev UI reloaded out from under
interactive sessions every few seconds during bursts (31k+ reloads in the
hot-dev log), which read as "tabs sometimes don't load when clicked".

Ignore test files in the dev watcher, scoped off vitest's test mode so
watch-mode re-runs still see changes. Verified live: test-file touch no
longer reloads a connected page, source HMR unaffected, vitest run green.
2026-07-10 11:09:40 +01:00
rcourtman f356994869 Extract the transport-independent action lifecycle service
Planning, approval decisions, and execution for typed resource actions
move out of the HTTP handlers in internal/api/actions.go into a new
internal/actionlifecycle.Service owned by api-contracts. The REST
handlers become thin decode/actor/error-mapping adapters over the one
shared service, and ResourceHandlers.ActionLifecycle() exposes the same
service for in-process consumers, so a future Patrol action broker
inherits identical resource lookup, availability checks, plan hashing,
audit persistence, remediation locks, plan-drift revalidation,
execution, and terminal publication instead of loopback HTTP or a
parallel lifecycle.

Behavior is preserved: same status codes, error codes, and audit/
lifecycle persistence ordering, backed by the existing api contract
tests plus new fail-closed proofs for the service itself (unknown
resource/capability, availability refusal, unapproved execution,
remediation lock, plan drift, missing executor, missing store).

Contract text in api-contracts, agent-lifecycle, and storage-recovery
now names the service alongside actions.go and planner.go; the
subsystem registry owns internal/actionlifecycle/ under api-contracts
with a dedicated path policy; the code-standards and contract source
pins follow the moved invariants; and the subsystem_lookup line-number
pin shifts with the api-contracts canonical-files list insertion.

This is the first slice of making the typed action lifecycle the only
autonomous execution route for Patrol, Assistant, and MCP.
2026-07-10 11:06:55 +01:00
rcourtman 3c252918b3 Add branch-coverage tests for eight more frontend models
Covers previously-uncovered branches in truenas page model, disk/storage
presentation, agent machine table, alert overview/config models, connections
table fleet-governance signals, and the TrueNAS detail drawer - 295 assertions
through public entry points, no source changes.
2026-07-10 10:39:47 +01:00
rcourtman 7da1f0ae99 Add branch-coverage tests for eight already-tested frontend models
Covers previously-uncovered branches in proxmox backup recovery, AI finding
presentation, chat tool/transcript formatting, docker page model, alert
history/overrides models, and storage page state - 275 assertions through
public entry points, no source changes.
2026-07-10 09:45:11 +01:00
rcourtman f2b327b42d Cover PBS/PMG resource adapters and vSphere page-model sort ranks 2026-07-10 08:51:21 +01:00
rcourtman 0abeb1a041 Update stale Patrol readiness copy assertions to match shipped strings
Commit 20b310201 renamed the Patrol provider-setup action copy
('Check model' -> 'Fix setup', 'Open Provider & Models' ->
'Check Patrol model' with href /settings/pulse-intelligence/patrol)
and updated the sibling patrol tests, but missed these four, leaving
build-and-test.yml red on main. Point them at the shipped copy.
2026-07-10 08:50:44 +01:00
rcourtman a0170d3252 Block silent downgrades on apply and give the updater a sanctioned rollback path
The in-app updater validated download URL and channel but never compared
the target against the running version, so any valid older release asset
URL installed silently while the UI presented it as an update. ApplyUpdate
now rejects targets at or below the running version on both the community
and Pro broker paths before any history entry or download, with an explicit
allowDowngrade opt-in on POST /api/updates/apply for sanctioned cases.

The rollback half already existed but nothing reached it: createBackup
retains three backups, restoreBackup works, and history records BackupPath,
yet no endpoint or UI called restoreBackup. RollbackToBackup restores the
retained backup recorded on a history entry after re-validating the path
against the managed backup roots, shares the update-in-flight slot with
ApplyUpdate, records an Action rollback history entry linked to the source
update, marks that update rolled_back, streams a restoring stage through
the existing status/SSE machinery, and restarts via the exit-for-systemd
path. POST /api/updates/rollback carries it with the same RequireAdmin plus
settings:write gating as apply. Rollback is purely local, so the Pro
edition gate never applies to it.

Settings now has the update history surface that was missing entirely:
nothing called /api/updates/history before. The Updates panel lists recent
updates with a Roll back action on successful entries whose backup is still
retained, behind a confirmation dialog naming the restore version, and the
rollback rides updateStore's shared pending-apply marker for the
post-restart toast. restoreBackup also honors PULSE_INSTALL_DIR now instead
of hardcoding /opt/pulse, matching createBackup.

Contract deltas ride along: api-contracts picks up the rollback transport
and downgrade-conflict semantics, agent-lifecycle and storage-recovery pin
rollback as server self-update plumbing, ai-runtime and cloud-paid pin the
update watcher stage vocabulary as non-assistant non-paid shell chrome, and
frontend-primitives adds UpdateHistorySection as the history/rollback
presentation owner with matching architecture proofs.
2026-07-10 01:46:08 +01:00
rcourtman eb63de0b75 Harden first-run security boundaries 2026-07-10 01:28:33 +01:00
rcourtman 26a4a062f6 Unify the update apply flow behind one store action with a post-update toast
Both the update banner and the Settings update panel duplicated the
confirm/apply POST with divergent error handling; the banner's failure
path was a native alert(). updateStore.applyUpdate() now owns the POST,
the shared error toast, and a persisted pending-apply marker recording
the pre-update version. On the next version fetch after the post-update
reload, the store confirms the running version moved and shows a
one-time 'Updated to vX.Y.Z' toast, clearing the marker either way.
2026-07-10 01:12:54 +01:00
rcourtman c862fb0ca0 Remove dead frontend type module and re-export barrel
Dead-code audit batch 5: types/responsive.ts (all 8 exports had zero
non-definition references) and the one-line
components/Settings/reportingResourceTypes.ts barrel (all consumers
import @/utils/reportingResourceTypes directly). Both were referenced
only via ?raw text imports in guardrail tests; those imports and their
assertions are dropped here in the same commit. The TYPE_COLUMN_*
contract remains pinned against the live sources
(utils/typeColumnContract.ts, utils/typeColumnDefinition.ts).
2026-07-10 00:36:30 +01:00
rcourtman e5faca5035 Fix Docker update copy to recreate the container instead of docker restart
docker restart reuses the image the container was created with, so the
pulled update never takes effect. Point users at docker compose pull &&
docker compose up -d, with pull/stop/rm and re-run for non-compose
installs, matching docs/DOCKER.md.
2026-07-10 00:22:39 +01:00
rcourtman 85b2bc4008 Improve platform attention workflows 2026-07-10 00:00:07 +01:00
rcourtman 20b3102015 Improve monitor-first frontend workflows 2026-07-09 23:26:53 +01:00
rcourtman 255c7c23d4 Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
rcourtman 54f700371e Add unit tests for 12 untested and weakly-tested frontend modules
Nightly GLM grunt wave: new Vitest coverage for pure logic that had no
test file or only shallow export coverage. 436 test cases, all green;
tsc and eslint clean. Tests characterize current behavior only; no
source was modified.

Untested modules now covered:
- api/responseUtils (19 coercion/guard fns)
- utils/workloads (8 predicates/builders)
- features/storageBackups/storageSearchQuery, storageMetricsIdentity
- utils/platformSupportManifest (12 manifest lookups)
- stores/sessionCapabilities, content/help registry

Weakly-tested modules strengthened (new *.coverage.test.ts):
- utils/format (5 formatters), features/alerts/helpers (apprise round-trip)
- utils/cloudPlans (parseCloudTier), utils/alerts, utils/agentResources
2026-07-09 23:08:09 +01:00
rcourtman 02283c5335 Make connected systems task-first 2026-07-09 22:48:52 +01:00
rcourtman cce58ceb19 Improve platform frontend coherence 2026-07-09 22:27:35 +01:00
rcourtman b26716b3c9 Add unit tests for localStorage, logger, toast utils 2026-07-09 21:47:27 +01:00